Skip to content

Commit

Permalink
pimd: handle new MSDP peers counters
Browse files Browse the repository at this point in the history
Add new version of `show msdp peer` command with extra details and
a new command to clear MSDP peer counters.

Signed-off-by: Rafael Zalamena <[email protected]>
  • Loading branch information
rzalamena committed Dec 23, 2024
1 parent f9c85ed commit 55429e6
Showing 1 changed file with 195 additions and 57 deletions.
252 changes: 195 additions & 57 deletions pimd/pim_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -7842,6 +7842,91 @@ static void ip_msdp_show_peers(struct pim_instance *pim, struct vty *vty,
vty_json(vty, json);
}

static void msdp_peer_details_add_json(struct json_object *peer_json,
const struct pim_msdp_peer *peer)
{
char state_str[PIM_MSDP_STATE_STRLEN];
char holdtimer[PIM_MSDP_TIMER_STRLEN];
char timebuf[PIM_MSDP_UPTIME_STRLEN];
char katimer[PIM_MSDP_TIMER_STRLEN];
char crtimer[PIM_MSDP_TIMER_STRLEN];
time_t now;

if (peer->state == PIM_MSDP_ESTABLISHED) {
now = pim_time_monotonic_sec();
pim_time_uptime(timebuf, sizeof(timebuf), now - peer->uptime);
} else
strlcpy(timebuf, "-", sizeof(timebuf));

pim_msdp_state_dump(peer->state, state_str, sizeof(state_str));
pim_time_timer_to_hhmmss(katimer, sizeof(katimer), peer->ka_timer);
pim_time_timer_to_hhmmss(crtimer, sizeof(crtimer), peer->cr_timer);
pim_time_timer_to_hhmmss(holdtimer, sizeof(holdtimer), peer->hold_timer);

if (peer->state == PIM_MSDP_ESTABLISHED) {
union {
struct sockaddr sa;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
} sock_address;
socklen_t sock_address_size = sizeof(sock_address);
char address_string[INET6_ADDRSTRLEN];

memset(&sock_address, 0, sizeof(sock_address));

if (getsockname(peer->fd, &sock_address.sa, &sock_address_size) == -1) {
zlog_warn("MSDP peer failed to get socket local address: (%d) %s", errno,
strerror(errno));
return;
}

inet_ntop(AF_INET, &sock_address.sin.sin_addr, address_string,
sizeof(address_string));
json_object_string_add(peer_json, "local", address_string);
json_object_int_add(peer_json, "localPort", ntohs(sock_address.sin.sin_port));

if (getpeername(peer->fd, &sock_address.sa, &sock_address_size) == -1) {
zlog_warn("MSDP peer failed to get socket peer address: (%d) %s", errno,
strerror(errno));
return;
}

inet_ntop(AF_INET, &sock_address.sin.sin_addr, address_string,
sizeof(address_string));
json_object_string_add(peer_json, "peer", address_string);
json_object_int_add(peer_json, "peerPort", ntohs(sock_address.sin.sin_port));
}

if (peer->flags & PIM_MSDP_PEERF_IN_GROUP)
json_object_string_add(peer_json, "meshGroupName", peer->mesh_group_name);

json_object_string_add(peer_json, "state", state_str);
json_object_string_add(peer_json, "upTime", timebuf);
json_object_string_add(peer_json, "keepAliveTimer", katimer);
json_object_string_add(peer_json, "connRetryTimer", crtimer);
json_object_string_add(peer_json, "holdTimer", holdtimer);
json_object_string_add(peer_json, "lastReset", peer->last_reset);
json_object_int_add(peer_json, "connAttempts", peer->conn_attempts);
json_object_int_add(peer_json, "establishedChanges", peer->est_flaps);
json_object_int_add(peer_json, "saCount", peer->sa_cnt);
json_object_int_add(peer_json, "kaSent", peer->ka_tx_cnt);
json_object_int_add(peer_json, "kaRcvd", peer->ka_rx_cnt);
json_object_int_add(peer_json, "saSent", peer->sa_tx_cnt);
json_object_int_add(peer_json, "saRcvd", peer->sa_rx_cnt);
if (peer->asn != 0)
json_object_int_add(peer_json, "asn", peer->asn);

json_object_int_add(peer_json, "saFilteredIn", peer->acl_in_count);
if (peer->acl_in)
json_object_string_add(peer_json, "saFilterIn", peer->acl_in);

json_object_int_add(peer_json, "saFilteredOut", peer->acl_out_count);
if (peer->acl_out)
json_object_string_add(peer_json, "saFilterout", peer->acl_out);

json_object_int_add(peer_json, "rpfLookupFailures", peer->rpf_lookup_failure_count);
}

