Message ID | 20200804081429.1032-1-rsalvaterra@gmail.com |
---|---|
State | Not Applicable |
Headers | show |
Series | [v2] busybox: fix fwmark and add fwmask support to ip rule | expand |
Hi Rui, On 03.08.20 22:14, Rui Salvaterra wrote: > BusyBox ip (rule) applet supports fwmark for policy routing (albeit through the > old and deprecated RTA_PROTOINFO message attribute), but fwmask is completely > unsupported. For this reason, mwan3 depends on ip(-tiny), which compiles to > over 280 kiB on MIPS32 (-mips16 -mtune=74kc -O2). > > This pending [1] BusyBox patch modernises the fwmark implementation (using the > FRA_FWMARK attribute) and also implements fwmask (FRA_FWMASK) required by mwan3, > allowing it to drop its dependecy on ip. > > Other potential candidates for dropping their ip dependency (relying only on > BusyBox ip) are shadowsocks-libev, strongswan and vpn-policy-routing. > > [1] http://lists.busybox.net/pipermail/busybox/2020-July/088164.html > > Signed-off-by: Rui Salvaterra <rsalvaterra@gmail.com> Not run-time tested but seem to compile fine on multiple architectures! Size increase is between 70-140B[1]. What do you think about the PROVIDES idea of Yousong? [1]: https://gitlab.com/aparcar/openwrt/-/jobs/669753470 > --- > package/utils/busybox/Makefile | 2 +- > .../302-ip-rule-add-support-for-fwmask.patch | 90 +++++++++++++++++++ > 2 files changed, 91 insertions(+), 1 deletion(-) > create mode 100644 package/utils/busybox/patches/302-ip-rule-add-support-for-fwmask.patch > > diff --git a/package/utils/busybox/Makefile b/package/utils/busybox/Makefile > index 01441d1e87..baf375eb13 100644 > --- a/package/utils/busybox/Makefile > +++ b/package/utils/busybox/Makefile > @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk > > PKG_NAME:=busybox > PKG_VERSION:=1.31.1 > -PKG_RELEASE:=1 > +PKG_RELEASE:=2 > PKG_FLAGS:=essential > > PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 > diff --git a/package/utils/busybox/patches/302-ip-rule-add-support-for-fwmask.patch b/package/utils/busybox/patches/302-ip-rule-add-support-for-fwmask.patch > new file mode 100644 > index 0000000000..abdc309068 > --- /dev/null > +++ b/package/utils/busybox/patches/302-ip-rule-add-support-for-fwmask.patch > @@ -0,0 +1,90 @@ > +From f06ac1e49b4a5a57660c7b370a7ebd436981bd89 Mon Sep 17 00:00:00 2001 > +From: Rui Salvaterra <rsalvaterra@gmail.com> > +Date: Fri, 31 Jul 2020 09:59:40 +0100 > +Subject: [PATCH] ip rule: add support for fwmark/fwmask for policy routing > + > +This adds support for fwmark/fwmask in ip rule which is needed, for example, in > +OpenWrt's mwan3. Masks are supported since Linux 2.6.19. > + > +Fixes: https://bugs.busybox.net/show_bug.cgi?id=11621 > + > +Signed-off-by: Rui Salvaterra <rsalvaterra@gmail.com> > +--- > + networking/ip.c | 2 +- > + networking/libiproute/iprule.c | 31 +++++++++++++++++++++++++------ > + 2 files changed, 26 insertions(+), 7 deletions(-) > + > +diff --git a/networking/ip.c b/networking/ip.c > +index 034ee4fc8..bade93e62 100644 > +--- a/networking/ip.c > ++++ b/networking/ip.c > +@@ -257,7 +257,7 @@ > + //usage:#define iprule_trivial_usage > + //usage: "[list] | add|del SELECTOR ACTION" > + //usage:#define iprule_full_usage "\n\n" > +-//usage: " SELECTOR := [from PREFIX] [to PREFIX] [tos TOS] [fwmark FWMARK]\n" > ++//usage: " SELECTOR := [from PREFIX] [to PREFIX] [tos TOS] [fwmark FWMARK[/MASK] ]\n" > + //usage: " [dev IFACE] [pref NUMBER]\n" > + //usage: " ACTION := [table TABLE_ID] [nat ADDR]\n" > + //usage: " [prohibit|reject|unreachable]\n" > +diff --git a/networking/libiproute/iprule.c b/networking/libiproute/iprule.c > +index 0ce0dfeef..40a09a4ab 100644 > +--- a/networking/libiproute/iprule.c > ++++ b/networking/libiproute/iprule.c > +@@ -17,8 +17,10 @@ > + #include <arpa/inet.h> > + > + /* from <linux/fib_rules.h>: */ > +-#define FRA_SUPPRESS_IFGROUP 13 > +-#define FRA_SUPPRESS_PREFIXLEN 14 > ++#define FRA_FWMARK 10 > ++#define FRA_SUPPRESS_IFGROUP 13 > ++#define FRA_SUPPRESS_PREFIXLEN 14 > ++#define FRA_FWMASK 16 > + > + #include "ip_common.h" /* #include "libbb.h" is inside */ > + #include "rt_names.h" > +@@ -117,8 +119,18 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM, > + if (r->rtm_tos) { > + printf("tos %s ", rtnl_dsfield_n2a(r->rtm_tos)); > + } > +- if (tb[RTA_PROTOINFO]) { > +- printf("fwmark %#x ", *(uint32_t*)RTA_DATA(tb[RTA_PROTOINFO])); > ++ > ++ if (tb[FRA_FWMARK] || tb[FRA_FWMASK]) { > ++ uint32_t mark = 0, mask = 0; > ++ > ++ if (tb[FRA_FWMARK]) > ++ mark = *(uint32_t*)RTA_DATA(tb[FRA_FWMARK]); > ++ > ++ if (tb[FRA_FWMASK] && > ++ (mask = *(uint32_t*)RTA_DATA(tb[FRA_FWMASK])) != 0xFFFFFFFF) > ++ printf("fwmark %#x/%#x ", mark, mask); > ++ else > ++ printf("fwmark %#x ", mark); > + } > + > + if (tb[RTA_IIF]) { > +@@ -257,10 +269,17 @@ static int iprule_modify(int cmd, char **argv) > + invarg_1_to_2(*argv, "TOS"); > + req.r.rtm_tos = tos; > + } else if (key == ARG_fwmark) { > +- uint32_t fwmark; > ++ char *slash; > ++ uint32_t fwmark, fwmask; > + NEXT_ARG(); > ++ if ((slash = strchr(*argv, '/')) != NULL) > ++ *slash = '\0'; > + fwmark = get_u32(*argv, keyword_fwmark); > +- addattr32(&req.n, sizeof(req), RTA_PROTOINFO, fwmark); > ++ addattr32(&req.n, sizeof(req), FRA_FWMARK, fwmark); > ++ if (slash) { > ++ fwmask = get_u32(slash + 1, "fwmask"); > ++ addattr32(&req.n, sizeof(req), FRA_FWMASK, fwmask); > ++ } > + } else if (key == ARG_realms) { > + uint32_t realm; > + NEXT_ARG(); > +-- > +2.28.0 > +
diff --git a/package/utils/busybox/Makefile b/package/utils/busybox/Makefile index 01441d1e87..baf375eb13 100644 --- a/package/utils/busybox/Makefile +++ b/package/utils/busybox/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=busybox PKG_VERSION:=1.31.1 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_FLAGS:=essential PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 diff --git a/package/utils/busybox/patches/302-ip-rule-add-support-for-fwmask.patch b/package/utils/busybox/patches/302-ip-rule-add-support-for-fwmask.patch new file mode 100644 index 0000000000..abdc309068 --- /dev/null +++ b/package/utils/busybox/patches/302-ip-rule-add-support-for-fwmask.patch @@ -0,0 +1,90 @@ +From f06ac1e49b4a5a57660c7b370a7ebd436981bd89 Mon Sep 17 00:00:00 2001 +From: Rui Salvaterra <rsalvaterra@gmail.com> +Date: Fri, 31 Jul 2020 09:59:40 +0100 +Subject: [PATCH] ip rule: add support for fwmark/fwmask for policy routing + +This adds support for fwmark/fwmask in ip rule which is needed, for example, in +OpenWrt's mwan3. Masks are supported since Linux 2.6.19. + +Fixes: https://bugs.busybox.net/show_bug.cgi?id=11621 + +Signed-off-by: Rui Salvaterra <rsalvaterra@gmail.com> +--- + networking/ip.c | 2 +- + networking/libiproute/iprule.c | 31 +++++++++++++++++++++++++------ + 2 files changed, 26 insertions(+), 7 deletions(-) + +diff --git a/networking/ip.c b/networking/ip.c +index 034ee4fc8..bade93e62 100644 +--- a/networking/ip.c ++++ b/networking/ip.c +@@ -257,7 +257,7 @@ + //usage:#define iprule_trivial_usage + //usage: "[list] | add|del SELECTOR ACTION" + //usage:#define iprule_full_usage "\n\n" +-//usage: " SELECTOR := [from PREFIX] [to PREFIX] [tos TOS] [fwmark FWMARK]\n" ++//usage: " SELECTOR := [from PREFIX] [to PREFIX] [tos TOS] [fwmark FWMARK[/MASK] ]\n" + //usage: " [dev IFACE] [pref NUMBER]\n" + //usage: " ACTION := [table TABLE_ID] [nat ADDR]\n" + //usage: " [prohibit|reject|unreachable]\n" +diff --git a/networking/libiproute/iprule.c b/networking/libiproute/iprule.c +index 0ce0dfeef..40a09a4ab 100644 +--- a/networking/libiproute/iprule.c ++++ b/networking/libiproute/iprule.c +@@ -17,8 +17,10 @@ + #include <arpa/inet.h> + + /* from <linux/fib_rules.h>: */ +-#define FRA_SUPPRESS_IFGROUP 13 +-#define FRA_SUPPRESS_PREFIXLEN 14 ++#define FRA_FWMARK 10 ++#define FRA_SUPPRESS_IFGROUP 13 ++#define FRA_SUPPRESS_PREFIXLEN 14 ++#define FRA_FWMASK 16 + + #include "ip_common.h" /* #include "libbb.h" is inside */ + #include "rt_names.h" +@@ -117,8 +119,18 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM, + if (r->rtm_tos) { + printf("tos %s ", rtnl_dsfield_n2a(r->rtm_tos)); + } +- if (tb[RTA_PROTOINFO]) { +- printf("fwmark %#x ", *(uint32_t*)RTA_DATA(tb[RTA_PROTOINFO])); ++ ++ if (tb[FRA_FWMARK] || tb[FRA_FWMASK]) { ++ uint32_t mark = 0, mask = 0; ++ ++ if (tb[FRA_FWMARK]) ++ mark = *(uint32_t*)RTA_DATA(tb[FRA_FWMARK]); ++ ++ if (tb[FRA_FWMASK] && ++ (mask = *(uint32_t*)RTA_DATA(tb[FRA_FWMASK])) != 0xFFFFFFFF) ++ printf("fwmark %#x/%#x ", mark, mask); ++ else ++ printf("fwmark %#x ", mark); + } + + if (tb[RTA_IIF]) { +@@ -257,10 +269,17 @@ static int iprule_modify(int cmd, char **argv) + invarg_1_to_2(*argv, "TOS"); + req.r.rtm_tos = tos; + } else if (key == ARG_fwmark) { +- uint32_t fwmark; ++ char *slash; ++ uint32_t fwmark, fwmask; + NEXT_ARG(); ++ if ((slash = strchr(*argv, '/')) != NULL) ++ *slash = '\0'; + fwmark = get_u32(*argv, keyword_fwmark); +- addattr32(&req.n, sizeof(req), RTA_PROTOINFO, fwmark); ++ addattr32(&req.n, sizeof(req), FRA_FWMARK, fwmark); ++ if (slash) { ++ fwmask = get_u32(slash + 1, "fwmask"); ++ addattr32(&req.n, sizeof(req), FRA_FWMASK, fwmask); ++ } + } else if (key == ARG_realms) { + uint32_t realm; + NEXT_ARG(); +-- +2.28.0 +
BusyBox ip (rule) applet supports fwmark for policy routing (albeit through the old and deprecated RTA_PROTOINFO message attribute), but fwmask is completely unsupported. For this reason, mwan3 depends on ip(-tiny), which compiles to over 280 kiB on MIPS32 (-mips16 -mtune=74kc -O2). This pending [1] BusyBox patch modernises the fwmark implementation (using the FRA_FWMARK attribute) and also implements fwmask (FRA_FWMASK) required by mwan3, allowing it to drop its dependecy on ip. Other potential candidates for dropping their ip dependency (relying only on BusyBox ip) are shadowsocks-libev, strongswan and vpn-policy-routing. [1] http://lists.busybox.net/pipermail/busybox/2020-July/088164.html Signed-off-by: Rui Salvaterra <rsalvaterra@gmail.com> --- package/utils/busybox/Makefile | 2 +- .../302-ip-rule-add-support-for-fwmask.patch | 90 +++++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 package/utils/busybox/patches/302-ip-rule-add-support-for-fwmask.patch