diff options
| author | Donatas Abraitis <donatas@opensourcerouting.org> | 2022-03-10 18:10:43 +0200 | 
|---|---|---|
| committer | Donatas Abraitis <donatas@opensourcerouting.org> | 2022-03-13 19:31:34 +0200 | 
| commit | f2058cb425b6f2e5efb3ac8608c47bcc2da5535d (patch) | |
| tree | fd6568d21b7d67043c2bfb19a24767949a2de6ac /pimd | |
| parent | 7547d5288e91d7bdc09aff4cd902d6cedbabfafc (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.c | 79 | ||||
| -rw-r--r-- | pimd/pim_iface.c | 16 | ||||
| -rw-r--r-- | pimd/pim_iface.h | 3 | ||||
| -rw-r--r-- | pimd/pim_igmp.c | 23 | ||||
| -rw-r--r-- | pimd/pim_igmp.h | 2 | ||||
| -rw-r--r-- | pimd/pim_igmp_mtrace.c | 4 | ||||
| -rw-r--r-- | pimd/pim_igmp_stats.c | 2 | ||||
| -rw-r--r-- | pimd/pim_igmp_stats.h | 2 | ||||
| -rw-r--r-- | pimd/pim_igmpv2.c | 4 | ||||
| -rw-r--r-- | pimd/pim_igmpv3.c | 2 | ||||
| -rw-r--r-- | pimd/pim_pim.c | 4 | ||||
| -rw-r--r-- | pimd/pim_sock.c | 7 | ||||
| -rw-r--r-- | pimd/pim_sock.h | 4 | 
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,  | 
