diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index 43d05dfe9c..b7f483dbc0 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -1047,14 +1047,14 @@ void pim_mroute_update_counters(struct channel_oil *c_oil) memset(&sgreq, 0, sizeof(sgreq)); + pim_zlookup_sg_statistics(c_oil); + #if PIM_IPV == 4 sgreq.src = *oil_origin(c_oil); sgreq.grp = *oil_mcastgrp(c_oil); - pim_zlookup_sg_statistics(c_oil); #else sgreq.src = c_oil->oil.mf6cc_origin; sgreq.grp = c_oil->oil.mf6cc_mcastgrp; - /* TODO Zlookup_sg_statistics for V6 to be added */ #endif if (ioctl(pim->mroute_socket, PIM_SIOCGETSGCNT, &sgreq)) { pim_sgaddr sg; diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c index 9e8e9cac39..a9553089c9 100644 --- a/pimd/pim_zlookup.c +++ b/pimd/pim_zlookup.c @@ -497,7 +497,6 @@ void pim_zlookup_show_ip_multicast(struct vty *vty) } } -#if PIM_IPV == 4 int pim_zlookup_sg_statistics(struct channel_oil *c_oil) { struct stream *s = zlookup->obuf; @@ -506,17 +505,16 @@ int pim_zlookup_sg_statistics(struct channel_oil *c_oil) pim_sgaddr sg; int count = 0; int ret; + pim_sgaddr more = {}; struct interface *ifp = - pim_if_find_by_vif_index(c_oil->pim, c_oil->oil.mfcc_parent); + pim_if_find_by_vif_index(c_oil->pim, *oil_parent(c_oil)); if (PIM_DEBUG_ZEBRA) { - pim_sgaddr more; - - more.src = c_oil->oil.mfcc_origin; - more.grp = c_oil->oil.mfcc_mcastgrp; - zlog_debug("Sending Request for New Channel Oil Information%pSG VIIF %d(%s)", - &more, c_oil->oil.mfcc_parent, - c_oil->pim->vrf->name); + more.src = *oil_origin(c_oil); + more.grp = *oil_mcastgrp(c_oil); + zlog_debug( + "Sending Request for New Channel Oil Information%pSG VIIF %d(%s)", + &more, *oil_parent(c_oil), c_oil->pim->vrf->name); } if (!ifp) @@ -525,8 +523,9 @@ int pim_zlookup_sg_statistics(struct channel_oil *c_oil) stream_reset(s); zclient_create_header(s, ZEBRA_IPMR_ROUTE_STATS, c_oil->pim->vrf->vrf_id); - stream_put_in_addr(s, &c_oil->oil.mfcc_origin); - stream_put_in_addr(s, &c_oil->oil.mfcc_mcastgrp); + stream_putl(s, PIM_AF); + stream_write(s, oil_origin(c_oil), sizeof(pim_addr)); + stream_write(s, oil_mcastgrp(c_oil), sizeof(pim_addr)); stream_putl(s, ifp->ifindex); stream_putw_at(s, 0, stream_get_endp(s)); @@ -560,20 +559,17 @@ int pim_zlookup_sg_statistics(struct channel_oil *c_oil) } } - sg.src.s_addr = stream_get_ipv4(s); - sg.grp.s_addr = stream_get_ipv4(s); - if (sg.src.s_addr != c_oil->oil.mfcc_origin.s_addr - || sg.grp.s_addr != c_oil->oil.mfcc_mcastgrp.s_addr) { - if (PIM_DEBUG_ZEBRA) { - pim_sgaddr more; + stream_get(&sg.src, s, sizeof(pim_addr)); + stream_get(&sg.grp, s, sizeof(pim_addr)); - more.src = c_oil->oil.mfcc_origin; - more.grp = c_oil->oil.mfcc_mcastgrp; + more.src = *oil_origin(c_oil); + more.grp = *oil_mcastgrp(c_oil); + if (pim_sgaddr_cmp(sg, more)) { + if (PIM_DEBUG_ZEBRA) flog_err( EC_LIB_ZAPI_MISSMATCH, "%s: Received wrong %pSG(%s) information requested", __func__, &more, c_oil->pim->vrf->name); - } zclient_lookup_failed(zlookup); return -3; } @@ -586,4 +582,3 @@ int pim_zlookup_sg_statistics(struct channel_oil *c_oil) return 0; } -#endif diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 7b377aad6d..4e97323cf6 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -1045,11 +1045,23 @@ static int netlink_route_change_read_multicast(struct nlmsghdr *h, 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]); + if (tb[RTA_SRC]) { + if (rtm->rtm_family == RTNL_FAMILY_IPMR) + m->src.ipaddr_v4 = + *(struct in_addr *)RTA_DATA(tb[RTA_SRC]); + else + m->src.ipaddr_v6 = + *(struct in6_addr *)RTA_DATA(tb[RTA_SRC]); + } - if (tb[RTA_DST]) - m->sg.grp = *(struct in_addr *)RTA_DATA(tb[RTA_DST]); + if (tb[RTA_DST]) { + if (rtm->rtm_family == RTNL_FAMILY_IPMR) + m->grp.ipaddr_v4 = + *(struct in_addr *)RTA_DATA(tb[RTA_DST]); + else + m->grp.ipaddr_v6 = + *(struct in6_addr *)RTA_DATA(tb[RTA_DST]); + } if (tb[RTA_EXPIRES]) m->lastused = *(unsigned long long *)RTA_DATA(tb[RTA_EXPIRES]); @@ -1074,6 +1086,17 @@ static int netlink_route_change_read_multicast(struct nlmsghdr *h, } } + if (rtm->rtm_family == RTNL_FAMILY_IPMR) { + SET_IPADDR_V4(&m->src); + SET_IPADDR_V4(&m->grp); + } else if (rtm->rtm_family == RTNL_FAMILY_IP6MR) { + SET_IPADDR_V6(&m->src); + SET_IPADDR_V6(&m->grp); + } else { + zlog_warn("%s: Invalid rtm_family received", __func__); + return 0; + } + if (IS_ZEBRA_DEBUG_KERNEL) { struct interface *ifp = NULL; struct zebra_vrf *zvrf = NULL; @@ -1089,11 +1112,10 @@ static int netlink_route_change_read_multicast(struct nlmsghdr *h, zvrf = zebra_vrf_lookup_by_id(vrf); ifp = if_lookup_by_index(iif, vrf); zlog_debug( - "MCAST VRF: %s(%d) %s (%pI4,%pI4) IIF: %s(%d) OIF: %s jiffies: %lld", + "MCAST VRF: %s(%d) %s (%pIA,%pIA) IIF: %s(%d) OIF: %s jiffies: %lld", zvrf_name(zvrf), vrf, nl_msg_type_to_str(h->nlmsg_type), - &m->sg.src, &m->sg.grp, ifp ? ifp->name : "Unknown", - iif, oif_list, - m->lastused); + &m->src, &m->grp, ifp ? ifp->name : "Unknown", iif, + oif_list, m->lastused); } return 0; } @@ -2263,13 +2285,29 @@ int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *in) req.n.nlmsg_flags = NLM_F_REQUEST; req.n.nlmsg_pid = zns->netlink_cmd.snl.nl_pid; - req.ndm.ndm_family = RTNL_FAMILY_IPMR; req.n.nlmsg_type = RTM_GETROUTE; nl_attr_put32(&req.n, sizeof(req), RTA_IIF, mroute->ifindex); nl_attr_put32(&req.n, sizeof(req), RTA_OIF, mroute->ifindex); - nl_attr_put32(&req.n, sizeof(req), RTA_SRC, mroute->sg.src.s_addr); - nl_attr_put32(&req.n, sizeof(req), RTA_DST, mroute->sg.grp.s_addr); + + if (mroute->family == AF_INET) { + req.ndm.ndm_family = RTNL_FAMILY_IPMR; + nl_attr_put(&req.n, sizeof(req), RTA_SRC, + &mroute->src.ipaddr_v4, + sizeof(mroute->src.ipaddr_v4)); + nl_attr_put(&req.n, sizeof(req), RTA_DST, + &mroute->grp.ipaddr_v4, + sizeof(mroute->grp.ipaddr_v4)); + } else { + req.ndm.ndm_family = RTNL_FAMILY_IP6MR; + nl_attr_put(&req.n, sizeof(req), RTA_SRC, + &mroute->src.ipaddr_v6, + sizeof(mroute->src.ipaddr_v6)); + nl_attr_put(&req.n, sizeof(req), RTA_DST, + &mroute->grp.ipaddr_v6, + sizeof(mroute->grp.ipaddr_v6)); + } + /* * What? * diff --git a/zebra/zebra_mroute.c b/zebra/zebra_mroute.c index ef0f2d8924..5d38c37901 100644 --- a/zebra/zebra_mroute.c +++ b/zebra/zebra_mroute.c @@ -39,20 +39,37 @@ void zebra_ipmr_route_stats(ZAPI_HANDLER_ARGS) int suc = -1; memset(&mroute, 0, sizeof(mroute)); - STREAM_GET(&mroute.sg.src, msg, 4); - STREAM_GET(&mroute.sg.grp, msg, 4); + STREAM_GETL(msg, mroute.family); + + switch (mroute.family) { + case AF_INET: + SET_IPADDR_V4(&mroute.src); + SET_IPADDR_V4(&mroute.grp); + STREAM_GET(&mroute.src.ipaddr_v4, msg, + sizeof(mroute.src.ipaddr_v4)); + STREAM_GET(&mroute.grp.ipaddr_v4, msg, + sizeof(mroute.grp.ipaddr_v4)); + break; + case AF_INET6: + SET_IPADDR_V6(&mroute.src); + SET_IPADDR_V6(&mroute.grp); + STREAM_GET(&mroute.src.ipaddr_v6, msg, + sizeof(mroute.src.ipaddr_v6)); + STREAM_GET(&mroute.grp.ipaddr_v6, msg, + sizeof(mroute.grp.ipaddr_v6)); + break; + default: + zlog_warn("%s: Invalid address family received while parsing", + __func__); + return; + } + STREAM_GETL(msg, mroute.ifindex); - if (IS_ZEBRA_DEBUG_KERNEL) { - char sbuf[40]; - char gbuf[40]; - - inet_ntop(AF_INET, &mroute.sg.src, sbuf, sizeof(sbuf)); - inet_ntop(AF_INET, &mroute.sg.grp, gbuf, sizeof(gbuf)); - - zlog_debug("Asking for (%s,%s)[%s(%u)] mroute information", - sbuf, gbuf, zvrf->vrf->name, zvrf->vrf->vrf_id); - } + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("Asking for (%pIA,%pIA)[%s(%u)] mroute information", + &mroute.src, &mroute.grp, zvrf->vrf->name, + zvrf->vrf->vrf_id); suc = kernel_get_ipmr_sg_stats(zvrf, &mroute); @@ -62,8 +79,19 @@ stream_failure: stream_reset(s); zclient_create_header(s, ZEBRA_IPMR_ROUTE_STATS, zvrf_id(zvrf)); - stream_put_in_addr(s, &mroute.sg.src); - stream_put_in_addr(s, &mroute.sg.grp); + + if (mroute.family == AF_INET) { + stream_write(s, &mroute.src.ipaddr_v4, + sizeof(mroute.src.ipaddr_v4)); + stream_write(s, &mroute.grp.ipaddr_v4, + sizeof(mroute.grp.ipaddr_v4)); + } else { + stream_write(s, &mroute.src.ipaddr_v6, + sizeof(mroute.src.ipaddr_v6)); + stream_write(s, &mroute.grp.ipaddr_v6, + sizeof(mroute.grp.ipaddr_v6)); + } + stream_put(s, &mroute.lastused, sizeof(mroute.lastused)); stream_putl(s, (uint32_t)suc); diff --git a/zebra/zebra_mroute.h b/zebra/zebra_mroute.h index 3c12b82da3..6c56c2e41d 100644 --- a/zebra/zebra_mroute.h +++ b/zebra/zebra_mroute.h @@ -29,7 +29,9 @@ extern "C" { #endif struct mcast_route_data { - struct prefix_sg sg; + int family; + struct ipaddr src; + struct ipaddr grp; unsigned int ifindex; unsigned long long lastused; };