]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: Allow S,G lookup to use RTNL_FAMILY_IPMR
authorDonald Sharp <sharpd@cumulusnetworks.com>
Tue, 6 Jun 2017 14:18:17 +0000 (10:18 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Mon, 24 Jul 2017 17:51:39 +0000 (13:51 -0400)
This current implementation unfortunately must
ask the kernel for all mroutes because vrf's
do not have the ability to request a single
mroute at this time.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
zebra/rt.h
zebra/rt_netlink.c
zebra/rt_socket.c
zebra/zebra_mroute.c

index 81dffdf44168f2063e83d5489a8260ee49be7c2d..ead6a6c5084d5ecec3e5af89c940c7e9033d2791 100644 (file)
@@ -42,7 +42,7 @@ extern int kernel_upd_lsp(zebra_lsp_t *);
 extern int kernel_del_lsp(zebra_lsp_t *);
 extern int mpls_kernel_init(void);
 
-extern int kernel_get_ipmr_sg_stats(void *mroute);
+extern int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *mroute);
 extern int kernel_add_vtep(vni_t vni, struct interface *ifp,
                           struct in_addr *vtep_ip);
 extern int kernel_del_vtep(vni_t vni, struct interface *ifp,
index c02774ca646534465f1e60a347b4542de3c57d02..73054594b7fad4e09d3dcc7d6fbd2e1bda8114df 100644 (file)
@@ -503,6 +503,9 @@ static int netlink_route_change_read_multicast(struct sockaddr_nl *snl,
        char gbuf[40];
        char oif_list[256] = "\0";
        vrf_id_t vrf = ns_id;
+       int table;
+       struct in_addr src = {.s_addr = 0};
+       struct in_addr grp = {.s_addr = 0};
 
        if (mroute)
                m = mroute;
@@ -518,14 +521,24 @@ static int netlink_route_change_read_multicast(struct sockaddr_nl *snl,
        memset(tb, 0, sizeof tb);
        netlink_parse_rtattr(tb, RTA_MAX, RTM_RTA(rtm), len);
 
+       if (tb[RTA_TABLE])
+               table = *(int *)RTA_DATA(tb[RTA_TABLE]);
+       else
+               table = rtm->rtm_table;
+
+       vrf = vrf_lookup_by_table(table);
+
        if (tb[RTA_IIF])
                iif = *(int *)RTA_DATA(tb[RTA_IIF]);
 
        if (tb[RTA_SRC])
-               m->sg.src = *(struct in_addr *)RTA_DATA(tb[RTA_SRC]);
+               src = *(struct in_addr *)RTA_DATA(tb[RTA_SRC]);
 
        if (tb[RTA_DST])
-               m->sg.grp = *(struct in_addr *)RTA_DATA(tb[RTA_DST]);
+               grp = *(struct in_addr *)RTA_DATA(tb[RTA_DST]);
+
+       if (m->sg.src.s_addr != src.s_addr || m->sg.grp.s_addr != grp.s_addr)
+               return 0;
 
        if ((RTA_EXPIRES <= RTA_MAX) && tb[RTA_EXPIRES])
                m->lastused = *(unsigned long long *)RTA_DATA(tb[RTA_EXPIRES]);
@@ -558,10 +571,12 @@ static int netlink_route_change_read_multicast(struct sockaddr_nl *snl,
                        sprintf(temp, "%s ", ifp->name);
                        strcat(oif_list, temp);
                }
+               struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(vrf);
                ifp = if_lookup_by_index(iif, vrf);
-               zlog_debug("MCAST %s (%s,%s) IIF: %s OIF: %s jiffies: %lld",
-                          nl_msg_type_to_str(h->nlmsg_type), sbuf, gbuf,
-                          ifp->name, oif_list, m->lastused);
+               zlog_debug(
+                       "MCAST VRF: %s(%d) %s (%s,%s) IIF: %s OIF: %s jiffies: %lld",
+                       zvrf->vrf->name, vrf, nl_msg_type_to_str(h->nlmsg_type),
+                       sbuf, gbuf, ifp->name, oif_list, m->lastused);
        }
        return 0;
 }
@@ -1503,38 +1518,21 @@ skip:
                            0);
 }
 
-int kernel_get_ipmr_sg_stats(void *in)
+int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, 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;
+       struct zebra_ns *zns = zvrf->zns;
 
        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.n.nlmsg_pid = zns->netlink_cmd.snl.nl_pid;
-
-       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_request(RTNL_FAMILY_IPMR, RTM_GETROUTE,
+                             &zns->netlink_cmd);
+       if (suc < 0)
+               return suc;
 
-       suc = netlink_talk(netlink_route_change_read_multicast, &req.n,
-                          &zns->netlink_cmd, zns, 0);
+       suc = netlink_parse_info(netlink_route_change_read_multicast,
+                                &zns->netlink_cmd, zns, 0, 0);
 
-       mroute = NULL;
        return suc;
 }
 
index 827d3987041dc14c37904edf1494b8602c0f0f09..683086f1098360a8996be64b08d0e48d2701cf00 100644 (file)
@@ -406,7 +406,7 @@ int kernel_neigh_update(int add, int ifindex, uint32_t addr, char *lla,
        return 0;
 }
 
-extern int kernel_get_ipmr_sg_stats(void *mroute)
+extern int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *mroute)
 {
        return 0;
 }
index 6b510f9d3b0c086ab1a2f84e7b87a25c943b7405..c4d674df23b43c9078d3baca6d5f92795135ae9a 100644 (file)
@@ -54,7 +54,7 @@ int zebra_ipmr_route_stats(struct zserv *client, int fd, u_short length,
                zlog_debug("Asking for (%s,%s) mroute information", sbuf, gbuf);
        }
 
-       suc = kernel_get_ipmr_sg_stats(&mroute);
+       suc = kernel_get_ipmr_sg_stats(zvrf, &mroute);
 
        s = client->obuf;