Merge pull request #6912 from GalaxyGorilla/ospf_ti_lfa_prep

ospfd: preparation for TI-LFA
This commit is contained in:
Olivier Dugeon 2020-08-24 18:12:03 +02:00 committed by GitHub
commit 4f4eed1cff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 543 additions and 394 deletions

View File

@ -995,7 +995,8 @@ void ospf_vl_delete(struct ospf *ospf, struct ospf_vl_data *vl_data)
ospf_vl_data_free(vl_data);
}
static int ospf_vl_set_params(struct ospf_vl_data *vl_data, struct vertex *v)
static int ospf_vl_set_params(struct ospf_area *area,
struct ospf_vl_data *vl_data, struct vertex *v)
{
int changed = 0;
struct ospf_interface *voi;
@ -1003,6 +1004,7 @@ static int ospf_vl_set_params(struct ospf_vl_data *vl_data, struct vertex *v)
struct vertex_parent *vp = NULL;
unsigned int i;
struct router_lsa *rl;
struct ospf_interface *oi;
voi = vl_data->vl_oi;
@ -1013,17 +1015,24 @@ static int ospf_vl_set_params(struct ospf_vl_data *vl_data, struct vertex *v)
}
for (ALL_LIST_ELEMENTS_RO(v->parents, node, vp)) {
vl_data->nexthop.oi = vp->nexthop->oi;
vl_data->nexthop.lsa_pos = vp->nexthop->lsa_pos;
vl_data->nexthop.router = vp->nexthop->router;
if (!IPV4_ADDR_SAME(&voi->address->u.prefix4,
&vl_data->nexthop.oi->address->u.prefix4))
changed = 1;
/*
* Only deal with interface data when the local
* (calculating) node is the SPF root node
*/
if (!area->spf_dry_run) {
oi = ospf_if_lookup_by_lsa_pos(
area, vl_data->nexthop.lsa_pos);
voi->address->u.prefix4 =
vl_data->nexthop.oi->address->u.prefix4;
voi->address->prefixlen =
vl_data->nexthop.oi->address->prefixlen;
if (!IPV4_ADDR_SAME(&voi->address->u.prefix4,
&oi->address->u.prefix4))
changed = 1;
voi->address->u.prefix4 = oi->address->u.prefix4;
voi->address->prefixlen = oi->address->prefixlen;
}
break; /* We take the first interface. */
}
@ -1114,7 +1123,7 @@ void ospf_vl_up_check(struct ospf_area *area, struct in_addr rid,
OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceUp);
}
if (ospf_vl_set_params(vl_data, v)) {
if (ospf_vl_set_params(area, vl_data, v)) {
if (IS_DEBUG_OSPF(ism, ISM_EVENTS))
zlog_debug(
"ospf_vl_up_check: VL cost change, scheduling router lsa refresh");

View File

@ -375,7 +375,7 @@ void ospf_intra_add_router(struct route_table *rt, struct vertex *v,
else
route_unlock_node(rn);
ospf_route_copy_nexthops_from_vertex(or, v);
ospf_route_copy_nexthops_from_vertex(area, or, v);
listnode_add(rn->info, or);
@ -438,7 +438,7 @@ void ospf_intra_add_transit(struct route_table *rt, struct vertex *v,
or->type = OSPF_DESTINATION_NETWORK;
or->u.std.origin = (struct lsa_header *)lsa;
ospf_route_copy_nexthops_from_vertex(or, v);
ospf_route_copy_nexthops_from_vertex(area, or, v);
rn->info = or ;
}
@ -453,7 +453,7 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link,
struct ospf_route * or ;
struct prefix_ipv4 p;
struct router_lsa *lsa;
struct ospf_interface *oi;
struct ospf_interface *oi = NULL;
struct ospf_path *path;
if (IS_DEBUG_OSPF_EVENT)
@ -538,7 +538,7 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link,
zlog_debug(
"ospf_intra_add_stub(): routes are equal, merge");
ospf_route_copy_nexthops_from_vertex(cur_or, v);
ospf_route_copy_nexthops_from_vertex(area, cur_or, v);
if (IPV4_ADDR_CMP(&cur_or->u.std.origin->id,
&lsa->header.id)
@ -563,7 +563,7 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link,
list_delete_all_node(cur_or->paths);
ospf_route_copy_nexthops_from_vertex(cur_or, v);
ospf_route_copy_nexthops_from_vertex(area, cur_or, v);
cur_or->u.std.origin = (struct lsa_header *)lsa;
return;
@ -588,24 +588,35 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link,
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_intra_add_stub(): this network is on remote router");
ospf_route_copy_nexthops_from_vertex(or, v);
ospf_route_copy_nexthops_from_vertex(area, or, v);
} else {
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_intra_add_stub(): this network is on this router");
if ((oi = ospf_if_lookup_by_lsa_pos(area, lsa_pos))) {
/*
* Only deal with interface data when we
* don't do a dry run
*/
if (!area->spf_dry_run)
oi = ospf_if_lookup_by_lsa_pos(area, lsa_pos);
if (oi || area->spf_dry_run) {
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_intra_add_stub(): the interface is %s",
IF_NAME(oi));
"ospf_intra_add_stub(): the lsa pos is %d",
lsa_pos);
path = ospf_path_new();
path->nexthop.s_addr = INADDR_ANY;
path->ifindex = oi->ifp->ifindex;
if (CHECK_FLAG(oi->connected->flags,
ZEBRA_IFA_UNNUMBERED))
path->unnumbered = 1;
if (oi) {
path->ifindex = oi->ifp->ifindex;
if (CHECK_FLAG(oi->connected->flags,
ZEBRA_IFA_UNNUMBERED))
path->unnumbered = 1;
}
listnode_add(or->paths, path);
} else {
if (IS_DEBUG_OSPF_EVENT)
@ -654,6 +665,37 @@ void ospf_route_table_dump(struct route_table *rt)
zlog_debug("========================================");
}
void ospf_route_table_print(struct vty *vty, struct route_table *rt)
{
struct route_node *rn;
struct ospf_route * or ;
struct listnode *pnode;
struct ospf_path *path;
vty_out(vty, "========== OSPF routing table ==========\n");
for (rn = route_top(rt); rn; rn = route_next(rn))
if ((or = rn->info) != NULL) {
if (or->type == OSPF_DESTINATION_NETWORK) {
vty_out(vty, "N %-18pFX %-15pI4 %s %d\n",
&rn->p, & or->u.std.area_id,
ospf_path_type_str[or->path_type],
or->cost);
for (ALL_LIST_ELEMENTS_RO(or->paths, pnode,
path))
vty_out(vty, " -> %s\n",
path->nexthop.s_addr != 0
? inet_ntoa(
path->nexthop)
: "directly connected");
} else
vty_out(vty, "R %-18pI4 %-15pI4 %s %d\n",
&rn->p.u.prefix4, & or->u.std.area_id,
ospf_path_type_str[or->path_type],
or->cost);
}
vty_out(vty, "========================================\n");
}
/* This is 16.4.1 implementation.
o Intra-area paths using non-backbone areas are always the most preferred.
o The other paths, intra-area backbone paths and inter-area paths,
@ -734,30 +776,41 @@ static int ospf_path_exist(struct list *plist, struct in_addr nexthop,
return 0;
}
void ospf_route_copy_nexthops_from_vertex(struct ospf_route *to,
void ospf_route_copy_nexthops_from_vertex(struct ospf_area *area,
struct ospf_route *to,
struct vertex *v)
{
struct listnode *node;
struct ospf_path *path;
struct vertex_nexthop *nexthop;
struct vertex_parent *vp;
struct ospf_interface *oi = NULL;
assert(to->paths);
for (ALL_LIST_ELEMENTS_RO(v->parents, node, vp)) {
nexthop = vp->nexthop;
if (nexthop->oi != NULL) {
if (!ospf_path_exist(to->paths, nexthop->router,
nexthop->oi)) {
path = ospf_path_new();
path->nexthop = nexthop->router;
path->ifindex = nexthop->oi->ifp->ifindex;
if (CHECK_FLAG(nexthop->oi->connected->flags,
/*
* Only deal with interface data when we
* don't do a dry run
*/
if (!area->spf_dry_run)
oi = ospf_if_lookup_by_lsa_pos(area, nexthop->lsa_pos);
if ((oi && !ospf_path_exist(to->paths, nexthop->router, oi))
|| area->spf_dry_run) {
path = ospf_path_new();
path->nexthop = nexthop->router;
if (oi) {
path->ifindex = oi->ifp->ifindex;
if (CHECK_FLAG(oi->connected->flags,
ZEBRA_IFA_UNNUMBERED))
path->unnumbered = 1;
listnode_add(to->paths, path);
}
listnode_add(to->paths, path);
}
}
}

View File

@ -132,6 +132,7 @@ extern void ospf_route_table_free(struct route_table *);
extern void ospf_route_install(struct ospf *, struct route_table *);
extern void ospf_route_table_dump(struct route_table *);
extern void ospf_route_table_print(struct vty *vty, struct route_table *rt);
extern void ospf_intra_add_router(struct route_table *, struct vertex *,
struct ospf_area *);
@ -146,7 +147,8 @@ extern void ospf_intra_add_stub(struct route_table *, struct router_lsa_link *,
extern int ospf_route_cmp(struct ospf *, struct ospf_route *,
struct ospf_route *);
extern void ospf_route_copy_nexthops(struct ospf_route *, struct list *);
extern void ospf_route_copy_nexthops_from_vertex(struct ospf_route *,
extern void ospf_route_copy_nexthops_from_vertex(struct ospf_area *area,
struct ospf_route *,
struct vertex *);
extern void ospf_route_subst(struct route_node *, struct ospf_route *,

File diff suppressed because it is too large Load Diff

View File

@ -49,15 +49,14 @@ struct vertex {
/* A nexthop taken on the root node to get to this (parent) vertex */
struct vertex_nexthop {
struct ospf_interface *oi; /* output intf on root node */
struct in_addr router; /* router address to send to */
int lsa_pos; /* LSA position for resolving the interface */
};
struct vertex_parent {
struct vertex_nexthop
*nexthop; /* link to nexthop info for this parent */
struct vertex *parent; /* parent vertex */
int backlink; /* index back to parent for router-lsa's */
struct vertex_nexthop *nexthop; /* nexthop address for this parent */
struct vertex *parent; /* parent vertex */
int backlink; /* index back to parent for router-lsa's */
};
/* What triggered the SPF ? */
@ -73,7 +72,18 @@ typedef enum {
} ospf_spf_reason_t;
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,
struct route_table *new_table,
struct route_table *new_rtrs, bool is_dry_run,
bool is_root_node);
extern int ospf_spf_calculate_areas(struct ospf *ospf,
struct route_table *new_table,
struct route_table *new_rtrs,
bool is_dry_run, bool is_root_node);
extern void ospf_rtrs_free(struct route_table *);
extern void ospf_spf_print(struct vty *vty, struct vertex *v, int i);
/* void ospf_spf_calculate_timer_add (); */
#endif /* _QUAGGA_OSPF_SPF_H */

View File

@ -414,6 +414,10 @@ struct ospf_area {
/* Shortest Path Tree. */
struct vertex *spf;
bool spf_dry_run; /* flag for checking if the SPF calculation is
intended for the local RIB */
bool spf_root_node; /* flag for checking if the calculating node is the
root node of the SPF tree */
/* Threads. */
struct thread *t_stub_router; /* Stub-router timer */