From: Stefan Tomanek Date: Mon, 19 Jun 2017 10:41:11 +0000 (+0200) Subject: busybox: backport 'ip rule suppress_{prefixlength, ifgroup}' X-Git-Tag: v17.01.5~198 X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=3129db331c366e5cafe43b7ec74f92990d01171c;p=openwrt%2Fopenwrt.git busybox: backport 'ip rule suppress_{prefixlength, ifgroup}' This is a backport from the busybox repository (192dce4b84fb32346ebc5194de7daa5da3b8d1b4); it enables the use of the suppress_{prefixlength,ifgroup} flags for policy routing rules. Signed-off-by: Stefan Tomanek (cherry picked from commit de6ff1512955953e56735896c044c7aac97e14d9) --- diff --git a/package/utils/busybox/patches/302-ip-rule-add-suppress-prefixlength.patch b/package/utils/busybox/patches/302-ip-rule-add-suppress-prefixlength.patch new file mode 100644 index 0000000000..7b4797505e --- /dev/null +++ b/package/utils/busybox/patches/302-ip-rule-add-suppress-prefixlength.patch @@ -0,0 +1,145 @@ +From dbac30c3784c267bbe44a2a3ebed4e827c8fe82a Mon Sep 17 00:00:00 2001 +From: Stefan Tomanek +Date: Tue, 13 Jun 2017 19:06:09 +0200 +Subject: [PATCH] ip rule: add suppress_{prefixlength,ifgroup} options + +(cherry-picked from 192dce4b84fb32346ebc5194de7daa5da3b8d1b4) + +function old new delta +iprule_modify 816 887 +71 +print_rule 610 680 +70 +------------------------------------------------------------------------------ +(add/remove: 0/0 grow/shrink: 2/0 up/down: 141/0) Total: 141 bytes + +Signed-off-by: Stefan Tomanek +Signed-off-by: Denys Vlasenko +--- + networking/libiproute/iprule.c | 73 ++++++++++++++++++++++++++---------------- + 1 file changed, 46 insertions(+), 27 deletions(-) + +--- a/networking/libiproute/iprule.c ++++ b/networking/libiproute/iprule.c +@@ -17,25 +17,32 @@ + #include + #include + ++/* from : */ ++#define FRA_SUPPRESS_IFGROUP 13 ++#define FRA_SUPPRESS_PREFIXLEN 14 ++ + #include "ip_common.h" /* #include "libbb.h" is inside */ + #include "rt_names.h" + #include "utils.h" + +-/* +-static void usage(void) __attribute__((noreturn)); +- +-static void usage(void) +-{ +- fprintf(stderr, "Usage: ip rule [ list | add | del ] SELECTOR ACTION\n"); +- fprintf(stderr, "SELECTOR := [ from PREFIX ] [ to PREFIX ] [ tos TOS ] [ fwmark FWMARK ]\n"); +- fprintf(stderr, " [ dev STRING ] [ pref NUMBER ]\n"); +- fprintf(stderr, "ACTION := [ table TABLE_ID ] [ nat ADDRESS ]\n"); +- fprintf(stderr, " [ prohibit | reject | unreachable ]\n"); +- fprintf(stderr, " [ realms [SRCREALM/]DSTREALM ]\n"); +- fprintf(stderr, "TABLE_ID := [ local | main | default | NUMBER ]\n"); +- exit(-1); +-} +-*/ ++/* If you add stuff here, update iprule_full_usage */ ++static const char keywords[] ALIGN1 = ++ "from\0""to\0""preference\0""order\0""priority\0" ++ "tos\0""fwmark\0""realms\0""table\0""lookup\0" ++ "suppress_prefixlength\0""suppress_ifgroup\0" ++ "dev\0""iif\0""nat\0""map-to\0""type\0""help\0" ++ ; ++#define keyword_preference (keywords + sizeof("from") + sizeof("to")) ++#define keyword_fwmark (keyword_preference + sizeof("preference") + sizeof("order") + sizeof("priority") + sizeof("tos")) ++#define keyword_realms (keyword_fwmark + sizeof("fwmark")) ++#define keyword_suppress_prefixlength (keyword_realms + sizeof("realms") + sizeof("table") + sizeof("lookup")) ++#define keyword_suppress_ifgroup (keyword_suppress_prefixlength + sizeof("suppress_prefixlength")) ++enum { ++ ARG_from = 1, ARG_to, ARG_preference, ARG_order, ARG_priority, ++ ARG_tos, ARG_fwmark, ARG_realms, ARG_table, ARG_lookup, ++ ARG_suppress_prefixlength, ARG_suppress_ifgroup, ++ ARG_dev, ARG_iif, ARG_nat, ARG_map_to, ARG_type, ARG_help, ++}; + + static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM, + struct nlmsghdr *n, void *arg UNUSED_PARAM) +@@ -119,6 +126,17 @@ static int FAST_FUNC print_rule(const st + else if (r->rtm_table) + printf("lookup %s ", rtnl_rttable_n2a(r->rtm_table)); + ++ if (tb[FRA_SUPPRESS_PREFIXLEN]) { ++ int pl = *(uint32_t*)RTA_DATA(tb[FRA_SUPPRESS_PREFIXLEN]); ++ if (pl != -1) ++ printf("%s %d ", keyword_suppress_prefixlength, pl); ++ } ++ if (tb[FRA_SUPPRESS_IFGROUP]) { ++ int grp = *(uint32_t*)RTA_DATA(tb[FRA_SUPPRESS_IFGROUP]); ++ if (grp != -1) ++ printf("%s %d ", keyword_suppress_ifgroup, grp); ++ } ++ + if (tb[RTA_FLOW]) { + uint32_t to = *(uint32_t*)RTA_DATA(tb[RTA_FLOW]); + uint32_t from = to>>16; +@@ -174,15 +192,6 @@ static int iprule_list(char **argv) + /* Return value becomes exitcode. It's okay to not return at all */ + static int iprule_modify(int cmd, char **argv) + { +- static const char keywords[] ALIGN1 = +- "from\0""to\0""preference\0""order\0""priority\0" +- "tos\0""fwmark\0""realms\0""table\0""lookup\0""dev\0" +- "iif\0""nat\0""map-to\0""type\0""help\0"; +- enum { +- ARG_from = 1, ARG_to, ARG_preference, ARG_order, ARG_priority, +- ARG_tos, ARG_fwmark, ARG_realms, ARG_table, ARG_lookup, ARG_dev, +- ARG_iif, ARG_nat, ARG_map_to, ARG_type, ARG_help +- }; + bool table_ok = 0; + struct rtnl_handle rth; + struct { +@@ -232,7 +241,7 @@ static int iprule_modify(int cmd, char * + ) { + uint32_t pref; + NEXT_ARG(); +- pref = get_u32(*argv, "preference"); ++ pref = get_u32(*argv, keyword_preference); + addattr32(&req.n, sizeof(req), RTA_PRIORITY, pref); + } else if (key == ARG_tos) { + uint32_t tos; +@@ -243,13 +252,13 @@ static int iprule_modify(int cmd, char * + } else if (key == ARG_fwmark) { + uint32_t fwmark; + NEXT_ARG(); +- fwmark = get_u32(*argv, "fwmark"); ++ fwmark = get_u32(*argv, keyword_fwmark); + addattr32(&req.n, sizeof(req), RTA_PROTOINFO, fwmark); + } else if (key == ARG_realms) { + uint32_t realm; + NEXT_ARG(); + if (get_rt_realms(&realm, *argv)) +- invarg_1_to_2(*argv, "realms"); ++ invarg_1_to_2(*argv, keyword_realms); + addattr32(&req.n, sizeof(req), RTA_FLOW, realm); + } else if (key == ARG_table || + key == ARG_lookup +@@ -265,6 +274,16 @@ static int iprule_modify(int cmd, char * + addattr32(&req.n, sizeof(req), RTA_TABLE, tid); + } + table_ok = 1; ++ } else if (key == ARG_suppress_prefixlength) { ++ int prefix_length; ++ NEXT_ARG(); ++ prefix_length = get_u32(*argv, keyword_suppress_prefixlength); ++ addattr32(&req.n, sizeof(req), FRA_SUPPRESS_PREFIXLEN, prefix_length); ++ } else if (key == ARG_suppress_ifgroup) { ++ int grp; ++ NEXT_ARG(); ++ grp = get_u32(*argv, keyword_suppress_ifgroup); ++ addattr32(&req.n, sizeof(req), FRA_SUPPRESS_IFGROUP, grp); + } else if (key == ARG_dev || + key == ARG_iif + ) {