summaryrefslogtreecommitdiff
path: root/ospfd/ospf_sr.c
diff options
context:
space:
mode:
Diffstat (limited to 'ospfd/ospf_sr.c')
-rw-r--r--ospfd/ospf_sr.c337
1 files changed, 200 insertions, 137 deletions
diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c
index 9a9e64cc23..181cc37f4f 100644
--- a/ospfd/ospf_sr.c
+++ b/ospfd/ospf_sr.c
@@ -279,17 +279,19 @@ static int sr_local_block_init(uint32_t lower_bound, uint32_t upper_bound)
*/
size = upper_bound - lower_bound + 1;
if (ospf_zebra_request_label_range(lower_bound, size)) {
- srlb->reserved = false;
+ zlog_err("SR: Error reserving SRLB [%u/%u] %u labels",
+ lower_bound, upper_bound, size);
return -1;
}
- osr_debug("SR (%s): Got new SRLB [%u/%u]", __func__, lower_bound,
- upper_bound);
+ osr_debug("SR: Got new SRLB [%u/%u], %u labels", lower_bound,
+ upper_bound, size);
/* Initialize the SRLB */
srlb->start = lower_bound;
srlb->end = upper_bound;
srlb->current = 0;
+
/* Compute the needed Used Mark number and allocate them */
srlb->max_block = size / SRLB_BLOCK_SIZE;
if ((size % SRLB_BLOCK_SIZE) != 0)
@@ -301,6 +303,31 @@ static int sr_local_block_init(uint32_t lower_bound, uint32_t upper_bound)
return 0;
}
+static int sr_global_block_init(uint32_t start, uint32_t size)
+{
+ struct sr_global_block *srgb = &OspfSR.srgb;
+
+ /* Check if already configured */
+ if (srgb->reserved)
+ return 0;
+
+ /* request chunk */
+ uint32_t end = start + size - 1;
+ if (ospf_zebra_request_label_range(start, size) < 0) {
+ zlog_err("SR: Error reserving SRGB [%u/%u], %u labels", start,
+ end, size);
+ return -1;
+ }
+
+ osr_debug("SR: Got new SRGB [%u/%u], %u labels", start, end, size);
+
+ /* success */
+ srgb->start = start;
+ srgb->size = size;
+ srgb->reserved = true;
+ return 0;
+}
+
/**
* Remove Segment Routing Local Block.
*
@@ -322,10 +349,31 @@ static void sr_local_block_delete(void)
/* Then reset SRLB structure */
if (srlb->used_mark != NULL)
XFREE(MTYPE_OSPF_SR_PARAMS, srlb->used_mark);
+
srlb->reserved = false;
}
/**
+ * Remove Segment Routing Global block
+ */
+static void sr_global_block_delete(void)
+{
+ struct sr_global_block *srgb = &OspfSR.srgb;
+
+ if (!srgb->reserved)
+ return;
+
+ osr_debug("SR (%s): Remove SRGB [%u/%u]", __func__, srgb->start,
+ srgb->start + srgb->size - 1);
+
+ ospf_zebra_release_label_range(srgb->start,
+ srgb->start + srgb->size - 1);
+
+ srgb->reserved = false;
+}
+
+
+/**
* Request a label from the Segment Routing Local Block.
*
* @return First available label on success or MPLS_INVALID_LABEL if the
@@ -337,9 +385,10 @@ mpls_label_t ospf_sr_local_block_request_label(void)
mpls_label_t label;
uint32_t index;
uint32_t pos;
+ uint32_t size = srlb->end - srlb->start + 1;
/* Check if we ran out of available labels */
- if (srlb->current >= srlb->end)
+ if (srlb->current >= size)
return MPLS_INVALID_LABEL;
/* Get first available label and mark it used */
@@ -351,7 +400,7 @@ mpls_label_t ospf_sr_local_block_request_label(void)
/* Jump to the next free position */
srlb->current++;
pos = srlb->current % SRLB_BLOCK_SIZE;
- while (srlb->current < srlb->end) {
+ while (srlb->current < size) {
if (pos == 0)
index++;
if (!((1ULL << pos) & srlb->used_mark[index]))
@@ -362,6 +411,10 @@ mpls_label_t ospf_sr_local_block_request_label(void)
}
}
+ if (srlb->current == size)
+ zlog_warn(
+ "SR: Warning, SRLB is depleted and next label request will fail");
+
return label;
}
@@ -469,16 +522,11 @@ static int ospf_sr_start(struct ospf *ospf)
* If the allocation fails, return an error to disable SR until a new
* SRLB and/or SRGB are successfully allocated.
*/
- sr_local_block_init(OspfSR.srlb.start, OspfSR.srlb.end);
- if (!OspfSR.srgb.reserved) {
- if (ospf_zebra_request_label_range(OspfSR.srgb.start,
- OspfSR.srgb.size)
- < 0) {
- OspfSR.srgb.reserved = false;
- return -1;
- } else
- OspfSR.srgb.reserved = true;
- }
+ if (sr_local_block_init(OspfSR.srlb.start, OspfSR.srlb.end) < 0)
+ return -1;
+
+ if (sr_global_block_init(OspfSR.srgb.start, OspfSR.srgb.size) < 0)
+ return -1;
/* SR is UP and ready to flood LSA */
OspfSR.status = SR_UP;
@@ -534,13 +582,10 @@ static void ospf_sr_stop(void)
/* Disable any re-attempt to connect to Label Manager */
THREAD_OFF(OspfSR.t_start_lm);
- /* Release SRGB & SRLB if active. */
- if (OspfSR.srgb.reserved) {
- ospf_zebra_release_label_range(
- OspfSR.srgb.start,
- OspfSR.srgb.start + OspfSR.srgb.size - 1);
- OspfSR.srgb.reserved = false;
- }
+ /* Release SRGB if active */
+ sr_global_block_delete();
+
+ /* Release SRLB if active */
sr_local_block_delete();
/*
@@ -581,7 +626,7 @@ int ospf_sr_init(void)
OspfSR.srgb.reserved = false;
OspfSR.srlb.start = DEFAULT_SRLB_LABEL;
- OspfSR.srlb.end = DEFAULT_SRLB_LABEL + DEFAULT_SRLB_SIZE - 1;
+ OspfSR.srlb.end = DEFAULT_SRLB_END;
OspfSR.srlb.reserved = false;
OspfSR.msd = 0;
@@ -1200,7 +1245,9 @@ static void update_ext_prefix_sid(struct sr_node *srn, struct sr_prefix *srp)
/* Search for existing Segment Prefix */
for (ALL_LIST_ELEMENTS_RO(srn->ext_prefix, node, pref))
- if (pref->instance == srp->instance) {
+ if (pref->instance == srp->instance
+ && prefix_same((struct prefix *)&srp->prefv4,
+ &pref->prefv4)) {
found = true;
break;
}
@@ -1231,9 +1278,6 @@ static void update_ext_prefix_sid(struct sr_node *srn, struct sr_prefix *srp)
/* Replace Segment Prefix */
listnode_delete(srn->ext_prefix, pref);
XFREE(MTYPE_OSPF_SR_PARAMS, pref);
- srp->srn = srn;
- IPV4_ADDR_COPY(&srp->adv_router,
- &srn->adv_router);
listnode_add(srn->ext_prefix, srp);
ospf_zebra_update_prefix_sid(srp);
} else {
@@ -2099,6 +2143,20 @@ static int ospf_sr_enabled(struct vty *vty)
return 0;
}
+/* tell if two ranges [r1_lower, r1_upper] and [r2_lower,r2_upper] overlap */
+static bool ranges_overlap(uint32_t r1_lower, uint32_t r1_upper,
+ uint32_t r2_lower, uint32_t r2_upper)
+{
+ return !((r1_upper < r2_lower) || (r1_lower > r2_upper));
+}
+
+
+/* tell if a range is valid */
+static bool sr_range_is_valid(uint32_t lower, uint32_t upper, uint32_t min_size)
+{
+ return (upper >= lower + min_size);
+}
+
/**
* Update SRGB and/or SRLB using new CLI values.
*
@@ -2136,12 +2194,8 @@ static int update_sr_blocks(uint32_t gb_lower, uint32_t gb_upper,
/* Release old SRGB if it has changed and is active. */
if (gb_changed) {
- if (OspfSR.srgb.reserved) {
- ospf_zebra_release_label_range(
- OspfSR.srgb.start,
- OspfSR.srgb.start + OspfSR.srgb.size - 1);
- OspfSR.srgb.reserved = false;
- }
+
+ sr_global_block_delete();
/* Set new SRGB values - but do not reserve yet (we need to
* release the SRLB too) */
@@ -2155,8 +2209,8 @@ static int update_sr_blocks(uint32_t gb_lower, uint32_t gb_upper,
/* Release old SRLB if it has changed and reserve new block as needed.
*/
if (lb_changed) {
- if (OspfSR.srlb.reserved)
- sr_local_block_delete();
+
+ sr_local_block_delete();
/* Set new SRLB values */
if (sr_local_block_init(lb_lower, lb_upper) < 0) {
@@ -2175,18 +2229,11 @@ static int update_sr_blocks(uint32_t gb_lower, uint32_t gb_upper,
* allocated.
*/
if (gb_changed) {
- if (ospf_zebra_request_label_range(OspfSR.srgb.start,
- OspfSR.srgb.size)
+ if (sr_global_block_init(OspfSR.srgb.start, OspfSR.srgb.size)
< 0) {
- OspfSR.srgb.reserved = false;
ospf_sr_stop();
return -1;
- } else
- OspfSR.srgb.reserved = true;
-
- osr_debug("SR(%s): Got new SRGB [%u/%u]", __func__,
- OspfSR.srgb.start,
- OspfSR.srgb.start + OspfSR.srgb.size - 1);
+ }
}
/* Update Self SR-Node */
@@ -2227,16 +2274,29 @@ DEFUN(sr_global_label_range, sr_global_label_range_cmd,
/* Get lower and upper bound for mandatory global-block */
gb_lower = strtoul(argv[idx_gb_low]->arg, NULL, 10);
gb_upper = strtoul(argv[idx_gb_up]->arg, NULL, 10);
+
/* SRLB values are taken from vtysh if there, else use the known ones */
lb_upper = argc > idx_lb_up ? strtoul(argv[idx_lb_up]->arg, NULL, 10)
: OspfSR.srlb.end;
lb_lower = argc > idx_lb_low ? strtoul(argv[idx_lb_low]->arg, NULL, 10)
: OspfSR.srlb.start;
+ /* check correctness of input SRGB */
+ if (!sr_range_is_valid(gb_lower, gb_upper, MIN_SRGB_SIZE)) {
+ vty_out(vty, "Invalid SRGB range\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ /* check correctness of SRLB */
+ if (!sr_range_is_valid(lb_lower, lb_upper, MIN_SRLB_SIZE)) {
+ vty_out(vty, "Invalid SRLB range\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
/* Validate SRGB against SRLB */
- if (!((gb_upper < lb_lower) || (gb_lower > lb_upper))) {
+ if (ranges_overlap(gb_lower, gb_upper, lb_lower, lb_upper)) {
vty_out(vty,
- "New SR Global Block (%u/%u) conflict with Local Block (%u/%u)\n",
+ "New SR Global Block (%u/%u) conflicts with Local Block (%u/%u)\n",
gb_lower, gb_upper, lb_lower, lb_upper);
return CMD_WARNING_CONFIG_FAILED;
}
@@ -2287,6 +2347,12 @@ DEFUN_HIDDEN(sr_local_label_range, sr_local_label_range_cmd,
lower = strtoul(argv[idx_low]->arg, NULL, 10);
upper = strtoul(argv[idx_up]->arg, NULL, 10);
+ /* check correctness of SRLB */
+ if (!sr_range_is_valid(lower, upper, MIN_SRLB_SIZE)) {
+ vty_out(vty, "Invalid SRLB range\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
/* Check if values have changed */
if ((OspfSR.srlb.start == lower)
&& (OspfSR.srlb.end == upper))
@@ -2294,9 +2360,10 @@ DEFUN_HIDDEN(sr_local_label_range, sr_local_label_range_cmd,
/* Validate SRLB against SRGB */
srgb_upper = OspfSR.srgb.start + OspfSR.srgb.size - 1;
- if (!((upper < OspfSR.srgb.start) || (lower > srgb_upper))) {
+
+ if (ranges_overlap(OspfSR.srgb.start, srgb_upper, lower, upper)) {
vty_out(vty,
- "New SR Local Block (%u/%u) conflict with Global Block (%u/%u)\n",
+ "New SR Local Block (%u/%u) conflicts with Global Block (%u/%u)\n",
lower, upper, OspfSR.srgb.start, srgb_upper);
return CMD_WARNING_CONFIG_FAILED;
}
@@ -2319,10 +2386,10 @@ DEFUN_HIDDEN(no_sr_local_label_range, no_sr_local_label_range_cmd,
/* Validate SRLB against SRGB */
srgb_end = OspfSR.srgb.start + OspfSR.srgb.size - 1;
- if (!((DEFAULT_SRLB_END < OspfSR.srgb.start)
- || (DEFAULT_SRLB_LABEL > srgb_end))) {
+ if (ranges_overlap(OspfSR.srgb.start, srgb_end, DEFAULT_SRLB_LABEL,
+ DEFAULT_SRLB_END)) {
vty_out(vty,
- "New SR Local Block (%u/%u) conflict with Global Block (%u/%u)\n",
+ "New SR Local Block (%u/%u) conflicts with Global Block (%u/%u)\n",
DEFAULT_SRLB_LABEL, DEFAULT_SRLB_END, OspfSR.srgb.start,
srgb_end);
return CMD_WARNING_CONFIG_FAILED;
@@ -2412,11 +2479,15 @@ DEFUN (sr_prefix_sid,
"Upstream neighbor must replace prefix-sid with explicit null label\n")
{
int idx = 0;
- struct prefix p;
+ struct prefix p, pexist;
uint32_t index;
struct listnode *node;
- struct sr_prefix *srp, *new = NULL;
+ struct sr_prefix *srp, *exist = NULL;
struct interface *ifp;
+ bool no_php_flag = false;
+ bool exp_null = false;
+ bool index_in_use = false;
+ uint8_t desired_flags = 0;
if (!ospf_sr_enabled(vty))
return CMD_WARNING_CONFIG_FAILED;
@@ -2437,53 +2508,67 @@ DEFUN (sr_prefix_sid,
return CMD_WARNING_CONFIG_FAILED;
}
+ /* Get options */
+ no_php_flag = argv_find(argv, argc, "no-php-flag", &idx);
+ exp_null = argv_find(argv, argc, "explicit-null", &idx);
+
+ desired_flags |= no_php_flag ? EXT_SUBTLV_PREFIX_SID_NPFLG : 0;
+ desired_flags |= exp_null ? EXT_SUBTLV_PREFIX_SID_NPFLG : 0;
+ desired_flags |= exp_null ? EXT_SUBTLV_PREFIX_SID_EFLG : 0;
+
/* Search for an existing Prefix-SID */
for (ALL_LIST_ELEMENTS_RO(OspfSR.self->ext_prefix, node, srp)) {
+ if (prefix_same((struct prefix *)&srp->prefv4, &p))
+ exist = srp;
if (srp->sid == index) {
- if (prefix_same((struct prefix *)&srp->prefv4, &p)) {
- new = srp;
- break;
- } else {
- vty_out(vty, "Index %u is already used\n",
- index);
- return CMD_WARNING_CONFIG_FAILED;
- }
+ index_in_use = true;
+ pexist = p;
}
}
- /* Create new Extended Prefix to SRDB if not found */
- if (new == NULL) {
- new = XCALLOC(MTYPE_OSPF_SR_PARAMS, sizeof(struct sr_prefix));
- IPV4_ADDR_COPY(&new->prefv4.prefix, &p.u.prefix4);
- new->prefv4.prefixlen = p.prefixlen;
- new->prefv4.family = p.family;
- new->sid = index;
- new->type = LOCAL_SID;
+ /* done if prefix segment already there with same index and flags */
+ if (exist && exist->sid == index && exist->flags == desired_flags)
+ return CMD_SUCCESS;
+
+ /* deny if index is already in use by a distinct prefix */
+ if (!exist && index_in_use) {
+ vty_out(vty, "Index %u is already used by %pFX\n", index,
+ &pexist);
+ return CMD_WARNING_CONFIG_FAILED;
}
/* First, remove old NHLFE if installed */
- if (srp == new && CHECK_FLAG(srp->flags, EXT_SUBTLV_PREFIX_SID_NPFLG)
- && !CHECK_FLAG(srp->flags, EXT_SUBTLV_PREFIX_SID_EFLG))
- ospf_zebra_delete_prefix_sid(srp);
- /* Then, reset Flag & labels to handle flag update */
- new->flags = 0;
- new->label_in = 0;
- new->nhlfe.label_out = 0;
+ if (exist && CHECK_FLAG(exist->flags, EXT_SUBTLV_PREFIX_SID_NPFLG)
+ && !CHECK_FLAG(exist->flags, EXT_SUBTLV_PREFIX_SID_EFLG))
+ ospf_zebra_delete_prefix_sid(exist);
- /* Set NO PHP flag if present and compute NHLFE */
- if (argv_find(argv, argc, "no-php-flag", &idx)) {
- SET_FLAG(new->flags, EXT_SUBTLV_PREFIX_SID_NPFLG);
- new->label_in = index2label(new->sid, OspfSR.self->srgb);
- new->nhlfe.label_out = MPLS_LABEL_IMPLICIT_NULL;
+ /* Create new Extended Prefix to SRDB if not found */
+ if (exist == NULL) {
+ srp = XCALLOC(MTYPE_OSPF_SR_PARAMS, sizeof(struct sr_prefix));
+ IPV4_ADDR_COPY(&srp->prefv4.prefix, &p.u.prefix4);
+ srp->prefv4.prefixlen = p.prefixlen;
+ srp->prefv4.family = p.family;
+ srp->sid = index;
+ srp->type = LOCAL_SID;
+ } else {
+ /* we work on the existing SR prefix */
+ srp = exist;
}
- /* Set EXPLICIT NULL flag is present */
- if (argv_find(argv, argc, "explicit-null", &idx)) {
- SET_FLAG(new->flags, EXT_SUBTLV_PREFIX_SID_NPFLG);
- SET_FLAG(new->flags, EXT_SUBTLV_PREFIX_SID_EFLG);
+
+ /* Reset labels to handle flag update */
+ srp->label_in = 0;
+ srp->nhlfe.label_out = 0;
+ srp->sid = index;
+ srp->flags = desired_flags;
+
+ /* If NO PHP flag is present, compute NHLFE and set label */
+ if (no_php_flag) {
+ srp->label_in = index2label(srp->sid, OspfSR.self->srgb);
+ srp->nhlfe.label_out = MPLS_LABEL_IMPLICIT_NULL;
}
osr_debug("SR (%s): Add new index %u to Prefix %pFX", __func__, index,
- (struct prefix *)&new->prefv4);
+ (struct prefix *)&srp->prefv4);
/* Get Interface and check if it is a Loopback */
ifp = if_lookup_prefix(&p, VRF_DEFAULT);
@@ -2494,7 +2579,8 @@ DEFUN (sr_prefix_sid,
* ready. In this case, store the prefix SID for latter
* update of this Extended Prefix
*/
- listnode_add(OspfSR.self->ext_prefix, new);
+ if (exist == NULL)
+ listnode_add(OspfSR.self->ext_prefix, srp);
zlog_info(
"Interface for prefix %pFX not found. Deferred LSA flooding",
&p);
@@ -2503,27 +2589,26 @@ DEFUN (sr_prefix_sid,
if (!if_is_loopback(ifp)) {
vty_out(vty, "interface %s is not a Loopback\n", ifp->name);
- XFREE(MTYPE_OSPF_SR_PARAMS, new);
+ XFREE(MTYPE_OSPF_SR_PARAMS, srp);
return CMD_WARNING_CONFIG_FAILED;
}
- new->nhlfe.ifindex = ifp->ifindex;
+ srp->nhlfe.ifindex = ifp->ifindex;
- /* Add this new SR Prefix if not already found */
- if (srp != new)
- listnode_add(OspfSR.self->ext_prefix, new);
+ /* Add SR Prefix if new */
+ if (!exist)
+ listnode_add(OspfSR.self->ext_prefix, srp);
/* Update Prefix SID if SR is UP */
if (OspfSR.status == SR_UP) {
- if (CHECK_FLAG(new->flags, EXT_SUBTLV_PREFIX_SID_NPFLG)
- && !CHECK_FLAG(new->flags, EXT_SUBTLV_PREFIX_SID_EFLG))
- ospf_zebra_update_prefix_sid(new);
+ if (no_php_flag && !exp_null)
+ ospf_zebra_update_prefix_sid(srp);
} else
return CMD_SUCCESS;
/* Finally, update Extended Prefix LSA id SR is UP */
- new->instance = ospf_ext_schedule_prefix_index(
- ifp, new->sid, &new->prefv4, new->flags);
- if (new->instance == 0) {
+ srp->instance = ospf_ext_schedule_prefix_index(
+ ifp, srp->sid, &srp->prefv4, srp->flags);
+ if (srp->instance == 0) {
vty_out(vty, "Unable to set index %u for prefix %pFX\n",
index, &p);
return CMD_WARNING;
@@ -2674,10 +2759,8 @@ static void show_sr_prefix(struct sbuf *sbuf, struct json_object *json,
srp->nhlfe.label_out);
json_object_string_add(json_obj, "interface",
itf ? itf->name : "-");
- json_object_string_add(
- json_obj, "nexthop",
- inet_ntop(AF_INET, &srp->nhlfe.nexthop,
- buf, sizeof(buf)));
+ json_object_string_addf(json_obj, "nexthop", "%pI4",
+ &srp->nhlfe.nexthop);
json_object_array_add(json_route, json_obj);
} else {
sbuf_push(sbuf, 0, "%20s %9s %15s\n",
@@ -2712,10 +2795,8 @@ static void show_sr_prefix(struct sbuf *sbuf, struct json_object *json,
path->srni.label_out);
json_object_string_add(json_obj, "interface",
itf ? itf->name : "-");
- json_object_string_add(
- json_obj, "nexthop",
- inet_ntop(AF_INET, &path->nexthop,
- buf, sizeof(buf)));
+ json_object_string_addf(json_obj, "nexthop", "%pI4",
+ &path->nexthop);
json_object_array_add(json_route, json_obj);
} else {
sbuf_push(sbuf, indent, "%20s %9s %15s\n",
@@ -2755,9 +2836,8 @@ static void show_sr_node(struct vty *vty, struct json_object *json,
if (json) {
json_node = json_object_new_object();
- json_object_string_add(json_node, "routerID",
- inet_ntop(AF_INET, &srn->adv_router,
- buf, sizeof(buf)));
+ json_object_string_addf(json_node, "routerID", "%pI4",
+ &srn->adv_router);
json_object_int_add(json_node, "srgbSize",
srn->srgb.range_size);
json_object_int_add(json_node, "srgbLabel",
@@ -2846,10 +2926,8 @@ static void show_sr_node(struct vty *vty, struct json_object *json,
srl->nhlfe[0].label_out);
json_object_string_add(json_obj, "interface",
itf ? itf->name : "-");
- json_object_string_add(
- json_obj, "nexthop",
- inet_ntop(AF_INET, &srl->nhlfe[0].nexthop,
- buf, sizeof(buf)));
+ json_object_string_addf(json_obj, "nexthop", "%pI4",
+ &srl->nhlfe[0].nexthop);
json_object_array_add(json_link, json_obj);
/* Backup Link */
json_obj = json_object_new_object();
@@ -2862,10 +2940,8 @@ static void show_sr_node(struct vty *vty, struct json_object *json,
srl->nhlfe[1].label_out);
json_object_string_add(json_obj, "interface",
itf ? itf->name : "-");
- json_object_string_add(
- json_obj, "nexthop",
- inet_ntop(AF_INET, &srl->nhlfe[1].nexthop,
- buf, sizeof(buf)));
+ json_object_string_addf(json_obj, "nexthop", "%pI4",
+ &srl->nhlfe[1].nexthop);
json_object_array_add(json_link, json_obj);
} else {
sbuf_push(&sbuf, 0, "%18s %21s %20s %9s %15s\n",
@@ -2925,7 +3001,6 @@ DEFUN (show_ip_opsf_srdb,
int idx = 0;
struct in_addr rid;
struct sr_node *srn;
- char buf[PREFIX_STRLEN];
bool uj = use_json(argc, argv);
json_object *json = NULL, *json_node_array = NULL;
@@ -2937,10 +3012,8 @@ DEFUN (show_ip_opsf_srdb,
if (uj) {
json = json_object_new_object();
json_node_array = json_object_new_array();
- json_object_string_add(
- json, "srdbID",
- inet_ntop(AF_INET, &OspfSR.self->adv_router,
- buf, sizeof(buf)));
+ json_object_string_addf(json, "srdbID", "%pI4",
+ &OspfSR.self->adv_router);
json_object_object_add(json, "srNodes", json_node_array);
} else {
vty_out(vty,
@@ -2951,12 +3024,8 @@ DEFUN (show_ip_opsf_srdb,
if (argv_find(argv, argc, "self-originate", &idx)) {
srn = OspfSR.self;
show_sr_node(vty, json_node_array, srn);
- if (uj) {
- vty_out(vty, "%s\n",
- json_object_to_json_string_ext(
- json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
+ if (uj)
+ vty_json(vty, json);
return CMD_SUCCESS;
}
@@ -2970,12 +3039,8 @@ DEFUN (show_ip_opsf_srdb,
srn = (struct sr_node *)hash_lookup(OspfSR.neighbors,
(void *)&rid);
show_sr_node(vty, json_node_array, srn);
- if (uj) {
- vty_out(vty, "%s\n",
- json_object_to_json_string_ext(
- json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
+ if (uj)
+ vty_json(vty, json);
return CMD_SUCCESS;
}
@@ -2984,9 +3049,7 @@ DEFUN (show_ip_opsf_srdb,
hash_iterate(OspfSR.neighbors, (void (*)(struct hash_bucket *,
void *))show_json_srdb,
(void *)json_node_array);
- vty_out(vty, "%s\n", json_object_to_json_string_ext(
- json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
+ vty_json(vty, json);
} else {
hash_iterate(OspfSR.neighbors, (void (*)(struct hash_bucket *,
void *))show_vty_srdb,