Skip to content

Commit 1882fa9

Browse files
sargunaboch
authored andcommitted
Add Matchall filter
1 parent 7b4c063 commit 1882fa9

4 files changed

Lines changed: 146 additions & 10 deletions

File tree

filter.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,21 @@ func (filter *U32) Type() string {
225225
return "u32"
226226
}
227227

228+
// MatchAll filters match all packets
229+
type MatchAll struct {
230+
FilterAttrs
231+
ClassId uint32
232+
Actions []Action
233+
}
234+
235+
func (filter *MatchAll) Attrs() *FilterAttrs {
236+
return &filter.FilterAttrs
237+
}
238+
239+
func (filter *MatchAll) Type() string {
240+
return "matchall"
241+
}
242+
228243
type FilterFwAttrs struct {
229244
ClassId uint32
230245
InDev string

filter_linux.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,14 @@ func (h *Handle) FilterAdd(filter Filter) error {
222222
bpfFlags |= nl.TCA_BPF_FLAG_ACT_DIRECT
223223
}
224224
nl.NewRtAttrChild(options, nl.TCA_BPF_FLAGS, nl.Uint32Attr(bpfFlags))
225+
case *MatchAll:
226+
actionsAttr := nl.NewRtAttrChild(options, nl.TCA_MATCHALL_ACT, nil)
227+
if err := EncodeActions(actionsAttr, filter.Actions); err != nil {
228+
return err
229+
}
230+
if filter.ClassId != 0 {
231+
nl.NewRtAttrChild(options, nl.TCA_MATCHALL_CLASSID, nl.Uint32Attr(filter.ClassId))
232+
}
225233
}
226234

227235
req.AddData(options)
@@ -288,6 +296,8 @@ func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
288296
filter = &Fw{}
289297
case "bpf":
290298
filter = &BpfFilter{}
299+
case "matchall":
300+
filter = &MatchAll{}
291301
default:
292302
filter = &GenericFilter{FilterType: filterType}
293303
}
@@ -312,6 +322,11 @@ func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
312322
if err != nil {
313323
return nil, err
314324
}
325+
case "matchall":
326+
detailed, err = parseMatchAllData(filter, data)
327+
if err != nil {
328+
return nil, err
329+
}
315330
default:
316331
detailed = true
317332
}
@@ -541,6 +556,28 @@ func parseBpfData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error)
541556
return detailed, nil
542557
}
543558

