Merge pull request #10964 from mobash-rasool/pim-zebra

zebra, pimd, pim6d: Modify code to get multicast IPv6 stats from kernel
This commit is contained in:
David Lamparter 2022-04-29 10:22:41 +02:00 committed by GitHub
commit ac83c58ddd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 112 additions and 49 deletions

View File

@ -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;

View File

@ -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

View File

@ -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?
*

View File

@ -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);

View File

@ -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;
};