diff options
| author | Russ White <russ@riw.us> | 2023-07-11 11:47:32 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-07-11 11:47:32 -0400 |
| commit | 6e89a5db228c75d83f9be7b3606b91257e0307d3 (patch) | |
| tree | 3d8e0dc9474ea768c653b4d7697cbf1fe5c07112 /ospfd | |
| parent | c8971388a9013ffb65b4de20fd1553f6e1e94311 (diff) | |
| parent | e72549c8f6f7b25738f8d4c913db025a7906558e (diff) | |
Merge pull request #13691 from LabNConsulting/aceelindem/ospf-opaque-interface-disable
ospfd: Configurable interface-level 'capability opaque' support
Diffstat (limited to 'ospfd')
| -rw-r--r-- | ospfd/ospf_flood.c | 9 | ||||
| -rw-r--r-- | ospfd/ospf_gr.c | 11 | ||||
| -rw-r--r-- | ospfd/ospf_interface.c | 32 | ||||
| -rw-r--r-- | ospfd/ospf_interface.h | 3 | ||||
| -rw-r--r-- | ospfd/ospf_opaque.c | 6 | ||||
| -rw-r--r-- | ospfd/ospf_packet.c | 16 | ||||
| -rw-r--r-- | ospfd/ospf_vty.c | 79 |
7 files changed, 132 insertions, 24 deletions
diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index 5ae15fd887..dd8c9268f1 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -568,6 +568,15 @@ int ospf_flood_through_interface(struct ospf_interface *oi, if (!ospf_if_is_enable(oi)) return 0; + if (IS_OPAQUE_LSA(lsa->data->type) && + !OSPF_IF_PARAM(oi, opaque_capable)) { + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) + zlog_debug( + "%s: Skipping interface %s (%s) with opaque disabled.", + __func__, IF_NAME(oi), ospf_get_name(oi->ospf)); + return 0; + } + /* If flood reduction is configured, set the DC bit on the lsa. */ if (IS_LSA_SELF(lsa)) { if (OSPF_FR_CONFIG(oi->area->ospf, oi->area)) { diff --git a/ospfd/ospf_gr.c b/ospfd/ospf_gr.c index 2a346f2388..c23c42052f 100644 --- a/ospfd/ospf_gr.c +++ b/ospfd/ospf_gr.c @@ -773,8 +773,15 @@ static void ospf_gr_prepare(void) } /* Send a Grace-LSA to all neighbors. */ - for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, inode, oi)) - ospf_gr_lsa_originate(oi, OSPF_GR_SW_RESTART, false); + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, inode, oi)) { + if (OSPF_IF_PARAM(oi, opaque_capable)) + ospf_gr_lsa_originate(oi, OSPF_GR_SW_RESTART, + false); + else + zlog_debug( + "GR: skipping grace LSA on interface %s (%s) with opaque capability disabled", + IF_NAME(oi), ospf_get_name(oi->ospf)); + } /* Record end of the grace period in non-volatile memory. */ ospf_gr_nvm_update(ospf, true); diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index 840756c05c..72de198116 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -548,6 +548,7 @@ static struct ospf_if_params *ospf_new_if_params(void) UNSET_IF_PARAM(oip, auth_crypt); UNSET_IF_PARAM(oip, auth_type); UNSET_IF_PARAM(oip, if_area); + UNSET_IF_PARAM(oip, opaque_capable); oip->auth_crypt = list_new(); @@ -556,6 +557,7 @@ static struct ospf_if_params *ospf_new_if_params(void) oip->ptp_dmvpn = 0; oip->p2mp_delay_reflood = OSPF_P2MP_DELAY_REFLOOD_DEFAULT; + oip->opaque_capable = OSPF_OPAQUE_CAPABLE_DEFAULT; return oip; } @@ -585,19 +587,20 @@ void ospf_free_if_params(struct interface *ifp, struct in_addr addr) oip = rn->info; route_unlock_node(rn); - if (!OSPF_IF_PARAM_CONFIGURED(oip, output_cost_cmd) - && !OSPF_IF_PARAM_CONFIGURED(oip, transmit_delay) - && !OSPF_IF_PARAM_CONFIGURED(oip, retransmit_interval) - && !OSPF_IF_PARAM_CONFIGURED(oip, passive_interface) - && !OSPF_IF_PARAM_CONFIGURED(oip, v_hello) - && !OSPF_IF_PARAM_CONFIGURED(oip, fast_hello) - && !OSPF_IF_PARAM_CONFIGURED(oip, v_wait) - && !OSPF_IF_PARAM_CONFIGURED(oip, priority) - && !OSPF_IF_PARAM_CONFIGURED(oip, type) - && !OSPF_IF_PARAM_CONFIGURED(oip, auth_simple) - && !OSPF_IF_PARAM_CONFIGURED(oip, auth_type) - && !OSPF_IF_PARAM_CONFIGURED(oip, if_area) - && listcount(oip->auth_crypt) == 0) { + if (!OSPF_IF_PARAM_CONFIGURED(oip, output_cost_cmd) && + !OSPF_IF_PARAM_CONFIGURED(oip, transmit_delay) && + !OSPF_IF_PARAM_CONFIGURED(oip, retransmit_interval) && + !OSPF_IF_PARAM_CONFIGURED(oip, passive_interface) && + !OSPF_IF_PARAM_CONFIGURED(oip, v_hello) && + !OSPF_IF_PARAM_CONFIGURED(oip, fast_hello) && + !OSPF_IF_PARAM_CONFIGURED(oip, v_wait) && + !OSPF_IF_PARAM_CONFIGURED(oip, priority) && + !OSPF_IF_PARAM_CONFIGURED(oip, type) && + !OSPF_IF_PARAM_CONFIGURED(oip, auth_simple) && + !OSPF_IF_PARAM_CONFIGURED(oip, auth_type) && + !OSPF_IF_PARAM_CONFIGURED(oip, if_area) && + !OSPF_IF_PARAM_CONFIGURED(oip, opaque_capable) && + listcount(oip->auth_crypt) == 0) { ospf_del_if_params(ifp, oip); rn->info = NULL; route_unlock_node(rn); @@ -703,6 +706,9 @@ int ospf_if_new_hook(struct interface *ifp) SET_IF_PARAM(IF_DEF_PARAMS(ifp), auth_type); IF_DEF_PARAMS(ifp)->auth_type = OSPF_AUTH_NOTSET; + SET_IF_PARAM(IF_DEF_PARAMS(ifp), opaque_capable); + IF_DEF_PARAMS(ifp)->opaque_capable = OSPF_OPAQUE_CAPABLE_DEFAULT; + rc = ospf_opaque_new_if(ifp); return rc; } diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h index ec1afa1b8b..38ec45c757 100644 --- a/ospfd/ospf_interface.h +++ b/ospfd/ospf_interface.h @@ -112,6 +112,9 @@ struct ospf_if_params { /* point-to-multipoint delayed reflooding configuration */ bool p2mp_delay_reflood; + + /* Opaque LSA capability at interface level (see RFC5250) */ + DECLARE_IF_PARAM(bool, opaque_capable); }; enum { MEMBER_ALLROUTERS = 0, diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c index 6894c6a009..27f47a6d79 100644 --- a/ospfd/ospf_opaque.c +++ b/ospfd/ospf_opaque.c @@ -1851,9 +1851,9 @@ static void ospf_opaque_type9_lsa_reoriginate_timer(struct event *t) return; } - if (!CHECK_FLAG(top->config, OSPF_OPAQUE_CAPABLE) - || !ospf_if_is_enable(oi) - || ospf_nbr_count_opaque_capable(oi) == 0) { + if (!CHECK_FLAG(top->config, OSPF_OPAQUE_CAPABLE) || + !OSPF_IF_PARAM(oi, opaque_capable) || !ospf_if_is_enable(oi) || + ospf_nbr_count_opaque_capable(oi) == 0) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( "Suspend re-origination of Type-9 Opaque-LSAs (opaque-type=%u) for a while...", diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 105c04c7a1..cfa0d5d574 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -953,8 +953,9 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh, } #endif /* REJECT_IF_TBIT_ON */ - if (CHECK_FLAG(oi->ospf->config, OSPF_OPAQUE_CAPABLE) - && CHECK_FLAG(hello->options, OSPF_OPTION_O)) { + if (CHECK_FLAG(oi->ospf->config, OSPF_OPAQUE_CAPABLE) && + OSPF_IF_PARAM(oi, opaque_capable) && + CHECK_FLAG(hello->options, OSPF_OPTION_O)) { /* * This router does know the correct usage of O-bit * the bit should be set in DD packet only. @@ -1362,8 +1363,9 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, } #endif /* REJECT_IF_TBIT_ON */ - if (CHECK_FLAG(dd->options, OSPF_OPTION_O) - && !CHECK_FLAG(oi->ospf->config, OSPF_OPAQUE_CAPABLE)) { + if (CHECK_FLAG(dd->options, OSPF_OPTION_O) && + (!CHECK_FLAG(oi->ospf->config, OSPF_OPAQUE_CAPABLE) || + !OSPF_IF_PARAM(oi, opaque_capable))) { /* * This node is not configured to handle O-bit, for now. * Clear it to ignore unsupported capability proposed by @@ -1448,7 +1450,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, /* This is where the real Options are saved */ nbr->options = dd->options; - if (CHECK_FLAG(oi->ospf->config, OSPF_OPAQUE_CAPABLE)) { + if (CHECK_FLAG(oi->ospf->config, OSPF_OPAQUE_CAPABLE) && + OSPF_IF_PARAM(oi, opaque_capable)) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( "Neighbor[%pI4] is %sOpaque-capable.", @@ -3435,7 +3438,8 @@ static int ospf_make_db_desc(struct ospf_interface *oi, /* Set Options. */ options = OPTIONS(oi); - if (CHECK_FLAG(oi->ospf->config, OSPF_OPAQUE_CAPABLE)) + if (CHECK_FLAG(oi->ospf->config, OSPF_OPAQUE_CAPABLE) && + OSPF_IF_PARAM(oi, opaque_capable)) SET_FLAG(options, OSPF_OPTION_O); if (OSPF_FR_CONFIG(oi->ospf, oi->area)) SET_FLAG(options, OSPF_OPTION_DC); diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 863055bf42..54fd60af23 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -3811,6 +3811,9 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, 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)); @@ -3830,6 +3833,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. */ @@ -9803,6 +9809,61 @@ 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; +} + DEFUN (ospf_max_metric_router_lsa_admin, ospf_max_metric_router_lsa_admin_cmd, @@ -12167,6 +12228,21 @@ 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"); + } + while (1) { if (rn == NULL) rn = route_top(IF_OIFS_PARAMS(ifp)); @@ -12976,6 +13052,9 @@ 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); + /* These commands are compatibitliy for previous version. */ install_element(INTERFACE_NODE, &ospf_authentication_key_cmd); install_element(INTERFACE_NODE, &ospf_message_digest_key_cmd); |
