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
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
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
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
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
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
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
191 state := getBaseState()
192 now := time.Now()
193 if err := XfrmStateAdd(state); err != nil {
194 t.Fatal(err)
195 }
196
197 s, err := XfrmStateGet(state)
198 if err != nil {
199 t.Fatal(err)
200 }
201
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 TestXfrmStateWithOutputMark(t *testing.T) {
229 minKernelRequired(t, 4, 14)
230 defer setUpNetlinkTest(t)()
231
232 state := getBaseState()
233 state.OutputMark = &XfrmMark{
234 Value: 0x0000000a,
235 }
236 if err := XfrmStateAdd(state); err != nil {
237 t.Fatal(err)
238 }
239 s, err := XfrmStateGet(state)
240 if err != nil {
241 t.Fatal(err)
242 }
243 if !compareStates(state, s) {
244 t.Fatalf("unexpected state returned.\nExpected: %v.\nGot %v", state, s)
245 }
246 if err = XfrmStateDel(s); err != nil {
247 t.Fatal(err)
248 }
249 }
250
251 func TestXfrmStateWithOutputMarkAndMask(t *testing.T) {
252 minKernelRequired(t, 4, 19)
253 defer setUpNetlinkTest(t)()
254
255 state := getBaseState()
256 state.OutputMark = &XfrmMark{
257 Value: 0x0000000a,
258 Mask: 0x0000000f,
259 }
260 if err := XfrmStateAdd(state); err != nil {
261 t.Fatal(err)
262 }
263 s, err := XfrmStateGet(state)
264 if err != nil {
265 t.Fatal(err)
266 }
267 if !compareStates(state, s) {
268 t.Fatalf("unexpected state returned.\nExpected: %v.\nGot %v", state, s)
269 }
270 if err = XfrmStateDel(s); err != nil {
271 t.Fatal(err)
272 }
273 }
274 func genStateSelectorForV6Payload() *XfrmPolicy {
275 _, wildcardV6Net, _ := net.ParseCIDR("::/0")
276 return &XfrmPolicy{
277 Src: wildcardV6Net,
278 Dst: wildcardV6Net,
279 }
280 }
281
282 func genStateSelectorForV4Payload() *XfrmPolicy {
283 _, wildcardV4Net, _ := net.ParseCIDR("0.0.0.0/0")
284 return &XfrmPolicy{
285 Src: wildcardV4Net,
286 Dst: wildcardV4Net,
287 }
288 }
289
290 func getBaseState() *XfrmState {
291 return &XfrmState{
292
293 Src: net.ParseIP("127.0.0.1").To4(),
294 Dst: net.ParseIP("127.0.0.2").To4(),
295 Proto: XFRM_PROTO_ESP,
296 Mode: XFRM_MODE_TUNNEL,
297 Spi: 1,
298 Auth: &XfrmStateAlgo{
299 Name: "hmac(sha256)",
300 Key: []byte("abcdefghijklmnopqrstuvwzyzABCDEF"),
301 },
302 Crypt: &XfrmStateAlgo{
303 Name: "cbc(aes)",
304 Key: []byte("abcdefghijklmnopqrstuvwzyzABCDEF"),
305 },
306 Mark: &XfrmMark{
307 Value: 0x12340000,
308 Mask: 0xffff0000,
309 },
310 }
311 }
312
313 func getBaseStateV4oV6() *XfrmState {
314 return &XfrmState{
315
316 Src: net.ParseIP("2001:dead::1").To16(),
317 Dst: net.ParseIP("2001:beef::1").To16(),
318 Proto: XFRM_PROTO_ESP,
319 Mode: XFRM_MODE_TUNNEL,
320 Spi: 1,
321 Auth: &XfrmStateAlgo{
322 Name: "hmac(sha256)",
323 Key: []byte("abcdefghijklmnopqrstuvwzyzABCDEF"),
324 },
325 Crypt: &XfrmStateAlgo{
326 Name: "cbc(aes)",
327 Key: []byte("abcdefghijklmnopqrstuvwzyzABCDEF"),
328 },
329 Mark: &XfrmMark{
330 Value: 0x12340000,
331 Mask: 0xffff0000,
332 },
333 Selector: genStateSelectorForV4Payload(),
334 }
335 }
336
337 func getBaseStateV6oV4() *XfrmState {
338 return &XfrmState{
339
340 Src: net.ParseIP("192.168.1.1").To4(),
341 Dst: net.ParseIP("192.168.2.2").To4(),
342 Proto: XFRM_PROTO_ESP,
343 Mode: XFRM_MODE_TUNNEL,
344 Spi: 1,
345 Auth: &XfrmStateAlgo{
346 Name: "hmac(sha256)",
347 Key: []byte("abcdefghijklmnopqrstuvwzyzABCDEF"),
348 },
349 Crypt: &XfrmStateAlgo{
350 Name: "cbc(aes)",
351 Key: []byte("abcdefghijklmnopqrstuvwzyzABCDEF"),
352 },
353 Mark: &XfrmMark{
354 Value: 0x12340000,
355 Mask: 0xffff0000,
356 },
357 Selector: genStateSelectorForV6Payload(),
358 }
359 }
360
361 func getAeadState() *XfrmState {
362
363 k, _ := hex.DecodeString("d0562776bf0e75830ba3f7f8eb6c09b555aa1177")
364 return &XfrmState{
365
366 Src: net.ParseIP("192.168.1.1"),
367 Dst: net.ParseIP("192.168.2.2"),
368 Proto: XFRM_PROTO_ESP,
369 Mode: XFRM_MODE_TUNNEL,
370 Spi: 2,
371 Aead: &XfrmStateAlgo{
372 Name: "rfc4106(gcm(aes))",
373 Key: k,
374 ICVLen: 64,
375 },
376 }
377 }
378 func compareSelector(a, b *XfrmPolicy) bool {
379 return a.Src.String() == b.Src.String() &&
380 a.Dst.String() == b.Dst.String() &&
381 a.Proto == b.Proto &&
382 a.DstPort == b.DstPort &&
383 a.SrcPort == b.SrcPort &&
384 a.Ifindex == b.Ifindex
385 }
386
387 func compareStates(a, b *XfrmState) bool {
388 if a == b {
389 return true
390 }
391 if a == nil || b == nil {
392 return false
393 }
394 if a.Selector != nil && b.Selector != nil {
395 if !compareSelector(a.Selector, b.Selector) {
396 return false
397 }
398 }
399
400 return a.Src.Equal(b.Src) && a.Dst.Equal(b.Dst) &&
401 a.Mode == b.Mode && a.Spi == b.Spi && a.Proto == b.Proto &&
402 a.Ifid == b.Ifid &&
403 compareAlgo(a.Auth, b.Auth) &&
404 compareAlgo(a.Crypt, b.Crypt) &&
405 compareAlgo(a.Aead, b.Aead) &&
406 compareMarks(a.Mark, b.Mark) &&
407 compareMarks(a.OutputMark, b.OutputMark)
408
409 }
410
411 func compareLimits(a, b *XfrmState) bool {
412 return a.Limits.TimeHard == b.Limits.TimeHard &&
413 a.Limits.TimeSoft == b.Limits.TimeSoft &&
414 a.Limits.PacketHard == b.Limits.PacketHard &&
415 a.Limits.PacketSoft == b.Limits.PacketSoft &&
416 a.Limits.ByteHard == b.Limits.ByteHard &&
417 a.Limits.ByteSoft == b.Limits.ByteSoft &&
418 a.Limits.TimeUseHard == b.Limits.TimeUseHard &&
419 a.Limits.TimeUseSoft == b.Limits.TimeUseSoft
420 }
421
422 func compareAlgo(a, b *XfrmStateAlgo) bool {
423 if a == b {
424 return true
425 }
426 if a == nil || b == nil {
427 return false
428 }
429 return a.Name == b.Name && bytes.Equal(a.Key, b.Key) &&
430 (a.TruncateLen == 0 || a.TruncateLen == b.TruncateLen) &&
431 (a.ICVLen == 0 || a.ICVLen == b.ICVLen)
432 }
433
434 func compareMarks(a, b *XfrmMark) bool {
435 if a == b {
436 return true
437 }
438 if a == nil || b == nil {
439 return false
440 }
441 return a.Value == b.Value && a.Mask == b.Mask
442 }
443
View as plain text