mirror of https://github.com/vishvananda/netlink
Add Matchall filter
This commit is contained in:
parent
7b4c06360e
commit
1882fa99fc
15
filter.go
15
filter.go
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
@ -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}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
|
|
@ -168,13 +168,13 @@ func TestAdvancedFilterAddDel(t *testing.T) {
|
|||
}
|
||||
|
||||
u32SelKeys := []TcU32Key{
|
||||
TcU32Key{
|
||||
{
|
||||
Mask: 0xff,
|
||||
Val: 80,
|
||||
Off: 20,
|
||||
OffMask: 0,
|
||||
},
|
||||
TcU32Key{
|
||||
{
|
||||
Mask: 0xffff,
|
||||
Val: 0x146ca,
|
||||
Off: 32,
|
||||
|
@ -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) {
|
||||
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)
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -643,7 +649,7 @@ 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)
|
||||
}
|
||||
|
@ -651,3 +657,74 @@ func TestFilterClsActBpfAddDel(t *testing.T) {
|
|||
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")
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue