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 setFqCodelFd(iface netlink.Link, path string) error { fd, err := netlink.BpfOpen(path) if err != nil { return fmt.Errorf("failed loading bpf program %v", err) } defer syscall.Close(fd) fq := &netlink.GenericQdisc{ QdiscAttrs: netlink.QdiscAttrs{ LinkIndex: iface.Attrs().Index, Handle: netlink.MakeHandle(1, 0), Parent: netlink.HANDLE_ROOT, }, QdiscType: "fq_codel", } if err := netlink.QdiscAdd(fq); err != nil { return fmt.Errorf("failed setting egress qdisc: %v", err) } u32 := &netlink.U32{ FilterAttrs: netlink.FilterAttrs{ LinkIndex: iface.Attrs().Index, Parent: fq.QdiscAttrs.Handle, Protocol: syscall.ETH_P_ALL, //Handle: 10, //Priority: 10, }, ClassId: netlink.MakeHandle(1, 2), BpfFd: fd, } if err := netlink.FilterAdd(u32); err != nil { return fmt.Errorf("failed adding egress filter: %v", err) } return nil }
func setIngressFd(iface netlink.Link, path string) error { fd, err := netlink.BpfOpen(path) if err != nil { return fmt.Errorf("failed loading bpf program %v", err) } defer syscall.Close(fd) ingress := &netlink.Ingress{ QdiscAttrs: netlink.QdiscAttrs{ LinkIndex: iface.Attrs().Index, Handle: netlink.MakeHandle(0xffff, 0), Parent: netlink.HANDLE_INGRESS, }, } if err := netlink.QdiscAdd(ingress); err != nil { return fmt.Errorf("failed setting ingress qdisc: %v", err) } u32 := &netlink.U32{ FilterAttrs: netlink.FilterAttrs{ LinkIndex: iface.Attrs().Index, Parent: ingress.QdiscAttrs.Handle, Priority: 1, Protocol: syscall.ETH_P_ALL, }, ClassId: netlink.MakeHandle(1, 1), BpfFd: fd, } if err := netlink.FilterAdd(u32); err != nil { return fmt.Errorf("failed adding ingress filter: %v", err) } return nil }
func setFqCodelFd(ifc, fd int) error { fq := &netlink.GenericQdisc{ QdiscAttrs: netlink.QdiscAttrs{ LinkIndex: ifc, Handle: netlink.MakeHandle(1, 0), Parent: netlink.HANDLE_ROOT, }, QdiscType: "fq_codel", } if err := netlink.QdiscAdd(fq); err != nil { return fmt.Errorf("failed setting egress qdisc: %v", err) } u32 := &netlink.U32{ FilterAttrs: netlink.FilterAttrs{ LinkIndex: ifc, Parent: fq.QdiscAttrs.Handle, Protocol: syscall.ETH_P_ALL, //Handle: 10, //Priority: 10, }, ClassId: netlink.MakeHandle(1, 2), BpfFd: fd, } if err := netlink.FilterAdd(u32); err != nil { return fmt.Errorf("failed adding egress filter: %v", err) } return nil }
func setIngressFd(ifc, fd int) error { ingress := &netlink.Ingress{ QdiscAttrs: netlink.QdiscAttrs{ LinkIndex: ifc, Handle: netlink.MakeHandle(0xffff, 0), Parent: netlink.HANDLE_INGRESS, }, } if err := netlink.QdiscAdd(ingress); err != nil { return fmt.Errorf("failed setting ingress qdisc: %v", err) } u32 := &netlink.U32{ FilterAttrs: netlink.FilterAttrs{ LinkIndex: ifc, Parent: ingress.QdiscAttrs.Handle, Priority: 1, Protocol: syscall.ETH_P_ALL, }, ClassId: netlink.MakeHandle(1, 1), BpfFd: fd, } if err := netlink.FilterAdd(u32); err != nil { return fmt.Errorf("failed adding ingress 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 }