summaryrefslogtreecommitdiffstats
path: root/zebra/rt_netlink.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2016-08-11 02:04:20 +0200
committerDonald Sharp <sharpd@cumulusnetworks.com>2016-12-22 02:26:06 +0100
commite3be04328f601963c825c722355f62c4b4e7cb31 (patch)
tree5ea05fcdf1d6c77bb4124650d9431fb47aa54af1 /zebra/rt_netlink.c
parentpimd: Fix igmp(*,G) not influencing S,G mroutes (diff)
downloadfrr-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.c57
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)