@@ -91,7 +91,7 @@ func TestDHCPServer_ServeEther6_solicit(t *testing.T) {
9191 t .Run (tc .name , func (t * testing.T ) {
9292 t .Parallel ()
9393
94- db := newTestDatabase (t , testLeases )
94+ db := newTestDatabase (t )
9595
9696 ndMgr , inCh , outCh := newTestNetworkDeviceManager (t , testIfaceAddrV6 )
9797 startTestDHCPServer (t , & dhcpsvc.Config {
@@ -185,7 +185,7 @@ func TestDHCPServer_ServeEther6_solicitRapidCommit(t *testing.T) {
185185 t .Run (tc .name , func (t * testing.T ) {
186186 t .Parallel ()
187187
188- db := newTestDatabase (t , testLeases )
188+ db := newTestDatabase (t )
189189
190190 onStore := func (ctx context.Context , leases []* dhcpsvc.Lease ) (err error ) {
191191 assert .Contains (t , leases , tc .want )
@@ -280,7 +280,7 @@ func TestDHCPServer_ServeEther6_request(t *testing.T) {
280280 t .Run (tc .name , func (t * testing.T ) {
281281 t .Parallel ()
282282
283- db := newTestDatabase (t , testLeases )
283+ db := newTestDatabase (t )
284284
285285 onStore := func (ctx context.Context , leases []* dhcpsvc.Lease ) (err error ) {
286286 assert .Contains (t , leases , tc .want )
@@ -361,7 +361,7 @@ func TestDHCPServer_ServeEther6_requestWithSolicit(t *testing.T) {
361361 t .Run (tc .name , func (t * testing.T ) {
362362 t .Parallel ()
363363
364- db := newTestDatabase (t , testLeases )
364+ db := newTestDatabase (t )
365365
366366 onStore := func (ctx context.Context , leases []* dhcpsvc.Lease ) (err error ) {
367367 assert .Contains (t , leases , tc .want )
@@ -469,7 +469,7 @@ func TestDHCPServer_ServeEther6_confirm(t *testing.T) {
469469 t .Run (tc .name , func (t * testing.T ) {
470470 t .Parallel ()
471471
472- db := newTestDatabase (t , testLeases )
472+ db := newTestDatabase (t )
473473
474474 ndMgr , inCh , outCh := newTestNetworkDeviceManager (t , testIfaceAddrV6 )
475475 startTestDHCPServer (t , & dhcpsvc.Config {
@@ -543,7 +543,7 @@ func TestDHCPServer_ServeEther6_renew(t *testing.T) {
543543 for _ , tc := range testCases {
544544 req := testutil .RequireTypeAssert [* layers.DHCPv6 ](t , tc .in .Layer (layers .LayerTypeDHCPv6 ))
545545
546- db := newTestDatabase (t , testLeases )
546+ db := newTestDatabase (t )
547547
548548 onStore := func (ctx context.Context , leases []* dhcpsvc.Lease ) (err error ) {
549549 assert .Contains (t , leases , tc .want )
@@ -630,7 +630,7 @@ func TestDHCPServer_ServeEther6_rebind(t *testing.T) {
630630 for _ , tc := range testCases {
631631 req := testutil .RequireTypeAssert [* layers.DHCPv6 ](t , tc .in .Layer (layers .LayerTypeDHCPv6 ))
632632
633- db := newTestDatabase (t , testLeases )
633+ db := newTestDatabase (t )
634634
635635 onStore := func (ctx context.Context , leases []* dhcpsvc.Lease ) (err error ) {
636636 assert .Contains (t , leases , tc .want )
@@ -699,10 +699,108 @@ func TestDHCPServer_ServeEther6_info(t *testing.T) {
699699 for _ , tc := range testCases {
700700 req := testutil .RequireTypeAssert [* layers.DHCPv6 ](t , tc .in .Layer (layers .LayerTypeDHCPv6 ))
701701
702+ db := newTestDatabase (t )
703+
702704 t .Run (tc .name , func (t * testing.T ) {
703705 t .Parallel ()
704706
705- db := newTestDatabase (t , testLeases )
707+ ndMgr , inCh , outCh := newTestNetworkDeviceManager (t , testIfaceAddrV6 )
708+ startTestDHCPServer (t , & dhcpsvc.Config {
709+ Database : db ,
710+ Interfaces : testIPv6InterfacesConf ,
711+ Logger : testLogger ,
712+ NetworkDeviceManager : ndMgr ,
713+ Enabled : true ,
714+ })
715+
716+ testutil .RequireSend (t , inCh , tc .in , testTimeout )
717+
718+ assertValidResponse6 (t , req , outCh , tc .wantOpts )
719+ })
720+ }
721+ }
722+
723+ func TestDHCPServer_ServeEther6_release (t * testing.T ) {
724+ t .Parallel ()
725+
726+ testCases := []struct {
727+ in gopacket.Packet
728+ want * dhcpsvc.Lease
729+ name string
730+ wantOpts layers.DHCPv6Options
731+ }{{
732+ in : newDHCPv6Release (t , testHWDynamic , testIPv6Dynamic ),
733+ want : testLease6Dynamic ,
734+ name : "success" ,
735+ wantOpts : layers.DHCPv6Options {
736+ newOptServerDUID (t , testIfaceHWAddr ),
737+ newOptClientDUID (t , testHWDynamic ),
738+ newOptIANAStatus (t , testIAID , layers .DHCPv6StatusCodeSuccess ),
739+ newOptPreference (t , 0 ),
740+ newOptSolMaxRT (t , dhcpsvc .DefaultSolMaxRT ),
741+ },
742+ }, {
743+ in : newDHCPv6Release (t , testHWStatic , testIPv6Static ),
744+ want : testLease6Static ,
745+ name : "success_static" ,
746+ wantOpts : layers.DHCPv6Options {
747+ newOptServerDUID (t , testIfaceHWAddr ),
748+ newOptClientDUID (t , testHWStatic ),
749+ newOptIANAStatus (t , testIAID , layers .DHCPv6StatusCodeSuccess ),
750+ newOptPreference (t , 0 ),
751+ newOptSolMaxRT (t , dhcpsvc .DefaultSolMaxRT ),
752+ },
753+ }, {
754+ in : newDHCPv6Release (t , testHWUnknown , testIPv6Unknown ),
755+ want : nil ,
756+ name : "no_binding" ,
757+ wantOpts : layers.DHCPv6Options {
758+ newOptServerDUID (t , testIfaceHWAddr ),
759+ newOptClientDUID (t , testHWUnknown ),
760+ newOptIANAStatus (t , testIAID , layers .DHCPv6StatusCodeNoBinding ),
761+ newOptPreference (t , 0 ),
762+ newOptSolMaxRT (t , dhcpsvc .DefaultSolMaxRT ),
763+ },
764+ }, {
765+ in : newDHCPv6Release (t , testHWDynamic , netip.Addr {}),
766+ want : nil ,
767+ name : "no_iana" ,
768+ wantOpts : layers.DHCPv6Options {
769+ newOptServerDUID (t , testIfaceHWAddr ),
770+ newOptClientDUID (t , testHWDynamic ),
771+ newOptPreference (t , 0 ),
772+ newOptSolMaxRT (t , dhcpsvc .DefaultSolMaxRT ),
773+ },
774+ }, {
775+ in : newDHCPv6Release (t , testHWDynamic , testIPv6Unknown ),
776+ want : nil ,
777+ name : "ip_mismatch" ,
778+ wantOpts : layers.DHCPv6Options {
779+ newOptServerDUID (t , testIfaceHWAddr ),
780+ newOptClientDUID (t , testHWDynamic ),
781+ newOptIANAStatus (t , testIAID , layers .DHCPv6StatusCodeNoBinding ),
782+ newOptPreference (t , 0 ),
783+ newOptSolMaxRT (t , dhcpsvc .DefaultSolMaxRT ),
784+ },
785+ }}
786+
787+ for _ , tc := range testCases {
788+ req := testutil .RequireTypeAssert [* layers.DHCPv6 ](t , tc .in .Layer (layers .LayerTypeDHCPv6 ))
789+
790+ db := newTestDatabase (t )
791+
792+ onStore := func (ctx context.Context , leases []* dhcpsvc.Lease ) (err error ) {
793+ assert .NotContains (t , leases , tc .want )
794+
795+ return nil
796+ }
797+
798+ if tc .want != nil {
799+ db .onStore = onStore
800+ }
801+
802+ t .Run (tc .name , func (t * testing.T ) {
803+ t .Parallel ()
706804
707805 ndMgr , inCh , outCh := newTestNetworkDeviceManager (t , testIfaceAddrV6 )
708806 startTestDHCPServer (t , & dhcpsvc.Config {
@@ -1036,3 +1134,31 @@ func newDHCPv6Renew(tb testing.TB, mac net.HardwareAddr, reqIP netip.Addr) (pkt
10361134
10371135 return newTestPacket (tb , layers .LinkTypeEthernet , eth , ip , udp , dhcp )
10381136}
1137+
1138+ // newDHCPv6Release creates a new DHCPv6 RELEASE packet for testing.
1139+ func newDHCPv6Release (tb testing.TB , mac net.HardwareAddr , reqIP netip.Addr ) (pkt gopacket.Packet ) {
1140+ tb .Helper ()
1141+
1142+ eth := newEthernetLayer (tb , mac , testIfaceHWAddr , layers .EthernetTypeIPv6 )
1143+ ip , udp := newIPv6UDPLayer (tb , netip.AddrPort {}, netip.AddrPort {})
1144+
1145+ dhcp := & layers.DHCPv6 {
1146+ MsgType : layers .DHCPv6MsgTypeRelease ,
1147+ HopCount : 0 ,
1148+ // Don't specify link and peer addresses, as they are intended for relay
1149+ // messages.
1150+ LinkAddr : nil ,
1151+ PeerAddr : nil ,
1152+ TransactionID : testTransactionID ,
1153+ Options : layers.DHCPv6Options {
1154+ newOptClientDUID (tb , mac ),
1155+ newOptServerDUID (tb , testIfaceHWAddr ),
1156+ },
1157+ }
1158+
1159+ if reqIP .IsValid () && reqIP .Is6 () {
1160+ dhcp .Options = append (dhcp .Options , newOptIANA (tb , testIAID , reqIP , testLeaseTTL ))
1161+ }
1162+
1163+ return newTestPacket (tb , layers .LinkTypeEthernet , eth , ip , udp , dhcp )
1164+ }
0 commit comments