fix(dhcp): can not renew an ip address

The dhcp server is systemd-networkd, and the dhcp
plugin can request an ip but can not renew it.
The systemd-networkd just ignore the renew request.

```
2024/09/14 21:46:00 no DHCP packet received within 10s
2024/09/14 21:46:00 retrying in 31.529038 seconds
2024/09/14 21:46:42 no DHCP packet received within 10s
2024/09/14 21:46:42 retrying in 63.150490 seconds
2024/09/14 21:47:45 98184616c91f15419f5cacd012697f85afaa2daeb5d3233e28b0ec21589fb45a/iot/eth1: no more tries
2024/09/14 21:47:45 98184616c91f15419f5cacd012697f85afaa2daeb5d3233e28b0ec21589fb45a/iot/eth1: renewal time expired, rebinding
2024/09/14 21:47:45 Link "eth1" down. Attempting to set up
2024/09/14 21:47:45 98184616c91f15419f5cacd012697f85afaa2daeb5d3233e28b0ec21589fb45a/iot/eth1: lease rebound, expiration is 2024-09-14 22:47:45.309270751 +0800 CST m=+11730.048516519
```

Follow the https://datatracker.ietf.org/doc/html/rfc2131#section-4.3.6,
following options must not be sent in renew

- Requested IP Address
- Server Identifier

Since the upstream code has been inactive for 6 years,
we should switch to another dhcpv4 library.
The new selected one is https://github.com/insomniacslk/dhcp.

Signed-off-by: Songmin Li <lisongmin@protonmail.com>
This commit is contained in:
Songmin Li
2024-09-14 22:00:20 +08:00
committed by Casey Callendrello
parent e4950728ce
commit d61e7e5e1f
310 changed files with 12785 additions and 11182 deletions

148
vendor/github.com/insomniacslk/dhcp/iana/archtype.go generated vendored Normal file
View File

@@ -0,0 +1,148 @@
package iana
import (
"fmt"
"strings"
"github.com/u-root/uio/uio"
)
// Arch encodes an architecture type per RFC 4578, Section 2.1.
type Arch uint16
// See RFC 4578, 5970, and http://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml#processor-architecture
const (
INTEL_X86PC Arch = 0
NEC_PC98 Arch = 1
EFI_ITANIUM Arch = 2
DEC_ALPHA Arch = 3
ARC_X86 Arch = 4
INTEL_LEAN_CLIENT Arch = 5
EFI_IA32 Arch = 6
EFI_X86_64 Arch = 7
EFI_XSCALE Arch = 8
EFI_BC Arch = 9
EFI_ARM32 Arch = 10
EFI_ARM64 Arch = 11
PPC_OPEN_FIRMWARE Arch = 12
PPC_EPAPR Arch = 13
PPC_OPAL Arch = 14
EFI_X86_HTTP Arch = 15
EFI_X86_64_HTTP Arch = 16
EFI_BC_HTTP Arch = 17
EFI_ARM32_HTTP Arch = 18
EFI_ARM64_HTTP Arch = 19
INTEL_X86PC_HTTP Arch = 20
UBOOT_ARM32 Arch = 21
UBOOT_ARM64 Arch = 22
UBOOT_ARM32_HTTP Arch = 23
UBOOT_ARM64_HTTP Arch = 24
EFI_RISCV32 Arch = 25
EFI_RISCV32_HTTP Arch = 26
EFI_RISCV64 Arch = 27
EFI_RISCV64_HTTP Arch = 28
EFI_RISCV128 Arch = 29
EFI_RISCV128_HTTP Arch = 30
S390_BASIC Arch = 31
S390_EXTENDED Arch = 32
EFI_MIPS32 Arch = 33
EFI_MIPS64 Arch = 34
EFI_SUNWAY32 Arch = 35
EFI_SUNWAY64 Arch = 36
)
// archTypeToStringMap maps an Arch to a mnemonic name
var archTypeToStringMap = map[Arch]string{
INTEL_X86PC: "Intel x86PC",
NEC_PC98: "NEC/PC98",
EFI_ITANIUM: "EFI Itanium",
DEC_ALPHA: "DEC Alpha",
ARC_X86: "Arc x86",
INTEL_LEAN_CLIENT: "Intel Lean Client",
EFI_IA32: "EFI IA32",
EFI_XSCALE: "EFI Xscale",
EFI_X86_64: "EFI x86-64",
EFI_BC: "EFI BC",
EFI_ARM32: "EFI ARM32",
EFI_ARM64: "EFI ARM64",
PPC_OPEN_FIRMWARE: "PowerPC Open Firmware",
PPC_EPAPR: "PowerPC ePAPR",
PPC_OPAL: "POWER OPAL v3",
EFI_X86_HTTP: "EFI x86 boot from HTTP",
EFI_X86_64_HTTP: "EFI x86-64 boot from HTTP",
EFI_BC_HTTP: "EFI BC boot from HTTP",
EFI_ARM32_HTTP: "EFI ARM32 boot from HTTP",
EFI_ARM64_HTTP: "EFI ARM64 boot from HTTP",
INTEL_X86PC_HTTP: "Intel x86PC boot from HTTP",
UBOOT_ARM32: "U-Boot ARM32",
UBOOT_ARM64: "U-Boot ARM64",
UBOOT_ARM32_HTTP: "U-boot ARM32 boot from HTTP",
UBOOT_ARM64_HTTP: "U-Boot ARM64 boot from HTTP",
EFI_RISCV32: "EFI RISC-V 32-bit",
EFI_RISCV32_HTTP: "EFI RISC-V 32-bit boot from HTTP",
EFI_RISCV64: "EFI RISC-V 64-bit",
EFI_RISCV64_HTTP: "EFI RISC-V 64-bit boot from HTTP",
EFI_RISCV128: "EFI RISC-V 128-bit",
EFI_RISCV128_HTTP: "EFI RISC-V 128-bit boot from HTTP",
S390_BASIC: "s390 Basic",
S390_EXTENDED: "s390 Extended",
EFI_MIPS32: "EFI MIPS32",
EFI_MIPS64: "EFI MIPS64",
EFI_SUNWAY32: "EFI Sunway 32-bit",
EFI_SUNWAY64: "EFI Sunway 64-bit",
}
// String returns a mnemonic name for a given architecture type.
func (a Arch) String() string {
if at := archTypeToStringMap[a]; at != "" {
return at
}
return "unknown"
}
// Archs represents multiple Arch values.
type Archs []Arch
// Contains returns whether b is one of the Archs in a.
func (a Archs) Contains(b Arch) bool {
for _, t := range a {
if t == b {
return true
}
}
return false
}
// ToBytes returns the serialized option defined by RFC 4578 (DHCPv4) and RFC
// 5970 (DHCPv6) as the Client System Architecture Option.
func (a Archs) ToBytes() []byte {
buf := uio.NewBigEndianBuffer(nil)
for _, at := range a {
buf.Write16(uint16(at))
}
return buf.Data()
}
// String returns the list of archs in a human-readable manner.
func (a Archs) String() string {
s := make([]string, 0, len(a))
for _, arch := range a {
s = append(s, arch.String())
}
return strings.Join(s, ", ")
}
// FromBytes parses a DHCP list of architecture types as defined by RFC 4578
// and RFC 5970.
func (a *Archs) FromBytes(data []byte) error {
buf := uio.NewBigEndianBuffer(data)
if buf.Len() == 0 {
return fmt.Errorf("must have at least one archtype if option is present")
}
*a = make([]Arch, 0, buf.Len()/2)
for buf.Has(2) {
*a = append(*a, Arch(buf.Read16()))
}
return buf.FinError()
}

