func ensureEgressFd(link netlink.Link, fd int) error { q, err := ensureQdisc(link, "fq_codel", netlink.MakeHandle(1, 0), netlink.HANDLE_ROOT) if err != nil { return err } fHandle := netlink.MakeHandle(0, 2) filter := &netlink.U32{ FilterAttrs: netlink.FilterAttrs{ LinkIndex: link.Attrs().Index, Parent: q.Attrs().Handle, Priority: 1, Protocol: syscall.ETH_P_ALL, }, Actions: []netlink.Action{ &netlink.BpfAction{Fd: fd, Name: "bpf1"}, }, ClassId: fHandle, } filters, err := netlink.FilterList(link, netlink.HANDLE_MIN_EGRESS) if err != nil { return fmt.Errorf("failed fetching egress filter list: %s", err) } for _, f := range filters { if f, ok := f.(*netlink.U32); ok { if f.ClassId == fHandle { return nil } } } if err := netlink.FilterAdd(filter); err != nil { return fmt.Errorf("failed adding egress filter: %v", err) } return nil }
func ensureIngressFd(link netlink.Link, fd int) error { q, err := ensureQdisc(link, "ingress", netlink.MakeHandle(0xffff, 0), netlink.HANDLE_INGRESS) if err != nil { return err } fHandle := netlink.MakeHandle(0, 1) filter := &netlink.U32{ FilterAttrs: netlink.FilterAttrs{ LinkIndex: link.Attrs().Index, Parent: q.Attrs().Handle, Priority: 1, Protocol: syscall.ETH_P_ALL, }, Actions: []netlink.Action{ &netlink.BpfAction{Fd: fd, Name: "bpf1"}, }, ClassId: fHandle, } filters, err := netlink.FilterList(link, netlink.HANDLE_MIN_INGRESS) if err != nil { return fmt.Errorf("failed fetching ingress filter list: %s", err) } for _, f := range filters { if f, ok := f.(*netlink.U32); ok { if f.ClassId == fHandle { return nil } // remove all previous filters to ensure the // current one is the only one to be executed netlink.FilterDel(f) } } if err := netlink.FilterAdd(filter); err != nil { return fmt.Errorf("failed adding ingress filter: %s", err) } //Debug.Printf("ensureIngressFd(%s) success\n", link.Attrs().Name) return nil }