Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Matchall filter #311

Merged
merged 1 commit into from
Jan 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,21 @@ func (filter *U32) Type() string {
return "u32"
}

// MatchAll filters match all packets
type MatchAll struct {
FilterAttrs
ClassId uint32
Actions []Action
}

func (filter *MatchAll) Attrs() *FilterAttrs {
return &filter.FilterAttrs
}

func (filter *MatchAll) Type() string {
return "matchall"
}

type FilterFwAttrs struct {
ClassId uint32
InDev string
Expand Down
37 changes: 37 additions & 0 deletions filter_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,14 @@ func (h *Handle) FilterAdd(filter Filter) error {
bpfFlags |= nl.TCA_BPF_FLAG_ACT_DIRECT
}
nl.NewRtAttrChild(options, nl.TCA_BPF_FLAGS, nl.Uint32Attr(bpfFlags))
case *MatchAll:
actionsAttr := nl.NewRtAttrChild(options, nl.TCA_MATCHALL_ACT, nil)
if err := EncodeActions(actionsAttr, filter.Actions); err != nil {
return err
}
if filter.ClassId != 0 {
nl.NewRtAttrChild(options, nl.TCA_MATCHALL_CLASSID, nl.Uint32Attr(filter.ClassId))
}
}

req.AddData(options)
Expand Down Expand Up @@ -288,6 +296,8 @@ func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
filter = &Fw{}
case "bpf":
filter = &BpfFilter{}
case "matchall":
filter = &MatchAll{}
default:
filter = &GenericFilter{FilterType: filterType}
}
Expand All @@ -312,6 +322,11 @@ func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
if err != nil {
return nil, err
}
case "matchall":
detailed, err = parseMatchAllData(filter, data)
if err != nil {
return nil, err
}
default:
detailed = true
}
Expand Down Expand Up @@ -541,6 +556,28 @@ func parseBpfData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error)
return detailed, nil
}

func parseMatchAllData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
native = nl.NativeEndian()
matchall := filter.(*MatchAll)
detailed := true
for _, datum := range data {
switch datum.Attr.Type {
case nl.TCA_MATCHALL_CLASSID:
matchall.ClassId = native.Uint32(datum.Value[0:4])
case nl.TCA_MATCHALL_ACT:
tables, err := nl.ParseRouteAttr(datum.Value)
if err != nil {
return detailed, err
}
matchall.Actions, err = parseActions(tables)
if err != nil {
return detailed, err
}
}
}
return detailed, nil
}

func AlignToAtm(size uint) uint {
var linksize, cells int
cells = int(size / nl.ATM_CELL_PAYLOAD)
Expand Down
97 changes: 87 additions & 10 deletions filter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,13 +168,13 @@ func TestAdvancedFilterAddDel(t *testing.T) {
}

u32SelKeys := []TcU32Key{
TcU32Key{
{
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes were made by gofmt, I can split it out into another PR, or a different commit

Mask: 0xff,
Val: 80,
Off: 20,
OffMask: 0,
},
TcU32Key{
{
Mask: 0xffff,
Val: 0x146ca,
Off: 32,
Expand Down Expand Up @@ -546,13 +546,11 @@ func TestFilterU32BpfAddDel(t *testing.T) {
}
}

func TestFilterClsActBpfAddDel(t *testing.T) {
tearDown := setUpNetlinkTest(t)
defer tearDown()
if err := LinkAdd(&Ifb{LinkAttrs{Name: "foo"}}); err != nil {
func setupLinkForTestWithQdisc(t *testing.T, linkName string) (Qdisc, Link) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

if err := LinkAdd(&Ifb{LinkAttrs{Name: linkName}}); err != nil {
t.Fatal(err)
}
link, err := LinkByName("foo")
link, err := LinkByName(linkName)
if err != nil {
t.Fatal(err)
}
Expand All @@ -568,8 +566,6 @@ func TestFilterClsActBpfAddDel(t *testing.T) {
QdiscAttrs: attrs,
QdiscType: "clsact",
}
// This feature was added in kernel 4.5
minKernelRequired(t, 4, 5)

if err := QdiscAdd(qdisc); err != nil {
t.Fatal(err)
Expand All @@ -584,7 +580,17 @@ func TestFilterClsActBpfAddDel(t *testing.T) {
if q, ok := qdiscs[0].(*GenericQdisc); !ok || q.Type() != "clsact" {
t.Fatal("qdisc is the wrong type")
}
return qdiscs[0], link
}

func TestFilterClsActBpfAddDel(t *testing.T) {
// This feature was added in kernel 4.5
minKernelRequired(t, 4, 5)

tearDown := setUpNetlinkTest(t)
defer tearDown()

qdisc, link := setupLinkForTestWithQdisc(t, "foo")
filterattrs := FilterAttrs{
LinkIndex: link.Attrs().Index,
Parent: HANDLE_MIN_EGRESS,
Expand Down Expand Up @@ -643,11 +649,82 @@ func TestFilterClsActBpfAddDel(t *testing.T) {
if err := QdiscDel(qdisc); err != nil {
t.Fatal(err)
}
qdiscs, err = SafeQdiscList(link)
qdiscs, err := SafeQdiscList(link)
if err != nil {
t.Fatal(err)
}
if len(qdiscs) != 0 {
t.Fatal("Failed to remove qdisc")
}
}

func TestFilterMatchAllAddDel(t *testing.T) {
// This classifier was added in kernel 4.7
minKernelRequired(t, 4, 7)

tearDown := setUpNetlinkTest(t)
defer tearDown()
_, link := setupLinkForTestWithQdisc(t, "foo")
_, link2 := setupLinkForTestWithQdisc(t, "bar")
filter := &MatchAll{
FilterAttrs: FilterAttrs{
LinkIndex: link.Attrs().Index,
Parent: HANDLE_MIN_EGRESS,
Priority: 32000,
Protocol: unix.ETH_P_ALL,
},
Actions: []Action{
&MirredAction{
ActionAttrs: ActionAttrs{
Action: TC_ACT_STOLEN,
},
MirredAction: TCA_EGRESS_REDIR,
Ifindex: link2.Attrs().Index,
},
},
}
if err := FilterAdd(filter); err != nil {
t.Fatal(err)
}

filters, err := FilterList(link, HANDLE_MIN_EGRESS)
if err != nil {
t.Fatal(err)
}
if len(filters) != 1 {
t.Fatal("Failed to add filter")
}
matchall, ok := filters[0].(*MatchAll)
if !ok {
t.Fatal("Filter is the wrong type")
}

if matchall.Priority != 32000 {
t.Fatal("Filter priority does not match")
}

if len(matchall.Actions) != 1 {
t.Fatal("Filter has no actions")
}

mirredAction, ok := matchall.Actions[0].(*MirredAction)
if !ok {
t.Fatal("Action does not match")
}

if mirredAction.Ifindex != link2.Attrs().Index {
t.Fatal("Action ifindex does not match")
}

if err := FilterDel(filter); err != nil {
t.Fatal(err)
}
filters, err = FilterList(link, HANDLE_MIN_EGRESS)
if err != nil {
t.Fatal(err)
}
if len(filters) != 0 {
t.Fatal("Failed to remove filter")
}

}
7 changes: 7 additions & 0 deletions nl/tc_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -673,3 +673,10 @@ const (
TCA_FW_MASK
TCA_FW_MAX = TCA_FW_MASK
)

const (
TCA_MATCHALL_UNSPEC = iota
TCA_MATCHALL_CLASSID
TCA_MATCHALL_ACT
TCA_MATCHALL_FLAGS
)