25
vendor/github.com/insomniacslk/dhcp/iana/entid.go generated vendored Normal file
View File

@@ -0,0 +1,25 @@
package iana
// EnterpriseID represents the Enterprise IDs as set by IANA
type EnterpriseID int
// See https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers for values
const (
EnterpriseIDCiscoSystems EnterpriseID = 9
EnterpriseIDCienaCorporation EnterpriseID = 1271
EnterpriseIDMellanoxTechnologiesLTD EnterpriseID = 33049
)
var enterpriseIDToStringMap = map[EnterpriseID]string{
EnterpriseIDCiscoSystems: "Cisco Systems",
EnterpriseIDCienaCorporation: "Ciena Corporation",
EnterpriseIDMellanoxTechnologiesLTD: "Mellanox Technologies LTD",
}
// String returns the vendor name for a given Enterprise ID
func (e EnterpriseID) String() string {
if vendor := enterpriseIDToStringMap[e]; vendor != "" {
return vendor
}
return "Unknown"
}

91
vendor/github.com/insomniacslk/dhcp/iana/hwtypes.go generated vendored Normal file
View File

@@ -0,0 +1,91 @@
package iana
// HWType is a hardware type as per RFC 2132 and defined by the IANA.
type HWType uint16
// See IANA for values.
const (
_ HWType = iota // skip 0
HWTypeEthernet
HWTypeExperimentalEthernet
HWTypeAmateurRadioAX25
HWTypeProteonTokenRing
HWTypeChaos
HWTypeIEEE802
HWTypeARCNET
HWTypeHyperchannel
HWTypeLanstar
HWTypeAutonet
HWTypeLocalTalk
HWTypeLocalNet
HWTypeUltraLink
HWTypeSMDS
HWTypeFrameRelay
HWTypeATM
HWTypeHDLC
HWTypeFibreChannel
HWTypeATM2
HWTypeSerialLine
HWTypeATM3
HWTypeMILSTD188220
HWTypeMetricom
HWTypeIEEE1394
HWTypeMAPOS
HWTypeTwinaxial
HWTypeEUI64
HWTypeHIPARP
HWTypeISO7816
HWTypeARPSec
HWTypeIPsec
HWTypeInfiniband
HWTypeCAI
HWTypeWiegandInterface
HWTypePureIP
)
var hwTypeToString = map[HWType]string{
HWTypeEthernet: "Ethernet",
HWTypeExperimentalEthernet: "Experimental Ethernet",
HWTypeAmateurRadioAX25: "Amateur Radio AX.25",
HWTypeProteonTokenRing: "Proteon ProNET Token Ring",
HWTypeChaos: "Chaos",
HWTypeIEEE802: "IEEE 802",
HWTypeARCNET: "ARCNET",
HWTypeHyperchannel: "Hyperchannel",
HWTypeLanstar: "Lanstar",
HWTypeAutonet: "Autonet Short Address",
HWTypeLocalTalk: "LocalTalk",
HWTypeLocalNet: "LocalNet",
HWTypeUltraLink: "Ultra link",
HWTypeSMDS: "SMDS",
HWTypeFrameRelay: "Frame Relay",
HWTypeATM: "ATM",
HWTypeHDLC: "HDLC",
HWTypeFibreChannel: "Fibre Channel",
HWTypeATM2: "ATM 2",
HWTypeSerialLine: "Serial Line",
HWTypeATM3: "ATM 3",
HWTypeMILSTD188220: "MIL-STD-188-220",
HWTypeMetricom: "Metricom",
HWTypeIEEE1394: "IEEE 1394.1995",
HWTypeMAPOS: "MAPOS",
HWTypeTwinaxial: "Twinaxial",
HWTypeEUI64: "EUI-64",
HWTypeHIPARP: "HIPARP",
HWTypeISO7816: "IP and ARP over ISO 7816-3",
HWTypeARPSec: "ARPSec",
HWTypeIPsec: "IPsec tunnel",
HWTypeInfiniband: "Infiniband",
HWTypeCAI: "CAI, TIA-102 Project 125 Common Air Interface",
HWTypeWiegandInterface: "Wiegand Interface",
HWTypePureIP: "Pure IP",
}
// String implements fmt.Stringer.
func (h HWType) String() string {
hwtype := hwTypeToString[h]
if hwtype == "" {
hwtype = "unknown"
}
return hwtype
}