static void ip_msdp_show_peers_detail(struct pim_instance *pim, struct vty *vty,
const char *peer, bool uj)
{
Expand All @@ -7867,6 +7952,13 @@ static void ip_msdp_show_peers_detail(struct pim_instance *pim, struct vty *vty,
if (strcmp(peer, "detail") && strcmp(peer, peer_str))
continue;

if (uj) {
json_row = json_object_new_object();
msdp_peer_details_add_json(json_row, mp);
json_object_object_add(json, peer_str, json_row);
continue;
}

if (mp->state == PIM_MSDP_ESTABLISHED) {
now = pim_time_monotonic_sec();
pim_time_uptime(timebuf, sizeof(timebuf),
Expand All @@ -7884,63 +7976,29 @@ static void ip_msdp_show_peers_detail(struct pim_instance *pim, struct vty *vty,
pim_time_timer_to_hhmmss(holdtimer, sizeof(holdtimer),
mp->hold_timer);

if (uj) {
json_row = json_object_new_object();
json_object_string_add(json_row, "peer", peer_str);
json_object_string_add(json_row, "local", local_str);
if (mp->flags & PIM_MSDP_PEERF_IN_GROUP)
json_object_string_add(json_row,
"meshGroupName",
mp->mesh_group_name);
json_object_string_add(json_row, "state", state_str);
json_object_string_add(json_row, "upTime", timebuf);
json_object_string_add(json_row, "keepAliveTimer",
katimer);
json_object_string_add(json_row, "connRetryTimer",
crtimer);
json_object_string_add(json_row, "holdTimer",
holdtimer);
json_object_string_add(json_row, "lastReset",
mp->last_reset);
json_object_int_add(json_row, "connAttempts",
mp->conn_attempts);
json_object_int_add(json_row, "establishedChanges",
mp->est_flaps);
json_object_int_add(json_row, "saCount", mp->sa_cnt);
json_object_int_add(json_row, "kaSent", mp->ka_tx_cnt);
json_object_int_add(json_row, "kaRcvd", mp->ka_rx_cnt);
json_object_int_add(json_row, "saSent", mp->sa_tx_cnt);
json_object_int_add(json_row, "saRcvd", mp->sa_rx_cnt);
json_object_object_add(json, peer_str, json_row);
} else {
vty_out(vty, "Peer : %s\n", peer_str);
vty_out(vty, " Local : %s\n", local_str);
if (mp->flags & PIM_MSDP_PEERF_IN_GROUP)
vty_out(vty, " Mesh Group : %s\n",
mp->mesh_group_name);
vty_out(vty, " State : %s\n", state_str);
vty_out(vty, " Uptime : %s\n", timebuf);

vty_out(vty, " Keepalive Timer : %s\n", katimer);
vty_out(vty, " Conn Retry Timer : %s\n", crtimer);
vty_out(vty, " Hold Timer : %s\n", holdtimer);
vty_out(vty, " Last Reset : %s\n",
mp->last_reset);
vty_out(vty, " Conn Attempts : %d\n",
mp->conn_attempts);
vty_out(vty, " Established Changes : %d\n",
mp->est_flaps);
vty_out(vty, " SA Count : %d\n",
mp->sa_cnt);
vty_out(vty, " Statistics :\n");
vty_out(vty,
" Sent Rcvd\n");
vty_out(vty, " Keepalives : %10d %10d\n",
mp->ka_tx_cnt, mp->ka_rx_cnt);
vty_out(vty, " SAs : %10d %10d\n",
mp->sa_tx_cnt, mp->sa_rx_cnt);
vty_out(vty, "\n");
}
vty_out(vty, "Peer : %s\n", peer_str);
vty_out(vty, " Local : %s\n", local_str);
if (mp->flags & PIM_MSDP_PEERF_IN_GROUP)
vty_out(vty, " Mesh Group : %s\n", mp->mesh_group_name);
if (mp->asn != 0)
vty_out(vty, " BGP/AS : %u\n", mp->asn);
else
vty_out(vty, " BGP/AS : -\n");
vty_out(vty, " State : %s\n", state_str);
vty_out(vty, " Uptime : %s\n", timebuf);

vty_out(vty, " Keepalive Timer : %s\n", katimer);
vty_out(vty, " Conn Retry Timer : %s\n", crtimer);
vty_out(vty, " Hold Timer : %s\n", holdtimer);
vty_out(vty, " Last Reset : %s\n", mp->last_reset);
vty_out(vty, " Conn Attempts : %d\n", mp->conn_attempts);
vty_out(vty, " Established Changes : %d\n", mp->est_flaps);
vty_out(vty, " SA Count : %d\n", mp->sa_cnt);
vty_out(vty, " Statistics :\n");
vty_out(vty, " Sent Rcvd\n");
vty_out(vty, " Keepalives : %10d %10d\n", mp->ka_tx_cnt, mp->ka_rx_cnt);
vty_out(vty, " SAs : %10d %10d\n", mp->sa_tx_cnt, mp->sa_rx_cnt);
vty_out(vty, "\n");
}

if (uj)
Expand Down Expand Up @@ -8021,6 +8079,85 @@ DEFUN (show_ip_msdp_peer_detail_vrf_all,
return CMD_SUCCESS;
}

static void clear_msdp_peer_counters(struct pim_msdp_peer *peer)
{
peer->ka_rx_cnt = 0;
peer->ka_tx_cnt = 0;
peer->sa_rx_cnt = 0;
peer->sa_tx_cnt = 0;
peer->est_flaps = 0;
peer->conn_attempts = 0;
peer->acl_in_count = 0;
peer->acl_out_count = 0;
peer->rpf_lookup_failure_count = 0;
}

DEFPY(clear_ip_msdp_peer_counters, clear_ip_msdp_peer_counters_cmd,
"clear ip msdp [<vrf all$vrf_all|vrf WORD$vrf_name>] peer [A.B.C.D$peer] counters",
CLEAR_STR
IP_STR
MSDP_STR
VRF_CMD_HELP_STR
VRF_CMD_HELP_STR
"MSDP peer information\n"
"Peer IP address\n"
"MSDP peer counters\n")
{
const struct pim_instance *pim;
struct pim_msdp_peer *msdp_peer = NULL;
struct vrf *vrf;

if (vrf_name) {
vrf = vrf_lookup_by_name(vrf_name);
if (vrf == NULL) {
vty_out(vty, "VRF %s does not exist\n", vrf_name);
return CMD_WARNING;
}
} else if (vrf_all) {
vrf = NULL;
} else {
vrf = vrf_lookup_by_id(VRF_DEFAULT);
if (vrf == NULL) {
vty_out(vty, "Default VRF does not exist\n");
return CMD_WARNING;
}
}

if (vrf) {
pim = vrf->info;

if (peer_str) {
msdp_peer = pim_msdp_peer_find(pim, peer);
if (msdp_peer)
clear_msdp_peer_counters(msdp_peer);
} else {
struct listnode *node;

for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, node, msdp_peer))
clear_msdp_peer_counters(msdp_peer);
}

return CMD_SUCCESS;
}

RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
pim = vrf->info;

if (peer_str) {
msdp_peer = pim_msdp_peer_find(pim, peer);
if (msdp_peer)
clear_msdp_peer_counters(msdp_peer);
} else {
struct listnode *node;

for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, node, msdp_peer))
clear_msdp_peer_counters(msdp_peer);
}
}

return CMD_SUCCESS;
}

static void ip_msdp_show_sa(struct pim_instance *pim, struct vty *vty, bool uj)
{
struct listnode *sanode;
Expand Down Expand Up @@ -9234,6 +9371,7 @@ void pim_cmd_init(void)

install_element(ENABLE_NODE, &clear_ip_mroute_count_cmd);
install_element(ENABLE_NODE, &clear_ip_msdp_peer_cmd);
install_element(ENABLE_NODE, &clear_ip_msdp_peer_counters_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);
Expand Down

0 comments on commit 55429e6

Please sign in to comment.