summaryrefslogtreecommitdiff
path: root/pimd
diff options
context:
space:
mode:
authorDonatas Abraitis <donatas@opensourcerouting.org>2022-03-10 18:10:43 +0200
committerDonatas Abraitis <donatas@opensourcerouting.org>2022-03-13 19:31:34 +0200
commitf2058cb425b6f2e5efb3ac8608c47bcc2da5535d (patch)
treefd6568d21b7d67043c2bfb19a24767949a2de6ac /pimd
parent7547d5288e91d7bdc09aff4cd902d6cedbabfafc (diff)
pimd: Add IGMP join sent/failed statistics
``` exit1-debian-11# sh ip igmp statistics IGMP statistics Interface : global V1 query : 0 V2 query : 0 V3 query : 0 V2 leave : 0 V1 report : 0 V2 report : 0 V3 report : 16 mtrace response : 0 mtrace request : 0 unsupported : 0 joins failed : 0 joins sent : 11 total groups : 4 total source groups : 0 exit1-debian-11# sh ip igmp statistics json { "global":{ "name":"global", "queryV1":0, "queryV2":0, "queryV3":0, "leaveV3":0, "reportV1":0, "reportV2":0, "reportV3":16, "mtraceResponse":0, "mtraceRequest":0, "unsupported":0, "totalGroups":4, "totalSourceGroups":0, "joinsFailed":0, "joinsSent":11 } } ``` Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
Diffstat (limited to 'pimd')
-rw-r--r--pimd/pim_cmd.c79
-rw-r--r--pimd/pim_iface.c16
-rw-r--r--pimd/pim_iface.h3
-rw-r--r--pimd/pim_igmp.c23
-rw-r--r--pimd/pim_igmp.h2
-rw-r--r--pimd/pim_igmp_mtrace.c4
-rw-r--r--pimd/pim_igmp_stats.c2
-rw-r--r--pimd/pim_igmp_stats.h2
-rw-r--r--pimd/pim_igmpv2.c4
-rw-r--r--pimd/pim_igmpv3.c2
-rw-r--r--pimd/pim_pim.c4
-rw-r--r--pimd/pim_sock.c7
-rw-r--r--pimd/pim_sock.h4
13 files changed, 96 insertions, 56 deletions
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index 8906caf00f..bf803a4836 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -1284,9 +1284,9 @@ static void igmp_show_statistics(struct pim_instance *pim, struct vty *vty,
const char *ifname, bool uj)
{
struct interface *ifp;
- struct igmp_stats rx_stats;
+ struct igmp_stats igmp_stats;
- igmp_stats_init(&rx_stats);
+ igmp_stats_init(&igmp_stats);
FOR_ALL_INTERFACES (pim->vrf, ifp) {
struct pim_interface *pim_ifp;
@@ -1303,7 +1303,9 @@ static void igmp_show_statistics(struct pim_instance *pim, struct vty *vty,
if (ifname && strcmp(ifname, ifp->name))
continue;
- rx_stats.total_groups +=
+ igmp_stats.joins_failed += pim_ifp->igmp_ifstat_joins_failed;
+ igmp_stats.joins_sent += pim_ifp->igmp_ifstat_joins_sent;
+ igmp_stats.total_groups +=
pim_ifp->gm_group_list
? listcount(pim_ifp->gm_group_list)
: 0;
@@ -1315,13 +1317,13 @@ static void igmp_show_statistics(struct pim_instance *pim, struct vty *vty,
if (pim_addr_is_any(src->source_addr))
continue;
- rx_stats.total_source_groups++;
+ igmp_stats.total_source_groups++;
}
}
for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_socket_list, sock_node,
igmp)) {
- igmp_stats_add(&rx_stats, &igmp->rx_stats);
+ igmp_stats_add(&igmp_stats, &igmp->igmp_stats);
}
}
if (uj) {
@@ -1333,45 +1335,58 @@ static void igmp_show_statistics(struct pim_instance *pim, struct vty *vty,
json_object_string_add(json_row, "name", ifname ? ifname :
"global");
- json_object_int_add(json_row, "queryV1", rx_stats.query_v1);
- json_object_int_add(json_row, "queryV2", rx_stats.query_v2);
- json_object_int_add(json_row, "queryV3", rx_stats.query_v3);
- json_object_int_add(json_row, "leaveV2", rx_stats.leave_v2);
- json_object_int_add(json_row, "reportV1", rx_stats.report_v1);
- json_object_int_add(json_row, "reportV2", rx_stats.report_v2);
- json_object_int_add(json_row, "reportV3", rx_stats.report_v3);
+ json_object_int_add(json_row, "queryV1", igmp_stats.query_v1);
+ json_object_int_add(json_row, "queryV2", igmp_stats.query_v2);
+ json_object_int_add(json_row, "queryV3", igmp_stats.query_v3);
+ json_object_int_add(json_row, "leaveV2", igmp_stats.leave_v2);
+ json_object_int_add(json_row, "reportV1", igmp_stats.report_v1);
+ json_object_int_add(json_row, "reportV2", igmp_stats.report_v2);
+ json_object_int_add(json_row, "reportV3", igmp_stats.report_v3);
json_object_int_add(json_row, "mtraceResponse",
- rx_stats.mtrace_rsp);
+ igmp_stats.mtrace_rsp);
json_object_int_add(json_row, "mtraceRequest",
- rx_stats.mtrace_req);
+ igmp_stats.mtrace_req);
json_object_int_add(json_row, "unsupported",
- rx_stats.unsupported);
+ igmp_stats.unsupported);
json_object_int_add(json_row, "totalGroups",
- rx_stats.total_groups);
+ igmp_stats.total_groups);
json_object_int_add(json_row, "totalSourceGroups",
- rx_stats.total_source_groups);
+ igmp_stats.total_source_groups);
+ json_object_int_add(json_row, "joinsFailed",
+ igmp_stats.joins_failed);
+ json_object_int_add(json_row, "joinsSent",
+ igmp_stats.joins_sent);
json_object_object_add(json, ifname ? ifname : "global",
json_row);
vty_json(vty, json);
} else {
- vty_out(vty, "IGMP RX statistics\n");
- vty_out(vty, "Interface : %s\n",
+ vty_out(vty, "IGMP statistics\n");
+ vty_out(vty, "Interface : %s\n",
ifname ? ifname : "global");
- vty_out(vty, "V1 query : %u\n", rx_stats.query_v1);
- vty_out(vty, "V2 query : %u\n", rx_stats.query_v2);
- vty_out(vty, "V3 query : %u\n", rx_stats.query_v3);
- vty_out(vty, "V2 leave : %u\n", rx_stats.leave_v2);
- vty_out(vty, "V1 report : %u\n", rx_stats.report_v1);
- vty_out(vty, "V2 report : %u\n", rx_stats.report_v2);
- vty_out(vty, "V3 report : %u\n", rx_stats.report_v3);
- vty_out(vty, "mtrace response : %u\n", rx_stats.mtrace_rsp);
- vty_out(vty, "mtrace request : %u\n", rx_stats.mtrace_req);
+ vty_out(vty, "V1 query : %u\n", igmp_stats.query_v1);
+ vty_out(vty, "V2 query : %u\n", igmp_stats.query_v2);
+ vty_out(vty, "V3 query : %u\n", igmp_stats.query_v3);
+ vty_out(vty, "V2 leave : %u\n", igmp_stats.leave_v2);
+ vty_out(vty, "V1 report : %u\n",
+ igmp_stats.report_v1);
+ vty_out(vty, "V2 report : %u\n",
+ igmp_stats.report_v2);
+ vty_out(vty, "V3 report : %u\n",
+ igmp_stats.report_v3);
+ vty_out(vty, "mtrace response : %u\n",
+ igmp_stats.mtrace_rsp);
+ vty_out(vty, "mtrace request : %u\n",
+ igmp_stats.mtrace_req);
vty_out(vty, "unsupported : %u\n",
- rx_stats.unsupported);
+ igmp_stats.unsupported);
+ vty_out(vty, "joins failed : %u\n",
+ igmp_stats.joins_failed);
+ vty_out(vty, "joins sent : %u\n",
+ igmp_stats.joins_sent);
vty_out(vty, "total groups : %u\n",
- rx_stats.total_groups);
+ igmp_stats.total_groups);
vty_out(vty, "total source groups : %u\n",
- rx_stats.total_source_groups);
+ igmp_stats.total_source_groups);
}
}
@@ -3995,6 +4010,8 @@ DEFUN (clear_ip_pim_interface_traffic,
pim_ifp->pim_ifstat_assert_send = 0;
pim_ifp->pim_ifstat_bsm_rx = 0;
pim_ifp->pim_ifstat_bsm_tx = 0;
+ pim_ifp->igmp_ifstat_joins_sent = 0;
+ pim_ifp->igmp_ifstat_joins_failed = 0;
}
return CMD_SUCCESS;
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c
index d1b4966ec9..98fa4c4882 100644
--- a/pimd/pim_iface.c
+++ b/pimd/pim_iface.c
@@ -53,8 +53,8 @@
#if PIM_IPV == 4
static void pim_if_igmp_join_del_all(struct interface *ifp);
static int igmp_join_sock(const char *ifname, ifindex_t ifindex,
- struct in_addr group_addr,
- struct in_addr source_addr);
+ struct in_addr group_addr, struct in_addr source_addr,
+ struct pim_interface *pim_ifp);
#endif
void pim_if_init(struct pim_instance *pim)
@@ -576,7 +576,7 @@ void pim_if_addr_add(struct connected *ifc)
close(ij->sock_fd);
join_fd = igmp_join_sock(
ifp->name, ifp->ifindex, ij->group_addr,
- ij->source_addr);
+ ij->source_addr, pim_ifp);
if (join_fd < 0) {
char group_str[INET_ADDRSTRLEN];
char source_str[INET_ADDRSTRLEN];
@@ -1248,12 +1248,16 @@ static struct gm_join *igmp_join_find(struct list *join_list,
}
static int igmp_join_sock(const char *ifname, ifindex_t ifindex,
- struct in_addr group_addr, struct in_addr source_addr)
+ struct in_addr group_addr, struct in_addr source_addr,
+ struct pim_interface *pim_ifp)
{
int join_fd;
+ pim_ifp->igmp_ifstat_joins_sent++;
+
join_fd = pim_socket_raw(IPPROTO_IGMP);
if (join_fd < 0) {
+ pim_ifp->igmp_ifstat_joins_failed++;
return -1;
}
@@ -1269,6 +1273,8 @@ static int igmp_join_sock(const char *ifname, ifindex_t ifindex,
__func__, join_fd, group_str, source_str, ifindex,
ifname, errno, safe_strerror(errno));
+ pim_ifp->igmp_ifstat_joins_failed++;
+
close(join_fd);
return -2;
}
@@ -1288,7 +1294,7 @@ static struct gm_join *igmp_join_new(struct interface *ifp,
assert(pim_ifp);
join_fd = igmp_join_sock(ifp->name, ifp->ifindex, group_addr,
- source_addr);
+ source_addr, pim_ifp);
if (join_fd < 0) {
char group_str[INET_ADDRSTRLEN];
char source_str[INET_ADDRSTRLEN];
diff --git a/pimd/pim_iface.h b/pimd/pim_iface.h
index a1c946149d..244e1aedd1 100644
--- a/pimd/pim_iface.h
+++ b/pimd/pim_iface.h
@@ -189,6 +189,9 @@ struct pim_interface {
bool bsm_enable; /* bsm processing enable */
bool ucast_bsm_accept; /* ucast bsm processing */
+ uint32_t igmp_ifstat_joins_sent;
+ uint32_t igmp_ifstat_joins_failed;
+
struct {
bool enabled;
uint32_t min_rx;
diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c
index 592cd7ec45..fcb335a5b3 100644
--- a/pimd/pim_igmp.c
+++ b/pimd/pim_igmp.c
@@ -220,6 +220,7 @@ static int igmp_sock_open(struct in_addr ifaddr, struct interface *ifp,
int fd;
int join = 0;
struct in_addr group;
+ struct pim_interface *pim_ifp = ifp->info;
fd = pim_socket_mcast(IPPROTO_IGMP, ifaddr, ifp, 1);
@@ -228,7 +229,8 @@ static int igmp_sock_open(struct in_addr ifaddr, struct interface *ifp,
if (PIM_IF_TEST_IGMP_LISTEN_ALLROUTERS(pim_options)) {
if (inet_aton(PIM_ALL_ROUTERS, &group)) {
- if (!pim_socket_join(fd, group, ifaddr, ifp->ifindex))
+ if (!pim_socket_join(fd, group, ifaddr, ifp->ifindex,
+ pim_ifp))
++join;
} else {
zlog_warn(
@@ -244,7 +246,7 @@ static int igmp_sock_open(struct in_addr ifaddr, struct interface *ifp,
IGMP routers must receive general queries for querier election.
*/
if (inet_aton(PIM_ALL_SYSTEMS, &group)) {
- if (!pim_socket_join(fd, group, ifaddr, ifp->ifindex))
+ if (!pim_socket_join(fd, group, ifaddr, ifp->ifindex, pim_ifp))
++join;
} else {
zlog_warn(
@@ -254,7 +256,8 @@ static int igmp_sock_open(struct in_addr ifaddr, struct interface *ifp,
}
if (inet_aton(PIM_ALL_IGMP_ROUTERS, &group)) {
- if (!pim_socket_join(fd, group, ifaddr, ifp->ifindex)) {
+ if (!pim_socket_join(fd, group, ifaddr, ifp->ifindex,
+ pim_ifp)) {
++join;
}
} else {
@@ -489,16 +492,16 @@ static int igmp_recv_query(struct gm_sock *igmp, int query_version,
/* Collecting IGMP Rx stats */
switch (query_version) {
case 1:
- igmp->rx_stats.query_v1++;
+ igmp->igmp_stats.query_v1++;
break;
case 2:
- igmp->rx_stats.query_v2++;
+ igmp->igmp_stats.query_v2++;
break;
case 3:
- igmp->rx_stats.query_v3++;
+ igmp->igmp_stats.query_v3++;
break;
default:
- igmp->rx_stats.unsupported++;
+ igmp->igmp_stats.unsupported++;
}
/*
@@ -630,7 +633,7 @@ static int igmp_v1_recv_report(struct gm_sock *igmp, struct in_addr from,
}
/* Collecting IGMP Rx stats */
- igmp->rx_stats.report_v1++;
+ igmp->igmp_stats.report_v1++;
if (PIM_DEBUG_IGMP_TRACE) {
zlog_warn("%s %s: FIXME WRITEME", __FILE__, __func__);
@@ -782,7 +785,7 @@ int pim_igmp_packet(struct gm_sock *igmp, char *buf, size_t len)
zlog_warn("Ignoring unsupported IGMP message type: %d", msg_type);
/* Collecting IGMP Rx stats */
- igmp->rx_stats.unsupported++;
+ igmp->igmp_stats.unsupported++;
return -1;
}
@@ -1159,7 +1162,7 @@ static struct gm_sock *igmp_sock_new(int fd, struct in_addr ifaddr,
pim_ifp->gm_default_robustness_variable;
igmp->sock_creation = pim_time_monotonic_sec();
- igmp_stats_init(&igmp->rx_stats);
+ igmp_stats_init(&igmp->igmp_stats);
if (mtrace_only) {
igmp->mtrace_only = mtrace_only;
diff --git a/pimd/pim_igmp.h b/pimd/pim_igmp.h
index 4d7229dcce..4160dcb118 100644
--- a/pimd/pim_igmp.h
+++ b/pimd/pim_igmp.h
@@ -100,7 +100,7 @@ struct gm_sock {
bool mtrace_only;
- struct igmp_stats rx_stats;
+ struct igmp_stats igmp_stats;
};
struct pim_interface;
diff --git a/pimd/pim_igmp_mtrace.c b/pimd/pim_igmp_mtrace.c
index d8210168e2..11bb2db7eb 100644
--- a/pimd/pim_igmp_mtrace.c
+++ b/pimd/pim_igmp_mtrace.c
@@ -626,7 +626,7 @@ int igmp_mtrace_recv_qry_req(struct gm_sock *igmp, struct ip *ip_hdr,
}
/* Collecting IGMP Rx stats */
- igmp->rx_stats.mtrace_req++;
+ igmp->igmp_stats.mtrace_req++;
if (PIM_DEBUG_MTRACE)
mtrace_debug(pim_ifp, mtracep, igmp_msg_len);
@@ -843,7 +843,7 @@ int igmp_mtrace_recv_response(struct gm_sock *igmp, struct ip *ip_hdr,
mtracep->checksum = checksum;
/* Collecting IGMP Rx stats */
- igmp->rx_stats.mtrace_rsp++;
+ igmp->igmp_stats.mtrace_rsp++;
if (PIM_DEBUG_MTRACE)
mtrace_debug(pim_ifp, mtracep, igmp_msg_len);
diff --git a/pimd/pim_igmp_stats.c b/pimd/pim_igmp_stats.c
index 0cf1bb1ec1..e1eb166b65 100644
--- a/pimd/pim_igmp_stats.c
+++ b/pimd/pim_igmp_stats.c
@@ -45,4 +45,6 @@ void igmp_stats_add(struct igmp_stats *a, struct igmp_stats *b)
a->unsupported += b->unsupported;
a->total_groups += b->total_groups;
a->total_source_groups += b->total_source_groups;
+ a->joins_sent += b->joins_sent;
+ a->joins_failed += b->joins_failed;
}
diff --git a/pimd/pim_igmp_stats.h b/pimd/pim_igmp_stats.h
index 47167efb3a..42c0c9ee31 100644
--- a/pimd/pim_igmp_stats.h
+++ b/pimd/pim_igmp_stats.h
@@ -35,6 +35,8 @@ struct igmp_stats {
uint32_t unsupported;
uint32_t total_groups;
uint32_t total_source_groups;
+ uint32_t joins_sent;
+ uint32_t joins_failed;
};
#if PIM_IPV == 4
diff --git a/pimd/pim_igmpv2.c b/pimd/pim_igmpv2.c
index a7c7c99ebf..09a82069a2 100644
--- a/pimd/pim_igmpv2.c
+++ b/pimd/pim_igmpv2.c
@@ -130,7 +130,7 @@ int igmp_v2_recv_report(struct gm_sock *igmp, struct in_addr from,
}
/* Collecting IGMP Rx stats */
- igmp->rx_stats.report_v2++;
+ igmp->igmp_stats.report_v2++;
memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr));
@@ -221,7 +221,7 @@ int igmp_v2_recv_leave(struct gm_sock *igmp, struct ip *ip_hdr,
}
/* Collecting IGMP Rx stats */
- igmp->rx_stats.leave_v2++;
+ igmp->igmp_stats.leave_v2++;
/*
* RFC 3376
diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c
index 87554bc8ba..1ce5fdc4b0 100644
--- a/pimd/pim_igmpv3.c
+++ b/pimd/pim_igmpv3.c
@@ -1854,7 +1854,7 @@ int igmp_v3_recv_report(struct gm_sock *igmp, struct in_addr from,
}
/* Collecting IGMP Rx stats */
- igmp->rx_stats.report_v3++;
+ igmp->igmp_stats.report_v3++;
num_groups = ntohs(
*(uint16_t *)(igmp_msg + IGMP_V3_REPORT_NUMGROUPS_OFFSET));
diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c
index d3edc5d0fe..3980e4828d 100644
--- a/pimd/pim_pim.c
+++ b/pimd/pim_pim.c
@@ -428,7 +428,7 @@ static int pim_sock_open(struct interface *ifp)
return -1;
if (pim_socket_join(fd, qpim_all_pim_routers_addr,
- pim_ifp->primary_address, ifp->ifindex)) {
+ pim_ifp->primary_address, ifp->ifindex, pim_ifp)) {
close(fd);
return -2;
}
@@ -467,6 +467,8 @@ void pim_ifstat_reset(struct interface *ifp)
pim_ifp->pim_ifstat_bsm_cfg_miss = 0;
pim_ifp->pim_ifstat_ucast_bsm_cfg_miss = 0;
pim_ifp->pim_ifstat_bsm_invalid_sz = 0;
+ pim_ifp->igmp_ifstat_joins_sent = 0;
+ pim_ifp->igmp_ifstat_joins_failed = 0;
}
void pim_sock_reset(struct interface *ifp)
diff --git a/pimd/pim_sock.c b/pimd/pim_sock.c
index 92e2d18451..8619cc3f83 100644
--- a/pimd/pim_sock.c
+++ b/pimd/pim_sock.c
@@ -38,6 +38,7 @@
#include "pimd.h"
#include "pim_mroute.h"
+#include "pim_iface.h"
#include "pim_sock.h"
#include "pim_str.h"
@@ -233,7 +234,8 @@ int pim_socket_mcast(int protocol, pim_addr ifaddr, struct interface *ifp,
return fd;
}
-int pim_socket_join(int fd, pim_addr group, pim_addr ifaddr, ifindex_t ifindex)
+int pim_socket_join(int fd, pim_addr group, pim_addr ifaddr, ifindex_t ifindex,
+ struct pim_interface *pim_ifp)
{
int ret;
@@ -248,11 +250,14 @@ int pim_socket_join(int fd, pim_addr group, pim_addr ifaddr, ifindex_t ifindex)
ret = setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &opt, sizeof(opt));
#endif
+ pim_ifp->igmp_ifstat_joins_sent++;
+
if (ret) {
flog_err(
EC_LIB_SOCKET,
"Failure socket joining fd=%d group %pPAs on interface address %pPAs: %m",
fd, &group, &ifaddr);
+ pim_ifp->igmp_ifstat_joins_failed++;
return ret;
}
diff --git a/pimd/pim_sock.h b/pimd/pim_sock.h
index 97cbda0c10..2e9c043e84 100644
--- a/pimd/pim_sock.h
+++ b/pimd/pim_sock.h
@@ -40,8 +40,8 @@ void pim_socket_ip_hdr(int fd);
int pim_socket_raw(int protocol);
int pim_socket_mcast(int protocol, pim_addr ifaddr, struct interface *ifp,
uint8_t loop);
-int pim_socket_join(int fd, pim_addr group, pim_addr ifaddr, ifindex_t ifindex);
-
+int pim_socket_join(int fd, pim_addr group, pim_addr ifaddr, ifindex_t ifindex,
+ struct pim_interface *pim_ifp);
int pim_socket_recvfromto(int fd, uint8_t *buf, size_t len,
struct sockaddr_storage *from, socklen_t *fromlen,
struct sockaddr_storage *to, socklen_t *tolen,