diff options
author | Donald Sharp <sharpd@cumulusnetworks.com> | 2016-08-11 02:04:20 +0200 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2016-12-22 02:26:06 +0100 |
commit | e3be04328f601963c825c722355f62c4b4e7cb31 (patch) | |
tree | 5ea05fcdf1d6c77bb4124650d9431fb47aa54af1 /zebra/rt_netlink.c | |
parent | pimd: Fix igmp(*,G) not influencing S,G mroutes (diff) | |
download | frr-e3be04328f601963c825c722355f62c4b4e7cb31.tar.xz frr-e3be04328f601963c825c722355f62c4b4e7cb31.zip |
lib, pimd, zebra: Allow pimd to ask the kernel about mroute info
When we need to lookup the mroute info for a route. Allow
pimd to ask the kernel.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Diffstat (limited to 'zebra/rt_netlink.c')
-rw-r--r-- | zebra/rt_netlink.c | 57 |
1 files changed, 49 insertions, 8 deletions
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index ff907bb87..5dc9a10e2 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -55,6 +55,8 @@ #include "zebra/zebra_mpls.h" #include "zebra/kernel_netlink.h" #include "zebra/rt_netlink.h" +#include "zebra/zebra_mroute.h" + /* TODO - Temporary definitions, need to refine. */ #ifndef AF_MPLS @@ -516,6 +518,8 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h, return 0; } +static struct mcast_route_data *mroute = NULL; + static int netlink_route_change_read_multicast (struct sockaddr_nl *snl, struct nlmsghdr *h, ns_id_t ns_id) @@ -524,7 +528,8 @@ netlink_route_change_read_multicast (struct sockaddr_nl *snl, struct nlmsghdr *h unsigned long long lastused = 0; struct rtmsg *rtm; struct rtattr *tb[RTA_MAX + 1]; - struct prefix_sg sg; + struct mcast_route_data *m; + struct mcast_route_data mr; int iif = 0; int count; int oif[256]; @@ -532,10 +537,13 @@ netlink_route_change_read_multicast (struct sockaddr_nl *snl, struct nlmsghdr *h char sbuf[40]; char gbuf[40]; char oif_list[256] = "\0"; - memset (&sg, 0, sizeof (sg)); - sg.family = IANA_AFI_IPMR; vrf_id_t vrf = ns_id; + if (mroute) + m = mroute; + else + m = &mr; + rtm = NLMSG_DATA (h); len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct rtmsg)); @@ -547,13 +555,13 @@ netlink_route_change_read_multicast (struct sockaddr_nl *snl, struct nlmsghdr *h iif = *(int *)RTA_DATA (tb[RTA_IIF]); if (tb[RTA_SRC]) - sg.src = *(struct in_addr *)RTA_DATA (tb[RTA_SRC]); + m->sg.src = *(struct in_addr *)RTA_DATA (tb[RTA_SRC]); if (tb[RTA_DST]) - sg.grp = *(struct in_addr *)RTA_DATA (tb[RTA_DST]); + m->sg.grp = *(struct in_addr *)RTA_DATA (tb[RTA_DST]); if (tb[RTA_EXPIRES]) - lastused = *(unsigned long long *)RTA_DATA (tb[RTA_EXPIRES]); + m->lastused = *(unsigned long long *)RTA_DATA (tb[RTA_EXPIRES]); if (tb[RTA_MULTIPATH]) { @@ -576,8 +584,8 @@ netlink_route_change_read_multicast (struct sockaddr_nl *snl, struct nlmsghdr *h if (IS_ZEBRA_DEBUG_KERNEL) { - strcpy (sbuf, inet_ntoa (sg.src)); - strcpy (gbuf, inet_ntoa (sg.grp)); + strcpy (sbuf, inet_ntoa (m->sg.src)); + strcpy (gbuf, inet_ntoa (m->sg.grp)); for (count = 0; count < oif_count; count++) { struct interface *ifp = if_lookup_by_index_vrf (oif[count], vrf); @@ -1508,6 +1516,39 @@ skip: } int +netlink_get_ipmr_sg_stats (void *in) +{ + int suc = 0; + struct mcast_route_data *mr = (struct mcast_route_data *)in; + struct { + struct nlmsghdr n; + struct ndmsg ndm; + char buf[256]; + } req; + + mroute = mr; + struct zebra_ns *zns = zebra_ns_lookup (NS_DEFAULT); + + memset(&req.n, 0, sizeof(req.n)); + memset(&req.ndm, 0, sizeof(req.ndm)); + + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg)); + req.n.nlmsg_flags = NLM_F_REQUEST; + req.ndm.ndm_family = AF_INET; + req.n.nlmsg_type = RTM_GETROUTE; + + addattr_l (&req.n, sizeof (req), RTA_IIF, &mroute->ifindex, 4); + addattr_l (&req.n, sizeof (req), RTA_OIF, &mroute->ifindex, 4); + addattr_l (&req.n, sizeof (req), RTA_SRC, &mroute->sg.src.s_addr, 4); + addattr_l (&req.n, sizeof (req), RTA_DST, &mroute->sg.grp.s_addr, 4); + + suc = netlink_talk (netlink_route_change_read_multicast, &req.n, &zns->netlink_cmd, zns); + + mroute = NULL; + return suc; +} + +int kernel_route_rib (struct prefix *p, struct rib *old, struct rib *new) { if (!old && new) |