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 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(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 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 ensureQdisc(link netlink.Link, qdiscType string, handle, parent uint32) (netlink.Qdisc, error) { qds, err := netlink.QdiscList(link) if err != nil { return nil, err } for _, q := range qds { if q.Attrs().Handle == handle { //Debug.Printf("Found existing ingress qdisc %x\n", q.Attrs().Handle) return q, nil } } qdisc := &netlink.GenericQdisc{ QdiscAttrs: netlink.QdiscAttrs{ LinkIndex: link.Attrs().Index, Handle: handle, Parent: parent, }, QdiscType: qdiscType, } if err := netlink.QdiscAdd(qdisc); err != nil { return nil, fmt.Errorf("failed ensuring qdisc: %v", err) } return qdisc, nil }