From da6402caf76586f92848445d514ead31371eeb23 Mon Sep 17 00:00:00 2001 From: Dmitri Dolguikh Date: Fri, 20 Oct 2017 16:12:37 -0700 Subject: [PATCH] Bootfile urls can be retrieved via remote api calls now --- dhcp6/address_pool.go | 21 ++----- dhcp6/boot_configuration.go | 79 ++++++++++++++++++++++++ dhcp6/packet.go | 60 +++++++++++------- dhcp6/packet_test.go | 49 ++++++++++++--- dhcp6/random_address_pool.go | 14 ++--- dhcp6/random_address_pool_test.go | 28 ++++----- pixiecore/cli/bootipv6cmd.go | 4 +- {pixiecore => pixiecorev6}/dhcpv6.go | 2 +- {pixiecore => pixiecorev6}/pixicorev6.go | 10 ++- 9 files changed, 191 insertions(+), 76 deletions(-) create mode 100644 dhcp6/boot_configuration.go rename {pixiecore => pixiecorev6}/dhcpv6.go (98%) rename {pixiecore => pixiecorev6}/pixicorev6.go (86%) diff --git a/dhcp6/address_pool.go b/dhcp6/address_pool.go index 21dc56c..281e4c8 100644 --- a/dhcp6/address_pool.go +++ b/dhcp6/address_pool.go @@ -6,26 +6,13 @@ import ( ) type IdentityAssociation struct { - ipAddress net.IP - clientId []byte - interfaceId []byte - createdAt time.Time + IpAddress net.IP + ClientId []byte + InterfaceId []byte + CreatedAt time.Time } type AddressPool interface { ReserveAddress(clientId, interfaceId []byte) *IdentityAssociation ReleaseAddress(clientId, interfaceId []byte) } - - - - - - - - - - - - - diff --git a/dhcp6/boot_configuration.go b/dhcp6/boot_configuration.go new file mode 100644 index 0000000..ecc8122 --- /dev/null +++ b/dhcp6/boot_configuration.go @@ -0,0 +1,79 @@ +package dhcp6 + +import ( + "net/http" + "time" + "strings" + "fmt" + "net/url" + "bytes" +) + +type BootConfiguration interface { + GetBootUrl(id []byte, clientArchType uint16) (string, error) +} + +type StaticBootConfiguration struct { + HttpBootUrl string + IPxeBootUrl string +} + +func MakeStaticBootConfiguration(httpBootUrl, ipxeBootUrl string) *StaticBootConfiguration { + return &StaticBootConfiguration{HttpBootUrl: httpBootUrl, IPxeBootUrl: ipxeBootUrl} +} + +func (bc *StaticBootConfiguration) GetBootUrl(id []byte, clientArchType uint16) (string, error) { + if 0x10 == clientArchType { + return bc.HttpBootUrl, nil + } + return bc.IPxeBootUrl, nil +} + +type ApiBootConfiguration struct { + client *http.Client + urlPrefix string +} + +func MakeApiBootConfiguration(url string, timeout time.Duration) *ApiBootConfiguration { + if !strings.HasSuffix(url, "/") { + url += "/" + } + return &ApiBootConfiguration{ + client: &http.Client{Timeout: timeout}, + urlPrefix: url + "v1", + } +} + +func (bc *ApiBootConfiguration) GetBootUrl(id []byte, clientArchType uint16) (string, error) { + reqURL := fmt.Sprintf("%s/boot/%x/%d", bc.urlPrefix, id, clientArchType) + resp, err := bc.client.Get(reqURL) + if err != nil { + return "", err + } + if resp.StatusCode != http.StatusOK { + resp.Body.Close() + return "", fmt.Errorf("%s: %s", reqURL, http.StatusText(resp.StatusCode)) + } + defer resp.Body.Close() + + buf := new(bytes.Buffer) + buf.ReadFrom(resp.Body) + url, _ := bc.makeURLAbsolute(buf.String()) + + return url, nil +} + +func (bc *ApiBootConfiguration) makeURLAbsolute(urlStr string) (string, error) { + u, err := url.Parse(urlStr) + if err != nil { + return "", fmt.Errorf("%q is not an URL", urlStr) + } + if !u.IsAbs() { + base, err := url.Parse(bc.urlPrefix) + if err != nil { + return "", err + } + u = base.ResolveReference(u) + } + return u.String(), nil +} diff --git a/dhcp6/packet.go b/dhcp6/packet.go index 5b072d1..47ce883 100644 --- a/dhcp6/packet.go +++ b/dhcp6/packet.go @@ -3,6 +3,7 @@ package dhcp6 import ( "fmt" "bytes" + "encoding/binary" ) type MessageType uint8 @@ -30,12 +31,11 @@ type Packet struct { } type PacketBuilder struct { - ServerDuid []byte - PreferredLifetime uint32 - ValidLifetime uint32 - BootFileUrlForHttpBoot string - BootFileUrlForIpxe string - Addresses AddressPool + ServerDuid []byte + PreferredLifetime uint32 + ValidLifetime uint32 + BootFileUrl BootConfiguration + Addresses AddressPool } func MakePacket(bs []byte, packetLength int) (*Packet, error) { @@ -48,10 +48,10 @@ func MakePacket(bs []byte, packetLength int) (*Packet, error) { return ret, nil } -func MakePacketBuilder(serverDuid []byte, preferredLifetime, validLifetime uint32, httpBootFileUrl, ipxeBootFileUrl string, +func MakePacketBuilder(serverDuid []byte, preferredLifetime, validLifetime uint32, bootFileUrl BootConfiguration, addressPool AddressPool) *PacketBuilder { return &PacketBuilder{ServerDuid: serverDuid, PreferredLifetime: preferredLifetime, ValidLifetime: validLifetime, - BootFileUrlForHttpBoot: httpBootFileUrl, BootFileUrlForIpxe: ipxeBootFileUrl, Addresses: addressPool} + BootFileUrl: bootFileUrl, Addresses: addressPool} } func (p *Packet) Marshal() ([]byte, error) { @@ -133,11 +133,11 @@ func (b *PacketBuilder) BuildResponse(in *Packet) *Packet { case MsgSolicit: association := b.Addresses.ReserveAddress(in.Options.ClientId(), in.Options.IaNaId()) return b.MakeMsgAdvertise(in.TransactionID, in.Options.ClientId(), in.Options.IaNaId(), - in.Options.ClientArchType(), association.ipAddress) + in.Options.ClientArchType(), association.IpAddress) case MsgRequest: association := b.Addresses.ReserveAddress(in.Options.ClientId(), in.Options.IaNaId()) return b.MakeMsgReply(in.TransactionID, in.Options.ClientId(), in.Options.IaNaId(), - in.Options.ClientArchType(), association.ipAddress) + in.Options.ClientArchType(), association.IpAddress) case MsgInformationRequest: return b.MakeMsgInformationRequestReply(in.TransactionID, in.Options.ClientId(), in.Options.ClientArchType()) @@ -155,13 +155,16 @@ func (b *PacketBuilder) MakeMsgAdvertise(transactionId [3]byte, clientId, iaId [ ret_options.AddOption(MakeIaNaOption(iaId, b.calculateT1(), b.calculateT2(), MakeIaAddrOption(ipAddress, b.PreferredLifetime, b.ValidLifetime))) ret_options.AddOption(MakeOption(OptServerId, b.ServerDuid)) - if 0x10 == clientArchType { // 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, []byte(b.BootFileUrlForHttpBoot))) - } else { - ret_options.AddOption(MakeOption(OptBootfileUrl, []byte(b.BootFileUrlForIpxe))) } + bootfileUrl, err := b.BootFileUrl.GetBootUrl(b.ExtractLLAddressOrId(clientId), clientArchType) + if err != nil { + fmt.Printf("!!!!!!!!!!!!!!!!!!!!!!!! %s", err) + return nil + } + ret_options.AddOption(MakeOption(OptBootfileUrl, []byte(bootfileUrl))) + // ret_options.AddOption(OptRecursiveDns, net.ParseIP("2001:db8:f00f:cafe::1")) //ret_options.AddOption(OptBootfileParam, []byte("http://") //ret.Options[OptPreference] = [][]byte("http://") @@ -175,13 +178,14 @@ func (b *PacketBuilder) MakeMsgReply(transactionId [3]byte, clientId, iaId []byt ret_options.AddOption(MakeIaNaOption(iaId, b.calculateT1(), b.calculateT2(), MakeIaAddrOption(ipAddress, b.PreferredLifetime, b.ValidLifetime))) ret_options.AddOption(MakeOption(OptServerId, b.ServerDuid)) - if 0x10 == clientArchType { // 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, []byte(b.BootFileUrlForHttpBoot))) - } else { - ret_options.AddOption(MakeOption(OptBootfileUrl, []byte(b.BootFileUrlForIpxe))) } + bootfileUrl, err := b.BootFileUrl.GetBootUrl(b.ExtractLLAddressOrId(clientId), clientArchType) + if err != nil { + return nil + } + ret_options.AddOption(MakeOption(OptBootfileUrl, []byte(bootfileUrl))) return &Packet{Type: MsgReply, TransactionID: transactionId, Options: ret_options} } @@ -190,13 +194,14 @@ func (b *PacketBuilder) MakeMsgInformationRequestReply(transactionId [3]byte, cl ret_options := make(Options) ret_options.AddOption(MakeOption(OptClientId, clientId)) ret_options.AddOption(MakeOption(OptServerId, b.ServerDuid)) - if 0x10 == clientArchType { // 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, []byte(b.BootFileUrlForHttpBoot))) - } else { - ret_options.AddOption(MakeOption(OptBootfileUrl, []byte(b.BootFileUrlForIpxe))) } + bootfileUrl, err := b.BootFileUrl.GetBootUrl(b.ExtractLLAddressOrId(clientId), clientArchType) + if err != nil { + return nil + } + ret_options.AddOption(MakeOption(OptBootfileUrl, []byte(bootfileUrl))) return &Packet{Type: MsgReply, TransactionID: transactionId, Options: ret_options} } @@ -221,3 +226,14 @@ func (b *PacketBuilder) calculateT2() uint32 { return (b.PreferredLifetime * 4)/5 } +func (b *PacketBuilder) ExtractLLAddressOrId(optClientId []byte) []byte { + idType := binary.BigEndian.Uint16(optClientId[0:2]) + switch idType { + case 1: + return optClientId[8:] + case 3: + return optClientId[4:] + default: + return optClientId[2:] + } +} \ No newline at end of file diff --git a/dhcp6/packet_test.go b/dhcp6/packet_test.go index 76ce62f..a17e3cd 100644 --- a/dhcp6/packet_test.go +++ b/dhcp6/packet_test.go @@ -12,7 +12,8 @@ func TestMakeMsgAdvertise(t *testing.T) { transactionId := [3]byte{'1', '2', '3'} expectedIp := net.ParseIP("2001:db8:f00f:cafe::1") - builder := MakePacketBuilder(expectedServerId, 90, 100, "httpbootfileurl", "ipxebootfileurl", + bootConfig := MakeStaticBootConfiguration("httpbootfileurl", "ipxebootfileurl") + builder := MakePacketBuilder(expectedServerId, 90, 100, bootConfig, 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) @@ -63,7 +64,8 @@ func TestMakeMsgAdvertiseWithHttpClientArch(t *testing.T) { transactionId := [3]byte{'1', '2', '3'} expectedIp := net.ParseIP("2001:db8:f00f:cafe::1") - builder := MakePacketBuilder(expectedServerId, 90, 100, "httpbootfileurl", "ipxebootfileurl", + bootConfig := MakeStaticBootConfiguration("httpbootfileurl", "ipxebootfileurl") + builder := MakePacketBuilder(expectedServerId, 90, 100, bootConfig, 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) @@ -85,7 +87,8 @@ func TestMakeMsgReply(t *testing.T) { transactionId := [3]byte{'1', '2', '3'} expectedIp := net.ParseIP("2001:db8:f00f:cafe::1") - builder := MakePacketBuilder(expectedServerId, 90, 100, "httpbootfileurl", "ipxebootfileurl", + bootConfig := MakeStaticBootConfiguration("httpbootfileurl", "ipxebootfileurl") + builder := MakePacketBuilder(expectedServerId, 90, 100, bootConfig, NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), net.ParseIP("2001:db8:f00f:cafe::1"), 100)) msg := builder.MakeMsgReply(transactionId, expectedClientId, []byte("1234"), 0x11, expectedIp) @@ -136,7 +139,8 @@ func TestMakeMsgReplyWithHttpClientArch(t *testing.T) { transactionId := [3]byte{'1', '2', '3'} expectedIp := net.ParseIP("2001:db8:f00f:cafe::1") - builder := MakePacketBuilder(expectedServerId, 90, 100, "httpbootfileurl", "ipxebootfileurl", + bootConfig := MakeStaticBootConfiguration("httpbootfileurl", "ipxebootfileurl") + builder := MakePacketBuilder(expectedServerId, 90, 100, bootConfig, NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), net.ParseIP("2001:db8:f00f:cafe::1"), 100)) msg := builder.MakeMsgReply(transactionId, expectedClientId, []byte("1234"), 0x10, expectedIp) @@ -157,7 +161,8 @@ func TestMakeMsgInformationRequestReply(t *testing.T) { expectedServerId := []byte("serverid") transactionId := [3]byte{'1', '2', '3'} - builder := MakePacketBuilder(expectedServerId, 90, 100, "httpbootfileurl", "ipxebootfileurl", + bootConfig := MakeStaticBootConfiguration("httpbootfileurl", "ipxebootfileurl") + builder := MakePacketBuilder(expectedServerId, 90, 100, bootConfig, NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), net.ParseIP("2001:db8:f00f:cafe::1"), 100)) msg := builder.MakeMsgInformationRequestReply(transactionId, expectedClientId, 0x11) @@ -202,7 +207,8 @@ func TestMakeMsgInformationRequestReplyWithHttpClientArch(t *testing.T) { expectedServerId := []byte("serverid") transactionId := [3]byte{'1', '2', '3'} - builder := MakePacketBuilder(expectedServerId, 90, 100, "httpbootfileurl", "ipxebootfileurl", + bootConfig := MakeStaticBootConfiguration("httpbootfileurl", "ipxebootfileurl") + builder := MakePacketBuilder(expectedServerId, 90, 100, bootConfig, NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), net.ParseIP("2001:db8:f00f:cafe::1"), 100)) msg := builder.MakeMsgInformationRequestReply(transactionId, expectedClientId, 0x10) @@ -223,7 +229,8 @@ func TestMakeMsgReleaseReply(t *testing.T) { expectedServerId := []byte("serverid") transactionId := [3]byte{'1', '2', '3'} - builder := MakePacketBuilder(expectedServerId, 90, 100, "httpbootfileurl", "ipxebootfileurl", + bootConfig := MakeStaticBootConfiguration("httpbootfileurl", "ipxebootfileurl") + builder := MakePacketBuilder(expectedServerId, 90, 100, bootConfig, NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), net.ParseIP("2001:db8:f00f:cafe::1"), 100)) msg := builder.MakeMsgReleaseReply(transactionId, expectedClientId) @@ -258,6 +265,33 @@ func TestMakeMsgReleaseReply(t *testing.T) { } } +func TestExtractLLAddressOrIdWithDUIDLLT(t *testing.T) { + builder := &PacketBuilder{} + expectedLLAddress := []byte{0xac, 0xbc, 0x32, 0xae, 0x86, 0x37} + llAddress := builder.ExtractLLAddressOrId([]byte{0x0, 0x1, 0x0, 0x1, 0x1, 0x2, 0x3, 0x4, 0xac, 0xbc, 0x32, 0xae, 0x86, 0x37}) + if string(expectedLLAddress) != string(llAddress) { + t.Fatalf("Expected ll address %x, got: %x", expectedLLAddress, llAddress) + } +} + +func TestExtractLLAddressOrIdWithDUIDEN(t *testing.T) { + builder := &PacketBuilder{} + expectedId := []byte{0x0, 0x1, 0x2, 0x3, 0xac, 0xbc, 0x32, 0xae, 0x86, 0x37} + id := builder.ExtractLLAddressOrId([]byte{0x0, 0x2, 0x0, 0x1, 0x2, 0x3, 0xac, 0xbc, 0x32, 0xae, 0x86, 0x37}) + if string(expectedId) != string(id) { + t.Fatalf("Expected id %x, got: %x", expectedId, id) + } +} + +func TestExtractLLAddressOrIdWithDUIDLL(t *testing.T) { + builder := &PacketBuilder{} + expectedLLAddress := []byte{0xac, 0xbc, 0x32, 0xae, 0x86, 0x37} + llAddress := builder.ExtractLLAddressOrId([]byte{0x0, 0x3, 0x0, 0x1, 0xac, 0xbc, 0x32, 0xae, 0x86, 0x37}) + if string(expectedLLAddress) != string(llAddress) { + t.Fatalf("Expected ll address %x, got: %x", expectedLLAddress, llAddress) + } +} + func TestShouldDiscardSolicitWithoutBootfileUrlOption(t *testing.T) { clientId := []byte("clientid") options := make(Options) @@ -343,6 +377,7 @@ func TestShouldDiscardRequestWithWrongServerId(t *testing.T) { t.Fatalf("Should discard request packet with wrong server id option, but didn't") } } + func MakeOptionRequestOptions(options []uint16) *Option { value := make([]byte, len(options)*2) for i, option := range(options) { diff --git a/dhcp6/random_address_pool.go b/dhcp6/random_address_pool.go index cef9c59..be1fad1 100644 --- a/dhcp6/random_address_pool.go +++ b/dhcp6/random_address_pool.go @@ -91,10 +91,10 @@ func (p *RandomAddressPool) ReserveAddress(clientId, interfaceId []byte) *Identi newIp := big.NewInt(0).Add(p.poolStartAddress, big.NewInt(0).SetUint64(hostOffset)) _, exists := p.usedIps[newIp.Uint64()]; if !exists { timeNow := p.timeNow() - to_ret := &IdentityAssociation{clientId: clientId, - interfaceId: interfaceId, - ipAddress: newIp.Bytes(), - createdAt: timeNow } + to_ret := &IdentityAssociation{ClientId: clientId, + InterfaceId: interfaceId, + IpAddress: newIp.Bytes(), + CreatedAt: timeNow } p.identityAssociations[clientIdHash] = to_ret p.usedIps[newIp.Uint64()] = struct{}{} p.identityAssociationExpirations.Push(&AssociationExpiration{expiresAt: p.calculateAssociationExpiration(timeNow), ia: to_ret}) @@ -113,7 +113,7 @@ func (p *RandomAddressPool) ReleaseAddress(clientId, interfaceId []byte) { p.lock <- 1 return } - delete(p.usedIps, big.NewInt(0).SetBytes(association.ipAddress).Uint64()) + delete(p.usedIps, big.NewInt(0).SetBytes(association.IpAddress).Uint64()) delete(p.identityAssociations, p.calculateIaIdHash(clientId, interfaceId)) p.lock <- 1 } @@ -125,8 +125,8 @@ func (p *RandomAddressPool) ExpireIdentityAssociations() { expiration := p.identityAssociationExpirations.Peek().(*AssociationExpiration) if p.timeNow().Before(expiration.expiresAt) { break } p.identityAssociationExpirations.Shift() - delete(p.identityAssociations, p.calculateIaIdHash(expiration.ia.clientId, expiration.ia.interfaceId)) - delete(p.usedIps, big.NewInt(0).SetBytes(expiration.ia.ipAddress).Uint64()) + delete(p.identityAssociations, p.calculateIaIdHash(expiration.ia.ClientId, expiration.ia.InterfaceId)) + delete(p.usedIps, big.NewInt(0).SetBytes(expiration.ia.IpAddress).Uint64()) } p.lock <- 1 } diff --git a/dhcp6/random_address_pool_test.go b/dhcp6/random_address_pool_test.go index 5584694..63308d6 100644 --- a/dhcp6/random_address_pool_test.go +++ b/dhcp6/random_address_pool_test.go @@ -20,20 +20,20 @@ func TestReserveAddress(t *testing.T) { if ia == nil { t.Fatalf("Expected a non-nil identity association") } - if string(ia.ipAddress) != string(expectedIp) { - t.Fatalf("Expected ip: %v, but got: %v", expectedIp, ia.ipAddress) + if string(ia.IpAddress) != string(expectedIp) { + t.Fatalf("Expected ip: %v, but got: %v", expectedIp, ia.IpAddress) } - if string(ia.clientId) != string(expectedClientId) { - t.Fatalf("Expected client id: %v, but got: %v", expectedClientId, ia.clientId) + if string(ia.ClientId) != string(expectedClientId) { + t.Fatalf("Expected client id: %v, but got: %v", expectedClientId, ia.ClientId) } - if string(ia.interfaceId) != string(expectedIaId) { - t.Fatalf("Expected interface id: %v, but got: %v", expectedIaId, ia.interfaceId) + if string(ia.InterfaceId) != string(expectedIaId) { + t.Fatalf("Expected interface id: %v, but got: %v", expectedIaId, ia.InterfaceId) } - if ia.createdAt != expectedTime { - t.Fatalf("Expected creation time: %v, but got: %v", expectedTime, ia.createdAt) + if ia.CreatedAt != expectedTime { + t.Fatalf("Expected creation time: %v, but got: %v", expectedTime, ia.CreatedAt) } - if ia.createdAt != expectedTime { - t.Fatalf("Expected creation time: %v, but got: %v", expectedTime, ia.createdAt) + if ia.CreatedAt != expectedTime { + t.Fatalf("Expected creation time: %v, but got: %v", expectedTime, ia.CreatedAt) } } @@ -53,8 +53,8 @@ func TestReserveAddressUpdatesAddressPool(t *testing.T) { if !exists { t.Fatalf("Expected to find identity association at %d but didn't", expectedIdx) } - if string(a.clientId) != string(expectedClientId) || string(a.interfaceId) != string(expectedIaId) { - t.Fatalf("Expected ia association with client id %x and ia id %x, but got %x %x respectively", expectedClientId, expectedIaId, a.clientId, a.interfaceId) + if string(a.ClientId) != string(expectedClientId) || string(a.InterfaceId) != string(expectedIaId) { + t.Fatalf("Expected ia association with client id %x and ia id %x, but got %x %x respectively", expectedClientId, expectedIaId, a.ClientId, a.InterfaceId) } } @@ -104,7 +104,7 @@ func TestReserveAddressReturnsExistingAssociation(t *testing.T) { firstAssociation := pool.ReserveAddress(expectedClientId, expectedIaId) secondAssociation := pool.ReserveAddress(expectedClientId, expectedIaId) - if string(firstAssociation.ipAddress) != string(secondAssociation.ipAddress) { + if string(firstAssociation.IpAddress) != string(secondAssociation.IpAddress) { t.Fatal("Expected return of the same ip address on both invocations") } } @@ -122,6 +122,6 @@ func TestReleaseAddress(t *testing.T) { pool.ReleaseAddress(expectedClientId, expectedIaId) _, exists := pool.identityAssociations[pool.calculateIaIdHash(expectedClientId, expectedIaId)]; if exists { - t.Fatalf("identity association for %v should've been removed, but is still available", a.ipAddress) + t.Fatalf("identity association for %v should've been removed, but is still available", a.IpAddress) } } diff --git a/pixiecore/cli/bootipv6cmd.go b/pixiecore/cli/bootipv6cmd.go index af79161..6a4825f 100644 --- a/pixiecore/cli/bootipv6cmd.go +++ b/pixiecore/cli/bootipv6cmd.go @@ -2,8 +2,8 @@ package cli import ( "github.com/spf13/cobra" - "go.universe.tf/netboot/pixiecore" "fmt" + "go.universe.tf/netboot/pixiecorev6" ) var bootIPv6Cmd = &cobra.Command{ @@ -23,7 +23,7 @@ var bootIPv6Cmd = &cobra.Command{ fatalf("Error reading flag: %s", err) } - s := pixiecore.NewServerV6() + s := pixiecorev6.NewServerV6() if addr == "" { fatalf("Please specify address to listen on") diff --git a/pixiecore/dhcpv6.go b/pixiecorev6/dhcpv6.go similarity index 98% rename from pixiecore/dhcpv6.go rename to pixiecorev6/dhcpv6.go index cf522fd..6558484 100644 --- a/pixiecore/dhcpv6.go +++ b/pixiecorev6/dhcpv6.go @@ -1,4 +1,4 @@ -package pixiecore +package pixiecorev6 import ( "go.universe.tf/netboot/dhcp6" diff --git a/pixiecore/pixicorev6.go b/pixiecorev6/pixicorev6.go similarity index 86% rename from pixiecore/pixicorev6.go rename to pixiecorev6/pixicorev6.go index 093744b..86991fb 100644 --- a/pixiecore/pixicorev6.go +++ b/pixiecorev6/pixicorev6.go @@ -1,4 +1,4 @@ -package pixiecore +package pixiecorev6 import ( "go.universe.tf/netboot/dhcp6" @@ -19,7 +19,6 @@ type ServerV6 struct { errs chan error eventsMu sync.Mutex - events map[string][]machineEvent Log func(subsystem, msg string) Debug func(subsystem, msg string) @@ -45,7 +44,6 @@ func (s *ServerV6) Serve() error { s.log("dhcp", "new connection...") - s.events = make(map[string][]machineEvent) // 5 buffer slots, one for each goroutine, plus one for // Shutdown(). We only ever pull the first error out, but shutdown // will likely generate some spurious errors from the other @@ -57,9 +55,9 @@ func (s *ServerV6) Serve() error { s.SetDUID(dhcp.SourceHardwareAddress()) 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, - "http://[2001:db8:f00f:cafe::4]/bootx64.efi", - "http://[2001:db8:f00f:cafe::4]/script.ipxe", addressPool) +// bootConfiguration := dhcp6.MakeStaticBootConfiguration("http://[2001:db8:f00f:cafe::4]/bootx64.efi", "http://[2001:db8:f00f:cafe::4]/script.ipxe") + bootConfiguration := dhcp6.MakeApiBootConfiguration("http://[2001:db8:f00f:cafe::4]:8888/", 10 *time.Second) + packetBuilder := dhcp6.MakePacketBuilder(s.Duid, 1800, 1850, bootConfiguration, addressPool) go func() { s.errs <- s.serveDHCP(dhcp, packetBuilder) }()