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 }