From 0dc4f6f3c9f5fd0847dccce476e20add79f9913b Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Wed, 29 Nov 2023 13:29:07 +0100 Subject: [PATCH 1/5] ospf6d: rework ospf6 neighbor state display A separate function ospf6_neighbor_state_message() is created to return a string that stands for the neighbor kind: DR, BDR, DROther, or PointToPoint. Signed-off-by: Philippe Guibert --- ospf6d/ospf6_neighbor.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c index 8b7afd89a7db..a7fd6cecc0cf 100644 --- a/ospf6d/ospf6_neighbor.c +++ b/ospf6d/ospf6_neighbor.c @@ -846,6 +846,24 @@ DEFPY(ipv6_ospf6_p2xp_neigh_poll_interval, p2xp_unicast_hello_sched(p2xp_cfg); return CMD_SUCCESS; + +} + +/* build state value */ +static void ospf6_neighbor_state_message(struct ospf6_neighbor *on, + char *nstate, size_t nstate_len) +{ + /* Neighbor State */ + if (on->ospf6_if->type == OSPF_IFTYPE_POINTOPOINT) + snprintf(nstate, nstate_len, "PointToPoint"); + else { + if (on->router_id == on->drouter) + snprintf(nstate, nstate_len, "DR"); + else if (on->router_id == on->bdrouter) + snprintf(nstate, nstate_len, "BR"); + else + snprintf(nstate, nstate_len, "DROther"); + } } /* show neighbor structure */ @@ -892,6 +910,7 @@ static void ospf6_neighbor_show(struct vty *vty, struct ospf6_neighbor *on, else snprintf(nstate, sizeof(nstate), "DROther"); } + ospf6_neighbor_state_message(on, nstate, sizeof(nstate)); /* Duration */ monotime_since(&on->last_changed, &res); From aac0d518e46aff6260b3c1cdaf59e77e74297dfb Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Wed, 29 Nov 2023 13:34:53 +0100 Subject: [PATCH 2/5] ospf6d: fix the nstate size with PointToPoint With a 16 byte nstate value, the "PointToPoint" string is missing one extra-character to handle the full string and the termination character. Fix this by enlarging the nstate buffer size to 17 instead of 16. Fixes: 508e53e2eef3 ("Ospf6d merge from Zebra repository with added privs stuff and merged zclient changes.") Signed-off-by: Philippe Guibert --- ospf6d/ospf6_neighbor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c index a7fd6cecc0cf..6d802053f985 100644 --- a/ospf6d/ospf6_neighbor.c +++ b/ospf6d/ospf6_neighbor.c @@ -873,7 +873,7 @@ static void ospf6_neighbor_show(struct vty *vty, struct ospf6_neighbor *on, char router_id[16]; char duration[64]; struct timeval res; - char nstate[16]; + char nstate[17]; char deadtime[64]; long h, m, s; json_object *json_route; From 568eef67db0eb44e62379b27491dfb4bc20254e8 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Wed, 29 Nov 2023 13:47:46 +0100 Subject: [PATCH 3/5] ospf6d: add json attributes to 'show ipv6 ospf6 neighbor detail' Add the following attributes in each neighbor of the vty command: 'show ipv6 ospf6 neighbor detail json' - nbrPriority : integer - Role: DR, BDR, DROther, or PointToPoint - nbrState : / where: o Role is the above attribute o state is "None", "Down", "Attempt", "Init", "Twoway", "ExStart", "ExChange", "Loading", "Full" - routerDeadIntervalTimerDueMsec: integer value otherwise "inactive" Enter in a deprecation workflow for neighborState value, which is replaced by nbrState. Signed-off-by: Philippe Guibert --- ospf6d/ospf6_neighbor.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c index 6d802053f985..d96a2ee9cd9c 100644 --- a/ospf6d/ospf6_neighbor.c +++ b/ospf6d/ospf6_neighbor.c @@ -866,6 +866,21 @@ static void ospf6_neighbor_state_message(struct ospf6_neighbor *on, } } +/* build nbrState value */ +static void ospf6_neighbor_nstate_message(struct ospf6_neighbor *on, + char *nstate, size_t nstate_len) +{ + char state[16]; + + memset(state, 0, sizeof(state)); + memset(nstate, 0, nstate_len); + + ospf6_neighbor_state_message(on, state, sizeof(state)); + + snprintf(nstate, nstate_len, "%s/%s", state, + ospf6_neighbor_state_str[on->state]); +} + /* show neighbor structure */ static void ospf6_neighbor_show(struct vty *vty, struct ospf6_neighbor *on, json_object *json_array, bool use_json) @@ -1003,12 +1018,15 @@ static void ospf6_neighbor_show_detail(struct vty *vty, json_object *json_neighbor; json_object *json_array; char db_desc_str[20]; + char nstate[25]; + long time_store; inet_ntop(AF_INET6, &on->linklocal_addr, linklocal_addr, sizeof(linklocal_addr)); inet_ntop(AF_INET, &on->drouter, drouter, sizeof(drouter)); inet_ntop(AF_INET, &on->bdrouter, bdrouter, sizeof(bdrouter)); + ospf6_neighbor_nstate_message(on, nstate, sizeof(nstate)); monotime(&now); timersub(&now, &on->last_changed, &res); timerstring(&res, duration, sizeof(duration)); @@ -1027,8 +1045,28 @@ static void ospf6_neighbor_show_detail(struct vty *vty, "%pI6", on->ospf6_if->linklocal_addr); json_object_string_add(json_neighbor, "linkLocalAddress", linklocal_addr); +#if CONFDATE > 20241129 + CPP_NOTICE( + "Remove %s() JSON keys: neighborState", __func__) +#endif json_object_string_add(json_neighbor, "neighborState", ospf6_neighbor_state_str[on->state]); + json_object_int_add(json_neighbor, "nbrPriority", on->priority); + json_object_string_add(json_neighbor, "nbrState", nstate); + json_object_string_add(json_neighbor, "Role", + ospf6_neighbor_state_str[on->state]); + if (on->inactivity_timer) { + time_store = + monotime_until(&on->inactivity_timer->u.sands, + NULL) + / 1000LL; + json_object_int_add(json_neighbor, + "routerDeadIntervalTimerDueMsec", + time_store); + } else + json_object_string_add(json_neighbor, + "routerDeadIntervalTimerDueMsec", + "inactive"); json_object_string_add(json_neighbor, "neighborStateDuration", duration); json_object_string_add(json_neighbor, "neighborDRouter", From f764521bab73d4952bb1e2fe0a13cddc55ede85e Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Wed, 29 Nov 2023 14:14:09 +0100 Subject: [PATCH 4/5] ospf6d: add json attributes to 'show ipv6 ospf6 neighbor' Add the following attributes in each neighbor of the vty command: 'show ipv6 ospf6 neighbor json': - nbrPriority : integer - Role: DR, BDR, DROther, or PointToPoint - nbrState : / where: o Role is the above attribute o state is "None", "Down", "Attempt", "Init", "Twoway", "ExStart", "ExChange", "Loading", "Full" - routerDeadIntervalTimerDueMsec: integer value otherwise "inactive" Enter in a deprecation workflow for state and priority values, which are replaced by nbrState. Signed-off-by: Philippe Guibert --- ospf6d/ospf6_neighbor.c | 102 +++++++++++++++++++--------------------- ospfd/ospf_vty.c | 11 ++--- 2 files changed, 51 insertions(+), 62 deletions(-) diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c index d96a2ee9cd9c..97f2e2e100ea 100644 --- a/ospf6d/ospf6_neighbor.c +++ b/ospf6d/ospf6_neighbor.c @@ -846,39 +846,25 @@ DEFPY(ipv6_ospf6_p2xp_neigh_poll_interval, p2xp_unicast_hello_sched(p2xp_cfg); return CMD_SUCCESS; - } -/* build state value */ -static void ospf6_neighbor_state_message(struct ospf6_neighbor *on, - char *nstate, size_t nstate_len) +static const char *ospf6_neighbor_role_message(struct ospf6_neighbor *on) { /* Neighbor State */ - if (on->ospf6_if->type == OSPF_IFTYPE_POINTOPOINT) - snprintf(nstate, nstate_len, "PointToPoint"); - else { - if (on->router_id == on->drouter) - snprintf(nstate, nstate_len, "DR"); - else if (on->router_id == on->bdrouter) - snprintf(nstate, nstate_len, "BR"); - else - snprintf(nstate, nstate_len, "DROther"); - } + if (on->router_id == on->drouter) + return "DR"; + if (on->router_id == on->bdrouter) + return "BR"; + return "DROther"; } -/* build nbrState value */ -static void ospf6_neighbor_nstate_message(struct ospf6_neighbor *on, - char *nstate, size_t nstate_len) +static const char *ospf6_neighbor_state_message(struct ospf6_neighbor *on) { - char state[16]; - - memset(state, 0, sizeof(state)); - memset(nstate, 0, nstate_len); - - ospf6_neighbor_state_message(on, state, sizeof(state)); - - snprintf(nstate, nstate_len, "%s/%s", state, - ospf6_neighbor_state_str[on->state]); + if (on->ospf6_if->type == OSPF_IFTYPE_POINTOMULTIPOINT) + return "PtMultipoint"; + if (on->ospf6_if->type == OSPF_IFTYPE_POINTOPOINT) + return "PointToPoint"; + return ospf6_neighbor_role_message(on); } /* show neighbor structure */ @@ -888,9 +874,8 @@ static void ospf6_neighbor_show(struct vty *vty, struct ospf6_neighbor *on, char router_id[16]; char duration[64]; struct timeval res; - char nstate[17]; char deadtime[64]; - long h, m, s; + long h, m, s, time_store; json_object *json_route; /* Router-ID (Name) */ @@ -912,21 +897,6 @@ static void ospf6_neighbor_show(struct vty *vty, struct ospf6_neighbor *on, } snprintf(deadtime, sizeof(deadtime), "%02ld:%02ld:%02ld", h, m, s); - /* Neighbor State */ - if (on->ospf6_if->type == OSPF_IFTYPE_POINTOPOINT) - snprintf(nstate, sizeof(nstate), "PointToPoint"); - else if (on->ospf6_if->type == OSPF_IFTYPE_POINTOMULTIPOINT) - snprintf(nstate, sizeof(nstate), "PtMultipoint"); - else { - if (on->router_id == on->drouter) - snprintf(nstate, sizeof(nstate), "DR"); - else if (on->router_id == on->bdrouter) - snprintf(nstate, sizeof(nstate), "BDR"); - else - snprintf(nstate, sizeof(nstate), "DROther"); - } - ospf6_neighbor_state_message(on, nstate, sizeof(nstate)); - /* Duration */ monotime_since(&on->last_changed, &res); timerstring(&res, duration, sizeof(duration)); @@ -940,11 +910,34 @@ static void ospf6_neighbor_show(struct vty *vty, struct ospf6_neighbor *on, json_route = json_object_new_object(); json_object_string_add(json_route, "neighborId", router_id); +#if CONFDATE > 20241129 + CPP_NOTICE( + "Remove %s() JSON keys: state, priority", __func__) +#endif json_object_int_add(json_route, "priority", on->priority); json_object_string_add(json_route, "deadTime", deadtime); json_object_string_add(json_route, "state", ospf6_neighbor_state_str[on->state]); - json_object_string_add(json_route, "ifState", nstate); + json_object_int_add(json_route, "nbrPriority", on->priority); + json_object_string_addf(json_route, "nbrState", "%s/%s", + ospf6_neighbor_state_str[on->state], + ospf6_neighbor_role_message(on)); + json_object_string_add(json_route, "role", + ospf6_neighbor_role_message(on)); + if (on->inactivity_timer) { + time_store = + monotime_until(&on->inactivity_timer->u.sands, + NULL) + / 1000LL; + json_object_int_add(json_route, + "routerDeadIntervalTimerDueMsec", + time_store); + } else + json_object_string_add(json_route, + "routerDeadIntervalTimerDueMsec", + "inactive"); + json_object_string_add(json_route, "ifState", + ospf6_neighbor_state_message(on)); json_object_string_add(json_route, "duration", duration); json_object_string_add(json_route, "interfaceName", on->ospf6_if->interface->name); @@ -956,7 +949,8 @@ static void ospf6_neighbor_show(struct vty *vty, struct ospf6_neighbor *on, } else vty_out(vty, "%-15s %3d %11s %8s/%-12s %11s %s[%s]\n", router_id, on->priority, deadtime, - ospf6_neighbor_state_str[on->state], nstate, duration, + ospf6_neighbor_state_str[on->state], + ospf6_neighbor_state_message(on), duration, on->ospf6_if->interface->name, ospf6_interface_state_str[on->ospf6_if->state]); } @@ -1018,7 +1012,6 @@ static void ospf6_neighbor_show_detail(struct vty *vty, json_object *json_neighbor; json_object *json_array; char db_desc_str[20]; - char nstate[25]; long time_store; inet_ntop(AF_INET6, &on->linklocal_addr, linklocal_addr, @@ -1026,7 +1019,6 @@ static void ospf6_neighbor_show_detail(struct vty *vty, inet_ntop(AF_INET, &on->drouter, drouter, sizeof(drouter)); inet_ntop(AF_INET, &on->bdrouter, bdrouter, sizeof(bdrouter)); - ospf6_neighbor_nstate_message(on, nstate, sizeof(nstate)); monotime(&now); timersub(&now, &on->last_changed, &res); timerstring(&res, duration, sizeof(duration)); @@ -1052,9 +1044,11 @@ static void ospf6_neighbor_show_detail(struct vty *vty, json_object_string_add(json_neighbor, "neighborState", ospf6_neighbor_state_str[on->state]); json_object_int_add(json_neighbor, "nbrPriority", on->priority); - json_object_string_add(json_neighbor, "nbrState", nstate); - json_object_string_add(json_neighbor, "Role", - ospf6_neighbor_state_str[on->state]); + json_object_string_addf(json_neighbor, "nbrState", "%s/%s", + ospf6_neighbor_state_str[on->state], + ospf6_neighbor_role_message(on)); + json_object_string_add(json_neighbor, "role", + ospf6_neighbor_role_message(on)); if (on->inactivity_timer) { time_store = monotime_until(&on->inactivity_timer->u.sands, @@ -1232,7 +1226,6 @@ static void ospf6_neighbor_show_detail(struct vty *vty, } else json_object_string_add(json_neighbor, "authStatus", "disabled"); - json_object_object_add(json, on->name, json_neighbor); } else { @@ -1389,9 +1382,10 @@ static void ospf6_neighbor_show_detail_common(struct vty *vty, } if (uj) { - if (showfunc != ospf6_neighbor_show_detail) - json_object_object_add(json, "neighbors", json_array); - else + if (showfunc != ospf6_neighbor_show_detail) { + json_object_object_add(json, "neighbors", + json_array); + } else json_object_free(json_array); vty_json(vty, json); } diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 93dd12ce4979..579ecbfc0cab 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -5089,14 +5089,9 @@ DEFUN (show_ip_ospf_neighbor_all, if (ospf) { ret = show_ip_ospf_neighbor_all_common(vty, ospf, json, uj, use_vrf); - if (uj) { - vty_out(vty, "%s\n", - json_object_to_json_string_ext( - json, JSON_C_TO_STRING_PRETTY)); - } - } - - if (uj) + if (uj) + vty_json(vty, json); + } else if (uj) json_object_free(json); return ret; From bee22912b57ec0c2b6478388225fc31f84d0cb87 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Wed, 29 Nov 2023 14:28:08 +0100 Subject: [PATCH 5/5] topotests: use the Role field when testing ospf6 To handle the future change of naming in the ospf6 state, align the ospf6 tests with the new 'Role' nickname instead of the old 'state' value. Signed-off-by: Philippe Guibert --- tests/topotests/lib/ospf.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/topotests/lib/ospf.py b/tests/topotests/lib/ospf.py index 5b18f8b679ce..706a8dd53953 100644 --- a/tests/topotests/lib/ospf.py +++ b/tests/topotests/lib/ospf.py @@ -780,15 +780,15 @@ def verify_ospf6_neighbor(tgen, topo=None, dut=None, input_dict=None, lan=False) "neighbors": { "r1": { "state": "Full", - "role": "DR" + "nbrState": "Full/DR" }, "r2": { "state": "Full", - "role": "DROther" + "nbrState": "Full/DROther" }, "r3": { "state": "Full", - "role": "DROther" + "nbrState": "Full/DROther" } } }