mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-15 07:15:19 +00:00
ospf6d: ospfv3-stub-area-support.patch
Support stubby and totally stubby areas in OSPFv3 Signed-off-by: Dinesh G Dutt <ddutt at cumulusnetworks.com> Reviewed-by: Pradosh Mohapatra <pmohapat at cumulusnetworks.com>
This commit is contained in:
parent
c3c0ac8395
commit
ca1f4309e6
@ -82,6 +82,11 @@
|
|||||||
#define OSPF_AREA_BACKBONE 0x00000000 /* 0.0.0.0 */
|
#define OSPF_AREA_BACKBONE 0x00000000 /* 0.0.0.0 */
|
||||||
#define OSPF_AREA_RANGE_COST_UNSPEC -1U
|
#define OSPF_AREA_RANGE_COST_UNSPEC -1U
|
||||||
|
|
||||||
|
#define OSPF_AREA_DEFAULT 0
|
||||||
|
#define OSPF_AREA_STUB 1
|
||||||
|
#define OSPF_AREA_NSSA 2
|
||||||
|
#define OSPF_AREA_TYPE_MAX 3
|
||||||
|
|
||||||
/* SPF Throttling timer values. */
|
/* SPF Throttling timer values. */
|
||||||
#define OSPF_SPF_DELAY_DEFAULT 200
|
#define OSPF_SPF_DELAY_DEFAULT 200
|
||||||
#define OSPF_SPF_HOLDTIME_DEFAULT 1000
|
#define OSPF_SPF_HOLDTIME_DEFAULT 1000
|
||||||
|
@ -57,8 +57,6 @@ static unsigned short timers_inited;
|
|||||||
|
|
||||||
static struct hash *cpu_record = NULL;
|
static struct hash *cpu_record = NULL;
|
||||||
|
|
||||||
/* Struct timeval's tv_usec one second value. */
|
|
||||||
#define TIMER_SECOND_MICRO 1000000L
|
|
||||||
|
|
||||||
/* Adjust so that tv_usec is in the range [0,TIMER_SECOND_MICRO).
|
/* Adjust so that tv_usec is in the range [0,TIMER_SECOND_MICRO).
|
||||||
And change negative values to 0. */
|
And change negative values to 0. */
|
||||||
|
@ -111,6 +111,9 @@ enum quagga_clkid {
|
|||||||
QUAGGA_CLK_REALTIME_STABILISED, /* like realtime, but non-decrementing */
|
QUAGGA_CLK_REALTIME_STABILISED, /* like realtime, but non-decrementing */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Struct timeval's tv_usec one second value. */
|
||||||
|
#define TIMER_SECOND_MICRO 1000000L
|
||||||
|
|
||||||
/* Thread types. */
|
/* Thread types. */
|
||||||
#define THREAD_READ 0
|
#define THREAD_READ 0
|
||||||
#define THREAD_WRITE 1
|
#define THREAD_WRITE 1
|
||||||
|
@ -91,7 +91,7 @@ ospf6_abr_delete_route (struct ospf6_route *range, struct ospf6_route *summary,
|
|||||||
ospf6_route_remove (summary, summary_table);
|
ospf6_route_remove (summary, summary_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old)
|
if (old && !OSPF6_LSA_IS_MAXAGE (old))
|
||||||
ospf6_lsa_purge (old);
|
ospf6_lsa_purge (old);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,35 +99,11 @@ void
|
|||||||
ospf6_abr_enable_area (struct ospf6_area *area)
|
ospf6_abr_enable_area (struct ospf6_area *area)
|
||||||
{
|
{
|
||||||
struct ospf6_area *oa;
|
struct ospf6_area *oa;
|
||||||
struct ospf6_route *ro;
|
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS (area->ospf6->area_list, node, nnode, oa))
|
for (ALL_LIST_ELEMENTS (area->ospf6->area_list, node, nnode, oa))
|
||||||
{
|
/* update B bit for each area */
|
||||||
/* update B bit for each area */
|
OSPF6_ROUTER_LSA_SCHEDULE (oa);
|
||||||
OSPF6_ROUTER_LSA_SCHEDULE (oa);
|
|
||||||
|
|
||||||
/* install other area's configured address range */
|
|
||||||
if (oa != area)
|
|
||||||
{
|
|
||||||
for (ro = ospf6_route_head (oa->range_table); ro;
|
|
||||||
ro = ospf6_route_next (ro))
|
|
||||||
{
|
|
||||||
if (CHECK_FLAG (ro->flag, OSPF6_ROUTE_ACTIVE_SUMMARY))
|
|
||||||
ospf6_abr_originate_summary_to_area (ro, area);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* install calculated routes to border routers */
|
|
||||||
for (ro = ospf6_route_head (area->ospf6->brouter_table); ro;
|
|
||||||
ro = ospf6_route_next (ro))
|
|
||||||
ospf6_abr_originate_summary_to_area (ro, area);
|
|
||||||
|
|
||||||
/* install calculated routes to network (may be rejected by ranges) */
|
|
||||||
for (ro = ospf6_route_head (area->ospf6->route_table); ro;
|
|
||||||
ro = ospf6_route_next (ro))
|
|
||||||
ospf6_abr_originate_summary_to_area (ro, area);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -167,6 +143,8 @@ ospf6_abr_disable_area (struct ospf6_area *area)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* RFC 2328 12.4.3. Summary-LSAs */
|
/* RFC 2328 12.4.3. Summary-LSAs */
|
||||||
|
/* Returns 1 if a summary LSA has been generated for the area */
|
||||||
|
/* This is used by the area/range logic to add/remove blackhole routes */
|
||||||
int
|
int
|
||||||
ospf6_abr_originate_summary_to_area (struct ospf6_route *route,
|
ospf6_abr_originate_summary_to_area (struct ospf6_route *route,
|
||||||
struct ospf6_area *area)
|
struct ospf6_area *area)
|
||||||
@ -295,6 +273,15 @@ ospf6_abr_originate_summary_to_area (struct ospf6_route *route,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (area->no_summary && (route->path.subtype != OSPF6_PATH_SUBTYPE_DEFAULT_RT))
|
||||||
|
{
|
||||||
|
if (is_debug)
|
||||||
|
zlog_debug ("Area has been stubbed, purge prefix LSA");
|
||||||
|
|
||||||
|
ospf6_abr_delete_route (route, summary, summary_table, old);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* do not generate if the route cost is greater or equal to LSInfinity */
|
/* do not generate if the route cost is greater or equal to LSInfinity */
|
||||||
if (route->path.cost >= OSPF_LS_INFINITY)
|
if (route->path.cost >= OSPF_LS_INFINITY)
|
||||||
{
|
{
|
||||||
@ -445,7 +432,6 @@ ospf6_abr_originate_summary_to_area (struct ospf6_route *route,
|
|||||||
summary->path.origin.adv_router, area->lsdb);
|
summary->path.origin.adv_router, area->lsdb);
|
||||||
}
|
}
|
||||||
summary = ospf6_route_add (summary, summary_table);
|
summary = ospf6_route_add (summary, summary_table);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -460,6 +446,7 @@ ospf6_abr_originate_summary_to_area (struct ospf6_route *route,
|
|||||||
summary->path.prefix_options = route->path.prefix_options;
|
summary->path.prefix_options = route->path.prefix_options;
|
||||||
summary->path.area_id = area->area_id;
|
summary->path.area_id = area->area_id;
|
||||||
summary->path.type = OSPF6_PATH_TYPE_INTER;
|
summary->path.type = OSPF6_PATH_TYPE_INTER;
|
||||||
|
summary->path.subtype = route->path.subtype;
|
||||||
summary->path.cost = route->path.cost;
|
summary->path.cost = route->path.cost;
|
||||||
/* summary->nexthop[0] = route->nexthop[0]; */
|
/* summary->nexthop[0] = route->nexthop[0]; */
|
||||||
|
|
||||||
@ -523,33 +510,95 @@ ospf6_abr_originate_summary_to_area (struct ospf6_route *route,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ospf6_abr_range_update (struct ospf6_route *range)
|
ospf6_abr_range_reset_cost (struct ospf6 *ospf6)
|
||||||
{
|
{
|
||||||
u_int32_t cost = 0;
|
struct listnode *node, *nnode;
|
||||||
struct ospf6_route *ro;
|
struct ospf6_area *oa;
|
||||||
int gen_range_summary = 0;
|
struct ospf6_route *range;
|
||||||
char buf[INET6_ADDRSTRLEN];
|
|
||||||
|
|
||||||
assert (range->type == OSPF6_DEST_TYPE_RANGE);
|
for (ALL_LIST_ELEMENTS (ospf6->area_list, node, nnode, oa))
|
||||||
prefix2str (&range->prefix, buf, sizeof (buf));
|
for (range = ospf6_route_head (oa->range_table); range;
|
||||||
|
range = ospf6_route_next (range))
|
||||||
|
OSPF6_ABR_RANGE_CLEAR_COST(range);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u_int32_t
|
||||||
|
ospf6_abr_range_compute_cost (struct ospf6_route *range, struct ospf6 *o)
|
||||||
|
{
|
||||||
|
struct ospf6_route *ro;
|
||||||
|
u_int32_t cost = 0;
|
||||||
|
|
||||||
|
for (ro = ospf6_route_match_head (&range->prefix, o->route_table);
|
||||||
|
ro; ro = ospf6_route_match_next (&range->prefix, ro))
|
||||||
|
{
|
||||||
|
if (ro->path.area_id == range->path.area_id &&
|
||||||
|
(ro->path.type == OSPF6_PATH_TYPE_INTRA) &&
|
||||||
|
! CHECK_FLAG (ro->flag, OSPF6_ROUTE_REMOVE))
|
||||||
|
cost = MAX (cost, ro->path.cost);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
ospf6_abr_range_summary_needs_update (struct ospf6_route *range,
|
||||||
|
u_int32_t cost)
|
||||||
|
{
|
||||||
|
int redo_summary = 0;
|
||||||
|
|
||||||
if (CHECK_FLAG(range->flag, OSPF6_ROUTE_REMOVE))
|
if (CHECK_FLAG(range->flag, OSPF6_ROUTE_REMOVE))
|
||||||
{
|
{
|
||||||
UNSET_FLAG (range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY);
|
UNSET_FLAG (range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY);
|
||||||
gen_range_summary = 1;
|
redo_summary = 1;
|
||||||
}
|
}
|
||||||
else
|
else if (CHECK_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE))
|
||||||
{
|
{
|
||||||
/* update range's cost and active flag */
|
if (range->path.cost != 0)
|
||||||
for (ro = ospf6_route_match_head (&range->prefix, ospf6->route_table);
|
|
||||||
ro; ro = ospf6_route_match_next (&range->prefix, ro))
|
|
||||||
{
|
{
|
||||||
if (ro->path.area_id == range->path.area_id &&
|
range->path.cost = 0;
|
||||||
(ro->path.type == OSPF6_PATH_TYPE_INTRA) &&
|
redo_summary = 1;
|
||||||
! CHECK_FLAG (ro->flag, OSPF6_ROUTE_REMOVE))
|
|
||||||
cost = MAX (cost, ro->path.cost);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (cost)
|
||||||
|
{
|
||||||
|
if ((OSPF6_PATH_COST_IS_CONFIGURED(range->path) &&
|
||||||
|
range->path.cost != range->path.u.cost_config))
|
||||||
|
{
|
||||||
|
range->path.cost = range->path.u.cost_config;
|
||||||
|
SET_FLAG (range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY);
|
||||||
|
redo_summary = 1;
|
||||||
|
}
|
||||||
|
else if (!OSPF6_PATH_COST_IS_CONFIGURED(range->path) &&
|
||||||
|
range->path.cost != cost)
|
||||||
|
{
|
||||||
|
range->path.cost = cost;
|
||||||
|
SET_FLAG (range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY);
|
||||||
|
redo_summary = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (CHECK_FLAG (range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY))
|
||||||
|
{
|
||||||
|
/* Cost is zero, meaning no active range */
|
||||||
|
UNSET_FLAG (range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY);
|
||||||
|
range->path.cost = OSPF_AREA_RANGE_COST_UNSPEC;
|
||||||
|
redo_summary = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (redo_summary);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ospf6_abr_range_update (struct ospf6_route *range)
|
||||||
|
{
|
||||||
|
u_int32_t cost = 0;
|
||||||
|
struct listnode *node, *nnode;
|
||||||
|
struct ospf6_area *oa;
|
||||||
|
int summary_orig = 0;
|
||||||
|
|
||||||
|
assert (range->type == OSPF6_DEST_TYPE_RANGE);
|
||||||
|
|
||||||
|
/* update range's cost and active flag */
|
||||||
|
cost = ospf6_abr_range_compute_cost (range, ospf6);
|
||||||
|
|
||||||
/* Non-zero cost is a proxy for active longer prefixes in this range.
|
/* Non-zero cost is a proxy for active longer prefixes in this range.
|
||||||
* If there are active routes covered by this range AND either the configured
|
* If there are active routes covered by this range AND either the configured
|
||||||
@ -561,56 +610,32 @@ ospf6_abr_range_update (struct ospf6_route *range)
|
|||||||
* work the first time. Subsequent times the path.cost is not 0 anyway if there
|
* work the first time. Subsequent times the path.cost is not 0 anyway if there
|
||||||
* were active ranges.
|
* were active ranges.
|
||||||
*/
|
*/
|
||||||
if (CHECK_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE))
|
|
||||||
|
if (ospf6_abr_range_summary_needs_update (range, cost))
|
||||||
{
|
{
|
||||||
if (range->path.cost != 0)
|
for (ALL_LIST_ELEMENTS (ospf6->area_list, node, nnode, oa))
|
||||||
|
summary_orig += ospf6_abr_originate_summary_to_area (range, oa);
|
||||||
|
|
||||||
|
if (CHECK_FLAG (range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY) && summary_orig)
|
||||||
{
|
{
|
||||||
range->path.cost = 0;
|
if (! CHECK_FLAG (range->flag, OSPF6_ROUTE_BLACKHOLE_ADDED))
|
||||||
gen_range_summary = 1;
|
{
|
||||||
}
|
if (IS_OSPF6_DEBUG_ABR)
|
||||||
}
|
zlog_debug ("Add discard route");
|
||||||
else if (cost &&
|
|
||||||
(((range->path.u.cost_config != OSPF_AREA_RANGE_COST_UNSPEC) &&
|
ospf6_zebra_add_discard (range);
|
||||||
(range->path.cost != range->path.u.cost_config)) ||
|
}
|
||||||
((range->path.u.cost_config == OSPF_AREA_RANGE_COST_UNSPEC) &&
|
|
||||||
(range->path.cost != cost))))
|
|
||||||
{
|
|
||||||
if (range->path.u.cost_config == OSPF_AREA_RANGE_COST_UNSPEC)
|
|
||||||
{
|
|
||||||
range->path.cost = cost;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
range->path.cost = range->path.u.cost_config;
|
/* Summary removed or no summary generated as no specifics exist */
|
||||||
}
|
if (CHECK_FLAG (range->flag, OSPF6_ROUTE_BLACKHOLE_ADDED))
|
||||||
|
{
|
||||||
|
if (IS_OSPF6_DEBUG_ABR)
|
||||||
|
zlog_debug ("Delete discard route");
|
||||||
|
|
||||||
SET_FLAG (range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY);
|
ospf6_zebra_delete_discard (range);
|
||||||
gen_range_summary = 1;
|
}
|
||||||
}
|
|
||||||
else if (!cost && CHECK_FLAG (range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY))
|
|
||||||
{
|
|
||||||
UNSET_FLAG (range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY);
|
|
||||||
range->path.cost = OSPF_AREA_RANGE_COST_UNSPEC;
|
|
||||||
gen_range_summary = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gen_range_summary)
|
|
||||||
{
|
|
||||||
ospf6_abr_originate_summary (range);
|
|
||||||
|
|
||||||
if (CHECK_FLAG (range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY))
|
|
||||||
{
|
|
||||||
if (IS_OSPF6_DEBUG_ABR)
|
|
||||||
zlog_debug ("Add discard route");
|
|
||||||
|
|
||||||
ospf6_zebra_add_discard (range);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (IS_OSPF6_DEBUG_ABR)
|
|
||||||
zlog_debug ("Delete discard route");
|
|
||||||
|
|
||||||
ospf6_zebra_delete_discard (range);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -636,6 +661,54 @@ ospf6_abr_originate_summary (struct ospf6_route *route)
|
|||||||
ospf6_abr_originate_summary_to_area (route, oa);
|
ospf6_abr_originate_summary_to_area (route, oa);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ospf6_abr_defaults_to_stub (struct ospf6 *o)
|
||||||
|
{
|
||||||
|
struct listnode *node, *nnode;
|
||||||
|
struct ospf6_area *oa;
|
||||||
|
struct ospf6_route *def, *route;
|
||||||
|
|
||||||
|
if (!o->backbone)
|
||||||
|
return;
|
||||||
|
|
||||||
|
def = ospf6_route_create();
|
||||||
|
def->type = OSPF6_DEST_TYPE_NETWORK;
|
||||||
|
def->prefix.family = AF_INET6;
|
||||||
|
def->prefix.prefixlen = 0;
|
||||||
|
memset (&def->prefix.u.prefix6, 0, sizeof(struct in6_addr));
|
||||||
|
def->type = OSPF6_DEST_TYPE_NETWORK;
|
||||||
|
def->path.type = OSPF6_PATH_TYPE_INTER;
|
||||||
|
def->path.subtype = OSPF6_PATH_SUBTYPE_DEFAULT_RT;
|
||||||
|
def->path.area_id = o->backbone->area_id;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS (ospf6->area_list, node, nnode, oa))
|
||||||
|
{
|
||||||
|
if (!IS_AREA_STUB (oa))
|
||||||
|
{
|
||||||
|
/* withdraw defaults when an area switches from stub to non-stub */
|
||||||
|
route = ospf6_route_lookup (&def->prefix, oa->summary_prefix);
|
||||||
|
if (route && (route->path.subtype == def->path.subtype))
|
||||||
|
{
|
||||||
|
if (IS_OSPF6_DEBUG_ABR)
|
||||||
|
zlog_debug ("Withdrawing default route from non-stubby area %s",
|
||||||
|
oa->name);
|
||||||
|
SET_FLAG (def->flag, OSPF6_ROUTE_REMOVE);
|
||||||
|
ospf6_abr_originate_summary_to_area (def, oa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* announce defaults to stubby areas */
|
||||||
|
if (IS_OSPF6_DEBUG_ABR)
|
||||||
|
zlog_debug ("Announcing default route into stubby area %s",
|
||||||
|
oa->name);
|
||||||
|
UNSET_FLAG (def->flag, OSPF6_ROUTE_REMOVE);
|
||||||
|
ospf6_abr_originate_summary_to_area (def, oa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ospf6_route_delete (def);
|
||||||
|
}
|
||||||
|
|
||||||
/* RFC 2328 16.2. Calculating the inter-area routes */
|
/* RFC 2328 16.2. Calculating the inter-area routes */
|
||||||
void
|
void
|
||||||
ospf6_abr_examin_summary (struct ospf6_lsa *lsa, struct ospf6_area *oa)
|
ospf6_abr_examin_summary (struct ospf6_lsa *lsa, struct ospf6_area *oa)
|
||||||
@ -939,6 +1012,21 @@ ospf6_abr_reimport (struct ospf6_area *oa)
|
|||||||
ospf6_abr_examin_summary (lsa, oa);
|
ospf6_abr_examin_summary (lsa, oa);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ospf6_abr_prefix_resummarize (struct ospf6 *o)
|
||||||
|
{
|
||||||
|
struct ospf6_route *route;
|
||||||
|
|
||||||
|
if (IS_OSPF6_DEBUG_ABR)
|
||||||
|
zlog_debug ("Re-examining Inter-Prefix Summaries");
|
||||||
|
|
||||||
|
for (route = ospf6_route_head (o->route_table); route;
|
||||||
|
route = ospf6_route_next (route))
|
||||||
|
ospf6_abr_originate_summary(route);
|
||||||
|
|
||||||
|
if (IS_OSPF6_DEBUG_ABR)
|
||||||
|
zlog_debug ("Finished re-examining Inter-Prefix Summaries");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Display functions */
|
/* Display functions */
|
||||||
|
@ -57,6 +57,8 @@ struct ospf6_inter_router_lsa
|
|||||||
{ (E)->metric &= htonl (0x00000000); \
|
{ (E)->metric &= htonl (0x00000000); \
|
||||||
(E)->metric |= htonl (0x00ffffff) & htonl (C); }
|
(E)->metric |= htonl (0x00ffffff) & htonl (C); }
|
||||||
|
|
||||||
|
#define OSPF6_ABR_RANGE_CLEAR_COST(range) (range->path.cost = OSPF_AREA_RANGE_COST_UNSPEC)
|
||||||
|
|
||||||
extern int ospf6_is_router_abr (struct ospf6 *o);
|
extern int ospf6_is_router_abr (struct ospf6 *o);
|
||||||
|
|
||||||
extern void ospf6_abr_enable_area (struct ospf6_area *oa);
|
extern void ospf6_abr_enable_area (struct ospf6_area *oa);
|
||||||
@ -66,9 +68,11 @@ extern int ospf6_abr_originate_summary_to_area (struct ospf6_route *route,
|
|||||||
struct ospf6_area *area);
|
struct ospf6_area *area);
|
||||||
extern void ospf6_abr_originate_summary (struct ospf6_route *route);
|
extern void ospf6_abr_originate_summary (struct ospf6_route *route);
|
||||||
extern void ospf6_abr_examin_summary (struct ospf6_lsa *lsa, struct ospf6_area *oa);
|
extern void ospf6_abr_examin_summary (struct ospf6_lsa *lsa, struct ospf6_area *oa);
|
||||||
|
extern void ospf6_abr_defaults_to_stub (struct ospf6 *);
|
||||||
extern void ospf6_abr_examin_brouter (u_int32_t router_id);
|
extern void ospf6_abr_examin_brouter (u_int32_t router_id);
|
||||||
extern void ospf6_abr_reimport (struct ospf6_area *oa);
|
extern void ospf6_abr_reimport (struct ospf6_area *oa);
|
||||||
extern void ospf6_abr_range_update (struct ospf6_route *range);
|
extern void ospf6_abr_range_reset_cost (struct ospf6 *ospf6);
|
||||||
|
extern void ospf6_abr_prefix_resummarize (struct ospf6 *ospf6);
|
||||||
|
|
||||||
extern int config_write_ospf6_debug_abr (struct vty *vty);
|
extern int config_write_ospf6_debug_abr (struct vty *vty);
|
||||||
extern void install_element_ospf6_debug_abr (void);
|
extern void install_element_ospf6_debug_abr (void);
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#include "ospf6_interface.h"
|
#include "ospf6_interface.h"
|
||||||
#include "ospf6_intra.h"
|
#include "ospf6_intra.h"
|
||||||
#include "ospf6_abr.h"
|
#include "ospf6_abr.h"
|
||||||
|
#include "ospf6_asbr.h"
|
||||||
#include "ospf6d.h"
|
#include "ospf6d.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -133,12 +134,82 @@ ospf6_area_route_hook_remove (struct ospf6_route *route)
|
|||||||
ospf6_route_remove (copy, ospf6->route_table);
|
ospf6_route_remove (copy, ospf6->route_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ospf6_area_stub_update (struct ospf6_area *area)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (IS_AREA_STUB (area))
|
||||||
|
{
|
||||||
|
if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
|
||||||
|
zlog_debug ("Stubbing out area for if %s\n", area->name);
|
||||||
|
OSPF6_OPT_CLEAR (area->options, OSPF6_OPT_E);
|
||||||
|
}
|
||||||
|
else if (IS_AREA_ENABLED (area))
|
||||||
|
{
|
||||||
|
if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
|
||||||
|
zlog_debug ("Normal area for if %s\n", area->name);
|
||||||
|
OSPF6_OPT_SET (area->options, OSPF6_OPT_E);
|
||||||
|
ospf6_asbr_send_externals_to_area (area);
|
||||||
|
}
|
||||||
|
|
||||||
|
OSPF6_ROUTER_LSA_SCHEDULE(area);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ospf6_area_stub_set (struct ospf6 *ospf6, struct ospf6_area *area)
|
||||||
|
{
|
||||||
|
if (!IS_AREA_STUB(area))
|
||||||
|
{
|
||||||
|
SET_FLAG (area->flag, OSPF6_AREA_STUB);
|
||||||
|
ospf6_area_stub_update (area);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ospf6_area_stub_unset (struct ospf6 *ospf6, struct ospf6_area *area)
|
||||||
|
{
|
||||||
|
if (IS_AREA_STUB (area))
|
||||||
|
{
|
||||||
|
UNSET_FLAG (area->flag, OSPF6_AREA_STUB);
|
||||||
|
ospf6_area_stub_update (area);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ospf6_area_no_summary_set (struct ospf6 *ospf6, struct ospf6_area *area)
|
||||||
|
{
|
||||||
|
if (area)
|
||||||
|
{
|
||||||
|
if (!area->no_summary)
|
||||||
|
{
|
||||||
|
area->no_summary = 1;
|
||||||
|
ospf6_abr_range_reset_cost (ospf6);
|
||||||
|
ospf6_abr_prefix_resummarize (ospf6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ospf6_area_no_summary_unset (struct ospf6 *ospf6, struct ospf6_area *area)
|
||||||
|
{
|
||||||
|
if (area)
|
||||||
|
{
|
||||||
|
if (area->no_summary)
|
||||||
|
{
|
||||||
|
area->no_summary = 0;
|
||||||
|
ospf6_abr_range_reset_cost (ospf6);
|
||||||
|
ospf6_abr_prefix_resummarize (ospf6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Make new area structure */
|
/* Make new area structure */
|
||||||
struct ospf6_area *
|
struct ospf6_area *
|
||||||
ospf6_area_create (u_int32_t area_id, struct ospf6 *o)
|
ospf6_area_create (u_int32_t area_id, struct ospf6 *o)
|
||||||
{
|
{
|
||||||
struct ospf6_area *oa;
|
struct ospf6_area *oa;
|
||||||
struct ospf6_route *route;
|
|
||||||
|
|
||||||
oa = XCALLOC (MTYPE_OSPF6_AREA, sizeof (struct ospf6_area));
|
oa = XCALLOC (MTYPE_OSPF6_AREA, sizeof (struct ospf6_area));
|
||||||
|
|
||||||
@ -180,6 +251,9 @@ ospf6_area_create (u_int32_t area_id, struct ospf6 *o)
|
|||||||
|
|
||||||
OSPF6_OPT_SET (oa->options, OSPF6_OPT_E);
|
OSPF6_OPT_SET (oa->options, OSPF6_OPT_E);
|
||||||
|
|
||||||
|
SET_FLAG (oa->flag, OSPF6_AREA_ACTIVE);
|
||||||
|
SET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
|
||||||
|
|
||||||
oa->ospf6 = o;
|
oa->ospf6 = o;
|
||||||
listnode_add_sort (o->area_list, oa);
|
listnode_add_sort (o->area_list, oa);
|
||||||
|
|
||||||
@ -188,11 +262,6 @@ ospf6_area_create (u_int32_t area_id, struct ospf6 *o)
|
|||||||
o->backbone = oa;
|
o->backbone = oa;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* import athoer area's routes as inter-area routes */
|
|
||||||
for (route = ospf6_route_head (o->route_table); route;
|
|
||||||
route = ospf6_route_next (route))
|
|
||||||
ospf6_abr_originate_summary_to_area (route, oa);
|
|
||||||
|
|
||||||
return oa;
|
return oa;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,16 +363,46 @@ ospf6_area_show (struct vty *vty, struct ospf6_area *oa)
|
|||||||
{
|
{
|
||||||
struct listnode *i;
|
struct listnode *i;
|
||||||
struct ospf6_interface *oi;
|
struct ospf6_interface *oi;
|
||||||
|
unsigned long result;
|
||||||
|
|
||||||
vty_out (vty, " Area %s%s", oa->name, VNL);
|
if (!IS_AREA_STUB (oa))
|
||||||
|
vty_out (vty, " Area %s%s", oa->name, VNL);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (oa->no_summary)
|
||||||
|
{
|
||||||
|
vty_out (vty, " Area %s[Stub, No Summary]%s", oa->name, VNL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vty_out (vty, " Area %s[Stub]%s", oa->name, VNL);
|
||||||
|
}
|
||||||
|
}
|
||||||
vty_out (vty, " Number of Area scoped LSAs is %u%s",
|
vty_out (vty, " Number of Area scoped LSAs is %u%s",
|
||||||
oa->lsdb->count, VNL);
|
oa->lsdb->count, VNL);
|
||||||
|
|
||||||
vty_out (vty, " Interface attached to this area:");
|
vty_out (vty, " Interface attached to this area:");
|
||||||
for (ALL_LIST_ELEMENTS_RO (oa->if_list, i, oi))
|
for (ALL_LIST_ELEMENTS_RO (oa->if_list, i, oi))
|
||||||
vty_out (vty, " %s", oi->interface->name);
|
vty_out (vty, " %s", oi->interface->name);
|
||||||
|
|
||||||
vty_out (vty, "%s", VNL);
|
vty_out (vty, "%s", VNL);
|
||||||
|
|
||||||
|
if (oa->ts_spf.tv_sec || oa->ts_spf.tv_usec)
|
||||||
|
{
|
||||||
|
result = timeval_elapsed (recent_relative_time (), oa->ts_spf);
|
||||||
|
if (result/TIMER_SECOND_MICRO > 0)
|
||||||
|
{
|
||||||
|
vty_out (vty, "SPF last executed %ld.%lds ago%s",
|
||||||
|
result/TIMER_SECOND_MICRO,
|
||||||
|
result%TIMER_SECOND_MICRO, VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vty_out (vty, "SPF last executed %ldus ago%s",
|
||||||
|
result, VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vty_out (vty, "SPF has not been run%s", VTY_NEWLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -346,7 +445,7 @@ DEFUN (area_range,
|
|||||||
int ret;
|
int ret;
|
||||||
struct ospf6_area *oa;
|
struct ospf6_area *oa;
|
||||||
struct prefix prefix;
|
struct prefix prefix;
|
||||||
struct ospf6_route *range, *route;
|
struct ospf6_route *range;
|
||||||
u_int32_t cost = OSPF_AREA_RANGE_COST_UNSPEC;
|
u_int32_t cost = OSPF_AREA_RANGE_COST_UNSPEC;
|
||||||
|
|
||||||
OSPF6_CMD_AREA_GET (argv[0], oa);
|
OSPF6_CMD_AREA_GET (argv[0], oa);
|
||||||
@ -398,9 +497,7 @@ DEFUN (area_range,
|
|||||||
if (ospf6_is_router_abr (ospf6))
|
if (ospf6_is_router_abr (ospf6))
|
||||||
{
|
{
|
||||||
/* Redo summaries if required */
|
/* Redo summaries if required */
|
||||||
for (route = ospf6_route_head (ospf6->route_table); route;
|
ospf6_abr_prefix_resummarize (ospf6);
|
||||||
route = ospf6_route_next (route))
|
|
||||||
ospf6_abr_originate_summary(route);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
@ -503,6 +600,13 @@ ospf6_area_config_write (struct vty *vty)
|
|||||||
prefix2str (&range->prefix, buf, sizeof (buf));
|
prefix2str (&range->prefix, buf, sizeof (buf));
|
||||||
vty_out (vty, " area %s range %s%s", oa->name, buf, VNL);
|
vty_out (vty, " area %s range %s%s", oa->name, buf, VNL);
|
||||||
}
|
}
|
||||||
|
if (IS_AREA_STUB (oa))
|
||||||
|
{
|
||||||
|
if (oa->no_summary)
|
||||||
|
vty_out (vty, " area %s stub no-summary%s", oa->name, VNL);
|
||||||
|
else
|
||||||
|
vty_out (vty, " area %s stub%s", oa->name, VNL);
|
||||||
|
}
|
||||||
if (PREFIX_NAME_IN (oa))
|
if (PREFIX_NAME_IN (oa))
|
||||||
vty_out (vty, " area %s filter-list prefix %s in%s",
|
vty_out (vty, " area %s filter-list prefix %s in%s",
|
||||||
oa->name, PREFIX_NAME_IN (oa), VNL);
|
oa->name, PREFIX_NAME_IN (oa), VNL);
|
||||||
@ -842,6 +946,94 @@ DEFUN (show_ipv6_ospf6_simulate_spf_tree_root,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFUN (ospf6_area_stub,
|
||||||
|
ospf6_area_stub_cmd,
|
||||||
|
"area (A.B.C.D|<0-4294967295>) stub",
|
||||||
|
"OSPF6 area parameters\n"
|
||||||
|
"OSPF6 area ID in IP address format\n"
|
||||||
|
"OSPF6 area ID as a decimal value\n"
|
||||||
|
"Configure OSPF6 area as stub\n")
|
||||||
|
{
|
||||||
|
struct ospf6_area *area;
|
||||||
|
|
||||||
|
OSPF6_CMD_AREA_GET(argv[0], area);
|
||||||
|
|
||||||
|
if (!ospf6_area_stub_set (ospf6, area))
|
||||||
|
{
|
||||||
|
vty_out (vty, "First deconfigure all virtual link through this area%s",
|
||||||
|
VTY_NEWLINE);
|
||||||
|
return CMD_WARNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
ospf6_area_no_summary_unset (ospf6, area);
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN (ospf6_area_stub_no_summary,
|
||||||
|
ospf6_area_stub_no_summary_cmd,
|
||||||
|
"area (A.B.C.D|<0-4294967295>) stub no-summary",
|
||||||
|
"OSPF6 stub parameters\n"
|
||||||
|
"OSPF6 area ID in IP address format\n"
|
||||||
|
"OSPF6 area ID as a decimal value\n"
|
||||||
|
"Configure OSPF6 area as stub\n"
|
||||||
|
"Do not inject inter-area routes into stub\n")
|
||||||
|
{
|
||||||
|
struct ospf6_area *area;
|
||||||
|
|
||||||
|
OSPF6_CMD_AREA_GET(argv[0], area);
|
||||||
|
|
||||||
|
if (!ospf6_area_stub_set (ospf6, area))
|
||||||
|
{
|
||||||
|
vty_out (vty, "First deconfigure all virtual link through this area%s",
|
||||||
|
VTY_NEWLINE);
|
||||||
|
return CMD_WARNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
ospf6_area_no_summary_set (ospf6, area);
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN (no_ospf6_area_stub,
|
||||||
|
no_ospf6_area_stub_cmd,
|
||||||
|
"no area (A.B.C.D|<0-4294967295>) stub",
|
||||||
|
NO_STR
|
||||||
|
"OSPF6 area parameters\n"
|
||||||
|
"OSPF6 area ID in IP address format\n"
|
||||||
|
"OSPF6 area ID as a decimal value\n"
|
||||||
|
"Configure OSPF6 area as stub\n")
|
||||||
|
{
|
||||||
|
struct ospf6_area *area;
|
||||||
|
|
||||||
|
OSPF6_CMD_AREA_GET(argv[0], area);
|
||||||
|
|
||||||
|
ospf6_area_stub_unset (ospf6, area);
|
||||||
|
ospf6_area_no_summary_unset (ospf6, area);
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN (no_ospf6_area_stub_no_summary,
|
||||||
|
no_ospf6_area_stub_no_summary_cmd,
|
||||||
|
"no area (A.B.C.D|<0-4294967295>) stub no-summary",
|
||||||
|
NO_STR
|
||||||
|
"OSPF6 area parameters\n"
|
||||||
|
"OSPF6 area ID in IP address format\n"
|
||||||
|
"OSPF6 area ID as a decimal value\n"
|
||||||
|
"Configure OSPF6 area as stub\n"
|
||||||
|
"Do not inject inter-area routes into area\n")
|
||||||
|
{
|
||||||
|
struct ospf6_area *area;
|
||||||
|
|
||||||
|
OSPF6_CMD_AREA_GET(argv[0], area);
|
||||||
|
|
||||||
|
ospf6_area_stub_unset (ospf6, area);
|
||||||
|
ospf6_area_no_summary_unset (ospf6, area);
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ospf6_area_init (void)
|
ospf6_area_init (void)
|
||||||
{
|
{
|
||||||
@ -858,6 +1050,11 @@ ospf6_area_init (void)
|
|||||||
install_element (OSPF6_NODE, &area_range_cost_cmd);
|
install_element (OSPF6_NODE, &area_range_cost_cmd);
|
||||||
install_element (OSPF6_NODE, &area_range_advertise_cost_cmd);
|
install_element (OSPF6_NODE, &area_range_advertise_cost_cmd);
|
||||||
install_element (OSPF6_NODE, &no_area_range_cmd);
|
install_element (OSPF6_NODE, &no_area_range_cmd);
|
||||||
|
install_element (OSPF6_NODE, &ospf6_area_stub_no_summary_cmd);
|
||||||
|
install_element (OSPF6_NODE, &ospf6_area_stub_cmd);
|
||||||
|
install_element (OSPF6_NODE, &no_ospf6_area_stub_no_summary_cmd);
|
||||||
|
install_element (OSPF6_NODE, &no_ospf6_area_stub_cmd);
|
||||||
|
|
||||||
|
|
||||||
install_element (OSPF6_NODE, &area_import_list_cmd);
|
install_element (OSPF6_NODE, &area_import_list_cmd);
|
||||||
install_element (OSPF6_NODE, &no_area_import_list_cmd);
|
install_element (OSPF6_NODE, &no_area_import_list_cmd);
|
||||||
|
@ -46,6 +46,9 @@ struct ospf6_area
|
|||||||
struct ospf6_route_table *summary_prefix;
|
struct ospf6_route_table *summary_prefix;
|
||||||
struct ospf6_route_table *summary_router;
|
struct ospf6_route_table *summary_router;
|
||||||
|
|
||||||
|
/* Area type */
|
||||||
|
int no_summary;
|
||||||
|
|
||||||
/* OSPF interface list */
|
/* OSPF interface list */
|
||||||
struct list *if_list;
|
struct list *if_list;
|
||||||
|
|
||||||
|
@ -412,6 +412,23 @@ ospf6_asbr_redistribute_unset (int type)
|
|||||||
ospf6_asbr_routemap_unset (type);
|
ospf6_asbr_routemap_unset (type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* When an area is unstubified, flood all the external LSAs in the area */
|
||||||
|
void
|
||||||
|
ospf6_asbr_send_externals_to_area (struct ospf6_area *oa)
|
||||||
|
{
|
||||||
|
struct ospf6_lsa *lsa;
|
||||||
|
|
||||||
|
for (lsa = ospf6_lsdb_head (oa->ospf6->lsdb); lsa;
|
||||||
|
lsa = ospf6_lsdb_next (lsa))
|
||||||
|
{
|
||||||
|
if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL)
|
||||||
|
{
|
||||||
|
zlog_debug ("%s: Flooding AS-External LSA %s\n", __func__, lsa->name);
|
||||||
|
ospf6_flood_area (NULL, lsa, oa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ospf6_asbr_redistribute_add (int type, int ifindex, struct prefix *prefix,
|
ospf6_asbr_redistribute_add (int type, int ifindex, struct prefix *prefix,
|
||||||
u_int nexthop_num, struct in6_addr *nexthop)
|
u_int nexthop_num, struct in6_addr *nexthop)
|
||||||
|
@ -91,6 +91,7 @@ extern int ospf6_redistribute_config_write (struct vty *vty);
|
|||||||
extern void ospf6_asbr_init (void);
|
extern void ospf6_asbr_init (void);
|
||||||
extern void ospf6_asbr_redistribute_reset (void);
|
extern void ospf6_asbr_redistribute_reset (void);
|
||||||
extern void ospf6_asbr_terminate (void);
|
extern void ospf6_asbr_terminate (void);
|
||||||
|
extern void ospf6_asbr_send_externals_to_area (struct ospf6_area *);
|
||||||
|
|
||||||
extern int config_write_ospf6_debug_asbr (struct vty *vty);
|
extern int config_write_ospf6_debug_asbr (struct vty *vty);
|
||||||
extern void install_element_ospf6_debug_asbr (void);
|
extern void install_element_ospf6_debug_asbr (void);
|
||||||
|
@ -422,7 +422,7 @@ ospf6_flood_interface (struct ospf6_neighbor *from,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
ospf6_flood_area (struct ospf6_neighbor *from,
|
ospf6_flood_area (struct ospf6_neighbor *from,
|
||||||
struct ospf6_lsa *lsa, struct ospf6_area *oa)
|
struct ospf6_lsa *lsa, struct ospf6_area *oa)
|
||||||
{
|
{
|
||||||
|
@ -52,6 +52,8 @@ extern void ospf6_decrement_retrans_count (struct ospf6_lsa *lsa);
|
|||||||
/* flooding & clear flooding */
|
/* flooding & clear flooding */
|
||||||
extern void ospf6_flood_clear (struct ospf6_lsa *lsa);
|
extern void ospf6_flood_clear (struct ospf6_lsa *lsa);
|
||||||
extern void ospf6_flood (struct ospf6_neighbor *from, struct ospf6_lsa *lsa);
|
extern void ospf6_flood (struct ospf6_neighbor *from, struct ospf6_lsa *lsa);
|
||||||
|
extern void ospf6_flood_area (struct ospf6_neighbor *from,
|
||||||
|
struct ospf6_lsa *lsa, struct ospf6_area *oa);
|
||||||
|
|
||||||
/* receive & install */
|
/* receive & install */
|
||||||
extern void ospf6_receive_lsa (struct ospf6_neighbor *from,
|
extern void ospf6_receive_lsa (struct ospf6_neighbor *from,
|
||||||
|
@ -140,6 +140,31 @@ ospf6_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ospf6_router_lsa_options_set (struct ospf6_area *oa,
|
||||||
|
struct ospf6_router_lsa *router_lsa)
|
||||||
|
{
|
||||||
|
OSPF6_OPT_CLEAR_ALL (router_lsa->options);
|
||||||
|
memcpy (router_lsa->options, oa->options, 3);
|
||||||
|
|
||||||
|
if (ospf6_is_router_abr (ospf6))
|
||||||
|
SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
|
||||||
|
else
|
||||||
|
UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
|
||||||
|
|
||||||
|
if (!IS_AREA_STUB (oa) && ospf6_asbr_is_asbr (oa->ospf6))
|
||||||
|
{
|
||||||
|
SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E);
|
||||||
|
}
|
||||||
|
|
||||||
|
UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_V);
|
||||||
|
UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_W);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ospf6_router_is_stub_router (struct ospf6_lsa *lsa)
|
ospf6_router_is_stub_router (struct ospf6_lsa *lsa)
|
||||||
{
|
{
|
||||||
@ -194,23 +219,7 @@ ospf6_router_lsa_originate (struct thread *thread)
|
|||||||
router_lsa = (struct ospf6_router_lsa *)
|
router_lsa = (struct ospf6_router_lsa *)
|
||||||
((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
|
((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
|
||||||
|
|
||||||
OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_V6);
|
ospf6_router_lsa_options_set (oa, router_lsa);
|
||||||
OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_E);
|
|
||||||
OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_MC);
|
|
||||||
OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_N);
|
|
||||||
OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_R);
|
|
||||||
OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_DC);
|
|
||||||
|
|
||||||
if (ospf6_is_router_abr (ospf6))
|
|
||||||
SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
|
|
||||||
else
|
|
||||||
UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
|
|
||||||
if (ospf6_asbr_is_asbr (ospf6))
|
|
||||||
SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E);
|
|
||||||
else
|
|
||||||
UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E);
|
|
||||||
UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_V);
|
|
||||||
UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_W);
|
|
||||||
|
|
||||||
/* describe links for each interfaces */
|
/* describe links for each interfaces */
|
||||||
lsdesc = (struct ospf6_router_lsdesc *)
|
lsdesc = (struct ospf6_router_lsdesc *)
|
||||||
@ -1469,7 +1478,11 @@ ospf6_intra_route_calculation (struct ospf6_area *oa)
|
|||||||
if (hook_add)
|
if (hook_add)
|
||||||
(*hook_add) (route);
|
(*hook_add) (route);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Redo the summaries as things might have changed */
|
||||||
|
ospf6_abr_originate_summary (route);
|
||||||
|
}
|
||||||
route->flag = 0;
|
route->flag = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1554,7 +1567,7 @@ ospf6_intra_brouter_calculation (struct ospf6_area *oa)
|
|||||||
inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
|
inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
|
||||||
if (brouter->path.area_id != oa->area_id)
|
if (brouter->path.area_id != oa->area_id)
|
||||||
continue;
|
continue;
|
||||||
brouter->flag = OSPF6_ROUTE_REMOVE;
|
SET_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE);
|
||||||
|
|
||||||
if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
|
if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
|
||||||
IS_OSPF6_DEBUG_ROUTE (MEMORY))
|
IS_OSPF6_DEBUG_ROUTE (MEMORY))
|
||||||
@ -1647,9 +1660,11 @@ ospf6_intra_brouter_calculation (struct ospf6_area *oa)
|
|||||||
IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
|
IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
|
||||||
zlog_info ("brouter %s still exists via area %s",
|
zlog_info ("brouter %s still exists via area %s",
|
||||||
brouter_name, oa->name);
|
brouter_name, oa->name);
|
||||||
|
/* But re-originate summaries */
|
||||||
|
ospf6_abr_originate_summary (brouter);
|
||||||
}
|
}
|
||||||
|
UNSET_FLAG (brouter->flag, OSPF6_ROUTE_ADD);
|
||||||
brouter->flag = 0;
|
UNSET_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
|
if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
|
||||||
|
@ -141,6 +141,7 @@ struct ospf6_lsa
|
|||||||
#define OSPF6_LSA_FLOODBACK 0x02
|
#define OSPF6_LSA_FLOODBACK 0x02
|
||||||
#define OSPF6_LSA_DUPLICATE 0x04
|
#define OSPF6_LSA_DUPLICATE 0x04
|
||||||
#define OSPF6_LSA_IMPLIEDACK 0x08
|
#define OSPF6_LSA_IMPLIEDACK 0x08
|
||||||
|
#define OSPF6_LSA_UNAPPROVED 0x10
|
||||||
#define OSPF6_LSA_SEQWRAPPED 0x20
|
#define OSPF6_LSA_SEQWRAPPED 0x20
|
||||||
|
|
||||||
struct ospf6_lsa_handler
|
struct ospf6_lsa_handler
|
||||||
|
@ -110,6 +110,10 @@ struct ospf6_path
|
|||||||
#define OSPF6_PATH_TYPE_REDISTRIBUTE 5
|
#define OSPF6_PATH_TYPE_REDISTRIBUTE 5
|
||||||
#define OSPF6_PATH_TYPE_MAX 6
|
#define OSPF6_PATH_TYPE_MAX 6
|
||||||
|
|
||||||
|
#define OSPF6_PATH_SUBTYPE_DEFAULT_RT 1
|
||||||
|
|
||||||
|
#define OSPF6_PATH_COST_IS_CONFIGURED(path) (path.u.cost_config != OSPF_AREA_RANGE_COST_UNSPEC)
|
||||||
|
|
||||||
#include "prefix.h"
|
#include "prefix.h"
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
#include "bitfield.h"
|
#include "bitfield.h"
|
||||||
|
@ -36,6 +36,8 @@
|
|||||||
#include "ospf6_lsdb.h"
|
#include "ospf6_lsdb.h"
|
||||||
#include "ospf6_route.h"
|
#include "ospf6_route.h"
|
||||||
#include "ospf6_area.h"
|
#include "ospf6_area.h"
|
||||||
|
#include "ospf6_proto.h"
|
||||||
|
#include "ospf6_abr.h"
|
||||||
#include "ospf6_spf.h"
|
#include "ospf6_spf.h"
|
||||||
#include "ospf6_intra.h"
|
#include "ospf6_intra.h"
|
||||||
#include "ospf6_interface.h"
|
#include "ospf6_interface.h"
|
||||||
@ -601,6 +603,9 @@ ospf6_spf_calculation_thread (struct thread *t)
|
|||||||
/* execute SPF calculation */
|
/* execute SPF calculation */
|
||||||
quagga_gettime (QUAGGA_CLK_MONOTONIC, &start);
|
quagga_gettime (QUAGGA_CLK_MONOTONIC, &start);
|
||||||
|
|
||||||
|
if (ospf6_is_router_abr (ospf6))
|
||||||
|
ospf6_abr_range_reset_cost (ospf6);
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa))
|
for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa))
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -634,10 +639,8 @@ ospf6_spf_calculation_thread (struct thread *t)
|
|||||||
areas_processed++;
|
areas_processed++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Redo summaries if required */
|
if (ospf6_is_router_abr (ospf6))
|
||||||
for (route = ospf6_route_head (ospf6->route_table); route;
|
ospf6_abr_defaults_to_stub (ospf6);
|
||||||
route = ospf6_route_next (route))
|
|
||||||
ospf6_abr_originate_summary(route);
|
|
||||||
|
|
||||||
quagga_gettime (QUAGGA_CLK_MONOTONIC, &end);
|
quagga_gettime (QUAGGA_CLK_MONOTONIC, &end);
|
||||||
timersub (&end, &start, &runtime);
|
timersub (&end, &start, &runtime);
|
||||||
|
@ -312,10 +312,6 @@ struct ospf_area
|
|||||||
|
|
||||||
/* Configured variables. */
|
/* Configured variables. */
|
||||||
int external_routing; /* ExternalRoutingCapability. */
|
int external_routing; /* ExternalRoutingCapability. */
|
||||||
#define OSPF_AREA_DEFAULT 0
|
|
||||||
#define OSPF_AREA_STUB 1
|
|
||||||
#define OSPF_AREA_NSSA 2
|
|
||||||
#define OSPF_AREA_TYPE_MAX 3
|
|
||||||
int no_summary; /* Don't inject summaries into stub.*/
|
int no_summary; /* Don't inject summaries into stub.*/
|
||||||
int shortcut_configured; /* Area configured as shortcut. */
|
int shortcut_configured; /* Area configured as shortcut. */
|
||||||
#define OSPF_SHORTCUT_DEFAULT 0
|
#define OSPF_SHORTCUT_DEFAULT 0
|
||||||
|
Loading…
Reference in New Issue
Block a user