Пример #1
0
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
}
Пример #2
0
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
}
Пример #3
0
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
}
Пример #4
0
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
}
Пример #5
0
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
}
Пример #6
0
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
}