github.com/vishvananda/netlink@v1.3.1/xfrm_state_linux_test.go (about) 1 package netlink 2 3 import ( 4 "bytes" 5 "encoding/hex" 6 "net" 7 "testing" 8 "time" 9 ) 10 11 func TestXfrmStateAddGetDel(t *testing.T) { 12 for _, s := range []*XfrmState{ 13 getBaseState(), 14 getAeadState(), 15 getBaseStateV6oV4(), 16 getBaseStateV4oV6(), 17 } { 18 testXfrmStateAddGetDel(t, s) 19 } 20 } 21 22 func testXfrmStateAddGetDel(t *testing.T, state *XfrmState) { 23 tearDown := setUpNetlinkTest(t) 24 defer tearDown() 25 if err := XfrmStateAdd(state); err != nil { 26 t.Fatal(err) 27 } 28 states, err := XfrmStateList(FAMILY_ALL) 29 if err != nil { 30 t.Fatal(err) 31 } 32 if len(states) != 1 { 33 t.Fatal("State not added properly") 34 } 35 36 if !compareStates(state, &states[0]) { 37 t.Fatalf("unexpected states returned") 38 } 39 40 // Get specific state 41 sa, err := XfrmStateGet(state) 42 if err != nil { 43 t.Fatal(err) 44 } 45 46 if !compareStates(state, sa) { 47 t.Fatalf("unexpected state returned") 48 } 49 50 if err = XfrmStateDel(state); err != nil { 51 t.Fatal(err) 52 } 53 54 states, err = XfrmStateList(FAMILY_ALL) 55 if err != nil { 56 t.Fatal(err) 57 } 58 if len(states) != 0 { 59 t.Fatal("State not removed properly") 60 } 61 62 if _, err := XfrmStateGet(state); err == nil { 63 t.Fatalf("Unexpected success") 64 } 65 } 66 67 func TestXfrmStateAllocSpi(t *testing.T) { 68 defer setUpNetlinkTest(t)() 69 70 state := getBaseState() 71 state.Spi = 0 72 state.Auth = nil 73 state.Crypt = nil 74 rstate, err := XfrmStateAllocSpi(state) 75 if err != nil { 76 t.Fatal(err) 77 } 78 if rstate.Spi == 0 { 79 t.Fatalf("SPI is not allocated") 80 } 81 rstate.Spi = 0 82 83 if !compareStates(state, rstate) { 84 t.Fatalf("State not properly allocated") 85 } 86 } 87 88 func TestXfrmStateFlush(t *testing.T) { 89 defer setUpNetlinkTest(t)() 90 91 state1 := getBaseState() 92 state2 := getBaseState() 93 state2.Src = net.ParseIP("127.1.0.1") 94 state2.Dst = net.ParseIP("127.1.0.2") 95 state2.Proto = XFRM_PROTO_AH 96 state2.Mode = XFRM_MODE_TUNNEL 97 state2.Spi = 20 98 state2.Mark = nil 99 state2.Crypt = nil 100 101 if err := XfrmStateAdd(state1); err != nil { 102 t.Fatal(err) 103 } 104 if err := XfrmStateAdd(state2); err != nil { 105 t.Fatal(err) 106 } 107 108 // flushing proto for which no state is present should return silently 109 if err := XfrmStateFlush(XFRM_PROTO_COMP); err != nil { 110 t.Fatal(err) 111 } 112 113 if err := XfrmStateFlush(XFRM_PROTO_AH); err != nil { 114 t.Fatal(err) 115 } 116 117 if _, err := XfrmStateGet(state2); err == nil { 118 t.Fatalf("Unexpected success") 119 } 120 121 if err := XfrmStateAdd(state2); err != nil { 122 t.Fatal(err) 123 } 124 125 if err := XfrmStateFlush(0); err != nil { 126 t.Fatal(err) 127 } 128 129 states, err := XfrmStateList(FAMILY_ALL) 130 if err != nil { 131 t.Fatal(err) 132 } 133 if len(states) != 0 { 134 t.Fatal("State not flushed properly") 135 } 136 137 } 138 139 func TestXfrmStateUpdateLimits(t *testing.T) { 140 defer setUpNetlinkTest(t)() 141 142 // Program state with limits 143 state := getBaseState() 144 state.Limits.TimeHard = 3600 145 state.Limits.TimeSoft = 60 146 state.Limits.PacketHard = 1000 147 state.Limits.PacketSoft = 50 148 state.Limits.ByteHard = 1000000 149 state.Limits.ByteSoft = 50000 150 state.Limits.TimeUseHard = 3000 151 state.Limits.TimeUseSoft = 1500 152 if err := XfrmStateAdd(state); err != nil { 153 t.Fatal(err) 154 } 155 // Verify limits 156 s, err := XfrmStateGet(state) 157 if err != nil { 158 t.Fatal(err) 159 } 160 if !compareLimits(state, s) { 161 t.Fatalf("Incorrect time hard/soft retrieved: %s", s.Print(true)) 162 } 163 164 // Update limits 165 state.Limits.TimeHard = 1800 166 state.Limits.TimeSoft = 30 167 state.Limits.PacketHard = 500 168 state.Limits.PacketSoft = 25 169 state.Limits.ByteHard = 500000 170 state.Limits.ByteSoft = 25000 171 state.Limits.TimeUseHard = 2000 172 state.Limits.TimeUseSoft = 1000 173 if err := XfrmStateUpdate(state); err != nil { 174 t.Fatal(err) 175 } 176 177 // Verify new limits 178 s, err = XfrmStateGet(state) 179 if err != nil { 180 t.Fatal(err) 181 } 182 if s.Limits.TimeHard != 1800 || s.Limits.TimeSoft != 30 { 183 t.Fatalf("Incorrect time hard retrieved: (%d, %d)", s.Limits.TimeHard, s.Limits.TimeSoft) 184 } 185 } 186 187 func TestXfrmStateStats(t *testing.T) { 188 defer setUpNetlinkTest(t)() 189 190 // Program state and record time 191 state := getBaseState() 192 now := time.Now() 193 if err := XfrmStateAdd(state); err != nil { 194 t.Fatal(err) 195 } 196 // Retrieve state 197 s, err := XfrmStateGet(state) 198 if err != nil { 199 t.Fatal(err) 200 } 201 // Verify stats: We expect zero counters, same second add time and unset use time 202 if s.Statistics.Bytes != 0 || s.Statistics.Packets != 0 || s.Statistics.AddTime != uint64(now.Unix()) || s.Statistics.UseTime != 0 { 203 t.Fatalf("Unexpected statistics (addTime: %s) for state:\n%s", now.Format(time.UnixDate), s.Print(true)) 204 } 205 } 206 207 func TestXfrmStateWithIfid(t *testing.T) { 208 minKernelRequired(t, 4, 19) 209 defer setUpNetlinkTest(t)() 210 211 state := getBaseState() 212 state.Ifid = 54321 213 if err := XfrmStateAdd(state); err != nil { 214 t.Fatal(err) 215 } 216 s, err := XfrmStateGet(state) 217 if err != nil { 218 t.Fatal(err) 219 } 220 if !compareStates(state, s) { 221 t.Fatalf("unexpected state returned.\nExpected: %v.\nGot %v", state, s) 222 } 223 if err = XfrmStateDel(s); err != nil { 224 t.Fatal(err) 225 } 226 } 227 228 func TestXfrmStateWithSADir(t *testing.T) { 229 minKernelRequired(t, 4, 19) 230 defer setUpNetlinkTest(t)() 231 232 state := getBaseState() 233 state.SADir = XFRM_SA_DIR_IN 234 if err := XfrmStateAdd(state); err != nil { 235 t.Fatal(err) 236 } 237 s, err := XfrmStateGet(state) 238 if err != nil { 239 t.Fatal(err) 240 } 241 if !compareStates(state, s) { 242 t.Fatalf("unexpected state returned.\nExpected: %v.\nGot %v", state, s) 243 } 244 if err = XfrmStateDel(s); err != nil { 245 t.Fatal(err) 246 } 247 } 248 249 func TestXfrmStateWithPcpunumWithoutSADir(t *testing.T) { 250 minKernelRequired(t, 4, 19) 251 defer setUpNetlinkTest(t)() 252 253 state := getBaseState() 254 pcpuNum := uint32(1) 255 state.Pcpunum = &pcpuNum 256 if err := XfrmStateAdd(state); err != nil { 257 t.Fatal(err) 258 } 259 s, err := XfrmStateGet(state) 260 if err != nil { 261 t.Fatal(err) 262 } 263 if !compareStates(state, s) { 264 t.Fatalf("unexpected state returned.\nExpected: %v.\nGot %v", state, s) 265 } 266 if err = XfrmStateDel(s); err != nil { 267 t.Fatal(err) 268 } 269 } 270 271 func TestXfrmStateWithPcpunumWithSADir(t *testing.T) { 272 minKernelRequired(t, 4, 19) 273 defer setUpNetlinkTest(t)() 274 275 state := getBaseState() 276 state.SADir = XFRM_SA_DIR_IN 277 pcpuNum := uint32(1) 278 state.Pcpunum = &pcpuNum 279 if err := XfrmStateAdd(state); err != nil { 280 t.Fatal(err) 281 } 282 s, err := XfrmStateGet(state) 283 if err != nil { 284 t.Fatal(err) 285 } 286 if !compareStates(state, s) { 287 t.Fatalf("unexpected state returned.\nExpected: %v.\nGot %v", state, s) 288 } 289 if err = XfrmStateDel(s); err != nil { 290 t.Fatal(err) 291 } 292 } 293 294 func TestXfrmStateWithOutputMark(t *testing.T) { 295 minKernelRequired(t, 4, 14) 296 defer setUpNetlinkTest(t)() 297 298 state := getBaseState() 299 state.OutputMark = &XfrmMark{ 300 Value: 0x0000000a, 301 } 302 if err := XfrmStateAdd(state); err != nil { 303 t.Fatal(err) 304 } 305 s, err := XfrmStateGet(state) 306 if err != nil { 307 t.Fatal(err) 308 } 309 if !compareStates(state, s) { 310 t.Fatalf("unexpected state returned.\nExpected: %v.\nGot %v", state, s) 311 } 312 if err = XfrmStateDel(s); err != nil { 313 t.Fatal(err) 314 } 315 } 316 317 func TestXfrmStateWithOutputMarkAndMask(t *testing.T) { 318 minKernelRequired(t, 4, 19) 319 defer setUpNetlinkTest(t)() 320 321 state := getBaseState() 322 state.OutputMark = &XfrmMark{ 323 Value: 0x0000000a, 324 Mask: 0x0000000f, 325 } 326 if err := XfrmStateAdd(state); err != nil { 327 t.Fatal(err) 328 } 329 s, err := XfrmStateGet(state) 330 if err != nil { 331 t.Fatal(err) 332 } 333 if !compareStates(state, s) { 334 t.Fatalf("unexpected state returned.\nExpected: %v.\nGot %v", state, s) 335 } 336 if err = XfrmStateDel(s); err != nil { 337 t.Fatal(err) 338 } 339 } 340 func genStateSelectorForV6Payload() *XfrmPolicy { 341 _, wildcardV6Net, _ := net.ParseCIDR("::/0") 342 return &XfrmPolicy{ 343 Src: wildcardV6Net, 344 Dst: wildcardV6Net, 345 } 346 } 347 348 func genStateSelectorForV4Payload() *XfrmPolicy { 349 _, wildcardV4Net, _ := net.ParseCIDR("0.0.0.0/0") 350 return &XfrmPolicy{ 351 Src: wildcardV4Net, 352 Dst: wildcardV4Net, 353 } 354 } 355 356 func getBaseState() *XfrmState { 357 return &XfrmState{ 358 // Force 4 byte notation for the IPv4 addresses 359 Src: net.ParseIP("127.0.0.1").To4(), 360 Dst: net.ParseIP("127.0.0.2").To4(), 361 Proto: XFRM_PROTO_ESP, 362 Mode: XFRM_MODE_TUNNEL, 363 Spi: 1, 364 Auth: &XfrmStateAlgo{ 365 Name: "hmac(sha256)", 366 Key: []byte("abcdefghijklmnopqrstuvwzyzABCDEF"), 367 }, 368 Crypt: &XfrmStateAlgo{ 369 Name: "cbc(aes)", 370 Key: []byte("abcdefghijklmnopqrstuvwzyzABCDEF"), 371 }, 372 Mark: &XfrmMark{ 373 Value: 0x12340000, 374 Mask: 0xffff0000, 375 }, 376 } 377 } 378 379 func getBaseStateV4oV6() *XfrmState { 380 return &XfrmState{ 381 // Force 4 byte notation for the IPv4 addressesd 382 Src: net.ParseIP("2001:dead::1").To16(), 383 Dst: net.ParseIP("2001:beef::1").To16(), 384 Proto: XFRM_PROTO_ESP, 385 Mode: XFRM_MODE_TUNNEL, 386 Spi: 1, 387 Auth: &XfrmStateAlgo{ 388 Name: "hmac(sha256)", 389 Key: []byte("abcdefghijklmnopqrstuvwzyzABCDEF"), 390 }, 391 Crypt: &XfrmStateAlgo{ 392 Name: "cbc(aes)", 393 Key: []byte("abcdefghijklmnopqrstuvwzyzABCDEF"), 394 }, 395 Mark: &XfrmMark{ 396 Value: 0x12340000, 397 Mask: 0xffff0000, 398 }, 399 Selector: genStateSelectorForV4Payload(), 400 } 401 } 402 403 func getBaseStateV6oV4() *XfrmState { 404 return &XfrmState{ 405 // Force 4 byte notation for the IPv4 addressesd 406 Src: net.ParseIP("192.168.1.1").To4(), 407 Dst: net.ParseIP("192.168.2.2").To4(), 408 Proto: XFRM_PROTO_ESP, 409 Mode: XFRM_MODE_TUNNEL, 410 Spi: 1, 411 Auth: &XfrmStateAlgo{ 412 Name: "hmac(sha256)", 413 Key: []byte("abcdefghijklmnopqrstuvwzyzABCDEF"), 414 }, 415 Crypt: &XfrmStateAlgo{ 416 Name: "cbc(aes)", 417 Key: []byte("abcdefghijklmnopqrstuvwzyzABCDEF"), 418 }, 419 Mark: &XfrmMark{ 420 Value: 0x12340000, 421 Mask: 0xffff0000, 422 }, 423 Selector: genStateSelectorForV6Payload(), 424 } 425 } 426 427 func getAeadState() *XfrmState { 428 // 128 key bits + 32 salt bits 429 k, _ := hex.DecodeString("d0562776bf0e75830ba3f7f8eb6c09b555aa1177") 430 return &XfrmState{ 431 // Leave IPv4 addresses in Ipv4 in IPv6 notation 432 Src: net.ParseIP("192.168.1.1"), 433 Dst: net.ParseIP("192.168.2.2"), 434 Proto: XFRM_PROTO_ESP, 435 Mode: XFRM_MODE_TUNNEL, 436 Spi: 2, 437 Aead: &XfrmStateAlgo{ 438 Name: "rfc4106(gcm(aes))", 439 Key: k, 440 ICVLen: 64, 441 }, 442 } 443 } 444 func compareSelector(a, b *XfrmPolicy) bool { 445 return a.Src.String() == b.Src.String() && 446 a.Dst.String() == b.Dst.String() && 447 a.Proto == b.Proto && 448 a.DstPort == b.DstPort && 449 a.SrcPort == b.SrcPort && 450 a.Ifindex == b.Ifindex 451 } 452 453 func compareStates(a, b *XfrmState) bool { 454 if a == b { 455 return true 456 } 457 if a == nil || b == nil { 458 return false 459 } 460 if a.Selector != nil && b.Selector != nil { 461 if !compareSelector(a.Selector, b.Selector) { 462 return false 463 } 464 } 465 466 return a.Src.Equal(b.Src) && a.Dst.Equal(b.Dst) && 467 a.Mode == b.Mode && a.Spi == b.Spi && a.Proto == b.Proto && 468 a.Ifid == b.Ifid && 469 compareAlgo(a.Auth, b.Auth) && 470 compareAlgo(a.Crypt, b.Crypt) && 471 compareAlgo(a.Aead, b.Aead) && 472 compareMarks(a.Mark, b.Mark) && 473 compareMarks(a.OutputMark, b.OutputMark) 474 475 } 476 477 func compareLimits(a, b *XfrmState) bool { 478 return a.Limits.TimeHard == b.Limits.TimeHard && 479 a.Limits.TimeSoft == b.Limits.TimeSoft && 480 a.Limits.PacketHard == b.Limits.PacketHard && 481 a.Limits.PacketSoft == b.Limits.PacketSoft && 482 a.Limits.ByteHard == b.Limits.ByteHard && 483 a.Limits.ByteSoft == b.Limits.ByteSoft && 484 a.Limits.TimeUseHard == b.Limits.TimeUseHard && 485 a.Limits.TimeUseSoft == b.Limits.TimeUseSoft 486 } 487 488 func compareAlgo(a, b *XfrmStateAlgo) bool { 489 if a == b { 490 return true 491 } 492 if a == nil || b == nil { 493 return false 494 } 495 return a.Name == b.Name && bytes.Equal(a.Key, b.Key) && 496 (a.TruncateLen == 0 || a.TruncateLen == b.TruncateLen) && 497 (a.ICVLen == 0 || a.ICVLen == b.ICVLen) 498 } 499 500 func compareMarks(a, b *XfrmMark) bool { 501 if a == b { 502 return true 503 } 504 if a == nil || b == nil { 505 return false 506 } 507 return a.Value == b.Value && a.Mask == b.Mask 508 }