diff --git a/ip/iprule.c b/ip/iprule.c index a5fcd432..d934f67d 100644 --- a/ip/iprule.c +++ b/ip/iprule.c @@ -39,6 +39,9 @@ static void usage(void) fprintf(stderr, " [ prohibit | reject | unreachable ]\n"); fprintf(stderr, " [ realms [SRCREALM/]DSTREALM ]\n"); fprintf(stderr, " [ goto NUMBER ]\n"); + fprintf(stderr, " SUPPRESSOR\n"); + fprintf(stderr, "SUPPRESSOR := [ suppress_prefixlength NUMBER ]\n"); + fprintf(stderr, " [ suppress_ifgroup DEVGROUP ]\n"); fprintf(stderr, "TABLE_ID := [ local | main | default | NUMBER ]\n"); exit(-1); } @@ -153,9 +156,24 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) } table = rtm_get_table(r, tb); - if (table) + if (table) { fprintf(fp, "lookup %s ", rtnl_rttable_n2a(table, b1, sizeof(b1))); + if (tb[FRA_SUPPRESS_PREFIXLEN]) { + int pl = rta_getattr_u32(tb[FRA_SUPPRESS_PREFIXLEN]); + if (pl != -1) { + fprintf(fp, "suppress_prefixlength %d ", pl); + } + } + if (tb[FRA_SUPPRESS_IFGROUP]) { + int group = rta_getattr_u32(tb[FRA_SUPPRESS_IFGROUP]); + if (group != -1) { + SPRINT_BUF(b1); + fprintf(fp, "suppress_ifgroup %s ", rtnl_group_n2a(group, b1, sizeof(b1))); + } + } + } + if (tb[FRA_FLOW]) { __u32 to = rta_getattr_u32(tb[FRA_FLOW]); __u32 from = to>>16; @@ -310,6 +328,20 @@ static int iprule_modify(int cmd, int argc, char **argv) addattr32(&req.n, sizeof(req), FRA_TABLE, tid); } table_ok = 1; + } else if (matches(*argv, "suppress_prefixlength") == 0 || + strcmp(*argv, "sup_pl") == 0) { + int pl; + NEXT_ARG(); + if (get_s32(&pl, *argv, 0) || pl < 0) + invarg("suppress_prefixlength value is invalid\n", *argv); + addattr32(&req.n, sizeof(req), FRA_SUPPRESS_PREFIXLEN, pl); + } else if (matches(*argv, "suppress_ifgroup") == 0 || + strcmp(*argv, "sup_group") == 0) { + NEXT_ARG(); + int group; + if (rtnl_group_a2n(&group, *argv)) + invarg("Invalid \"suppress_ifgroup\" value\n", *argv); + addattr32(&req.n, sizeof(req), FRA_SUPPRESS_IFGROUP, group); } else if (strcmp(*argv, "dev") == 0 || strcmp(*argv, "iif") == 0) { NEXT_ARG(); diff --git a/man/man8/ip-rule.8 b/man/man8/ip-rule.8 index 36e46f1b..62df3b0b 100644 --- a/man/man8/ip-rule.8 +++ b/man/man8/ip-rule.8 @@ -43,6 +43,14 @@ ip-rule \- routing policy database management .IR ADDRESS " ] [ " .BR prohibit " | " reject " | " unreachable " ] [ " realms .RI "[" SRCREALM "/]" DSTREALM " ]" +.I SUPPRESSOR + +.ti -8 +.IR SUPPRESSOR " := [ " +.B suppress_prefixlength +.IR NUMBER " ] [ " +.B suppress_ifgroup +.IR GROUP " ]" .ti -8 .IR TABLE_ID " := [ " @@ -216,6 +224,15 @@ The options preference and order are synonyms with priority. the routing table identifier to lookup if the rule selector matches. It is also possible to use lookup instead of table. +.TP +.BI suppress_prefixlength " NUMBER" +reject routing decisions that have a prefix length of NUMBER or less. + +.TP +.BI suppress_ifgroup " GROUP" +reject routing decisions that use a device belonging to the interface +group GROUP. + .TP .BI realms " FROM/TO" Realms to select if the rule matched and the routing table lookup