From: Donald Sharp Date: Tue, 6 Jun 2017 14:18:17 +0000 (-0400) Subject: zebra: Allow S,G lookup to use RTNL_FAMILY_IPMR X-Git-Tag: frr-4.0-dev~468^2~60 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=43b5cc5ee6bc51802dd5171c61d9240ee988e534;p=mirror%2Ffrr.git zebra: Allow S,G lookup to use RTNL_FAMILY_IPMR 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 --- diff --git a/zebra/rt.h b/zebra/rt.h index 81dffdf441..ead6a6c508 100644 --- a/zebra/rt.h +++ b/zebra/rt.h @@ -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, diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index c02774ca64..73054594b7 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -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; } diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c index 827d398704..683086f109 100644 --- a/zebra/rt_socket.c +++ b/zebra/rt_socket.c @@ -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; } diff --git a/zebra/zebra_mroute.c b/zebra/zebra_mroute.c index 6b510f9d3b..c4d674df23 100644 --- a/zebra/zebra_mroute.c +++ b/zebra/zebra_mroute.c @@ -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;