ip: Display ip rule protocol used

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>
Signed-off-by: David Ahern <dsahern@gmail.com>
This commit is contained in:
Donald Sharp 2018-02-28 18:43:59 -05:00 committed by David Ahern
parent 5baaf07cb3
commit 7c083da77c
2 changed files with 51 additions and 5 deletions

View File

@ -47,6 +47,7 @@ static void usage(void)
" [ iif STRING ] [ oif STRING ] [ pref NUMBER ] [ l3mdev ]\n" " [ iif STRING ] [ oif STRING ] [ pref NUMBER ] [ l3mdev ]\n"
" [ uidrange NUMBER-NUMBER ]\n" " [ uidrange NUMBER-NUMBER ]\n"
"ACTION := [ table TABLE_ID ]\n" "ACTION := [ table TABLE_ID ]\n"
" [ protocol PROTO ]\n"
" [ nat ADDRESS ]\n" " [ nat ADDRESS ]\n"
" [ realms [SRCREALM/]DSTREALM ]\n" " [ realms [SRCREALM/]DSTREALM ]\n"
" [ goto NUMBER ]\n" " [ goto NUMBER ]\n"
@ -71,6 +72,8 @@ static struct
struct fib_rule_uid_range range; struct fib_rule_uid_range range;
inet_prefix src; inet_prefix src;
inet_prefix dst; inet_prefix dst;
int protocol;
int protocolmask;
} filter; } filter;
static inline int frh_get_table(struct fib_rule_hdr *frh, struct rtattr **tb) 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, rtnl_rtntype_n2a(frh->action,
b1, sizeof(b1))); 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"); fprintf(fp, "\n");
fflush(fp); fflush(fp);
return 0; return 0;
@ -391,6 +404,13 @@ static int flush_rule(const struct sockaddr_nl *who, struct nlmsghdr *n,
parse_rtattr(tb, FRA_MAX, RTM_RTA(frh), len); parse_rtattr(tb, FRA_MAX, RTM_RTA(frh), len);
if (tb[FRA_PROTOCOL]) {
__u8 protocol = rta_getattr_u8(tb[FRA_PROTOCOL]);
if ((filter.protocol ^ protocol) & filter.protocolmask)
return 0;
}
if (tb[FRA_PRIORITY]) { if (tb[FRA_PRIORITY]) {
n->nlmsg_type = RTM_DELRULE; n->nlmsg_type = RTM_DELRULE;
n->nlmsg_flags = NLM_F_REQUEST; n->nlmsg_flags = NLM_F_REQUEST;
@ -415,9 +435,8 @@ static int iprule_list_flush_or_save(int argc, char **argv, int action)
if (af == AF_UNSPEC) if (af == AF_UNSPEC)
af = AF_INET; af = AF_INET;
if (action != IPRULE_LIST && argc > 0) { if (action == IPRULE_SAVE && argc > 0) {
fprintf(stderr, "\"ip rule %s\" does not take any arguments.\n", fprintf(stderr, "\"ip rule save\" does not take any arguments.\n");
action == IPRULE_SAVE ? "save" : "flush");
return -1; return -1;
} }
@ -508,7 +527,18 @@ static int iprule_list_flush_or_save(int argc, char **argv, int action)
NEXT_ARG(); NEXT_ARG();
if (get_prefix(&filter.src, *argv, af)) if (get_prefix(&filter.src, *argv, af))
invarg("from value is invalid\n", *argv); 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 || if (matches(*argv, "dst") == 0 ||
matches(*argv, "to") == 0) { matches(*argv, "to") == 0) {
NEXT_ARG(); NEXT_ARG();

View File

@ -50,6 +50,8 @@ ip-rule \- routing policy database management
.IR ACTION " := [ " .IR ACTION " := [ "
.B table .B table
.IR TABLE_ID " ] [ " .IR TABLE_ID " ] [ "
.B protocol
.IR PROTO " ] [ "
.B nat .B nat
.IR ADDRESS " ] [ " .IR ADDRESS " ] [ "
.B realms .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. the routing table identifier to lookup if the rule selector matches.
It is also possible to use lookup instead of table. It is also possible to use lookup instead of table.
.TP
.BI protocol " PROTO"
the routing protocol who installed the rule in question. As an example when zebra installs a rule it would get RTPROT_ZEBRA as the installing protocol.
.TP .TP
.BI suppress_prefixlength " NUMBER" .BI suppress_prefixlength " NUMBER"
reject routing decisions that have a prefix length of NUMBER or less. reject routing decisions that have a prefix length of NUMBER or less.
@ -275,7 +281,11 @@ updates, it flushes the routing cache with
.RE .RE
.TP .TP
.B ip rule flush - also dumps all the deleted rules. .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 .TP
.B ip rule show - list rules .B ip rule show - list rules
This command has no arguments. This command has no arguments.
@ -283,6 +293,12 @@ The options list or lst are synonyms with show.
.TP .TP
.B ip rule save .B ip rule save
.RS
.TP
.BI protocol " PROTO"
Select the originating protocol.
.RE
.TP
save rules table information to stdout save rules table information to stdout
.RS .RS
This command behaves like This command behaves like