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

     1  //  Copyright (c) 2022 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 vpp2210_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/vpp2210/ip_types"
    31  	"go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2210/memclnt"
    32  	vpp_nat_ed "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2210/nat44_ed"
    33  	vpp_nat_ei "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2210/nat44_ei"
    34  	"go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2210/nat_types"
    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/vpp2210"
    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(&memclnt.ControlPingReply{})
    78  
    79  	// output interfaces
    80  	ctx.MockVpp.MockReply(
    81  		&vpp_nat_ed.Nat44EdOutputInterfaceDetails{
    82  			SwIfIndex: 3,
    83  		},
    84  		&vpp_nat_ed.Nat44EdOutputInterfaceGetReply{
    85  			Retval: 0,
    86  			Cursor: ^uint32(0),
    87  		})
    88  
    89  	// address pool
    90  	ctx.MockVpp.MockReply(
    91  		&vpp_nat_ed.Nat44AddressDetails{
    92  			IPAddress: ipTo4Address("192.168.10.1"),
    93  			Flags:     nat_types.NAT_IS_TWICE_NAT,
    94  			VrfID:     1,
    95  		},
    96  		&vpp_nat_ed.Nat44AddressDetails{
    97  			IPAddress: ipTo4Address("192.168.10.2"),
    98  			VrfID:     2,
    99  		})
   100  	ctx.MockVpp.MockReply(&memclnt.ControlPingReply{})
   101  
   102  	swIfIndexes.Put("if0", &ifaceidx.IfaceMetadata{SwIfIndex: 1})
   103  	swIfIndexes.Put("if1", &ifaceidx.IfaceMetadata{SwIfIndex: 2})
   104  	swIfIndexes.Put("if2", &ifaceidx.IfaceMetadata{SwIfIndex: 3})
   105  
   106  	globalCfg, err := natHandler.Nat44GlobalConfigDump(true)
   107  	Expect(err).To(Succeed())
   108  
   109  	Expect(globalCfg.Forwarding).To(BeTrue())
   110  
   111  	Expect(globalCfg.AddressPool).To(HaveLen(2))
   112  	Expect(globalCfg.AddressPool[0].Address).To(Equal("192.168.10.1"))
   113  	Expect(globalCfg.AddressPool[0].TwiceNat).To(BeTrue())
   114  	Expect(globalCfg.AddressPool[0].VrfId).To(BeEquivalentTo(1))
   115  	Expect(globalCfg.AddressPool[1].Address).To(Equal("192.168.10.2"))
   116  	Expect(globalCfg.AddressPool[1].TwiceNat).To(BeFalse())
   117  	Expect(globalCfg.AddressPool[1].VrfId).To(BeEquivalentTo(2))
   118  
   119  	Expect(globalCfg.NatInterfaces).To(HaveLen(3))
   120  	Expect(globalCfg.NatInterfaces[0].Name).To(Equal("if0"))
   121  	Expect(globalCfg.NatInterfaces[0].IsInside).To(BeFalse())
   122  	Expect(globalCfg.NatInterfaces[0].OutputFeature).To(BeFalse())
   123  	Expect(globalCfg.NatInterfaces[1].Name).To(Equal("if1"))
   124  	Expect(globalCfg.NatInterfaces[1].IsInside).To(BeTrue())
   125  	Expect(globalCfg.NatInterfaces[1].OutputFeature).To(BeFalse())
   126  	Expect(globalCfg.NatInterfaces[2].Name).To(Equal("if2"))
   127  	Expect(globalCfg.NatInterfaces[2].IsInside).To(BeFalse())
   128  	Expect(globalCfg.NatInterfaces[2].OutputFeature).To(BeTrue())
   129  
   130  	/*Expect(globalCfg.VirtualReassembly).ToNot(BeNil())
   131  	Expect(globalCfg.VirtualReassembly.Timeout).To(BeEquivalentTo(10))
   132  	Expect(globalCfg.VirtualReassembly.MaxReassemblies).To(BeEquivalentTo(5))
   133  	Expect(globalCfg.VirtualReassembly.MaxFragments).To(BeEquivalentTo(7))
   134  	Expect(globalCfg.VirtualReassembly.DropFragments).To(BeTrue())*/
   135  }
   136  
   137  func TestNat44EdInterfacesDump(t *testing.T) {
   138  	ctx, natHandler, swIfIndexes, _ := natTestSetup(t)
   139  	defer ctx.TeardownTestCtx()
   140  
   141  	ctx.MockVpp.MockReply(&vpp_nat_ed.Nat44EdPluginEnableDisableReply{})
   142  	err := natHandler.EnableNAT44Plugin(vppcalls.Nat44InitOpts{EndpointDependent: true})
   143  	Expect(err).ShouldNot(HaveOccurred())
   144  
   145  	// non-output interfaces
   146  	ctx.MockVpp.MockReply(
   147  		&vpp_nat_ed.Nat44InterfaceDetails{
   148  			SwIfIndex: 1,
   149  			Flags:     nat_types.NAT_IS_OUTSIDE,
   150  		},
   151  		&vpp_nat_ed.Nat44InterfaceDetails{
   152  			SwIfIndex: 2,
   153  			Flags:     nat_types.NAT_IS_INSIDE,
   154  		})
   155  	ctx.MockVpp.MockReply(&memclnt.ControlPingReply{})
   156  
   157  	// output interfaces
   158  	ctx.MockVpp.MockReply(
   159  		&vpp_nat_ed.Nat44EdOutputInterfaceDetails{
   160  			SwIfIndex: 3,
   161  		},
   162  		&vpp_nat_ed.Nat44EdOutputInterfaceGetReply{
   163  			Retval: 0,
   164  			Cursor: ^uint32(0),
   165  		})
   166  
   167  	swIfIndexes.Put("if0", &ifaceidx.IfaceMetadata{SwIfIndex: 1})
   168  	swIfIndexes.Put("if1", &ifaceidx.IfaceMetadata{SwIfIndex: 2})
   169  	swIfIndexes.Put("if2", &ifaceidx.IfaceMetadata{SwIfIndex: 3})
   170  
   171  	interfaces, err := natHandler.Nat44InterfacesDump()
   172  	Expect(err).To(Succeed())
   173  
   174  	Expect(interfaces).To(HaveLen(3))
   175  
   176  	Expect(interfaces[0].Name).To(Equal("if0"))
   177  	Expect(interfaces[0].NatInside).To(BeFalse())
   178  	Expect(interfaces[0].NatOutside).To(BeTrue())
   179  	Expect(interfaces[0].OutputFeature).To(BeFalse())
   180  
   181  	Expect(interfaces[1].Name).To(Equal("if1"))
   182  	Expect(interfaces[1].NatInside).To(BeTrue())
   183  	Expect(interfaces[1].NatOutside).To(BeFalse())
   184  	Expect(interfaces[1].OutputFeature).To(BeFalse())
   185  
   186  	Expect(interfaces[2].Name).To(Equal("if2"))
   187  	Expect(interfaces[2].NatInside).To(BeFalse())
   188  	Expect(interfaces[2].NatOutside).To(BeFalse())
   189  	Expect(interfaces[2].OutputFeature).To(BeTrue())
   190  }
   191  
   192  func TestNat44EiInterfacesDump(t *testing.T) {
   193  	ctx, natHandler, swIfIndexes, _ := natTestSetup(t)
   194  	defer ctx.TeardownTestCtx()
   195  
   196  	ctx.MockVpp.MockReply(&vpp_nat_ei.Nat44EiPluginEnableDisableReply{})
   197  	err := natHandler.EnableNAT44Plugin(vppcalls.Nat44InitOpts{EndpointDependent: false})
   198  	Expect(err).ShouldNot(HaveOccurred())
   199  
   200  	// non-output interfaces
   201  	ctx.MockVpp.MockReply(
   202  		&vpp_nat_ei.Nat44EiInterfaceDetails{
   203  			SwIfIndex: 1,
   204  			Flags:     vpp_nat_ei.NAT44_EI_IF_OUTSIDE,
   205  		},
   206  		&vpp_nat_ei.Nat44EiInterfaceDetails{
   207  			SwIfIndex: 2,
   208  			Flags:     vpp_nat_ei.NAT44_EI_IF_INSIDE,
   209  		})
   210  	ctx.MockVpp.MockReply(&memclnt.ControlPingReply{})
   211  
   212  	// output interfaces
   213  	ctx.MockVpp.MockReply(
   214  		&vpp_nat_ei.Nat44EiOutputInterfaceDetails{
   215  			SwIfIndex: 3,
   216  		},
   217  		&vpp_nat_ei.Nat44EiOutputInterfaceGetReply{
   218  			Retval: 0,
   219  			Cursor: ^uint32(0),
   220  		})
   221  
   222  	swIfIndexes.Put("if0", &ifaceidx.IfaceMetadata{SwIfIndex: 1})
   223  	swIfIndexes.Put("if1", &ifaceidx.IfaceMetadata{SwIfIndex: 2})
   224  	swIfIndexes.Put("if2", &ifaceidx.IfaceMetadata{SwIfIndex: 3})
   225  
   226  	interfaces, err := natHandler.Nat44InterfacesDump()
   227  	Expect(err).To(Succeed())
   228  
   229  	Expect(interfaces).To(HaveLen(3))
   230  
   231  	Expect(interfaces[0].Name).To(Equal("if0"))
   232  	Expect(interfaces[0].NatInside).To(BeFalse())
   233  	Expect(interfaces[0].NatOutside).To(BeTrue())
   234  	Expect(interfaces[0].OutputFeature).To(BeFalse())
   235  
   236  	Expect(interfaces[1].Name).To(Equal("if1"))
   237  	Expect(interfaces[1].NatInside).To(BeTrue())
   238  	Expect(interfaces[1].NatOutside).To(BeFalse())
   239  	Expect(interfaces[1].OutputFeature).To(BeFalse())
   240  
   241  	Expect(interfaces[2].Name).To(Equal("if2"))
   242  	Expect(interfaces[2].NatInside).To(BeFalse())
   243  	Expect(interfaces[2].NatOutside).To(BeFalse())
   244  	Expect(interfaces[2].OutputFeature).To(BeTrue())
   245  }
   246  
   247  func TestNat44EdAddressPoolsDump(t *testing.T) {
   248  	ctx, natHandler, _, _ := natTestSetup(t)
   249  	defer ctx.TeardownTestCtx()
   250  
   251  	ctx.MockVpp.MockReply(&vpp_nat_ed.Nat44EdPluginEnableDisableReply{})
   252  	err := natHandler.EnableNAT44Plugin(vppcalls.Nat44InitOpts{EndpointDependent: true})
   253  	Expect(err).ShouldNot(HaveOccurred())
   254  
   255  	// address pool
   256  	ctx.MockVpp.MockReply(
   257  		&vpp_nat_ed.Nat44AddressDetails{
   258  			IPAddress: ipTo4Address("192.168.10.1"),
   259  			Flags:     nat_types.NAT_IS_TWICE_NAT,
   260  			VrfID:     1,
   261  		},
   262  		&vpp_nat_ed.Nat44AddressDetails{
   263  			IPAddress: ipTo4Address("192.168.10.2"),
   264  			VrfID:     2,
   265  		},
   266  		&vpp_nat_ed.Nat44AddressDetails{
   267  			IPAddress: ipTo4Address("192.168.10.3"),
   268  			VrfID:     2,
   269  		},
   270  		&vpp_nat_ed.Nat44AddressDetails{
   271  			IPAddress: ipTo4Address("192.168.10.4"),
   272  			VrfID:     2,
   273  		})
   274  	ctx.MockVpp.MockReply(&memclnt.ControlPingReply{})
   275  
   276  	pools, err := natHandler.Nat44AddressPoolsDump()
   277  	Expect(err).To(Succeed())
   278  
   279  	Expect(pools).To(HaveLen(2))
   280  
   281  	Expect(pools[0].FirstIp).To(Equal("192.168.10.1"))
   282  	Expect(pools[0].LastIp).To(Equal(""))
   283  	Expect(pools[0].TwiceNat).To(BeTrue())
   284  	Expect(pools[0].VrfId).To(BeEquivalentTo(1))
   285  
   286  	Expect(pools[1].FirstIp).To(Equal("192.168.10.2"))
   287  	Expect(pools[1].LastIp).To(Equal("192.168.10.4"))
   288  	Expect(pools[1].TwiceNat).To(BeFalse())
   289  	Expect(pools[1].VrfId).To(BeEquivalentTo(2))
   290  }
   291  
   292  func TestNat44EiAddressPoolsDump(t *testing.T) {
   293  	ctx, natHandler, _, _ := natTestSetup(t)
   294  	defer ctx.TeardownTestCtx()
   295  
   296  	ctx.MockVpp.MockReply(&vpp_nat_ei.Nat44EiPluginEnableDisableReply{})
   297  	err := natHandler.EnableNAT44Plugin(vppcalls.Nat44InitOpts{EndpointDependent: false})
   298  	Expect(err).ShouldNot(HaveOccurred())
   299  
   300  	// address pool
   301  	ctx.MockVpp.MockReply(
   302  		&vpp_nat_ei.Nat44EiAddressDetails{
   303  			IPAddress: ipTo4Address("192.168.10.1"),
   304  			VrfID:     1,
   305  		},
   306  		&vpp_nat_ei.Nat44EiAddressDetails{
   307  			IPAddress: ipTo4Address("192.168.10.2"),
   308  			VrfID:     2,
   309  		},
   310  		&vpp_nat_ei.Nat44EiAddressDetails{
   311  			IPAddress: ipTo4Address("192.168.10.3"),
   312  			VrfID:     2,
   313  		},
   314  		&vpp_nat_ei.Nat44EiAddressDetails{
   315  			IPAddress: ipTo4Address("192.168.10.4"),
   316  			VrfID:     2,
   317  		})
   318  	ctx.MockVpp.MockReply(&memclnt.ControlPingReply{})
   319  
   320  	pools, err := natHandler.Nat44AddressPoolsDump()
   321  	Expect(err).To(Succeed())
   322  
   323  	Expect(pools).To(HaveLen(2))
   324  
   325  	Expect(pools[0].FirstIp).To(Equal("192.168.10.1"))
   326  	Expect(pools[0].LastIp).To(Equal(""))
   327  	Expect(pools[0].VrfId).To(BeEquivalentTo(1))
   328  
   329  	Expect(pools[1].FirstIp).To(Equal("192.168.10.2"))
   330  	Expect(pools[1].LastIp).To(Equal("192.168.10.4"))
   331  	Expect(pools[1].TwiceNat).To(BeFalse())
   332  	Expect(pools[1].VrfId).To(BeEquivalentTo(2))
   333  }
   334  
   335  func TestDNATDump(t *testing.T) {
   336  	ctx, natHandler, swIfIndexes, dhcpIndexes := natTestSetup(t)
   337  	defer ctx.TeardownTestCtx()
   338  
   339  	ctx.MockVpp.MockReply(&vpp_nat_ed.Nat44EdPluginEnableDisableReply{})
   340  	err := natHandler.EnableNAT44Plugin(vppcalls.Nat44InitOpts{EndpointDependent: true})
   341  	Expect(err).ShouldNot(HaveOccurred())
   342  
   343  	// non-LB static mappings
   344  	ctx.MockVpp.MockReply(
   345  		&vpp_nat_ed.Nat44StaticMappingDetails{
   346  			LocalIPAddress:    ipTo4Address("10.10.11.120"),
   347  			ExternalIPAddress: ipTo4Address("10.36.20.20"),
   348  			Protocol:          6,
   349  			LocalPort:         8080,
   350  			ExternalPort:      80,
   351  			ExternalSwIfIndex: vpp2210.NoInterface,
   352  			VrfID:             1,
   353  			Tag:               "DNAT 1",
   354  			Flags:             nat_types.NAT_IS_TWICE_NAT,
   355  		},
   356  		&vpp_nat_ed.Nat44StaticMappingDetails{
   357  			LocalIPAddress:    ipTo4Address("10.10.11.120"),
   358  			Protocol:          6,
   359  			LocalPort:         8080,
   360  			ExternalPort:      80,
   361  			ExternalSwIfIndex: 1,
   362  			VrfID:             1,
   363  			Tag:               "DNAT 1",
   364  			Flags:             nat_types.NAT_IS_TWICE_NAT,
   365  		},
   366  		&vpp_nat_ed.Nat44StaticMappingDetails{
   367  			LocalIPAddress:    ipTo4Address("10.10.11.140"),
   368  			Protocol:          6,
   369  			LocalPort:         8081,
   370  			ExternalPort:      80,
   371  			ExternalSwIfIndex: 2,
   372  			VrfID:             1,
   373  			Tag:               "DNAT 2",
   374  			Flags:             nat_types.NAT_IS_SELF_TWICE_NAT,
   375  		},
   376  		// auto-generated mappings with interface replaced by all assigned IP addresses
   377  		&vpp_nat_ed.Nat44StaticMappingDetails{
   378  			LocalIPAddress:    ipTo4Address("10.10.11.120"),
   379  			ExternalIPAddress: ipTo4Address("10.36.20.30"),
   380  			Protocol:          6,
   381  			LocalPort:         8080,
   382  			ExternalPort:      80,
   383  			ExternalSwIfIndex: vpp2210.NoInterface,
   384  			VrfID:             1,
   385  			Tag:               "DNAT 1",
   386  			Flags:             nat_types.NAT_IS_TWICE_NAT,
   387  		},
   388  		&vpp_nat_ed.Nat44StaticMappingDetails{
   389  			LocalIPAddress:    ipTo4Address("10.10.11.120"),
   390  			ExternalIPAddress: ipTo4Address("10.36.20.31"),
   391  			Protocol:          6,
   392  			LocalPort:         8080,
   393  			ExternalPort:      80,
   394  			ExternalSwIfIndex: vpp2210.NoInterface,
   395  			VrfID:             1,
   396  			Tag:               "DNAT 1",
   397  			Flags:             nat_types.NAT_IS_TWICE_NAT,
   398  		},
   399  		&vpp_nat_ed.Nat44StaticMappingDetails{
   400  			LocalIPAddress:    ipTo4Address("10.10.11.140"),
   401  			ExternalIPAddress: ipTo4Address("10.36.40.10"),
   402  			Protocol:          6,
   403  			LocalPort:         8081,
   404  			ExternalPort:      80,
   405  			ExternalSwIfIndex: vpp2210.NoInterface,
   406  			VrfID:             1,
   407  			Tag:               "DNAT 2",
   408  			Flags:             nat_types.NAT_IS_SELF_TWICE_NAT,
   409  		},
   410  		&vpp_nat_ed.Nat44StaticMappingDetails{
   411  			LocalIPAddress:    ipTo4Address("10.10.11.140"),
   412  			ExternalIPAddress: ipTo4Address("10.36.40.20"),
   413  			Protocol:          6,
   414  			LocalPort:         8081,
   415  			ExternalPort:      80,
   416  			ExternalSwIfIndex: vpp2210.NoInterface,
   417  			VrfID:             1,
   418  			Tag:               "DNAT 2",
   419  			Flags:             nat_types.NAT_IS_SELF_TWICE_NAT,
   420  		},
   421  	)
   422  
   423  	ctx.MockVpp.MockReply(&memclnt.ControlPingReply{})
   424  
   425  	// LB static mappings
   426  	ctx.MockVpp.MockReply(&vpp_nat_ed.Nat44LbStaticMappingDetails{
   427  		ExternalAddr: ipTo4Address("10.36.20.60"),
   428  		ExternalPort: 53,
   429  		Protocol:     17,
   430  		Flags:        nat_types.NAT_IS_OUT2IN_ONLY,
   431  		Tag:          "DNAT 2",
   432  		LocalNum:     2,
   433  		Locals: []vpp_nat_ed.Nat44LbAddrPort{
   434  			{
   435  				Addr:        ipTo4Address("10.10.11.161"),
   436  				Port:        53,
   437  				Probability: 1,
   438  				VrfID:       0,
   439  			},
   440  			{
   441  				Addr:        ipTo4Address("10.10.11.162"),
   442  				Port:        153,
   443  				Probability: 2,
   444  				VrfID:       0,
   445  			},
   446  		},
   447  	})
   448  
   449  	ctx.MockVpp.MockReply(&memclnt.ControlPingReply{})
   450  
   451  	// identity mappings
   452  	ctx.MockVpp.MockReply(
   453  		&vpp_nat_ed.Nat44IdentityMappingDetails{
   454  			Flags:     nat_types.NAT_IS_ADDR_ONLY,
   455  			Protocol:  17,
   456  			IPAddress: ipTo4Address("10.10.11.200"),
   457  			SwIfIndex: vpp2210.NoInterface,
   458  			VrfID:     1,
   459  			Tag:       "DNAT 3",
   460  		},
   461  		&vpp_nat_ed.Nat44IdentityMappingDetails{
   462  			Flags:     nat_types.NAT_IS_ADDR_ONLY,
   463  			Protocol:  17,
   464  			SwIfIndex: 2,
   465  			VrfID:     1,
   466  			Tag:       "DNAT 3",
   467  		},
   468  		// auto-generated mappings with interface replaced by all assigned IP addresses
   469  		&vpp_nat_ed.Nat44IdentityMappingDetails{
   470  			Flags:     nat_types.NAT_IS_ADDR_ONLY,
   471  			Protocol:  17,
   472  			IPAddress: ipTo4Address("10.36.40.10"),
   473  			SwIfIndex: vpp2210.NoInterface,
   474  			VrfID:     1,
   475  			Tag:       "DNAT 3",
   476  		},
   477  		&vpp_nat_ed.Nat44IdentityMappingDetails{
   478  			Flags:     nat_types.NAT_IS_ADDR_ONLY,
   479  			Protocol:  17,
   480  			IPAddress: ipTo4Address("10.36.40.20"),
   481  			SwIfIndex: vpp2210.NoInterface,
   482  			VrfID:     1,
   483  			Tag:       "DNAT 3",
   484  		},
   485  	)
   486  
   487  	ctx.MockVpp.MockReply(&memclnt.ControlPingReply{})
   488  
   489  	// interfaces and their IP addresses
   490  	swIfIndexes.Put("if0", &ifaceidx.IfaceMetadata{SwIfIndex: 1, IPAddresses: []string{"10.36.20.30", "10.36.20.31"}})
   491  	swIfIndexes.Put("if1", &ifaceidx.IfaceMetadata{SwIfIndex: 2, IPAddresses: []string{"10.36.40.10"}})
   492  	dhcpIndexes.Put("if1", &ifs.DHCPLease{InterfaceName: "if0", HostIpAddress: "10.36.40.20"})
   493  
   494  	dnats, err := natHandler.DNat44Dump()
   495  	Expect(err).To(Succeed())
   496  
   497  	Expect(dnats).To(HaveLen(3))
   498  
   499  	dnat := dnats[0]
   500  	Expect(dnat.Label).To(Equal("DNAT 1"))
   501  	Expect(dnat.IdMappings).To(HaveLen(0))
   502  	Expect(dnat.StMappings).To(HaveLen(2))
   503  	// 1st mapping
   504  	Expect(dnat.StMappings[0].TwiceNat).To(Equal(nat.DNat44_StaticMapping_ENABLED))
   505  	Expect(dnat.StMappings[0].Protocol).To(Equal(nat.DNat44_TCP))
   506  	Expect(dnat.StMappings[0].ExternalInterface).To(BeEmpty())
   507  	Expect(dnat.StMappings[0].ExternalIp).To(Equal("10.36.20.20"))
   508  	Expect(dnat.StMappings[0].ExternalPort).To(BeEquivalentTo(80))
   509  	Expect(dnat.StMappings[0].LocalIps).To(HaveLen(1))
   510  	Expect(dnat.StMappings[0].LocalIps[0].VrfId).To(BeEquivalentTo(1))
   511  	Expect(dnat.StMappings[0].LocalIps[0].LocalIp).To(Equal("10.10.11.120"))
   512  	Expect(dnat.StMappings[0].LocalIps[0].LocalPort).To(BeEquivalentTo(8080))
   513  	Expect(dnat.StMappings[0].LocalIps[0].Probability).To(BeEquivalentTo(0))
   514  	// 2nd mapping
   515  	Expect(dnat.StMappings[1].TwiceNat).To(Equal(nat.DNat44_StaticMapping_ENABLED))
   516  	Expect(dnat.StMappings[1].Protocol).To(Equal(nat.DNat44_TCP))
   517  	Expect(dnat.StMappings[1].ExternalInterface).To(BeEquivalentTo("if0"))
   518  	Expect(dnat.StMappings[1].ExternalIp).To(BeEquivalentTo("0.0.0.0"))
   519  	Expect(dnat.StMappings[1].ExternalPort).To(BeEquivalentTo(80))
   520  	Expect(dnat.StMappings[1].LocalIps).To(HaveLen(1))
   521  	Expect(dnat.StMappings[1].LocalIps[0].VrfId).To(BeEquivalentTo(1))
   522  	Expect(dnat.StMappings[1].LocalIps[0].LocalIp).To(Equal("10.10.11.120"))
   523  	Expect(dnat.StMappings[1].LocalIps[0].LocalPort).To(BeEquivalentTo(8080))
   524  	Expect(dnat.StMappings[1].LocalIps[0].Probability).To(BeEquivalentTo(0))
   525  
   526  	dnat = dnats[1]
   527  	// -> non-LB mapping
   528  	Expect(dnat.Label).To(Equal("DNAT 2"))
   529  	Expect(dnat.IdMappings).To(HaveLen(0))
   530  	Expect(dnat.StMappings).To(HaveLen(2))
   531  	Expect(dnat.StMappings[0].TwiceNat).To(Equal(nat.DNat44_StaticMapping_SELF))
   532  	Expect(dnat.StMappings[0].Protocol).To(Equal(nat.DNat44_TCP))
   533  	Expect(dnat.StMappings[0].ExternalInterface).To(Equal("if1"))
   534  	Expect(dnat.StMappings[0].ExternalIp).To(BeEquivalentTo("0.0.0.0"))
   535  	Expect(dnat.StMappings[0].ExternalPort).To(BeEquivalentTo(80))
   536  	Expect(dnat.StMappings[0].LocalIps).To(HaveLen(1))
   537  	Expect(dnat.StMappings[0].LocalIps[0].VrfId).To(BeEquivalentTo(1))
   538  	Expect(dnat.StMappings[0].LocalIps[0].LocalIp).To(Equal("10.10.11.140"))
   539  	Expect(dnat.StMappings[0].LocalIps[0].LocalPort).To(BeEquivalentTo(8081))
   540  	Expect(dnat.StMappings[0].LocalIps[0].Probability).To(BeEquivalentTo(0))
   541  	// -> LB mapping
   542  	Expect(dnat.StMappings[1].TwiceNat).To(Equal(nat.DNat44_StaticMapping_DISABLED))
   543  	Expect(dnat.StMappings[1].Protocol).To(Equal(nat.DNat44_UDP))
   544  	Expect(dnat.StMappings[1].ExternalInterface).To(BeEmpty())
   545  	Expect(dnat.StMappings[1].ExternalIp).To(Equal("10.36.20.60"))
   546  	Expect(dnat.StMappings[1].ExternalPort).To(BeEquivalentTo(53))
   547  	Expect(dnat.StMappings[1].LocalIps).To(HaveLen(2))
   548  	Expect(dnat.StMappings[1].LocalIps[0].VrfId).To(BeEquivalentTo(0))
   549  	Expect(dnat.StMappings[1].LocalIps[0].LocalIp).To(Equal("10.10.11.161"))
   550  	Expect(dnat.StMappings[1].LocalIps[0].LocalPort).To(BeEquivalentTo(53))
   551  	Expect(dnat.StMappings[1].LocalIps[0].Probability).To(BeEquivalentTo(1))
   552  	Expect(dnat.StMappings[1].LocalIps[1].VrfId).To(BeEquivalentTo(0))
   553  	Expect(dnat.StMappings[1].LocalIps[1].LocalIp).To(Equal("10.10.11.162"))
   554  	Expect(dnat.StMappings[1].LocalIps[1].LocalPort).To(BeEquivalentTo(153))
   555  	Expect(dnat.StMappings[1].LocalIps[1].Probability).To(BeEquivalentTo(2))
   556  
   557  	dnat = dnats[2]
   558  	Expect(dnat.Label).To(Equal("DNAT 3"))
   559  	Expect(dnat.StMappings).To(HaveLen(0))
   560  	Expect(dnat.IdMappings).To(HaveLen(2))
   561  	// 1st mapping
   562  	Expect(dnat.IdMappings[0].VrfId).To(BeEquivalentTo(1))
   563  	Expect(dnat.IdMappings[0].Protocol).To(Equal(nat.DNat44_UDP))
   564  	Expect(dnat.IdMappings[0].Port).To(BeEquivalentTo(0))
   565  	Expect(dnat.IdMappings[0].IpAddress).To(Equal("10.10.11.200"))
   566  	Expect(dnat.IdMappings[0].Interface).To(BeEmpty())
   567  	// 2nd mapping
   568  	Expect(dnat.IdMappings[1].VrfId).To(BeEquivalentTo(1))
   569  	Expect(dnat.IdMappings[1].Protocol).To(Equal(nat.DNat44_UDP))
   570  	Expect(dnat.IdMappings[1].Port).To(BeEquivalentTo(0))
   571  	Expect(dnat.IdMappings[1].IpAddress).To(BeEquivalentTo("0.0.0.0"))
   572  	Expect(dnat.IdMappings[1].Interface).To(BeEquivalentTo("if1"))
   573  }
   574  
   575  func natTestSetup(t *testing.T) (*vppmock.TestCtx, vppcalls.NatVppAPI, ifaceidx.IfaceMetadataIndexRW, idxmap.NamedMappingRW) {
   576  	ctx := vppmock.SetupTestCtx(t)
   577  	log := logrus.NewLogger("test-log")
   578  	swIfIndexes := ifaceidx.NewIfaceIndex(logrus.DefaultLogger(), "test-sw_if_indexes")
   579  	dhcpIndexes := idxmap_mem.NewNamedMapping(logrus.DefaultLogger(), "test-dhcp_indexes", nil)
   580  	natHandler := vpp2210.NewNatVppHandler(ctx.MockVPPClient, swIfIndexes, dhcpIndexes, log)
   581  	return ctx, natHandler, swIfIndexes, dhcpIndexes
   582  }
   583  
   584  func ipTo4Address(ipStr string) (addr ip_types.IP4Address) {
   585  	netIP := net.ParseIP(ipStr)
   586  	if ip4 := netIP.To4(); ip4 != nil {
   587  		copy(addr[:], ip4)
   588  	}
   589  	return
   590  }