From b78d515ee1d47ee66c1132a7c69848b74b0c91c7 Mon Sep 17 00:00:00 2001 From: Dmitri Dolguikh Date: Mon, 30 Oct 2017 15:14:32 -0700 Subject: [PATCH] Added cli options for address pool configuration --- dhcp6/packet_builder.go | 24 ++++++++++-------------- dhcp6/packet_builder_test.go | 30 ++++++++++-------------------- pixiecore/cli/bootipv6cmd.go | 19 +++++++++++++++++++ pixiecore/cli/ipv6apicmd.go | 21 +++++++++++++++++++-- pixiecorev6/dhcpv6.go | 4 ++-- pixiecorev6/pixicorev6.go | 16 ++++++++-------- 6 files changed, 68 insertions(+), 46 deletions(-) diff --git a/dhcp6/packet_builder.go b/dhcp6/packet_builder.go index 809367f..6e0a700 100644 --- a/dhcp6/packet_builder.go +++ b/dhcp6/packet_builder.go @@ -9,46 +9,42 @@ type PacketBuilder struct { ServerDuid []byte PreferredLifetime uint32 ValidLifetime uint32 - Configuration BootConfiguration - Addresses AddressPool } -func MakePacketBuilder(serverDuid []byte, preferredLifetime, validLifetime uint32, bootFileUrl BootConfiguration, - addressPool AddressPool) *PacketBuilder { - return &PacketBuilder{ServerDuid: serverDuid, PreferredLifetime: preferredLifetime, ValidLifetime: validLifetime, - Configuration: bootFileUrl, Addresses: addressPool} +func MakePacketBuilder(serverDuid []byte, preferredLifetime, validLifetime uint32) *PacketBuilder { + return &PacketBuilder{ServerDuid: serverDuid, PreferredLifetime: preferredLifetime, ValidLifetime: validLifetime} } -func (b *PacketBuilder) BuildResponse(in *Packet) (*Packet, error) { +func (b *PacketBuilder) BuildResponse(in *Packet, configuration BootConfiguration, addresses AddressPool) (*Packet, error) { switch in.Type { case MsgSolicit: - bootFileUrl, err := b.Configuration.GetBootUrl(b.ExtractLLAddressOrId(in.Options.ClientId()), in.Options.ClientArchType()) + bootFileUrl, err := configuration.GetBootUrl(b.ExtractLLAddressOrId(in.Options.ClientId()), in.Options.ClientArchType()) if err != nil { return nil, err } - associations, err := b.Addresses.ReserveAddresses(in.Options.ClientId(), in.Options.IaNaIds()) + associations, err := addresses.ReserveAddresses(in.Options.ClientId(), in.Options.IaNaIds()) if err != nil { return b.MakeMsgAdvertiseWithNoAddrsAvailable(in.TransactionID, in.Options.ClientId(), err), err } return b.MakeMsgAdvertise(in.TransactionID, in.Options.ClientId(), - in.Options.ClientArchType(), associations, bootFileUrl, b.Configuration.GetPreference()), nil + in.Options.ClientArchType(), associations, bootFileUrl, configuration.GetPreference()), nil case MsgRequest: - bootFileUrl, err := b.Configuration.GetBootUrl(b.ExtractLLAddressOrId(in.Options.ClientId()), in.Options.ClientArchType()) + bootFileUrl, err := configuration.GetBootUrl(b.ExtractLLAddressOrId(in.Options.ClientId()), in.Options.ClientArchType()) if err != nil { return nil, err } - associations, err := b.Addresses.ReserveAddresses(in.Options.ClientId(), in.Options.IaNaIds()) + associations, err := addresses.ReserveAddresses(in.Options.ClientId(), in.Options.IaNaIds()) return b.MakeMsgReply(in.TransactionID, in.Options.ClientId(), in.Options.ClientArchType(), associations, iasWithoutAddesses(associations, in.Options.IaNaIds()), bootFileUrl, err), err case MsgInformationRequest: - bootFileUrl, err := b.Configuration.GetBootUrl(b.ExtractLLAddressOrId(in.Options.ClientId()), in.Options.ClientArchType()) + bootFileUrl, err := configuration.GetBootUrl(b.ExtractLLAddressOrId(in.Options.ClientId()), in.Options.ClientArchType()) if err != nil { return nil, err } return b.MakeMsgInformationRequestReply(in.TransactionID, in.Options.ClientId(), in.Options.ClientArchType(), bootFileUrl), nil case MsgRelease: - b.Addresses.ReleaseAddresses(in.Options.ClientId(), in.Options.IaNaIds()) + addresses.ReleaseAddresses(in.Options.ClientId(), in.Options.IaNaIds()) return b.MakeMsgReleaseReply(in.TransactionID, in.Options.ClientId()), nil default: return nil, nil diff --git a/dhcp6/packet_builder_test.go b/dhcp6/packet_builder_test.go index ddf571c..a99fac5 100644 --- a/dhcp6/packet_builder_test.go +++ b/dhcp6/packet_builder_test.go @@ -16,8 +16,7 @@ func TestMakeMsgAdvertise(t *testing.T) { expectedBootFileUrl := []byte("http://bootfileurl") identityAssociation := &IdentityAssociation{IpAddress: expectedIp, InterfaceId: expectedInterfaceId} - builder := MakePacketBuilder(expectedServerId, 90, 100, nil, - NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), 1, 100)) + builder := MakePacketBuilder(expectedServerId, 90, 100) msg := builder.MakeMsgAdvertise(transactionId, expectedClientId, 0x11, []*IdentityAssociation{identityAssociation}, expectedBootFileUrl, nil) @@ -67,8 +66,7 @@ func TestMakeMsgAdvertise(t *testing.T) { func TestShouldSetPreferenceOptionWhenSpecified(t *testing.T) { identityAssociation := &IdentityAssociation{IpAddress: net.ParseIP("2001:db8:f00f:cafe::1"), InterfaceId: []byte("id-1")} - builder := MakePacketBuilder([]byte("serverid"), 90, 100, nil, - NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), 1, 100)) + builder := MakePacketBuilder([]byte("serverid"), 90, 100) expectedPreference := []byte{128} msg := builder.MakeMsgAdvertise([3]byte{'t', 'i', 'd'}, []byte("clientid"), 0x11, @@ -91,8 +89,7 @@ func TestMakeMsgAdvertiseWithHttpClientArch(t *testing.T) { expectedBootFileUrl := []byte("http://bootfileurl") identityAssociation := &IdentityAssociation{IpAddress: expectedIp, InterfaceId: []byte("id-1")} - builder := MakePacketBuilder(expectedServerId, 90, 100, nil, - NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), 1, 100)) + builder := MakePacketBuilder(expectedServerId, 90, 100) msg := builder.MakeMsgAdvertise(transactionId, expectedClientId, 0x10, []*IdentityAssociation{identityAssociation}, expectedBootFileUrl, nil) @@ -116,8 +113,7 @@ func TestMakeNoAddrsAvailable(t *testing.T) { transactionId := [3]byte{'1', '2', '3'} expectedMessage := "Boom!" - builder := MakePacketBuilder(expectedServerId, 90, 100, nil, - NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), 1, 100)) + builder := MakePacketBuilder(expectedServerId, 90, 100) msg := builder.MakeMsgAdvertiseWithNoAddrsAvailable(transactionId, expectedClientId, fmt.Errorf(expectedMessage)) @@ -164,8 +160,7 @@ func TestMakeMsgReply(t *testing.T) { expectedBootFileUrl := []byte("http://bootfileurl") identityAssociation := &IdentityAssociation{IpAddress: expectedIp, InterfaceId: []byte("id-1")} - builder := MakePacketBuilder(expectedServerId, 90, 100, nil, - NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), 1, 100)) + builder := MakePacketBuilder(expectedServerId, 90, 100) msg := builder.MakeMsgReply(transactionId, expectedClientId, 0x11, []*IdentityAssociation{identityAssociation}, make([][]byte, 0), expectedBootFileUrl, nil) @@ -221,8 +216,7 @@ func TestMakeMsgReplyWithHttpClientArch(t *testing.T) { expectedBootFileUrl := []byte("http://bootfileurl") identityAssociation := &IdentityAssociation{IpAddress: expectedIp, InterfaceId: []byte("id-1")} - builder := MakePacketBuilder(expectedServerId, 90, 100, nil, - NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), 1, 100)) + builder := MakePacketBuilder(expectedServerId, 90, 100) msg := builder.MakeMsgReply(transactionId, expectedClientId, 0x10, []*IdentityAssociation{identityAssociation}, make([][]byte, 0), @@ -251,8 +245,7 @@ func TestMakeMsgReplyWithNoAddrsAvailable(t *testing.T) { identityAssociation := &IdentityAssociation{IpAddress: expectedIp, InterfaceId: []byte("id-1")} expectedErrorMessage := "Boom!" - builder := MakePacketBuilder(expectedServerId, 90, 100, nil, - NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), 1, 100)) + builder := MakePacketBuilder(expectedServerId, 90, 100) msg := builder.MakeMsgReply(transactionId, expectedClientId, 0x10, []*IdentityAssociation{identityAssociation}, [][]byte{[]byte("id-2")}, expectedBootFileUrl, @@ -303,8 +296,7 @@ func TestMakeMsgInformationRequestReply(t *testing.T) { transactionId := [3]byte{'1', '2', '3'} expectedBootFileUrl := []byte("http://bootfileurl") - builder := MakePacketBuilder(expectedServerId, 90, 100, nil, - NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), 1, 100)) + builder := MakePacketBuilder(expectedServerId, 90, 100) msg := builder.MakeMsgInformationRequestReply(transactionId, expectedClientId, 0x11, expectedBootFileUrl) @@ -352,8 +344,7 @@ func TestMakeMsgInformationRequestReplyWithHttpClientArch(t *testing.T) { transactionId := [3]byte{'1', '2', '3'} expectedBootFileUrl := []byte("http://bootfileurl") - builder := MakePacketBuilder(expectedServerId, 90, 100, nil, - NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), 1, 100)) + builder := MakePacketBuilder(expectedServerId, 90, 100) msg := builder.MakeMsgInformationRequestReply(transactionId, expectedClientId, 0x10, expectedBootFileUrl) @@ -376,8 +367,7 @@ func TestMakeMsgReleaseReply(t *testing.T) { expectedServerId := []byte("serverid") transactionId := [3]byte{'1', '2', '3'} - builder := MakePacketBuilder(expectedServerId, 90, 100, nil, - NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::1"), 1, 100)) + builder := MakePacketBuilder(expectedServerId, 90, 100) msg := builder.MakeMsgReleaseReply(transactionId, expectedClientId) diff --git a/pixiecore/cli/bootipv6cmd.go b/pixiecore/cli/bootipv6cmd.go index 11a56fe..7af2c14 100644 --- a/pixiecore/cli/bootipv6cmd.go +++ b/pixiecore/cli/bootipv6cmd.go @@ -5,6 +5,7 @@ import ( "fmt" "go.universe.tf/netboot/pixiecorev6" "go.universe.tf/netboot/dhcp6" + "net" ) var bootIPv6Cmd = &cobra.Command{ @@ -51,6 +52,21 @@ var bootIPv6Cmd = &cobra.Command{ } s.BootConfig = dhcp6.MakeStaticBootConfiguration(httpBootUrl, ipxeUrl, preference, cmd.Flags().Changed("preference")) + addressPoolStart, err := cmd.Flags().GetString("address-pool-start") + if err != nil { + fatalf("Error reading flag: %s", err) + } + addressPoolSize, err := cmd.Flags().GetUint64("address-pool-size") + if err != nil { + fatalf("Error reading flag: %s", err) + } + addressPoolValidLifetime, err := cmd.Flags().GetUint32("address-pool-lifetime") + if err != nil { + fatalf("Error reading flag: %s", err) + } + s.AddressPool = dhcp6.NewRandomAddressPool(net.ParseIP(addressPoolStart), addressPoolSize, addressPoolValidLifetime) + s.PacketBuilder = dhcp6.MakePacketBuilder(s.Duid, addressPoolValidLifetime - addressPoolValidLifetime*3/100, addressPoolValidLifetime) + fmt.Println(s.Serve()) }, } @@ -61,6 +77,9 @@ func serverv6ConfigFlags(cmd *cobra.Command) { 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().Uint8("preference", 255, "Set dhcp server preference value") + cmd.Flags().StringP("address-pool-start", "", "2001:db8:f00f:cafe:ffff::100", "Starting ip of the address pool, e.g. 2001:db8:f00f:cafe:ffff::100") + cmd.Flags().Uint64("address-pool-size", 50, "Address pool size") + cmd.Flags().Uint32("address-pool-lifetime", 1850, "Address pool ip valid lifetime in seconds") } func init() { diff --git a/pixiecore/cli/ipv6apicmd.go b/pixiecore/cli/ipv6apicmd.go index 41d7753..c1aaeae 100644 --- a/pixiecore/cli/ipv6apicmd.go +++ b/pixiecore/cli/ipv6apicmd.go @@ -6,6 +6,7 @@ import ( "go.universe.tf/netboot/pixiecorev6" "go.universe.tf/netboot/dhcp6" "time" + "net" ) var ipv6ApiCmd = &cobra.Command{ @@ -40,15 +41,28 @@ var ipv6ApiCmd = &cobra.Command{ if apiUrl == "" { fatalf("Please specify ipxe config file url") } - s.Address = addr 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")) + addressPoolStart, err := cmd.Flags().GetString("address-pool-start") + if err != nil { + fatalf("Error reading flag: %s", err) + } + addressPoolSize, err := cmd.Flags().GetUint64("address-pool-size") + if err != nil { + fatalf("Error reading flag: %s", err) + } + addressPoolValidLifetime, err := cmd.Flags().GetUint32("address-pool-lifetime") + if err != nil { + fatalf("Error reading flag: %s", err) + } + s.AddressPool = dhcp6.NewRandomAddressPool(net.ParseIP(addressPoolStart), addressPoolSize, addressPoolValidLifetime) + s.PacketBuilder = dhcp6.MakePacketBuilder(s.Duid, addressPoolValidLifetime - addressPoolValidLifetime*3/100, addressPoolValidLifetime) + fmt.Println(s.Serve()) }, } @@ -59,6 +73,9 @@ func serverv6ApiConfigFlags(cmd *cobra.Command) { 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().Uint8("preference", 255, "Set dhcp server preference value") + cmd.Flags().StringP("address-pool-start", "", "2001:db8:f00f:cafe:ffff::100", "Starting ip of the address pool, e.g. 2001:db8:f00f:cafe:ffff::100") + cmd.Flags().Uint64("address-pool-size", 50, "Address pool size") + cmd.Flags().Uint32("address-pool-lifetime", 1850, "Address pool ip address valid lifetime in seconds") } func init() { diff --git a/pixiecorev6/dhcpv6.go b/pixiecorev6/dhcpv6.go index fd2e992..5e51e0b 100644 --- a/pixiecorev6/dhcpv6.go +++ b/pixiecorev6/dhcpv6.go @@ -5,7 +5,7 @@ import ( "fmt" ) -func (s *ServerV6) serveDHCP(conn *dhcp6.Conn, packetBuilder *dhcp6.PacketBuilder) error { +func (s *ServerV6) serveDHCP(conn *dhcp6.Conn) error { s.debug("dhcpv6", "Waiting for packets...\n") for { pkt, src, err := conn.RecvDHCP() @@ -19,7 +19,7 @@ func (s *ServerV6) serveDHCP(conn *dhcp6.Conn, packetBuilder *dhcp6.PacketBuilde s.debug("dhcpv6", fmt.Sprintf("Received (%d) packet (%d): %s\n", pkt.Type, pkt.TransactionID, pkt.Options.HumanReadable())) - response, err := packetBuilder.BuildResponse(pkt) + response, err := s.PacketBuilder.BuildResponse(pkt, s.BootConfig, s.AddressPool) if err != nil { s.log("dhcpv6", fmt.Sprintf("Error creating response for transaction: %d: %s", pkt.TransactionID, err)) if response == nil { diff --git a/pixiecorev6/pixicorev6.go b/pixiecorev6/pixicorev6.go index 416b077..1cdd93b 100644 --- a/pixiecorev6/pixicorev6.go +++ b/pixiecorev6/pixicorev6.go @@ -9,10 +9,13 @@ import ( ) type ServerV6 struct { - Address string - Port string - Duid []byte - BootConfig dhcp6.BootConfiguration + Address string + Port string + Duid []byte + + BootConfig dhcp6.BootConfiguration + PacketBuilder *dhcp6.PacketBuilder + AddressPool dhcp6.AddressPool errs chan error @@ -46,10 +49,7 @@ func (s *ServerV6) Serve() error { s.SetDUID(dhcp.SourceHardwareAddress()) - addressPool := dhcp6.NewRandomAddressPool(net.ParseIP("2001:db8:f00f:cafe::10"), 90, 1850) - 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) }() // Wait for either a fatal error, or Shutdown(). err = <-s.errs