ip rule: add support for fwmark/fwmask for policy routing
No binary (build failed)
—
(log yok)
| @@ -252,7 +252,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" | |
| @@ -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,18 @@ 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(); | |
| + | slash = strchr(*argv, '/'); |
| + | if (slash) |
| + | *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(); | |