Skip to content

Commit d3b8a16

Browse files
chengzhycnaboch
authored andcommitted
add actions support for fwfilter
Signed-off-by: chengzhycn <[email protected]>
1 parent 8baf7b0 commit d3b8a16

File tree

3 files changed

+143
-0
lines changed

3 files changed

+143
-0
lines changed

filter.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ type FwFilter struct {
349349
InDev string
350350
Mask uint32
351351
Police *PoliceAction
352+
Actions []Action
352353
}
353354

354355
func (filter *FwFilter) Attrs() *FilterAttrs {

filter_linux.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,10 @@ func (h *Handle) filterModify(filter Filter, flags int) error {
312312
native.PutUint32(b, filter.ClassId)
313313
options.AddRtAttr(nl.TCA_FW_CLASSID, b)
314314
}
315+
actionsAttr := options.AddRtAttr(nl.TCA_FW_ACT, nil)
316+
if err := EncodeActions(actionsAttr, filter.Actions); err != nil {
317+
return err
318+
}
315319
case *BpfFilter:
316320
var bpfFlags uint32
317321
if filter.ClassId != 0 {
@@ -861,6 +865,15 @@ func parseFwData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
861865
parsePolice(aattr, &police)
862866
}
863867
fw.Police = &police
868+
case nl.TCA_FW_ACT:
869+
tables, err := nl.ParseRouteAttr(datum.Value)
870+
if err != nil {
871+
return detailed, err
872+
}
873+
fw.Actions, err = parseActions(tables)
874+
if err != nil {
875+
return detailed, err
876+
}
864877
}
865878
}
866879
return detailed, nil

filter_test.go

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,135 @@ func TestFilterFwAddDel(t *testing.T) {
510510
}
511511
}
512512

513+
func TestFilterFwActAddDel(t *testing.T) {
514+
tearDown := setUpNetlinkTest(t)
515+
defer tearDown()
516+
if err := LinkAdd(&Ifb{LinkAttrs{Name: "foo"}}); err != nil {
517+
t.Fatal(err)
518+
}
519+
if err := LinkAdd(&Ifb{LinkAttrs{Name: "bar"}}); err != nil {
520+
t.Fatal(err)
521+
}
522+
link, err := LinkByName("foo")
523+
if err != nil {
524+
t.Fatal(err)
525+
}
526+
if err := LinkSetUp(link); err != nil {
527+
t.Fatal(err)
528+
}
529+
redir, err := LinkByName("bar")
530+
if err != nil {
531+
t.Fatal(err)
532+
}
533+
if err := LinkSetUp(redir); err != nil {
534+
t.Fatal(err)
535+
}
536+
qdisc := &Ingress{
537+
QdiscAttrs: QdiscAttrs{
538+
LinkIndex: link.Attrs().Index,
539+
Handle: MakeHandle(0xffff, 0),
540+
Parent: HANDLE_INGRESS,
541+
},
542+
}
543+
if err := QdiscAdd(qdisc); err != nil {
544+
t.Fatal(err)
545+
}
546+
qdiscs, err := SafeQdiscList(link)
547+
if err != nil {
548+
t.Fatal(err)
549+
}
550+
if len(qdiscs) != 1 {
551+
t.Fatal("Failed to add qdisc")
552+
}
553+
_, ok := qdiscs[0].(*Ingress)
554+
if !ok {
555+
t.Fatal("Qdisc is the wrong type")
556+
}
557+
558+
classId := MakeHandle(1, 1)
559+
filter := &FwFilter{
560+
FilterAttrs: FilterAttrs{
561+
LinkIndex: link.Attrs().Index,
562+
Parent: MakeHandle(0xffff, 0),
563+
Priority: 1,
564+
Protocol: unix.ETH_P_ALL,
565+
Handle: MakeHandle(0, 0x6),
566+
},
567+
ClassId: classId,
568+
Actions: []Action{
569+
&MirredAction{
570+
ActionAttrs: ActionAttrs{
571+
Action: TC_ACT_STOLEN,
572+
},
573+
MirredAction: TCA_EGRESS_REDIR,
574+
Ifindex: redir.Attrs().Index,
575+
},
576+
},
577+
}
578+
579+
if err := FilterAdd(filter); err != nil {
580+
t.Fatal(err)
581+
}
582+
583+
filters, err := FilterList(link, MakeHandle(0xffff, 0))
584+
if err != nil {
585+
t.Fatal(err)
586+
}
587+
if len(filters) != 1 {
588+
t.Fatal("Failed to add filter")
589+
}
590+
fw, ok := filters[0].(*FwFilter)
591+
if !ok {
592+
t.Fatal("Filter is the wrong type")
593+
}
594+
595+
if len(fw.Actions) != 1 {
596+
t.Fatalf("Too few Actions in filter")
597+
}
598+
if fw.ClassId != classId {
599+
t.Fatalf("ClassId of the filter is the wrong value")
600+
}
601+
602+
mia, ok := fw.Actions[0].(*MirredAction)
603+
if !ok {
604+
t.Fatal("Unable to find mirred action")
605+
}
606+
607+
if mia.Attrs().Action != TC_ACT_STOLEN {
608+
t.Fatal("Mirred action isn't TC_ACT_STOLEN")
609+
}
610+
611+
if mia.MirredAction != TCA_EGRESS_REDIR {
612+
t.Fatal("MirredAction isn't TCA_EGRESS_REDIR")
613+
}
614+
615+
if mia.Ifindex != redir.Attrs().Index {
616+
t.Fatal("Unmatched redirect index")
617+
}
618+
619+
if err := FilterDel(filter); err != nil {
620+
t.Fatal(err)
621+
}
622+
filters, err = FilterList(link, MakeHandle(0xffff, 0))
623+
if err != nil {
624+
t.Fatal(err)
625+
}
626+
if len(filters) != 0 {
627+
t.Fatal("Failed to remove filter")
628+
}
629+
630+
if err := QdiscDel(qdisc); err != nil {
631+
t.Fatal(err)
632+
}
633+
qdiscs, err = SafeQdiscList(link)
634+
if err != nil {
635+
t.Fatal(err)
636+
}
637+
if len(qdiscs) != 0 {
638+
t.Fatal("Failed to remove qdisc")
639+
}
640+
}
641+
513642
func TestFilterU32BpfAddDel(t *testing.T) {
514643
t.Skipf("Fd does not match in ci")
515644
tearDown := setUpNetlinkTest(t)

0 commit comments

Comments
 (0)