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

     1  //  Copyright (c) 2019 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 vpp2101_test
    16  
    17  import (
    18  	"bytes"
    19  	"net"
    20  	"testing"
    21  
    22  	. "github.com/onsi/gomega"
    23  
    24  	"go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2101/ip_types"
    25  	vpp_nat "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2101/nat44"
    26  	"go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2101/nat_types"
    27  	"go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/ifaceidx"
    28  	vpp2101 "go.ligato.io/vpp-agent/v3/plugins/vpp/natplugin/vppcalls/vpp2101"
    29  	nat "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/nat"
    30  )
    31  
    32  func TestSetNat44Forwarding(t *testing.T) {
    33  	ctx, natHandler, _, _ := natTestSetup(t)
    34  	defer ctx.TeardownTestCtx()
    35  
    36  	ctx.MockVpp.MockReply(&vpp_nat.Nat44ForwardingEnableDisableReply{})
    37  	err := natHandler.SetNat44Forwarding(true)
    38  
    39  	Expect(err).ShouldNot(HaveOccurred())
    40  
    41  	t.Logf("Msg: %+v (%#v)", ctx.MockChannel.Msg, ctx.MockChannel.Msg)
    42  	msg, ok := ctx.MockChannel.Msg.(*vpp_nat.Nat44ForwardingEnableDisable)
    43  	Expect(ok).To(BeTrue())
    44  	Expect(msg).ToNot(BeNil())
    45  	Expect(msg.Enable).To(BeTrue())
    46  }
    47  
    48  func TestUnsetNat44Forwarding(t *testing.T) {
    49  	ctx, natHandler, _, _ := natTestSetup(t)
    50  	defer ctx.TeardownTestCtx()
    51  
    52  	ctx.MockVpp.MockReply(&vpp_nat.Nat44ForwardingEnableDisableReply{})
    53  	err := natHandler.SetNat44Forwarding(false)
    54  
    55  	Expect(err).ShouldNot(HaveOccurred())
    56  
    57  	msg, ok := ctx.MockChannel.Msg.(*vpp_nat.Nat44ForwardingEnableDisable)
    58  	Expect(ok).To(BeTrue())
    59  	Expect(msg).ToNot(BeNil())
    60  	Expect(msg.Enable).To(BeFalse())
    61  }
    62  
    63  func TestSetNat44ForwardingError(t *testing.T) {
    64  	ctx, natHandler, _, _ := natTestSetup(t)
    65  	defer ctx.TeardownTestCtx()
    66  
    67  	// Incorrect reply object
    68  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelStaticMappingV2Reply{})
    69  	err := natHandler.SetNat44Forwarding(true)
    70  
    71  	Expect(err).Should(HaveOccurred())
    72  }
    73  
    74  func TestSetNat44ForwardingRetval(t *testing.T) {
    75  	ctx, natHandler, _, _ := natTestSetup(t)
    76  	defer ctx.TeardownTestCtx()
    77  
    78  	ctx.MockVpp.MockReply(&vpp_nat.Nat44ForwardingEnableDisableReply{
    79  		Retval: 1,
    80  	})
    81  	err := natHandler.SetNat44Forwarding(true)
    82  
    83  	Expect(err).Should(HaveOccurred())
    84  }
    85  
    86  func TestEnableNat44InterfaceAsInside(t *testing.T) {
    87  	ctx, natHandler, swIfIndexes, _ := natTestSetup(t)
    88  	defer ctx.TeardownTestCtx()
    89  
    90  	swIfIndexes.Put("if0", &ifaceidx.IfaceMetadata{SwIfIndex: 1})
    91  
    92  	ctx.MockVpp.MockReply(&vpp_nat.Nat44InterfaceAddDelFeatureReply{})
    93  	err := natHandler.EnableNat44Interface("if0", true, false)
    94  
    95  	Expect(err).ShouldNot(HaveOccurred())
    96  
    97  	msg, ok := ctx.MockChannel.Msg.(*vpp_nat.Nat44InterfaceAddDelFeature)
    98  	Expect(ok).To(BeTrue())
    99  	Expect(msg).ToNot(BeNil())
   100  	Expect(msg.IsAdd).To(BeTrue())
   101  	Expect(msg.Flags).To(BeEquivalentTo(nat_types.NAT_IS_INSIDE))
   102  	Expect(msg.SwIfIndex).To(BeEquivalentTo(1))
   103  }
   104  
   105  func TestEnableNat44InterfaceAsOutside(t *testing.T) {
   106  	ctx, natHandler, swIfIndexes, _ := natTestSetup(t)
   107  	defer ctx.TeardownTestCtx()
   108  
   109  	swIfIndexes.Put("if1", &ifaceidx.IfaceMetadata{SwIfIndex: 2})
   110  
   111  	ctx.MockVpp.MockReply(&vpp_nat.Nat44InterfaceAddDelFeatureReply{})
   112  	err := natHandler.EnableNat44Interface("if1", false, false)
   113  
   114  	Expect(err).ShouldNot(HaveOccurred())
   115  
   116  	msg, ok := ctx.MockChannel.Msg.(*vpp_nat.Nat44InterfaceAddDelFeature)
   117  	Expect(ok).To(BeTrue())
   118  	Expect(msg).ToNot(BeNil())
   119  	Expect(msg.IsAdd).To(BeTrue())
   120  	Expect(msg.Flags).To(BeEquivalentTo(0))
   121  	Expect(msg.SwIfIndex).To(BeEquivalentTo(2))
   122  }
   123  
   124  func TestEnableNat44InterfaceError(t *testing.T) {
   125  	ctx, natHandler, swIfIndexes, _ := natTestSetup(t)
   126  	defer ctx.TeardownTestCtx()
   127  
   128  	swIfIndexes.Put("if1", &ifaceidx.IfaceMetadata{SwIfIndex: 2})
   129  
   130  	// Incorrect reply object
   131  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelAddressRangeReply{})
   132  	err := natHandler.EnableNat44Interface("if1", false, false)
   133  
   134  	Expect(err).Should(HaveOccurred())
   135  }
   136  
   137  func TestEnableNat44InterfaceRetval(t *testing.T) {
   138  	ctx, natHandler, swIfIndexes, _ := natTestSetup(t)
   139  	defer ctx.TeardownTestCtx()
   140  
   141  	swIfIndexes.Put("if1", &ifaceidx.IfaceMetadata{SwIfIndex: 2})
   142  
   143  	ctx.MockVpp.MockReply(&vpp_nat.Nat44InterfaceAddDelFeatureReply{
   144  		Retval: 1,
   145  	})
   146  	err := natHandler.EnableNat44Interface("if1", false, false)
   147  
   148  	Expect(err).Should(HaveOccurred())
   149  }
   150  
   151  func TestDisableNat44InterfaceAsInside(t *testing.T) {
   152  	ctx, natHandler, swIfIndexes, _ := natTestSetup(t)
   153  	defer ctx.TeardownTestCtx()
   154  
   155  	swIfIndexes.Put("if0", &ifaceidx.IfaceMetadata{SwIfIndex: 1})
   156  
   157  	ctx.MockVpp.MockReply(&vpp_nat.Nat44InterfaceAddDelFeatureReply{})
   158  	err := natHandler.DisableNat44Interface("if0", true, false)
   159  
   160  	Expect(err).ShouldNot(HaveOccurred())
   161  
   162  	msg, ok := ctx.MockChannel.Msg.(*vpp_nat.Nat44InterfaceAddDelFeature)
   163  	Expect(ok).To(BeTrue())
   164  	Expect(msg).ToNot(BeNil())
   165  	Expect(msg.IsAdd).To(BeFalse())
   166  	Expect(msg.Flags).To(BeEquivalentTo(nat_types.NAT_IS_INSIDE))
   167  	Expect(msg.SwIfIndex).To(BeEquivalentTo(1))
   168  }
   169  
   170  func TestDisableNat44InterfaceAsOutside(t *testing.T) {
   171  	ctx, natHandler, swIfIndexes, _ := natTestSetup(t)
   172  	defer ctx.TeardownTestCtx()
   173  
   174  	swIfIndexes.Put("if1", &ifaceidx.IfaceMetadata{SwIfIndex: 2})
   175  
   176  	ctx.MockVpp.MockReply(&vpp_nat.Nat44InterfaceAddDelFeatureReply{})
   177  	err := natHandler.DisableNat44Interface("if1", false, false)
   178  
   179  	Expect(err).ShouldNot(HaveOccurred())
   180  
   181  	msg, ok := ctx.MockChannel.Msg.(*vpp_nat.Nat44InterfaceAddDelFeature)
   182  	Expect(ok).To(BeTrue())
   183  	Expect(msg).ToNot(BeNil())
   184  	Expect(msg.IsAdd).To(BeFalse())
   185  	Expect(msg.Flags).To(BeEquivalentTo(0))
   186  	Expect(msg.SwIfIndex).To(BeEquivalentTo(2))
   187  }
   188  
   189  func TestEnableNat44InterfaceOutputAsInside(t *testing.T) {
   190  	ctx, natHandler, swIfIndexes, _ := natTestSetup(t)
   191  	defer ctx.TeardownTestCtx()
   192  
   193  	swIfIndexes.Put("if0", &ifaceidx.IfaceMetadata{SwIfIndex: 1})
   194  
   195  	ctx.MockVpp.MockReply(&vpp_nat.Nat44InterfaceAddDelOutputFeatureReply{})
   196  	err := natHandler.EnableNat44Interface("if0", true, true)
   197  
   198  	Expect(err).ShouldNot(HaveOccurred())
   199  
   200  	msg, ok := ctx.MockChannel.Msg.(*vpp_nat.Nat44InterfaceAddDelOutputFeature)
   201  	Expect(ok).To(BeTrue())
   202  	Expect(msg).ToNot(BeNil())
   203  	Expect(msg.IsAdd).To(BeTrue())
   204  	Expect(msg.Flags).To(BeEquivalentTo(nat_types.NAT_IS_INSIDE))
   205  	Expect(msg.SwIfIndex).To(BeEquivalentTo(1))
   206  }
   207  
   208  func TestEnableNat44InterfaceOutputAsOutside(t *testing.T) {
   209  	ctx, natHandler, swIfIndexes, _ := natTestSetup(t)
   210  	defer ctx.TeardownTestCtx()
   211  
   212  	swIfIndexes.Put("if1", &ifaceidx.IfaceMetadata{SwIfIndex: 2})
   213  
   214  	ctx.MockVpp.MockReply(&vpp_nat.Nat44InterfaceAddDelOutputFeatureReply{})
   215  	err := natHandler.EnableNat44Interface("if1", false, true)
   216  
   217  	Expect(err).ShouldNot(HaveOccurred())
   218  
   219  	msg, ok := ctx.MockChannel.Msg.(*vpp_nat.Nat44InterfaceAddDelOutputFeature)
   220  	Expect(ok).To(BeTrue())
   221  	Expect(msg).ToNot(BeNil())
   222  	Expect(msg.IsAdd).To(BeTrue())
   223  	Expect(msg.Flags).To(BeEquivalentTo(0))
   224  	Expect(msg.SwIfIndex).To(BeEquivalentTo(2))
   225  }
   226  
   227  func TestEnableNat44InterfaceOutputError(t *testing.T) {
   228  	ctx, natHandler, swIfIndexes, _ := natTestSetup(t)
   229  	defer ctx.TeardownTestCtx()
   230  
   231  	swIfIndexes.Put("if1", &ifaceidx.IfaceMetadata{SwIfIndex: 2})
   232  
   233  	// Incorrect reply object
   234  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelStaticMappingV2Reply{})
   235  	err := natHandler.EnableNat44Interface("if1", false, true)
   236  
   237  	Expect(err).Should(HaveOccurred())
   238  }
   239  
   240  func TestEnableNat44InterfaceOutputRetval(t *testing.T) {
   241  	ctx, natHandler, swIfIndexes, _ := natTestSetup(t)
   242  	defer ctx.TeardownTestCtx()
   243  
   244  	swIfIndexes.Put("if1", &ifaceidx.IfaceMetadata{SwIfIndex: 2})
   245  
   246  	ctx.MockVpp.MockReply(&vpp_nat.Nat44InterfaceAddDelOutputFeatureReply{
   247  		Retval: 1,
   248  	})
   249  	err := natHandler.EnableNat44Interface("if1", false, true)
   250  
   251  	Expect(err).Should(HaveOccurred())
   252  }
   253  
   254  func TestDisableNat44InterfaceOutputAsInside(t *testing.T) {
   255  	ctx, natHandler, swIfIndexes, _ := natTestSetup(t)
   256  	defer ctx.TeardownTestCtx()
   257  
   258  	swIfIndexes.Put("if0", &ifaceidx.IfaceMetadata{SwIfIndex: 1})
   259  
   260  	ctx.MockVpp.MockReply(&vpp_nat.Nat44InterfaceAddDelOutputFeatureReply{})
   261  	err := natHandler.DisableNat44Interface("if0", true, true)
   262  
   263  	Expect(err).ShouldNot(HaveOccurred())
   264  
   265  	msg, ok := ctx.MockChannel.Msg.(*vpp_nat.Nat44InterfaceAddDelOutputFeature)
   266  	Expect(ok).To(BeTrue())
   267  	Expect(msg).ToNot(BeNil())
   268  	Expect(msg.IsAdd).To(BeFalse())
   269  	Expect(msg.Flags).To(BeEquivalentTo(nat_types.NAT_IS_INSIDE))
   270  	Expect(msg.SwIfIndex).To(BeEquivalentTo(1))
   271  }
   272  
   273  func TestDisableNat44InterfaceOutputAsOutside(t *testing.T) {
   274  	ctx, natHandler, swIfIndexes, _ := natTestSetup(t)
   275  	defer ctx.TeardownTestCtx()
   276  
   277  	swIfIndexes.Put("if1", &ifaceidx.IfaceMetadata{SwIfIndex: 2})
   278  
   279  	ctx.MockVpp.MockReply(&vpp_nat.Nat44InterfaceAddDelOutputFeatureReply{})
   280  	err := natHandler.DisableNat44Interface("if1", false, true)
   281  
   282  	Expect(err).ShouldNot(HaveOccurred())
   283  
   284  	msg, ok := ctx.MockChannel.Msg.(*vpp_nat.Nat44InterfaceAddDelOutputFeature)
   285  	Expect(ok).To(BeTrue())
   286  	Expect(msg).ToNot(BeNil())
   287  	Expect(msg.IsAdd).To(BeFalse())
   288  	Expect(msg.Flags).To(BeEquivalentTo(0))
   289  	Expect(msg.SwIfIndex).To(BeEquivalentTo(2))
   290  }
   291  
   292  func TestAddNat44AddressPool(t *testing.T) {
   293  	ctx, natHandler, _, _ := natTestSetup(t)
   294  	defer ctx.TeardownTestCtx()
   295  
   296  	addr1 := net.ParseIP("10.0.0.1").To4()
   297  	addr2 := net.ParseIP("10.0.0.10").To4()
   298  
   299  	// first IP only
   300  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelAddressRangeReply{})
   301  	err := natHandler.AddNat44AddressPool(0, addr1.String(), "", false)
   302  	Expect(err).ShouldNot(HaveOccurred())
   303  
   304  	msg, ok := ctx.MockChannel.Msg.(*vpp_nat.Nat44AddDelAddressRange)
   305  	Expect(ok).To(BeTrue())
   306  	Expect(msg.IsAdd).To(BeTrue())
   307  	Expect(addressTo4IP(msg.FirstIPAddress)).To(BeEquivalentTo(addr1.String()))
   308  	Expect(addressTo4IP(msg.LastIPAddress)).To(BeEquivalentTo(addr1.String()))
   309  	Expect(msg.VrfID).To(BeEquivalentTo(0))
   310  	Expect(msg.Flags).To(BeEquivalentTo(0))
   311  
   312  	// first IP + last IP
   313  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelAddressRangeReply{})
   314  	err = natHandler.AddNat44AddressPool(0, addr1.String(), addr2.String(), false)
   315  	Expect(err).ShouldNot(HaveOccurred())
   316  
   317  	msg, ok = ctx.MockChannel.Msg.(*vpp_nat.Nat44AddDelAddressRange)
   318  	Expect(ok).To(BeTrue())
   319  	Expect(msg.IsAdd).To(BeTrue())
   320  	Expect(addressTo4IP(msg.FirstIPAddress)).To(BeEquivalentTo(addr1.String()))
   321  	Expect(addressTo4IP(msg.LastIPAddress)).To(BeEquivalentTo(addr2.String()))
   322  	Expect(msg.VrfID).To(BeEquivalentTo(0))
   323  	Expect(msg.Flags).To(BeEquivalentTo(0))
   324  }
   325  
   326  func TestAddNat44AddressPoolError(t *testing.T) {
   327  	ctx, natHandler, _, _ := natTestSetup(t)
   328  	defer ctx.TeardownTestCtx()
   329  
   330  	addr := net.ParseIP("10.0.0.1").To4()
   331  
   332  	// Incorrect reply object
   333  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelIdentityMappingReply{})
   334  	err := natHandler.AddNat44AddressPool(0, addr.String(), "", false)
   335  
   336  	Expect(err).Should(HaveOccurred())
   337  }
   338  
   339  func TestAddNat44AddressPoolRetval(t *testing.T) {
   340  	ctx, natHandler, _, _ := natTestSetup(t)
   341  	defer ctx.TeardownTestCtx()
   342  
   343  	addr := net.ParseIP("10.0.0.1").To4()
   344  
   345  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelAddressRangeReply{
   346  		Retval: 1,
   347  	})
   348  	err := natHandler.AddNat44AddressPool(0, addr.String(), "", false)
   349  
   350  	Expect(err).Should(HaveOccurred())
   351  }
   352  
   353  func TestDelNat44AddressPool(t *testing.T) {
   354  	ctx, natHandler, _, _ := natTestSetup(t)
   355  	defer ctx.TeardownTestCtx()
   356  
   357  	addr := net.ParseIP("10.0.0.1").To4()
   358  
   359  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelAddressRangeReply{})
   360  	err := natHandler.DelNat44AddressPool(0, addr.String(), "", false)
   361  
   362  	Expect(err).ShouldNot(HaveOccurred())
   363  
   364  	msg, ok := ctx.MockChannel.Msg.(*vpp_nat.Nat44AddDelAddressRange)
   365  	Expect(ok).To(BeTrue())
   366  	Expect(msg.IsAdd).To(BeFalse())
   367  	Expect(addressTo4IP(msg.FirstIPAddress)).To(BeEquivalentTo(addr.String()))
   368  	Expect(addressTo4IP(msg.LastIPAddress)).To(BeEquivalentTo(addr.String()))
   369  	Expect(msg.VrfID).To(BeEquivalentTo(0))
   370  	Expect(msg.Flags).To(BeEquivalentTo(0))
   371  }
   372  
   373  /* DEPRECATED
   374  
   375  func TestSetNat44VirtualReassemblyIPv4(t *testing.T) {
   376  	ctx, natHandler, _, _ := natTestSetup(t)
   377  	defer ctx.TeardownTestCtx()
   378  
   379  	ctx.MockVpp.MockReply(&vpp_nat.NatSetReassReply{})
   380  	err := natHandler.SetVirtualReassemblyIPv4(&nat.VirtualReassembly{
   381  		Timeout:         10,
   382  		MaxFragments:    20,
   383  		MaxReassemblies: 30,
   384  		DropFragments:   true,
   385  	})
   386  
   387  	Expect(err).ShouldNot(HaveOccurred())
   388  
   389  	msg, ok := ctx.MockChannel.Msg.(*vpp_nat.NatSetReass)
   390  	Expect(ok).To(BeTrue())
   391  	Expect(msg.Timeout).To(BeEquivalentTo(10))
   392  	Expect(msg.MaxFrag).To(BeEquivalentTo(20))
   393  	Expect(msg.MaxReass).To(BeEquivalentTo(30))
   394  	Expect(msg.DropFrag).To(BeEquivalentTo(1))
   395  }
   396  
   397  func TestSetNat44VirtualReassemblyIPv6(t *testing.T) {
   398  	ctx, natHandler, _, _ := natTestSetup(t)
   399  	defer ctx.TeardownTestCtx()
   400  
   401  	ctx.MockVpp.MockReply(&vpp_nat.NatSetReassReply{})
   402  	err := natHandler.SetVirtualReassemblyIPv6(&nat.VirtualReassembly{
   403  		Timeout:         5,
   404  		MaxFragments:    10,
   405  		MaxReassemblies: 15,
   406  		DropFragments:   true,
   407  	})
   408  
   409  	Expect(err).ShouldNot(HaveOccurred())
   410  
   411  	msg, ok := ctx.MockChannel.Msg.(*vpp_nat.NatSetReass)
   412  	Expect(ok).To(BeTrue())
   413  	Expect(msg.Timeout).To(BeEquivalentTo(5))
   414  	Expect(msg.MaxFrag).To(BeEquivalentTo(10))
   415  	Expect(msg.MaxReass).To(BeEquivalentTo(15))
   416  	Expect(msg.DropFrag).To(BeEquivalentTo(1))
   417  }*/
   418  
   419  func TestAddNat44StaticMapping(t *testing.T) {
   420  	ctx, natHandler, swIfIndexes, _ := natTestSetup(t)
   421  	defer ctx.TeardownTestCtx()
   422  
   423  	swIfIndexes.Put("if0", &ifaceidx.IfaceMetadata{SwIfIndex: 1})
   424  
   425  	localIP := net.ParseIP("10.0.0.1").To4()
   426  	externalIP := net.ParseIP("10.0.0.2").To4()
   427  
   428  	// DataContext
   429  	mapping := &nat.DNat44_StaticMapping{
   430  		ExternalIp:        externalIP.String(),
   431  		ExternalPort:      8080,
   432  		ExternalInterface: "if0", // overrides external IP
   433  		Protocol:          nat.DNat44_TCP,
   434  		TwiceNat:          nat.DNat44_StaticMapping_ENABLED,
   435  		LocalIps: []*nat.DNat44_StaticMapping_LocalIP{
   436  			{
   437  				LocalIp:   localIP.String(),
   438  				VrfId:     1,
   439  				LocalPort: 24,
   440  			},
   441  		},
   442  	}
   443  
   444  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelStaticMappingV2Reply{})
   445  	err := natHandler.AddNat44StaticMapping(mapping, "DNAT 1")
   446  
   447  	Expect(err).ShouldNot(HaveOccurred())
   448  
   449  	msg, ok := ctx.MockChannel.Msg.(*vpp_nat.Nat44AddDelStaticMappingV2)
   450  	Expect(ok).To(BeTrue())
   451  	Expect(msg.Tag).To(BeEquivalentTo("DNAT 1"))
   452  	Expect(msg.VrfID).To(BeEquivalentTo(1))
   453  	Expect(msg.IsAdd).To(BeTrue())
   454  	Expect(msg.LocalPort).To(BeEquivalentTo(24))
   455  	Expect(msg.ExternalPort).To(BeEquivalentTo(8080))
   456  	Expect(msg.Protocol).To(BeEquivalentTo(6))
   457  	Expect(addressTo4IP(msg.ExternalIPAddress)).To(BeEquivalentTo("0.0.0.0"))
   458  	Expect(msg.ExternalSwIfIndex).To(BeEquivalentTo(1))
   459  	Expect(addressTo4IP(msg.LocalIPAddress)).To(BeEquivalentTo(localIP.String()))
   460  	Expect(msg.Flags).To(BeEquivalentTo(nat_types.NAT_IS_TWICE_NAT + nat_types.NAT_IS_OUT2IN_ONLY))
   461  }
   462  
   463  func TestAddNat44IdentityMappingWithInterface(t *testing.T) {
   464  	ctx, natHandler, _, _ := natTestSetup(t)
   465  	defer ctx.TeardownTestCtx()
   466  
   467  	localIP := net.ParseIP("10.0.0.1").To4()
   468  	externalIP := net.ParseIP("10.0.0.2").To4()
   469  
   470  	// DataContext
   471  	mapping := &nat.DNat44_StaticMapping{
   472  		ExternalIp: externalIP.String(),
   473  		Protocol:   nat.DNat44_TCP,
   474  		LocalIps: []*nat.DNat44_StaticMapping_LocalIP{
   475  			{
   476  				LocalIp: localIP.String(),
   477  			},
   478  		},
   479  	}
   480  
   481  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelStaticMappingV2Reply{})
   482  	err := natHandler.AddNat44StaticMapping(mapping, "DNAT 1")
   483  
   484  	Expect(err).ShouldNot(HaveOccurred())
   485  
   486  	msg, ok := ctx.MockChannel.Msg.(*vpp_nat.Nat44AddDelStaticMappingV2)
   487  	Expect(ok).To(BeTrue())
   488  	Expect(msg.Tag).To(BeEquivalentTo("DNAT 1"))
   489  	Expect(msg.IsAdd).To(BeTrue())
   490  	Expect(addressTo4IP(msg.ExternalIPAddress)).To(BeEquivalentTo(externalIP.String()))
   491  	Expect(addressTo4IP(msg.LocalIPAddress)).To(BeEquivalentTo(localIP.String()))
   492  	Expect(msg.Flags).To(BeEquivalentTo(nat_types.NAT_IS_OUT2IN_ONLY + nat_types.NAT_IS_ADDR_ONLY))
   493  }
   494  
   495  func TestAddNat44StaticMappingError(t *testing.T) {
   496  	ctx, natHandler, _, _ := natTestSetup(t)
   497  	defer ctx.TeardownTestCtx()
   498  
   499  	// Incorrect reply object
   500  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelLbStaticMappingReply{})
   501  	err := natHandler.AddNat44StaticMapping(&nat.DNat44_StaticMapping{}, "")
   502  
   503  	Expect(err).Should(HaveOccurred())
   504  }
   505  
   506  func TestAddNat44StaticMappingRetval(t *testing.T) {
   507  	ctx, natHandler, _, _ := natTestSetup(t)
   508  	defer ctx.TeardownTestCtx()
   509  
   510  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelStaticMappingV2Reply{
   511  		Retval: 1,
   512  	})
   513  	err := natHandler.AddNat44StaticMapping(&nat.DNat44_StaticMapping{}, "")
   514  
   515  	Expect(err).Should(HaveOccurred())
   516  }
   517  
   518  func TestDelNat44StaticMapping(t *testing.T) {
   519  	ctx, natHandler, swIfIndexes, _ := natTestSetup(t)
   520  	defer ctx.TeardownTestCtx()
   521  
   522  	swIfIndexes.Put("if0", &ifaceidx.IfaceMetadata{SwIfIndex: 1})
   523  
   524  	localIP := net.ParseIP("10.0.0.1").To4()
   525  	externalIP := net.ParseIP("10.0.0.2").To4()
   526  
   527  	mapping := &nat.DNat44_StaticMapping{
   528  		ExternalIp:        externalIP.String(),
   529  		ExternalPort:      8080,
   530  		ExternalInterface: "if0", // overrides external IP
   531  		Protocol:          nat.DNat44_TCP,
   532  		TwiceNat:          nat.DNat44_StaticMapping_ENABLED,
   533  		LocalIps: []*nat.DNat44_StaticMapping_LocalIP{
   534  			{
   535  				LocalIp:   localIP.String(),
   536  				VrfId:     1,
   537  				LocalPort: 24,
   538  			},
   539  		},
   540  	}
   541  
   542  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelStaticMappingV2Reply{})
   543  	err := natHandler.DelNat44StaticMapping(mapping, "DNAT 1")
   544  
   545  	Expect(err).ShouldNot(HaveOccurred())
   546  
   547  	msg, ok := ctx.MockChannel.Msg.(*vpp_nat.Nat44AddDelStaticMappingV2)
   548  	Expect(ok).To(BeTrue())
   549  	Expect(msg.Tag).To(BeEquivalentTo("DNAT 1"))
   550  	Expect(msg.VrfID).To(BeEquivalentTo(1))
   551  	Expect(msg.IsAdd).To(BeFalse())
   552  	Expect(msg.LocalPort).To(BeEquivalentTo(24))
   553  	Expect(msg.ExternalPort).To(BeEquivalentTo(8080))
   554  	Expect(msg.Protocol).To(BeEquivalentTo(6))
   555  	Expect(addressTo4IP(msg.ExternalIPAddress)).To(BeEquivalentTo("0.0.0.0"))
   556  	Expect(msg.ExternalSwIfIndex).To(BeEquivalentTo(1))
   557  	Expect(addressTo4IP(msg.LocalIPAddress)).To(BeEquivalentTo(localIP.String()))
   558  	Expect(msg.Flags).To(BeEquivalentTo(nat_types.NAT_IS_TWICE_NAT + nat_types.NAT_IS_OUT2IN_ONLY))
   559  }
   560  
   561  func TestDelNat44StaticMappingAddrOnly(t *testing.T) {
   562  	ctx, natHandler, _, _ := natTestSetup(t)
   563  	defer ctx.TeardownTestCtx()
   564  
   565  	localIP := net.ParseIP("10.0.0.1").To4()
   566  	externalIP := net.ParseIP("10.0.0.2").To4()
   567  
   568  	mapping := &nat.DNat44_StaticMapping{
   569  		ExternalIp: externalIP.String(),
   570  		Protocol:   nat.DNat44_TCP,
   571  		LocalIps: []*nat.DNat44_StaticMapping_LocalIP{
   572  			{
   573  				LocalIp: localIP.String(),
   574  			},
   575  		},
   576  	}
   577  
   578  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelStaticMappingV2Reply{})
   579  	err := natHandler.DelNat44StaticMapping(mapping, "DNAT 1")
   580  
   581  	Expect(err).ShouldNot(HaveOccurred())
   582  
   583  	msg, ok := ctx.MockChannel.Msg.(*vpp_nat.Nat44AddDelStaticMappingV2)
   584  	Expect(ok).To(BeTrue())
   585  	Expect(msg.Tag).To(BeEquivalentTo("DNAT 1"))
   586  	Expect(msg.IsAdd).To(BeFalse())
   587  	Expect(addressTo4IP(msg.ExternalIPAddress)).To(BeEquivalentTo(externalIP.String()))
   588  	Expect(addressTo4IP(msg.LocalIPAddress)).To(BeEquivalentTo(localIP.String()))
   589  }
   590  
   591  func TestAddNat44StaticMappingLb(t *testing.T) {
   592  	ctx, natHandler, _, _ := natTestSetup(t)
   593  	defer ctx.TeardownTestCtx()
   594  
   595  	externalIP := net.ParseIP("10.0.0.1").To4()
   596  	localIP1 := net.ParseIP("10.0.0.2").To4()
   597  	localIP2 := net.ParseIP("10.0.0.3").To4()
   598  
   599  	mapping := &nat.DNat44_StaticMapping{
   600  		ExternalIp:        externalIP.String(),
   601  		ExternalPort:      8080,
   602  		ExternalInterface: "if0",
   603  		Protocol:          nat.DNat44_TCP,
   604  		TwiceNat:          nat.DNat44_StaticMapping_ENABLED,
   605  		LocalIps:          localIPs(localIP1, localIP2),
   606  	}
   607  
   608  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelLbStaticMappingReply{})
   609  	err := natHandler.AddNat44StaticMapping(mapping, "DNAT 1")
   610  
   611  	Expect(err).ShouldNot(HaveOccurred())
   612  
   613  	msg, ok := ctx.MockChannel.Msg.(*vpp_nat.Nat44AddDelLbStaticMapping)
   614  	Expect(ok).To(BeTrue())
   615  	Expect(msg.Tag).To(BeEquivalentTo("DNAT 1"))
   616  	Expect(msg.IsAdd).To(BeTrue())
   617  	Expect(addressTo4IP(msg.ExternalAddr)).To(BeEquivalentTo(externalIP.String()))
   618  	Expect(msg.ExternalPort).To(BeEquivalentTo(8080))
   619  	Expect(msg.Protocol).To(BeEquivalentTo(6))
   620  	Expect(msg.Flags).To(BeEquivalentTo(nat_types.NAT_IS_TWICE_NAT + nat_types.NAT_IS_OUT2IN_ONLY))
   621  
   622  	// Local IPs
   623  	Expect(msg.Locals).To(HaveLen(2))
   624  	expectedCount := 0
   625  	for _, local := range msg.Locals {
   626  		localAddr := make(net.IP, net.IPv4len)
   627  		copy(localAddr, local.Addr[:])
   628  		if bytes.Equal(localAddr, localIP1) && local.Port == 8080 && local.Probability == 35 {
   629  			expectedCount++
   630  		}
   631  		copy(localAddr, local.Addr[:])
   632  		if bytes.Equal(localAddr, localIP2) && local.Port == 8181 && local.Probability == 65 {
   633  			expectedCount++
   634  		}
   635  	}
   636  	Expect(expectedCount).To(BeEquivalentTo(2))
   637  }
   638  
   639  func TestDelNat44StaticMappingLb(t *testing.T) {
   640  	ctx, natHandler, _, _ := natTestSetup(t)
   641  	defer ctx.TeardownTestCtx()
   642  
   643  	externalIP := net.ParseIP("10.0.0.1").To4()
   644  	localIP1 := net.ParseIP("10.0.0.2").To4()
   645  	localIP2 := net.ParseIP("10.0.0.3").To4()
   646  
   647  	mapping := &nat.DNat44_StaticMapping{
   648  		ExternalIp:        externalIP.String(),
   649  		ExternalPort:      8080,
   650  		ExternalInterface: "if0",
   651  		Protocol:          nat.DNat44_TCP,
   652  		TwiceNat:          nat.DNat44_StaticMapping_ENABLED,
   653  		LocalIps:          localIPs(localIP1, localIP2),
   654  	}
   655  
   656  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelLbStaticMappingReply{})
   657  	err := natHandler.DelNat44StaticMapping(mapping, "DNAT 1")
   658  
   659  	Expect(err).ShouldNot(HaveOccurred())
   660  
   661  	msg, ok := ctx.MockChannel.Msg.(*vpp_nat.Nat44AddDelLbStaticMapping)
   662  	Expect(ok).To(BeTrue())
   663  	Expect(msg.Tag).To(BeEquivalentTo("DNAT 1"))
   664  	Expect(msg.IsAdd).To(BeFalse())
   665  	Expect(addressTo4IP(msg.ExternalAddr)).To(BeEquivalentTo(externalIP.String()))
   666  	Expect(msg.ExternalPort).To(BeEquivalentTo(8080))
   667  	Expect(msg.Protocol).To(BeEquivalentTo(6))
   668  	Expect(msg.Flags).To(BeEquivalentTo(nat_types.NAT_IS_TWICE_NAT + nat_types.NAT_IS_OUT2IN_ONLY))
   669  
   670  	// Local IPs
   671  	Expect(msg.Locals).To(HaveLen(2))
   672  	expectedCount := 0
   673  	for _, local := range msg.Locals {
   674  		localAddr := make(net.IP, net.IPv4len)
   675  		copy(localAddr, local.Addr[:])
   676  		if bytes.Equal(localAddr, localIP1) && local.Port == 8080 && local.Probability == 35 {
   677  			expectedCount++
   678  		}
   679  		copy(localAddr, local.Addr[:])
   680  		if bytes.Equal(localAddr, localIP2) && local.Port == 8181 && local.Probability == 65 {
   681  			expectedCount++
   682  		}
   683  	}
   684  	Expect(expectedCount).To(BeEquivalentTo(2))
   685  }
   686  
   687  func TestAddNat44IdentityMapping(t *testing.T) {
   688  	ctx, natHandler, swIfIndexes, _ := natTestSetup(t)
   689  	defer ctx.TeardownTestCtx()
   690  
   691  	swIfIndexes.Put("if0", &ifaceidx.IfaceMetadata{SwIfIndex: 1})
   692  
   693  	address := net.ParseIP("10.0.0.1").To4()
   694  
   695  	mapping := &nat.DNat44_IdentityMapping{
   696  		VrfId:     1,
   697  		Interface: "if0", // overrides IP address
   698  		IpAddress: address.String(),
   699  		Port:      9000,
   700  		Protocol:  nat.DNat44_UDP,
   701  	}
   702  
   703  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelIdentityMappingReply{})
   704  	err := natHandler.AddNat44IdentityMapping(mapping, "DNAT 1")
   705  
   706  	Expect(err).ShouldNot(HaveOccurred())
   707  
   708  	msg, ok := ctx.MockChannel.Msg.(*vpp_nat.Nat44AddDelIdentityMapping)
   709  	Expect(ok).To(BeTrue())
   710  	Expect(msg.Tag).To(BeEquivalentTo("DNAT 1"))
   711  	Expect(msg.VrfID).To(BeEquivalentTo(1))
   712  	Expect(addressTo4IP(msg.IPAddress)).To(BeEquivalentTo("0.0.0.0"))
   713  	Expect(msg.IsAdd).To(BeTrue())
   714  	Expect(msg.SwIfIndex).To(BeEquivalentTo(1))
   715  	Expect(msg.Protocol).To(BeEquivalentTo(17))
   716  	Expect(msg.Port).To(BeEquivalentTo(9000))
   717  	Expect(msg.Flags).To(BeEquivalentTo(0))
   718  }
   719  
   720  func TestAddNat44IdentityMappingAddrOnly(t *testing.T) {
   721  	ctx, natHandler, swIfIndexes, _ := natTestSetup(t)
   722  	defer ctx.TeardownTestCtx()
   723  
   724  	swIfIndexes.Put("if0", &ifaceidx.IfaceMetadata{SwIfIndex: 1})
   725  
   726  	// IPAddress == nil and Port == 0 means it's address only
   727  	mapping := &nat.DNat44_IdentityMapping{
   728  		VrfId:     1,
   729  		Interface: "if0", // overrides IP address
   730  		Protocol:  nat.DNat44_UDP,
   731  	}
   732  
   733  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelIdentityMappingReply{})
   734  	err := natHandler.AddNat44IdentityMapping(mapping, "DNAT 1")
   735  
   736  	Expect(err).ShouldNot(HaveOccurred())
   737  
   738  	msg, ok := ctx.MockChannel.Msg.(*vpp_nat.Nat44AddDelIdentityMapping)
   739  	Expect(ok).To(BeTrue())
   740  	Expect(msg.Tag).To(BeEquivalentTo("DNAT 1"))
   741  	Expect(addressTo4IP(msg.IPAddress)).To(BeEquivalentTo("0.0.0.0"))
   742  	Expect(msg.IsAdd).To(BeTrue())
   743  	Expect(msg.Protocol).To(BeEquivalentTo(17))
   744  	Expect(msg.SwIfIndex).To(BeEquivalentTo(1))
   745  	Expect(msg.Flags).To(BeEquivalentTo(nat_types.NAT_IS_ADDR_ONLY))
   746  }
   747  
   748  func TestAddNat44IdentityMappingNoInterface(t *testing.T) {
   749  	ctx, natHandler, _, _ := natTestSetup(t)
   750  	defer ctx.TeardownTestCtx()
   751  
   752  	address := net.ParseIP("10.0.0.1").To4()
   753  
   754  	mapping := &nat.DNat44_IdentityMapping{
   755  		VrfId:     1,
   756  		Protocol:  nat.DNat44_UDP,
   757  		IpAddress: address.String(),
   758  		Port:      8989,
   759  	}
   760  
   761  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelIdentityMappingReply{})
   762  	err := natHandler.AddNat44IdentityMapping(mapping, "DNAT 2")
   763  
   764  	Expect(err).ShouldNot(HaveOccurred())
   765  
   766  	msg, ok := ctx.MockChannel.Msg.(*vpp_nat.Nat44AddDelIdentityMapping)
   767  	Expect(ok).To(BeTrue())
   768  	Expect(msg.Tag).To(BeEquivalentTo("DNAT 2"))
   769  	Expect(addressTo4IP(msg.IPAddress)).To(BeEquivalentTo(address.String()))
   770  	Expect(msg.Port).To(BeEquivalentTo(8989))
   771  	Expect(msg.SwIfIndex).To(BeEquivalentTo(vpp2101.NoInterface))
   772  	Expect(msg.Flags).To(BeEquivalentTo(0))
   773  }
   774  
   775  func TestAddNat44IdentityMappingError(t *testing.T) {
   776  	ctx, natHandler, _, _ := natTestSetup(t)
   777  	defer ctx.TeardownTestCtx()
   778  
   779  	// Incorrect reply object
   780  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelStaticMappingV2Reply{})
   781  	err := natHandler.AddNat44IdentityMapping(&nat.DNat44_IdentityMapping{}, "")
   782  
   783  	Expect(err).Should(HaveOccurred())
   784  }
   785  
   786  func TestAddNat44IdentityMappingRetval(t *testing.T) {
   787  	ctx, natHandler, _, _ := natTestSetup(t)
   788  	defer ctx.TeardownTestCtx()
   789  
   790  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelIdentityMappingReply{
   791  		Retval: 1,
   792  	})
   793  	err := natHandler.AddNat44IdentityMapping(&nat.DNat44_IdentityMapping{}, "")
   794  
   795  	Expect(err).Should(HaveOccurred())
   796  }
   797  
   798  func TestDelNat44IdentityMapping(t *testing.T) {
   799  	ctx, natHandler, swIfIndexes, _ := natTestSetup(t)
   800  	defer ctx.TeardownTestCtx()
   801  
   802  	swIfIndexes.Put("if0", &ifaceidx.IfaceMetadata{SwIfIndex: 1})
   803  
   804  	address := net.ParseIP("10.0.0.1").To4()
   805  
   806  	mapping := &nat.DNat44_IdentityMapping{
   807  		Interface: "if0",
   808  		IpAddress: address.String(),
   809  		Protocol:  nat.DNat44_TCP,
   810  		VrfId:     1,
   811  	}
   812  
   813  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelIdentityMappingReply{})
   814  	err := natHandler.DelNat44IdentityMapping(mapping, "DNAT 2")
   815  
   816  	Expect(err).ShouldNot(HaveOccurred())
   817  
   818  	msg, ok := ctx.MockChannel.Msg.(*vpp_nat.Nat44AddDelIdentityMapping)
   819  	Expect(ok).To(BeTrue())
   820  	Expect(msg.Tag).To(BeEquivalentTo("DNAT 2"))
   821  	Expect(msg.VrfID).To(BeEquivalentTo(1))
   822  	Expect(addressTo4IP(msg.IPAddress)).To(BeEquivalentTo("0.0.0.0"))
   823  	Expect(msg.IsAdd).To(BeFalse())
   824  	Expect(msg.SwIfIndex).To(BeEquivalentTo(1))
   825  	Expect(msg.Protocol).To(BeEquivalentTo(6))
   826  	Expect(msg.Flags).To(BeEquivalentTo(nat_types.NAT_IS_ADDR_ONLY))
   827  }
   828  
   829  func TestNat44MappingLongTag(t *testing.T) {
   830  	ctx, natHandler, swIfIndexes, _ := natTestSetup(t)
   831  	defer ctx.TeardownTestCtx()
   832  
   833  	swIfIndexes.Put("if0", &ifaceidx.IfaceMetadata{SwIfIndex: 1})
   834  
   835  	normalTag := "normalTag"
   836  	longTag := "some-weird-tag-which-is-much-longer-than-allowed-sixty-four-bytes"
   837  
   838  	localIP1 := net.ParseIP("10.0.0.1").To4()
   839  	localIP2 := net.ParseIP("20.0.0.1").To4()
   840  	externalIP := net.ParseIP("10.0.0.2").To4()
   841  
   842  	mapping := &nat.DNat44_StaticMapping{
   843  		LocalIps: []*nat.DNat44_StaticMapping_LocalIP{
   844  			{
   845  				LocalIp: localIP1.String(),
   846  			},
   847  		},
   848  		ExternalIp: externalIP.String(),
   849  	}
   850  	lbMapping := &nat.DNat44_StaticMapping{
   851  		LocalIps:     localIPs(localIP1, localIP2),
   852  		ExternalIp:   externalIP.String(),
   853  		ExternalPort: 8080,
   854  		Protocol:     nat.DNat44_TCP,
   855  		TwiceNat:     nat.DNat44_StaticMapping_ENABLED,
   856  	}
   857  	idMapping := &nat.DNat44_IdentityMapping{
   858  		IpAddress: localIP1.String(),
   859  		Protocol:  nat.DNat44_UDP,
   860  		VrfId:     1,
   861  		Interface: "if0",
   862  	}
   863  
   864  	// 1. test
   865  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelStaticMappingV2Reply{})
   866  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelLbStaticMappingReply{})
   867  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelIdentityMappingReply{})
   868  	// 2. test
   869  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelStaticMappingV2Reply{})
   870  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelLbStaticMappingReply{})
   871  	ctx.MockVpp.MockReply(&vpp_nat.Nat44AddDelIdentityMappingReply{})
   872  
   873  	// Successful scenario (to ensure there is no other error)
   874  	err := natHandler.AddNat44StaticMapping(mapping, normalTag)
   875  	Expect(err).To(BeNil())
   876  	err = natHandler.AddNat44StaticMapping(lbMapping, normalTag)
   877  	Expect(err).To(BeNil())
   878  	err = natHandler.AddNat44IdentityMapping(idMapping, normalTag)
   879  	Expect(err).To(BeNil())
   880  
   881  	// Replace tags and test again
   882  	err = natHandler.AddNat44StaticMapping(mapping, longTag)
   883  	Expect(err).ToNot(BeNil())
   884  	err = natHandler.AddNat44StaticMapping(lbMapping, longTag)
   885  	Expect(err).ToNot(BeNil())
   886  	err = natHandler.AddNat44IdentityMapping(idMapping, longTag)
   887  	Expect(err).ToNot(BeNil())
   888  }
   889  
   890  func localIPs(addr1, addr2 net.IP) []*nat.DNat44_StaticMapping_LocalIP {
   891  	return []*nat.DNat44_StaticMapping_LocalIP{
   892  		{
   893  			LocalIp:     addr1.String(),
   894  			LocalPort:   8080,
   895  			Probability: 35,
   896  		},
   897  		{
   898  			LocalIp:     addr2.String(),
   899  			LocalPort:   8181,
   900  			Probability: 65,
   901  		},
   902  	}
   903  }
   904  
   905  func addressTo4IP(address ip_types.IP4Address) string {
   906  	ipAddr := make(net.IP, net.IPv4len)
   907  	copy(ipAddr[:], address[:])
   908  	if ipAddr.To4() == nil {
   909  		return ""
   910  	}
   911  	return ipAddr.To4().String()
   912  }