From: Felix Fietkau Date: Fri, 18 Mar 2022 11:24:42 +0000 (+0100) Subject: interface: rework adding/removing filters, do not delete clsact X-Git-Url: http://git.openwrt.org/feed/routing.git%5Ed11075cd40a88602bf4ba2b275f72100ddcb4767?a=commitdiff_plain;h=8fbaf39dbc957bd5b46686cb54532ce4db677e7b;p=project%2Fqosify.git interface: rework adding/removing filters, do not delete clsact This allows qosify to coexist with other services that need to add filters on clsact Signed-off-by: Felix Fietkau --- diff --git a/interface.c b/interface.c index 056c52f..667cf12 100644 --- a/interface.c +++ b/interface.c @@ -195,36 +195,27 @@ interface_ifb_name(struct qosify_iface *iface) } static int -prepare_tc_cmd(char *buf, int len, const char *type, const char *cmd, - const char *dev, const char *extra) +prepare_qdisc_cmd(char *buf, int len, const char *dev, bool add, const char *type) { - return snprintf(buf, len, "tc %s %s dev '%s' %s", type, cmd, dev, extra); + return snprintf(buf, len, "tc qdisc %s dev '%s' %s", + add ? "add" : "del", dev, type); } static int -__cmd_add_del_qdisc(const char *ifname, const char *type, bool add) +prepare_filter_cmd(char *buf, int len, const char *dev, int prio, bool add, bool egress) { - char buf[64]; - - prepare_tc_cmd(buf, sizeof(buf), "qdisc", add ? "add" : "del", ifname, type); - - return qosify_run_cmd(buf, true); -} - -static int -cmd_del_qdisc(const char *ifname, const char *type) -{ - return __cmd_add_del_qdisc(ifname, type, false); + return snprintf(buf, len, "tc filter %s dev '%s' %sgress prio %d", + add ? "add" : "del", dev, egress ? "e" : "in", prio); } static int -cmd_add_bpf_filter(const char *ifname, bool egress, bool eth) +cmd_add_bpf_filter(const char *ifname, int prio, bool egress, bool eth) { char buf[512]; int ofs; - ofs = prepare_tc_cmd(buf, sizeof(buf), "filter", "add", ifname, egress ? "egress" : "ingress"); - APPEND(buf, ofs, " prio 10 bpf object-pinned /sys/fs/bpf/qosify_%sgress_%s verbose direct-action", + ofs = prepare_filter_cmd(buf, sizeof(buf), ifname, prio, true, egress); + APPEND(buf, ofs, " bpf object-pinned /sys/fs/bpf/qosify_%sgress_%s verbose direct-action", egress ? "e" : "in", eth ? "eth" : "ip"); @@ -240,9 +231,10 @@ cmd_add_qdisc(struct qosify_iface *iface, const char *ifname, bool egress, bool char buf[512]; int ofs; - __cmd_add_del_qdisc(ifname, "clsact", true); + ofs = prepare_qdisc_cmd(buf, sizeof(buf), ifname, true, "clsact"); + qosify_run_cmd(buf, true); - ofs = prepare_tc_cmd(buf, sizeof(buf), "qdisc", "add", ifname, "root cake"); + ofs = prepare_qdisc_cmd(buf, sizeof(buf), ifname, true, "root cake"); if (bw) APPEND(buf, ofs, " bandwidth %s", bw); @@ -264,44 +256,36 @@ cmd_add_qdisc(struct qosify_iface *iface, const char *ifname, bool egress, bool return qosify_run_cmd(buf, false); } -static int -cmd_del_ingress(struct qosify_iface *iface) -{ - char buf[256]; - - snprintf(buf, sizeof(buf), "ip link del '%s'", interface_ifb_name(iface)); - - return qosify_run_cmd(buf, true); -} - static int cmd_add_ingress(struct qosify_iface *iface, bool eth) { const char *ifbdev = interface_ifb_name(iface); char buf[256]; + int prio = QOSIFY_PRIO_BASE; int ofs; - ofs = prepare_tc_cmd(buf, sizeof(buf), "filter", "add", iface->ifname, " ingress"); - APPEND(buf, ofs, " protocol ip prio 5 u32 match ip sport 53 0xffff " + cmd_add_bpf_filter(iface->ifname, prio++, false, eth); + + ofs = prepare_filter_cmd(buf, sizeof(buf), iface->ifname, prio++, true, false); + APPEND(buf, ofs, " protocol ip u32 match ip sport 53 0xffff " "flowid 1:1 action mirred egress redirect dev ifb-dns"); qosify_run_cmd(buf, false); - ofs = prepare_tc_cmd(buf, sizeof(buf), "filter", "add", iface->ifname, " ingress"); - APPEND(buf, ofs, " protocol 802.1Q prio 6 u32 offset plus 4 match ip sport 53 0xffff " + ofs = prepare_filter_cmd(buf, sizeof(buf), iface->ifname, prio++, true, false); + APPEND(buf, ofs, " protocol 802.1Q u32 offset plus 4 match ip sport 53 0xffff " "flowid 1:1 action mirred egress redirect dev ifb-dns"); qosify_run_cmd(buf, false); - ofs = prepare_tc_cmd(buf, sizeof(buf), "filter", "add", iface->ifname, " ingress"); - APPEND(buf, ofs, " protocol ipv6 prio 7 u32 match ip6 sport 53 0xffff " + ofs = prepare_filter_cmd(buf, sizeof(buf), iface->ifname, prio++, true, false); + APPEND(buf, ofs, " protocol ipv6 u32 match ip6 sport 53 0xffff " "flowid 1:1 action mirred egress redirect dev ifb-dns"); qosify_run_cmd(buf, false); - ofs = prepare_tc_cmd(buf, sizeof(buf), "filter", "add", iface->ifname, " ingress"); - APPEND(buf, ofs, " protocol ipv6 prio 8 u32 offset plus 4 match ip6 sport 53 0xffff " + ofs = prepare_filter_cmd(buf, sizeof(buf), iface->ifname, prio++, true, false); + APPEND(buf, ofs, " protocol ipv6 u32 offset plus 4 match ip6 sport 53 0xffff " "flowid 1:1 action mirred egress redirect dev ifb-dns"); qosify_run_cmd(buf, false); - cmd_add_bpf_filter(iface->ifname, false, eth); if (!iface->config.ingress) return 0; @@ -314,9 +298,9 @@ cmd_add_ingress(struct qosify_iface *iface, bool eth) snprintf(buf, sizeof(buf), "ip link set dev '%s' up", ifbdev); qosify_run_cmd(buf, false); - ofs = prepare_tc_cmd(buf, sizeof(buf), "filter", "add", iface->ifname, " ingress"); - APPEND(buf, ofs, " protocol all prio 20 u32 match u32 0 0 " - "flowid 1:1 action mirred egress redirect dev '%s'", ifbdev); + ofs = prepare_filter_cmd(buf, sizeof(buf), iface->ifname, prio++, true, false); + APPEND(buf, ofs, " protocol all u32 match u32 0 0 flowid 1:1" + " action mirred egress redirect dev '%s'", ifbdev); return qosify_run_cmd(buf, false); } @@ -327,15 +311,28 @@ static int cmd_add_egress(struct qosify_iface *iface, bool eth) cmd_add_qdisc(iface, iface->ifname, true, eth); - return cmd_add_bpf_filter(iface->ifname, true, eth); + return cmd_add_bpf_filter(iface->ifname, QOSIFY_PRIO_BASE, true, eth); } static void interface_clear_qdisc(struct qosify_iface *iface) { - cmd_del_qdisc(iface->ifname, "root"); - cmd_del_qdisc(iface->ifname, "clsact"); - cmd_del_ingress(iface); + char buf[64]; + int i; + + prepare_qdisc_cmd(buf, sizeof(buf), iface->ifname, false, "root"); + qosify_run_cmd(buf, true); + + for (i = 0; i < 6; i++) { + prepare_filter_cmd(buf, sizeof(buf), iface->ifname, QOSIFY_PRIO_BASE + i, false, false); + qosify_run_cmd(buf, true); + } + + prepare_filter_cmd(buf, sizeof(buf), iface->ifname, QOSIFY_PRIO_BASE, false, true); + qosify_run_cmd(buf, true); + + snprintf(buf, sizeof(buf), "ip link del '%s'", interface_ifb_name(iface)); + qosify_run_cmd(buf, true); } static void diff --git a/qosify.h b/qosify.h index bd08879..5f14d4a 100644 --- a/qosify.h +++ b/qosify.h @@ -26,6 +26,8 @@ #define QOSIFY_DNS_IFNAME "ifb-dns" +#define QOSIFY_PRIO_BASE 0x110 + enum qosify_map_id { CL_MAP_TCP_PORTS, CL_MAP_UDP_PORTS,