diff options
author | Donatas Abraitis <donatas@opensourcerouting.org> | 2023-07-21 09:14:22 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-21 09:14:22 +0200 |
commit | 3a58764e3a7a5912187d5d062e06044bc1cd7044 (patch) | |
tree | afeda04df0af66d136cfd53e3d7a83f7f5a92aa0 /ospfd | |
parent | Merge pull request #14066 from opensourcerouting/fix/libyang_2.1.80 (diff) | |
parent | ospfd: Implement OSPF prefix-suppression as specified in RFC 6860 (diff) | |
download | frr-3a58764e3a7a5912187d5d062e06044bc1cd7044.tar.xz frr-3a58764e3a7a5912187d5d062e06044bc1cd7044.zip |
Merge pull request #14034 from LabNConsulting/aceelindem/ospf_prefix_suppression
ospfd: Implement OSPF prefix-suppression as specified in RFC 6860
Diffstat (limited to 'ospfd')
-rw-r--r-- | ospfd/ospf_interface.c | 3 | ||||
-rw-r--r-- | ospfd/ospf_interface.h | 3 | ||||
-rw-r--r-- | ospfd/ospf_lsa.c | 72 | ||||
-rw-r--r-- | ospfd/ospf_route.c | 6 | ||||
-rw-r--r-- | ospfd/ospf_vty.c | 83 |
5 files changed, 146 insertions, 21 deletions
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index 72de19811..bdab672b4 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -600,6 +600,7 @@ void ospf_free_if_params(struct interface *ifp, struct in_addr addr) !OSPF_IF_PARAM_CONFIGURED(oip, auth_type) && !OSPF_IF_PARAM_CONFIGURED(oip, if_area) && !OSPF_IF_PARAM_CONFIGURED(oip, opaque_capable) && + !OSPF_IF_PARAM_CONFIGURED(oip, prefix_suppression) && listcount(oip->auth_crypt) == 0) { ospf_del_if_params(ifp, oip); rn->info = NULL; @@ -709,6 +710,8 @@ int ospf_if_new_hook(struct interface *ifp) SET_IF_PARAM(IF_DEF_PARAMS(ifp), opaque_capable); IF_DEF_PARAMS(ifp)->opaque_capable = OSPF_OPAQUE_CAPABLE_DEFAULT; + IF_DEF_PARAMS(ifp)->prefix_suppression = OSPF_PREFIX_SUPPRESSION_DEFAULT; + rc = ospf_opaque_new_if(ifp); return rc; } diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h index 38ec45c75..47b70f803 100644 --- a/ospfd/ospf_interface.h +++ b/ospfd/ospf_interface.h @@ -81,6 +81,9 @@ struct ospf_if_params { /* Fast-Hellos */ DECLARE_IF_PARAM(uint8_t, fast_hello); + /* Prefix-Suppression */ + DECLARE_IF_PARAM(bool, prefix_suppression); + /* Authentication data. */ uint8_t auth_simple[OSPF_AUTH_SIMPLE_SIZE + 1]; /* Simple password. */ uint8_t auth_simple__config : 1; diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 27e7e0275..7ef983427 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -539,16 +539,23 @@ static int lsa_link_ptop_set(struct stream **s, struct ospf_interface *oi) } /* no need for a stub link for unnumbered interfaces */ - if (oi->ptp_dmvpn - || !CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED)) { - /* Regardless of the state of the neighboring router, we must - add a Type 3 link (stub network). - N.B. Options 1 & 2 share basically the same logic. */ - masklen2ip(oi->address->prefixlen, &mask); - id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr - & mask.s_addr; - links += link_info_set(s, id, mask, LSA_LINK_TYPE_STUB, 0, - oi->output_cost); + if (OSPF_IF_PARAM(oi, prefix_suppression)) { + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug("LSA[Type1]: Interface %s stub link omitted due prefix-suppression", + oi->ifp->name); + } else { + if (oi->ptp_dmvpn || + !CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED)) { + /* Regardless of the state of the neighboring router, we must + add a Type 3 link (stub network). + N.B. Options 1 & 2 share basically the same logic. */ + masklen2ip(oi->address->prefixlen, &mask); + id.s_addr = + CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr & + mask.s_addr; + links += link_info_set(s, id, mask, LSA_LINK_TYPE_STUB, + 0, oi->output_cost); + } } return links; @@ -563,10 +570,15 @@ static int lsa_link_broadcast_set(struct stream **s, struct ospf_interface *oi) /* Describe Type 3 Link. */ if (oi->state == ISM_Waiting) { + if (OSPF_IF_PARAM(oi, prefix_suppression)) { + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug("LSA[Type1]: Interface %s stub link omitted due prefix-suppression", + oi->ifp->name); + return 0; + } if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) - zlog_debug( - "LSA[Type1]: Interface %s is in state Waiting. Adding stub interface", - oi->ifp->name); + zlog_debug("LSA[Type1]: Interface %s is in state Waiting. Adding stub interface", + oi->ifp->name); masklen2ip(oi->address->prefixlen, &mask); id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr; return link_info_set(s, id, mask, LSA_LINK_TYPE_STUB, 0, @@ -587,10 +599,15 @@ static int lsa_link_broadcast_set(struct stream **s, struct ospf_interface *oi) } /* Describe type 3 link. */ else { + if (OSPF_IF_PARAM(oi, prefix_suppression)) { + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug("LSA[Type1]: Interface %s stub link omitted due prefix-suppression", + oi->ifp->name); + return 0; + } if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) - zlog_debug( - "LSA[Type1]: Interface %s has no DR. Adding stub interface", - oi->ifp->name); + zlog_debug("LSA[Type1]: Interface %s has no DR. Adding stub interface", + oi->ifp->name); masklen2ip(oi->address->prefixlen, &mask); id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr; return link_info_set(s, id, mask, LSA_LINK_TYPE_STUB, 0, @@ -603,7 +620,7 @@ static int lsa_link_loopback_set(struct stream **s, struct ospf_interface *oi) struct in_addr id, mask; /* Describe Type 3 Link. */ - if (oi->state != ISM_Loopback) + if ((oi->state != ISM_Loopback) || OSPF_IF_PARAM(oi, prefix_suppression)) return 0; mask.s_addr = 0xffffffff; @@ -645,9 +662,15 @@ static int lsa_link_ptomp_set(struct stream **s, struct ospf_interface *oi) struct in_addr id, mask; uint16_t cost = ospf_link_cost(oi); - mask.s_addr = 0xffffffff; - id.s_addr = oi->address->u.prefix4.s_addr; - links += link_info_set(s, id, mask, LSA_LINK_TYPE_STUB, 0, 0); + if (OSPF_IF_PARAM(oi, prefix_suppression)) { + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug("LSA[Type1]: Interface %s stub link omitted due prefix-suppression", + oi->ifp->name); + } else { + mask.s_addr = 0xffffffff; + id.s_addr = oi->address->u.prefix4.s_addr; + links += link_info_set(s, id, mask, LSA_LINK_TYPE_STUB, 0, 0); + } if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) zlog_debug("PointToMultipoint: running ptomultip_set"); @@ -1006,7 +1029,14 @@ static void ospf_network_lsa_body_set(struct stream *s, struct route_node *rn; struct ospf_neighbor *nbr; - masklen2ip(oi->address->prefixlen, &mask); + if (OSPF_IF_PARAM(oi, prefix_suppression)) { + mask.s_addr = 0xffffffff; + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug("LSA[Type2]: Interface %s network mask set to host mask due prefix-suppression", + oi->ifp->name); + } else { + masklen2ip(oi->address->prefixlen, &mask); + } stream_put_ipv4(s, mask.s_addr); /* The network-LSA lists those routers that are fully adjacent to diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c index 3ffa7c0bb..170909fa9 100644 --- a/ospfd/ospf_route.c +++ b/ospfd/ospf_route.c @@ -463,6 +463,12 @@ void ospf_intra_add_transit(struct route_table *rt, struct vertex *v, the IP network number, which can be obtained by masking the Vertex ID (Link State ID) with its associated subnet mask (found in the body of the associated network-LSA). */ + if (lsa->mask.s_addr == 0xffffffff) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Suppress installing LSA[Type2,%pI4] route due to host mask", + &(lsa->header.id)); + return; + } p.family = AF_INET; p.prefix = v->id; p.prefixlen = ip_masklen(lsa->mask); diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index a23802719..d3dbd4821 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -4076,6 +4076,20 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, 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); @@ -9865,6 +9879,56 @@ DEFPY(ip_ospf_capability_opaque, ip_ospf_capability_opaque_addr_cmd, } +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, "max-metric router-lsa administrative", @@ -12285,6 +12349,22 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf) 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)); @@ -13097,6 +13177,9 @@ static void ospf_vty_if_init(void) /* "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); |