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"
" [ 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,13 @@ 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]) {
__u8 protocol = rta_getattr_u8(tb[FRA_PROTOCOL]);
if ((filter.protocol ^ protocol) & filter.protocolmask)
return 0;
}
if (tb[FRA_PRIORITY]) {
n->nlmsg_type = RTM_DELRULE;
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)
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");
if (action == IPRULE_SAVE && argc > 0) {
fprintf(stderr, "\"ip rule save\" does not take any arguments.\n");
return -1;
}
@ -508,7 +527,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();

View File

@ -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 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
.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 protocol " PROTO"
Select the originating protocol.
.RE
.TP
save rules table information to stdout
.RS
This command behaves like