Message ID | 20180223193248.16744-3-sharpd@cumulusnetworks.com |
---|---|
State | Changes Requested, archived |
Delegated to: | David Ahern |
Headers | show |
Series | None | expand |
On 2/23/18 12:32 PM, Donald Sharp wrote: > @@ -391,6 +404,10 @@ static int flush_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, > > parse_rtattr(tb, FRA_MAX, RTM_RTA(frh), len); > > + if (tb[FRA_PROTOCOL] && > + (filter.protocol^rta_getattr_u8(tb[FRA_PROTOCOL]))&filter.protocolmask) > + return 0; > + Please use an intermediate variable for rta conversion and put whitespace around '^' and '&'; existing code that does the above is a poor example to follow. ;-) > if (tb[FRA_PRIORITY]) { > n->nlmsg_type = RTM_DELRULE; > n->nlmsg_flags = NLM_F_REQUEST; > @@ -415,12 +432,6 @@ static int iprule_list_flush_or_save(int argc, char **argv, int action) > if (af == AF_UNSPEC) > af = AF_INET; > > - if (action != IPRULE_LIST && argc > 0) { > - fprintf(stderr, "\"ip rule %s\" does not take any arguments.\n", > - action == IPRULE_SAVE ? "save" : "flush"); You need to keep this for IPRULE_SAVE; only IPRULE_FLUSH is allowing arguments with this patch. > - return -1; > - } > - > switch (action) { > case IPRULE_SAVE: > if (save_rule_prep()) > @@ -508,7 +519,18 @@ static int iprule_list_flush_or_save(int argc, char **argv, int action) > NEXT_ARG(); > if (get_prefix(&filter.src, *argv, af)) > invarg("from value is invalid\n", *argv); > - } else { > + } else if (matches(*argv, "protocol") == 0) { > + __u32 prot; > + NEXT_ARG(); > + filter.protocolmask = -1; > + if (rtnl_rtprot_a2n(&prot, *argv)) { > + if (strcmp(*argv, "all") != 0) > + invarg("invalid \"protocol\"\n", *argv); > + prot = 0; > + filter.protocolmask = 0; > + } > + filter.protocol = prot; > + } else{ > if (matches(*argv, "dst") == 0 || > matches(*argv, "to") == 0) { > NEXT_ARG(); > diff --git a/man/man8/ip-rule.8 b/man/man8/ip-rule.8 > index a5c47981..f4070542 100644 > --- a/man/man8/ip-rule.8 > +++ b/man/man8/ip-rule.8 > @@ -50,6 +50,8 @@ ip-rule \- routing policy database management > .IR ACTION " := [ " > .B table > .IR TABLE_ID " ] [ " > +.B protocol > +.IR PROTO " ] [ " > .B nat > .IR ADDRESS " ] [ " > .B realms > @@ -240,6 +242,10 @@ 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 protocol " PROTO" > +the protocol who installed the rule in question. "protocol" is getting a bit vague. Make it clearer by using something like 'routing protocol' as the description and given an example (e.g., zebra for RTPROT_ZEBRA) > + > .TP > .BI suppress_prefixlength " NUMBER" > reject routing decisions that have a prefix length of NUMBER or less. > @@ -275,7 +281,11 @@ updates, it flushes the routing cache with > .RE > .TP > .B ip rule flush - also dumps all the deleted rules. > -This command has no arguments. > +.RS > +.TP > +.BI protocol " PROTO" > +Select the originating protocol. > +.RE > .TP > .B ip rule show - list rules > This command has no arguments. > @@ -283,6 +293,12 @@ The options list or lst are synonyms with show. > > .TP > .B ip rule save > +.RS > +.TP > +.BI protocl " PROTO" missing an 'o' between 'c' and 'l' > +Select the originating protocol. > +.RE > +.TP > save rules table information to stdout > .RS > This command behaves like >
diff --git a/ip/iprule.c b/ip/iprule.c index 94356bf8..17df9e9b 100644 --- a/ip/iprule.c +++ b/ip/iprule.c @@ -47,6 +47,7 @@ static void usage(void) " [ iif STRING ] [ oif STRING ] [ pref NUMBER ] [ l3mdev ]\n" " [ uidrange NUMBER-NUMBER ]\n" "ACTION := [ table TABLE_ID ]\n" + " [ protocol PROTO ]\n" " [ nat ADDRESS ]\n" " [ realms [SRCREALM/]DSTREALM ]\n" " [ goto NUMBER ]\n" @@ -71,6 +72,8 @@ static struct struct fib_rule_uid_range range; inet_prefix src; inet_prefix dst; + int protocol; + int protocolmask; } filter; static inline int frh_get_table(struct fib_rule_hdr *frh, struct rtattr **tb) @@ -338,6 +341,16 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) rtnl_rtntype_n2a(frh->action, b1, sizeof(b1))); + if (tb[FRA_PROTOCOL]) { + __u8 protocol = rta_getattr_u8(tb[FRA_PROTOCOL]); + + if ((protocol && protocol != RTPROT_KERNEL) || + show_details > 0) { + fprintf(fp, " proto %s ", + rtnl_rtprot_n2a(protocol, b1, sizeof(b1))); + } + } + fprintf(fp, "\n"); fflush(fp); return 0; @@ -391,6 +404,10 @@ static int flush_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, parse_rtattr(tb, FRA_MAX, RTM_RTA(frh), len); + if (tb[FRA_PROTOCOL] && + (filter.protocol^rta_getattr_u8(tb[FRA_PROTOCOL]))&filter.protocolmask) + return 0; + if (tb[FRA_PRIORITY]) { n->nlmsg_type = RTM_DELRULE; n->nlmsg_flags = NLM_F_REQUEST; @@ -415,12 +432,6 @@ static int iprule_list_flush_or_save(int argc, char **argv, int action) if (af == AF_UNSPEC) af = AF_INET; - if (action != IPRULE_LIST && argc > 0) { - fprintf(stderr, "\"ip rule %s\" does not take any arguments.\n", - action == IPRULE_SAVE ? "save" : "flush"); - return -1; - } - switch (action) { case IPRULE_SAVE: if (save_rule_prep()) @@ -508,7 +519,18 @@ static int iprule_list_flush_or_save(int argc, char **argv, int action) NEXT_ARG(); if (get_prefix(&filter.src, *argv, af)) invarg("from value is invalid\n", *argv); - } else { + } else if (matches(*argv, "protocol") == 0) { + __u32 prot; + NEXT_ARG(); + filter.protocolmask = -1; + if (rtnl_rtprot_a2n(&prot, *argv)) { + if (strcmp(*argv, "all") != 0) + invarg("invalid \"protocol\"\n", *argv); + prot = 0; + filter.protocolmask = 0; + } + filter.protocol = prot; + } else{ if (matches(*argv, "dst") == 0 || matches(*argv, "to") == 0) { NEXT_ARG(); diff --git a/man/man8/ip-rule.8 b/man/man8/ip-rule.8 index a5c47981..f4070542 100644 --- a/man/man8/ip-rule.8 +++ b/man/man8/ip-rule.8 @@ -50,6 +50,8 @@ ip-rule \- routing policy database management .IR ACTION " := [ " .B table .IR TABLE_ID " ] [ " +.B protocol +.IR PROTO " ] [ " .B nat .IR ADDRESS " ] [ " .B realms @@ -240,6 +242,10 @@ 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 protocol " PROTO" +the protocol who installed the rule in question. + .TP .BI suppress_prefixlength " NUMBER" reject routing decisions that have a prefix length of NUMBER or less. @@ -275,7 +281,11 @@ updates, it flushes the routing cache with .RE .TP .B ip rule flush - also dumps all the deleted rules. -This command has no arguments. +.RS +.TP +.BI protocol " PROTO" +Select the originating protocol. +.RE .TP .B ip rule show - list rules This command has no arguments. @@ -283,6 +293,12 @@ The options list or lst are synonyms with show. .TP .B ip rule save +.RS +.TP +.BI protocl " PROTO" +Select the originating protocol. +.RE +.TP save rules table information to stdout .RS This command behaves like
Modify 'ip rule' command to notice when the kernel passes to us the originating protocol. Add code to allow the `ip rule flush protocol XXX` command to be accepted and properly handled. Modify the documentation to reflect these code changes. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com> --- ip/iprule.c | 36 +++++++++++++++++++++++++++++------- man/man8/ip-rule.8 | 18 +++++++++++++++++- 2 files changed, 46 insertions(+), 8 deletions(-)