diff options
author | Madhuri Kuruganti <maduri111@gmail.com> | 2022-09-04 14:46:09 +0200 |
---|---|---|
committer | Madhuri Kuruganti <maduri111@gmail.com> | 2022-10-12 10:13:55 +0200 |
commit | a3d3a14c09cf212c7d402670247c4d518b99d8b7 (patch) | |
tree | 5dad10bdebb5d4bc7fbdfc7dc8da9c910e7c3d51 | |
parent | bgpd: optimal router reflection cli and fsm changes (diff) | |
download | frr-a3d3a14c09cf212c7d402670247c4d518b99d8b7.tar.xz frr-a3d3a14c09cf212c7d402670247c4d518b99d8b7.zip |
ospfd: rSPF calc and messaging for optimal route reflection
Signed-off-by: Madhuri Kuruganti <maduri111@gmail.com>
-rw-r--r-- | ospfd/ospf_dump.c | 38 | ||||
-rw-r--r-- | ospfd/ospf_dump.h | 5 | ||||
-rw-r--r-- | ospfd/ospf_lsa.c | 98 | ||||
-rw-r--r-- | ospfd/ospf_lsa.h | 26 | ||||
-rw-r--r-- | ospfd/ospf_lsdb.c | 9 | ||||
-rw-r--r-- | ospfd/ospf_memory.c | 1 | ||||
-rw-r--r-- | ospfd/ospf_memory.h | 1 | ||||
-rw-r--r-- | ospfd/ospf_orr.c | 457 | ||||
-rw-r--r-- | ospfd/ospf_orr.h | 44 | ||||
-rw-r--r-- | ospfd/ospf_spf.c | 215 | ||||
-rw-r--r-- | ospfd/ospf_spf.h | 2 | ||||
-rw-r--r-- | ospfd/ospf_vty.c | 31 | ||||
-rw-r--r-- | ospfd/ospf_zebra.c | 7 | ||||
-rw-r--r-- | ospfd/ospfd.h | 9 | ||||
-rw-r--r-- | ospfd/subdir.am | 2 |
15 files changed, 905 insertions, 40 deletions
diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c index 9f6adf322..eb9991ad8 100644 --- a/ospfd/ospf_dump.c +++ b/ospfd/ospf_dump.c @@ -63,6 +63,7 @@ unsigned long conf_debug_ospf_ldp_sync; unsigned long conf_debug_ospf_gr; unsigned long conf_debug_ospf_bfd; unsigned long conf_debug_ospf_client_api; +unsigned long conf_debug_ospf_orr; /* Enable debug option variables -- valid only session. */ unsigned long term_debug_ospf_packet[5] = {0, 0, 0, 0, 0}; @@ -81,6 +82,7 @@ unsigned long term_debug_ospf_ldp_sync; unsigned long term_debug_ospf_gr; unsigned long term_debug_ospf_bfd; unsigned long term_debug_ospf_client_api; +unsigned long term_debug_ospf_orr; const char *ospf_redist_string(unsigned int route_type) { @@ -1601,6 +1603,25 @@ DEFPY (debug_ospf_client_api, return CMD_SUCCESS; } +DEFPY (debug_ospf_orr, + debug_ospf_orr_cmd, + "[no$no] debug ospf orr", + NO_STR + DEBUG_STR + OSPF_STR + "OSPF ORR information\n") +{ + if (vty->node == CONFIG_NODE) + CONF_DEBUG_ON(orr, ORR); + + if (!no) + TERM_DEBUG_ON(orr, ORR); + else + TERM_DEBUG_OFF(orr, ORR); + + return CMD_SUCCESS; +} + DEFUN (no_debug_ospf, no_debug_ospf_cmd, "no debug ospf", @@ -1643,6 +1664,8 @@ DEFUN (no_debug_ospf, for (i = 0; i < 5; i++) DEBUG_PACKET_OFF(i, flag); + + DEBUG_OFF(orr, ORR); } for (i = 0; i < 5; i++) @@ -1673,6 +1696,7 @@ DEFUN (no_debug_ospf, TERM_DEBUG_OFF(ti_lfa, TI_LFA); TERM_DEBUG_OFF(bfd, BFD_LIB); TERM_DEBUG_OFF(client_api, CLIENT_API); + TERM_DEBUG_OFF(orr, ORR); return CMD_SUCCESS; } @@ -1802,6 +1826,12 @@ static int show_debugging_ospf_common(struct vty *vty) if (IS_DEBUG_OSPF(client_api, CLIENT_API) == OSPF_DEBUG_CLIENT_API) vty_out(vty, " OSPF client-api debugging is on\n"); + /* Show debug status for ORR. */ + if (IS_DEBUG_OSPF(orr, ORR) == OSPF_DEBUG_ORR) + vty_out(vty, " OSPF ORR debugging is on\n"); + + vty_out(vty, "\n"); + return CMD_SUCCESS; } @@ -2014,6 +2044,12 @@ static int config_write_debug(struct vty *vty) write = 1; } + /* debug ospf orr */ + if (IS_CONF_DEBUG_OSPF(orr, ORR) == OSPF_DEBUG_ORR) { + vty_out(vty, "debug ospf%s orr\n", str); + write = 1; + } + return write; } @@ -2035,6 +2071,7 @@ void ospf_debug_init(void) install_element(ENABLE_NODE, &debug_ospf_default_info_cmd); install_element(ENABLE_NODE, &debug_ospf_ldp_sync_cmd); install_element(ENABLE_NODE, &debug_ospf_client_api_cmd); + install_element(ENABLE_NODE, &debug_ospf_orr_cmd); install_element(ENABLE_NODE, &no_debug_ospf_ism_cmd); install_element(ENABLE_NODE, &no_debug_ospf_nsm_cmd); install_element(ENABLE_NODE, &no_debug_ospf_lsa_cmd); @@ -2074,6 +2111,7 @@ void ospf_debug_init(void) install_element(CONFIG_NODE, &debug_ospf_default_info_cmd); install_element(CONFIG_NODE, &debug_ospf_ldp_sync_cmd); install_element(CONFIG_NODE, &debug_ospf_client_api_cmd); + install_element(CONFIG_NODE, &debug_ospf_orr_cmd); install_element(CONFIG_NODE, &no_debug_ospf_nsm_cmd); install_element(CONFIG_NODE, &no_debug_ospf_lsa_cmd); install_element(CONFIG_NODE, &no_debug_ospf_zebra_cmd); diff --git a/ospfd/ospf_dump.h b/ospfd/ospf_dump.h index 251be7c8d..e9ba8fc79 100644 --- a/ospfd/ospf_dump.h +++ b/ospfd/ospf_dump.h @@ -70,6 +70,8 @@ #define OSPF_DEBUG_CLIENT_API 0x01 +#define OSPF_DEBUG_ORR 0x01 + /* Macro for setting debug option. */ #define CONF_DEBUG_PACKET_ON(a, b) conf_debug_ospf_packet[a] |= (b) #define CONF_DEBUG_PACKET_OFF(a, b) conf_debug_ospf_packet[a] &= ~(b) @@ -129,6 +131,8 @@ #define AREA_NAME(A) ospf_area_name_string ((A)) #define IF_NAME(I) ospf_if_name_string ((I)) +#define IS_DEBUG_OSPF_ORR IS_DEBUG_OSPF(orr, ORR) + /* Extern debug flag. */ extern unsigned long term_debug_ospf_packet[]; extern unsigned long term_debug_ospf_event; @@ -146,6 +150,7 @@ extern unsigned long term_debug_ospf_ldp_sync; extern unsigned long term_debug_ospf_gr; extern unsigned long term_debug_ospf_bfd; extern unsigned long term_debug_ospf_client_api; +extern unsigned long term_debug_ospf_orr; /* Message Strings. */ extern char *ospf_lsa_type_str[]; diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 0df0072f6..6f42fa8d3 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -52,6 +52,8 @@ #include "ospfd/ospf_zebra.h" #include "ospfd/ospf_abr.h" #include "ospfd/ospf_errors.h" +#include "ospfd/ospf_te.h" +#include "ospfd/ospf_orr.h" static struct ospf_lsa *ospf_handle_summarylsa_lsId_chg(struct ospf *ospf, struct prefix_ipv4 *p, @@ -2640,6 +2642,15 @@ ospf_router_lsa_install(struct ospf *ospf, struct ospf_lsa *new, int rt_recalc) ospf_refresher_register_lsa(ospf, new); } + /* For BGP ORR SPF should be calculated from specified root(s) */ + else if (ospf->orr_spf_request) { + ospf_lsa_unlock(&area->router_lsa_rcvd); + area->router_lsa_rcvd = ospf_lsa_lock(new); + SET_FLAG(new->flags, OSPF_LSA_ORR); + ospf_refresher_register_lsa(ospf, new); + ospf_orr_root_update_rcvd_lsa(area->router_lsa_rcvd); + } + if (rt_recalc) ospf_spf_calculate_schedule(ospf, SPF_FLAG_ROUTER_LSA_INSTALL); return new; @@ -3400,6 +3411,82 @@ struct ospf_lsa *ospf_lsa_lookup_by_id(struct ospf_area *area, uint32_t type, return NULL; } +struct ospf_lsa *ospf_lsa_lookup_by_adv_rid(struct ospf_area *area, + uint32_t type, struct in_addr id) +{ + struct ospf_lsa *lsa = NULL; + struct route_node *rn = NULL; + + switch (type) { + case OSPF_ROUTER_LSA: + for (rn = route_top(ROUTER_LSDB(area)); rn; + rn = route_next(rn)) { + lsa = rn->info; + if (lsa) { + if (IPV4_ADDR_SAME(&lsa->data->adv_router, + &id)) { + route_unlock_node(rn); + return lsa; + } + } + } + break; + case OSPF_NETWORK_LSA: + case OSPF_SUMMARY_LSA: + case OSPF_ASBR_SUMMARY_LSA: + case OSPF_AS_EXTERNAL_LSA: + case OSPF_AS_NSSA_LSA: + case OSPF_OPAQUE_LINK_LSA: + case OSPF_OPAQUE_AREA_LSA: + case OSPF_OPAQUE_AS_LSA: + /* Currently not used. */ + break; + default: + break; + } + + return NULL; +} + +struct ospf_lsa *ospf_lsa_lookup_by_mpls_te_rid(struct ospf_area *area, + uint32_t type, + struct in_addr id) +{ + struct ospf_lsa *lsa = NULL; + struct route_node *rn = NULL; + struct lsa_header *lsah = NULL; + uint32_t lsid; + uint8_t opaque_type; + struct tlv_header *tlvh = NULL; + struct te_tlv_router_addr *router_addr = NULL; + + if (type != OSPF_OPAQUE_AREA_LSA) + return NULL; + + for (rn = route_top(OPAQUE_AREA_LSDB(area)); rn; rn = route_next(rn)) { + lsa = rn->info; + if (lsa) { + lsah = lsa->data; + lsid = ntohl(lsah->id.s_addr); + opaque_type = GET_OPAQUE_TYPE(lsid); + if (opaque_type != OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA) + continue; + + tlvh = TLV_HDR_TOP(lsah); + if (!tlvh || + (ntohs(tlvh->type) != TE_TLV_ROUTER_ADDR) || + (ntohs(tlvh->length) != TE_LINK_SUBTLV_DEF_SIZE)) + continue; + router_addr = (struct te_tlv_router_addr *)tlvh; + if (IPV4_ADDR_SAME(&router_addr->value, &id)) { + route_unlock_node(rn); + return lsa; + } + } + } + return NULL; +} + struct ospf_lsa *ospf_lsa_lookup_by_header(struct ospf_area *area, struct lsa_header *lsah) { @@ -3823,8 +3910,9 @@ struct ospf_lsa *ospf_lsa_refresh(struct ospf *ospf, struct ospf_lsa *lsa) struct as_external_lsa *al; struct prefix_ipv4 p; - assert(CHECK_FLAG(lsa->flags, OSPF_LSA_SELF)); - assert(IS_LSA_SELF(lsa)); + if (!CHECK_FLAG(lsa->flags, OSPF_LSA_SELF) && !IS_LSA_SELF(lsa) && + !IS_LSA_ORR(lsa)) + return NULL; assert(lsa->lock > 0); switch (lsa->data->type) { @@ -3894,7 +3982,8 @@ void ospf_refresher_register_lsa(struct ospf *ospf, struct ospf_lsa *lsa) uint16_t index, current_index; assert(lsa->lock > 0); - assert(IS_LSA_SELF(lsa)); + if (!IS_LSA_SELF(lsa) && !IS_LSA_ORR(lsa)) + return; if (lsa->refresh_list < 0) { int delay; @@ -3943,7 +4032,8 @@ void ospf_refresher_register_lsa(struct ospf *ospf, struct ospf_lsa *lsa) void ospf_refresher_unregister_lsa(struct ospf *ospf, struct ospf_lsa *lsa) { assert(lsa->lock > 0); - assert(IS_LSA_SELF(lsa)); + if (!IS_LSA_SELF(lsa) || !IS_LSA_ORR(lsa)) + return; if (lsa->refresh_list >= 0) { struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list]; diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h index 97c15d1e3..a2a2393c9 100644 --- a/ospfd/ospf_lsa.h +++ b/ospfd/ospf_lsa.h @@ -74,15 +74,16 @@ struct vertex; /* OSPF LSA. */ struct ospf_lsa { /* LSA origination flag. */ - uint8_t flags; -#define OSPF_LSA_SELF 0x01 -#define OSPF_LSA_SELF_CHECKED 0x02 -#define OSPF_LSA_RECEIVED 0x04 -#define OSPF_LSA_APPROVED 0x08 -#define OSPF_LSA_DISCARD 0x10 -#define OSPF_LSA_LOCAL_XLT 0x20 -#define OSPF_LSA_PREMATURE_AGE 0x40 -#define OSPF_LSA_IN_MAXAGE 0x80 + uint16_t flags; +#define OSPF_LSA_SELF 0x0001 +#define OSPF_LSA_SELF_CHECKED 0x0002 +#define OSPF_LSA_RECEIVED 0x0004 +#define OSPF_LSA_APPROVED 0x0008 +#define OSPF_LSA_DISCARD 0x0010 +#define OSPF_LSA_LOCAL_XLT 0x0020 +#define OSPF_LSA_PREMATURE_AGE 0x0040 +#define OSPF_LSA_IN_MAXAGE 0x0080 +#define OSPF_LSA_ORR 0x0100 /* LSA data. and size */ struct lsa_header *data; @@ -222,6 +223,7 @@ enum lsid_status { LSID_AVAILABLE = 0, LSID_CHANGE, LSID_NOT_AVAILABLE }; #define IS_LSA_MAXAGE(L) (LS_AGE ((L)) == OSPF_LSA_MAXAGE) #define IS_LSA_MAX_SEQ(L) \ ((L)->data->ls_seqnum == htonl(OSPF_MAX_SEQUENCE_NUMBER)) +#define IS_LSA_ORR(L) (CHECK_FLAG ((L)->flags, OSPF_LSA_ORR)) #define OSPF_LSA_UPDATE_DELAY 2 @@ -292,6 +294,12 @@ extern struct ospf_lsa *ospf_lsa_lookup(struct ospf *ospf, struct ospf_area *, struct in_addr); extern struct ospf_lsa *ospf_lsa_lookup_by_id(struct ospf_area *, uint32_t, struct in_addr); +extern struct ospf_lsa *ospf_lsa_lookup_by_adv_rid(struct ospf_area *area, + uint32_t type, + struct in_addr id); +extern struct ospf_lsa *ospf_lsa_lookup_by_mpls_te_rid(struct ospf_area *area, + uint32_t type, + struct in_addr id); extern struct ospf_lsa *ospf_lsa_lookup_by_header(struct ospf_area *, struct lsa_header *); extern int ospf_lsa_more_recent(struct ospf_lsa *, struct ospf_lsa *); diff --git a/ospfd/ospf_lsdb.c b/ospfd/ospf_lsdb.c index f4fb858a5..3c65ac388 100644 --- a/ospfd/ospf_lsdb.c +++ b/ospfd/ospf_lsdb.c @@ -30,6 +30,7 @@ #include "ospfd/ospf_asbr.h" #include "ospfd/ospf_lsa.h" #include "ospfd/ospf_lsdb.h" +#include "ospfd/ospf_orr.h" struct ospf_lsdb *ospf_lsdb_new(void) { @@ -87,6 +88,10 @@ static void ospf_lsdb_delete_entry(struct ospf_lsdb *lsdb, assert(rn->table == lsdb->type[lsa->data->type].db); + /* Update ORR Root table MPLS-TE Router address's advertise router */ + if (lsa->data->type == OSPF_OPAQUE_AREA_LSA) + ospf_orr_root_table_update(lsa, false); + if (IS_LSA_SELF(lsa)) lsdb->type[lsa->data->type].count_self--; lsdb->type[lsa->data->type].count--; @@ -134,6 +139,10 @@ void ospf_lsdb_add(struct ospf_lsdb *lsdb, struct ospf_lsa *lsa) #endif /* MONITOR_LSDB_CHANGE */ lsdb->type[lsa->data->type].checksum += ntohs(lsa->data->checksum); rn->info = ospf_lsa_lock(lsa); /* lsdb */ + + /* Update ORR Root table MPLS-TE Router address's advertise router */ + if (lsa->data->type == OSPF_OPAQUE_AREA_LSA) + ospf_orr_root_table_update(lsa, true); } void ospf_lsdb_delete(struct ospf_lsdb *lsdb, struct ospf_lsa *lsa) diff --git a/ospfd/ospf_memory.c b/ospfd/ospf_memory.c index 283844389..5577a291b 100644 --- a/ospfd/ospf_memory.c +++ b/ospfd/ospf_memory.c @@ -60,3 +60,4 @@ DEFINE_MTYPE(OSPFD, OSPF_GR_HELPER, "OSPF Graceful Restart Helper"); DEFINE_MTYPE(OSPFD, OSPF_EXTERNAL_RT_AGGR, "OSPF External Route Summarisation"); DEFINE_MTYPE(OSPFD, OSPF_P_SPACE, "OSPF TI-LFA P-Space"); DEFINE_MTYPE(OSPFD, OSPF_Q_SPACE, "OSPF TI-LFA Q-Space"); +DEFINE_MTYPE(OSPFD, OSPF_ORR_ROOT, "OSPF ORR Root"); diff --git a/ospfd/ospf_memory.h b/ospfd/ospf_memory.h index 9bd0a844a..3d2133b11 100644 --- a/ospfd/ospf_memory.h +++ b/ospfd/ospf_memory.h @@ -59,5 +59,6 @@ DECLARE_MTYPE(OSPF_GR_HELPER); DECLARE_MTYPE(OSPF_EXTERNAL_RT_AGGR); DECLARE_MTYPE(OSPF_P_SPACE); DECLARE_MTYPE(OSPF_Q_SPACE); +DECLARE_MTYPE(OSPF_ORR_ROOT); #endif /* _QUAGGA_OSPF_MEMORY_H */ diff --git a/ospfd/ospf_orr.c b/ospfd/ospf_orr.c new file mode 100644 index 000000000..d9cf14aab --- /dev/null +++ b/ospfd/ospf_orr.c @@ -0,0 +1,457 @@ +/* + * OSPF BGP-IGP IGP metric update handling routines + * Copyright (C) 2021 Samsung R&D Institute India - Bangalore. + * Madhurilatha Kuruganti + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <zebra.h> +#include <string.h> + +#include "monotime.h" +#include "memory.h" +#include "thread.h" +#include "prefix.h" +#include "table.h" +#include "vty.h" +#include "command.h" +#include "plist.h" +#include "log.h" +#include "zclient.h" +#include <lib/json.h> +#include "defaults.h" +#include "orr_msg.h" + +#include "ospfd.h" +#include "ospf_asbr.h" +#include "ospf_dump.h" +#include "ospf_lsa.h" +#include "ospf_orr.h" +#include "ospf_route.h" +#include "ospf_spf.h" +#include "ospf_te.h" + +static void ospf_show_orr_root(struct orr_root *root); +void ospf_show_orr(struct ospf *ospf, afi_t afi, safi_t safi); +static struct orr_root *ospf_orr_root_new(struct ospf *ospf, afi_t afi, + safi_t safi, struct prefix *p) +{ + struct list *orr_root_list = NULL; + struct orr_root *root = NULL; + + if (!ospf->orr_root[afi][safi]) + ospf->orr_root[afi][safi] = list_new(); + + orr_root_list = ospf->orr_root[afi][safi]; + root = XCALLOC(MTYPE_OSPF_ORR_ROOT, sizeof(struct orr_root)); + + listnode_add(orr_root_list, root); + + root->afi = afi; + root->safi = safi; + prefix_copy(&root->prefix, p); + IPV4_ADDR_COPY(&root->router_id, &p->u.prefix4); + root->new_rtrs = NULL; + root->new_table = NULL; + + ospf_orr_debug("%s: For %s %s, created ORR Root entry %pFX.", __func__, + afi2str(afi), safi2str(safi), p); + + return root; +} + +static struct orr_root *ospf_orr_root_lookup(struct ospf *ospf, afi_t afi, + safi_t safi, struct in_addr *rid) +{ + struct list *orr_root_list = NULL; + struct orr_root *root = NULL; + struct listnode *node; + + orr_root_list = ospf->orr_root[afi][safi]; + if (!orr_root_list) + return NULL; + + for (ALL_LIST_ELEMENTS_RO(orr_root_list, node, root)) + if (IPV4_ADDR_SAME(&root->router_id, rid)) + return root; + + ospf_orr_debug("%s: For %s %s, ORR Root '%pI4' not found.", __func__, + afi2str(afi), safi2str(safi), rid); + + return NULL; +} + +static struct orr_root *ospf_orr_root_lookup_by_adv_rid(struct ospf *ospf, + afi_t afi, safi_t safi, + struct in_addr *rid) +{ + struct list *orr_root_list = NULL; + struct orr_root *root = NULL; + struct listnode *node; + + orr_root_list = ospf->orr_root[afi][safi]; + if (!orr_root_list) + return NULL; + + for (ALL_LIST_ELEMENTS_RO(orr_root_list, node, root)) + if (IPV4_ADDR_SAME(&root->adv_router, rid)) + return root; + + return NULL; +} + +/* + * Lookup each area's LSDB if is there is any opaque area LSA received and + * update the root database with the advertising router. + */ +static struct ospf_lsa * +ospf_orr_lookup_opaque_area_lsa_by_id(struct in_addr rid) +{ + struct ospf_lsa *lsa = NULL; + struct ospf_area *area = NULL; + struct ospf *ospf = NULL; + struct listnode *node = NULL, *nnode = NULL; + + /* if ospf is not enabled ignore */ + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + if (!ospf) + return NULL; + + /* Lookup for Opaque area LSA in each area. */ + for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) { + lsa = ospf_lsa_lookup_by_mpls_te_rid(area, OSPF_OPAQUE_AREA_LSA, + rid); + if (!lsa) + continue; + ospf_orr_debug( + "%s: Opaque Area LSA found in area %pI4 for %pI4", + __func__, &area->area_id, &rid); + return lsa; + } + return NULL; +} + +/* + * Lookup each area's LSDB if is there is any opaque area LSA received and + * update the root database with the advertising router. + */ +static struct ospf_lsa *ospf_orr_lookup_router_lsa_by_id(struct in_addr rid) +{ + struct ospf_lsa *lsa = NULL; + struct ospf_area *area = NULL; + struct ospf *ospf = NULL; + struct listnode *node = NULL, *nnode = NULL; + + /* if ospf is not enabled ignore */ + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + if (!ospf) + return NULL; + + /* Lookup for Router LSA in each area. */ + for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) { + lsa = ospf_lsa_lookup_by_adv_rid(area, OSPF_ROUTER_LSA, rid); + if (!lsa) + continue; + ospf_orr_debug("%s: Router LSA found in area %pI4 for %pI4", + __func__, &area->area_id, &rid); + return lsa; + } + return NULL; +} + +/* + * BGP-IGP IGP metric msg between BGP and IGP + */ +int ospf_orr_igp_metric_register(struct orr_igp_metric_reg msg) +{ + afi_t afi; + safi_t safi; + struct ospf *ospf = NULL; + struct ospf_lsa *lsa = NULL; + struct orr_root *root = NULL; + + /* if ospf is not enabled ignore */ + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + if (!ospf) + return -1; + + if (msg.proto != ZEBRA_ROUTE_BGP) + return -1; + + afi = family2afi(msg.prefix.family); + safi = msg.safi; + + ospf_orr_debug( + "%s: Received IGP metric %s message from BGP for location %pFX", + __func__, msg.reg ? "Register" : "Unregister", &msg.prefix); + + /* Get ORR Root entry for the given address-family */ + root = ospf_orr_root_lookup(ospf, afi, safi, &msg.prefix.u.prefix4); + + /* Should not hit this condition */ + if ((root && msg.reg) || (!root && !msg.reg)) + return -1; + + /* Create ORR Root entry and calculate SPF from root */ + if (!root) { + root = ospf_orr_root_new(ospf, afi, safi, &msg.prefix); + if (!root) { + ospf_orr_debug( + "%s: For %s %s, Failed to create ORR Root entry %pFX.", + __func__, afi2str(afi), safi2str(safi), + &msg.prefix); + return -1; + } + ospf->orr_spf_request++; + + lsa = ospf_orr_lookup_opaque_area_lsa_by_id(root->router_id); + if (!lsa || !lsa->data) + return -1; + + IPV4_ADDR_COPY(&root->adv_router, &lsa->data->adv_router); + + /* Lookup LSDB for Router LSA */ + if (!root->router_lsa_rcvd) { + lsa = ospf_orr_lookup_router_lsa_by_id( + root->adv_router); + if (!lsa || !lsa->data) + return -1; + root->router_lsa_rcvd = lsa; + } + + /* Compute SPF for all root nodes */ + ospf_spf_calculate_schedule(ospf, SPF_FLAG_ORR_ROOT_CHANGE); + } + /* Delete ORR Root entry. SPF calculation not required. */ + else { + listnode_delete(ospf->orr_root[afi][safi], root); + XFREE(MTYPE_OSPF_ORR_ROOT, root); + + /* If last node is deleted in the list */ + if (!ospf->orr_root[afi][safi]->count) + list_delete(&ospf->orr_root[afi][safi]); + + ospf->orr_spf_request--; + } + ospf_show_orr(ospf, afi, safi); + return 0; +} + +void ospf_orr_igp_metric_send_update(struct orr_root *root, + unsigned short instance) +{ + int ret; + uint8_t count = 0; + struct route_node *rn; + struct ospf_route *or; + struct orr_igp_metric_info msg; + + memset(&msg, 0, sizeof(msg)); + msg.proto = ZEBRA_ROUTE_OSPF; + msg.safi = root->safi; + msg.instId = instance; + prefix_copy(&msg.root, &root->prefix); + msg.num_entries = root->new_table->count; + + /* Update prefix table from ORR Route table */ + for (rn = route_top(root->new_table); rn; rn = route_next(rn)) { + or = rn->info; + if (!or) + continue; + + if (or->type != OSPF_DESTINATION_NETWORK) + continue; + + if (count < ORR_MAX_PREFIX) { + prefix_copy(&msg.nexthop[count].prefix, + (struct prefix_ipv4 *)&rn->p); + msg.nexthop[count].metric = or->cost; + count++; + } else { + msg.num_entries = count; + ret = zclient_send_opaque(zclient, + ORR_IGP_METRIC_UPDATE, + (uint8_t *)&msg, sizeof(msg)); + if (ret != ZCLIENT_SEND_SUCCESS) + ospf_orr_debug( + "%s: Failed to send message to BGP.", + __func__); + count = 0; + prefix_copy(&msg.nexthop[count].prefix, + (struct prefix_ipv4 *)&rn->p); + msg.nexthop[count].metric = or->cost; + count++; + } + } + if (count <= ORR_MAX_PREFIX) { + msg.num_entries = count; + ret = zclient_send_opaque(zclient, ORR_IGP_METRIC_UPDATE, + (uint8_t *)&msg, sizeof(msg)); + if (ret != ZCLIENT_SEND_SUCCESS) + ospf_orr_debug("%s: Failed to send message to BGP.", + __func__); + } +} + +static void ospf_show_orr_root(struct orr_root *root) +{ + if (!root) + return; + + ospf_orr_debug("%s: Router-Address: %pI4:", __func__, &root->router_id); + ospf_orr_debug("%s: Advertising Router: %pI4:", __func__, + &root->adv_router); +} + +void ospf_show_orr(struct ospf *ospf, afi_t afi, safi_t safi) +{ + struct listnode *node = NULL; + struct orr_root *orr_root = NULL; + struct list *orr_root_list = NULL; + + FOREACH_AFI_SAFI (afi, safi) { + orr_root_list = ospf->orr_root[afi][safi]; + if (!orr_root_list) + return; + + ospf_orr_debug("%s: For Address Family %s %s:", __func__, + afi2str(afi), safi2str(safi)); + for (ALL_LIST_ELEMENTS_RO(orr_root_list, node, orr_root)) + ospf_show_orr_root(orr_root); + } +} + +void ospf_orr_root_table_update(struct ospf_lsa *lsa, bool add) +{ + afi_t afi; + safi_t safi; + struct lsa_header *lsah = lsa->data; + uint32_t lsid = ntohl(lsah->id.s_addr); + uint8_t opaque_type = GET_OPAQUE_TYPE(lsid); + uint32_t opaque_id = GET_OPAQUE_ID(lsid); + struct tlv_header *tlvh = TLV_HDR_TOP(lsah); + struct te_tlv_router_addr *router_addr = NULL; + struct orr_root *root = NULL; + struct ospf *ospf = NULL; + + /* if ospf is not enabled ignore */ + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + if (!ospf) + return; + + if (opaque_type != OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA) + return; + + if (!tlvh || (ntohs(tlvh->type) != TE_TLV_ROUTER_ADDR) || + (ntohs(tlvh->length) != TE_LINK_SUBTLV_DEF_SIZE)) + return; + + router_addr = (struct te_tlv_router_addr *)tlvh; + if (IS_DEBUG_OSPF_ORR) { + zlog_debug("[OSPF-ORR] %s: Opaque-area LSA %s LSDB", __func__, + add ? "added to" : "deleted from"); + zlog_debug("[OSPF-ORR] %s: Opaque-Type %u (%s)", __func__, + opaque_type, "Traffic Engineering LSA"); + zlog_debug("[OSPF-ORR] %s: Opaque-ID 0x%x", __func__, + opaque_id); + zlog_debug("[OSPF-ORR] %s: Opaque-Info: %u octets of data%s", + __func__, ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE, + VALID_OPAQUE_INFO_LEN(lsah) ? "" + : "(Invalid length?)"); + zlog_debug("[OSPF-ORR] %s: Router-Address: %pI4", __func__, + &router_addr->value); + zlog_debug("[OSPF-ORR] %s: Advertising Router: %pI4", __func__, + &lsa->data->adv_router); + } + /* + * When Opaque LSA is added or removed from LSDB check if there is any + * change in MPLS-TE Router address and Advertising router address and + * update the table accordingly if there is no change in the mapping + * ignore update + * + * Get ORR Root entry for the given address-family + */ + FOREACH_AFI_SAFI (afi, safi) { + root = ospf_orr_root_lookup(ospf, afi, safi, + &router_addr->value); + if (root) { + IPV4_ADDR_COPY(&root->adv_router, + &lsa->data->adv_router); + ospf_show_orr(ospf, afi, safi); + break; + } + } +} + +void ospf_orr_root_update_rcvd_lsa(struct ospf_lsa *lsa) +{ + afi_t afi; + safi_t safi; + struct orr_root *root = NULL; + + if (!lsa || !lsa->area || !lsa->area->ospf) + return; + + FOREACH_AFI_SAFI (afi, safi) { + root = ospf_orr_root_lookup_by_adv_rid( + lsa->area->ospf, afi, safi, &lsa->data->adv_router); + if (!root) + continue; + + ospf_orr_debug("%s: Received LSA[Type%d:%pI4]", __func__, + lsa->data->type, &lsa->data->adv_router); + + root->router_lsa_rcvd = lsa; + /* Compute SPF for all root nodes */ + ospf_spf_calculate_schedule(lsa->area->ospf, + SPF_FLAG_ORR_ROOT_CHANGE); + return; + } +} + +/* Install routes to root table. */ +void ospf_orr_route_install(struct orr_root *root, struct route_table *rt) +{ + struct route_node *rn; + struct ospf_route *or; + + /* + * rt contains new routing table, new_table contains an old one. + * updating pointers + */ + if (root->old_table) + ospf_route_table_free(root->old_table); + + root->old_table = root->new_table; + root->new_table = rt; + + /* Install new routes. */ + for (rn = route_top(rt); rn; rn = route_next(rn)) { + or = rn->info; + if (or) { + if (or->type == OSPF_DESTINATION_NETWORK) { + if (!ospf_route_match_same( + root->old_table, + (struct prefix_ipv4 *)&rn->p, or)) { + } + } else if (or->type == OSPF_DESTINATION_DISCARD) + if (!ospf_route_match_same( + root->old_table, + (struct prefix_ipv4 *)&rn->p, or)) { + } + } + } +} diff --git a/ospfd/ospf_orr.h b/ospfd/ospf_orr.h new file mode 100644 index 000000000..44e826d22 --- /dev/null +++ b/ospfd/ospf_orr.h @@ -0,0 +1,44 @@ +/* + * OSPF BGP-IGP IGP metric update handling routines + * Copyright (C) 2021 Samsung R&D Institute India - Bangalore. + * Madhurilatha Kuruganti + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _ZEBRA_OSPF_ORR_H +#define _ZEBRA_OSPF_ORR_H + +#define BGP_OSPF_LSINFINITY 65535 + +/* Macro to log debug message */ +#define ospf_orr_debug(...) \ + do { \ + if (IS_DEBUG_OSPF_ORR) \ + zlog_debug("[OSPF-ORR] "__VA_ARGS__); \ + } while (0) + +extern struct zclient *zclient; + +extern int ospf_orr_igp_metric_register(struct orr_igp_metric_reg orr_reg); +extern void ospf_orr_igp_metric_send_update(struct orr_root *root, + unsigned short instance); +extern void ospf_orr_root_table_update(struct ospf_lsa *lsa, bool add); +extern struct orr_root *ospf_get_orr(struct ospf *ospf, afi_t afi, safi_t safi); +extern void ospf_orr_root_update_rcvd_lsa(struct ospf_lsa *lsa); +extern void ospf_orr_route_install(struct orr_root *root, + struct route_table *rt); + +#endif /* _ZEBRA_OSPF_ORR_H */ diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index 4edc1de81..b20ac756e 100644 --- a/ospfd/ospf_spf.c +++ b/ospfd/ospf_spf.c @@ -53,6 +53,8 @@ #include "ospfd/ospf_apiserver.h" #endif +#include "ospfd/ospf_orr.h" + /* Variables to ensure a SPF scheduled log message is printed only once */ static unsigned int spf_reason_flags = 0; @@ -1824,6 +1826,36 @@ void ospf_spf_calculate_areas(struct ospf *ospf, struct route_table *new_table, all_rtrs, new_rtrs); } +/* Print Reason for SPF calculation */ +static void ospf_spf_calculation_reason2str(char *rbuf) +{ + rbuf[0] = '\0'; + if (spf_reason_flags) { + if (spf_reason_flags & (1 << SPF_FLAG_ROUTER_LSA_INSTALL)) + strlcat(rbuf, "R, ", sizeof(rbuf)); + if (spf_reason_flags & (1 << SPF_FLAG_NETWORK_LSA_INSTALL)) + strlcat(rbuf, "N, ", sizeof(rbuf)); + if (spf_reason_flags & (1 << SPF_FLAG_SUMMARY_LSA_INSTALL)) + strlcat(rbuf, "S, ", sizeof(rbuf)); + if (spf_reason_flags & (1 << SPF_FLAG_ASBR_SUMMARY_LSA_INSTALL)) + strlcat(rbuf, "AS, ", sizeof(rbuf)); + if (spf_reason_flags & (1 << SPF_FLAG_ABR_STATUS_CHANGE)) + strlcat(rbuf, "ABR, ", sizeof(rbuf)); + if (spf_reason_flags & (1 << SPF_FLAG_ASBR_STATUS_CHANGE)) + strlcat(rbuf, "ASBR, ", sizeof(rbuf)); + if (spf_reason_flags & (1 << SPF_FLAG_MAXAGE)) + strlcat(rbuf, "M, ", sizeof(rbuf)); + if (spf_reason_flags & (1 << SPF_FLAG_ORR_ROOT_CHANGE)) + strlcat(rbuf, "ORR, ", sizeof(rbuf)); + + size_t rbuflen = strlen(rbuf); + if (rbuflen >= 2) + rbuf[rbuflen - 2] = '\0'; /* skip the last ", " */ + else + rbuf[0] = '\0'; + } +} + /* Worker for SPF calculation scheduler. */ static void ospf_spf_calculate_schedule_worker(struct thread *thread) { @@ -1926,31 +1958,7 @@ static void ospf_spf_calculate_schedule_worker(struct thread *thread) total_spf_time = monotime_since(&spf_start_time, &ospf->ts_spf_duration); - rbuf[0] = '\0'; - if (spf_reason_flags) { - if (spf_reason_flags & (1 << SPF_FLAG_ROUTER_LSA_INSTALL)) - strlcat(rbuf, "R, ", sizeof(rbuf)); - if (spf_reason_flags & (1 << SPF_FLAG_NETWORK_LSA_INSTALL)) - strlcat(rbuf, "N, ", sizeof(rbuf)); - if (spf_reason_flags & (1 << SPF_FLAG_SUMMARY_LSA_INSTALL)) - strlcat(rbuf, "S, ", sizeof(rbuf)); - if (spf_reason_flags & (1 << SPF_FLAG_ASBR_SUMMARY_LSA_INSTALL)) - strlcat(rbuf, "AS, ", sizeof(rbuf)); - if (spf_reason_flags & (1 << SPF_FLAG_ABR_STATUS_CHANGE)) - strlcat(rbuf, "ABR, ", sizeof(rbuf)); - if (spf_reason_flags & (1 << SPF_FLAG_ASBR_STATUS_CHANGE)) - strlcat(rbuf, "ASBR, ", sizeof(rbuf)); - if (spf_reason_flags & (1 << SPF_FLAG_MAXAGE)) - strlcat(rbuf, "M, ", sizeof(rbuf)); - if (spf_reason_flags & (1 << SPF_FLAG_GR_FINISH)) - strlcat(rbuf, "GR, ", sizeof(rbuf)); - - size_t rbuflen = strlen(rbuf); - if (rbuflen >= 2) - rbuf[rbuflen - 2] = '\0'; /* skip the last ", " */ - else - rbuf[0] = '\0'; - } + ospf_spf_calculation_reason2str(rbuf); if (IS_DEBUG_OSPF_EVENT) { zlog_info("SPF Processing Time(usecs): %ld", total_spf_time); @@ -1967,6 +1975,152 @@ static void ospf_spf_calculate_schedule_worker(struct thread *thread) ospf_clear_spf_reason_flags(); } +/* Worker for ORR SPF calculation scheduler. */ +static void ospf_orr_spf_calculate_schedule_worker(struct thread *thread) +{ + afi_t afi; + safi_t safi; + struct ospf_area *area; + struct ospf *ospf = THREAD_ARG(thread); + struct route_table *new_table, *new_rtrs; + struct route_table *all_rtrs = NULL; + struct timeval start_time, spf_start_time; + unsigned long ia_time, rt_time; + unsigned long abr_time, total_spf_time, spf_time; + struct listnode *rnode; + struct listnode *anode, *annode; + struct list *orr_root_list; + struct orr_root *root; + char rbuf[32]; /* reason_buf */ + + ospf->t_spf_calc = NULL; + + /* Execute SPF for each ORR Root node */ + FOREACH_AFI_SAFI (afi, safi) { + orr_root_list = ospf->orr_root[afi][safi]; + if (!orr_root_list) + continue; + for (ALL_LIST_ELEMENTS_RO(orr_root_list, rnode, root)) { + if (!root || !root->router_lsa_rcvd) + continue; + ospf_orr_debug( + "%s: For %s %s, MPLS TE Router address %pI4 advertised by %pI4", + __func__, afi2str(afi), safi2str(safi), + &root->router_id, &root->adv_router); + + ospf_vl_unapprove(ospf); + + /* + * Execute SPF for each area including backbone, see RFC + * 2328 16.1. + */ + monotime(&spf_start_time); + new_table = route_table_init(); /* routing table */ + new_rtrs = + route_table_init(); /* ABR/ASBR routing table */ + + /* Calculate SPF for each area. */ + for (ALL_LIST_ELEMENTS(ospf->areas, anode, annode, + area)) { + /* + * Do backbone last, so as to first discover + * intra-area paths for any back-bone + * virtual-links + */ + if (ospf->backbone && ospf->backbone == area) + continue; + + ospf_spf_calculate(area, root->router_lsa_rcvd, + new_table, all_rtrs, + new_rtrs, false, true); + } + + /* SPF for backbone, if required */ + if (ospf->backbone) + ospf_spf_calculate(ospf->backbone, + root->router_lsa_rcvd, + new_table, all_rtrs, + new_rtrs, false, true); + + spf_time = monotime_since(&spf_start_time, NULL); + + ospf_vl_shut_unapproved(ospf); + + /* Calculate inter-area routes, see RFC 2328 16.2. */ + monotime(&start_time); + ospf_ia_routing(ospf, new_table, new_rtrs); + ia_time = monotime_since(&start_time, NULL); + + /* + * REVISIT : Pruning of unreachable networks,routers and + * ase routes calculation skipped + */ + + ospf_orr_debug( + "%s: ospf install new route, vrf %s id %u new_table count %lu", + __func__, ospf_vrf_id_to_name(ospf->vrf_id), + ospf->vrf_id, new_table->count); + + /* Update routing table. */ + monotime(&start_time); + ospf_orr_route_install(root, new_table); + rt_time = monotime_since(&start_time, NULL); + + /* Free old ABR/ASBR routing table */ + if (root->old_rtrs) + /* ospf_route_delete (ospf->old_rtrs); */ + ospf_rtrs_free(root->old_rtrs); + + /* Update ABR/ASBR routing table */ + root->old_rtrs = root->new_rtrs; + root->new_rtrs = new_rtrs; + + /* + * ABRs may require additional changes, see RFC + * 2328 16.7. + */ + monotime(&start_time); + if (IS_OSPF_ABR(ospf)) { + if (ospf->anyNSSA) + ospf_abr_nssa_check_status(ospf); + ospf_abr_task(ospf); + } + abr_time = monotime_since(&start_time, NULL); + + /* Schedule Segment Routing update */ + ospf_sr_update_task(ospf); + + total_spf_time = monotime_since(&spf_start_time, + &ospf->ts_spf_duration); + + ospf_spf_calculation_reason2str(rbuf); + + if (IS_DEBUG_OSPF_ORR) { + zlog_info("SPF Processing Time(usecs): %ld", + total_spf_time); + zlog_info(" SPF Time: %ld", + spf_time); + zlog_info(" InterArea: %ld", ia_time); + zlog_info(" RouteInstall: %ld", rt_time); + if (IS_OSPF_ABR(ospf)) + zlog_info( + " ABR: %ld (%d areas)", + abr_time, ospf->areas->count); + zlog_info("Reason(s) for SPF: %s", rbuf); + } + + root->new_table = new_table; + root->new_rtrs = new_rtrs; + + /* Send IGP Metric update to BGP */ + ospf_orr_igp_metric_send_update(root, ospf->instance); + + } /* ALL_LIST_ELEMENTS_RO() */ + } /* FOREACH_AFI_SAFI() */ + + ospf_clear_spf_reason_flags(); +} + /* * Add schedule for SPF calculation. To avoid frequenst SPF calc, we set timer * for SPF calc. @@ -2025,8 +2179,15 @@ void ospf_spf_calculate_schedule(struct ospf *ospf, ospf_spf_reason_t reason) zlog_debug("SPF: calculation timer delay = %ld msec", delay); ospf->t_spf_calc = NULL; - thread_add_timer_msec(master, ospf_spf_calculate_schedule_worker, ospf, - delay, &ospf->t_spf_calc); + + if (spf_reason_flags & (1 << SPF_FLAG_ORR_ROOT_CHANGE)) + thread_add_timer_msec(master, + ospf_orr_spf_calculate_schedule_worker, + ospf, delay, &ospf->t_spf_calc); + else + thread_add_timer_msec(master, + ospf_spf_calculate_schedule_worker, ospf, + delay, &ospf->t_spf_calc); } /* Restart OSPF SPF algorithm*/ diff --git a/ospfd/ospf_spf.h b/ospfd/ospf_spf.h index 834bfd0bb..88daf4c01 100644 --- a/ospfd/ospf_spf.h +++ b/ospfd/ospf_spf.h @@ -70,8 +70,10 @@ typedef enum { SPF_FLAG_ASBR_STATUS_CHANGE, SPF_FLAG_CONFIG_CHANGE, SPF_FLAG_GR_FINISH, + SPF_FLAG_ORR_ROOT_CHANGE, } ospf_spf_reason_t; +extern unsigned int ospf_get_spf_reason_flags(void); extern void ospf_spf_calculate_schedule(struct ospf *, ospf_spf_reason_t); extern void ospf_spf_calculate(struct ospf_area *area, struct ospf_lsa *root_lsa, diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index c957c8c01..ce9067397 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -55,6 +55,7 @@ #include "ospfd/ospf_dump.h" #include "ospfd/ospf_bfd.h" #include "ospfd/ospf_ldp_sync.h" +#include "ospfd/ospf_orr.h" FRR_CFG_DEFAULT_BOOL(OSPF_LOG_ADJACENCY_CHANGES, @@ -11236,6 +11237,36 @@ static int show_ip_ospf_route_common(struct vty *vty, struct ospf *ospf, if (ospf->all_rtrs) show_ip_ospf_route_router(vty, ospf, ospf->all_rtrs, json_vrf); + /* Show ORR routes */ + if (ospf->orr_spf_request) { + afi_t afi; + safi_t safi; + struct orr_root *root = NULL; + struct listnode *node = NULL; + struct list *orr_root_list = NULL; + + FOREACH_AFI_SAFI (afi, safi) { + orr_root_list = ospf->orr_root[afi][safi]; + if (!orr_root_list) + continue; + for (ALL_LIST_ELEMENTS_RO(orr_root_list, node, root)) { + if (!root->new_table) + continue; + if (!json) + vty_out(vty, + "Calculated from location" + " %pI4\n", + &root->router_id); + show_ip_ospf_route_network( + vty, ospf, root->new_table, json_vrf); + if (!root->new_rtrs) + continue; + show_ip_ospf_route_router( + vty, ospf, root->new_rtrs, json_vrf); + } + } + } + /* Show AS External routes. */ show_ip_ospf_route_external(vty, ospf, ospf->old_external_route, json_vrf); diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index 1754512b5..461586424 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -53,6 +53,7 @@ #include "ospfd/ospf_te.h" #include "ospfd/ospf_sr.h" #include "ospfd/ospf_ldp_sync.h" +#include "ospfd/ospf_orr.h" DEFINE_MTYPE_STATIC(OSPFD, OSPF_EXTERNAL, "OSPF External route table"); DEFINE_MTYPE_STATIC(OSPFD, OSPF_REDISTRIBUTE, "OSPF Redistriute"); @@ -2081,6 +2082,7 @@ static void ospf_zebra_connected(struct zclient *zclient) bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER, VRF_DEFAULT); zclient_send_reg_requests(zclient, VRF_DEFAULT); + zclient_register_opaque(zclient, ORR_IGP_METRIC_REGISTER); } /* @@ -2093,6 +2095,7 @@ static int ospf_opaque_msg_handler(ZAPI_CALLBACK_ARGS) struct ldp_igp_sync_if_state state; struct ldp_igp_sync_announce announce; struct zapi_opaque_reg_info dst; + struct orr_igp_metric_reg orr_reg; int ret = 0; s = zclient->ibuf; @@ -2116,6 +2119,10 @@ static int ospf_opaque_msg_handler(ZAPI_CALLBACK_ARGS) STREAM_GET(&announce, s, sizeof(announce)); ret = ospf_ldp_sync_announce_update(announce); break; + case ORR_IGP_METRIC_REGISTER: + STREAM_GET(&orr_reg, s, sizeof(orr_reg)); + ret = ospf_orr_igp_metric_register(orr_reg); + break; default: break; } diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index 3a43010f8..2f3ad04c4 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -35,6 +35,8 @@ #include "ospf_memory.h" #include "ospf_dump_api.h" +#include "orr_msg.h" + #define OSPF_VERSION 2 /* VTY port number. */ @@ -406,6 +408,10 @@ struct ospf { bool ti_lfa_enabled; enum protection_type ti_lfa_protection_type; + /* BGP ORR Root node list */ + uint32_t orr_spf_request; + struct list *orr_root[AFI_MAX][SAFI_MAX]; + QOBJ_FIELDS; }; DECLARE_QOBJ_TYPE(ospf); @@ -591,6 +597,9 @@ struct ospf_area { uint32_t act_ints; /* Active interfaces. */ uint32_t full_nbrs; /* Fully adjacent neighbors. */ uint32_t full_vls; /* Fully adjacent virtual neighbors. */ + + /* BGP-ORR Received LSAs */ + struct ospf_lsa *router_lsa_rcvd; }; /* OSPF config network structure. */ diff --git a/ospfd/subdir.am b/ospfd/subdir.am index 4f9cbc7b1..78688fac9 100644 --- a/ospfd/subdir.am +++ b/ospfd/subdir.am @@ -48,6 +48,7 @@ ospfd_libfrrospf_a_SOURCES = \ ospfd/ospf_network.c \ ospfd/ospf_nsm.c \ ospfd/ospf_opaque.c \ + ospfd/ospf_orr.c \ ospfd/ospf_packet.c \ ospfd/ospf_ri.c \ ospfd/ospf_route.c \ @@ -101,6 +102,7 @@ noinst_HEADERS += \ ospfd/ospf_memory.h \ ospfd/ospf_neighbor.h \ ospfd/ospf_network.h \ + ospfd/ospf_orr.h \ ospfd/ospf_packet.h \ ospfd/ospf_ri.h \ ospfd/ospf_gr.h \ |