ip rule: add suppress_{prefixlength,ifgroup} options
No binary (build failed)
—
(log yok)
| @@ -17,25 +17,32 @@ | |
| #include <netinet/ip.h> | |
| #include <arpa/inet.h> | |
| + | /* from <linux/fib_rules.h>: */ |
| + | #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 struct sockaddr_nl *who UNUSED_PARAM, | |
| 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 **argv) | |
| ) { | |
| 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 **argv) | |
| } 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 **argv) | |
| 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 | |
| ) { | |