2
vendor/github.com/insomniacslk/dhcp/iana/iana.go generated vendored Normal file
View File

@@ -0,0 +1,2 @@
// Package iana contains constants defined by IANA.
package iana

View File

@@ -0,0 +1,77 @@
package iana
// StatusCode represents a IANA status code for DHCPv6
//
// IANA Status Codes for DHCPv6
// https://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml#dhcpv6-parameters-5
type StatusCode uint16
// IANA status codes
const (
// RFC 3315 par. 24..4
StatusSuccess StatusCode = 0
StatusUnspecFail StatusCode = 1
StatusNoAddrsAvail StatusCode = 2
StatusNoBinding StatusCode = 3
StatusNotOnLink StatusCode = 4
StatusUseMulticast StatusCode = 5
StatusNoPrefixAvail StatusCode = 6
// RFC 5007
StatusUnknownQueryType StatusCode = 7
StatusMalformedQuery StatusCode = 8
StatusNotConfigured StatusCode = 9
StatusNotAllowed StatusCode = 10
// RFC 5460
StatusQueryTerminated StatusCode = 11
// RFC 7653
StatusDataMissing StatusCode = 12
StatusCatchUpComplete StatusCode = 13
StatusNotSupported StatusCode = 14
StatusTLSConnectionRefused StatusCode = 15
// RFC 8156
StatusAddressInUse StatusCode = 16
StatusConfigurationConflict StatusCode = 17
StatusMissingBindingInformation StatusCode = 18
StatusOutdatedBindingInformation StatusCode = 19
StatusServerShuttingDown StatusCode = 20
StatusDNSUpdateNotSupported StatusCode = 21
StatusExcessiveTimeSkew StatusCode = 22
)
// String returns a mnemonic name for a given status code
func (s StatusCode) String() string {
if sc := statusCodeToStringMap[s]; sc != "" {
return sc
}
return "Unknown"
}
var statusCodeToStringMap = map[StatusCode]string{
StatusSuccess: "Success",
StatusUnspecFail: "UnspecFail",
StatusNoAddrsAvail: "NoAddrsAvail",
StatusNoBinding: "NoBinding",
StatusNotOnLink: "NotOnLink",
StatusUseMulticast: "UseMulticast",
StatusNoPrefixAvail: "NoPrefixAvail",
// RFC 5007
StatusUnknownQueryType: "UnknownQueryType",
StatusMalformedQuery: "MalformedQuery",
StatusNotConfigured: "NotConfigured",
StatusNotAllowed: "NotAllowed",
// RFC 5460
StatusQueryTerminated: "QueryTerminated",
// RFC 7653
StatusDataMissing: "DataMissing",
StatusCatchUpComplete: "CatchUpComplete",
StatusNotSupported: "NotSupported",
StatusTLSConnectionRefused: "TLSConnectionRefused",
// RFC 8156
StatusAddressInUse: "AddressInUse",
StatusConfigurationConflict: "ConfigurationConflict",
StatusMissingBindingInformation: "MissingBindingInformation",
StatusOutdatedBindingInformation: "OutdatedBindingInformation",
StatusServerShuttingDown: "ServerShuttingDown",
StatusDNSUpdateNotSupported: "DNSUpdateNotSupported",
StatusExcessiveTimeSkew: "ExcessiveTimeSkew",
}