559+
func parseMatchAllData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
560+
native = nl.NativeEndian()
561+
matchall := filter.(*MatchAll)
562+
detailed := true
563+
for _, datum := range data {
564+
switch datum.Attr.Type {
565+
case nl.TCA_MATCHALL_CLASSID:
566+
matchall.ClassId = native.Uint32(datum.Value[0:4])
567+
case nl.TCA_MATCHALL_ACT:
568+
tables, err := nl.ParseRouteAttr(datum.Value)
569+
if err != nil {
570+
return detailed, err
571+
}
572+
matchall.Actions, err = parseActions(tables)
573+
if err != nil {
574+
return detailed, err
575+
}
576+
}
577+
}
578+
return detailed, nil
579+
}
580+
544581
func AlignToAtm(size uint) uint {
545582
var linksize, cells int
546583
cells = int(size / nl.ATM_CELL_PAYLOAD)

filter_test.go

Lines changed: 87 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -168,13 +168,13 @@ func TestAdvancedFilterAddDel(t *testing.T) {
168168
}
169169

170170
u32SelKeys := []TcU32Key{
171-
TcU32Key{
171+
{
172172
Mask: 0xff,
173173
Val: 80,
174174
Off: 20,
175175
OffMask: 0,
176176
},
177-
TcU32Key{
177+
{
178178
Mask: 0xffff,
179179
Val: 0x146ca,
180180
Off: 32,
@@ -546,13 +546,11 @@ func TestFilterU32BpfAddDel(t *testing.T) {
546546
}
547547
}
548548

549-
func TestFilterClsActBpfAddDel(t *testing.T) {
550-
tearDown := setUpNetlinkTest(t)
551-
defer tearDown()
552-
if err := LinkAdd(&Ifb{LinkAttrs{Name: "foo"}}); err != nil {
549+
func setupLinkForTestWithQdisc(t *testing.T, linkName string) (Qdisc, Link) {
550+
if err := LinkAdd(&Ifb{LinkAttrs{Name: linkName}}); err != nil {
553551
t.Fatal(err)
554552
}
555-
link, err := LinkByName("foo")
553+
link, err := LinkByName(linkName)
556554
if err != nil {
557555
t.Fatal(err)
558556
}
@@ -568,8 +566,6 @@ func TestFilterClsActBpfAddDel(t *testing.T) {
568566
QdiscAttrs: attrs,
569567
QdiscType: "clsact",
570568
}
571-
// This feature was added in kernel 4.5
572-
minKernelRequired(t, 4, 5)
573569

574570
if err := QdiscAdd(qdisc); err != nil {
575571
t.Fatal(err)
@@ -584,7 +580,17 @@ func TestFilterClsActBpfAddDel(t *testing.T) {
584580
if q, ok := qdiscs[0].(*GenericQdisc); !ok || q.Type() != "clsact" {
585581
t.Fatal("qdisc is the wrong type")
586582
}
583+
return qdiscs[0], link
584+
}
585+
586+
func TestFilterClsActBpfAddDel(t *testing.T) {
587+
// This feature was added in kernel 4.5
588+
minKernelRequired(t, 4, 5)
587589

590+
tearDown := setUpNetlinkTest(t)
591+
defer tearDown()
592+
593+
qdisc, link := setupLinkForTestWithQdisc(t, "foo")
588594
filterattrs := FilterAttrs{
589595
LinkIndex: link.Attrs().Index,
590596
Parent: HANDLE_MIN_EGRESS,
@@ -643,11 +649,82 @@ func TestFilterClsActBpfAddDel(t *testing.T) {
643649
if err := QdiscDel(qdisc); err != nil {
644650
t.Fatal(err)
645651
}
646-
qdiscs, err = SafeQdiscList(link)
652+
qdiscs, err := SafeQdiscList(link)
647653
if err != nil {
648654
t.Fatal(err)
649655
}
650656
if len(qdiscs) != 0 {
651657
t.Fatal("Failed to remove qdisc")
652658
}
653659
}
660+
661+
func TestFilterMatchAllAddDel(t *testing.T) {
662+
// This classifier was added in kernel 4.7
663+
minKernelRequired(t, 4, 7)
664+
665+
tearDown := setUpNetlinkTest(t)
666+
defer tearDown()
667+
_, link := setupLinkForTestWithQdisc(t, "foo")
668+
_, link2 := setupLinkForTestWithQdisc(t, "bar")
669+
filter := &MatchAll{
670+
FilterAttrs: FilterAttrs{
671+
LinkIndex: link.Attrs().Index,
672+
Parent: HANDLE_MIN_EGRESS,
673+
Priority: 32000,
674+
Protocol: unix.ETH_P_ALL,
675+
},
676+
Actions: []Action{
677+
&MirredAction{
678+
ActionAttrs: ActionAttrs{
679+
Action: TC_ACT_STOLEN,
680+
},
681+
MirredAction: TCA_EGRESS_REDIR,
682+
Ifindex: link2.Attrs().Index,
683+
},
684+
},
685+
}
686+
if err := FilterAdd(filter); err != nil {
687+
t.Fatal(err)
688+
}
689+
690+
filters, err := FilterList(link, HANDLE_MIN_EGRESS)
691+
if err != nil {
692+
t.Fatal(err)
693+
}
694+
if len(filters) != 1 {
695+
t.Fatal("Failed to add filter")
696+
}
697+
matchall, ok := filters[0].(*MatchAll)
698+
if !ok {
699+
t.Fatal("Filter is the wrong type")
700+
}
701+
702+
if matchall.Priority != 32000 {
703+
t.Fatal("Filter priority does not match")
704+
}
705+
706+
if len(matchall.Actions) != 1 {
707+
t.Fatal("Filter has no actions")
708+
}
709+
710+
mirredAction, ok := matchall.Actions[0].(*MirredAction)
711+
if !ok {
712+
t.Fatal("Action does not match")
713+
}
714+
715+
if mirredAction.Ifindex != link2.Attrs().Index {
716+
t.Fatal("Action ifindex does not match")
717+
}
718+
719+
if err := FilterDel(filter); err != nil {
720+
t.Fatal(err)
721+
}
722+
filters, err = FilterList(link, HANDLE_MIN_EGRESS)
723+
if err != nil {
724+
t.Fatal(err)
725+
}
726+
if len(filters) != 0 {
727+
t.Fatal("Failed to remove filter")
728+
}
729+
730+
}

nl/tc_linux.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,3 +673,10 @@ const (
673673
TCA_FW_MASK
674674
TCA_FW_MAX = TCA_FW_MASK
675675
)
676+
677+
const (
678+
TCA_MATCHALL_UNSPEC = iota
679+
TCA_MATCHALL_CLASSID
680+
TCA_MATCHALL_ACT
681+
TCA_MATCHALL_FLAGS
682+
)

0 commit comments

Comments
 (0)