SVN revisions 916-920 from Zebra. ABR support is almost done.

This commit is contained in:
hasso 2004-08-15 05:52:07 +00:00
parent f841e02e16
commit 6452df092b
26 changed files with 1732 additions and 1218 deletions

View File

@ -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.

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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 */

View File

@ -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

View File

@ -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 */

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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 ();

View File

@ -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);
}

View File

@ -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);

View File

@ -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++;
}

View File

@ -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,

View File

@ -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);

View File

@ -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);
}

View File

@ -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 ++;

View File

@ -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)",

View File

@ -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 ();

View File

@ -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;
}

View File

@ -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))
{

View File

@ -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;

View File

@ -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);

View File

@ -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