go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/ipsecplugin/vppcalls/vpp2210/ipsec_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  	"encoding/hex"
    19  	"fmt"
    20  	"testing"
    21  
    22  	. "github.com/onsi/gomega"
    23  	"go.ligato.io/cn-infra/v2/logging/logrus"
    24  
    25  	"go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2210/ip_types"
    26  	vpp_ipsec "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2210/ipsec"
    27  	"go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2210/ipsec_types"
    28  	"go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2210/tunnel_types"
    29  	"go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/ifaceidx"
    30  	"go.ligato.io/vpp-agent/v3/plugins/vpp/ipsecplugin/vppcalls"
    31  	"go.ligato.io/vpp-agent/v3/plugins/vpp/ipsecplugin/vppcalls/vpp2210"
    32  	"go.ligato.io/vpp-agent/v3/plugins/vpp/vppmock"
    33  	ipsec "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipsec"
    34  )
    35  
    36  func ipToAddr(ip string) ip_types.Address {
    37  	addr, err := vpp2210.IPToAddress(ip)
    38  	if err != nil {
    39  		panic(fmt.Sprintf("invalid IP: %s", ip))
    40  	}
    41  	return addr
    42  }
    43  
    44  func TestVppAddSPD(t *testing.T) {
    45  	ctx, ipSecHandler, _ := ipSecTestSetup(t)
    46  	defer ctx.TeardownTestCtx()
    47  
    48  	ctx.MockVpp.MockReply(&vpp_ipsec.IpsecSpdAddDelReply{})
    49  
    50  	err := ipSecHandler.AddSPD(10)
    51  
    52  	Expect(err).ShouldNot(HaveOccurred())
    53  	Expect(ctx.MockChannel.Msg).To(BeEquivalentTo(&vpp_ipsec.IpsecSpdAddDel{
    54  		IsAdd: true,
    55  		SpdID: 10,
    56  	}))
    57  }
    58  
    59  func TestVppDelSPD(t *testing.T) {
    60  	ctx, ipSecHandler, _ := ipSecTestSetup(t)
    61  	defer ctx.TeardownTestCtx()
    62  
    63  	ctx.MockVpp.MockReply(&vpp_ipsec.IpsecSpdAddDelReply{})
    64  
    65  	err := ipSecHandler.DeleteSPD(10)
    66  
    67  	Expect(err).ShouldNot(HaveOccurred())
    68  	Expect(ctx.MockChannel.Msg).To(BeEquivalentTo(&vpp_ipsec.IpsecSpdAddDel{
    69  		IsAdd: false,
    70  		SpdID: 10,
    71  	}))
    72  }
    73  
    74  func TestVppAddSP(t *testing.T) {
    75  	ctx, ipSecHandler, _ := ipSecTestSetup(t)
    76  	defer ctx.TeardownTestCtx()
    77  
    78  	// FIXME: bug in VPP?
    79  	// ctx.MockVpp.MockReply(&vpp_ipsec.IpsecSpdEntryAddDelV2Reply{})
    80  	ctx.MockVpp.MockReply(&vpp_ipsec.IpsecSpdEntryAddDelReply{})
    81  
    82  	err := ipSecHandler.AddSP(&ipsec.SecurityPolicy{
    83  		SaIndex:    5,
    84  		SpdIndex:   10,
    85  		Priority:   10,
    86  		IsOutbound: true,
    87  	})
    88  
    89  	Expect(err).ShouldNot(HaveOccurred())
    90  	Expect(ctx.MockChannel.Msg).To(BeEquivalentTo(&vpp_ipsec.IpsecSpdEntryAddDelV2{
    91  		IsAdd: true,
    92  		Entry: ipsec_types.IpsecSpdEntryV2{
    93  			SpdID:              10,
    94  			SaID:               5,
    95  			Priority:           10,
    96  			IsOutbound:         true,
    97  			RemoteAddressStart: ipToAddr("0.0.0.0"),
    98  			RemoteAddressStop:  ipToAddr("255.255.255.255"),
    99  			LocalAddressStart:  ipToAddr("0.0.0.0"),
   100  			LocalAddressStop:   ipToAddr("255.255.255.255"),
   101  			RemotePortStop:     65535,
   102  			LocalPortStop:      65535,
   103  		},
   104  	}))
   105  }
   106  
   107  func TestVppDelSP(t *testing.T) {
   108  	ctx, ipSecHandler, _ := ipSecTestSetup(t)
   109  	defer ctx.TeardownTestCtx()
   110  
   111  	// FIXME: bug in VPP?
   112  	// ctx.MockVpp.MockReply(&vpp_ipsec.IpsecSpdEntryAddDelV2Reply{})
   113  	ctx.MockVpp.MockReply(&vpp_ipsec.IpsecSpdEntryAddDelReply{})
   114  
   115  	err := ipSecHandler.DeleteSP(&ipsec.SecurityPolicy{
   116  		SpdIndex:   10,
   117  		SaIndex:    2,
   118  		Priority:   5,
   119  		IsOutbound: true,
   120  	})
   121  
   122  	Expect(err).ShouldNot(HaveOccurred())
   123  	Expect(ctx.MockChannel.Msg).To(BeEquivalentTo(&vpp_ipsec.IpsecSpdEntryAddDelV2{
   124  		IsAdd: false,
   125  		Entry: ipsec_types.IpsecSpdEntryV2{
   126  			SpdID:              10,
   127  			SaID:               2,
   128  			Priority:           5,
   129  			IsOutbound:         true,
   130  			RemoteAddressStart: ipToAddr("0.0.0.0"),
   131  			RemoteAddressStop:  ipToAddr("255.255.255.255"),
   132  			LocalAddressStart:  ipToAddr("0.0.0.0"),
   133  			LocalAddressStop:   ipToAddr("255.255.255.255"),
   134  			RemotePortStop:     65535,
   135  			LocalPortStop:      65535,
   136  		},
   137  	}))
   138  }
   139  
   140  func TestVppInterfaceAddSPD(t *testing.T) {
   141  	ctx, ipSecHandler, ifIndex := ipSecTestSetup(t)
   142  	defer ctx.TeardownTestCtx()
   143  
   144  	ctx.MockVpp.MockReply(&vpp_ipsec.IpsecInterfaceAddDelSpdReply{})
   145  
   146  	ifIndex.Put("if1", &ifaceidx.IfaceMetadata{SwIfIndex: 2})
   147  
   148  	err := ipSecHandler.AddSPDInterface(10, &ipsec.SecurityPolicyDatabase_Interface{
   149  		Name: "if1",
   150  	})
   151  
   152  	Expect(err).ShouldNot(HaveOccurred())
   153  	Expect(ctx.MockChannel.Msg).To(BeEquivalentTo(&vpp_ipsec.IpsecInterfaceAddDelSpd{
   154  		IsAdd:     true,
   155  		SpdID:     10,
   156  		SwIfIndex: 2,
   157  	}))
   158  }
   159  
   160  func TestVppInterfaceDelSPD(t *testing.T) {
   161  	ctx, ipSecHandler, ifIndex := ipSecTestSetup(t)
   162  	defer ctx.TeardownTestCtx()
   163  
   164  	ctx.MockVpp.MockReply(&vpp_ipsec.IpsecInterfaceAddDelSpdReply{})
   165  
   166  	ifIndex.Put("if1", &ifaceidx.IfaceMetadata{SwIfIndex: 2})
   167  
   168  	err := ipSecHandler.DeleteSPDInterface(10, &ipsec.SecurityPolicyDatabase_Interface{
   169  		Name: "if1",
   170  	})
   171  
   172  	Expect(err).ShouldNot(HaveOccurred())
   173  	Expect(ctx.MockChannel.Msg).To(BeEquivalentTo(&vpp_ipsec.IpsecInterfaceAddDelSpd{
   174  		IsAdd:     false,
   175  		SpdID:     10,
   176  		SwIfIndex: 2,
   177  	}))
   178  }
   179  
   180  func ipSecTestSetup(t *testing.T) (*vppmock.TestCtx, vppcalls.IPSecVppAPI, ifaceidx.IfaceMetadataIndexRW) {
   181  	ctx := vppmock.SetupTestCtx(t)
   182  	log := logrus.NewLogger("test-log")
   183  	ifIndex := ifaceidx.NewIfaceIndex(log, "ipsec-test-ifidx")
   184  	ipSecHandler := vpp2210.NewIPSecVppHandler(ctx.MockChannel, ifIndex, log)
   185  	return ctx, ipSecHandler, ifIndex
   186  }
   187  
   188  func TestVppAddSA(t *testing.T) {
   189  	ctx, ipSecHandler, _ := ipSecTestSetup(t)
   190  	defer ctx.TeardownTestCtx()
   191  
   192  	ctx.MockVpp.MockReply(&vpp_ipsec.IpsecSadEntryAddDelV3Reply{})
   193  
   194  	cryptoKey, err := hex.DecodeString("")
   195  	Expect(err).To(BeNil())
   196  
   197  	err = ipSecHandler.AddSA(&ipsec.SecurityAssociation{
   198  		Index:         1,
   199  		Spi:           uint32(1001),
   200  		UseEsn:        true,
   201  		UseAntiReplay: true,
   202  		Protocol:      ipsec.SecurityAssociation_ESP,
   203  	})
   204  
   205  	Expect(err).ShouldNot(HaveOccurred())
   206  	Expect(ctx.MockChannel.Msg).To(BeEquivalentTo(&vpp_ipsec.IpsecSadEntryAddDelV3{
   207  		IsAdd: true,
   208  		Entry: ipsec_types.IpsecSadEntryV3{
   209  			SadID: 1,
   210  			Spi:   1001,
   211  			CryptoKey: ipsec_types.Key{
   212  				Length: uint8(len(cryptoKey)),
   213  				Data:   cryptoKey,
   214  			},
   215  			IntegrityKey: ipsec_types.Key{
   216  				Length: uint8(len(cryptoKey)),
   217  				Data:   cryptoKey,
   218  			},
   219  			Flags:      ipsec_types.IPSEC_API_SAD_FLAG_USE_ESN | ipsec_types.IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY,
   220  			Protocol:   ipsec_types.IPSEC_API_PROTO_ESP,
   221  			UDPSrcPort: ^uint16(0),
   222  			UDPDstPort: ^uint16(0),
   223  		},
   224  	}))
   225  }
   226  
   227  func TestVppDelSA(t *testing.T) {
   228  	ctx, ipSecHandler, _ := ipSecTestSetup(t)
   229  	defer ctx.TeardownTestCtx()
   230  
   231  	ctx.MockVpp.MockReply(&vpp_ipsec.IpsecSadEntryAddDelV3Reply{})
   232  
   233  	cryptoKey, err := hex.DecodeString("")
   234  	Expect(err).To(BeNil())
   235  
   236  	err = ipSecHandler.DeleteSA(&ipsec.SecurityAssociation{
   237  		Index:         1,
   238  		Spi:           uint32(1001),
   239  		UseEsn:        true,
   240  		UseAntiReplay: true,
   241  		Protocol:      ipsec.SecurityAssociation_ESP,
   242  	})
   243  
   244  	Expect(err).ShouldNot(HaveOccurred())
   245  	Expect(ctx.MockChannel.Msg).To(BeEquivalentTo(&vpp_ipsec.IpsecSadEntryAddDelV3{
   246  		IsAdd: false,
   247  		Entry: ipsec_types.IpsecSadEntryV3{
   248  			SadID: 1,
   249  			Spi:   1001,
   250  			CryptoKey: ipsec_types.Key{
   251  				Length: uint8(len(cryptoKey)),
   252  				Data:   cryptoKey,
   253  			},
   254  			IntegrityKey: ipsec_types.Key{
   255  				Length: uint8(len(cryptoKey)),
   256  				Data:   cryptoKey,
   257  			},
   258  			Flags:      ipsec_types.IPSEC_API_SAD_FLAG_USE_ESN | ipsec_types.IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY,
   259  			Protocol:   ipsec_types.IPSEC_API_PROTO_ESP,
   260  			UDPSrcPort: ^uint16(0),
   261  			UDPDstPort: ^uint16(0),
   262  		},
   263  	}))
   264  }
   265  
   266  func TestVppAddSATunnelMode(t *testing.T) {
   267  	ctx, ipSecHandler, _ := ipSecTestSetup(t)
   268  	defer ctx.TeardownTestCtx()
   269  
   270  	ctx.MockVpp.MockReply(&vpp_ipsec.IpsecSadEntryAddDelV3Reply{})
   271  
   272  	cryptoKey, err := hex.DecodeString("")
   273  	Expect(err).To(BeNil())
   274  
   275  	err = ipSecHandler.AddSA(&ipsec.SecurityAssociation{
   276  		Index:         1,
   277  		Spi:           uint32(1001),
   278  		TunnelSrcAddr: "10.1.0.1",
   279  		TunnelDstAddr: "20.1.0.1",
   280  		Protocol:      ipsec.SecurityAssociation_ESP,
   281  	})
   282  
   283  	Expect(err).ShouldNot(HaveOccurred())
   284  	Expect(ctx.MockChannel.Msg).To(BeEquivalentTo(&vpp_ipsec.IpsecSadEntryAddDelV3{
   285  		IsAdd: true,
   286  		Entry: ipsec_types.IpsecSadEntryV3{
   287  			SadID: 1,
   288  			Spi:   1001,
   289  			CryptoKey: ipsec_types.Key{
   290  				Length: uint8(len(cryptoKey)),
   291  				Data:   cryptoKey,
   292  			},
   293  			IntegrityKey: ipsec_types.Key{
   294  				Length: uint8(len(cryptoKey)),
   295  				Data:   cryptoKey,
   296  			},
   297  			Tunnel: tunnel_types.Tunnel{
   298  				Src: ip_types.Address{
   299  					Af: ip_types.ADDRESS_IP4,
   300  					Un: ip_types.AddressUnionIP4(ip_types.IP4Address{10, 1, 0, 1}),
   301  				},
   302  				Dst: ip_types.Address{
   303  					Af: ip_types.ADDRESS_IP4,
   304  					Un: ip_types.AddressUnionIP4(ip_types.IP4Address{20, 1, 0, 1}),
   305  				},
   306  			},
   307  			Flags:      ipsec_types.IPSEC_API_SAD_FLAG_IS_TUNNEL,
   308  			Protocol:   ipsec_types.IPSEC_API_PROTO_ESP,
   309  			UDPSrcPort: ^uint16(0),
   310  			UDPDstPort: ^uint16(0),
   311  		},
   312  	}))
   313  }
   314  
   315  func TestVppAddSATunnelModeIPv6(t *testing.T) {
   316  	ctx, ipSecHandler, _ := ipSecTestSetup(t)
   317  	defer ctx.TeardownTestCtx()
   318  
   319  	ctx.MockVpp.MockReply(&vpp_ipsec.IpsecSadEntryAddDelV3Reply{})
   320  
   321  	cryptoKey, err := hex.DecodeString("")
   322  	Expect(err).To(BeNil())
   323  
   324  	err = ipSecHandler.AddSA(&ipsec.SecurityAssociation{
   325  		Index:         1,
   326  		Spi:           uint32(1001),
   327  		TunnelSrcAddr: "1234::",
   328  		TunnelDstAddr: "abcd::",
   329  		Protocol:      ipsec.SecurityAssociation_ESP,
   330  	})
   331  
   332  	Expect(err).ShouldNot(HaveOccurred())
   333  	Expect(ctx.MockChannel.Msg).To(BeEquivalentTo(&vpp_ipsec.IpsecSadEntryAddDelV3{
   334  		IsAdd: true,
   335  		Entry: ipsec_types.IpsecSadEntryV3{
   336  			SadID: 1,
   337  			Spi:   1001,
   338  			CryptoKey: ipsec_types.Key{
   339  				Length: uint8(len(cryptoKey)),
   340  				Data:   cryptoKey,
   341  			},
   342  			IntegrityKey: ipsec_types.Key{
   343  				Length: uint8(len(cryptoKey)),
   344  				Data:   cryptoKey,
   345  			},
   346  			Tunnel: tunnel_types.Tunnel{
   347  				Src: ip_types.Address{
   348  					Af: ip_types.ADDRESS_IP6,
   349  					Un: ip_types.AddressUnion{XXX_UnionData: [16]byte{18, 52}},
   350  				},
   351  				Dst: ip_types.Address{
   352  					Af: ip_types.ADDRESS_IP6,
   353  					Un: ip_types.AddressUnion{XXX_UnionData: [16]byte{171, 205}},
   354  				},
   355  			},
   356  			Flags:      ipsec_types.IPSEC_API_SAD_FLAG_IS_TUNNEL | ipsec_types.IPSEC_API_SAD_FLAG_IS_TUNNEL_V6,
   357  			Protocol:   ipsec_types.IPSEC_API_PROTO_ESP,
   358  			UDPSrcPort: ^uint16(0),
   359  			UDPDstPort: ^uint16(0),
   360  		},
   361  	}))
   362  }
   363  
   364  func TestVppAddTunnelProtection(t *testing.T) {
   365  	ctx, ipSecHandler, ifIndex := ipSecTestSetup(t)
   366  	defer ctx.TeardownTestCtx()
   367  
   368  	ifIndex.Put("ipip-tunnel", &ifaceidx.IfaceMetadata{SwIfIndex: 5})
   369  
   370  	ctx.MockVpp.MockReply(&vpp_ipsec.IpsecTunnelProtectUpdateReply{})
   371  	err := ipSecHandler.AddTunnelProtection(&ipsec.TunnelProtection{
   372  		Interface: "ipip-tunnel",
   373  		SaOut:     []uint32{10},
   374  		SaIn:      []uint32{20, 30},
   375  	})
   376  
   377  	Expect(err).ShouldNot(HaveOccurred())
   378  	Expect(ctx.MockChannel.Msg).To(BeEquivalentTo(&vpp_ipsec.IpsecTunnelProtectUpdate{
   379  		Tunnel: vpp_ipsec.IpsecTunnelProtect{
   380  			SwIfIndex: 5,
   381  			SaOut:     10,
   382  			NSaIn:     2,
   383  			SaIn:      []uint32{20, 30},
   384  		},
   385  	}))
   386  }
   387  
   388  func TestVppDelTunnelProtection(t *testing.T) {
   389  	ctx, ipSecHandler, ifIndex := ipSecTestSetup(t)
   390  	defer ctx.TeardownTestCtx()
   391  
   392  	ifIndex.Put("ipip-tunnel", &ifaceidx.IfaceMetadata{SwIfIndex: 5})
   393  
   394  	ctx.MockVpp.MockReply(&vpp_ipsec.IpsecTunnelProtectDelReply{})
   395  
   396  	err := ipSecHandler.DeleteTunnelProtection(&ipsec.TunnelProtection{
   397  		Interface: "ipip-tunnel",
   398  	})
   399  
   400  	Expect(err).ShouldNot(HaveOccurred())
   401  	Expect(ctx.MockChannel.Msg).To(BeEquivalentTo(&vpp_ipsec.IpsecTunnelProtectDel{
   402  		SwIfIndex: 5,
   403  	}))
   404  }