Add vrf keyword to 'ip route' commands. Allows: 1. Users can list routes by VRF name: $ ip route show vrf NAME
VRF tables have all routes including local and broadcast routes. The VRF keyword filters LOCAL and BROADCAST routes; to see all routes the table option can be used. Or to see local routes only for a VRF: $ ip route show vrf NAME type local 2. Add or delete a route for a VRF: $ ip route {add|delete} vrf NAME <route spec> 3. Do a route lookup for a VRF: $ ip route get vrf NAME ADDRESS Signed-off-by: David Ahern <d...@cumulusnetworks.com> --- ip/iproute.c | 32 ++++++++++++++++++++++++++++++-- man/man8/ip-route.8.in | 19 ++++++++++++++++++- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/ip/iproute.c b/ip/iproute.c index aae693d17be8..bd661c16cb46 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -67,10 +67,10 @@ static void usage(void) fprintf(stderr, " ip route showdump\n"); fprintf(stderr, " ip route get ADDRESS [ from ADDRESS iif STRING ]\n"); fprintf(stderr, " [ oif STRING ] [ tos TOS ]\n"); - fprintf(stderr, " [ mark NUMBER ]\n"); + fprintf(stderr, " [ mark NUMBER ] [ vrf NAME ]\n"); fprintf(stderr, " ip route { add | del | change | append | replace } ROUTE\n"); fprintf(stderr, "SELECTOR := [ root PREFIX ] [ match PREFIX ] [ exact PREFIX ]\n"); - fprintf(stderr, " [ table TABLE_ID ] [ proto RTPROTO ]\n"); + fprintf(stderr, " [ table TABLE_ID ] [ vrf NAME ] [ proto RTPROTO ]\n"); fprintf(stderr, " [ type TYPE ] [ scope SCOPE ]\n"); fprintf(stderr, "ROUTE := NODE_SPEC [ INFO_SPEC ]\n"); fprintf(stderr, "NODE_SPEC := [ TYPE ] PREFIX [ tos TOS ]\n"); @@ -1141,6 +1141,20 @@ static int iproute_modify(int cmd, unsigned int flags, int argc, char **argv) addattr32(&req.n, sizeof(req), RTA_TABLE, tid); } table_ok = 1; + } else if (matches(*argv, "vrf") == 0) { + __u32 tid; + + NEXT_ARG(); + tid = ipvrf_get_table(*argv); + if (tid == 0) + invarg("Invalid VRF\n", *argv); + if (tid < 256) + req.r.rtm_table = tid; + else { + req.r.rtm_table = RT_TABLE_UNSPEC; + addattr32(&req.n, sizeof(req), RTA_TABLE, tid); + } + table_ok = 1; } else if (strcmp(*argv, "dev") == 0 || strcmp(*argv, "oif") == 0) { NEXT_ARG(); @@ -1395,6 +1409,15 @@ static int iproute_list_flush_or_save(int argc, char **argv, int action) } } else filter.tb = tid; + } else if (matches(*argv, "vrf") == 0) { + __u32 tid; + + NEXT_ARG(); + tid = ipvrf_get_table(*argv); + if (tid == 0) + invarg("Invalid VRF\n", *argv); + filter.tb = tid; + filter.typemask = ~(1 << RTN_LOCAL | 1<<RTN_BROADCAST); } else if (matches(*argv, "cached") == 0 || matches(*argv, "cloned") == 0) { filter.cloned = 1; @@ -1681,6 +1704,11 @@ static int iproute_get(int argc, char **argv) req.r.rtm_flags |= RTM_F_NOTIFY; } else if (matches(*argv, "connected") == 0) { connected = 1; + } else if (matches(*argv, "vrf") == 0) { + NEXT_ARG(); + if (!name_is_vrf(*argv)) + invarg("Invalid VRF\n", *argv); + odev = *argv; } else { inet_prefix addr; diff --git a/man/man8/ip-route.8.in b/man/man8/ip-route.8.in index d7fb8fba8bb0..d4fae3cc783b 100644 --- a/man/man8/ip-route.8.in +++ b/man/man8/ip-route.8.in @@ -33,7 +33,9 @@ ip-route \- routing table management .RB " ] [ " oif .IR STRING " ] [ " .B tos -.IR TOS " ]" +.IR TOS " ] [ " +.B vrf +.IR NAME " ] " .ti -8 .BR "ip route" " { " add " | " del " | " change " | " append " | "\ @@ -50,6 +52,8 @@ replace " } " .IR PREFIX " ] [ " .B table .IR TABLE_ID " ] [ " +.B vrf +.IR NAME " ] [ " .B proto .IR RTPROTO " ] [ " .B type @@ -369,6 +373,11 @@ routes, which are put into the table by default. .TP +.BI vrf " NAME" +the vrf name to add this route to. Implicitly means the table +associated with the VRF. + +.TP .BI dev " NAME" the output device name. @@ -746,6 +755,10 @@ show the routes from this table(s). The default setting is to show table .in -8 .TP +.BI vrf " NAME" +show the routes for the table associated with the vrf name + +.TP .B cloned .TP .B cached @@ -855,6 +868,10 @@ the device from which this packet is expected to arrive. force the output device on which this packet will be routed. .TP +.BI vrf " NAME" +force the vrf device on which this packet will be routed. + +.TP .B connected if no source address .RB "(option " from ")" -- 2.1.4