From 1a11782c408a60afb464fe232fc2e3fa1e298436 Mon Sep 17 00:00:00 2001 From: Dinesh G Dutt Date: Wed, 11 Jan 2017 14:33:39 -0800 Subject: [PATCH] *: Add source of route as protocol string in ip route pushed into kernel Ticket: CM-14313 Reviewed By: Testing Done: bgpmin, ospfmin, bgp_kitchen_sink_test 'ip route show' displays all routes as belonging to protocol zebra. The user has to run an additional command (in vtysh) to get the actual source of a route (bgp/ospf/static etc.). This patch addresses that by pushing the appropriate protocol string into the protocol field of the netlink route update message. Now you can see routes with the correct origin as well as filter on them (ip route show proto ospf). 'ospf' is used for both IPv4 and IPv6 routes, even though the OSPF version is different in both cases. Sample output (old): 9.9.12.13 via 69.254.2.38 dev swp3.2 proto zebra metric 20 9.9.13.3 proto zebra metric 20 nexthop via 69.254.2.30 dev swp1.2 weight 1 nexthop via 69.254.2.34 dev swp2.2 weight 1 nexthop via 69.254.2.38 dev swp3.2 weight 1 Sample output (new): 9.9.12.13 via 69.254.2.38 dev swp3.2 proto bgp metric 20 9.9.13.3 proto bgp metric 20 nexthop via 69.254.2.30 dev swp1.2 weight 1 nexthop via 69.254.2.34 dev swp2.2 weight 1 nexthop via 69.254.2.38 dev swp3.2 weight 1 Signed-off-by: Dinesh Dutt --- cumulus/etc/iproute2/rt_protos.d/frr.conf | 8 ++++ debian/frr.dirs | 1 + tools/frr | 9 ++++- zebra/kernel_netlink.c | 5 +++ zebra/rt_netlink.c | 49 +++++++++++++++++++++-- zebra/rt_netlink.h | 8 ++++ 6 files changed, 75 insertions(+), 5 deletions(-) create mode 100644 cumulus/etc/iproute2/rt_protos.d/frr.conf diff --git a/cumulus/etc/iproute2/rt_protos.d/frr.conf b/cumulus/etc/iproute2/rt_protos.d/frr.conf new file mode 100644 index 0000000000..883782e4dd --- /dev/null +++ b/cumulus/etc/iproute2/rt_protos.d/frr.conf @@ -0,0 +1,8 @@ +# Additional protocol strings defined by quagga for each of its daemons + +186 bgp +187 isis +188 ospf +189 rip +190 ripng +191 static diff --git a/debian/frr.dirs b/debian/frr.dirs index 58290080d0..56699b2daa 100644 --- a/debian/frr.dirs +++ b/debian/frr.dirs @@ -1,5 +1,6 @@ etc/logrotate.d/ etc/frr/ +etc/iproute2/rt_protos.d/ usr/share/doc/frr/ usr/share/doc/frr/examples/ usr/share/lintian/overrides/ diff --git a/tools/frr b/tools/frr index 2ecaadbb53..a6d99feaf6 100755 --- a/tools/frr +++ b/tools/frr @@ -532,8 +532,15 @@ case "$1" in fi if [ -z "$dmn" -o "$dmn" = "zebra" ]; then - echo "Removing all routes made by zebra." + echo "Removing all routes made by quagga." + ip route flush proto bgp + ip route flush proto ospf + ip route flush proto static + ip route flush proto rip + ip route flush proto ripng ip route flush proto zebra + ip route flush proto isis + else [ -n "$dmn" ] && eval "${dmn/-/_}=0" start_watchfrr diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index 9f9a62f384..20cb62e318 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -91,6 +91,11 @@ static const struct message rtproto_str[] = { #ifdef RTPROT_BIRD {RTPROT_BIRD, "BIRD"}, #endif /* RTPROT_BIRD */ + {RTPROT_BGP, "BGP"}, + {RTPROT_OSPF, "OSPF"}, + {RTPROT_ISIS, "IS-IS"}, + {RTPROT_RIP, "RIP"}, + {RTPROT_RIPNG, "RIPNG"}, {0, NULL} }; diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index c04f9188fa..01922e1ad5 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -92,6 +92,47 @@ struct gw_family_t union g_addr gate; }; +static inline int is_selfroute(int proto) +{ + if ((proto == RTPROT_BGP) || (proto == RTPROT_OSPF) || + (proto == RTPROT_STATIC) || (proto == RTPROT_ZEBRA) || + (proto == RTPROT_ISIS) || (proto == RTPROT_RIPNG)) { + return 1; + } + + return 0; +} + +static inline int get_rt_proto(int proto) +{ + switch (proto) { + case ZEBRA_ROUTE_BGP: + proto = RTPROT_BGP; + break; + case ZEBRA_ROUTE_OSPF: + case ZEBRA_ROUTE_OSPF6: + proto = RTPROT_OSPF; + break; + case ZEBRA_ROUTE_STATIC: + proto = RTPROT_STATIC; + break; + case ZEBRA_ROUTE_ISIS: + proto = RTPROT_ISIS; + break; + case ZEBRA_ROUTE_RIP: + proto = RTPROT_RIP; + break; + case ZEBRA_ROUTE_RIPNG: + proto = RTPROT_RIPNG; + break; + default: + proto = RTPROT_ZEBRA; + break; + } + + return proto; +} + /* Pending: create an efficient table_id (in a tree/hash) based lookup) */ @@ -181,7 +222,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h, } /* Route which inserted by Zebra. */ - if (rtm->rtm_protocol == RTPROT_ZEBRA) + if (is_selfroute(rtm->rtm_protocol)) flags |= ZEBRA_FLAG_SELFROUTE; index = 0; @@ -367,9 +408,9 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h, if (rtm->rtm_protocol == RTPROT_KERNEL) return 0; - if (rtm->rtm_protocol == RTPROT_ZEBRA && h->nlmsg_type == RTM_NEWROUTE) + if (is_selfroute(rtm->rtm_protocol) && h->nlmsg_type == RTM_NEWROUTE) return 0; - if (rtm->rtm_protocol == RTPROT_ZEBRA) + if (is_selfroute(rtm->rtm_protocol)) SET_FLAG(zebra_flags, ZEBRA_FLAG_SELFROUTE); if (rtm->rtm_src_len != 0) @@ -1151,7 +1192,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib, req.n.nlmsg_type = cmd; req.r.rtm_family = family; req.r.rtm_dst_len = p->prefixlen; - req.r.rtm_protocol = RTPROT_ZEBRA; + req.r.rtm_protocol = get_rt_proto(rib->type); req.r.rtm_scope = RT_SCOPE_UNIVERSE; if ((rib->flags & ZEBRA_FLAG_BLACKHOLE) || (rib->flags & ZEBRA_FLAG_REJECT)) diff --git a/zebra/rt_netlink.h b/zebra/rt_netlink.h index 7183525fba..d1f01bda4c 100644 --- a/zebra/rt_netlink.h +++ b/zebra/rt_netlink.h @@ -28,6 +28,14 @@ #define NL_DEFAULT_ROUTE_METRIC 20 +/* Additional protocol strings to push into routes */ +#define RTPROT_BGP 186 +#define RTPROT_ISIS 187 +#define RTPROT_OSPF 188 +#define RTPROT_RIP 189 +#define RTPROT_RIPNG 190 + + extern void clear_nhlfe_installed (zebra_lsp_t *lsp); extern int -- 2.39.5