go.ligato.io/vpp-agent/v3@v3.5.0/tests/integration/vpp/130_ipsec_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 vpp 16 17 import ( 18 "fmt" 19 "testing" 20 21 "go.ligato.io/cn-infra/v2/logging/logrus" 22 "google.golang.org/protobuf/proto" 23 24 "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/ifaceidx" 25 ifplugin_vppcalls "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/vppcalls" 26 ipsec_vppcalls "go.ligato.io/vpp-agent/v3/plugins/vpp/ipsecplugin/vppcalls" 27 interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces" 28 ipsec "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipsec" 29 30 _ "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin" 31 _ "go.ligato.io/vpp-agent/v3/plugins/vpp/ipsecplugin" 32 ) 33 34 func TestIPSec(t *testing.T) { 35 ctx := setupVPP(t) 36 defer ctx.teardownVPP() 37 38 spdIfaceDumpOk := false // determines if ipsec_spd_interface_dump works correctly 39 40 ifIndexes := ifaceidx.NewIfaceIndex(logrus.NewLogger("test"), "test-ifidx") 41 ifHandler := ifplugin_vppcalls.CompatibleInterfaceVppHandler(ctx.vppClient, logrus.NewLogger("test-if")) 42 ipsecHandler := ipsec_vppcalls.CompatibleIPSecVppHandler(ctx.vppClient, ifIndexes, logrus.NewLogger("test-ipsec")) 43 44 tests := []struct { 45 name string 46 ipip *interfaces.IPIPLink 47 saOut *ipsec.SecurityAssociation 48 saIn *ipsec.SecurityAssociation 49 spd *ipsec.SecurityPolicyDatabase 50 spOut *ipsec.SecurityPolicy 51 spIn *ipsec.SecurityPolicy 52 tp *ipsec.TunnelProtection 53 }{ 54 { 55 name: "Create IPSec tunnel (IPv4)", 56 ipip: &interfaces.IPIPLink{ 57 SrcAddr: "20.30.40.50", 58 DstAddr: "50.40.30.20", 59 }, 60 saOut: &ipsec.SecurityAssociation{ 61 Index: 10, 62 Spi: 123, 63 Protocol: ipsec.SecurityAssociation_ESP, 64 CryptoAlg: ipsec.CryptoAlg_AES_CBC_128, 65 CryptoKey: "d9a4ec50aed76f1bf80bc915d8fcfe1c", 66 IntegAlg: ipsec.IntegAlg_SHA1_96, 67 IntegKey: "bf9b150aaf5c2a87d79898b11eabd055e70abdbe", 68 EnableUdpEncap: true, 69 }, 70 saIn: &ipsec.SecurityAssociation{ 71 Index: 20, 72 Spi: 456, 73 Protocol: ipsec.SecurityAssociation_ESP, 74 CryptoAlg: ipsec.CryptoAlg_AES_CBC_128, 75 CryptoKey: "d9a4ec50aed76f1bf80bc915d8fcfe1c", 76 IntegAlg: ipsec.IntegAlg_SHA1_96, 77 IntegKey: "bf9b150aaf5c2a87d79898b11eabd055e70abdbe", 78 EnableUdpEncap: true, 79 }, 80 spd: &ipsec.SecurityPolicyDatabase{ 81 Index: 100, 82 }, 83 spOut: &ipsec.SecurityPolicy{ 84 SpdIndex: 100, 85 SaIndex: 10, 86 Priority: 0, 87 IsOutbound: true, 88 RemoteAddrStart: "10.10.1.1", 89 RemoteAddrStop: "10.10.1.255", 90 LocalAddrStart: "10.10.2.1", 91 LocalAddrStop: "10.10.2.255", 92 Protocol: 0, 93 Action: ipsec.SecurityPolicy_PROTECT, 94 }, 95 spIn: &ipsec.SecurityPolicy{ 96 SpdIndex: 100, 97 SaIndex: 20, 98 Priority: 0, 99 IsOutbound: false, 100 RemoteAddrStart: "10.10.1.1", 101 RemoteAddrStop: "10.10.1.255", 102 LocalAddrStart: "10.10.2.1", 103 LocalAddrStop: "10.10.2.255", 104 Protocol: 0, 105 RemotePortStart: 1000, 106 RemotePortStop: 5000, 107 LocalPortStart: 2000, 108 LocalPortStop: 7000, 109 Action: ipsec.SecurityPolicy_PROTECT, 110 }, 111 tp: &ipsec.TunnelProtection{ 112 SaOut: []uint32{10}, 113 SaIn: []uint32{20}, 114 }, 115 }, 116 { 117 name: "Create IPSec tunnel (IPv6)", 118 ipip: &interfaces.IPIPLink{ 119 SrcAddr: "2001:db8:0:1:1:1:1:1", 120 DstAddr: "2002:db8:0:1:1:1:1:1", 121 }, 122 saOut: &ipsec.SecurityAssociation{ 123 Index: 1, 124 Spi: 789, 125 Protocol: ipsec.SecurityAssociation_ESP, 126 CryptoAlg: ipsec.CryptoAlg_AES_CBC_128, 127 CryptoKey: "d9a4ec50aed76f1bf80bc915d8fcfe1c", 128 IntegAlg: ipsec.IntegAlg_SHA1_96, 129 IntegKey: "bf9b150aaf5c2a87d79898b11eabd055e70abdbe", 130 }, 131 saIn: &ipsec.SecurityAssociation{ 132 Index: 2, 133 Spi: 321, 134 Protocol: ipsec.SecurityAssociation_ESP, 135 CryptoAlg: ipsec.CryptoAlg_AES_CBC_128, 136 CryptoKey: "d9a4ec50aed76f1bf80bc915d8fcfe1c", 137 IntegAlg: ipsec.IntegAlg_SHA1_96, 138 IntegKey: "bf9b150aaf5c2a87d79898b11eabd055e70abdbe", 139 }, 140 tp: &ipsec.TunnelProtection{ 141 SaOut: []uint32{1}, 142 SaIn: []uint32{2}, 143 }, 144 spd: &ipsec.SecurityPolicyDatabase{ 145 Index: 101, 146 }, 147 spOut: &ipsec.SecurityPolicy{ 148 SpdIndex: 101, 149 SaIndex: 1, 150 Priority: 0, 151 IsOutbound: true, 152 RemoteAddrStart: "2001:1000::1", 153 RemoteAddrStop: "2001:1000::1000", 154 LocalAddrStart: "2001:2000::1", 155 LocalAddrStop: "2001:2000::1000", 156 Protocol: 0, 157 Action: ipsec.SecurityPolicy_PROTECT, 158 }, 159 spIn: &ipsec.SecurityPolicy{ 160 SpdIndex: 101, 161 SaIndex: 2, 162 Priority: 0, 163 IsOutbound: false, 164 RemoteAddrStart: "2001:1000::1", 165 RemoteAddrStop: "2001:1000::1000", 166 LocalAddrStart: "2001:2000::1", 167 LocalAddrStop: "2001:2000::1000", 168 Protocol: 0, 169 RemotePortStart: 1000, 170 RemotePortStop: 5000, 171 LocalPortStart: 2000, 172 LocalPortStop: 7000, 173 Action: ipsec.SecurityPolicy_PROTECT, 174 }, 175 }, 176 { 177 name: "Create multipoint IPSec tunnel", 178 ipip: &interfaces.IPIPLink{ 179 SrcAddr: "20.30.40.50", 180 TunnelMode: interfaces.IPIPLink_POINT_TO_MULTIPOINT, 181 }, 182 saOut: &ipsec.SecurityAssociation{ 183 Index: 100, 184 Spi: 123, 185 Protocol: ipsec.SecurityAssociation_ESP, 186 CryptoAlg: ipsec.CryptoAlg_AES_CBC_128, 187 CryptoKey: "d9a4ec50aed76f1bf80bc915d8fcfe1c", 188 IntegAlg: ipsec.IntegAlg_SHA1_96, 189 IntegKey: "bf9b150aaf5c2a87d79898b11eabd055e70abdbe", 190 EnableUdpEncap: true, 191 }, 192 saIn: &ipsec.SecurityAssociation{ 193 Index: 101, 194 Spi: 456, 195 Protocol: ipsec.SecurityAssociation_ESP, 196 CryptoAlg: ipsec.CryptoAlg_AES_CBC_128, 197 CryptoKey: "d9a4ec50aed76f1bf80bc915d8fcfe1c", 198 IntegAlg: ipsec.IntegAlg_SHA1_96, 199 IntegKey: "bf9b150aaf5c2a87d79898b11eabd055e70abdbe", 200 EnableUdpEncap: true, 201 }, 202 spd: &ipsec.SecurityPolicyDatabase{ 203 Index: 102, 204 }, 205 spOut: &ipsec.SecurityPolicy{ 206 SpdIndex: 102, 207 SaIndex: 100, 208 Priority: 0, 209 IsOutbound: true, 210 RemoteAddrStart: "10.10.1.1", 211 RemoteAddrStop: "10.10.1.255", 212 LocalAddrStart: "10.10.2.1", 213 LocalAddrStop: "10.10.2.255", 214 Protocol: 0, 215 Action: ipsec.SecurityPolicy_PROTECT, 216 }, 217 spIn: &ipsec.SecurityPolicy{ 218 SpdIndex: 102, 219 SaIndex: 101, 220 Priority: 0, 221 IsOutbound: false, 222 RemoteAddrStart: "10.10.1.1", 223 RemoteAddrStop: "10.10.1.255", 224 LocalAddrStart: "10.10.2.1", 225 LocalAddrStop: "10.10.2.255", 226 Protocol: 0, 227 RemotePortStart: 1000, 228 RemotePortStop: 5000, 229 LocalPortStart: 2000, 230 LocalPortStop: 7000, 231 Action: ipsec.SecurityPolicy_PROTECT, 232 }, 233 tp: &ipsec.TunnelProtection{ 234 SaOut: []uint32{100}, 235 SaIn: []uint32{101}, 236 NextHopAddr: "4.5.6.7", 237 }, 238 }, 239 } 240 for i, test := range tests { 241 t.Run(test.name, func(t *testing.T) { 242 // create IPIP tunnel + SAs + tunnel protection + SPs 243 ifName := fmt.Sprintf("ipip%d", i) 244 ifIdx, err := ifHandler.AddIpipTunnel(ifName, 0, test.ipip) 245 if err != nil { 246 t.Fatalf("IPIP tunnel add failed: %v", err) 247 } 248 ifIndexes.Clear() 249 ifIndexes.Put(ifName, &ifaceidx.IfaceMetadata{ 250 SwIfIndex: ifIdx, 251 }) 252 err = ipsecHandler.AddSA(test.saOut) 253 if err != nil { 254 t.Fatalf("IPSec SA add failed: %v", err) 255 } 256 err = ipsecHandler.AddSA(test.saIn) 257 if err != nil { 258 t.Fatalf("IPSec SA add failed: %v", err) 259 } 260 test.tp.Interface = ifName 261 err = ipsecHandler.AddTunnelProtection(test.tp) 262 if err != nil { 263 t.Fatalf("add tunnel protection failed: %v\n", err) 264 } 265 err = ipsecHandler.AddSPD(test.spd.Index) 266 if err != nil { 267 t.Fatalf("add SPD failed: %v\n", err) 268 } 269 err = ipsecHandler.AddSPDInterface(test.spd.Index, &ipsec.SecurityPolicyDatabase_Interface{Name: ifName}) 270 if err != nil { 271 t.Fatalf("add SPD-Interface failed: %v\n", err) 272 } 273 err = ipsecHandler.AddSP(test.spOut) 274 if err != nil { 275 t.Fatalf("add SP failed: %v\n", err) 276 } 277 err = ipsecHandler.AddSP(test.spIn) 278 if err != nil { 279 t.Fatalf("add SP failed: %v\n", err) 280 } 281 282 // check created SAs + tunnel protection + SPs 283 saList, err := ipsecHandler.DumpIPSecSA() 284 if err != nil { 285 t.Fatalf("dumping SAs failed: %v", err) 286 } 287 if len(saList) != 2 { 288 t.Fatalf("Invalid number of SAs: %d", len(saList)) 289 } 290 for _, sa := range saList { 291 if sa.Sa.Index != test.saOut.Index && sa.Sa.Index != test.saIn.Index { 292 t.Fatalf("Invalid SA index: %d", sa.Sa.Index) 293 } 294 } 295 tpList, err := ipsecHandler.DumpTunnelProtections() 296 if err != nil { 297 t.Fatalf("dumping tunnel protections failed: %v", err) 298 } 299 if len(tpList) != 1 { 300 t.Fatalf("Invalid number of tunnel protections: %d", len(tpList)) 301 } 302 if tpList[0].Interface != ifName { 303 t.Fatalf("Invalid interface name in tunnel protections: %s", tpList[0].Interface) 304 } 305 if tpList[0].SaIn[0] != test.saIn.Index || tpList[0].SaOut[0] != test.saOut.Index { 306 t.Fatalf("tunnel protection SA mismatch (%d != %d || %d != %d)", 307 tpList[0].SaIn[0], test.saIn.Index, tpList[0].SaOut[0], test.saOut.Index) 308 } 309 if tpList[0].NextHopAddr != test.tp.NextHopAddr { 310 t.Fatalf("tunnel protection next hop mismatch (%v != %v)", tpList[0].NextHopAddr, test.tp.NextHopAddr) 311 } 312 spdList, err := ipsecHandler.DumpIPSecSPD() 313 if err != nil { 314 t.Fatalf("dumping of SPDs failed: %v", err) 315 } 316 if len(spdList) != 1 { 317 t.Fatalf("Invalid number of SPDs: %d", len(spdList)) 318 } 319 if spdList[0].Index != test.spd.Index { 320 t.Fatalf("Invalid SPD index: %d", spdList[0].Index) 321 } 322 if spdIfaceDumpOk { 323 if len(spdList[0].Interfaces) != 1 { 324 t.Fatalf("Invalid number of interfaces inside SPDs: %d", len(spdList[0].Interfaces)) 325 } 326 if spdList[0].Interfaces[0].Name != ifName { 327 t.Fatalf("Invalid interface name in tunnel protections: %s", spdList[0].Interfaces[0].Name) 328 } 329 } 330 spList, err := ipsecHandler.DumpIPSecSP() 331 if err != nil { 332 t.Fatalf("dumping of SPs failed: %v", err) 333 } 334 if len(spList) != 2 { 335 t.Fatalf("Invalid number of SPs: %d", len(spList)) 336 } 337 for _, sp := range spList { 338 if !proto.Equal(sp, test.spOut) && !proto.Equal(sp, test.spIn) { 339 t.Fatalf("Invalid SP: %+v", sp) 340 } 341 } 342 343 // delete SPs, tunnel protection, SAs and IPIP tunnel 344 err = ipsecHandler.DeleteSP(test.spIn) 345 if err != nil { 346 t.Fatalf("delete of security policy failed: %v\n", err) 347 } 348 err = ipsecHandler.DeleteSP(test.spOut) 349 if err != nil { 350 t.Fatalf("delete of security policy failed: %v\n", err) 351 } 352 spList, err = ipsecHandler.DumpIPSecSP() 353 if err != nil { 354 t.Fatalf("dumping of security policies failed: %v", err) 355 } 356 if len(spList) != 0 { 357 t.Fatalf("%d SPs found in dump after removing", len(spList)) 358 } 359 err = ipsecHandler.DeleteSPDInterface(test.spd.Index, &ipsec.SecurityPolicyDatabase_Interface{Name: ifName}) 360 if err != nil { 361 t.Fatalf("delete of SPD failed: %v\n", err) 362 } 363 err = ipsecHandler.DeleteSPD(test.spd.Index) 364 if err != nil { 365 t.Fatalf("delete of SPD failed: %v\n", err) 366 } 367 spdList, err = ipsecHandler.DumpIPSecSPD() 368 if err != nil { 369 t.Fatalf("dumping of SPDs failed: %v", err) 370 } 371 if len(spdList) != 0 { 372 t.Fatalf("%d SPDs found in dump after removing", len(spdList)) 373 } 374 err = ipsecHandler.DeleteTunnelProtection(test.tp) 375 if err != nil { 376 t.Fatalf("delete tunnel protection failed: %v\n", err) 377 } 378 tpList, err = ipsecHandler.DumpTunnelProtections() 379 if err != nil { 380 t.Fatalf("dumping tunnel protections failed: %v", err) 381 } 382 if len(tpList) != 0 { 383 t.Fatalf("%d tunnel protections found in dump after removing", len(tpList)) 384 } 385 err = ipsecHandler.DeleteSA(test.saOut) 386 if err != nil { 387 t.Fatalf("delete SA failed: %v\n", err) 388 } 389 err = ipsecHandler.DeleteSA(test.saIn) 390 if err != nil { 391 t.Fatalf("delete SA failed: %v\n", err) 392 } 393 saList, err = ipsecHandler.DumpIPSecSA() 394 if err != nil { 395 t.Fatalf("dumping SAs failed: %v", err) 396 } 397 if len(saList) != 0 { 398 t.Fatalf("%d SAs found in dump after removing", len(saList)) 399 } 400 err = ifHandler.DelIpipTunnel(ifName, ifIdx) 401 if err != nil { 402 t.Fatalf("delete IPIP tunnel failed: %v\n", err) 403 } 404 ifaces, err := ifHandler.DumpInterfaces(ctx.Ctx) 405 if err != nil { 406 t.Fatalf("dumping interfaces failed: %v", err) 407 } 408 if _, ok := ifaces[ifIdx]; ok { 409 t.Fatalf("IPIP interface was found in dump after removing") 410 } 411 }) 412 } 413 }