diff options
Diffstat (limited to 'ospfd/ospf_vty.c')
| -rw-r--r-- | ospfd/ospf_vty.c | 939 |
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); |
