go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/natplugin/vppcalls/vpp2106/dump_nat_vppcalls_test.go (about)

     1  //  Copyright (c) 2021 Cisco and/or its affiliates.
     2  //
     3  //  Licensed under the Apache License, Version 2.0 (the "License");
     4  //  you may not use this file except in compliance with the License.
     5  //  You may obtain a copy of the License at:
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  //  Unless required by applicable law or agreed to in writing, software
    10  //  distributed under the License is distributed on an "AS IS" BASIS,
    11  //  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  //  See the License for the specific language governing permissions and
    13  //  limitations under the License.
    14  
    15  package vpp2106_test
    16  
    17  import (
    18  	"net"
    19  	"testing"
    20  
    21  	. "github.com/onsi/gomega"
    22  
    23  	ifs "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces"
    24  	nat "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/nat"
    25  
    26  	"go.ligato.io/cn-infra/v2/idxmap"
    27  	idxmap_mem "go.ligato.io/cn-infra/v2/idxmap/mem"
    28  	"go.ligato.io/cn-infra/v2/logging/logrus"
    29  
    30  	"go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2106/ip_types"
    31  	vpp_nat_ed "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2106/nat44_ed"
    32  	vpp_nat_ei "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2106/nat44_ei"
    33  	"go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2106/nat_types"
    34  	vpp_vpe "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2106/vpe"
    35  	"go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/ifaceidx"
    36  	"go.ligato.io/vpp-agent/v3/plugins/vpp/natplugin/vppcalls"
    37  	"go.ligato.io/vpp-agent/v3/plugins/vpp/natplugin/vppcalls/vpp2106"
    38  	"go.ligato.io/vpp-agent/v3/plugins/vpp/vppmock"
    39  )
    40  
    41  func TestNat44EdGlobalConfigDump(t *testing.T) {
    42  	ctx, natHandler, swIfIndexes, _ := natTestSetup(t)
    43  	defer ctx.TeardownTestCtx()
    44  
    45  	ctx.MockVpp.MockReply(&vpp_nat_ed.Nat44EdPluginEnableDisableReply{})
    46  	err := natHandler.EnableNAT44Plugin(vppcalls.Nat44InitOpts{EndpointDependent: true})
    47  	Expect(err).ShouldNot(HaveOccurred())
    48  
    49  	// forwarding
    50  	ctx.MockVpp.MockReply(&vpp_nat_ed.Nat44ShowRunningConfigReply{
    51  		ForwardingEnabled: true,
    52  	})
    53  
    54  	// virtual reassembly
    55  	/*ctx.MockVpp.MockReply(&vpp_nat_ed.NatGetReassReply{
    56  		// IPv4
    57  		IP4Timeout:  10,
    58  		IP4MaxReass: 5,
    59  		IP4MaxFrag:  7,
    60  		IP4DropFrag: 1,
    61  		// IPv6
    62  		IP6Timeout:  20,
    63  		IP6MaxReass: 8,
    64  		IP6MaxFrag:  13,
    65  		IP6DropFrag: 0,*
    66  	})*/
    67  
    68  	// non-output interfaces
    69  	ctx.MockVpp.MockReply(
    70  		&vpp_nat_ed.Nat44InterfaceDetails{
    71  			SwIfIndex: 1,
    72  		},
    73  		&vpp_nat_ed.Nat44InterfaceDetails{
    74  			SwIfIndex: 2,
    75  			Flags:     nat_types.NAT_IS_INSIDE,
    76  		})
    77  	ctx.MockVpp.MockReply(&vpp_vpe.ControlPingReply{})
    78  
    79  	// output interfaces
    80  	ctx.MockVpp.MockReply(&vpp_nat_ed.Nat44InterfaceOutputFeatureDetails{
    81  		SwIfIndex: 3,
    82  		Flags:     nat_types.NAT_IS_INSIDE,
    83  	})
    84  	ctx.MockVpp.MockReply(&vpp_vpe.ControlPingReply{})
    85  
    86  	// address pool
    87  	ctx.MockVpp.MockReply(
    88  		&vpp_nat_ed.Nat44AddressDetails{
    89  			IPAddress: ipTo4Address("192.168.10.1"),
    90  			Flags:     nat_types.NAT_IS_TWICE_NAT,
    91  			VrfID:     1,
    92  		},
    93  		&vpp_nat_ed.Nat44AddressDetails{
    94  			IPAddress: ipTo4Address("192.168.10.2"),
    95  			VrfID:     2,
    96  		})
    97  	ctx.MockVpp.MockReply(&vpp_vpe.ControlPingReply{})
    98  
    99  	swIfIndexes.Put("if0", &ifaceidx.IfaceMetadata{SwIfIndex: 1})
   100  	swIfIndexes.Put("if1", &ifaceidx.IfaceMetadata{SwIfIndex: 2})
   101  	swIfIndexes.Put("if2", &ifaceidx.IfaceMetadata{SwIfIndex: 3})
   102  
   103  	globalCfg, err := natHandler.Nat44GlobalConfigDump(true)
   104  	Expect(err).To(Succeed())
   105  
   106  	Expect(globalCfg.Forwarding).To(BeTrue())
   107  
   108  	Expect(globalCfg.AddressPool).To(HaveLen(2))
   109  	Expect(globalCfg.AddressPool[0].Address).To(Equal("192.168.10.1"))
   110  	Expect(globalCfg.AddressPool[0].TwiceNat).To(BeTrue())
   111  	Expect(globalCfg.AddressPool[0].VrfId).To(BeEquivalentTo(1))
   112  	Expect(globalCfg.AddressPool[1].Address).To(Equal("192.168.10.2"))
   113  	Expect(globalCfg.AddressPool[1].TwiceNat).To(BeFalse())
   114  	Expect(globalCfg.AddressPool[1].VrfId).To(BeEquivalentTo(2))
   115  
   116  	Expect(globalCfg.NatInterfaces).To(HaveLen(3))
   117  	Expect(globalCfg.NatInterfaces[0].Name).To(Equal("if0"))
   118  	Expect(globalCfg.NatInterfaces[0].IsInside).To(BeFalse())
   119  	Expect(globalCfg.NatInterfaces[0].OutputFeature).To(BeFalse())
   120  	Expect(globalCfg.NatInterfaces[1].Name).To(Equal("if1"))
   121  	Expect(globalCfg.NatInterfaces[1].IsInside).To(BeTrue())
   122  	Expect(globalCfg.NatInterfaces[1].OutputFeature).To(BeFalse())
   123  	Expect(globalCfg.NatInterfaces[2].Name).To(Equal("if2"))
   124  	Expect(globalCfg.NatInterfaces[2].IsInside).To(BeTrue())
   125  	Expect(globalCfg.NatInterfaces[2].OutputFeature).To(BeTrue())
   126  
   127  	/*Expect(globalCfg.VirtualReassembly).ToNot(BeNil())
   128  	Expect(globalCfg.VirtualReassembly.Timeout).To(BeEquivalentTo(10))
   129  	Expect(globalCfg.VirtualReassembly.MaxReassemblies).To(BeEquivalentTo(5))
   130  	Expect(globalCfg.VirtualReassembly.MaxFragments).To(BeEquivalentTo(7))
   131  	Expect(globalCfg.VirtualReassembly.DropFragments).To(BeTrue())*/
   132  }
   133  
   134  func TestNat44EdInterfacesDump(t *testing.T) {
   135  	ctx, natHandler, swIfIndexes, _ := natTestSetup(t)
   136  	defer ctx.TeardownTestCtx()
   137  
   138  	ctx.MockVpp.MockReply(&vpp_nat_ed.Nat44EdPluginEnableDisableReply{})
   139  	err := natHandler.EnableNAT44Plugin(vppcalls.Nat44InitOpts{EndpointDependent: true})
   140  	Expect(err).ShouldNot(HaveOccurred())
   141  
   142  	// non-output interfaces
   143  	ctx.MockVpp.MockReply(
   144  		&vpp_nat_ed.Nat44InterfaceDetails{
   145  			SwIfIndex: 1,
   146  			Flags:     nat_types.NAT_IS_OUTSIDE,
   147  		},
   148  		&vpp_nat_ed.Nat44InterfaceDetails{
   149  			SwIfIndex: 2,
   150  			Flags:     nat_types.NAT_IS_INSIDE,
   151  		})
   152  	ctx.MockVpp.MockReply(&vpp_vpe.ControlPingReply{})
   153  
   154  	// output interfaces
   155  	ctx.MockVpp.MockReply(&vpp_nat_ed.Nat44InterfaceOutputFeatureDetails{
   156  		SwIfIndex: 3,
   157  		Flags:     nat_types.NAT_IS_INSIDE | nat_types.NAT_IS_OUTSIDE,
   158  	})
   159  	ctx.MockVpp.MockReply(&vpp_vpe.ControlPingReply{})
   160  
   161  	swIfIndexes.Put("if0", &ifaceidx.IfaceMetadata{SwIfIndex: 1})
   162  	swIfIndexes.Put("if1", &ifaceidx.IfaceMetadata{SwIfIndex: 2})
   163  	swIfIndexes.Put("if2", &ifaceidx.IfaceMetadata{SwIfIndex: 3})
   164  
   165  	interfaces, err := natHandler.Nat44InterfacesDump()
   166  	Expect(err).To(Succeed())
   167  
   168  	Expect(interfaces).To(HaveLen(3))
   169  
   170  	Expect(interfaces[0].Name).To(Equal("if0"))
   171  	Expect(interfaces[0].NatInside).To(BeFalse())
   172  	Expect(interfaces[0].NatOutside).To(BeTrue())
   173  	Expect(interfaces[0].OutputFeature).To(BeFalse())
   174  
   175  	Expect(interfaces[1].Name).To(Equal("if1"))
   176  	Expect(interfaces[1].NatInside).To(BeTrue())
   177  	Expect(interfaces[1].NatOutside).To(BeFalse())
   178  	Expect(interfaces[1].OutputFeature).To(BeFalse())
   179  
   180  	Expect(interfaces[2].Name).To(Equal("if2"))
   181  	Expect(interfaces[2].NatInside).To(BeTrue())
   182  	Expect(interfaces[2].NatOutside).To(BeTrue())
   183  	Expect(interfaces[2].OutputFeature).To(BeTrue())
   184  }
   185  
   186  func TestNat44EiInterfacesDump(t *testing.T) {
   187  	ctx, natHandler, swIfIndexes, _ := natTestSetup(t)
   188  	defer ctx.TeardownTestCtx()
   189  
   190  	ctx.MockVpp.MockReply(&vpp_nat_ei.Nat44EiPluginEnableDisableReply{})
   191  	err := natHandler.EnableNAT44Plugin(vppcalls.Nat44InitOpts{EndpointDependent: false})
   192  	Expect(err).ShouldNot(HaveOccurred())
   193  
   194  	// non-output interfaces
   195  	ctx.MockVpp.MockReply(
   196  		&vpp_nat_ei.Nat44EiInterfaceDetails{
   197  			SwIfIndex: 1,
   198  			Flags:     vpp_nat_ei.NAT44_EI_IF_OUTSIDE,
   199  		},
   200  		&vpp_nat_ei.Nat44EiInterfaceDetails{
   201  			SwIfIndex: 2,
   202  			Flags:     vpp_nat_ei.NAT44_EI_IF_INSIDE,
   203  		})
   204  	ctx.MockVpp.MockReply(&vpp_vpe.ControlPingReply{})
   205  
   206  	// output interfaces
   207  	ctx.MockVpp.MockReply(&vpp_nat_ei.Nat44EiInterfaceOutputFeatureDetails{
   208  		SwIfIndex: 3,
   209  		Flags:     vpp_nat_ei.NAT44_EI_IF_INSIDE | vpp_nat_ei.NAT44_EI_IF_OUTSIDE,
   210  	})
   211  	ctx.MockVpp.MockReply(&vpp_vpe.ControlPingReply{})
   212  
   213  	swIfIndexes.Put("if0", &ifaceidx.IfaceMetadata{SwIfIndex: 1})
   214  	swIfIndexes.Put("if1", &ifaceidx.IfaceMetadata{SwIfIndex: 2})
   215  	swIfIndexes.Put("if2", &ifaceidx.IfaceMetadata{SwIfIndex: 3})
   216  
   217  	interfaces, err := natHandler.Nat44InterfacesDump()
   218  	Expect(err).To(Succeed())
   219  
   220  	Expect(interfaces).To(HaveLen(3))
   221  
   222  	Expect(interfaces[0].Name).To(Equal("if0"))
   223  	Expect(interfaces[0].NatInside).To(BeFalse())
   224  	Expect(interfaces[0].NatOutside).To(BeTrue())
   225  	Expect(interfaces[0].OutputFeature).To(BeFalse())
   226  
   227  	Expect(interfaces[1].Name).To(Equal("if1"))
   228  	Expect(interfaces[1].NatInside).To(BeTrue())
   229  	Expect(interfaces[1].NatOutside).To(BeFalse())
   230  	Expect(interfaces[1].OutputFeature).To(BeFalse())
   231  
   232  	Expect(interfaces[2].Name).To(Equal("if2"))
   233  	Expect(interfaces[2].NatInside).To(BeTrue())
   234  	Expect(interfaces[2].NatOutside).To(BeTrue())
   235  	Expect(interfaces[2].OutputFeature).To(BeTrue())
   236  }
   237  
   238  func TestNat44EdAddressPoolsDump(t *testing.T) {
   239  	ctx, natHandler, _, _ := natTestSetup(t)
   240  	defer ctx.TeardownTestCtx()
   241  
   242  	ctx.MockVpp.MockReply(&vpp_nat_ed.Nat44EdPluginEnableDisableReply{})
   243  	err := natHandler.EnableNAT44Plugin(vppcalls.Nat44InitOpts{EndpointDependent: true})
   244  	Expect(err).ShouldNot(HaveOccurred())
   245  
   246  	// address pool
   247  	ctx.MockVpp.MockReply(
   248  		&vpp_nat_ed.Nat44AddressDetails{
   249  			IPAddress: ipTo4Address("192.168.10.1"),
   250  			Flags:     nat_types.NAT_IS_TWICE_NAT,
   251  			VrfID:     1,
   252  		},
   253  		&vpp_nat_ed.Nat44AddressDetails{
   254  			IPAddress: ipTo4Address("192.168.10.2"),
   255  			VrfID:     2,
   256  		},
   257  		&vpp_nat_ed.Nat44AddressDetails{
   258  			IPAddress: ipTo4Address("192.168.10.3"),
   259  			VrfID:     2,
   260  		},
   261  		&vpp_nat_ed.Nat44AddressDetails{
   262  			IPAddress: ipTo4Address("192.168.10.4"),
   263  			VrfID:     2,
   264  		})
   265  	ctx.MockVpp.MockReply(&vpp_vpe.ControlPingReply{})
   266  
   267  	pools, err := natHandler.Nat44AddressPoolsDump()
   268  	Expect(err).To(Succeed())
   269  
   270  	Expect(pools).To(HaveLen(2))
   271  
   272  	Expect(pools[0].FirstIp).To(Equal("192.168.10.1"))
   273  	Expect(pools[0].LastIp).To(Equal(""))
   274  	Expect(pools[0].TwiceNat).To(BeTrue())
   275  	Expect(pools[0].VrfId).To(BeEquivalentTo(1))
   276  
   277  	Expect(pools[1].FirstIp).To(Equal("192.168.10.2"))
   278  	Expect(pools[1].LastIp).To(Equal("192.168.10.4"))
   279  	Expect(pools[1].TwiceNat).To(BeFalse())
   280  	Expect(pools[1].VrfId).To(BeEquivalentTo(2))
   281  }
   282  
   283  func TestNat44EiAddressPoolsDump(t *testing.T) {
   284  	ctx, natHandler, _, _ := natTestSetup(t)
   285  	defer ctx.TeardownTestCtx()
   286  
   287  	ctx.MockVpp.MockReply(&vpp_nat_ei.Nat44EiPluginEnableDisableReply{})
   288  	err := natHandler.EnableNAT44Plugin(vppcalls.Nat44InitOpts{EndpointDependent: false})
   289  	Expect(err).ShouldNot(HaveOccurred())
   290  
   291  	// address pool
   292  	ctx.MockVpp.MockReply(
   293  		&vpp_nat_ei.Nat44EiAddressDetails{
   294  			IPAddress: ipTo4Address("192.168.10.1"),
   295  			VrfID:     1,
   296  		},
   297  		&vpp_nat_ei.Nat44EiAddressDetails{
   298  			IPAddress: ipTo4Address("192.168.10.2"),
   299  			VrfID:     2,
   300  		},
   301  		&vpp_nat_ei.Nat44EiAddressDetails{
   302  			IPAddress: ipTo4Address("192.168.10.3"),
   303  			VrfID:     2,
   304  		},
   305  		&vpp_nat_ei.Nat44EiAddressDetails{
   306  			IPAddress: ipTo4Address("192.168.10.4"),
   307  			VrfID:     2,
   308  		})
   309  	ctx.MockVpp.MockReply(&vpp_vpe.ControlPingReply{})
   310  
   311  	pools, err := natHandler.Nat44AddressPoolsDump()
   312  	Expect(err).To(Succeed())
   313  
   314  	Expect(pools).To(HaveLen(2))
   315  
   316  	Expect(pools[0].FirstIp).To(Equal("192.168.10.1"))
   317  	Expect(pools[0].LastIp).To(Equal(""))
   318  	Expect(pools[0].VrfId).To(BeEquivalentTo(1))
   319  
   320  	Expect(pools[1].FirstIp).To(Equal("192.168.10.2"))
   321  	Expect(pools[1].LastIp).To(Equal("192.168.10.4"))
   322  	Expect(pools[1].TwiceNat).To(BeFalse())
   323  	Expect(pools[1].VrfId).To(BeEquivalentTo(2))
   324  }
   325  
   326  func TestDNATDump(t *testing.T) {
   327  	ctx, natHandler, swIfIndexes, dhcpIndexes := natTestSetup(t)
   328  	defer ctx.TeardownTestCtx()
   329  
   330  	ctx.MockVpp.MockReply(&vpp_nat_ed.Nat44EdPluginEnableDisableReply{})
   331  	err := natHandler.EnableNAT44Plugin(vppcalls.Nat44InitOpts{EndpointDependent: true})
   332  	Expect(err).ShouldNot(HaveOccurred())
   333  
   334  	// non-LB static mappings
   335  	ctx.MockVpp.MockReply(
   336  		&vpp_nat_ed.Nat44StaticMappingDetails{
   337  			LocalIPAddress:    ipTo4Address("10.10.11.120"),
   338  			ExternalIPAddress: ipTo4Address("10.36.20.20"),
   339  			Protocol:          6,
   340  			LocalPort:         8080,
   341  			ExternalPort:      80,
   342  			ExternalSwIfIndex: vpp2106.NoInterface,
   343  			VrfID:             1,
   344  			Tag:               "DNAT 1",
   345  			Flags:             nat_types.NAT_IS_TWICE_NAT,
   346  		},
   347  		&vpp_nat_ed.Nat44StaticMappingDetails{
   348  			LocalIPAddress:    ipTo4Address("10.10.11.120"),
   349  			Protocol:          6,
   350  			LocalPort:         8080,
   351  			ExternalPort:      80,
   352  			ExternalSwIfIndex: 1,
   353  			VrfID:             1,
   354  			Tag:               "DNAT 1",
   355  			Flags:             nat_types.NAT_IS_TWICE_NAT,
   356  		},
   357  		&vpp_nat_ed.Nat44StaticMappingDetails{
   358  			LocalIPAddress:    ipTo4Address("10.10.11.140"),
   359  			Protocol:          6,
   360  			LocalPort:         8081,
   361  			ExternalPort:      80,
   362  			ExternalSwIfIndex: 2,
   363  			VrfID:             1,
   364  			Tag:               "DNAT 2",
   365  			Flags:             nat_types.NAT_IS_SELF_TWICE_NAT,
   366  		},
   367  		// auto-generated mappings with interface replaced by all assigned IP addresses
   368  		&vpp_nat_ed.Nat44StaticMappingDetails{
   369  			LocalIPAddress:    ipTo4Address("10.10.11.120"),
   370  			ExternalIPAddress: ipTo4Address("10.36.20.30"),
   371  			Protocol:          6,
   372  			LocalPort:         8080,
   373  			ExternalPort:      80,
   374  			ExternalSwIfIndex: vpp2106.NoInterface,
   375  			VrfID:             1,
   376  			Tag:               "DNAT 1",
   377  			Flags:             nat_types.NAT_IS_TWICE_NAT,
   378  		},
   379  		&vpp_nat_ed.Nat44StaticMappingDetails{
   380  			LocalIPAddress:    ipTo4Address("10.10.11.120"),
   381  			ExternalIPAddress: ipTo4Address("10.36.20.31"),
   382  			Protocol:          6,
   383  			LocalPort:         8080,
   384  			ExternalPort:      80,
   385  			ExternalSwIfIndex: vpp2106.NoInterface,
   386  			VrfID:             1,
   387  			Tag:               "DNAT 1",
   388  			Flags:             nat_types.NAT_IS_TWICE_NAT,
   389  		},
   390  		&vpp_nat_ed.Nat44StaticMappingDetails{
   391  			LocalIPAddress:    ipTo4Address("10.10.11.140"),
   392  			ExternalIPAddress: ipTo4Address("10.36.40.10"),
   393  			Protocol:          6,
   394  			LocalPort:         8081,
   395  			ExternalPort:      80,
   396  			ExternalSwIfIndex: vpp2106.NoInterface,
   397  			VrfID:             1,
   398  			Tag:               "DNAT 2",
   399  			Flags:             nat_types.NAT_IS_SELF_TWICE_NAT,
   400  		},
   401  		&vpp_nat_ed.Nat44StaticMappingDetails{
   402  			LocalIPAddress:    ipTo4Address("10.10.11.140"),
   403  			ExternalIPAddress: ipTo4Address("10.36.40.20"),
   404  			Protocol:          6,
   405  			LocalPort:         8081,
   406  			ExternalPort:      80,
   407  			ExternalSwIfIndex: vpp2106.NoInterface,
   408  			VrfID:             1,
   409  			Tag:               "DNAT 2",
   410  			Flags:             nat_types.NAT_IS_SELF_TWICE_NAT,
   411  		},
   412  	)
   413  
   414  	ctx.MockVpp.MockReply(&vpp_vpe.ControlPingReply{})
   415  
   416  	// LB static mappings
   417  	ctx.MockVpp.MockReply(&vpp_nat_ed.Nat44LbStaticMappingDetails{
   418  		ExternalAddr: ipTo4Address("10.36.20.60"),
   419  		ExternalPort: 53,
   420  		Protocol:     17,
   421  		Flags:        nat_types.NAT_IS_OUT2IN_ONLY,
   422  		Tag:          "DNAT 2",
   423  		LocalNum:     2,
   424  		Locals: []vpp_nat_ed.Nat44LbAddrPort{
   425  			{
   426  				Addr:        ipTo4Address("10.10.11.161"),
   427  				Port:        53,
   428  				Probability: 1,
   429  				VrfID:       0,
   430  			},
   431  			{
   432  				Addr:        ipTo4Address("10.10.11.162"),
   433  				Port:        153,
   434  				Probability: 2,
   435  				VrfID:       0,
   436  			},
   437  		},
   438  	})
   439  
   440  	ctx.MockVpp.MockReply(&vpp_vpe.ControlPingReply{})
   441  
   442  	// identity mappings
   443  	ctx.MockVpp.MockReply(
   444  		&vpp_nat_ed.Nat44IdentityMappingDetails{
   445  			Flags:     nat_types.NAT_IS_ADDR_ONLY,
   446  			Protocol:  17,
   447  			IPAddress: ipTo4Address("10.10.11.200"),
   448  			SwIfIndex: vpp2106.NoInterface,
   449  			VrfID:     1,
   450  			Tag:       "DNAT 3",
   451  		},
   452  		&vpp_nat_ed.Nat44IdentityMappingDetails{
   453  			Flags:     nat_types.NAT_IS_ADDR_ONLY,
   454  			Protocol:  17,
   455  			SwIfIndex: 2,
   456  			VrfID:     1,
   457  			Tag:       "DNAT 3",
   458  		},
   459  		// auto-generated mappings with interface replaced by all assigned IP addresses
   460  		&vpp_nat_ed.Nat44IdentityMappingDetails{
   461  			Flags:     nat_types.NAT_IS_ADDR_ONLY,
   462  			Protocol:  17,
   463  			IPAddress: ipTo4Address("10.36.40.10"),
   464  			SwIfIndex: vpp2106.NoInterface,
   465  			VrfID:     1,
   466  			Tag:       "DNAT 3",
   467  		},
   468  		&vpp_nat_ed.Nat44IdentityMappingDetails{
   469  			Flags:     nat_types.NAT_IS_ADDR_ONLY,
   470  			Protocol:  17,
   471  			IPAddress: ipTo4Address("10.36.40.20"),
   472  			SwIfIndex: vpp2106.NoInterface,
   473  			VrfID:     1,
   474  			Tag:       "DNAT 3",
   475  		},
   476  	)
   477  
   478  	ctx.MockVpp.MockReply(&vpp_vpe.ControlPingReply{})
   479  
   480  	// interfaces and their IP addresses
   481  	swIfIndexes.Put("if0", &ifaceidx.IfaceMetadata{SwIfIndex: 1, IPAddresses: []string{"10.36.20.30", "10.36.20.31"}})
   482  	swIfIndexes.Put("if1", &ifaceidx.IfaceMetadata{SwIfIndex: 2, IPAddresses: []string{"10.36.40.10"}})
   483  	dhcpIndexes.Put("if1", &ifs.DHCPLease{InterfaceName: "if0", HostIpAddress: "10.36.40.20"})
   484  
   485  	dnats, err := natHandler.DNat44Dump()
   486  	Expect(err).To(Succeed())
   487  
   488  	Expect(dnats).To(HaveLen(3))
   489  
   490  	dnat := dnats[0]
   491  	Expect(dnat.Label).To(Equal("DNAT 1"))
   492  	Expect(dnat.IdMappings).To(HaveLen(0))
   493  	Expect(dnat.StMappings).To(HaveLen(2))
   494  	// 1st mapping
   495  	Expect(dnat.StMappings[0].TwiceNat).To(Equal(nat.DNat44_StaticMapping_ENABLED))
   496  	Expect(dnat.StMappings[0].Protocol).To(Equal(nat.DNat44_TCP))
   497  	Expect(dnat.StMappings[0].ExternalInterface).To(BeEmpty())
   498  	Expect(dnat.StMappings[0].ExternalIp).To(Equal("10.36.20.20"))
   499  	Expect(dnat.StMappings[0].ExternalPort).To(BeEquivalentTo(80))
   500  	Expect(dnat.StMappings[0].LocalIps).To(HaveLen(1))
   501  	Expect(dnat.StMappings[0].LocalIps[0].VrfId).To(BeEquivalentTo(1))
   502  	Expect(dnat.StMappings[0].LocalIps[0].LocalIp).To(Equal("10.10.11.120"))
   503  	Expect(dnat.StMappings[0].LocalIps[0].LocalPort).To(BeEquivalentTo(8080))
   504  	Expect(dnat.StMappings[0].LocalIps[0].Probability).To(BeEquivalentTo(0))
   505  	// 2nd mapping
   506  	Expect(dnat.StMappings[1].TwiceNat).To(Equal(nat.DNat44_StaticMapping_ENABLED))
   507  	Expect(dnat.StMappings[1].Protocol).To(Equal(nat.DNat44_TCP))
   508  	Expect(dnat.StMappings[1].ExternalInterface).To(BeEquivalentTo("if0"))
   509  	Expect(dnat.StMappings[1].ExternalIp).To(BeEquivalentTo("0.0.0.0"))
   510  	Expect(dnat.StMappings[1].ExternalPort).To(BeEquivalentTo(80))
   511  	Expect(dnat.StMappings[1].LocalIps).To(HaveLen(1))
   512  	Expect(dnat.StMappings[1].LocalIps[0].VrfId).To(BeEquivalentTo(1))
   513  	Expect(dnat.StMappings[1].LocalIps[0].LocalIp).To(Equal("10.10.11.120"))
   514  	Expect(dnat.StMappings[1].LocalIps[0].LocalPort).To(BeEquivalentTo(8080))
   515  	Expect(dnat.StMappings[1].LocalIps[0].Probability).To(BeEquivalentTo(0))
   516  
   517  	dnat = dnats[1]
   518  	// -> non-LB mapping
   519  	Expect(dnat.Label).To(Equal("DNAT 2"))
   520  	Expect(dnat.IdMappings).To(HaveLen(0))
   521  	Expect(dnat.StMappings).To(HaveLen(2))
   522  	Expect(dnat.StMappings[0].TwiceNat).To(Equal(nat.DNat44_StaticMapping_SELF))
   523  	Expect(dnat.StMappings[0].Protocol).To(Equal(nat.DNat44_TCP))
   524  	Expect(dnat.StMappings[0].ExternalInterface).To(Equal("if1"))
   525  	Expect(dnat.StMappings[0].ExternalIp).To(BeEquivalentTo("0.0.0.0"))
   526  	Expect(dnat.StMappings[0].ExternalPort).To(BeEquivalentTo(80))
   527  	Expect(dnat.StMappings[0].LocalIps).To(HaveLen(1))
   528  	Expect(dnat.StMappings[0].LocalIps[0].VrfId).To(BeEquivalentTo(1))
   529  	Expect(dnat.StMappings[0].LocalIps[0].LocalIp).To(Equal("10.10.11.140"))
   530  	Expect(dnat.StMappings[0].LocalIps[0].LocalPort).To(BeEquivalentTo(8081))
   531  	Expect(dnat.StMappings[0].LocalIps[0].Probability).To(BeEquivalentTo(0))
   532  	// -> LB mapping
   533  	Expect(dnat.StMappings[1].TwiceNat).To(Equal(nat.DNat44_StaticMapping_DISABLED))
   534  	Expect(dnat.StMappings[1].Protocol).To(Equal(nat.DNat44_UDP))
   535  	Expect(dnat.StMappings[1].ExternalInterface).To(BeEmpty())
   536  	Expect(dnat.StMappings[1].ExternalIp).To(Equal("10.36.20.60"))
   537  	Expect(dnat.StMappings[1].ExternalPort).To(BeEquivalentTo(53))
   538  	Expect(dnat.StMappings[1].LocalIps).To(HaveLen(2))
   539  	Expect(dnat.StMappings[1].LocalIps[0].VrfId).To(BeEquivalentTo(0))
   540  	Expect(dnat.StMappings[1].LocalIps[0].LocalIp).To(Equal("10.10.11.161"))
   541  	Expect(dnat.StMappings[1].LocalIps[0].LocalPort).To(BeEquivalentTo(53))
   542  	Expect(dnat.StMappings[1].LocalIps[0].Probability).To(BeEquivalentTo(1))
   543  	Expect(dnat.StMappings[1].LocalIps[1].VrfId).To(BeEquivalentTo(0))
   544  	Expect(dnat.StMappings[1].LocalIps[1].LocalIp).To(Equal("10.10.11.162"))
   545  	Expect(dnat.StMappings[1].LocalIps[1].LocalPort).To(BeEquivalentTo(153))
   546  	Expect(dnat.StMappings[1].LocalIps[1].Probability).To(BeEquivalentTo(2))
   547  
   548  	dnat = dnats[2]
   549  	Expect(dnat.Label).To(Equal("DNAT 3"))
   550  	Expect(dnat.StMappings).To(HaveLen(0))
   551  	Expect(dnat.IdMappings).To(HaveLen(2))
   552  	// 1st mapping
   553  	Expect(dnat.IdMappings[0].VrfId).To(BeEquivalentTo(1))
   554  	Expect(dnat.IdMappings[0].Protocol).To(Equal(nat.DNat44_UDP))
   555  	Expect(dnat.IdMappings[0].Port).To(BeEquivalentTo(0))
   556  	Expect(dnat.IdMappings[0].IpAddress).To(Equal("10.10.11.200"))
   557  	Expect(dnat.IdMappings[0].Interface).To(BeEmpty())
   558  	// 2nd mapping
   559  	Expect(dnat.IdMappings[1].VrfId).To(BeEquivalentTo(1))
   560  	Expect(dnat.IdMappings[1].Protocol).To(Equal(nat.DNat44_UDP))
   561  	Expect(dnat.IdMappings[1].Port).To(BeEquivalentTo(0))
   562  	Expect(dnat.IdMappings[1].IpAddress).To(BeEquivalentTo("0.0.0.0"))
   563  	Expect(dnat.IdMappings[1].Interface).To(BeEquivalentTo("if1"))
   564  }
   565  
   566  func natTestSetup(t *testing.T) (*vppmock.TestCtx, vppcalls.NatVppAPI, ifaceidx.IfaceMetadataIndexRW, idxmap.NamedMappingRW) {
   567  	ctx := vppmock.SetupTestCtx(t)
   568  	log := logrus.NewLogger("test-log")
   569  	swIfIndexes := ifaceidx.NewIfaceIndex(logrus.DefaultLogger(), "test-sw_if_indexes")
   570  	dhcpIndexes := idxmap_mem.NewNamedMapping(logrus.DefaultLogger(), "test-dhcp_indexes", nil)
   571  	natHandler := vpp2106.NewNatVppHandler(ctx.MockVPPClient, swIfIndexes, dhcpIndexes, log)
   572  	return ctx, natHandler, swIfIndexes, dhcpIndexes
   573  }
   574  
   575  func ipTo4Address(ipStr string) (addr ip_types.IP4Address) {
   576  	netIP := net.ParseIP(ipStr)
   577  	if ip4 := netIP.To4(); ip4 != nil {
   578  		copy(addr[:], ip4)
   579  	}
   580  	return
   581  }