diff options
Diffstat (limited to 'pimd/pim_cmd.c')
| -rw-r--r-- | pimd/pim_cmd.c | 276 |
1 files changed, 222 insertions, 54 deletions
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index e6e9c2d0c8..7788191454 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -658,6 +658,7 @@ static void igmp_show_interfaces_single(struct pim_instance *pim, long oqpi_msec; /* Other Querier Present Interval */ long qri_msec; time_t now; + int lmqc; json_object *json = NULL; json_object *json_row = NULL; @@ -702,8 +703,8 @@ static void igmp_show_interfaces_single(struct pim_instance *pim, pim_ifp->igmp_query_max_response_time_dsec); lmqt_msec = PIM_IGMP_LMQT_MSEC( - pim_ifp->igmp_query_max_response_time_dsec, - igmp->querier_robustness_variable); + pim_ifp->igmp_specific_query_max_response_time_dsec, + pim_ifp->igmp_last_member_query_count); ohpi_msec = PIM_IGMP_OHPI_DSEC( @@ -719,6 +720,7 @@ static void igmp_show_interfaces_single(struct pim_instance *pim, pim_ifp->pim_sock_fd); else mloop = 0; + lmqc = pim_ifp->igmp_last_member_query_count; if (uj) { json_row = json_object_new_object(); @@ -744,6 +746,9 @@ static void igmp_show_interfaces_single(struct pim_instance *pim, "timerGroupMembershipIntervalMsec", gmi_msec); json_object_int_add(json_row, + "lastMemberQueryCount", + lmqc); + json_object_int_add(json_row, "timerLastMemberQueryMsec", lmqt_msec); json_object_int_add( @@ -810,6 +815,9 @@ static void igmp_show_interfaces_single(struct pim_instance *pim, "Group Membership Interval : %lis\n", gmi_msec / 1000); vty_out(vty, + "Last Member Query Count : %d\n", + lmqc); + vty_out(vty, "Last Member Query Time : %lis\n", lmqt_msec / 1000); vty_out(vty, @@ -3074,7 +3082,7 @@ static void pim_show_group_rp_mappings_info(struct pim_instance *pim, json_object *json_row = NULL; if (pim->global_scope.current_bsr.s_addr == INADDR_ANY) - strncpy(bsr_str, "0.0.0.0", sizeof(bsr_str)); + strlcpy(bsr_str, "0.0.0.0", sizeof(bsr_str)); else pim_inet4_dump("<bsr?>", pim->global_scope.current_bsr, bsr_str, @@ -3642,7 +3650,7 @@ static void pim_show_bsr(struct pim_instance *pim, vty_out(vty, "PIMv2 Bootstrap information\n"); if (pim->global_scope.current_bsr.s_addr == INADDR_ANY) { - strncpy(bsr_str, "0.0.0.0", sizeof(bsr_str)); + strlcpy(bsr_str, "0.0.0.0", sizeof(bsr_str)); pim_time_uptime(uptime, sizeof(uptime), pim->global_scope.current_bsr_first_ts); pim_time_uptime(last_bsm_seen, sizeof(last_bsm_seen), @@ -3661,16 +3669,16 @@ static void pim_show_bsr(struct pim_instance *pim, switch (pim->global_scope.state) { case NO_INFO: - strncpy(bsr_state, "NO_INFO", sizeof(bsr_state)); + strlcpy(bsr_state, "NO_INFO", sizeof(bsr_state)); break; case ACCEPT_ANY: - strncpy(bsr_state, "ACCEPT_ANY", sizeof(bsr_state)); + strlcpy(bsr_state, "ACCEPT_ANY", sizeof(bsr_state)); break; case ACCEPT_PREFERRED: - strncpy(bsr_state, "ACCEPT_PREFERRED", sizeof(bsr_state)); + strlcpy(bsr_state, "ACCEPT_PREFERRED", sizeof(bsr_state)); break; default: - strncpy(bsr_state, "", sizeof(bsr_state)); + strlcpy(bsr_state, "", sizeof(bsr_state)); } if (uj) { @@ -3798,44 +3806,51 @@ DEFUN (clear_ip_pim_statistics, return CMD_SUCCESS; } -static void mroute_add_all(struct pim_instance *pim) +static void clear_mroute(struct pim_instance *pim) { - struct listnode *node; - struct channel_oil *c_oil; + struct pim_upstream *up; + struct interface *ifp; - for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) { - if (pim_mroute_add(c_oil, __PRETTY_FUNCTION__)) { - /* just log warning */ - char source_str[INET_ADDRSTRLEN]; - char group_str[INET_ADDRSTRLEN]; - pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, - source_str, sizeof(source_str)); - pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, - group_str, sizeof(group_str)); - zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC", - __FILE__, __PRETTY_FUNCTION__, source_str, - group_str); + /* scan interfaces */ + FOR_ALL_INTERFACES (pim->vrf, ifp) { + struct pim_interface *pim_ifp = ifp->info; + struct listnode *sock_node; + struct igmp_sock *igmp; + struct pim_ifchannel *ch; + + if (!pim_ifp) + continue; + + /* deleting all ifchannels */ + while (!RB_EMPTY(pim_ifchannel_rb, &pim_ifp->ifchannel_rb)) { + ch = RB_ROOT(pim_ifchannel_rb, &pim_ifp->ifchannel_rb); + + pim_ifchannel_delete(ch); } - } -} -static void mroute_del_all(struct pim_instance *pim) -{ - struct listnode *node; - struct channel_oil *c_oil; + /* clean up all igmp groups */ + /* scan igmp sockets */ + for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, + igmp)) { + + struct igmp_group *grp; + + if (igmp->igmp_group_list) { + while (igmp->igmp_group_list->count) { + grp = listnode_head( + igmp->igmp_group_list); + igmp_group_delete(grp); + } + } - for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) { - if (pim_mroute_del(c_oil, __PRETTY_FUNCTION__)) { - /* just log warning */ - char source_str[INET_ADDRSTRLEN]; - char group_str[INET_ADDRSTRLEN]; - pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, - source_str, sizeof(source_str)); - pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, - group_str, sizeof(group_str)); - zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC", - __FILE__, __PRETTY_FUNCTION__, source_str, - group_str); + } + } + + /* clean up all upstreams*/ + if (pim->upstream_list) { + while (pim->upstream_list->count) { + up = listnode_head(pim->upstream_list); + pim_upstream_del(pim, up, __PRETTY_FUNCTION__); } } } @@ -3854,8 +3869,7 @@ DEFUN (clear_ip_mroute, if (!vrf) return CMD_WARNING; - mroute_del_all(vrf->info); - mroute_add_all(vrf->info); + clear_mroute(vrf->info); return CMD_SUCCESS; } @@ -5602,11 +5616,54 @@ DEFUN (show_ip_mroute_vrf_all, return CMD_SUCCESS; } +DEFUN (clear_ip_mroute_count, + clear_ip_mroute_count_cmd, + "clear ip mroute [vrf NAME] count", + CLEAR_STR + IP_STR + MROUTE_STR + VRF_CMD_HELP_STR + "Route and packet count data\n") +{ + int idx = 2; + struct listnode *node; + struct channel_oil *c_oil; + struct static_route *sr; + struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); + struct pim_instance *pim; + + if (!vrf) + return CMD_WARNING; + + pim = vrf->info; + for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) { + if (!c_oil->installed) + continue; + + pim_mroute_update_counters(c_oil); + c_oil->cc.origpktcnt = c_oil->cc.pktcnt; + c_oil->cc.origbytecnt = c_oil->cc.bytecnt; + c_oil->cc.origwrong_if = c_oil->cc.wrong_if; + } + + for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, sr)) { + if (!sr->c_oil.installed) + continue; + + pim_mroute_update_counters(&sr->c_oil); + + sr->c_oil.cc.origpktcnt = sr->c_oil.cc.pktcnt; + sr->c_oil.cc.origbytecnt = sr->c_oil.cc.bytecnt; + sr->c_oil.cc.origwrong_if = sr->c_oil.cc.wrong_if; + } + return CMD_SUCCESS; +} + static void show_mroute_count(struct pim_instance *pim, struct vty *vty) { struct listnode *node; struct channel_oil *c_oil; - struct static_route *s_route; + struct static_route *sr; vty_out(vty, "\n"); @@ -5630,28 +5687,30 @@ static void show_mroute_count(struct pim_instance *pim, struct vty *vty) vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n", source_str, group_str, c_oil->cc.lastused / 100, - c_oil->cc.pktcnt, c_oil->cc.bytecnt, - c_oil->cc.wrong_if); + c_oil->cc.pktcnt - c_oil->cc.origpktcnt, + c_oil->cc.bytecnt - c_oil->cc.origbytecnt, + c_oil->cc.wrong_if - c_oil->cc.origwrong_if); } - for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) { + for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, sr)) { char group_str[INET_ADDRSTRLEN]; char source_str[INET_ADDRSTRLEN]; - if (!s_route->c_oil.installed) + if (!sr->c_oil.installed) continue; - pim_mroute_update_counters(&s_route->c_oil); + pim_mroute_update_counters(&sr->c_oil); - pim_inet4_dump("<group?>", s_route->c_oil.oil.mfcc_mcastgrp, + pim_inet4_dump("<group?>", sr->c_oil.oil.mfcc_mcastgrp, group_str, sizeof(group_str)); - pim_inet4_dump("<source?>", s_route->c_oil.oil.mfcc_origin, + pim_inet4_dump("<source?>", sr->c_oil.oil.mfcc_origin, source_str, sizeof(source_str)); vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n", - source_str, group_str, s_route->c_oil.cc.lastused, - s_route->c_oil.cc.pktcnt, s_route->c_oil.cc.bytecnt, - s_route->c_oil.cc.wrong_if); + source_str, group_str, sr->c_oil.cc.lastused, + sr->c_oil.cc.pktcnt - sr->c_oil.cc.origpktcnt, + sr->c_oil.cc.bytecnt - sr->c_oil.cc.origbytecnt, + sr->c_oil.cc.wrong_if - sr->c_oil.cc.origwrong_if); } } @@ -7161,6 +7220,106 @@ DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec, return CMD_SUCCESS; } +#define IGMP_LAST_MEMBER_QUERY_COUNT_MIN (1) +#define IGMP_LAST_MEMBER_QUERY_COUNT_MAX (7) + +DEFUN (interface_ip_igmp_last_member_query_count, + interface_ip_igmp_last_member_query_count_cmd, + "ip igmp last-member-query-count (1-7)", + IP_STR + IFACE_IGMP_STR + IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR + "Last member query count\n") +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + struct pim_interface *pim_ifp = ifp->info; + int last_member_query_count; + int ret; + + if (!pim_ifp) { + ret = pim_cmd_igmp_start(vty, ifp); + if (ret != CMD_SUCCESS) + return ret; + pim_ifp = ifp->info; + } + + last_member_query_count = atoi(argv[3]->arg); + + pim_ifp->igmp_last_member_query_count = last_member_query_count; + + return CMD_SUCCESS; +} + +DEFUN (interface_no_ip_igmp_last_member_query_count, + interface_no_ip_igmp_last_member_query_count_cmd, + "no ip igmp last-member-query-count", + NO_STR + IP_STR + IFACE_IGMP_STR + IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR) +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + struct pim_interface *pim_ifp = ifp->info; + + if (!pim_ifp) + return CMD_SUCCESS; + + pim_ifp->igmp_last_member_query_count = + IGMP_DEFAULT_ROBUSTNESS_VARIABLE; + + return CMD_SUCCESS; +} + +#define IGMP_LAST_MEMBER_QUERY_INTERVAL_MIN (1) +#define IGMP_LAST_MEMBER_QUERY_INTERVAL_MAX (255) + +DEFUN (interface_ip_igmp_last_member_query_interval, + interface_ip_igmp_last_member_query_interval_cmd, + "ip igmp last-member-query-interval (1-255)", + IP_STR + IFACE_IGMP_STR + IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR + "Last member query interval in deciseconds\n") +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + struct pim_interface *pim_ifp = ifp->info; + int last_member_query_interval; + int ret; + + if (!pim_ifp) { + ret = pim_cmd_igmp_start(vty, ifp); + if (ret != CMD_SUCCESS) + return ret; + pim_ifp = ifp->info; + } + + last_member_query_interval = atoi(argv[3]->arg); + pim_ifp->igmp_specific_query_max_response_time_dsec + = last_member_query_interval; + + return CMD_SUCCESS; +} + +DEFUN (interface_no_ip_igmp_last_member_query_interval, + interface_no_ip_igmp_last_member_query_interval_cmd, + "no ip igmp last-member-query-interval", + NO_STR + IP_STR + IFACE_IGMP_STR + IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR) +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + struct pim_interface *pim_ifp = ifp->info; + + if (!pim_ifp) + return CMD_SUCCESS; + + pim_ifp->igmp_specific_query_max_response_time_dsec = + IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC; + + return CMD_SUCCESS; +} + DEFUN (interface_ip_pim_drprio, interface_ip_pim_drprio_cmd, "ip pim drpriority (1-4294967295)", @@ -10116,6 +10275,14 @@ void pim_cmd_init(void) &interface_ip_igmp_query_max_response_time_dsec_cmd); install_element(INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_dsec_cmd); + install_element(INTERFACE_NODE, + &interface_ip_igmp_last_member_query_count_cmd); + install_element(INTERFACE_NODE, + &interface_no_ip_igmp_last_member_query_count_cmd); + install_element(INTERFACE_NODE, + &interface_ip_igmp_last_member_query_interval_cmd); + install_element(INTERFACE_NODE, + &interface_no_ip_igmp_last_member_query_interval_cmd); install_element(INTERFACE_NODE, &interface_ip_pim_activeactive_cmd); install_element(INTERFACE_NODE, &interface_ip_pim_ssm_cmd); install_element(INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd); @@ -10187,6 +10354,7 @@ void pim_cmd_init(void) install_element(VIEW_NODE, &show_ip_pim_bsm_db_cmd); install_element(VIEW_NODE, &show_ip_pim_statistics_cmd); + install_element(ENABLE_NODE, &clear_ip_mroute_count_cmd); install_element(ENABLE_NODE, &clear_ip_interfaces_cmd); install_element(ENABLE_NODE, &clear_ip_igmp_interfaces_cmd); install_element(ENABLE_NODE, &clear_ip_mroute_cmd); |
