mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-11 23:17:34 +00:00
Merge pull request #6912 from GalaxyGorilla/ospf_ti_lfa_prep
ospfd: preparation for TI-LFA
This commit is contained in:
commit
4f4eed1cff
@ -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");
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 *,
|
||||
|
783
ospfd/ospf_spf.c
783
ospfd/ospf_spf.c
File diff suppressed because it is too large
Load Diff
@ -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 */
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user