Skip to content

Commit a3bedeb

Browse files
committed
Fix reading of rule type and add l3mdev flag.
When reading rules, makes sure to populate the type field of Rule. Also adds a l3mdev flag to Rule, reads it when listing rules, sets it when updating rules, and makes sure it is taken into account when comparing rules using Equal as introduced in vishvananda#1095.
1 parent 6a8c071 commit a3bedeb

File tree

3 files changed

+40
-3
lines changed

3 files changed

+40
-3
lines changed

rule.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ type Rule struct {
2929
UIDRange *RuleUIDRange
3030
Protocol uint8
3131
Type uint8
32+
L3mdev uint8
3233
}
3334

3435
func (r Rule) Equal(x Rule) bool {
@@ -59,7 +60,8 @@ func (r Rule) Equal(x Rule) bool {
5960
r.SuppressPrefixlen == x.SuppressPrefixlen &&
6061
(r.Dport == x.Dport || (r.Dport != nil && x.Dport != nil && r.Dport.Equal(*x.Dport))) &&
6162
(r.Sport == x.Sport || (r.Sport != nil && x.Sport != nil && r.Sport.Equal(*x.Sport))) &&
62-
(r.UIDRange == x.UIDRange || (r.UIDRange != nil && x.UIDRange != nil && r.UIDRange.Equal(*x.UIDRange)))
63+
(r.UIDRange == x.UIDRange || (r.UIDRange != nil && x.UIDRange != nil && r.UIDRange.Equal(*x.UIDRange))) &&
64+
r.L3mdev == x.L3mdev
6365
}
6466

6567
func ptrEqual(a, b *uint32) bool {

rule_linux.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,10 @@ func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
178178
req.AddData(nl.NewRtAttr(nl.FRA_PROTOCOL, nl.Uint8Attr(rule.Protocol)))
179179
}
180180

181+
if rule.L3mdev > 0 {
182+
req.AddData(nl.NewRtAttr(nl.FRA_L3MDEV, nl.Uint8Attr(rule.L3mdev)))
183+
}
184+
181185
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
182186
return err
183187
}
@@ -239,6 +243,7 @@ func (h *Handle) RuleListFiltered(family int, filter *Rule, filterMask uint64) (
239243
rule.Invert = msg.Flags&FibRuleInvert > 0
240244
rule.Family = int(msg.Family)
241245
rule.Tos = uint(msg.Tos)
246+
rule.Type = msg.Type
242247

243248
for j := range attrs {
244249
switch attrs[j].Attr.Type {
@@ -291,6 +296,8 @@ func (h *Handle) RuleListFiltered(family int, filter *Rule, filterMask uint64) (
291296
rule.UIDRange = NewRuleUIDRange(native.Uint32(attrs[j].Value[0:4]), native.Uint32(attrs[j].Value[4:8]))
292297
case nl.FRA_PROTOCOL:
293298
rule.Protocol = uint8(attrs[j].Value[0])
299+
case nl.FRA_L3MDEV:
300+
rule.L3mdev = uint8(attrs[j].Value[0])
294301
}
295302
}
296303

@@ -341,7 +348,7 @@ func (r Rule) typeString() string {
341348
case unix.RTN_UNSPEC: // zero
342349
return ""
343350
case unix.RTN_UNICAST:
344-
return ""
351+
return "unicast"
345352
case unix.RTN_LOCAL:
346353
return "local"
347354
case unix.RTN_BROADCAST:

rule_test.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ func TestRuleAddDel(t *testing.T) {
2727
rule := NewRule()
2828
rule.Family = FAMILY_V4
2929
rule.Table = unix.RT_TABLE_MAIN
30+
rule.Type = unix.RTN_UNICAST
3031
rule.Src = srcNet
3132
rule.Dst = dstNet
3233
rule.Priority = 5
@@ -55,7 +56,7 @@ func TestRuleAddDel(t *testing.T) {
5556
// find this rule
5657
found := ruleExists(rules, *rule)
5758
if !found {
58-
t.Fatal("Rule has diffrent options than one added")
59+
t.Fatal("Rule has different options than one added")
5960
}
6061

6162
if err := RuleDel(rule); err != nil {
@@ -126,6 +127,7 @@ func runRuleListFiltered(t *testing.T, family int, srcNet, dstNet *net.IPNet) {
126127
r.Priority = 1 // Must add priority and table otherwise it's auto-assigned
127128
r.Family = family
128129
r.Table = 1
130+
r.Type = unix.RTN_UNICAST
129131
RuleAdd(r)
130132
return r
131133
},
@@ -144,6 +146,7 @@ func runRuleListFiltered(t *testing.T, family int, srcNet, dstNet *net.IPNet) {
144146
r.Priority = 1 // Must add priority and table otherwise it's auto-assigned
145147
r.Family = family
146148
r.Table = 1
149+
r.Type = unix.RTN_UNICAST
147150
RuleAdd(r)
148151
return r
149152
},
@@ -162,6 +165,7 @@ func runRuleListFiltered(t *testing.T, family int, srcNet, dstNet *net.IPNet) {
162165
r.Priority = 1 // Must add priority and table otherwise it's auto-assigned
163166
r.Family = family
164167
r.Table = 1
168+
r.Type = unix.RTN_UNICAST
165169
RuleAdd(r)
166170

167171
rc := *r // Create almost identical copy
@@ -198,6 +202,7 @@ func runRuleListFiltered(t *testing.T, family int, srcNet, dstNet *net.IPNet) {
198202
r.Priority = 1 // Must add priority and table otherwise it's auto-assigned
199203
r.Family = family
200204
r.Table = 1
205+
r.Type = unix.RTN_UNICAST
201206
RuleAdd(r)
202207

203208
rc := *r // Create almost identical copy
@@ -234,6 +239,7 @@ func runRuleListFiltered(t *testing.T, family int, srcNet, dstNet *net.IPNet) {
234239
r.Priority = 0
235240
r.Family = family
236241
r.Table = 1
242+
r.Type = unix.RTN_UNICAST
237243
RuleAdd(r)
238244
return r
239245
},
@@ -253,6 +259,7 @@ func runRuleListFiltered(t *testing.T, family int, srcNet, dstNet *net.IPNet) {
253259
r.Src = srcNet
254260
r.Family = family
255261
r.Table = 1
262+
r.Type = unix.RTN_UNICAST
256263
RuleAdd(r)
257264

258265
r.Priority = 32765 // Set priority for assertion
@@ -275,6 +282,7 @@ func runRuleListFiltered(t *testing.T, family int, srcNet, dstNet *net.IPNet) {
275282
r.Priority = 5
276283
r.Family = family
277284
r.Table = 1
285+
r.Type = unix.RTN_UNICAST
278286
RuleAdd(r)
279287

280288
for i := 2; i < 5; i++ {
@@ -317,6 +325,7 @@ func runRuleListFiltered(t *testing.T, family int, srcNet, dstNet *net.IPNet) {
317325
r.Priority = 1 // Must add priority otherwise it's auto-assigned
318326
r.Family = family
319327
r.Table = 199
328+
r.Type = unix.RTN_UNICAST
320329
RuleAdd(r)
321330
return r
322331
},
@@ -335,6 +344,7 @@ func runRuleListFiltered(t *testing.T, family int, srcNet, dstNet *net.IPNet) {
335344
r.Priority = 1 // Must add priority and table otherwise it's auto-assigned
336345
r.Family = family
337346
r.Table = 1
347+
r.Type = unix.RTN_UNICAST
338348
r.Mask = &[]uint32{0x5}[0]
339349
RuleAdd(r)
340350
return r
@@ -354,6 +364,7 @@ func runRuleListFiltered(t *testing.T, family int, srcNet, dstNet *net.IPNet) {
354364
r.Priority = 1 // Must add priority, table, mask otherwise it's auto-assigned
355365
r.Family = family
356366
r.Table = 1
367+
r.Type = unix.RTN_UNICAST
357368
r.Mask = &[]uint32{0xff}[0]
358369
r.Mark = 0xbb
359370
RuleAdd(r)
@@ -374,6 +385,7 @@ func runRuleListFiltered(t *testing.T, family int, srcNet, dstNet *net.IPNet) {
374385
r.Priority = 1
375386
r.Family = family
376387
r.Table = 100
388+
r.Type = unix.RTN_UNICAST
377389
r.Mark = 0
378390
r.Mask = nil
379391
if err := RuleAdd(r); err != nil {
@@ -396,6 +408,7 @@ func runRuleListFiltered(t *testing.T, family int, srcNet, dstNet *net.IPNet) {
396408
r.Priority = 1
397409
r.Family = family
398410
r.Table = 100
411+
r.Type = unix.RTN_UNICAST
399412
r.Mark = 0
400413
r.Mask = &[]uint32{0xFFFFFFFF}[0]
401414
if err := RuleAdd(r); err != nil {
@@ -418,6 +431,7 @@ func runRuleListFiltered(t *testing.T, family int, srcNet, dstNet *net.IPNet) {
418431
r.Priority = 1
419432
r.Family = family
420433
r.Table = 100
434+
r.Type = unix.RTN_UNICAST
421435
r.Mark = 0x1234
422436
r.Mask = &[]uint32{0}[0]
423437
if err := RuleAdd(r); err != nil {
@@ -440,6 +454,7 @@ func runRuleListFiltered(t *testing.T, family int, srcNet, dstNet *net.IPNet) {
440454
r.Priority = 1
441455
r.Family = family
442456
r.Table = 100
457+
r.Type = unix.RTN_UNICAST
443458
r.Mark = 0
444459
r.Mask = &[]uint32{0xFFFFFFFF}[0]
445460
if err := RuleAdd(r); err != nil {
@@ -462,6 +477,7 @@ func runRuleListFiltered(t *testing.T, family int, srcNet, dstNet *net.IPNet) {
462477
r.Priority = 1
463478
r.Family = family
464479
r.Table = 100
480+
r.Type = unix.RTN_UNICAST
465481
r.Mark = 0xFFFFFFFF
466482
r.Mask = nil
467483
if err := RuleAdd(r); err != nil {
@@ -484,6 +500,7 @@ func runRuleListFiltered(t *testing.T, family int, srcNet, dstNet *net.IPNet) {
484500
r.Priority = 1
485501
r.Family = family
486502
r.Table = 100
503+
r.Type = unix.RTN_UNICAST
487504
r.Mark = 0x1234
488505
r.Mask = nil
489506
if err := RuleAdd(r); err != nil {
@@ -506,6 +523,7 @@ func runRuleListFiltered(t *testing.T, family int, srcNet, dstNet *net.IPNet) {
506523
r.Priority = 1
507524
r.Family = family
508525
r.Table = 100
526+
r.Type = unix.RTN_UNICAST
509527
r.Mark = 0x12345678
510528
r.Mask = nil
511529
if err := RuleAdd(r); err != nil {
@@ -528,6 +546,7 @@ func runRuleListFiltered(t *testing.T, family int, srcNet, dstNet *net.IPNet) {
528546
r.Priority = 1
529547
r.Family = family
530548
r.Table = 100
549+
r.Type = unix.RTN_UNICAST
531550
r.Mark = 0xFFFFFFFF
532551
r.Mask = &[]uint32{0}[0]
533552
if err := RuleAdd(r); err != nil {
@@ -550,6 +569,7 @@ func runRuleListFiltered(t *testing.T, family int, srcNet, dstNet *net.IPNet) {
550569
r.Priority = 1
551570
r.Family = family
552571
r.Table = 100
572+
r.Type = unix.RTN_UNICAST
553573
r.Mark = 0xFFFFFFFF
554574
r.Mask = &[]uint32{0xFFFFFFFF}[0]
555575
if err := RuleAdd(r); err != nil {
@@ -572,6 +592,7 @@ func runRuleListFiltered(t *testing.T, family int, srcNet, dstNet *net.IPNet) {
572592
r.Priority = 1 // Must add priority, table, mask otherwise it's auto-assigned
573593
r.Family = family
574594
r.Table = 12
595+
r.Type = unix.RTN_UNICAST
575596
r.Tos = 12 // Tos must equal table
576597
RuleAdd(r)
577598
return r
@@ -599,6 +620,12 @@ func runRuleListFiltered(t *testing.T, family int, srcNet, dstNet *net.IPNet) {
599620

600621
if len(wantRules) != len(rules) {
601622
t.Errorf("Expected len: %d, got: %d", len(wantRules), len(rules))
623+
for i := range wantRules {
624+
t.Errorf("Rules mismatch, want %v", wantRules[i])
625+
}
626+
for i := range rules {
627+
t.Errorf("Rules mismatch, got %v", rules[i])
628+
}
602629
} else {
603630
for i := range wantRules {
604631
if !wantRules[i].Equal(rules[i]) {
@@ -699,6 +726,7 @@ func TestRuleEqual(t *testing.T) {
699726
{UIDRange: &RuleUIDRange{Start: 3, End: 5}},
700727
{Protocol: FAMILY_V6},
701728
{Type: unix.RTN_UNREACHABLE},
729+
{L3mdev: 1},
702730
}
703731
for i1 := range cases {
704732
for i2 := range cases {

0 commit comments

Comments
 (0)