From: Mladen Sablic Date: Tue, 27 Feb 2018 22:16:45 +0000 (+0100) Subject: pimd: mtrace only IGMP sockets X-Git-Tag: frr-5.0-dev~175^2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=f83f396624b34c5e50241910f6bdbfacb4249559;p=mirror%2Ffrr.git pimd: mtrace only IGMP sockets Feature of mtrace only IGMP sockets on pim sm and pim ssm interfaces. Modifed IGMP socket creation and show igmp interface command output. Signed-off-by: Mladen Sablic --- diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 6002794658..803e7bb013 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -604,11 +604,18 @@ static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty, json_object_object_add(json, ifp->name, json_row); + if (igmp->mtrace_only) { + json_object_boolean_true_add( + json_row, "mtraceOnly"); + } } else { vty_out(vty, "%-9s %5s %15s %d %7s %11s %8s\n", ifp->name, - if_is_up(ifp) ? "up" : "down", + if_is_up(ifp) + ? (igmp->mtrace_only ? "mtrc" + : "up") + : "down", inet_ntoa(igmp->ifaddr), pim_ifp->igmp_version, igmp->t_igmp_query_timer ? "local" @@ -758,10 +765,17 @@ static void igmp_show_interfaces_single(struct pim_instance *pim, json_object_object_add(json, ifp->name, json_row); + if (igmp->mtrace_only) { + json_object_boolean_true_add( + json_row, "mtraceOnly"); + } } else { vty_out(vty, "Interface : %s\n", ifp->name); vty_out(vty, "State : %s\n", - if_is_up(ifp) ? "up" : "down"); + if_is_up(ifp) + ? (igmp->mtrace_only ? "mtrace" + : "up") + : "down"); vty_out(vty, "Address : %s\n", inet_ntoa(pim_ifp->primary_address)); vty_out(vty, "Uptime : %s\n", uptime); diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index 998f8fc2ca..ff7238ae97 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -574,7 +574,11 @@ void pim_if_addr_add(struct connected *ifc) /* if addr new, add IGMP socket */ if (ifc->address->family == AF_INET) pim_igmp_sock_add(pim_ifp->igmp_socket_list, - ifaddr, ifp); + ifaddr, ifp, false); + } else if (igmp->mtrace_only) { + igmp_sock_delete(igmp); + pim_igmp_sock_add(pim_ifp->igmp_socket_list, ifaddr, + ifp, false); } /* Replay Static IGMP groups */ @@ -611,6 +615,20 @@ void pim_if_addr_add(struct connected *ifc) } } } /* igmp */ + else { + struct igmp_sock *igmp; + + /* lookup IGMP socket */ + igmp = pim_igmp_sock_lookup_ifaddr(pim_ifp->igmp_socket_list, + ifaddr); + if (ifc->address->family == AF_INET) { + if (igmp) + igmp_sock_delete(igmp); + /* if addr new, add IGMP socket */ + pim_igmp_sock_add(pim_ifp->igmp_socket_list, ifaddr, + ifp, true); + } + } /* igmp mtrace only */ if (PIM_IF_TEST_PIM(pim_ifp->options)) { diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c index c0a58516d9..5e1aecc3a3 100644 --- a/pimd/pim_igmp.c +++ b/pimd/pim_igmp.c @@ -281,6 +281,9 @@ static int igmp_recv_query(struct igmp_sock *igmp, int query_version, uint16_t recv_checksum; uint16_t checksum; + if (igmp->mtrace_only) + return 0; + memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr)); ifp = igmp->interface; @@ -387,6 +390,9 @@ static int igmp_v1_recv_report(struct igmp_sock *igmp, struct in_addr from, on_trace(__PRETTY_FUNCTION__, igmp->interface, from); + if (igmp->mtrace_only) + return 0; + if (igmp_msg_len != IGMP_V12_MSG_SIZE) { zlog_warn( "Recv IGMP report v1 from %s on %s: size=%d other than correct=%d", @@ -510,7 +516,6 @@ int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len) return igmp_mtrace_recv_response(igmp, ip_hdr, ip_hdr->ip_src, from_str, igmp_msg, igmp_msg_len); - break; case PIM_IGMP_MTRACE_QUERY_REQUEST: return igmp_mtrace_recv_qry_req(igmp, ip_hdr, ip_hdr->ip_src, from_str, igmp_msg, @@ -819,7 +824,7 @@ static int igmp_group_hash_equal(const void *arg1, const void *arg2) } static struct igmp_sock *igmp_sock_new(int fd, struct in_addr ifaddr, - struct interface *ifp) + struct interface *ifp, int mtrace_only) { struct pim_interface *pim_ifp; struct igmp_sock *igmp; @@ -862,6 +867,13 @@ static struct igmp_sock *igmp_sock_new(int fd, struct in_addr ifaddr, pim_ifp->igmp_default_robustness_variable; igmp->sock_creation = pim_time_monotonic_sec(); + if (mtrace_only) { + igmp->mtrace_only = mtrace_only; + return igmp; + } + + igmp->mtrace_only = false; + /* igmp_startup_mode_on() will reset QQI: @@ -919,7 +931,8 @@ static void igmp_read_on(struct igmp_sock *igmp) struct igmp_sock *pim_igmp_sock_add(struct list *igmp_sock_list, struct in_addr ifaddr, - struct interface *ifp) + struct interface *ifp, + bool mtrace_only) { struct pim_interface *pim_ifp; struct igmp_sock *igmp; @@ -934,7 +947,7 @@ struct igmp_sock *pim_igmp_sock_add(struct list *igmp_sock_list, return 0; } - igmp = igmp_sock_new(fd, ifaddr, ifp); + igmp = igmp_sock_new(fd, ifaddr, ifp, mtrace_only); if (!igmp) { zlog_err("%s %s: igmp_sock_new() failure", __FILE__, __PRETTY_FUNCTION__); diff --git a/pimd/pim_igmp.h b/pimd/pim_igmp.h index 962c50e76a..561a127d0f 100644 --- a/pimd/pim_igmp.h +++ b/pimd/pim_igmp.h @@ -90,6 +90,8 @@ struct igmp_sock { int querier_robustness_variable; /* QRV */ int startup_query_count; + bool mtrace_only; + struct list *igmp_group_list; /* list of struct igmp_group */ struct hash *igmp_group_hash; }; @@ -99,7 +101,8 @@ struct igmp_sock *pim_igmp_sock_lookup_ifaddr(struct list *igmp_sock_list, struct igmp_sock *igmp_sock_lookup_by_fd(struct list *igmp_sock_list, int fd); struct igmp_sock *pim_igmp_sock_add(struct list *igmp_sock_list, struct in_addr ifaddr, - struct interface *ifp); + struct interface *ifp, + bool mtrace_only); void igmp_sock_delete(struct igmp_sock *igmp); void igmp_sock_free(struct igmp_sock *igmp); void igmp_sock_delete_all(struct interface *ifp); diff --git a/pimd/pim_igmpv2.c b/pimd/pim_igmpv2.c index efa36e618f..dbbe83a965 100644 --- a/pimd/pim_igmpv2.c +++ b/pimd/pim_igmpv2.c @@ -111,6 +111,9 @@ int igmp_v2_recv_report(struct igmp_sock *igmp, struct in_addr from, on_trace(__PRETTY_FUNCTION__, igmp->interface, from); + if (igmp->mtrace_only) + return 0; + if (igmp_msg_len != IGMP_V12_MSG_SIZE) { zlog_warn( "Recv IGMPv2 REPORT from %s on %s: size=%d other than correct=%d", @@ -154,6 +157,9 @@ int igmp_v2_recv_leave(struct igmp_sock *igmp, struct in_addr from, on_trace(__PRETTY_FUNCTION__, igmp->interface, from); + if (igmp->mtrace_only) + return 0; + if (igmp_msg_len != IGMP_V12_MSG_SIZE) { zlog_warn( "Recv IGMPv2 LEAVE from %s on %s: size=%d other than correct=%d", diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c index ecde546c06..3360e36b4a 100644 --- a/pimd/pim_igmpv3.c +++ b/pimd/pim_igmpv3.c @@ -1874,6 +1874,9 @@ int igmp_v3_recv_report(struct igmp_sock *igmp, struct in_addr from, int local_ncb = 0; struct pim_interface *pim_ifp; + if (igmp->mtrace_only) + return 0; + pim_ifp = igmp->interface->info; if (igmp_msg_len < IGMP_V3_MSG_MIN_SIZE) {