mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-02 17:36:36 +00:00
SVN revisions 916-920 from Zebra. ABR support is almost done.
This commit is contained in:
parent
f841e02e16
commit
6452df092b
@ -1,3 +1,25 @@
|
||||
2004-08-15 Yasuhiro Ohara <yasu@sfc.wide.ad.jp>
|
||||
|
||||
* *.c: Area support almost done. (almost ! ;p)
|
||||
* ospf6d.h: version 0.9.7i
|
||||
|
||||
2004-08-15 Yasuhiro Ohara <yasu@sfc.wide.ad.jp>
|
||||
|
||||
* ospf6_message.c: Bug cause BadLSReq is fixed.
|
||||
* ospf6_abr.c: Border Router check.
|
||||
* ospf6d.h: version 0.9.7h
|
||||
|
||||
2004-08-14 Yasuhiro Ohara <yasu@sfc.wide.ad.jp>
|
||||
|
||||
* ospf6_area.[ch], ospf6_abr.[ch]: area range,
|
||||
border-routers, Inter-Area-Router-LSA origination
|
||||
* ospf6d.h: version 0.9.7g
|
||||
|
||||
2004-08-12 Yasuhiro Ohara <yasu@sfc.wide.ad.jp>
|
||||
|
||||
* *.[c,h]: LSA refreshing is changed and cleaned up.
|
||||
* ospf6d.h: version 0.9.7f
|
||||
|
||||
2004-08-01 Yasuhiro Ohara <yasu@sfc.wide.ad.jp>
|
||||
|
||||
* ospf6_abr.[ch]: add files for abr function.
|
||||
|
@ -34,18 +34,42 @@
|
||||
#include "ospf6_lsa.h"
|
||||
#include "ospf6_route.h"
|
||||
#include "ospf6_lsdb.h"
|
||||
#include "ospf6_message.h"
|
||||
|
||||
#include "ospf6_top.h"
|
||||
#include "ospf6_area.h"
|
||||
#include "ospf6_interface.h"
|
||||
#include "ospf6_neighbor.h"
|
||||
|
||||
#include "ospf6_abr.h"
|
||||
#include "ospf6_flood.h"
|
||||
#include "ospf6d.h"
|
||||
|
||||
unsigned char conf_debug_ospf6_abr;
|
||||
|
||||
int
|
||||
ospf6_is_router_abr (struct ospf6 *o)
|
||||
{
|
||||
listnode node;
|
||||
struct ospf6_area *oa;
|
||||
int area_count = 0;
|
||||
|
||||
for (node = listhead (o->area_list); node; nextnode (node))
|
||||
{
|
||||
oa = OSPF6_AREA (getdata (node));
|
||||
if (IS_AREA_ENABLED (oa))
|
||||
area_count++;
|
||||
}
|
||||
|
||||
if (area_count > 1)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* RFC 2328 12.4.3. Summary-LSAs */
|
||||
void
|
||||
ospf6_abr_originate_prefix_to_area (struct ospf6_route *route,
|
||||
struct ospf6_area *area)
|
||||
ospf6_abr_originate_summary_to_area (struct ospf6_route *route,
|
||||
struct ospf6_area *area)
|
||||
{
|
||||
struct ospf6_lsa *lsa, *old = NULL;
|
||||
struct ospf6_interface *oi;
|
||||
@ -55,26 +79,63 @@ ospf6_abr_originate_prefix_to_area (struct ospf6_route *route,
|
||||
struct ospf6_lsa_header *lsa_header;
|
||||
caddr_t p;
|
||||
struct ospf6_inter_prefix_lsa *prefix_lsa;
|
||||
struct ospf6_inter_router_lsa *router_lsa;
|
||||
struct ospf6_route_table *summary_table = NULL;
|
||||
u_int16_t type;
|
||||
|
||||
summary = ospf6_route_lookup (&route->prefix, area->summary_table);
|
||||
if (IS_OSPF6_DEBUG_ABR)
|
||||
{
|
||||
char buf[64];
|
||||
if (route->type == OSPF6_DEST_TYPE_ROUTER)
|
||||
{
|
||||
inet_ntop (AF_INET,
|
||||
&(ospf6_linkstate_prefix_adv_router (&route->prefix)),
|
||||
buf, sizeof (buf));
|
||||
zlog_info ("Originating summary in area %s for ASBR %s",
|
||||
area->name, buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
prefix2str (&route->prefix, buf, sizeof (buf));
|
||||
zlog_info ("Originating summary in area %s for %s",
|
||||
area->name, buf);
|
||||
}
|
||||
}
|
||||
|
||||
if (route->type == OSPF6_DEST_TYPE_ROUTER)
|
||||
summary_table = area->summary_router;
|
||||
else
|
||||
summary_table = area->summary_prefix;
|
||||
summary = ospf6_route_lookup (&route->prefix, summary_table);
|
||||
if (summary)
|
||||
old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTER_PREFIX),
|
||||
old = ospf6_lsdb_lookup (summary->path.origin.type,
|
||||
summary->path.origin.id,
|
||||
area->ospf6->router_id, area->lsdb);
|
||||
|
||||
/* if this route has just removed, remove corresponding LSA */
|
||||
if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE))
|
||||
{
|
||||
if (IS_OSPF6_DEBUG_ABR)
|
||||
zlog_info ("The route has just removed, purge previous LSA");
|
||||
if (summary)
|
||||
ospf6_route_remove (summary, summary_table);
|
||||
if (old)
|
||||
ospf6_lsa_premature_aging (old);
|
||||
ospf6_lsa_purge (old);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Only destination type network and address range are considered */
|
||||
if (route->type != OSPF6_DEST_TYPE_NETWORK)
|
||||
/* Only destination type network, range or ASBR are considered */
|
||||
if (route->type != OSPF6_DEST_TYPE_NETWORK &&
|
||||
route->type != OSPF6_DEST_TYPE_RANGE &&
|
||||
(route->type != OSPF6_DEST_TYPE_ROUTER ||
|
||||
! CHECK_FLAG (route->path.router_bits, OSPF6_ROUTER_BIT_E)))
|
||||
{
|
||||
if (IS_OSPF6_DEBUG_ABR)
|
||||
zlog_info ("Route type is none of network, range nor ASBR, withdraw");
|
||||
if (summary)
|
||||
ospf6_route_remove (summary, summary_table);
|
||||
if (old)
|
||||
ospf6_lsa_premature_aging (old);
|
||||
ospf6_lsa_purge (old);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -82,95 +143,203 @@ ospf6_abr_originate_prefix_to_area (struct ospf6_route *route,
|
||||
if (route->path.type == OSPF6_PATH_TYPE_EXTERNAL1 ||
|
||||
route->path.type == OSPF6_PATH_TYPE_EXTERNAL2)
|
||||
{
|
||||
if (IS_OSPF6_DEBUG_ABR)
|
||||
zlog_info ("Path type is external, withdraw");
|
||||
if (summary)
|
||||
ospf6_route_remove (summary, summary_table);
|
||||
if (old)
|
||||
ospf6_lsa_premature_aging (old);
|
||||
return;
|
||||
}
|
||||
|
||||
/* do not generate if the route cost is greater or equal to LSInfinity */
|
||||
if (route->path.cost >= LS_INFINITY)
|
||||
{
|
||||
if (old)
|
||||
ospf6_lsa_premature_aging (old);
|
||||
return;
|
||||
}
|
||||
|
||||
/* if this is an inter-area route */
|
||||
if (route->path.type == OSPF6_PATH_TYPE_INTRA)
|
||||
{
|
||||
/* search for configured address range for the route's area */
|
||||
route_area = ospf6_area_lookup (route->path.area_id, area->ospf6);
|
||||
assert (route_area);
|
||||
range = ospf6_route_lookup_bestmatch (&route->prefix,
|
||||
route_area->summary_table);
|
||||
}
|
||||
|
||||
/* ranges are ignored when originate backbone routes to transit area.
|
||||
Otherwise, if ranges are configured, the route is suppressed. */
|
||||
if (range && (route->path.area_id != htonl (0) || ! area->transit_capability))
|
||||
{
|
||||
if (old)
|
||||
ospf6_lsa_premature_aging (old);
|
||||
if (range->path.cost < route->path.cost)
|
||||
range->path.cost = route->path.cost;
|
||||
SET_FLAG (range->flag, OSPF6_ROUTE_HAVE_LONGER);
|
||||
ospf6_lsa_purge (old);
|
||||
return;
|
||||
}
|
||||
|
||||
/* do not generate if the path's area is the same as target area */
|
||||
if (route->path.area_id == area->area_id)
|
||||
{
|
||||
if (IS_OSPF6_DEBUG_ABR)
|
||||
zlog_info ("The route is in the area itself, ignore");
|
||||
if (summary)
|
||||
ospf6_route_remove (summary, summary_table);
|
||||
if (old)
|
||||
ospf6_lsa_premature_aging (old);
|
||||
ospf6_lsa_purge (old);
|
||||
return;
|
||||
}
|
||||
|
||||
/* do not generate if the nexthops belongs to the target area */
|
||||
oi = ospf6_interface_lookup_by_ifindex (route->nexthop[0].ifindex);
|
||||
if (oi && oi->area && oi->area->area_id == area->area_id)
|
||||
if (oi && oi->area && oi->area == area)
|
||||
{
|
||||
if (IS_OSPF6_DEBUG_ABR)
|
||||
zlog_info ("The route's nexthop is in the same area, ignore");
|
||||
if (summary)
|
||||
ospf6_route_remove (summary, summary_table);
|
||||
if (old)
|
||||
ospf6_lsa_premature_aging (old);
|
||||
ospf6_lsa_purge (old);
|
||||
return;
|
||||
}
|
||||
|
||||
/* do not generate if the route cost is greater or equal to LSInfinity */
|
||||
if (route->path.cost >= LS_INFINITY)
|
||||
{
|
||||
if (IS_OSPF6_DEBUG_ABR)
|
||||
zlog_info ("The cost exceeds LSInfinity, withdraw");
|
||||
if (summary)
|
||||
ospf6_route_remove (summary, summary_table);
|
||||
if (old)
|
||||
ospf6_lsa_purge (old);
|
||||
return;
|
||||
}
|
||||
|
||||
/* if this is a route to ASBR */
|
||||
if (route->type == OSPF6_DEST_TYPE_ROUTER)
|
||||
{
|
||||
/* Only the prefered best path is considered */
|
||||
if (! CHECK_FLAG (route->flag, OSPF6_ROUTE_BEST))
|
||||
{
|
||||
if (IS_OSPF6_DEBUG_ABR)
|
||||
zlog_info ("This is the secondary path to the ASBR, ignore");
|
||||
if (summary)
|
||||
ospf6_route_remove (summary, summary_table);
|
||||
if (old)
|
||||
ospf6_lsa_purge (old);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Do not generate if the area is stub */
|
||||
/* XXX */
|
||||
}
|
||||
|
||||
/* if this is an intra-area route, this may be suppressed by aggregation */
|
||||
if (route->type == OSPF6_DEST_TYPE_NETWORK &&
|
||||
route->path.type == OSPF6_PATH_TYPE_INTRA)
|
||||
{
|
||||
/* search for configured address range for the route's area */
|
||||
route_area = ospf6_area_lookup (route->path.area_id, area->ospf6);
|
||||
assert (route_area);
|
||||
range = ospf6_route_lookup_bestmatch (&route->prefix,
|
||||
route_area->range_table);
|
||||
|
||||
/* ranges are ignored when originate backbone routes to transit area.
|
||||
Otherwise, if ranges are configured, the route is suppressed. */
|
||||
if (range && ! CHECK_FLAG (range->flag, OSPF6_ROUTE_REMOVE) &&
|
||||
(route->path.area_id != BACKBONE_AREA_ID ||
|
||||
! IS_AREA_TRANSIT (area)))
|
||||
{
|
||||
if (IS_OSPF6_DEBUG_ABR)
|
||||
{
|
||||
char buf[64];
|
||||
prefix2str (&range->prefix, buf, sizeof (buf));
|
||||
zlog_info ("Suppressed by range %s of area %s",
|
||||
buf, route_area->name);
|
||||
}
|
||||
|
||||
if (summary)
|
||||
ospf6_route_remove (summary, summary_table);
|
||||
if (old)
|
||||
ospf6_lsa_purge (old);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If this is a configured address range */
|
||||
if (route->type == OSPF6_DEST_TYPE_RANGE)
|
||||
{
|
||||
/* If DoNotAdvertise is set */
|
||||
if (CHECK_FLAG (route->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE))
|
||||
{
|
||||
if (IS_OSPF6_DEBUG_ABR)
|
||||
zlog_info ("This is the range with DoNotAdvertise set. ignore");
|
||||
if (summary)
|
||||
ospf6_route_remove (summary, summary_table);
|
||||
if (old)
|
||||
ospf6_lsa_purge (old);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Whether the route have active longer prefix */
|
||||
if (! CHECK_FLAG (route->flag, OSPF6_ROUTE_ACTIVE_SUMMARY))
|
||||
{
|
||||
if (IS_OSPF6_DEBUG_ABR)
|
||||
zlog_info ("The range is not active. withdraw");
|
||||
if (summary)
|
||||
ospf6_route_remove (summary, summary_table);
|
||||
if (old)
|
||||
ospf6_lsa_purge (old);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* the route is going to be originated. store it in area's summary_table */
|
||||
if (summary == NULL)
|
||||
{
|
||||
summary = ospf6_route_copy (route);
|
||||
summary->path.origin.type = htons (OSPF6_LSTYPE_INTER_PREFIX);
|
||||
if (route->type == OSPF6_DEST_TYPE_NETWORK ||
|
||||
route->type == OSPF6_DEST_TYPE_RANGE)
|
||||
summary->path.origin.type = htons (OSPF6_LSTYPE_INTER_PREFIX);
|
||||
else
|
||||
summary->path.origin.type = htons (OSPF6_LSTYPE_INTER_ROUTER);
|
||||
summary->path.origin.adv_router = area->ospf6->router_id;
|
||||
summary->path.origin.id =
|
||||
ospf6_new_ls_id (summary->path.origin.type,
|
||||
summary->path.origin.adv_router, area->lsdb);
|
||||
ospf6_route_add (summary, area->summary_table);
|
||||
ospf6_route_add (summary, summary_table);
|
||||
}
|
||||
else
|
||||
{
|
||||
summary->type = route->type;
|
||||
gettimeofday (&summary->changed, NULL);
|
||||
}
|
||||
|
||||
summary->path.router_bits = route->path.router_bits;
|
||||
summary->path.options[0] = route->path.options[0];
|
||||
summary->path.options[1] = route->path.options[1];
|
||||
summary->path.options[2] = route->path.options[2];
|
||||
summary->path.prefix_options = route->path.prefix_options;
|
||||
summary->path.area_id = area->area_id;
|
||||
summary->path.type = OSPF6_PATH_TYPE_INTER;
|
||||
summary->path.cost = route->path.cost;
|
||||
summary->nexthop[0] = route->nexthop[0];
|
||||
|
||||
/* prepare buffer */
|
||||
memset (buffer, 0, sizeof (buffer));
|
||||
lsa_header = (struct ospf6_lsa_header *) buffer;
|
||||
prefix_lsa = (struct ospf6_inter_prefix_lsa *)
|
||||
((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
|
||||
p = (caddr_t) prefix_lsa + sizeof (struct ospf6_inter_prefix_lsa);
|
||||
|
||||
/* Fill Inter-Area-Prefix-LSA */
|
||||
OSPF6_ABR_SUMMARY_METRIC_SET (prefix_lsa, route->path.cost);
|
||||
if (route->type == OSPF6_DEST_TYPE_ROUTER)
|
||||
{
|
||||
router_lsa = (struct ospf6_inter_router_lsa *)
|
||||
((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
|
||||
p = (caddr_t) router_lsa + sizeof (struct ospf6_inter_router_lsa);
|
||||
|
||||
/* prefixlen */
|
||||
prefix_lsa->prefix.prefix_length = route->prefix.prefixlen;
|
||||
/* Fill Inter-Area-Router-LSA */
|
||||
router_lsa->options[0] = route->path.options[0];
|
||||
router_lsa->options[1] = route->path.options[1];
|
||||
router_lsa->options[2] = route->path.options[2];
|
||||
OSPF6_ABR_SUMMARY_METRIC_SET (router_lsa, route->path.cost);
|
||||
router_lsa->router_id =
|
||||
ospf6_linkstate_prefix_adv_router (&route->prefix);
|
||||
type = htons (OSPF6_LSTYPE_INTER_ROUTER);
|
||||
}
|
||||
else
|
||||
{
|
||||
prefix_lsa = (struct ospf6_inter_prefix_lsa *)
|
||||
((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
|
||||
p = (caddr_t) prefix_lsa + sizeof (struct ospf6_inter_prefix_lsa);
|
||||
|
||||
/* PrefixOptions */
|
||||
prefix_lsa->prefix.prefix_options = route->path.prefix_options;
|
||||
/* Fill Inter-Area-Prefix-LSA */
|
||||
OSPF6_ABR_SUMMARY_METRIC_SET (prefix_lsa, route->path.cost);
|
||||
prefix_lsa->prefix.prefix_length = route->prefix.prefixlen;
|
||||
prefix_lsa->prefix.prefix_options = route->path.prefix_options;
|
||||
|
||||
/* set Prefix */
|
||||
memcpy (p, &route->prefix.u.prefix6,
|
||||
OSPF6_PREFIX_SPACE (route->prefix.prefixlen));
|
||||
ospf6_prefix_apply_mask (&prefix_lsa->prefix);
|
||||
p += OSPF6_PREFIX_SPACE (route->prefix.prefixlen);
|
||||
/* set Prefix */
|
||||
memcpy (p, &route->prefix.u.prefix6,
|
||||
OSPF6_PREFIX_SPACE (route->prefix.prefixlen));
|
||||
ospf6_prefix_apply_mask (&prefix_lsa->prefix);
|
||||
p += OSPF6_PREFIX_SPACE (route->prefix.prefixlen);
|
||||
type = htons (OSPF6_LSTYPE_INTER_PREFIX);
|
||||
}
|
||||
|
||||
/* Fill LSA Header */
|
||||
lsa_header->age = 0;
|
||||
lsa_header->type = htons (OSPF6_LSTYPE_INTER_PREFIX);
|
||||
lsa_header->type = type;
|
||||
lsa_header->id = summary->path.origin.id;
|
||||
lsa_header->adv_router = area->ospf6->router_id;
|
||||
lsa_header->seqnum =
|
||||
@ -183,23 +352,63 @@ ospf6_abr_originate_prefix_to_area (struct ospf6_route *route,
|
||||
|
||||
/* create LSA */
|
||||
lsa = ospf6_lsa_create (lsa_header);
|
||||
lsa->scope = area;
|
||||
SET_FLAG (lsa->flag, OSPF6_LSA_REFRESH); /* XXX */
|
||||
|
||||
if (IS_OSPF6_DEBUG_ABR)
|
||||
zlog_info ("Originate as %s", lsa->name);
|
||||
|
||||
/* Originate */
|
||||
ospf6_lsa_originate (lsa);
|
||||
ospf6_lsa_originate_area (lsa, area);
|
||||
}
|
||||
|
||||
void
|
||||
ospf6_abr_originate_prefix (struct ospf6_route *route, struct ospf6 *o)
|
||||
ospf6_abr_range_update (struct ospf6_route *range)
|
||||
{
|
||||
u_int32_t cost = 0;
|
||||
struct ospf6_route *ro;
|
||||
|
||||
assert (range->type == OSPF6_DEST_TYPE_RANGE);
|
||||
|
||||
/* update range's cost and active flag */
|
||||
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 &&
|
||||
! CHECK_FLAG (ro->flag, OSPF6_ROUTE_REMOVE))
|
||||
cost = MAX (cost, ro->path.cost);
|
||||
}
|
||||
|
||||
if (range->path.cost != cost)
|
||||
{
|
||||
range->path.cost = cost;
|
||||
|
||||
if (range->path.cost)
|
||||
SET_FLAG (range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY);
|
||||
else
|
||||
UNSET_FLAG (range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY);
|
||||
|
||||
ospf6_abr_originate_summary (range);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ospf6_abr_originate_summary (struct ospf6_route *route)
|
||||
{
|
||||
listnode node;
|
||||
struct ospf6_area *oa;
|
||||
struct ospf6_route *range = NULL;
|
||||
|
||||
for (node = listhead (o->area_list); node; nextnode (node))
|
||||
if (route->type == OSPF6_DEST_TYPE_NETWORK)
|
||||
{
|
||||
oa = ospf6_area_lookup (route->path.area_id, ospf6);
|
||||
range = ospf6_route_lookup_bestmatch (&route->prefix, oa->range_table);
|
||||
if (range)
|
||||
ospf6_abr_range_update (range);
|
||||
}
|
||||
|
||||
for (node = listhead (ospf6->area_list); node; nextnode (node))
|
||||
{
|
||||
oa = (struct ospf6_area *) getdata (node);
|
||||
ospf6_abr_originate_prefix_to_area (route, oa);
|
||||
ospf6_abr_originate_summary_to_area (route, oa);
|
||||
}
|
||||
}
|
||||
|
||||
@ -211,7 +420,7 @@ ospf6_abr_examin_summary (struct ospf6_lsa *lsa, struct ospf6_area *oa)
|
||||
struct ospf6_route_table *table = NULL;
|
||||
struct ospf6_route *range, *route, *old = NULL;
|
||||
struct ospf6_route *abr_entry;
|
||||
u_char type;
|
||||
u_char type = 0;
|
||||
char options[3] = {0, 0, 0};
|
||||
u_int8_t prefix_options = 0;
|
||||
u_int32_t cost = 0;
|
||||
@ -274,18 +483,22 @@ ospf6_abr_examin_summary (struct ospf6_lsa *lsa, struct ospf6_area *oa)
|
||||
}
|
||||
|
||||
/* (3) if the prefix is equal to an active configured address range */
|
||||
range = ospf6_route_lookup (&prefix, oa->summary_table);
|
||||
if (range && CHECK_FLAG (range->flag, OSPF6_ROUTE_HAVE_LONGER))
|
||||
if (lsa->header->type == htons (OSPF6_LSTYPE_INTER_PREFIX))
|
||||
{
|
||||
if (old)
|
||||
ospf6_route_remove (old, oa->ospf6->route_table);
|
||||
return;
|
||||
range = ospf6_route_lookup (&prefix, oa->range_table);
|
||||
if (range)
|
||||
{
|
||||
if (old)
|
||||
ospf6_route_remove (old, oa->ospf6->route_table);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* (4) if the routing table entry for the ABR does not exist */
|
||||
ospf6_linkstate_prefix (lsa->header->adv_router, htonl (0), &abr_prefix);
|
||||
abr_entry = ospf6_route_lookup (&abr_prefix, oa->ospf6->brouter_table);
|
||||
if (abr_entry == NULL)
|
||||
if (abr_entry == NULL || abr_entry->path.area_id != oa->area_id ||
|
||||
! CHECK_FLAG (abr_entry->path.router_bits, OSPF6_ROUTER_BIT_B))
|
||||
{
|
||||
if (old)
|
||||
ospf6_route_remove (old, oa->ospf6->route_table);
|
||||
@ -318,11 +531,6 @@ ospf6_abr_examin_summary (struct ospf6_lsa *lsa, struct ospf6_area *oa)
|
||||
ospf6_route_add (route, table);
|
||||
}
|
||||
|
||||
int
|
||||
dummy (struct ospf6_lsa *lsa)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/* Display functions */
|
||||
int
|
||||
@ -412,15 +620,25 @@ install_element_ospf6_debug_abr ()
|
||||
install_element (CONFIG_NODE, &no_debug_ospf6_abr_cmd);
|
||||
}
|
||||
|
||||
struct ospf6_lsa_handler inter_prefix_handler =
|
||||
{
|
||||
OSPF6_LSTYPE_INTER_PREFIX,
|
||||
"Inter-Prefix",
|
||||
ospf6_inter_area_prefix_lsa_show
|
||||
};
|
||||
|
||||
struct ospf6_lsa_handler inter_router_handler =
|
||||
{
|
||||
OSPF6_LSTYPE_INTER_ROUTER,
|
||||
"Inter-Router",
|
||||
ospf6_inter_area_router_lsa_show
|
||||
};
|
||||
|
||||
void
|
||||
ospf6_abr_init ()
|
||||
{
|
||||
ospf6_lstype[3].name = "Inter-Area-Prefix-LSA";
|
||||
ospf6_lstype[3].reoriginate = dummy;
|
||||
ospf6_lstype[3].show = ospf6_inter_area_prefix_lsa_show;
|
||||
ospf6_lstype[4].name = "Inter-Area-Router-LSA";
|
||||
ospf6_lstype[4].reoriginate = dummy;
|
||||
ospf6_lstype[4].show = ospf6_inter_area_router_lsa_show;
|
||||
ospf6_install_lsa_handler (&inter_prefix_handler);
|
||||
ospf6_install_lsa_handler (&inter_router_handler);
|
||||
}
|
||||
|
||||
|
||||
|
@ -52,9 +52,11 @@ struct ospf6_inter_router_lsa
|
||||
{ (E)->metric &= htonl (0x00000000); \
|
||||
(E)->metric |= htonl (0x00ffffff) & htonl (C); }
|
||||
|
||||
void ospf6_abr_originate_prefix_to_area (struct ospf6_route *route,
|
||||
struct ospf6_area *area);
|
||||
void ospf6_abr_originate_prefix (struct ospf6_route *route, struct ospf6 *o);
|
||||
int ospf6_is_router_abr (struct ospf6 *o);
|
||||
|
||||
void ospf6_abr_originate_summary_to_area (struct ospf6_route *route,
|
||||
struct ospf6_area *area);
|
||||
void ospf6_abr_originate_summary (struct ospf6_route *route);
|
||||
void ospf6_abr_examin_summary (struct ospf6_lsa *lsa, struct ospf6_area *oa);
|
||||
|
||||
int config_write_ospf6_debug_abr (struct vty *vty);
|
||||
|
@ -48,29 +48,18 @@ ospf6_area_cmp (void *va, void *vb)
|
||||
{
|
||||
struct ospf6_area *oa = (struct ospf6_area *) va;
|
||||
struct ospf6_area *ob = (struct ospf6_area *) vb;
|
||||
return (ntohl (oa->area_id) - ntohl (ob->area_id));
|
||||
}
|
||||
|
||||
int
|
||||
ospf6_area_is_stub (struct ospf6_area *o6a)
|
||||
{
|
||||
if (OSPF6_OPT_ISSET (o6a->options, OSPF6_OPT_E))
|
||||
return 0;
|
||||
return 1;
|
||||
return (ntohl (oa->area_id) < ntohl (ob->area_id) ? -1 : 1);
|
||||
}
|
||||
|
||||
/* schedule routing table recalculation */
|
||||
void
|
||||
ospf6_area_lsdb_hook_add (struct ospf6_lsa *lsa)
|
||||
{
|
||||
struct ospf6_area *oa;
|
||||
|
||||
oa = (struct ospf6_area *) lsa->scope;
|
||||
switch (ntohs (lsa->header->type))
|
||||
{
|
||||
case OSPF6_LSTYPE_ROUTER:
|
||||
case OSPF6_LSTYPE_NETWORK:
|
||||
ospf6_spf_schedule (oa);
|
||||
ospf6_spf_schedule (OSPF6_AREA (lsa->lsdb->data));
|
||||
break;
|
||||
|
||||
case OSPF6_LSTYPE_INTRA_PREFIX:
|
||||
@ -83,7 +72,8 @@ ospf6_area_lsdb_hook_add (struct ospf6_lsa *lsa)
|
||||
|
||||
default:
|
||||
if (IS_OSPF6_DEBUG_LSA (RECV))
|
||||
zlog_info ("Unknown LSA in Area %s's lsdb", oa->name);
|
||||
zlog_info ("Unknown LSA in Area %s's lsdb",
|
||||
OSPF6_AREA (lsa->lsdb->data)->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -91,14 +81,11 @@ ospf6_area_lsdb_hook_add (struct ospf6_lsa *lsa)
|
||||
void
|
||||
ospf6_area_lsdb_hook_remove (struct ospf6_lsa *lsa)
|
||||
{
|
||||
struct ospf6_area *oa;
|
||||
|
||||
oa = (struct ospf6_area *) lsa->scope;
|
||||
switch (ntohs (lsa->header->type))
|
||||
{
|
||||
case OSPF6_LSTYPE_ROUTER:
|
||||
case OSPF6_LSTYPE_NETWORK:
|
||||
ospf6_spf_schedule (oa);
|
||||
ospf6_spf_schedule (OSPF6_AREA (lsa->lsdb->data));
|
||||
break;
|
||||
|
||||
case OSPF6_LSTYPE_INTRA_PREFIX:
|
||||
@ -111,7 +98,8 @@ ospf6_area_lsdb_hook_remove (struct ospf6_lsa *lsa)
|
||||
|
||||
default:
|
||||
if (IS_OSPF6_DEBUG_LSA (RECV))
|
||||
zlog_info ("Unknown LSA in Area %s's lsdb", oa->name);
|
||||
zlog_info ("Unknown LSA in Area %s's lsdb",
|
||||
OSPF6_AREA (lsa->lsdb->data)->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -146,17 +134,20 @@ ospf6_area_create (u_int32_t area_id, struct ospf6 *o)
|
||||
oa->area_id = area_id;
|
||||
oa->if_list = list_new ();
|
||||
|
||||
oa->summary_table = ospf6_route_table_create ();
|
||||
|
||||
oa->lsdb = ospf6_lsdb_create ();
|
||||
oa->lsdb = ospf6_lsdb_create (oa);
|
||||
oa->lsdb->hook_add = ospf6_area_lsdb_hook_add;
|
||||
oa->lsdb->hook_remove = ospf6_area_lsdb_hook_remove;
|
||||
oa->lsdb_self = ospf6_lsdb_create (oa);
|
||||
|
||||
oa->spf_table = ospf6_route_table_create ();
|
||||
oa->route_table = ospf6_route_table_create ();
|
||||
oa->route_table->hook_add = ospf6_area_route_hook_add;
|
||||
oa->route_table->hook_remove = ospf6_area_route_hook_remove;
|
||||
|
||||
oa->range_table = ospf6_route_table_create ();
|
||||
oa->summary_prefix = ospf6_route_table_create ();
|
||||
oa->summary_router = ospf6_route_table_create ();
|
||||
|
||||
/* set default options */
|
||||
OSPF6_OPT_SET (oa->options, OSPF6_OPT_V6);
|
||||
OSPF6_OPT_SET (oa->options, OSPF6_OPT_E);
|
||||
@ -168,7 +159,7 @@ ospf6_area_create (u_int32_t area_id, struct ospf6 *o)
|
||||
/* 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_prefix_to_area (route, oa);
|
||||
ospf6_abr_originate_summary_to_area (route, oa);
|
||||
|
||||
return oa;
|
||||
}
|
||||
@ -179,7 +170,9 @@ ospf6_area_delete (struct ospf6_area *oa)
|
||||
listnode n;
|
||||
struct ospf6_interface *oi;
|
||||
|
||||
ospf6_route_table_delete (oa->summary_table);
|
||||
ospf6_route_table_delete (oa->range_table);
|
||||
ospf6_route_table_delete (oa->summary_prefix);
|
||||
ospf6_route_table_delete (oa->summary_router);
|
||||
|
||||
/* ospf6 interface list */
|
||||
for (n = listhead (oa->if_list); n; nextnode (n))
|
||||
@ -190,6 +183,8 @@ ospf6_area_delete (struct ospf6_area *oa)
|
||||
list_delete (oa->if_list);
|
||||
|
||||
ospf6_lsdb_delete (oa->lsdb);
|
||||
ospf6_lsdb_delete (oa->lsdb_self);
|
||||
|
||||
ospf6_route_table_delete (oa->spf_table);
|
||||
ospf6_route_table_delete (oa->route_table);
|
||||
|
||||
@ -224,13 +219,23 @@ ospf6_area_lookup (u_int32_t area_id, struct ospf6 *ospf6)
|
||||
return (struct ospf6_area *) NULL;
|
||||
}
|
||||
|
||||
struct ospf6_area *
|
||||
ospf6_area_get (u_int32_t area_id, struct ospf6 *o)
|
||||
{
|
||||
struct ospf6_area *oa;
|
||||
oa = ospf6_area_lookup (area_id, o);
|
||||
if (oa == NULL)
|
||||
oa = ospf6_area_create (area_id, o);
|
||||
return oa;
|
||||
}
|
||||
|
||||
void
|
||||
ospf6_area_enable (struct ospf6_area *oa)
|
||||
{
|
||||
listnode i;
|
||||
struct ospf6_interface *oi;
|
||||
|
||||
UNSET_FLAG (oa->flag, OSPF6_AREA_DISABLE);
|
||||
SET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
|
||||
|
||||
for (i = listhead (oa->if_list); i; nextnode (i))
|
||||
{
|
||||
@ -245,7 +250,7 @@ ospf6_area_disable (struct ospf6_area *oa)
|
||||
listnode i;
|
||||
struct ospf6_interface *oi;
|
||||
|
||||
SET_FLAG (oa->flag, OSPF6_AREA_DISABLE);
|
||||
UNSET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
|
||||
|
||||
for (i = listhead (oa->if_list); i; nextnode (i))
|
||||
{
|
||||
@ -291,6 +296,130 @@ ospf6_area_show (struct vty *vty, struct ospf6_area *oa)
|
||||
} \
|
||||
}
|
||||
|
||||
#define OSPF6_CMD_AREA_GET(str, oa) \
|
||||
{ \
|
||||
u_int32_t area_id = 0; \
|
||||
if (inet_pton (AF_INET, str, &area_id) != 1) \
|
||||
{ \
|
||||
vty_out (vty, "Malformed Area-ID: %s%s", str, VNL); \
|
||||
return CMD_SUCCESS; \
|
||||
} \
|
||||
oa = ospf6_area_get (area_id, ospf6); \
|
||||
}
|
||||
|
||||
DEFUN (area_range,
|
||||
area_range_cmd,
|
||||
"area A.B.C.D range X:X::X:X/M",
|
||||
"OSPF area parameters\n"
|
||||
OSPF6_AREA_ID_STR
|
||||
"Configured address range\n"
|
||||
"Specify IPv6 prefix\n"
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
struct ospf6_area *oa;
|
||||
struct prefix prefix;
|
||||
struct ospf6_route *range;
|
||||
|
||||
OSPF6_CMD_AREA_GET (argv[0], oa);
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
ret = str2prefix (argv[0], &prefix);
|
||||
if (ret != 1 || prefix.family != AF_INET6)
|
||||
{
|
||||
vty_out (vty, "Malformed argument: %s%s", argv[0], VNL);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
range = ospf6_route_lookup (&prefix, oa->range_table);
|
||||
if (range == NULL)
|
||||
{
|
||||
range = ospf6_route_create ();
|
||||
range->type = OSPF6_DEST_TYPE_RANGE;
|
||||
range->prefix = prefix;
|
||||
}
|
||||
|
||||
if (argc)
|
||||
{
|
||||
if (! strcmp (argv[0], "not-advertise"))
|
||||
SET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
|
||||
else if (! strcmp (argv[0], "advertise"))
|
||||
UNSET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
|
||||
}
|
||||
|
||||
ospf6_route_add (range, oa->range_table);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
ALIAS (area_range,
|
||||
area_range_advertise_cmd,
|
||||
"area A.B.C.D range X:X::X:X/M (advertise|not-advertise)",
|
||||
"OSPF area parameters\n"
|
||||
OSPF6_AREA_ID_STR
|
||||
"Configured address range\n"
|
||||
"Specify IPv6 prefix\n"
|
||||
);
|
||||
|
||||
DEFUN (no_area_range,
|
||||
no_area_range_cmd,
|
||||
"no area A.B.C.D range X:X::X:X/M",
|
||||
"OSPF area parameters\n"
|
||||
OSPF6_AREA_ID_STR
|
||||
"Configured address range\n"
|
||||
"Specify IPv6 prefix\n"
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
struct ospf6_area *oa;
|
||||
struct prefix prefix;
|
||||
struct ospf6_route *range;
|
||||
|
||||
OSPF6_CMD_AREA_GET (argv[0], oa);
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
ret = str2prefix (argv[0], &prefix);
|
||||
if (ret != 1 || prefix.family != AF_INET6)
|
||||
{
|
||||
vty_out (vty, "Malformed argument: %s%s", argv[0], VNL);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
range = ospf6_route_lookup (&prefix, oa->range_table);
|
||||
if (range == NULL)
|
||||
{
|
||||
vty_out (vty, "Range %s does not exists.%s", argv[0], VNL);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
ospf6_route_remove (range, oa->range_table);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
ospf6_area_config_write (struct vty *vty)
|
||||
{
|
||||
listnode node;
|
||||
struct ospf6_area *oa;
|
||||
struct ospf6_route *range;
|
||||
char buf[128];
|
||||
|
||||
for (node = listhead (ospf6->area_list); node; nextnode (node))
|
||||
{
|
||||
oa = OSPF6_AREA (getdata (node));
|
||||
|
||||
for (range = ospf6_route_head (oa->range_table); range;
|
||||
range = ospf6_route_next (range))
|
||||
{
|
||||
prefix2str (&range->prefix, buf, sizeof (buf));
|
||||
vty_out (vty, " area %s range %s%s", oa->name, buf, VNL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEFUN (show_ipv6_ospf6_area_route_intra,
|
||||
show_ipv6_ospf6_area_route_intra_cmd,
|
||||
"show ipv6 ospf6 area A.B.C.D route intra-area",
|
||||
@ -876,5 +1005,10 @@ ospf6_area_init ()
|
||||
install_element (ENABLE_NODE, &show_ipv6_ospf6_area_route_intra_match_detail_cmd);
|
||||
|
||||
install_element (ENABLE_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd);
|
||||
|
||||
install_element (OSPF6_NODE, &area_range_cmd);
|
||||
install_element (OSPF6_NODE, &area_range_advertise_cmd);
|
||||
install_element (OSPF6_NODE, &no_area_range_cmd);
|
||||
}
|
||||
|
||||
|
||||
|
@ -41,16 +41,17 @@ struct ospf6_area
|
||||
/* OSPF Option */
|
||||
u_char options[3];
|
||||
|
||||
/* TransitCapability */
|
||||
int transit_capability;
|
||||
|
||||
/* Summary routes to be originated (includes Configured Address Ranges) */
|
||||
struct ospf6_route_table *summary_table;
|
||||
struct ospf6_route_table *range_table;
|
||||
struct ospf6_route_table *summary_prefix;
|
||||
struct ospf6_route_table *summary_router;
|
||||
|
||||
/* OSPF interface list */
|
||||
list if_list;
|
||||
|
||||
struct ospf6_lsdb *lsdb;
|
||||
struct ospf6_lsdb *lsdb;
|
||||
struct ospf6_lsdb *lsdb_self;
|
||||
|
||||
struct ospf6_route_table *spf_table;
|
||||
struct ospf6_route_table *route_table;
|
||||
|
||||
@ -62,12 +63,21 @@ struct ospf6_area
|
||||
u_int32_t router_lsa_size_limit;
|
||||
};
|
||||
|
||||
#define OSPF6_AREA_DISABLE 0x01
|
||||
#define OSPF6_AREA_STUB 0x02
|
||||
#define OSPF6_AREA_ENABLE 0x01
|
||||
#define OSPF6_AREA_ACTIVE 0x02
|
||||
#define OSPF6_AREA_TRANSIT 0x04 /* TransitCapability */
|
||||
#define OSPF6_AREA_STUB 0x08
|
||||
|
||||
#define BACKBONE_AREA_ID (htonl (0))
|
||||
#define IS_AREA_BACKBONE(oa) ((oa)->area_id == BACKBONE_AREA_ID)
|
||||
#define IS_AREA_ENABLED(oa) (CHECK_FLAG ((oa)->flag, OSPF6_AREA_ENABLE))
|
||||
#define IS_AREA_ACTIVE(oa) (CHECK_FLAG ((oa)->flag, OSPF6_AREA_ACTIVE))
|
||||
#define IS_AREA_TRANSIT(oa) (CHECK_FLAG ((oa)->flag, OSPF6_AREA_TRANSIT))
|
||||
#define IS_AREA_STUB(oa) (CHECK_FLAG ((oa)->flag, OSPF6_AREA_STUB))
|
||||
|
||||
/* prototypes */
|
||||
int ospf6_area_cmp (void *va, void *vb);
|
||||
int ospf6_area_is_stub (struct ospf6_area *o6a);
|
||||
|
||||
struct ospf6_area *ospf6_area_create (u_int32_t, struct ospf6 *);
|
||||
void ospf6_area_delete (struct ospf6_area *);
|
||||
struct ospf6_area *ospf6_area_lookup (u_int32_t, struct ospf6 *);
|
||||
@ -76,6 +86,8 @@ void ospf6_area_enable (struct ospf6_area *);
|
||||
void ospf6_area_disable (struct ospf6_area *);
|
||||
|
||||
void ospf6_area_show (struct vty *, struct ospf6_area *);
|
||||
|
||||
void ospf6_area_config_write (struct vty *vty);
|
||||
void ospf6_area_init ();
|
||||
|
||||
#endif /* OSPF_AREA_H */
|
||||
|
@ -37,10 +37,15 @@
|
||||
#include "ospf6_lsdb.h"
|
||||
#include "ospf6_route.h"
|
||||
#include "ospf6_zebra.h"
|
||||
#include "ospf6_message.h"
|
||||
|
||||
#include "ospf6_top.h"
|
||||
#include "ospf6_area.h"
|
||||
#include "ospf6_interface.h"
|
||||
#include "ospf6_neighbor.h"
|
||||
#include "ospf6_asbr.h"
|
||||
#include "ospf6_intra.h"
|
||||
#include "ospf6_flood.h"
|
||||
#include "ospf6d.h"
|
||||
|
||||
unsigned char conf_debug_ospf6_asbr = 0;
|
||||
@ -61,20 +66,19 @@ char *zroute_abname[] =
|
||||
|
||||
/* AS External LSA origination */
|
||||
void
|
||||
ospf6_as_external_lsa_originate_sub (struct ospf6_route *route, int force)
|
||||
ospf6_as_external_lsa_originate (struct ospf6_route *route)
|
||||
{
|
||||
char buffer[OSPF6_MAX_LSASIZE];
|
||||
struct ospf6_lsa_header *lsa_header;
|
||||
struct ospf6_lsa *old, *lsa;
|
||||
|
||||
struct ospf6_external_info *info = route->route_option;
|
||||
struct ospf6_as_external_lsa *as_external_lsa;
|
||||
char buf[64];
|
||||
caddr_t p;
|
||||
|
||||
/* find previous LSA */
|
||||
old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),
|
||||
htonl (info->id), ospf6->router_id,
|
||||
route->path.origin.id, ospf6->router_id,
|
||||
ospf6->lsdb);
|
||||
|
||||
if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
|
||||
@ -99,7 +103,7 @@ ospf6_as_external_lsa_originate_sub (struct ospf6_route *route, int force)
|
||||
UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_E);
|
||||
|
||||
/* forwarding address */
|
||||
if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding))
|
||||
if (! IN6_IS_ADDR_UNSPECIFIED (&route->nexthop[0].address))
|
||||
SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F);
|
||||
else
|
||||
UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F);
|
||||
@ -128,7 +132,7 @@ ospf6_as_external_lsa_originate_sub (struct ospf6_route *route, int force)
|
||||
/* Forwarding address */
|
||||
if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F))
|
||||
{
|
||||
memcpy (p, &info->forwarding, sizeof (struct in6_addr));
|
||||
memcpy (p, &route->nexthop[0].address, sizeof (struct in6_addr));
|
||||
p += sizeof (struct in6_addr);
|
||||
}
|
||||
|
||||
@ -141,7 +145,7 @@ ospf6_as_external_lsa_originate_sub (struct ospf6_route *route, int force)
|
||||
/* Fill LSA Header */
|
||||
lsa_header->age = 0;
|
||||
lsa_header->type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
|
||||
lsa_header->id = htonl (info->id);
|
||||
lsa_header->id = route->path.origin.id;
|
||||
lsa_header->adv_router = ospf6->router_id;
|
||||
lsa_header->seqnum =
|
||||
ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
|
||||
@ -153,37 +157,11 @@ ospf6_as_external_lsa_originate_sub (struct ospf6_route *route, int force)
|
||||
|
||||
/* create LSA */
|
||||
lsa = ospf6_lsa_create (lsa_header);
|
||||
lsa->scope = ospf6;
|
||||
if (force)
|
||||
SET_FLAG (lsa->flag, OSPF6_LSA_REFRESH);
|
||||
|
||||
/* Originate */
|
||||
ospf6_lsa_originate (lsa);
|
||||
ospf6_lsa_originate_process (lsa, ospf6);
|
||||
}
|
||||
|
||||
int
|
||||
ospf6_as_external_lsa_reoriginate (struct ospf6_lsa *lsa)
|
||||
{
|
||||
struct prefix prefix_id;
|
||||
struct route_node *node;
|
||||
struct ospf6_route *route;
|
||||
|
||||
/* create/update binding in external_id_table */
|
||||
prefix_id.family = AF_INET;
|
||||
prefix_id.prefixlen = 32;
|
||||
prefix_id.u.prefix4.s_addr = lsa->header->id;
|
||||
node = route_node_get (ospf6->external_id_table, &prefix_id);
|
||||
route = node->info;
|
||||
|
||||
if (route)
|
||||
ospf6_as_external_lsa_originate_sub (route, 1);
|
||||
else
|
||||
ospf6_lsa_premature_aging (lsa);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
ospf6_asbr_lsa_add (struct ospf6_lsa *lsa)
|
||||
@ -217,7 +195,7 @@ ospf6_asbr_lsa_add (struct ospf6_lsa *lsa)
|
||||
asbr_id.family = AF_INET;
|
||||
asbr_id.prefixlen = 32;
|
||||
asbr_id.u.prefix4.s_addr = lsa->header->adv_router;
|
||||
asbr_entry = ospf6_route_lookup (&asbr_id, ospf6->asbr_table);
|
||||
asbr_entry = ospf6_route_lookup (&asbr_id, ospf6->brouter_table);
|
||||
|
||||
if (asbr_entry == NULL)
|
||||
{
|
||||
@ -545,7 +523,7 @@ ospf6_asbr_redistribute_add (int type, int ifindex, struct prefix *prefix,
|
||||
zlog_info ("Advertise as AS-External Id:%s", ibuf);
|
||||
}
|
||||
|
||||
ospf6_as_external_lsa_originate_sub (match, 0);
|
||||
ospf6_as_external_lsa_originate (match);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -593,7 +571,7 @@ ospf6_asbr_redistribute_add (int type, int ifindex, struct prefix *prefix,
|
||||
zlog_info ("Advertise as AS-External Id:%s", ibuf);
|
||||
}
|
||||
|
||||
ospf6_as_external_lsa_originate_sub (route, 0);
|
||||
ospf6_as_external_lsa_originate (route);
|
||||
|
||||
/* Router-Bit (ASBR Flag) may have to be updated */
|
||||
for (lnode = listhead (ospf6->area_list); lnode; nextnode (lnode))
|
||||
@ -649,7 +627,7 @@ ospf6_asbr_redistribute_remove (int type, int ifindex, struct prefix *prefix)
|
||||
lsa = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),
|
||||
htonl (info->id), ospf6->router_id, ospf6->lsdb);
|
||||
if (lsa)
|
||||
ospf6_lsa_premature_aging (lsa);
|
||||
ospf6_lsa_purge (lsa);
|
||||
|
||||
/* remove binding in external_id_table */
|
||||
prefix_id.family = AF_INET;
|
||||
@ -1254,95 +1232,23 @@ DEFUN (show_ipv6_ospf6_redistribute,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (show_ipv6_ospf6_asbr,
|
||||
show_ipv6_ospf6_asbr_cmd,
|
||||
"show ipv6 ospf6 asbr",
|
||||
SHOW_STR
|
||||
IP6_STR
|
||||
OSPF6_STR
|
||||
"Show AS Boundary Router table\n"
|
||||
)
|
||||
struct ospf6_lsa_handler as_external_handler =
|
||||
{
|
||||
ospf6_lsentry_table_show (vty, argc, argv, ospf6->asbr_table);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
ALIAS (show_ipv6_ospf6_asbr,
|
||||
show_ipv6_ospf6_asbr_1_cmd,
|
||||
"show ipv6 ospf6 asbr (A.B.C.D|A.B.C.D/M|detail)",
|
||||
SHOW_STR
|
||||
IP6_STR
|
||||
OSPF6_STR
|
||||
"Show AS Boundary Router table\n"
|
||||
"Specify Router-ID\n"
|
||||
"Display multiple entry by specifying match-prefix of Router-ID\n"
|
||||
"Display Detail\n"
|
||||
);
|
||||
|
||||
ALIAS (show_ipv6_ospf6_asbr,
|
||||
show_ipv6_ospf6_asbr_2_cmd,
|
||||
"show ipv6 ospf6 asbr (A.B.C.D|A.B.C.D/M|*) (A.B.C.D|A.B.C.D/M|detail)",
|
||||
SHOW_STR
|
||||
IP6_STR
|
||||
OSPF6_STR
|
||||
"Show AS Boundary Router table\n"
|
||||
"Specify Router-ID\n"
|
||||
"Display multiple entry by specifying match-prefix of Router-ID\n"
|
||||
"Wildcard Router-ID\n"
|
||||
"Specify Link State ID\n"
|
||||
"Display multiple entry by specifying match-prefix of Link State ID\n"
|
||||
"Display Detail\n"
|
||||
);
|
||||
|
||||
DEFUN (show_ipv6_ospf6_asbr_3,
|
||||
show_ipv6_ospf6_asbr_3_cmd,
|
||||
"show ipv6 ospf6 asbr (A.B.C.D|*) A.B.C.D/M detail",
|
||||
SHOW_STR
|
||||
IP6_STR
|
||||
OSPF6_STR
|
||||
"Show AS Boundary Router table\n"
|
||||
"Specify Router-ID\n"
|
||||
"Wildcard Router-ID\n"
|
||||
"Display multiple entry by specifying match-prefix of Link State ID\n"
|
||||
"Display Detail\n"
|
||||
)
|
||||
{
|
||||
char *sargv[CMD_ARGC_MAX];
|
||||
int i, sargc;
|
||||
|
||||
/* copy argv to sargv and then append "detail" */
|
||||
for (i = 0; i < argc; i++)
|
||||
sargv[i] = argv[i];
|
||||
sargc = argc;
|
||||
sargv[sargc++] = "detail";
|
||||
sargv[sargc] = NULL;
|
||||
|
||||
ospf6_lsentry_table_show (vty, sargc, sargv, ospf6->asbr_table);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
OSPF6_LSTYPE_AS_EXTERNAL,
|
||||
"AS-External",
|
||||
ospf6_as_external_lsa_show
|
||||
};
|
||||
|
||||
void
|
||||
ospf6_asbr_init ()
|
||||
{
|
||||
ospf6_routemap_init ();
|
||||
|
||||
ospf6_lstype[5].name = "AS-External";
|
||||
ospf6_lstype[5].reoriginate = ospf6_as_external_lsa_reoriginate;
|
||||
ospf6_lstype[5].show = ospf6_as_external_lsa_show;
|
||||
ospf6_install_lsa_handler (&as_external_handler);
|
||||
|
||||
install_element (VIEW_NODE, &show_ipv6_ospf6_redistribute_cmd);
|
||||
install_element (ENABLE_NODE, &show_ipv6_ospf6_redistribute_cmd);
|
||||
|
||||
install_element (VIEW_NODE, &show_ipv6_ospf6_asbr_cmd);
|
||||
install_element (VIEW_NODE, &show_ipv6_ospf6_asbr_1_cmd);
|
||||
install_element (VIEW_NODE, &show_ipv6_ospf6_asbr_2_cmd);
|
||||
install_element (VIEW_NODE, &show_ipv6_ospf6_asbr_3_cmd);
|
||||
install_element (ENABLE_NODE, &show_ipv6_ospf6_asbr_cmd);
|
||||
install_element (ENABLE_NODE, &show_ipv6_ospf6_asbr_1_cmd);
|
||||
install_element (ENABLE_NODE, &show_ipv6_ospf6_asbr_2_cmd);
|
||||
install_element (ENABLE_NODE, &show_ipv6_ospf6_asbr_3_cmd);
|
||||
|
||||
install_element (OSPF6_NODE, &ospf6_redistribute_cmd);
|
||||
install_element (OSPF6_NODE, &ospf6_redistribute_routemap_cmd);
|
||||
install_element (OSPF6_NODE, &no_ospf6_redistribute_cmd);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -23,15 +23,31 @@
|
||||
#define OSPF6_FLOOD_H
|
||||
|
||||
/* Function Prototypes */
|
||||
void *ospf6_get_lsa_scope (u_int16_t type, struct ospf6_neighbor *from);
|
||||
struct ospf6_lsdb *ospf6_get_scoped_lsdb (u_int16_t type, void *scope);
|
||||
struct ospf6_lsdb *ospf6_get_scoped_lsdb (struct ospf6_lsa *lsa);
|
||||
struct ospf6_lsdb *ospf6_get_scoped_lsdb_self (struct ospf6_lsa *lsa);
|
||||
|
||||
void ospf6_decrement_onretrans (struct ospf6_lsa *lsa);
|
||||
/* origination & purging */
|
||||
void ospf6_lsa_originate (struct ospf6_lsa *lsa);
|
||||
void ospf6_lsa_originate_process (struct ospf6_lsa *lsa,
|
||||
struct ospf6 *process);
|
||||
void ospf6_lsa_originate_area (struct ospf6_lsa *lsa,
|
||||
struct ospf6_area *oa);
|
||||
void ospf6_lsa_originate_interface (struct ospf6_lsa *lsa,
|
||||
struct ospf6_interface *oi);
|
||||
void ospf6_lsa_purge (struct ospf6_lsa *lsa);
|
||||
|
||||
/* access method to retrans_count */
|
||||
void ospf6_increment_retrans_count (struct ospf6_lsa *lsa);
|
||||
void ospf6_decrement_retrans_count (struct ospf6_lsa *lsa);
|
||||
|
||||
/* flooding & clear flooding */
|
||||
void ospf6_flood_clear (struct ospf6_lsa *lsa);
|
||||
void ospf6_flood_lsa (struct ospf6_lsa *lsa, struct ospf6_neighbor *from);
|
||||
void ospf6_install_lsa (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb);
|
||||
void ospf6_receive_lsa (struct ospf6_lsa_header *header,
|
||||
struct ospf6_neighbor *from);
|
||||
void ospf6_flood (struct ospf6_neighbor *from, struct ospf6_lsa *lsa);
|
||||
|
||||
/* receive & install */
|
||||
void ospf6_receive_lsa (struct ospf6_neighbor *from,
|
||||
struct ospf6_lsa_header *header);
|
||||
void ospf6_install_lsa (struct ospf6_lsa *lsa);
|
||||
|
||||
#endif /* OSPF6_FLOOD_H */
|
||||
|
||||
|
@ -89,21 +89,18 @@ ospf6_interface_lookup_by_name (char *ifname)
|
||||
void
|
||||
ospf6_interface_lsdb_hook (struct ospf6_lsa *lsa)
|
||||
{
|
||||
struct ospf6_interface *oi;
|
||||
|
||||
oi = (struct ospf6_interface *) lsa->scope;
|
||||
switch (ntohs (lsa->header->type))
|
||||
{
|
||||
case OSPF6_LSTYPE_LINK:
|
||||
if (oi->state == OSPF6_INTERFACE_DR)
|
||||
OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
|
||||
ospf6_spf_schedule (oi->area);
|
||||
if (OSPF6_INTERFACE (lsa->lsdb->data)->state == OSPF6_INTERFACE_DR)
|
||||
OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (OSPF6_INTERFACE (lsa->lsdb->data));
|
||||
ospf6_spf_schedule (OSPF6_INTERFACE (lsa->lsdb->data)->area);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (IS_OSPF6_DEBUG_LSA (RECV))
|
||||
zlog_info ("Unknown LSA in Interface %s's lsdb",
|
||||
oi->interface->name);
|
||||
OSPF6_INTERFACE (lsa->lsdb->data)->interface->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -151,11 +148,12 @@ ospf6_interface_create (struct interface *ifp)
|
||||
oi->ifmtu = iobuflen;
|
||||
}
|
||||
|
||||
oi->lsupdate_list = ospf6_lsdb_create ();
|
||||
oi->lsack_list = ospf6_lsdb_create ();
|
||||
oi->lsdb = ospf6_lsdb_create ();
|
||||
oi->lsupdate_list = ospf6_lsdb_create (oi);
|
||||
oi->lsack_list = ospf6_lsdb_create (oi);
|
||||
oi->lsdb = ospf6_lsdb_create (oi);
|
||||
oi->lsdb->hook_add = ospf6_interface_lsdb_hook;
|
||||
oi->lsdb->hook_remove = ospf6_interface_lsdb_hook;
|
||||
oi->lsdb_self = ospf6_lsdb_create (oi);
|
||||
|
||||
oi->route_connected = ospf6_route_table_create ();
|
||||
|
||||
@ -188,6 +186,8 @@ ospf6_interface_delete (struct ospf6_interface *oi)
|
||||
ospf6_lsdb_remove_all (oi->lsack_list);
|
||||
|
||||
ospf6_lsdb_delete (oi->lsdb);
|
||||
ospf6_lsdb_delete (oi->lsdb_self);
|
||||
|
||||
ospf6_lsdb_delete (oi->lsupdate_list);
|
||||
ospf6_lsdb_delete (oi->lsack_list);
|
||||
|
||||
@ -428,7 +428,14 @@ ospf6_interface_state_change (u_char next_state, struct ospf6_interface *oi)
|
||||
ospf6_join_alldrouters (oi->interface->ifindex);
|
||||
|
||||
OSPF6_ROUTER_LSA_SCHEDULE (oi->area);
|
||||
if (prev_state == OSPF6_INTERFACE_DR || next_state == OSPF6_INTERFACE_DR)
|
||||
if (next_state == OSPF6_INTERFACE_DOWN)
|
||||
{
|
||||
OSPF6_NETWORK_LSA_EXECUTE (oi);
|
||||
OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT (oi);
|
||||
OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
|
||||
}
|
||||
else if (prev_state == OSPF6_INTERFACE_DR ||
|
||||
next_state == OSPF6_INTERFACE_DR)
|
||||
{
|
||||
OSPF6_NETWORK_LSA_SCHEDULE (oi);
|
||||
OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
|
||||
|
@ -84,6 +84,7 @@ struct ospf6_interface
|
||||
|
||||
/* Linklocal LSA Database: includes Link-LSA */
|
||||
struct ospf6_lsdb *lsdb;
|
||||
struct ospf6_lsdb *lsdb_self;
|
||||
|
||||
struct ospf6_lsdb *lsupdate_list;
|
||||
struct ospf6_lsdb *lsack_list;
|
||||
|
@ -43,6 +43,8 @@
|
||||
#include "ospf6_neighbor.h"
|
||||
#include "ospf6_intra.h"
|
||||
#include "ospf6_asbr.h"
|
||||
#include "ospf6_abr.h"
|
||||
#include "ospf6_flood.h"
|
||||
#include "ospf6d.h"
|
||||
|
||||
/******************************/
|
||||
@ -97,9 +99,11 @@ ospf6_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ospf6_router_lsa_originate_sub (struct ospf6_area *oa, int force)
|
||||
int
|
||||
ospf6_router_lsa_originate (struct thread *thread)
|
||||
{
|
||||
struct ospf6_area *oa;
|
||||
|
||||
char buffer [OSPF6_MAX_LSASIZE];
|
||||
struct ospf6_lsa_header *lsa_header;
|
||||
struct ospf6_lsa *lsa;
|
||||
@ -114,6 +118,9 @@ ospf6_router_lsa_originate_sub (struct ospf6_area *oa, int force)
|
||||
u_int32_t router;
|
||||
int count;
|
||||
|
||||
oa = (struct ospf6_area *) THREAD_ARG (thread);
|
||||
oa->thread_router_lsa = NULL;
|
||||
|
||||
if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
|
||||
zlog_info ("Originate Router-LSA for Area %s", oa->name);
|
||||
|
||||
@ -129,7 +136,10 @@ ospf6_router_lsa_originate_sub (struct ospf6_area *oa, int force)
|
||||
OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_R);
|
||||
OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_DC);
|
||||
|
||||
UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
|
||||
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
|
||||
@ -171,7 +181,7 @@ ospf6_router_lsa_originate_sub (struct ospf6_area *oa, int force)
|
||||
{
|
||||
if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
|
||||
zlog_info ("Size limit setting for Router-LSA too short");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Fill LSA Header */
|
||||
@ -189,12 +199,9 @@ ospf6_router_lsa_originate_sub (struct ospf6_area *oa, int force)
|
||||
|
||||
/* create LSA */
|
||||
lsa = ospf6_lsa_create (lsa_header);
|
||||
lsa->scope = oa;
|
||||
if (force)
|
||||
SET_FLAG (lsa->flag, OSPF6_LSA_REFRESH);
|
||||
|
||||
/* Originate */
|
||||
ospf6_lsa_originate (lsa);
|
||||
ospf6_lsa_originate_area (lsa, oa);
|
||||
|
||||
/* Reset setting for consecutive origination */
|
||||
memset ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa),
|
||||
@ -277,15 +284,17 @@ ospf6_router_lsa_originate_sub (struct ospf6_area *oa, int force)
|
||||
|
||||
/* create LSA */
|
||||
lsa = ospf6_lsa_create (lsa_header);
|
||||
lsa->scope = oa;
|
||||
if (force)
|
||||
SET_FLAG (lsa->flag, OSPF6_LSA_REFRESH);
|
||||
|
||||
/* Originate */
|
||||
ospf6_lsa_originate (lsa);
|
||||
ospf6_lsa_originate_area (lsa, oa);
|
||||
|
||||
link_state_id ++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
|
||||
zlog_info ("Nothing to describe in Router-LSA, suppress");
|
||||
}
|
||||
|
||||
/* Do premature-aging of rest, undesired Router-LSAs */
|
||||
type = ntohs (OSPF6_LSTYPE_ROUTER);
|
||||
@ -295,36 +304,12 @@ ospf6_router_lsa_originate_sub (struct ospf6_area *oa, int force)
|
||||
{
|
||||
if (ntohl (lsa->header->id) < link_state_id)
|
||||
continue;
|
||||
ospf6_lsa_premature_aging (lsa);
|
||||
ospf6_lsa_purge (lsa);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ospf6_router_lsa_originate (struct thread *thread)
|
||||
{
|
||||
struct ospf6_area *oa;
|
||||
int force = 0;
|
||||
|
||||
oa = (struct ospf6_area *) THREAD_ARG (thread);
|
||||
oa->thread_router_lsa = NULL;
|
||||
ospf6_router_lsa_originate_sub (oa, force);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ospf6_router_lsa_reoriginate (struct ospf6_lsa *lsa)
|
||||
{
|
||||
struct ospf6_area *oa;
|
||||
int force = 1;
|
||||
|
||||
oa = (struct ospf6_area *) lsa->scope;
|
||||
ospf6_router_lsa_originate_sub (oa, force);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*******************************/
|
||||
/* RFC2740 3.4.3.2 Network-LSA */
|
||||
/*******************************/
|
||||
@ -355,9 +340,11 @@ ospf6_network_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ospf6_network_lsa_originate_sub (struct ospf6_interface *oi, int force)
|
||||
int
|
||||
ospf6_network_lsa_originate (struct thread *thread)
|
||||
{
|
||||
struct ospf6_interface *oi;
|
||||
|
||||
char buffer [OSPF6_MAX_LSASIZE];
|
||||
struct ospf6_lsa_header *lsa_header;
|
||||
|
||||
@ -370,15 +357,13 @@ ospf6_network_lsa_originate_sub (struct ospf6_interface *oi, int force)
|
||||
listnode i;
|
||||
u_int16_t type;
|
||||
|
||||
/* If self-originated Network-LSA for currently unenabled I/F
|
||||
(but was once enabled, so other routers send it to this router),
|
||||
we can't find oi->area for ospf6_lsdb_lookup (), and so can't
|
||||
do premature aging of the Network-LSA. Just let the LSA flow
|
||||
in network (other routers LSDB) for maximum duration of
|
||||
MaxAge. The contents of this router's Router-LSA will preclude
|
||||
the stale Network-LSA to be involved in routing calculation. */
|
||||
if (oi->area == NULL)
|
||||
return;
|
||||
oi = (struct ospf6_interface *) THREAD_ARG (thread);
|
||||
oi->thread_network_lsa = NULL;
|
||||
|
||||
/* The interface must be enabled until here. A Network-LSA of a
|
||||
disabled interface (but was once enabled) should be flushed
|
||||
by ospf6_lsa_refresh (), and does not come here. */
|
||||
assert (oi->area);
|
||||
|
||||
old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_NETWORK),
|
||||
htonl (oi->interface->ifindex),
|
||||
@ -388,8 +373,8 @@ ospf6_network_lsa_originate_sub (struct ospf6_interface *oi, int force)
|
||||
if (oi->state != OSPF6_INTERFACE_DR)
|
||||
{
|
||||
if (old)
|
||||
ospf6_lsa_premature_aging (old);
|
||||
return;
|
||||
ospf6_lsa_purge (old);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
|
||||
@ -408,8 +393,8 @@ ospf6_network_lsa_originate_sub (struct ospf6_interface *oi, int force)
|
||||
if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
|
||||
zlog_info ("Interface stub, ignore");
|
||||
if (old)
|
||||
ospf6_lsa_premature_aging (old);
|
||||
return;
|
||||
ospf6_lsa_purge (old);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* prepare buffer */
|
||||
@ -466,35 +451,9 @@ ospf6_network_lsa_originate_sub (struct ospf6_interface *oi, int force)
|
||||
|
||||
/* create LSA */
|
||||
lsa = ospf6_lsa_create (lsa_header);
|
||||
lsa->scope = oi->area;
|
||||
if (force)
|
||||
SET_FLAG (lsa->flag, OSPF6_LSA_REFRESH);
|
||||
|
||||
/* Originate */
|
||||
ospf6_lsa_originate (lsa);
|
||||
}
|
||||
|
||||
int
|
||||
ospf6_network_lsa_originate (struct thread *thread)
|
||||
{
|
||||
struct ospf6_interface *oi;
|
||||
int force = 0;
|
||||
|
||||
oi = (struct ospf6_interface *) THREAD_ARG (thread);
|
||||
oi->thread_network_lsa = NULL;
|
||||
ospf6_network_lsa_originate_sub (oi, force);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ospf6_network_lsa_reoriginate (struct ospf6_lsa *lsa)
|
||||
{
|
||||
struct ospf6_interface *oi;
|
||||
int force = 1;
|
||||
|
||||
oi = ospf6_interface_lookup_by_ifindex (ntohl (lsa->header->id));
|
||||
ospf6_network_lsa_originate_sub (oi, force);
|
||||
ospf6_lsa_originate_area (lsa, oi->area);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -558,9 +517,11 @@ ospf6_link_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ospf6_link_lsa_originate_sub (struct ospf6_interface *oi, int force)
|
||||
int
|
||||
ospf6_link_lsa_originate (struct thread *thread)
|
||||
{
|
||||
struct ospf6_interface *oi;
|
||||
|
||||
char buffer[OSPF6_MAX_LSASIZE];
|
||||
struct ospf6_lsa_header *lsa_header;
|
||||
struct ospf6_lsa *old, *lsa;
|
||||
@ -569,8 +530,10 @@ ospf6_link_lsa_originate_sub (struct ospf6_interface *oi, int force)
|
||||
struct ospf6_route *route;
|
||||
struct ospf6_prefix *op;
|
||||
|
||||
if (oi->area == NULL)
|
||||
return;
|
||||
oi = (struct ospf6_interface *) THREAD_ARG (thread);
|
||||
oi->thread_link_lsa = NULL;
|
||||
|
||||
assert (oi->area);
|
||||
|
||||
/* find previous LSA */
|
||||
old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_LINK),
|
||||
@ -580,8 +543,8 @@ ospf6_link_lsa_originate_sub (struct ospf6_interface *oi, int force)
|
||||
if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE))
|
||||
{
|
||||
if (old)
|
||||
ospf6_lsa_premature_aging (old);
|
||||
return;
|
||||
ospf6_lsa_purge (old);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
|
||||
@ -594,8 +557,8 @@ ospf6_link_lsa_originate_sub (struct ospf6_interface *oi, int force)
|
||||
zlog_info ("No Linklocal address on %s, defer originating",
|
||||
oi->interface->name);
|
||||
if (old)
|
||||
ospf6_lsa_premature_aging (old);
|
||||
return;
|
||||
ospf6_lsa_purge (old);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* prepare buffer */
|
||||
@ -641,35 +604,9 @@ ospf6_link_lsa_originate_sub (struct ospf6_interface *oi, int force)
|
||||
|
||||
/* create LSA */
|
||||
lsa = ospf6_lsa_create (lsa_header);
|
||||
lsa->scope = oi;
|
||||
if (force)
|
||||
SET_FLAG (lsa->flag, OSPF6_LSA_REFRESH);
|
||||
|
||||
/* Originate */
|
||||
ospf6_lsa_originate (lsa);
|
||||
}
|
||||
|
||||
int
|
||||
ospf6_link_lsa_originate (struct thread *thread)
|
||||
{
|
||||
struct ospf6_interface *oi;
|
||||
int force = 0;
|
||||
|
||||
oi = (struct ospf6_interface *) THREAD_ARG (thread);
|
||||
oi->thread_link_lsa = NULL;
|
||||
ospf6_link_lsa_originate_sub (oi, force);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ospf6_link_lsa_reoriginate (struct ospf6_lsa *lsa)
|
||||
{
|
||||
struct ospf6_interface *oi;
|
||||
int force = 1;
|
||||
|
||||
oi = ospf6_interface_lookup_by_ifindex (ntohl (lsa->header->id));
|
||||
ospf6_link_lsa_originate_sub (oi, force);
|
||||
ospf6_lsa_originate_interface (lsa, oi);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -736,10 +673,11 @@ ospf6_intra_prefix_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ospf6_intra_prefix_lsa_originate_stub_sub (struct ospf6_area *oa,
|
||||
int force)
|
||||
int
|
||||
ospf6_intra_prefix_lsa_originate_stub (struct thread *thread)
|
||||
{
|
||||
struct ospf6_area *oa;
|
||||
|
||||
char buffer[OSPF6_MAX_LSASIZE];
|
||||
struct ospf6_lsa_header *lsa_header;
|
||||
struct ospf6_lsa *old, *lsa;
|
||||
@ -755,15 +693,18 @@ ospf6_intra_prefix_lsa_originate_stub_sub (struct ospf6_area *oa,
|
||||
char buf[BUFSIZ];
|
||||
struct ospf6_route_table *route_advertise;
|
||||
|
||||
oa = (struct ospf6_area *) THREAD_ARG (thread);
|
||||
oa->thread_intra_prefix_lsa = NULL;
|
||||
|
||||
/* find previous LSA */
|
||||
old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX),
|
||||
htonl (0), oa->ospf6->router_id, oa->lsdb);
|
||||
|
||||
if (CHECK_FLAG (oa->flag, OSPF6_AREA_DISABLE))
|
||||
if (! IS_AREA_ENABLED (oa))
|
||||
{
|
||||
if (old)
|
||||
ospf6_lsa_premature_aging (old);
|
||||
return;
|
||||
ospf6_lsa_purge (old);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
|
||||
@ -830,9 +771,9 @@ ospf6_intra_prefix_lsa_originate_stub_sub (struct ospf6_area *oa,
|
||||
if (route_advertise->count == 0)
|
||||
{
|
||||
if (old)
|
||||
ospf6_lsa_premature_aging (old);
|
||||
ospf6_lsa_purge (old);
|
||||
ospf6_route_table_delete (route_advertise);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* put prefixes to advertise */
|
||||
@ -857,7 +798,7 @@ ospf6_intra_prefix_lsa_originate_stub_sub (struct ospf6_area *oa,
|
||||
{
|
||||
if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
|
||||
zlog_info ("Quit to Advertise Intra-Prefix: no route to advertise");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
intra_prefix_lsa->prefix_num = htons (prefix_num);
|
||||
@ -877,18 +818,19 @@ ospf6_intra_prefix_lsa_originate_stub_sub (struct ospf6_area *oa,
|
||||
|
||||
/* create LSA */
|
||||
lsa = ospf6_lsa_create (lsa_header);
|
||||
lsa->scope = oa;
|
||||
if (force)
|
||||
SET_FLAG (lsa->flag, OSPF6_LSA_REFRESH);
|
||||
|
||||
/* Originate */
|
||||
ospf6_lsa_originate (lsa);
|
||||
ospf6_lsa_originate_area (lsa, oa);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ospf6_intra_prefix_lsa_originate_transit_sub (struct ospf6_interface *oi,
|
||||
int force)
|
||||
|
||||
int
|
||||
ospf6_intra_prefix_lsa_originate_transit (struct thread *thread)
|
||||
{
|
||||
struct ospf6_interface *oi;
|
||||
|
||||
char buffer[OSPF6_MAX_LSASIZE];
|
||||
struct ospf6_lsa_header *lsa_header;
|
||||
struct ospf6_lsa *old, *lsa;
|
||||
@ -906,8 +848,10 @@ ospf6_intra_prefix_lsa_originate_transit_sub (struct ospf6_interface *oi,
|
||||
u_int16_t type;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
if (oi->area == NULL)
|
||||
return;
|
||||
oi = (struct ospf6_interface *) THREAD_ARG (thread);
|
||||
oi->thread_intra_prefix_lsa = NULL;
|
||||
|
||||
assert (oi->area);
|
||||
|
||||
/* find previous LSA */
|
||||
old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX),
|
||||
@ -917,8 +861,8 @@ ospf6_intra_prefix_lsa_originate_transit_sub (struct ospf6_interface *oi,
|
||||
if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE))
|
||||
{
|
||||
if (old)
|
||||
ospf6_lsa_premature_aging (old);
|
||||
return;
|
||||
ospf6_lsa_purge (old);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
|
||||
@ -941,8 +885,8 @@ ospf6_intra_prefix_lsa_originate_transit_sub (struct ospf6_interface *oi,
|
||||
if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
|
||||
zlog_info (" Interface is not DR");
|
||||
if (old)
|
||||
ospf6_lsa_premature_aging (old);
|
||||
return;
|
||||
ospf6_lsa_purge (old);
|
||||
return 0;
|
||||
}
|
||||
|
||||
full_count = 0;
|
||||
@ -957,8 +901,8 @@ ospf6_intra_prefix_lsa_originate_transit_sub (struct ospf6_interface *oi,
|
||||
if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
|
||||
zlog_info (" Interface is stub");
|
||||
if (old)
|
||||
ospf6_lsa_premature_aging (old);
|
||||
return;
|
||||
ospf6_lsa_purge (old);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* connected prefix to advertise */
|
||||
@ -1053,7 +997,7 @@ ospf6_intra_prefix_lsa_originate_transit_sub (struct ospf6_interface *oi,
|
||||
{
|
||||
if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
|
||||
zlog_info ("Quit to Advertise Intra-Prefix: no route to advertise");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
intra_prefix_lsa->prefix_num = htons (prefix_num);
|
||||
@ -1073,69 +1017,9 @@ ospf6_intra_prefix_lsa_originate_transit_sub (struct ospf6_interface *oi,
|
||||
|
||||
/* create LSA */
|
||||
lsa = ospf6_lsa_create (lsa_header);
|
||||
lsa->scope = oi->area;
|
||||
if (force)
|
||||
SET_FLAG (lsa->flag, OSPF6_LSA_REFRESH);
|
||||
|
||||
/* Originate */
|
||||
ospf6_lsa_originate (lsa);
|
||||
}
|
||||
|
||||
int
|
||||
ospf6_intra_prefix_lsa_originate_stub (struct thread *thread)
|
||||
{
|
||||
struct ospf6_area *oa;
|
||||
int force = 0;
|
||||
|
||||
oa = (struct ospf6_area *) THREAD_ARG (thread);
|
||||
oa->thread_intra_prefix_lsa = NULL;
|
||||
ospf6_intra_prefix_lsa_originate_stub_sub (oa, force);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ospf6_intra_prefix_lsa_originate_transit (struct thread *thread)
|
||||
{
|
||||
struct ospf6_interface *oi;
|
||||
int force = 0;
|
||||
|
||||
oi = (struct ospf6_interface *) THREAD_ARG (thread);
|
||||
oi->thread_intra_prefix_lsa = NULL;
|
||||
ospf6_intra_prefix_lsa_originate_transit_sub (oi, force);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ospf6_intra_prefix_lsa_reoriginate (struct ospf6_lsa *lsa)
|
||||
{
|
||||
struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
|
||||
u_int16_t type;
|
||||
u_int32_t id;
|
||||
struct ospf6_area *oa;
|
||||
struct ospf6_interface *oi;
|
||||
int force = 1;
|
||||
|
||||
intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
|
||||
((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
|
||||
type = ntohs (intra_prefix_lsa->ref_type);
|
||||
id = ntohl (intra_prefix_lsa->ref_id);
|
||||
|
||||
if (type == OSPF6_LSTYPE_ROUTER && id == 0)
|
||||
{
|
||||
oa = (struct ospf6_area *) lsa->scope;
|
||||
ospf6_intra_prefix_lsa_originate_stub_sub (oa, force);
|
||||
}
|
||||
else if (type == OSPF6_LSTYPE_NETWORK && id != 0)
|
||||
{
|
||||
if (intra_prefix_lsa->ref_id != lsa->header->id)
|
||||
ospf6_lsa_premature_aging (lsa);
|
||||
oi = ospf6_interface_lookup_by_ifindex (id);
|
||||
ospf6_intra_prefix_lsa_originate_transit_sub (oi, force);
|
||||
}
|
||||
else
|
||||
ospf6_lsa_premature_aging (lsa);
|
||||
ospf6_lsa_originate_area (lsa, oi->area);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1155,7 +1039,8 @@ ospf6_intra_prefix_lsa_add (struct ospf6_lsa *lsa)
|
||||
if (IS_OSPF6_DEBUG_ROUTE (INTRA))
|
||||
zlog_info ("%s found", lsa->name);
|
||||
|
||||
oa = (struct ospf6_area *) lsa->scope;
|
||||
oa = OSPF6_AREA (lsa->lsdb->data);
|
||||
|
||||
intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
|
||||
OSPF6_LSA_HEADER_END (lsa->header);
|
||||
if (intra_prefix_lsa->ref_type == htons (OSPF6_LSTYPE_ROUTER))
|
||||
@ -1244,7 +1129,8 @@ ospf6_intra_prefix_lsa_remove (struct ospf6_lsa *lsa)
|
||||
if (IS_OSPF6_DEBUG_ROUTE (INTRA))
|
||||
zlog_info ("%s disappearing", lsa->name);
|
||||
|
||||
oa = (struct ospf6_area *) lsa->scope;
|
||||
oa = OSPF6_AREA (lsa->lsdb->data);
|
||||
|
||||
intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
|
||||
OSPF6_LSA_HEADER_END (lsa->header);
|
||||
|
||||
@ -1355,21 +1241,22 @@ ospf6_intra_route_calculation (struct ospf6_area *oa)
|
||||
}
|
||||
|
||||
void
|
||||
ospf6_intra_asbr_calculation (struct ospf6_area *oa)
|
||||
ospf6_intra_brouter_calculation (struct ospf6_area *oa)
|
||||
{
|
||||
struct ospf6_route *lsentry, *copy;
|
||||
void (*hook_add) (struct ospf6_route *) = NULL;
|
||||
void (*hook_remove) (struct ospf6_route *) = NULL;
|
||||
|
||||
if (IS_OSPF6_DEBUG_ASBR)
|
||||
zlog_info ("Intra-area ASBR calculation for area %s", oa->name);
|
||||
if (IS_OSPF6_DEBUG_ROUTE (INTRA))
|
||||
zlog_info ("Border-router calculation for area %s", oa->name);
|
||||
|
||||
hook_add = oa->ospf6->asbr_table->hook_add;
|
||||
hook_remove = oa->ospf6->asbr_table->hook_remove;
|
||||
oa->ospf6->asbr_table->hook_add = NULL;
|
||||
oa->ospf6->asbr_table->hook_remove = NULL;
|
||||
hook_add = oa->ospf6->brouter_table->hook_add;
|
||||
hook_remove = oa->ospf6->brouter_table->hook_remove;
|
||||
oa->ospf6->brouter_table->hook_add = NULL;
|
||||
oa->ospf6->brouter_table->hook_remove = NULL;
|
||||
|
||||
for (lsentry = ospf6_route_head (oa->ospf6->asbr_table); lsentry;
|
||||
/* withdraw the previous router entries for the area */
|
||||
for (lsentry = ospf6_route_head (oa->ospf6->brouter_table); lsentry;
|
||||
lsentry = ospf6_route_next (lsentry))
|
||||
{
|
||||
if (lsentry->path.area_id != oa->area_id)
|
||||
@ -1384,20 +1271,21 @@ ospf6_intra_asbr_calculation (struct ospf6_area *oa)
|
||||
continue;
|
||||
if (ospf6_linkstate_prefix_id (&lsentry->prefix) != htonl (0))
|
||||
continue;
|
||||
if (! CHECK_FLAG (lsentry->path.router_bits, OSPF6_ROUTER_BIT_E))
|
||||
if (! CHECK_FLAG (lsentry->path.router_bits, OSPF6_ROUTER_BIT_E) &&
|
||||
! CHECK_FLAG (lsentry->path.router_bits, OSPF6_ROUTER_BIT_B))
|
||||
continue;
|
||||
|
||||
copy = ospf6_route_copy (lsentry);
|
||||
copy->type = OSPF6_DEST_TYPE_ROUTER;
|
||||
copy->prefix.family = AF_INET;
|
||||
copy->prefix.prefixlen = 32;
|
||||
ospf6_route_add (copy, oa->ospf6->asbr_table);
|
||||
ospf6_route_add (copy, oa->ospf6->brouter_table);
|
||||
}
|
||||
|
||||
oa->ospf6->asbr_table->hook_add = hook_add;
|
||||
oa->ospf6->asbr_table->hook_remove = hook_remove;
|
||||
oa->ospf6->brouter_table->hook_add = hook_add;
|
||||
oa->ospf6->brouter_table->hook_remove = hook_remove;
|
||||
|
||||
for (lsentry = ospf6_route_head (oa->ospf6->asbr_table); lsentry;
|
||||
for (lsentry = ospf6_route_head (oa->ospf6->brouter_table); lsentry;
|
||||
lsentry = ospf6_route_next (lsentry))
|
||||
{
|
||||
if (lsentry->path.area_id != oa->area_id)
|
||||
@ -1411,7 +1299,7 @@ ospf6_intra_asbr_calculation (struct ospf6_area *oa)
|
||||
}
|
||||
|
||||
if (CHECK_FLAG (lsentry->flag, OSPF6_ROUTE_REMOVE))
|
||||
ospf6_route_remove (lsentry, oa->ospf6->asbr_table);
|
||||
ospf6_route_remove (lsentry, oa->ospf6->brouter_table);
|
||||
else if (CHECK_FLAG (lsentry->flag, OSPF6_ROUTE_ADD) ||
|
||||
CHECK_FLAG (lsentry->flag, OSPF6_ROUTE_CHANGE))
|
||||
{
|
||||
@ -1422,27 +1310,45 @@ ospf6_intra_asbr_calculation (struct ospf6_area *oa)
|
||||
lsentry->flag = 0;
|
||||
}
|
||||
|
||||
if (IS_OSPF6_DEBUG_ASBR)
|
||||
zlog_info ("Intra-area ASBR calculation for area %s: Done", oa->name);
|
||||
if (IS_OSPF6_DEBUG_ROUTE (INTRA))
|
||||
zlog_info ("Border-router calculation for area %s: Done", oa->name);
|
||||
}
|
||||
|
||||
struct ospf6_lsa_handler router_handler =
|
||||
{
|
||||
OSPF6_LSTYPE_ROUTER,
|
||||
"Router",
|
||||
ospf6_router_lsa_show
|
||||
};
|
||||
|
||||
struct ospf6_lsa_handler network_handler =
|
||||
{
|
||||
OSPF6_LSTYPE_NETWORK,
|
||||
"Network",
|
||||
ospf6_network_lsa_show
|
||||
};
|
||||
|
||||
struct ospf6_lsa_handler link_handler =
|
||||
{
|
||||
OSPF6_LSTYPE_LINK,
|
||||
"Link",
|
||||
ospf6_link_lsa_show
|
||||
};
|
||||
|
||||
struct ospf6_lsa_handler intra_prefix_handler =
|
||||
{
|
||||
OSPF6_LSTYPE_INTRA_PREFIX,
|
||||
"Intra-Prefix",
|
||||
ospf6_intra_prefix_lsa_show
|
||||
};
|
||||
|
||||
void
|
||||
ospf6_intra_init ()
|
||||
{
|
||||
ospf6_lstype[1].name = "Router";
|
||||
ospf6_lstype[2].name = "Network";
|
||||
ospf6_lstype[8].name = "Link";
|
||||
ospf6_lstype[9].name = "Intra-Prefix";
|
||||
|
||||
ospf6_lstype[1].reoriginate = ospf6_router_lsa_reoriginate;
|
||||
ospf6_lstype[2].reoriginate = ospf6_network_lsa_reoriginate;
|
||||
ospf6_lstype[8].reoriginate = ospf6_link_lsa_reoriginate;
|
||||
ospf6_lstype[9].reoriginate = ospf6_intra_prefix_lsa_reoriginate;
|
||||
|
||||
ospf6_lstype[1].show = ospf6_router_lsa_show;
|
||||
ospf6_lstype[2].show = ospf6_network_lsa_show;
|
||||
ospf6_lstype[8].show = ospf6_link_lsa_show;
|
||||
ospf6_lstype[9].show = ospf6_intra_prefix_lsa_show;
|
||||
ospf6_install_lsa_handler (&router_handler);
|
||||
ospf6_install_lsa_handler (&network_handler);
|
||||
ospf6_install_lsa_handler (&link_handler);
|
||||
ospf6_install_lsa_handler (&intra_prefix_handler);
|
||||
}
|
||||
|
||||
|
||||
|
@ -128,6 +128,18 @@ struct ospf6_intra_prefix_lsa
|
||||
oi, 0); \
|
||||
} while (0)
|
||||
|
||||
#define OSPF6_NETWORK_LSA_EXECUTE(oi) \
|
||||
do { \
|
||||
THREAD_OFF ((oi)->thread_network_lsa); \
|
||||
thread_execute (master, ospf6_network_lsa_originate, oi, 0); \
|
||||
} while (0)
|
||||
#define OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi) \
|
||||
do { \
|
||||
THREAD_OFF ((oi)->thread_intra_prefix_lsa); \
|
||||
thread_execute (master, ospf6_intra_prefix_lsa_originate_transit, oi, 0); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* Function Prototypes */
|
||||
char *ospf6_router_lsdesc_lookup (u_char type, u_int32_t interface_id,
|
||||
u_int32_t neighbor_interface_id,
|
||||
@ -145,7 +157,7 @@ void ospf6_intra_prefix_lsa_add (struct ospf6_lsa *lsa);
|
||||
void ospf6_intra_prefix_lsa_remove (struct ospf6_lsa *lsa);
|
||||
|
||||
void ospf6_intra_route_calculation (struct ospf6_area *oa);
|
||||
void ospf6_intra_asbr_calculation (struct ospf6_area *oa);
|
||||
void ospf6_intra_brouter_calculation (struct ospf6_area *oa);
|
||||
|
||||
void ospf6_intra_init ();
|
||||
|
||||
|
@ -43,7 +43,7 @@
|
||||
|
||||
unsigned char conf_debug_ospf6_lsa = 0;
|
||||
|
||||
struct ospf6_lstype ospf6_lstype[OSPF6_LSTYPE_SIZE];
|
||||
struct ospf6_lsa_handler *ospf6_lsa_handler[OSPF6_LSTYPE_SIZE];
|
||||
|
||||
char *ospf6_lstype_str[OSPF6_LSTYPE_SIZE] =
|
||||
{"Unknown", "Router", "Network", "Inter-Prefix", "Inter-Router",
|
||||
@ -53,10 +53,10 @@ char *
|
||||
ospf6_lstype_name (u_int16_t type)
|
||||
{
|
||||
static char buf[8];
|
||||
int index = ntohs (type) & OSPF6_LSTYPE_FCODE_MASK;
|
||||
int index = OSPF6_LSTYPE_INDEX (type);
|
||||
|
||||
if (index < OSPF6_LSTYPE_SIZE && ospf6_lstype_str[index])
|
||||
return ospf6_lstype_str[index];
|
||||
if (ospf6_lsa_handler[index])
|
||||
return ospf6_lsa_handler[index]->name;
|
||||
|
||||
snprintf (buf, sizeof (buf), "0x%04hx", ntohs (type));
|
||||
return buf;
|
||||
@ -125,8 +125,7 @@ ospf6_lsa_age_set (struct ospf6_lsa *lsa)
|
||||
lsa->birth.tv_usec = now.tv_usec;
|
||||
if (ntohs (lsa->header->age) != MAXAGE)
|
||||
lsa->expire = thread_add_timer (master, ospf6_lsa_expire, lsa,
|
||||
MAXAGE + lsa->birth.tv_sec
|
||||
- now.tv_sec);
|
||||
MAXAGE + lsa->birth.tv_sec - now.tv_sec);
|
||||
else
|
||||
lsa->expire = NULL;
|
||||
return;
|
||||
@ -271,37 +270,6 @@ ospf6_lsa_header_print (struct ospf6_lsa *lsa)
|
||||
ospf6_lsa_header_print_raw (lsa->header);
|
||||
}
|
||||
|
||||
void
|
||||
ospf6_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
|
||||
{
|
||||
char adv_router[64], id[64];
|
||||
int index;
|
||||
|
||||
assert (lsa && lsa->header);
|
||||
|
||||
inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));
|
||||
inet_ntop (AF_INET, &lsa->header->adv_router,
|
||||
adv_router, sizeof (adv_router));
|
||||
|
||||
vty_out (vty, "Age: %4hu Type: %s%s", ospf6_lsa_age_current (lsa),
|
||||
OSPF6_LSTYPE_NAME (lsa->header->type), VNL);
|
||||
vty_out (vty, "Link State ID: %s%s", id, VNL);
|
||||
vty_out (vty, "Advertising Router: %s%s", adv_router, VNL);
|
||||
vty_out (vty, "LS Sequence Number: %#010lx%s",
|
||||
(u_long) ntohl (lsa->header->seqnum), VNL);
|
||||
vty_out (vty, "CheckSum: %#06hx Length: %hu%s",
|
||||
ntohs (lsa->header->checksum),
|
||||
ntohs (lsa->header->length), VNL);
|
||||
|
||||
index = OSPF6_LSTYPE_INDEX (ntohs (lsa->header->type));
|
||||
if (ospf6_lstype[index].show)
|
||||
(*ospf6_lstype[index].show) (vty, lsa);
|
||||
else
|
||||
vty_out (vty, "%sUnknown LSA type ...%s", VNL, VNL);
|
||||
|
||||
vty_out (vty, "%s", VNL);
|
||||
}
|
||||
|
||||
void
|
||||
ospf6_lsa_show_summary_header (struct vty *vty)
|
||||
{
|
||||
@ -360,6 +328,7 @@ ospf6_lsa_show_dump (struct vty *vty, struct ospf6_lsa *lsa)
|
||||
}
|
||||
|
||||
vty_out (vty, "%s%s", VNL, VNL);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
@ -386,10 +355,44 @@ ospf6_lsa_show_internal (struct vty *vty, struct ospf6_lsa *lsa)
|
||||
vty_out (vty, " Prev: %p This: %p Next: %p%s",
|
||||
lsa->prev, lsa, lsa->next, VNL);
|
||||
vty_out (vty, "%s", VNL);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
ospf6_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
|
||||
{
|
||||
char adv_router[64], id[64];
|
||||
int index;
|
||||
|
||||
assert (lsa && lsa->header);
|
||||
|
||||
inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));
|
||||
inet_ntop (AF_INET, &lsa->header->adv_router,
|
||||
adv_router, sizeof (adv_router));
|
||||
|
||||
vty_out (vty, "Age: %4hu Type: %s%s", ospf6_lsa_age_current (lsa),
|
||||
OSPF6_LSTYPE_NAME (lsa->header->type), VNL);
|
||||
vty_out (vty, "Link State ID: %s%s", id, VNL);
|
||||
vty_out (vty, "Advertising Router: %s%s", adv_router, VNL);
|
||||
vty_out (vty, "LS Sequence Number: %#010lx%s",
|
||||
(u_long) ntohl (lsa->header->seqnum), VNL);
|
||||
vty_out (vty, "CheckSum: %#06hx Length: %hu%s",
|
||||
ntohs (lsa->header->checksum),
|
||||
ntohs (lsa->header->length), VNL);
|
||||
|
||||
index = OSPF6_LSTYPE_INDEX (lsa->header->type);
|
||||
if (ospf6_lsa_handler[index]->show)
|
||||
(*ospf6_lsa_handler[index]->show) (vty, lsa);
|
||||
else
|
||||
{
|
||||
ospf6_lsa_show_dump (vty, lsa);
|
||||
vty_out (vty, "%sUnknown LSA type ...%s", VNL, VNL);
|
||||
}
|
||||
|
||||
vty_out (vty, "%s", VNL);
|
||||
}
|
||||
|
||||
/* OSPFv3 LSA creation/deletion function */
|
||||
|
||||
struct ospf6_lsa *
|
||||
ospf6_lsa_create (struct ospf6_lsa_header *header)
|
||||
{
|
||||
@ -414,7 +417,6 @@ ospf6_lsa_create (struct ospf6_lsa_header *header)
|
||||
memset (lsa, 0, sizeof (struct ospf6_lsa));
|
||||
|
||||
lsa->header = (struct ospf6_lsa_header *) new_header;
|
||||
lsa->headeronly = 0; /* this is not header only */
|
||||
|
||||
/* dump string */
|
||||
ospf6_lsa_printbuf (lsa, lsa->name, sizeof (lsa->name));
|
||||
@ -449,7 +451,7 @@ ospf6_lsa_create_headeronly (struct ospf6_lsa_header *header)
|
||||
memset (lsa, 0, sizeof (struct ospf6_lsa));
|
||||
|
||||
lsa->header = (struct ospf6_lsa_header *) new_header;
|
||||
lsa->headeronly = 1; /* this is header only */
|
||||
SET_FLAG (lsa->flag, OSPF6_LSA_HEADERONLY);
|
||||
|
||||
/* dump string */
|
||||
ospf6_lsa_printbuf (lsa, lsa->name, sizeof (lsa->name));
|
||||
@ -475,8 +477,8 @@ ospf6_lsa_delete (struct ospf6_lsa *lsa)
|
||||
|
||||
if (IS_OSPF6_DEBUG_LSA (MEMORY))
|
||||
zlog_info ("Delete LSA %s Memory: %s (%p/%p)",
|
||||
(lsa->headeronly ? "(Header-only) " : ""),
|
||||
lsa->name, lsa, lsa->header);
|
||||
(CHECK_FLAG (lsa->flag, OSPF6_LSA_HEADERONLY) ?
|
||||
"(Header-only) " : ""), lsa->name, lsa, lsa->header);
|
||||
|
||||
/* do free */
|
||||
XFREE (MTYPE_OSPF6_LSA, lsa->header);
|
||||
@ -492,7 +494,7 @@ ospf6_lsa_copy (struct ospf6_lsa *lsa)
|
||||
zlog_info ("Create LSA Copy from %s", lsa->name);
|
||||
|
||||
ospf6_lsa_age_current (lsa);
|
||||
if (lsa->headeronly)
|
||||
if (CHECK_FLAG (lsa->flag, OSPF6_LSA_HEADERONLY))
|
||||
copy = ospf6_lsa_create_headeronly (lsa->header);
|
||||
else
|
||||
copy = ospf6_lsa_create (lsa->header);
|
||||
@ -500,7 +502,7 @@ ospf6_lsa_copy (struct ospf6_lsa *lsa)
|
||||
|
||||
copy->installed = lsa->installed;
|
||||
copy->originated = lsa->originated;
|
||||
copy->scope = lsa->scope;
|
||||
copy->lsdb = lsa->lsdb;
|
||||
|
||||
return copy;
|
||||
}
|
||||
@ -527,77 +529,12 @@ ospf6_lsa_unlock (struct ospf6_lsa *lsa)
|
||||
ospf6_lsa_delete (lsa);
|
||||
}
|
||||
|
||||
void
|
||||
ospf6_lsa_originate (struct ospf6_lsa *lsa)
|
||||
{
|
||||
struct ospf6_lsa *old;
|
||||
struct ospf6_lsdb *lsdb = NULL;
|
||||
|
||||
/* find previous LSA */
|
||||
lsdb = ospf6_get_scoped_lsdb (lsa->header->type, lsa->scope);
|
||||
if (lsdb == NULL)
|
||||
{
|
||||
zlog_warn ("Can't decide scoped LSDB");
|
||||
ospf6_lsa_delete (lsa);
|
||||
return;
|
||||
}
|
||||
|
||||
old = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
|
||||
lsa->header->adv_router, lsdb);
|
||||
if (old)
|
||||
{
|
||||
/* If this origination is neither different instance nor refresh,
|
||||
suppress this origination */
|
||||
if (! CHECK_FLAG (old->flag, OSPF6_LSA_REFRESH) &&
|
||||
! OSPF6_LSA_IS_DIFFER (lsa, old))
|
||||
{
|
||||
if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
|
||||
zlog_info ("Suppress updating LSA: %s", lsa->name);
|
||||
ospf6_lsa_delete (lsa);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
lsa->refresh = thread_add_timer (master, ospf6_lsa_refresh, lsa,
|
||||
LS_REFRESH_TIME);
|
||||
|
||||
if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
|
||||
{
|
||||
zlog_info ("LSA Originate:");
|
||||
ospf6_lsa_header_print (lsa);
|
||||
}
|
||||
|
||||
if (old)
|
||||
ospf6_flood_clear (old);
|
||||
ospf6_flood_lsa (lsa, NULL);
|
||||
ospf6_install_lsa (lsa, lsdb);
|
||||
}
|
||||
|
||||
void
|
||||
ospf6_lsa_re_originate (struct ospf6_lsa *lsa)
|
||||
{
|
||||
u_int16_t index;
|
||||
|
||||
if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
|
||||
{
|
||||
zlog_info ("LSA Reoriginate:");
|
||||
ospf6_lsa_header_print (lsa);
|
||||
}
|
||||
|
||||
index = OSPF6_LSTYPE_INDEX (ntohs (lsa->header->type));
|
||||
if (ospf6_lstype[index].reoriginate)
|
||||
(*ospf6_lstype[index].reoriginate) (lsa);
|
||||
else
|
||||
ospf6_lsa_premature_aging (lsa);
|
||||
}
|
||||
|
||||
|
||||
/* ospf6 lsa expiry */
|
||||
int
|
||||
ospf6_lsa_expire (struct thread *thread)
|
||||
{
|
||||
struct ospf6_lsa *lsa;
|
||||
struct ospf6_lsdb *lsdb = NULL;
|
||||
|
||||
lsa = (struct ospf6_lsa *) THREAD_ARG (thread);
|
||||
|
||||
@ -613,22 +550,16 @@ ospf6_lsa_expire (struct thread *thread)
|
||||
ospf6_lsa_header_print (lsa);
|
||||
}
|
||||
|
||||
if (lsa->headeronly)
|
||||
if (CHECK_FLAG (lsa->flag, OSPF6_LSA_HEADERONLY))
|
||||
return 0; /* dbexchange will do something ... */
|
||||
|
||||
/* reflood lsa */
|
||||
ospf6_flood_lsa (lsa, NULL);
|
||||
ospf6_flood (NULL, lsa);
|
||||
|
||||
/* reinstall lsa */
|
||||
lsdb = ospf6_get_scoped_lsdb (lsa->header->type, lsa->scope);
|
||||
if (lsdb == NULL)
|
||||
{
|
||||
zlog_warn ("Can't decide scoped LSDB: %s", lsa->name);
|
||||
return 0;
|
||||
}
|
||||
if (IS_OSPF6_DEBUG_LSA (DATABASE))
|
||||
zlog_info ("Reinstall MaxAge %s", lsa->name);
|
||||
ospf6_lsdb_add (lsa, lsdb);
|
||||
ospf6_lsdb_add (lsa, lsa->lsdb);
|
||||
|
||||
/* schedule maxage remover */
|
||||
ospf6_maxage_remove (ospf6);
|
||||
@ -636,29 +567,52 @@ ospf6_lsa_expire (struct thread *thread)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Below will become dummy thread.
|
||||
refresh function must be set individually per each LSAs */
|
||||
int
|
||||
ospf6_lsa_refresh (struct thread *thread)
|
||||
{
|
||||
struct ospf6_lsa *lsa;
|
||||
struct ospf6_lsa *old, *self, *new;
|
||||
struct ospf6_lsdb *lsdb_self;
|
||||
|
||||
assert (thread);
|
||||
lsa = (struct ospf6_lsa *) THREAD_ARG (thread);
|
||||
assert (lsa && lsa->header);
|
||||
old = (struct ospf6_lsa *) THREAD_ARG (thread);
|
||||
assert (old && old->header);
|
||||
|
||||
lsa->refresh = (struct thread *) NULL;
|
||||
old->refresh = (struct thread *) NULL;
|
||||
|
||||
/* this will be used later to decide really originate or not */
|
||||
SET_FLAG (lsa->flag, OSPF6_LSA_REFRESH);
|
||||
lsdb_self = ospf6_get_scoped_lsdb_self (old);
|
||||
self = ospf6_lsdb_lookup (old->header->type, old->header->id,
|
||||
old->header->adv_router, lsdb_self);
|
||||
if (self == NULL)
|
||||
{
|
||||
ospf6_lsa_premature_aging (old);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Reset age, increment LS sequence number. */
|
||||
self->header->age = htons (0);
|
||||
self->header->seqnum =
|
||||
ospf6_new_ls_seqnum (self->header->type, self->header->id,
|
||||
self->header->adv_router, old->lsdb);
|
||||
ospf6_lsa_checksum (self->header);
|
||||
|
||||
new = ospf6_lsa_create (self->header);
|
||||
new->lsdb = old->lsdb;
|
||||
new->refresh = thread_add_timer (master, ospf6_lsa_refresh, new,
|
||||
LS_REFRESH_TIME);
|
||||
|
||||
/* store it in the LSDB for self-originated LSAs */
|
||||
ospf6_lsdb_add (ospf6_lsa_copy (new), lsdb_self);
|
||||
|
||||
if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
|
||||
{
|
||||
zlog_info ("LSA Refresh:");
|
||||
ospf6_lsa_header_print (lsa);
|
||||
ospf6_lsa_header_print (new);
|
||||
}
|
||||
|
||||
ospf6_lsa_re_originate (lsa);
|
||||
ospf6_flood_clear (old);
|
||||
ospf6_flood (NULL, new);
|
||||
ospf6_install_lsa (new);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -708,14 +662,7 @@ ospf6_lsa_checksum (struct ospf6_lsa_header *lsa_header)
|
||||
}
|
||||
|
||||
int
|
||||
ospf6_unknown_reoriginate (struct ospf6_lsa *lsa)
|
||||
{
|
||||
ospf6_lsa_premature_aging (lsa);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ospf6_unknown_show (struct vty *vty, struct ospf6_lsa *lsa)
|
||||
ospf6_unknown_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
|
||||
{
|
||||
u_char *start, *end, *current;
|
||||
char byte[4];
|
||||
@ -739,14 +686,26 @@ ospf6_unknown_show (struct vty *vty, struct ospf6_lsa *lsa)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ospf6_install_lsa_handler (struct ospf6_lsa_handler *handler)
|
||||
{
|
||||
/* might need to adjust dynamic array length ... */
|
||||
int index = OSPF6_LSTYPE_INDEX (htons (handler->type));
|
||||
ospf6_lsa_handler[index] = handler;
|
||||
}
|
||||
|
||||
struct ospf6_lsa_handler unknown_handler =
|
||||
{
|
||||
OSPF6_LSTYPE_UNKNOWN,
|
||||
"Unknown",
|
||||
ospf6_unknown_lsa_show
|
||||
};
|
||||
|
||||
void
|
||||
ospf6_lsa_init ()
|
||||
{
|
||||
memset (ospf6_lstype, 0, sizeof (ospf6_lstype));
|
||||
|
||||
ospf6_lstype[0].name = "Unknown";
|
||||
ospf6_lstype[0].reoriginate = ospf6_unknown_reoriginate;
|
||||
ospf6_lstype[0].show = ospf6_unknown_show;
|
||||
memset (ospf6_lsa_handler, 0, sizeof (ospf6_lsa_handler));
|
||||
ospf6_install_lsa_handler (&unknown_handler);
|
||||
}
|
||||
|
||||
|
||||
|
@ -62,11 +62,12 @@ extern unsigned char conf_debug_ospf6_lsa;
|
||||
#define OSPF6_LSTYPE_FCODE_MASK 0x1fff
|
||||
|
||||
/* LSA scope */
|
||||
#define OSPF6_LSA_SCOPE_LINKLOCAL 0x0000
|
||||
#define OSPF6_LSA_SCOPE_AREA 0x2000
|
||||
#define OSPF6_LSA_SCOPE_AS 0x4000
|
||||
#define OSPF6_LSA_SCOPE_RESERVED 0x6000
|
||||
#define OSPF6_SCOPE_LINKLOCAL 0x0000
|
||||
#define OSPF6_SCOPE_AREA 0x2000
|
||||
#define OSPF6_SCOPE_AS 0x4000
|
||||
#define OSPF6_SCOPE_RESERVED 0x6000
|
||||
|
||||
/* XXX U-bit handling should be treated here */
|
||||
#define OSPF6_LSA_SCOPE(type) \
|
||||
(ntohs (type) & OSPF6_LSTYPE_SCOPE_MASK)
|
||||
|
||||
@ -103,55 +104,46 @@ struct ospf6_lsa_header
|
||||
|
||||
struct ospf6_lsa
|
||||
{
|
||||
char name[64]; /* dump string */
|
||||
char name[64]; /* dump string */
|
||||
|
||||
struct ospf6_lsa *prev;
|
||||
struct ospf6_lsa *next;
|
||||
struct ospf6_lsa *prev;
|
||||
struct ospf6_lsa *next;
|
||||
|
||||
unsigned char lock; /* reference counter */
|
||||
unsigned char flag; /* special meaning (e.g. floodback) */
|
||||
unsigned char lock; /* reference counter */
|
||||
unsigned char flag; /* special meaning (e.g. floodback) */
|
||||
|
||||
struct timeval birth; /* tv_sec when LS age 0 */
|
||||
struct timeval installed; /* used by MinLSArrival check */
|
||||
struct timeval originated; /* used by MinLSInterval check */
|
||||
struct timeval birth; /* tv_sec when LS age 0 */
|
||||
struct timeval installed; /* used by MinLSArrival check */
|
||||
struct timeval originated; /* used by MinLSInterval check */
|
||||
|
||||
struct thread *expire;
|
||||
struct thread *refresh; /* For self-originated LSA */
|
||||
struct thread *expire;
|
||||
struct thread *refresh; /* For self-originated LSA */
|
||||
|
||||
void *scope; /* pointer to scope data structure */
|
||||
int headeronly; /* indicate this is LS header only */
|
||||
int onretrans;
|
||||
int retrans_count;
|
||||
|
||||
struct ospf6_lsdb;
|
||||
struct ospf6_lsdb *lsdb;
|
||||
|
||||
/* lsa instance */
|
||||
struct ospf6_lsa_header *header;
|
||||
};
|
||||
|
||||
#define OSPF6_LSA_FLOODBACK 0x01
|
||||
#define OSPF6_LSA_DUPLICATE 0x02
|
||||
#define OSPF6_LSA_IMPLIEDACK 0x04
|
||||
#define OSPF6_LSA_REFRESH 0x08
|
||||
#define OSPF6_LSA_HEADERONLY 0x01
|
||||
#define OSPF6_LSA_FLOODBACK 0x02
|
||||
#define OSPF6_LSA_DUPLICATE 0x04
|
||||
#define OSPF6_LSA_IMPLIEDACK 0x08
|
||||
|
||||
struct ospf6_lstype
|
||||
struct ospf6_lsa_handler
|
||||
{
|
||||
u_int16_t type; /* network byte order */
|
||||
char *name;
|
||||
int (*reoriginate) (struct ospf6_lsa *);
|
||||
int (*show) (struct vty *, struct ospf6_lsa *);
|
||||
};
|
||||
|
||||
extern struct ospf6_lstype ospf6_lstype[OSPF6_LSTYPE_SIZE];
|
||||
#define OSPF6_LSTYPE_INDEX(type) \
|
||||
(((type) & OSPF6_LSTYPE_FCODE_MASK) < OSPF6_LSTYPE_SIZE ? \
|
||||
((type) & OSPF6_LSTYPE_FCODE_MASK) : OSPF6_LSTYPE_UNKNOWN)
|
||||
|
||||
#if 0
|
||||
extern char *ospf6_lstype_str[OSPF6_LSTYPE_SIZE];
|
||||
#define OSPF6_LSTYPE_NAME(type) \
|
||||
((ntohs (type) & OSPF6_LSTYPE_FCODE_MASK) < OSPF6_LSTYPE_SIZE ? \
|
||||
ospf6_lstype_str[ntohs (type) & OSPF6_LSTYPE_FCODE_MASK] : \
|
||||
ospf6_lstype_str[OSPF6_LSTYPE_UNKNOWN])
|
||||
#else /*0*/
|
||||
(ntohs (type) & OSPF6_LSTYPE_FCODE_MASK) : OSPF6_LSTYPE_UNKNOWN)
|
||||
#define OSPF6_LSTYPE_NAME(type) (ospf6_lstype_name (type))
|
||||
#endif /*0*/
|
||||
|
||||
/* Macro for LSA Origination */
|
||||
/* void (CONTINUE_IF_...) (struct prefix *addr); */
|
||||
@ -219,11 +211,11 @@ int ospf6_lsa_compare (struct ospf6_lsa *, struct ospf6_lsa *);
|
||||
char *ospf6_lsa_printbuf (struct ospf6_lsa *lsa, char *buf, int size);
|
||||
void ospf6_lsa_header_print_raw (struct ospf6_lsa_header *header);
|
||||
void ospf6_lsa_header_print (struct ospf6_lsa *lsa);
|
||||
void ospf6_lsa_show (struct vty *vty, struct ospf6_lsa *lsa);
|
||||
void ospf6_lsa_show_summary_header (struct vty *vty);
|
||||
void ospf6_lsa_show_summary (struct vty *vty, struct ospf6_lsa *lsa);
|
||||
void ospf6_lsa_show_dump (struct vty *vty, struct ospf6_lsa *lsa);
|
||||
void ospf6_lsa_show_internal (struct vty *vty, struct ospf6_lsa *lsa);
|
||||
void ospf6_lsa_show (struct vty *vty, struct ospf6_lsa *lsa);
|
||||
|
||||
struct ospf6_lsa *ospf6_lsa_create (struct ospf6_lsa_header *header);
|
||||
struct ospf6_lsa *ospf6_lsa_create_headeronly (struct ospf6_lsa_header *header);
|
||||
@ -233,8 +225,6 @@ struct ospf6_lsa *ospf6_lsa_copy (struct ospf6_lsa *);
|
||||
void ospf6_lsa_lock (struct ospf6_lsa *);
|
||||
void ospf6_lsa_unlock (struct ospf6_lsa *);
|
||||
|
||||
void ospf6_lsa_originate (struct ospf6_lsa *);
|
||||
void ospf6_lsa_re_originate (struct ospf6_lsa *lsa);
|
||||
int ospf6_lsa_expire (struct thread *);
|
||||
int ospf6_lsa_refresh (struct thread *);
|
||||
|
||||
@ -242,6 +232,7 @@ unsigned short ospf6_lsa_checksum (struct ospf6_lsa_header *);
|
||||
int ospf6_lsa_prohibited_duration (u_int16_t type, u_int32_t id,
|
||||
u_int32_t adv_router, void *scope);
|
||||
|
||||
void ospf6_install_lsa_handler (struct ospf6_lsa_handler *handler);
|
||||
void ospf6_lsa_init ();
|
||||
|
||||
int config_write_ospf6_debug_lsa (struct vty *vty);
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include "ospf6d.h"
|
||||
|
||||
struct ospf6_lsdb *
|
||||
ospf6_lsdb_create ()
|
||||
ospf6_lsdb_create (void *data)
|
||||
{
|
||||
struct ospf6_lsdb *lsdb;
|
||||
|
||||
@ -46,6 +46,7 @@ ospf6_lsdb_create ()
|
||||
}
|
||||
memset (lsdb, 0, sizeof (struct ospf6_lsdb));
|
||||
|
||||
lsdb->data = data;
|
||||
lsdb->table = route_table_init ();
|
||||
return lsdb;
|
||||
}
|
||||
@ -228,6 +229,7 @@ ospf6_lsdb_remove (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb)
|
||||
|
||||
ospf6_lsa_unlock (lsa);
|
||||
route_unlock_node (node);
|
||||
|
||||
ospf6_lsdb_count_assert (lsdb);
|
||||
}
|
||||
|
||||
@ -475,7 +477,7 @@ ospf6_new_ls_id (u_int16_t type, u_int32_t adv_router,
|
||||
if (ntohl (lsa->header->id) < id)
|
||||
continue;
|
||||
if (ntohl (lsa->header->id) > id)
|
||||
return ((u_int32_t) htonl (id));
|
||||
break;
|
||||
id++;
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
struct ospf6_lsdb
|
||||
{
|
||||
void *data; /* data structure that holds this lsdb */
|
||||
struct route_table *table;
|
||||
u_int32_t count;
|
||||
void (*hook_add) (struct ospf6_lsa *);
|
||||
@ -40,7 +41,7 @@ struct ospf6_lsdb
|
||||
{ \
|
||||
if (! OSPF6_LSA_IS_MAXAGE (lsa)) \
|
||||
continue; \
|
||||
if (lsa->onretrans != 0) \
|
||||
if (lsa->retrans_count != 0) \
|
||||
continue; \
|
||||
if (IS_OSPF6_DEBUG_LSA (TIMER)) \
|
||||
zlog_info (" remove maxage %s", lsa->name); \
|
||||
@ -49,7 +50,7 @@ struct ospf6_lsdb
|
||||
} while (0)
|
||||
|
||||
/* Function Prototypes */
|
||||
struct ospf6_lsdb *ospf6_lsdb_create ();
|
||||
struct ospf6_lsdb *ospf6_lsdb_create (void *data);
|
||||
void ospf6_lsdb_delete (struct ospf6_lsdb *lsdb);
|
||||
|
||||
struct ospf6_lsa *ospf6_lsdb_lookup (u_int16_t type, u_int32_t id,
|
||||
|
@ -245,7 +245,7 @@ ospf6_header_examin (struct in6_addr *src, struct in6_addr *dst,
|
||||
/* Area-ID check */
|
||||
if (oh->area_id != oi->area->area_id)
|
||||
{
|
||||
if (oh->area_id == 0)
|
||||
if (oh->area_id == BACKBONE_AREA_ID)
|
||||
{
|
||||
if (IS_OSPF6_DEBUG_MESSAGE (type, RECV))
|
||||
zlog_info ("Message may be via Virtual Link: not supported");
|
||||
@ -519,21 +519,34 @@ ospf6_dbdesc_recv_master (struct ospf6_header *oh,
|
||||
struct ospf6_lsdb *lsdb = NULL;
|
||||
|
||||
his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p);
|
||||
his->scope = ospf6_get_lsa_scope (his->header->type, on);
|
||||
lsdb = ospf6_get_scoped_lsdb (his->header->type, his->scope);
|
||||
if (lsdb == NULL)
|
||||
|
||||
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
|
||||
zlog_info ("%s", his->name);
|
||||
|
||||
switch (OSPF6_LSA_SCOPE (his->header->type))
|
||||
{
|
||||
zlog_warn ("Can't decide scoped LSDB");
|
||||
case OSPF6_SCOPE_LINKLOCAL:
|
||||
lsdb = on->ospf6_if->lsdb;
|
||||
break;
|
||||
case OSPF6_SCOPE_AREA:
|
||||
lsdb = on->ospf6_if->area->lsdb;
|
||||
break;
|
||||
case OSPF6_SCOPE_AS:
|
||||
lsdb = on->ospf6_if->area->ospf6->lsdb;
|
||||
break;
|
||||
case OSPF6_SCOPE_RESERVED:
|
||||
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
|
||||
zlog_info ("Ignoring LSA of reserved scope");
|
||||
ospf6_lsa_delete (his);
|
||||
thread_add_event (master, seqnumber_mismatch, on, 0);
|
||||
return;
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ntohs (his->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
|
||||
ospf6_area_is_stub (on->ospf6_if->area))
|
||||
IS_AREA_STUB (on->ospf6_if->area))
|
||||
{
|
||||
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
|
||||
zlog_info ("E-bit mismatch with LSA Headers");
|
||||
zlog_info ("SeqNumMismatch (E-bit mismatch), discard");
|
||||
ospf6_lsa_delete (his);
|
||||
thread_add_event (master, seqnumber_mismatch, on, 0);
|
||||
return;
|
||||
@ -541,14 +554,24 @@ ospf6_dbdesc_recv_master (struct ospf6_header *oh,
|
||||
|
||||
mine = ospf6_lsdb_lookup (his->header->type, his->header->id,
|
||||
his->header->adv_router, lsdb);
|
||||
if (mine == NULL || ospf6_lsa_compare (his, mine) < 0)
|
||||
if (mine == NULL)
|
||||
{
|
||||
if (IS_OSPF6_DEBUG_LSA (RECV) || IS_OSPF6_DEBUG_LSA (DATABASE))
|
||||
zlog_info ("Add %s's request-list: %s", on->name, his->name);
|
||||
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
|
||||
zlog_info ("Add request (No database copy)", his->name);
|
||||
ospf6_lsdb_add (his, on->request_list);
|
||||
}
|
||||
else if (ospf6_lsa_compare (his, mine) < 0)
|
||||
{
|
||||
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
|
||||
zlog_info ("Add request (Received MoreRecent)", his->name);
|
||||
ospf6_lsdb_add (his, on->request_list);
|
||||
}
|
||||
else
|
||||
ospf6_lsa_delete (his);
|
||||
{
|
||||
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
|
||||
zlog_info ("Discard (Existing MoreRecent)", his->name);
|
||||
ospf6_lsa_delete (his);
|
||||
}
|
||||
}
|
||||
|
||||
if (p != OSPF6_MESSAGE_END (oh))
|
||||
@ -721,18 +744,28 @@ ospf6_dbdesc_recv_slave (struct ospf6_header *oh,
|
||||
struct ospf6_lsdb *lsdb = NULL;
|
||||
|
||||
his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p);
|
||||
his->scope = ospf6_get_lsa_scope (his->header->type, on);
|
||||
lsdb = ospf6_get_scoped_lsdb (his->header->type, his->scope);
|
||||
if (lsdb == NULL)
|
||||
|
||||
switch (OSPF6_LSA_SCOPE (his->header->type))
|
||||
{
|
||||
zlog_warn ("Can't decide scoped LSDB");
|
||||
case OSPF6_SCOPE_LINKLOCAL:
|
||||
lsdb = on->ospf6_if->lsdb;
|
||||
break;
|
||||
case OSPF6_SCOPE_AREA:
|
||||
lsdb = on->ospf6_if->area->lsdb;
|
||||
break;
|
||||
case OSPF6_SCOPE_AS:
|
||||
lsdb = on->ospf6_if->area->ospf6->lsdb;
|
||||
break;
|
||||
case OSPF6_SCOPE_RESERVED:
|
||||
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
|
||||
zlog_info ("Ignoring LSA of reserved scope");
|
||||
ospf6_lsa_delete (his);
|
||||
thread_add_event (master, seqnumber_mismatch, on, 0);
|
||||
return;
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ntohs (his->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
|
||||
ospf6_area_is_stub (on->ospf6_if->area))
|
||||
if (OSPF6_LSA_SCOPE (his->header->type) == OSPF6_SCOPE_AS &&
|
||||
IS_AREA_STUB (on->ospf6_if->area))
|
||||
{
|
||||
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
|
||||
zlog_info ("E-bit mismatch with LSA Headers");
|
||||
@ -745,8 +778,8 @@ ospf6_dbdesc_recv_slave (struct ospf6_header *oh,
|
||||
his->header->adv_router, lsdb);
|
||||
if (mine == NULL || ospf6_lsa_compare (his, mine) < 0)
|
||||
{
|
||||
if (IS_OSPF6_DEBUG_LSA (RECV) || IS_OSPF6_DEBUG_LSA (DATABASE))
|
||||
zlog_info ("Add %s to request-list of %s", his->name, on->name);
|
||||
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
|
||||
zlog_info ("Add request-list: %s", his->name);
|
||||
ospf6_lsdb_add (his, on->request_list);
|
||||
}
|
||||
else
|
||||
@ -838,7 +871,6 @@ ospf6_lsreq_recv (struct in6_addr *src, struct in6_addr *dst,
|
||||
struct ospf6_neighbor *on;
|
||||
char *p;
|
||||
struct ospf6_lsreq_entry *e;
|
||||
void *scope = NULL;
|
||||
struct ospf6_lsdb *lsdb = NULL;
|
||||
struct ospf6_lsa *lsa;
|
||||
|
||||
@ -875,8 +907,24 @@ ospf6_lsreq_recv (struct in6_addr *src, struct in6_addr *dst,
|
||||
p += sizeof (struct ospf6_lsreq_entry))
|
||||
{
|
||||
e = (struct ospf6_lsreq_entry *) p;
|
||||
scope = ospf6_get_lsa_scope (e->type, on);
|
||||
lsdb = ospf6_get_scoped_lsdb (e->type, scope);
|
||||
|
||||
switch (OSPF6_LSA_SCOPE (e->type))
|
||||
{
|
||||
case OSPF6_SCOPE_LINKLOCAL:
|
||||
lsdb = on->ospf6_if->lsdb;
|
||||
break;
|
||||
case OSPF6_SCOPE_AREA:
|
||||
lsdb = on->ospf6_if->area->lsdb;
|
||||
break;
|
||||
case OSPF6_SCOPE_AS:
|
||||
lsdb = on->ospf6_if->area->ospf6->lsdb;
|
||||
break;
|
||||
default:
|
||||
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
|
||||
zlog_info ("Ignoring LSA of reserved scope");
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Find database copy */
|
||||
lsa = ospf6_lsdb_lookup (e->type, e->id, e->adv_router, lsdb);
|
||||
@ -895,9 +943,6 @@ ospf6_lsreq_recv (struct in6_addr *src, struct in6_addr *dst,
|
||||
return;
|
||||
}
|
||||
|
||||
if (IS_OSPF6_DEBUG_LSA (DATABASE))
|
||||
zlog_info ("Add copy of %s to lsupdate_list of %s",
|
||||
lsa->name, on->name);
|
||||
ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->lsupdate_list);
|
||||
}
|
||||
|
||||
@ -969,7 +1014,7 @@ ospf6_lsupdate_recv (struct in6_addr *src, struct in6_addr *dst,
|
||||
break;
|
||||
}
|
||||
|
||||
ospf6_receive_lsa ((struct ospf6_lsa_header *) p, on);
|
||||
ospf6_receive_lsa (on, (struct ospf6_lsa_header *) p);
|
||||
num--;
|
||||
}
|
||||
|
||||
@ -1041,11 +1086,27 @@ ospf6_lsack_recv (struct in6_addr *src, struct in6_addr *dst,
|
||||
p += sizeof (struct ospf6_lsa_header))
|
||||
{
|
||||
his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p);
|
||||
his->scope = ospf6_get_lsa_scope (his->header->type, on);
|
||||
lsdb = ospf6_get_scoped_lsdb (his->header->type, his->scope);
|
||||
|
||||
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV) ||
|
||||
IS_OSPF6_DEBUG_LSA (SEND))
|
||||
switch (OSPF6_LSA_SCOPE (his->header->type))
|
||||
{
|
||||
case OSPF6_SCOPE_LINKLOCAL:
|
||||
lsdb = on->ospf6_if->lsdb;
|
||||
break;
|
||||
case OSPF6_SCOPE_AREA:
|
||||
lsdb = on->ospf6_if->area->lsdb;
|
||||
break;
|
||||
case OSPF6_SCOPE_AS:
|
||||
lsdb = on->ospf6_if->area->ospf6->lsdb;
|
||||
break;
|
||||
case OSPF6_SCOPE_RESERVED:
|
||||
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
|
||||
zlog_info ("Ignoring LSA of reserved scope");
|
||||
ospf6_lsa_delete (his);
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
|
||||
zlog_info ("%s acknowledged by %s", his->name, on->name);
|
||||
|
||||
/* Find database copy */
|
||||
@ -1080,18 +1141,14 @@ ospf6_lsack_recv (struct in6_addr *src, struct in6_addr *dst,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV) ||
|
||||
IS_OSPF6_DEBUG_LSA (SEND))
|
||||
if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
|
||||
zlog_info ("Acknowledged, remove from %s's retrans-list",
|
||||
on->name);
|
||||
|
||||
if (OSPF6_LSA_IS_MAXAGE (mine))
|
||||
ospf6_maxage_remove (on->ospf6_if->area->ospf6);
|
||||
|
||||
if (IS_OSPF6_DEBUG_LSA (DATABASE))
|
||||
zlog_info ("remove %s from retrans_list of %s",
|
||||
mine->name, on->name);
|
||||
ospf6_decrement_onretrans (mine);
|
||||
ospf6_decrement_retrans_count (mine);
|
||||
ospf6_lsdb_remove (mine, on->retrans_list);
|
||||
ospf6_lsa_delete (his);
|
||||
}
|
||||
@ -1473,8 +1530,6 @@ ospf6_dbdesc_send_newone (struct thread *thread)
|
||||
unsigned int size = 0;
|
||||
|
||||
on = (struct ospf6_neighbor *) THREAD_ARG (thread);
|
||||
if (IS_OSPF6_DEBUG_LSA (DATABASE))
|
||||
zlog_info ("Remove entire dbdesc_list of %s: sending newone", on->name);
|
||||
ospf6_lsdb_remove_all (on->dbdesc_list);
|
||||
|
||||
/* move LSAs from summary_list to dbdesc_list (within neighbor structure)
|
||||
@ -1489,9 +1544,6 @@ ospf6_dbdesc_send_newone (struct thread *thread)
|
||||
break;
|
||||
}
|
||||
|
||||
if (IS_OSPF6_DEBUG_LSA (DATABASE))
|
||||
zlog_info ("Move %s from summary_list to dbdesc_list of %s",
|
||||
lsa->name, on->name);
|
||||
ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->dbdesc_list);
|
||||
ospf6_lsdb_remove (lsa, on->summary_list);
|
||||
size += sizeof (struct ospf6_lsa_header);
|
||||
@ -1587,21 +1639,25 @@ ospf6_lsupdate_send_neighbor (struct thread *thread)
|
||||
on = (struct ospf6_neighbor *) THREAD_ARG (thread);
|
||||
on->thread_send_lsupdate = (struct thread *) NULL;
|
||||
|
||||
if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
|
||||
zlog_info ("LSUpdate to neighbor %s", on->name);
|
||||
|
||||
if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
|
||||
{
|
||||
if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
|
||||
zlog_info ("Quit to send LSUpdate to neighbor %s state %s",
|
||||
on->name, ospf6_neighbor_state_str[on->state]);
|
||||
zlog_info ("Quit to send (neighbor state %s)",
|
||||
ospf6_neighbor_state_str[on->state]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if we have nothing to send, return */
|
||||
if (on->lsupdate_list->count == 0 &&
|
||||
on->retrans_list->count == 0)
|
||||
return 0;
|
||||
|
||||
if (IS_OSPF6_DEBUG_LSA (SEND))
|
||||
zlog_info ("LSA Send to %s", on->name);
|
||||
{
|
||||
if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
|
||||
zlog_info ("Quit to send (nothing to send)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset (sendbuf, 0, iobuflen);
|
||||
oh = (struct ospf6_header *) sendbuf;
|
||||
@ -1623,9 +1679,6 @@ ospf6_lsupdate_send_neighbor (struct thread *thread)
|
||||
break;
|
||||
}
|
||||
|
||||
if (IS_OSPF6_DEBUG_LSA (SEND))
|
||||
ospf6_lsa_header_print (lsa);
|
||||
|
||||
ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
|
||||
memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
|
||||
p += OSPF6_LSA_SIZE (lsa->header);
|
||||
@ -1645,9 +1698,6 @@ ospf6_lsupdate_send_neighbor (struct thread *thread)
|
||||
break;
|
||||
}
|
||||
|
||||
if (IS_OSPF6_DEBUG_LSA (SEND))
|
||||
ospf6_lsa_header_print (lsa);
|
||||
|
||||
ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
|
||||
memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
|
||||
p += OSPF6_LSA_SIZE (lsa->header);
|
||||
|
@ -51,7 +51,7 @@ ospf6_neighbor_cmp (void *va, void *vb)
|
||||
{
|
||||
struct ospf6_neighbor *ona = (struct ospf6_neighbor *) va;
|
||||
struct ospf6_neighbor *onb = (struct ospf6_neighbor *) vb;
|
||||
return (ntohl (ona->router_id) - ntohl (onb->router_id));
|
||||
return (ntohl (ona->router_id) < ntohl (onb->router_id) ? -1 : 1);
|
||||
}
|
||||
|
||||
struct ospf6_neighbor *
|
||||
@ -94,14 +94,14 @@ ospf6_neighbor_create (u_int32_t router_id, struct ospf6_interface *oi)
|
||||
gettimeofday (&on->last_changed, (struct timezone *) NULL);
|
||||
on->router_id = router_id;
|
||||
|
||||
on->summary_list = ospf6_lsdb_create ();
|
||||
on->request_list = ospf6_lsdb_create ();
|
||||
on->retrans_list = ospf6_lsdb_create ();
|
||||
on->summary_list = ospf6_lsdb_create (on);
|
||||
on->request_list = ospf6_lsdb_create (on);
|
||||
on->retrans_list = ospf6_lsdb_create (on);
|
||||
|
||||
on->dbdesc_list = ospf6_lsdb_create ();
|
||||
on->lsreq_list = ospf6_lsdb_create ();
|
||||
on->lsupdate_list = ospf6_lsdb_create ();
|
||||
on->lsack_list = ospf6_lsdb_create ();
|
||||
on->dbdesc_list = ospf6_lsdb_create (on);
|
||||
on->lsreq_list = ospf6_lsdb_create (on);
|
||||
on->lsupdate_list = ospf6_lsdb_create (on);
|
||||
on->lsack_list = ospf6_lsdb_create (on);
|
||||
|
||||
listnode_add_sort (oi->neighbor_list, on);
|
||||
return on;
|
||||
@ -117,7 +117,7 @@ ospf6_neighbor_delete (struct ospf6_neighbor *on)
|
||||
for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
|
||||
lsa = ospf6_lsdb_next (lsa))
|
||||
{
|
||||
ospf6_decrement_onretrans (lsa);
|
||||
ospf6_decrement_retrans_count (lsa);
|
||||
ospf6_lsdb_remove (lsa, on->retrans_list);
|
||||
}
|
||||
|
||||
@ -286,7 +286,7 @@ negotiation_done (struct thread *thread)
|
||||
for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
|
||||
lsa = ospf6_lsdb_next (lsa))
|
||||
{
|
||||
ospf6_decrement_onretrans (lsa);
|
||||
ospf6_decrement_retrans_count (lsa);
|
||||
ospf6_lsdb_remove (lsa, on->retrans_list);
|
||||
}
|
||||
|
||||
@ -300,7 +300,7 @@ negotiation_done (struct thread *thread)
|
||||
"summary_list"), on->name);
|
||||
if (OSPF6_LSA_IS_MAXAGE (lsa))
|
||||
{
|
||||
lsa->onretrans++;
|
||||
ospf6_increment_retrans_count (lsa);
|
||||
ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
|
||||
}
|
||||
else
|
||||
@ -317,7 +317,7 @@ negotiation_done (struct thread *thread)
|
||||
"summary_list"), on->name);
|
||||
if (OSPF6_LSA_IS_MAXAGE (lsa))
|
||||
{
|
||||
lsa->onretrans++;
|
||||
ospf6_increment_retrans_count (lsa);
|
||||
ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
|
||||
}
|
||||
else
|
||||
@ -334,7 +334,7 @@ negotiation_done (struct thread *thread)
|
||||
"summary_list"), on->name);
|
||||
if (OSPF6_LSA_IS_MAXAGE (lsa))
|
||||
{
|
||||
lsa->onretrans++;
|
||||
ospf6_increment_retrans_count (lsa);
|
||||
ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
|
||||
}
|
||||
else
|
||||
@ -431,7 +431,7 @@ adj_ok (struct thread *thread)
|
||||
for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
|
||||
lsa = ospf6_lsdb_next (lsa))
|
||||
{
|
||||
ospf6_decrement_onretrans (lsa);
|
||||
ospf6_decrement_retrans_count (lsa);
|
||||
ospf6_lsdb_remove (lsa, on->retrans_list);
|
||||
}
|
||||
}
|
||||
@ -464,7 +464,7 @@ seqnumber_mismatch (struct thread *thread)
|
||||
for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
|
||||
lsa = ospf6_lsdb_next (lsa))
|
||||
{
|
||||
ospf6_decrement_onretrans (lsa);
|
||||
ospf6_decrement_retrans_count (lsa);
|
||||
ospf6_lsdb_remove (lsa, on->retrans_list);
|
||||
}
|
||||
|
||||
@ -500,7 +500,7 @@ bad_lsreq (struct thread *thread)
|
||||
for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
|
||||
lsa = ospf6_lsdb_next (lsa))
|
||||
{
|
||||
ospf6_decrement_onretrans (lsa);
|
||||
ospf6_decrement_retrans_count (lsa);
|
||||
ospf6_lsdb_remove (lsa, on->retrans_list);
|
||||
}
|
||||
|
||||
@ -534,7 +534,7 @@ oneway_received (struct thread *thread)
|
||||
for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
|
||||
lsa = ospf6_lsdb_next (lsa))
|
||||
{
|
||||
ospf6_decrement_onretrans (lsa);
|
||||
ospf6_decrement_retrans_count (lsa);
|
||||
ospf6_lsdb_remove (lsa, on->retrans_list);
|
||||
}
|
||||
|
||||
|
@ -36,12 +36,15 @@ ospf6_prefix_apply_mask (struct ospf6_prefix *op)
|
||||
offset = op->prefix_length % 8;
|
||||
mask = 0xff << (8 - offset);
|
||||
|
||||
if (index >= 16)
|
||||
if (index > 16)
|
||||
{
|
||||
zlog_warn ("Apply mask to ospf6_prefix failed");
|
||||
zlog_warn ("Prefix length too long: %d", op->prefix_length);
|
||||
return;
|
||||
}
|
||||
|
||||
if (index == 16)
|
||||
return;
|
||||
|
||||
pnt[index] &= mask;
|
||||
index ++;
|
||||
|
||||
|
@ -1069,6 +1069,32 @@ ospf6_lsentry_table_show (struct vty *vty, int argc, char **argv,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
ospf6_brouter_show_header (struct vty *vty)
|
||||
{
|
||||
vty_out (vty, "%-15s %-8s %-14s %-10s %-15s%s",
|
||||
"Router-ID", "Rtr-Bits", "Options", "Path-Type", "Area", VNL);
|
||||
}
|
||||
|
||||
void
|
||||
ospf6_brouter_show (struct vty *vty, struct ospf6_route *route)
|
||||
{
|
||||
u_int32_t adv_router;
|
||||
char adv[16], rbits[16], options[16], area[16];
|
||||
|
||||
adv_router = ospf6_linkstate_prefix_adv_router (&route->prefix);
|
||||
inet_ntop (AF_INET, &adv_router, adv, sizeof (adv));
|
||||
ospf6_capability_printbuf (route->path.router_bits, rbits, sizeof (rbits));
|
||||
ospf6_options_printbuf (route->path.options, options, sizeof (options));
|
||||
inet_ntop (AF_INET, &route->path.area_id, area, sizeof (area));
|
||||
|
||||
/* vty_out (vty, "%-15s %-8s %-14s %-10s %-15s%s",
|
||||
"Router-ID", "Rtr-Bits", "Options", "Path-Type", "Area", VNL); */
|
||||
vty_out (vty, "%-15s %-8s %-14s %-10s %-15s%s",
|
||||
adv, rbits, options, OSPF6_PATH_TYPE_NAME (route->path.type),
|
||||
area, VNL);
|
||||
}
|
||||
|
||||
DEFUN (debug_ospf6_route,
|
||||
debug_ospf6_route_cmd,
|
||||
"debug ospf6 route (table|intra-area|inter-area)",
|
||||
|
@ -90,6 +90,7 @@ struct ospf6_path
|
||||
|
||||
/* Path-type */
|
||||
u_char type;
|
||||
u_char subtype; /* only used for redistribute i.e ZEBRA_ROUTE_XXX */
|
||||
|
||||
/* Cost */
|
||||
u_int8_t metric_type;
|
||||
@ -97,12 +98,13 @@ struct ospf6_path
|
||||
u_int32_t cost_e2;
|
||||
};
|
||||
|
||||
#define OSPF6_PATH_TYPE_NONE 0
|
||||
#define OSPF6_PATH_TYPE_INTRA 1
|
||||
#define OSPF6_PATH_TYPE_INTER 2
|
||||
#define OSPF6_PATH_TYPE_EXTERNAL1 3
|
||||
#define OSPF6_PATH_TYPE_EXTERNAL2 4
|
||||
#define OSPF6_PATH_TYPE_MAX 5
|
||||
#define OSPF6_PATH_TYPE_NONE 0
|
||||
#define OSPF6_PATH_TYPE_INTRA 1
|
||||
#define OSPF6_PATH_TYPE_INTER 2
|
||||
#define OSPF6_PATH_TYPE_EXTERNAL1 3
|
||||
#define OSPF6_PATH_TYPE_EXTERNAL2 4
|
||||
#define OSPF6_PATH_TYPE_REDISTRIBUTE 5
|
||||
#define OSPF6_PATH_TYPE_MAX 6
|
||||
|
||||
#include "prefix.h"
|
||||
#include "table.h"
|
||||
@ -147,13 +149,15 @@ struct ospf6_route
|
||||
#define OSPF6_DEST_TYPE_NETWORK 2
|
||||
#define OSPF6_DEST_TYPE_DISCARD 3
|
||||
#define OSPF6_DEST_TYPE_LINKSTATE 4
|
||||
#define OSPF6_DEST_TYPE_MAX 5
|
||||
#define OSPF6_DEST_TYPE_RANGE 5
|
||||
#define OSPF6_DEST_TYPE_MAX 6
|
||||
|
||||
#define OSPF6_ROUTE_CHANGE 0x01
|
||||
#define OSPF6_ROUTE_ADD 0x02
|
||||
#define OSPF6_ROUTE_REMOVE 0x04
|
||||
#define OSPF6_ROUTE_BEST 0x08
|
||||
#define OSPF6_ROUTE_HAVE_LONGER 0x10
|
||||
#define OSPF6_ROUTE_CHANGE 0x01
|
||||
#define OSPF6_ROUTE_ADD 0x02
|
||||
#define OSPF6_ROUTE_REMOVE 0x04
|
||||
#define OSPF6_ROUTE_BEST 0x08
|
||||
#define OSPF6_ROUTE_ACTIVE_SUMMARY 0x08
|
||||
#define OSPF6_ROUTE_DO_NOT_ADVERTISE 0x10
|
||||
|
||||
struct ospf6_route_table
|
||||
{
|
||||
@ -252,11 +256,18 @@ struct ospf6_route_table *ospf6_route_table_create ();
|
||||
void ospf6_route_table_delete (struct ospf6_route_table *);
|
||||
void ospf6_route_dump (struct ospf6_route_table *table);
|
||||
|
||||
|
||||
void ospf6_route_show (struct vty *vty, struct ospf6_route *route);
|
||||
void ospf6_route_show_detail (struct vty *vty, struct ospf6_route *route);
|
||||
|
||||
int ospf6_route_table_show (struct vty *, int, char **,
|
||||
struct ospf6_route_table *);
|
||||
int ospf6_lsentry_table_show (struct vty *, int, char **,
|
||||
struct ospf6_route_table *);
|
||||
|
||||
void ospf6_brouter_show_header (struct vty *vty);
|
||||
void ospf6_brouter_show (struct vty *vty, struct ospf6_route *route);
|
||||
|
||||
int config_write_ospf6_debug_route (struct vty *vty);
|
||||
void install_element_ospf6_debug_route ();
|
||||
void ospf6_route_init ();
|
||||
|
@ -342,8 +342,11 @@ ospf6_spf_install (struct ospf6_vertex *v,
|
||||
|
||||
/* There should be no case where candidate being installed (variable
|
||||
"v") is closer than the one in the SPF tree (variable "route").
|
||||
In the case something's gone wrong with the behavior of
|
||||
In the case something has gone wrong with the behavior of
|
||||
Priority-Queue. */
|
||||
|
||||
/* the case where the route exists already is handled and returned
|
||||
up to here. */
|
||||
assert (route == NULL);
|
||||
|
||||
route = ospf6_route_create ();
|
||||
@ -387,6 +390,8 @@ ospf6_spf_table_finish (struct ospf6_route_table *result_table)
|
||||
}
|
||||
}
|
||||
|
||||
/* RFC2328 16.1. Calculating the shortest-path tree for an area */
|
||||
/* RFC2740 3.8.1. Calculating the shortest path tree for an area */
|
||||
void
|
||||
ospf6_spf_calculation (u_int32_t router_id,
|
||||
struct ospf6_route_table *result_table,
|
||||
@ -415,7 +420,7 @@ ospf6_spf_calculation (u_int32_t router_id,
|
||||
root->area = oa;
|
||||
root->cost = 0;
|
||||
root->hops = 0;
|
||||
root->nexthop[0].ifindex = 0; /* should have been loopbak I/F ... */
|
||||
root->nexthop[0].ifindex = 0; /* loopbak I/F is better ... */
|
||||
inet_pton (AF_INET6, "::1", &root->nexthop[0].address);
|
||||
|
||||
/* Actually insert root to the candidate-list as the only candidate */
|
||||
@ -427,7 +432,7 @@ ospf6_spf_calculation (u_int32_t router_id,
|
||||
/* get closest candidate from priority queue */
|
||||
v = pqueue_dequeue (candidate_list);
|
||||
|
||||
/* install may result in merging and rejecting of the vertex */
|
||||
/* installing may result in merging or rejecting of the vertex */
|
||||
if (ospf6_spf_install (v, result_table) < 0)
|
||||
continue;
|
||||
|
||||
@ -507,7 +512,7 @@ ospf6_spf_calculation_thread (struct thread *t)
|
||||
}
|
||||
|
||||
ospf6_intra_route_calculation (oa);
|
||||
ospf6_intra_asbr_calculation (oa);
|
||||
ospf6_intra_brouter_calculation (oa);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -42,8 +42,10 @@
|
||||
#include "ospf6_interface.h"
|
||||
#include "ospf6_neighbor.h"
|
||||
|
||||
#include "ospf6_flood.h"
|
||||
#include "ospf6_asbr.h"
|
||||
#include "ospf6_abr.h"
|
||||
#include "ospf6_intra.h"
|
||||
#include "ospf6d.h"
|
||||
|
||||
/* global ospf6d variable */
|
||||
@ -84,17 +86,31 @@ ospf6_top_lsdb_hook_remove (struct ospf6_lsa *lsa)
|
||||
void
|
||||
ospf6_top_route_hook_add (struct ospf6_route *route)
|
||||
{
|
||||
ospf6_abr_originate_prefix (route, ospf6);
|
||||
ospf6_abr_originate_summary (route);
|
||||
ospf6_zebra_route_update_add (route);
|
||||
}
|
||||
|
||||
void
|
||||
ospf6_top_route_hook_remove (struct ospf6_route *route)
|
||||
{
|
||||
ospf6_abr_originate_prefix (route, ospf6);
|
||||
ospf6_abr_originate_summary (route);
|
||||
ospf6_zebra_route_update_remove (route);
|
||||
}
|
||||
|
||||
void
|
||||
ospf6_top_brouter_hook_add (struct ospf6_route *route)
|
||||
{
|
||||
ospf6_abr_originate_summary (route);
|
||||
ospf6_asbr_lsentry_add (route);
|
||||
}
|
||||
|
||||
void
|
||||
ospf6_top_brouter_hook_remove (struct ospf6_route *route)
|
||||
{
|
||||
ospf6_abr_originate_summary (route);
|
||||
ospf6_asbr_lsentry_remove (route);
|
||||
}
|
||||
|
||||
struct ospf6 *
|
||||
ospf6_create ()
|
||||
{
|
||||
@ -107,7 +123,8 @@ ospf6_create ()
|
||||
gettimeofday (&o->starttime, (struct timezone *) NULL);
|
||||
o->area_list = list_new ();
|
||||
o->area_list->cmp = ospf6_area_cmp;
|
||||
o->lsdb = ospf6_lsdb_create ();
|
||||
o->lsdb = ospf6_lsdb_create (o);
|
||||
o->lsdb_self = ospf6_lsdb_create (o);
|
||||
o->lsdb->hook_add = ospf6_top_lsdb_hook_add;
|
||||
o->lsdb->hook_remove = ospf6_top_lsdb_hook_remove;
|
||||
|
||||
@ -115,11 +132,9 @@ ospf6_create ()
|
||||
o->route_table->hook_add = ospf6_top_route_hook_add;
|
||||
o->route_table->hook_remove = ospf6_top_route_hook_remove;
|
||||
|
||||
o->asbr_table = ospf6_route_table_create ();
|
||||
o->asbr_table->hook_add = ospf6_asbr_lsentry_add;
|
||||
o->asbr_table->hook_remove = ospf6_asbr_lsentry_remove;
|
||||
|
||||
o->brouter_table = ospf6_route_table_create ();
|
||||
o->brouter_table->hook_add = ospf6_top_brouter_hook_add;
|
||||
o->brouter_table->hook_remove = ospf6_top_brouter_hook_remove;
|
||||
|
||||
o->external_table = ospf6_route_table_create ();
|
||||
o->external_id_table = route_table_init ();
|
||||
@ -140,9 +155,9 @@ ospf6_delete (struct ospf6 *o)
|
||||
}
|
||||
|
||||
ospf6_lsdb_delete (o->lsdb);
|
||||
ospf6_lsdb_delete (o->lsdb_self);
|
||||
|
||||
ospf6_route_table_delete (o->route_table);
|
||||
ospf6_route_table_delete (o->asbr_table);
|
||||
ospf6_route_table_delete (o->brouter_table);
|
||||
|
||||
ospf6_route_table_delete (o->external_table);
|
||||
@ -185,7 +200,7 @@ ospf6_disable (struct ospf6 *o)
|
||||
|
||||
ospf6_lsdb_remove_all (o->lsdb);
|
||||
ospf6_route_remove_all (o->route_table);
|
||||
ospf6_route_remove_all (o->asbr_table);
|
||||
ospf6_route_remove_all (o->brouter_table);
|
||||
}
|
||||
}
|
||||
|
||||
@ -320,10 +335,12 @@ DEFUN (ospf6_interface_area,
|
||||
)
|
||||
{
|
||||
struct ospf6 *o;
|
||||
struct ospf6_area *oa;
|
||||
struct ospf6_area *oa, *area;
|
||||
struct ospf6_interface *oi;
|
||||
struct interface *ifp;
|
||||
u_int32_t area_id;
|
||||
listnode node;
|
||||
struct ospf6_route *ro;
|
||||
|
||||
o = (struct ospf6 *) vty->index;
|
||||
|
||||
@ -355,8 +372,31 @@ DEFUN (ospf6_interface_area,
|
||||
listnode_add (oa->if_list, oi); /* sort ?? */
|
||||
oi->area = oa;
|
||||
|
||||
SET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
|
||||
|
||||
/* start up */
|
||||
thread_add_event (master, interface_up, oi, 0);
|
||||
|
||||
/* ABR stuff, redistribute inter-area LSAs and
|
||||
re-originate Router-LSA (B-bit may have been changed) */
|
||||
for (node = listhead (o->area_list); node; nextnode (node))
|
||||
{
|
||||
area = OSPF6_AREA (getdata (node));
|
||||
OSPF6_ROUTER_LSA_SCHEDULE (area);
|
||||
|
||||
for (ro = ospf6_route_head (area->range_table); ro;
|
||||
ro = ospf6_route_next (ro))
|
||||
ospf6_abr_originate_summary_to_area (ro, oa);
|
||||
}
|
||||
|
||||
for (ro = ospf6_route_head (o->brouter_table); ro;
|
||||
ro = ospf6_route_next (ro))
|
||||
ospf6_abr_originate_summary_to_area (ro, oa);
|
||||
|
||||
for (ro = ospf6_route_head (o->route_table); ro;
|
||||
ro = ospf6_route_next (ro))
|
||||
ospf6_abr_originate_summary_to_area (ro, oa);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
@ -372,8 +412,12 @@ DEFUN (no_ospf6_interface_area,
|
||||
{
|
||||
struct ospf6 *o;
|
||||
struct ospf6_interface *oi;
|
||||
struct ospf6_area *oa, *area;
|
||||
struct interface *ifp;
|
||||
u_int32_t area_id;
|
||||
listnode node;
|
||||
struct ospf6_route *ro;
|
||||
struct ospf6_lsa *old;
|
||||
|
||||
o = (struct ospf6 *) vty->index;
|
||||
|
||||
@ -407,9 +451,45 @@ DEFUN (no_ospf6_interface_area,
|
||||
|
||||
thread_execute (master, interface_down, oi, 0);
|
||||
|
||||
oa = oi->area;
|
||||
listnode_delete (oi->area->if_list, oi);
|
||||
oi->area = (struct ospf6_area *) NULL;
|
||||
|
||||
/* Withdraw inter-area routes from this area, if necessary */
|
||||
if (oa->if_list->count == 0)
|
||||
{
|
||||
UNSET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
|
||||
|
||||
for (ro = ospf6_route_head (oa->summary_prefix); ro;
|
||||
ro = ospf6_route_next (ro))
|
||||
{
|
||||
old = ospf6_lsdb_lookup (ro->path.origin.type,
|
||||
ro->path.origin.id,
|
||||
oa->ospf6->router_id, oa->lsdb);
|
||||
if (old)
|
||||
ospf6_lsa_purge (old);
|
||||
ospf6_route_remove (ro, oa->summary_prefix);
|
||||
}
|
||||
for (ro = ospf6_route_head (oa->summary_router); ro;
|
||||
ro = ospf6_route_next (ro))
|
||||
{
|
||||
old = ospf6_lsdb_lookup (ro->path.origin.type,
|
||||
ro->path.origin.id,
|
||||
oa->ospf6->router_id, oa->lsdb);
|
||||
if (old)
|
||||
ospf6_lsa_purge (old);
|
||||
ospf6_route_remove (ro, oa->summary_router);
|
||||
}
|
||||
}
|
||||
|
||||
/* Schedule Refreshment of Router-LSA for each area
|
||||
(ABR status may change) */
|
||||
for (node = listhead (o->area_list); node; nextnode (node))
|
||||
{
|
||||
area = OSPF6_AREA (getdata (node));
|
||||
OSPF6_ROUTER_LSA_SCHEDULE (area);
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
@ -562,6 +642,7 @@ config_write_ospf6 (struct vty *vty)
|
||||
vty_out (vty, " router-id %s%s", router_id, VNL);
|
||||
|
||||
ospf6_redistribute_config_write (vty);
|
||||
ospf6_area_config_write (vty);
|
||||
|
||||
for (j = listhead (ospf6->area_list); j; nextnode (j))
|
||||
{
|
||||
|
@ -38,9 +38,9 @@ struct ospf6
|
||||
|
||||
/* AS scope link state database */
|
||||
struct ospf6_lsdb *lsdb;
|
||||
struct ospf6_lsdb *lsdb_self;
|
||||
|
||||
struct ospf6_route_table *route_table;
|
||||
struct ospf6_route_table *asbr_table;
|
||||
struct ospf6_route_table *brouter_table;
|
||||
|
||||
struct ospf6_route_table *external_table;
|
||||
|
131
ospf6d/ospf6d.c
131
ospf6d/ospf6d.c
@ -140,7 +140,8 @@ route_prev (struct route_node *node)
|
||||
return prev;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* show database functions */
|
||||
DEFUN (show_version_ospf6,
|
||||
show_version_ospf6_cmd,
|
||||
"show version ospf6",
|
||||
@ -186,7 +187,7 @@ config_write_ospf6_debug (struct vty *vty)
|
||||
static int
|
||||
parse_show_level (int argc, char **argv)
|
||||
{
|
||||
int level;
|
||||
int level = 0;
|
||||
if (argc)
|
||||
{
|
||||
if (! strncmp (argv[0], "de", 2))
|
||||
@ -204,7 +205,7 @@ parse_show_level (int argc, char **argv)
|
||||
static u_int16_t
|
||||
parse_type_spec (int argc, char **argv)
|
||||
{
|
||||
u_int16_t type;
|
||||
u_int16_t type = 0;
|
||||
assert (argc);
|
||||
if (! strcmp (argv[0], "router"))
|
||||
type = htons (OSPF6_LSTYPE_ROUTER);
|
||||
@ -316,7 +317,7 @@ DEFUN (show_ipv6_ospf6_database_type,
|
||||
|
||||
switch (OSPF6_LSA_SCOPE (type))
|
||||
{
|
||||
case OSPF6_LSA_SCOPE_AREA:
|
||||
case OSPF6_SCOPE_AREA:
|
||||
for (i = listhead (o->area_list); i; nextnode (i))
|
||||
{
|
||||
oa = (struct ospf6_area *) getdata (i);
|
||||
@ -325,7 +326,7 @@ DEFUN (show_ipv6_ospf6_database_type,
|
||||
}
|
||||
break;
|
||||
|
||||
case OSPF6_LSA_SCOPE_LINKLOCAL:
|
||||
case OSPF6_SCOPE_LINKLOCAL:
|
||||
for (i = listhead (o->area_list); i; nextnode (i))
|
||||
{
|
||||
oa = (struct ospf6_area *) getdata (i);
|
||||
@ -339,7 +340,7 @@ DEFUN (show_ipv6_ospf6_database_type,
|
||||
}
|
||||
break;
|
||||
|
||||
case OSPF6_LSA_SCOPE_AS:
|
||||
case OSPF6_SCOPE_AS:
|
||||
vty_out (vty, AS_LSDB_TITLE_FORMAT, VNL, VNL, VNL);
|
||||
ospf6_lsdb_show (vty, level, &type, NULL, NULL, o->lsdb);
|
||||
break;
|
||||
@ -623,7 +624,7 @@ DEFUN (show_ipv6_ospf6_database_type_id,
|
||||
|
||||
switch (OSPF6_LSA_SCOPE (type))
|
||||
{
|
||||
case OSPF6_LSA_SCOPE_AREA:
|
||||
case OSPF6_SCOPE_AREA:
|
||||
for (i = listhead (o->area_list); i; nextnode (i))
|
||||
{
|
||||
oa = (struct ospf6_area *) getdata (i);
|
||||
@ -632,7 +633,7 @@ DEFUN (show_ipv6_ospf6_database_type_id,
|
||||
}
|
||||
break;
|
||||
|
||||
case OSPF6_LSA_SCOPE_LINKLOCAL:
|
||||
case OSPF6_SCOPE_LINKLOCAL:
|
||||
for (i = listhead (o->area_list); i; nextnode (i))
|
||||
{
|
||||
oa = (struct ospf6_area *) getdata (i);
|
||||
@ -646,7 +647,7 @@ DEFUN (show_ipv6_ospf6_database_type_id,
|
||||
}
|
||||
break;
|
||||
|
||||
case OSPF6_LSA_SCOPE_AS:
|
||||
case OSPF6_SCOPE_AS:
|
||||
vty_out (vty, AS_LSDB_TITLE_FORMAT, VNL, VNL, VNL);
|
||||
ospf6_lsdb_show (vty, level, &type, &id, NULL, o->lsdb);
|
||||
break;
|
||||
@ -782,7 +783,7 @@ DEFUN (show_ipv6_ospf6_database_type_router,
|
||||
|
||||
switch (OSPF6_LSA_SCOPE (type))
|
||||
{
|
||||
case OSPF6_LSA_SCOPE_AREA:
|
||||
case OSPF6_SCOPE_AREA:
|
||||
for (i = listhead (o->area_list); i; nextnode (i))
|
||||
{
|
||||
oa = (struct ospf6_area *) getdata (i);
|
||||
@ -791,7 +792,7 @@ DEFUN (show_ipv6_ospf6_database_type_router,
|
||||
}
|
||||
break;
|
||||
|
||||
case OSPF6_LSA_SCOPE_LINKLOCAL:
|
||||
case OSPF6_SCOPE_LINKLOCAL:
|
||||
for (i = listhead (o->area_list); i; nextnode (i))
|
||||
{
|
||||
oa = (struct ospf6_area *) getdata (i);
|
||||
@ -805,7 +806,7 @@ DEFUN (show_ipv6_ospf6_database_type_router,
|
||||
}
|
||||
break;
|
||||
|
||||
case OSPF6_LSA_SCOPE_AS:
|
||||
case OSPF6_SCOPE_AS:
|
||||
vty_out (vty, AS_LSDB_TITLE_FORMAT, VNL, VNL, VNL);
|
||||
ospf6_lsdb_show (vty, level, &type, NULL, &adv_router, o->lsdb);
|
||||
break;
|
||||
@ -918,7 +919,7 @@ DEFUN (show_ipv6_ospf6_database_id_router,
|
||||
if ((inet_pton (AF_INET, argv[0], &id)) != 1)
|
||||
{
|
||||
vty_out (vty, "Link state ID is not parsable: %s%s",
|
||||
argv[1], VNL);
|
||||
argv[0], VNL);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1014,7 +1015,7 @@ DEFUN (show_ipv6_ospf6_database_adv_router_linkstate_id,
|
||||
if ((inet_pton (AF_INET, argv[0], &id)) != 1)
|
||||
{
|
||||
vty_out (vty, "Link state ID is not parsable: %s%s",
|
||||
argv[1], VNL);
|
||||
argv[0], VNL);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1125,7 +1126,7 @@ DEFUN (show_ipv6_ospf6_database_type_id_router,
|
||||
|
||||
switch (OSPF6_LSA_SCOPE (type))
|
||||
{
|
||||
case OSPF6_LSA_SCOPE_AREA:
|
||||
case OSPF6_SCOPE_AREA:
|
||||
for (i = listhead (o->area_list); i; nextnode (i))
|
||||
{
|
||||
oa = (struct ospf6_area *) getdata (i);
|
||||
@ -1134,7 +1135,7 @@ DEFUN (show_ipv6_ospf6_database_type_id_router,
|
||||
}
|
||||
break;
|
||||
|
||||
case OSPF6_LSA_SCOPE_LINKLOCAL:
|
||||
case OSPF6_SCOPE_LINKLOCAL:
|
||||
for (i = listhead (o->area_list); i; nextnode (i))
|
||||
{
|
||||
oa = (struct ospf6_area *) getdata (i);
|
||||
@ -1148,7 +1149,7 @@ DEFUN (show_ipv6_ospf6_database_type_id_router,
|
||||
}
|
||||
break;
|
||||
|
||||
case OSPF6_LSA_SCOPE_AS:
|
||||
case OSPF6_SCOPE_AS:
|
||||
vty_out (vty, AS_LSDB_TITLE_FORMAT, VNL, VNL, VNL);
|
||||
ospf6_lsdb_show (vty, level, &type, &id, &adv_router, o->lsdb);
|
||||
break;
|
||||
@ -1250,7 +1251,7 @@ DEFUN (show_ipv6_ospf6_database_type_adv_router_linkstate_id,
|
||||
|
||||
switch (OSPF6_LSA_SCOPE (type))
|
||||
{
|
||||
case OSPF6_LSA_SCOPE_AREA:
|
||||
case OSPF6_SCOPE_AREA:
|
||||
for (i = listhead (o->area_list); i; nextnode (i))
|
||||
{
|
||||
oa = (struct ospf6_area *) getdata (i);
|
||||
@ -1259,7 +1260,7 @@ DEFUN (show_ipv6_ospf6_database_type_adv_router_linkstate_id,
|
||||
}
|
||||
break;
|
||||
|
||||
case OSPF6_LSA_SCOPE_LINKLOCAL:
|
||||
case OSPF6_SCOPE_LINKLOCAL:
|
||||
for (i = listhead (o->area_list); i; nextnode (i))
|
||||
{
|
||||
oa = (struct ospf6_area *) getdata (i);
|
||||
@ -1273,7 +1274,7 @@ DEFUN (show_ipv6_ospf6_database_type_adv_router_linkstate_id,
|
||||
}
|
||||
break;
|
||||
|
||||
case OSPF6_LSA_SCOPE_AS:
|
||||
case OSPF6_SCOPE_AS:
|
||||
vty_out (vty, AS_LSDB_TITLE_FORMAT, VNL, VNL, VNL);
|
||||
ospf6_lsdb_show (vty, level, &type, &id, &adv_router, o->lsdb);
|
||||
break;
|
||||
@ -1416,7 +1417,7 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated,
|
||||
|
||||
switch (OSPF6_LSA_SCOPE (type))
|
||||
{
|
||||
case OSPF6_LSA_SCOPE_AREA:
|
||||
case OSPF6_SCOPE_AREA:
|
||||
for (i = listhead (o->area_list); i; nextnode (i))
|
||||
{
|
||||
oa = (struct ospf6_area *) getdata (i);
|
||||
@ -1425,7 +1426,7 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated,
|
||||
}
|
||||
break;
|
||||
|
||||
case OSPF6_LSA_SCOPE_LINKLOCAL:
|
||||
case OSPF6_SCOPE_LINKLOCAL:
|
||||
for (i = listhead (o->area_list); i; nextnode (i))
|
||||
{
|
||||
oa = (struct ospf6_area *) getdata (i);
|
||||
@ -1439,7 +1440,7 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated,
|
||||
}
|
||||
break;
|
||||
|
||||
case OSPF6_LSA_SCOPE_AS:
|
||||
case OSPF6_SCOPE_AS:
|
||||
vty_out (vty, AS_LSDB_TITLE_FORMAT, VNL, VNL, VNL);
|
||||
ospf6_lsdb_show (vty, level, &type, NULL, &adv_router, o->lsdb);
|
||||
break;
|
||||
@ -1517,7 +1518,7 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated_linkstate_id,
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
if ((inet_pton (AF_INET, argv[1], &id)) != 1)
|
||||
if ((inet_pton (AF_INET, argv[0], &id)) != 1)
|
||||
{
|
||||
vty_out (vty, "Link State ID is not parsable: %s%s",
|
||||
argv[0], VNL);
|
||||
@ -1532,7 +1533,7 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated_linkstate_id,
|
||||
|
||||
switch (OSPF6_LSA_SCOPE (type))
|
||||
{
|
||||
case OSPF6_LSA_SCOPE_AREA:
|
||||
case OSPF6_SCOPE_AREA:
|
||||
for (i = listhead (o->area_list); i; nextnode (i))
|
||||
{
|
||||
oa = (struct ospf6_area *) getdata (i);
|
||||
@ -1541,7 +1542,7 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated_linkstate_id,
|
||||
}
|
||||
break;
|
||||
|
||||
case OSPF6_LSA_SCOPE_LINKLOCAL:
|
||||
case OSPF6_SCOPE_LINKLOCAL:
|
||||
for (i = listhead (o->area_list); i; nextnode (i))
|
||||
{
|
||||
oa = (struct ospf6_area *) getdata (i);
|
||||
@ -1555,7 +1556,7 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated_linkstate_id,
|
||||
}
|
||||
break;
|
||||
|
||||
case OSPF6_LSA_SCOPE_AS:
|
||||
case OSPF6_SCOPE_AS:
|
||||
vty_out (vty, AS_LSDB_TITLE_FORMAT, VNL, VNL, VNL);
|
||||
ospf6_lsdb_show (vty, level, &type, &id, &adv_router, o->lsdb);
|
||||
break;
|
||||
@ -1633,7 +1634,7 @@ DEFUN (show_ipv6_ospf6_database_type_id_self_originated,
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
if ((inet_pton (AF_INET, argv[1], &id)) != 1)
|
||||
if ((inet_pton (AF_INET, argv[0], &id)) != 1)
|
||||
{
|
||||
vty_out (vty, "Link State ID is not parsable: %s%s",
|
||||
argv[0], VNL);
|
||||
@ -1648,7 +1649,7 @@ DEFUN (show_ipv6_ospf6_database_type_id_self_originated,
|
||||
|
||||
switch (OSPF6_LSA_SCOPE (type))
|
||||
{
|
||||
case OSPF6_LSA_SCOPE_AREA:
|
||||
case OSPF6_SCOPE_AREA:
|
||||
for (i = listhead (o->area_list); i; nextnode (i))
|
||||
{
|
||||
oa = (struct ospf6_area *) getdata (i);
|
||||
@ -1657,7 +1658,7 @@ DEFUN (show_ipv6_ospf6_database_type_id_self_originated,
|
||||
}
|
||||
break;
|
||||
|
||||
case OSPF6_LSA_SCOPE_LINKLOCAL:
|
||||
case OSPF6_SCOPE_LINKLOCAL:
|
||||
for (i = listhead (o->area_list); i; nextnode (i))
|
||||
{
|
||||
oa = (struct ospf6_area *) getdata (i);
|
||||
@ -1671,7 +1672,7 @@ DEFUN (show_ipv6_ospf6_database_type_id_self_originated,
|
||||
}
|
||||
break;
|
||||
|
||||
case OSPF6_LSA_SCOPE_AS:
|
||||
case OSPF6_SCOPE_AS:
|
||||
vty_out (vty, AS_LSDB_TITLE_FORMAT, VNL, VNL, VNL);
|
||||
ospf6_lsdb_show (vty, level, &type, &id, &adv_router, o->lsdb);
|
||||
break;
|
||||
@ -1712,6 +1713,68 @@ ALIAS (show_ipv6_ospf6_database_type_id_self_originated,
|
||||
"Display LSA's internal information\n"
|
||||
);
|
||||
|
||||
|
||||
DEFUN (show_ipv6_ospf6_border_routers,
|
||||
show_ipv6_ospf6_border_routers_cmd,
|
||||
"show ipv6 ospf6 border-routers",
|
||||
SHOW_STR
|
||||
IP6_STR
|
||||
OSPF6_STR
|
||||
"Display routing table for ABR and ASBR\n"
|
||||
)
|
||||
{
|
||||
u_int32_t adv_router;
|
||||
void (*showfunc) (struct vty *, struct ospf6_route *);
|
||||
struct ospf6_route *ro;
|
||||
struct prefix prefix;
|
||||
|
||||
OSPF6_CMD_CHECK_RUNNING ();
|
||||
|
||||
if (argc && ! strcmp ("detail", argv[0]))
|
||||
{
|
||||
showfunc = ospf6_route_show_detail;
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
else
|
||||
showfunc = ospf6_brouter_show;
|
||||
|
||||
if (argc)
|
||||
{
|
||||
if ((inet_pton (AF_INET, argv[0], &adv_router)) != 1)
|
||||
{
|
||||
vty_out (vty, "Router ID is not parsable: %s%s", argv[0], VNL);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
ospf6_linkstate_prefix (adv_router, 0, &prefix);
|
||||
ro = ospf6_route_lookup (&prefix, ospf6->brouter_table);
|
||||
ospf6_route_show_detail (vty, ro);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
if (showfunc == ospf6_brouter_show)
|
||||
ospf6_brouter_show_header (vty);
|
||||
|
||||
for (ro = ospf6_route_head (ospf6->brouter_table); ro;
|
||||
ro = ospf6_route_next (ro))
|
||||
(*showfunc) (vty, ro);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
ALIAS (show_ipv6_ospf6_border_routers,
|
||||
show_ipv6_ospf6_border_routers_detail_cmd,
|
||||
"show ipv6 ospf6 border-routers (A.B.C.D|detail)",
|
||||
SHOW_STR
|
||||
IP6_STR
|
||||
OSPF6_STR
|
||||
"Display routing table for ABR and ASBR\n"
|
||||
"Specify Router-ID\n"
|
||||
"Display Detail\n"
|
||||
);
|
||||
|
||||
|
||||
/* Install ospf related commands. */
|
||||
void
|
||||
ospf6_init ()
|
||||
@ -1726,10 +1789,16 @@ ospf6_init ()
|
||||
install_element_ospf6_debug_spf ();
|
||||
install_element_ospf6_debug_route ();
|
||||
install_element_ospf6_debug_asbr ();
|
||||
install_element_ospf6_debug_abr ();
|
||||
|
||||
install_element (VIEW_NODE, &show_version_ospf6_cmd);
|
||||
install_element (ENABLE_NODE, &show_version_ospf6_cmd);
|
||||
|
||||
install_element (VIEW_NODE, &show_ipv6_ospf6_border_routers_cmd);
|
||||
install_element (VIEW_NODE, &show_ipv6_ospf6_border_routers_detail_cmd);
|
||||
install_element (ENABLE_NODE, &show_ipv6_ospf6_border_routers_cmd);
|
||||
install_element (ENABLE_NODE, &show_ipv6_ospf6_border_routers_detail_cmd);
|
||||
|
||||
#define INSTALL(n,c) \
|
||||
install_element (n ## _NODE, &show_ipv6_ospf6_ ## c);
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
#ifndef OSPF6D_H
|
||||
#define OSPF6D_H
|
||||
|
||||
#define OSPF6_DAEMON_VERSION "0.9.7e"
|
||||
#define OSPF6_DAEMON_VERSION "0.9.7i"
|
||||
|
||||
/* global variables */
|
||||
extern int errno;
|
||||
@ -50,6 +50,12 @@ extern struct thread_master *master;
|
||||
#endif /* IPV6_DROP_MEMBERSHIP */
|
||||
#endif /* ! IPV6_LEAVE_GROUP */
|
||||
|
||||
/* cast macro */
|
||||
#define OSPF6_PROCESS(x) ((struct ospf6 *) (x))
|
||||
#define OSPF6_AREA(x) ((struct ospf6_area *) (x))
|
||||
#define OSPF6_INTERFACE(x) ((struct ospf6_interface *) (x))
|
||||
#define OSPF6_NEIGHBOR(x) ((struct ospf6_neighbor *) (x))
|
||||
|
||||
/* operation on timeval structure */
|
||||
#ifndef timerclear
|
||||
#define timerclear(a) (a)->tv_sec = (tvp)->tv_usec = 0
|
||||
|
Loading…
Reference in New Issue
Block a user