mirror of
https://github.com/danderson/netboot.git
synced 2025-10-17 10:31:28 +02:00
added support for setting server preference option
This commit is contained in:
parent
4d45c38c40
commit
f89f6af9a6
@ -11,15 +11,25 @@ import (
|
|||||||
|
|
||||||
type BootConfiguration interface {
|
type BootConfiguration interface {
|
||||||
GetBootUrl(id []byte, clientArchType uint16) ([]byte, error)
|
GetBootUrl(id []byte, clientArchType uint16) ([]byte, error)
|
||||||
|
GetPreference() []byte
|
||||||
|
GetRecursiveDns() []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
type StaticBootConfiguration struct {
|
type StaticBootConfiguration struct {
|
||||||
HttpBootUrl []byte
|
HttpBootUrl []byte
|
||||||
IPxeBootUrl []byte
|
IPxeBootUrl []byte
|
||||||
|
RecursiveDns []byte
|
||||||
|
Preference []byte
|
||||||
|
UsePreference bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func MakeStaticBootConfiguration(httpBootUrl, ipxeBootUrl string) *StaticBootConfiguration {
|
func MakeStaticBootConfiguration(httpBootUrl, ipxeBootUrl string, preference uint8, usePreference bool) *StaticBootConfiguration {
|
||||||
return &StaticBootConfiguration{HttpBootUrl: []byte(httpBootUrl), IPxeBootUrl: []byte(ipxeBootUrl)}
|
ret := &StaticBootConfiguration{HttpBootUrl: []byte(httpBootUrl), IPxeBootUrl: []byte(ipxeBootUrl), UsePreference: usePreference}
|
||||||
|
if usePreference {
|
||||||
|
ret.Preference = make([]byte, 1)
|
||||||
|
ret.Preference[0] = byte(preference)
|
||||||
|
}
|
||||||
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bc *StaticBootConfiguration) GetBootUrl(id []byte, clientArchType uint16) ([]byte, error) {
|
func (bc *StaticBootConfiguration) GetBootUrl(id []byte, clientArchType uint16) ([]byte, error) {
|
||||||
@ -29,19 +39,37 @@ func (bc *StaticBootConfiguration) GetBootUrl(id []byte, clientArchType uint16)
|
|||||||
return bc.IPxeBootUrl, nil
|
return bc.IPxeBootUrl, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type ApiBootConfiguration struct {
|
func (bc *StaticBootConfiguration) GetPreference() []byte {
|
||||||
client *http.Client
|
return bc.Preference
|
||||||
urlPrefix string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func MakeApiBootConfiguration(url string, timeout time.Duration) *ApiBootConfiguration {
|
func (bc *StaticBootConfiguration) GetRecursiveDns() []byte {
|
||||||
|
return bc.RecursiveDns
|
||||||
|
}
|
||||||
|
|
||||||
|
type ApiBootConfiguration struct {
|
||||||
|
client *http.Client
|
||||||
|
urlPrefix string
|
||||||
|
RecursiveDns []byte
|
||||||
|
Preference []byte
|
||||||
|
UsePreference bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakeApiBootConfiguration(url string, timeout time.Duration, preference uint8, usePreference bool) *ApiBootConfiguration {
|
||||||
if !strings.HasSuffix(url, "/") {
|
if !strings.HasSuffix(url, "/") {
|
||||||
url += "/"
|
url += "/"
|
||||||
}
|
}
|
||||||
return &ApiBootConfiguration{
|
ret := &ApiBootConfiguration{
|
||||||
client: &http.Client{Timeout: timeout},
|
client: &http.Client{Timeout: timeout},
|
||||||
urlPrefix: url + "v1",
|
urlPrefix: url + "v1",
|
||||||
|
UsePreference: usePreference,
|
||||||
}
|
}
|
||||||
|
if usePreference {
|
||||||
|
ret.Preference = make([]byte, 1)
|
||||||
|
ret.Preference[0] = byte(preference)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bc *ApiBootConfiguration) GetBootUrl(id []byte, clientArchType uint16) ([]byte, error) {
|
func (bc *ApiBootConfiguration) GetBootUrl(id []byte, clientArchType uint16) ([]byte, error) {
|
||||||
@ -77,3 +105,11 @@ func (bc *ApiBootConfiguration) makeURLAbsolute(urlStr string) (string, error) {
|
|||||||
}
|
}
|
||||||
return u.String(), nil
|
return u.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (bc *ApiBootConfiguration) GetPreference() []byte {
|
||||||
|
return bc.Preference
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bc *ApiBootConfiguration) GetRecursiveDns() []byte {
|
||||||
|
return bc.RecursiveDns
|
||||||
|
}
|
||||||
|
@ -34,7 +34,7 @@ type PacketBuilder struct {
|
|||||||
ServerDuid []byte
|
ServerDuid []byte
|
||||||
PreferredLifetime uint32
|
PreferredLifetime uint32
|
||||||
ValidLifetime uint32
|
ValidLifetime uint32
|
||||||
BootFileUrl BootConfiguration
|
Configuration BootConfiguration
|
||||||
Addresses AddressPool
|
Addresses AddressPool
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ func MakePacket(bs []byte, packetLength int) (*Packet, error) {
|
|||||||
func MakePacketBuilder(serverDuid []byte, preferredLifetime, validLifetime uint32, bootFileUrl BootConfiguration,
|
func MakePacketBuilder(serverDuid []byte, preferredLifetime, validLifetime uint32, bootFileUrl BootConfiguration,
|
||||||
addressPool AddressPool) *PacketBuilder {
|
addressPool AddressPool) *PacketBuilder {
|
||||||
return &PacketBuilder{ServerDuid: serverDuid, PreferredLifetime: preferredLifetime, ValidLifetime: validLifetime,
|
return &PacketBuilder{ServerDuid: serverDuid, PreferredLifetime: preferredLifetime, ValidLifetime: validLifetime,
|
||||||
BootFileUrl: bootFileUrl, Addresses: addressPool}
|
Configuration: bootFileUrl, Addresses: addressPool}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Packet) Marshal() ([]byte, error) {
|
func (p *Packet) Marshal() ([]byte, error) {
|
||||||
@ -129,25 +129,26 @@ func ShouldDiscardInformationRequest(p *Packet, serverDuid []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *PacketBuilder) BuildResponse(in *Packet) (*Packet, error) {
|
func (b *PacketBuilder) BuildResponse(in *Packet) (*Packet, error) {
|
||||||
|
|
||||||
switch in.Type {
|
switch in.Type {
|
||||||
case MsgSolicit:
|
case MsgSolicit:
|
||||||
association := b.Addresses.ReserveAddress(in.Options.ClientId(), in.Options.IaNaId())
|
association := b.Addresses.ReserveAddress(in.Options.ClientId(), in.Options.IaNaId())
|
||||||
bootFileUrl, err := b.BootFileUrl.GetBootUrl(b.ExtractLLAddressOrId(in.Options.ClientId()), in.Options.ClientArchType())
|
bootFileUrl, err := b.Configuration.GetBootUrl(b.ExtractLLAddressOrId(in.Options.ClientId()), in.Options.ClientArchType())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return b.MakeMsgAdvertise(in.TransactionID, in.Options.ClientId(), in.Options.IaNaId(),
|
return b.MakeMsgAdvertise(in.TransactionID, in.Options.ClientId(), in.Options.IaNaId(),
|
||||||
in.Options.ClientArchType(), association.IpAddress, bootFileUrl), nil
|
in.Options.ClientArchType(), association.IpAddress, bootFileUrl, b.Configuration.GetPreference()), nil
|
||||||
case MsgRequest:
|
case MsgRequest:
|
||||||
association := b.Addresses.ReserveAddress(in.Options.ClientId(), in.Options.IaNaId())
|
association := b.Addresses.ReserveAddress(in.Options.ClientId(), in.Options.IaNaId())
|
||||||
bootFileUrl, err := b.BootFileUrl.GetBootUrl(b.ExtractLLAddressOrId(in.Options.ClientId()), in.Options.ClientArchType())
|
bootFileUrl, err := b.Configuration.GetBootUrl(b.ExtractLLAddressOrId(in.Options.ClientId()), in.Options.ClientArchType())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return b.MakeMsgReply(in.TransactionID, in.Options.ClientId(), in.Options.IaNaId(),
|
return b.MakeMsgReply(in.TransactionID, in.Options.ClientId(), in.Options.IaNaId(),
|
||||||
in.Options.ClientArchType(), association.IpAddress, bootFileUrl), nil
|
in.Options.ClientArchType(), association.IpAddress, bootFileUrl), nil
|
||||||
case MsgInformationRequest:
|
case MsgInformationRequest:
|
||||||
bootFileUrl, err := b.BootFileUrl.GetBootUrl(b.ExtractLLAddressOrId(in.Options.ClientId()), in.Options.ClientArchType())
|
bootFileUrl, err := b.Configuration.GetBootUrl(b.ExtractLLAddressOrId(in.Options.ClientId()), in.Options.ClientArchType())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -161,8 +162,8 @@ func (b *PacketBuilder) BuildResponse(in *Packet) (*Packet, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *PacketBuilder) MakeMsgAdvertise(transactionId [3]byte, clientId, iaId []byte, clientArchType uint16, ipAddress []byte,
|
func (b *PacketBuilder) MakeMsgAdvertise(transactionId [3]byte, clientId, iaId []byte, clientArchType uint16, ipAddress,
|
||||||
bootFileUrl []byte) *Packet {
|
bootFileUrl, preference []byte) *Packet {
|
||||||
ret_options := make(Options)
|
ret_options := make(Options)
|
||||||
ret_options.AddOption(MakeOption(OptClientId, clientId))
|
ret_options.AddOption(MakeOption(OptClientId, clientId))
|
||||||
ret_options.AddOption(MakeIaNaOption(iaId, b.calculateT1(), b.calculateT2(),
|
ret_options.AddOption(MakeIaNaOption(iaId, b.calculateT1(), b.calculateT2(),
|
||||||
@ -172,15 +173,15 @@ func (b *PacketBuilder) MakeMsgAdvertise(transactionId [3]byte, clientId, iaId [
|
|||||||
ret_options.AddOption(MakeOption(OptVendorClass, []byte {0, 0, 0, 0, 0, 10, 72, 84, 84, 80, 67, 108, 105, 101, 110, 116})) // HTTPClient
|
ret_options.AddOption(MakeOption(OptVendorClass, []byte {0, 0, 0, 0, 0, 10, 72, 84, 84, 80, 67, 108, 105, 101, 110, 116})) // HTTPClient
|
||||||
}
|
}
|
||||||
ret_options.AddOption(MakeOption(OptBootfileUrl, bootFileUrl))
|
ret_options.AddOption(MakeOption(OptBootfileUrl, bootFileUrl))
|
||||||
|
if preference != nil {ret_options.AddOption(MakeOption(OptPreference, preference))}
|
||||||
|
|
||||||
// ret_options.AddOption(OptRecursiveDns, net.ParseIP("2001:db8:f00f:cafe::1"))
|
// ret_options.AddOption(OptRecursiveDns, net.ParseIP("2001:db8:f00f:cafe::1"))
|
||||||
//ret_options.AddOption(OptBootfileParam, []byte("http://")
|
//ret_options.AddOption(OptBootfileParam, []byte("http://")
|
||||||
//ret.Options[OptPreference] = [][]byte("http://")
|
|
||||||
|
|
||||||
return &Packet{Type: MsgAdvertise, TransactionID: transactionId, Options: ret_options}
|
return &Packet{Type: MsgAdvertise, TransactionID: transactionId, Options: ret_options}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *PacketBuilder) MakeMsgReply(transactionId [3]byte, clientId, iaId []byte, clientArchType uint16, ipAddress []byte,
|
func (b *PacketBuilder) MakeMsgReply(transactionId [3]byte, clientId, iaId []byte, clientArchType uint16, ipAddress,
|
||||||
bootFileUrl []byte) *Packet {
|
bootFileUrl []byte) *Packet {
|
||||||
ret_options := make(Options)
|
ret_options := make(Options)
|
||||||
ret_options.AddOption(MakeOption(OptClientId, clientId))
|
ret_options.AddOption(MakeOption(OptClientId, clientId))
|
||||||
|
@ -16,7 +16,8 @@ func TestMakeMsgAdvertise(t *testing.T) {
|
|||||||
builder := MakePacketBuilder(expectedServerId, 90, 100, nil,
|
builder := MakePacketBuilder(expectedServerId, 90, 100, nil,
|
||||||
NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), net.ParseIP("2001:db8:f00f:cafe::1"), 100))
|
NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), net.ParseIP("2001:db8:f00f:cafe::1"), 100))
|
||||||
|
|
||||||
msg := builder.MakeMsgAdvertise(transactionId, expectedClientId, []byte("1234"), 0x11, expectedIp, expectedBootFileUrl)
|
msg := builder.MakeMsgAdvertise(transactionId, expectedClientId, []byte("1234"), 0x11, expectedIp,
|
||||||
|
expectedBootFileUrl, nil)
|
||||||
|
|
||||||
if msg.Type != MsgAdvertise {
|
if msg.Type != MsgAdvertise {
|
||||||
t.Fatalf("Expected message type %d, got %d", MsgAdvertise, msg.Type)
|
t.Fatalf("Expected message type %d, got %d", MsgAdvertise, msg.Type)
|
||||||
@ -59,6 +60,28 @@ func TestMakeMsgAdvertise(t *testing.T) {
|
|||||||
if iaNaOption == nil {
|
if iaNaOption == nil {
|
||||||
t.Fatalf("interface non-temporary association option should be present")
|
t.Fatalf("interface non-temporary association option should be present")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
preferenceOption := msg.Options[OptPreference]
|
||||||
|
if preferenceOption != nil {
|
||||||
|
t.Fatalf("Preference option shouldn't be set")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestShouldSetPreferenceOptionWhenSpecified(t *testing.T) {
|
||||||
|
builder := MakePacketBuilder([]byte("serverid"), 90, 100, nil,
|
||||||
|
NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), net.ParseIP("2001:db8:f00f:cafe::1"), 100))
|
||||||
|
|
||||||
|
expectedPreference := []byte{128}
|
||||||
|
msg := builder.MakeMsgAdvertise([3]byte{'t', 'i', 'd'}, []byte("clientid"), []byte("1234"), 0x11,
|
||||||
|
net.ParseIP("2001:db8:f00f:cafe::1"), []byte("http://bootfileurl"), expectedPreference)
|
||||||
|
|
||||||
|
preferenceOption := msg.Options[OptPreference]
|
||||||
|
if preferenceOption == nil {
|
||||||
|
t.Fatalf("Preference option should be set")
|
||||||
|
}
|
||||||
|
if string(expectedPreference) != string(preferenceOption.Value) {
|
||||||
|
t.Fatalf("Expected preference value %d, got %d", expectedPreference, preferenceOption.Value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMakeMsgAdvertiseWithHttpClientArch(t *testing.T) {
|
func TestMakeMsgAdvertiseWithHttpClientArch(t *testing.T) {
|
||||||
@ -71,7 +94,8 @@ func TestMakeMsgAdvertiseWithHttpClientArch(t *testing.T) {
|
|||||||
builder := MakePacketBuilder(expectedServerId, 90, 100, nil,
|
builder := MakePacketBuilder(expectedServerId, 90, 100, nil,
|
||||||
NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), net.ParseIP("2001:db8:f00f:cafe::1"), 100))
|
NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), net.ParseIP("2001:db8:f00f:cafe::1"), 100))
|
||||||
|
|
||||||
msg := builder.MakeMsgAdvertise(transactionId, expectedClientId, []byte("1234"), 0x10, expectedIp, expectedBootFileUrl)
|
msg := builder.MakeMsgAdvertise(transactionId, expectedClientId, []byte("1234"), 0x10, expectedIp,
|
||||||
|
expectedBootFileUrl, nil)
|
||||||
|
|
||||||
vendorClassOption := msg.Options[OptVendorClass]
|
vendorClassOption := msg.Options[OptVendorClass]
|
||||||
if vendorClassOption == nil {
|
if vendorClassOption == nil {
|
||||||
@ -82,7 +106,7 @@ func TestMakeMsgAdvertiseWithHttpClientArch(t *testing.T) {
|
|||||||
t.Fatalf("Bootfile URL option should be present")
|
t.Fatalf("Bootfile URL option should be present")
|
||||||
}
|
}
|
||||||
if string(expectedBootFileUrl) != string(bootfileUrlOption.Value) {
|
if string(expectedBootFileUrl) != string(bootfileUrlOption.Value) {
|
||||||
t.Fatalf("Expected bootfile URL %v, got %v", expectedBootFileUrl, bootfileUrlOption)
|
t.Fatalf("Expected bootfile URL %s, got %s", expectedBootFileUrl, bootfileUrlOption)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,11 @@ var bootIPv6Cmd = &cobra.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
s.Address = addr
|
s.Address = addr
|
||||||
s.BootUrls = dhcp6.MakeStaticBootConfiguration(httpBootUrl, ipxeUrl)
|
preference, err := cmd.Flags().GetUint8("preference")
|
||||||
|
if err != nil {
|
||||||
|
fatalf("Error reading flag: %s", err)
|
||||||
|
}
|
||||||
|
s.BootConfig = dhcp6.MakeStaticBootConfiguration(httpBootUrl, ipxeUrl, preference, cmd.Flags().Changed("preference"))
|
||||||
|
|
||||||
fmt.Println(s.Serve())
|
fmt.Println(s.Serve())
|
||||||
},
|
},
|
||||||
@ -56,6 +60,7 @@ func serverv6ConfigFlags(cmd *cobra.Command) {
|
|||||||
cmd.Flags().StringP("ipxe-url", "", "", "IPXE config file url, e.g. http://[2001:db8:f00f:cafe::4]/script.ipxe")
|
cmd.Flags().StringP("ipxe-url", "", "", "IPXE config file url, e.g. http://[2001:db8:f00f:cafe::4]/script.ipxe")
|
||||||
cmd.Flags().StringP("httpboot-url", "", "", "HTTPBoot url, e.g. http://[2001:db8:f00f:cafe::4]/bootx64.efi")
|
cmd.Flags().StringP("httpboot-url", "", "", "HTTPBoot url, e.g. http://[2001:db8:f00f:cafe::4]/bootx64.efi")
|
||||||
cmd.Flags().Bool("debug", false, "Enable debug-level logging")
|
cmd.Flags().Bool("debug", false, "Enable debug-level logging")
|
||||||
|
cmd.Flags().Uint8("preference", 255, "Set dhcp server preference value")
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -42,7 +42,12 @@ var ipv6ApiCmd = &cobra.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
s.Address = addr
|
s.Address = addr
|
||||||
s.BootUrls = dhcp6.MakeApiBootConfiguration(apiUrl, apiTimeout)
|
preference, err := cmd.Flags().GetUint8("preference")
|
||||||
|
if err != nil {
|
||||||
|
fatalf("Error reading flag: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.BootConfig = dhcp6.MakeApiBootConfiguration(apiUrl, apiTimeout, preference, cmd.Flags().Changed("preference"))
|
||||||
|
|
||||||
fmt.Println(s.Serve())
|
fmt.Println(s.Serve())
|
||||||
},
|
},
|
||||||
@ -53,6 +58,7 @@ func serverv6ApiConfigFlags(cmd *cobra.Command) {
|
|||||||
cmd.Flags().StringP("api-request-url", "", "", "Ipv6-specific API server url")
|
cmd.Flags().StringP("api-request-url", "", "", "Ipv6-specific API server url")
|
||||||
cmd.Flags().Duration("api-request-timeout", 5*time.Second, "Timeout for request to the API server")
|
cmd.Flags().Duration("api-request-timeout", 5*time.Second, "Timeout for request to the API server")
|
||||||
cmd.Flags().Bool("debug", false, "Enable debug-level logging")
|
cmd.Flags().Bool("debug", false, "Enable debug-level logging")
|
||||||
|
cmd.Flags().Uint8("preference", 255, "Set dhcp server preference value")
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -21,11 +21,11 @@ func (s *ServerV6) serveDHCP(conn *dhcp6.Conn, packetBuilder *dhcp6.PacketBuilde
|
|||||||
|
|
||||||
response, err := packetBuilder.BuildResponse(pkt)
|
response, err := packetBuilder.BuildResponse(pkt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log("dhcpv6", fmt.Sprintf("Error creating response for transaction: %s: %s", pkt.TransactionID, err))
|
s.log("dhcpv6", fmt.Sprintf("Error creating response for transaction: %d: %s", pkt.TransactionID, err))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if response == nil {
|
if response == nil {
|
||||||
s.log("dhcpv6", fmt.Sprintf("Don't know how to respond to packet type: %d (transaction id %s)", pkt.Type, pkt.TransactionID))
|
s.log("dhcpv6", fmt.Sprintf("Don't know how to respond to packet type: %d (transaction id %d)", pkt.Type, pkt.TransactionID))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,10 +9,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ServerV6 struct {
|
type ServerV6 struct {
|
||||||
Address string
|
Address string
|
||||||
Port string
|
Port string
|
||||||
Duid []byte
|
Duid []byte
|
||||||
BootUrls dhcp6.BootConfiguration
|
BootConfig dhcp6.BootConfiguration
|
||||||
|
|
||||||
errs chan error
|
errs chan error
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ func (s *ServerV6) Serve() error {
|
|||||||
s.SetDUID(dhcp.SourceHardwareAddress())
|
s.SetDUID(dhcp.SourceHardwareAddress())
|
||||||
|
|
||||||
addressPool := dhcp6.NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::10"), net.ParseIP("2001:db8:f00f:cafe::100"), 1850)
|
addressPool := dhcp6.NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::10"), net.ParseIP("2001:db8:f00f:cafe::100"), 1850)
|
||||||
packetBuilder := dhcp6.MakePacketBuilder(s.Duid, 1800, 1850, s.BootUrls, addressPool)
|
packetBuilder := dhcp6.MakePacketBuilder(s.Duid, 1800, 1850, s.BootConfig, addressPool)
|
||||||
|
|
||||||
go func() { s.errs <- s.serveDHCP(dhcp, packetBuilder) }()
|
go func() { s.errs <- s.serveDHCP(dhcp, packetBuilder) }()
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user