mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-29 04:25:43 +00:00
bgpd, ospfd: update BGP when routes are removed from OSPF routing table
Signed-off-by: Madhuri Kuruganti <maduri111@gmail.com>
This commit is contained in:
parent
5fcf01c9ae
commit
bba9435157
@ -159,7 +159,6 @@ static void bgp_orr_group_free(struct bgp_orr_group *orr_group)
|
||||
|
||||
/* Unset ORR Group parameters */
|
||||
XFREE(MTYPE_BGP_ORR_GROUP_NAME, orr_group->name);
|
||||
memset(orr_group, 0, sizeof(struct bgp_orr_group));
|
||||
|
||||
listnode_delete(bgp->orr_group[afi][safi], orr_group);
|
||||
XFREE(MTYPE_BGP_ORR_GROUP, orr_group);
|
||||
@ -933,6 +932,7 @@ static int bgp_orr_igp_metric_update(struct orr_igp_metric_info *table)
|
||||
{
|
||||
afi_t afi;
|
||||
safi_t safi;
|
||||
bool add = false;
|
||||
bool root_found = false;
|
||||
uint32_t instId = 0;
|
||||
uint32_t numEntries = 0;
|
||||
@ -943,7 +943,7 @@ static int bgp_orr_igp_metric_update(struct orr_igp_metric_info *table)
|
||||
|
||||
struct list *orr_group_list = NULL;
|
||||
struct bgp_orr_group *group = NULL;
|
||||
struct listnode *node;
|
||||
struct listnode *node, *nnode;
|
||||
|
||||
struct bgp_orr_igp_metric *igp_metric = NULL;
|
||||
struct list *bgp_orr_igp_metric = NULL;
|
||||
@ -955,6 +955,7 @@ static int bgp_orr_igp_metric_update(struct orr_igp_metric_info *table)
|
||||
afi = family2afi(table->root.family);
|
||||
safi = table->safi;
|
||||
instId = table->instId;
|
||||
add = table->add;
|
||||
numEntries = table->num_entries;
|
||||
prefix_copy(&root, &table->root);
|
||||
|
||||
@ -985,8 +986,8 @@ static int bgp_orr_igp_metric_update(struct orr_igp_metric_info *table)
|
||||
zlog_debug("[BGP-ORR] %s: Address family %s", __func__,
|
||||
get_afi_safi_str(afi, safi, false));
|
||||
zlog_debug("[BGP-ORR] %s: Root %pFX", __func__, &root);
|
||||
zlog_debug("[BGP-ORR] %s: Number of entries %d", __func__,
|
||||
numEntries);
|
||||
zlog_debug("[BGP-ORR] %s: Number of entries to be %s %d",
|
||||
__func__, add ? "added" : "deleted", numEntries);
|
||||
zlog_debug("[BGP-ORR] %s: Prefix (Cost) :", __func__);
|
||||
for (entry = 0; entry < numEntries; entry++)
|
||||
zlog_debug("[BGP-ORR] %s: %pFX (%d)", __func__,
|
||||
@ -1007,27 +1008,52 @@ static int bgp_orr_igp_metric_update(struct orr_igp_metric_info *table)
|
||||
* group
|
||||
*/
|
||||
if (prefix_cmp(&pfx, &root) == 0) {
|
||||
if (!group->igp_metric_info)
|
||||
group->igp_metric_info = list_new();
|
||||
if (add) {
|
||||
/* Add new routes */
|
||||
if (!group->igp_metric_info)
|
||||
group->igp_metric_info = list_new();
|
||||
|
||||
bgp_orr_igp_metric = group->igp_metric_info;
|
||||
if (!bgp_orr_igp_metric)
|
||||
bgp_orr_igp_metric_register(group, false);
|
||||
assert(bgp_orr_igp_metric);
|
||||
|
||||
for (entry = 0; entry < numEntries; entry++) {
|
||||
igp_metric = XCALLOC(
|
||||
MTYPE_ORR_IGP_INFO,
|
||||
sizeof(struct bgp_orr_igp_metric));
|
||||
if (!igp_metric)
|
||||
bgp_orr_igp_metric = group->igp_metric_info;
|
||||
if (!bgp_orr_igp_metric)
|
||||
bgp_orr_igp_metric_register(group,
|
||||
false);
|
||||
assert(bgp_orr_igp_metric);
|
||||
|
||||
prefix_copy(&igp_metric->prefix,
|
||||
&table->nexthop[entry].prefix);
|
||||
igp_metric->igp_metric =
|
||||
table->nexthop[entry].metric;
|
||||
listnode_add(bgp_orr_igp_metric, igp_metric);
|
||||
for (entry = 0; entry < numEntries; entry++) {
|
||||
igp_metric = XCALLOC(
|
||||
MTYPE_ORR_IGP_INFO,
|
||||
sizeof(struct
|
||||
bgp_orr_igp_metric));
|
||||
if (!igp_metric)
|
||||
bgp_orr_igp_metric_register(
|
||||
group, false);
|
||||
|
||||
prefix_copy(
|
||||
&igp_metric->prefix,
|
||||
&table->nexthop[entry].prefix);
|
||||
igp_metric->igp_metric =
|
||||
table->nexthop[entry].metric;
|
||||
listnode_add(bgp_orr_igp_metric,
|
||||
igp_metric);
|
||||
}
|
||||
} else {
|
||||
/* Delete old routes */
|
||||
for (entry = 0; entry < numEntries; entry++) {
|
||||
for (ALL_LIST_ELEMENTS(
|
||||
group->igp_metric_info,
|
||||
node, nnode, igp_metric)) {
|
||||
if (prefix_cmp(
|
||||
&igp_metric->prefix,
|
||||
&table->nexthop[entry]
|
||||
.prefix))
|
||||
continue;
|
||||
listnode_delete(
|
||||
group->igp_metric_info,
|
||||
igp_metric);
|
||||
XFREE(MTYPE_ORR_IGP_INFO,
|
||||
igp_metric);
|
||||
}
|
||||
}
|
||||
}
|
||||
root_found = true;
|
||||
break;
|
||||
|
@ -51,6 +51,9 @@ struct orr_igp_metric_info {
|
||||
|
||||
safi_t safi;
|
||||
|
||||
/* Add or delete routes */
|
||||
bool add;
|
||||
|
||||
/* IGP metric from Active Root. */
|
||||
struct prefix root;
|
||||
uint32_t num_entries;
|
||||
|
@ -258,8 +258,8 @@ int ospf_orr_igp_metric_register(struct orr_igp_metric_reg msg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ospf_orr_igp_metric_send_update(struct orr_root *root,
|
||||
unsigned short instance)
|
||||
void ospf_orr_igp_metric_send_update_add(struct orr_root *root,
|
||||
unsigned short instance)
|
||||
{
|
||||
int ret;
|
||||
uint8_t count = 0;
|
||||
@ -271,8 +271,8 @@ void ospf_orr_igp_metric_send_update(struct orr_root *root,
|
||||
msg.proto = ZEBRA_ROUTE_OSPF;
|
||||
msg.safi = root->safi;
|
||||
msg.instId = instance;
|
||||
msg.add = true;
|
||||
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)) {
|
||||
@ -280,7 +280,8 @@ void ospf_orr_igp_metric_send_update(struct orr_root *root,
|
||||
if (!or)
|
||||
continue;
|
||||
|
||||
if (or->type != OSPF_DESTINATION_NETWORK)
|
||||
if (or->type != OSPF_DESTINATION_NETWORK &&
|
||||
or->type != OSPF_DESTINATION_DISCARD)
|
||||
continue;
|
||||
|
||||
if (ospf_route_match_same(root->old_table,
|
||||
@ -318,6 +319,74 @@ void ospf_orr_igp_metric_send_update(struct orr_root *root,
|
||||
}
|
||||
}
|
||||
|
||||
void ospf_orr_igp_metric_send_update_delete(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;
|
||||
|
||||
if (!root->old_table)
|
||||
return;
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.proto = ZEBRA_ROUTE_OSPF;
|
||||
msg.instId = instance;
|
||||
msg.safi = root->safi;
|
||||
msg.add = false;
|
||||
prefix_copy(&msg.root, &root->prefix);
|
||||
|
||||
/* Update prefix table from ORR Route table */
|
||||
for (rn = route_top(root->old_table); rn; rn = route_next(rn)) {
|
||||
or = rn->info;
|
||||
if (!or)
|
||||
continue;
|
||||
|
||||
if (or->path_type != OSPF_PATH_INTRA_AREA &&
|
||||
or->path_type != OSPF_PATH_INTER_AREA)
|
||||
continue;
|
||||
|
||||
if (or->type != OSPF_DESTINATION_NETWORK &&
|
||||
or->type != OSPF_DESTINATION_DISCARD)
|
||||
continue;
|
||||
|
||||
if (ospf_route_exist_new_table(root->new_table,
|
||||
(struct prefix_ipv4 *)&rn->p))
|
||||
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 > 0 && 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)
|
||||
@ -438,7 +507,8 @@ void ospf_orr_root_update_rcvd_lsa(struct ospf_lsa *lsa)
|
||||
}
|
||||
|
||||
/* Do not Install routes to root table. Just update table ponters */
|
||||
void ospf_orr_route_install(struct orr_root *root, struct route_table *rt)
|
||||
void ospf_orr_route_install(struct orr_root *root, struct route_table *rt,
|
||||
unsigned short instance)
|
||||
{
|
||||
/*
|
||||
* rt contains new routing table, new_table contains an old one.
|
||||
@ -449,6 +519,14 @@ void ospf_orr_route_install(struct orr_root *root, struct route_table *rt)
|
||||
|
||||
root->old_table = root->new_table;
|
||||
root->new_table = rt;
|
||||
|
||||
/* Send update to BGP to delete old routes. */
|
||||
ospf_orr_igp_metric_send_update_delete(root, instance);
|
||||
|
||||
/* REVISIT: Skipping external route table for now */
|
||||
|
||||
/* Send update to BGP to add new routes. */
|
||||
ospf_orr_igp_metric_send_update_add(root, instance);
|
||||
}
|
||||
|
||||
void ospf_orr_spf_calculate_schedule(struct ospf *ospf)
|
||||
|
@ -34,12 +34,15 @@
|
||||
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_igp_metric_send_update_add(struct orr_root *root,
|
||||
unsigned short instance);
|
||||
extern void ospf_orr_igp_metric_send_update_delete(struct orr_root *root,
|
||||
unsigned short instance);
|
||||
extern void ospf_orr_root_table_update(struct ospf_lsa *lsa, bool add);
|
||||
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);
|
||||
struct route_table *rt,
|
||||
unsigned short instance);
|
||||
extern void ospf_orr_spf_calculate_schedule(struct ospf *ospf);
|
||||
extern void ospf_orr_spf_calculate_area(struct ospf *ospf,
|
||||
struct ospf_area *area,
|
||||
|
@ -151,8 +151,8 @@ void ospf_route_table_free(struct route_table *rt)
|
||||
otherwise return 0. Since the ZEBRA-RIB does an implicit
|
||||
withdraw, it is not necessary to send a delete, an add later
|
||||
will act like an implicit delete. */
|
||||
static int ospf_route_exist_new_table(struct route_table *rt,
|
||||
struct prefix_ipv4 *prefix)
|
||||
int ospf_route_exist_new_table(struct route_table *rt,
|
||||
struct prefix_ipv4 *prefix)
|
||||
{
|
||||
struct route_node *rn;
|
||||
|
||||
|
@ -172,5 +172,6 @@ extern void ospf_delete_discard_route(struct ospf *, struct route_table *,
|
||||
struct prefix_ipv4 *);
|
||||
extern int ospf_route_match_same(struct route_table *, struct prefix_ipv4 *,
|
||||
struct ospf_route *);
|
||||
|
||||
extern int ospf_route_exist_new_table(struct route_table *rt,
|
||||
struct prefix_ipv4 *prefix);
|
||||
#endif /* _ZEBRA_OSPF_ROUTE_H */
|
||||
|
@ -2060,7 +2060,7 @@ void ospf_orr_spf_calculate_schedule_worker(struct thread *thread)
|
||||
|
||||
/* Update routing table. */
|
||||
monotime(&start_time);
|
||||
ospf_orr_route_install(root, new_table);
|
||||
ospf_orr_route_install(root, new_table, ospf->instance);
|
||||
rt_time = monotime_since(&start_time, NULL);
|
||||
|
||||
/*
|
||||
@ -2111,13 +2111,6 @@ void ospf_orr_spf_calculate_schedule_worker(struct thread *thread)
|
||||
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() */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user