github.com/vishvananda/netlink@v1.3.0/xfrm_policy_linux_test.go (about) 1 package netlink 2 3 import ( 4 "bytes" 5 "net" 6 "testing" 7 ) 8 9 const zeroCIDR = "0.0.0.0/0" 10 11 func TestXfrmPolicyAddUpdateDel(t *testing.T) { 12 tearDown := setUpNetlinkTest(t) 13 defer tearDown() 14 15 policy := getPolicy() 16 if err := XfrmPolicyAdd(policy); err != nil { 17 t.Fatal(err) 18 } 19 policies, err := XfrmPolicyList(FAMILY_ALL) 20 if err != nil { 21 t.Fatal(err) 22 } 23 24 if len(policies) != 1 { 25 t.Fatal("Policy not added properly") 26 } 27 28 if !comparePolicies(policy, &policies[0]) { 29 t.Fatalf("unexpected policy returned.\nExpected: %v.\nGot %v", policy, policies[0]) 30 } 31 32 if policies[0].Ifindex != 0 { 33 t.Fatalf("default policy has a non-zero interface index.\nGot %d", policies[0].Ifindex) 34 } 35 36 if policies[0].Ifid != 0 { 37 t.Fatalf("default policy has non-zero if_id.\nGot %d", policies[0].Ifid) 38 } 39 40 if policies[0].Action != XFRM_POLICY_ALLOW { 41 t.Fatalf("default policy has non-allow action.\nGot %s", policies[0].Action) 42 } 43 44 // Look for a specific policy 45 sp, err := XfrmPolicyGet(policy) 46 if err != nil { 47 t.Fatal(err) 48 } 49 50 if !comparePolicies(policy, sp) { 51 t.Fatalf("unexpected policy returned") 52 } 53 54 // Modify the policy 55 policy.Priority = 100 56 if err := XfrmPolicyUpdate(policy); err != nil { 57 t.Fatal(err) 58 } 59 sp, err = XfrmPolicyGet(policy) 60 if err != nil { 61 t.Fatal(err) 62 } 63 if sp.Priority != 100 { 64 t.Fatalf("failed to modify the policy") 65 } 66 67 if err = XfrmPolicyDel(policy); err != nil { 68 t.Fatal(err) 69 } 70 71 policies, err = XfrmPolicyList(FAMILY_ALL) 72 if err != nil { 73 t.Fatal(err) 74 } 75 if len(policies) != 0 { 76 t.Fatal("Policy not removed properly") 77 } 78 79 // Src and dst are not mandatory field. Creation should succeed 80 policy.Src = nil 81 policy.Dst = nil 82 if err = XfrmPolicyAdd(policy); err != nil { 83 t.Fatal(err) 84 } 85 86 sp, err = XfrmPolicyGet(policy) 87 if err != nil { 88 t.Fatal(err) 89 } 90 91 if !comparePolicies(policy, sp) { 92 t.Fatalf("unexpected policy returned") 93 } 94 95 if err = XfrmPolicyDel(policy); err != nil { 96 t.Fatal(err) 97 } 98 99 if _, err := XfrmPolicyGet(policy); err == nil { 100 t.Fatalf("Unexpected success") 101 } 102 } 103 104 func TestXfrmPolicyFlush(t *testing.T) { 105 defer setUpNetlinkTest(t)() 106 107 p1 := getPolicy() 108 if err := XfrmPolicyAdd(p1); err != nil { 109 t.Fatal(err) 110 } 111 112 p1.Dir = XFRM_DIR_IN 113 s := p1.Src 114 p1.Src = p1.Dst 115 p1.Dst = s 116 if err := XfrmPolicyAdd(p1); err != nil { 117 t.Fatal(err) 118 } 119 120 policies, err := XfrmPolicyList(FAMILY_ALL) 121 if err != nil { 122 t.Fatal(err) 123 } 124 if len(policies) != 2 { 125 t.Fatalf("unexpected number of policies: %d", len(policies)) 126 } 127 128 if err := XfrmPolicyFlush(); err != nil { 129 t.Fatal(err) 130 } 131 132 policies, err = XfrmPolicyList(FAMILY_ALL) 133 if err != nil { 134 t.Fatal(err) 135 } 136 if len(policies) != 0 { 137 t.Fatalf("unexpected number of policies: %d", len(policies)) 138 } 139 140 } 141 142 func TestXfrmPolicyBlockWithIfindex(t *testing.T) { 143 defer setUpNetlinkTest(t)() 144 145 pBlock := getPolicy() 146 pBlock.Action = XFRM_POLICY_BLOCK 147 pBlock.Ifindex = 1 // loopback interface 148 if err := XfrmPolicyAdd(pBlock); err != nil { 149 t.Fatal(err) 150 } 151 policies, err := XfrmPolicyList(FAMILY_ALL) 152 if err != nil { 153 t.Fatal(err) 154 } 155 if len(policies) != 1 { 156 t.Fatalf("unexpected number of policies: %d", len(policies)) 157 } 158 if !comparePolicies(pBlock, &policies[0]) { 159 t.Fatalf("unexpected policy returned.\nExpected: %v.\nGot %v", pBlock, policies[0]) 160 } 161 if err = XfrmPolicyDel(pBlock); err != nil { 162 t.Fatal(err) 163 } 164 } 165 166 func TestXfrmPolicyWithIfid(t *testing.T) { 167 minKernelRequired(t, 4, 19) 168 defer setUpNetlinkTest(t)() 169 170 pol := getPolicy() 171 pol.Ifid = 54321 172 173 if err := XfrmPolicyAdd(pol); err != nil { 174 t.Fatal(err) 175 } 176 policies, err := XfrmPolicyList(FAMILY_ALL) 177 if err != nil { 178 t.Fatal(err) 179 } 180 if len(policies) != 1 { 181 t.Fatalf("unexpected number of policies: %d", len(policies)) 182 } 183 if !comparePolicies(pol, &policies[0]) { 184 t.Fatalf("unexpected policy returned.\nExpected: %v.\nGot %v", pol, policies[0]) 185 } 186 if err = XfrmPolicyDel(&policies[0]); err != nil { 187 t.Fatal(err) 188 } 189 } 190 191 func TestXfrmPolicyWithOptional(t *testing.T) { 192 minKernelRequired(t, 4, 19) 193 defer setUpNetlinkTest(t)() 194 195 pol := getPolicy() 196 pol.Dir = XFRM_DIR_IN 197 pol.Tmpls[0].Optional = 1 198 199 if err := XfrmPolicyAdd(pol); err != nil { 200 t.Fatal(err) 201 } 202 policies, err := XfrmPolicyList(FAMILY_ALL) 203 if err != nil { 204 t.Fatal(err) 205 } 206 if len(policies) != 1 { 207 t.Fatalf("unexpected number of policies: %d", len(policies)) 208 } 209 if !comparePolicies(pol, &policies[0]) { 210 t.Fatalf("unexpected policy returned.\nExpected: %v.\nGot %v", pol, policies[0]) 211 } 212 if err = XfrmPolicyDel(&policies[0]); err != nil { 213 t.Fatal(err) 214 } 215 } 216 217 func comparePolicies(a, b *XfrmPolicy) bool { 218 if a == b { 219 return true 220 } 221 if a == nil || b == nil { 222 return false 223 } 224 // Do not check Index which is assigned by kernel 225 return a.Dir == b.Dir && a.Priority == b.Priority && 226 compareIPNet(a.Src, b.Src) && compareIPNet(a.Dst, b.Dst) && 227 a.Action == b.Action && a.Ifindex == b.Ifindex && 228 a.Mark.Value == b.Mark.Value && a.Mark.Mask == b.Mark.Mask && 229 a.Ifid == b.Ifid && compareTemplates(a.Tmpls, b.Tmpls) 230 } 231 232 func compareTemplates(a, b []XfrmPolicyTmpl) bool { 233 if len(a) != len(b) { 234 return false 235 } 236 for i, ta := range a { 237 tb := b[i] 238 if !ta.Dst.Equal(tb.Dst) || !ta.Src.Equal(tb.Src) || ta.Spi != tb.Spi || 239 ta.Mode != tb.Mode || ta.Reqid != tb.Reqid || ta.Proto != tb.Proto || 240 ta.Optional != tb.Optional { 241 return false 242 } 243 } 244 return true 245 } 246 247 func compareIPNet(a, b *net.IPNet) bool { 248 if a == b { 249 return true 250 } 251 // For unspecified src/dst parseXfrmPolicy would set the zero address cidr 252 if (a == nil && b.String() == zeroCIDR) || (b == nil && a.String() == zeroCIDR) { 253 return true 254 } 255 if a == nil || b == nil { 256 return false 257 } 258 return a.IP.Equal(b.IP) && bytes.Equal(a.Mask, b.Mask) 259 } 260 261 func getPolicy() *XfrmPolicy { 262 src, _ := ParseIPNet("127.1.1.1/32") 263 dst, _ := ParseIPNet("127.1.1.2/32") 264 policy := &XfrmPolicy{ 265 Src: src, 266 Dst: dst, 267 Proto: 17, 268 DstPort: 1234, 269 SrcPort: 5678, 270 Dir: XFRM_DIR_OUT, 271 Mark: &XfrmMark{ 272 Value: 0xabff22, 273 Mask: 0xffffffff, 274 }, 275 Priority: 10, 276 } 277 tmpl := XfrmPolicyTmpl{ 278 Src: net.ParseIP("127.0.0.1"), 279 Dst: net.ParseIP("127.0.0.2"), 280 Proto: XFRM_PROTO_ESP, 281 Mode: XFRM_MODE_TUNNEL, 282 Spi: 0x1bcdef99, 283 } 284 policy.Tmpls = append(policy.Tmpls, tmpl) 285 return policy 286 }