summaryrefslogtreecommitdiffstats
path: root/ospfd
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 04:24:31 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 04:24:31 +0000
commitacb594b1d825c6e12369cebb941968ec08c840ce (patch)
treed544788908e7353a4f117e2991f15f4236a0c963 /ospfd
parentAdding upstream version 9.1. (diff)
downloadfrr-acb594b1d825c6e12369cebb941968ec08c840ce.tar.xz
frr-acb594b1d825c6e12369cebb941968ec08c840ce.zip
Adding upstream version 10.0.upstream/10.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ospfd')
-rw-r--r--ospfd/ospf_api.h4
-rw-r--r--ospfd/ospf_apiserver.c2
-rw-r--r--ospfd/ospf_auth.c6
-rw-r--r--ospfd/ospf_ext.c249
-rw-r--r--ospfd/ospf_flood.c2
-rw-r--r--ospfd/ospf_gr.c42
-rw-r--r--ospfd/ospf_interface.c34
-rw-r--r--ospfd/ospf_interface.h1
-rw-r--r--ospfd/ospf_lsa.c3
-rw-r--r--ospfd/ospf_main.c48
-rw-r--r--ospfd/ospf_nsm.c4
-rw-r--r--ospfd/ospf_opaque.c147
-rw-r--r--ospfd/ospf_opaque.h1
-rw-r--r--ospfd/ospf_packet.c6
-rw-r--r--ospfd/ospf_ri.c308
-rw-r--r--ospfd/ospf_snmp.c5
-rw-r--r--ospfd/ospf_sr.c1
-rw-r--r--ospfd/ospf_te.c508
-rw-r--r--ospfd/ospf_vty.c19
-rw-r--r--ospfd/ospf_zebra.c32
-rw-r--r--ospfd/ospfd.c68
-rw-r--r--ospfd/ospfd.h3
22 files changed, 992 insertions, 501 deletions
diff --git a/ospfd/ospf_api.h b/ospfd/ospf_api.h
index 6c8bed3..6160a0f 100644
--- a/ospfd/ospf_api.h
+++ b/ospfd/ospf_api.h
@@ -21,10 +21,6 @@
#define MTYPE_OSPF_API_MSG MTYPE_TMP
#define MTYPE_OSPF_API_FIFO MTYPE_TMP
-/* Default API server port to accept connection request from client-side. */
-/* This value could be overridden by "ospfapi" entry in "/etc/services". */
-#define OSPF_API_SYNC_PORT 2607
-
/* -----------------------------------------------------------
* Generic messages
* -----------------------------------------------------------
diff --git a/ospfd/ospf_apiserver.c b/ospfd/ospf_apiserver.c
index 34e59c5..419113e 100644
--- a/ospfd/ospf_apiserver.c
+++ b/ospfd/ospf_apiserver.c
@@ -2092,7 +2092,7 @@ void ospf_apiserver_flush_opaque_lsa(struct ospf_apiserver *apiserv,
lsa, (void *)&param, 0);
break;
case OSPF_OPAQUE_AS_LSA:
- LSDB_LOOP (OPAQUE_LINK_LSDB(ospf), rn, lsa)
+ LSDB_LOOP (OPAQUE_AS_LSDB(ospf), rn, lsa)
apiserver_flush_opaque_type_callback(lsa,
(void *)&param, 0);
break;
diff --git a/ospfd/ospf_auth.c b/ospfd/ospf_auth.c
index 11ee1dd..2b090dc 100644
--- a/ospfd/ospf_auth.c
+++ b/ospfd/ospf_auth.c
@@ -5,6 +5,12 @@
*/
#include <zebra.h>
+#include <sys/stat.h>
+
+#ifdef CRYPTO_OPENSSL
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#endif
#include "linklist.h"
#include "if.h"
diff --git a/ospfd/ospf_ext.c b/ospfd/ospf_ext.c
index 75b5803..df0b3b9 100644
--- a/ospfd/ospf_ext.c
+++ b/ospfd/ospf_ext.c
@@ -31,6 +31,7 @@
#include "network.h"
#include "if.h"
#include "libospf.h" /* for ospf interface types */
+#include <lib/json.h>
#include "ospfd/ospfd.h"
#include "ospfd/ospf_interface.h"
@@ -1715,85 +1716,138 @@ static void ospf_ext_lsa_schedule(struct ext_itf *exti, enum lsa_opcode op)
/* Cisco experimental SubTLV */
static uint16_t show_vty_ext_link_rmt_itf_addr(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct ext_subtlv_rmt_itf_addr *top =
(struct ext_subtlv_rmt_itf_addr *)tlvh;
check_tlv_size(EXT_SUBTLV_RMT_ITF_ADDR_SIZE, "Remote Itf. Address");
- vty_out(vty,
- " Remote Interface Address Sub-TLV: Length %u\n Address: %pI4\n",
- ntohs(top->header.length), &top->value);
+ if (!json)
+ vty_out(vty,
+ " Remote Interface Address Sub-TLV: Length %u\n Address: %pI4\n",
+ ntohs(top->header.length), &top->value);
+ else
+ json_object_string_addf(json, "remoteInterfaceAddress", "%pI4",
+ &top->value);
return TLV_SIZE(tlvh);
}
/* Adjacency SID SubTLV */
static uint16_t show_vty_ext_link_adj_sid(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct ext_subtlv_adj_sid *top = (struct ext_subtlv_adj_sid *)tlvh;
+ uint8_t tlv_size;
- check_tlv_size(EXT_SUBTLV_ADJ_SID_SIZE, "Adjacency SID");
+ tlv_size = CHECK_FLAG(top->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG)
+ ? SID_LABEL_SIZE(EXT_SUBTLV_ADJ_SID_SIZE)
+ : SID_INDEX_SIZE(EXT_SUBTLV_ADJ_SID_SIZE);
+ check_tlv_size(tlv_size, "Adjacency SID");
- vty_out(vty,
- " Adj-SID Sub-TLV: Length %u\n\tFlags: 0x%x\n\tMT-ID:0x%x\n\tWeight: 0x%x\n\t%s: %u\n",
- ntohs(top->header.length), top->flags, top->mtid, top->weight,
- CHECK_FLAG(top->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG) ? "Label"
- : "Index",
- CHECK_FLAG(top->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG)
- ? GET_LABEL(ntohl(top->value))
- : ntohl(top->value));
+ if (!json)
+ vty_out(vty,
+ " Adj-SID Sub-TLV: Length %u\n\tFlags: 0x%x\n\tMT-ID:0x%x\n\tWeight: 0x%x\n\t%s: %u\n",
+ ntohs(top->header.length), top->flags, top->mtid,
+ top->weight,
+ CHECK_FLAG(top->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG)
+ ? "Label"
+ : "Index",
+ CHECK_FLAG(top->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG)
+ ? GET_LABEL(ntohl(top->value))
+ : ntohl(top->value));
+ else {
+ json_object_string_addf(json, "flags", "0x%x", top->flags);
+ json_object_string_addf(json, "mtID", "0x%x", top->mtid);
+ json_object_string_addf(json, "weight", "0x%x", top->weight);
+ if (CHECK_FLAG(top->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG))
+ json_object_int_add(json, "label",
+ GET_LABEL(ntohl(top->value)));
+ else
+ json_object_int_add(json, "index", ntohl(top->value));
+ }
return TLV_SIZE(tlvh);
}
/* LAN Adjacency SubTLV */
static uint16_t show_vty_ext_link_lan_adj_sid(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct ext_subtlv_lan_adj_sid *top =
(struct ext_subtlv_lan_adj_sid *)tlvh;
+ uint8_t tlv_size;
- check_tlv_size(EXT_SUBTLV_LAN_ADJ_SID_SIZE, "Lan-Adjacency SID");
+ tlv_size = CHECK_FLAG(top->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG)
+ ? SID_LABEL_SIZE(EXT_SUBTLV_LAN_ADJ_SID_SIZE)
+ : SID_INDEX_SIZE(EXT_SUBTLV_LAN_ADJ_SID_SIZE);
+ check_tlv_size(tlv_size, "LAN-Adjacency SID");
- vty_out(vty,
- " LAN-Adj-SID Sub-TLV: Length %u\n\tFlags: 0x%x\n\tMT-ID:0x%x\n\tWeight: 0x%x\n\tNeighbor ID: %pI4\n\t%s: %u\n",
- ntohs(top->header.length), top->flags, top->mtid, top->weight,
- &top->neighbor_id,
- CHECK_FLAG(top->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG) ? "Label"
- : "Index",
- CHECK_FLAG(top->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG)
- ? GET_LABEL(ntohl(top->value))
- : ntohl(top->value));
+ if (!json)
+ vty_out(vty,
+ " LAN-Adj-SID Sub-TLV: Length %u\n\tFlags: 0x%x\n\tMT-ID:0x%x\n\tWeight: 0x%x\n\tNeighbor ID: %pI4\n\t%s: %u\n",
+ ntohs(top->header.length), top->flags, top->mtid,
+ top->weight, &top->neighbor_id,
+ CHECK_FLAG(top->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG)
+ ? "Label"
+ : "Index",
+ CHECK_FLAG(top->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG)
+ ? GET_LABEL(ntohl(top->value))
+ : ntohl(top->value));
+ else {
+ json_object_string_addf(json, "flags", "0x%x", top->flags);
+ json_object_string_addf(json, "mtID", "0x%x", top->mtid);
+ json_object_string_addf(json, "weight", "0x%x", top->weight);
+ json_object_string_addf(json, "neighborID", "%pI4",
+ &top->neighbor_id);
+ if (CHECK_FLAG(top->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG))
+ json_object_int_add(json, "label",
+ GET_LABEL(ntohl(top->value)));
+ else
+ json_object_int_add(json, "index", ntohl(top->value));
+ }
return TLV_SIZE(tlvh);
}
static uint16_t show_vty_unknown_tlv(struct vty *vty, struct tlv_header *tlvh,
- size_t buf_size)
+ size_t buf_size, json_object *json)
{
+ json_object *obj;
+
if (TLV_SIZE(tlvh) > buf_size) {
vty_out(vty, " TLV size %d exceeds buffer size. Abort!",
TLV_SIZE(tlvh));
return buf_size;
}
-
- vty_out(vty, " Unknown TLV: [type(0x%x), length(0x%x)]\n",
- ntohs(tlvh->type), ntohs(tlvh->length));
+ if (!json)
+ vty_out(vty, " Unknown TLV: [type(0x%x), length(0x%x)]\n",
+ ntohs(tlvh->type), ntohs(tlvh->length));
+ else {
+ obj = json_object_new_object();
+ json_object_string_addf(obj, "type", "0x%x",
+ ntohs(tlvh->type));
+ json_object_string_addf(obj, "length", "0x%x",
+ ntohs(tlvh->length));
+ json_object_object_add(json, "unknownTLV", obj);
+ }
return TLV_SIZE(tlvh);
}
/* Extended Link Sub TLVs */
static uint16_t show_vty_link_info(struct vty *vty, struct tlv_header *ext,
- size_t buf_size)
+ size_t buf_size, json_object *json)
{
struct ext_tlv_link *top = (struct ext_tlv_link *)ext;
struct tlv_header *tlvh;
uint16_t length = ntohs(top->header.length);
uint16_t sum = 0;
+ json_object *jadj = NULL, *obj = NULL;
/* Verify that TLV length is valid against remaining buffer size */
if (length > buf_size) {
@@ -1803,12 +1857,22 @@ static uint16_t show_vty_link_info(struct vty *vty, struct tlv_header *ext,
return buf_size;
}
- vty_out(vty,
- " Extended Link TLV: Length %u\n Link Type: 0x%x\n"
- " Link ID: %pI4\n",
- ntohs(top->header.length), top->link_type,
- &top->link_id);
- vty_out(vty, " Link data: %pI4\n", &top->link_data);
+ if (!json) {
+ vty_out(vty,
+ " Extended Link TLV: Length %u\n Link Type: 0x%x\n"
+ " Link ID: %pI4\n",
+ ntohs(top->header.length), top->link_type,
+ &top->link_id);
+ vty_out(vty, " Link data: %pI4\n", &top->link_data);
+ } else {
+ json_object_string_addf(json, "linkType", "0x%x",
+ top->link_type);
+ json_object_string_addf(json, "linkID", "%pI4", &top->link_id);
+ json_object_string_addf(json, "linkData", "%pI4",
+ &top->link_data);
+ jadj = json_object_new_array();
+ json_object_object_add(json, "adjacencySID", jadj);
+ }
/* Skip Extended TLV and parse sub-TLVs */
length -= EXT_TLV_LINK_SIZE;
@@ -1817,16 +1881,27 @@ static uint16_t show_vty_link_info(struct vty *vty, struct tlv_header *ext,
for (; sum < length && tlvh; tlvh = TLV_HDR_NEXT(tlvh)) {
switch (ntohs(tlvh->type)) {
case EXT_SUBTLV_ADJ_SID:
- sum += show_vty_ext_link_adj_sid(vty, tlvh);
+ if (json) {
+ obj = json_object_new_object();
+ json_object_array_add(jadj, obj);
+ } else
+ obj = NULL;
+ sum += show_vty_ext_link_adj_sid(vty, tlvh, obj);
break;
case EXT_SUBTLV_LAN_ADJ_SID:
- sum += show_vty_ext_link_lan_adj_sid(vty, tlvh);
+ if (json) {
+ obj = json_object_new_object();
+ json_object_array_add(jadj, obj);
+ } else
+ obj = NULL;
+ sum += show_vty_ext_link_lan_adj_sid(vty, tlvh, obj);
break;
case EXT_SUBTLV_RMT_ITF_ADDR:
- sum += show_vty_ext_link_rmt_itf_addr(vty, tlvh);
+ sum += show_vty_ext_link_rmt_itf_addr(vty, tlvh, json);
break;
default:
- sum += show_vty_unknown_tlv(vty, tlvh, length - sum);
+ sum += show_vty_unknown_tlv(vty, tlvh, length - sum,
+ json);
break;
}
}
@@ -1841,9 +1916,12 @@ static void ospf_ext_link_show_info(struct vty *vty, struct json_object *json,
struct lsa_header *lsah = lsa->data;
struct tlv_header *tlvh;
uint16_t length = 0, sum = 0;
+ json_object *jlink = NULL;
- if (json)
- return;
+ if (json) {
+ jlink = json_object_new_object();
+ json_object_object_add(json, "extendedLink", jlink);
+ }
/* Initialize TLV browsing */
length = lsa->size - OSPF_LSA_HEADER_SIZE;
@@ -1852,10 +1930,12 @@ static void ospf_ext_link_show_info(struct vty *vty, struct json_object *json,
tlvh = TLV_HDR_NEXT(tlvh)) {
switch (ntohs(tlvh->type)) {
case EXT_TLV_LINK:
- sum += show_vty_link_info(vty, tlvh, length - sum);
+ sum += show_vty_link_info(vty, tlvh, length - sum,
+ jlink);
break;
default:
- sum += show_vty_unknown_tlv(vty, tlvh, length - sum);
+ sum += show_vty_unknown_tlv(vty, tlvh, length - sum,
+ jlink);
break;
}
}
@@ -1863,34 +1943,51 @@ static void ospf_ext_link_show_info(struct vty *vty, struct json_object *json,
/* Prefix SID SubTLV */
static uint16_t show_vty_ext_pref_pref_sid(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct ext_subtlv_prefix_sid *top =
(struct ext_subtlv_prefix_sid *)tlvh;
+ uint8_t tlv_size;
- check_tlv_size(EXT_SUBTLV_PREFIX_SID_SIZE, "Prefix SID");
-
- vty_out(vty,
- " Prefix SID Sub-TLV: Length %u\n\tAlgorithm: %u\n\tFlags: 0x%x\n\tMT-ID:0x%x\n\t%s: %u\n",
- ntohs(top->header.length), top->algorithm, top->flags,
- top->mtid,
- CHECK_FLAG(top->flags, EXT_SUBTLV_PREFIX_SID_VFLG) ? "Label"
- : "Index",
- CHECK_FLAG(top->flags, EXT_SUBTLV_PREFIX_SID_VFLG)
- ? GET_LABEL(ntohl(top->value))
- : ntohl(top->value));
+ tlv_size = CHECK_FLAG(top->flags, EXT_SUBTLV_PREFIX_SID_VFLG)
+ ? SID_LABEL_SIZE(EXT_SUBTLV_PREFIX_SID_SIZE)
+ : SID_INDEX_SIZE(EXT_SUBTLV_PREFIX_SID_SIZE);
+ check_tlv_size(tlv_size, "Prefix SID");
+ if (!json)
+ vty_out(vty,
+ " Prefix SID Sub-TLV: Length %u\n\tAlgorithm: %u\n\tFlags: 0x%x\n\tMT-ID:0x%x\n\t%s: %u\n",
+ ntohs(top->header.length), top->algorithm, top->flags,
+ top->mtid,
+ CHECK_FLAG(top->flags, EXT_SUBTLV_PREFIX_SID_VFLG)
+ ? "Label"
+ : "Index",
+ CHECK_FLAG(top->flags, EXT_SUBTLV_PREFIX_SID_VFLG)
+ ? GET_LABEL(ntohl(top->value))
+ : ntohl(top->value));
+ else {
+ json_object_int_add(json, "algorithm", top->algorithm);
+ json_object_string_addf(json, "flags", "0x%x", top->flags);
+ json_object_string_addf(json, "mtID", "0x%x", top->mtid);
+ if (CHECK_FLAG(top->flags, EXT_SUBTLV_PREFIX_SID_VFLG))
+ json_object_int_add(json, "label",
+ GET_LABEL(ntohl(top->value)));
+ else
+ json_object_int_add(json, "index", ntohl(top->value));
+ }
return TLV_SIZE(tlvh);
}
/* Extended Prefix SubTLVs */
static uint16_t show_vty_pref_info(struct vty *vty, struct tlv_header *ext,
- size_t buf_size)
+ size_t buf_size, json_object *json)
{
struct ext_tlv_prefix *top = (struct ext_tlv_prefix *)ext;
struct tlv_header *tlvh;
uint16_t length = ntohs(top->header.length);
uint16_t sum = 0;
+ json_object *jsid = NULL;
/* Verify that TLV length is valid against remaining buffer size */
if (length > buf_size) {
@@ -1900,11 +1997,21 @@ static uint16_t show_vty_pref_info(struct vty *vty, struct tlv_header *ext,
return buf_size;
}
- vty_out(vty,
- " Extended Prefix TLV: Length %u\n\tRoute Type: %u\n"
- "\tAddress Family: 0x%x\n\tFlags: 0x%x\n\tAddress: %pI4/%u\n",
- ntohs(top->header.length), top->route_type, top->af, top->flags,
- &top->address, top->pref_length);
+ if (!json)
+ vty_out(vty,
+ " Extended Prefix TLV: Length %u\n\tRoute Type: %u\n"
+ "\tAddress Family: 0x%x\n\tFlags: 0x%x\n\tAddress: %pI4/%u\n",
+ ntohs(top->header.length), top->route_type, top->af,
+ top->flags, &top->address, top->pref_length);
+ else {
+ json_object_int_add(json, "routeType", top->route_type);
+ json_object_string_addf(json, "addressFamily", "0x%x", top->af);
+ json_object_string_addf(json, "flags", "0x%x", top->flags);
+ json_object_string_addf(json, "address", "%pI4", &top->address);
+ json_object_int_add(json, "prefixLength", top->pref_length);
+ jsid = json_object_new_object();
+ json_object_object_add(json, "prefixSID", jsid);
+ }
/* Skip Extended Prefix TLV and parse sub-TLVs */
length -= EXT_TLV_PREFIX_SIZE;
@@ -1913,10 +2020,11 @@ static uint16_t show_vty_pref_info(struct vty *vty, struct tlv_header *ext,
for (; sum < length && tlvh; tlvh = TLV_HDR_NEXT(tlvh)) {
switch (ntohs(tlvh->type)) {
case EXT_SUBTLV_PREFIX_SID:
- sum += show_vty_ext_pref_pref_sid(vty, tlvh);
+ sum += show_vty_ext_pref_pref_sid(vty, tlvh, jsid);
break;
default:
- sum += show_vty_unknown_tlv(vty, tlvh, length - sum);
+ sum += show_vty_unknown_tlv(vty, tlvh, length - sum,
+ json);
break;
}
}
@@ -1931,9 +2039,12 @@ static void ospf_ext_pref_show_info(struct vty *vty, struct json_object *json,
struct lsa_header *lsah = lsa->data;
struct tlv_header *tlvh;
uint16_t length = 0, sum = 0;
+ json_object *jpref = NULL;
- if (json)
- return;
+ if (json) {
+ jpref = json_object_new_object();
+ json_object_object_add(json, "extendedPrefix", jpref);
+ }
/* Initialize TLV browsing */
length = lsa->size - OSPF_LSA_HEADER_SIZE;
@@ -1942,10 +2053,12 @@ static void ospf_ext_pref_show_info(struct vty *vty, struct json_object *json,
tlvh = TLV_HDR_NEXT(tlvh)) {
switch (ntohs(tlvh->type)) {
case EXT_TLV_PREFIX:
- sum += show_vty_pref_info(vty, tlvh, length - sum);
+ sum += show_vty_pref_info(vty, tlvh, length - sum,
+ jpref);
break;
default:
- sum += show_vty_unknown_tlv(vty, tlvh, length - sum);
+ sum += show_vty_unknown_tlv(vty, tlvh, length - sum,
+ jpref);
break;
}
}
diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c
index dd8c926..95a593a 100644
--- a/ospfd/ospf_flood.c
+++ b/ospfd/ospf_flood.c
@@ -954,7 +954,7 @@ int ospf_flood_through(struct ospf *ospf, struct ospf_neighbor *inbr,
if (IS_DEBUG_OSPF_NSSA)
zlog_debug("%s: LOCAL NSSA FLOOD of Type-7.", __func__);
- /* Fallthrough */
+ fallthrough;
default:
lsa_ack_flag = ospf_flood_through_area(lsa->area, inbr, lsa);
break;
diff --git a/ospfd/ospf_gr.c b/ospfd/ospf_gr.c
index c23c420..0a4d579 100644
--- a/ospfd/ospf_gr.c
+++ b/ospfd/ospf_gr.c
@@ -555,21 +555,6 @@ static void ospf_gr_grace_period_expired(struct event *thread)
ospf_gr_restart_exit(ospf, "grace period has expired");
}
-/*
- * Returns the path of the file (non-volatile memory) that contains GR status
- * information.
- */
-static char *ospf_gr_nvm_filepath(struct ospf *ospf)
-{
- static char filepath[MAXPATHLEN];
- char instance[16] = "";
-
- if (ospf->instance)
- snprintf(instance, sizeof(instance), "-%d", ospf->instance);
- snprintf(filepath, sizeof(filepath), OSPFD_GR_STATE, instance);
- return filepath;
-}
-
/* Send extra Grace-LSA out the interface (unplanned outages only). */
void ospf_gr_iface_send_grace_lsa(struct event *thread)
{
@@ -591,18 +576,14 @@ void ospf_gr_iface_send_grace_lsa(struct event *thread)
*/
static void ospf_gr_nvm_update(struct ospf *ospf, bool prepare)
{
- char *filepath;
const char *inst_name;
json_object *json;
json_object *json_instances;
json_object *json_instance;
- filepath = ospf_gr_nvm_filepath(ospf);
inst_name = ospf_get_name(ospf);
- json = json_object_from_file(filepath);
- if (json == NULL)
- json = json_object_new_object();
+ json = frr_daemon_state_load();
json_object_object_get_ex(json, "instances", &json_instances);
if (!json_instances) {
@@ -630,8 +611,7 @@ static void ospf_gr_nvm_update(struct ospf *ospf, bool prepare)
json_object_int_add(json_instance, "timestamp",
time(NULL) + ospf->gr_info.grace_period);
- json_object_to_file_ext(filepath, json, JSON_C_TO_STRING_PRETTY);
- json_object_free(json);
+ frr_daemon_state_save(&json);
}
/*
@@ -640,17 +620,13 @@ static void ospf_gr_nvm_update(struct ospf *ospf, bool prepare)
*/
void ospf_gr_nvm_delete(struct ospf *ospf)
{
- char *filepath;
const char *inst_name;
json_object *json;
json_object *json_instances;
- filepath = ospf_gr_nvm_filepath(ospf);
inst_name = ospf_get_name(ospf);
- json = json_object_from_file(filepath);
- if (json == NULL)
- json = json_object_new_object();
+ json = frr_daemon_state_load();
json_object_object_get_ex(json, "instances", &json_instances);
if (!json_instances) {
@@ -660,8 +636,7 @@ void ospf_gr_nvm_delete(struct ospf *ospf)
json_object_object_del(json_instances, inst_name);
- json_object_to_file_ext(filepath, json, JSON_C_TO_STRING_PRETTY);
- json_object_free(json);
+ frr_daemon_state_save(&json);
}
/*
@@ -670,7 +645,6 @@ void ospf_gr_nvm_delete(struct ospf *ospf)
*/
void ospf_gr_nvm_read(struct ospf *ospf)
{
- char *filepath;
const char *inst_name;
json_object *json;
json_object *json_instances;
@@ -679,12 +653,9 @@ void ospf_gr_nvm_read(struct ospf *ospf)
json_object *json_grace_period;
time_t timestamp = 0;
- filepath = ospf_gr_nvm_filepath(ospf);
inst_name = ospf_get_name(ospf);
- json = json_object_from_file(filepath);
- if (json == NULL)
- json = json_object_new_object();
+ json = frr_daemon_state_load();
json_object_object_get_ex(json, "instances", &json_instances);
if (!json_instances) {
@@ -730,8 +701,7 @@ void ospf_gr_nvm_read(struct ospf *ospf)
json_object_object_del(json_instances, inst_name);
- json_object_to_file_ext(filepath, json, JSON_C_TO_STRING_PRETTY);
- json_object_free(json);
+ frr_daemon_state_save(&json);
}
void ospf_gr_unplanned_start_interface(struct ospf_interface *oi)
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c
index 7601419..0969ae1 100644
--- a/ospfd/ospf_interface.c
+++ b/ospfd/ospf_interface.c
@@ -339,6 +339,8 @@ void ospf_if_free(struct ospf_interface *oi)
assert(oi->state == ISM_Down);
+ ospf_opaque_type9_lsa_if_cleanup(oi);
+
ospf_opaque_type9_lsa_term(oi);
QOBJ_UNREG(oi);
@@ -380,26 +382,6 @@ int ospf_if_is_up(struct ospf_interface *oi)
return if_is_up(oi->ifp);
}
-struct ospf_interface *ospf_if_exists(struct ospf_interface *oic)
-{
- struct listnode *node;
- struct ospf *ospf;
- struct ospf_interface *oi;
-
- if (!oic)
- return NULL;
-
- ospf = oic->ospf;
- if (ospf == NULL)
- return NULL;
-
- for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi))
- if (oi == oic)
- return oi;
-
- return NULL;
-}
-
/* Lookup OSPF interface by router LSA posistion */
struct ospf_interface *ospf_if_lookup_by_lsa_pos(struct ospf_area *area,
int lsa_pos)
@@ -932,7 +914,7 @@ struct ospf_interface *ospf_vl_new(struct ospf *ospf,
{
struct ospf_interface *voi;
struct interface *vi;
- char ifname[INTERFACE_NAMSIZ];
+ char ifname[IFNAMSIZ];
struct ospf_area *area;
struct in_addr area_id;
struct connected *co;
@@ -962,7 +944,7 @@ struct ospf_interface *ospf_vl_new(struct ospf *ospf,
UNSET_FLAG(vi->status, ZEBRA_INTERFACE_LINKDETECTION);
co = connected_new();
co->ifp = vi;
- listnode_add(vi->connected, co);
+ if_connected_add_tail(vi->connected, co);
p = prefix_ipv4_new();
p->family = AF_INET;
@@ -1167,7 +1149,7 @@ static int ospf_vl_set_params(struct ospf_area *area,
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"found back link through VL");
- /* fallthru */
+ fallthrough;
case LSA_LINK_TYPE_TRANSIT:
case LSA_LINK_TYPE_POINTOPOINT:
if (!IPV4_ADDR_SAME(&vl_data->peer_addr,
@@ -1562,8 +1544,10 @@ void ospf_reset_hello_timer(struct interface *ifp, struct in_addr addr,
void ospf_if_init(void)
{
- if_zapi_callbacks(ospf_ifp_create, ospf_ifp_up,
- ospf_ifp_down, ospf_ifp_destroy);
+ hook_register_prio(if_real, 0, ospf_ifp_create);
+ hook_register_prio(if_up, 0, ospf_ifp_up);
+ hook_register_prio(if_down, 0, ospf_ifp_down);
+ hook_register_prio(if_unreal, 0, ospf_ifp_destroy);
/* Initialize Zebra interface data structure. */
hook_register_prio(if_add, 0, ospf_if_new_hook);
diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h
index e2290a8..08a2b11 100644
--- a/ospfd/ospf_interface.h
+++ b/ospfd/ospf_interface.h
@@ -300,7 +300,6 @@ extern int ospf_if_up(struct ospf_interface *oi);
extern int ospf_if_down(struct ospf_interface *oi);
extern int ospf_if_is_up(struct ospf_interface *oi);
-extern struct ospf_interface *ospf_if_exists(struct ospf_interface *oi);
extern struct ospf_interface *ospf_if_lookup_by_lsa_pos(struct ospf_area *area,
int lsa_pos);
extern struct ospf_interface *
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index e47f832..f125fa9 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -3096,13 +3096,14 @@ struct ospf_lsa *ospf_lsa_install(struct ospf *ospf, struct ospf_interface *oi,
/* Incoming "oi" for this LSA has set at LSUpd
* reception. */
}
- /* Fallthrough */
+ fallthrough;
case OSPF_OPAQUE_AREA_LSA:
case OSPF_OPAQUE_AS_LSA:
new = ospf_opaque_lsa_install(lsa, rt_recalc);
break;
case OSPF_AS_NSSA_LSA:
new = ospf_external_lsa_install(ospf, lsa, rt_recalc);
+ break;
default: /* type-6,8,9....nothing special */
break;
}
diff --git a/ospfd/ospf_main.c b/ospfd/ospf_main.c
index dd00024..6a4a9a1 100644
--- a/ospfd/ospf_main.c
+++ b/ospfd/ospf_main.c
@@ -45,6 +45,16 @@
#include "ospfd/ospf_ldp_sync.h"
#include "ospfd/ospf_routemap_nb.h"
+#define OSPFD_STATE_NAME "%s/ospfd.json", frr_libstatedir
+#define OSPFD_INST_STATE_NAME(i) "%s/ospfd-%d.json", frr_runstatedir, i
+
+/* this one includes the path... because the instance number was in the path
+ * before :( ... which totally didn't have a mkdir anywhere.
+ */
+#define OSPFD_COMPAT_STATE_NAME "%s/ospfd-gr.json", frr_libstatedir
+#define OSPFD_COMPAT_INST_STATE_NAME(i) \
+ "%s-%d/ospfd-gr.json", frr_runstatedir, i
+
/* ospfd privileges */
zebra_capabilities_t _caps_p[] = {ZCAP_NET_RAW, ZCAP_BIND, ZCAP_NET_ADMIN,
ZCAP_SYS_ADMIN};
@@ -89,6 +99,7 @@ static void sigint(void)
zlog_notice("Terminating on signal");
bfd_protocol_integration_set_shutdown(true);
ospf_terminate();
+
exit(0);
}
@@ -125,15 +136,31 @@ static const struct frr_yang_module_info *const ospfd_yang_modules[] = {
&frr_ospf_route_map_info,
};
-FRR_DAEMON_INFO(ospfd, OSPF, .vty_port = OSPF_VTY_PORT,
+/* actual paths filled in main() */
+static char state_path[512];
+static char state_compat_path[512];
+static char *state_paths[] = {
+ state_path,
+ state_compat_path,
+ NULL,
+};
- .proghelp = "Implementation of the OSPFv2 routing protocol.",
+/* clang-format off */
+FRR_DAEMON_INFO(ospfd, OSPF,
+ .vty_port = OSPF_VTY_PORT,
+ .proghelp = "Implementation of the OSPFv2 routing protocol.",
- .signals = ospf_signals, .n_signals = array_size(ospf_signals),
+ .signals = ospf_signals,
+ .n_signals = array_size(ospf_signals),
- .privs = &ospfd_privs, .yang_modules = ospfd_yang_modules,
- .n_yang_modules = array_size(ospfd_yang_modules),
+ .privs = &ospfd_privs,
+
+ .yang_modules = ospfd_yang_modules,
+ .n_yang_modules = array_size(ospfd_yang_modules),
+
+ .state_paths = state_paths,
);
+/* clang-format on */
/** Max wait time for config to load before accepting hellos */
#define OSPF_PRE_CONFIG_MAX_WAIT_SECONDS 600
@@ -207,6 +234,17 @@ int main(int argc, char **argv)
exit(1);
}
+ if (ospf_instance) {
+ snprintf(state_path, sizeof(state_path),
+ OSPFD_INST_STATE_NAME(ospf_instance));
+ snprintf(state_compat_path, sizeof(state_compat_path),
+ OSPFD_COMPAT_INST_STATE_NAME(ospf_instance));
+ } else {
+ snprintf(state_path, sizeof(state_path), OSPFD_STATE_NAME);
+ snprintf(state_compat_path, sizeof(state_compat_path),
+ OSPFD_COMPAT_STATE_NAME);
+ }
+
/* OSPF master init. */
ospf_master_init(frr_init());
diff --git a/ospfd/ospf_nsm.c b/ospfd/ospf_nsm.c
index bcbe028..08aa103 100644
--- a/ospfd/ospf_nsm.c
+++ b/ospfd/ospf_nsm.c
@@ -107,7 +107,7 @@ static void nsm_timer_set(struct ospf_neighbor *nbr)
case NSM_Down:
EVENT_OFF(nbr->t_inactivity);
EVENT_OFF(nbr->t_hello_reply);
- /* fallthru */
+ fallthrough;
case NSM_Attempt:
case NSM_Init:
case NSM_TwoWay:
@@ -219,7 +219,7 @@ static int ospf_db_summary_add(struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
case OSPF_OPAQUE_LINK_LSA:
/* Exclude type-9 LSAs that does not have the same "oi" with
* "nbr". */
- if (ospf_if_exists(lsa->oi) != nbr->oi)
+ if (lsa->oi != nbr->oi)
return 0;
break;
case OSPF_OPAQUE_AREA_LSA:
diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c
index 27f47a6..5d2d656 100644
--- a/ospfd/ospf_opaque.c
+++ b/ospfd/ospf_opaque.c
@@ -257,7 +257,7 @@ static void free_opaque_info_per_type(struct opaque_info_per_type *oipt,
struct ospf_opaque_functab {
uint8_t opaque_type;
- struct opaque_info_per_type *oipt;
+ uint32_t ref_count;
int (*new_if_hook)(struct interface *ifp);
int (*del_if_hook)(struct interface *ifp);
@@ -280,9 +280,28 @@ static struct list *ospf_opaque_type9_funclist;
static struct list *ospf_opaque_type10_funclist;
static struct list *ospf_opaque_type11_funclist;
+static void ospf_opaque_functab_ref(struct ospf_opaque_functab *functab)
+{
+ functab->ref_count++;
+}
+
+static void ospf_opaque_functab_deref(struct ospf_opaque_functab *functab)
+{
+ assert(functab->ref_count);
+ functab->ref_count--;
+ if (functab->ref_count == 0)
+ XFREE(MTYPE_OSPF_OPAQUE_FUNCTAB, functab);
+}
+
static void ospf_opaque_del_functab(void *val)
{
- XFREE(MTYPE_OSPF_OPAQUE_FUNCTAB, val);
+ struct ospf_opaque_functab *functab = (struct ospf_opaque_functab *)val;
+
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: Opaque LSA functab list deletion callback type %u (%p)",
+ __func__, functab->opaque_type, functab);
+
+ ospf_opaque_functab_deref(functab);
return;
}
@@ -290,6 +309,9 @@ static void ospf_opaque_funclist_init(void)
{
struct list *funclist;
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: Function list initialize", __func__);
+
funclist = ospf_opaque_wildcard_funclist = list_new();
funclist->del = ospf_opaque_del_functab;
@@ -308,6 +330,9 @@ static void ospf_opaque_funclist_term(void)
{
struct list *funclist;
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: Function list terminate", __func__);
+
funclist = ospf_opaque_wildcard_funclist;
list_delete(&funclist);
@@ -383,18 +408,24 @@ int ospf_register_opaque_functab(
for (ALL_LIST_ELEMENTS(funclist, node, nnode, functab))
if (functab->opaque_type == opaque_type) {
- flog_warn(
- EC_OSPF_LSA,
- "%s: Duplicated entry?: lsa_type(%u), opaque_type(%u)",
- __func__, lsa_type, opaque_type);
- return -1;
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: Opaque LSA functab found type %u, (%p)",
+ __func__, functab->opaque_type,
+ functab);
+ break;
}
- new = XCALLOC(MTYPE_OSPF_OPAQUE_FUNCTAB,
- sizeof(struct ospf_opaque_functab));
+ if (functab == NULL)
+ new = XCALLOC(MTYPE_OSPF_OPAQUE_FUNCTAB,
+ sizeof(struct ospf_opaque_functab));
+ else {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: Re-register Opaque LSA type %u, opaque type %u, (%p)",
+ __func__, lsa_type, opaque_type, functab);
+ return 0;
+ }
new->opaque_type = opaque_type;
- new->oipt = NULL;
new->new_if_hook = new_if_hook;
new->del_if_hook = del_if_hook;
new->ism_change_hook = ism_change_hook;
@@ -408,7 +439,12 @@ int ospf_register_opaque_functab(
new->new_lsa_hook = new_lsa_hook;
new->del_lsa_hook = del_lsa_hook;
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: Register Opaque LSA type %u, opaque type %u, (%p)",
+ __func__, lsa_type, opaque_type, new);
+
listnode_add(funclist, new);
+ ospf_opaque_functab_ref(new);
return 0;
}
@@ -422,15 +458,18 @@ void ospf_delete_opaque_functab(uint8_t lsa_type, uint8_t opaque_type)
if ((funclist = ospf_get_opaque_funclist(lsa_type)) != NULL)
for (ALL_LIST_ELEMENTS(funclist, node, nnode, functab)) {
if (functab->opaque_type == opaque_type) {
- /* Cleanup internal control information, if it
- * still remains. */
- if (functab->oipt != NULL)
- free_opaque_info_per_type(functab->oipt,
- true);
- /* Dequeue listnode entry from the list. */
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: Delete Opaque functab LSA type %u, opaque type %u, (%p)",
+ __func__, lsa_type,
+ opaque_type, functab);
+
+ /* Dequeue listnode entry from the function table
+ * list coreesponding to the opaque LSA type.
+ * Note that the list deletion callback frees
+ * the functab entry memory.
+ */
listnode_delete(funclist, functab);
-
- XFREE(MTYPE_OSPF_OPAQUE_FUNCTAB, functab);
+ ospf_opaque_functab_deref(functab);
break;
}
}
@@ -565,10 +604,15 @@ register_opaque_info_per_type(struct ospf_opaque_functab *functab,
oipt->opaque_type = GET_OPAQUE_TYPE(ntohl(new->data->id.s_addr));
oipt->status = PROC_NORMAL;
oipt->functab = functab;
- functab->oipt = oipt;
+ ospf_opaque_functab_ref(functab);
oipt->id_list = list_new();
oipt->id_list->del = free_opaque_info_per_id;
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: Register Opaque info-per-type LSA type %u, opaque type %u, (%p), Functab (%p)",
+ __func__, oipt->lsa_type, oipt->opaque_type, oipt,
+ oipt->functab);
+
out:
return oipt;
}
@@ -614,6 +658,15 @@ static void free_opaque_info_per_type(struct opaque_info_per_type *oipt,
}
listnode_delete(l, oipt);
}
+
+ if (oipt->functab)
+ ospf_opaque_functab_deref(oipt->functab);
+
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: Free Opaque info-per-type LSA type %u, opaque type %u, (%p), Functab (%p)",
+ __func__, oipt->lsa_type, oipt->opaque_type, oipt,
+ oipt->functab);
+
XFREE(MTYPE_OPAQUE_INFO_PER_TYPE, oipt);
return;
}
@@ -746,6 +799,45 @@ int ospf_opaque_is_owned(struct ospf_lsa *lsa)
return (oipt != NULL && lookup_opaque_info_by_id(oipt, lsa) != NULL);
}
+/*
+ * Cleanup Link-Local LSAs assocaited with an interface that is being deleted.
+ * Since these LSAs are stored in the area link state database (LSDB) as opposed
+ * to a separate per-interface, they must be deleted from the area database.
+ * Since their flooding scope is solely the deleted OSPF interface, there is no
+ * need to attempt to flush them from the routing domain. For link local LSAs
+ * originated via the OSPF server API, LSA deletion before interface deletion
+ * is required so that the callback can access the OSPF interface address.
+ */
+void ospf_opaque_type9_lsa_if_cleanup(struct ospf_interface *oi)
+{
+ struct route_node *rn;
+ struct ospf_lsdb *lsdb;
+ struct ospf_lsa *lsa;
+
+ lsdb = oi->area->lsdb;
+ LSDB_LOOP (OPAQUE_LINK_LSDB(oi->area), rn, lsa)
+ /*
+ * While the LSA shouldn't be referenced on any LSA
+ * lists since the flooding scoped is confined to the
+ * interface being deleted, clear the pointer to the
+ * deleted interface to avoid references and set the
+ * age to MAXAGE to avoid flush processing when the LSA
+ * is removed from the interface opaque info list.
+ */
+ if (lsa->oi == oi) {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("Delete Type-9 Opaque-LSA on interface delete: [opaque-type=%u, opaque-id=%x]",
+ GET_OPAQUE_TYPE(
+ ntohl(lsa->data->id.s_addr)),
+ GET_OPAQUE_ID(ntohl(
+ lsa->data->id.s_addr)));
+ ospf_lsdb_delete(lsdb, lsa);
+ lsa->data->ls_age = htons(OSPF_LSA_MAXAGE);
+ lsa->oi = NULL;
+ ospf_lsa_discard(lsa);
+ }
+}
+
/*------------------------------------------------------------------------*
* Following are (vty) configuration functions for Opaque-LSAs handling.
*------------------------------------------------------------------------*/
@@ -1159,12 +1251,12 @@ void ospf_opaque_config_write_debug(struct vty *vty)
void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa,
json_object *json)
{
- char buf[128], *bp;
struct lsa_header *lsah = lsa->data;
uint32_t lsid = ntohl(lsah->id.s_addr);
uint8_t opaque_type = GET_OPAQUE_TYPE(lsid);
uint32_t opaque_id = GET_OPAQUE_ID(lsid);
struct ospf_opaque_functab *functab;
+ json_object *jopaque = NULL;
int len, lenValid;
/* Switch output functionality by vty address. */
@@ -1185,17 +1277,14 @@ void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa,
ospf_opaque_type_name(opaque_type));
json_object_int_add(json, "opaqueId", opaque_id);
len = ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE;
- json_object_int_add(json, "opaqueDataLength", len);
+ json_object_int_add(json, "opaqueLength", len);
lenValid = VALID_OPAQUE_INFO_LEN(lsah);
- json_object_boolean_add(json, "opaqueDataLengthValid",
+ json_object_boolean_add(json, "opaqueLengthValid",
lenValid);
if (lenValid) {
- bp = asnprintfrr(MTYPE_TMP, buf, sizeof(buf),
- "%*pHXn", (int)len,
- (lsah + 1));
- json_object_string_add(json, "opaqueData", buf);
- if (bp != buf)
- XFREE(MTYPE_TMP, bp);
+ jopaque = json_object_new_object();
+ json_object_object_add(json, "opaqueValues",
+ jopaque);
}
}
} else {
@@ -1212,7 +1301,7 @@ void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa,
/* Call individual output functions. */
if ((functab = ospf_opaque_functab_lookup(lsa)) != NULL)
if (functab->show_opaque_info != NULL)
- (*functab->show_opaque_info)(vty, json, lsa);
+ (*functab->show_opaque_info)(vty, jopaque, lsa);
return;
}
diff --git a/ospfd/ospf_opaque.h b/ospfd/ospf_opaque.h
index e0c78cd..54651f8 100644
--- a/ospfd/ospf_opaque.h
+++ b/ospfd/ospf_opaque.h
@@ -109,6 +109,7 @@ extern void ospf_opaque_term(void);
extern void ospf_opaque_finish(void);
extern int ospf_opaque_type9_lsa_init(struct ospf_interface *oi);
extern void ospf_opaque_type9_lsa_term(struct ospf_interface *oi);
+extern void ospf_opaque_type9_lsa_if_cleanup(struct ospf_interface *oi);
extern int ospf_opaque_type10_lsa_init(struct ospf_area *area);
extern void ospf_opaque_type10_lsa_term(struct ospf_area *area);
extern int ospf_opaque_type11_lsa_init(struct ospf *ospf);
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index b37efa3..4bf4ae9 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -1042,7 +1042,7 @@ static void ospf_db_desc_proc(struct stream *s, struct ospf_interface *oi,
/* Neighbour has a more recent LSA, we must request it
*/
ospf_ls_request_add(nbr, new);
- /* fallthru */
+ fallthrough;
case 0:
/* If we have a copy of this LSA, it's either less
* recent
@@ -1231,7 +1231,7 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh,
through to case ExStart below. */
if (nbr->state != NSM_ExStart)
break;
- /* fallthru */
+ fallthrough;
case NSM_ExStart:
/* Initial DBD */
if ((IS_SET_DD_ALL(dd->flags) == OSPF_DD_FLAG_ALL)
@@ -1641,7 +1641,7 @@ static struct list *ospf_ls_upd_list_lsa(struct ospf_neighbor *nbr,
case OSPF_OPAQUE_LINK_LSA:
lsa->oi = oi; /* Remember incoming interface for
flooding control. */
- /* Fallthrough */
+ fallthrough;
default:
lsa->area = oi->area;
break;
diff --git a/ospfd/ospf_ri.c b/ospfd/ospf_ri.c
index 725443f..99326b4 100644
--- a/ospfd/ospf_ri.c
+++ b/ospfd/ospf_ri.c
@@ -24,6 +24,7 @@
#include "hash.h"
#include "sockunion.h" /* for inet_aton() */
#include "mpls.h"
+#include <lib/json.h>
#include "ospfd/ospfd.h"
#include "ospfd/ospf_interface.h"
@@ -153,6 +154,7 @@ static int ospf_router_info_unregister(void)
void ospf_router_info_term(void)
{
+ list_delete(&OspfRI.area_info);
list_delete(&OspfRI.pce_info.pce_domain);
list_delete(&OspfRI.pce_info.pce_neighbor);
@@ -1215,15 +1217,20 @@ static int ospf_router_info_lsa_update(struct ospf_lsa *lsa)
} \
} while (0)
-static uint16_t show_vty_router_cap(struct vty *vty, struct tlv_header *tlvh)
+static uint16_t show_vty_router_cap(struct vty *vty, struct tlv_header *tlvh,
+ json_object *json)
{
struct ri_tlv_router_cap *top = (struct ri_tlv_router_cap *)tlvh;
check_tlv_size(RI_TLV_CAPABILITIES_SIZE, "Router Capabilities");
if (vty != NULL)
- vty_out(vty, " Router Capabilities: 0x%x\n",
- ntohl(top->value));
+ if (!json)
+ vty_out(vty, " Router Capabilities: 0x%x\n",
+ ntohl(top->value));
+ else
+ json_object_string_addf(json, "routerCapabilities",
+ "0x%x", ntohl(top->value));
else
zlog_debug(" Router Capabilities: 0x%x", ntohl(top->value));
@@ -1231,7 +1238,8 @@ static uint16_t show_vty_router_cap(struct vty *vty, struct tlv_header *tlvh)
}
static uint16_t show_vty_pce_subtlv_address(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct ri_pce_subtlv_address *top =
(struct ri_pce_subtlv_address *)tlvh;
@@ -1239,20 +1247,28 @@ static uint16_t show_vty_pce_subtlv_address(struct vty *vty,
if (ntohs(top->address.type) == PCE_ADDRESS_IPV4) {
check_tlv_size(PCE_ADDRESS_IPV4_SIZE, "PCE Address");
if (vty != NULL)
- vty_out(vty, " PCE Address: %pI4\n",
- &top->address.value);
+ if (!json)
+ vty_out(vty, " PCE Address: %pI4\n",
+ &top->address.value);
+ else
+ json_object_string_addf(json, "pceAddress",
+ "%pI4",
+ &top->address.value);
else
zlog_debug(" PCE Address: %pI4",
&top->address.value);
} else if (ntohs(top->address.type) == PCE_ADDRESS_IPV6) {
- /* TODO: Add support to IPv6 with inet_ntop() */
check_tlv_size(PCE_ADDRESS_IPV6_SIZE, "PCE Address");
if (vty != NULL)
- vty_out(vty, " PCE Address: 0x%x\n",
- ntohl(top->address.value.s_addr));
+ if (!json)
+ vty_out(vty,
+ " PCE Address: unsupported IPv6\n");
+ else
+ json_object_string_add(json, "pceAddress",
+ "unsupported IPv6");
+
else
- zlog_debug(" PCE Address: 0x%x",
- ntohl(top->address.value.s_addr));
+ zlog_debug(" PCE Address: unsupported IPv6");
} else {
if (vty != NULL)
vty_out(vty, " Wrong PCE Address type: 0x%x\n",
@@ -1266,7 +1282,8 @@ static uint16_t show_vty_pce_subtlv_address(struct vty *vty,
}
static uint16_t show_vty_pce_subtlv_path_scope(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct ri_pce_subtlv_path_scope *top =
(struct ri_pce_subtlv_path_scope *)tlvh;
@@ -1274,7 +1291,12 @@ static uint16_t show_vty_pce_subtlv_path_scope(struct vty *vty,
check_tlv_size(RI_PCE_SUBTLV_PATH_SCOPE_SIZE, "PCE Path Scope");
if (vty != NULL)
- vty_out(vty, " PCE Path Scope: 0x%x\n", ntohl(top->value));
+ if (!json)
+ vty_out(vty, " PCE Path Scope: 0x%x\n",
+ ntohl(top->value));
+ else
+ json_object_string_addf(json, "pcePathScope", "0x%x",
+ ntohl(top->value));
else
zlog_debug(" PCE Path Scope: 0x%x", ntohl(top->value));
@@ -1282,7 +1304,8 @@ static uint16_t show_vty_pce_subtlv_path_scope(struct vty *vty,
}
static uint16_t show_vty_pce_subtlv_domain(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct ri_pce_subtlv_domain *top = (struct ri_pce_subtlv_domain *)tlvh;
struct in_addr tmp;
@@ -1292,13 +1315,21 @@ static uint16_t show_vty_pce_subtlv_domain(struct vty *vty,
if (ntohs(top->type) == PCE_DOMAIN_TYPE_AREA) {
tmp.s_addr = top->value;
if (vty != NULL)
- vty_out(vty, " PCE Domain Area: %pI4\n", &tmp);
+ if (!json)
+ vty_out(vty, " PCE Domain Area: %pI4\n", &tmp);
+ else
+ json_object_string_addf(json, "pceDomainArea",
+ "%pI4", &tmp);
else
zlog_debug(" PCE Domain Area: %pI4", &tmp);
} else if (ntohs(top->type) == PCE_DOMAIN_TYPE_AS) {
if (vty != NULL)
- vty_out(vty, " PCE Domain AS: %d\n",
- ntohl(top->value));
+ if (!json)
+ vty_out(vty, " PCE Domain AS: %d\n",
+ ntohl(top->value));
+ else
+ json_object_int_add(json, "pceDomainAS",
+ ntohl(top->value));
else
zlog_debug(" PCE Domain AS: %d", ntohl(top->value));
} else {
@@ -1314,7 +1345,8 @@ static uint16_t show_vty_pce_subtlv_domain(struct vty *vty,
}
static uint16_t show_vty_pce_subtlv_neighbor(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct ri_pce_subtlv_neighbor *top =
@@ -1326,13 +1358,22 @@ static uint16_t show_vty_pce_subtlv_neighbor(struct vty *vty,
if (ntohs(top->type) == PCE_DOMAIN_TYPE_AREA) {
tmp.s_addr = top->value;
if (vty != NULL)
- vty_out(vty, " PCE Neighbor Area: %pI4\n", &tmp);
+ if (!json)
+ vty_out(vty, " PCE Neighbor Area: %pI4\n",
+ &tmp);
+ else
+ json_object_string_addf(json, "pceNeighborArea",
+ "%pI4", &tmp);
else
zlog_debug(" PCE Neighbor Area: %pI4", &tmp);
} else if (ntohs(top->type) == PCE_DOMAIN_TYPE_AS) {
if (vty != NULL)
- vty_out(vty, " PCE Neighbor AS: %d\n",
- ntohl(top->value));
+ if (!json)
+ vty_out(vty, " PCE Neighbor AS: %d\n",
+ ntohl(top->value));
+ else
+ json_object_int_add(json, "pceNeighborAS",
+ ntohl(top->value));
else
zlog_debug(" PCE Neighbor AS: %d",
ntohl(top->value));
@@ -1349,7 +1390,8 @@ static uint16_t show_vty_pce_subtlv_neighbor(struct vty *vty,
}
static uint16_t show_vty_pce_subtlv_cap_flag(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct ri_pce_subtlv_cap_flag *top =
(struct ri_pce_subtlv_cap_flag *)tlvh;
@@ -1357,8 +1399,12 @@ static uint16_t show_vty_pce_subtlv_cap_flag(struct vty *vty,
check_tlv_size(RI_PCE_SUBTLV_CAP_FLAG_SIZE, "PCE Capabilities");
if (vty != NULL)
- vty_out(vty, " PCE Capabilities Flag: 0x%x\n",
- ntohl(top->value));
+ if (!json)
+ vty_out(vty, " PCE Capabilities Flag: 0x%x\n",
+ ntohl(top->value));
+ else
+ json_object_string_addf(json, "pceCapabilities",
+ "0x%x", ntohl(top->value));
else
zlog_debug(" PCE Capabilities Flag: 0x%x",
ntohl(top->value));
@@ -1367,8 +1413,10 @@ static uint16_t show_vty_pce_subtlv_cap_flag(struct vty *vty,
}
static uint16_t show_vty_unknown_tlv(struct vty *vty, struct tlv_header *tlvh,
- size_t buf_size)
+ size_t buf_size, json_object *json)
{
+ json_object *obj;
+
if (TLV_SIZE(tlvh) > buf_size) {
if (vty != NULL)
vty_out(vty,
@@ -1382,8 +1430,18 @@ static uint16_t show_vty_unknown_tlv(struct vty *vty, struct tlv_header *tlvh,
}
if (vty != NULL)
- vty_out(vty, " Unknown TLV: [type(0x%x), length(0x%x)]\n",
- ntohs(tlvh->type), ntohs(tlvh->length));
+ if (!json)
+ vty_out(vty,
+ " Unknown TLV: [type(0x%x), length(0x%x)]\n",
+ ntohs(tlvh->type), ntohs(tlvh->length));
+ else {
+ obj = json_object_new_object();
+ json_object_string_addf(obj, "type", "0x%x",
+ ntohs(tlvh->type));
+ json_object_string_addf(obj, "length", "0x%x",
+ ntohs(tlvh->length));
+ json_object_object_add(json, "unknownTLV", obj);
+ }
else
zlog_debug(" Unknown TLV: [type(0x%x), length(0x%x)]",
ntohs(tlvh->type), ntohs(tlvh->length));
@@ -1392,7 +1450,7 @@ static uint16_t show_vty_unknown_tlv(struct vty *vty, struct tlv_header *tlvh,
}
static uint16_t show_vty_pce_info(struct vty *vty, struct tlv_header *ri,
- size_t buf_size)
+ size_t buf_size, json_object *json)
{
struct tlv_header *tlvh;
uint16_t length = ntohs(ri->length);
@@ -1409,22 +1467,23 @@ static uint16_t show_vty_pce_info(struct vty *vty, struct tlv_header *ri,
for (tlvh = ri; sum < length; tlvh = TLV_HDR_NEXT(tlvh)) {
switch (ntohs(tlvh->type)) {
case RI_PCE_SUBTLV_ADDRESS:
- sum += show_vty_pce_subtlv_address(vty, tlvh);
+ sum += show_vty_pce_subtlv_address(vty, tlvh, json);
break;
case RI_PCE_SUBTLV_PATH_SCOPE:
- sum += show_vty_pce_subtlv_path_scope(vty, tlvh);
+ sum += show_vty_pce_subtlv_path_scope(vty, tlvh, json);
break;
case RI_PCE_SUBTLV_DOMAIN:
- sum += show_vty_pce_subtlv_domain(vty, tlvh);
+ sum += show_vty_pce_subtlv_domain(vty, tlvh, json);
break;
case RI_PCE_SUBTLV_NEIGHBOR:
- sum += show_vty_pce_subtlv_neighbor(vty, tlvh);
+ sum += show_vty_pce_subtlv_neighbor(vty, tlvh, json);
break;
case RI_PCE_SUBTLV_CAP_FLAG:
- sum += show_vty_pce_subtlv_cap_flag(vty, tlvh);
+ sum += show_vty_pce_subtlv_cap_flag(vty, tlvh, json);
break;
default:
- sum += show_vty_unknown_tlv(vty, tlvh, length - sum);
+ sum += show_vty_unknown_tlv(vty, tlvh, length - sum,
+ json);
break;
}
}
@@ -1432,33 +1491,62 @@ static uint16_t show_vty_pce_info(struct vty *vty, struct tlv_header *ri,
}
/* Display Segment Routing Algorithm TLV information */
-static uint16_t show_vty_sr_algorithm(struct vty *vty, struct tlv_header *tlvh)
+static uint16_t show_vty_sr_algorithm(struct vty *vty, struct tlv_header *tlvh,
+ json_object *json)
{
struct ri_sr_tlv_sr_algorithm *algo =
(struct ri_sr_tlv_sr_algorithm *)tlvh;
int i;
+ json_object *json_algo, *obj;
+ char buf[2];
check_tlv_size(ALGORITHM_COUNT, "Segment Routing Algorithm");
- if (vty != NULL) {
- vty_out(vty, " Segment Routing Algorithm TLV:\n");
- for (i = 0; i < ntohs(algo->header.length); i++) {
- switch (algo->value[i]) {
- case 0:
- vty_out(vty, " Algorithm %d: SPF\n", i);
- break;
- case 1:
- vty_out(vty, " Algorithm %d: Strict SPF\n",
- i);
- break;
- default:
- vty_out(vty,
- " Algorithm %d: Unknown value %d\n", i,
- algo->value[i]);
- break;
+ if (vty != NULL)
+ if (!json) {
+ vty_out(vty, " Segment Routing Algorithm TLV:\n");
+ for (i = 0; i < ntohs(algo->header.length); i++) {
+ switch (algo->value[i]) {
+ case 0:
+ vty_out(vty,
+ " Algorithm %d: SPF\n", i);
+ break;
+ case 1:
+ vty_out(vty,
+ " Algorithm %d: Strict SPF\n",
+ i);
+ break;
+ default:
+ vty_out(vty,
+ " Algorithm %d: Unknown value %d\n", i,
+ algo->value[i]);
+ break;
+ }
+ }
+ } else {
+ json_algo = json_object_new_array();
+ json_object_object_add(json, "algorithms",
+ json_algo);
+ for (i = 0; i < ntohs(algo->header.length); i++) {
+ obj = json_object_new_object();
+ snprintfrr(buf, 2, "%d", i);
+ switch (algo->value[i]) {
+ case 0:
+ json_object_string_add(obj, buf, "SPF");
+ break;
+ case 1:
+ json_object_string_add(obj, buf,
+ "strictSPF");
+ break;
+ default:
+ json_object_string_add(obj, buf,
+ "unknown");
+ break;
+ }
+ json_object_array_add(json_algo, obj);
}
}
- } else {
+ else {
zlog_debug(" Segment Routing Algorithm TLV:");
for (i = 0; i < ntohs(algo->header.length); i++)
switch (algo->value[i]) {
@@ -1479,24 +1567,47 @@ static uint16_t show_vty_sr_algorithm(struct vty *vty, struct tlv_header *tlvh)
}
/* Display Segment Routing SID/Label Range TLV information */
-static uint16_t show_vty_sr_range(struct vty *vty, struct tlv_header *tlvh)
+static uint16_t show_vty_sr_range(struct vty *vty, struct tlv_header *tlvh,
+ json_object *json)
{
struct ri_sr_tlv_sid_label_range *range =
(struct ri_sr_tlv_sid_label_range *)tlvh;
+ json_object *obj;
+ uint32_t upper;
check_tlv_size(RI_SR_TLV_LABEL_RANGE_SIZE, "SR Label Range");
- if (vty != NULL) {
- vty_out(vty,
- " Segment Routing %s Range TLV:\n"
- " Range Size = %d\n"
- " SID Label = %d\n\n",
- ntohs(range->header.type) == RI_SR_TLV_SRGB_LABEL_RANGE
- ? "Global"
- : "Local",
- GET_RANGE_SIZE(ntohl(range->size)),
- GET_LABEL(ntohl(range->lower.value)));
- } else {
+ if (vty != NULL)
+ if (!json) {
+ vty_out(vty,
+ " Segment Routing %s Range TLV:\n"
+ " Range Size = %d\n"
+ " SID Label = %d\n\n",
+ ntohs(range->header.type) ==
+ RI_SR_TLV_SRGB_LABEL_RANGE
+ ? "Global"
+ : "Local",
+ GET_RANGE_SIZE(ntohl(range->size)),
+ GET_LABEL(ntohl(range->lower.value)));
+ } else {
+ /*
+ * According to draft-ietf-teas-yang-sr-te-topo, SRGB
+ * and SRLB are describe with lower and upper bounds
+ */
+ upper = GET_LABEL(ntohl(range->lower.value)) +
+ GET_RANGE_SIZE(ntohl(range->size)) - 1;
+ obj = json_object_new_object();
+ json_object_int_add(obj, "upperBound", upper);
+ json_object_int_add(obj, "lowerBound",
+ GET_LABEL(ntohl(range->lower.value)));
+ json_object_object_add(json,
+ ntohs(range->header.type) ==
+ RI_SR_TLV_SRGB_LABEL_RANGE
+ ? "srgb"
+ : "srlb",
+ obj);
+ }
+ else {
zlog_debug(
" Segment Routing %s Range TLV: Range Size = %d SID Label = %d",
ntohs(range->header.type) == RI_SR_TLV_SRGB_LABEL_RANGE
@@ -1510,22 +1621,25 @@ static uint16_t show_vty_sr_range(struct vty *vty, struct tlv_header *tlvh)
}
/* Display Segment Routing Maximum Stack Depth TLV information */
-static uint16_t show_vty_sr_msd(struct vty *vty, struct tlv_header *tlvh)
+static uint16_t show_vty_sr_msd(struct vty *vty, struct tlv_header *tlvh,
+ json_object *json)
{
struct ri_sr_tlv_node_msd *msd = (struct ri_sr_tlv_node_msd *)tlvh;
check_tlv_size(RI_SR_TLV_NODE_MSD_SIZE, "Node Maximum Stack Depth");
- if (vty != NULL) {
- vty_out(vty,
- " Segment Routing MSD TLV:\n"
- " Node Maximum Stack Depth = %d\n",
- msd->value);
- } else {
+ if (vty != NULL)
+ if (!json)
+ vty_out(vty,
+ " Segment Routing MSD TLV:\n"
+ " Node Maximum Stack Depth = %d\n",
+ msd->value);
+ else
+ json_object_int_add(json, "nodeMsd", msd->value);
+ else
zlog_debug(
" Segment Routing MSD TLV: Node Maximum Stack Depth = %d",
msd->value);
- }
return TLV_SIZE(tlvh);
}
@@ -1537,9 +1651,14 @@ static void ospf_router_info_show_info(struct vty *vty,
struct lsa_header *lsah = lsa->data;
struct tlv_header *tlvh;
uint16_t length = 0, sum = 0;
+ json_object *jri = NULL, *jpce = NULL, *jsr = NULL;
- if (json)
- return;
+ if (json) {
+ jri = json_object_new_object();
+ json_object_object_add(json, "routerInformation", jri);
+ jpce = json_object_new_object();
+ jsr = json_object_new_object();
+ }
/* Initialize TLV browsing */
length = lsa->size - OSPF_LSA_HEADER_SIZE;
@@ -1548,30 +1667,36 @@ static void ospf_router_info_show_info(struct vty *vty,
tlvh = TLV_HDR_NEXT(tlvh)) {
switch (ntohs(tlvh->type)) {
case RI_TLV_CAPABILITIES:
- sum += show_vty_router_cap(vty, tlvh);
+ sum += show_vty_router_cap(vty, tlvh, jri);
break;
case RI_TLV_PCE:
tlvh++;
sum += TLV_HDR_SIZE;
- sum += show_vty_pce_info(vty, tlvh, length - sum);
+ sum += show_vty_pce_info(vty, tlvh, length - sum, jpce);
break;
case RI_SR_TLV_SR_ALGORITHM:
- sum += show_vty_sr_algorithm(vty, tlvh);
+ sum += show_vty_sr_algorithm(vty, tlvh, jsr);
break;
case RI_SR_TLV_SRGB_LABEL_RANGE:
case RI_SR_TLV_SRLB_LABEL_RANGE:
- sum += show_vty_sr_range(vty, tlvh);
+ sum += show_vty_sr_range(vty, tlvh, jsr);
break;
case RI_SR_TLV_NODE_MSD:
- sum += show_vty_sr_msd(vty, tlvh);
+ sum += show_vty_sr_msd(vty, tlvh, jsr);
break;
default:
- sum += show_vty_unknown_tlv(vty, tlvh, length);
+ sum += show_vty_unknown_tlv(vty, tlvh, length, jri);
break;
}
}
+ if (json) {
+ if (json_object_object_length(jpce) > 1)
+ json_object_object_add(jri, "pceInformation", jpce);
+ if (json_object_object_length(jsr) > 1)
+ json_object_object_add(jri, "segmentRouting", jsr);
+ }
return;
}
@@ -1722,9 +1847,11 @@ DEFUN (router_info,
DEFUN (no_router_info,
no_router_info_cmd,
- "no router-info",
+ "no router-info [<area|as>]",
NO_STR
- "Disable the Router Information functionality\n")
+ "Disable the Router Information functionality\n"
+ "Disable the Router Information functionality with AS flooding scope\n"
+ "Disable the Router Information functionality with Area flooding scope\n")
{
if (!OspfRI.enabled)
@@ -2042,7 +2169,7 @@ DEFUN (show_ip_ospf_router_info,
if (OspfRI.enabled) {
vty_out(vty, "--- Router Information parameters ---\n");
- show_vty_router_cap(vty, &OspfRI.router_cap.header);
+ show_vty_router_cap(vty, &OspfRI.router_cap.header, NULL);
} else {
if (vty != NULL)
vty_out(vty,
@@ -2071,27 +2198,32 @@ DEFUN (show_ip_opsf_router_info_pce,
if (pce->pce_address.header.type != 0)
show_vty_pce_subtlv_address(vty,
- &pce->pce_address.header);
+ &pce->pce_address.header,
+ NULL);
if (pce->pce_scope.header.type != 0)
show_vty_pce_subtlv_path_scope(vty,
- &pce->pce_scope.header);
+ &pce->pce_scope.header,
+ NULL);
for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, domain)) {
if (domain->header.type != 0)
show_vty_pce_subtlv_domain(vty,
- &domain->header);
+ &domain->header,
+ NULL);
}
for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, neighbor)) {
if (neighbor->header.type != 0)
show_vty_pce_subtlv_neighbor(vty,
- &neighbor->header);
+ &neighbor->header,
+ NULL);
}
if (pce->pce_cap_flag.header.type != 0)
show_vty_pce_subtlv_cap_flag(vty,
- &pce->pce_cap_flag.header);
+ &pce->pce_cap_flag.header,
+ NULL);
} else {
vty_out(vty, " PCE info is disabled on this router\n");
diff --git a/ospfd/ospf_snmp.c b/ospfd/ospf_snmp.c
index c9aaa9f..fc0c143 100644
--- a/ospfd/ospf_snmp.c
+++ b/ospfd/ospf_snmp.c
@@ -1348,7 +1348,7 @@ static int ospf_snmp_if_update(struct interface *ifp)
ifindex = 0;
/* Lookup first IPv4 address entry. */
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
+ frr_each (if_connected, ifp->connected, ifc) {
p = CONNECTED_ID(ifc);
if (p->family == AF_INET) {
@@ -1396,11 +1396,10 @@ static int ospf_snmp_if_update(struct interface *ifp)
static int ospf_snmp_is_if_have_addr(struct interface *ifp)
{
- struct listnode *nn;
struct connected *ifc;
/* Is this interface having any connected IPv4 address ? */
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, nn, ifc)) {
+ frr_each (if_connected, ifp->connected, ifc) {
if (CONNECTED_PREFIX(ifc)->family == AF_INET)
return 1;
}
diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c
index 467cb05..e26fe6f 100644
--- a/ospfd/ospf_sr.c
+++ b/ospfd/ospf_sr.c
@@ -580,6 +580,7 @@ static void ospf_sr_stop(void)
hash_clean(OspfSR.neighbors, (void *)sr_node_del);
OspfSR.self = NULL;
OspfSR.status = SR_OFF;
+ OspfSR.msd = 0;
}
/*
diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c
index 3cf39e5..80ebab3 100644
--- a/ospfd/ospf_te.c
+++ b/ospfd/ospf_te.c
@@ -31,6 +31,7 @@
#include "link_state.h"
#include "zclient.h"
#include "printfrr.h"
+#include <lib/json.h>
#include "ospfd/ospfd.h"
#include "ospfd/ospf_interface.h"
@@ -980,8 +981,8 @@ static void ospf_mpls_te_nsm_change(struct ospf_neighbor *nbr, int old_state)
struct ospf_interface *oi = nbr->oi;
struct mpls_te_link *lp;
- /* Process Neighbor only when its state is NSM Full */
- if (nbr->state != NSM_Full)
+ /* Process Link only when neighbor old or new state is NSM Full */
+ if (nbr->state != NSM_Full && old_state != NSM_Full)
return;
/* Get interface information for Traffic Engineering */
@@ -1839,6 +1840,7 @@ static void ospf_te_delete_subnet(struct ls_ted *ted, struct in_addr addr)
p.family = AF_INET;
p.prefixlen = IPV4_MAX_BITLEN;
p.u.prefix4 = addr;
+ ote_debug(" |- Delete Subnet info. for Prefix %pFX", &p);
subnet = ls_find_subnet(ted, &p);
/* Remove subnet if found */
@@ -1851,8 +1853,7 @@ static void ospf_te_delete_subnet(struct ls_ted *ted, struct in_addr addr)
/**
* Parse Router LSA. This function will create or update corresponding Vertex,
- * Edge and Subnet. It also remove Edge and Subnet if they are marked as Orphan
- * once Router LSA is parsed.
+ * Edge and Subnet.
*
* @param ted Link State Traffic Engineering Database
* @param lsa OSPF Link State Advertisement
@@ -1864,9 +1865,6 @@ static int ospf_te_parse_router_lsa(struct ls_ted *ted, struct ospf_lsa *lsa)
struct router_lsa *rl;
enum ls_node_type type;
struct ls_vertex *vertex;
- struct ls_edge *edge;
- struct ls_subnet *subnet;
- struct listnode *node;
int len, links;
/* Sanity Check */
@@ -1909,13 +1907,6 @@ static int ospf_te_parse_router_lsa(struct ls_ted *ted, struct ospf_lsa *lsa)
vertex->status = SYNC;
}
- /* Mark outgoing Edge and Subnet as ORPHAN to detect deletion */
- for (ALL_LIST_ELEMENTS_RO(vertex->outgoing_edges, node, edge))
- edge->status = ORPHAN;
-
- for (ALL_LIST_ELEMENTS_RO(vertex->prefixes, node, subnet))
- subnet->status = ORPHAN;
-
/* Then, process Link Information */
len = lsa->size - OSPF_LSA_HEADER_SIZE - OSPF_ROUTER_LSA_MIN_SIZE;
links = ntohs(rl->links);
@@ -1948,11 +1939,6 @@ static int ospf_te_parse_router_lsa(struct ls_ted *ted, struct ospf_lsa *lsa)
break;
}
}
- /* Clean remaining Orphan Edges or Subnets */
- if (OspfMplsTE.export)
- ls_vertex_clean(ted, vertex, zclient);
- else
- ls_vertex_clean(ted, vertex, NULL);
return 0;
}
@@ -2260,6 +2246,10 @@ static int ospf_te_parse_te(struct ls_ted *ted, struct ospf_lsa *lsa)
}
/* Get corresponding Edge from Link State Data Base */
+ if (IPV4_NET0(attr.standard.local.s_addr) && !attr.standard.local_id) {
+ ote_debug(" |- Found no TE Link local address/ID. Abort!");
+ return -1;
+ }
edge = get_edge(ted, attr.adv, attr.standard.local);
old = edge->attributes;
@@ -2405,7 +2395,10 @@ static int ospf_te_delete_te(struct ls_ted *ted, struct ospf_lsa *lsa)
ote_debug(" |- Delete TE info. for Edge %pI4",
&edge->attributes->standard.local);
- /* Remove Link State Attributes TE information */
+ /* First remove the associated Subnet */
+ ospf_te_delete_subnet(ted, attr->standard.local);
+
+ /* Then ,remove Link State Attributes TE information */
memset(&attr->standard, 0, sizeof(struct ls_standard));
attr->flags &= 0x0FFFF;
memset(&attr->extended, 0, sizeof(struct ls_extended));
@@ -2420,7 +2413,6 @@ static int ospf_te_delete_te(struct ls_ted *ted, struct ospf_lsa *lsa)
edge->status = SYNC;
} else {
/* Remove completely the Edge if Segment Routing is not set */
- ospf_te_delete_subnet(ted, attr->standard.local);
edge->status = DELETE;
ospf_te_export(LS_MSG_TYPE_ATTRIBUTES, edge);
ls_edge_del_all(ted, edge);
@@ -3154,14 +3146,19 @@ static void ospf_te_init_ted(struct ls_ted *ted, struct ospf *ospf)
} \
} while (0)
-static uint16_t show_vty_router_addr(struct vty *vty, struct tlv_header *tlvh)
+static uint16_t show_vty_router_addr(struct vty *vty, struct tlv_header *tlvh,
+ json_object *json)
{
struct te_tlv_router_addr *top = (struct te_tlv_router_addr *)tlvh;
check_tlv_size(TE_LINK_SUBTLV_DEF_SIZE, "Router Address");
if (vty != NULL)
- vty_out(vty, " Router-Address: %pI4\n", &top->value);
+ if (!json)
+ vty_out(vty, " Router-Address: %pI4\n", &top->value);
+ else
+ json_object_string_addf(json, "routerAddress", "%pI4",
+ &top->value);
else
zlog_debug(" Router-Address: %pI4", &top->value);
@@ -3169,7 +3166,7 @@ static uint16_t show_vty_router_addr(struct vty *vty, struct tlv_header *tlvh)
}
static uint16_t show_vty_link_header(struct vty *vty, struct tlv_header *tlvh,
- size_t buf_size)
+ size_t buf_size, json_object *json)
{
struct te_tlv_link *top = (struct te_tlv_link *)tlvh;
@@ -3186,8 +3183,12 @@ static uint16_t show_vty_link_header(struct vty *vty, struct tlv_header *tlvh,
}
if (vty != NULL)
- vty_out(vty, " Link: %u octets of data\n",
- ntohs(top->header.length));
+ if (!json)
+ vty_out(vty, " Link: %u octets of data\n",
+ ntohs(top->header.length));
+ else
+ json_object_int_add(json, "teLinkDataLength",
+ ntohs(top->header.length));
else
zlog_debug(" Link: %u octets of data",
ntohs(top->header.length));
@@ -3196,7 +3197,8 @@ static uint16_t show_vty_link_header(struct vty *vty, struct tlv_header *tlvh,
}
static uint16_t show_vty_link_subtlv_link_type(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_link_type *top;
const char *cp = "Unknown";
@@ -3216,8 +3218,11 @@ static uint16_t show_vty_link_subtlv_link_type(struct vty *vty,
}
if (vty != NULL)
- vty_out(vty, " Link-Type: %s (%u)\n", cp,
- top->link_type.value);
+ if (!json)
+ vty_out(vty, " Link-Type: %s (%u)\n", cp,
+ top->link_type.value);
+ else
+ json_object_string_add(json, "accessType", cp);
else
zlog_debug(" Link-Type: %s (%u)", cp, top->link_type.value);
@@ -3225,7 +3230,8 @@ static uint16_t show_vty_link_subtlv_link_type(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_link_id(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_link_id *top;
@@ -3233,7 +3239,11 @@ static uint16_t show_vty_link_subtlv_link_id(struct vty *vty,
top = (struct te_link_subtlv_link_id *)tlvh;
if (vty != NULL)
- vty_out(vty, " Link-ID: %pI4\n", &top->value);
+ if (!json)
+ vty_out(vty, " Link-ID: %pI4\n", &top->value);
+ else
+ json_object_string_addf(json, "linkID", "%pI4",
+ &top->value);
else
zlog_debug(" Link-ID: %pI4", &top->value);
@@ -3242,9 +3252,12 @@ static uint16_t show_vty_link_subtlv_link_id(struct vty *vty,
static uint16_t show_vty_link_subtlv_lclif_ipaddr(struct vty *vty,
struct tlv_header *tlvh,
- size_t buf_size)
+ size_t buf_size,
+ json_object *json)
{
struct te_link_subtlv_lclif_ipaddr *top;
+ json_object *json_addr, *json_obj;
+ char buf[4];
int i, n;
if (TLV_SIZE(tlvh) > buf_size) {
@@ -3263,13 +3276,29 @@ static uint16_t show_vty_link_subtlv_lclif_ipaddr(struct vty *vty,
n = ntohs(tlvh->length) / sizeof(top->value[0]);
if (vty != NULL)
- vty_out(vty, " Local Interface IP Address(es): %d\n", n);
+ if (!json)
+ vty_out(vty, " Local Interface IP Address(es): %d\n",
+ n);
+ else {
+ json_addr = json_object_new_array();
+ json_object_object_add(json, "localIPAddresses",
+ json_addr);
+ }
else
zlog_debug(" Local Interface IP Address(es): %d", n);
for (i = 0; i < n; i++) {
if (vty != NULL)
- vty_out(vty, " #%d: %pI4\n", i, &top->value[i]);
+ if (!json)
+ vty_out(vty, " #%d: %pI4\n", i,
+ &top->value[i]);
+ else {
+ json_obj = json_object_new_object();
+ snprintfrr(buf, 2, "%d", i);
+ json_object_string_addf(json_obj, buf, "%pI4",
+ &top->value[i]);
+ json_object_array_add(json_addr, json_obj);
+ }
else
zlog_debug(" #%d: %pI4", i, &top->value[i]);
}
@@ -3278,9 +3307,12 @@ static uint16_t show_vty_link_subtlv_lclif_ipaddr(struct vty *vty,
static uint16_t show_vty_link_subtlv_rmtif_ipaddr(struct vty *vty,
struct tlv_header *tlvh,
- size_t buf_size)
+ size_t buf_size,
+ json_object *json)
{
struct te_link_subtlv_rmtif_ipaddr *top;
+ json_object *json_addr, *json_obj;
+ char buf[4];
int i, n;
if (TLV_SIZE(tlvh) > buf_size) {
@@ -3298,13 +3330,29 @@ static uint16_t show_vty_link_subtlv_rmtif_ipaddr(struct vty *vty,
top = (struct te_link_subtlv_rmtif_ipaddr *)tlvh;
n = ntohs(tlvh->length) / sizeof(top->value[0]);
if (vty != NULL)
- vty_out(vty, " Remote Interface IP Address(es): %d\n", n);
+ if (!json)
+ vty_out(vty, " Remote Interface IP Address(es): %d\n",
+ n);
+ else {
+ json_addr = json_object_new_array();
+ json_object_object_add(json, "remoteIPAddresses",
+ json_addr);
+ }
else
zlog_debug(" Remote Interface IP Address(es): %d", n);
for (i = 0; i < n; i++) {
if (vty != NULL)
- vty_out(vty, " #%d: %pI4\n", i, &top->value[i]);
+ if (!json)
+ vty_out(vty, " #%d: %pI4\n", i,
+ &top->value[i]);
+ else {
+ json_obj = json_object_new_object();
+ snprintfrr(buf, 2, "%d", i);
+ json_object_string_addf(json_obj, buf, "%pI4",
+ &top->value[i]);
+ json_object_array_add(json_addr, json_obj);
+ }
else
zlog_debug(" #%d: %pI4", i, &top->value[i]);
}
@@ -3312,7 +3360,8 @@ static uint16_t show_vty_link_subtlv_rmtif_ipaddr(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_te_metric(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_te_metric *top;
@@ -3320,8 +3369,12 @@ static uint16_t show_vty_link_subtlv_te_metric(struct vty *vty,
top = (struct te_link_subtlv_te_metric *)tlvh;
if (vty != NULL)
- vty_out(vty, " Traffic Engineering Metric: %u\n",
- (uint32_t)ntohl(top->value));
+ if (!json)
+ vty_out(vty, " Traffic Engineering Metric: %u\n",
+ (uint32_t)ntohl(top->value));
+ else
+ json_object_int_add(json, "teDefaultMetric",
+ (uint32_t)ntohl(top->value));
else
zlog_debug(" Traffic Engineering Metric: %u",
(uint32_t)ntohl(top->value));
@@ -3330,7 +3383,8 @@ static uint16_t show_vty_link_subtlv_te_metric(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_max_bw(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_max_bw *top;
float fval;
@@ -3341,7 +3395,11 @@ static uint16_t show_vty_link_subtlv_max_bw(struct vty *vty,
fval = ntohf(top->value);
if (vty != NULL)
- vty_out(vty, " Maximum Bandwidth: %g (Bytes/sec)\n", fval);
+ if (!json)
+ vty_out(vty, " Maximum Bandwidth: %g (Bytes/sec)\n",
+ fval);
+ else
+ json_object_double_add(json, "maxLinkBandwidth", fval);
else
zlog_debug(" Maximum Bandwidth: %g (Bytes/sec)", fval);
@@ -3349,7 +3407,8 @@ static uint16_t show_vty_link_subtlv_max_bw(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_max_rsv_bw(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_max_rsv_bw *top;
float fval;
@@ -3360,8 +3419,12 @@ static uint16_t show_vty_link_subtlv_max_rsv_bw(struct vty *vty,
fval = ntohf(top->value);
if (vty != NULL)
- vty_out(vty, " Maximum Reservable Bandwidth: %g (Bytes/sec)\n",
- fval);
+ if (!json)
+ vty_out(vty, " Maximum Reservable Bandwidth: %g (Bytes/sec)\n",
+ fval);
+ else
+ json_object_double_add(json, "maxResvLinkBandwidth",
+ fval);
else
zlog_debug(" Maximum Reservable Bandwidth: %g (Bytes/sec)",
fval);
@@ -3370,18 +3433,27 @@ static uint16_t show_vty_link_subtlv_max_rsv_bw(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_unrsv_bw(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_unrsv_bw *top;
+ json_object *json_bw, *json_obj;
float fval1, fval2;
+ char buf[16];
int i;
check_tlv_size(TE_LINK_SUBTLV_UNRSV_SIZE, "Unreserved Bandwidth");
top = (struct te_link_subtlv_unrsv_bw *)tlvh;
if (vty != NULL)
- vty_out(vty,
- " Unreserved Bandwidth per Class Type in Byte/s:\n");
+ if (!json)
+ vty_out(vty,
+ " Unreserved Bandwidth per Class Type in Byte/s:\n");
+ else {
+ json_bw = json_object_new_array();
+ json_object_object_add(json, "unreservedBandwidth",
+ json_bw);
+ }
else
zlog_debug(
" Unreserved Bandwidth per Class Type in Byte/s:");
@@ -3390,9 +3462,20 @@ static uint16_t show_vty_link_subtlv_unrsv_bw(struct vty *vty,
fval2 = ntohf(top->value[i + 1]);
if (vty != NULL)
- vty_out(vty,
- " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n",
- i, fval1, i + 1, fval2);
+ if (!json)
+ vty_out(vty,
+ " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n",
+ i, fval1, i + 1, fval2);
+ else {
+ json_obj = json_object_new_object();
+ snprintfrr(buf, 12, "classType-%u", i);
+ json_object_double_add(json_obj, buf, fval1);
+ json_object_array_add(json_bw, json_obj);
+ json_obj = json_object_new_object();
+ snprintfrr(buf, 12, "classType-%u", i + 1);
+ json_object_double_add(json_obj, buf, fval2);
+ json_object_array_add(json_bw, json_obj);
+ }
else
zlog_debug(
" [%d]: %g (Bytes/sec), [%d]: %g (Bytes/sec)",
@@ -3403,7 +3486,8 @@ static uint16_t show_vty_link_subtlv_unrsv_bw(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_rsc_clsclr(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_rsc_clsclr *top;
@@ -3411,8 +3495,13 @@ static uint16_t show_vty_link_subtlv_rsc_clsclr(struct vty *vty,
top = (struct te_link_subtlv_rsc_clsclr *)tlvh;
if (vty != NULL)
- vty_out(vty, " Resource class/color: 0x%x\n",
- (uint32_t)ntohl(top->value));
+ if (!json)
+ vty_out(vty, " Resource class/color: 0x%x\n",
+ (uint32_t)ntohl(top->value));
+ else
+ json_object_string_addf(json, "administrativeGroup",
+ "0x%x",
+ (uint32_t)ntohl(top->value));
else
zlog_debug(" Resource Class/Color: 0x%x",
(uint32_t)ntohl(top->value));
@@ -3421,7 +3510,8 @@ static uint16_t show_vty_link_subtlv_rsc_clsclr(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_lrrid(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_lrrid *top;
@@ -3430,10 +3520,17 @@ static uint16_t show_vty_link_subtlv_lrrid(struct vty *vty,
top = (struct te_link_subtlv_lrrid *)tlvh;
if (vty != NULL) {
- vty_out(vty, " Local TE Router ID: %pI4\n",
- &top->local);
- vty_out(vty, " Remote TE Router ID: %pI4\n",
- &top->remote);
+ if (!json) {
+ vty_out(vty, " Local TE Router ID: %pI4\n",
+ &top->local);
+ vty_out(vty, " Remote TE Router ID: %pI4\n",
+ &top->remote);
+ } else {
+ json_object_string_addf(json, "localTeRouterID", "%pI4",
+ &top->local);
+ json_object_string_addf(json, "remoteTeRouterID",
+ "%pI4", &top->remote);
+ }
} else {
zlog_debug(" Local TE Router ID: %pI4",
&top->local);
@@ -3445,7 +3542,8 @@ static uint16_t show_vty_link_subtlv_lrrid(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_llri(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_llri *top;
@@ -3454,10 +3552,17 @@ static uint16_t show_vty_link_subtlv_llri(struct vty *vty,
top = (struct te_link_subtlv_llri *)tlvh;
if (vty != NULL) {
- vty_out(vty, " Link Local ID: %d\n",
- (uint32_t)ntohl(top->local));
- vty_out(vty, " Link Remote ID: %d\n",
- (uint32_t)ntohl(top->remote));
+ if (!json) {
+ vty_out(vty, " Link Local ID: %d\n",
+ (uint32_t)ntohl(top->local));
+ vty_out(vty, " Link Remote ID: %d\n",
+ (uint32_t)ntohl(top->remote));
+ } else {
+ json_object_int_add(json, "localLinkID",
+ (uint32_t)ntohl(top->local));
+ json_object_int_add(json, "remoteLinkID",
+ (uint32_t)ntohl(top->remote));
+ }
} else {
zlog_debug(" Link Local ID: %d",
(uint32_t)ntohl(top->local));
@@ -3469,7 +3574,8 @@ static uint16_t show_vty_link_subtlv_llri(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_rip(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_rip *top;
@@ -3478,8 +3584,12 @@ static uint16_t show_vty_link_subtlv_rip(struct vty *vty,
top = (struct te_link_subtlv_rip *)tlvh;
if (vty != NULL)
- vty_out(vty, " Inter-AS TE Remote ASBR IP address: %pI4\n",
- &top->value);
+ if (!json)
+ vty_out(vty, " Inter-AS TE Remote ASBR IP address: %pI4\n",
+ &top->value);
+ else
+ json_object_string_addf(json, "remoteAsbrAddress",
+ "%pI4", &top->value);
else
zlog_debug(" Inter-AS TE Remote ASBR IP address: %pI4",
&top->value);
@@ -3488,7 +3598,8 @@ static uint16_t show_vty_link_subtlv_rip(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_ras(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_ras *top;
@@ -3497,8 +3608,12 @@ static uint16_t show_vty_link_subtlv_ras(struct vty *vty,
top = (struct te_link_subtlv_ras *)tlvh;
if (vty != NULL)
- vty_out(vty, " Inter-AS TE Remote AS number: %u\n",
- ntohl(top->value));
+ if (!json)
+ vty_out(vty, " Inter-AS TE Remote AS number: %u\n",
+ ntohl(top->value));
+ else
+ json_object_int_add(json, "remoteAsbrNumber",
+ ntohl(top->value));
else
zlog_debug(" Inter-AS TE Remote AS number: %u",
ntohl(top->value));
@@ -3507,7 +3622,8 @@ static uint16_t show_vty_link_subtlv_ras(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_av_delay(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_av_delay *top;
uint32_t delay;
@@ -3520,8 +3636,15 @@ static uint16_t show_vty_link_subtlv_av_delay(struct vty *vty,
anomalous = (uint32_t)ntohl(top->value) & TE_EXT_ANORMAL;
if (vty != NULL)
- vty_out(vty, " %s Average Link Delay: %d (micro-sec)\n",
- anomalous ? "Anomalous" : "Normal", delay);
+ if (!json)
+ vty_out(vty, " %s Average Link Delay: %d (micro-sec)\n",
+ anomalous ? "Anomalous" : "Normal", delay);
+ else {
+ json_object_int_add(json, "oneWayDelay", delay);
+ json_object_string_add(json, "oneWayDelayNormality",
+ anomalous ? "abnormal"
+ : "normal");
+ }
else
zlog_debug(" %s Average Link Delay: %d (micro-sec)",
anomalous ? "Anomalous" : "Normal", delay);
@@ -3530,7 +3653,8 @@ static uint16_t show_vty_link_subtlv_av_delay(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_mm_delay(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_mm_delay *top;
uint32_t low, high;
@@ -3544,8 +3668,20 @@ static uint16_t show_vty_link_subtlv_mm_delay(struct vty *vty,
high = (uint32_t)ntohl(top->high);
if (vty != NULL)
- vty_out(vty, " %s Min/Max Link Delay: %d/%d (micro-sec)\n",
- anomalous ? "Anomalous" : "Normal", low, high);
+ if (!json)
+ vty_out(vty,
+ " %s Min/Max Link Delay: %d/%d (micro-sec)\n",
+ anomalous ? "Anomalous" : "Normal", low, high);
+ else {
+ json_object_int_add(json, "oneWayMinDelay", low);
+ json_object_string_add(json, "oneWayMinDelayNormality",
+ anomalous ? "abnormal"
+ : "normal");
+ json_object_int_add(json, "oneWayMaxDelay", high);
+ json_object_string_add(json, "oneWayMaxDelayNormality",
+ anomalous ? "abnormal"
+ : "normal");
+ }
else
zlog_debug(" %s Min/Max Link Delay: %d/%d (micro-sec)",
anomalous ? "Anomalous" : "Normal", low, high);
@@ -3554,7 +3690,8 @@ static uint16_t show_vty_link_subtlv_mm_delay(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_delay_var(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_delay_var *top;
uint32_t jitter;
@@ -3565,7 +3702,12 @@ static uint16_t show_vty_link_subtlv_delay_var(struct vty *vty,
jitter = (uint32_t)ntohl(top->value) & TE_EXT_MASK;
if (vty != NULL)
- vty_out(vty, " Delay Variation: %d (micro-sec)\n", jitter);
+ if (!json)
+ vty_out(vty, " Delay Variation: %d (micro-sec)\n",
+ jitter);
+ else
+ json_object_int_add(json, "oneWayDelayVariation",
+ jitter);
else
zlog_debug(" Delay Variation: %d (micro-sec)", jitter);
@@ -3573,7 +3715,8 @@ static uint16_t show_vty_link_subtlv_delay_var(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_pkt_loss(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_pkt_loss *top;
uint32_t loss;
@@ -3588,8 +3731,16 @@ static uint16_t show_vty_link_subtlv_pkt_loss(struct vty *vty,
anomalous = (uint32_t)ntohl(top->value) & TE_EXT_ANORMAL;
if (vty != NULL)
- vty_out(vty, " %s Link Loss: %g (%%)\n",
- anomalous ? "Anomalous" : "Normal", fval);
+ if (!json)
+ vty_out(vty, " %s Link Loss: %g (%%)\n",
+ anomalous ? "Anomalous" : "Normal", fval);
+ else {
+ json_object_double_add(json, "oneWayPacketLoss", fval);
+ json_object_string_add(json,
+ "oneWayPacketLossNormality",
+ anomalous ? "abnormal"
+ : "normal");
+ }
else
zlog_debug(" %s Link Loss: %g (%%)",
anomalous ? "Anomalous" : "Normal", fval);
@@ -3598,7 +3749,8 @@ static uint16_t show_vty_link_subtlv_pkt_loss(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_res_bw(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_res_bw *top;
float fval;
@@ -3609,9 +3761,13 @@ static uint16_t show_vty_link_subtlv_res_bw(struct vty *vty,
fval = ntohf(top->value);
if (vty != NULL)
- vty_out(vty,
- " Unidirectional Residual Bandwidth: %g (Bytes/sec)\n",
- fval);
+ if (!json)
+ vty_out(vty,
+ " Unidirectional Residual Bandwidth: %g (Bytes/sec)\n",
+ fval);
+ else
+ json_object_double_add(json, "oneWayResidualBandwidth",
+ fval);
else
zlog_debug(
" Unidirectional Residual Bandwidth: %g (Bytes/sec)",
@@ -3621,7 +3777,8 @@ static uint16_t show_vty_link_subtlv_res_bw(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_ava_bw(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_ava_bw *top;
float fval;
@@ -3632,9 +3789,13 @@ static uint16_t show_vty_link_subtlv_ava_bw(struct vty *vty,
fval = ntohf(top->value);
if (vty != NULL)
- vty_out(vty,
- " Unidirectional Available Bandwidth: %g (Bytes/sec)\n",
- fval);
+ if (!json)
+ vty_out(vty,
+ " Unidirectional Available Bandwidth: %g (Bytes/sec)\n",
+ fval);
+ else
+ json_object_double_add(json, "oneWayAvailableBandwidth",
+ fval);
else
zlog_debug(
" Unidirectional Available Bandwidth: %g (Bytes/sec)",
@@ -3644,7 +3805,8 @@ static uint16_t show_vty_link_subtlv_ava_bw(struct vty *vty,
}
static uint16_t show_vty_link_subtlv_use_bw(struct vty *vty,
- struct tlv_header *tlvh)
+ struct tlv_header *tlvh,
+ json_object *json)
{
struct te_link_subtlv_use_bw *top;
float fval;
@@ -3655,9 +3817,13 @@ static uint16_t show_vty_link_subtlv_use_bw(struct vty *vty,
fval = ntohf(top->value);
if (vty != NULL)
- vty_out(vty,
- " Unidirectional Utilized Bandwidth: %g (Bytes/sec)\n",
- fval);
+ if (!json)
+ vty_out(vty,
+ " Unidirectional Utilized Bandwidth: %g (Bytes/sec)\n",
+ fval);
+ else
+ json_object_double_add(json, "oneWayUtilizedBandwidth",
+ fval);
else
zlog_debug(
" Unidirectional Utilized Bandwidth: %g (Bytes/sec)",
@@ -3667,8 +3833,10 @@ static uint16_t show_vty_link_subtlv_use_bw(struct vty *vty,
}
static uint16_t show_vty_unknown_tlv(struct vty *vty, struct tlv_header *tlvh,
- size_t buf_size)
+ size_t buf_size, json_object *json)
{
+ json_object *obj;
+
if (TLV_SIZE(tlvh) > buf_size) {
if (vty != NULL)
vty_out(vty,
@@ -3682,8 +3850,17 @@ static uint16_t show_vty_unknown_tlv(struct vty *vty, struct tlv_header *tlvh,
}
if (vty != NULL)
- vty_out(vty, " Unknown TLV: [type(0x%x), length(0x%x)]\n",
- ntohs(tlvh->type), ntohs(tlvh->length));
+ if (!json)
+ vty_out(vty, " Unknown TLV: [type(0x%x), length(0x%x)]\n",
+ ntohs(tlvh->type), ntohs(tlvh->length));
+ else {
+ obj = json_object_new_object();
+ json_object_string_addf(obj, "type", "0x%x",
+ ntohs(tlvh->type));
+ json_object_string_addf(obj, "length", "0x%x",
+ ntohs(tlvh->length));
+ json_object_object_add(json, "unknownTLV", obj);
+ }
else
zlog_debug(" Unknown TLV: [type(0x%x), length(0x%x)]",
ntohs(tlvh->type), ntohs(tlvh->length));
@@ -3693,7 +3870,8 @@ static uint16_t show_vty_unknown_tlv(struct vty *vty, struct tlv_header *tlvh,
static uint16_t ospf_mpls_te_show_link_subtlv(struct vty *vty,
struct tlv_header *tlvh0,
- uint16_t subtotal, uint16_t total)
+ uint16_t subtotal, uint16_t total,
+ json_object *json)
{
struct tlv_header *tlvh;
uint16_t sum = subtotal;
@@ -3701,69 +3879,72 @@ static uint16_t ospf_mpls_te_show_link_subtlv(struct vty *vty,
for (tlvh = tlvh0; sum < total; tlvh = TLV_HDR_NEXT(tlvh)) {
switch (ntohs(tlvh->type)) {
case TE_LINK_SUBTLV_LINK_TYPE:
- sum += show_vty_link_subtlv_link_type(vty, tlvh);
+ sum += show_vty_link_subtlv_link_type(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_LINK_ID:
- sum += show_vty_link_subtlv_link_id(vty, tlvh);
+ sum += show_vty_link_subtlv_link_id(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_LCLIF_IPADDR:
sum += show_vty_link_subtlv_lclif_ipaddr(vty, tlvh,
- total - sum);
+ total - sum,
+ json);
break;
case TE_LINK_SUBTLV_RMTIF_IPADDR:
sum += show_vty_link_subtlv_rmtif_ipaddr(vty, tlvh,
- total - sum);
+ total - sum,
+ json);
break;
case TE_LINK_SUBTLV_TE_METRIC:
- sum += show_vty_link_subtlv_te_metric(vty, tlvh);
+ sum += show_vty_link_subtlv_te_metric(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_MAX_BW:
- sum += show_vty_link_subtlv_max_bw(vty, tlvh);
+ sum += show_vty_link_subtlv_max_bw(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_MAX_RSV_BW:
- sum += show_vty_link_subtlv_max_rsv_bw(vty, tlvh);
+ sum += show_vty_link_subtlv_max_rsv_bw(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_UNRSV_BW:
- sum += show_vty_link_subtlv_unrsv_bw(vty, tlvh);
+ sum += show_vty_link_subtlv_unrsv_bw(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_RSC_CLSCLR:
- sum += show_vty_link_subtlv_rsc_clsclr(vty, tlvh);
+ sum += show_vty_link_subtlv_rsc_clsclr(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_LRRID:
- sum += show_vty_link_subtlv_lrrid(vty, tlvh);
+ sum += show_vty_link_subtlv_lrrid(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_LLRI:
- sum += show_vty_link_subtlv_llri(vty, tlvh);
+ sum += show_vty_link_subtlv_llri(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_RIP:
- sum += show_vty_link_subtlv_rip(vty, tlvh);
+ sum += show_vty_link_subtlv_rip(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_RAS:
- sum += show_vty_link_subtlv_ras(vty, tlvh);
+ sum += show_vty_link_subtlv_ras(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_AV_DELAY:
- sum += show_vty_link_subtlv_av_delay(vty, tlvh);
+ sum += show_vty_link_subtlv_av_delay(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_MM_DELAY:
- sum += show_vty_link_subtlv_mm_delay(vty, tlvh);
+ sum += show_vty_link_subtlv_mm_delay(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_DELAY_VAR:
- sum += show_vty_link_subtlv_delay_var(vty, tlvh);
+ sum += show_vty_link_subtlv_delay_var(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_PKT_LOSS:
- sum += show_vty_link_subtlv_pkt_loss(vty, tlvh);
+ sum += show_vty_link_subtlv_pkt_loss(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_RES_BW:
- sum += show_vty_link_subtlv_res_bw(vty, tlvh);
+ sum += show_vty_link_subtlv_res_bw(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_AVA_BW:
- sum += show_vty_link_subtlv_ava_bw(vty, tlvh);
+ sum += show_vty_link_subtlv_ava_bw(vty, tlvh, json);
break;
case TE_LINK_SUBTLV_USE_BW:
- sum += show_vty_link_subtlv_use_bw(vty, tlvh);
+ sum += show_vty_link_subtlv_use_bw(vty, tlvh, json);
break;
default:
- sum += show_vty_unknown_tlv(vty, tlvh, total - sum);
+ sum += show_vty_unknown_tlv(vty, tlvh, total - sum,
+ json);
break;
}
}
@@ -3775,37 +3956,47 @@ static void ospf_mpls_te_show_info(struct vty *vty, struct json_object *json,
{
struct lsa_header *lsah = lsa->data;
struct tlv_header *tlvh, *next;
- uint16_t sum, total;
+ uint16_t sum, sub, total;
uint16_t (*subfunc)(struct vty * vty, struct tlv_header * tlvh,
- uint16_t subtotal, uint16_t total) = NULL;
-
- if (json)
- return;
+ uint16_t subtotal, uint16_t total,
+ struct json_object *json) = NULL;
+ json_object *jobj = NULL;
sum = 0;
+ sub = 0;
total = lsa->size - OSPF_LSA_HEADER_SIZE;
for (tlvh = TLV_HDR_TOP(lsah); sum < total && tlvh;
tlvh = (next ? next : TLV_HDR_NEXT(tlvh))) {
if (subfunc != NULL) {
- sum = (*subfunc)(vty, tlvh, sum, total);
+ sum = (*subfunc)(vty, tlvh, sum, total, jobj);
next = (struct tlv_header *)((char *)tlvh + sum);
subfunc = NULL;
continue;
}
next = NULL;
+ sub = total - sum;
switch (ntohs(tlvh->type)) {
case TE_TLV_ROUTER_ADDR:
- sum += show_vty_router_addr(vty, tlvh);
+ if (json) {
+ jobj = json_object_new_object();
+ json_object_object_add(json, "teRouterAddress",
+ jobj);
+ }
+ sum += show_vty_router_addr(vty, tlvh, jobj);
break;
case TE_TLV_LINK:
- sum += show_vty_link_header(vty, tlvh, total - sum);
+ if (json) {
+ jobj = json_object_new_object();
+ json_object_object_add(json, "teLink", jobj);
+ }
+ sum += show_vty_link_header(vty, tlvh, sub, jobj);
subfunc = ospf_mpls_te_show_link_subtlv;
next = TLV_DATA(tlvh);
break;
default:
- sum += show_vty_unknown_tlv(vty, tlvh, total - sum);
+ sum += show_vty_unknown_tlv(vty, tlvh, sub, json);
break;
}
}
@@ -4139,7 +4330,8 @@ DEFUN (show_ip_ospf_mpls_te_router,
if (ntohs(OspfMplsTE.router_addr.header.type) != 0)
show_vty_router_addr(vty,
- &OspfMplsTE.router_addr.header);
+ &OspfMplsTE.router_addr.header,
+ NULL);
else
vty_out(vty, " Router address is not set\n");
vty_out(vty, " Link State distribution is %s\n",
@@ -4148,7 +4340,8 @@ DEFUN (show_ip_ospf_mpls_te_router,
return CMD_SUCCESS;
}
-static void show_mpls_te_link_sub(struct vty *vty, struct interface *ifp)
+static void show_mpls_te_link_sub(struct vty *vty, struct interface *ifp,
+ json_object *json)
{
struct mpls_te_link *lp;
@@ -4178,53 +4371,69 @@ static void show_mpls_te_link_sub(struct vty *vty, struct interface *ifp)
if (TLV_TYPE(lp->link_type) != 0)
show_vty_link_subtlv_link_type(vty,
- &lp->link_type.header);
+ &lp->link_type.header,
+ json);
if (TLV_TYPE(lp->link_id) != 0)
- show_vty_link_subtlv_link_id(vty, &lp->link_id.header);
+ show_vty_link_subtlv_link_id(vty, &lp->link_id.header,
+ json);
if (TLV_TYPE(lp->lclif_ipaddr) != 0)
show_vty_link_subtlv_lclif_ipaddr(
vty, &lp->lclif_ipaddr.header,
- lp->lclif_ipaddr.header.length);
+ lp->lclif_ipaddr.header.length,
+ json);
if (TLV_TYPE(lp->rmtif_ipaddr) != 0)
show_vty_link_subtlv_rmtif_ipaddr(
vty, &lp->rmtif_ipaddr.header,
- lp->rmtif_ipaddr.header.length);
+ lp->rmtif_ipaddr.header.length,
+ json);
if (TLV_TYPE(lp->rip) != 0)
- show_vty_link_subtlv_rip(vty, &lp->rip.header);
+ show_vty_link_subtlv_rip(vty, &lp->rip.header, json);
if (TLV_TYPE(lp->ras) != 0)
- show_vty_link_subtlv_ras(vty, &lp->ras.header);
+ show_vty_link_subtlv_ras(vty, &lp->ras.header, json);
if (TLV_TYPE(lp->te_metric) != 0)
show_vty_link_subtlv_te_metric(vty,
- &lp->te_metric.header);
+ &lp->te_metric.header,
+ json);
if (TLV_TYPE(lp->max_bw) != 0)
- show_vty_link_subtlv_max_bw(vty, &lp->max_bw.header);
+ show_vty_link_subtlv_max_bw(vty, &lp->max_bw.header,
+ json);
if (TLV_TYPE(lp->max_rsv_bw) != 0)
show_vty_link_subtlv_max_rsv_bw(vty,
- &lp->max_rsv_bw.header);
+ &lp->max_rsv_bw.header,
+ json);
if (TLV_TYPE(lp->unrsv_bw) != 0)
show_vty_link_subtlv_unrsv_bw(vty,
- &lp->unrsv_bw.header);
+ &lp->unrsv_bw.header,
+ json);
if (TLV_TYPE(lp->rsc_clsclr) != 0)
show_vty_link_subtlv_rsc_clsclr(vty,
- &lp->rsc_clsclr.header);
+ &lp->rsc_clsclr.header,
+ json);
if (TLV_TYPE(lp->av_delay) != 0)
show_vty_link_subtlv_av_delay(vty,
- &lp->av_delay.header);
+ &lp->av_delay.header,
+ json);
if (TLV_TYPE(lp->mm_delay) != 0)
show_vty_link_subtlv_mm_delay(vty,
- &lp->mm_delay.header);
+ &lp->mm_delay.header,
+ json);
if (TLV_TYPE(lp->delay_var) != 0)
show_vty_link_subtlv_delay_var(vty,
- &lp->delay_var.header);
+ &lp->delay_var.header,
+ json);
if (TLV_TYPE(lp->pkt_loss) != 0)
show_vty_link_subtlv_pkt_loss(vty,
- &lp->pkt_loss.header);
+ &lp->pkt_loss.header,
+ json);
if (TLV_TYPE(lp->res_bw) != 0)
- show_vty_link_subtlv_res_bw(vty, &lp->res_bw.header);
+ show_vty_link_subtlv_res_bw(vty, &lp->res_bw.header,
+ json);
if (TLV_TYPE(lp->ava_bw) != 0)
- show_vty_link_subtlv_ava_bw(vty, &lp->ava_bw.header);
+ show_vty_link_subtlv_ava_bw(vty, &lp->ava_bw.header,
+ json);
if (TLV_TYPE(lp->use_bw) != 0)
- show_vty_link_subtlv_use_bw(vty, &lp->use_bw.header);
+ show_vty_link_subtlv_use_bw(vty, &lp->use_bw.header,
+ json);
vty_out(vty, "---------------\n\n");
} else {
vty_out(vty, " %s: MPLS-TE is disabled on this interface\n",
@@ -4253,7 +4462,6 @@ DEFUN (show_ip_ospf_mpls_te_link,
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL || !ospf->oi_running)
return CMD_SUCCESS;
-
vrf = vrf_lookup_by_id(VRF_DEFAULT);
if (!vrf)
return CMD_SUCCESS;
@@ -4267,11 +4475,11 @@ DEFUN (show_ip_ospf_mpls_te_link,
}
if (!ifp) {
FOR_ALL_INTERFACES (vrf, ifp)
- show_mpls_te_link_sub(vty, ifp);
+ show_mpls_te_link_sub(vty, ifp, NULL);
return CMD_SUCCESS;
}
- show_mpls_te_link_sub(vty, ifp);
+ show_mpls_te_link_sub(vty, ifp, NULL);
return CMD_SUCCESS;
}
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index 355742a..93dd12c 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -22,6 +22,7 @@
#include "defaults.h"
#include "lib/printfrr.h"
#include "keychain.h"
+#include "frrdistance.h"
#include "ospfd/ospfd.h"
#include "ospfd/ospf_asbr.h"
@@ -1871,7 +1872,7 @@ DEFUN (no_ospf_area_import_list,
DEFUN (ospf_area_filter_list,
ospf_area_filter_list_cmd,
- "area <A.B.C.D|(0-4294967295)> filter-list prefix PREFIXLIST_NAME <in|out>",
+ "area <A.B.C.D|(0-4294967295)> filter-list prefix PREFIXLIST4_NAME <in|out>",
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n"
@@ -1916,7 +1917,7 @@ DEFUN (ospf_area_filter_list,
DEFUN (no_ospf_area_filter_list,
no_ospf_area_filter_list_cmd,
- "no area <A.B.C.D|(0-4294967295)> filter-list prefix PREFIXLIST_NAME <in|out>",
+ "no area <A.B.C.D|(0-4294967295)> filter-list prefix PREFIXLIST4_NAME <in|out>",
NO_STR
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
@@ -5709,7 +5710,7 @@ DEFPY(show_ip_ospf_neighbor_id,
"%% OSPF is not enabled in vrf %s\n",
vrf_name);
else
- vty_json_empty(vty);
+ vty_json_empty(vty, NULL);
return CMD_SUCCESS;
}
ret = show_ip_ospf_neighbor_id_common(
@@ -6210,7 +6211,7 @@ DEFPY(show_ip_ospf_neighbor_int,
if (!ospf || !ospf->oi_running) {
if (json)
- vty_json_empty(vty);
+ vty_json_empty(vty, NULL);
return ret;
}
@@ -6220,7 +6221,7 @@ DEFPY(show_ip_ospf_neighbor_int,
ifp = if_lookup_by_name(ifname, vrf_id);
if (!ifp) {
if (json)
- vty_json_empty(vty);
+ vty_json_empty(vty, NULL);
else
vty_out(vty, "No such interface.\n");
return ret;
@@ -6257,7 +6258,7 @@ DEFPY(show_ip_ospf_neighbor_int_detail,
"%% OSPF is not enabled in vrf %s\n",
vrf_name);
else
- vty_json_empty(vty);
+ vty_json_empty(vty, NULL);
return CMD_SUCCESS;
}
return show_ip_ospf_neighbor_int_detail_common(
@@ -8301,7 +8302,7 @@ DEFUN_HIDDEN (ospf_dead_interval,
DEFUN (ip_ospf_dead_interval_minimal,
ip_ospf_dead_interval_minimal_addr_cmd,
- "ip ospf dead-interval minimal hello-multiplier (1-10) [A.B.C.D]",
+ "ip ospf dead-interval minimal hello-multiplier (2-20) [A.B.C.D]",
"IP Information\n"
"OSPF interface commands\n"
"Interval time after which a neighbor is declared down\n"
@@ -8322,7 +8323,7 @@ DEFUN (ip_ospf_dead_interval_minimal,
DEFUN (no_ip_ospf_dead_interval,
no_ip_ospf_dead_interval_cmd,
- "no ip ospf dead-interval [<(1-65535)|minimal hello-multiplier (1-10)> [A.B.C.D]]",
+ "no ip ospf dead-interval [<(1-65535)|minimal hello-multiplier (2-20)> [A.B.C.D]]",
NO_STR
"IP Information\n"
"OSPF interface commands\n"
@@ -8389,7 +8390,7 @@ DEFUN (no_ip_ospf_dead_interval,
DEFUN_HIDDEN (no_ospf_dead_interval,
no_ospf_dead_interval_cmd,
- "no ospf dead-interval [<(1-65535)|minimal hello-multiplier (1-10)> [A.B.C.D]]",
+ "no ospf dead-interval [<(1-65535)|minimal hello-multiplier (2-20)> [A.B.C.D]]",
NO_STR
"OSPF interface commands\n"
"Interval time after which a neighbor is declared down\n"
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index 1af703d..bb6cc3a 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -1487,30 +1487,20 @@ void ospf_zebra_import_default_route(struct ospf *ospf, bool unreg)
__func__);
}
-static int ospf_zebra_import_check_update(ZAPI_CALLBACK_ARGS)
+static void ospf_zebra_import_check_update(struct vrf *vrf, struct prefix *match,
+ struct zapi_route *nhr)
{
- struct ospf *ospf;
- struct zapi_route nhr;
- struct prefix matched;
+ struct ospf *ospf = vrf->info;
- ospf = ospf_lookup_by_vrf_id(vrf_id);
if (ospf == NULL || !IS_OSPF_ASBR(ospf))
- return 0;
-
- if (!zapi_nexthop_update_decode(zclient->ibuf, &matched, &nhr)) {
- zlog_err("%s[%u]: Failure to decode route", __func__,
- ospf->vrf_id);
- return -1;
- }
+ return;
- if (matched.family != AF_INET || matched.prefixlen != 0 ||
- nhr.type == ZEBRA_ROUTE_OSPF)
- return 0;
+ if (match->family != AF_INET || match->prefixlen != 0 ||
+ nhr->type == ZEBRA_ROUTE_OSPF)
+ return;
- ospf->nssa_default_import_check.status = !!nhr.nexthop_num;
+ ospf->nssa_default_import_check.status = !!nhr->nexthop_num;
ospf_abr_nssa_type7_defaults(ospf);
-
- return 0;
}
int ospf_distribute_list_out_set(struct ospf *ospf, int type, const char *name)
@@ -2183,7 +2173,6 @@ static zclient_handler *const ospf_handlers[] = {
[ZEBRA_REDISTRIBUTE_ROUTE_ADD] = ospf_zebra_read_route,
[ZEBRA_REDISTRIBUTE_ROUTE_DEL] = ospf_zebra_read_route,
- [ZEBRA_NEXTHOP_UPDATE] = ospf_zebra_import_check_update,
[ZEBRA_OPAQUE_MESSAGE] = ospf_opaque_msg_handler,
@@ -2197,11 +2186,10 @@ void ospf_zebra_init(struct event_loop *master, unsigned short instance)
array_size(ospf_handlers));
zclient_init(zclient, ZEBRA_ROUTE_OSPF, instance, &ospfd_privs);
zclient->zebra_connected = ospf_zebra_connected;
+ zclient->nexthop_update = ospf_zebra_import_check_update;
/* Initialize special zclient for synchronous message exchanges. */
- struct zclient_options options = zclient_options_default;
- options.synchronous = true;
- zclient_sync = zclient_new(master, &options, NULL, 0);
+ zclient_sync = zclient_new(master, &zclient_options_sync, NULL, 0);
zclient_sync->sock = -1;
zclient_sync->redist_default = ZEBRA_ROUTE_OSPF;
zclient_sync->instance = instance;
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index 9ed1d30..4c4666d 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -575,39 +575,12 @@ static struct ospf *ospf_lookup_by_name(const char *vrf_name)
return NULL;
}
-/* Handle the second half of deferred shutdown. This is called either
- * from the deferred-shutdown timer thread, or directly through
- * ospf_deferred_shutdown_check.
- *
- * Function is to cleanup G-R state, if required then call ospf_finish_final
- * to complete shutdown of this ospf instance. Possibly exit if the
- * whole process is being shutdown and this was the last OSPF instance.
- */
-static void ospf_deferred_shutdown_finish(struct ospf *ospf)
-{
- ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
- EVENT_OFF(ospf->t_deferred_shutdown);
-
- ospf_finish_final(ospf);
-
- /* *ospf is now invalid */
-
- /* ospfd being shut-down? If so, was this the last ospf instance? */
- if (CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN)
- && (listcount(om->ospf) == 0)) {
- frr_fini();
- exit(0);
- }
-
- return;
-}
-
-/* Timer thread for G-R */
+/* Timer thread for deferred shutdown */
static void ospf_deferred_shutdown_timer(struct event *t)
{
struct ospf *ospf = EVENT_ARG(t);
- ospf_deferred_shutdown_finish(ospf);
+ ospf_finish_final(ospf);
}
/* Check whether deferred-shutdown must be scheduled, otherwise call
@@ -634,15 +607,12 @@ static void ospf_deferred_shutdown_check(struct ospf *ospf)
ospf_router_lsa_update_area(area);
}
timeout = ospf->stub_router_shutdown_time;
+ OSPF_TIMER_ON(ospf->t_deferred_shutdown,
+ ospf_deferred_shutdown_timer, timeout);
} else {
/* No timer needed */
- ospf_deferred_shutdown_finish(ospf);
- return;
+ ospf_finish_final(ospf);
}
-
- OSPF_TIMER_ON(ospf->t_deferred_shutdown, ospf_deferred_shutdown_timer,
- timeout);
- return;
}
/* Shut down the entire process */
@@ -657,10 +627,6 @@ void ospf_terminate(void)
SET_FLAG(om->options, OSPF_MASTER_SHUTDOWN);
- /* Skip some steps if OSPF not actually running */
- if (listcount(om->ospf) == 0)
- goto done;
-
for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf))
ospf_finish(ospf);
@@ -678,6 +644,11 @@ void ospf_terminate(void)
/* Cleanup vrf info */
ospf_vrf_terminate();
+ keychain_terminate();
+
+ ospf_opaque_term();
+ list_delete(&om->ospf);
+
/* Deliberately go back up, hopefully to thread scheduler, as
* One or more ospf_finish()'s may have deferred shutdown to a timer
* thread
@@ -687,20 +658,17 @@ void ospf_terminate(void)
zclient_stop(zclient_sync);
zclient_free(zclient_sync);
-done:
frr_fini();
}
void ospf_finish(struct ospf *ospf)
{
- /* let deferred shutdown decide */
- ospf_deferred_shutdown_check(ospf);
-
- /* if ospf_deferred_shutdown returns, then ospf_finish_final is
- * deferred to expiry of G-S timer thread. Return back up, hopefully
- * to thread scheduler.
- */
- return;
+ if (CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN))
+ ospf_finish_final(ospf);
+ else {
+ /* let deferred shutdown decide */
+ ospf_deferred_shutdown_check(ospf);
+ }
}
/* Final cleanup of ospf instance */
@@ -900,6 +868,7 @@ static void ospf_finish_final(struct ospf *ospf)
EVENT_OFF(ospf->t_ase_calc);
EVENT_OFF(ospf->t_maxage);
EVENT_OFF(ospf->t_maxage_walker);
+ EVENT_OFF(ospf->t_deferred_shutdown);
EVENT_OFF(ospf->t_abr_task);
EVENT_OFF(ospf->t_abr_fr);
EVENT_OFF(ospf->t_asbr_check);
@@ -1442,7 +1411,6 @@ static void ospf_network_run_interface(struct ospf *ospf, struct interface *ifp,
struct prefix *p,
struct ospf_area *given_area)
{
- struct listnode *cnode;
struct connected *co;
if (memcmp(ifp->name, "VLINK", 5) == 0)
@@ -1454,7 +1422,7 @@ static void ospf_network_run_interface(struct ospf *ospf, struct interface *ifp,
/* if interface prefix is match specified prefix,
then create socket and join multicast group. */
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, co))
+ frr_each (if_connected, ifp->connected, co)
ospf_network_run_subnet(ospf, co, p, given_area);
}
diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h
index 2ab7db1..6051dff 100644
--- a/ospfd/ospfd.h
+++ b/ospfd/ospfd.h
@@ -22,9 +22,6 @@
#define OSPF_VERSION 2
-/* VTY port number. */
-#define OSPF_VTY_PORT 2604
-
/* IP TTL for OSPF protocol. */
#define OSPF_IP_TTL 1
#define OSPF_VL_IP_TTL 100