summaryrefslogtreecommitdiff
path: root/ospfd/ospf_vty.c
diff options
context:
space:
mode:
Diffstat (limited to 'ospfd/ospf_vty.c')
-rw-r--r--ospfd/ospf_vty.c939
1 files changed, 695 insertions, 244 deletions
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index 09dd0081eb..bf131ff225 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -21,6 +21,8 @@
#include <lib/json.h>
#include "defaults.h"
#include "lib/printfrr.h"
+#include "keychain.h"
+#include "frrdistance.h"
#include "ospfd/ospfd.h"
#include "ospfd/ospf_asbr.h"
@@ -40,6 +42,7 @@
#include "ospfd/ospf_bfd.h"
#include "ospfd/ospf_ldp_sync.h"
#include "ospfd/ospf_network.h"
+#include "ospfd/ospf_memory.h"
FRR_CFG_DEFAULT_BOOL(OSPF_LOG_ADJACENCY_CHANGES,
{ .val_bool = true, .match_profile = "datacenter", },
@@ -232,9 +235,12 @@ DEFUN (no_router_ospf,
return CMD_NOT_MY_INSTANCE;
ospf = ospf_lookup(instance, vrf_name);
- if (ospf)
+ if (ospf) {
+ if (ospf->gr_info.restart_support)
+ ospf_gr_nvm_delete(ospf);
+
ospf_finish(ospf);
- else
+ } else
ret = CMD_WARNING_CONFIG_FAILED;
return ret;
@@ -805,6 +811,8 @@ struct ospf_vl_config_data {
char *auth_key; /* simple password if present */
int crypto_key_id; /* Cryptographic key ID */
char *md5_key; /* MD5 authentication key */
+ char *keychain; /* Cryptographic keychain */
+ int del_keychain;
int hello_interval; /* Obvious what these are... */
int retransmit_interval;
int transmit_delay;
@@ -887,6 +895,10 @@ static int ospf_vl_set_security(struct ospf_vl_data *vl_data,
strlcpy((char *)IF_DEF_PARAMS(ifp)->auth_simple,
vl_config->auth_key,
sizeof(IF_DEF_PARAMS(ifp)->auth_simple));
+ } else if (vl_config->keychain) {
+ SET_IF_PARAM(IF_DEF_PARAMS(ifp), keychain_name);
+ XFREE(MTYPE_OSPF_IF_PARAMS, IF_DEF_PARAMS(ifp)->keychain_name);
+ IF_DEF_PARAMS(ifp)->keychain_name = XSTRDUP(MTYPE_OSPF_IF_PARAMS, vl_config->keychain);
} else if (vl_config->md5_key) {
if (ospf_crypt_key_lookup(IF_DEF_PARAMS(ifp)->auth_crypt,
vl_config->crypto_key_id)
@@ -915,6 +927,9 @@ static int ospf_vl_set_security(struct ospf_vl_data *vl_data,
ospf_crypt_key_delete(IF_DEF_PARAMS(ifp)->auth_crypt,
vl_config->crypto_key_id);
+ } else if (vl_config->del_keychain) {
+ UNSET_IF_PARAM(IF_DEF_PARAMS(ifp), keychain_name);
+ XFREE(MTYPE_OSPF_IF_PARAMS, IF_DEF_PARAMS(ifp)->keychain_name);
}
return CMD_SUCCESS;
@@ -1019,9 +1034,11 @@ static int ospf_vl_set(struct ospf *ospf, struct ospf_vl_config_data *vl_config)
DEFUN (ospf_area_vlink,
ospf_area_vlink_cmd,
- "area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D [authentication [<message-digest|null>]] [<message-digest-key (1-255) md5 KEY|authentication-key AUTH_KEY>]",
+ "area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D [authentication [<key-chain KEYCHAIN_NAME|message-digest|null>]] [<message-digest-key (1-255) md5 KEY|authentication-key AUTH_KEY>]",
VLINK_HELPSTR_IPADDR
"Enable authentication on this virtual link\n"
+ "Use a key-chain for cryptographic authentication keys\n"
+ "Key-chain name\n"
"Use message-digest authentication\n"
"Use null authentication\n"
VLINK_HELPSTR_AUTH_MD5
@@ -1064,7 +1081,10 @@ DEFUN (ospf_area_vlink,
vl_config.auth_type = OSPF_AUTH_SIMPLE;
}
- if (argv_find(argv, argc, "message-digest", &idx)) {
+ if (argv_find(argv, argc, "key-chain", &idx)) {
+ vl_config.auth_type = OSPF_AUTH_CRYPTOGRAPHIC;
+ vl_config.keychain = argv[idx+1]->arg;
+ } else if (argv_find(argv, argc, "message-digest", &idx)) {
/* authentication message-digest */
vl_config.auth_type = OSPF_AUTH_CRYPTOGRAPHIC;
} else if (argv_find(argv, argc, "null", &idx)) {
@@ -1094,10 +1114,12 @@ DEFUN (ospf_area_vlink,
DEFUN (no_ospf_area_vlink,
no_ospf_area_vlink_cmd,
- "no area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D [authentication [<message-digest|null>]] [<message-digest-key (1-255) md5 KEY|authentication-key AUTH_KEY>]",
+ "no area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D [authentication [<key-chain KEYCHAIN_NAME|message-digest|null>]] [<message-digest-key (1-255) md5 KEY|authentication-key AUTH_KEY>]",
NO_STR
VLINK_HELPSTR_IPADDR
"Enable authentication on this virtual link\n"
+ "Use a key-chain for cryptographic authentication keys\n"
+ "Key-chain name\n"
"Use message-digest authentication\n"
"Use null authentication\n"
VLINK_HELPSTR_AUTH_MD5
@@ -1157,6 +1179,11 @@ DEFUN (no_ospf_area_vlink,
vl_config.auth_type = OSPF_AUTH_NOTSET;
}
+ if (argv_find(argv, argc, "key-chain", &idx)) {
+ vl_config.del_keychain = 1;
+ vl_config.keychain = NULL;
+ }
+
if (argv_find(argv, argc, "message-digest-key", &idx)) {
vl_config.md5_key = NULL;
vl_config.crypto_key_id = strtol(argv[idx + 1]->arg, NULL, 10);
@@ -1526,7 +1553,7 @@ DEFPY (ospf_area_nssa,
/* Flush the external LSA for the specified area */
ospf_flush_lsa_from_area(ospf, area_id, OSPF_AS_EXTERNAL_LSA);
ospf_schedule_abr_task(ospf);
- ospf_schedule_asbr_nssa_redist_update(ospf);
+ ospf_schedule_asbr_redist_update(ospf);
return CMD_SUCCESS;
}
@@ -1845,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"
@@ -1890,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"
@@ -2055,6 +2082,13 @@ DEFUN (ospf_abr_type,
if (ospf->abr_type != abr_type) {
ospf->abr_type = abr_type;
ospf_schedule_abr_task(ospf);
+
+ /* The ABR task might not initiate SPF recalculation if the
+ * OSPF flags remain the same. And inter-area routes would not
+ * be added/deleted according to the new ABR type. So this
+ * needs to be done here too.
+ */
+ ospf_spf_calculate_schedule(ospf, SPF_FLAG_ABR_STATUS_CHANGE);
}
return CMD_SUCCESS;
@@ -2372,130 +2406,30 @@ DEFUN (no_ospf_timers_lsa_min_arrival,
return CMD_SUCCESS;
}
-DEFUN (ospf_neighbor,
- ospf_neighbor_cmd,
- "neighbor A.B.C.D [priority (0-255) [poll-interval (1-65535)]]",
- NEIGHBOR_STR
- "Neighbor IP address\n"
- "Neighbor Priority\n"
- "Priority\n"
- "Dead Neighbor Polling interval\n"
- "Seconds\n")
-{
- VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
- int idx_ipv4 = 1;
- int idx_pri = 3;
- int idx_poll = 5;
- struct in_addr nbr_addr;
- unsigned int priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
- unsigned int interval = OSPF_POLL_INTERVAL_DEFAULT;
-
- if (!inet_aton(argv[idx_ipv4]->arg, &nbr_addr)) {
- vty_out(vty, "Please specify Neighbor ID by A.B.C.D\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (argc > 2)
- priority = strtoul(argv[idx_pri]->arg, NULL, 10);
-
- if (argc > 4)
- interval = strtoul(argv[idx_poll]->arg, NULL, 10);
-
- ospf_nbr_nbma_set(ospf, nbr_addr);
-
- if (argc > 2)
- ospf_nbr_nbma_priority_set(ospf, nbr_addr, priority);
-
- if (argc > 4)
- ospf_nbr_nbma_poll_interval_set(ospf, nbr_addr, interval);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (ospf_neighbor_poll_interval,
- ospf_neighbor_poll_interval_cmd,
- "neighbor A.B.C.D poll-interval (1-65535) [priority (0-255)]",
- NEIGHBOR_STR
- "Neighbor IP address\n"
- "Dead Neighbor Polling interval\n"
- "Seconds\n"
- "OSPF priority of non-broadcast neighbor\n"
- "Priority\n")
-{
- VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
- int idx_ipv4 = 1;
- int idx_poll = 3;
- int idx_pri = 5;
- struct in_addr nbr_addr;
- unsigned int priority;
- unsigned int interval;
-
- if (!inet_aton(argv[idx_ipv4]->arg, &nbr_addr)) {
- vty_out(vty, "Please specify Neighbor ID by A.B.C.D\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- interval = strtoul(argv[idx_poll]->arg, NULL, 10);
-
- priority = argc > 4 ? strtoul(argv[idx_pri]->arg, NULL, 10)
- : OSPF_NEIGHBOR_PRIORITY_DEFAULT;
-
- ospf_nbr_nbma_set(ospf, nbr_addr);
- ospf_nbr_nbma_poll_interval_set(ospf, nbr_addr, interval);
-
- if (argc > 4)
- ospf_nbr_nbma_priority_set(ospf, nbr_addr, priority);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (no_ospf_neighbor,
- no_ospf_neighbor_cmd,
- "no neighbor A.B.C.D [priority (0-255) [poll-interval (1-65525)]]",
- NO_STR
- NEIGHBOR_STR
- "Neighbor IP address\n"
- "Neighbor Priority\n"
- "Priority\n"
- "Dead Neighbor Polling interval\n"
- "Seconds\n")
+DEFPY(ospf_neighbor, ospf_neighbor_cmd,
+ "[no] neighbor A.B.C.D$nbr_address [{priority (0-255)$priority | poll-interval (1-65535)$interval}]",
+ NO_STR
+ NEIGHBOR_STR
+ "Neighbor IP address\n"
+ "Neighbor Priority\n"
+ "Priority\n"
+ "Dead Neighbor Polling interval\n"
+ "Seconds\n")
{
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
- int idx_ipv4 = 2;
- struct in_addr nbr_addr;
-
- if (!inet_aton(argv[idx_ipv4]->arg, &nbr_addr)) {
- vty_out(vty, "Please specify Neighbor ID by A.B.C.D\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- (void)ospf_nbr_nbma_unset(ospf, nbr_addr);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (no_ospf_neighbor_poll,
- no_ospf_neighbor_poll_cmd,
- "no neighbor A.B.C.D poll-interval (1-65535) [priority (0-255)]",
- NO_STR
- NEIGHBOR_STR
- "Neighbor IP address\n"
- "Dead Neighbor Polling interval\n"
- "Seconds\n"
- "Neighbor Priority\n"
- "Priority\n")
-{
- VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
- int idx_ipv4 = 2;
- struct in_addr nbr_addr;
+ if (no)
+ ospf_nbr_nbma_unset(ospf, nbr_address);
+ else {
+ ospf_nbr_nbma_set(ospf, nbr_address);
+ if (priority_str)
+ ospf_nbr_nbma_priority_set(ospf, nbr_address, priority);
- if (!inet_aton(argv[idx_ipv4]->arg, &nbr_addr)) {
- vty_out(vty, "Please specify Neighbor ID by A.B.C.D\n");
- return CMD_WARNING_CONFIG_FAILED;
+ if (interval_str)
+ ospf_nbr_nbma_poll_interval_set(ospf, nbr_address,
+ interval);
}
- (void)ospf_nbr_nbma_unset(ospf, nbr_addr);
-
return CMD_SUCCESS;
}
@@ -3587,18 +3521,41 @@ static void ospf_interface_auth_show(struct vty *vty, struct ospf_interface *oi,
case OSPF_AUTH_CRYPTOGRAPHIC: {
struct crypt_key *ckey;
- if (list_isempty(OSPF_IF_PARAM(oi, auth_crypt)))
- return;
-
- ckey = listgetdata(listtail(OSPF_IF_PARAM(oi, auth_crypt)));
- if (ckey) {
+ if (OSPF_IF_PARAM(oi, keychain_name)) {
if (use_json) {
json_object_string_add(json, "authentication",
- "authenticationMessageDigest");
+ "authenticationKeyChain");
+ json_object_string_add(json, "keychain",
+ OSPF_IF_PARAM(oi, keychain_name));
} else {
vty_out(vty,
" Cryptographic authentication enabled\n");
- vty_out(vty, " Algorithm:MD5\n");
+ struct keychain *keychain = keychain_lookup(OSPF_IF_PARAM(oi, keychain_name));
+
+ if (keychain) {
+ struct key *key = key_lookup_for_send(keychain);
+
+ if (key) {
+ vty_out(vty, " Sending SA: Key %u, Algorithm %s - key chain %s\n",
+ key->index, keychain_get_algo_name_by_id(key->hash_algo),
+ OSPF_IF_PARAM(oi, keychain_name));
+ }
+ }
+ }
+ } else {
+ if (list_isempty(OSPF_IF_PARAM(oi, auth_crypt)))
+ return;
+
+ ckey = listgetdata(listtail(OSPF_IF_PARAM(oi, auth_crypt)));
+ if (ckey) {
+ if (use_json) {
+ json_object_string_add(json, "authentication",
+ "authenticationMessageDigest");
+ } else {
+ vty_out(vty,
+ " Cryptographic authentication enabled\n");
+ vty_out(vty, " Algorithm:MD5\n");
+ }
}
}
break;
@@ -3617,6 +3574,9 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
struct ospf_neighbor *nbr;
struct route_node *rn;
uint32_t bandwidth = ifp->bandwidth ? ifp->bandwidth : ifp->speed;
+ struct ospf_if_params *params;
+ json_object *json_ois = NULL;
+ json_object *json_oi = NULL;
/* Is interface up? */
if (use_json) {
@@ -3667,17 +3627,33 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
}
}
+ if (use_json) {
+ json_ois = json_object_new_object();
+ json_object_object_add(json_interface_sub, "interfaceIp",
+ json_ois);
+ }
+
for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
struct ospf_interface *oi = rn->info;
if (oi == NULL)
continue;
+#if CONFDATE > 20240601
+ CPP_NOTICE(
+ "Use all fields following ospfEnabled from interfaceIp hierarchy")
+#endif
+
+ if (use_json)
+ json_oi = json_object_new_object();
+
if (CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED)) {
- if (use_json)
+ if (use_json) {
json_object_boolean_true_add(json_interface_sub,
"ifUnnumbered");
- else
+ json_object_boolean_true_add(json_oi,
+ "ifUnnumbered");
+ } else
vty_out(vty, " This interface is UNNUMBERED,");
} else {
struct in_addr dest;
@@ -3691,6 +3667,13 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
json_object_int_add(json_interface_sub,
"ipAddressPrefixlen",
oi->address->prefixlen);
+
+ json_object_string_addf(
+ json_oi, "ipAddress", "%pI4",
+ &oi->address->u.prefix4);
+ json_object_int_add(json_oi,
+ "ipAddressPrefixlen",
+ oi->address->prefixlen);
} else
vty_out(vty, " Internet Address %pFX,",
oi->address);
@@ -3713,17 +3696,29 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
}
if (use_json) {
- json_object_string_add(
- json_interface_sub,
- "ospfIfType", dstr);
- if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
+ json_object_string_add(json_interface_sub,
+ "ospfIfType", dstr);
+
+ json_object_string_add(json_oi, "ospfIfType",
+ dstr);
+
+ if (oi->type == OSPF_IFTYPE_VIRTUALLINK) {
json_object_string_addf(
json_interface_sub, "vlinkPeer",
"%pI4", &dest);
- else
+
+ json_object_string_addf(json_oi,
+ "vlinkPeer",
+ "%pI4", &dest);
+ } else {
json_object_string_addf(
json_interface_sub,
"localIfUsed", "%pI4", &dest);
+
+ json_object_string_addf(json_oi,
+ "localIfUsed",
+ "%pI4", &dest);
+ }
} else
vty_out(vty, " %s %pI4,", dstr,
&dest);
@@ -3731,10 +3726,18 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
if (use_json) {
json_object_string_add(json_interface_sub, "area",
ospf_area_desc_string(oi->area));
- if (OSPF_IF_PARAM(oi, mtu_ignore))
+
+ json_object_string_add(json_oi, "area",
+ ospf_area_desc_string(oi->area));
+
+ if (OSPF_IF_PARAM(oi, mtu_ignore)) {
+ json_object_boolean_true_add(
+ json_oi, "mtuMismatchDetect");
json_object_boolean_true_add(
json_interface_sub,
"mtuMismatchDetect");
+ }
+
json_object_string_addf(json_interface_sub, "routerId",
"%pI4", &ospf->router_id);
json_object_string_add(json_interface_sub,
@@ -3742,14 +3745,29 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
ospf_network_type_str[oi->type]);
json_object_int_add(json_interface_sub, "cost",
oi->output_cost);
- json_object_int_add(
- json_interface_sub, "transmitDelaySecs",
- OSPF_IF_PARAM(oi, transmit_delay));
+ json_object_int_add(json_interface_sub,
+ "transmitDelaySecs",
+ OSPF_IF_PARAM(oi, transmit_delay));
json_object_string_add(json_interface_sub, "state",
lookup_msg(ospf_ism_state_msg,
oi->state, NULL));
json_object_int_add(json_interface_sub, "priority",
PRIORITY(oi));
+
+ json_object_string_addf(json_oi, "routerId", "%pI4",
+ &ospf->router_id);
+ json_object_string_add(json_oi, "networkType",
+ ospf_network_type_str[oi->type]);
+ json_object_int_add(json_oi, "cost", oi->output_cost);
+ json_object_int_add(json_oi, "transmitDelaySecs",
+ OSPF_IF_PARAM(oi, transmit_delay));
+ json_object_string_add(json_oi, "state",
+ lookup_msg(ospf_ism_state_msg,
+ oi->state, NULL));
+ json_object_int_add(json_oi, "priority", PRIORITY(oi));
+ json_object_boolean_add(
+ json_interface_sub, "opaqueCapable",
+ OSPF_IF_PARAM(oi, opaque_capable));
} else {
vty_out(vty, " Area %s\n",
ospf_area_desc_string(oi->area));
@@ -3769,6 +3787,9 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
OSPF_IF_PARAM(oi, transmit_delay),
lookup_msg(ospf_ism_state_msg, oi->state, NULL),
PRIORITY(oi));
+ if (!OSPF_IF_PARAM(oi, opaque_capable))
+ vty_out(vty,
+ " Opaque LSA capability disabled on interface\n");
}
/* Show DR information. */
@@ -3787,6 +3808,13 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
json_interface_sub, "drAddress",
"%pI4",
&nbr->address.u.prefix4);
+
+ json_object_string_addf(
+ json_oi, "drId", "%pI4",
+ &nbr->router_id);
+ json_object_string_addf(
+ json_oi, "drAddress", "%pI4",
+ &nbr->address.u.prefix4);
} else {
vty_out(vty,
" Designated Router (ID) %pI4",
@@ -3812,6 +3840,13 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
json_interface_sub,
"bdrAddress", "%pI4",
&nbr->address.u.prefix4);
+
+ json_object_string_addf(
+ json_oi, "bdrId", "%pI4",
+ &nbr->router_id);
+ json_object_string_addf(
+ json_oi, "bdrAddress", "%pI4",
+ &nbr->address.u.prefix4);
} else {
vty_out(vty,
" Backup Designated Router (ID) %pI4,",
@@ -3827,28 +3862,43 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
if (oi->params
&& ntohl(oi->params->network_lsa_seqnum)
!= OSPF_INITIAL_SEQUENCE_NUMBER) {
- if (use_json)
+ if (use_json) {
json_object_int_add(
json_interface_sub,
"networkLsaSequence",
ntohl(oi->params->network_lsa_seqnum));
- else
+
+ json_object_int_add(
+ json_oi, "networkLsaSequence",
+ ntohl(oi->params->network_lsa_seqnum));
+ } else {
vty_out(vty,
" Saved Network-LSA sequence number 0x%x\n",
ntohl(oi->params->network_lsa_seqnum));
+ }
}
if (use_json) {
if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS)
|| OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) {
- if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS))
+ if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS)) {
json_object_boolean_true_add(
json_interface_sub,
"mcastMemberOspfAllRouters");
- if (OI_MEMBER_CHECK(oi, MEMBER_DROUTERS))
+
+ json_object_boolean_true_add(
+ json_oi,
+ "mcastMemberOspfAllRouters");
+ }
+ if (OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) {
json_object_boolean_true_add(
json_interface_sub,
"mcastMemberOspfDesignatedRouters");
+
+ json_object_boolean_true_add(
+ json_oi,
+ "mcastMemberOspfDesignatedRouters");
+ }
}
} else {
vty_out(vty, " Multicast group memberships:");
@@ -3864,23 +3914,38 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
}
if (use_json) {
- if (OSPF_IF_PARAM(oi, fast_hello) == 0)
+ if (OSPF_IF_PARAM(oi, fast_hello) == 0) {
json_object_int_add(
json_interface_sub, "timerMsecs",
OSPF_IF_PARAM(oi, v_hello) * 1000);
- else
+
+ json_object_int_add(json_oi, "timerMsecs",
+ OSPF_IF_PARAM(oi, v_hello) *
+ 1000);
+ } else {
json_object_int_add(
json_interface_sub, "timerMsecs",
1000 / OSPF_IF_PARAM(oi, fast_hello));
- json_object_int_add(json_interface_sub,
- "timerDeadSecs",
+
+ json_object_int_add(
+ json_oi, "timerMsecs",
+ 1000 / OSPF_IF_PARAM(oi, fast_hello));
+ }
+ json_object_int_add(json_interface_sub, "timerDeadSecs",
OSPF_IF_PARAM(oi, v_wait));
- json_object_int_add(json_interface_sub,
- "timerWaitSecs",
+ json_object_int_add(json_interface_sub, "timerWaitSecs",
OSPF_IF_PARAM(oi, v_wait));
json_object_int_add(
json_interface_sub, "timerRetransmitSecs",
OSPF_IF_PARAM(oi, retransmit_interval));
+
+ json_object_int_add(json_oi, "timerDeadSecs",
+ OSPF_IF_PARAM(oi, v_wait));
+ json_object_int_add(json_oi, "timerWaitSecs",
+ OSPF_IF_PARAM(oi, v_wait));
+ json_object_int_add(
+ json_oi, "timerRetransmitSecs",
+ OSPF_IF_PARAM(oi, retransmit_interval));
} else {
vty_out(vty, " Timer intervals configured,");
vty_out(vty, " Hello ");
@@ -3909,17 +3974,23 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
json_object_int_add(json_interface_sub,
"timerHelloInMsecs",
time_store);
+ json_object_int_add(json_oi,
+ "timerHelloInMsecs",
+ time_store);
} else
vty_out(vty, " Hello due in %s\n",
ospf_timer_dump(oi->t_hello, timebuf,
sizeof(timebuf)));
} else /* passive-interface is set */
{
- if (use_json)
+ if (use_json) {
json_object_boolean_true_add(
json_interface_sub,
"timerPassiveIface");
- else
+
+ json_object_boolean_true_add(
+ json_oi, "timerPassiveIface");
+ } else
vty_out(vty,
" No Hellos (Passive interface)\n");
}
@@ -3930,16 +4001,89 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
json_object_int_add(json_interface_sub,
"nbrAdjacentCount",
ospf_nbr_count(oi, NSM_Full));
+
+ json_object_int_add(json_oi, "nbrCount",
+ ospf_nbr_count(oi, 0));
+ json_object_int_add(json_oi, "nbrAdjacentCount",
+ ospf_nbr_count(oi, NSM_Full));
} else
vty_out(vty,
" Neighbor Count is %d, Adjacent neighbor count is %d\n",
ospf_nbr_count(oi, 0),
ospf_nbr_count(oi, NSM_Full));
+ params = IF_DEF_PARAMS(ifp);
+ if (params &&
+ OSPF_IF_PARAM_CONFIGURED(params, v_gr_hello_delay)) {
+ if (use_json) {
+ json_object_int_add(json_interface_sub,
+ "grHelloDelaySecs",
+ params->v_gr_hello_delay);
+
+ json_object_int_add(json_oi, "grHelloDelaySecs",
+ params->v_gr_hello_delay);
+ } else
+ vty_out(vty,
+ " Graceful Restart hello delay: %us\n",
+ params->v_gr_hello_delay);
+ }
+
ospf_interface_bfd_show(vty, ifp, json_interface_sub);
+ if (use_json) {
+ json_object_boolean_add(json_interface_sub,
+ "prefixSuppression",
+ OSPF_IF_PARAM(oi,
+ prefix_suppression));
+ json_object_boolean_add(json_oi, "prefixSuppression",
+ OSPF_IF_PARAM(oi,
+ prefix_suppression));
+ } else {
+ if (OSPF_IF_PARAM(oi, prefix_suppression))
+ vty_out(vty,
+ " Suppress advertisement of interface IP prefix\n");
+ }
+
/* OSPF Authentication information */
ospf_interface_auth_show(vty, oi, json_interface_sub, use_json);
+
+ ospf_interface_auth_show(vty, oi, json_oi, use_json);
+
+ /* Point-to-Multipoint Interface options. */
+ if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) {
+ if (use_json) {
+ json_object_boolean_add(json_interface_sub,
+ "p2mpDelayReflood",
+ oi->p2mp_delay_reflood);
+
+ json_object_boolean_add(json_oi,
+ "p2mpDelayReflood",
+ oi->p2mp_delay_reflood);
+ } else {
+ vty_out(vty,
+ " %sDelay reflooding LSAs received on P2MP interface\n",
+ oi->p2mp_delay_reflood ? "" : "Don't ");
+ }
+ if (use_json) {
+ json_object_boolean_add(json_interface_sub,
+ "p2mpNonBroadcast",
+ oi->p2mp_non_broadcast);
+
+ json_object_boolean_add(json_oi,
+ "p2mpNonBroadcast",
+ oi->p2mp_non_broadcast);
+ } else {
+ vty_out(vty,
+ " P2MP interface does %ssupport broadcast\n",
+ oi->p2mp_non_broadcast ? "not " : "");
+ }
+ }
+
+ /* Add ospf_interface object to main json blob using SIP as key
+ */
+ if (use_json)
+ json_object_object_addf(json_ois, json_oi, "%pI4",
+ &oi->address->u.prefix4);
}
}
@@ -3996,16 +4140,15 @@ static int show_ip_ospf_interface_common(struct vty *vty, struct ospf *ospf,
/* Interface name is specified. */
ifp = if_lookup_by_name(intf_name, ospf->vrf_id);
if (ifp == NULL) {
- if (use_json)
+ if (use_json) {
json_object_boolean_true_add(json_vrf,
"noSuchIface");
- else
+ json_object_free(json_interface);
+ } else
vty_out(vty, "No such interface name\n");
} else {
- if (use_json) {
+ if (use_json)
json_interface_sub = json_object_new_object();
- json_interface = json_object_new_object();
- }
show_ip_ospf_interface_sub(
vty, ospf, ifp, json_interface_sub, use_json);
@@ -4148,6 +4291,9 @@ static int show_ip_ospf_interface_traffic_common(
rn = route_next(rn)) {
oi = rn->info;
+ if (oi == NULL)
+ continue;
+
if (use_json) {
json_interface_sub =
json_object_new_object();
@@ -5479,7 +5625,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(
@@ -5739,7 +5885,7 @@ static int show_ip_ospf_neighbor_detail_all_common(struct vty *vty,
prev_nbr = nbr;
}
- if (oi->type != OSPF_IFTYPE_NBMA)
+ if (!OSPF_IF_NON_BROADCAST(oi))
continue;
struct listnode *nd;
@@ -5980,7 +6126,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;
}
@@ -5990,7 +6136,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;
@@ -6027,7 +6173,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(
@@ -7351,24 +7497,26 @@ DEFPY (show_ip_ospf_database,
DEFUN (ip_ospf_authentication_args,
ip_ospf_authentication_args_addr_cmd,
- "ip ospf authentication <null|message-digest> [A.B.C.D]",
+ "ip ospf authentication <null|message-digest|key-chain KEYCHAIN_NAME> [A.B.C.D]",
"IP Information\n"
"OSPF interface commands\n"
"Enable authentication on this interface\n"
"Use null authentication\n"
"Use message-digest authentication\n"
+ "Use a key-chain for cryptographic authentication keys\n"
+ "Key-chain name\n"
"Address of interface\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_encryption = 3;
- int idx_ipv4 = 4;
+ int idx_ipv4 = argc-1;
struct in_addr addr;
int ret;
struct ospf_if_params *params;
params = IF_DEF_PARAMS(ifp);
- if (argc == 5) {
+ if (argv[idx_ipv4]->type == IPV4_TKN) {
ret = inet_aton(argv[idx_ipv4]->arg, &addr);
if (!ret) {
vty_out(vty,
@@ -7391,6 +7539,17 @@ DEFUN (ip_ospf_authentication_args,
if (argv[idx_encryption]->arg[0] == 'm') {
SET_IF_PARAM(params, auth_type);
params->auth_type = OSPF_AUTH_CRYPTOGRAPHIC;
+ UNSET_IF_PARAM(params, keychain_name);
+ XFREE(MTYPE_OSPF_IF_PARAMS, params->keychain_name);
+ return CMD_SUCCESS;
+ }
+
+ if (argv[idx_encryption]->arg[0] == 'k') {
+ SET_IF_PARAM(params, auth_type);
+ params->auth_type = OSPF_AUTH_CRYPTOGRAPHIC;
+ SET_IF_PARAM(params, keychain_name);
+ params->keychain_name = XSTRDUP(MTYPE_OSPF_IF_PARAMS, argv[idx_encryption+1]->arg);
+ UNSET_IF_PARAM(params, auth_crypt);
return CMD_SUCCESS;
}
@@ -7434,18 +7593,20 @@ DEFUN (ip_ospf_authentication,
DEFUN (no_ip_ospf_authentication_args,
no_ip_ospf_authentication_args_addr_cmd,
- "no ip ospf authentication <null|message-digest> [A.B.C.D]",
+ "no ip ospf authentication <null|message-digest|key-chain [KEYCHAIN_NAME]> [A.B.C.D]",
NO_STR
"IP Information\n"
"OSPF interface commands\n"
"Enable authentication on this interface\n"
"Use null authentication\n"
"Use message-digest authentication\n"
+ "Use a key-chain for cryptographic authentication keys\n"
+ "Key-chain name\n"
"Address of interface\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_encryption = 4;
- int idx_ipv4 = 5;
+ int idx_ipv4 = argc-1;
struct in_addr addr;
int ret;
struct ospf_if_params *params;
@@ -7454,7 +7615,7 @@ DEFUN (no_ip_ospf_authentication_args,
params = IF_DEF_PARAMS(ifp);
- if (argc == 6) {
+ if (argv[idx_ipv4]->type == IPV4_TKN) {
ret = inet_aton(argv[idx_ipv4]->arg, &addr);
if (!ret) {
vty_out(vty,
@@ -7469,6 +7630,10 @@ DEFUN (no_ip_ospf_authentication_args,
}
params->auth_type = OSPF_AUTH_NOTSET;
UNSET_IF_PARAM(params, auth_type);
+
+ XFREE(MTYPE_OSPF_IF_PARAMS, params->keychain_name);
+ UNSET_IF_PARAM(params, keychain_name);
+
if (params != IF_DEF_PARAMS(ifp)) {
ospf_free_if_params(ifp, addr);
ospf_if_update_params(ifp, addr);
@@ -7476,7 +7641,8 @@ DEFUN (no_ip_ospf_authentication_args,
} else {
if (argv[idx_encryption]->arg[0] == 'n') {
auth_type = OSPF_AUTH_NULL;
- } else if (argv[idx_encryption]->arg[0] == 'm') {
+ } else if (argv[idx_encryption]->arg[0] == 'm' ||
+ argv[idx_encryption]->arg[0] == 'k') {
auth_type = OSPF_AUTH_CRYPTOGRAPHIC;
} else {
vty_out(vty, "Unexpected input encountered\n");
@@ -7492,6 +7658,8 @@ DEFUN (no_ip_ospf_authentication_args,
if (params->auth_type == auth_type) {
params->auth_type = OSPF_AUTH_NOTSET;
UNSET_IF_PARAM(params, auth_type);
+ XFREE(MTYPE_OSPF_IF_PARAMS, params->keychain_name);
+ UNSET_IF_PARAM(params, keychain_name);
}
for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn;
@@ -7500,6 +7668,8 @@ DEFUN (no_ip_ospf_authentication_args,
if (params->auth_type == auth_type) {
params->auth_type = OSPF_AUTH_NOTSET;
UNSET_IF_PARAM(params, auth_type);
+ XFREE(MTYPE_OSPF_IF_PARAMS, params->keychain_name);
+ UNSET_IF_PARAM(params, keychain_name);
if (params != IF_DEF_PARAMS(ifp)) {
ospf_free_if_params(
ifp, rn->p.u.prefix4);
@@ -8047,7 +8217,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"
@@ -8068,7 +8238,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"
@@ -8135,7 +8305,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"
@@ -8291,13 +8461,18 @@ DEFUN_HIDDEN (no_ospf_hello_interval,
}
DEFUN(ip_ospf_network, ip_ospf_network_cmd,
- "ip ospf network <broadcast|non-broadcast|point-to-multipoint|point-to-point [dmvpn]>",
+ "ip ospf network <broadcast|"
+ "non-broadcast|"
+ "point-to-multipoint [delay-reflood|non-broadcast]|"
+ "point-to-point [dmvpn]>",
"IP Information\n"
"OSPF interface commands\n"
"Network type\n"
"Specify OSPF broadcast multi-access network\n"
"Specify OSPF NBMA network\n"
"Specify OSPF point-to-multipoint network\n"
+ "Specify OSPF delayed reflooding of LSAs received on P2MP interface\n"
+ "Specify OSPF point-to-multipoint network doesn't support broadcast\n"
"Specify OSPF point-to-point network\n"
"Specify OSPF point-to-point DMVPN network\n")
{
@@ -8305,6 +8480,8 @@ DEFUN(ip_ospf_network, ip_ospf_network_cmd,
int idx = 0;
int old_type = IF_DEF_PARAMS(ifp)->type;
uint8_t old_ptp_dmvpn = IF_DEF_PARAMS(ifp)->ptp_dmvpn;
+ uint8_t old_p2mp_delay_reflood = IF_DEF_PARAMS(ifp)->p2mp_delay_reflood;
+ uint8_t old_p2mp_non_broadcast = IF_DEF_PARAMS(ifp)->p2mp_non_broadcast;
struct route_node *rn;
if (old_type == OSPF_IFTYPE_LOOPBACK) {
@@ -8314,21 +8491,30 @@ DEFUN(ip_ospf_network, ip_ospf_network_cmd,
}
IF_DEF_PARAMS(ifp)->ptp_dmvpn = 0;
+ IF_DEF_PARAMS(ifp)->p2mp_delay_reflood =
+ OSPF_P2MP_DELAY_REFLOOD_DEFAULT;
+ IF_DEF_PARAMS(ifp)->p2mp_non_broadcast = OSPF_P2MP_NON_BROADCAST_DEFAULT;
if (argv_find(argv, argc, "broadcast", &idx))
IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_BROADCAST;
- else if (argv_find(argv, argc, "non-broadcast", &idx))
- IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_NBMA;
- else if (argv_find(argv, argc, "point-to-multipoint", &idx))
+ else if (argv_find(argv, argc, "point-to-multipoint", &idx)) {
IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_POINTOMULTIPOINT;
+ if (argv_find(argv, argc, "delay-reflood", &idx))
+ IF_DEF_PARAMS(ifp)->p2mp_delay_reflood = true;
+ if (argv_find(argv, argc, "non-broadcast", &idx))
+ IF_DEF_PARAMS(ifp)->p2mp_non_broadcast = true;
+ } else if (argv_find(argv, argc, "non-broadcast", &idx))
+ IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_NBMA;
else if (argv_find(argv, argc, "point-to-point", &idx)) {
IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_POINTOPOINT;
if (argv_find(argv, argc, "dmvpn", &idx))
IF_DEF_PARAMS(ifp)->ptp_dmvpn = 1;
}
- if (IF_DEF_PARAMS(ifp)->type == old_type
- && IF_DEF_PARAMS(ifp)->ptp_dmvpn == old_ptp_dmvpn)
+ if (IF_DEF_PARAMS(ifp)->type == old_type &&
+ IF_DEF_PARAMS(ifp)->ptp_dmvpn == old_ptp_dmvpn &&
+ IF_DEF_PARAMS(ifp)->p2mp_delay_reflood == old_p2mp_delay_reflood &&
+ IF_DEF_PARAMS(ifp)->p2mp_non_broadcast == old_p2mp_non_broadcast)
return CMD_SUCCESS;
SET_IF_PARAM(IF_DEF_PARAMS(ifp), type);
@@ -8340,10 +8526,22 @@ DEFUN(ip_ospf_network, ip_ospf_network_cmd,
continue;
oi->type = IF_DEF_PARAMS(ifp)->type;
+ oi->ptp_dmvpn = IF_DEF_PARAMS(ifp)->ptp_dmvpn;
+ oi->p2mp_delay_reflood = IF_DEF_PARAMS(ifp)->p2mp_delay_reflood;
+ oi->p2mp_non_broadcast = IF_DEF_PARAMS(ifp)->p2mp_non_broadcast;
- if (oi->state > ISM_Down) {
- OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceDown);
- OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceUp);
+ /*
+ * The OSPF interface only needs to be flapped if the network
+ * type or DMVPN parameter changes.
+ */
+ if (IF_DEF_PARAMS(ifp)->type != old_type ||
+ IF_DEF_PARAMS(ifp)->ptp_dmvpn != old_ptp_dmvpn ||
+ IF_DEF_PARAMS(ifp)->p2mp_non_broadcast !=
+ old_p2mp_non_broadcast) {
+ if (oi->state > ISM_Down) {
+ OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceDown);
+ OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceUp);
+ }
}
}
@@ -8381,6 +8579,9 @@ DEFUN (no_ip_ospf_network,
IF_DEF_PARAMS(ifp)->type = ospf_default_iftype(ifp);
IF_DEF_PARAMS(ifp)->ptp_dmvpn = 0;
+ IF_DEF_PARAMS(ifp)->p2mp_delay_reflood =
+ OSPF_P2MP_DELAY_REFLOOD_DEFAULT;
+ IF_DEF_PARAMS(ifp)->p2mp_non_broadcast = OSPF_P2MP_NON_BROADCAST_DEFAULT;
if (IF_DEF_PARAMS(ifp)->type == old_type)
return CMD_SUCCESS;
@@ -8392,6 +8593,8 @@ DEFUN (no_ip_ospf_network,
continue;
oi->type = IF_DEF_PARAMS(ifp)->type;
+ oi->ptp_dmvpn = IF_DEF_PARAMS(ifp)->ptp_dmvpn;
+ oi->p2mp_delay_reflood = IF_DEF_PARAMS(ifp)->p2mp_delay_reflood;
if (oi->state > ISM_Down) {
OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceDown);
@@ -8640,6 +8843,59 @@ DEFUN_HIDDEN (no_ospf_retransmit_interval,
return no_ip_ospf_retransmit_interval(self, vty, argc, argv);
}
+DEFPY (ip_ospf_gr_hdelay,
+ ip_ospf_gr_hdelay_cmd,
+ "ip ospf graceful-restart hello-delay (1-1800)",
+ IP_STR
+ "OSPF interface commands\n"
+ "Graceful Restart parameters\n"
+ "Delay the sending of the first hello packets.\n"
+ "Delay in seconds\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct ospf_if_params *params;
+
+ params = IF_DEF_PARAMS(ifp);
+
+ /* Note: new or updated value won't affect ongoing graceful restart. */
+ SET_IF_PARAM(params, v_gr_hello_delay);
+ params->v_gr_hello_delay = hello_delay;
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (no_ip_ospf_gr_hdelay,
+ no_ip_ospf_gr_hdelay_cmd,
+ "no ip ospf graceful-restart hello-delay [(1-1800)]",
+ NO_STR
+ IP_STR
+ "OSPF interface commands\n"
+ "Graceful Restart parameters\n"
+ "Delay the sending of the first hello packets.\n"
+ "Delay in seconds\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct ospf_if_params *params;
+ struct route_node *rn;
+
+ params = IF_DEF_PARAMS(ifp);
+ UNSET_IF_PARAM(params, v_gr_hello_delay);
+ params->v_gr_hello_delay = OSPF_HELLO_DELAY_DEFAULT;
+
+ for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
+ struct ospf_interface *oi;
+
+ oi = rn->info;
+ if (!oi)
+ continue;
+
+ oi->gr.hello_delay.elapsed_seconds = 0;
+ EVENT_OFF(oi->gr.hello_delay.t_grace_send);
+ }
+
+ return CMD_SUCCESS;
+}
+
DEFUN (ip_ospf_transmit_delay,
ip_ospf_transmit_delay_addr_cmd,
"ip ospf transmit-delay (1-65535) [A.B.C.D]",
@@ -9380,6 +9636,8 @@ DEFUN (ospf_default_metric,
ospf->default_metric = metric;
+ ospf_schedule_asbr_redist_update(ospf);
+
return CMD_SUCCESS;
}
@@ -9394,6 +9652,8 @@ DEFUN (no_ospf_default_metric,
ospf->default_metric = -1;
+ ospf_schedule_asbr_redist_update(ospf);
+
return CMD_SUCCESS;
}
@@ -9570,6 +9830,111 @@ DEFUN (no_ip_ospf_mtu_ignore,
return CMD_SUCCESS;
}
+DEFPY(ip_ospf_capability_opaque, ip_ospf_capability_opaque_addr_cmd,
+ "[no] ip ospf capability opaque [A.B.C.D]$ip_addr",
+ NO_STR
+ "IP Information\n"
+ "OSPF interface commands\n"
+ "Disable OSPF capability on this interface\n"
+ "Disable OSPF opaque LSA capability on this interface\n"
+ "Address of interface\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct route_node *rn;
+ bool old_opaque_capable;
+ bool opaque_capable_change;
+
+ struct ospf_if_params *params;
+ params = IF_DEF_PARAMS(ifp);
+
+ if (ip_addr.s_addr != INADDR_ANY) {
+ params = ospf_get_if_params(ifp, ip_addr);
+ ospf_if_update_params(ifp, ip_addr);
+ }
+
+ old_opaque_capable = params->opaque_capable;
+ params->opaque_capable = (no) ? false : true;
+ opaque_capable_change = (old_opaque_capable != params->opaque_capable);
+ if (params->opaque_capable != OSPF_OPAQUE_CAPABLE_DEFAULT)
+ SET_IF_PARAM(params, opaque_capable);
+ else {
+ UNSET_IF_PARAM(params, opaque_capable);
+ if (params != IF_DEF_PARAMS(ifp)) {
+ ospf_free_if_params(ifp, ip_addr);
+ ospf_if_update_params(ifp, ip_addr);
+ }
+ }
+
+ /*
+ * If there is a change to the opaque capability, flap the interface
+ * to reset all the neighbor adjacencies.
+ */
+ if (opaque_capable_change) {
+ for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
+ struct ospf_interface *oi = rn->info;
+
+ if (oi && (oi->state > ISM_Down) &&
+ (ip_addr.s_addr == INADDR_ANY ||
+ IPV4_ADDR_SAME(&oi->address->u.prefix4,
+ &ip_addr))) {
+ OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceDown);
+ OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceUp);
+ }
+ }
+ }
+ return CMD_SUCCESS;
+}
+
+
+DEFPY(ip_ospf_prefix_suppression, ip_ospf_prefix_suppression_addr_cmd,
+ "[no] ip ospf prefix-suppression [A.B.C.D]$ip_addr", NO_STR
+ "IP Information\n"
+ "OSPF interface commands\n"
+ "Supress OSPF prefix advertisement on this interface\n"
+ "Address of interface\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct route_node *rn;
+ bool prefix_suppression_change;
+ struct ospf_if_params *params;
+
+ params = IF_DEF_PARAMS(ifp);
+
+ if (ip_addr.s_addr != INADDR_ANY) {
+ params = ospf_get_if_params(ifp, ip_addr);
+ ospf_if_update_params(ifp, ip_addr);
+ }
+
+ prefix_suppression_change = (params->prefix_suppression == (bool)no);
+ params->prefix_suppression = (no) ? false : true;
+ if (params->prefix_suppression != OSPF_PREFIX_SUPPRESSION_DEFAULT)
+ SET_IF_PARAM(params, prefix_suppression);
+ else {
+ UNSET_IF_PARAM(params, prefix_suppression);
+ if (params != IF_DEF_PARAMS(ifp)) {
+ ospf_free_if_params(ifp, ip_addr);
+ ospf_if_update_params(ifp, ip_addr);
+ }
+ }
+
+ /*
+ * If there is a change to the prefix suppression, update the Router-LSA.
+ */
+ if (prefix_suppression_change) {
+ for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
+ struct ospf_interface *oi = rn->info;
+
+ if (oi && (oi->state > ISM_Down) &&
+ (ip_addr.s_addr == INADDR_ANY ||
+ IPV4_ADDR_SAME(&oi->address->u.prefix4, &ip_addr))) {
+ (void)ospf_router_lsa_update_area(oi->area);
+ if (oi->state == ISM_DR)
+ ospf_network_lsa_update(oi);
+ }
+ }
+ }
+ return CMD_SUCCESS;
+}
DEFUN (ospf_max_metric_router_lsa_admin,
ospf_max_metric_router_lsa_admin_cmd,
@@ -10368,38 +10733,23 @@ DEFPY (show_ip_ospf_gr_helper,
}
ospf = ospf_lookup_by_inst_name(inst, vrf_name);
-
- if (ospf == NULL || !ospf->oi_running) {
-
- if (uj)
- vty_json(vty, json);
- else
- vty_out(vty,
- "%% OSPF is not enabled in vrf %s\n",
- vrf_name);
-
- return CMD_SUCCESS;
- }
-
} else {
/* Default Vrf */
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ }
- if (ospf == NULL || !ospf->oi_running) {
-
- if (uj)
- vty_json(vty, json);
- else
- vty_out(vty,
- "%% OSPF is not enabled in vrf default\n");
+ if (ospf == NULL || !ospf->oi_running) {
- return CMD_SUCCESS;
- }
+ if (uj)
+ vty_json(vty, json);
+ else
+ vty_out(vty,
+ "%% OSPF is not enabled in vrf %s\n", vrf_name ? vrf_name : "default");
- ospf_show_gr_helper_details(vty, ospf, use_vrf, json, uj,
- detail);
+ return CMD_SUCCESS;
}
+ ospf_show_gr_helper_details(vty, ospf, use_vrf, json, uj, detail);
if (uj)
vty_json(vty, json);
@@ -10438,7 +10788,7 @@ static void config_write_stub_router(struct vty *vty, struct ospf *ospf)
static void show_ip_ospf_route_network(struct vty *vty, struct ospf *ospf,
struct route_table *rt,
- json_object *json)
+ json_object *json, bool detail)
{
struct route_node *rn;
struct ospf_route * or ;
@@ -10498,15 +10848,17 @@ static void show_ip_ospf_route_network(struct vty *vty, struct ospf *ospf,
if (json) {
json_object_string_add(json_route, "routeType",
"N");
+ json_object_boolean_add(json_route, "transit",
+ or->u.std.transit);
json_object_int_add(json_route, "cost",
or->cost);
json_object_string_addf(json_route, "area",
"%pI4",
&or->u.std.area_id);
} else {
- vty_out(vty, "N %-18s [%d] area: %pI4\n",
- buf1, or->cost,
- &or->u.std.area_id);
+ vty_out(vty, "N %s %-18s [%d] area: %pI4\n",
+ or->u.std.transit && detail ? "T" : " ",
+ buf1, or->cost, &or->u.std.area_id);
}
break;
default:
@@ -10563,6 +10915,11 @@ static void show_ip_ospf_route_network(struct vty *vty, struct ospf *ospf,
ifindex2ifname(
path->ifindex,
ospf->vrf_id));
+ json_object_string_addf(
+ json_nexthop,
+ "advertisedRouter",
+ "%pI4",
+ &path->adv_router);
} else {
vty_out(vty,
"%24s via %pI4, %s\n",
@@ -10572,6 +10929,11 @@ static void show_ip_ospf_route_network(struct vty *vty, struct ospf *ospf,
path->ifindex,
ospf->vrf_id));
}
+ if (detail && !json)
+ vty_out(vty,
+ "%24s adv %pI4\n",
+ "",
+ &path->adv_router);
}
}
}
@@ -10726,7 +11088,7 @@ static void show_ip_ospf_route_router(struct vty *vty, struct ospf *ospf,
static void show_ip_ospf_route_external(struct vty *vty, struct ospf *ospf,
struct route_table *rt,
- json_object *json)
+ json_object *json, bool detail)
{
struct route_node *rn;
struct ospf_route *er;
@@ -10830,6 +11192,11 @@ static void show_ip_ospf_route_external(struct vty *vty, struct ospf *ospf,
ifindex2ifname(
path->ifindex,
ospf->vrf_id));
+ json_object_string_addf(
+ json_nexthop,
+ "advertisedRouter",
+ "%pI4",
+ &path->adv_router);
} else {
vty_out(vty,
"%24s via %pI4, %s\n",
@@ -10839,6 +11206,10 @@ static void show_ip_ospf_route_external(struct vty *vty, struct ospf *ospf,
path->ifindex,
ospf->vrf_id));
}
+ if (detail && !json)
+ vty_out(vty,
+ "%24s adv %pI4\n", "",
+ &path->adv_router);
}
}
}
@@ -11125,7 +11496,8 @@ DEFUN (show_ip_ospf_instance_border_routers,
}
static int show_ip_ospf_route_common(struct vty *vty, struct ospf *ospf,
- json_object *json, uint8_t use_vrf)
+ json_object *json, uint8_t use_vrf,
+ bool detail)
{
json_object *json_vrf = NULL;
@@ -11152,8 +11524,15 @@ static int show_ip_ospf_route_common(struct vty *vty, struct ospf *ospf,
return CMD_SUCCESS;
}
+ if (detail && json == NULL) {
+ vty_out(vty, "Codes: N - network T - transitive\n");
+ vty_out(vty, " IA - inter-area E - external route\n");
+ vty_out(vty, " D - destination R - router\n\n");
+ }
+
/* Show Network routes. */
- show_ip_ospf_route_network(vty, ospf, ospf->new_table, json_vrf);
+ show_ip_ospf_route_network(vty, ospf, ospf->new_table, json_vrf,
+ detail);
/* Show Router routes. */
show_ip_ospf_route_router(vty, ospf, ospf->new_rtrs, json_vrf);
@@ -11164,7 +11543,7 @@ static int show_ip_ospf_route_common(struct vty *vty, struct ospf *ospf,
/* Show AS External routes. */
show_ip_ospf_route_external(vty, ospf, ospf->old_external_route,
- json_vrf);
+ json_vrf, detail);
if (json) {
if (use_vrf) {
@@ -11182,13 +11561,14 @@ static int show_ip_ospf_route_common(struct vty *vty, struct ospf *ospf,
DEFUN (show_ip_ospf_route,
show_ip_ospf_route_cmd,
- "show ip ospf [vrf <NAME|all>] route [json]",
+ "show ip ospf [vrf <NAME|all>] route [detail] [json]",
SHOW_STR
IP_STR
"OSPF information\n"
VRF_CMD_HELP_STR
"All VRFs\n"
"OSPF routing table\n"
+ "Detailed information\n"
JSON_STR)
{
struct ospf *ospf = NULL;
@@ -11197,14 +11577,19 @@ DEFUN (show_ip_ospf_route,
bool all_vrf = false;
int ret = CMD_SUCCESS;
int inst = 0;
+ int idx = 0;
int idx_vrf = 0;
uint8_t use_vrf = 0;
bool uj = use_json(argc, argv);
+ bool detail = false;
json_object *json = NULL;
if (uj)
json = json_object_new_object();
+ if (argv_find(argv, argc, "detail", &idx))
+ detail = true;
+
OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
/* vrf input is provided could be all or specific vrf*/
@@ -11218,8 +11603,8 @@ DEFUN (show_ip_ospf_route,
if (!ospf->oi_running)
continue;
ospf_output = true;
- ret = show_ip_ospf_route_common(vty, ospf, json,
- use_vrf);
+ ret = show_ip_ospf_route_common(
+ vty, ospf, json, use_vrf, detail);
}
if (uj) {
@@ -11256,7 +11641,8 @@ DEFUN (show_ip_ospf_route,
}
if (ospf) {
- ret = show_ip_ospf_route_common(vty, ospf, json, use_vrf);
+ ret = show_ip_ospf_route_common(vty, ospf, json, use_vrf,
+ detail);
/* Keep Non-pretty format */
if (uj)
vty_out(vty, "%s\n",
@@ -11272,16 +11658,22 @@ DEFUN (show_ip_ospf_route,
DEFUN (show_ip_ospf_instance_route,
show_ip_ospf_instance_route_cmd,
- "show ip ospf (1-65535) route",
+ "show ip ospf (1-65535) route [detail]",
SHOW_STR
IP_STR
"OSPF information\n"
"Instance ID\n"
- "OSPF routing table\n")
+ "OSPF routing table\n"
+ "Detailed information\n")
{
int idx_number = 3;
+ int idx = 0;
struct ospf *ospf;
unsigned short instance = 0;
+ bool detail = false;
+
+ if (argv_find(argv, argc, "detail", &idx))
+ detail = true;
instance = strtoul(argv[idx_number]->arg, NULL, 10);
if (instance != ospf_instance)
@@ -11291,7 +11683,7 @@ DEFUN (show_ip_ospf_instance_route,
if (!ospf || !ospf->oi_running)
return CMD_SUCCESS;
- return show_ip_ospf_route_common(vty, ospf, NULL, 0);
+ return show_ip_ospf_route_common(vty, ospf, NULL, 0, detail);
}
@@ -11513,7 +11905,7 @@ static int ospf_show_summary_address(struct vty *vty, struct ospf *ospf,
ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
if (!uj) {
- vty_out(vty, "aggregation delay interval :%u(in seconds)\n\n",
+ vty_out(vty, "aggregation delay interval: %u(in seconds)\n\n",
ospf->aggr_delay_interval);
} else {
json_object_int_add(json_vrf, "aggregationDelayInterval",
@@ -11687,11 +12079,11 @@ static const char *const ospf_int_type_str[] = {
"loopback"
};
-static const char *interface_config_auth_str(struct ospf_if_params *params)
+static int interface_config_auth_str(struct ospf_if_params *params, char *buf)
{
if (!OSPF_IF_PARAM_CONFIGURED(params, auth_type)
|| params->auth_type == OSPF_AUTH_NOTSET)
- return NULL;
+ return 0;
/* Translation tables are not that much help
* here due to syntax
@@ -11699,16 +12091,22 @@ static const char *interface_config_auth_str(struct ospf_if_params *params)
switch (params->auth_type) {
case OSPF_AUTH_NULL:
- return " null";
+ snprintf(buf, BUFSIZ, " null");
+ break;
case OSPF_AUTH_SIMPLE:
- return "";
+ snprintf(buf, BUFSIZ, " ");
+ break;
case OSPF_AUTH_CRYPTOGRAPHIC:
- return " message-digest";
+ if (OSPF_IF_PARAM_CONFIGURED(params, keychain_name))
+ snprintf(buf, BUFSIZ, " key-chain %s", params->keychain_name);
+ else
+ snprintf(buf, BUFSIZ, " message-digest");
+ break;
}
- return "";
+ return 1;
}
static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
@@ -11718,7 +12116,8 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
struct crypt_key *ck;
struct route_node *rn = NULL;
struct ospf_if_params *params;
- const char *auth_str;
+ char buf[BUFSIZ];
+ int ret = 0;
int write = 0;
FOR_ALL_INTERFACES (vrf, ifp) {
@@ -11747,6 +12146,14 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
== OSPF_IFTYPE_POINTOPOINT
&& params->ptp_dmvpn)
vty_out(vty, " dmvpn");
+ if (params->type ==
+ OSPF_IFTYPE_POINTOMULTIPOINT &&
+ params->p2mp_delay_reflood)
+ vty_out(vty, " delay-reflood");
+ if (params->type ==
+ OSPF_IFTYPE_POINTOMULTIPOINT &&
+ params->p2mp_non_broadcast)
+ vty_out(vty, " non-broadcast");
if (params != IF_DEF_PARAMS(ifp) && rn)
vty_out(vty, " %pI4",
&rn->p.u.prefix4);
@@ -11755,10 +12162,10 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
}
/* OSPF interface authentication print */
- auth_str = interface_config_auth_str(params);
- if (auth_str) {
+ ret = interface_config_auth_str(params, buf);
+ if (ret) {
vty_out(vty, " ip ospf authentication%s",
- auth_str);
+ buf);
if (params != IF_DEF_PARAMS(ifp) && rn)
vty_out(vty, " %pI4",
&rn->p.u.prefix4);
@@ -11832,6 +12239,15 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
vty_out(vty, "\n");
}
+ /* Hello Graceful-Restart Delay print. */
+ if (OSPF_IF_PARAM_CONFIGURED(params,
+ v_gr_hello_delay) &&
+ params->v_gr_hello_delay !=
+ OSPF_HELLO_DELAY_DEFAULT)
+ vty_out(vty,
+ " ip ospf graceful-restart hello-delay %u\n",
+ params->v_gr_hello_delay);
+
/* Router Priority print. */
if (OSPF_IF_PARAM_CONFIGURED(params, priority)
&& params->priority
@@ -11921,6 +12337,37 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
if (params && params->ldp_sync_info)
ospf_ldp_sync_if_write_config(vty, params);
+ /* Capability opaque print. */
+ if (OSPF_IF_PARAM_CONFIGURED(params, opaque_capable) &&
+ params->opaque_capable !=
+ OSPF_OPAQUE_CAPABLE_DEFAULT) {
+ if (params->opaque_capable == false)
+ vty_out(vty,
+ " no ip ospf capability opaque");
+ else
+ vty_out(vty,
+ " ip ospf capability opaque");
+ if (params != IF_DEF_PARAMS(ifp) && rn)
+ vty_out(vty, " %pI4", &rn->p.u.prefix4);
+ vty_out(vty, "\n");
+ }
+
+ /* prefix-suppression print. */
+ if (OSPF_IF_PARAM_CONFIGURED(params,
+ prefix_suppression) &&
+ params->prefix_suppression !=
+ OSPF_PREFIX_SUPPRESSION_DEFAULT) {
+ if (params->prefix_suppression == false)
+ vty_out(vty,
+ " no ip ospf prefix-suppression");
+ else
+ vty_out(vty,
+ " ip ospf prefix-suppression");
+ if (params != IF_DEF_PARAMS(ifp) && rn)
+ vty_out(vty, " %pI4", &rn->p.u.prefix4);
+ vty_out(vty, "\n");
+ }
+
while (1) {
if (rn == NULL)
rn = route_top(IF_OIFS_PARAMS(ifp));
@@ -12158,8 +12605,9 @@ static int config_write_virtual_link(struct vty *vty, struct ospf *ospf)
{
struct listnode *node;
struct ospf_vl_data *vl_data;
- const char *auth_str;
char buf[INET_ADDRSTRLEN];
+ char buf2[BUFSIZ];
+ int ret = 0;
/* Virtual-Link print */
for (ALL_LIST_ELEMENTS_RO(ospf->vlinks, node, vl_data)) {
@@ -12192,12 +12640,12 @@ static int config_write_virtual_link(struct vty *vty, struct ospf *ospf)
vty_out(vty, " area %s virtual-link %pI4\n", buf,
&vl_data->vl_peer);
/* Auth type */
- auth_str = interface_config_auth_str(
- IF_DEF_PARAMS(oi->ifp));
- if (auth_str)
+ ret = interface_config_auth_str(
+ IF_DEF_PARAMS(oi->ifp), buf2);
+ if (ret)
vty_out(vty,
" area %s virtual-link %pI4 authentication%s\n",
- buf, &vl_data->vl_peer, auth_str);
+ buf, &vl_data->vl_peer, buf2);
/* Auth key */
if (IF_DEF_PARAMS(vl_data->vl_oi->ifp)->auth_simple[0]
!= '\0')
@@ -12730,6 +13178,12 @@ static void ospf_vty_if_init(void)
install_element(INTERFACE_NODE, &ip_ospf_passive_cmd);
install_element(INTERFACE_NODE, &no_ip_ospf_passive_cmd);
+ /* "ip ospf capability opaque" commands. */
+ install_element(INTERFACE_NODE, &ip_ospf_capability_opaque_addr_cmd);
+
+ /* "ip ospf prefix-suppression" commands. */
+ install_element(INTERFACE_NODE, &ip_ospf_prefix_suppression_addr_cmd);
+
/* These commands are compatibitliy for previous version. */
install_element(INTERFACE_NODE, &ospf_authentication_key_cmd);
install_element(INTERFACE_NODE, &ospf_message_digest_key_cmd);
@@ -13228,11 +13682,8 @@ void ospf_vty_init(void)
install_element(OSPF_NODE, &ospf_auto_cost_reference_bandwidth_cmd);
install_element(OSPF_NODE, &no_ospf_auto_cost_reference_bandwidth_cmd);
- /* "neighbor" commands. */
+ /* "neighbor" command. */
install_element(OSPF_NODE, &ospf_neighbor_cmd);
- install_element(OSPF_NODE, &ospf_neighbor_poll_interval_cmd);
- install_element(OSPF_NODE, &no_ospf_neighbor_cmd);
- install_element(OSPF_NODE, &no_ospf_neighbor_poll_cmd);
/* write multiplier commands */
install_element(OSPF_NODE, &ospf_write_multiplier_cmd);