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,