diff options
author | whitespace / reindent <invalid@invalid.invalid> | 2017-07-17 14:03:14 +0200 |
---|---|---|
committer | whitespace / reindent <invalid@invalid.invalid> | 2017-07-17 14:04:07 +0200 |
commit | d62a17aedeb0eebdba98238874bb13d62c48dbf9 (patch) | |
tree | 3b319b1d61c8b85b4d1f06adf8b844bb8a9b5107 /ospf6d | |
parent | *: add indent control files (diff) | |
download | frr-d62a17aedeb0eebdba98238874bb13d62c48dbf9.tar.xz frr-d62a17aedeb0eebdba98238874bb13d62c48dbf9.zip |
*: reindentreindent-master-after
indent.py `git ls-files | pcregrep '\.[ch]$' | pcregrep -v '^(ldpd|babeld|nhrpd)/'`
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'ospf6d')
39 files changed, 17046 insertions, 17856 deletions
diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c index 2e195d0af..f198ac4af 100644 --- a/ospf6d/ospf6_abr.c +++ b/ospf6d/ospf6_abr.c @@ -51,1068 +51,1034 @@ unsigned char conf_debug_ospf6_abr; -int -ospf6_is_router_abr (struct ospf6 *o) +int ospf6_is_router_abr(struct ospf6 *o) { - struct listnode *node; - struct ospf6_area *oa; - int area_count = 0; + struct listnode *node; + struct ospf6_area *oa; + int area_count = 0; - for (ALL_LIST_ELEMENTS_RO (o->area_list, node, oa)) - if (IS_AREA_ENABLED (oa)) - area_count++; + for (ALL_LIST_ELEMENTS_RO(o->area_list, node, oa)) + if (IS_AREA_ENABLED(oa)) + area_count++; - if (area_count > 1) - return 1; - return 0; + if (area_count > 1) + return 1; + return 0; } -static int -ospf6_abr_nexthops_belong_to_area (struct ospf6_route *route, - struct ospf6_area *area) +static int ospf6_abr_nexthops_belong_to_area(struct ospf6_route *route, + struct ospf6_area *area) { - struct ospf6_interface *oi; - - oi = ospf6_interface_lookup_by_ifindex (ospf6_route_get_first_nh_index(route)); - if (oi && oi->area && oi->area == area) - return 1; - else - return 0; + struct ospf6_interface *oi; + + oi = ospf6_interface_lookup_by_ifindex( + ospf6_route_get_first_nh_index(route)); + if (oi && oi->area && oi->area == area) + return 1; + else + return 0; } -static void -ospf6_abr_delete_route (struct ospf6_route *range, struct ospf6_route *summary, - struct ospf6_route_table *summary_table, - struct ospf6_lsa *old) +static void ospf6_abr_delete_route(struct ospf6_route *range, + struct ospf6_route *summary, + struct ospf6_route_table *summary_table, + struct ospf6_lsa *old) { - if (summary) - { - ospf6_route_remove (summary, summary_table); - } + if (summary) { + ospf6_route_remove(summary, summary_table); + } - if (old && !OSPF6_LSA_IS_MAXAGE (old)) - ospf6_lsa_purge (old); + if (old && !OSPF6_LSA_IS_MAXAGE(old)) + ospf6_lsa_purge(old); } -void -ospf6_abr_enable_area (struct ospf6_area *area) +void ospf6_abr_enable_area(struct ospf6_area *area) { - struct ospf6_area *oa; - struct listnode *node, *nnode; + struct ospf6_area *oa; + struct listnode *node, *nnode; - for (ALL_LIST_ELEMENTS (area->ospf6->area_list, node, nnode, oa)) - /* update B bit for each area */ - OSPF6_ROUTER_LSA_SCHEDULE (oa); + for (ALL_LIST_ELEMENTS(area->ospf6->area_list, node, nnode, oa)) + /* update B bit for each area */ + OSPF6_ROUTER_LSA_SCHEDULE(oa); } -void -ospf6_abr_disable_area (struct ospf6_area *area) +void ospf6_abr_disable_area(struct ospf6_area *area) { - struct ospf6_area *oa; - struct ospf6_route *ro, *nro; - struct ospf6_lsa *old; - struct listnode *node, *nnode; - - /* Withdraw all summary prefixes previously originated */ - for (ro = ospf6_route_head (area->summary_prefix); ro; ro = nro) - { - nro = ospf6_route_next (ro); - old = ospf6_lsdb_lookup (ro->path.origin.type, ro->path.origin.id, - area->ospf6->router_id, area->lsdb); - if (old) - ospf6_lsa_purge (old); - ospf6_route_remove (ro, area->summary_prefix); - } - - /* Withdraw all summary router-routes previously originated */ - for (ro = ospf6_route_head (area->summary_router); ro; ro = nro) - { - nro = ospf6_route_next (ro); - old = ospf6_lsdb_lookup (ro->path.origin.type, ro->path.origin.id, - area->ospf6->router_id, area->lsdb); - if (old) - ospf6_lsa_purge (old); - ospf6_route_remove (ro, area->summary_router); - } - - /* Schedule Router-LSA for each area (ABR status may change) */ - for (ALL_LIST_ELEMENTS (area->ospf6->area_list, node, nnode, oa)) - /* update B bit for each area */ - OSPF6_ROUTER_LSA_SCHEDULE (oa); + struct ospf6_area *oa; + struct ospf6_route *ro, *nro; + struct ospf6_lsa *old; + struct listnode *node, *nnode; + + /* Withdraw all summary prefixes previously originated */ + for (ro = ospf6_route_head(area->summary_prefix); ro; ro = nro) { + nro = ospf6_route_next(ro); + old = ospf6_lsdb_lookup(ro->path.origin.type, + ro->path.origin.id, + area->ospf6->router_id, area->lsdb); + if (old) + ospf6_lsa_purge(old); + ospf6_route_remove(ro, area->summary_prefix); + } + + /* Withdraw all summary router-routes previously originated */ + for (ro = ospf6_route_head(area->summary_router); ro; ro = nro) { + nro = ospf6_route_next(ro); + old = ospf6_lsdb_lookup(ro->path.origin.type, + ro->path.origin.id, + area->ospf6->router_id, area->lsdb); + if (old) + ospf6_lsa_purge(old); + ospf6_route_remove(ro, area->summary_router); + } + + /* Schedule Router-LSA for each area (ABR status may change) */ + for (ALL_LIST_ELEMENTS(area->ospf6->area_list, node, nnode, oa)) + /* update B bit for each area */ + OSPF6_ROUTER_LSA_SCHEDULE(oa); } /* RFC 2328 12.4.3. Summary-LSAs */ /* Returns 1 if a summary LSA has been generated for the area */ /* This is used by the area/range logic to add/remove blackhole routes */ -int -ospf6_abr_originate_summary_to_area (struct ospf6_route *route, - struct ospf6_area *area) +int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, + struct ospf6_area *area) { - struct ospf6_lsa *lsa, *old = NULL; - struct ospf6_route *summary, *range = NULL; - struct ospf6_area *route_area; - char buffer[OSPF6_MAX_LSASIZE]; - 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; - char buf[PREFIX2STR_BUFFER]; - int is_debug = 0; - - /* 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_debug) - zlog_debug ("Route type is none of network, range nor ASBR, ignore"); - return 0; - } - - /* AS External routes are never considered */ - if (route->path.type == OSPF6_PATH_TYPE_EXTERNAL1 || - route->path.type == OSPF6_PATH_TYPE_EXTERNAL2) - { - if (is_debug) - zlog_debug ("Path type is external, skip"); - return 0; - } - - /* do not generate if the path's area is the same as target area */ - if (route->path.area_id == area->area_id) - { - if (is_debug) - zlog_debug ("The route is in the area itself, ignore"); - return 0; - } - - /* do not generate if the nexthops belongs to the target area */ - if (ospf6_abr_nexthops_belong_to_area (route, area)) - { - if (is_debug) - zlog_debug ("The route's nexthop is in the same area, ignore"); - return 0; - } - - if (route->type == OSPF6_DEST_TYPE_ROUTER) - { - if (ADV_ROUTER_IN_PREFIX (&route->prefix) == area->ospf6->router_id) - { - inet_ntop (AF_INET, &(ADV_ROUTER_IN_PREFIX (&route->prefix)), buf, - sizeof (buf)); - zlog_debug ("%s: Skipping ASBR announcement for ABR (%s)", __func__, - buf); - return 0; + struct ospf6_lsa *lsa, *old = NULL; + struct ospf6_route *summary, *range = NULL; + struct ospf6_area *route_area; + char buffer[OSPF6_MAX_LSASIZE]; + 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; + char buf[PREFIX2STR_BUFFER]; + int is_debug = 0; + + /* 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_debug) + zlog_debug( + "Route type is none of network, range nor ASBR, ignore"); + return 0; } - } - - if (route->type == OSPF6_DEST_TYPE_ROUTER) - { - if (IS_OSPF6_DEBUG_ABR || IS_OSPF6_DEBUG_ORIGINATE (INTER_ROUTER)) - { - is_debug++; - inet_ntop (AF_INET, &(ADV_ROUTER_IN_PREFIX (&route->prefix)), - buf, sizeof (buf)); - zlog_debug ("Originating summary in area %s for ASBR %s", - area->name, buf); - } - summary_table = area->summary_router; - } - else - { - if (IS_OSPF6_DEBUG_ABR || IS_OSPF6_DEBUG_ORIGINATE (INTER_PREFIX)) - { - is_debug++; - prefix2str (&route->prefix, buf, sizeof (buf)); - zlog_debug ("Originating summary in area %s for %s", - area->name, buf); - } - summary_table = area->summary_prefix; - } - - summary = ospf6_route_lookup (&route->prefix, summary_table); - if (summary) - 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_debug) - zlog_debug ("The route has just removed, purge previous LSA"); - - if (route->type == OSPF6_DEST_TYPE_RANGE) - { - /* Whether the route have active longer prefix */ - if (! CHECK_FLAG (route->flag, OSPF6_ROUTE_ACTIVE_SUMMARY)) - { - if (is_debug) - zlog_debug ("The range is not active. withdraw"); - - ospf6_abr_delete_route (route, summary, summary_table, old); - } + + /* AS External routes are never considered */ + if (route->path.type == OSPF6_PATH_TYPE_EXTERNAL1 + || route->path.type == OSPF6_PATH_TYPE_EXTERNAL2) { + if (is_debug) + zlog_debug("Path type is external, skip"); + return 0; } - else - if (old) - ospf6_lsa_purge (old); - - return 0; - } - - if ((route->type == OSPF6_DEST_TYPE_ROUTER) && IS_AREA_STUB(area)) - { - if (is_debug) - zlog_debug ("Area has been stubbed, purge Inter-Router LSA"); - - ospf6_abr_delete_route (route, summary, summary_table, old); - return 0; - } - - if (area->no_summary && (route->path.subtype != OSPF6_PATH_SUBTYPE_DEFAULT_RT)) - { - if (is_debug) - zlog_debug ("Area has been stubbed, purge prefix LSA"); - - ospf6_abr_delete_route (route, summary, summary_table, old); - return 0; - } - - /* do not generate if the route cost is greater or equal to LSInfinity */ - if (route->path.cost >= OSPF_LS_INFINITY) - { - /* When we're clearing the range route because all active prefixes - * under the range are gone, we set the range's cost to - * OSPF_AREA_RANGE_COST_UNSPEC, which is > OSPF_LS_INFINITY. We - * don't want to trigger the code here for that. This code is for - * handling routes that have gone to infinity. The range removal happens - * elsewhere. - */ - if ((route->type != OSPF6_DEST_TYPE_RANGE) && - (route->path.cost != OSPF_AREA_RANGE_COST_UNSPEC)) - { - if (is_debug) - zlog_debug ("The cost exceeds LSInfinity, withdraw"); - if (old) - ospf6_lsa_purge (old); - return 0; + + /* do not generate if the path's area is the same as target area */ + if (route->path.area_id == area->area_id) { + if (is_debug) + zlog_debug("The route is in the area itself, ignore"); + return 0; + } + + /* do not generate if the nexthops belongs to the target area */ + if (ospf6_abr_nexthops_belong_to_area(route, area)) { + if (is_debug) + zlog_debug( + "The route's nexthop is in the same area, ignore"); + return 0; + } + + if (route->type == OSPF6_DEST_TYPE_ROUTER) { + if (ADV_ROUTER_IN_PREFIX(&route->prefix) + == area->ospf6->router_id) { + inet_ntop(AF_INET, + &(ADV_ROUTER_IN_PREFIX(&route->prefix)), buf, + sizeof(buf)); + zlog_debug( + "%s: Skipping ASBR announcement for ABR (%s)", + __func__, buf); + return 0; + } + } + + if (route->type == OSPF6_DEST_TYPE_ROUTER) { + if (IS_OSPF6_DEBUG_ABR + || IS_OSPF6_DEBUG_ORIGINATE(INTER_ROUTER)) { + is_debug++; + inet_ntop(AF_INET, + &(ADV_ROUTER_IN_PREFIX(&route->prefix)), buf, + sizeof(buf)); + zlog_debug("Originating summary in area %s for ASBR %s", + area->name, buf); + } + summary_table = area->summary_router; + } else { + if (IS_OSPF6_DEBUG_ABR + || IS_OSPF6_DEBUG_ORIGINATE(INTER_PREFIX)) { + is_debug++; + prefix2str(&route->prefix, buf, sizeof(buf)); + zlog_debug("Originating summary in area %s for %s", + area->name, buf); + } + summary_table = area->summary_prefix; + } + + summary = ospf6_route_lookup(&route->prefix, summary_table); + if (summary) + 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_debug) + zlog_debug( + "The route has just removed, purge previous LSA"); + + if (route->type == OSPF6_DEST_TYPE_RANGE) { + /* Whether the route have active longer prefix */ + if (!CHECK_FLAG(route->flag, + OSPF6_ROUTE_ACTIVE_SUMMARY)) { + if (is_debug) + zlog_debug( + "The range is not active. withdraw"); + + ospf6_abr_delete_route(route, summary, + summary_table, old); + } + } else if (old) + ospf6_lsa_purge(old); + + return 0; + } + + if ((route->type == OSPF6_DEST_TYPE_ROUTER) && IS_AREA_STUB(area)) { + if (is_debug) + zlog_debug( + "Area has been stubbed, purge Inter-Router LSA"); + + ospf6_abr_delete_route(route, summary, summary_table, old); + return 0; + } + + if (area->no_summary + && (route->path.subtype != OSPF6_PATH_SUBTYPE_DEFAULT_RT)) { + if (is_debug) + zlog_debug("Area has been stubbed, purge prefix LSA"); + + ospf6_abr_delete_route(route, summary, summary_table, old); + return 0; + } + + /* do not generate if the route cost is greater or equal to LSInfinity + */ + if (route->path.cost >= OSPF_LS_INFINITY) { + /* When we're clearing the range route because all active + * prefixes + * under the range are gone, we set the range's cost to + * OSPF_AREA_RANGE_COST_UNSPEC, which is > OSPF_LS_INFINITY. We + * don't want to trigger the code here for that. This code is + * for + * handling routes that have gone to infinity. The range removal + * happens + * elsewhere. + */ + if ((route->type != OSPF6_DEST_TYPE_RANGE) + && (route->path.cost != OSPF_AREA_RANGE_COST_UNSPEC)) { + if (is_debug) + zlog_debug( + "The cost exceeds LSInfinity, withdraw"); + if (old) + ospf6_lsa_purge(old); + return 0; + } + } + + /* 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_debug) + zlog_debug( + "This is the secondary path to the ASBR, ignore"); + ospf6_abr_delete_route(route, summary, summary_table, + old); + return 0; + } + + /* 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 != OSPF_AREA_BACKBONE + || !IS_AREA_TRANSIT(area))) { + if (is_debug) { + prefix2str(&range->prefix, buf, sizeof(buf)); + zlog_debug("Suppressed by range %s of area %s", + buf, route_area->name); + } + ospf6_abr_delete_route(route, summary, summary_table, + old); + return 0; + } + } + + /* 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_debug) + zlog_debug( + "This is the range with DoNotAdvertise set. ignore"); + ospf6_abr_delete_route(route, summary, summary_table, + old); + return 0; + } + + /* If there are no active prefixes in this range, remove */ + if (!CHECK_FLAG(route->flag, OSPF6_ROUTE_ACTIVE_SUMMARY)) { + if (is_debug) + zlog_debug("The range is not active. withdraw"); + ospf6_abr_delete_route(route, summary, summary_table, + old); + return 0; + } + } + + /* Check export list */ + if (EXPORT_NAME(area)) { + if (EXPORT_LIST(area) == NULL) + EXPORT_LIST(area) = + access_list_lookup(AFI_IP6, EXPORT_NAME(area)); + + if (EXPORT_LIST(area)) + if (access_list_apply(EXPORT_LIST(area), &route->prefix) + == FILTER_DENY) { + if (is_debug) { + inet_ntop(AF_INET, + &(ADV_ROUTER_IN_PREFIX( + &route->prefix)), + buf, sizeof(buf)); + zlog_debug( + "prefix %s was denied by export list", + buf); + } + return 0; + } + } + + /* Check filter-list */ + if (PREFIX_NAME_OUT(area)) { + if (PREFIX_LIST_OUT(area) == NULL) + PREFIX_LIST_OUT(area) = prefix_list_lookup( + AFI_IP6, PREFIX_NAME_OUT(area)); + + if (PREFIX_LIST_OUT(area)) + if (prefix_list_apply(PREFIX_LIST_OUT(area), + &route->prefix) + != PREFIX_PERMIT) { + if (is_debug) { + inet_ntop(AF_INET, + &(ADV_ROUTER_IN_PREFIX( + &route->prefix)), + buf, sizeof(buf)); + zlog_debug( + "prefix %s was denied by filter-list out", + buf); + } + return 0; + } } - } - - /* 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_debug) - zlog_debug ("This is the secondary path to the ASBR, ignore"); - ospf6_abr_delete_route (route, summary, summary_table, old); - return 0; - } - - /* 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 != OSPF_AREA_BACKBONE || - ! IS_AREA_TRANSIT (area))) - { - if (is_debug) - { - prefix2str (&range->prefix, buf, sizeof (buf)); - zlog_debug ("Suppressed by range %s of area %s", - buf, route_area->name); - } - ospf6_abr_delete_route (route, summary, summary_table, old); - return 0; - } - } - - /* 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_debug) - zlog_debug ("This is the range with DoNotAdvertise set. ignore"); - ospf6_abr_delete_route (route, summary, summary_table, old); - return 0; - } - - /* If there are no active prefixes in this range, remove */ - if (! CHECK_FLAG (route->flag, OSPF6_ROUTE_ACTIVE_SUMMARY)) - { - if (is_debug) - zlog_debug ("The range is not active. withdraw"); - ospf6_abr_delete_route (route, summary, summary_table, old); - return 0; - } - } - - /* Check export list */ - if (EXPORT_NAME (area)) - { - if (EXPORT_LIST (area) == NULL) - EXPORT_LIST (area) = - access_list_lookup (AFI_IP6, EXPORT_NAME (area)); - - if (EXPORT_LIST (area)) - if (access_list_apply (EXPORT_LIST (area), - &route->prefix) == FILTER_DENY) - { - if (is_debug) - { - inet_ntop (AF_INET, &(ADV_ROUTER_IN_PREFIX (&route->prefix)), - buf, sizeof(buf)); - zlog_debug ("prefix %s was denied by export list", buf); - } - return 0; - } - } - - /* Check filter-list */ - if (PREFIX_NAME_OUT (area)) - { - if (PREFIX_LIST_OUT (area) == NULL) - PREFIX_LIST_OUT (area) = - prefix_list_lookup(AFI_IP6, PREFIX_NAME_OUT (area)); - - if (PREFIX_LIST_OUT (area)) - if (prefix_list_apply (PREFIX_LIST_OUT (area), - &route->prefix) != PREFIX_PERMIT) - { - if (is_debug) - { - inet_ntop (AF_INET, &(ADV_ROUTER_IN_PREFIX (&route->prefix)), - buf, sizeof (buf)); - zlog_debug ("prefix %s was denied by filter-list out", buf); - } - return 0; - } - } - - /* 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.adv_router = area->ospf6->router_id; - - if (route->type == OSPF6_DEST_TYPE_ROUTER) - { - summary->path.origin.type = htons (OSPF6_LSTYPE_INTER_ROUTER); - summary->path.origin.id = ADV_ROUTER_IN_PREFIX (&route->prefix); + + /* 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.adv_router = area->ospf6->router_id; + + if (route->type == OSPF6_DEST_TYPE_ROUTER) { + summary->path.origin.type = + htons(OSPF6_LSTYPE_INTER_ROUTER); + summary->path.origin.id = + ADV_ROUTER_IN_PREFIX(&route->prefix); + } else { + summary->path.origin.type = + htons(OSPF6_LSTYPE_INTER_PREFIX); + summary->path.origin.id = ospf6_new_ls_id( + summary->path.origin.type, + summary->path.origin.adv_router, area->lsdb); + } + summary = ospf6_route_add(summary, summary_table); + } else { + summary->type = route->type; + monotime(&summary->changed); } - else - { - summary->path.origin.type = htons (OSPF6_LSTYPE_INTER_PREFIX); - summary->path.origin.id = - ospf6_new_ls_id (summary->path.origin.type, - summary->path.origin.adv_router, area->lsdb); + + 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.subtype = route->path.subtype; + 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; + + 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); + + /* 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 = ADV_ROUTER_IN_PREFIX(&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); + + /* 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); + type = htons(OSPF6_LSTYPE_INTER_PREFIX); } - summary = ospf6_route_add (summary, summary_table); - } - else - { - summary->type = route->type; - monotime(&summary->changed); - } - - 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.subtype = route->path.subtype; - 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; - - 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); - - /* 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 = ADV_ROUTER_IN_PREFIX (&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); - - /* 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); - type = htons (OSPF6_LSTYPE_INTER_PREFIX); - } - - /* Fill LSA Header */ - lsa_header->age = 0; - lsa_header->type = type; - lsa_header->id = summary->path.origin.id; - lsa_header->adv_router = area->ospf6->router_id; - lsa_header->seqnum = - ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id, - lsa_header->adv_router, area->lsdb); - lsa_header->length = htons ((caddr_t) p - (caddr_t) lsa_header); - - /* LSA checksum */ - ospf6_lsa_checksum (lsa_header); - - /* create LSA */ - lsa = ospf6_lsa_create (lsa_header); - - /* Originate */ - ospf6_lsa_originate_area (lsa, area); - - return 1; + + /* Fill LSA Header */ + lsa_header->age = 0; + lsa_header->type = type; + lsa_header->id = summary->path.origin.id; + lsa_header->adv_router = area->ospf6->router_id; + lsa_header->seqnum = + ospf6_new_ls_seqnum(lsa_header->type, lsa_header->id, + lsa_header->adv_router, area->lsdb); + lsa_header->length = htons((caddr_t)p - (caddr_t)lsa_header); + + /* LSA checksum */ + ospf6_lsa_checksum(lsa_header); + + /* create LSA */ + lsa = ospf6_lsa_create(lsa_header); + + /* Originate */ + ospf6_lsa_originate_area(lsa, area); + + return 1; } -void -ospf6_abr_range_reset_cost (struct ospf6 *ospf6) +void ospf6_abr_range_reset_cost(struct ospf6 *ospf6) { - struct listnode *node, *nnode; - struct ospf6_area *oa; - struct ospf6_route *range; - - for (ALL_LIST_ELEMENTS (ospf6->area_list, node, nnode, oa)) - for (range = ospf6_route_head (oa->range_table); range; - range = ospf6_route_next (range)) - OSPF6_ABR_RANGE_CLEAR_COST(range); + struct listnode *node, *nnode; + struct ospf6_area *oa; + struct ospf6_route *range; + + for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa)) + for (range = ospf6_route_head(oa->range_table); range; + range = ospf6_route_next(range)) + OSPF6_ABR_RANGE_CLEAR_COST(range); } -static inline u_int32_t -ospf6_abr_range_compute_cost (struct ospf6_route *range, struct ospf6 *o) +static inline u_int32_t ospf6_abr_range_compute_cost(struct ospf6_route *range, + struct ospf6 *o) { - struct ospf6_route *ro; - u_int32_t cost = 0; - - for (ro = ospf6_route_match_head (&range->prefix, o->route_table); - ro; ro = ospf6_route_match_next (&range->prefix, ro)) - { - if (ro->path.area_id == range->path.area_id && - (ro->path.type == OSPF6_PATH_TYPE_INTRA) && - ! CHECK_FLAG (ro->flag, OSPF6_ROUTE_REMOVE)) - cost = MAX (cost, ro->path.cost); - } - - return cost; + struct ospf6_route *ro; + u_int32_t cost = 0; + + for (ro = ospf6_route_match_head(&range->prefix, o->route_table); ro; + ro = ospf6_route_match_next(&range->prefix, ro)) { + if (ro->path.area_id == range->path.area_id + && (ro->path.type == OSPF6_PATH_TYPE_INTRA) + && !CHECK_FLAG(ro->flag, OSPF6_ROUTE_REMOVE)) + cost = MAX(cost, ro->path.cost); + } + + return cost; } static inline int -ospf6_abr_range_summary_needs_update (struct ospf6_route *range, - u_int32_t cost) +ospf6_abr_range_summary_needs_update(struct ospf6_route *range, u_int32_t cost) { - int redo_summary = 0; - - if (CHECK_FLAG(range->flag, OSPF6_ROUTE_REMOVE)) - { - UNSET_FLAG (range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY); - redo_summary = 1; - } - else if (CHECK_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE)) - { - if (range->path.cost != 0) - { - range->path.cost = 0; - redo_summary = 1; - } - } - else if (cost) - { - if ((OSPF6_PATH_COST_IS_CONFIGURED(range->path) && - range->path.cost != range->path.u.cost_config)) - { - range->path.cost = range->path.u.cost_config; - SET_FLAG (range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY); - redo_summary = 1; + int redo_summary = 0; + + if (CHECK_FLAG(range->flag, OSPF6_ROUTE_REMOVE)) { + UNSET_FLAG(range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY); + redo_summary = 1; + } else if (CHECK_FLAG(range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE)) { + if (range->path.cost != 0) { + range->path.cost = 0; + redo_summary = 1; + } + } else if (cost) { + if ((OSPF6_PATH_COST_IS_CONFIGURED(range->path) + && range->path.cost != range->path.u.cost_config)) { + range->path.cost = range->path.u.cost_config; + SET_FLAG(range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY); + redo_summary = 1; + } else if (!OSPF6_PATH_COST_IS_CONFIGURED(range->path) + && range->path.cost != cost) { + range->path.cost = cost; + SET_FLAG(range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY); + redo_summary = 1; + } + } else if (CHECK_FLAG(range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY)) { + /* Cost is zero, meaning no active range */ + UNSET_FLAG(range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY); + range->path.cost = OSPF_AREA_RANGE_COST_UNSPEC; + redo_summary = 1; } - else if (!OSPF6_PATH_COST_IS_CONFIGURED(range->path) && - range->path.cost != cost) - { - range->path.cost = cost; - SET_FLAG (range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY); - redo_summary = 1; - } - } - else if (CHECK_FLAG (range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY)) - { - /* Cost is zero, meaning no active range */ - UNSET_FLAG (range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY); - range->path.cost = OSPF_AREA_RANGE_COST_UNSPEC; - redo_summary = 1; - } - - return (redo_summary); + + return (redo_summary); } -static void -ospf6_abr_range_update (struct ospf6_route *range) +static void ospf6_abr_range_update(struct ospf6_route *range) { - u_int32_t cost = 0; - struct listnode *node, *nnode; - struct ospf6_area *oa; - int summary_orig = 0; - - assert (range->type == OSPF6_DEST_TYPE_RANGE); - - /* update range's cost and active flag */ - cost = ospf6_abr_range_compute_cost (range, ospf6); - - /* Non-zero cost is a proxy for active longer prefixes in this range. - * If there are active routes covered by this range AND either the configured - * cost has changed or the summarized cost has changed then redo summaries. - * Alternately, if there are no longer active prefixes and there are - * summary announcements, withdraw those announcements. - * - * The don't advertise code relies on the path.cost being set to UNSPEC to - * work the first time. Subsequent times the path.cost is not 0 anyway if there - * were active ranges. - */ - - if (ospf6_abr_range_summary_needs_update (range, cost)) - { - for (ALL_LIST_ELEMENTS (ospf6->area_list, node, nnode, oa)) - summary_orig += ospf6_abr_originate_summary_to_area (range, oa); - - if (CHECK_FLAG (range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY) && summary_orig) - { - if (! CHECK_FLAG (range->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) - { - if (IS_OSPF6_DEBUG_ABR) - zlog_debug ("Add discard route"); - - ospf6_zebra_add_discard (range); - } + u_int32_t cost = 0; + struct listnode *node, *nnode; + struct ospf6_area *oa; + int summary_orig = 0; + + assert(range->type == OSPF6_DEST_TYPE_RANGE); + + /* update range's cost and active flag */ + cost = ospf6_abr_range_compute_cost(range, ospf6); + + /* Non-zero cost is a proxy for active longer prefixes in this range. + * If there are active routes covered by this range AND either the + * configured + * cost has changed or the summarized cost has changed then redo + * summaries. + * Alternately, if there are no longer active prefixes and there are + * summary announcements, withdraw those announcements. + * + * The don't advertise code relies on the path.cost being set to UNSPEC + * to + * work the first time. Subsequent times the path.cost is not 0 anyway + * if there + * were active ranges. + */ + + if (ospf6_abr_range_summary_needs_update(range, cost)) { + for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa)) + summary_orig += + ospf6_abr_originate_summary_to_area(range, oa); + + if (CHECK_FLAG(range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY) + && summary_orig) { + if (!CHECK_FLAG(range->flag, + OSPF6_ROUTE_BLACKHOLE_ADDED)) { + if (IS_OSPF6_DEBUG_ABR) + zlog_debug("Add discard route"); + + ospf6_zebra_add_discard(range); + } + } else { + /* Summary removed or no summary generated as no + * specifics exist */ + if (CHECK_FLAG(range->flag, + OSPF6_ROUTE_BLACKHOLE_ADDED)) { + if (IS_OSPF6_DEBUG_ABR) + zlog_debug("Delete discard route"); + + ospf6_zebra_delete_discard(range); + } + } } - else - { - /* Summary removed or no summary generated as no specifics exist */ - if (CHECK_FLAG (range->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) - { - if (IS_OSPF6_DEBUG_ABR) - zlog_debug ("Delete discard route"); - - ospf6_zebra_delete_discard (range); - } - } - } } -void -ospf6_abr_originate_summary (struct ospf6_route *route) +void ospf6_abr_originate_summary(struct ospf6_route *route) { - struct listnode *node, *nnode; - struct ospf6_area *oa; - struct ospf6_route *range = NULL; - - 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); + struct listnode *node, *nnode; + struct ospf6_area *oa; + struct ospf6_route *range = NULL; + + 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 (ALL_LIST_ELEMENTS (ospf6->area_list, node, nnode, oa)) - ospf6_abr_originate_summary_to_area (route, oa); + for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa)) + ospf6_abr_originate_summary_to_area(route, oa); } -void -ospf6_abr_defaults_to_stub (struct ospf6 *o) +void ospf6_abr_defaults_to_stub(struct ospf6 *o) { - struct listnode *node, *nnode; - struct ospf6_area *oa; - struct ospf6_route *def, *route; - - if (!o->backbone) - return; - - def = ospf6_route_create(); - def->type = OSPF6_DEST_TYPE_NETWORK; - def->prefix.family = AF_INET6; - def->prefix.prefixlen = 0; - memset (&def->prefix.u.prefix6, 0, sizeof(struct in6_addr)); - def->type = OSPF6_DEST_TYPE_NETWORK; - def->path.type = OSPF6_PATH_TYPE_INTER; - def->path.subtype = OSPF6_PATH_SUBTYPE_DEFAULT_RT; - def->path.area_id = o->backbone->area_id; - - for (ALL_LIST_ELEMENTS (ospf6->area_list, node, nnode, oa)) - { - if (!IS_AREA_STUB (oa)) - { - /* withdraw defaults when an area switches from stub to non-stub */ - route = ospf6_route_lookup (&def->prefix, oa->summary_prefix); - if (route && (route->path.subtype == def->path.subtype)) - { - if (IS_OSPF6_DEBUG_ABR) - zlog_debug ("Withdrawing default route from non-stubby area %s", - oa->name); - SET_FLAG (def->flag, OSPF6_ROUTE_REMOVE); - ospf6_abr_originate_summary_to_area (def, oa); - } - } - else - { - /* announce defaults to stubby areas */ - if (IS_OSPF6_DEBUG_ABR) - zlog_debug ("Announcing default route into stubby area %s", - oa->name); - UNSET_FLAG (def->flag, OSPF6_ROUTE_REMOVE); - ospf6_abr_originate_summary_to_area (def, oa); + struct listnode *node, *nnode; + struct ospf6_area *oa; + struct ospf6_route *def, *route; + + if (!o->backbone) + return; + + def = ospf6_route_create(); + def->type = OSPF6_DEST_TYPE_NETWORK; + def->prefix.family = AF_INET6; + def->prefix.prefixlen = 0; + memset(&def->prefix.u.prefix6, 0, sizeof(struct in6_addr)); + def->type = OSPF6_DEST_TYPE_NETWORK; + def->path.type = OSPF6_PATH_TYPE_INTER; + def->path.subtype = OSPF6_PATH_SUBTYPE_DEFAULT_RT; + def->path.area_id = o->backbone->area_id; + + for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa)) { + if (!IS_AREA_STUB(oa)) { + /* withdraw defaults when an area switches from stub to + * non-stub */ + route = ospf6_route_lookup(&def->prefix, + oa->summary_prefix); + if (route + && (route->path.subtype == def->path.subtype)) { + if (IS_OSPF6_DEBUG_ABR) + zlog_debug( + "Withdrawing default route from non-stubby area %s", + oa->name); + SET_FLAG(def->flag, OSPF6_ROUTE_REMOVE); + ospf6_abr_originate_summary_to_area(def, oa); + } + } else { + /* announce defaults to stubby areas */ + if (IS_OSPF6_DEBUG_ABR) + zlog_debug( + "Announcing default route into stubby area %s", + oa->name); + UNSET_FLAG(def->flag, OSPF6_ROUTE_REMOVE); + ospf6_abr_originate_summary_to_area(def, oa); + } } - } - ospf6_route_delete (def); + ospf6_route_delete(def); } /* RFC 2328 16.2. Calculating the inter-area routes */ -void -ospf6_abr_examin_summary (struct ospf6_lsa *lsa, struct ospf6_area *oa) +void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa) { - struct prefix prefix, abr_prefix; - struct ospf6_route_table *table = NULL; - struct ospf6_route *range, *route, *old = NULL; - struct ospf6_route *abr_entry; - u_char type = 0; - char options[3] = {0, 0, 0}; - u_int8_t prefix_options = 0; - u_int32_t cost = 0; - u_char router_bits = 0; - char buf[PREFIX2STR_BUFFER]; - int is_debug = 0; - struct ospf6_inter_prefix_lsa *prefix_lsa = NULL; - struct ospf6_inter_router_lsa *router_lsa = NULL; - - memset (&prefix, 0, sizeof (prefix)); - - if (lsa->header->type == htons (OSPF6_LSTYPE_INTER_PREFIX)) - { - if (IS_OSPF6_DEBUG_EXAMIN (INTER_PREFIX)) - { - is_debug++; - zlog_debug ("Examin %s in area %s", lsa->name, oa->name); - } - - prefix_lsa = (struct ospf6_inter_prefix_lsa *) - OSPF6_LSA_HEADER_END (lsa->header); - prefix.family = AF_INET6; - prefix.prefixlen = prefix_lsa->prefix.prefix_length; - ospf6_prefix_in6_addr (&prefix.u.prefix6, &prefix_lsa->prefix); - if (is_debug) - prefix2str (&prefix, buf, sizeof (buf)); - table = oa->ospf6->route_table; - type = OSPF6_DEST_TYPE_NETWORK; - prefix_options = prefix_lsa->prefix.prefix_options; - cost = OSPF6_ABR_SUMMARY_METRIC (prefix_lsa); - } - else if (lsa->header->type == htons (OSPF6_LSTYPE_INTER_ROUTER)) - { - if (IS_OSPF6_DEBUG_EXAMIN (INTER_ROUTER)) - { - is_debug++; - zlog_debug ("Examin %s in area %s", lsa->name, oa->name); - } - - router_lsa = (struct ospf6_inter_router_lsa *) - OSPF6_LSA_HEADER_END (lsa->header); - ospf6_linkstate_prefix (router_lsa->router_id, htonl (0), &prefix); - if (is_debug) - inet_ntop (AF_INET, &router_lsa->router_id, buf, sizeof (buf)); - - table = oa->ospf6->brouter_table; - type = OSPF6_DEST_TYPE_ROUTER; - options[0] = router_lsa->options[0]; - options[1] = router_lsa->options[1]; - options[2] = router_lsa->options[2]; - cost = OSPF6_ABR_SUMMARY_METRIC (router_lsa); - SET_FLAG (router_bits, OSPF6_ROUTER_BIT_E); - } - else - assert (0); - - /* Find existing route */ - route = ospf6_route_lookup (&prefix, table); - if (route) - ospf6_route_lock (route); - while (route && ospf6_route_is_prefix (&prefix, route)) - { - if (route->path.area_id == oa->area_id && - route->path.origin.type == lsa->header->type && - route->path.origin.id == lsa->header->id && - route->path.origin.adv_router == lsa->header->adv_router && - ! CHECK_FLAG (route->flag, OSPF6_ROUTE_WAS_REMOVED)) - old = route; - route = ospf6_route_next (route); - } - if (route) - ospf6_route_unlock (route); - - /* (1) if cost == LSInfinity or if the LSA is MaxAge */ - if (cost == OSPF_LS_INFINITY) - { - if (is_debug) - zlog_debug ("cost is LS_INFINITY, ignore"); - if (old) - ospf6_route_remove (old, table); - return; - } - if (OSPF6_LSA_IS_MAXAGE (lsa)) - { - if (is_debug) - zlog_debug ("LSA is MaxAge, ignore"); - if (old) - ospf6_route_remove (old, table); - return; - } - - /* (2) if the LSA is self-originated, ignore */ - if (lsa->header->adv_router == oa->ospf6->router_id) - { - if (is_debug) - zlog_debug ("LSA is self-originated, ignore"); - if (old) - ospf6_route_remove (old, table); - return; - } - - /* (3) if the prefix is equal to an active configured address range */ - /* or if the NU bit is set in the prefix */ - if (lsa->header->type == htons (OSPF6_LSTYPE_INTER_PREFIX)) - { - range = ospf6_route_lookup (&prefix, oa->range_table); - if (range) - { - if (is_debug) - zlog_debug ("Prefix is equal to address range, ignore"); - if (old) - ospf6_route_remove (old, table); - return; - } - - if (CHECK_FLAG (prefix_lsa->prefix.prefix_options, - OSPF6_PREFIX_OPTION_NU) || - CHECK_FLAG (prefix_lsa->prefix.prefix_options, - OSPF6_PREFIX_OPTION_LA)) - { - if (is_debug) - zlog_debug ("Prefix has NU/LA bit set, ignore"); - if (old) - ospf6_route_remove (old, table); - return; + struct prefix prefix, abr_prefix; + struct ospf6_route_table *table = NULL; + struct ospf6_route *range, *route, *old = NULL; + struct ospf6_route *abr_entry; + u_char type = 0; + char options[3] = {0, 0, 0}; + u_int8_t prefix_options = 0; + u_int32_t cost = 0; + u_char router_bits = 0; + char buf[PREFIX2STR_BUFFER]; + int is_debug = 0; + struct ospf6_inter_prefix_lsa *prefix_lsa = NULL; + struct ospf6_inter_router_lsa *router_lsa = NULL; + + memset(&prefix, 0, sizeof(prefix)); + + if (lsa->header->type == htons(OSPF6_LSTYPE_INTER_PREFIX)) { + if (IS_OSPF6_DEBUG_EXAMIN(INTER_PREFIX)) { + is_debug++; + zlog_debug("Examin %s in area %s", lsa->name, oa->name); + } + + prefix_lsa = + (struct ospf6_inter_prefix_lsa *)OSPF6_LSA_HEADER_END( + lsa->header); + prefix.family = AF_INET6; + prefix.prefixlen = prefix_lsa->prefix.prefix_length; + ospf6_prefix_in6_addr(&prefix.u.prefix6, &prefix_lsa->prefix); + if (is_debug) + prefix2str(&prefix, buf, sizeof(buf)); + table = oa->ospf6->route_table; + type = OSPF6_DEST_TYPE_NETWORK; + prefix_options = prefix_lsa->prefix.prefix_options; + cost = OSPF6_ABR_SUMMARY_METRIC(prefix_lsa); + } else if (lsa->header->type == htons(OSPF6_LSTYPE_INTER_ROUTER)) { + if (IS_OSPF6_DEBUG_EXAMIN(INTER_ROUTER)) { + is_debug++; + zlog_debug("Examin %s in area %s", lsa->name, oa->name); + } + + router_lsa = + (struct ospf6_inter_router_lsa *)OSPF6_LSA_HEADER_END( + lsa->header); + ospf6_linkstate_prefix(router_lsa->router_id, htonl(0), + &prefix); + if (is_debug) + inet_ntop(AF_INET, &router_lsa->router_id, buf, + sizeof(buf)); + + table = oa->ospf6->brouter_table; + type = OSPF6_DEST_TYPE_ROUTER; + options[0] = router_lsa->options[0]; + options[1] = router_lsa->options[1]; + options[2] = router_lsa->options[2]; + cost = OSPF6_ABR_SUMMARY_METRIC(router_lsa); + SET_FLAG(router_bits, OSPF6_ROUTER_BIT_E); + } else + assert(0); + + /* Find existing route */ + route = ospf6_route_lookup(&prefix, table); + if (route) + ospf6_route_lock(route); + while (route && ospf6_route_is_prefix(&prefix, route)) { + if (route->path.area_id == oa->area_id + && route->path.origin.type == lsa->header->type + && route->path.origin.id == lsa->header->id + && route->path.origin.adv_router == lsa->header->adv_router + && !CHECK_FLAG(route->flag, OSPF6_ROUTE_WAS_REMOVED)) + old = route; + route = ospf6_route_next(route); + } + if (route) + ospf6_route_unlock(route); + + /* (1) if cost == LSInfinity or if the LSA is MaxAge */ + if (cost == OSPF_LS_INFINITY) { + if (is_debug) + zlog_debug("cost is LS_INFINITY, ignore"); + if (old) + ospf6_route_remove(old, table); + return; + } + if (OSPF6_LSA_IS_MAXAGE(lsa)) { + if (is_debug) + zlog_debug("LSA is MaxAge, ignore"); + if (old) + ospf6_route_remove(old, table); + return; + } + + /* (2) if the LSA is self-originated, ignore */ + if (lsa->header->adv_router == oa->ospf6->router_id) { + if (is_debug) + zlog_debug("LSA is self-originated, ignore"); + if (old) + ospf6_route_remove(old, table); + return; } - } - - if (lsa->header->type == htons (OSPF6_LSTYPE_INTER_ROUTER)) - { - /* To pass test suites */ - if (! OSPF6_OPT_ISSET (router_lsa->options, OSPF6_OPT_R) || - ! OSPF6_OPT_ISSET (router_lsa->options, OSPF6_OPT_V6)) - { - if (is_debug) - zlog_debug ("Prefix has NU/LA bit set, ignore"); - if (old) - ospf6_route_remove (old, table); - - return; + + /* (3) if the prefix is equal to an active configured address range */ + /* or if the NU bit is set in the prefix */ + if (lsa->header->type == htons(OSPF6_LSTYPE_INTER_PREFIX)) { + range = ospf6_route_lookup(&prefix, oa->range_table); + if (range) { + if (is_debug) + zlog_debug( + "Prefix is equal to address range, ignore"); + if (old) + ospf6_route_remove(old, table); + return; + } + + if (CHECK_FLAG(prefix_lsa->prefix.prefix_options, + OSPF6_PREFIX_OPTION_NU) + || CHECK_FLAG(prefix_lsa->prefix.prefix_options, + OSPF6_PREFIX_OPTION_LA)) { + if (is_debug) + zlog_debug("Prefix has NU/LA bit set, ignore"); + if (old) + ospf6_route_remove(old, table); + return; + } } - /* Avoid infinite recursion if someone has maliciously announced an - Inter-Router LSA for an ABR - */ - if (lsa->header->adv_router == router_lsa->router_id) - { - if (is_debug) - zlog_debug ("Ignorning Inter-Router LSA for an ABR (%s)", - buf); - if (old) - ospf6_route_remove (old, table); - - return; + + if (lsa->header->type == htons(OSPF6_LSTYPE_INTER_ROUTER)) { + /* To pass test suites */ + if (!OSPF6_OPT_ISSET(router_lsa->options, OSPF6_OPT_R) + || !OSPF6_OPT_ISSET(router_lsa->options, OSPF6_OPT_V6)) { + if (is_debug) + zlog_debug("Prefix has NU/LA bit set, ignore"); + if (old) + ospf6_route_remove(old, table); + + return; + } + /* Avoid infinite recursion if someone has maliciously announced + an + Inter-Router LSA for an ABR + */ + if (lsa->header->adv_router == router_lsa->router_id) { + if (is_debug) + zlog_debug( + "Ignorning Inter-Router LSA for an ABR (%s)", + buf); + if (old) + ospf6_route_remove(old, 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 || abr_entry->path.area_id != oa->area_id + || CHECK_FLAG(abr_entry->flag, OSPF6_ROUTE_REMOVE) + || !CHECK_FLAG(abr_entry->path.router_bits, OSPF6_ROUTER_BIT_B)) { + if (is_debug) + zlog_debug("ABR router entry does not exist, ignore"); + if (old) + ospf6_route_remove(old, table); + return; + } + + /* Check import list */ + if (IMPORT_NAME(oa)) { + if (IMPORT_LIST(oa) == NULL) + IMPORT_LIST(oa) = + access_list_lookup(AFI_IP6, IMPORT_NAME(oa)); + + if (IMPORT_LIST(oa)) + if (access_list_apply(IMPORT_LIST(oa), &prefix) + == FILTER_DENY) { + if (is_debug) + zlog_debug( + "Prefix was denied by import-list"); + if (old) + ospf6_route_remove(old, table); + return; + } + } + + /* Check input prefix-list */ + if (PREFIX_NAME_IN(oa)) { + if (PREFIX_LIST_IN(oa) == NULL) + PREFIX_LIST_IN(oa) = + prefix_list_lookup(AFI_IP6, PREFIX_NAME_IN(oa)); + + if (PREFIX_LIST_IN(oa)) + if (prefix_list_apply(PREFIX_LIST_IN(oa), &prefix) + != PREFIX_PERMIT) { + if (is_debug) + zlog_debug( + "Prefix was denied by prefix-list"); + if (old) + ospf6_route_remove(old, table); + return; + } + } + + /* (5),(6): the path preference is handled by the sorting + in the routing table. Always install the path by substituting + old route (if any). */ + if (old) + route = ospf6_route_copy(old); + else + route = ospf6_route_create(); + + route->type = type; + route->prefix = prefix; + route->path.origin.type = lsa->header->type; + route->path.origin.id = lsa->header->id; + route->path.origin.adv_router = lsa->header->adv_router; + route->path.router_bits = router_bits; + route->path.options[0] = options[0]; + route->path.options[1] = options[1]; + route->path.options[2] = options[2]; + route->path.prefix_options = prefix_options; + route->path.area_id = oa->area_id; + route->path.type = OSPF6_PATH_TYPE_INTER; + route->path.cost = abr_entry->path.cost + cost; + + ospf6_route_copy_nexthops(route, abr_entry); + + /* (7) If the routes are identical, copy the next hops over to existing + route. ospf6's route table implementation will otherwise string both + routes, but keep the older one as the best route since the routes + are identical. + */ + old = ospf6_route_lookup(&prefix, table); + + if (old && (ospf6_route_cmp(route, old) == 0)) { + ospf6_route_merge_nexthops(old, route); + /* Update RIB/FIB */ + if (table->hook_add) + (*table->hook_add)(old); + + /* Delete new route */ + ospf6_route_delete(route); + } else { + if (is_debug) + zlog_debug("Install route: %s", buf); + /* ospf6_ia_add_nw_route (table, &prefix, route); */ + ospf6_route_add(route, table); } - } - - /* (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 || abr_entry->path.area_id != oa->area_id || - CHECK_FLAG (abr_entry->flag, OSPF6_ROUTE_REMOVE) || - ! CHECK_FLAG (abr_entry->path.router_bits, OSPF6_ROUTER_BIT_B)) - { - if (is_debug) - zlog_debug ("ABR router entry does not exist, ignore"); - if (old) - ospf6_route_remove (old, table); - return; - } - - /* Check import list */ - if (IMPORT_NAME (oa)) - { - if (IMPORT_LIST (oa) == NULL) - IMPORT_LIST (oa) = access_list_lookup (AFI_IP6, IMPORT_NAME (oa)); - - if (IMPORT_LIST (oa)) - if (access_list_apply (IMPORT_LIST (oa), &prefix) == FILTER_DENY) - { - if (is_debug) - zlog_debug ("Prefix was denied by import-list"); - if (old) - ospf6_route_remove (old, table); - return; - } - } - - /* Check input prefix-list */ - if (PREFIX_NAME_IN (oa)) - { - if (PREFIX_LIST_IN (oa) == NULL) - PREFIX_LIST_IN (oa) = prefix_list_lookup (AFI_IP6, PREFIX_NAME_IN (oa)); - - if (PREFIX_LIST_IN (oa)) - if (prefix_list_apply (PREFIX_LIST_IN (oa), &prefix) != PREFIX_PERMIT) - { - if (is_debug) - zlog_debug ("Prefix was denied by prefix-list"); - if (old) - ospf6_route_remove (old, table); - return; - } - } - - /* (5),(6): the path preference is handled by the sorting - in the routing table. Always install the path by substituting - old route (if any). */ - if (old) - route = ospf6_route_copy (old); - else - route = ospf6_route_create (); - - route->type = type; - route->prefix = prefix; - route->path.origin.type = lsa->header->type; - route->path.origin.id = lsa->header->id; - route->path.origin.adv_router = lsa->header->adv_router; - route->path.router_bits = router_bits; - route->path.options[0] = options[0]; - route->path.options[1] = options[1]; - route->path.options[2] = options[2]; - route->path.prefix_options = prefix_options; - route->path.area_id = oa->area_id; - route->path.type = OSPF6_PATH_TYPE_INTER; - route->path.cost = abr_entry->path.cost + cost; - - ospf6_route_copy_nexthops (route, abr_entry); - - /* (7) If the routes are identical, copy the next hops over to existing - route. ospf6's route table implementation will otherwise string both - routes, but keep the older one as the best route since the routes - are identical. - */ - old = ospf6_route_lookup (&prefix, table); - - if (old && (ospf6_route_cmp (route, old) == 0)) - { - ospf6_route_merge_nexthops (old, route); - /* Update RIB/FIB */ - if (table->hook_add) - (*table->hook_add) (old); - - /* Delete new route */ - ospf6_route_delete (route); - } - else - { - if (is_debug) - zlog_debug ("Install route: %s", buf); - /* ospf6_ia_add_nw_route (table, &prefix, route); */ - ospf6_route_add (route, table); - } } -void -ospf6_abr_examin_brouter (u_int32_t router_id) +void ospf6_abr_examin_brouter(u_int32_t router_id) { - struct ospf6_lsa *lsa; - struct ospf6_area *oa; - u_int16_t type; - - if (ospf6_is_router_abr (ospf6)) - oa = ospf6->backbone; - else - oa = listgetdata(listhead(ospf6->area_list)); - - /* - * It is possible to designate a non backbone - * area first. If that is the case safely - * fall out of this function. - */ - if (oa == NULL) - return; - - type = htons (OSPF6_LSTYPE_INTER_ROUTER); - for (ALL_LSDB_TYPED_ADVRTR(oa->lsdb, type, router_id, lsa)) - ospf6_abr_examin_summary (lsa, oa); - - type = htons (OSPF6_LSTYPE_INTER_PREFIX); - for (ALL_LSDB_TYPED_ADVRTR(oa->lsdb, type, router_id, lsa)) - ospf6_abr_examin_summary (lsa, oa); + struct ospf6_lsa *lsa; + struct ospf6_area *oa; + u_int16_t type; + + if (ospf6_is_router_abr(ospf6)) + oa = ospf6->backbone; + else + oa = listgetdata(listhead(ospf6->area_list)); + + /* + * It is possible to designate a non backbone + * area first. If that is the case safely + * fall out of this function. + */ + if (oa == NULL) + return; + + type = htons(OSPF6_LSTYPE_INTER_ROUTER); + for (ALL_LSDB_TYPED_ADVRTR(oa->lsdb, type, router_id, lsa)) + ospf6_abr_examin_summary(lsa, oa); + + type = htons(OSPF6_LSTYPE_INTER_PREFIX); + for (ALL_LSDB_TYPED_ADVRTR(oa->lsdb, type, router_id, lsa)) + ospf6_abr_examin_summary(lsa, oa); } -void -ospf6_abr_reimport (struct ospf6_area *oa) +void ospf6_abr_reimport(struct ospf6_area *oa) { - struct ospf6_lsa *lsa; - u_int16_t type; + struct ospf6_lsa *lsa; + u_int16_t type; - type = htons (OSPF6_LSTYPE_INTER_ROUTER); - for (ALL_LSDB_TYPED(oa->lsdb, type, lsa)) - ospf6_abr_examin_summary (lsa, oa); + type = htons(OSPF6_LSTYPE_INTER_ROUTER); + for (ALL_LSDB_TYPED(oa->lsdb, type, lsa)) + ospf6_abr_examin_summary(lsa, oa); - type = htons (OSPF6_LSTYPE_INTER_PREFIX); - for (ALL_LSDB_TYPED(oa->lsdb, type, lsa)) - ospf6_abr_examin_summary (lsa, oa); + type = htons(OSPF6_LSTYPE_INTER_PREFIX); + for (ALL_LSDB_TYPED(oa->lsdb, type, lsa)) + ospf6_abr_examin_summary(lsa, oa); } -void -ospf6_abr_prefix_resummarize (struct ospf6 *o) +void ospf6_abr_prefix_resummarize(struct ospf6 *o) { - struct ospf6_route *route; + struct ospf6_route *route; - if (IS_OSPF6_DEBUG_ABR) - zlog_debug ("Re-examining Inter-Prefix Summaries"); + if (IS_OSPF6_DEBUG_ABR) + zlog_debug("Re-examining Inter-Prefix Summaries"); - for (route = ospf6_route_head (o->route_table); route; - route = ospf6_route_next (route)) - ospf6_abr_originate_summary(route); + for (route = ospf6_route_head(o->route_table); route; + route = ospf6_route_next(route)) + ospf6_abr_originate_summary(route); - if (IS_OSPF6_DEBUG_ABR) - zlog_debug ("Finished re-examining Inter-Prefix Summaries"); + if (IS_OSPF6_DEBUG_ABR) + zlog_debug("Finished re-examining Inter-Prefix Summaries"); } /* Display functions */ -static char * -ospf6_inter_area_prefix_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf, - int buflen, int pos) +static char *ospf6_inter_area_prefix_lsa_get_prefix_str(struct ospf6_lsa *lsa, + char *buf, int buflen, + int pos) { - struct ospf6_inter_prefix_lsa *prefix_lsa; - struct in6_addr in6; - - if (lsa != NULL) - { - prefix_lsa = (struct ospf6_inter_prefix_lsa *) - OSPF6_LSA_HEADER_END (lsa->header); - - ospf6_prefix_in6_addr (&in6, &prefix_lsa->prefix); - if (buf) - { - inet_ntop (AF_INET6, &in6, buf, buflen); - sprintf (&buf[strlen(buf)], "/%d", prefix_lsa->prefix.prefix_length); + struct ospf6_inter_prefix_lsa *prefix_lsa; + struct in6_addr in6; + + if (lsa != NULL) { + prefix_lsa = + (struct ospf6_inter_prefix_lsa *)OSPF6_LSA_HEADER_END( + lsa->header); + + ospf6_prefix_in6_addr(&in6, &prefix_lsa->prefix); + if (buf) { + inet_ntop(AF_INET6, &in6, buf, buflen); + sprintf(&buf[strlen(buf)], "/%d", + prefix_lsa->prefix.prefix_length); + } } - } - return (buf); + return (buf); } -static int -ospf6_inter_area_prefix_lsa_show (struct vty *vty, struct ospf6_lsa *lsa) +static int ospf6_inter_area_prefix_lsa_show(struct vty *vty, + struct ospf6_lsa *lsa) { - struct ospf6_inter_prefix_lsa *prefix_lsa; - char buf[INET6_ADDRSTRLEN]; + struct ospf6_inter_prefix_lsa *prefix_lsa; + char buf[INET6_ADDRSTRLEN]; - prefix_lsa = (struct ospf6_inter_prefix_lsa *) - OSPF6_LSA_HEADER_END (lsa->header); + prefix_lsa = (struct ospf6_inter_prefix_lsa *)OSPF6_LSA_HEADER_END( + lsa->header); - vty_out (vty, " Metric: %lu\n", - (u_long) OSPF6_ABR_SUMMARY_METRIC (prefix_lsa)); + vty_out(vty, " Metric: %lu\n", + (u_long)OSPF6_ABR_SUMMARY_METRIC(prefix_lsa)); - ospf6_prefix_options_printbuf (prefix_lsa->prefix.prefix_options, - buf, sizeof (buf)); - vty_out (vty, " Prefix Options: %s\n", buf); + ospf6_prefix_options_printbuf(prefix_lsa->prefix.prefix_options, buf, + sizeof(buf)); + vty_out(vty, " Prefix Options: %s\n", buf); - vty_out (vty, " Prefix: %s\n", - ospf6_inter_area_prefix_lsa_get_prefix_str (lsa, buf, sizeof(buf), - 0)); + vty_out(vty, " Prefix: %s\n", + ospf6_inter_area_prefix_lsa_get_prefix_str(lsa, buf, + sizeof(buf), 0)); - return 0; + return 0; } -static char * -ospf6_inter_area_router_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf, - int buflen, int pos) +static char *ospf6_inter_area_router_lsa_get_prefix_str(struct ospf6_lsa *lsa, + char *buf, int buflen, + int pos) { - struct ospf6_inter_router_lsa *router_lsa; + struct ospf6_inter_router_lsa *router_lsa; - if (lsa != NULL) - { - router_lsa = (struct ospf6_inter_router_lsa *) - OSPF6_LSA_HEADER_END (lsa->header); + if (lsa != NULL) { + router_lsa = + (struct ospf6_inter_router_lsa *)OSPF6_LSA_HEADER_END( + lsa->header); - if (buf) - inet_ntop (AF_INET, &router_lsa->router_id, buf, buflen); - } + if (buf) + inet_ntop(AF_INET, &router_lsa->router_id, buf, buflen); + } - return (buf); + return (buf); } -static int -ospf6_inter_area_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa) +static int ospf6_inter_area_router_lsa_show(struct vty *vty, + struct ospf6_lsa *lsa) { - struct ospf6_inter_router_lsa *router_lsa; - char buf[64]; + struct ospf6_inter_router_lsa *router_lsa; + char buf[64]; - router_lsa = (struct ospf6_inter_router_lsa *) - OSPF6_LSA_HEADER_END (lsa->header); + router_lsa = (struct ospf6_inter_router_lsa *)OSPF6_LSA_HEADER_END( + lsa->header); - ospf6_options_printbuf (router_lsa->options, buf, sizeof (buf)); - vty_out (vty, " Options: %s\n", buf); - vty_out (vty, " Metric: %lu\n", - (u_long) OSPF6_ABR_SUMMARY_METRIC (router_lsa)); + ospf6_options_printbuf(router_lsa->options, buf, sizeof(buf)); + vty_out(vty, " Options: %s\n", buf); + vty_out(vty, " Metric: %lu\n", + (u_long)OSPF6_ABR_SUMMARY_METRIC(router_lsa)); - inet_ntop (AF_INET, &router_lsa->router_id, buf, sizeof (buf)); - vty_out (vty, " Destination Router ID: %s\n", buf); + inet_ntop(AF_INET, &router_lsa->router_id, buf, sizeof(buf)); + vty_out(vty, " Destination Router ID: %s\n", buf); - return 0; + return 0; } /* Debug commands */ @@ -1124,8 +1090,8 @@ DEFUN (debug_ospf6_abr, "Debug OSPFv3 ABR function\n" ) { - OSPF6_DEBUG_ABR_ON (); - return CMD_SUCCESS; + OSPF6_DEBUG_ABR_ON(); + return CMD_SUCCESS; } DEFUN (no_debug_ospf6_abr, @@ -1137,50 +1103,43 @@ DEFUN (no_debug_ospf6_abr, "Debug OSPFv3 ABR function\n" ) { - OSPF6_DEBUG_ABR_OFF (); - return CMD_SUCCESS; + OSPF6_DEBUG_ABR_OFF(); + return CMD_SUCCESS; } -int -config_write_ospf6_debug_abr (struct vty *vty) +int config_write_ospf6_debug_abr(struct vty *vty) { - if (IS_OSPF6_DEBUG_ABR) - vty_out (vty, "debug ospf6 abr\n"); - return 0; + if (IS_OSPF6_DEBUG_ABR) + vty_out(vty, "debug ospf6 abr\n"); + return 0; } -void -install_element_ospf6_debug_abr (void) +void install_element_ospf6_debug_abr(void) { - install_element (ENABLE_NODE, &debug_ospf6_abr_cmd); - install_element (ENABLE_NODE, &no_debug_ospf6_abr_cmd); - install_element (CONFIG_NODE, &debug_ospf6_abr_cmd); - install_element (CONFIG_NODE, &no_debug_ospf6_abr_cmd); + install_element(ENABLE_NODE, &debug_ospf6_abr_cmd); + install_element(ENABLE_NODE, &no_debug_ospf6_abr_cmd); + install_element(CONFIG_NODE, &debug_ospf6_abr_cmd); + install_element(CONFIG_NODE, &no_debug_ospf6_abr_cmd); } -struct ospf6_lsa_handler inter_prefix_handler = -{ - OSPF6_LSTYPE_INTER_PREFIX, - "Inter-Prefix", - "IAP", - ospf6_inter_area_prefix_lsa_show, - ospf6_inter_area_prefix_lsa_get_prefix_str, +struct ospf6_lsa_handler inter_prefix_handler = { + OSPF6_LSTYPE_INTER_PREFIX, + "Inter-Prefix", + "IAP", + ospf6_inter_area_prefix_lsa_show, + ospf6_inter_area_prefix_lsa_get_prefix_str, }; -struct ospf6_lsa_handler inter_router_handler = -{ - OSPF6_LSTYPE_INTER_ROUTER, - "Inter-Router", - "IAR", - ospf6_inter_area_router_lsa_show, - ospf6_inter_area_router_lsa_get_prefix_str, +struct ospf6_lsa_handler inter_router_handler = { + OSPF6_LSTYPE_INTER_ROUTER, + "Inter-Router", + "IAR", + ospf6_inter_area_router_lsa_show, + ospf6_inter_area_router_lsa_get_prefix_str, }; -void -ospf6_abr_init (void) +void ospf6_abr_init(void) { - ospf6_install_lsa_handler (&inter_prefix_handler); - ospf6_install_lsa_handler (&inter_router_handler); + ospf6_install_lsa_handler(&inter_prefix_handler); + ospf6_install_lsa_handler(&inter_router_handler); } - - diff --git a/ospf6d/ospf6_abr.h b/ospf6d/ospf6_abr.h index 55d657cfc..61a6a7342 100644 --- a/ospf6d/ospf6_abr.h +++ b/ospf6d/ospf6_abr.h @@ -28,57 +28,55 @@ /* Debug option */ extern unsigned char conf_debug_ospf6_abr; -#define OSPF6_DEBUG_ABR_ON() \ - (conf_debug_ospf6_abr = 1) -#define OSPF6_DEBUG_ABR_OFF() \ - (conf_debug_ospf6_abr = 0) -#define IS_OSPF6_DEBUG_ABR \ - (conf_debug_ospf6_abr) +#define OSPF6_DEBUG_ABR_ON() (conf_debug_ospf6_abr = 1) +#define OSPF6_DEBUG_ABR_OFF() (conf_debug_ospf6_abr = 0) +#define IS_OSPF6_DEBUG_ABR (conf_debug_ospf6_abr) /* Inter-Area-Prefix-LSA */ #define OSPF6_INTER_PREFIX_LSA_MIN_SIZE 4U /* w/o IPv6 prefix */ -struct ospf6_inter_prefix_lsa -{ - u_int32_t metric; - struct ospf6_prefix prefix; +struct ospf6_inter_prefix_lsa { + u_int32_t metric; + struct ospf6_prefix prefix; }; /* Inter-Area-Router-LSA */ #define OSPF6_INTER_ROUTER_LSA_FIX_SIZE 12U -struct ospf6_inter_router_lsa -{ - u_char mbz; - u_char options[3]; - u_int32_t metric; - u_int32_t router_id; +struct ospf6_inter_router_lsa { + u_char mbz; + u_char options[3]; + u_int32_t metric; + u_int32_t router_id; }; #define OSPF6_ABR_SUMMARY_METRIC(E) (ntohl ((E)->metric & htonl (0x00ffffff))) -#define OSPF6_ABR_SUMMARY_METRIC_SET(E,C) \ - { (E)->metric &= htonl (0x00000000); \ - (E)->metric |= htonl (0x00ffffff) & htonl (C); } +#define OSPF6_ABR_SUMMARY_METRIC_SET(E, C) \ + { \ + (E)->metric &= htonl(0x00000000); \ + (E)->metric |= htonl(0x00ffffff) & htonl(C); \ + } #define OSPF6_ABR_RANGE_CLEAR_COST(range) (range->path.cost = OSPF_AREA_RANGE_COST_UNSPEC) -extern int ospf6_is_router_abr (struct ospf6 *o); +extern int ospf6_is_router_abr(struct ospf6 *o); -extern void ospf6_abr_enable_area (struct ospf6_area *oa); -extern void ospf6_abr_disable_area (struct ospf6_area *oa); +extern void ospf6_abr_enable_area(struct ospf6_area *oa); +extern void ospf6_abr_disable_area(struct ospf6_area *oa); -extern int ospf6_abr_originate_summary_to_area (struct ospf6_route *route, - struct ospf6_area *area); -extern void ospf6_abr_originate_summary (struct ospf6_route *route); -extern void ospf6_abr_examin_summary (struct ospf6_lsa *lsa, struct ospf6_area *oa); -extern void ospf6_abr_defaults_to_stub (struct ospf6 *); -extern void ospf6_abr_examin_brouter (u_int32_t router_id); -extern void ospf6_abr_reimport (struct ospf6_area *oa); -extern void ospf6_abr_range_reset_cost (struct ospf6 *ospf6); -extern void ospf6_abr_prefix_resummarize (struct ospf6 *ospf6); +extern int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, + struct ospf6_area *area); +extern void ospf6_abr_originate_summary(struct ospf6_route *route); +extern void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, + struct ospf6_area *oa); +extern void ospf6_abr_defaults_to_stub(struct ospf6 *); +extern void ospf6_abr_examin_brouter(u_int32_t router_id); +extern void ospf6_abr_reimport(struct ospf6_area *oa); +extern void ospf6_abr_range_reset_cost(struct ospf6 *ospf6); +extern void ospf6_abr_prefix_resummarize(struct ospf6 *ospf6); -extern int config_write_ospf6_debug_abr (struct vty *vty); -extern void install_element_ospf6_debug_abr (void); -extern int ospf6_abr_config_write (struct vty *vty); +extern int config_write_ospf6_debug_abr(struct vty *vty); +extern void install_element_ospf6_debug_abr(void); +extern int ospf6_abr_config_write(struct vty *vty); -extern void ospf6_abr_init (void); +extern void ospf6_abr_init(void); #endif /*OSPF6_ABR_H*/ diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index 8e6408bf4..a4cc0bf42 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -45,163 +45,146 @@ #include "ospf6_asbr.h" #include "ospf6d.h" -int -ospf6_area_cmp (void *va, void *vb) +int 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) ? -1 : 1); + 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) ? -1 : 1); } /* schedule routing table recalculation */ -static void -ospf6_area_lsdb_hook_add (struct ospf6_lsa *lsa) -{ - switch (ntohs (lsa->header->type)) - { - case OSPF6_LSTYPE_ROUTER: - case OSPF6_LSTYPE_NETWORK: - if (IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type)) - { - zlog_debug ("Examin %s", lsa->name); - zlog_debug ("Schedule SPF Calculation for %s", - OSPF6_AREA (lsa->lsdb->data)->name); - } - ospf6_spf_schedule (OSPF6_PROCESS(OSPF6_AREA (lsa->lsdb->data)->ospf6), - ospf6_lsadd_to_spf_reason(lsa)); - break; - - case OSPF6_LSTYPE_INTRA_PREFIX: - ospf6_intra_prefix_lsa_add (lsa); - break; - - case OSPF6_LSTYPE_INTER_PREFIX: - case OSPF6_LSTYPE_INTER_ROUTER: - ospf6_abr_examin_summary (lsa, (struct ospf6_area *) lsa->lsdb->data); - break; - - default: - break; - } +static void ospf6_area_lsdb_hook_add(struct ospf6_lsa *lsa) +{ + switch (ntohs(lsa->header->type)) { + case OSPF6_LSTYPE_ROUTER: + case OSPF6_LSTYPE_NETWORK: + if (IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa->header->type)) { + zlog_debug("Examin %s", lsa->name); + zlog_debug("Schedule SPF Calculation for %s", + OSPF6_AREA(lsa->lsdb->data)->name); + } + ospf6_spf_schedule( + OSPF6_PROCESS(OSPF6_AREA(lsa->lsdb->data)->ospf6), + ospf6_lsadd_to_spf_reason(lsa)); + break; + + case OSPF6_LSTYPE_INTRA_PREFIX: + ospf6_intra_prefix_lsa_add(lsa); + break; + + case OSPF6_LSTYPE_INTER_PREFIX: + case OSPF6_LSTYPE_INTER_ROUTER: + ospf6_abr_examin_summary(lsa, + (struct ospf6_area *)lsa->lsdb->data); + break; + + default: + break; + } } -static void -ospf6_area_lsdb_hook_remove (struct ospf6_lsa *lsa) -{ - switch (ntohs (lsa->header->type)) - { - case OSPF6_LSTYPE_ROUTER: - case OSPF6_LSTYPE_NETWORK: - if (IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type)) - { - zlog_debug ("LSA disappearing: %s", lsa->name); - zlog_debug ("Schedule SPF Calculation for %s", - OSPF6_AREA (lsa->lsdb->data)->name); - } - ospf6_spf_schedule (OSPF6_PROCESS(OSPF6_AREA (lsa->lsdb->data)->ospf6), - ospf6_lsremove_to_spf_reason(lsa)); - break; - - case OSPF6_LSTYPE_INTRA_PREFIX: - ospf6_intra_prefix_lsa_remove (lsa); - break; - - case OSPF6_LSTYPE_INTER_PREFIX: - case OSPF6_LSTYPE_INTER_ROUTER: - ospf6_abr_examin_summary (lsa, (struct ospf6_area *) lsa->lsdb->data); - break; - - default: - break; - } +static void ospf6_area_lsdb_hook_remove(struct ospf6_lsa *lsa) +{ + switch (ntohs(lsa->header->type)) { + case OSPF6_LSTYPE_ROUTER: + case OSPF6_LSTYPE_NETWORK: + if (IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa->header->type)) { + zlog_debug("LSA disappearing: %s", lsa->name); + zlog_debug("Schedule SPF Calculation for %s", + OSPF6_AREA(lsa->lsdb->data)->name); + } + ospf6_spf_schedule( + OSPF6_PROCESS(OSPF6_AREA(lsa->lsdb->data)->ospf6), + ospf6_lsremove_to_spf_reason(lsa)); + break; + + case OSPF6_LSTYPE_INTRA_PREFIX: + ospf6_intra_prefix_lsa_remove(lsa); + break; + + case OSPF6_LSTYPE_INTER_PREFIX: + case OSPF6_LSTYPE_INTER_ROUTER: + ospf6_abr_examin_summary(lsa, + (struct ospf6_area *)lsa->lsdb->data); + break; + + default: + break; + } } -static void -ospf6_area_route_hook_add (struct ospf6_route *route) +static void ospf6_area_route_hook_add(struct ospf6_route *route) { - struct ospf6_route *copy = ospf6_route_copy (route); - ospf6_route_add (copy, ospf6->route_table); + struct ospf6_route *copy = ospf6_route_copy(route); + ospf6_route_add(copy, ospf6->route_table); } -static void -ospf6_area_route_hook_remove (struct ospf6_route *route) +static void ospf6_area_route_hook_remove(struct ospf6_route *route) { - struct ospf6_route *copy; + struct ospf6_route *copy; - copy = ospf6_route_lookup_identical (route, ospf6->route_table); - if (copy) - ospf6_route_remove (copy, ospf6->route_table); + copy = ospf6_route_lookup_identical(route, ospf6->route_table); + if (copy) + ospf6_route_remove(copy, ospf6->route_table); } -static void -ospf6_area_stub_update (struct ospf6_area *area) +static void ospf6_area_stub_update(struct ospf6_area *area) { - if (IS_AREA_STUB (area)) - { - if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER)) - zlog_debug ("Stubbing out area for if %s\n", area->name); - OSPF6_OPT_CLEAR (area->options, OSPF6_OPT_E); - } - else if (IS_AREA_ENABLED (area)) - { - if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER)) - zlog_debug ("Normal area for if %s\n", area->name); - OSPF6_OPT_SET (area->options, OSPF6_OPT_E); - ospf6_asbr_send_externals_to_area (area); - } - - OSPF6_ROUTER_LSA_SCHEDULE(area); + if (IS_AREA_STUB(area)) { + if (IS_OSPF6_DEBUG_ORIGINATE(ROUTER)) + zlog_debug("Stubbing out area for if %s\n", area->name); + OSPF6_OPT_CLEAR(area->options, OSPF6_OPT_E); + } else if (IS_AREA_ENABLED(area)) { + if (IS_OSPF6_DEBUG_ORIGINATE(ROUTER)) + zlog_debug("Normal area for if %s\n", area->name); + OSPF6_OPT_SET(area->options, OSPF6_OPT_E); + ospf6_asbr_send_externals_to_area(area); + } + + OSPF6_ROUTER_LSA_SCHEDULE(area); } -static int -ospf6_area_stub_set (struct ospf6 *ospf6, struct ospf6_area *area) +static int ospf6_area_stub_set(struct ospf6 *ospf6, struct ospf6_area *area) { - if (!IS_AREA_STUB(area)) - { - SET_FLAG (area->flag, OSPF6_AREA_STUB); - ospf6_area_stub_update (area); - } + if (!IS_AREA_STUB(area)) { + SET_FLAG(area->flag, OSPF6_AREA_STUB); + ospf6_area_stub_update(area); + } - return (1); + return (1); } -static void -ospf6_area_stub_unset (struct ospf6 *ospf6, struct ospf6_area *area) +static void ospf6_area_stub_unset(struct ospf6 *ospf6, struct ospf6_area *area) { - if (IS_AREA_STUB (area)) - { - UNSET_FLAG (area->flag, OSPF6_AREA_STUB); - ospf6_area_stub_update (area); - } + if (IS_AREA_STUB(area)) { + UNSET_FLAG(area->flag, OSPF6_AREA_STUB); + ospf6_area_stub_update(area); + } } -static void -ospf6_area_no_summary_set (struct ospf6 *ospf6, struct ospf6_area *area) +static void ospf6_area_no_summary_set(struct ospf6 *ospf6, + struct ospf6_area *area) { - if (area) - { - if (!area->no_summary) - { - area->no_summary = 1; - ospf6_abr_range_reset_cost (ospf6); - ospf6_abr_prefix_resummarize (ospf6); + if (area) { + if (!area->no_summary) { + area->no_summary = 1; + ospf6_abr_range_reset_cost(ospf6); + ospf6_abr_prefix_resummarize(ospf6); + } } - } } -static void -ospf6_area_no_summary_unset (struct ospf6 *ospf6, struct ospf6_area *area) +static void ospf6_area_no_summary_unset(struct ospf6 *ospf6, + struct ospf6_area *area) { - if (area) - { - if (area->no_summary) - { - area->no_summary = 0; - ospf6_abr_range_reset_cost (ospf6); - ospf6_abr_prefix_resummarize (ospf6); + if (area) { + if (area->no_summary) { + area->no_summary = 0; + ospf6_abr_range_reset_cost(ospf6); + ospf6_abr_prefix_resummarize(ospf6); + } } - } } /** @@ -211,221 +194,199 @@ ospf6_area_no_summary_unset (struct ospf6 *ospf6, struct ospf6_area *area) * @param o - ospf6 instance * @param df - display format for area ID */ -struct ospf6_area * -ospf6_area_create (u_int32_t area_id, struct ospf6 *o, int df) +struct ospf6_area *ospf6_area_create(u_int32_t area_id, struct ospf6 *o, int df) { - struct ospf6_area *oa; - - oa = XCALLOC (MTYPE_OSPF6_AREA, sizeof (struct ospf6_area)); - - switch (df) - { - case OSPF6_AREA_FMT_DECIMAL: - snprintf (oa->name, sizeof (oa->name), "%u", ntohl (area_id)); - break; - default: - case OSPF6_AREA_FMT_DOTTEDQUAD: - inet_ntop (AF_INET, &area_id, oa->name, sizeof (oa->name)); - break; - } - - oa->area_id = area_id; - oa->if_list = list_new (); - - 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 (AREA, SPF_RESULTS); - oa->spf_table->scope = oa; - oa->route_table = OSPF6_ROUTE_TABLE_CREATE (AREA, ROUTES); - oa->route_table->scope = oa; - 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 (AREA, PREFIX_RANGES); - oa->range_table->scope = oa; - bf_init(oa->range_table->idspace, 32); - oa->summary_prefix = OSPF6_ROUTE_TABLE_CREATE (AREA, SUMMARY_PREFIXES); - oa->summary_prefix->scope = oa; - oa->summary_router = OSPF6_ROUTE_TABLE_CREATE (AREA, SUMMARY_ROUTERS); - oa->summary_router->scope = oa; - - /* set default options */ - if (CHECK_FLAG (o->flag, OSPF6_STUB_ROUTER)) - { - OSPF6_OPT_CLEAR (oa->options, OSPF6_OPT_V6); - OSPF6_OPT_CLEAR (oa->options, OSPF6_OPT_R); - } - else - { - OSPF6_OPT_SET (oa->options, OSPF6_OPT_V6); - OSPF6_OPT_SET (oa->options, OSPF6_OPT_R); - } - - OSPF6_OPT_SET (oa->options, OSPF6_OPT_E); - - SET_FLAG (oa->flag, OSPF6_AREA_ACTIVE); - SET_FLAG (oa->flag, OSPF6_AREA_ENABLE); - - oa->ospf6 = o; - listnode_add_sort (o->area_list, oa); - - if (area_id == OSPF_AREA_BACKBONE) - { - o->backbone = oa; - } - - return oa; + struct ospf6_area *oa; + + oa = XCALLOC(MTYPE_OSPF6_AREA, sizeof(struct ospf6_area)); + + switch (df) { + case OSPF6_AREA_FMT_DECIMAL: + snprintf(oa->name, sizeof(oa->name), "%u", ntohl(area_id)); + break; + default: + case OSPF6_AREA_FMT_DOTTEDQUAD: + inet_ntop(AF_INET, &area_id, oa->name, sizeof(oa->name)); + break; + } + + oa->area_id = area_id; + oa->if_list = list_new(); + + 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(AREA, SPF_RESULTS); + oa->spf_table->scope = oa; + oa->route_table = OSPF6_ROUTE_TABLE_CREATE(AREA, ROUTES); + oa->route_table->scope = oa; + 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(AREA, PREFIX_RANGES); + oa->range_table->scope = oa; + bf_init(oa->range_table->idspace, 32); + oa->summary_prefix = OSPF6_ROUTE_TABLE_CREATE(AREA, SUMMARY_PREFIXES); + oa->summary_prefix->scope = oa; + oa->summary_router = OSPF6_ROUTE_TABLE_CREATE(AREA, SUMMARY_ROUTERS); + oa->summary_router->scope = oa; + + /* set default options */ + if (CHECK_FLAG(o->flag, OSPF6_STUB_ROUTER)) { + OSPF6_OPT_CLEAR(oa->options, OSPF6_OPT_V6); + OSPF6_OPT_CLEAR(oa->options, OSPF6_OPT_R); + } else { + OSPF6_OPT_SET(oa->options, OSPF6_OPT_V6); + OSPF6_OPT_SET(oa->options, OSPF6_OPT_R); + } + + OSPF6_OPT_SET(oa->options, OSPF6_OPT_E); + + SET_FLAG(oa->flag, OSPF6_AREA_ACTIVE); + SET_FLAG(oa->flag, OSPF6_AREA_ENABLE); + + oa->ospf6 = o; + listnode_add_sort(o->area_list, oa); + + if (area_id == OSPF_AREA_BACKBONE) { + o->backbone = oa; + } + + return oa; } -void -ospf6_area_delete (struct ospf6_area *oa) +void ospf6_area_delete(struct ospf6_area *oa) { - struct listnode *n; - struct ospf6_interface *oi; + struct listnode *n; + struct ospf6_interface *oi; - /* The ospf6_interface structs store configuration - * information which should not be lost/reset when - * deleting an area. - * So just detach the interface from the area and - * keep it around. */ - for (ALL_LIST_ELEMENTS_RO (oa->if_list, n, oi)) - oi->area = NULL; + /* The ospf6_interface structs store configuration + * information which should not be lost/reset when + * deleting an area. + * So just detach the interface from the area and + * keep it around. */ + for (ALL_LIST_ELEMENTS_RO(oa->if_list, n, oi)) + oi->area = NULL; - list_delete (oa->if_list); + list_delete(oa->if_list); - ospf6_lsdb_delete (oa->lsdb); - ospf6_lsdb_delete (oa->lsdb_self); + ospf6_lsdb_delete(oa->lsdb); + ospf6_lsdb_delete(oa->lsdb_self); - ospf6_spf_table_finish (oa->spf_table); - ospf6_route_table_delete (oa->spf_table); - ospf6_route_table_delete (oa->route_table); + ospf6_spf_table_finish(oa->spf_table); + ospf6_route_table_delete(oa->spf_table); + ospf6_route_table_delete(oa->route_table); - ospf6_route_table_delete (oa->range_table); - ospf6_route_table_delete (oa->summary_prefix); - ospf6_route_table_delete (oa->summary_router); + ospf6_route_table_delete(oa->range_table); + ospf6_route_table_delete(oa->summary_prefix); + ospf6_route_table_delete(oa->summary_router); - listnode_delete (oa->ospf6->area_list, oa); - oa->ospf6 = NULL; + listnode_delete(oa->ospf6->area_list, oa); + oa->ospf6 = NULL; - /* free area */ - XFREE (MTYPE_OSPF6_AREA, oa); + /* free area */ + XFREE(MTYPE_OSPF6_AREA, oa); } -struct ospf6_area * -ospf6_area_lookup (u_int32_t area_id, struct ospf6 *ospf6) +struct ospf6_area *ospf6_area_lookup(u_int32_t area_id, struct ospf6 *ospf6) { - struct ospf6_area *oa; - struct listnode *n; + struct ospf6_area *oa; + struct listnode *n; - for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, n, oa)) - if (oa->area_id == area_id) - return oa; + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, n, oa)) + if (oa->area_id == area_id) + return oa; - return (struct ospf6_area *) NULL; + return (struct ospf6_area *)NULL; } -void -ospf6_area_enable (struct ospf6_area *oa) +void ospf6_area_enable(struct ospf6_area *oa) { - struct listnode *node, *nnode; - struct ospf6_interface *oi; + struct listnode *node, *nnode; + struct ospf6_interface *oi; - SET_FLAG (oa->flag, OSPF6_AREA_ENABLE); + SET_FLAG(oa->flag, OSPF6_AREA_ENABLE); - for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi)) - ospf6_interface_enable (oi); - ospf6_abr_enable_area (oa); + for (ALL_LIST_ELEMENTS(oa->if_list, node, nnode, oi)) + ospf6_interface_enable(oi); + ospf6_abr_enable_area(oa); } -void -ospf6_area_disable (struct ospf6_area *oa) +void ospf6_area_disable(struct ospf6_area *oa) { - struct listnode *node, *nnode; - struct ospf6_interface *oi; + struct listnode *node, *nnode; + struct ospf6_interface *oi; - UNSET_FLAG (oa->flag, OSPF6_AREA_ENABLE); + UNSET_FLAG(oa->flag, OSPF6_AREA_ENABLE); - for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi)) - ospf6_interface_disable (oi); + for (ALL_LIST_ELEMENTS(oa->if_list, node, nnode, oi)) + ospf6_interface_disable(oi); - ospf6_abr_disable_area (oa); - ospf6_lsdb_remove_all (oa->lsdb); - ospf6_lsdb_remove_all (oa->lsdb_self); + ospf6_abr_disable_area(oa); + ospf6_lsdb_remove_all(oa->lsdb); + ospf6_lsdb_remove_all(oa->lsdb_self); - ospf6_spf_table_finish(oa->spf_table); - ospf6_route_remove_all(oa->route_table); + ospf6_spf_table_finish(oa->spf_table); + ospf6_route_remove_all(oa->route_table); - THREAD_OFF (oa->thread_router_lsa); - THREAD_OFF (oa->thread_intra_prefix_lsa); + THREAD_OFF(oa->thread_router_lsa); + THREAD_OFF(oa->thread_intra_prefix_lsa); } -void -ospf6_area_show (struct vty *vty, struct ospf6_area *oa) +void ospf6_area_show(struct vty *vty, struct ospf6_area *oa) { - struct listnode *i; - struct ospf6_interface *oi; - unsigned long result; - - if (!IS_AREA_STUB (oa)) - vty_out (vty, " Area %s\n", oa->name); - else - { - if (oa->no_summary) - { - vty_out (vty, " Area %s[Stub, No Summary]\n", oa->name); - } - else - { - vty_out (vty, " Area %s[Stub]\n", oa->name); - } - } - vty_out (vty, " Number of Area scoped LSAs is %u\n", - oa->lsdb->count); - - vty_out (vty, " Interface attached to this area:"); - for (ALL_LIST_ELEMENTS_RO (oa->if_list, i, oi)) - vty_out (vty, " %s", oi->interface->name); - vty_out (vty, "\n"); - - if (oa->ts_spf.tv_sec || oa->ts_spf.tv_usec) - { - result = monotime_since(&oa->ts_spf, NULL); - if (result/TIMER_SECOND_MICRO > 0) - { - vty_out (vty, "SPF last executed %ld.%lds ago\n", - result/TIMER_SECOND_MICRO, - result % TIMER_SECOND_MICRO); + struct listnode *i; + struct ospf6_interface *oi; + unsigned long result; + + if (!IS_AREA_STUB(oa)) + vty_out(vty, " Area %s\n", oa->name); + else { + if (oa->no_summary) { + vty_out(vty, " Area %s[Stub, No Summary]\n", oa->name); + } else { + vty_out(vty, " Area %s[Stub]\n", oa->name); + } } - else - { - vty_out (vty, "SPF last executed %ldus ago\n", - result); + vty_out(vty, " Number of Area scoped LSAs is %u\n", + oa->lsdb->count); + + vty_out(vty, " Interface attached to this area:"); + for (ALL_LIST_ELEMENTS_RO(oa->if_list, i, oi)) + vty_out(vty, " %s", oi->interface->name); + vty_out(vty, "\n"); + + if (oa->ts_spf.tv_sec || oa->ts_spf.tv_usec) { + result = monotime_since(&oa->ts_spf, NULL); + if (result / TIMER_SECOND_MICRO > 0) { + vty_out(vty, "SPF last executed %ld.%lds ago\n", + result / TIMER_SECOND_MICRO, + result % TIMER_SECOND_MICRO); + } else { + vty_out(vty, "SPF last executed %ldus ago\n", result); + } + } else + vty_out(vty, "SPF has not been run\n"); +} + + +#define OSPF6_CMD_AREA_GET(str, oa) \ + { \ + char *ep; \ + u_int32_t area_id = htonl(strtoul(str, &ep, 10)); \ + if (*ep && inet_pton(AF_INET, str, &area_id) != 1) { \ + vty_out(vty, "Malformed Area-ID: %s\n", str); \ + return CMD_SUCCESS; \ + } \ + int format = !*ep ? OSPF6_AREA_FMT_DECIMAL \ + : OSPF6_AREA_FMT_DOTTEDQUAD; \ + oa = ospf6_area_lookup(area_id, ospf6); \ + if (oa == NULL) \ + oa = ospf6_area_create(area_id, ospf6, format); \ } - } - else - vty_out (vty, "SPF has not been run\n"); -} - - -#define OSPF6_CMD_AREA_GET(str, oa) \ -{ \ - char *ep; \ - u_int32_t area_id = htonl (strtoul (str, &ep, 10)); \ - if (*ep && inet_pton (AF_INET, str, &area_id) != 1) \ - { \ - vty_out (vty, "Malformed Area-ID: %s\n", str); \ - return CMD_SUCCESS; \ - } \ - int format = !*ep ? OSPF6_AREA_FMT_DECIMAL : \ - OSPF6_AREA_FMT_DOTTEDQUAD; \ - oa = ospf6_area_lookup (area_id, ospf6); \ - if (oa == NULL) \ - oa = ospf6_area_create (area_id, ospf6, format); \ -} DEFUN (area_range, area_range_cmd, @@ -440,66 +401,58 @@ DEFUN (area_range, "User specified metric for this range\n" "Advertised metric for this range\n") { - int idx_ipv4 = 1; - int idx_ipv6_prefixlen = 3; - int idx_type = 4; - int ret; - struct ospf6_area *oa; - struct prefix prefix; - struct ospf6_route *range; - u_int32_t cost = OSPF_AREA_RANGE_COST_UNSPEC; - - OSPF6_CMD_AREA_GET (argv[idx_ipv4]->arg, oa); - - ret = str2prefix (argv[idx_ipv6_prefixlen]->arg, &prefix); - if (ret != 1 || prefix.family != AF_INET6) - { - vty_out (vty, "Malformed argument: %s\n", argv[idx_ipv6_prefixlen]->arg); - return CMD_SUCCESS; - } - - range = ospf6_route_lookup (&prefix, oa->range_table); - if (range == NULL) - { - range = ospf6_route_create (); - range->type = OSPF6_DEST_TYPE_RANGE; - range->prefix = prefix; - range->path.area_id = oa->area_id; - range->path.cost = OSPF_AREA_RANGE_COST_UNSPEC; - } - - if (argc > idx_type) - { - if (strmatch (argv[idx_type]->text, "not-advertise")) - { - SET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE); + int idx_ipv4 = 1; + int idx_ipv6_prefixlen = 3; + int idx_type = 4; + int ret; + struct ospf6_area *oa; + struct prefix prefix; + struct ospf6_route *range; + u_int32_t cost = OSPF_AREA_RANGE_COST_UNSPEC; + + OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, oa); + + ret = str2prefix(argv[idx_ipv6_prefixlen]->arg, &prefix); + if (ret != 1 || prefix.family != AF_INET6) { + vty_out(vty, "Malformed argument: %s\n", + argv[idx_ipv6_prefixlen]->arg); + return CMD_SUCCESS; } - else if (strmatch (argv[idx_type]->text, "advertise")) - { - UNSET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE); + + range = ospf6_route_lookup(&prefix, oa->range_table); + if (range == NULL) { + range = ospf6_route_create(); + range->type = OSPF6_DEST_TYPE_RANGE; + range->prefix = prefix; + range->path.area_id = oa->area_id; + range->path.cost = OSPF_AREA_RANGE_COST_UNSPEC; } - else - { - cost = strtoul(argv[5]->arg, NULL, 10); - UNSET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE); + + if (argc > idx_type) { + if (strmatch(argv[idx_type]->text, "not-advertise")) { + SET_FLAG(range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE); + } else if (strmatch(argv[idx_type]->text, "advertise")) { + UNSET_FLAG(range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE); + } else { + cost = strtoul(argv[5]->arg, NULL, 10); + UNSET_FLAG(range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE); + } } - } - range->path.u.cost_config = cost; + range->path.u.cost_config = cost; - zlog_debug ("%s: for prefix %s, flag = %x\n", __func__, argv[idx_ipv6_prefixlen]->arg, range->flag); - if (range->rnode == NULL) - { - ospf6_route_add (range, oa->range_table); - } + zlog_debug("%s: for prefix %s, flag = %x\n", __func__, + argv[idx_ipv6_prefixlen]->arg, range->flag); + if (range->rnode == NULL) { + ospf6_route_add(range, oa->range_table); + } - if (ospf6_is_router_abr (ospf6)) - { - /* Redo summaries if required */ - ospf6_abr_prefix_resummarize (ospf6); - } + if (ospf6_is_router_abr(ospf6)) { + /* Redo summaries if required */ + ospf6_abr_prefix_resummarize(ospf6); + } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_area_range, @@ -516,96 +469,91 @@ DEFUN (no_area_range, "User specified metric for this range\n" "Advertised metric for this range\n") { - int idx_ipv4 = 2; - int idx_ipv6 = 4; - int ret; - struct ospf6_area *oa; - struct prefix prefix; - struct ospf6_route *range, *route; - - OSPF6_CMD_AREA_GET (argv[idx_ipv4]->arg, oa); - - ret = str2prefix (argv[idx_ipv6]->arg, &prefix); - if (ret != 1 || prefix.family != AF_INET6) - { - vty_out (vty, "Malformed argument: %s\n", argv[idx_ipv6]->arg); - return CMD_SUCCESS; - } - - range = ospf6_route_lookup (&prefix, oa->range_table); - if (range == NULL) - { - vty_out (vty, "Range %s does not exists.\n", argv[idx_ipv6]->arg); - return CMD_SUCCESS; - } - - if (ospf6_is_router_abr(oa->ospf6)) - { - /* Blow away the aggregated LSA and route */ - SET_FLAG (range->flag, OSPF6_ROUTE_REMOVE); - - /* Redo summaries if required */ - for (route = ospf6_route_head (ospf6->route_table); route; - route = ospf6_route_next (route)) - ospf6_abr_originate_summary(route); - - /* purge the old aggregated summary LSA */ - ospf6_abr_originate_summary(range); - } - ospf6_route_remove (range, oa->range_table); - - return CMD_SUCCESS; -} + int idx_ipv4 = 2; + int idx_ipv6 = 4; + int ret; + struct ospf6_area *oa; + struct prefix prefix; + struct ospf6_route *range, *route; -void -ospf6_area_config_write (struct vty *vty) -{ - struct listnode *node; - struct ospf6_area *oa; - struct ospf6_route *range; - char buf[PREFIX2STR_BUFFER]; - - for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa)) - { - 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", oa->name, buf); - - if (CHECK_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE)) - { - vty_out (vty, " not-advertise"); - } - else - { - // "advertise" is the default so we do not display it - if (range->path.u.cost_config != OSPF_AREA_RANGE_COST_UNSPEC) - vty_out (vty, " cost %d", range->path.u.cost_config); - } - vty_out (vty, "\n"); - - } - if (IS_AREA_STUB (oa)) - { - if (oa->no_summary) - vty_out (vty, " area %s stub no-summary\n", oa->name); - else - vty_out (vty, " area %s stub\n", oa->name); + OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, oa); + + ret = str2prefix(argv[idx_ipv6]->arg, &prefix); + if (ret != 1 || prefix.family != AF_INET6) { + vty_out(vty, "Malformed argument: %s\n", argv[idx_ipv6]->arg); + return CMD_SUCCESS; + } + + range = ospf6_route_lookup(&prefix, oa->range_table); + if (range == NULL) { + vty_out(vty, "Range %s does not exists.\n", + argv[idx_ipv6]->arg); + return CMD_SUCCESS; + } + + if (ospf6_is_router_abr(oa->ospf6)) { + /* Blow away the aggregated LSA and route */ + SET_FLAG(range->flag, OSPF6_ROUTE_REMOVE); + + /* Redo summaries if required */ + for (route = ospf6_route_head(ospf6->route_table); route; + route = ospf6_route_next(route)) + ospf6_abr_originate_summary(route); + + /* purge the old aggregated summary LSA */ + ospf6_abr_originate_summary(range); + } + ospf6_route_remove(range, oa->range_table); + + return CMD_SUCCESS; +} + +void ospf6_area_config_write(struct vty *vty) +{ + struct listnode *node; + struct ospf6_area *oa; + struct ospf6_route *range; + char buf[PREFIX2STR_BUFFER]; + + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) { + 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", oa->name, buf); + + if (CHECK_FLAG(range->flag, + OSPF6_ROUTE_DO_NOT_ADVERTISE)) { + vty_out(vty, " not-advertise"); + } else { + // "advertise" is the default so we do not + // display it + if (range->path.u.cost_config + != OSPF_AREA_RANGE_COST_UNSPEC) + vty_out(vty, " cost %d", + range->path.u.cost_config); + } + vty_out(vty, "\n"); + } + if (IS_AREA_STUB(oa)) { + if (oa->no_summary) + vty_out(vty, " area %s stub no-summary\n", + oa->name); + else + vty_out(vty, " area %s stub\n", oa->name); + } + if (PREFIX_NAME_IN(oa)) + vty_out(vty, " area %s filter-list prefix %s in\n", + oa->name, PREFIX_NAME_IN(oa)); + if (PREFIX_NAME_OUT(oa)) + vty_out(vty, " area %s filter-list prefix %s out\n", + oa->name, PREFIX_NAME_OUT(oa)); + if (IMPORT_NAME(oa)) + vty_out(vty, " area %s import-list %s\n", oa->name, + IMPORT_NAME(oa)); + if (EXPORT_NAME(oa)) + vty_out(vty, " area %s export-list %s\n", oa->name, + EXPORT_NAME(oa)); } - if (PREFIX_NAME_IN (oa)) - vty_out (vty, " area %s filter-list prefix %s in\n", - oa->name, PREFIX_NAME_IN (oa)); - if (PREFIX_NAME_OUT (oa)) - vty_out (vty, " area %s filter-list prefix %s out\n", - oa->name, PREFIX_NAME_OUT (oa)); - if (IMPORT_NAME (oa)) - vty_out (vty, " area %s import-list %s\n", - oa->name, IMPORT_NAME (oa)); - if (EXPORT_NAME (oa)) - vty_out (vty, " area %s export-list %s\n", - oa->name, EXPORT_NAME (oa)); - } } DEFUN (area_filter_list, @@ -619,38 +567,35 @@ DEFUN (area_filter_list, "Filter networks sent to this area\n" "Filter networks sent from this area\n") { - char *inout = argv[argc - 1]->text; - char *areaid = argv[1]->arg; - char *plistname = argv[4]->arg; - - struct ospf6_area *area; - struct prefix_list *plist; - - OSPF6_CMD_AREA_GET (areaid, area); - - plist = prefix_list_lookup (AFI_IP6, plistname); - if (strmatch (inout, "in")) - { - PREFIX_LIST_IN (area) = plist; - if (PREFIX_NAME_IN (area)) - free (PREFIX_NAME_IN (area)); - - PREFIX_NAME_IN (area) = strdup (plistname); - ospf6_abr_reimport (area); - } - else - { - PREFIX_LIST_OUT (area) = plist; - if (PREFIX_NAME_OUT (area)) - free (PREFIX_NAME_OUT (area)); - - PREFIX_NAME_OUT (area) = strdup (plistname); - ospf6_abr_enable_area (area); - } - - return CMD_SUCCESS; + char *inout = argv[argc - 1]->text; + char *areaid = argv[1]->arg; + char *plistname = argv[4]->arg; + + struct ospf6_area *area; + struct prefix_list *plist; + + OSPF6_CMD_AREA_GET(areaid, area); + + plist = prefix_list_lookup(AFI_IP6, plistname); + if (strmatch(inout, "in")) { + PREFIX_LIST_IN(area) = plist; + if (PREFIX_NAME_IN(area)) + free(PREFIX_NAME_IN(area)); + + PREFIX_NAME_IN(area) = strdup(plistname); + ospf6_abr_reimport(area); + } else { + PREFIX_LIST_OUT(area) = plist; + if (PREFIX_NAME_OUT(area)) + free(PREFIX_NAME_OUT(area)); + + PREFIX_NAME_OUT(area) = strdup(plistname); + ospf6_abr_enable_area(area); + } + + return CMD_SUCCESS; } - + DEFUN (no_area_filter_list, no_area_filter_list_cmd, "no area A.B.C.D filter-list prefix WORD <in|out>", @@ -663,42 +608,39 @@ DEFUN (no_area_filter_list, "Filter networks sent to this area\n" "Filter networks sent from this area\n") { - char *inout = argv[argc - 1]->text; - char *areaid = argv[2]->arg; - char *plistname = argv[5]->arg; - - struct ospf6_area *area; - - OSPF6_CMD_AREA_GET (areaid, area); - - if (strmatch (inout, "in")) - { - if (PREFIX_NAME_IN (area)) - if (!strmatch (PREFIX_NAME_IN (area), plistname)) - return CMD_SUCCESS; - - PREFIX_LIST_IN (area) = NULL; - if (PREFIX_NAME_IN (area)) - free (PREFIX_NAME_IN (area)); - - PREFIX_NAME_IN (area) = NULL; - ospf6_abr_reimport (area); - } - else - { - if (PREFIX_NAME_OUT (area)) - if (!strmatch (PREFIX_NAME_OUT (area), plistname)) - return CMD_SUCCESS; - - PREFIX_LIST_OUT (area) = NULL; - if (PREFIX_NAME_OUT (area)) - free (PREFIX_NAME_OUT (area)); - - PREFIX_NAME_OUT (area) = NULL; - ospf6_abr_enable_area (area); - } - - return CMD_SUCCESS; + char *inout = argv[argc - 1]->text; + char *areaid = argv[2]->arg; + char *plistname = argv[5]->arg; + + struct ospf6_area *area; + + OSPF6_CMD_AREA_GET(areaid, area); + + if (strmatch(inout, "in")) { + if (PREFIX_NAME_IN(area)) + if (!strmatch(PREFIX_NAME_IN(area), plistname)) + return CMD_SUCCESS; + + PREFIX_LIST_IN(area) = NULL; + if (PREFIX_NAME_IN(area)) + free(PREFIX_NAME_IN(area)); + + PREFIX_NAME_IN(area) = NULL; + ospf6_abr_reimport(area); + } else { + if (PREFIX_NAME_OUT(area)) + if (!strmatch(PREFIX_NAME_OUT(area), plistname)) + return CMD_SUCCESS; + + PREFIX_LIST_OUT(area) = NULL; + if (PREFIX_NAME_OUT(area)) + free(PREFIX_NAME_OUT(area)); + + PREFIX_NAME_OUT(area) = NULL; + ospf6_abr_enable_area(area); + } + + return CMD_SUCCESS; } DEFUN (area_import_list, @@ -709,24 +651,24 @@ DEFUN (area_import_list, "Set the filter for networks from other areas announced to the specified one\n" "Name of the acess-list\n") { - int idx_ipv4 = 1; - int idx_name = 3; - struct ospf6_area *area; - struct access_list *list; + int idx_ipv4 = 1; + int idx_name = 3; + struct ospf6_area *area; + struct access_list *list; - OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area); + OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area); - list = access_list_lookup (AFI_IP6, argv[idx_name]->arg); + list = access_list_lookup(AFI_IP6, argv[idx_name]->arg); - IMPORT_LIST (area) = list; + IMPORT_LIST(area) = list; - if (IMPORT_NAME (area)) - free (IMPORT_NAME (area)); + if (IMPORT_NAME(area)) + free(IMPORT_NAME(area)); - IMPORT_NAME (area) = strdup (argv[idx_name]->arg); - ospf6_abr_reimport (area); + IMPORT_NAME(area) = strdup(argv[idx_name]->arg); + ospf6_abr_reimport(area); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_area_import_list, @@ -738,20 +680,20 @@ DEFUN (no_area_import_list, "Unset the filter for networks announced to other areas\n" "Name of the access-list\n") { - int idx_ipv4 = 2; - struct ospf6_area *area; + int idx_ipv4 = 2; + struct ospf6_area *area; - OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area); + OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area); - IMPORT_LIST (area) = 0; + IMPORT_LIST(area) = 0; - if (IMPORT_NAME (area)) - free (IMPORT_NAME (area)); + if (IMPORT_NAME(area)) + free(IMPORT_NAME(area)); - IMPORT_NAME (area) = NULL; - ospf6_abr_reimport (area); + IMPORT_NAME(area) = NULL; + ospf6_abr_reimport(area); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (area_export_list, @@ -762,24 +704,24 @@ DEFUN (area_export_list, "Set the filter for networks announced to other areas\n" "Name of the acess-list\n") { - int idx_ipv4 = 1; - int idx_name = 3; - struct ospf6_area *area; - struct access_list *list; + int idx_ipv4 = 1; + int idx_name = 3; + struct ospf6_area *area; + struct access_list *list; - OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area); + OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area); - list = access_list_lookup (AFI_IP6, argv[idx_name]->arg); + list = access_list_lookup(AFI_IP6, argv[idx_name]->arg); - EXPORT_LIST (area) = list; + EXPORT_LIST(area) = list; - if (EXPORT_NAME (area)) - free (EXPORT_NAME (area)); + if (EXPORT_NAME(area)) + free(EXPORT_NAME(area)); - EXPORT_NAME (area) = strdup (argv[idx_name]->arg); - ospf6_abr_enable_area (area); + EXPORT_NAME(area) = strdup(argv[idx_name]->arg); + ospf6_abr_enable_area(area); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_area_export_list, @@ -791,20 +733,20 @@ DEFUN (no_area_export_list, "Unset the filter for networks announced to other areas\n" "Name of the access-list\n") { - int idx_ipv4 = 2; - struct ospf6_area *area; + int idx_ipv4 = 2; + struct ospf6_area *area; - OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area); + OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area); - EXPORT_LIST (area) = 0; + EXPORT_LIST(area) = 0; - if (EXPORT_NAME (area)) - free (EXPORT_NAME (area)); + if (EXPORT_NAME(area)) + free(EXPORT_NAME(area)); - EXPORT_NAME (area) = NULL; - ospf6_abr_enable_area (area); + EXPORT_NAME(area) = NULL; + ospf6_abr_enable_area(area); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (show_ipv6_ospf6_spf_tree, @@ -816,30 +758,28 @@ DEFUN (show_ipv6_ospf6_spf_tree, "Shortest Path First caculation\n" "Show SPF tree\n") { - struct listnode *node; - struct ospf6_area *oa; - struct ospf6_vertex *root; - struct ospf6_route *route; - struct prefix prefix; - - OSPF6_CMD_CHECK_RUNNING (); - - ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix); - - for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa)) - { - route = ospf6_route_lookup (&prefix, oa->spf_table); - if (route == NULL) - { - vty_out (vty, "LS entry for root not found in area %s\n", - oa->name); - continue; - } - root = (struct ospf6_vertex *) route->route_option; - ospf6_spf_display_subtree (vty, "", 0, root); - } - - return CMD_SUCCESS; + struct listnode *node; + struct ospf6_area *oa; + struct ospf6_vertex *root; + struct ospf6_route *route; + struct prefix prefix; + + OSPF6_CMD_CHECK_RUNNING(); + + ospf6_linkstate_prefix(ospf6->router_id, htonl(0), &prefix); + + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) { + route = ospf6_route_lookup(&prefix, oa->spf_table); + if (route == NULL) { + vty_out(vty, "LS entry for root not found in area %s\n", + oa->name); + continue; + } + root = (struct ospf6_vertex *)route->route_option; + ospf6_spf_display_subtree(vty, "", 0, root); + } + + return CMD_SUCCESS; } DEFUN (show_ipv6_ospf6_area_spf_tree, @@ -853,40 +793,37 @@ DEFUN (show_ipv6_ospf6_area_spf_tree, "Shortest Path First caculation\n" "Show SPF tree\n") { - int idx_ipv4 = 4; - u_int32_t area_id; - struct ospf6_area *oa; - struct ospf6_vertex *root; - struct ospf6_route *route; - struct prefix prefix; - - OSPF6_CMD_CHECK_RUNNING (); - - ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix); - - if (inet_pton (AF_INET, argv[idx_ipv4]->arg, &area_id) != 1) - { - vty_out (vty, "Malformed Area-ID: %s\n", argv[idx_ipv4]->arg); - return CMD_SUCCESS; - } - oa = ospf6_area_lookup (area_id, ospf6); - if (oa == NULL) - { - vty_out (vty, "No such Area: %s\n", argv[idx_ipv4]->arg); - return CMD_SUCCESS; - } - - route = ospf6_route_lookup (&prefix, oa->spf_table); - if (route == NULL) - { - vty_out (vty, "LS entry for root not found in area %s\n", - oa->name); - return CMD_SUCCESS; - } - root = (struct ospf6_vertex *) route->route_option; - ospf6_spf_display_subtree (vty, "", 0, root); - - return CMD_SUCCESS; + int idx_ipv4 = 4; + u_int32_t area_id; + struct ospf6_area *oa; + struct ospf6_vertex *root; + struct ospf6_route *route; + struct prefix prefix; + + OSPF6_CMD_CHECK_RUNNING(); + + ospf6_linkstate_prefix(ospf6->router_id, htonl(0), &prefix); + + if (inet_pton(AF_INET, argv[idx_ipv4]->arg, &area_id) != 1) { + vty_out(vty, "Malformed Area-ID: %s\n", argv[idx_ipv4]->arg); + return CMD_SUCCESS; + } + oa = ospf6_area_lookup(area_id, ospf6); + if (oa == NULL) { + vty_out(vty, "No such Area: %s\n", argv[idx_ipv4]->arg); + return CMD_SUCCESS; + } + + route = ospf6_route_lookup(&prefix, oa->spf_table); + if (route == NULL) { + vty_out(vty, "LS entry for root not found in area %s\n", + oa->name); + return CMD_SUCCESS; + } + root = (struct ospf6_vertex *)route->route_option; + ospf6_spf_display_subtree(vty, "", 0, root); + + return CMD_SUCCESS; } DEFUN (show_ipv6_ospf6_simulate_spf_tree_root, @@ -901,56 +838,53 @@ DEFUN (show_ipv6_ospf6_simulate_spf_tree_root, "OSPF6 area parameters\n" OSPF6_AREA_ID_STR) { - int idx_ipv4 = 5; - int idx_ipv4_2 = 7; - u_int32_t area_id; - struct ospf6_area *oa; - struct ospf6_vertex *root; - struct ospf6_route *route; - struct prefix prefix; - u_int32_t router_id; - struct ospf6_route_table *spf_table; - unsigned char tmp_debug_ospf6_spf = 0; - - OSPF6_CMD_CHECK_RUNNING (); - - inet_pton (AF_INET, argv[idx_ipv4]->arg, &router_id); - ospf6_linkstate_prefix (router_id, htonl (0), &prefix); - - if (inet_pton (AF_INET, argv[idx_ipv4_2]->arg, &area_id) != 1) - { - vty_out (vty, "Malformed Area-ID: %s\n", argv[idx_ipv4_2]->arg); - return CMD_SUCCESS; - } - oa = ospf6_area_lookup (area_id, ospf6); - if (oa == NULL) - { - vty_out (vty, "No such Area: %s\n", argv[idx_ipv4_2]->arg); - return CMD_SUCCESS; - } - - tmp_debug_ospf6_spf = conf_debug_ospf6_spf; - conf_debug_ospf6_spf = 0; - - spf_table = OSPF6_ROUTE_TABLE_CREATE (NONE, SPF_RESULTS); - ospf6_spf_calculation (router_id, spf_table, oa); - - conf_debug_ospf6_spf = tmp_debug_ospf6_spf; - - route = ospf6_route_lookup (&prefix, spf_table); - if (route == NULL) - { - ospf6_spf_table_finish (spf_table); - ospf6_route_table_delete (spf_table); - return CMD_SUCCESS; - } - root = (struct ospf6_vertex *) route->route_option; - ospf6_spf_display_subtree (vty, "", 0, root); - - ospf6_spf_table_finish (spf_table); - ospf6_route_table_delete (spf_table); - - return CMD_SUCCESS; + int idx_ipv4 = 5; + int idx_ipv4_2 = 7; + u_int32_t area_id; + struct ospf6_area *oa; + struct ospf6_vertex *root; + struct ospf6_route *route; + struct prefix prefix; + u_int32_t router_id; + struct ospf6_route_table *spf_table; + unsigned char tmp_debug_ospf6_spf = 0; + + OSPF6_CMD_CHECK_RUNNING(); + + inet_pton(AF_INET, argv[idx_ipv4]->arg, &router_id); + ospf6_linkstate_prefix(router_id, htonl(0), &prefix); + + if (inet_pton(AF_INET, argv[idx_ipv4_2]->arg, &area_id) != 1) { + vty_out(vty, "Malformed Area-ID: %s\n", argv[idx_ipv4_2]->arg); + return CMD_SUCCESS; + } + oa = ospf6_area_lookup(area_id, ospf6); + if (oa == NULL) { + vty_out(vty, "No such Area: %s\n", argv[idx_ipv4_2]->arg); + return CMD_SUCCESS; + } + + tmp_debug_ospf6_spf = conf_debug_ospf6_spf; + conf_debug_ospf6_spf = 0; + + spf_table = OSPF6_ROUTE_TABLE_CREATE(NONE, SPF_RESULTS); + ospf6_spf_calculation(router_id, spf_table, oa); + + conf_debug_ospf6_spf = tmp_debug_ospf6_spf; + + route = ospf6_route_lookup(&prefix, spf_table); + if (route == NULL) { + ospf6_spf_table_finish(spf_table); + ospf6_route_table_delete(spf_table); + return CMD_SUCCESS; + } + root = (struct ospf6_vertex *)route->route_option; + ospf6_spf_display_subtree(vty, "", 0, root); + + ospf6_spf_table_finish(spf_table); + ospf6_route_table_delete(spf_table); + + return CMD_SUCCESS; } DEFUN (ospf6_area_stub, @@ -961,20 +895,20 @@ DEFUN (ospf6_area_stub, "OSPF6 area ID as a decimal value\n" "Configure OSPF6 area as stub\n") { - int idx_ipv4_number = 1; - struct ospf6_area *area; + int idx_ipv4_number = 1; + struct ospf6_area *area; - OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area); + OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area); - if (!ospf6_area_stub_set (ospf6, area)) - { - vty_out (vty,"First deconfigure all virtual link through this area\n"); - return CMD_WARNING_CONFIG_FAILED; - } + if (!ospf6_area_stub_set(ospf6, area)) { + vty_out(vty, + "First deconfigure all virtual link through this area\n"); + return CMD_WARNING_CONFIG_FAILED; + } - ospf6_area_no_summary_unset (ospf6, area); + ospf6_area_no_summary_unset(ospf6, area); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (ospf6_area_stub_no_summary, @@ -986,20 +920,20 @@ DEFUN (ospf6_area_stub_no_summary, "Configure OSPF6 area as stub\n" "Do not inject inter-area routes into stub\n") { - int idx_ipv4_number = 1; - struct ospf6_area *area; + int idx_ipv4_number = 1; + struct ospf6_area *area; - OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area); + OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area); - if (!ospf6_area_stub_set (ospf6, area)) - { - vty_out (vty,"First deconfigure all virtual link through this area\n"); - return CMD_WARNING_CONFIG_FAILED; - } + if (!ospf6_area_stub_set(ospf6, area)) { + vty_out(vty, + "First deconfigure all virtual link through this area\n"); + return CMD_WARNING_CONFIG_FAILED; + } - ospf6_area_no_summary_set (ospf6, area); + ospf6_area_no_summary_set(ospf6, area); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ospf6_area_stub, @@ -1011,15 +945,15 @@ DEFUN (no_ospf6_area_stub, "OSPF6 area ID as a decimal value\n" "Configure OSPF6 area as stub\n") { - int idx_ipv4_number = 2; - struct ospf6_area *area; + int idx_ipv4_number = 2; + struct ospf6_area *area; - OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area); + OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area); - ospf6_area_stub_unset (ospf6, area); - ospf6_area_no_summary_unset (ospf6, area); + ospf6_area_stub_unset(ospf6, area); + ospf6_area_no_summary_unset(ospf6, area); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ospf6_area_stub_no_summary, @@ -1032,40 +966,36 @@ DEFUN (no_ospf6_area_stub_no_summary, "Configure OSPF6 area as stub\n" "Do not inject inter-area routes into area\n") { - int idx_ipv4_number = 2; - struct ospf6_area *area; + int idx_ipv4_number = 2; + struct ospf6_area *area; - OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area); + OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area); - ospf6_area_stub_unset (ospf6, area); - ospf6_area_no_summary_unset (ospf6, area); + ospf6_area_stub_unset(ospf6, area); + ospf6_area_no_summary_unset(ospf6, area); - return CMD_SUCCESS; + return CMD_SUCCESS; } -void -ospf6_area_init (void) +void ospf6_area_init(void) { - install_element (VIEW_NODE, &show_ipv6_ospf6_spf_tree_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_area_spf_tree_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd); - - install_element (OSPF6_NODE, &area_range_cmd); - install_element (OSPF6_NODE, &no_area_range_cmd); - install_element (OSPF6_NODE, &ospf6_area_stub_no_summary_cmd); - install_element (OSPF6_NODE, &ospf6_area_stub_cmd); - install_element (OSPF6_NODE, &no_ospf6_area_stub_no_summary_cmd); - install_element (OSPF6_NODE, &no_ospf6_area_stub_cmd); + install_element(VIEW_NODE, &show_ipv6_ospf6_spf_tree_cmd); + install_element(VIEW_NODE, &show_ipv6_ospf6_area_spf_tree_cmd); + install_element(VIEW_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd); + install_element(OSPF6_NODE, &area_range_cmd); + install_element(OSPF6_NODE, &no_area_range_cmd); + install_element(OSPF6_NODE, &ospf6_area_stub_no_summary_cmd); + install_element(OSPF6_NODE, &ospf6_area_stub_cmd); + install_element(OSPF6_NODE, &no_ospf6_area_stub_no_summary_cmd); + install_element(OSPF6_NODE, &no_ospf6_area_stub_cmd); - install_element (OSPF6_NODE, &area_import_list_cmd); - install_element (OSPF6_NODE, &no_area_import_list_cmd); - install_element (OSPF6_NODE, &area_export_list_cmd); - install_element (OSPF6_NODE, &no_area_export_list_cmd); - install_element (OSPF6_NODE, &area_filter_list_cmd); - install_element (OSPF6_NODE, &no_area_filter_list_cmd); + install_element(OSPF6_NODE, &area_import_list_cmd); + install_element(OSPF6_NODE, &no_area_import_list_cmd); + install_element(OSPF6_NODE, &area_export_list_cmd); + install_element(OSPF6_NODE, &no_area_export_list_cmd); + install_element(OSPF6_NODE, &area_filter_list_cmd); + install_element(OSPF6_NODE, &no_area_filter_list_cmd); } - - diff --git a/ospf6d/ospf6_area.h b/ospf6d/ospf6_area.h index 86c68af17..4bc24a6dd 100644 --- a/ospf6d/ospf6_area.h +++ b/ospf6d/ospf6_area.h @@ -23,85 +23,81 @@ #include "ospf6_top.h" -struct ospf6_area -{ - /* Reference to Top data structure */ - struct ospf6 *ospf6; +struct ospf6_area { + /* Reference to Top data structure */ + struct ospf6 *ospf6; - /* Area-ID */ - u_int32_t area_id; + /* Area-ID */ + u_int32_t area_id; #define OSPF6_AREA_FMT_DOTTEDQUAD 1 #define OSPF6_AREA_FMT_DECIMAL 2 - /* Area-ID string */ - char name[16]; + /* Area-ID string */ + char name[16]; - /* flag */ - u_char flag; + /* flag */ + u_char flag; - /* OSPF Option */ - u_char options[3]; + /* OSPF Option */ + u_char options[3]; - /* Summary routes to be originated (includes Configured Address Ranges) */ - struct ospf6_route_table *range_table; - struct ospf6_route_table *summary_prefix; - struct ospf6_route_table *summary_router; + /* Summary routes to be originated (includes Configured Address Ranges) + */ + struct ospf6_route_table *range_table; + struct ospf6_route_table *summary_prefix; + struct ospf6_route_table *summary_router; - /* Area type */ - int no_summary; + /* Area type */ + int no_summary; - /* OSPF interface list */ - struct list *if_list; + /* OSPF interface list */ + struct list *if_list; - struct ospf6_lsdb *lsdb; - struct ospf6_lsdb *lsdb_self; + struct ospf6_lsdb *lsdb; + struct ospf6_lsdb *lsdb_self; - struct ospf6_route_table *spf_table; - struct ospf6_route_table *route_table; + struct ospf6_route_table *spf_table; + struct ospf6_route_table *route_table; - u_int32_t spf_calculation; /* SPF calculation count */ + u_int32_t spf_calculation; /* SPF calculation count */ - struct thread *thread_router_lsa; - struct thread *thread_intra_prefix_lsa; - u_int32_t router_lsa_size_limit; + struct thread *thread_router_lsa; + struct thread *thread_intra_prefix_lsa; + u_int32_t router_lsa_size_limit; - /* Area announce list */ - struct - { - char *name; - struct access_list *list; - } _export; + /* Area announce list */ + struct { + char *name; + struct access_list *list; + } _export; #define EXPORT_NAME(A) (A)->_export.name #define EXPORT_LIST(A) (A)->_export.list - /* Area acceptance list */ - struct - { - char *name; - struct access_list *list; - } import; + /* Area acceptance list */ + struct { + char *name; + struct access_list *list; + } import; #define IMPORT_NAME(A) (A)->import.name #define IMPORT_LIST(A) (A)->import.list - /* Type 3 LSA Area prefix-list */ - struct - { - char *name; - struct prefix_list *list; - } plist_in; + /* Type 3 LSA Area prefix-list */ + struct { + char *name; + struct prefix_list *list; + } plist_in; #define PREFIX_NAME_IN(A) (A)->plist_in.name #define PREFIX_LIST_IN(A) (A)->plist_in.list - struct - { - char *name; - struct prefix_list *list; - } plist_out; + struct { + char *name; + struct prefix_list *list; + } plist_out; #define PREFIX_NAME_OUT(A) (A)->plist_out.name #define PREFIX_LIST_OUT(A) (A)->plist_out.list - /* Time stamps. */ - struct timeval ts_spf; /* SPF calculation time stamp. */ + /* Time stamps. */ + struct timeval ts_spf; /* SPF calculation time stamp. */ }; #define OSPF6_AREA_ENABLE 0x01 @@ -115,18 +111,18 @@ struct ospf6_area #define IS_AREA_STUB(oa) (CHECK_FLAG ((oa)->flag, OSPF6_AREA_STUB)) /* prototypes */ -extern int ospf6_area_cmp (void *va, void *vb); +extern int ospf6_area_cmp(void *va, void *vb); -extern struct ospf6_area *ospf6_area_create (u_int32_t, struct ospf6 *, int); -extern void ospf6_area_delete (struct ospf6_area *); -extern struct ospf6_area *ospf6_area_lookup (u_int32_t, struct ospf6 *); +extern struct ospf6_area *ospf6_area_create(u_int32_t, struct ospf6 *, int); +extern void ospf6_area_delete(struct ospf6_area *); +extern struct ospf6_area *ospf6_area_lookup(u_int32_t, struct ospf6 *); -extern void ospf6_area_enable (struct ospf6_area *); -extern void ospf6_area_disable (struct ospf6_area *); +extern void ospf6_area_enable(struct ospf6_area *); +extern void ospf6_area_disable(struct ospf6_area *); -extern void ospf6_area_show (struct vty *, struct ospf6_area *); +extern void ospf6_area_show(struct vty *, struct ospf6_area *); -extern void ospf6_area_config_write (struct vty *vty); -extern void ospf6_area_init (void); +extern void ospf6_area_config_write(struct vty *vty); +extern void ospf6_area_init(void); #endif /* OSPF_AREA_H */ diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index 3404ba020..7f8341d0e 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -52,632 +52,584 @@ unsigned char conf_debug_ospf6_asbr = 0; #define ZROUTE_NAME(x) zebra_route_string(x) /* AS External LSA origination */ -static void -ospf6_as_external_lsa_originate (struct ospf6_route *route) +static void ospf6_as_external_lsa_originate(struct ospf6_route *route) { - char buffer[OSPF6_MAX_LSASIZE]; - struct ospf6_lsa_header *lsa_header; - struct ospf6_lsa *lsa; - struct ospf6_external_info *info = route->route_option; - - struct ospf6_as_external_lsa *as_external_lsa; - char buf[PREFIX2STR_BUFFER]; - caddr_t p; - - if (IS_OSPF6_DEBUG_ASBR || IS_OSPF6_DEBUG_ORIGINATE (AS_EXTERNAL)) - { - prefix2str (&route->prefix, buf, sizeof (buf)); - zlog_debug ("Originate AS-External-LSA for %s", buf); - } - - /* prepare buffer */ - memset (buffer, 0, sizeof (buffer)); - lsa_header = (struct ospf6_lsa_header *) buffer; - as_external_lsa = (struct ospf6_as_external_lsa *) - ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header)); - p = (caddr_t) - ((caddr_t) as_external_lsa + sizeof (struct ospf6_as_external_lsa)); - - /* Fill AS-External-LSA */ - /* Metric type */ - if (route->path.metric_type == 2) - SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_E); - else - UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_E); - - /* forwarding address */ - if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding)) - SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F); - else - UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F); - - /* external route tag */ - if (info->tag) - SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T); - else - UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T); - - /* Set metric */ - OSPF6_ASBR_METRIC_SET (as_external_lsa, route->path.cost); - - /* prefixlen */ - as_external_lsa->prefix.prefix_length = route->prefix.prefixlen; - - /* PrefixOptions */ - as_external_lsa->prefix.prefix_options = route->path.prefix_options; - - /* don't use refer LS-type */ - as_external_lsa->prefix.prefix_refer_lstype = htons (0); - - /* set Prefix */ - memcpy (p, &route->prefix.u.prefix6, - OSPF6_PREFIX_SPACE (route->prefix.prefixlen)); - ospf6_prefix_apply_mask (&as_external_lsa->prefix); - p += OSPF6_PREFIX_SPACE (route->prefix.prefixlen); - - /* Forwarding address */ - if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F)) - { - memcpy (p, &info->forwarding, sizeof (struct in6_addr)); - p += sizeof (struct in6_addr); - } - - /* External Route Tag */ - if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T)) - { - route_tag_t network_order = htonl(info->tag); - - memcpy (p, &network_order, sizeof(network_order)); - p += sizeof(network_order); - } - - /* Fill LSA Header */ - lsa_header->age = 0; - lsa_header->type = htons (OSPF6_LSTYPE_AS_EXTERNAL); - 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, - lsa_header->adv_router, ospf6->lsdb); - lsa_header->length = htons ((caddr_t) p - (caddr_t) lsa_header); - - /* LSA checksum */ - ospf6_lsa_checksum (lsa_header); - - /* create LSA */ - lsa = ospf6_lsa_create (lsa_header); - - /* Originate */ - ospf6_lsa_originate_process (lsa, ospf6); + char buffer[OSPF6_MAX_LSASIZE]; + struct ospf6_lsa_header *lsa_header; + struct ospf6_lsa *lsa; + struct ospf6_external_info *info = route->route_option; + + struct ospf6_as_external_lsa *as_external_lsa; + char buf[PREFIX2STR_BUFFER]; + caddr_t p; + + if (IS_OSPF6_DEBUG_ASBR || IS_OSPF6_DEBUG_ORIGINATE(AS_EXTERNAL)) { + prefix2str(&route->prefix, buf, sizeof(buf)); + zlog_debug("Originate AS-External-LSA for %s", buf); + } + + /* prepare buffer */ + memset(buffer, 0, sizeof(buffer)); + lsa_header = (struct ospf6_lsa_header *)buffer; + as_external_lsa = (struct ospf6_as_external_lsa + *)((caddr_t)lsa_header + + sizeof(struct ospf6_lsa_header)); + p = (caddr_t)((caddr_t)as_external_lsa + + sizeof(struct ospf6_as_external_lsa)); + + /* Fill AS-External-LSA */ + /* Metric type */ + if (route->path.metric_type == 2) + SET_FLAG(as_external_lsa->bits_metric, OSPF6_ASBR_BIT_E); + else + UNSET_FLAG(as_external_lsa->bits_metric, OSPF6_ASBR_BIT_E); + + /* forwarding address */ + if (!IN6_IS_ADDR_UNSPECIFIED(&info->forwarding)) + SET_FLAG(as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F); + else + UNSET_FLAG(as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F); + + /* external route tag */ + if (info->tag) + SET_FLAG(as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T); + else + UNSET_FLAG(as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T); + + /* Set metric */ + OSPF6_ASBR_METRIC_SET(as_external_lsa, route->path.cost); + + /* prefixlen */ + as_external_lsa->prefix.prefix_length = route->prefix.prefixlen; + + /* PrefixOptions */ + as_external_lsa->prefix.prefix_options = route->path.prefix_options; + + /* don't use refer LS-type */ + as_external_lsa->prefix.prefix_refer_lstype = htons(0); + + /* set Prefix */ + memcpy(p, &route->prefix.u.prefix6, + OSPF6_PREFIX_SPACE(route->prefix.prefixlen)); + ospf6_prefix_apply_mask(&as_external_lsa->prefix); + p += OSPF6_PREFIX_SPACE(route->prefix.prefixlen); + + /* Forwarding address */ + if (CHECK_FLAG(as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F)) { + memcpy(p, &info->forwarding, sizeof(struct in6_addr)); + p += sizeof(struct in6_addr); + } + + /* External Route Tag */ + if (CHECK_FLAG(as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T)) { + route_tag_t network_order = htonl(info->tag); + + memcpy(p, &network_order, sizeof(network_order)); + p += sizeof(network_order); + } + + /* Fill LSA Header */ + lsa_header->age = 0; + lsa_header->type = htons(OSPF6_LSTYPE_AS_EXTERNAL); + 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, + lsa_header->adv_router, ospf6->lsdb); + lsa_header->length = htons((caddr_t)p - (caddr_t)lsa_header); + + /* LSA checksum */ + ospf6_lsa_checksum(lsa_header); + + /* create LSA */ + lsa = ospf6_lsa_create(lsa_header); + + /* Originate */ + ospf6_lsa_originate_process(lsa, ospf6); } -static route_tag_t -ospf6_as_external_lsa_get_tag (struct ospf6_lsa *lsa) +static route_tag_t ospf6_as_external_lsa_get_tag(struct ospf6_lsa *lsa) { - struct ospf6_as_external_lsa *external; - ptrdiff_t tag_offset; - route_tag_t network_order; + struct ospf6_as_external_lsa *external; + ptrdiff_t tag_offset; + route_tag_t network_order; - if (!lsa) - return 0; + if (!lsa) + return 0; - external = (struct ospf6_as_external_lsa *) - OSPF6_LSA_HEADER_END (lsa->header); + external = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END( + lsa->header); - if (!CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_T)) - return 0; + if (!CHECK_FLAG(external->bits_metric, OSPF6_ASBR_BIT_T)) + return 0; - tag_offset = sizeof(*external) + OSPF6_PREFIX_SPACE(external->prefix.prefix_length); - if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F)) - tag_offset += sizeof(struct in6_addr); + tag_offset = sizeof(*external) + + OSPF6_PREFIX_SPACE(external->prefix.prefix_length); + if (CHECK_FLAG(external->bits_metric, OSPF6_ASBR_BIT_F)) + tag_offset += sizeof(struct in6_addr); - memcpy(&network_order, (caddr_t)external + tag_offset, sizeof(network_order)); - return ntohl(network_order); + memcpy(&network_order, (caddr_t)external + tag_offset, + sizeof(network_order)); + return ntohl(network_order); } -void -ospf6_asbr_lsa_add (struct ospf6_lsa *lsa) +void ospf6_asbr_lsa_add(struct ospf6_lsa *lsa) { - struct ospf6_as_external_lsa *external; - struct prefix asbr_id; - struct ospf6_route *asbr_entry, *route; - char buf[PREFIX2STR_BUFFER]; - - external = (struct ospf6_as_external_lsa *) - OSPF6_LSA_HEADER_END (lsa->header); - - if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL)) - zlog_debug ("Calculate AS-External route for %s", lsa->name); - - if (lsa->header->adv_router == ospf6->router_id) - { - if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL)) - zlog_debug ("Ignore self-originated AS-External-LSA"); - return; - } - - if (OSPF6_ASBR_METRIC (external) == OSPF_LS_INFINITY) - { - if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL)) - zlog_debug ("Ignore LSA with LSInfinity Metric"); - return; - } - - if (CHECK_FLAG(external->prefix.prefix_options, OSPF6_PREFIX_OPTION_NU)) - { - if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL)) - zlog_debug ("Ignore LSA with NU bit set Metric"); - return; - } - - ospf6_linkstate_prefix (lsa->header->adv_router, htonl (0), &asbr_id); - asbr_entry = ospf6_route_lookup (&asbr_id, ospf6->brouter_table); - if (asbr_entry == NULL || - ! CHECK_FLAG (asbr_entry->path.router_bits, OSPF6_ROUTER_BIT_E)) - { - if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL)) - { - prefix2str (&asbr_id, buf, sizeof (buf)); - zlog_debug ("ASBR entry not found: %s", buf); - } - return; - } - - route = ospf6_route_create (); - route->type = OSPF6_DEST_TYPE_NETWORK; - route->prefix.family = AF_INET6; - route->prefix.prefixlen = external->prefix.prefix_length; - ospf6_prefix_in6_addr (&route->prefix.u.prefix6, &external->prefix); - - route->path.area_id = asbr_entry->path.area_id; - route->path.origin.type = lsa->header->type; - route->path.origin.id = lsa->header->id; - route->path.origin.adv_router = lsa->header->adv_router; - - route->path.prefix_options = external->prefix.prefix_options; - if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E)) - { - route->path.type = OSPF6_PATH_TYPE_EXTERNAL2; - route->path.metric_type = 2; - route->path.cost = asbr_entry->path.cost; - route->path.u.cost_e2 = OSPF6_ASBR_METRIC (external); - } - else - { - route->path.type = OSPF6_PATH_TYPE_EXTERNAL1; - route->path.metric_type = 1; - route->path.cost = asbr_entry->path.cost + OSPF6_ASBR_METRIC (external); - route->path.u.cost_e2 = 0; - } - - route->path.tag = ospf6_as_external_lsa_get_tag (lsa); - - ospf6_route_copy_nexthops (route, asbr_entry); - - if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL)) - { - prefix2str (&route->prefix, buf, sizeof (buf)); - zlog_debug ("AS-External route add: %s", buf); - } - - ospf6_route_add (route, ospf6->route_table); + struct ospf6_as_external_lsa *external; + struct prefix asbr_id; + struct ospf6_route *asbr_entry, *route; + char buf[PREFIX2STR_BUFFER]; + + external = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END( + lsa->header); + + if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) + zlog_debug("Calculate AS-External route for %s", lsa->name); + + if (lsa->header->adv_router == ospf6->router_id) { + if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) + zlog_debug("Ignore self-originated AS-External-LSA"); + return; + } + + if (OSPF6_ASBR_METRIC(external) == OSPF_LS_INFINITY) { + if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) + zlog_debug("Ignore LSA with LSInfinity Metric"); + return; + } + + if (CHECK_FLAG(external->prefix.prefix_options, + OSPF6_PREFIX_OPTION_NU)) { + if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) + zlog_debug("Ignore LSA with NU bit set Metric"); + return; + } + + ospf6_linkstate_prefix(lsa->header->adv_router, htonl(0), &asbr_id); + asbr_entry = ospf6_route_lookup(&asbr_id, ospf6->brouter_table); + if (asbr_entry == NULL + || !CHECK_FLAG(asbr_entry->path.router_bits, OSPF6_ROUTER_BIT_E)) { + if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) { + prefix2str(&asbr_id, buf, sizeof(buf)); + zlog_debug("ASBR entry not found: %s", buf); + } + return; + } + + route = ospf6_route_create(); + route->type = OSPF6_DEST_TYPE_NETWORK; + route->prefix.family = AF_INET6; + route->prefix.prefixlen = external->prefix.prefix_length; + ospf6_prefix_in6_addr(&route->prefix.u.prefix6, &external->prefix); + + route->path.area_id = asbr_entry->path.area_id; + route->path.origin.type = lsa->header->type; + route->path.origin.id = lsa->header->id; + route->path.origin.adv_router = lsa->header->adv_router; + + route->path.prefix_options = external->prefix.prefix_options; + if (CHECK_FLAG(external->bits_metric, OSPF6_ASBR_BIT_E)) { + route->path.type = OSPF6_PATH_TYPE_EXTERNAL2; + route->path.metric_type = 2; + route->path.cost = asbr_entry->path.cost; + route->path.u.cost_e2 = OSPF6_ASBR_METRIC(external); + } else { + route->path.type = OSPF6_PATH_TYPE_EXTERNAL1; + route->path.metric_type = 1; + route->path.cost = + asbr_entry->path.cost + OSPF6_ASBR_METRIC(external); + route->path.u.cost_e2 = 0; + } + + route->path.tag = ospf6_as_external_lsa_get_tag(lsa); + + ospf6_route_copy_nexthops(route, asbr_entry); + + if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) { + prefix2str(&route->prefix, buf, sizeof(buf)); + zlog_debug("AS-External route add: %s", buf); + } + + ospf6_route_add(route, ospf6->route_table); } -void -ospf6_asbr_lsa_remove (struct ospf6_lsa *lsa) +void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa) { - struct ospf6_as_external_lsa *external; - struct prefix prefix; - struct ospf6_route *route, *nroute; - char buf[PREFIX2STR_BUFFER]; - - external = (struct ospf6_as_external_lsa *) - OSPF6_LSA_HEADER_END (lsa->header); - - if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL)) - zlog_debug ("Withdraw AS-External route for %s", lsa->name); - - if (lsa->header->adv_router == ospf6->router_id) - { - if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL)) - zlog_debug ("Ignore self-originated AS-External-LSA"); - return; - } - - memset (&prefix, 0, sizeof (struct prefix)); - prefix.family = AF_INET6; - prefix.prefixlen = external->prefix.prefix_length; - ospf6_prefix_in6_addr (&prefix.u.prefix6, &external->prefix); - - route = ospf6_route_lookup (&prefix, ospf6->route_table); - if (route == NULL) - { - if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL)) - { - prefix2str (&prefix, buf, sizeof (buf)); - zlog_debug ("AS-External route %s not found", buf); - } - return; - } - - for (ospf6_route_lock (route); - route && ospf6_route_is_prefix (&prefix, route); - route = nroute) - { - nroute = ospf6_route_next (route); - if (route->type != OSPF6_DEST_TYPE_NETWORK) - continue; - if (route->path.origin.type != lsa->header->type) - continue; - if (route->path.origin.id != lsa->header->id) - continue; - if (route->path.origin.adv_router != lsa->header->adv_router) - continue; - - if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL)) - { - prefix2str (&route->prefix, buf, sizeof (buf)); - zlog_debug ("AS-External route remove: %s", buf); - } - ospf6_route_remove (route, ospf6->route_table); - } - if (route != NULL) - ospf6_route_unlock (route); + struct ospf6_as_external_lsa *external; + struct prefix prefix; + struct ospf6_route *route, *nroute; + char buf[PREFIX2STR_BUFFER]; + + external = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END( + lsa->header); + + if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) + zlog_debug("Withdraw AS-External route for %s", lsa->name); + + if (lsa->header->adv_router == ospf6->router_id) { + if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) + zlog_debug("Ignore self-originated AS-External-LSA"); + return; + } + + memset(&prefix, 0, sizeof(struct prefix)); + prefix.family = AF_INET6; + prefix.prefixlen = external->prefix.prefix_length; + ospf6_prefix_in6_addr(&prefix.u.prefix6, &external->prefix); + + route = ospf6_route_lookup(&prefix, ospf6->route_table); + if (route == NULL) { + if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) { + prefix2str(&prefix, buf, sizeof(buf)); + zlog_debug("AS-External route %s not found", buf); + } + return; + } + + for (ospf6_route_lock(route); + route && ospf6_route_is_prefix(&prefix, route); route = nroute) { + nroute = ospf6_route_next(route); + if (route->type != OSPF6_DEST_TYPE_NETWORK) + continue; + if (route->path.origin.type != lsa->header->type) + continue; + if (route->path.origin.id != lsa->header->id) + continue; + if (route->path.origin.adv_router != lsa->header->adv_router) + continue; + + if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) { + prefix2str(&route->prefix, buf, sizeof(buf)); + zlog_debug("AS-External route remove: %s", buf); + } + ospf6_route_remove(route, ospf6->route_table); + } + if (route != NULL) + ospf6_route_unlock(route); } -void -ospf6_asbr_lsentry_add (struct ospf6_route *asbr_entry) +void ospf6_asbr_lsentry_add(struct ospf6_route *asbr_entry) { - struct ospf6_lsa *lsa; - u_int16_t type; - u_int32_t router; - - if (! CHECK_FLAG (asbr_entry->flag, OSPF6_ROUTE_BEST)) - { - char buf[16]; - inet_ntop (AF_INET, &ADV_ROUTER_IN_PREFIX (&asbr_entry->prefix), - buf, sizeof (buf)); - zlog_info ("ignore non-best path: lsentry %s add", buf); - return; - } - - type = htons (OSPF6_LSTYPE_AS_EXTERNAL); - router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix); - for (ALL_LSDB_TYPED_ADVRTR(ospf6->lsdb, type, router, lsa)) - { - if (! OSPF6_LSA_IS_MAXAGE (lsa)) - ospf6_asbr_lsa_add (lsa); - } + struct ospf6_lsa *lsa; + u_int16_t type; + u_int32_t router; + + if (!CHECK_FLAG(asbr_entry->flag, OSPF6_ROUTE_BEST)) { + char buf[16]; + inet_ntop(AF_INET, &ADV_ROUTER_IN_PREFIX(&asbr_entry->prefix), + buf, sizeof(buf)); + zlog_info("ignore non-best path: lsentry %s add", buf); + return; + } + + type = htons(OSPF6_LSTYPE_AS_EXTERNAL); + router = ospf6_linkstate_prefix_adv_router(&asbr_entry->prefix); + for (ALL_LSDB_TYPED_ADVRTR(ospf6->lsdb, type, router, lsa)) { + if (!OSPF6_LSA_IS_MAXAGE(lsa)) + ospf6_asbr_lsa_add(lsa); + } } -void -ospf6_asbr_lsentry_remove (struct ospf6_route *asbr_entry) +void ospf6_asbr_lsentry_remove(struct ospf6_route *asbr_entry) { - struct ospf6_lsa *lsa; - u_int16_t type; - u_int32_t router; - - type = htons (OSPF6_LSTYPE_AS_EXTERNAL); - router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix); - for (ALL_LSDB_TYPED_ADVRTR(ospf6->lsdb, type, router, lsa)) - ospf6_asbr_lsa_remove (lsa); + struct ospf6_lsa *lsa; + u_int16_t type; + u_int32_t router; + + type = htons(OSPF6_LSTYPE_AS_EXTERNAL); + router = ospf6_linkstate_prefix_adv_router(&asbr_entry->prefix); + for (ALL_LSDB_TYPED_ADVRTR(ospf6->lsdb, type, router, lsa)) + ospf6_asbr_lsa_remove(lsa); } - /* redistribute function */ -static void -ospf6_asbr_routemap_set (int type, const char *mapname) +static void ospf6_asbr_routemap_set(int type, const char *mapname) { - if (ospf6->rmap[type].name) - free (ospf6->rmap[type].name); - ospf6->rmap[type].name = strdup (mapname); - ospf6->rmap[type].map = route_map_lookup_by_name (mapname); + if (ospf6->rmap[type].name) + free(ospf6->rmap[type].name); + ospf6->rmap[type].name = strdup(mapname); + ospf6->rmap[type].map = route_map_lookup_by_name(mapname); } -static void -ospf6_asbr_routemap_unset (int type) +static void ospf6_asbr_routemap_unset(int type) { - if (ospf6->rmap[type].name) - free (ospf6->rmap[type].name); - ospf6->rmap[type].name = NULL; - ospf6->rmap[type].map = NULL; + if (ospf6->rmap[type].name) + free(ospf6->rmap[type].name); + ospf6->rmap[type].name = NULL; + ospf6->rmap[type].map = NULL; } -static void -ospf6_asbr_routemap_update (const char *mapname) +static void ospf6_asbr_routemap_update(const char *mapname) { - int type; - - if (ospf6 == NULL) - return; - - for (type = 0; type < ZEBRA_ROUTE_MAX; type++) - { - if (ospf6->rmap[type].name) - ospf6->rmap[type].map = - route_map_lookup_by_name (ospf6->rmap[type].name); - else - ospf6->rmap[type].map = NULL; - } + int type; + + if (ospf6 == NULL) + return; + + for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { + if (ospf6->rmap[type].name) + ospf6->rmap[type].map = route_map_lookup_by_name( + ospf6->rmap[type].name); + else + ospf6->rmap[type].map = NULL; + } } -int -ospf6_asbr_is_asbr (struct ospf6 *o) +int ospf6_asbr_is_asbr(struct ospf6 *o) { - return o->external_table->count; + return o->external_table->count; } -static void -ospf6_asbr_redistribute_set (int type) +static void ospf6_asbr_redistribute_set(int type) { - ospf6_zebra_redistribute (type); + ospf6_zebra_redistribute(type); } -static void -ospf6_asbr_redistribute_unset (int type) +static void ospf6_asbr_redistribute_unset(int type) { - struct ospf6_route *route; - struct ospf6_external_info *info; + struct ospf6_route *route; + struct ospf6_external_info *info; - ospf6_zebra_no_redistribute (type); + ospf6_zebra_no_redistribute(type); - for (route = ospf6_route_head (ospf6->external_table); route; - route = ospf6_route_next (route)) - { - info = route->route_option; - if (info->type != type) - continue; + for (route = ospf6_route_head(ospf6->external_table); route; + route = ospf6_route_next(route)) { + info = route->route_option; + if (info->type != type) + continue; - ospf6_asbr_redistribute_remove (info->type, 0, &route->prefix); - } + ospf6_asbr_redistribute_remove(info->type, 0, &route->prefix); + } - ospf6_asbr_routemap_unset (type); + ospf6_asbr_routemap_unset(type); } /* When an area is unstubified, flood all the external LSAs in the area */ -void -ospf6_asbr_send_externals_to_area (struct ospf6_area *oa) +void ospf6_asbr_send_externals_to_area(struct ospf6_area *oa) { - struct ospf6_lsa *lsa; - - for (ALL_LSDB(oa->ospf6->lsdb, lsa)) - { - if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL) - { - zlog_debug ("%s: Flooding AS-External LSA %s\n", __func__, lsa->name); - ospf6_flood_area (NULL, lsa, oa); + struct ospf6_lsa *lsa; + + for (ALL_LSDB(oa->ospf6->lsdb, lsa)) { + if (ntohs(lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL) { + zlog_debug("%s: Flooding AS-External LSA %s\n", + __func__, lsa->name); + ospf6_flood_area(NULL, lsa, oa); + } } - } } -void -ospf6_asbr_redistribute_add (int type, ifindex_t ifindex, struct prefix *prefix, - u_int nexthop_num, struct in6_addr *nexthop, route_tag_t tag) +void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex, + struct prefix *prefix, u_int nexthop_num, + struct in6_addr *nexthop, route_tag_t tag) { - int ret; - struct ospf6_route troute; - struct ospf6_external_info tinfo; - struct ospf6_route *route, *match; - struct ospf6_external_info *info; - struct prefix prefix_id; - struct route_node *node; - char pbuf[PREFIX2STR_BUFFER], ibuf[16]; - struct listnode *lnode, *lnnode; - struct ospf6_area *oa; - - if (! ospf6_zebra_is_redistribute (type)) - return; - - if (IS_OSPF6_DEBUG_ASBR) - { - prefix2str (prefix, pbuf, sizeof (pbuf)); - zlog_debug ("Redistribute %s (%s)", pbuf, ZROUTE_NAME (type)); - } - - /* if route-map was specified but not found, do not advertise */ - if (ospf6->rmap[type].name) - { - if (ospf6->rmap[type].map == NULL) - ospf6_asbr_routemap_update (NULL); - if (ospf6->rmap[type].map == NULL) - { - zlog_warn ("route-map \"%s\" not found, suppress redistributing", - ospf6->rmap[type].name); - return; - } - } - - /* apply route-map */ - if (ospf6->rmap[type].map) - { - memset (&troute, 0, sizeof (troute)); - memset (&tinfo, 0, sizeof (tinfo)); - troute.route_option = &tinfo; - tinfo.ifindex = ifindex; - tinfo.tag = tag; - - ret = route_map_apply (ospf6->rmap[type].map, prefix, - RMAP_OSPF6, &troute); - if (ret == RMAP_DENYMATCH) - { - if (IS_OSPF6_DEBUG_ASBR) - zlog_debug ("Denied by route-map \"%s\"", ospf6->rmap[type].name); - return; - } - } - - match = ospf6_route_lookup (prefix, ospf6->external_table); - if (match) - { - info = match->route_option; - - /* copy result of route-map */ - if (ospf6->rmap[type].map) - { - if (troute.path.metric_type) - match->path.metric_type = troute.path.metric_type; - if (troute.path.cost) - match->path.cost = troute.path.cost; - if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding)) - memcpy (&info->forwarding, &tinfo.forwarding, - sizeof (struct in6_addr)); - info->tag = tinfo.tag; - } - else - { - /* If there is no route-map, simply update the tag */ - info->tag = tag; - } - - info->type = type; - - if (nexthop_num && nexthop) - ospf6_route_add_nexthop (match, ifindex, nexthop); - else - ospf6_route_add_nexthop (match, ifindex, NULL); - - /* create/update binding in external_id_table */ - prefix_id.family = AF_INET; - prefix_id.prefixlen = 32; - prefix_id.u.prefix4.s_addr = htonl (info->id); - node = route_node_get (ospf6->external_id_table, &prefix_id); - node->info = match; - - if (IS_OSPF6_DEBUG_ASBR) - { - inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf)); - zlog_debug ("Advertise as AS-External Id:%s", ibuf); - } - - match->path.origin.id = htonl (info->id); - ospf6_as_external_lsa_originate (match); - return; - } - - /* create new entry */ - route = ospf6_route_create (); - route->type = OSPF6_DEST_TYPE_NETWORK; - memcpy (&route->prefix, prefix, sizeof (struct prefix)); - - info = (struct ospf6_external_info *) - XCALLOC (MTYPE_OSPF6_EXTERNAL_INFO, sizeof (struct ospf6_external_info)); - route->route_option = info; - info->id = ospf6->external_id++; - - /* copy result of route-map */ - if (ospf6->rmap[type].map) - { - if (troute.path.metric_type) - route->path.metric_type = troute.path.metric_type; - if (troute.path.cost) - route->path.cost = troute.path.cost; - if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding)) - memcpy (&info->forwarding, &tinfo.forwarding, - sizeof (struct in6_addr)); - info->tag = tinfo.tag; - } - else - { - /* If there is no route-map, simply set the tag */ - info->tag = tag; - } - - info->type = type; - if (nexthop_num && nexthop) - ospf6_route_add_nexthop (route, ifindex, nexthop); - else - ospf6_route_add_nexthop (route, ifindex, NULL); - - /* create/update binding in external_id_table */ - prefix_id.family = AF_INET; - prefix_id.prefixlen = 32; - prefix_id.u.prefix4.s_addr = htonl (info->id); - node = route_node_get (ospf6->external_id_table, &prefix_id); - node->info = route; - - route = ospf6_route_add (route, ospf6->external_table); - route->route_option = info; - - if (IS_OSPF6_DEBUG_ASBR) - { - inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf)); - zlog_debug ("Advertise as AS-External Id:%s", ibuf); - } - - route->path.origin.id = htonl (info->id); - ospf6_as_external_lsa_originate (route); - - /* Router-Bit (ASBR Flag) may have to be updated */ - for (ALL_LIST_ELEMENTS (ospf6->area_list, lnode, lnnode, oa)) - OSPF6_ROUTER_LSA_SCHEDULE (oa); + int ret; + struct ospf6_route troute; + struct ospf6_external_info tinfo; + struct ospf6_route *route, *match; + struct ospf6_external_info *info; + struct prefix prefix_id; + struct route_node *node; + char pbuf[PREFIX2STR_BUFFER], ibuf[16]; + struct listnode *lnode, *lnnode; + struct ospf6_area *oa; + + if (!ospf6_zebra_is_redistribute(type)) + return; + + if (IS_OSPF6_DEBUG_ASBR) { + prefix2str(prefix, pbuf, sizeof(pbuf)); + zlog_debug("Redistribute %s (%s)", pbuf, ZROUTE_NAME(type)); + } + + /* if route-map was specified but not found, do not advertise */ + if (ospf6->rmap[type].name) { + if (ospf6->rmap[type].map == NULL) + ospf6_asbr_routemap_update(NULL); + if (ospf6->rmap[type].map == NULL) { + zlog_warn( + "route-map \"%s\" not found, suppress redistributing", + ospf6->rmap[type].name); + return; + } + } + + /* apply route-map */ + if (ospf6->rmap[type].map) { + memset(&troute, 0, sizeof(troute)); + memset(&tinfo, 0, sizeof(tinfo)); + troute.route_option = &tinfo; + tinfo.ifindex = ifindex; + tinfo.tag = tag; + + ret = route_map_apply(ospf6->rmap[type].map, prefix, RMAP_OSPF6, + &troute); + if (ret == RMAP_DENYMATCH) { + if (IS_OSPF6_DEBUG_ASBR) + zlog_debug("Denied by route-map \"%s\"", + ospf6->rmap[type].name); + return; + } + } + + match = ospf6_route_lookup(prefix, ospf6->external_table); + if (match) { + info = match->route_option; + + /* copy result of route-map */ + if (ospf6->rmap[type].map) { + if (troute.path.metric_type) + match->path.metric_type = + troute.path.metric_type; + if (troute.path.cost) + match->path.cost = troute.path.cost; + if (!IN6_IS_ADDR_UNSPECIFIED(&tinfo.forwarding)) + memcpy(&info->forwarding, &tinfo.forwarding, + sizeof(struct in6_addr)); + info->tag = tinfo.tag; + } else { + /* If there is no route-map, simply update the tag */ + info->tag = tag; + } + + info->type = type; + + if (nexthop_num && nexthop) + ospf6_route_add_nexthop(match, ifindex, nexthop); + else + ospf6_route_add_nexthop(match, ifindex, NULL); + + /* create/update binding in external_id_table */ + prefix_id.family = AF_INET; + prefix_id.prefixlen = 32; + prefix_id.u.prefix4.s_addr = htonl(info->id); + node = route_node_get(ospf6->external_id_table, &prefix_id); + node->info = match; + + if (IS_OSPF6_DEBUG_ASBR) { + inet_ntop(AF_INET, &prefix_id.u.prefix4, ibuf, + sizeof(ibuf)); + zlog_debug("Advertise as AS-External Id:%s", ibuf); + } + + match->path.origin.id = htonl(info->id); + ospf6_as_external_lsa_originate(match); + return; + } + + /* create new entry */ + route = ospf6_route_create(); + route->type = OSPF6_DEST_TYPE_NETWORK; + memcpy(&route->prefix, prefix, sizeof(struct prefix)); + + info = (struct ospf6_external_info *)XCALLOC( + MTYPE_OSPF6_EXTERNAL_INFO, sizeof(struct ospf6_external_info)); + route->route_option = info; + info->id = ospf6->external_id++; + + /* copy result of route-map */ + if (ospf6->rmap[type].map) { + if (troute.path.metric_type) + route->path.metric_type = troute.path.metric_type; + if (troute.path.cost) + route->path.cost = troute.path.cost; + if (!IN6_IS_ADDR_UNSPECIFIED(&tinfo.forwarding)) + memcpy(&info->forwarding, &tinfo.forwarding, + sizeof(struct in6_addr)); + info->tag = tinfo.tag; + } else { + /* If there is no route-map, simply set the tag */ + info->tag = tag; + } + + info->type = type; + if (nexthop_num && nexthop) + ospf6_route_add_nexthop(route, ifindex, nexthop); + else + ospf6_route_add_nexthop(route, ifindex, NULL); + + /* create/update binding in external_id_table */ + prefix_id.family = AF_INET; + prefix_id.prefixlen = 32; + prefix_id.u.prefix4.s_addr = htonl(info->id); + node = route_node_get(ospf6->external_id_table, &prefix_id); + node->info = route; + + route = ospf6_route_add(route, ospf6->external_table); + route->route_option = info; + + if (IS_OSPF6_DEBUG_ASBR) { + inet_ntop(AF_INET, &prefix_id.u.prefix4, ibuf, sizeof(ibuf)); + zlog_debug("Advertise as AS-External Id:%s", ibuf); + } + + route->path.origin.id = htonl(info->id); + ospf6_as_external_lsa_originate(route); + + /* Router-Bit (ASBR Flag) may have to be updated */ + for (ALL_LIST_ELEMENTS(ospf6->area_list, lnode, lnnode, oa)) + OSPF6_ROUTER_LSA_SCHEDULE(oa); } -void -ospf6_asbr_redistribute_remove (int type, ifindex_t ifindex, - struct prefix *prefix) +void ospf6_asbr_redistribute_remove(int type, ifindex_t ifindex, + struct prefix *prefix) { - struct ospf6_route *match; - struct ospf6_external_info *info = NULL; - struct route_node *node; - struct ospf6_lsa *lsa; - struct prefix prefix_id; - char pbuf[PREFIX2STR_BUFFER], ibuf[16]; - struct listnode *lnode, *lnnode; - struct ospf6_area *oa; - - match = ospf6_route_lookup (prefix, ospf6->external_table); - if (match == NULL) - { - if (IS_OSPF6_DEBUG_ASBR) - { - prefix2str (prefix, pbuf, sizeof (pbuf)); - zlog_debug ("No such route %s to withdraw", pbuf); - } - return; - } - - info = match->route_option; - assert (info); - - if (info->type != type) - { - if (IS_OSPF6_DEBUG_ASBR) - { - prefix2str (prefix, pbuf, sizeof (pbuf)); - zlog_debug ("Original protocol mismatch: %s", pbuf); - } - return; - } - - if (IS_OSPF6_DEBUG_ASBR) - { - prefix2str (prefix, pbuf, sizeof (pbuf)); - inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf)); - zlog_debug ("Withdraw %s (AS-External Id:%s)", pbuf, ibuf); - } - - lsa = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL), - htonl (info->id), ospf6->router_id, ospf6->lsdb); - if (lsa) - ospf6_lsa_purge (lsa); - - /* remove binding in external_id_table */ - prefix_id.family = AF_INET; - prefix_id.prefixlen = 32; - prefix_id.u.prefix4.s_addr = htonl (info->id); - node = route_node_lookup (ospf6->external_id_table, &prefix_id); - assert (node); - node->info = NULL; - route_unlock_node (node); - - ospf6_route_remove (match, ospf6->external_table); - XFREE (MTYPE_OSPF6_EXTERNAL_INFO, info); - - /* Router-Bit (ASBR Flag) may have to be updated */ - for (ALL_LIST_ELEMENTS (ospf6->area_list, lnode, lnnode, oa)) - OSPF6_ROUTER_LSA_SCHEDULE (oa); + struct ospf6_route *match; + struct ospf6_external_info *info = NULL; + struct route_node *node; + struct ospf6_lsa *lsa; + struct prefix prefix_id; + char pbuf[PREFIX2STR_BUFFER], ibuf[16]; + struct listnode *lnode, *lnnode; + struct ospf6_area *oa; + + match = ospf6_route_lookup(prefix, ospf6->external_table); + if (match == NULL) { + if (IS_OSPF6_DEBUG_ASBR) { + prefix2str(prefix, pbuf, sizeof(pbuf)); + zlog_debug("No such route %s to withdraw", pbuf); + } + return; + } + + info = match->route_option; + assert(info); + + if (info->type != type) { + if (IS_OSPF6_DEBUG_ASBR) { + prefix2str(prefix, pbuf, sizeof(pbuf)); + zlog_debug("Original protocol mismatch: %s", pbuf); + } + return; + } + + if (IS_OSPF6_DEBUG_ASBR) { + prefix2str(prefix, pbuf, sizeof(pbuf)); + inet_ntop(AF_INET, &prefix_id.u.prefix4, ibuf, sizeof(ibuf)); + zlog_debug("Withdraw %s (AS-External Id:%s)", pbuf, ibuf); + } + + lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_AS_EXTERNAL), + htonl(info->id), ospf6->router_id, ospf6->lsdb); + if (lsa) + ospf6_lsa_purge(lsa); + + /* remove binding in external_id_table */ + prefix_id.family = AF_INET; + prefix_id.prefixlen = 32; + prefix_id.u.prefix4.s_addr = htonl(info->id); + node = route_node_lookup(ospf6->external_id_table, &prefix_id); + assert(node); + node->info = NULL; + route_unlock_node(node); + + ospf6_route_remove(match, ospf6->external_table); + XFREE(MTYPE_OSPF6_EXTERNAL_INFO, info); + + /* Router-Bit (ASBR Flag) may have to be updated */ + for (ALL_LIST_ELEMENTS(ospf6->area_list, lnode, lnnode, oa)) + OSPF6_ROUTER_LSA_SCHEDULE(oa); } DEFUN (ospf6_redistribute, @@ -686,16 +638,16 @@ DEFUN (ospf6_redistribute, "Redistribute\n" FRR_REDIST_HELP_STR_OSPF6D) { - int type; + int type; - char *proto = argv[argc - 1]->text; - type = proto_redistnum(AFI_IP6, proto); - if (type < 0) - return CMD_WARNING_CONFIG_FAILED; + char *proto = argv[argc - 1]->text; + type = proto_redistnum(AFI_IP6, proto); + if (type < 0) + return CMD_WARNING_CONFIG_FAILED; - ospf6_asbr_redistribute_unset (type); - ospf6_asbr_redistribute_set (type); - return CMD_SUCCESS; + ospf6_asbr_redistribute_unset(type); + ospf6_asbr_redistribute_set(type); + return CMD_SUCCESS; } DEFUN (ospf6_redistribute_routemap, @@ -706,19 +658,19 @@ DEFUN (ospf6_redistribute_routemap, "Route map reference\n" "Route map name\n") { - int idx_protocol = 1; - int idx_word = 3; - int type; - - char *proto = argv[idx_protocol]->text; - type = proto_redistnum(AFI_IP6, proto); - if (type < 0) - return CMD_WARNING_CONFIG_FAILED; - - ospf6_asbr_redistribute_unset (type); - ospf6_asbr_routemap_set (type, argv[idx_word]->arg); - ospf6_asbr_redistribute_set (type); - return CMD_SUCCESS; + int idx_protocol = 1; + int idx_word = 3; + int type; + + char *proto = argv[idx_protocol]->text; + type = proto_redistnum(AFI_IP6, proto); + if (type < 0) + return CMD_WARNING_CONFIG_FAILED; + + ospf6_asbr_redistribute_unset(type); + ospf6_asbr_routemap_set(type, argv[idx_word]->arg); + ospf6_asbr_redistribute_set(type); + return CMD_SUCCESS; } DEFUN (no_ospf6_redistribute, @@ -730,364 +682,323 @@ DEFUN (no_ospf6_redistribute, "Route map reference\n" "Route map name\n") { - int idx_protocol = 2; - int type; + int idx_protocol = 2; + int type; - char *proto = argv[idx_protocol]->text; - type = proto_redistnum(AFI_IP6, proto); - if (type < 0) - return CMD_WARNING_CONFIG_FAILED; + char *proto = argv[idx_protocol]->text; + type = proto_redistnum(AFI_IP6, proto); + if (type < 0) + return CMD_WARNING_CONFIG_FAILED; - ospf6_asbr_redistribute_unset (type); + ospf6_asbr_redistribute_unset(type); - return CMD_SUCCESS; + return CMD_SUCCESS; } -int -ospf6_redistribute_config_write (struct vty *vty) +int ospf6_redistribute_config_write(struct vty *vty) { - int type; - - for (type = 0; type < ZEBRA_ROUTE_MAX; type++) - { - if (type == ZEBRA_ROUTE_OSPF6) - continue; - if (! ospf6_zebra_is_redistribute (type)) - continue; - - if (ospf6->rmap[type].name) - vty_out (vty, " redistribute %s route-map %s\n", - ZROUTE_NAME (type), ospf6->rmap[type].name); - else - vty_out (vty, " redistribute %s\n", - ZROUTE_NAME (type)); - } - - return 0; + int type; + + for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { + if (type == ZEBRA_ROUTE_OSPF6) + continue; + if (!ospf6_zebra_is_redistribute(type)) + continue; + + if (ospf6->rmap[type].name) + vty_out(vty, " redistribute %s route-map %s\n", + ZROUTE_NAME(type), ospf6->rmap[type].name); + else + vty_out(vty, " redistribute %s\n", ZROUTE_NAME(type)); + } + + return 0; } -static void -ospf6_redistribute_show_config (struct vty *vty) +static void ospf6_redistribute_show_config(struct vty *vty) { - int type; - int nroute[ZEBRA_ROUTE_MAX]; - int total; - struct ospf6_route *route; - struct ospf6_external_info *info; - - total = 0; - for (type = 0; type < ZEBRA_ROUTE_MAX; type++) - nroute[type] = 0; - for (route = ospf6_route_head (ospf6->external_table); route; - route = ospf6_route_next (route)) - { - info = route->route_option; - nroute[info->type]++; - total++; - } - - vty_out (vty, "Redistributing External Routes from:\n"); - for (type = 0; type < ZEBRA_ROUTE_MAX; type++) - { - if (type == ZEBRA_ROUTE_OSPF6) - continue; - if (! ospf6_zebra_is_redistribute (type)) - continue; - - if (ospf6->rmap[type].name) - vty_out (vty, " %d: %s with route-map \"%s\"%s\n", nroute[type], - ZROUTE_NAME (type), ospf6->rmap[type].name, - (ospf6->rmap[type].map ? "" : " (not found !)")); - else - vty_out (vty, " %d: %s\n", nroute[type], - ZROUTE_NAME (type)); - } - vty_out (vty, "Total %d routes\n", total); -} + int type; + int nroute[ZEBRA_ROUTE_MAX]; + int total; + struct ospf6_route *route; + struct ospf6_external_info *info; + + total = 0; + for (type = 0; type < ZEBRA_ROUTE_MAX; type++) + nroute[type] = 0; + for (route = ospf6_route_head(ospf6->external_table); route; + route = ospf6_route_next(route)) { + info = route->route_option; + nroute[info->type]++; + total++; + } + vty_out(vty, "Redistributing External Routes from:\n"); + for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { + if (type == ZEBRA_ROUTE_OSPF6) + continue; + if (!ospf6_zebra_is_redistribute(type)) + continue; + + if (ospf6->rmap[type].name) + vty_out(vty, " %d: %s with route-map \"%s\"%s\n", + nroute[type], ZROUTE_NAME(type), + ospf6->rmap[type].name, + (ospf6->rmap[type].map ? "" + : " (not found !)")); + else + vty_out(vty, " %d: %s\n", nroute[type], + ZROUTE_NAME(type)); + } + vty_out(vty, "Total %d routes\n", total); +} /* Routemap Functions */ static route_map_result_t -ospf6_routemap_rule_match_address_prefixlist (void *rule, - struct prefix *prefix, - route_map_object_t type, - void *object) +ospf6_routemap_rule_match_address_prefixlist(void *rule, struct prefix *prefix, + route_map_object_t type, + void *object) { - struct prefix_list *plist; + struct prefix_list *plist; - if (type != RMAP_OSPF6) - return RMAP_NOMATCH; + if (type != RMAP_OSPF6) + return RMAP_NOMATCH; - plist = prefix_list_lookup (AFI_IP6, (char *) rule); - if (plist == NULL) - return RMAP_NOMATCH; + plist = prefix_list_lookup(AFI_IP6, (char *)rule); + if (plist == NULL) + return RMAP_NOMATCH; - return (prefix_list_apply (plist, prefix) == PREFIX_DENY ? - RMAP_NOMATCH : RMAP_MATCH); + return (prefix_list_apply(plist, prefix) == PREFIX_DENY ? RMAP_NOMATCH + : RMAP_MATCH); } static void * -ospf6_routemap_rule_match_address_prefixlist_compile (const char *arg) +ospf6_routemap_rule_match_address_prefixlist_compile(const char *arg) { - return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); + return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); } -static void -ospf6_routemap_rule_match_address_prefixlist_free (void *rule) +static void ospf6_routemap_rule_match_address_prefixlist_free(void *rule) { - XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); } -struct route_map_rule_cmd -ospf6_routemap_rule_match_address_prefixlist_cmd = -{ - "ipv6 address prefix-list", - ospf6_routemap_rule_match_address_prefixlist, - ospf6_routemap_rule_match_address_prefixlist_compile, - ospf6_routemap_rule_match_address_prefixlist_free, +struct route_map_rule_cmd ospf6_routemap_rule_match_address_prefixlist_cmd = { + "ipv6 address prefix-list", + ospf6_routemap_rule_match_address_prefixlist, + ospf6_routemap_rule_match_address_prefixlist_compile, + ospf6_routemap_rule_match_address_prefixlist_free, }; /* `match interface IFNAME' */ /* Match function should return 1 if match is success else return zero. */ static route_map_result_t -ospf6_routemap_rule_match_interface (void *rule, struct prefix *prefix, - route_map_object_t type, void *object) +ospf6_routemap_rule_match_interface(void *rule, struct prefix *prefix, + route_map_object_t type, void *object) { - struct interface *ifp; - struct ospf6_external_info *ei; + struct interface *ifp; + struct ospf6_external_info *ei; - if (type == RMAP_OSPF6) - { - ei = ((struct ospf6_route *) object)->route_option; - ifp = if_lookup_by_name ((char *)rule, VRF_DEFAULT); + if (type == RMAP_OSPF6) { + ei = ((struct ospf6_route *)object)->route_option; + ifp = if_lookup_by_name((char *)rule, VRF_DEFAULT); - if (ifp != NULL - && ei->ifindex == ifp->ifindex) - return RMAP_MATCH; - } + if (ifp != NULL && ei->ifindex == ifp->ifindex) + return RMAP_MATCH; + } - return RMAP_NOMATCH; + return RMAP_NOMATCH; } /* Route map `interface' match statement. `arg' should be interface name. */ -static void * -ospf6_routemap_rule_match_interface_compile (const char *arg) +static void *ospf6_routemap_rule_match_interface_compile(const char *arg) { - return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); + return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); } /* Free route map's compiled `interface' value. */ -static void -ospf6_routemap_rule_match_interface_free (void *rule) +static void ospf6_routemap_rule_match_interface_free(void *rule) { - XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); } /* Route map commands for interface matching. */ -struct route_map_rule_cmd -ospf6_routemap_rule_match_interface_cmd = -{ - "interface", - ospf6_routemap_rule_match_interface, - ospf6_routemap_rule_match_interface_compile, - ospf6_routemap_rule_match_interface_free -}; +struct route_map_rule_cmd ospf6_routemap_rule_match_interface_cmd = { + "interface", ospf6_routemap_rule_match_interface, + ospf6_routemap_rule_match_interface_compile, + ospf6_routemap_rule_match_interface_free}; /* Match function for matching route tags */ -static route_map_result_t -ospf6_routemap_rule_match_tag (void *rule, struct prefix *prefix, - route_map_object_t type, void *object) +static route_map_result_t ospf6_routemap_rule_match_tag(void *rule, + struct prefix *prefix, + route_map_object_t type, + void *object) { - route_tag_t *tag = rule; - struct ospf6_route *route = object; - struct ospf6_external_info *info = route->route_option; + route_tag_t *tag = rule; + struct ospf6_route *route = object; + struct ospf6_external_info *info = route->route_option; - if (type == RMAP_OSPF6 && info->tag == *tag) - return RMAP_MATCH; + if (type == RMAP_OSPF6 && info->tag == *tag) + return RMAP_MATCH; - return RMAP_NOMATCH; + return RMAP_NOMATCH; } -static struct route_map_rule_cmd -ospf6_routemap_rule_match_tag_cmd = -{ - "tag", - ospf6_routemap_rule_match_tag, - route_map_rule_tag_compile, - route_map_rule_tag_free, +static struct route_map_rule_cmd ospf6_routemap_rule_match_tag_cmd = { + "tag", ospf6_routemap_rule_match_tag, route_map_rule_tag_compile, + route_map_rule_tag_free, }; static route_map_result_t -ospf6_routemap_rule_set_metric_type (void *rule, struct prefix *prefix, - route_map_object_t type, void *object) +ospf6_routemap_rule_set_metric_type(void *rule, struct prefix *prefix, + route_map_object_t type, void *object) { - char *metric_type = rule; - struct ospf6_route *route = object; + char *metric_type = rule; + struct ospf6_route *route = object; - if (type != RMAP_OSPF6) - return RMAP_OKAY; + if (type != RMAP_OSPF6) + return RMAP_OKAY; - if (strcmp (metric_type, "type-2") == 0) - route->path.metric_type = 2; - else - route->path.metric_type = 1; + if (strcmp(metric_type, "type-2") == 0) + route->path.metric_type = 2; + else + route->path.metric_type = 1; - return RMAP_OKAY; + return RMAP_OKAY; } -static void * -ospf6_routemap_rule_set_metric_type_compile (const char *arg) +static void *ospf6_routemap_rule_set_metric_type_compile(const char *arg) { - if (strcmp (arg, "type-2") && strcmp (arg, "type-1")) - return NULL; - return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); + if (strcmp(arg, "type-2") && strcmp(arg, "type-1")) + return NULL; + return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); } -static void -ospf6_routemap_rule_set_metric_type_free (void *rule) +static void ospf6_routemap_rule_set_metric_type_free(void *rule) { - XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); } -struct route_map_rule_cmd -ospf6_routemap_rule_set_metric_type_cmd = -{ - "metric-type", - ospf6_routemap_rule_set_metric_type, - ospf6_routemap_rule_set_metric_type_compile, - ospf6_routemap_rule_set_metric_type_free, +struct route_map_rule_cmd ospf6_routemap_rule_set_metric_type_cmd = { + "metric-type", ospf6_routemap_rule_set_metric_type, + ospf6_routemap_rule_set_metric_type_compile, + ospf6_routemap_rule_set_metric_type_free, }; static route_map_result_t -ospf6_routemap_rule_set_metric (void *rule, struct prefix *prefix, - route_map_object_t type, void *object) +ospf6_routemap_rule_set_metric(void *rule, struct prefix *prefix, + route_map_object_t type, void *object) { - char *metric = rule; - struct ospf6_route *route = object; + char *metric = rule; + struct ospf6_route *route = object; - if (type != RMAP_OSPF6) - return RMAP_OKAY; + if (type != RMAP_OSPF6) + return RMAP_OKAY; - route->path.cost = atoi (metric); - return RMAP_OKAY; + route->path.cost = atoi(metric); + return RMAP_OKAY; } -static void * -ospf6_routemap_rule_set_metric_compile (const char *arg) +static void *ospf6_routemap_rule_set_metric_compile(const char *arg) { - u_int32_t metric; - char *endp; - metric = strtoul (arg, &endp, 0); - if (metric > OSPF_LS_INFINITY || *endp != '\0') - return NULL; - return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); + u_int32_t metric; + char *endp; + metric = strtoul(arg, &endp, 0); + if (metric > OSPF_LS_INFINITY || *endp != '\0') + return NULL; + return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); } -static void -ospf6_routemap_rule_set_metric_free (void *rule) +static void ospf6_routemap_rule_set_metric_free(void *rule) { - XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); } -struct route_map_rule_cmd -ospf6_routemap_rule_set_metric_cmd = -{ - "metric", - ospf6_routemap_rule_set_metric, - ospf6_routemap_rule_set_metric_compile, - ospf6_routemap_rule_set_metric_free, +struct route_map_rule_cmd ospf6_routemap_rule_set_metric_cmd = { + "metric", ospf6_routemap_rule_set_metric, + ospf6_routemap_rule_set_metric_compile, + ospf6_routemap_rule_set_metric_free, }; static route_map_result_t -ospf6_routemap_rule_set_forwarding (void *rule, struct prefix *prefix, - route_map_object_t type, void *object) +ospf6_routemap_rule_set_forwarding(void *rule, struct prefix *prefix, + route_map_object_t type, void *object) { - char *forwarding = rule; - struct ospf6_route *route = object; - struct ospf6_external_info *info = route->route_option; + char *forwarding = rule; + struct ospf6_route *route = object; + struct ospf6_external_info *info = route->route_option; - if (type != RMAP_OSPF6) - return RMAP_OKAY; + if (type != RMAP_OSPF6) + return RMAP_OKAY; - if (inet_pton (AF_INET6, forwarding, &info->forwarding) != 1) - { - memset (&info->forwarding, 0, sizeof (struct in6_addr)); - return RMAP_ERROR; - } + if (inet_pton(AF_INET6, forwarding, &info->forwarding) != 1) { + memset(&info->forwarding, 0, sizeof(struct in6_addr)); + return RMAP_ERROR; + } - return RMAP_OKAY; + return RMAP_OKAY; } -static void * -ospf6_routemap_rule_set_forwarding_compile (const char *arg) +static void *ospf6_routemap_rule_set_forwarding_compile(const char *arg) { - struct in6_addr a; - if (inet_pton (AF_INET6, arg, &a) != 1) - return NULL; - return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); + struct in6_addr a; + if (inet_pton(AF_INET6, arg, &a) != 1) + return NULL; + return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); } -static void -ospf6_routemap_rule_set_forwarding_free (void *rule) +static void ospf6_routemap_rule_set_forwarding_free(void *rule) { - XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); } -struct route_map_rule_cmd -ospf6_routemap_rule_set_forwarding_cmd = -{ - "forwarding-address", - ospf6_routemap_rule_set_forwarding, - ospf6_routemap_rule_set_forwarding_compile, - ospf6_routemap_rule_set_forwarding_free, +struct route_map_rule_cmd ospf6_routemap_rule_set_forwarding_cmd = { + "forwarding-address", ospf6_routemap_rule_set_forwarding, + ospf6_routemap_rule_set_forwarding_compile, + ospf6_routemap_rule_set_forwarding_free, }; -static route_map_result_t -ospf6_routemap_rule_set_tag (void *rule, struct prefix *prefix, - route_map_object_t type, void *object) +static route_map_result_t ospf6_routemap_rule_set_tag(void *rule, + struct prefix *prefix, + route_map_object_t type, + void *object) { - route_tag_t *tag = rule; - struct ospf6_route *route = object; - struct ospf6_external_info *info = route->route_option; + route_tag_t *tag = rule; + struct ospf6_route *route = object; + struct ospf6_external_info *info = route->route_option; - if (type != RMAP_OSPF6) - return RMAP_OKAY; + if (type != RMAP_OSPF6) + return RMAP_OKAY; - info->tag = *tag; - return RMAP_OKAY; + info->tag = *tag; + return RMAP_OKAY; } -static struct route_map_rule_cmd -ospf6_routemap_rule_set_tag_cmd = -{ - "tag", - ospf6_routemap_rule_set_tag, - route_map_rule_tag_compile, - route_map_rule_tag_free, +static struct route_map_rule_cmd ospf6_routemap_rule_set_tag_cmd = { + "tag", ospf6_routemap_rule_set_tag, route_map_rule_tag_compile, + route_map_rule_tag_free, }; -static int -route_map_command_status (struct vty *vty, int ret) +static int route_map_command_status(struct vty *vty, int ret) { - if (! ret) - return CMD_SUCCESS; - - switch (ret) - { - case RMAP_RULE_MISSING: - vty_out (vty, "OSPF6 Can't find rule.\n"); - break; - case RMAP_COMPILE_ERROR: - vty_out (vty, "OSPF6 Argument is malformed.\n"); - break; - default: - vty_out (vty, "OSPF6 route-map add set failed.\n"); - break; - } - return CMD_WARNING_CONFIG_FAILED; + if (!ret) + return CMD_SUCCESS; + + switch (ret) { + case RMAP_RULE_MISSING: + vty_out(vty, "OSPF6 Can't find rule.\n"); + break; + case RMAP_COMPILE_ERROR: + vty_out(vty, "OSPF6 Argument is malformed.\n"); + break; + default: + vty_out(vty, "OSPF6 route-map add set failed.\n"); + break; + } + return CMD_WARNING_CONFIG_FAILED; } /* add "set metric-type" */ @@ -1099,11 +1010,11 @@ DEFUN (ospf6_routemap_set_metric_type, "OSPF6 external type 1 metric\n" "OSPF6 external type 2 metric\n") { - VTY_DECLVAR_CONTEXT(route_map_index, route_map_index); - int idx_external = 2; - int ret = route_map_add_set (route_map_index, - "metric-type", argv[idx_external]->arg); - return route_map_command_status (vty, ret); + VTY_DECLVAR_CONTEXT(route_map_index, route_map_index); + int idx_external = 2; + int ret = route_map_add_set(route_map_index, "metric-type", + argv[idx_external]->arg); + return route_map_command_status(vty, ret); } /* delete "set metric-type" */ @@ -1116,11 +1027,10 @@ DEFUN (ospf6_routemap_no_set_metric_type, "OSPF6 external type 1 metric\n" "OSPF6 external type 2 metric\n") { - VTY_DECLVAR_CONTEXT(route_map_index, route_map_index); - char *ext = (argc == 4) ? argv[3]->text : NULL; - int ret = route_map_delete_set (route_map_index, - "metric-type", ext); - return route_map_command_status (vty, ret); + VTY_DECLVAR_CONTEXT(route_map_index, route_map_index); + char *ext = (argc == 4) ? argv[3]->text : NULL; + int ret = route_map_delete_set(route_map_index, "metric-type", ext); + return route_map_command_status(vty, ret); } /* add "set forwarding-address" */ @@ -1131,11 +1041,11 @@ DEFUN (ospf6_routemap_set_forwarding, "Forwarding Address\n" "IPv6 Address\n") { - VTY_DECLVAR_CONTEXT(route_map_index, route_map_index); - int idx_ipv6 = 2; - int ret = route_map_add_set (route_map_index, - "forwarding-address", argv[idx_ipv6]->arg); - return route_map_command_status (vty, ret); + VTY_DECLVAR_CONTEXT(route_map_index, route_map_index); + int idx_ipv6 = 2; + int ret = route_map_add_set(route_map_index, "forwarding-address", + argv[idx_ipv6]->arg); + return route_map_command_status(vty, ret); } /* delete "set forwarding-address" */ @@ -1147,154 +1057,158 @@ DEFUN (ospf6_routemap_no_set_forwarding, "Forwarding Address\n" "IPv6 Address\n") { - VTY_DECLVAR_CONTEXT(route_map_index, route_map_index); - int idx_ipv6 = 3; - int ret = route_map_delete_set (route_map_index, - "forwarding-address", argv[idx_ipv6]->arg); - return route_map_command_status (vty, ret); + VTY_DECLVAR_CONTEXT(route_map_index, route_map_index); + int idx_ipv6 = 3; + int ret = route_map_delete_set(route_map_index, "forwarding-address", + argv[idx_ipv6]->arg); + return route_map_command_status(vty, ret); } -static void -ospf6_routemap_init (void) +static void ospf6_routemap_init(void) { - route_map_init (); + route_map_init(); - route_map_add_hook (ospf6_asbr_routemap_update); - route_map_delete_hook (ospf6_asbr_routemap_update); + route_map_add_hook(ospf6_asbr_routemap_update); + route_map_delete_hook(ospf6_asbr_routemap_update); - route_map_set_metric_hook (generic_set_add); - route_map_no_set_metric_hook (generic_set_delete); + route_map_set_metric_hook(generic_set_add); + route_map_no_set_metric_hook(generic_set_delete); - route_map_match_tag_hook (generic_match_add); - route_map_no_match_tag_hook (generic_match_delete); + route_map_match_tag_hook(generic_match_add); + route_map_no_match_tag_hook(generic_match_delete); - route_map_match_ipv6_address_prefix_list_hook (generic_match_add); - route_map_no_match_ipv6_address_prefix_list_hook (generic_match_delete); + route_map_match_ipv6_address_prefix_list_hook(generic_match_add); + route_map_no_match_ipv6_address_prefix_list_hook(generic_match_delete); - route_map_match_interface_hook (generic_match_add); - route_map_no_match_interface_hook (generic_match_delete); + route_map_match_interface_hook(generic_match_add); + route_map_no_match_interface_hook(generic_match_delete); - route_map_install_match (&ospf6_routemap_rule_match_address_prefixlist_cmd); - route_map_install_match (&ospf6_routemap_rule_match_interface_cmd); - route_map_install_match (&ospf6_routemap_rule_match_tag_cmd); + route_map_install_match( + &ospf6_routemap_rule_match_address_prefixlist_cmd); + route_map_install_match(&ospf6_routemap_rule_match_interface_cmd); + route_map_install_match(&ospf6_routemap_rule_match_tag_cmd); - route_map_install_set (&ospf6_routemap_rule_set_metric_type_cmd); - route_map_install_set (&ospf6_routemap_rule_set_metric_cmd); - route_map_install_set (&ospf6_routemap_rule_set_forwarding_cmd); - route_map_install_set (&ospf6_routemap_rule_set_tag_cmd); + route_map_install_set(&ospf6_routemap_rule_set_metric_type_cmd); + route_map_install_set(&ospf6_routemap_rule_set_metric_cmd); + route_map_install_set(&ospf6_routemap_rule_set_forwarding_cmd); + route_map_install_set(&ospf6_routemap_rule_set_tag_cmd); - /* ASE Metric Type (e.g. Type-1/Type-2) */ - install_element (RMAP_NODE, &ospf6_routemap_set_metric_type_cmd); - install_element (RMAP_NODE, &ospf6_routemap_no_set_metric_type_cmd); + /* ASE Metric Type (e.g. Type-1/Type-2) */ + install_element(RMAP_NODE, &ospf6_routemap_set_metric_type_cmd); + install_element(RMAP_NODE, &ospf6_routemap_no_set_metric_type_cmd); - /* ASE Metric */ - install_element (RMAP_NODE, &ospf6_routemap_set_forwarding_cmd); - install_element (RMAP_NODE, &ospf6_routemap_no_set_forwarding_cmd); + /* ASE Metric */ + install_element(RMAP_NODE, &ospf6_routemap_set_forwarding_cmd); + install_element(RMAP_NODE, &ospf6_routemap_no_set_forwarding_cmd); } /* Display functions */ -static char * -ospf6_as_external_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf, - int buflen, int pos) +static char *ospf6_as_external_lsa_get_prefix_str(struct ospf6_lsa *lsa, + char *buf, int buflen, + int pos) { - struct ospf6_as_external_lsa *external; - struct in6_addr in6; - int prefix_length = 0; - - if (lsa) - { - external = (struct ospf6_as_external_lsa *) - OSPF6_LSA_HEADER_END (lsa->header); - - if (pos == 0) - { - ospf6_prefix_in6_addr (&in6, &external->prefix); - prefix_length = external->prefix.prefix_length; - } - else { - in6 = *((struct in6_addr *) - ((caddr_t) external + sizeof (struct ospf6_as_external_lsa) + - OSPF6_PREFIX_SPACE (external->prefix.prefix_length))); + struct ospf6_as_external_lsa *external; + struct in6_addr in6; + int prefix_length = 0; + + if (lsa) { + external = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END( + lsa->header); + + if (pos == 0) { + ospf6_prefix_in6_addr(&in6, &external->prefix); + prefix_length = external->prefix.prefix_length; + } else { + in6 = *((struct in6_addr + *)((caddr_t)external + + sizeof(struct + ospf6_as_external_lsa) + + OSPF6_PREFIX_SPACE( + external->prefix + .prefix_length))); + } + if (buf) { + inet_ntop(AF_INET6, &in6, buf, buflen); + if (prefix_length) + sprintf(&buf[strlen(buf)], "/%d", + prefix_length); + } } - if (buf) - { - inet_ntop (AF_INET6, &in6, buf, buflen); - if (prefix_length) - sprintf (&buf[strlen(buf)], "/%d", prefix_length); - } - } - return (buf); + return (buf); } -static int -ospf6_as_external_lsa_show (struct vty *vty, struct ospf6_lsa *lsa) +static int ospf6_as_external_lsa_show(struct vty *vty, struct ospf6_lsa *lsa) { - struct ospf6_as_external_lsa *external; - char buf[64]; - - assert (lsa->header); - external = (struct ospf6_as_external_lsa *) - OSPF6_LSA_HEADER_END (lsa->header); - - /* bits */ - snprintf (buf, sizeof (buf), "%c%c%c", - (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E) ? 'E' : '-'), - (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F) ? 'F' : '-'), - (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_T) ? 'T' : '-')); - - vty_out (vty, " Bits: %s\n", buf); - vty_out (vty, " Metric: %5lu\n", (u_long) OSPF6_ASBR_METRIC (external)); - - ospf6_prefix_options_printbuf (external->prefix.prefix_options, - buf, sizeof (buf)); - vty_out (vty, " Prefix Options: %s\n", buf); - - vty_out (vty, " Referenced LSType: %d\n", - ntohs (external->prefix.prefix_refer_lstype)); - - vty_out (vty, " Prefix: %s\n", - ospf6_as_external_lsa_get_prefix_str (lsa, buf, sizeof(buf), 0)); - - /* Forwarding-Address */ - if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F)) - { - vty_out (vty, " Forwarding-Address: %s\n", - ospf6_as_external_lsa_get_prefix_str (lsa, buf, sizeof(buf), 1)); - } - - /* Tag */ - if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_T)) - { - vty_out (vty, " Tag: %"ROUTE_TAG_PRI"\n", - ospf6_as_external_lsa_get_tag (lsa)); - } - - return 0; + struct ospf6_as_external_lsa *external; + char buf[64]; + + assert(lsa->header); + external = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END( + lsa->header); + + /* bits */ + snprintf(buf, sizeof(buf), "%c%c%c", + (CHECK_FLAG(external->bits_metric, OSPF6_ASBR_BIT_E) ? 'E' + : '-'), + (CHECK_FLAG(external->bits_metric, OSPF6_ASBR_BIT_F) ? 'F' + : '-'), + (CHECK_FLAG(external->bits_metric, OSPF6_ASBR_BIT_T) ? 'T' + : '-')); + + vty_out(vty, " Bits: %s\n", buf); + vty_out(vty, " Metric: %5lu\n", + (u_long)OSPF6_ASBR_METRIC(external)); + + ospf6_prefix_options_printbuf(external->prefix.prefix_options, buf, + sizeof(buf)); + vty_out(vty, " Prefix Options: %s\n", buf); + + vty_out(vty, " Referenced LSType: %d\n", + ntohs(external->prefix.prefix_refer_lstype)); + + vty_out(vty, " Prefix: %s\n", + ospf6_as_external_lsa_get_prefix_str(lsa, buf, sizeof(buf), 0)); + + /* Forwarding-Address */ + if (CHECK_FLAG(external->bits_metric, OSPF6_ASBR_BIT_F)) { + vty_out(vty, " Forwarding-Address: %s\n", + ospf6_as_external_lsa_get_prefix_str(lsa, buf, + sizeof(buf), 1)); + } + + /* Tag */ + if (CHECK_FLAG(external->bits_metric, OSPF6_ASBR_BIT_T)) { + vty_out(vty, " Tag: %" ROUTE_TAG_PRI "\n", + ospf6_as_external_lsa_get_tag(lsa)); + } + + return 0; } -static void -ospf6_asbr_external_route_show (struct vty *vty, struct ospf6_route *route) +static void ospf6_asbr_external_route_show(struct vty *vty, + struct ospf6_route *route) { - struct ospf6_external_info *info = route->route_option; - char prefix[PREFIX2STR_BUFFER], id[16], forwarding[64]; - u_int32_t tmp_id; - - prefix2str (&route->prefix, prefix, sizeof (prefix)); - tmp_id = ntohl (info->id); - inet_ntop (AF_INET, &tmp_id, id, sizeof (id)); - if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding)) - inet_ntop (AF_INET6, &info->forwarding, forwarding, sizeof (forwarding)); - else - snprintf (forwarding, sizeof (forwarding), ":: (ifindex %d)", - ospf6_route_get_first_nh_index (route)); - - vty_out (vty, "%c %-32s %-15s type-%d %5lu %s\n", - zebra_route_char(info->type), - prefix, id, route->path.metric_type, - (u_long) (route->path.metric_type == 2 ? - route->path.u.cost_e2 : route->path.cost), - forwarding); + struct ospf6_external_info *info = route->route_option; + char prefix[PREFIX2STR_BUFFER], id[16], forwarding[64]; + u_int32_t tmp_id; + + prefix2str(&route->prefix, prefix, sizeof(prefix)); + tmp_id = ntohl(info->id); + inet_ntop(AF_INET, &tmp_id, id, sizeof(id)); + if (!IN6_IS_ADDR_UNSPECIFIED(&info->forwarding)) + inet_ntop(AF_INET6, &info->forwarding, forwarding, + sizeof(forwarding)); + else + snprintf(forwarding, sizeof(forwarding), ":: (ifindex %d)", + ospf6_route_get_first_nh_index(route)); + + vty_out(vty, "%c %-32s %-15s type-%d %5lu %s\n", + zebra_route_char(info->type), prefix, id, + route->path.metric_type, + (u_long)(route->path.metric_type == 2 ? route->path.u.cost_e2 + : route->path.cost), + forwarding); } DEFUN (show_ipv6_ospf6_redistribute, @@ -1306,60 +1220,51 @@ DEFUN (show_ipv6_ospf6_redistribute, "redistributing External information\n" ) { - struct ospf6_route *route; + struct ospf6_route *route; - OSPF6_CMD_CHECK_RUNNING (); + OSPF6_CMD_CHECK_RUNNING(); - ospf6_redistribute_show_config (vty); + ospf6_redistribute_show_config(vty); - for (route = ospf6_route_head (ospf6->external_table); route; - route = ospf6_route_next (route)) - ospf6_asbr_external_route_show (vty, route); + for (route = ospf6_route_head(ospf6->external_table); route; + route = ospf6_route_next(route)) + ospf6_asbr_external_route_show(vty, route); - return CMD_SUCCESS; + return CMD_SUCCESS; } -struct ospf6_lsa_handler as_external_handler = -{ - OSPF6_LSTYPE_AS_EXTERNAL, - "AS-External", - "ASE", - ospf6_as_external_lsa_show, - ospf6_as_external_lsa_get_prefix_str -}; +struct ospf6_lsa_handler as_external_handler = { + OSPF6_LSTYPE_AS_EXTERNAL, "AS-External", "ASE", + ospf6_as_external_lsa_show, ospf6_as_external_lsa_get_prefix_str}; -void -ospf6_asbr_init (void) +void ospf6_asbr_init(void) { - ospf6_routemap_init (); + ospf6_routemap_init(); - ospf6_install_lsa_handler (&as_external_handler); + ospf6_install_lsa_handler(&as_external_handler); - install_element (VIEW_NODE, &show_ipv6_ospf6_redistribute_cmd); + install_element(VIEW_NODE, &show_ipv6_ospf6_redistribute_cmd); - install_element (OSPF6_NODE, &ospf6_redistribute_cmd); - install_element (OSPF6_NODE, &ospf6_redistribute_routemap_cmd); - install_element (OSPF6_NODE, &no_ospf6_redistribute_cmd); + install_element(OSPF6_NODE, &ospf6_redistribute_cmd); + install_element(OSPF6_NODE, &ospf6_redistribute_routemap_cmd); + install_element(OSPF6_NODE, &no_ospf6_redistribute_cmd); } -void -ospf6_asbr_redistribute_reset (void) +void ospf6_asbr_redistribute_reset(void) { - int type; - - for (type = 0; type < ZEBRA_ROUTE_MAX; type++) - { - if (type == ZEBRA_ROUTE_OSPF6) - continue; - if (ospf6_zebra_is_redistribute (type)) - ospf6_asbr_redistribute_unset(type); - } + int type; + + for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { + if (type == ZEBRA_ROUTE_OSPF6) + continue; + if (ospf6_zebra_is_redistribute(type)) + ospf6_asbr_redistribute_unset(type); + } } -void -ospf6_asbr_terminate (void) +void ospf6_asbr_terminate(void) { - route_map_finish (); + route_map_finish(); } DEFUN (debug_ospf6_asbr, @@ -1370,8 +1275,8 @@ DEFUN (debug_ospf6_asbr, "Debug OSPFv3 ASBR function\n" ) { - OSPF6_DEBUG_ASBR_ON (); - return CMD_SUCCESS; + OSPF6_DEBUG_ASBR_ON(); + return CMD_SUCCESS; } DEFUN (no_debug_ospf6_asbr, @@ -1383,23 +1288,21 @@ DEFUN (no_debug_ospf6_asbr, "Debug OSPFv3 ASBR function\n" ) { - OSPF6_DEBUG_ASBR_OFF (); - return CMD_SUCCESS; + OSPF6_DEBUG_ASBR_OFF(); + return CMD_SUCCESS; } -int -config_write_ospf6_debug_asbr (struct vty *vty) +int config_write_ospf6_debug_asbr(struct vty *vty) { - if (IS_OSPF6_DEBUG_ASBR) - vty_out (vty, "debug ospf6 asbr\n"); - return 0; + if (IS_OSPF6_DEBUG_ASBR) + vty_out(vty, "debug ospf6 asbr\n"); + return 0; } -void -install_element_ospf6_debug_asbr () +void install_element_ospf6_debug_asbr() { - install_element (ENABLE_NODE, &debug_ospf6_asbr_cmd); - install_element (ENABLE_NODE, &no_debug_ospf6_asbr_cmd); - install_element (CONFIG_NODE, &debug_ospf6_asbr_cmd); - install_element (CONFIG_NODE, &no_debug_ospf6_asbr_cmd); + install_element(ENABLE_NODE, &debug_ospf6_asbr_cmd); + install_element(ENABLE_NODE, &no_debug_ospf6_asbr_cmd); + install_element(CONFIG_NODE, &debug_ospf6_asbr_cmd); + install_element(CONFIG_NODE, &no_debug_ospf6_asbr_cmd); } diff --git a/ospf6d/ospf6_asbr.h b/ospf6d/ospf6_asbr.h index aaa3c72a4..73053452e 100644 --- a/ospf6d/ospf6_asbr.h +++ b/ospf6d/ospf6_asbr.h @@ -30,38 +30,33 @@ /* Debug option */ extern unsigned char conf_debug_ospf6_asbr; -#define OSPF6_DEBUG_ASBR_ON() \ - (conf_debug_ospf6_asbr = 1) -#define OSPF6_DEBUG_ASBR_OFF() \ - (conf_debug_ospf6_asbr = 0) -#define IS_OSPF6_DEBUG_ASBR \ - (conf_debug_ospf6_asbr) +#define OSPF6_DEBUG_ASBR_ON() (conf_debug_ospf6_asbr = 1) +#define OSPF6_DEBUG_ASBR_OFF() (conf_debug_ospf6_asbr = 0) +#define IS_OSPF6_DEBUG_ASBR (conf_debug_ospf6_asbr) -struct ospf6_external_info -{ - /* External route type */ - int type; +struct ospf6_external_info { + /* External route type */ + int type; - /* Originating Link State ID */ - u_int32_t id; + /* Originating Link State ID */ + u_int32_t id; - struct in6_addr forwarding; + struct in6_addr forwarding; - route_tag_t tag; + route_tag_t tag; - ifindex_t ifindex; + ifindex_t ifindex; }; /* AS-External-LSA */ #define OSPF6_AS_EXTERNAL_LSA_MIN_SIZE 4U /* w/o IPv6 prefix */ -struct ospf6_as_external_lsa -{ - u_int32_t bits_metric; - - struct ospf6_prefix prefix; - /* followed by none or one forwarding address */ - /* followed by none or one external route tag */ - /* followed by none or one referenced LS-ID */ +struct ospf6_as_external_lsa { + u_int32_t bits_metric; + + struct ospf6_prefix prefix; + /* followed by none or one forwarding address */ + /* followed by none or one external route tag */ + /* followed by none or one referenced LS-ID */ }; #define OSPF6_ASBR_BIT_T ntohl (0x01000000) @@ -69,32 +64,34 @@ struct ospf6_as_external_lsa #define OSPF6_ASBR_BIT_E ntohl (0x04000000) #define OSPF6_ASBR_METRIC(E) (ntohl ((E)->bits_metric & htonl (0x00ffffff))) -#define OSPF6_ASBR_METRIC_SET(E,C) \ - { (E)->bits_metric &= htonl (0xff000000); \ - (E)->bits_metric |= htonl (0x00ffffff) & htonl (C); } - -extern void ospf6_asbr_lsa_add (struct ospf6_lsa *lsa); -extern void ospf6_asbr_lsa_remove (struct ospf6_lsa *lsa); -extern void ospf6_asbr_lsentry_add (struct ospf6_route *asbr_entry); -extern void ospf6_asbr_lsentry_remove (struct ospf6_route *asbr_entry); - -extern int ospf6_asbr_is_asbr (struct ospf6 *o); -extern void ospf6_asbr_redistribute_add (int type, ifindex_t ifindex, - struct prefix *prefix, - u_int nexthop_num, - struct in6_addr *nexthop, - route_tag_t tag); -extern void ospf6_asbr_redistribute_remove (int type, ifindex_t ifindex, - struct prefix *prefix); - -extern int ospf6_redistribute_config_write (struct vty *vty); - -extern void ospf6_asbr_init (void); -extern void ospf6_asbr_redistribute_reset (void); -extern void ospf6_asbr_terminate (void); -extern void ospf6_asbr_send_externals_to_area (struct ospf6_area *); - -extern int config_write_ospf6_debug_asbr (struct vty *vty); -extern void install_element_ospf6_debug_asbr (void); +#define OSPF6_ASBR_METRIC_SET(E, C) \ + { \ + (E)->bits_metric &= htonl(0xff000000); \ + (E)->bits_metric |= htonl(0x00ffffff) & htonl(C); \ + } + +extern void ospf6_asbr_lsa_add(struct ospf6_lsa *lsa); +extern void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa); +extern void ospf6_asbr_lsentry_add(struct ospf6_route *asbr_entry); +extern void ospf6_asbr_lsentry_remove(struct ospf6_route *asbr_entry); + +extern int ospf6_asbr_is_asbr(struct ospf6 *o); +extern void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex, + struct prefix *prefix, + u_int nexthop_num, + struct in6_addr *nexthop, + route_tag_t tag); +extern void ospf6_asbr_redistribute_remove(int type, ifindex_t ifindex, + struct prefix *prefix); + +extern int ospf6_redistribute_config_write(struct vty *vty); + +extern void ospf6_asbr_init(void); +extern void ospf6_asbr_redistribute_reset(void); +extern void ospf6_asbr_terminate(void); +extern void ospf6_asbr_send_externals_to_area(struct ospf6_area *); + +extern int config_write_ospf6_debug_asbr(struct vty *vty); +extern void install_element_ospf6_debug_asbr(void); #endif /* OSPF6_ASBR_H */ diff --git a/ospf6d/ospf6_bfd.c b/ospf6d/ospf6_bfd.c index f460bf065..fa0030b6d 100644 --- a/ospf6d/ospf6_bfd.c +++ b/ospf6d/ospf6_bfd.c @@ -47,22 +47,20 @@ extern struct zclient *zclient; /* * ospf6_bfd_info_free - Free BFD info structure */ -void -ospf6_bfd_info_free(void **bfd_info) +void ospf6_bfd_info_free(void **bfd_info) { - bfd_info_free((struct bfd_info **) bfd_info); + bfd_info_free((struct bfd_info **)bfd_info); } /* * ospf6_bfd_show_info - Show BFD info structure */ -void -ospf6_bfd_show_info(struct vty *vty, void *bfd_info, int param_only) +void ospf6_bfd_show_info(struct vty *vty, void *bfd_info, int param_only) { - if (param_only) - bfd_show_param(vty, bfd_info, 1, 0, 0, NULL); - else - bfd_show_info(vty, bfd_info, 0, 1, 0, NULL); + if (param_only) + bfd_show_param(vty, bfd_info, 1, 0, 0, NULL); + else + bfd_show_info(vty, bfd_info, 0, 1, 0, NULL); } /* @@ -70,45 +68,44 @@ ospf6_bfd_show_info(struct vty *vty, void *bfd_info, int param_only) * zebra for starting/stopping the monitoring of * the neighbor rechahability. */ -void -ospf6_bfd_reg_dereg_nbr (struct ospf6_neighbor *on, int command) +void ospf6_bfd_reg_dereg_nbr(struct ospf6_neighbor *on, int command) { - struct ospf6_interface *oi = on->ospf6_if; - struct interface *ifp = oi->interface; - struct bfd_info *bfd_info; - char src[64]; - - if (!oi->bfd_info || !on->bfd_info) - return; - bfd_info = (struct bfd_info *)oi->bfd_info; - - if (IS_OSPF6_DEBUG_ZEBRA(SEND)) - { - inet_ntop (AF_INET6, &on->linklocal_addr, src, sizeof (src)); - zlog_debug ("%s nbr (%s) with BFD", - bfd_get_command_dbg_str(command), src); - } - - bfd_peer_sendmsg (zclient, bfd_info, AF_INET6, &on->linklocal_addr, - on->ospf6_if->linklocal_addr, ifp->name, - 0, 0, command, 0, VRF_DEFAULT); - - if (command == ZEBRA_BFD_DEST_DEREGISTER) - bfd_info_free((struct bfd_info **)&on->bfd_info); + struct ospf6_interface *oi = on->ospf6_if; + struct interface *ifp = oi->interface; + struct bfd_info *bfd_info; + char src[64]; + + if (!oi->bfd_info || !on->bfd_info) + return; + bfd_info = (struct bfd_info *)oi->bfd_info; + + if (IS_OSPF6_DEBUG_ZEBRA(SEND)) { + inet_ntop(AF_INET6, &on->linklocal_addr, src, sizeof(src)); + zlog_debug("%s nbr (%s) with BFD", + bfd_get_command_dbg_str(command), src); + } + + bfd_peer_sendmsg(zclient, bfd_info, AF_INET6, &on->linklocal_addr, + on->ospf6_if->linklocal_addr, ifp->name, 0, 0, command, + 0, VRF_DEFAULT); + + if (command == ZEBRA_BFD_DEST_DEREGISTER) + bfd_info_free((struct bfd_info **)&on->bfd_info); } /* * ospf6_bfd_trigger_event - Neighbor is registered/deregistered with BFD when * neighbor state is changed to/from 2way. */ -void -ospf6_bfd_trigger_event(struct ospf6_neighbor *on, int old_state, int state) +void ospf6_bfd_trigger_event(struct ospf6_neighbor *on, int old_state, + int state) { - if ((old_state < OSPF6_NEIGHBOR_TWOWAY) && (state >= OSPF6_NEIGHBOR_TWOWAY)) - ospf6_bfd_reg_dereg_nbr(on, ZEBRA_BFD_DEST_REGISTER); - else if ((old_state >= OSPF6_NEIGHBOR_TWOWAY) && - (state < OSPF6_NEIGHBOR_TWOWAY)) - ospf6_bfd_reg_dereg_nbr(on, ZEBRA_BFD_DEST_DEREGISTER); + if ((old_state < OSPF6_NEIGHBOR_TWOWAY) + && (state >= OSPF6_NEIGHBOR_TWOWAY)) + ospf6_bfd_reg_dereg_nbr(on, ZEBRA_BFD_DEST_REGISTER); + else if ((old_state >= OSPF6_NEIGHBOR_TWOWAY) + && (state < OSPF6_NEIGHBOR_TWOWAY)) + ospf6_bfd_reg_dereg_nbr(on, ZEBRA_BFD_DEST_DEREGISTER); } /* @@ -117,71 +114,66 @@ ospf6_bfd_trigger_event(struct ospf6_neighbor *on, int old_state, int state) * zebra for starting/stopping the monitoring of * the neighbor rechahability. */ -static void -ospf6_bfd_reg_dereg_all_nbr (struct ospf6_interface *oi, int command) +static void ospf6_bfd_reg_dereg_all_nbr(struct ospf6_interface *oi, int command) { - struct ospf6_neighbor *on; - struct listnode *node; - - for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, node, on)) - { - if (command == ZEBRA_BFD_DEST_REGISTER) - ospf6_bfd_info_nbr_create(oi, on); - - if (on->state < OSPF6_NEIGHBOR_TWOWAY) - { - if (command == ZEBRA_BFD_DEST_DEREGISTER) - bfd_info_free((struct bfd_info **)&on->bfd_info); - continue; - } - - ospf6_bfd_reg_dereg_nbr(on, command); - } + struct ospf6_neighbor *on; + struct listnode *node; + + for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, node, on)) { + if (command == ZEBRA_BFD_DEST_REGISTER) + ospf6_bfd_info_nbr_create(oi, on); + + if (on->state < OSPF6_NEIGHBOR_TWOWAY) { + if (command == ZEBRA_BFD_DEST_DEREGISTER) + bfd_info_free( + (struct bfd_info **)&on->bfd_info); + continue; + } + + ospf6_bfd_reg_dereg_nbr(on, command); + } } /* * ospf6_bfd_nbr_replay - Replay all the neighbors that have BFD enabled * to zebra */ -static int -ospf6_bfd_nbr_replay (int command, struct zclient *zclient, zebra_size_t length, - vrf_id_t vrf_id) +static int ospf6_bfd_nbr_replay(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct listnode *inode, *nnode; - struct interface *ifp; - struct ospf6_interface *oi; - struct ospf6_neighbor *on; - char dst[64]; - - if (IS_OSPF6_DEBUG_ZEBRA(RECV)) - zlog_debug("Zebra: BFD Dest replay request"); - - /* Send the client registration */ - bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER); - - /* Replay the neighbor, if BFD is enabled on the interface*/ - for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), inode, ifp)) - { - oi = (struct ospf6_interface *) ifp->info; - - if (!oi || !oi->bfd_info) - continue; - - for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, nnode, on)) - { - if (on->state < OSPF6_NEIGHBOR_TWOWAY) - continue; - - if (IS_OSPF6_DEBUG_ZEBRA(SEND)) - { - inet_ntop (AF_INET6, &on->linklocal_addr, dst, sizeof (dst)); - zlog_debug ("Replaying nbr (%s) to BFD", dst); - } - - ospf6_bfd_reg_dereg_nbr(on, ZEBRA_BFD_DEST_UPDATE); - } - } - return 0; + struct listnode *inode, *nnode; + struct interface *ifp; + struct ospf6_interface *oi; + struct ospf6_neighbor *on; + char dst[64]; + + if (IS_OSPF6_DEBUG_ZEBRA(RECV)) + zlog_debug("Zebra: BFD Dest replay request"); + + /* Send the client registration */ + bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER); + + /* Replay the neighbor, if BFD is enabled on the interface*/ + for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), inode, ifp)) { + oi = (struct ospf6_interface *)ifp->info; + + if (!oi || !oi->bfd_info) + continue; + + for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, nnode, on)) { + if (on->state < OSPF6_NEIGHBOR_TWOWAY) + continue; + + if (IS_OSPF6_DEBUG_ZEBRA(SEND)) { + inet_ntop(AF_INET6, &on->linklocal_addr, dst, + sizeof(dst)); + zlog_debug("Replaying nbr (%s) to BFD", dst); + } + + ospf6_bfd_reg_dereg_nbr(on, ZEBRA_BFD_DEST_UPDATE); + } + } + return 0; } /* @@ -189,134 +181,129 @@ ospf6_bfd_nbr_replay (int command, struct zclient *zclient, zebra_size_t length, * has changed and bring down the neighbor * connectivity if BFD down is received. */ -static int -ospf6_bfd_interface_dest_update (int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int ospf6_bfd_interface_dest_update(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct interface *ifp; - struct ospf6_interface *oi; - struct ospf6_neighbor *on; - struct prefix dp; - struct prefix sp; - struct listnode *node, *nnode; - char dst[64]; - int status; - int old_status; - struct bfd_info *bfd_info; - struct timeval tv; - - ifp = bfd_get_peer_info(zclient->ibuf, &dp, &sp, &status, vrf_id); - - if ((ifp == NULL) || (dp.family != AF_INET6)) - return 0; - - if (IS_OSPF6_DEBUG_ZEBRA (RECV)) - { - char buf[PREFIX2STR_BUFFER]; - prefix2str(&dp, buf, sizeof(buf)); - zlog_debug("Zebra: interface %s bfd destination %s %s", ifp->name, buf, - bfd_get_status_str(status)); - } - - - oi = (struct ospf6_interface *) ifp->info; - if (!oi || !oi->bfd_info) - return 0; - - for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on)) - { - if (memcmp(&(on->linklocal_addr), &dp.u.prefix6, sizeof(struct in6_addr))) - continue; - - if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT)) - { - inet_ntop (AF_INET6, &on->linklocal_addr, dst, sizeof (dst)); - zlog_debug ("[%s:%s]: BFD %s", ifp->name, dst, - bfd_get_status_str(status)); - } - - if (!on->bfd_info) - continue; - - bfd_info = (struct bfd_info *)on->bfd_info; - if (bfd_info->status == status) - continue; - - old_status = bfd_info->status; - bfd_info->status = status; - monotime(&tv); - bfd_info->last_update = tv.tv_sec; - - if ((status == BFD_STATUS_DOWN) && (old_status == BFD_STATUS_UP)) - { - THREAD_OFF (on->inactivity_timer); - thread_add_event(master, inactivity_timer, on, 0, NULL); - } - } - - return 0; + struct interface *ifp; + struct ospf6_interface *oi; + struct ospf6_neighbor *on; + struct prefix dp; + struct prefix sp; + struct listnode *node, *nnode; + char dst[64]; + int status; + int old_status; + struct bfd_info *bfd_info; + struct timeval tv; + + ifp = bfd_get_peer_info(zclient->ibuf, &dp, &sp, &status, vrf_id); + + if ((ifp == NULL) || (dp.family != AF_INET6)) + return 0; + + if (IS_OSPF6_DEBUG_ZEBRA(RECV)) { + char buf[PREFIX2STR_BUFFER]; + prefix2str(&dp, buf, sizeof(buf)); + zlog_debug("Zebra: interface %s bfd destination %s %s", + ifp->name, buf, bfd_get_status_str(status)); + } + + + oi = (struct ospf6_interface *)ifp->info; + if (!oi || !oi->bfd_info) + return 0; + + for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) { + if (memcmp(&(on->linklocal_addr), &dp.u.prefix6, + sizeof(struct in6_addr))) + continue; + + if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) { + inet_ntop(AF_INET6, &on->linklocal_addr, dst, + sizeof(dst)); + zlog_debug("[%s:%s]: BFD %s", ifp->name, dst, + bfd_get_status_str(status)); + } + + if (!on->bfd_info) + continue; + + bfd_info = (struct bfd_info *)on->bfd_info; + if (bfd_info->status == status) + continue; + + old_status = bfd_info->status; + bfd_info->status = status; + monotime(&tv); + bfd_info->last_update = tv.tv_sec; + + if ((status == BFD_STATUS_DOWN) + && (old_status == BFD_STATUS_UP)) { + THREAD_OFF(on->inactivity_timer); + thread_add_event(master, inactivity_timer, on, 0, NULL); + } + } + + return 0; } /* * ospf6_bfd_info_nbr_create - Create/update BFD information for a neighbor. */ -void -ospf6_bfd_info_nbr_create (struct ospf6_interface *oi, - struct ospf6_neighbor *on) +void ospf6_bfd_info_nbr_create(struct ospf6_interface *oi, + struct ospf6_neighbor *on) { - struct bfd_info *oi_bfd_info; - struct bfd_info *on_bfd_info; + struct bfd_info *oi_bfd_info; + struct bfd_info *on_bfd_info; - if (!oi->bfd_info) - return; + if (!oi->bfd_info) + return; - oi_bfd_info = (struct bfd_info *)oi->bfd_info; + oi_bfd_info = (struct bfd_info *)oi->bfd_info; - if (!on->bfd_info) - on->bfd_info = bfd_info_create(); + if (!on->bfd_info) + on->bfd_info = bfd_info_create(); - on_bfd_info = (struct bfd_info *)on->bfd_info; - on_bfd_info->detect_mult = oi_bfd_info->detect_mult; - on_bfd_info->desired_min_tx = oi_bfd_info->desired_min_tx; - on_bfd_info->required_min_rx = oi_bfd_info->required_min_rx; + on_bfd_info = (struct bfd_info *)on->bfd_info; + on_bfd_info->detect_mult = oi_bfd_info->detect_mult; + on_bfd_info->desired_min_tx = oi_bfd_info->desired_min_tx; + on_bfd_info->required_min_rx = oi_bfd_info->required_min_rx; } /* * ospf6_bfd_write_config - Write the interface BFD configuration. */ -void -ospf6_bfd_write_config(struct vty *vty, struct ospf6_interface *oi) +void ospf6_bfd_write_config(struct vty *vty, struct ospf6_interface *oi) { - struct bfd_info *bfd_info; + struct bfd_info *bfd_info; - if (!oi->bfd_info) - return; + if (!oi->bfd_info) + return; - bfd_info = (struct bfd_info *)oi->bfd_info; + bfd_info = (struct bfd_info *)oi->bfd_info; - if (CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG)) - vty_out (vty, " ipv6 ospf6 bfd %d %d %d\n", - bfd_info->detect_mult, bfd_info->required_min_rx, - bfd_info->desired_min_tx); - else - vty_out (vty, " ipv6 ospf6 bfd\n"); + if (CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG)) + vty_out(vty, " ipv6 ospf6 bfd %d %d %d\n", + bfd_info->detect_mult, bfd_info->required_min_rx, + bfd_info->desired_min_tx); + else + vty_out(vty, " ipv6 ospf6 bfd\n"); } /* * ospf6_bfd_if_param_set - Set the configured BFD paramter values for * interface. */ -static void -ospf6_bfd_if_param_set (struct ospf6_interface *oi, u_int32_t min_rx, - u_int32_t min_tx, u_int8_t detect_mult, - int defaults) +static void ospf6_bfd_if_param_set(struct ospf6_interface *oi, u_int32_t min_rx, + u_int32_t min_tx, u_int8_t detect_mult, + int defaults) { - int command = 0; + int command = 0; - bfd_set_param((struct bfd_info **)&(oi->bfd_info), min_rx, min_tx, detect_mult, - defaults, &command); - if (command) - ospf6_bfd_reg_dereg_all_nbr(oi, command); + bfd_set_param((struct bfd_info **)&(oi->bfd_info), min_rx, min_tx, + detect_mult, defaults, &command); + if (command) + ospf6_bfd_reg_dereg_all_nbr(oi, command); } DEFUN (ipv6_ospf6_bfd, @@ -327,18 +314,18 @@ DEFUN (ipv6_ospf6_bfd, "Enables BFD support\n" ) { - VTY_DECLVAR_CONTEXT(interface, ifp); - struct ospf6_interface *oi; - assert (ifp); - - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) - oi = ospf6_interface_create (ifp); - assert (oi); - - ospf6_bfd_if_param_set (oi, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX, - BFD_DEF_DETECT_MULT, 1); - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(interface, ifp); + struct ospf6_interface *oi; + assert(ifp); + + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + oi = ospf6_interface_create(ifp); + assert(oi); + + ospf6_bfd_if_param_set(oi, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX, + BFD_DEF_DETECT_MULT, 1); + return CMD_SUCCESS; } DEFUN (ipv6_ospf6_bfd_param, @@ -351,30 +338,32 @@ DEFUN (ipv6_ospf6_bfd_param, "Required min receive interval\n" "Desired min transmit interval\n") { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx_number = 3; - int idx_number_2 = 4; - int idx_number_3 = 5; - struct ospf6_interface *oi; - u_int32_t rx_val; - u_int32_t tx_val; - u_int8_t dm_val; - int ret; - - assert (ifp); - - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) - oi = ospf6_interface_create (ifp); - assert (oi); - - if ((ret = bfd_validate_param (vty, argv[idx_number]->arg, argv[idx_number_2]->arg, argv[idx_number_3]->arg, &dm_val, - &rx_val, &tx_val)) != CMD_SUCCESS) - return ret; - - ospf6_bfd_if_param_set (oi, rx_val, tx_val, dm_val, 0); - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx_number = 3; + int idx_number_2 = 4; + int idx_number_3 = 5; + struct ospf6_interface *oi; + u_int32_t rx_val; + u_int32_t tx_val; + u_int8_t dm_val; + int ret; + + assert(ifp); + + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + oi = ospf6_interface_create(ifp); + assert(oi); + + if ((ret = bfd_validate_param( + vty, argv[idx_number]->arg, argv[idx_number_2]->arg, + argv[idx_number_3]->arg, &dm_val, &rx_val, &tx_val)) + != CMD_SUCCESS) + return ret; + + ospf6_bfd_if_param_set(oi, rx_val, tx_val, dm_val, 0); + + return CMD_SUCCESS; } DEFUN (no_ipv6_ospf6_bfd, @@ -386,35 +375,33 @@ DEFUN (no_ipv6_ospf6_bfd, "Disables BFD support\n" ) { - VTY_DECLVAR_CONTEXT(interface, ifp); - struct ospf6_interface *oi; - assert (ifp); - - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) - oi = ospf6_interface_create (ifp); - assert (oi); - - if (oi->bfd_info) - { - ospf6_bfd_reg_dereg_all_nbr(oi, ZEBRA_BFD_DEST_DEREGISTER); - bfd_info_free((struct bfd_info **)&(oi->bfd_info)); - } - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(interface, ifp); + struct ospf6_interface *oi; + assert(ifp); + + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + oi = ospf6_interface_create(ifp); + assert(oi); + + if (oi->bfd_info) { + ospf6_bfd_reg_dereg_all_nbr(oi, ZEBRA_BFD_DEST_DEREGISTER); + bfd_info_free((struct bfd_info **)&(oi->bfd_info)); + } + + return CMD_SUCCESS; } -void -ospf6_bfd_init(void) +void ospf6_bfd_init(void) { - bfd_gbl_init(); + bfd_gbl_init(); - /* Initialize BFD client functions */ - zclient->interface_bfd_dest_update = ospf6_bfd_interface_dest_update; - zclient->bfd_dest_replay = ospf6_bfd_nbr_replay; + /* Initialize BFD client functions */ + zclient->interface_bfd_dest_update = ospf6_bfd_interface_dest_update; + zclient->bfd_dest_replay = ospf6_bfd_nbr_replay; - /* Install BFD command */ - install_element (INTERFACE_NODE, &ipv6_ospf6_bfd_cmd); - install_element (INTERFACE_NODE, &ipv6_ospf6_bfd_param_cmd); - install_element (INTERFACE_NODE, &no_ipv6_ospf6_bfd_cmd); + /* Install BFD command */ + install_element(INTERFACE_NODE, &ipv6_ospf6_bfd_cmd); + install_element(INTERFACE_NODE, &ipv6_ospf6_bfd_param_cmd); + install_element(INTERFACE_NODE, &no_ipv6_ospf6_bfd_cmd); } diff --git a/ospf6d/ospf6_bfd.h b/ospf6d/ospf6_bfd.h index 913f7dcf4..19dff1ff7 100644 --- a/ospf6d/ospf6_bfd.h +++ b/ospf6d/ospf6_bfd.h @@ -23,25 +23,20 @@ #ifndef OSPF6_BFD_H #define OSPF6_BFD_H -extern void -ospf6_bfd_init(void); +extern void ospf6_bfd_init(void); -extern void -ospf6_bfd_trigger_event(struct ospf6_neighbor *nbr, int old_state, int state); +extern void ospf6_bfd_trigger_event(struct ospf6_neighbor *nbr, int old_state, + int state); -extern void -ospf6_bfd_write_config(struct vty *vty, struct ospf6_interface *oi); +extern void ospf6_bfd_write_config(struct vty *vty, struct ospf6_interface *oi); -extern void -ospf6_bfd_info_nbr_create (struct ospf6_interface *oi, - struct ospf6_neighbor *on); +extern void ospf6_bfd_info_nbr_create(struct ospf6_interface *oi, + struct ospf6_neighbor *on); -extern void -ospf6_bfd_info_free(void **bfd_info); +extern void ospf6_bfd_info_free(void **bfd_info); -extern void -ospf6_bfd_show_info(struct vty *vty, void *bfd_info, int param_only); +extern void ospf6_bfd_show_info(struct vty *vty, void *bfd_info, + int param_only); -extern void -ospf6_bfd_reg_dereg_nbr (struct ospf6_neighbor *on, int command); +extern void ospf6_bfd_reg_dereg_nbr(struct ospf6_neighbor *on, int command); #endif /* OSPF6_BFD_H */ diff --git a/ospf6d/ospf6_flood.c b/ospf6d/ospf6_flood.c index f816c6f48..42716fbc7 100644 --- a/ospf6d/ospf6_flood.c +++ b/ospf6d/ospf6_flood.c @@ -43,963 +43,933 @@ unsigned char conf_debug_ospf6_flooding; -struct ospf6_lsdb * -ospf6_get_scoped_lsdb (struct ospf6_lsa *lsa) +struct ospf6_lsdb *ospf6_get_scoped_lsdb(struct ospf6_lsa *lsa) { - struct ospf6_lsdb *lsdb = NULL; - switch (OSPF6_LSA_SCOPE (lsa->header->type)) - { - case OSPF6_SCOPE_LINKLOCAL: - lsdb = OSPF6_INTERFACE (lsa->lsdb->data)->lsdb; - break; - case OSPF6_SCOPE_AREA: - lsdb = OSPF6_AREA (lsa->lsdb->data)->lsdb; - break; - case OSPF6_SCOPE_AS: - lsdb = OSPF6_PROCESS (lsa->lsdb->data)->lsdb; - break; - default: - assert (0); - break; - } - return lsdb; + struct ospf6_lsdb *lsdb = NULL; + switch (OSPF6_LSA_SCOPE(lsa->header->type)) { + case OSPF6_SCOPE_LINKLOCAL: + lsdb = OSPF6_INTERFACE(lsa->lsdb->data)->lsdb; + break; + case OSPF6_SCOPE_AREA: + lsdb = OSPF6_AREA(lsa->lsdb->data)->lsdb; + break; + case OSPF6_SCOPE_AS: + lsdb = OSPF6_PROCESS(lsa->lsdb->data)->lsdb; + break; + default: + assert(0); + break; + } + return lsdb; } -struct ospf6_lsdb * -ospf6_get_scoped_lsdb_self (struct ospf6_lsa *lsa) +struct ospf6_lsdb *ospf6_get_scoped_lsdb_self(struct ospf6_lsa *lsa) { - struct ospf6_lsdb *lsdb_self = NULL; - switch (OSPF6_LSA_SCOPE (lsa->header->type)) - { - case OSPF6_SCOPE_LINKLOCAL: - lsdb_self = OSPF6_INTERFACE (lsa->lsdb->data)->lsdb_self; - break; - case OSPF6_SCOPE_AREA: - lsdb_self = OSPF6_AREA (lsa->lsdb->data)->lsdb_self; - break; - case OSPF6_SCOPE_AS: - lsdb_self = OSPF6_PROCESS (lsa->lsdb->data)->lsdb_self; - break; - default: - assert (0); - break; - } - return lsdb_self; + struct ospf6_lsdb *lsdb_self = NULL; + switch (OSPF6_LSA_SCOPE(lsa->header->type)) { + case OSPF6_SCOPE_LINKLOCAL: + lsdb_self = OSPF6_INTERFACE(lsa->lsdb->data)->lsdb_self; + break; + case OSPF6_SCOPE_AREA: + lsdb_self = OSPF6_AREA(lsa->lsdb->data)->lsdb_self; + break; + case OSPF6_SCOPE_AS: + lsdb_self = OSPF6_PROCESS(lsa->lsdb->data)->lsdb_self; + break; + default: + assert(0); + break; + } + return lsdb_self; } -void -ospf6_lsa_originate (struct ospf6_lsa *lsa) +void ospf6_lsa_originate(struct ospf6_lsa *lsa) { - struct ospf6_lsa *old; - struct ospf6_lsdb *lsdb_self; - - /* find previous LSA */ - old = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id, - lsa->header->adv_router, lsa->lsdb); - - /* if the new LSA does not differ from previous, - suppress this update of the LSA */ - if (old && ! OSPF6_LSA_IS_DIFFER (lsa, old)) - { - if (IS_OSPF6_DEBUG_ORIGINATE_TYPE (lsa->header->type)) - zlog_debug ("Suppress updating LSA: %s", lsa->name); - ospf6_lsa_delete (lsa); - return; - } - - /* store it in the LSDB for self-originated LSAs */ - lsdb_self = ospf6_get_scoped_lsdb_self (lsa); - ospf6_lsdb_add (ospf6_lsa_copy (lsa), lsdb_self); - - lsa->refresh = NULL; - thread_add_timer(master, ospf6_lsa_refresh, lsa, OSPF_LS_REFRESH_TIME, - &lsa->refresh); - - if (IS_OSPF6_DEBUG_LSA_TYPE (lsa->header->type) || - IS_OSPF6_DEBUG_ORIGINATE_TYPE (lsa->header->type)) - { - zlog_debug ("LSA Originate:"); - ospf6_lsa_header_print (lsa); - } - - ospf6_install_lsa (lsa); - ospf6_flood (NULL, lsa); + struct ospf6_lsa *old; + struct ospf6_lsdb *lsdb_self; + + /* find previous LSA */ + old = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id, + lsa->header->adv_router, lsa->lsdb); + + /* if the new LSA does not differ from previous, + suppress this update of the LSA */ + if (old && !OSPF6_LSA_IS_DIFFER(lsa, old)) { + if (IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa->header->type)) + zlog_debug("Suppress updating LSA: %s", lsa->name); + ospf6_lsa_delete(lsa); + return; + } + + /* store it in the LSDB for self-originated LSAs */ + lsdb_self = ospf6_get_scoped_lsdb_self(lsa); + ospf6_lsdb_add(ospf6_lsa_copy(lsa), lsdb_self); + + lsa->refresh = NULL; + thread_add_timer(master, ospf6_lsa_refresh, lsa, OSPF_LS_REFRESH_TIME, + &lsa->refresh); + + if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type) + || IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa->header->type)) { + zlog_debug("LSA Originate:"); + ospf6_lsa_header_print(lsa); + } + + ospf6_install_lsa(lsa); + ospf6_flood(NULL, lsa); } -void -ospf6_lsa_originate_process (struct ospf6_lsa *lsa, - struct ospf6 *process) +void ospf6_lsa_originate_process(struct ospf6_lsa *lsa, struct ospf6 *process) { - lsa->lsdb = process->lsdb; - ospf6_lsa_originate (lsa); + lsa->lsdb = process->lsdb; + ospf6_lsa_originate(lsa); } -void -ospf6_lsa_originate_area (struct ospf6_lsa *lsa, - struct ospf6_area *oa) +void ospf6_lsa_originate_area(struct ospf6_lsa *lsa, struct ospf6_area *oa) { - lsa->lsdb = oa->lsdb; - ospf6_lsa_originate (lsa); + lsa->lsdb = oa->lsdb; + ospf6_lsa_originate(lsa); } -void -ospf6_lsa_originate_interface (struct ospf6_lsa *lsa, - struct ospf6_interface *oi) +void ospf6_lsa_originate_interface(struct ospf6_lsa *lsa, + struct ospf6_interface *oi) { - lsa->lsdb = oi->lsdb; - ospf6_lsa_originate (lsa); + lsa->lsdb = oi->lsdb; + ospf6_lsa_originate(lsa); } -void -ospf6_lsa_purge (struct ospf6_lsa *lsa) +void ospf6_lsa_purge(struct ospf6_lsa *lsa) { - struct ospf6_lsa *self; - struct ospf6_lsdb *lsdb_self; - - /* remove it from the LSDB for self-originated LSAs */ - lsdb_self = ospf6_get_scoped_lsdb_self (lsa); - self = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id, - lsa->header->adv_router, lsdb_self); - if (self) - { - THREAD_OFF (self->expire); - THREAD_OFF (self->refresh); - ospf6_lsdb_remove (self, lsdb_self); - } - - ospf6_lsa_premature_aging (lsa); + struct ospf6_lsa *self; + struct ospf6_lsdb *lsdb_self; + + /* remove it from the LSDB for self-originated LSAs */ + lsdb_self = ospf6_get_scoped_lsdb_self(lsa); + self = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id, + lsa->header->adv_router, lsdb_self); + if (self) { + THREAD_OFF(self->expire); + THREAD_OFF(self->refresh); + ospf6_lsdb_remove(self, lsdb_self); + } + + ospf6_lsa_premature_aging(lsa); } -void -ospf6_increment_retrans_count (struct ospf6_lsa *lsa) +void ospf6_increment_retrans_count(struct ospf6_lsa *lsa) { - /* The LSA must be the original one (see the description - in ospf6_decrement_retrans_count () below) */ - lsa->retrans_count++; + /* The LSA must be the original one (see the description + in ospf6_decrement_retrans_count () below) */ + lsa->retrans_count++; } -void -ospf6_decrement_retrans_count (struct ospf6_lsa *lsa) +void ospf6_decrement_retrans_count(struct ospf6_lsa *lsa) { - struct ospf6_lsdb *lsdb; - struct ospf6_lsa *orig; - - /* The LSA must be on the retrans-list of a neighbor. It means - the "lsa" is a copied one, and we have to decrement the - retransmission count of the original one (instead of this "lsa"'s). - In order to find the original LSA, first we have to find - appropriate LSDB that have the original LSA. */ - lsdb = ospf6_get_scoped_lsdb (lsa); - - /* Find the original LSA of which the retrans_count should be decremented */ - orig = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id, - lsa->header->adv_router, lsdb); - if (orig) - { - orig->retrans_count--; - assert (orig->retrans_count >= 0); - } + struct ospf6_lsdb *lsdb; + struct ospf6_lsa *orig; + + /* The LSA must be on the retrans-list of a neighbor. It means + the "lsa" is a copied one, and we have to decrement the + retransmission count of the original one (instead of this "lsa"'s). + In order to find the original LSA, first we have to find + appropriate LSDB that have the original LSA. */ + lsdb = ospf6_get_scoped_lsdb(lsa); + + /* Find the original LSA of which the retrans_count should be + * decremented */ + orig = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id, + lsa->header->adv_router, lsdb); + if (orig) { + orig->retrans_count--; + assert(orig->retrans_count >= 0); + } } /* RFC2328 section 13.2 Installing LSAs in the database */ -void -ospf6_install_lsa (struct ospf6_lsa *lsa) +void ospf6_install_lsa(struct ospf6_lsa *lsa) { - struct timeval now; - struct ospf6_lsa *old; - - if (IS_OSPF6_DEBUG_LSA_TYPE (lsa->header->type) || - IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type)) - zlog_debug ("Install LSA: %s", lsa->name); - - /* Remove the old instance from all neighbors' Link state - retransmission list (RFC2328 13.2 last paragraph) */ - old = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id, - lsa->header->adv_router, lsa->lsdb); - if (old) - { - THREAD_OFF (old->expire); - THREAD_OFF (old->refresh); - ospf6_flood_clear (old); - } - - monotime(&now); - if (! OSPF6_LSA_IS_MAXAGE (lsa)) { - lsa->expire = NULL; - thread_add_timer(master, ospf6_lsa_expire, lsa, OSPF_LSA_MAXAGE + lsa->birth.tv_sec - now.tv_sec, - &lsa->expire); - } - else - lsa->expire = NULL; - - if (OSPF6_LSA_IS_SEQWRAP(lsa) && - ! (CHECK_FLAG(lsa->flag,OSPF6_LSA_SEQWRAPPED) && - lsa->header->seqnum == htonl(OSPF_MAX_SEQUENCE_NUMBER))) - { - if (IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type)) - zlog_debug("lsa install wrapping: sequence 0x%x", - ntohl(lsa->header->seqnum)); - SET_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED); - /* in lieu of premature_aging, since we do not want to recreate this lsa - * and/or mess with timers etc, we just want to wrap the sequence number - * and reflood the lsa before continuing. - * NOTE: Flood needs to be called right after this function call, by the - * caller - */ - lsa->header->seqnum = htonl (OSPF_MAX_SEQUENCE_NUMBER); - lsa->header->age = htons (OSPF_LSA_MAXAGE); - ospf6_lsa_checksum (lsa->header); - } - - /* actually install */ - lsa->installed = now; - ospf6_lsdb_add (lsa, lsa->lsdb); - - return; + struct timeval now; + struct ospf6_lsa *old; + + if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type) + || IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa->header->type)) + zlog_debug("Install LSA: %s", lsa->name); + + /* Remove the old instance from all neighbors' Link state + retransmission list (RFC2328 13.2 last paragraph) */ + old = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id, + lsa->header->adv_router, lsa->lsdb); + if (old) { + THREAD_OFF(old->expire); + THREAD_OFF(old->refresh); + ospf6_flood_clear(old); + } + + monotime(&now); + if (!OSPF6_LSA_IS_MAXAGE(lsa)) { + lsa->expire = NULL; + thread_add_timer(master, ospf6_lsa_expire, lsa, + OSPF_LSA_MAXAGE + lsa->birth.tv_sec + - now.tv_sec, + &lsa->expire); + } else + lsa->expire = NULL; + + if (OSPF6_LSA_IS_SEQWRAP(lsa) + && !(CHECK_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED) + && lsa->header->seqnum == htonl(OSPF_MAX_SEQUENCE_NUMBER))) { + if (IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa->header->type)) + zlog_debug("lsa install wrapping: sequence 0x%x", + ntohl(lsa->header->seqnum)); + SET_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED); + /* in lieu of premature_aging, since we do not want to recreate + * this lsa + * and/or mess with timers etc, we just want to wrap the + * sequence number + * and reflood the lsa before continuing. + * NOTE: Flood needs to be called right after this function + * call, by the + * caller + */ + lsa->header->seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER); + lsa->header->age = htons(OSPF_LSA_MAXAGE); + ospf6_lsa_checksum(lsa->header); + } + + /* actually install */ + lsa->installed = now; + ospf6_lsdb_add(lsa, lsa->lsdb); + + return; } /* RFC2740 section 3.5.2. Sending Link State Update packets */ /* RFC2328 section 13.3 Next step in the flooding procedure */ -static void -ospf6_flood_interface (struct ospf6_neighbor *from, - struct ospf6_lsa *lsa, struct ospf6_interface *oi) +static void ospf6_flood_interface(struct ospf6_neighbor *from, + struct ospf6_lsa *lsa, + struct ospf6_interface *oi) { - struct listnode *node, *nnode; - struct ospf6_neighbor *on; - struct ospf6_lsa *req; - int retrans_added = 0; - int is_debug = 0; - - if (IS_OSPF6_DEBUG_FLOODING || - IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type)) - { - is_debug++; - zlog_debug ("Flooding on %s: %s", oi->interface->name, lsa->name); - } - - /* (1) For each neighbor */ - for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on)) - { - if (is_debug) - zlog_debug ("To neighbor %s", on->name); - - /* (a) if neighbor state < Exchange, examin next */ - if (on->state < OSPF6_NEIGHBOR_EXCHANGE) - { - if (is_debug) - zlog_debug ("Neighbor state less than ExChange, next neighbor"); - continue; - } - - /* (b) if neighbor not yet Full, check request-list */ - if (on->state != OSPF6_NEIGHBOR_FULL) - { - if (is_debug) - zlog_debug ("Neighbor not yet Full"); - - req = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id, - lsa->header->adv_router, on->request_list); - if (req == NULL) - { - if (is_debug) - zlog_debug ("Not on request-list for this neighbor"); - /* fall through */ - } - else - { - /* If new LSA less recent, examin next neighbor */ - if (ospf6_lsa_compare (lsa, req) > 0) - { - if (is_debug) - zlog_debug ("Requesting is older, next neighbor"); - continue; - } - - /* If the same instance, delete from request-list and - examin next neighbor */ - if (ospf6_lsa_compare (lsa, req) == 0) - { - if (is_debug) - zlog_debug ("Requesting the same, remove it, next neighbor"); - if (req == on->last_ls_req) - { - ospf6_lsa_unlock (req); - on->last_ls_req = NULL; - } - ospf6_lsdb_remove (req, on->request_list); - ospf6_check_nbr_loading (on); - continue; - } - - /* If the new LSA is more recent, delete from request-list */ - if (ospf6_lsa_compare (lsa, req) < 0) - { - if (is_debug) - zlog_debug ("Received is newer, remove requesting"); - if (req == on->last_ls_req) - { - ospf6_lsa_unlock (req); - on->last_ls_req = NULL; - } - ospf6_lsdb_remove (req, on->request_list); - ospf6_check_nbr_loading (on); - /* fall through */ - } - } - } - - /* (c) If the new LSA was received from this neighbor, - examin next neighbor */ - if (from == on) - { - if (is_debug) - zlog_debug ("Received is from the neighbor, next neighbor"); - continue; - } - - /* (d) add retrans-list, schedule retransmission */ - if (is_debug) - zlog_debug ("Add retrans-list of this neighbor"); - ospf6_increment_retrans_count (lsa); - ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list); - thread_add_timer(master, ospf6_lsupdate_send_neighbor, on, on->ospf6_if->rxmt_interval, - &on->thread_send_lsupdate); - retrans_added++; - } - - /* (2) examin next interface if not added to retrans-list */ - if (retrans_added == 0) - { - if (is_debug) - zlog_debug ("No retransmission scheduled, next interface"); - return; - } - - /* (3) If the new LSA was received on this interface, - and it was from DR or BDR, examin next interface */ - if (from && from->ospf6_if == oi && - (from->router_id == oi->drouter || from->router_id == oi->bdrouter)) - { - if (is_debug) - zlog_debug ("Received is from the I/F's DR or BDR, next interface"); - return; - } - - /* (4) If the new LSA was received on this interface, - and the interface state is BDR, examin next interface */ - if (from && from->ospf6_if == oi) - { - if (oi->state == OSPF6_INTERFACE_BDR) - { - if (is_debug) - zlog_debug ("Received is from the I/F, itself BDR, next interface"); - return; + struct listnode *node, *nnode; + struct ospf6_neighbor *on; + struct ospf6_lsa *req; + int retrans_added = 0; + int is_debug = 0; + + if (IS_OSPF6_DEBUG_FLOODING + || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa->header->type)) { + is_debug++; + zlog_debug("Flooding on %s: %s", oi->interface->name, + lsa->name); + } + + /* (1) For each neighbor */ + for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) { + if (is_debug) + zlog_debug("To neighbor %s", on->name); + + /* (a) if neighbor state < Exchange, examin next */ + if (on->state < OSPF6_NEIGHBOR_EXCHANGE) { + if (is_debug) + zlog_debug( + "Neighbor state less than ExChange, next neighbor"); + continue; + } + + /* (b) if neighbor not yet Full, check request-list */ + if (on->state != OSPF6_NEIGHBOR_FULL) { + if (is_debug) + zlog_debug("Neighbor not yet Full"); + + req = ospf6_lsdb_lookup( + lsa->header->type, lsa->header->id, + lsa->header->adv_router, on->request_list); + if (req == NULL) { + if (is_debug) + zlog_debug( + "Not on request-list for this neighbor"); + /* fall through */ + } else { + /* If new LSA less recent, examin next neighbor + */ + if (ospf6_lsa_compare(lsa, req) > 0) { + if (is_debug) + zlog_debug( + "Requesting is older, next neighbor"); + continue; + } + + /* If the same instance, delete from + request-list and + examin next neighbor */ + if (ospf6_lsa_compare(lsa, req) == 0) { + if (is_debug) + zlog_debug( + "Requesting the same, remove it, next neighbor"); + if (req == on->last_ls_req) { + ospf6_lsa_unlock(req); + on->last_ls_req = NULL; + } + ospf6_lsdb_remove(req, + on->request_list); + ospf6_check_nbr_loading(on); + continue; + } + + /* If the new LSA is more recent, delete from + * request-list */ + if (ospf6_lsa_compare(lsa, req) < 0) { + if (is_debug) + zlog_debug( + "Received is newer, remove requesting"); + if (req == on->last_ls_req) { + ospf6_lsa_unlock(req); + on->last_ls_req = NULL; + } + ospf6_lsdb_remove(req, + on->request_list); + ospf6_check_nbr_loading(on); + /* fall through */ + } + } + } + + /* (c) If the new LSA was received from this neighbor, + examin next neighbor */ + if (from == on) { + if (is_debug) + zlog_debug( + "Received is from the neighbor, next neighbor"); + continue; + } + + /* (d) add retrans-list, schedule retransmission */ + if (is_debug) + zlog_debug("Add retrans-list of this neighbor"); + ospf6_increment_retrans_count(lsa); + ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list); + thread_add_timer(master, ospf6_lsupdate_send_neighbor, on, + on->ospf6_if->rxmt_interval, + &on->thread_send_lsupdate); + retrans_added++; + } + + /* (2) examin next interface if not added to retrans-list */ + if (retrans_added == 0) { + if (is_debug) + zlog_debug( + "No retransmission scheduled, next interface"); + return; + } + + /* (3) If the new LSA was received on this interface, + and it was from DR or BDR, examin next interface */ + if (from && from->ospf6_if == oi + && (from->router_id == oi->drouter + || from->router_id == oi->bdrouter)) { + if (is_debug) + zlog_debug( + "Received is from the I/F's DR or BDR, next interface"); + return; + } + + /* (4) If the new LSA was received on this interface, + and the interface state is BDR, examin next interface */ + if (from && from->ospf6_if == oi) { + if (oi->state == OSPF6_INTERFACE_BDR) { + if (is_debug) + zlog_debug( + "Received is from the I/F, itself BDR, next interface"); + return; + } + SET_FLAG(lsa->flag, OSPF6_LSA_FLOODBACK); + } + + /* (5) flood the LSA out the interface. */ + if (is_debug) + zlog_debug("Schedule flooding for the interface"); + if ((oi->type == OSPF_IFTYPE_BROADCAST) + || (oi->type == OSPF_IFTYPE_POINTOPOINT)) { + ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsupdate_list); + thread_add_event(master, ospf6_lsupdate_send_interface, oi, 0, + &oi->thread_send_lsupdate); + } else { + /* reschedule retransmissions to all neighbors */ + for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) { + THREAD_OFF(on->thread_send_lsupdate); + on->thread_send_lsupdate = NULL; + thread_add_event(master, ospf6_lsupdate_send_neighbor, + on, 0, &on->thread_send_lsupdate); + } } - SET_FLAG(lsa->flag, OSPF6_LSA_FLOODBACK); - } - - /* (5) flood the LSA out the interface. */ - if (is_debug) - zlog_debug ("Schedule flooding for the interface"); - if ((oi->type == OSPF_IFTYPE_BROADCAST) || - (oi->type == OSPF_IFTYPE_POINTOPOINT)) - { - ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsupdate_list); - thread_add_event(master, ospf6_lsupdate_send_interface, oi, 0, - &oi->thread_send_lsupdate); - } - else - { - /* reschedule retransmissions to all neighbors */ - for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on)) - { - THREAD_OFF (on->thread_send_lsupdate); - on->thread_send_lsupdate = NULL; - thread_add_event(master, ospf6_lsupdate_send_neighbor, on, 0, - &on->thread_send_lsupdate); - } - } } -void -ospf6_flood_area (struct ospf6_neighbor *from, - struct ospf6_lsa *lsa, struct ospf6_area *oa) +void ospf6_flood_area(struct ospf6_neighbor *from, struct ospf6_lsa *lsa, + struct ospf6_area *oa) { - struct listnode *node, *nnode; - struct ospf6_interface *oi; + struct listnode *node, *nnode; + struct ospf6_interface *oi; - for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi)) - { - if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL && - oi != OSPF6_INTERFACE (lsa->lsdb->data)) - continue; + for (ALL_LIST_ELEMENTS(oa->if_list, node, nnode, oi)) { + if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_LINKLOCAL + && oi != OSPF6_INTERFACE(lsa->lsdb->data)) + continue; #if 0 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS && ospf6_is_interface_virtual_link (oi)) continue; -#endif/*0*/ +#endif /*0*/ - ospf6_flood_interface (from, lsa, oi); - } + ospf6_flood_interface(from, lsa, oi); + } } -static void -ospf6_flood_process (struct ospf6_neighbor *from, - struct ospf6_lsa *lsa, struct ospf6 *process) +static void ospf6_flood_process(struct ospf6_neighbor *from, + struct ospf6_lsa *lsa, struct ospf6 *process) { - struct listnode *node, *nnode; - struct ospf6_area *oa; - - for (ALL_LIST_ELEMENTS (process->area_list, node, nnode, oa)) - { - if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AREA && - oa != OSPF6_AREA (lsa->lsdb->data)) - continue; - if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL && - oa != OSPF6_INTERFACE (lsa->lsdb->data)->area) - continue; - - if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL && - IS_AREA_STUB (oa)) - continue; - - ospf6_flood_area (from, lsa, oa); - } + struct listnode *node, *nnode; + struct ospf6_area *oa; + + for (ALL_LIST_ELEMENTS(process->area_list, node, nnode, oa)) { + if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_AREA + && oa != OSPF6_AREA(lsa->lsdb->data)) + continue; + if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_LINKLOCAL + && oa != OSPF6_INTERFACE(lsa->lsdb->data)->area) + continue; + + if (ntohs(lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL + && IS_AREA_STUB(oa)) + continue; + + ospf6_flood_area(from, lsa, oa); + } } -void -ospf6_flood (struct ospf6_neighbor *from, struct ospf6_lsa *lsa) +void ospf6_flood(struct ospf6_neighbor *from, struct ospf6_lsa *lsa) { - ospf6_flood_process (from, lsa, ospf6); + ospf6_flood_process(from, lsa, ospf6); } -static void -ospf6_flood_clear_interface (struct ospf6_lsa *lsa, struct ospf6_interface *oi) +static void ospf6_flood_clear_interface(struct ospf6_lsa *lsa, + struct ospf6_interface *oi) { - struct listnode *node, *nnode; - struct ospf6_neighbor *on; - struct ospf6_lsa *rem; - - for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on)) - { - rem = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id, - lsa->header->adv_router, on->retrans_list); - if (rem && ! ospf6_lsa_compare (rem, lsa)) - { - if (IS_OSPF6_DEBUG_FLOODING || - IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type)) - zlog_debug ("Remove %s from retrans_list of %s", - rem->name, on->name); - ospf6_decrement_retrans_count (rem); - ospf6_lsdb_remove (rem, on->retrans_list); - } - } + struct listnode *node, *nnode; + struct ospf6_neighbor *on; + struct ospf6_lsa *rem; + + for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) { + rem = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id, + lsa->header->adv_router, + on->retrans_list); + if (rem && !ospf6_lsa_compare(rem, lsa)) { + if (IS_OSPF6_DEBUG_FLOODING + || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa->header->type)) + zlog_debug("Remove %s from retrans_list of %s", + rem->name, on->name); + ospf6_decrement_retrans_count(rem); + ospf6_lsdb_remove(rem, on->retrans_list); + } + } } -static void -ospf6_flood_clear_area (struct ospf6_lsa *lsa, struct ospf6_area *oa) +static void ospf6_flood_clear_area(struct ospf6_lsa *lsa, struct ospf6_area *oa) { - struct listnode *node, *nnode; - struct ospf6_interface *oi; + struct listnode *node, *nnode; + struct ospf6_interface *oi; - for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi)) - { - if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL && - oi != OSPF6_INTERFACE (lsa->lsdb->data)) - continue; + for (ALL_LIST_ELEMENTS(oa->if_list, node, nnode, oi)) { + if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_LINKLOCAL + && oi != OSPF6_INTERFACE(lsa->lsdb->data)) + continue; #if 0 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS && ospf6_is_interface_virtual_link (oi)) continue; -#endif/*0*/ +#endif /*0*/ - ospf6_flood_clear_interface (lsa, oi); - } + ospf6_flood_clear_interface(lsa, oi); + } } -static void -ospf6_flood_clear_process (struct ospf6_lsa *lsa, struct ospf6 *process) +static void ospf6_flood_clear_process(struct ospf6_lsa *lsa, + struct ospf6 *process) { - struct listnode *node, *nnode; - struct ospf6_area *oa; - - for (ALL_LIST_ELEMENTS (process->area_list, node, nnode, oa)) - { - if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AREA && - oa != OSPF6_AREA (lsa->lsdb->data)) - continue; - if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL && - oa != OSPF6_INTERFACE (lsa->lsdb->data)->area) - continue; - - if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL && - IS_AREA_STUB (oa)) - continue; - - ospf6_flood_clear_area (lsa, oa); - } + struct listnode *node, *nnode; + struct ospf6_area *oa; + + for (ALL_LIST_ELEMENTS(process->area_list, node, nnode, oa)) { + if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_AREA + && oa != OSPF6_AREA(lsa->lsdb->data)) + continue; + if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_LINKLOCAL + && oa != OSPF6_INTERFACE(lsa->lsdb->data)->area) + continue; + + if (ntohs(lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL + && IS_AREA_STUB(oa)) + continue; + + ospf6_flood_clear_area(lsa, oa); + } } -void -ospf6_flood_clear (struct ospf6_lsa *lsa) +void ospf6_flood_clear(struct ospf6_lsa *lsa) { - ospf6_flood_clear_process (lsa, ospf6); + ospf6_flood_clear_process(lsa, ospf6); } /* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */ -static void -ospf6_acknowledge_lsa_bdrouter (struct ospf6_lsa *lsa, int ismore_recent, - struct ospf6_neighbor *from) +static void ospf6_acknowledge_lsa_bdrouter(struct ospf6_lsa *lsa, + int ismore_recent, + struct ospf6_neighbor *from) { - struct ospf6_interface *oi; - int is_debug = 0; - - if (IS_OSPF6_DEBUG_FLOODING || - IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type)) - is_debug++; - - assert (from && from->ospf6_if); - oi = from->ospf6_if; - - /* LSA is more recent than database copy, but was not flooded - back out receiving interface. Delayed acknowledgement sent - if advertisement received from Designated Router, - otherwide do nothing. */ - if (ismore_recent < 0) - { - if (oi->drouter == from->router_id) - { - if (is_debug) - zlog_debug ("Delayed acknowledgement (BDR & MoreRecent & from DR)"); - /* Delayed acknowledgement */ - ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list); - thread_add_timer(master, ospf6_lsack_send_interface, oi, 3, - &oi->thread_send_lsack); - } - else - { - if (is_debug) - zlog_debug ("No acknowledgement (BDR & MoreRecent & ! from DR)"); - } - return; - } - - /* LSA is a duplicate, and was treated as an implied acknowledgement. - Delayed acknowledgement sent if advertisement received from - Designated Router, otherwise do nothing */ - if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) && - CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK)) - { - if (oi->drouter == from->router_id) - { - if (is_debug) - zlog_debug ("Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)"); - /* Delayed acknowledgement */ - ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list); - thread_add_timer(master, ospf6_lsack_send_interface, oi, 3, - &oi->thread_send_lsack); - } - else - { - if (is_debug) - zlog_debug ("No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)"); - } - return; - } - - /* LSA is a duplicate, and was not treated as an implied acknowledgement. - Direct acknowledgement sent */ - if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) && - ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK)) - { - if (is_debug) - zlog_debug ("Direct acknowledgement (BDR & Duplicate)"); - ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list); - thread_add_event(master, ospf6_lsack_send_neighbor, from, 0, - &from->thread_send_lsack); - return; - } - - /* LSA's LS age is equal to Maxage, and there is no current instance - of the LSA in the link state database, and none of router's - neighbors are in states Exchange or Loading */ - /* Direct acknowledgement sent, but this case is handled in - early of ospf6_receive_lsa () */ + struct ospf6_interface *oi; + int is_debug = 0; + + if (IS_OSPF6_DEBUG_FLOODING + || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa->header->type)) + is_debug++; + + assert(from && from->ospf6_if); + oi = from->ospf6_if; + + /* LSA is more recent than database copy, but was not flooded + back out receiving interface. Delayed acknowledgement sent + if advertisement received from Designated Router, + otherwide do nothing. */ + if (ismore_recent < 0) { + if (oi->drouter == from->router_id) { + if (is_debug) + zlog_debug( + "Delayed acknowledgement (BDR & MoreRecent & from DR)"); + /* Delayed acknowledgement */ + ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsack_list); + thread_add_timer(master, ospf6_lsack_send_interface, oi, + 3, &oi->thread_send_lsack); + } else { + if (is_debug) + zlog_debug( + "No acknowledgement (BDR & MoreRecent & ! from DR)"); + } + return; + } + + /* LSA is a duplicate, and was treated as an implied acknowledgement. + Delayed acknowledgement sent if advertisement received from + Designated Router, otherwise do nothing */ + if (CHECK_FLAG(lsa->flag, OSPF6_LSA_DUPLICATE) + && CHECK_FLAG(lsa->flag, OSPF6_LSA_IMPLIEDACK)) { + if (oi->drouter == from->router_id) { + if (is_debug) + zlog_debug( + "Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)"); + /* Delayed acknowledgement */ + ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsack_list); + thread_add_timer(master, ospf6_lsack_send_interface, oi, + 3, &oi->thread_send_lsack); + } else { + if (is_debug) + zlog_debug( + "No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)"); + } + return; + } + + /* LSA is a duplicate, and was not treated as an implied + acknowledgement. + Direct acknowledgement sent */ + if (CHECK_FLAG(lsa->flag, OSPF6_LSA_DUPLICATE) + && !CHECK_FLAG(lsa->flag, OSPF6_LSA_IMPLIEDACK)) { + if (is_debug) + zlog_debug("Direct acknowledgement (BDR & Duplicate)"); + ospf6_lsdb_add(ospf6_lsa_copy(lsa), from->lsack_list); + thread_add_event(master, ospf6_lsack_send_neighbor, from, 0, + &from->thread_send_lsack); + return; + } + + /* LSA's LS age is equal to Maxage, and there is no current instance + of the LSA in the link state database, and none of router's + neighbors are in states Exchange or Loading */ + /* Direct acknowledgement sent, but this case is handled in + early of ospf6_receive_lsa () */ } -static void -ospf6_acknowledge_lsa_allother (struct ospf6_lsa *lsa, int ismore_recent, - struct ospf6_neighbor *from) +static void ospf6_acknowledge_lsa_allother(struct ospf6_lsa *lsa, + int ismore_recent, + struct ospf6_neighbor *from) { - struct ospf6_interface *oi; - int is_debug = 0; - - if (IS_OSPF6_DEBUG_FLOODING || - IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type)) - is_debug++; - - assert (from && from->ospf6_if); - oi = from->ospf6_if; - - /* LSA has been flood back out receiving interface. - No acknowledgement sent. */ - if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK)) - { - if (is_debug) - zlog_debug ("No acknowledgement (AllOther & FloodBack)"); - return; - } - - /* LSA is more recent than database copy, but was not flooded - back out receiving interface. Delayed acknowledgement sent. */ - if (ismore_recent < 0) - { - if (is_debug) - zlog_debug ("Delayed acknowledgement (AllOther & MoreRecent)"); - /* Delayed acknowledgement */ - ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list); - thread_add_timer(master, ospf6_lsack_send_interface, oi, 3, - &oi->thread_send_lsack); - return; - } - - /* LSA is a duplicate, and was treated as an implied acknowledgement. - No acknowledgement sent. */ - if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) && - CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK)) - { - if (is_debug) - zlog_debug ("No acknowledgement (AllOther & Duplicate & ImpliedAck)"); - return; - } - - /* LSA is a duplicate, and was not treated as an implied acknowledgement. - Direct acknowledgement sent */ - if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) && - ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK)) - { - if (is_debug) - zlog_debug ("Direct acknowledgement (AllOther & Duplicate)"); - ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list); - thread_add_event(master, ospf6_lsack_send_neighbor, from, 0, - &from->thread_send_lsack); - return; - } - - /* LSA's LS age is equal to Maxage, and there is no current instance - of the LSA in the link state database, and none of router's - neighbors are in states Exchange or Loading */ - /* Direct acknowledgement sent, but this case is handled in - early of ospf6_receive_lsa () */ + struct ospf6_interface *oi; + int is_debug = 0; + + if (IS_OSPF6_DEBUG_FLOODING + || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa->header->type)) + is_debug++; + + assert(from && from->ospf6_if); + oi = from->ospf6_if; + + /* LSA has been flood back out receiving interface. + No acknowledgement sent. */ + if (CHECK_FLAG(lsa->flag, OSPF6_LSA_FLOODBACK)) { + if (is_debug) + zlog_debug("No acknowledgement (AllOther & FloodBack)"); + return; + } + + /* LSA is more recent than database copy, but was not flooded + back out receiving interface. Delayed acknowledgement sent. */ + if (ismore_recent < 0) { + if (is_debug) + zlog_debug( + "Delayed acknowledgement (AllOther & MoreRecent)"); + /* Delayed acknowledgement */ + ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsack_list); + thread_add_timer(master, ospf6_lsack_send_interface, oi, 3, + &oi->thread_send_lsack); + return; + } + + /* LSA is a duplicate, and was treated as an implied acknowledgement. + No acknowledgement sent. */ + if (CHECK_FLAG(lsa->flag, OSPF6_LSA_DUPLICATE) + && CHECK_FLAG(lsa->flag, OSPF6_LSA_IMPLIEDACK)) { + if (is_debug) + zlog_debug( + "No acknowledgement (AllOther & Duplicate & ImpliedAck)"); + return; + } + + /* LSA is a duplicate, and was not treated as an implied + acknowledgement. + Direct acknowledgement sent */ + if (CHECK_FLAG(lsa->flag, OSPF6_LSA_DUPLICATE) + && !CHECK_FLAG(lsa->flag, OSPF6_LSA_IMPLIEDACK)) { + if (is_debug) + zlog_debug( + "Direct acknowledgement (AllOther & Duplicate)"); + ospf6_lsdb_add(ospf6_lsa_copy(lsa), from->lsack_list); + thread_add_event(master, ospf6_lsack_send_neighbor, from, 0, + &from->thread_send_lsack); + return; + } + + /* LSA's LS age is equal to Maxage, and there is no current instance + of the LSA in the link state database, and none of router's + neighbors are in states Exchange or Loading */ + /* Direct acknowledgement sent, but this case is handled in + early of ospf6_receive_lsa () */ } -static void -ospf6_acknowledge_lsa (struct ospf6_lsa *lsa, int ismore_recent, - struct ospf6_neighbor *from) +static void ospf6_acknowledge_lsa(struct ospf6_lsa *lsa, int ismore_recent, + struct ospf6_neighbor *from) { - struct ospf6_interface *oi; + struct ospf6_interface *oi; - assert (from && from->ospf6_if); - oi = from->ospf6_if; + assert(from && from->ospf6_if); + oi = from->ospf6_if; - if (oi->state == OSPF6_INTERFACE_BDR) - ospf6_acknowledge_lsa_bdrouter (lsa, ismore_recent, from); - else - ospf6_acknowledge_lsa_allother (lsa, ismore_recent, from); + if (oi->state == OSPF6_INTERFACE_BDR) + ospf6_acknowledge_lsa_bdrouter(lsa, ismore_recent, from); + else + ospf6_acknowledge_lsa_allother(lsa, ismore_recent, from); } /* RFC2328 section 13 (4): if MaxAge LSA and if we have no instance, and no neighbor is in states Exchange or Loading returns 1 if match this case, else returns 0 */ -static int -ospf6_is_maxage_lsa_drop (struct ospf6_lsa *lsa, struct ospf6_neighbor *from) +static int ospf6_is_maxage_lsa_drop(struct ospf6_lsa *lsa, + struct ospf6_neighbor *from) { - struct ospf6_neighbor *on; - struct ospf6_interface *oi; - struct ospf6_area *oa; - struct ospf6 *process = NULL; - struct listnode *i, *j, *k; - int count = 0; - - if (! OSPF6_LSA_IS_MAXAGE (lsa)) - return 0; - - if (ospf6_lsdb_lookup (lsa->header->type, lsa->header->id, - lsa->header->adv_router, lsa->lsdb)) - return 0; - - process = from->ospf6_if->area->ospf6; - - for (ALL_LIST_ELEMENTS_RO (process->area_list, i, oa)) - for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi)) - for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, k, on)) - if (on->state == OSPF6_NEIGHBOR_EXCHANGE || - on->state == OSPF6_NEIGHBOR_LOADING) - count++; - - if (count == 0) - return 1; - return 0; + struct ospf6_neighbor *on; + struct ospf6_interface *oi; + struct ospf6_area *oa; + struct ospf6 *process = NULL; + struct listnode *i, *j, *k; + int count = 0; + + if (!OSPF6_LSA_IS_MAXAGE(lsa)) + return 0; + + if (ospf6_lsdb_lookup(lsa->header->type, lsa->header->id, + lsa->header->adv_router, lsa->lsdb)) + return 0; + + process = from->ospf6_if->area->ospf6; + + for (ALL_LIST_ELEMENTS_RO(process->area_list, i, oa)) + for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) + for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, k, on)) + if (on->state == OSPF6_NEIGHBOR_EXCHANGE + || on->state == OSPF6_NEIGHBOR_LOADING) + count++; + + if (count == 0) + return 1; + return 0; } /* RFC2328 section 13 The Flooding Procedure */ -void -ospf6_receive_lsa (struct ospf6_neighbor *from, - struct ospf6_lsa_header *lsa_header) +void ospf6_receive_lsa(struct ospf6_neighbor *from, + struct ospf6_lsa_header *lsa_header) { - struct ospf6_lsa *new = NULL, *old = NULL, *rem = NULL; - int ismore_recent; - int is_debug = 0; - unsigned int time_delta_ms; - - ismore_recent = 1; - assert (from); - - /* make lsa structure for received lsa */ - new = ospf6_lsa_create (lsa_header); - - if (IS_OSPF6_DEBUG_FLOODING || - IS_OSPF6_DEBUG_FLOOD_TYPE (new->header->type)) - { - is_debug++; - zlog_debug ("LSA Receive from %s", from->name); - ospf6_lsa_header_print (new); - } - - /* (1) LSA Checksum */ - if (! ospf6_lsa_checksum_valid (new->header)) - { - if (is_debug) - zlog_debug ("Wrong LSA Checksum, discard"); - ospf6_lsa_delete (new); - return; - } - - /* (2) Examine the LSA's LS type. - RFC2470 3.5.1. Receiving Link State Update packets */ - if (IS_AREA_STUB (from->ospf6_if->area) && - OSPF6_LSA_SCOPE (new->header->type) == OSPF6_SCOPE_AS) - { - if (is_debug) - zlog_debug ("AS-External-LSA (or AS-scope LSA) in stub area, discard"); - ospf6_lsa_delete (new); - return; - } - - /* (3) LSA which have reserved scope is discarded - RFC2470 3.5.1. Receiving Link State Update packets */ - /* Flooding scope check. LSAs with unknown scope are discarded here. - Set appropriate LSDB for the LSA */ - switch (OSPF6_LSA_SCOPE (new->header->type)) - { - case OSPF6_SCOPE_LINKLOCAL: - new->lsdb = from->ospf6_if->lsdb; - break; - case OSPF6_SCOPE_AREA: - new->lsdb = from->ospf6_if->area->lsdb; - break; - case OSPF6_SCOPE_AS: - new->lsdb = from->ospf6_if->area->ospf6->lsdb; - break; - default: - if (is_debug) - zlog_debug ("LSA has reserved scope, discard"); - ospf6_lsa_delete (new); - return; - } - - /* (4) if MaxAge LSA and if we have no instance, and no neighbor - is in states Exchange or Loading */ - if (ospf6_is_maxage_lsa_drop (new, from)) - { - /* log */ - if (is_debug) - zlog_debug ("Drop MaxAge LSA with direct acknowledgement."); - - /* a) Acknowledge back to neighbor (Direct acknowledgement, 13.5) */ - ospf6_lsdb_add (ospf6_lsa_copy (new), from->lsack_list); - thread_add_event(master, ospf6_lsack_send_neighbor, from, 0, - &from->thread_send_lsack); - - /* b) Discard */ - ospf6_lsa_delete (new); - return; - } - - /* (5) */ - /* lookup the same database copy in lsdb */ - old = ospf6_lsdb_lookup (new->header->type, new->header->id, - new->header->adv_router, new->lsdb); - if (old) - { - ismore_recent = ospf6_lsa_compare (new, old); - if (ntohl (new->header->seqnum) == ntohl (old->header->seqnum)) - { - if (is_debug) - zlog_debug ("Received is duplicated LSA"); - SET_FLAG (new->flag, OSPF6_LSA_DUPLICATE); - } - } - - /* if no database copy or received is more recent */ - if (old == NULL || ismore_recent < 0) - { - /* in case we have no database copy */ - ismore_recent = -1; - - /* (a) MinLSArrival check */ - if (old) - { - struct timeval now, res; - monotime(&now); - timersub (&now, &old->installed, &res); - time_delta_ms = (res.tv_sec * 1000) + (int)(res.tv_usec/1000); - if (time_delta_ms < from->ospf6_if->area->ospf6->lsa_minarrival) - { - if (is_debug) - zlog_debug ("LSA can't be updated within MinLSArrival, %dms < %dms, discard", - time_delta_ms, from->ospf6_if->area->ospf6->lsa_minarrival); - ospf6_lsa_delete (new); - return; /* examin next lsa */ - } - } - - monotime(&new->received); - - if (is_debug) - zlog_debug ("Install, Flood, Possibly acknowledge the received LSA"); - - /* Remove older copies of this LSA from retx lists */ - if (old) - ospf6_flood_clear (old); - - /* (b) immediately flood and (c) remove from all retrans-list */ - /* Prevent self-originated LSA to be flooded. this is to make - reoriginated instance of the LSA not to be rejected by other routers - due to MinLSArrival. */ - if (new->header->adv_router != from->ospf6_if->area->ospf6->router_id) - ospf6_flood (from, new); - - /* (d), installing lsdb, which may cause routing - table calculation (replacing database copy) */ - ospf6_install_lsa (new); - - if (OSPF6_LSA_IS_MAXAGE (new)) - ospf6_maxage_remove (from->ospf6_if->area->ospf6); - - /* (e) possibly acknowledge */ - ospf6_acknowledge_lsa (new, ismore_recent, from); - - /* (f) Self Originated LSA, section 13.4 */ - if (new->header->adv_router == from->ospf6_if->area->ospf6->router_id) - { - /* Self-originated LSA (newer than ours) is received from - another router. We have to make a new instance of the LSA - or have to flush this LSA. */ - if (is_debug) - { - zlog_debug ("Newer instance of the self-originated LSA"); - zlog_debug ("Schedule reorigination"); - } - new->refresh = NULL; - thread_add_event(master, ospf6_lsa_refresh, new, 0, &new->refresh); - } - - return; - } - - /* (6) if there is instance on sending neighbor's request list */ - if (ospf6_lsdb_lookup (new->header->type, new->header->id, - new->header->adv_router, from->request_list)) - { - /* if no database copy, should go above state (5) */ - assert (old); - - if (is_debug) - { - zlog_debug ("Received is not newer, on the neighbor's request-list"); - zlog_debug ("BadLSReq, discard the received LSA"); - } - - /* BadLSReq */ - thread_add_event(master, bad_lsreq, from, 0, NULL); - - ospf6_lsa_delete (new); - return; - } - - /* (7) if neither one is more recent */ - if (ismore_recent == 0) - { - if (is_debug) - zlog_debug ("The same instance as database copy (neither recent)"); - - /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack */ - rem = ospf6_lsdb_lookup (new->header->type, new->header->id, - new->header->adv_router, from->retrans_list); - if (rem) - { - if (is_debug) - { - zlog_debug ("It is on the neighbor's retrans-list."); - zlog_debug ("Treat as an Implied acknowledgement"); - } - SET_FLAG (new->flag, OSPF6_LSA_IMPLIEDACK); - ospf6_decrement_retrans_count (rem); - ospf6_lsdb_remove (rem, from->retrans_list); - } - - if (is_debug) - zlog_debug ("Possibly acknowledge and then discard"); - - /* (b) possibly acknowledge */ - ospf6_acknowledge_lsa (new, ismore_recent, from); - - ospf6_lsa_delete (new); - return; - } - - /* (8) previous database copy is more recent */ - { - assert (old); - - /* If database copy is in 'Seqnumber Wrapping', - simply discard the received LSA */ - if (OSPF6_LSA_IS_MAXAGE (old) && - old->header->seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER)) - { - if (is_debug) - { - zlog_debug ("The LSA is in Seqnumber Wrapping"); - zlog_debug ("MaxAge & MaxSeqNum, discard"); - } - ospf6_lsa_delete (new); - return; - } - - /* Otherwise, Send database copy of this LSA to this neighbor */ - { - if (is_debug) - { - zlog_debug ("Database copy is more recent."); - zlog_debug ("Send back directly and then discard"); - } - - /* XXX, MinLSArrival check !? RFC 2328 13 (8) */ - - ospf6_lsdb_add (ospf6_lsa_copy (old), from->lsupdate_list); - thread_add_event(master, ospf6_lsupdate_send_neighbor, from, 0, - &from->thread_send_lsupdate); - ospf6_lsa_delete (new); - return; - } - return; - } + struct ospf6_lsa *new = NULL, *old = NULL, *rem = NULL; + int ismore_recent; + int is_debug = 0; + unsigned int time_delta_ms; + + ismore_recent = 1; + assert(from); + + /* make lsa structure for received lsa */ + new = ospf6_lsa_create(lsa_header); + + if (IS_OSPF6_DEBUG_FLOODING + || IS_OSPF6_DEBUG_FLOOD_TYPE(new->header->type)) { + is_debug++; + zlog_debug("LSA Receive from %s", from->name); + ospf6_lsa_header_print(new); + } + + /* (1) LSA Checksum */ + if (!ospf6_lsa_checksum_valid(new->header)) { + if (is_debug) + zlog_debug("Wrong LSA Checksum, discard"); + ospf6_lsa_delete(new); + return; + } + + /* (2) Examine the LSA's LS type. + RFC2470 3.5.1. Receiving Link State Update packets */ + if (IS_AREA_STUB(from->ospf6_if->area) + && OSPF6_LSA_SCOPE(new->header->type) == OSPF6_SCOPE_AS) { + if (is_debug) + zlog_debug( + "AS-External-LSA (or AS-scope LSA) in stub area, discard"); + ospf6_lsa_delete(new); + return; + } + + /* (3) LSA which have reserved scope is discarded + RFC2470 3.5.1. Receiving Link State Update packets */ + /* Flooding scope check. LSAs with unknown scope are discarded here. + Set appropriate LSDB for the LSA */ + switch (OSPF6_LSA_SCOPE(new->header->type)) { + case OSPF6_SCOPE_LINKLOCAL: + new->lsdb = from->ospf6_if->lsdb; + break; + case OSPF6_SCOPE_AREA: + new->lsdb = from->ospf6_if->area->lsdb; + break; + case OSPF6_SCOPE_AS: + new->lsdb = from->ospf6_if->area->ospf6->lsdb; + break; + default: + if (is_debug) + zlog_debug("LSA has reserved scope, discard"); + ospf6_lsa_delete(new); + return; + } + + /* (4) if MaxAge LSA and if we have no instance, and no neighbor + is in states Exchange or Loading */ + if (ospf6_is_maxage_lsa_drop(new, from)) { + /* log */ + if (is_debug) + zlog_debug( + "Drop MaxAge LSA with direct acknowledgement."); + + /* a) Acknowledge back to neighbor (Direct acknowledgement, + * 13.5) */ + ospf6_lsdb_add(ospf6_lsa_copy(new), from->lsack_list); + thread_add_event(master, ospf6_lsack_send_neighbor, from, 0, + &from->thread_send_lsack); + + /* b) Discard */ + ospf6_lsa_delete(new); + return; + } + + /* (5) */ + /* lookup the same database copy in lsdb */ + old = ospf6_lsdb_lookup(new->header->type, new->header->id, + new->header->adv_router, new->lsdb); + if (old) { + ismore_recent = ospf6_lsa_compare(new, old); + if (ntohl(new->header->seqnum) == ntohl(old->header->seqnum)) { + if (is_debug) + zlog_debug("Received is duplicated LSA"); + SET_FLAG(new->flag, OSPF6_LSA_DUPLICATE); + } + } + + /* if no database copy or received is more recent */ + if (old == NULL || ismore_recent < 0) { + /* in case we have no database copy */ + ismore_recent = -1; + + /* (a) MinLSArrival check */ + if (old) { + struct timeval now, res; + monotime(&now); + timersub(&now, &old->installed, &res); + time_delta_ms = + (res.tv_sec * 1000) + (int)(res.tv_usec / 1000); + if (time_delta_ms + < from->ospf6_if->area->ospf6->lsa_minarrival) { + if (is_debug) + zlog_debug( + "LSA can't be updated within MinLSArrival, %dms < %dms, discard", + time_delta_ms, + from->ospf6_if->area->ospf6 + ->lsa_minarrival); + ospf6_lsa_delete(new); + return; /* examin next lsa */ + } + } + + monotime(&new->received); + + if (is_debug) + zlog_debug( + "Install, Flood, Possibly acknowledge the received LSA"); + + /* Remove older copies of this LSA from retx lists */ + if (old) + ospf6_flood_clear(old); + + /* (b) immediately flood and (c) remove from all retrans-list */ + /* Prevent self-originated LSA to be flooded. this is to make + reoriginated instance of the LSA not to be rejected by other + routers + due to MinLSArrival. */ + if (new->header->adv_router + != from->ospf6_if->area->ospf6->router_id) + ospf6_flood(from, new); + + /* (d), installing lsdb, which may cause routing + table calculation (replacing database copy) */ + ospf6_install_lsa(new); + + if (OSPF6_LSA_IS_MAXAGE(new)) + ospf6_maxage_remove(from->ospf6_if->area->ospf6); + + /* (e) possibly acknowledge */ + ospf6_acknowledge_lsa(new, ismore_recent, from); + + /* (f) Self Originated LSA, section 13.4 */ + if (new->header->adv_router + == from->ospf6_if->area->ospf6->router_id) { + /* Self-originated LSA (newer than ours) is received + from + another router. We have to make a new instance of the + LSA + or have to flush this LSA. */ + if (is_debug) { + zlog_debug( + "Newer instance of the self-originated LSA"); + zlog_debug("Schedule reorigination"); + } + new->refresh = NULL; + thread_add_event(master, ospf6_lsa_refresh, new, 0, + &new->refresh); + } + + return; + } + + /* (6) if there is instance on sending neighbor's request list */ + if (ospf6_lsdb_lookup(new->header->type, new->header->id, + new->header->adv_router, from->request_list)) { + /* if no database copy, should go above state (5) */ + assert(old); + + if (is_debug) { + zlog_debug( + "Received is not newer, on the neighbor's request-list"); + zlog_debug("BadLSReq, discard the received LSA"); + } + + /* BadLSReq */ + thread_add_event(master, bad_lsreq, from, 0, NULL); + + ospf6_lsa_delete(new); + return; + } + + /* (7) if neither one is more recent */ + if (ismore_recent == 0) { + if (is_debug) + zlog_debug( + "The same instance as database copy (neither recent)"); + + /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack + */ + rem = ospf6_lsdb_lookup(new->header->type, new->header->id, + new->header->adv_router, + from->retrans_list); + if (rem) { + if (is_debug) { + zlog_debug( + "It is on the neighbor's retrans-list."); + zlog_debug( + "Treat as an Implied acknowledgement"); + } + SET_FLAG(new->flag, OSPF6_LSA_IMPLIEDACK); + ospf6_decrement_retrans_count(rem); + ospf6_lsdb_remove(rem, from->retrans_list); + } + + if (is_debug) + zlog_debug("Possibly acknowledge and then discard"); + + /* (b) possibly acknowledge */ + ospf6_acknowledge_lsa(new, ismore_recent, from); + + ospf6_lsa_delete(new); + return; + } + + /* (8) previous database copy is more recent */ + { + assert(old); + + /* If database copy is in 'Seqnumber Wrapping', + simply discard the received LSA */ + if (OSPF6_LSA_IS_MAXAGE(old) + && old->header->seqnum == htonl(OSPF_MAX_SEQUENCE_NUMBER)) { + if (is_debug) { + zlog_debug("The LSA is in Seqnumber Wrapping"); + zlog_debug("MaxAge & MaxSeqNum, discard"); + } + ospf6_lsa_delete(new); + return; + } + + /* Otherwise, Send database copy of this LSA to this neighbor */ + { + if (is_debug) { + zlog_debug("Database copy is more recent."); + zlog_debug( + "Send back directly and then discard"); + } + + /* XXX, MinLSArrival check !? RFC 2328 13 (8) */ + + ospf6_lsdb_add(ospf6_lsa_copy(old), + from->lsupdate_list); + thread_add_event(master, ospf6_lsupdate_send_neighbor, + from, 0, &from->thread_send_lsupdate); + ospf6_lsa_delete(new); + return; + } + return; + } } @@ -1011,8 +981,8 @@ DEFUN (debug_ospf6_flooding, "Debug OSPFv3 flooding function\n" ) { - OSPF6_DEBUG_FLOODING_ON (); - return CMD_SUCCESS; + OSPF6_DEBUG_FLOODING_ON(); + return CMD_SUCCESS; } DEFUN (no_debug_ospf6_flooding, @@ -1024,28 +994,21 @@ DEFUN (no_debug_ospf6_flooding, "Debug OSPFv3 flooding function\n" ) { - OSPF6_DEBUG_FLOODING_OFF (); - return CMD_SUCCESS; + OSPF6_DEBUG_FLOODING_OFF(); + return CMD_SUCCESS; } -int -config_write_ospf6_debug_flood (struct vty *vty) +int config_write_ospf6_debug_flood(struct vty *vty) { - if (IS_OSPF6_DEBUG_FLOODING) - vty_out (vty, "debug ospf6 flooding\n"); - return 0; + if (IS_OSPF6_DEBUG_FLOODING) + vty_out(vty, "debug ospf6 flooding\n"); + return 0; } -void -install_element_ospf6_debug_flood (void) +void install_element_ospf6_debug_flood(void) { - install_element (ENABLE_NODE, &debug_ospf6_flooding_cmd); - install_element (ENABLE_NODE, &no_debug_ospf6_flooding_cmd); - install_element (CONFIG_NODE, &debug_ospf6_flooding_cmd); - install_element (CONFIG_NODE, &no_debug_ospf6_flooding_cmd); + install_element(ENABLE_NODE, &debug_ospf6_flooding_cmd); + install_element(ENABLE_NODE, &no_debug_ospf6_flooding_cmd); + install_element(CONFIG_NODE, &debug_ospf6_flooding_cmd); + install_element(CONFIG_NODE, &no_debug_ospf6_flooding_cmd); } - - - - - diff --git a/ospf6d/ospf6_flood.h b/ospf6d/ospf6_flood.h index 72482cadf..610eefc80 100644 --- a/ospf6d/ospf6_flood.h +++ b/ospf6d/ospf6_flood.h @@ -23,45 +23,40 @@ /* Debug option */ extern unsigned char conf_debug_ospf6_flooding; -#define OSPF6_DEBUG_FLOODING_ON() \ - (conf_debug_ospf6_flooding = 1) -#define OSPF6_DEBUG_FLOODING_OFF() \ - (conf_debug_ospf6_flooding = 0) -#define IS_OSPF6_DEBUG_FLOODING \ - (conf_debug_ospf6_flooding) +#define OSPF6_DEBUG_FLOODING_ON() (conf_debug_ospf6_flooding = 1) +#define OSPF6_DEBUG_FLOODING_OFF() (conf_debug_ospf6_flooding = 0) +#define IS_OSPF6_DEBUG_FLOODING (conf_debug_ospf6_flooding) /* Function Prototypes */ -extern struct ospf6_lsdb *ospf6_get_scoped_lsdb (struct ospf6_lsa *lsa); -extern struct ospf6_lsdb *ospf6_get_scoped_lsdb_self (struct ospf6_lsa *lsa); +extern struct ospf6_lsdb *ospf6_get_scoped_lsdb(struct ospf6_lsa *lsa); +extern struct ospf6_lsdb *ospf6_get_scoped_lsdb_self(struct ospf6_lsa *lsa); /* origination & purging */ -extern void ospf6_lsa_originate (struct ospf6_lsa *lsa); -extern void ospf6_lsa_originate_process (struct ospf6_lsa *lsa, - struct ospf6 *process); -extern void ospf6_lsa_originate_area (struct ospf6_lsa *lsa, - struct ospf6_area *oa); -extern void ospf6_lsa_originate_interface (struct ospf6_lsa *lsa, - struct ospf6_interface *oi); -extern void ospf6_lsa_purge (struct ospf6_lsa *lsa); +extern void ospf6_lsa_originate(struct ospf6_lsa *lsa); +extern void ospf6_lsa_originate_process(struct ospf6_lsa *lsa, + struct ospf6 *process); +extern void ospf6_lsa_originate_area(struct ospf6_lsa *lsa, + struct ospf6_area *oa); +extern void ospf6_lsa_originate_interface(struct ospf6_lsa *lsa, + struct ospf6_interface *oi); +extern void ospf6_lsa_purge(struct ospf6_lsa *lsa); /* access method to retrans_count */ -extern void ospf6_increment_retrans_count (struct ospf6_lsa *lsa); -extern void ospf6_decrement_retrans_count (struct ospf6_lsa *lsa); +extern void ospf6_increment_retrans_count(struct ospf6_lsa *lsa); +extern void ospf6_decrement_retrans_count(struct ospf6_lsa *lsa); /* flooding & clear flooding */ -extern void ospf6_flood_clear (struct ospf6_lsa *lsa); -extern void ospf6_flood (struct ospf6_neighbor *from, struct ospf6_lsa *lsa); -extern void ospf6_flood_area (struct ospf6_neighbor *from, - struct ospf6_lsa *lsa, struct ospf6_area *oa); +extern void ospf6_flood_clear(struct ospf6_lsa *lsa); +extern void ospf6_flood(struct ospf6_neighbor *from, struct ospf6_lsa *lsa); +extern void ospf6_flood_area(struct ospf6_neighbor *from, struct ospf6_lsa *lsa, + struct ospf6_area *oa); /* receive & install */ -extern void ospf6_receive_lsa (struct ospf6_neighbor *from, - struct ospf6_lsa_header *header); -extern void ospf6_install_lsa (struct ospf6_lsa *lsa); +extern void ospf6_receive_lsa(struct ospf6_neighbor *from, + struct ospf6_lsa_header *header); +extern void ospf6_install_lsa(struct ospf6_lsa *lsa); -extern int config_write_ospf6_debug_flood (struct vty *vty); -extern void install_element_ospf6_debug_flood (void); +extern int config_write_ospf6_debug_flood(struct vty *vty); +extern void install_element_ospf6_debug_flood(void); #endif /* OSPF6_FLOOD_H */ - - diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index ab5b4f935..1d17a1c23 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -46,959 +46,922 @@ DEFINE_MTYPE_STATIC(OSPF6D, CFG_PLIST_NAME, "configured prefix list names") DEFINE_QOBJ_TYPE(ospf6_interface) DEFINE_HOOK(ospf6_interface_change, - (struct ospf6_interface *oi, int state, int old_state), - (oi, state, old_state)) + (struct ospf6_interface * oi, int state, int old_state), + (oi, state, old_state)) unsigned char conf_debug_ospf6_interface = 0; -const char *ospf6_interface_state_str[] = -{ - "None", - "Down", - "Loopback", - "Waiting", - "PointToPoint", - "DROther", - "BDR", - "DR", - NULL -}; +const char *ospf6_interface_state_str[] = { + "None", "Down", "Loopback", "Waiting", "PointToPoint", + "DROther", "BDR", "DR", NULL}; -struct ospf6_interface * -ospf6_interface_lookup_by_ifindex (ifindex_t ifindex) +struct ospf6_interface *ospf6_interface_lookup_by_ifindex(ifindex_t ifindex) { - struct ospf6_interface *oi; - struct interface *ifp; + struct ospf6_interface *oi; + struct interface *ifp; - ifp = if_lookup_by_index (ifindex, VRF_DEFAULT); - if (ifp == NULL) - return (struct ospf6_interface *) NULL; + ifp = if_lookup_by_index(ifindex, VRF_DEFAULT); + if (ifp == NULL) + return (struct ospf6_interface *)NULL; - oi = (struct ospf6_interface *) ifp->info; - return oi; + oi = (struct ospf6_interface *)ifp->info; + return oi; } /* schedule routing table recalculation */ -static void -ospf6_interface_lsdb_hook (struct ospf6_lsa *lsa, unsigned int reason) +static void ospf6_interface_lsdb_hook(struct ospf6_lsa *lsa, + unsigned int reason) { - struct ospf6_interface *oi; - - if (lsa == NULL) - return; - - oi = lsa->lsdb->data; - switch (ntohs (lsa->header->type)) - { - case OSPF6_LSTYPE_LINK: - if (oi->state == OSPF6_INTERFACE_DR) - OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi); - if (oi->area) - ospf6_spf_schedule (oi->area->ospf6, reason); - break; - - default: - break; - } + struct ospf6_interface *oi; + + if (lsa == NULL) + return; + + oi = lsa->lsdb->data; + switch (ntohs(lsa->header->type)) { + case OSPF6_LSTYPE_LINK: + if (oi->state == OSPF6_INTERFACE_DR) + OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi); + if (oi->area) + ospf6_spf_schedule(oi->area->ospf6, reason); + break; + + default: + break; + } } -static void -ospf6_interface_lsdb_hook_add (struct ospf6_lsa *lsa) +static void ospf6_interface_lsdb_hook_add(struct ospf6_lsa *lsa) { - ospf6_interface_lsdb_hook(lsa, ospf6_lsadd_to_spf_reason(lsa)); + ospf6_interface_lsdb_hook(lsa, ospf6_lsadd_to_spf_reason(lsa)); } -static void -ospf6_interface_lsdb_hook_remove (struct ospf6_lsa *lsa) +static void ospf6_interface_lsdb_hook_remove(struct ospf6_lsa *lsa) { - ospf6_interface_lsdb_hook(lsa, ospf6_lsremove_to_spf_reason(lsa)); + ospf6_interface_lsdb_hook(lsa, ospf6_lsremove_to_spf_reason(lsa)); } -static u_char -ospf6_default_iftype(struct interface *ifp) +static u_char ospf6_default_iftype(struct interface *ifp) { - if (if_is_pointopoint (ifp)) - return OSPF_IFTYPE_POINTOPOINT; - else if (if_is_loopback (ifp)) - return OSPF_IFTYPE_LOOPBACK; - else - return OSPF_IFTYPE_BROADCAST; + if (if_is_pointopoint(ifp)) + return OSPF_IFTYPE_POINTOPOINT; + else if (if_is_loopback(ifp)) + return OSPF_IFTYPE_LOOPBACK; + else + return OSPF_IFTYPE_BROADCAST; } -static u_int32_t -ospf6_interface_get_cost (struct ospf6_interface *oi) +static u_int32_t ospf6_interface_get_cost(struct ospf6_interface *oi) { - /* If all else fails, use default OSPF cost */ - u_int32_t cost; - u_int32_t bw, refbw; - - bw = oi->interface->bandwidth ? oi->interface->bandwidth : OSPF6_INTERFACE_BANDWIDTH; - refbw = ospf6 ? ospf6->ref_bandwidth : OSPF6_REFERENCE_BANDWIDTH; - - /* A specifed ip ospf cost overrides a calculated one. */ - if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_NOAUTOCOST)) - cost = oi->cost; - else - { - cost = (u_int32_t) ((double)refbw / (double)bw + (double)0.5); - if (cost < 1) cost = 1; - else if (cost > UINT32_MAX) cost = UINT32_MAX; - } - - return cost; + /* If all else fails, use default OSPF cost */ + u_int32_t cost; + u_int32_t bw, refbw; + + bw = oi->interface->bandwidth ? oi->interface->bandwidth + : OSPF6_INTERFACE_BANDWIDTH; + refbw = ospf6 ? ospf6->ref_bandwidth : OSPF6_REFERENCE_BANDWIDTH; + + /* A specifed ip ospf cost overrides a calculated one. */ + if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST)) + cost = oi->cost; + else { + cost = (u_int32_t)((double)refbw / (double)bw + (double)0.5); + if (cost < 1) + cost = 1; + else if (cost > UINT32_MAX) + cost = UINT32_MAX; + } + + return cost; } -static void -ospf6_interface_recalculate_cost (struct ospf6_interface *oi) +static void ospf6_interface_recalculate_cost(struct ospf6_interface *oi) { - u_int32_t newcost; - - newcost = ospf6_interface_get_cost (oi); - if (newcost == oi->cost) return; - oi->cost = newcost; - - /* update cost held in route_connected list in ospf6_interface */ - ospf6_interface_connected_route_update (oi->interface); - - /* execute LSA hooks */ - if (oi->area) - { - OSPF6_LINK_LSA_SCHEDULE (oi); - OSPF6_ROUTER_LSA_SCHEDULE (oi->area); - OSPF6_NETWORK_LSA_SCHEDULE (oi); - OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi); - OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area); - } + u_int32_t newcost; + + newcost = ospf6_interface_get_cost(oi); + if (newcost == oi->cost) + return; + oi->cost = newcost; + + /* update cost held in route_connected list in ospf6_interface */ + ospf6_interface_connected_route_update(oi->interface); + + /* execute LSA hooks */ + if (oi->area) { + OSPF6_LINK_LSA_SCHEDULE(oi); + OSPF6_ROUTER_LSA_SCHEDULE(oi->area); + OSPF6_NETWORK_LSA_SCHEDULE(oi); + OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi); + OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area); + } } /* Create new ospf6 interface structure */ -struct ospf6_interface * -ospf6_interface_create (struct interface *ifp) +struct ospf6_interface *ospf6_interface_create(struct interface *ifp) { - struct ospf6_interface *oi; - unsigned int iobuflen; - - oi = (struct ospf6_interface *) - XCALLOC (MTYPE_OSPF6_IF, sizeof (struct ospf6_interface)); - - if (!oi) - { - zlog_err ("Can't malloc ospf6_interface for ifindex %d", ifp->ifindex); - return (struct ospf6_interface *) NULL; - } - - oi->area = (struct ospf6_area *) NULL; - oi->neighbor_list = list_new (); - oi->neighbor_list->cmp = ospf6_neighbor_cmp; - oi->linklocal_addr = (struct in6_addr *) NULL; - oi->instance_id = OSPF6_INTERFACE_INSTANCE_ID; - oi->transdelay = OSPF6_INTERFACE_TRANSDELAY; - oi->priority = OSPF6_INTERFACE_PRIORITY; - - oi->hello_interval = OSPF_HELLO_INTERVAL_DEFAULT; - oi->dead_interval = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT; - oi->rxmt_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT; - oi->type = ospf6_default_iftype (ifp); - oi->state = OSPF6_INTERFACE_DOWN; - oi->flag = 0; - oi->mtu_ignore = 0; - oi->c_ifmtu = 0; - - /* Try to adjust I/O buffer size with IfMtu */ - oi->ifmtu = ifp->mtu6; - iobuflen = ospf6_iobuf_size (ifp->mtu6); - if (oi->ifmtu > iobuflen) - { - if (IS_OSPF6_DEBUG_INTERFACE) - zlog_debug ("Interface %s: IfMtu is adjusted to I/O buffer size: %d.", - ifp->name, iobuflen); - oi->ifmtu = iobuflen; - } - - QOBJ_REG (oi, ospf6_interface); - - 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_add; - oi->lsdb->hook_remove = ospf6_interface_lsdb_hook_remove; - oi->lsdb_self = ospf6_lsdb_create (oi); - - oi->route_connected = OSPF6_ROUTE_TABLE_CREATE (INTERFACE, CONNECTED_ROUTES); - oi->route_connected->scope = oi; - - /* link both */ - oi->interface = ifp; - ifp->info = oi; - - /* Compute cost. */ - oi->cost = ospf6_interface_get_cost(oi); - - return oi; + struct ospf6_interface *oi; + unsigned int iobuflen; + + oi = (struct ospf6_interface *)XCALLOC(MTYPE_OSPF6_IF, + sizeof(struct ospf6_interface)); + + if (!oi) { + zlog_err("Can't malloc ospf6_interface for ifindex %d", + ifp->ifindex); + return (struct ospf6_interface *)NULL; + } + + oi->area = (struct ospf6_area *)NULL; + oi->neighbor_list = list_new(); + oi->neighbor_list->cmp = ospf6_neighbor_cmp; + oi->linklocal_addr = (struct in6_addr *)NULL; + oi->instance_id = OSPF6_INTERFACE_INSTANCE_ID; + oi->transdelay = OSPF6_INTERFACE_TRANSDELAY; + oi->priority = OSPF6_INTERFACE_PRIORITY; + + oi->hello_interval = OSPF_HELLO_INTERVAL_DEFAULT; + oi->dead_interval = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT; + oi->rxmt_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT; + oi->type = ospf6_default_iftype(ifp); + oi->state = OSPF6_INTERFACE_DOWN; + oi->flag = 0; + oi->mtu_ignore = 0; + oi->c_ifmtu = 0; + + /* Try to adjust I/O buffer size with IfMtu */ + oi->ifmtu = ifp->mtu6; + iobuflen = ospf6_iobuf_size(ifp->mtu6); + if (oi->ifmtu > iobuflen) { + if (IS_OSPF6_DEBUG_INTERFACE) + zlog_debug( + "Interface %s: IfMtu is adjusted to I/O buffer size: %d.", + ifp->name, iobuflen); + oi->ifmtu = iobuflen; + } + + QOBJ_REG(oi, ospf6_interface); + + 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_add; + oi->lsdb->hook_remove = ospf6_interface_lsdb_hook_remove; + oi->lsdb_self = ospf6_lsdb_create(oi); + + oi->route_connected = + OSPF6_ROUTE_TABLE_CREATE(INTERFACE, CONNECTED_ROUTES); + oi->route_connected->scope = oi; + + /* link both */ + oi->interface = ifp; + ifp->info = oi; + + /* Compute cost. */ + oi->cost = ospf6_interface_get_cost(oi); + + return oi; } -void -ospf6_interface_delete (struct ospf6_interface *oi) +void ospf6_interface_delete(struct ospf6_interface *oi) { - struct listnode *node, *nnode; - struct ospf6_neighbor *on; + struct listnode *node, *nnode; + struct ospf6_neighbor *on; + + QOBJ_UNREG(oi); - QOBJ_UNREG (oi); + for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) + ospf6_neighbor_delete(on); - for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on)) - ospf6_neighbor_delete (on); - - list_delete (oi->neighbor_list); + list_delete(oi->neighbor_list); - THREAD_OFF (oi->thread_send_hello); - THREAD_OFF (oi->thread_send_lsupdate); - THREAD_OFF (oi->thread_send_lsack); + THREAD_OFF(oi->thread_send_hello); + THREAD_OFF(oi->thread_send_lsupdate); + THREAD_OFF(oi->thread_send_lsack); - ospf6_lsdb_remove_all (oi->lsdb); - ospf6_lsdb_remove_all (oi->lsupdate_list); - ospf6_lsdb_remove_all (oi->lsack_list); + ospf6_lsdb_remove_all(oi->lsdb); + ospf6_lsdb_remove_all(oi->lsupdate_list); + ospf6_lsdb_remove_all(oi->lsack_list); - ospf6_lsdb_delete (oi->lsdb); - ospf6_lsdb_delete (oi->lsdb_self); + ospf6_lsdb_delete(oi->lsdb); + ospf6_lsdb_delete(oi->lsdb_self); - ospf6_lsdb_delete (oi->lsupdate_list); - ospf6_lsdb_delete (oi->lsack_list); + ospf6_lsdb_delete(oi->lsupdate_list); + ospf6_lsdb_delete(oi->lsack_list); - ospf6_route_table_delete (oi->route_connected); + ospf6_route_table_delete(oi->route_connected); - /* cut link */ - oi->interface->info = NULL; + /* cut link */ + oi->interface->info = NULL; - /* plist_name */ - if (oi->plist_name) - XFREE (MTYPE_CFG_PLIST_NAME, oi->plist_name); + /* plist_name */ + if (oi->plist_name) + XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name); - ospf6_bfd_info_free(&(oi->bfd_info)); + ospf6_bfd_info_free(&(oi->bfd_info)); - XFREE (MTYPE_OSPF6_IF, oi); + XFREE(MTYPE_OSPF6_IF, oi); } -void -ospf6_interface_enable (struct ospf6_interface *oi) +void ospf6_interface_enable(struct ospf6_interface *oi) { - UNSET_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE); - ospf6_interface_state_update (oi->interface); + UNSET_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE); + ospf6_interface_state_update(oi->interface); } -void -ospf6_interface_disable (struct ospf6_interface *oi) +void ospf6_interface_disable(struct ospf6_interface *oi) { - SET_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE); + SET_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE); - thread_execute (master, interface_down, oi, 0); + thread_execute(master, interface_down, oi, 0); - ospf6_lsdb_remove_all (oi->lsdb); - ospf6_lsdb_remove_all (oi->lsdb_self); - ospf6_lsdb_remove_all (oi->lsupdate_list); - ospf6_lsdb_remove_all (oi->lsack_list); + ospf6_lsdb_remove_all(oi->lsdb); + ospf6_lsdb_remove_all(oi->lsdb_self); + ospf6_lsdb_remove_all(oi->lsupdate_list); + ospf6_lsdb_remove_all(oi->lsack_list); - THREAD_OFF (oi->thread_send_hello); - THREAD_OFF (oi->thread_send_lsupdate); - THREAD_OFF (oi->thread_send_lsack); + THREAD_OFF(oi->thread_send_hello); + THREAD_OFF(oi->thread_send_lsupdate); + THREAD_OFF(oi->thread_send_lsack); - THREAD_OFF (oi->thread_network_lsa); - THREAD_OFF (oi->thread_link_lsa); - THREAD_OFF (oi->thread_intra_prefix_lsa); + THREAD_OFF(oi->thread_network_lsa); + THREAD_OFF(oi->thread_link_lsa); + THREAD_OFF(oi->thread_intra_prefix_lsa); } static struct in6_addr * -ospf6_interface_get_linklocal_address (struct interface *ifp) +ospf6_interface_get_linklocal_address(struct interface *ifp) { - struct listnode *n; - struct connected *c; - struct in6_addr *l = (struct in6_addr *) NULL; - - /* for each connected address */ - for (ALL_LIST_ELEMENTS_RO (ifp->connected, n, c)) - { - /* if family not AF_INET6, ignore */ - if (c->address->family != AF_INET6) - continue; - - /* linklocal scope check */ - if (IN6_IS_ADDR_LINKLOCAL (&c->address->u.prefix6)) - l = &c->address->u.prefix6; - } - return l; + struct listnode *n; + struct connected *c; + struct in6_addr *l = (struct in6_addr *)NULL; + + /* for each connected address */ + for (ALL_LIST_ELEMENTS_RO(ifp->connected, n, c)) { + /* if family not AF_INET6, ignore */ + if (c->address->family != AF_INET6) + continue; + + /* linklocal scope check */ + if (IN6_IS_ADDR_LINKLOCAL(&c->address->u.prefix6)) + l = &c->address->u.prefix6; + } + return l; } -void -ospf6_interface_if_add (struct interface *ifp) +void ospf6_interface_if_add(struct interface *ifp) { - struct ospf6_interface *oi; - unsigned int iobuflen; - - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) - return; - - /* Try to adjust I/O buffer size with IfMtu */ - if (oi->ifmtu == 0) - oi->ifmtu = ifp->mtu6; - iobuflen = ospf6_iobuf_size (ifp->mtu6); - if (oi->ifmtu > iobuflen) - { - if (IS_OSPF6_DEBUG_INTERFACE) - zlog_debug ("Interface %s: IfMtu is adjusted to I/O buffer size: %d.", - ifp->name, iobuflen); - oi->ifmtu = iobuflen; - } - - /* interface start */ - ospf6_interface_state_update(oi->interface); + struct ospf6_interface *oi; + unsigned int iobuflen; + + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + return; + + /* Try to adjust I/O buffer size with IfMtu */ + if (oi->ifmtu == 0) + oi->ifmtu = ifp->mtu6; + iobuflen = ospf6_iobuf_size(ifp->mtu6); + if (oi->ifmtu > iobuflen) { + if (IS_OSPF6_DEBUG_INTERFACE) + zlog_debug( + "Interface %s: IfMtu is adjusted to I/O buffer size: %d.", + ifp->name, iobuflen); + oi->ifmtu = iobuflen; + } + + /* interface start */ + ospf6_interface_state_update(oi->interface); } -void -ospf6_interface_if_del (struct interface *ifp) +void ospf6_interface_if_del(struct interface *ifp) { - struct ospf6_interface *oi; + struct ospf6_interface *oi; - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) - return; + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + return; - /* interface stop */ - if (oi->area) - thread_execute (master, interface_down, oi, 0); + /* interface stop */ + if (oi->area) + thread_execute(master, interface_down, oi, 0); - listnode_delete (oi->area->if_list, oi); - oi->area = (struct ospf6_area *) NULL; + listnode_delete(oi->area->if_list, oi); + oi->area = (struct ospf6_area *)NULL; - /* cut link */ - oi->interface = NULL; - ifp->info = NULL; + /* cut link */ + oi->interface = NULL; + ifp->info = NULL; - ospf6_interface_delete (oi); + ospf6_interface_delete(oi); } -void -ospf6_interface_state_update (struct interface *ifp) +void ospf6_interface_state_update(struct interface *ifp) { - struct ospf6_interface *oi; - unsigned int iobuflen; - - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) - return; - if (oi->area == NULL) - return; - if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE)) - return; - - /* Adjust the mtu values if the kernel told us something new */ - if (ifp->mtu6 != oi->ifmtu) - { - /* If nothing configured, accept it and check for buffer size */ - if (!oi->c_ifmtu) - { - oi->ifmtu = ifp->mtu6; - iobuflen = ospf6_iobuf_size (ifp->mtu6); - if (oi->ifmtu > iobuflen) - { - if (IS_OSPF6_DEBUG_INTERFACE) - zlog_debug ("Interface %s: IfMtu is adjusted to I/O buffer size: %d.", - ifp->name, iobuflen); - oi->ifmtu = iobuflen; - } - } - else if (oi->c_ifmtu > ifp->mtu6) - { - oi->ifmtu = ifp->mtu6; - zlog_warn ("Configured mtu %u on %s overridden by kernel %u", - oi->c_ifmtu, ifp->name, ifp->mtu6); - } - else - oi->ifmtu = oi->c_ifmtu; - } - - if (if_is_operative (ifp) - && (ospf6_interface_get_linklocal_address(oi->interface) - || if_is_loopback(oi->interface))) - thread_add_event(master, interface_up, oi, 0, NULL); - else - thread_add_event(master, interface_down, oi, 0, NULL); - - return; + struct ospf6_interface *oi; + unsigned int iobuflen; + + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + return; + if (oi->area == NULL) + return; + if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) + return; + + /* Adjust the mtu values if the kernel told us something new */ + if (ifp->mtu6 != oi->ifmtu) { + /* If nothing configured, accept it and check for buffer size */ + if (!oi->c_ifmtu) { + oi->ifmtu = ifp->mtu6; + iobuflen = ospf6_iobuf_size(ifp->mtu6); + if (oi->ifmtu > iobuflen) { + if (IS_OSPF6_DEBUG_INTERFACE) + zlog_debug( + "Interface %s: IfMtu is adjusted to I/O buffer size: %d.", + ifp->name, iobuflen); + oi->ifmtu = iobuflen; + } + } else if (oi->c_ifmtu > ifp->mtu6) { + oi->ifmtu = ifp->mtu6; + zlog_warn( + "Configured mtu %u on %s overridden by kernel %u", + oi->c_ifmtu, ifp->name, ifp->mtu6); + } else + oi->ifmtu = oi->c_ifmtu; + } + + if (if_is_operative(ifp) + && (ospf6_interface_get_linklocal_address(oi->interface) + || if_is_loopback(oi->interface))) + thread_add_event(master, interface_up, oi, 0, NULL); + else + thread_add_event(master, interface_down, oi, 0, NULL); + + return; } -void -ospf6_interface_connected_route_update (struct interface *ifp) +void ospf6_interface_connected_route_update(struct interface *ifp) { - struct ospf6_interface *oi; - struct ospf6_route *route; - struct connected *c; - struct listnode *node, *nnode; - struct in6_addr nh_addr; - - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) - return; - - /* reset linklocal pointer */ - oi->linklocal_addr = ospf6_interface_get_linklocal_address (ifp); - - /* if area is null, do not make connected-route list */ - if (oi->area == NULL) - return; - - if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE)) - return; - - /* update "route to advertise" interface route table */ - ospf6_route_remove_all (oi->route_connected); - - for (ALL_LIST_ELEMENTS (oi->interface->connected, node, nnode, c)) - { - if (c->address->family != AF_INET6) - continue; - - CONTINUE_IF_ADDRESS_LINKLOCAL (IS_OSPF6_DEBUG_INTERFACE, c->address); - CONTINUE_IF_ADDRESS_UNSPECIFIED (IS_OSPF6_DEBUG_INTERFACE, c->address); - CONTINUE_IF_ADDRESS_LOOPBACK (IS_OSPF6_DEBUG_INTERFACE, c->address); - CONTINUE_IF_ADDRESS_V4COMPAT (IS_OSPF6_DEBUG_INTERFACE, c->address); - CONTINUE_IF_ADDRESS_V4MAPPED (IS_OSPF6_DEBUG_INTERFACE, c->address); - - /* apply filter */ - if (oi->plist_name) - { - struct prefix_list *plist; - enum prefix_list_type ret; - char buf[PREFIX2STR_BUFFER]; - - prefix2str (c->address, buf, sizeof (buf)); - plist = prefix_list_lookup (AFI_IP6, oi->plist_name); - ret = prefix_list_apply (plist, (void *) c->address); - if (ret == PREFIX_DENY) - { - if (IS_OSPF6_DEBUG_INTERFACE) - zlog_debug ("%s on %s filtered by prefix-list %s ", - buf, oi->interface->name, oi->plist_name); - continue; - } - } - - route = ospf6_route_create (); - memcpy (&route->prefix, c->address, sizeof (struct prefix)); - apply_mask (&route->prefix); - route->type = OSPF6_DEST_TYPE_NETWORK; - route->path.area_id = oi->area->area_id; - route->path.type = OSPF6_PATH_TYPE_INTRA; - route->path.cost = oi->cost; - inet_pton (AF_INET6, "::1", &nh_addr); - ospf6_route_add_nexthop (route, oi->interface->ifindex, &nh_addr); - ospf6_route_add (route, oi->route_connected); - } - - /* create new Link-LSA */ - OSPF6_LINK_LSA_SCHEDULE (oi); - OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi); - OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area); + struct ospf6_interface *oi; + struct ospf6_route *route; + struct connected *c; + struct listnode *node, *nnode; + struct in6_addr nh_addr; + + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + return; + + /* reset linklocal pointer */ + oi->linklocal_addr = ospf6_interface_get_linklocal_address(ifp); + + /* if area is null, do not make connected-route list */ + if (oi->area == NULL) + return; + + if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) + return; + + /* update "route to advertise" interface route table */ + ospf6_route_remove_all(oi->route_connected); + + for (ALL_LIST_ELEMENTS(oi->interface->connected, node, nnode, c)) { + if (c->address->family != AF_INET6) + continue; + + CONTINUE_IF_ADDRESS_LINKLOCAL(IS_OSPF6_DEBUG_INTERFACE, + c->address); + CONTINUE_IF_ADDRESS_UNSPECIFIED(IS_OSPF6_DEBUG_INTERFACE, + c->address); + CONTINUE_IF_ADDRESS_LOOPBACK(IS_OSPF6_DEBUG_INTERFACE, + c->address); + CONTINUE_IF_ADDRESS_V4COMPAT(IS_OSPF6_DEBUG_INTERFACE, + c->address); + CONTINUE_IF_ADDRESS_V4MAPPED(IS_OSPF6_DEBUG_INTERFACE, + c->address); + + /* apply filter */ + if (oi->plist_name) { + struct prefix_list *plist; + enum prefix_list_type ret; + char buf[PREFIX2STR_BUFFER]; + + prefix2str(c->address, buf, sizeof(buf)); + plist = prefix_list_lookup(AFI_IP6, oi->plist_name); + ret = prefix_list_apply(plist, (void *)c->address); + if (ret == PREFIX_DENY) { + if (IS_OSPF6_DEBUG_INTERFACE) + zlog_debug( + "%s on %s filtered by prefix-list %s ", + buf, oi->interface->name, + oi->plist_name); + continue; + } + } + + route = ospf6_route_create(); + memcpy(&route->prefix, c->address, sizeof(struct prefix)); + apply_mask(&route->prefix); + route->type = OSPF6_DEST_TYPE_NETWORK; + route->path.area_id = oi->area->area_id; + route->path.type = OSPF6_PATH_TYPE_INTRA; + route->path.cost = oi->cost; + inet_pton(AF_INET6, "::1", &nh_addr); + ospf6_route_add_nexthop(route, oi->interface->ifindex, + &nh_addr); + ospf6_route_add(route, oi->route_connected); + } + + /* create new Link-LSA */ + OSPF6_LINK_LSA_SCHEDULE(oi); + OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi); + OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area); } -static void -ospf6_interface_state_change (u_char next_state, struct ospf6_interface *oi) +static void ospf6_interface_state_change(u_char next_state, + struct ospf6_interface *oi) { - u_char prev_state; - - prev_state = oi->state; - oi->state = next_state; - - if (prev_state == next_state) - return; - - /* log */ - if (IS_OSPF6_DEBUG_INTERFACE) - { - zlog_debug ("Interface state change %s: %s -> %s", oi->interface->name, - ospf6_interface_state_str[prev_state], - ospf6_interface_state_str[next_state]); - } - oi->state_change++; - - if ((prev_state == OSPF6_INTERFACE_DR || - prev_state == OSPF6_INTERFACE_BDR) && - (next_state != OSPF6_INTERFACE_DR && - next_state != OSPF6_INTERFACE_BDR)) - ospf6_sso (oi->interface->ifindex, &alldrouters6, IPV6_LEAVE_GROUP); - - if ((prev_state != OSPF6_INTERFACE_DR && - prev_state != OSPF6_INTERFACE_BDR) && - (next_state == OSPF6_INTERFACE_DR || - next_state == OSPF6_INTERFACE_BDR)) - ospf6_sso (oi->interface->ifindex, &alldrouters6, IPV6_JOIN_GROUP); - - OSPF6_ROUTER_LSA_SCHEDULE (oi->area); - 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); - OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area); - } - - hook_call(ospf6_interface_change, oi, next_state, prev_state); + u_char prev_state; + + prev_state = oi->state; + oi->state = next_state; + + if (prev_state == next_state) + return; + + /* log */ + if (IS_OSPF6_DEBUG_INTERFACE) { + zlog_debug("Interface state change %s: %s -> %s", + oi->interface->name, + ospf6_interface_state_str[prev_state], + ospf6_interface_state_str[next_state]); + } + oi->state_change++; + + if ((prev_state == OSPF6_INTERFACE_DR + || prev_state == OSPF6_INTERFACE_BDR) + && (next_state != OSPF6_INTERFACE_DR + && next_state != OSPF6_INTERFACE_BDR)) + ospf6_sso(oi->interface->ifindex, &alldrouters6, + IPV6_LEAVE_GROUP); + + if ((prev_state != OSPF6_INTERFACE_DR + && prev_state != OSPF6_INTERFACE_BDR) + && (next_state == OSPF6_INTERFACE_DR + || next_state == OSPF6_INTERFACE_BDR)) + ospf6_sso(oi->interface->ifindex, &alldrouters6, + IPV6_JOIN_GROUP); + + OSPF6_ROUTER_LSA_SCHEDULE(oi->area); + 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); + OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area); + } + + hook_call(ospf6_interface_change, oi, next_state, prev_state); } /* DR Election, RFC2328 section 9.4 */ -#define IS_ELIGIBLE(n) \ - ((n)->state >= OSPF6_NEIGHBOR_TWOWAY && (n)->priority != 0) +#define IS_ELIGIBLE(n) \ + ((n)->state >= OSPF6_NEIGHBOR_TWOWAY && (n)->priority != 0) -static struct ospf6_neighbor * -better_bdrouter (struct ospf6_neighbor *a, struct ospf6_neighbor *b) +static struct ospf6_neighbor *better_bdrouter(struct ospf6_neighbor *a, + struct ospf6_neighbor *b) { - if ((a == NULL || ! IS_ELIGIBLE (a) || a->drouter == a->router_id) && - (b == NULL || ! IS_ELIGIBLE (b) || b->drouter == b->router_id)) - return NULL; - else if (a == NULL || ! IS_ELIGIBLE (a) || a->drouter == a->router_id) - return b; - else if (b == NULL || ! IS_ELIGIBLE (b) || b->drouter == b->router_id) - return a; - - if (a->bdrouter == a->router_id && b->bdrouter != b->router_id) - return a; - if (a->bdrouter != a->router_id && b->bdrouter == b->router_id) - return b; - - if (a->priority > b->priority) - return a; - if (a->priority < b->priority) - return b; - - if (ntohl (a->router_id) > ntohl (b->router_id)) - return a; - if (ntohl (a->router_id) < ntohl (b->router_id)) - return b; - - zlog_warn ("Router-ID duplicate ?"); - return a; + if ((a == NULL || !IS_ELIGIBLE(a) || a->drouter == a->router_id) + && (b == NULL || !IS_ELIGIBLE(b) || b->drouter == b->router_id)) + return NULL; + else if (a == NULL || !IS_ELIGIBLE(a) || a->drouter == a->router_id) + return b; + else if (b == NULL || !IS_ELIGIBLE(b) || b->drouter == b->router_id) + return a; + + if (a->bdrouter == a->router_id && b->bdrouter != b->router_id) + return a; + if (a->bdrouter != a->router_id && b->bdrouter == b->router_id) + return b; + + if (a->priority > b->priority) + return a; + if (a->priority < b->priority) + return b; + + if (ntohl(a->router_id) > ntohl(b->router_id)) + return a; + if (ntohl(a->router_id) < ntohl(b->router_id)) + return b; + + zlog_warn("Router-ID duplicate ?"); + return a; } -static struct ospf6_neighbor * -better_drouter (struct ospf6_neighbor *a, struct ospf6_neighbor *b) +static struct ospf6_neighbor *better_drouter(struct ospf6_neighbor *a, + struct ospf6_neighbor *b) { - if ((a == NULL || ! IS_ELIGIBLE (a) || a->drouter != a->router_id) && - (b == NULL || ! IS_ELIGIBLE (b) || b->drouter != b->router_id)) - return NULL; - else if (a == NULL || ! IS_ELIGIBLE (a) || a->drouter != a->router_id) - return b; - else if (b == NULL || ! IS_ELIGIBLE (b) || b->drouter != b->router_id) - return a; - - if (a->drouter == a->router_id && b->drouter != b->router_id) - return a; - if (a->drouter != a->router_id && b->drouter == b->router_id) - return b; - - if (a->priority > b->priority) - return a; - if (a->priority < b->priority) - return b; - - if (ntohl (a->router_id) > ntohl (b->router_id)) - return a; - if (ntohl (a->router_id) < ntohl (b->router_id)) - return b; - - zlog_warn ("Router-ID duplicate ?"); - return a; + if ((a == NULL || !IS_ELIGIBLE(a) || a->drouter != a->router_id) + && (b == NULL || !IS_ELIGIBLE(b) || b->drouter != b->router_id)) + return NULL; + else if (a == NULL || !IS_ELIGIBLE(a) || a->drouter != a->router_id) + return b; + else if (b == NULL || !IS_ELIGIBLE(b) || b->drouter != b->router_id) + return a; + + if (a->drouter == a->router_id && b->drouter != b->router_id) + return a; + if (a->drouter != a->router_id && b->drouter == b->router_id) + return b; + + if (a->priority > b->priority) + return a; + if (a->priority < b->priority) + return b; + + if (ntohl(a->router_id) > ntohl(b->router_id)) + return a; + if (ntohl(a->router_id) < ntohl(b->router_id)) + return b; + + zlog_warn("Router-ID duplicate ?"); + return a; } -static u_char -dr_election (struct ospf6_interface *oi) +static u_char dr_election(struct ospf6_interface *oi) { - struct listnode *node, *nnode; - struct ospf6_neighbor *on, *drouter, *bdrouter, myself; - struct ospf6_neighbor *best_drouter, *best_bdrouter; - u_char next_state = 0; - - drouter = bdrouter = NULL; - best_drouter = best_bdrouter = NULL; - - /* pseudo neighbor myself, including noting current DR/BDR (1) */ - memset (&myself, 0, sizeof (myself)); - inet_ntop (AF_INET, &oi->area->ospf6->router_id, myself.name, - sizeof (myself.name)); - myself.state = OSPF6_NEIGHBOR_TWOWAY; - myself.drouter = oi->drouter; - myself.bdrouter = oi->bdrouter; - myself.priority = oi->priority; - myself.router_id = oi->area->ospf6->router_id; - - /* Electing BDR (2) */ - for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on)) - bdrouter = better_bdrouter (bdrouter, on); - - best_bdrouter = bdrouter; - bdrouter = better_bdrouter (best_bdrouter, &myself); - - /* Electing DR (3) */ - for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on)) - drouter = better_drouter (drouter, on); - - best_drouter = drouter; - drouter = better_drouter (best_drouter, &myself); - if (drouter == NULL) - drouter = bdrouter; - - /* the router itself is newly/no longer DR/BDR (4) */ - if ((drouter == &myself && myself.drouter != myself.router_id) || - (drouter != &myself && myself.drouter == myself.router_id) || - (bdrouter == &myself && myself.bdrouter != myself.router_id) || - (bdrouter != &myself && myself.bdrouter == myself.router_id)) - { - myself.drouter = (drouter ? drouter->router_id : htonl (0)); - myself.bdrouter = (bdrouter ? bdrouter->router_id : htonl (0)); - - /* compatible to Electing BDR (2) */ - bdrouter = better_bdrouter (best_bdrouter, &myself); - - /* compatible to Electing DR (3) */ - drouter = better_drouter (best_drouter, &myself); - if (drouter == NULL) - drouter = bdrouter; - } - - /* Set interface state accordingly (5) */ - if (drouter && drouter == &myself) - next_state = OSPF6_INTERFACE_DR; - else if (bdrouter && bdrouter == &myself) - next_state = OSPF6_INTERFACE_BDR; - else - next_state = OSPF6_INTERFACE_DROTHER; - - /* If NBMA, schedule Start for each neighbor having priority of 0 (6) */ - /* XXX */ - - /* If DR or BDR change, invoke AdjOK? for each neighbor (7) */ - /* RFC 2328 section 12.4. Originating LSAs (3) will be handled - accordingly after AdjOK */ - if (oi->drouter != (drouter ? drouter->router_id : htonl (0)) || - oi->bdrouter != (bdrouter ? bdrouter->router_id : htonl (0))) - { - if (IS_OSPF6_DEBUG_INTERFACE) - zlog_debug ("DR Election on %s: DR: %s BDR: %s", oi->interface->name, - (drouter ? drouter->name : "0.0.0.0"), - (bdrouter ? bdrouter->name : "0.0.0.0")); - - for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, node, on)) - { - if (on->state < OSPF6_NEIGHBOR_TWOWAY) - continue; - /* Schedule AdjOK. */ - thread_add_event(master, adj_ok, on, 0, NULL); - } - } - - oi->drouter = (drouter ? drouter->router_id : htonl (0)); - oi->bdrouter = (bdrouter ? bdrouter->router_id : htonl (0)); - return next_state; + struct listnode *node, *nnode; + struct ospf6_neighbor *on, *drouter, *bdrouter, myself; + struct ospf6_neighbor *best_drouter, *best_bdrouter; + u_char next_state = 0; + + drouter = bdrouter = NULL; + best_drouter = best_bdrouter = NULL; + + /* pseudo neighbor myself, including noting current DR/BDR (1) */ + memset(&myself, 0, sizeof(myself)); + inet_ntop(AF_INET, &oi->area->ospf6->router_id, myself.name, + sizeof(myself.name)); + myself.state = OSPF6_NEIGHBOR_TWOWAY; + myself.drouter = oi->drouter; + myself.bdrouter = oi->bdrouter; + myself.priority = oi->priority; + myself.router_id = oi->area->ospf6->router_id; + + /* Electing BDR (2) */ + for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) + bdrouter = better_bdrouter(bdrouter, on); + + best_bdrouter = bdrouter; + bdrouter = better_bdrouter(best_bdrouter, &myself); + + /* Electing DR (3) */ + for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) + drouter = better_drouter(drouter, on); + + best_drouter = drouter; + drouter = better_drouter(best_drouter, &myself); + if (drouter == NULL) + drouter = bdrouter; + + /* the router itself is newly/no longer DR/BDR (4) */ + if ((drouter == &myself && myself.drouter != myself.router_id) + || (drouter != &myself && myself.drouter == myself.router_id) + || (bdrouter == &myself && myself.bdrouter != myself.router_id) + || (bdrouter != &myself && myself.bdrouter == myself.router_id)) { + myself.drouter = (drouter ? drouter->router_id : htonl(0)); + myself.bdrouter = (bdrouter ? bdrouter->router_id : htonl(0)); + + /* compatible to Electing BDR (2) */ + bdrouter = better_bdrouter(best_bdrouter, &myself); + + /* compatible to Electing DR (3) */ + drouter = better_drouter(best_drouter, &myself); + if (drouter == NULL) + drouter = bdrouter; + } + + /* Set interface state accordingly (5) */ + if (drouter && drouter == &myself) + next_state = OSPF6_INTERFACE_DR; + else if (bdrouter && bdrouter == &myself) + next_state = OSPF6_INTERFACE_BDR; + else + next_state = OSPF6_INTERFACE_DROTHER; + + /* If NBMA, schedule Start for each neighbor having priority of 0 (6) */ + /* XXX */ + + /* If DR or BDR change, invoke AdjOK? for each neighbor (7) */ + /* RFC 2328 section 12.4. Originating LSAs (3) will be handled + accordingly after AdjOK */ + if (oi->drouter != (drouter ? drouter->router_id : htonl(0)) + || oi->bdrouter != (bdrouter ? bdrouter->router_id : htonl(0))) { + if (IS_OSPF6_DEBUG_INTERFACE) + zlog_debug("DR Election on %s: DR: %s BDR: %s", + oi->interface->name, + (drouter ? drouter->name : "0.0.0.0"), + (bdrouter ? bdrouter->name : "0.0.0.0")); + + for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, node, on)) { + if (on->state < OSPF6_NEIGHBOR_TWOWAY) + continue; + /* Schedule AdjOK. */ + thread_add_event(master, adj_ok, on, 0, NULL); + } + } + + oi->drouter = (drouter ? drouter->router_id : htonl(0)); + oi->bdrouter = (bdrouter ? bdrouter->router_id : htonl(0)); + return next_state; } /* Interface State Machine */ -int -interface_up (struct thread *thread) +int interface_up(struct thread *thread) { - struct ospf6_interface *oi; - - oi = (struct ospf6_interface *) THREAD_ARG (thread); - assert (oi && oi->interface); - - if (IS_OSPF6_DEBUG_INTERFACE) - zlog_debug ("Interface Event %s: [InterfaceUp]", - oi->interface->name); - - /* check physical interface is up */ - if (! if_is_operative (oi->interface)) - { - if (IS_OSPF6_DEBUG_INTERFACE) - zlog_debug ("Interface %s is down, can't execute [InterfaceUp]", - oi->interface->name); - return 0; - } - - /* check interface has a link-local address */ - if (! (ospf6_interface_get_linklocal_address(oi->interface) - || if_is_loopback(oi->interface))) - { - if (IS_OSPF6_DEBUG_INTERFACE) - zlog_debug ("Interface %s has no link local address, can't execute [InterfaceUp]", - oi->interface->name); - return 0; - } - - /* Recompute cost */ - ospf6_interface_recalculate_cost (oi); - - /* if already enabled, do nothing */ - if (oi->state > OSPF6_INTERFACE_DOWN) - { - if (IS_OSPF6_DEBUG_INTERFACE) - zlog_debug ("Interface %s already enabled", - oi->interface->name); - return 0; - } - - /* If no area assigned, return */ - if (oi->area == NULL) - { - zlog_debug ("%s: Not scheduleing Hello for %s as there is no area assigned yet", __func__, - oi->interface->name); - return 0; - } - - /* Join AllSPFRouters */ - if (ospf6_sso (oi->interface->ifindex, &allspfrouters6, IPV6_JOIN_GROUP) < 0) - { - if (oi->sso_try_cnt++ < OSPF6_INTERFACE_SSO_RETRY_MAX) - { - zlog_info("Scheduling %s for sso retry, trial count: %d", - oi->interface->name, oi->sso_try_cnt); - thread_add_timer(master, interface_up, oi, - OSPF6_INTERFACE_SSO_RETRY_INT, NULL); - } - return 0; - } - oi->sso_try_cnt = 0; /* Reset on success */ - - /* Update interface route */ - ospf6_interface_connected_route_update (oi->interface); - - /* Schedule Hello */ - if (! CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE) && - !if_is_loopback (oi->interface)) { - oi->thread_send_hello = NULL; - thread_add_event(master, ospf6_hello_send, oi, 0, &oi->thread_send_hello); - } - - /* decide next interface state */ - if ((if_is_pointopoint (oi->interface)) || - (oi->type == OSPF_IFTYPE_POINTOPOINT)) { - ospf6_interface_state_change (OSPF6_INTERFACE_POINTTOPOINT, oi); - } - else if (oi->priority == 0) - ospf6_interface_state_change (OSPF6_INTERFACE_DROTHER, oi); - else - { - ospf6_interface_state_change (OSPF6_INTERFACE_WAITING, oi); - thread_add_timer(master, wait_timer, oi, oi->dead_interval, NULL); - } - - return 0; + struct ospf6_interface *oi; + + oi = (struct ospf6_interface *)THREAD_ARG(thread); + assert(oi && oi->interface); + + if (IS_OSPF6_DEBUG_INTERFACE) + zlog_debug("Interface Event %s: [InterfaceUp]", + oi->interface->name); + + /* check physical interface is up */ + if (!if_is_operative(oi->interface)) { + if (IS_OSPF6_DEBUG_INTERFACE) + zlog_debug( + "Interface %s is down, can't execute [InterfaceUp]", + oi->interface->name); + return 0; + } + + /* check interface has a link-local address */ + if (!(ospf6_interface_get_linklocal_address(oi->interface) + || if_is_loopback(oi->interface))) { + if (IS_OSPF6_DEBUG_INTERFACE) + zlog_debug( + "Interface %s has no link local address, can't execute [InterfaceUp]", + oi->interface->name); + return 0; + } + + /* Recompute cost */ + ospf6_interface_recalculate_cost(oi); + + /* if already enabled, do nothing */ + if (oi->state > OSPF6_INTERFACE_DOWN) { + if (IS_OSPF6_DEBUG_INTERFACE) + zlog_debug("Interface %s already enabled", + oi->interface->name); + return 0; + } + + /* If no area assigned, return */ + if (oi->area == NULL) { + zlog_debug( + "%s: Not scheduleing Hello for %s as there is no area assigned yet", + __func__, oi->interface->name); + return 0; + } + + /* Join AllSPFRouters */ + if (ospf6_sso(oi->interface->ifindex, &allspfrouters6, IPV6_JOIN_GROUP) + < 0) { + if (oi->sso_try_cnt++ < OSPF6_INTERFACE_SSO_RETRY_MAX) { + zlog_info( + "Scheduling %s for sso retry, trial count: %d", + oi->interface->name, oi->sso_try_cnt); + thread_add_timer(master, interface_up, oi, + OSPF6_INTERFACE_SSO_RETRY_INT, NULL); + } + return 0; + } + oi->sso_try_cnt = 0; /* Reset on success */ + + /* Update interface route */ + ospf6_interface_connected_route_update(oi->interface); + + /* Schedule Hello */ + if (!CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE) + && !if_is_loopback(oi->interface)) { + oi->thread_send_hello = NULL; + thread_add_event(master, ospf6_hello_send, oi, 0, + &oi->thread_send_hello); + } + + /* decide next interface state */ + if ((if_is_pointopoint(oi->interface)) + || (oi->type == OSPF_IFTYPE_POINTOPOINT)) { + ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOPOINT, oi); + } else if (oi->priority == 0) + ospf6_interface_state_change(OSPF6_INTERFACE_DROTHER, oi); + else { + ospf6_interface_state_change(OSPF6_INTERFACE_WAITING, oi); + thread_add_timer(master, wait_timer, oi, oi->dead_interval, + NULL); + } + + return 0; } -int -wait_timer (struct thread *thread) +int wait_timer(struct thread *thread) { - struct ospf6_interface *oi; + struct ospf6_interface *oi; - oi = (struct ospf6_interface *) THREAD_ARG (thread); - assert (oi && oi->interface); + oi = (struct ospf6_interface *)THREAD_ARG(thread); + assert(oi && oi->interface); - if (IS_OSPF6_DEBUG_INTERFACE) - zlog_debug ("Interface Event %s: [WaitTimer]", - oi->interface->name); + if (IS_OSPF6_DEBUG_INTERFACE) + zlog_debug("Interface Event %s: [WaitTimer]", + oi->interface->name); - if (oi->state == OSPF6_INTERFACE_WAITING) - ospf6_interface_state_change (dr_election (oi), oi); + if (oi->state == OSPF6_INTERFACE_WAITING) + ospf6_interface_state_change(dr_election(oi), oi); - return 0; + return 0; } -int -backup_seen (struct thread *thread) +int backup_seen(struct thread *thread) { - struct ospf6_interface *oi; + struct ospf6_interface *oi; - oi = (struct ospf6_interface *) THREAD_ARG (thread); - assert (oi && oi->interface); + oi = (struct ospf6_interface *)THREAD_ARG(thread); + assert(oi && oi->interface); - if (IS_OSPF6_DEBUG_INTERFACE) - zlog_debug ("Interface Event %s: [BackupSeen]", - oi->interface->name); + if (IS_OSPF6_DEBUG_INTERFACE) + zlog_debug("Interface Event %s: [BackupSeen]", + oi->interface->name); - if (oi->state == OSPF6_INTERFACE_WAITING) - ospf6_interface_state_change (dr_election (oi), oi); + if (oi->state == OSPF6_INTERFACE_WAITING) + ospf6_interface_state_change(dr_election(oi), oi); - return 0; + return 0; } -int -neighbor_change (struct thread *thread) +int neighbor_change(struct thread *thread) { - struct ospf6_interface *oi; + struct ospf6_interface *oi; - oi = (struct ospf6_interface *) THREAD_ARG (thread); - assert (oi && oi->interface); + oi = (struct ospf6_interface *)THREAD_ARG(thread); + assert(oi && oi->interface); - if (IS_OSPF6_DEBUG_INTERFACE) - zlog_debug ("Interface Event %s: [NeighborChange]", - oi->interface->name); + if (IS_OSPF6_DEBUG_INTERFACE) + zlog_debug("Interface Event %s: [NeighborChange]", + oi->interface->name); - if (oi->state == OSPF6_INTERFACE_DROTHER || - oi->state == OSPF6_INTERFACE_BDR || - oi->state == OSPF6_INTERFACE_DR) - ospf6_interface_state_change (dr_election (oi), oi); + if (oi->state == OSPF6_INTERFACE_DROTHER + || oi->state == OSPF6_INTERFACE_BDR + || oi->state == OSPF6_INTERFACE_DR) + ospf6_interface_state_change(dr_election(oi), oi); - return 0; + return 0; } -int -interface_down (struct thread *thread) +int interface_down(struct thread *thread) { - struct ospf6_interface *oi; - struct listnode *node, *nnode; - struct ospf6_neighbor *on; + struct ospf6_interface *oi; + struct listnode *node, *nnode; + struct ospf6_neighbor *on; - oi = (struct ospf6_interface *) THREAD_ARG (thread); - assert (oi && oi->interface); + oi = (struct ospf6_interface *)THREAD_ARG(thread); + assert(oi && oi->interface); - if (IS_OSPF6_DEBUG_INTERFACE) - zlog_debug ("Interface Event %s: [InterfaceDown]", - oi->interface->name); + if (IS_OSPF6_DEBUG_INTERFACE) + zlog_debug("Interface Event %s: [InterfaceDown]", + oi->interface->name); - /* Stop Hellos */ - THREAD_OFF (oi->thread_send_hello); + /* Stop Hellos */ + THREAD_OFF(oi->thread_send_hello); - /* Leave AllSPFRouters */ - if (oi->state > OSPF6_INTERFACE_DOWN) - ospf6_sso (oi->interface->ifindex, &allspfrouters6, IPV6_LEAVE_GROUP); + /* Leave AllSPFRouters */ + if (oi->state > OSPF6_INTERFACE_DOWN) + ospf6_sso(oi->interface->ifindex, &allspfrouters6, + IPV6_LEAVE_GROUP); - ospf6_interface_state_change (OSPF6_INTERFACE_DOWN, oi); + ospf6_interface_state_change(OSPF6_INTERFACE_DOWN, oi); - for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on)) - ospf6_neighbor_delete (on); - - list_delete_all_node (oi->neighbor_list); + for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) + ospf6_neighbor_delete(on); - /* When interface state is reset, also reset information about - * DR election, as it is no longer valid. */ - oi->drouter = oi->prev_drouter = htonl(0); - oi->bdrouter = oi->prev_bdrouter = htonl(0); - return 0; + list_delete_all_node(oi->neighbor_list); + + /* When interface state is reset, also reset information about + * DR election, as it is no longer valid. */ + oi->drouter = oi->prev_drouter = htonl(0); + oi->bdrouter = oi->prev_bdrouter = htonl(0); + return 0; } /* show specified interface structure */ -static int -ospf6_interface_show (struct vty *vty, struct interface *ifp) +static int ospf6_interface_show(struct vty *vty, struct interface *ifp) { - struct ospf6_interface *oi; - struct connected *c; - struct prefix *p; - struct listnode *i; - char strbuf[PREFIX2STR_BUFFER], drouter[32], bdrouter[32]; - const char *updown[3] = {"down", "up", NULL}; - const char *type; - struct timeval res, now; - char duration[32]; - struct ospf6_lsa *lsa; - - /* check physical interface type */ - if (if_is_loopback (ifp)) - type = "LOOPBACK"; - else if (if_is_broadcast (ifp)) - type = "BROADCAST"; - else if (if_is_pointopoint (ifp)) - type = "POINTOPOINT"; - else - type = "UNKNOWN"; - - vty_out (vty, "%s is %s, type %s\n", - ifp->name, updown[if_is_operative (ifp)], type); - vty_out (vty, " Interface ID: %d\n", ifp->ifindex); - - if (ifp->info == NULL) - { - vty_out (vty, " OSPF not enabled on this interface\n"); - return 0; - } - else - oi = (struct ospf6_interface *) ifp->info; - - vty_out (vty, " Internet Address:\n"); - - for (ALL_LIST_ELEMENTS_RO (ifp->connected, i, c)) - { - p = c->address; - prefix2str (p, strbuf, sizeof (strbuf)); - switch (p->family) - { - case AF_INET: - vty_out (vty, " inet : %s\n", strbuf); - break; - case AF_INET6: - vty_out (vty, " inet6: %s\n", strbuf); - break; - default: - vty_out (vty, " ??? : %s\n", strbuf); - break; - } - } - - if (oi->area) - { - vty_out (vty, " Instance ID %d, Interface MTU %d (autodetect: %d)\n", - oi->instance_id, oi->ifmtu, ifp->mtu6); - vty_out (vty, " MTU mismatch detection: %s\n", oi->mtu_ignore ? - "disabled" : "enabled"); - inet_ntop (AF_INET, &oi->area->area_id, - strbuf, sizeof (strbuf)); - vty_out (vty, " Area ID %s, Cost %u\n", strbuf, oi->cost); - } - else - vty_out (vty, " Not Attached to Area\n"); - - vty_out (vty, " State %s, Transmit Delay %d sec, Priority %d\n", - ospf6_interface_state_str[oi->state], - oi->transdelay, oi->priority); - vty_out (vty, " Timer intervals configured:\n"); - vty_out (vty, " Hello %d, Dead %d, Retransmit %d\n", - oi->hello_interval, oi->dead_interval, oi->rxmt_interval); - - inet_ntop (AF_INET, &oi->drouter, drouter, sizeof (drouter)); - inet_ntop (AF_INET, &oi->bdrouter, bdrouter, sizeof (bdrouter)); - vty_out (vty, " DR: %s BDR: %s\n", drouter, bdrouter); - - vty_out (vty, " Number of I/F scoped LSAs is %u\n", - oi->lsdb->count); - - monotime(&now); - - timerclear (&res); - if (oi->thread_send_lsupdate) - timersub (&oi->thread_send_lsupdate->u.sands, &now, &res); - timerstring (&res, duration, sizeof (duration)); - vty_out (vty, " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n", - oi->lsupdate_list->count, duration, - (oi->thread_send_lsupdate ? "on" : "off")); - for (ALL_LSDB(oi->lsupdate_list, lsa)) - vty_out (vty, " %s\n", lsa->name); - - timerclear (&res); - if (oi->thread_send_lsack) - timersub (&oi->thread_send_lsack->u.sands, &now, &res); - timerstring (&res, duration, sizeof (duration)); - vty_out (vty, " %d Pending LSAs for LSAck in Time %s [thread %s]\n", - oi->lsack_list->count, duration, - (oi->thread_send_lsack ? "on" : "off")); - for (ALL_LSDB(oi->lsack_list, lsa)) - vty_out (vty, " %s\n", lsa->name); - ospf6_bfd_show_info(vty, oi->bfd_info, 1); - return 0; + struct ospf6_interface *oi; + struct connected *c; + struct prefix *p; + struct listnode *i; + char strbuf[PREFIX2STR_BUFFER], drouter[32], bdrouter[32]; + const char *updown[3] = {"down", "up", NULL}; + const char *type; + struct timeval res, now; + char duration[32]; + struct ospf6_lsa *lsa; + + /* check physical interface type */ + if (if_is_loopback(ifp)) + type = "LOOPBACK"; + else if (if_is_broadcast(ifp)) + type = "BROADCAST"; + else if (if_is_pointopoint(ifp)) + type = "POINTOPOINT"; + else + type = "UNKNOWN"; + + vty_out(vty, "%s is %s, type %s\n", ifp->name, + updown[if_is_operative(ifp)], type); + vty_out(vty, " Interface ID: %d\n", ifp->ifindex); + + if (ifp->info == NULL) { + vty_out(vty, " OSPF not enabled on this interface\n"); + return 0; + } else + oi = (struct ospf6_interface *)ifp->info; + + vty_out(vty, " Internet Address:\n"); + + for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) { + p = c->address; + prefix2str(p, strbuf, sizeof(strbuf)); + switch (p->family) { + case AF_INET: + vty_out(vty, " inet : %s\n", strbuf); + break; + case AF_INET6: + vty_out(vty, " inet6: %s\n", strbuf); + break; + default: + vty_out(vty, " ??? : %s\n", strbuf); + break; + } + } + + if (oi->area) { + vty_out(vty, + " Instance ID %d, Interface MTU %d (autodetect: %d)\n", + oi->instance_id, oi->ifmtu, ifp->mtu6); + vty_out(vty, " MTU mismatch detection: %s\n", + oi->mtu_ignore ? "disabled" : "enabled"); + inet_ntop(AF_INET, &oi->area->area_id, strbuf, sizeof(strbuf)); + vty_out(vty, " Area ID %s, Cost %u\n", strbuf, oi->cost); + } else + vty_out(vty, " Not Attached to Area\n"); + + vty_out(vty, " State %s, Transmit Delay %d sec, Priority %d\n", + ospf6_interface_state_str[oi->state], oi->transdelay, + oi->priority); + vty_out(vty, " Timer intervals configured:\n"); + vty_out(vty, " Hello %d, Dead %d, Retransmit %d\n", + oi->hello_interval, oi->dead_interval, oi->rxmt_interval); + + inet_ntop(AF_INET, &oi->drouter, drouter, sizeof(drouter)); + inet_ntop(AF_INET, &oi->bdrouter, bdrouter, sizeof(bdrouter)); + vty_out(vty, " DR: %s BDR: %s\n", drouter, bdrouter); + + vty_out(vty, " Number of I/F scoped LSAs is %u\n", oi->lsdb->count); + + monotime(&now); + + timerclear(&res); + if (oi->thread_send_lsupdate) + timersub(&oi->thread_send_lsupdate->u.sands, &now, &res); + timerstring(&res, duration, sizeof(duration)); + vty_out(vty, + " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n", + oi->lsupdate_list->count, duration, + (oi->thread_send_lsupdate ? "on" : "off")); + for (ALL_LSDB(oi->lsupdate_list, lsa)) + vty_out(vty, " %s\n", lsa->name); + + timerclear(&res); + if (oi->thread_send_lsack) + timersub(&oi->thread_send_lsack->u.sands, &now, &res); + timerstring(&res, duration, sizeof(duration)); + vty_out(vty, " %d Pending LSAs for LSAck in Time %s [thread %s]\n", + oi->lsack_list->count, duration, + (oi->thread_send_lsack ? "on" : "off")); + for (ALL_LSDB(oi->lsack_list, lsa)) + vty_out(vty, " %s\n", lsa->name); + ospf6_bfd_show_info(vty, oi->bfd_info, 1); + return 0; } /* show interface */ @@ -1011,27 +974,24 @@ DEFUN (show_ipv6_ospf6_interface, INTERFACE_STR IFNAME_STR) { - int idx_ifname = 4; - struct interface *ifp; - struct listnode *i; - - if (argc == 5) - { - ifp = if_lookup_by_name (argv[idx_ifname]->arg, VRF_DEFAULT); - if (ifp == NULL) - { - vty_out (vty, "No such Interface: %s\n", argv[idx_ifname]->arg); - return CMD_WARNING; - } - ospf6_interface_show (vty, ifp); - } - else - { - for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), i, ifp)) - ospf6_interface_show (vty, ifp); - } - - return CMD_SUCCESS; + int idx_ifname = 4; + struct interface *ifp; + struct listnode *i; + + if (argc == 5) { + ifp = if_lookup_by_name(argv[idx_ifname]->arg, VRF_DEFAULT); + if (ifp == NULL) { + vty_out(vty, "No such Interface: %s\n", + argv[idx_ifname]->arg); + return CMD_WARNING; + } + ospf6_interface_show(vty, ifp); + } else { + for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), i, ifp)) + ospf6_interface_show(vty, ifp); + } + + return CMD_SUCCESS; } DEFUN (show_ipv6_ospf6_interface_ifname_prefix, @@ -1048,28 +1008,28 @@ DEFUN (show_ipv6_ospf6_interface_ifname_prefix, OSPF6_ROUTE_MATCH_STR "Display details of the prefixes\n") { - int idx_ifname = 4; - int idx_prefix = 6; - struct interface *ifp; - struct ospf6_interface *oi; - - ifp = if_lookup_by_name (argv[idx_ifname]->arg, VRF_DEFAULT); - if (ifp == NULL) - { - vty_out (vty, "No such Interface: %s\n", argv[idx_ifname]->arg); - return CMD_WARNING; - } - - oi = ifp->info; - if (oi == NULL) - { - vty_out (vty, "OSPFv3 is not enabled on %s\n", argv[idx_ifname]->arg); - return CMD_WARNING; - } - - ospf6_route_table_show (vty, idx_prefix, argc, argv, oi->route_connected); - - return CMD_SUCCESS; + int idx_ifname = 4; + int idx_prefix = 6; + struct interface *ifp; + struct ospf6_interface *oi; + + ifp = if_lookup_by_name(argv[idx_ifname]->arg, VRF_DEFAULT); + if (ifp == NULL) { + vty_out(vty, "No such Interface: %s\n", argv[idx_ifname]->arg); + return CMD_WARNING; + } + + oi = ifp->info; + if (oi == NULL) { + vty_out(vty, "OSPFv3 is not enabled on %s\n", + argv[idx_ifname]->arg); + return CMD_WARNING; + } + + ospf6_route_table_show(vty, idx_prefix, argc, argv, + oi->route_connected); + + return CMD_SUCCESS; } DEFUN (show_ipv6_ospf6_interface_prefix, @@ -1085,21 +1045,21 @@ DEFUN (show_ipv6_ospf6_interface_prefix, OSPF6_ROUTE_MATCH_STR "Display details of the prefixes\n") { - int idx_prefix = 5; - struct listnode *i; - struct ospf6_interface *oi; - struct interface *ifp; - - for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), i, ifp)) - { - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) - continue; - - ospf6_route_table_show (vty, idx_prefix, argc, argv, oi->route_connected); - } + int idx_prefix = 5; + struct listnode *i; + struct ospf6_interface *oi; + struct interface *ifp; + + for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), i, ifp)) { + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + continue; + + ospf6_route_table_show(vty, idx_prefix, argc, argv, + oi->route_connected); + } - return CMD_SUCCESS; + return CMD_SUCCESS; } /* interface variable set command */ @@ -1112,55 +1072,51 @@ DEFUN (ipv6_ospf6_ifmtu, "OSPFv3 Interface MTU\n" ) { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx_number = 3; - struct ospf6_interface *oi; - unsigned int ifmtu, iobuflen; - struct listnode *node, *nnode; - struct ospf6_neighbor *on; - - assert (ifp); - - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) - oi = ospf6_interface_create (ifp); - assert (oi); - - ifmtu = strtol (argv[idx_number]->arg, NULL, 10); - - if (oi->c_ifmtu == ifmtu) - return CMD_SUCCESS; - - if (ifp->mtu6 != 0 && ifp->mtu6 < ifmtu) - { - vty_out (vty, "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)\n", - ifp->name, ifp->mtu6); - return CMD_WARNING_CONFIG_FAILED; - } - - if (oi->ifmtu < ifmtu) - { - iobuflen = ospf6_iobuf_size (ifmtu); - if (iobuflen < ifmtu) - { - vty_out (vty, "%s's ifmtu is adjusted to I/O buffer size (%d).\n", - ifp->name, iobuflen); - oi->ifmtu = oi->c_ifmtu = iobuflen; - } - else - oi->ifmtu = oi->c_ifmtu = ifmtu; - } - else - oi->ifmtu = oi->c_ifmtu = ifmtu; - - /* re-establish adjacencies */ - for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on)) - { - THREAD_OFF (on->inactivity_timer); - thread_add_event(master, inactivity_timer, on, 0, NULL); - } - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx_number = 3; + struct ospf6_interface *oi; + unsigned int ifmtu, iobuflen; + struct listnode *node, *nnode; + struct ospf6_neighbor *on; + + assert(ifp); + + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + oi = ospf6_interface_create(ifp); + assert(oi); + + ifmtu = strtol(argv[idx_number]->arg, NULL, 10); + + if (oi->c_ifmtu == ifmtu) + return CMD_SUCCESS; + + if (ifp->mtu6 != 0 && ifp->mtu6 < ifmtu) { + vty_out(vty, + "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)\n", + ifp->name, ifp->mtu6); + return CMD_WARNING_CONFIG_FAILED; + } + + if (oi->ifmtu < ifmtu) { + iobuflen = ospf6_iobuf_size(ifmtu); + if (iobuflen < ifmtu) { + vty_out(vty, + "%s's ifmtu is adjusted to I/O buffer size (%d).\n", + ifp->name, iobuflen); + oi->ifmtu = oi->c_ifmtu = iobuflen; + } else + oi->ifmtu = oi->c_ifmtu = ifmtu; + } else + oi->ifmtu = oi->c_ifmtu = ifmtu; + + /* re-establish adjacencies */ + for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) { + THREAD_OFF(on->inactivity_timer); + thread_add_event(master, inactivity_timer, on, 0, NULL); + } + + return CMD_SUCCESS; } DEFUN (no_ipv6_ospf6_ifmtu, @@ -1173,44 +1129,40 @@ DEFUN (no_ipv6_ospf6_ifmtu, "OSPFv3 Interface MTU\n" ) { - VTY_DECLVAR_CONTEXT(interface, ifp); - struct ospf6_interface *oi; - unsigned int iobuflen; - struct listnode *node, *nnode; - struct ospf6_neighbor *on; - - assert (ifp); - - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) - oi = ospf6_interface_create (ifp); - assert (oi); - - if (oi->ifmtu < ifp->mtu) - { - iobuflen = ospf6_iobuf_size (ifp->mtu); - if (iobuflen < ifp->mtu) - { - vty_out (vty, "%s's ifmtu is adjusted to I/O buffer size (%d).\n", - ifp->name, iobuflen); - oi->ifmtu = iobuflen; - } - else - oi->ifmtu = ifp->mtu; - } - else - oi->ifmtu = ifp->mtu; - - oi->c_ifmtu = 0; - - /* re-establish adjacencies */ - for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on)) - { - THREAD_OFF (on->inactivity_timer); - thread_add_event(master, inactivity_timer, on, 0, NULL); - } - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(interface, ifp); + struct ospf6_interface *oi; + unsigned int iobuflen; + struct listnode *node, *nnode; + struct ospf6_neighbor *on; + + assert(ifp); + + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + oi = ospf6_interface_create(ifp); + assert(oi); + + if (oi->ifmtu < ifp->mtu) { + iobuflen = ospf6_iobuf_size(ifp->mtu); + if (iobuflen < ifp->mtu) { + vty_out(vty, + "%s's ifmtu is adjusted to I/O buffer size (%d).\n", + ifp->name, iobuflen); + oi->ifmtu = iobuflen; + } else + oi->ifmtu = ifp->mtu; + } else + oi->ifmtu = ifp->mtu; + + oi->c_ifmtu = 0; + + /* re-establish adjacencies */ + for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) { + THREAD_OFF(on->inactivity_timer); + thread_add_event(master, inactivity_timer, on, 0, NULL); + } + + return CMD_SUCCESS; } DEFUN (ipv6_ospf6_cost, @@ -1222,35 +1174,34 @@ DEFUN (ipv6_ospf6_cost, "Outgoing metric of this interface\n" ) { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx_number = 3; - struct ospf6_interface *oi; - unsigned long int lcost; - - assert (ifp); - - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) - oi = ospf6_interface_create (ifp); - assert (oi); - - lcost = strtol (argv[idx_number]->arg, NULL, 10); - - if (lcost > UINT32_MAX) - { - vty_out (vty, "Cost %ld is out of range\n", lcost); - return CMD_WARNING_CONFIG_FAILED; - } - - if (oi->cost == lcost) - return CMD_SUCCESS; - - oi->cost = lcost; - SET_FLAG (oi->flag, OSPF6_INTERFACE_NOAUTOCOST); - - ospf6_interface_recalculate_cost(oi); - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx_number = 3; + struct ospf6_interface *oi; + unsigned long int lcost; + + assert(ifp); + + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + oi = ospf6_interface_create(ifp); + assert(oi); + + lcost = strtol(argv[idx_number]->arg, NULL, 10); + + if (lcost > UINT32_MAX) { + vty_out(vty, "Cost %ld is out of range\n", lcost); + return CMD_WARNING_CONFIG_FAILED; + } + + if (oi->cost == lcost) + return CMD_SUCCESS; + + oi->cost = lcost; + SET_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST); + + ospf6_interface_recalculate_cost(oi); + + return CMD_SUCCESS; } DEFUN (no_ipv6_ospf6_cost, @@ -1262,20 +1213,20 @@ DEFUN (no_ipv6_ospf6_cost, "Calculate interface cost from bandwidth\n" ) { - VTY_DECLVAR_CONTEXT(interface, ifp); - struct ospf6_interface *oi; - assert (ifp); + VTY_DECLVAR_CONTEXT(interface, ifp); + struct ospf6_interface *oi; + assert(ifp); - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) - oi = ospf6_interface_create (ifp); - assert (oi); + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + oi = ospf6_interface_create(ifp); + assert(oi); - UNSET_FLAG (oi->flag, OSPF6_INTERFACE_NOAUTOCOST); + UNSET_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST); - ospf6_interface_recalculate_cost(oi); + ospf6_interface_recalculate_cost(oi); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (auto_cost_reference_bandwidth, @@ -1285,30 +1236,29 @@ DEFUN (auto_cost_reference_bandwidth, "Use reference bandwidth method to assign OSPF cost\n" "The reference bandwidth in terms of Mbits per second\n") { - VTY_DECLVAR_CONTEXT(ospf6, o); - int idx_number = 2; - struct ospf6_area *oa; - struct ospf6_interface *oi; - struct listnode *i, *j; - u_int32_t refbw; - - refbw = strtol (argv[idx_number]->arg, NULL, 10); - if (refbw < 1 || refbw > 4294967) - { - vty_out (vty, "reference-bandwidth value is invalid\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* If reference bandwidth is changed. */ - if ((refbw) == o->ref_bandwidth) - return CMD_SUCCESS; - - o->ref_bandwidth = refbw; - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi)) - ospf6_interface_recalculate_cost (oi); - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(ospf6, o); + int idx_number = 2; + struct ospf6_area *oa; + struct ospf6_interface *oi; + struct listnode *i, *j; + u_int32_t refbw; + + refbw = strtol(argv[idx_number]->arg, NULL, 10); + if (refbw < 1 || refbw > 4294967) { + vty_out(vty, "reference-bandwidth value is invalid\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + /* If reference bandwidth is changed. */ + if ((refbw) == o->ref_bandwidth) + return CMD_SUCCESS; + + o->ref_bandwidth = refbw; + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) + for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) + ospf6_interface_recalculate_cost(oi); + + return CMD_SUCCESS; } DEFUN (no_auto_cost_reference_bandwidth, @@ -1319,20 +1269,20 @@ DEFUN (no_auto_cost_reference_bandwidth, "Use reference bandwidth method to assign OSPF cost\n" "The reference bandwidth in terms of Mbits per second\n") { - VTY_DECLVAR_CONTEXT(ospf6, o); - struct ospf6_area *oa; - struct ospf6_interface *oi; - struct listnode *i, *j; + VTY_DECLVAR_CONTEXT(ospf6, o); + struct ospf6_area *oa; + struct ospf6_interface *oi; + struct listnode *i, *j; - if (o->ref_bandwidth == OSPF6_REFERENCE_BANDWIDTH) - return CMD_SUCCESS; + if (o->ref_bandwidth == OSPF6_REFERENCE_BANDWIDTH) + return CMD_SUCCESS; - o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH; - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi)) - ospf6_interface_recalculate_cost (oi); + o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH; + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) + for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) + ospf6_interface_recalculate_cost(oi); - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -1345,18 +1295,18 @@ DEFUN (ipv6_ospf6_hellointerval, SECONDS_STR ) { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx_number = 3; - struct ospf6_interface *oi; - assert (ifp); - - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) - oi = ospf6_interface_create (ifp); - assert (oi); - - oi->hello_interval = strtol (argv[idx_number]->arg, NULL, 10); - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx_number = 3; + struct ospf6_interface *oi; + assert(ifp); + + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + oi = ospf6_interface_create(ifp); + assert(oi); + + oi->hello_interval = strtol(argv[idx_number]->arg, NULL, 10); + return CMD_SUCCESS; } /* interface variable set command */ @@ -1369,18 +1319,18 @@ DEFUN (ipv6_ospf6_deadinterval, SECONDS_STR ) { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx_number = 3; - struct ospf6_interface *oi; - assert (ifp); - - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) - oi = ospf6_interface_create (ifp); - assert (oi); - - oi->dead_interval = strtol (argv[idx_number]->arg, NULL, 10); - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx_number = 3; + struct ospf6_interface *oi; + assert(ifp); + + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + oi = ospf6_interface_create(ifp); + assert(oi); + + oi->dead_interval = strtol(argv[idx_number]->arg, NULL, 10); + return CMD_SUCCESS; } /* interface variable set command */ @@ -1392,18 +1342,18 @@ DEFUN (ipv6_ospf6_transmitdelay, "Link state transmit delay\n" SECONDS_STR) { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx_number = 3; - struct ospf6_interface *oi; - assert (ifp); - - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) - oi = ospf6_interface_create (ifp); - assert (oi); - - oi->transdelay = strtol (argv[idx_number]->arg, NULL, 10); - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx_number = 3; + struct ospf6_interface *oi; + assert(ifp); + + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + oi = ospf6_interface_create(ifp); + assert(oi); + + oi->transdelay = strtol(argv[idx_number]->arg, NULL, 10); + return CMD_SUCCESS; } /* interface variable set command */ @@ -1416,18 +1366,18 @@ DEFUN (ipv6_ospf6_retransmitinterval, SECONDS_STR ) { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx_number = 3; - struct ospf6_interface *oi; - assert (ifp); - - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) - oi = ospf6_interface_create (ifp); - assert (oi); - - oi->rxmt_interval = strtol (argv[idx_number]->arg, NULL, 10); - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx_number = 3; + struct ospf6_interface *oi; + assert(ifp); + + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + oi = ospf6_interface_create(ifp); + assert(oi); + + oi->rxmt_interval = strtol(argv[idx_number]->arg, NULL, 10); + return CMD_SUCCESS; } /* interface variable set command */ @@ -1440,25 +1390,24 @@ DEFUN (ipv6_ospf6_priority, "Priority value\n" ) { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx_number = 3; - struct ospf6_interface *oi; - assert (ifp); + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx_number = 3; + struct ospf6_interface *oi; + assert(ifp); - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) - oi = ospf6_interface_create (ifp); - assert (oi); + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + oi = ospf6_interface_create(ifp); + assert(oi); - oi->priority = strtol (argv[idx_number]->arg, NULL, 10); + oi->priority = strtol(argv[idx_number]->arg, NULL, 10); - if (oi->area && - (oi->state == OSPF6_INTERFACE_DROTHER || - oi->state == OSPF6_INTERFACE_BDR || - oi->state == OSPF6_INTERFACE_DR)) - ospf6_interface_state_change (dr_election (oi), oi); + if (oi->area && (oi->state == OSPF6_INTERFACE_DROTHER + || oi->state == OSPF6_INTERFACE_BDR + || oi->state == OSPF6_INTERFACE_DR)) + ospf6_interface_state_change(dr_election(oi), oi); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (ipv6_ospf6_instance, @@ -1470,18 +1419,18 @@ DEFUN (ipv6_ospf6_instance, "Instance ID value\n" ) { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx_number = 3; - struct ospf6_interface *oi; - assert (ifp); - - oi = (struct ospf6_interface *)ifp->info; - if (oi == NULL) - oi = ospf6_interface_create (ifp); - assert (oi); - - oi->instance_id = strtol (argv[idx_number]->arg, NULL, 10); - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx_number = 3; + struct ospf6_interface *oi; + assert(ifp); + + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + oi = ospf6_interface_create(ifp); + assert(oi); + + oi->instance_id = strtol(argv[idx_number]->arg, NULL, 10); + return CMD_SUCCESS; } DEFUN (ipv6_ospf6_passive, @@ -1492,28 +1441,27 @@ DEFUN (ipv6_ospf6_passive, "Passive interface; no adjacency will be formed on this interface\n" ) { - VTY_DECLVAR_CONTEXT(interface, ifp); - struct ospf6_interface *oi; - struct listnode *node, *nnode; - struct ospf6_neighbor *on; + VTY_DECLVAR_CONTEXT(interface, ifp); + struct ospf6_interface *oi; + struct listnode *node, *nnode; + struct ospf6_neighbor *on; - assert (ifp); + assert(ifp); - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) - oi = ospf6_interface_create (ifp); - assert (oi); + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + oi = ospf6_interface_create(ifp); + assert(oi); - SET_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE); - THREAD_OFF (oi->thread_send_hello); + SET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE); + THREAD_OFF(oi->thread_send_hello); - for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on)) - { - THREAD_OFF (on->inactivity_timer); - thread_add_event(master, inactivity_timer, on, 0, NULL); - } + for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) { + THREAD_OFF(on->inactivity_timer); + thread_add_event(master, inactivity_timer, on, 0, NULL); + } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ipv6_ospf6_passive, @@ -1525,21 +1473,22 @@ DEFUN (no_ipv6_ospf6_passive, "passive interface: No Adjacency will be formed on this I/F\n" ) { - VTY_DECLVAR_CONTEXT(interface, ifp); - struct ospf6_interface *oi; - assert (ifp); + VTY_DECLVAR_CONTEXT(interface, ifp); + struct ospf6_interface *oi; + assert(ifp); - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) - oi = ospf6_interface_create (ifp); - assert (oi); + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + oi = ospf6_interface_create(ifp); + assert(oi); - UNSET_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE); - THREAD_OFF (oi->thread_send_hello); - oi->thread_send_hello = NULL; - thread_add_event(master, ospf6_hello_send, oi, 0, &oi->thread_send_hello); + UNSET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE); + THREAD_OFF(oi->thread_send_hello); + oi->thread_send_hello = NULL; + thread_add_event(master, ospf6_hello_send, oi, 0, + &oi->thread_send_hello); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (ipv6_ospf6_mtu_ignore, @@ -1550,18 +1499,18 @@ DEFUN (ipv6_ospf6_mtu_ignore, "Disable MTU mismatch detection on this interface\n" ) { - VTY_DECLVAR_CONTEXT(interface, ifp); - struct ospf6_interface *oi; - assert (ifp); + VTY_DECLVAR_CONTEXT(interface, ifp); + struct ospf6_interface *oi; + assert(ifp); - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) - oi = ospf6_interface_create (ifp); - assert (oi); + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + oi = ospf6_interface_create(ifp); + assert(oi); - oi->mtu_ignore = 1; + oi->mtu_ignore = 1; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ipv6_ospf6_mtu_ignore, @@ -1573,18 +1522,18 @@ DEFUN (no_ipv6_ospf6_mtu_ignore, "Disable MTU mismatch detection on this interface\n" ) { - VTY_DECLVAR_CONTEXT(interface, ifp); - struct ospf6_interface *oi; - assert (ifp); + VTY_DECLVAR_CONTEXT(interface, ifp); + struct ospf6_interface *oi; + assert(ifp); - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) - oi = ospf6_interface_create (ifp); - assert (oi); + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + oi = ospf6_interface_create(ifp); + assert(oi); - oi->mtu_ignore = 0; + oi->mtu_ignore = 0; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (ipv6_ospf6_advertise_prefix_list, @@ -1597,34 +1546,32 @@ DEFUN (ipv6_ospf6_advertise_prefix_list, "Prefix list name\n" ) { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx_word = 4; - struct ospf6_interface *oi; - assert (ifp); - - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) - oi = ospf6_interface_create (ifp); - assert (oi); - - if (oi->plist_name) - XFREE (MTYPE_CFG_PLIST_NAME, oi->plist_name); - oi->plist_name = XSTRDUP (MTYPE_CFG_PLIST_NAME, argv[idx_word]->arg); - - ospf6_interface_connected_route_update (oi->interface); - - if (oi->area) - { - OSPF6_LINK_LSA_SCHEDULE (oi); - if (oi->state == OSPF6_INTERFACE_DR) - { - OSPF6_NETWORK_LSA_SCHEDULE (oi); - OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi); - } - OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area); - } - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx_word = 4; + struct ospf6_interface *oi; + assert(ifp); + + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + oi = ospf6_interface_create(ifp); + assert(oi); + + if (oi->plist_name) + XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name); + oi->plist_name = XSTRDUP(MTYPE_CFG_PLIST_NAME, argv[idx_word]->arg); + + ospf6_interface_connected_route_update(oi->interface); + + if (oi->area) { + OSPF6_LINK_LSA_SCHEDULE(oi); + if (oi->state == OSPF6_INTERFACE_DR) { + OSPF6_NETWORK_LSA_SCHEDULE(oi); + OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi); + } + OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area); + } + + return CMD_SUCCESS; } DEFUN (no_ipv6_ospf6_advertise_prefix_list, @@ -1637,35 +1584,32 @@ DEFUN (no_ipv6_ospf6_advertise_prefix_list, "Filter prefix using prefix-list\n" ) { - VTY_DECLVAR_CONTEXT(interface, ifp); - struct ospf6_interface *oi; - assert (ifp); - - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) - oi = ospf6_interface_create (ifp); - assert (oi); - - if (oi->plist_name) - { - XFREE (MTYPE_CFG_PLIST_NAME, oi->plist_name); - oi->plist_name = NULL; - } - - ospf6_interface_connected_route_update (oi->interface); - - if (oi->area) - { - OSPF6_LINK_LSA_SCHEDULE (oi); - if (oi->state == OSPF6_INTERFACE_DR) - { - OSPF6_NETWORK_LSA_SCHEDULE (oi); - OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi); - } - OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area); - } - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(interface, ifp); + struct ospf6_interface *oi; + assert(ifp); + + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + oi = ospf6_interface_create(ifp); + assert(oi); + + if (oi->plist_name) { + XFREE(MTYPE_CFG_PLIST_NAME, oi->plist_name); + oi->plist_name = NULL; + } + + ospf6_interface_connected_route_update(oi->interface); + + if (oi->area) { + OSPF6_LINK_LSA_SCHEDULE(oi); + if (oi->state == OSPF6_INTERFACE_DR) { + OSPF6_NETWORK_LSA_SCHEDULE(oi); + OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi); + } + OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area); + } + + return CMD_SUCCESS; } DEFUN (ipv6_ospf6_network, @@ -1678,37 +1622,34 @@ DEFUN (ipv6_ospf6_network, "Specify OSPF6 point-to-point network\n" ) { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx_network = 3; - struct ospf6_interface *oi; - assert (ifp); - - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) { - oi = ospf6_interface_create (ifp); - } - assert (oi); - - if (strncmp (argv[idx_network]->arg, "b", 1) == 0) - { - if (oi->type == OSPF_IFTYPE_BROADCAST) - return CMD_SUCCESS; - - oi->type = OSPF_IFTYPE_BROADCAST; - } - else if (strncmp (argv[idx_network]->arg, "point-to-p", 10) == 0) - { - if (oi->type == OSPF_IFTYPE_POINTOPOINT) { - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx_network = 3; + struct ospf6_interface *oi; + assert(ifp); + + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) { + oi = ospf6_interface_create(ifp); + } + assert(oi); + + if (strncmp(argv[idx_network]->arg, "b", 1) == 0) { + if (oi->type == OSPF_IFTYPE_BROADCAST) + return CMD_SUCCESS; + + oi->type = OSPF_IFTYPE_BROADCAST; + } else if (strncmp(argv[idx_network]->arg, "point-to-p", 10) == 0) { + if (oi->type == OSPF_IFTYPE_POINTOPOINT) { + return CMD_SUCCESS; + } + oi->type = OSPF_IFTYPE_POINTOPOINT; } - oi->type = OSPF_IFTYPE_POINTOPOINT; - } - /* Reset the interface */ - thread_add_event(master, interface_down, oi, 0, NULL); - thread_add_event(master, interface_up, oi, 0, NULL); + /* Reset the interface */ + thread_add_event(master, interface_down, oi, 0, NULL); + thread_add_event(master, interface_up, oi, 0, NULL); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ipv6_ospf6_network, @@ -1719,171 +1660,162 @@ DEFUN (no_ipv6_ospf6_network, OSPF6_STR "Set default network type\n") { - VTY_DECLVAR_CONTEXT(interface, ifp); - struct ospf6_interface *oi; - int type; + VTY_DECLVAR_CONTEXT(interface, ifp); + struct ospf6_interface *oi; + int type; - assert (ifp); + assert(ifp); - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) { - return CMD_SUCCESS; - } + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) { + return CMD_SUCCESS; + } - type = ospf6_default_iftype (ifp); - if (oi->type == type) - { - return CMD_SUCCESS; - } - oi->type = type; + type = ospf6_default_iftype(ifp); + if (oi->type == type) { + return CMD_SUCCESS; + } + oi->type = type; - /* Reset the interface */ - thread_add_event(master, interface_down, oi, 0, NULL); - thread_add_event(master, interface_up, oi, 0, NULL); + /* Reset the interface */ + thread_add_event(master, interface_down, oi, 0, NULL); + thread_add_event(master, interface_up, oi, 0, NULL); - return CMD_SUCCESS; + return CMD_SUCCESS; } -static int -config_write_ospf6_interface (struct vty *vty) +static int config_write_ospf6_interface(struct vty *vty) { - struct listnode *i; - struct ospf6_interface *oi; - struct interface *ifp; - - for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), i, ifp)) - { - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) - continue; - - vty_out (vty, "interface %s\n", - oi->interface->name); - - if (ifp->desc) - vty_out (vty, " description %s\n", ifp->desc); - if (oi->c_ifmtu) - vty_out (vty, " ipv6 ospf6 ifmtu %d\n", oi->c_ifmtu); - - if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_NOAUTOCOST)) - vty_out (vty, " ipv6 ospf6 cost %d\n", - oi->cost); - - if (oi->hello_interval != OSPF6_INTERFACE_HELLO_INTERVAL) - vty_out (vty, " ipv6 ospf6 hello-interval %d\n", - oi->hello_interval); - - if (oi->dead_interval != OSPF6_INTERFACE_DEAD_INTERVAL) - vty_out (vty, " ipv6 ospf6 dead-interval %d\n", - oi->dead_interval); - - if (oi->rxmt_interval != OSPF6_INTERFACE_RXMT_INTERVAL) - vty_out (vty, " ipv6 ospf6 retransmit-interval %d\n", - oi->rxmt_interval); - - if (oi->priority != OSPF6_INTERFACE_PRIORITY) - vty_out (vty, " ipv6 ospf6 priority %d\n", - oi->priority); - - if (oi->transdelay != OSPF6_INTERFACE_TRANSDELAY) - vty_out (vty, " ipv6 ospf6 transmit-delay %d\n", - oi->transdelay); - - if (oi->instance_id != OSPF6_INTERFACE_INSTANCE_ID) - vty_out (vty, " ipv6 ospf6 instance-id %d\n", - oi->instance_id); - - if (oi->plist_name) - vty_out (vty, " ipv6 ospf6 advertise prefix-list %s\n", - oi->plist_name); - - if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE)) - vty_out (vty, " ipv6 ospf6 passive\n"); - - if (oi->mtu_ignore) - vty_out (vty, " ipv6 ospf6 mtu-ignore\n"); - - if (oi->type != ospf6_default_iftype(ifp)) - { - if (oi->type == OSPF_IFTYPE_POINTOPOINT) - vty_out (vty, " ipv6 ospf6 network point-to-point\n"); - else if (oi->type == OSPF_IFTYPE_BROADCAST) - vty_out (vty, " ipv6 ospf6 network broadcast\n"); - } - - ospf6_bfd_write_config(vty, oi); - - vty_out (vty, "!\n"); - } - return 0; + struct listnode *i; + struct ospf6_interface *oi; + struct interface *ifp; + + for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), i, ifp)) { + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + continue; + + vty_out(vty, "interface %s\n", oi->interface->name); + + if (ifp->desc) + vty_out(vty, " description %s\n", ifp->desc); + if (oi->c_ifmtu) + vty_out(vty, " ipv6 ospf6 ifmtu %d\n", oi->c_ifmtu); + + if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_NOAUTOCOST)) + vty_out(vty, " ipv6 ospf6 cost %d\n", oi->cost); + + if (oi->hello_interval != OSPF6_INTERFACE_HELLO_INTERVAL) + vty_out(vty, " ipv6 ospf6 hello-interval %d\n", + oi->hello_interval); + + if (oi->dead_interval != OSPF6_INTERFACE_DEAD_INTERVAL) + vty_out(vty, " ipv6 ospf6 dead-interval %d\n", + oi->dead_interval); + + if (oi->rxmt_interval != OSPF6_INTERFACE_RXMT_INTERVAL) + vty_out(vty, " ipv6 ospf6 retransmit-interval %d\n", + oi->rxmt_interval); + + if (oi->priority != OSPF6_INTERFACE_PRIORITY) + vty_out(vty, " ipv6 ospf6 priority %d\n", oi->priority); + + if (oi->transdelay != OSPF6_INTERFACE_TRANSDELAY) + vty_out(vty, " ipv6 ospf6 transmit-delay %d\n", + oi->transdelay); + + if (oi->instance_id != OSPF6_INTERFACE_INSTANCE_ID) + vty_out(vty, " ipv6 ospf6 instance-id %d\n", + oi->instance_id); + + if (oi->plist_name) + vty_out(vty, " ipv6 ospf6 advertise prefix-list %s\n", + oi->plist_name); + + if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE)) + vty_out(vty, " ipv6 ospf6 passive\n"); + + if (oi->mtu_ignore) + vty_out(vty, " ipv6 ospf6 mtu-ignore\n"); + + if (oi->type != ospf6_default_iftype(ifp)) { + if (oi->type == OSPF_IFTYPE_POINTOPOINT) + vty_out(vty, + " ipv6 ospf6 network point-to-point\n"); + else if (oi->type == OSPF_IFTYPE_BROADCAST) + vty_out(vty, " ipv6 ospf6 network broadcast\n"); + } + + ospf6_bfd_write_config(vty, oi); + + vty_out(vty, "!\n"); + } + return 0; } -static struct cmd_node interface_node = -{ - INTERFACE_NODE, - "%s(config-if)# ", - 1 /* VTYSH */ +static struct cmd_node interface_node = { + INTERFACE_NODE, "%s(config-if)# ", 1 /* VTYSH */ }; -void -ospf6_interface_init (void) +void ospf6_interface_init(void) { - /* Install interface node. */ - install_node (&interface_node, config_write_ospf6_interface); - if_cmd_init (); - - install_element (VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_cmd); - - install_element (INTERFACE_NODE, &ipv6_ospf6_cost_cmd); - install_element (INTERFACE_NODE, &no_ipv6_ospf6_cost_cmd); - install_element (INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd); - install_element (INTERFACE_NODE, &no_ipv6_ospf6_ifmtu_cmd); - install_element (INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd); - install_element (INTERFACE_NODE, &ipv6_ospf6_hellointerval_cmd); - install_element (INTERFACE_NODE, &ipv6_ospf6_priority_cmd); - install_element (INTERFACE_NODE, &ipv6_ospf6_retransmitinterval_cmd); - install_element (INTERFACE_NODE, &ipv6_ospf6_transmitdelay_cmd); - install_element (INTERFACE_NODE, &ipv6_ospf6_instance_cmd); - - install_element (INTERFACE_NODE, &ipv6_ospf6_passive_cmd); - install_element (INTERFACE_NODE, &no_ipv6_ospf6_passive_cmd); - - install_element (INTERFACE_NODE, &ipv6_ospf6_mtu_ignore_cmd); - install_element (INTERFACE_NODE, &no_ipv6_ospf6_mtu_ignore_cmd); - - install_element (INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd); - install_element (INTERFACE_NODE, &no_ipv6_ospf6_advertise_prefix_list_cmd); - - install_element (INTERFACE_NODE, &ipv6_ospf6_network_cmd); - install_element (INTERFACE_NODE, &no_ipv6_ospf6_network_cmd); - - /* reference bandwidth commands */ - install_element (OSPF6_NODE, &auto_cost_reference_bandwidth_cmd); - install_element (OSPF6_NODE, &no_auto_cost_reference_bandwidth_cmd); + /* Install interface node. */ + install_node(&interface_node, config_write_ospf6_interface); + if_cmd_init(); + + install_element(VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd); + install_element(VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd); + install_element(VIEW_NODE, + &show_ipv6_ospf6_interface_ifname_prefix_cmd); + + install_element(INTERFACE_NODE, &ipv6_ospf6_cost_cmd); + install_element(INTERFACE_NODE, &no_ipv6_ospf6_cost_cmd); + install_element(INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd); + install_element(INTERFACE_NODE, &no_ipv6_ospf6_ifmtu_cmd); + install_element(INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd); + install_element(INTERFACE_NODE, &ipv6_ospf6_hellointerval_cmd); + install_element(INTERFACE_NODE, &ipv6_ospf6_priority_cmd); + install_element(INTERFACE_NODE, &ipv6_ospf6_retransmitinterval_cmd); + install_element(INTERFACE_NODE, &ipv6_ospf6_transmitdelay_cmd); + install_element(INTERFACE_NODE, &ipv6_ospf6_instance_cmd); + + install_element(INTERFACE_NODE, &ipv6_ospf6_passive_cmd); + install_element(INTERFACE_NODE, &no_ipv6_ospf6_passive_cmd); + + install_element(INTERFACE_NODE, &ipv6_ospf6_mtu_ignore_cmd); + install_element(INTERFACE_NODE, &no_ipv6_ospf6_mtu_ignore_cmd); + + install_element(INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd); + install_element(INTERFACE_NODE, + &no_ipv6_ospf6_advertise_prefix_list_cmd); + + install_element(INTERFACE_NODE, &ipv6_ospf6_network_cmd); + install_element(INTERFACE_NODE, &no_ipv6_ospf6_network_cmd); + + /* reference bandwidth commands */ + install_element(OSPF6_NODE, &auto_cost_reference_bandwidth_cmd); + install_element(OSPF6_NODE, &no_auto_cost_reference_bandwidth_cmd); } /* Clear the specified interface structure */ -static void -ospf6_interface_clear (struct vty *vty, struct interface *ifp) +static void ospf6_interface_clear(struct vty *vty, struct interface *ifp) { - struct ospf6_interface *oi; + struct ospf6_interface *oi; - if (!if_is_operative (ifp)) - return; + if (!if_is_operative(ifp)) + return; - if (ifp->info == NULL) - return; + if (ifp->info == NULL) + return; - oi = (struct ospf6_interface *) ifp->info; + oi = (struct ospf6_interface *)ifp->info; - if (IS_OSPF6_DEBUG_INTERFACE) - zlog_debug ("Interface %s: clear by reset", ifp->name); + if (IS_OSPF6_DEBUG_INTERFACE) + zlog_debug("Interface %s: clear by reset", ifp->name); - /* Reset the interface */ - thread_add_event(master, interface_down, oi, 0, NULL); - thread_add_event(master, interface_up, oi, 0, NULL); + /* Reset the interface */ + thread_add_event(master, interface_down, oi, 0, NULL); + thread_add_event(master, interface_up, oi, 0, NULL); } /* Clear interface */ @@ -1897,32 +1829,32 @@ DEFUN (clear_ipv6_ospf6_interface, IFNAME_STR ) { - int idx_ifname = 4; - struct interface *ifp; - struct listnode *node; - - if (argc == 4) /* Clear all the ospfv3 interfaces. */ - { - for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) - ospf6_interface_clear (vty, ifp); - } - else /* Interface name is specified. */ - { - if ((ifp = if_lookup_by_name (argv[idx_ifname]->arg, VRF_DEFAULT)) == NULL) - { - vty_out (vty, "No such Interface: %s\n", argv[idx_ifname]->arg); - return CMD_WARNING; - } - ospf6_interface_clear (vty, ifp); - } - - return CMD_SUCCESS; + int idx_ifname = 4; + struct interface *ifp; + struct listnode *node; + + if (argc == 4) /* Clear all the ospfv3 interfaces. */ + { + for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) + ospf6_interface_clear(vty, ifp); + } else /* Interface name is specified. */ + { + if ((ifp = if_lookup_by_name(argv[idx_ifname]->arg, + VRF_DEFAULT)) + == NULL) { + vty_out(vty, "No such Interface: %s\n", + argv[idx_ifname]->arg); + return CMD_WARNING; + } + ospf6_interface_clear(vty, ifp); + } + + return CMD_SUCCESS; } -void -install_element_ospf6_clear_interface (void) +void install_element_ospf6_clear_interface(void) { - install_element (ENABLE_NODE, &clear_ipv6_ospf6_interface_cmd); + install_element(ENABLE_NODE, &clear_ipv6_ospf6_interface_cmd); } DEFUN (debug_ospf6_interface, @@ -1933,8 +1865,8 @@ DEFUN (debug_ospf6_interface, "Debug OSPFv3 Interface\n" ) { - OSPF6_DEBUG_INTERFACE_ON (); - return CMD_SUCCESS; + OSPF6_DEBUG_INTERFACE_ON(); + return CMD_SUCCESS; } DEFUN (no_debug_ospf6_interface, @@ -1946,25 +1878,21 @@ DEFUN (no_debug_ospf6_interface, "Debug OSPFv3 Interface\n" ) { - OSPF6_DEBUG_INTERFACE_OFF (); - return CMD_SUCCESS; + OSPF6_DEBUG_INTERFACE_OFF(); + return CMD_SUCCESS; } -int -config_write_ospf6_debug_interface (struct vty *vty) +int config_write_ospf6_debug_interface(struct vty *vty) { - if (IS_OSPF6_DEBUG_INTERFACE) - vty_out (vty, "debug ospf6 interface\n"); - return 0; + if (IS_OSPF6_DEBUG_INTERFACE) + vty_out(vty, "debug ospf6 interface\n"); + return 0; } -void -install_element_ospf6_debug_interface (void) +void install_element_ospf6_debug_interface(void) { - install_element (ENABLE_NODE, &debug_ospf6_interface_cmd); - install_element (ENABLE_NODE, &no_debug_ospf6_interface_cmd); - install_element (CONFIG_NODE, &debug_ospf6_interface_cmd); - install_element (CONFIG_NODE, &no_debug_ospf6_interface_cmd); + install_element(ENABLE_NODE, &debug_ospf6_interface_cmd); + install_element(ENABLE_NODE, &no_debug_ospf6_interface_cmd); + install_element(CONFIG_NODE, &debug_ospf6_interface_cmd); + install_element(CONFIG_NODE, &no_debug_ospf6_interface_cmd); } - - diff --git a/ospf6d/ospf6_interface.h b/ospf6d/ospf6_interface.h index 327402d75..384413236 100644 --- a/ospf6d/ospf6_interface.h +++ b/ospf6d/ospf6_interface.h @@ -27,101 +27,97 @@ /* Debug option */ extern unsigned char conf_debug_ospf6_interface; -#define OSPF6_DEBUG_INTERFACE_ON() \ - (conf_debug_ospf6_interface = 1) -#define OSPF6_DEBUG_INTERFACE_OFF() \ - (conf_debug_ospf6_interface = 0) -#define IS_OSPF6_DEBUG_INTERFACE \ - (conf_debug_ospf6_interface) +#define OSPF6_DEBUG_INTERFACE_ON() (conf_debug_ospf6_interface = 1) +#define OSPF6_DEBUG_INTERFACE_OFF() (conf_debug_ospf6_interface = 0) +#define IS_OSPF6_DEBUG_INTERFACE (conf_debug_ospf6_interface) /* Interface structure */ -struct ospf6_interface -{ - /* IF info from zebra */ - struct interface *interface; +struct ospf6_interface { + /* IF info from zebra */ + struct interface *interface; - /* back pointer */ - struct ospf6_area *area; + /* back pointer */ + struct ospf6_area *area; - /* list of ospf6 neighbor */ - struct list *neighbor_list; + /* list of ospf6 neighbor */ + struct list *neighbor_list; - /* linklocal address of this I/F */ - struct in6_addr *linklocal_addr; + /* linklocal address of this I/F */ + struct in6_addr *linklocal_addr; - /* Interface ID; use interface->ifindex */ + /* Interface ID; use interface->ifindex */ - /* ospf6 instance id */ - u_char instance_id; + /* ospf6 instance id */ + u_char instance_id; - /* I/F transmission delay */ - u_int32_t transdelay; + /* I/F transmission delay */ + u_int32_t transdelay; - /* Network Type */ - u_char type; + /* Network Type */ + u_char type; - /* Router Priority */ - u_char priority; + /* Router Priority */ + u_char priority; - /* Time Interval */ - u_int16_t hello_interval; - u_int16_t dead_interval; - u_int32_t rxmt_interval; + /* Time Interval */ + u_int16_t hello_interval; + u_int16_t dead_interval; + u_int32_t rxmt_interval; - u_int32_t state_change; + u_int32_t state_change; - /* Cost */ - u_int32_t cost; + /* Cost */ + u_int32_t cost; - /* I/F MTU */ - u_int32_t ifmtu; + /* I/F MTU */ + u_int32_t ifmtu; - /* Configured MTU */ - u_int32_t c_ifmtu; + /* Configured MTU */ + u_int32_t c_ifmtu; - /* Interface State */ - u_char state; + /* Interface State */ + u_char state; - /* Interface socket setting trial counter, resets on success */ - u_char sso_try_cnt; + /* Interface socket setting trial counter, resets on success */ + u_char sso_try_cnt; - /* OSPF6 Interface flag */ - char flag; + /* OSPF6 Interface flag */ + char flag; - /* MTU mismatch check */ - u_char mtu_ignore; + /* MTU mismatch check */ + u_char mtu_ignore; - /* Decision of DR Election */ - u_int32_t drouter; - u_int32_t bdrouter; - u_int32_t prev_drouter; - u_int32_t prev_bdrouter; + /* Decision of DR Election */ + u_int32_t drouter; + u_int32_t bdrouter; + u_int32_t prev_drouter; + u_int32_t prev_bdrouter; - /* Linklocal LSA Database: includes Link-LSA */ - struct ospf6_lsdb *lsdb; - struct ospf6_lsdb *lsdb_self; + /* 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; + struct ospf6_lsdb *lsupdate_list; + struct ospf6_lsdb *lsack_list; - /* Ongoing Tasks */ - struct thread *thread_send_hello; - struct thread *thread_send_lsupdate; - struct thread *thread_send_lsack; + /* Ongoing Tasks */ + struct thread *thread_send_hello; + struct thread *thread_send_lsupdate; + struct thread *thread_send_lsack; - struct thread *thread_network_lsa; - struct thread *thread_link_lsa; - struct thread *thread_intra_prefix_lsa; + struct thread *thread_network_lsa; + struct thread *thread_link_lsa; + struct thread *thread_intra_prefix_lsa; - struct ospf6_route_table *route_connected; + struct ospf6_route_table *route_connected; - /* prefix-list name to filter connected prefix */ - char *plist_name; + /* prefix-list name to filter connected prefix */ + char *plist_name; - /* BFD information */ - void *bfd_info; + /* BFD information */ + void *bfd_info; - QOBJ_FIELDS + QOBJ_FIELDS }; DECLARE_QOBJ_TYPE(ospf6_interface) @@ -156,37 +152,36 @@ extern const char *ospf6_interface_state_str[]; #define OSPF6_INTERFACE_SSO_RETRY_INT 1 #define OSPF6_INTERFACE_SSO_RETRY_MAX 5 - /* Function Prototypes */ -extern struct ospf6_interface *ospf6_interface_lookup_by_ifindex (ifindex_t); -extern struct ospf6_interface *ospf6_interface_create (struct interface *); -extern void ospf6_interface_delete (struct ospf6_interface *); +extern struct ospf6_interface *ospf6_interface_lookup_by_ifindex(ifindex_t); +extern struct ospf6_interface *ospf6_interface_create(struct interface *); +extern void ospf6_interface_delete(struct ospf6_interface *); -extern void ospf6_interface_enable (struct ospf6_interface *); -extern void ospf6_interface_disable (struct ospf6_interface *); +extern void ospf6_interface_enable(struct ospf6_interface *); +extern void ospf6_interface_disable(struct ospf6_interface *); -extern void ospf6_interface_if_add (struct interface *); -extern void ospf6_interface_if_del (struct interface *); -extern void ospf6_interface_state_update (struct interface *); -extern void ospf6_interface_connected_route_update (struct interface *); +extern void ospf6_interface_if_add(struct interface *); +extern void ospf6_interface_if_del(struct interface *); +extern void ospf6_interface_state_update(struct interface *); +extern void ospf6_interface_connected_route_update(struct interface *); /* interface event */ -extern int interface_up (struct thread *); -extern int interface_down (struct thread *); -extern int wait_timer (struct thread *); -extern int backup_seen (struct thread *); -extern int neighbor_change (struct thread *); +extern int interface_up(struct thread *); +extern int interface_down(struct thread *); +extern int wait_timer(struct thread *); +extern int backup_seen(struct thread *); +extern int neighbor_change(struct thread *); -extern void ospf6_interface_init (void); +extern void ospf6_interface_init(void); -extern void install_element_ospf6_clear_interface (void); +extern void install_element_ospf6_clear_interface(void); -extern int config_write_ospf6_debug_interface (struct vty *vty); -extern void install_element_ospf6_debug_interface (void); +extern int config_write_ospf6_debug_interface(struct vty *vty); +extern void install_element_ospf6_debug_interface(void); DECLARE_HOOK(ospf6_interface_change, - (struct ospf6_interface *oi, int state, int old_state), - (oi, state, old_state)) + (struct ospf6_interface * oi, int state, int old_state), + (oi, state, old_state)) #endif /* OSPF6_INTERFACE_H */ diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c index 0ab503d15..7c5c44fca 100644 --- a/ospf6d/ospf6_intra.c +++ b/ospf6d/ospf6_intra.c @@ -56,491 +56,481 @@ u_int32_t conf_debug_ospf6_brouter_specific_area_id; /* RFC2740 3.4.3.1 Router-LSA */ /******************************/ -static char * -ospf6_router_lsa_get_nbr_id (struct ospf6_lsa *lsa, char *buf, int buflen, - int pos) +static char *ospf6_router_lsa_get_nbr_id(struct ospf6_lsa *lsa, char *buf, + int buflen, int pos) { - struct ospf6_router_lsa *router_lsa; - struct ospf6_router_lsdesc *lsdesc; - char *start, *end; - char buf1[INET_ADDRSTRLEN], buf2[INET_ADDRSTRLEN]; - - if (lsa) - { - router_lsa = (struct ospf6_router_lsa *) - ((char *) lsa->header + sizeof (struct ospf6_lsa_header)); - start = (char *) router_lsa + sizeof (struct ospf6_router_lsa); - end = (char *) lsa->header + ntohs (lsa->header->length); - - lsdesc = (struct ospf6_router_lsdesc *) - (start + pos*(sizeof (struct ospf6_router_lsdesc))); - if ((char *)lsdesc < end) - { - if (buf && (buflen > INET_ADDRSTRLEN*2)) - { - inet_ntop (AF_INET, &lsdesc->neighbor_interface_id, - buf1, sizeof(buf1)); - inet_ntop (AF_INET, &lsdesc->neighbor_router_id, - buf2, sizeof(buf2)); - sprintf (buf, "%s/%s", buf2, buf1); - } + struct ospf6_router_lsa *router_lsa; + struct ospf6_router_lsdesc *lsdesc; + char *start, *end; + char buf1[INET_ADDRSTRLEN], buf2[INET_ADDRSTRLEN]; + + if (lsa) { + router_lsa = (struct ospf6_router_lsa + *)((char *)lsa->header + + sizeof(struct ospf6_lsa_header)); + start = (char *)router_lsa + sizeof(struct ospf6_router_lsa); + end = (char *)lsa->header + ntohs(lsa->header->length); + + lsdesc = (struct ospf6_router_lsdesc + *)(start + + pos * (sizeof(struct + ospf6_router_lsdesc))); + if ((char *)lsdesc < end) { + if (buf && (buflen > INET_ADDRSTRLEN * 2)) { + inet_ntop(AF_INET, + &lsdesc->neighbor_interface_id, buf1, + sizeof(buf1)); + inet_ntop(AF_INET, &lsdesc->neighbor_router_id, + buf2, sizeof(buf2)); + sprintf(buf, "%s/%s", buf2, buf1); + } + } else + return NULL; } - else - return NULL; - } - return buf; + return buf; } -static int -ospf6_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa) +static int ospf6_router_lsa_show(struct vty *vty, struct ospf6_lsa *lsa) { - char *start, *end, *current; - char buf[32], name[32], bits[16], options[32]; - struct ospf6_router_lsa *router_lsa; - struct ospf6_router_lsdesc *lsdesc; - - router_lsa = (struct ospf6_router_lsa *) - ((char *) lsa->header + sizeof (struct ospf6_lsa_header)); - - ospf6_capability_printbuf (router_lsa->bits, bits, sizeof (bits)); - ospf6_options_printbuf (router_lsa->options, options, sizeof (options)); - vty_out (vty, " Bits: %s Options: %s\n", bits, options); - - start = (char *) router_lsa + sizeof (struct ospf6_router_lsa); - end = (char *) lsa->header + ntohs (lsa->header->length); - for (current = start; current + sizeof (struct ospf6_router_lsdesc) <= end; - current += sizeof (struct ospf6_router_lsdesc)) - { - lsdesc = (struct ospf6_router_lsdesc *) current; - - if (lsdesc->type == OSPF6_ROUTER_LSDESC_POINTTOPOINT) - snprintf (name, sizeof (name), "Point-To-Point"); - else if (lsdesc->type == OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK) - snprintf (name, sizeof (name), "Transit-Network"); - else if (lsdesc->type == OSPF6_ROUTER_LSDESC_STUB_NETWORK) - snprintf (name, sizeof (name), "Stub-Network"); - else if (lsdesc->type == OSPF6_ROUTER_LSDESC_VIRTUAL_LINK) - snprintf (name, sizeof (name), "Virtual-Link"); - else - snprintf (name, sizeof (name), "Unknown (%#x)", lsdesc->type); - - vty_out (vty, " Type: %s Metric: %d\n", - name, ntohs (lsdesc->metric)); - vty_out (vty, " Interface ID: %s\n", - inet_ntop (AF_INET, &lsdesc->interface_id, - buf, sizeof (buf))); - vty_out (vty, " Neighbor Interface ID: %s\n", - inet_ntop (AF_INET, &lsdesc->neighbor_interface_id, - buf, sizeof (buf))); - vty_out (vty, " Neighbor Router ID: %s\n", - inet_ntop (AF_INET, &lsdesc->neighbor_router_id, - buf, sizeof (buf))); - } - return 0; + char *start, *end, *current; + char buf[32], name[32], bits[16], options[32]; + struct ospf6_router_lsa *router_lsa; + struct ospf6_router_lsdesc *lsdesc; + + router_lsa = + (struct ospf6_router_lsa *)((char *)lsa->header + + sizeof(struct ospf6_lsa_header)); + + ospf6_capability_printbuf(router_lsa->bits, bits, sizeof(bits)); + ospf6_options_printbuf(router_lsa->options, options, sizeof(options)); + vty_out(vty, " Bits: %s Options: %s\n", bits, options); + + start = (char *)router_lsa + sizeof(struct ospf6_router_lsa); + end = (char *)lsa->header + ntohs(lsa->header->length); + for (current = start; + current + sizeof(struct ospf6_router_lsdesc) <= end; + current += sizeof(struct ospf6_router_lsdesc)) { + lsdesc = (struct ospf6_router_lsdesc *)current; + + if (lsdesc->type == OSPF6_ROUTER_LSDESC_POINTTOPOINT) + snprintf(name, sizeof(name), "Point-To-Point"); + else if (lsdesc->type == OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK) + snprintf(name, sizeof(name), "Transit-Network"); + else if (lsdesc->type == OSPF6_ROUTER_LSDESC_STUB_NETWORK) + snprintf(name, sizeof(name), "Stub-Network"); + else if (lsdesc->type == OSPF6_ROUTER_LSDESC_VIRTUAL_LINK) + snprintf(name, sizeof(name), "Virtual-Link"); + else + snprintf(name, sizeof(name), "Unknown (%#x)", + lsdesc->type); + + vty_out(vty, " Type: %s Metric: %d\n", name, + ntohs(lsdesc->metric)); + vty_out(vty, " Interface ID: %s\n", + inet_ntop(AF_INET, &lsdesc->interface_id, buf, + sizeof(buf))); + vty_out(vty, " Neighbor Interface ID: %s\n", + inet_ntop(AF_INET, &lsdesc->neighbor_interface_id, buf, + sizeof(buf))); + vty_out(vty, " Neighbor Router ID: %s\n", + inet_ntop(AF_INET, &lsdesc->neighbor_router_id, buf, + sizeof(buf))); + } + return 0; } -static void -ospf6_router_lsa_options_set (struct ospf6_area *oa, - struct ospf6_router_lsa *router_lsa) +static void ospf6_router_lsa_options_set(struct ospf6_area *oa, + struct ospf6_router_lsa *router_lsa) { - OSPF6_OPT_CLEAR_ALL (router_lsa->options); - memcpy (router_lsa->options, oa->options, 3); - - if (ospf6_is_router_abr (ospf6)) - SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B); - else - UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B); - - if (!IS_AREA_STUB (oa) && ospf6_asbr_is_asbr (oa->ospf6)) - { - SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E); - } - else - { - UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E); - } - - UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_V); - UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_W); + OSPF6_OPT_CLEAR_ALL(router_lsa->options); + memcpy(router_lsa->options, oa->options, 3); + + if (ospf6_is_router_abr(ospf6)) + SET_FLAG(router_lsa->bits, OSPF6_ROUTER_BIT_B); + else + UNSET_FLAG(router_lsa->bits, OSPF6_ROUTER_BIT_B); + + if (!IS_AREA_STUB(oa) && ospf6_asbr_is_asbr(oa->ospf6)) { + SET_FLAG(router_lsa->bits, OSPF6_ROUTER_BIT_E); + } else { + UNSET_FLAG(router_lsa->bits, OSPF6_ROUTER_BIT_E); + } + + UNSET_FLAG(router_lsa->bits, OSPF6_ROUTER_BIT_V); + UNSET_FLAG(router_lsa->bits, OSPF6_ROUTER_BIT_W); } -int -ospf6_router_is_stub_router (struct ospf6_lsa *lsa) +int ospf6_router_is_stub_router(struct ospf6_lsa *lsa) { - struct ospf6_router_lsa *rtr_lsa; - - if (lsa != NULL && OSPF6_LSA_IS_TYPE (ROUTER, lsa)) - { - rtr_lsa = (struct ospf6_router_lsa *) - ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header)); - - if (!OSPF6_OPT_ISSET (rtr_lsa->options, OSPF6_OPT_R)) - { - return (OSPF6_IS_STUB_ROUTER); - } - else if (!OSPF6_OPT_ISSET (rtr_lsa->options, OSPF6_OPT_V6)) - { - return (OSPF6_IS_STUB_ROUTER_V6); + struct ospf6_router_lsa *rtr_lsa; + + if (lsa != NULL && OSPF6_LSA_IS_TYPE(ROUTER, lsa)) { + rtr_lsa = (struct ospf6_router_lsa + *)((caddr_t)lsa->header + + sizeof(struct ospf6_lsa_header)); + + if (!OSPF6_OPT_ISSET(rtr_lsa->options, OSPF6_OPT_R)) { + return (OSPF6_IS_STUB_ROUTER); + } else if (!OSPF6_OPT_ISSET(rtr_lsa->options, OSPF6_OPT_V6)) { + return (OSPF6_IS_STUB_ROUTER_V6); + } } - } - return (OSPF6_NOT_STUB_ROUTER); + return (OSPF6_NOT_STUB_ROUTER); } -int -ospf6_router_lsa_originate (struct thread *thread) +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; - - u_int32_t link_state_id = 0; - struct listnode *node, *nnode; - struct listnode *j; - struct ospf6_interface *oi; - struct ospf6_neighbor *on, *drouter = NULL; - struct ospf6_router_lsa *router_lsa; - struct ospf6_router_lsdesc *lsdesc; - u_int16_t type; - u_int32_t router; - int count; - - oa = (struct ospf6_area *) THREAD_ARG (thread); - oa->thread_router_lsa = NULL; - - if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER)) - zlog_debug ("Originate Router-LSA for Area %s", oa->name); - - memset (buffer, 0, sizeof (buffer)); - lsa_header = (struct ospf6_lsa_header *) buffer; - router_lsa = (struct ospf6_router_lsa *) - ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header)); - - ospf6_router_lsa_options_set (oa, router_lsa); - - /* describe links for each interfaces */ - lsdesc = (struct ospf6_router_lsdesc *) - ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa)); - - for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi)) - { - /* Interfaces in state Down or Loopback are not described */ - if (oi->state == OSPF6_INTERFACE_DOWN || - oi->state == OSPF6_INTERFACE_LOOPBACK) - continue; - - /* Nor are interfaces without any full adjacencies described */ - count = 0; - for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on)) - if (on->state == OSPF6_NEIGHBOR_FULL) - count++; - - if (count == 0) - continue; - - /* Multiple Router-LSA instance according to size limit setting */ - if ( (oa->router_lsa_size_limit != 0) - && ((size_t)((char *)lsdesc - buffer) - + sizeof (struct ospf6_router_lsdesc) - > oa->router_lsa_size_limit)) - { - if ((caddr_t) lsdesc == (caddr_t) router_lsa + - sizeof (struct ospf6_router_lsa)) - { - if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER)) - zlog_debug ("Size limit setting for Router-LSA too short"); - return 0; - } - - link_state_id ++; - } - - /* Point-to-Point interfaces */ - if (oi->type == OSPF_IFTYPE_POINTOPOINT) - { - for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on)) - { - if (on->state != OSPF6_NEIGHBOR_FULL) - continue; - - lsdesc->type = OSPF6_ROUTER_LSDESC_POINTTOPOINT; - lsdesc->metric = htons (oi->cost); - lsdesc->interface_id = htonl (oi->interface->ifindex); - lsdesc->neighbor_interface_id = htonl (on->ifindex); - lsdesc->neighbor_router_id = on->router_id; - - lsdesc++; - } - } - - /* Broadcast and NBMA interfaces */ - else if (oi->type == OSPF_IFTYPE_BROADCAST) - { - /* If this router is not DR, - and If this router not fully adjacent with DR, - this interface is not transit yet: ignore. */ - if (oi->state != OSPF6_INTERFACE_DR) - { - drouter = ospf6_neighbor_lookup (oi->drouter, oi); - if (drouter == NULL || drouter->state != OSPF6_NEIGHBOR_FULL) - continue; - } - - lsdesc->type = OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK; - lsdesc->metric = htons (oi->cost); - lsdesc->interface_id = htonl (oi->interface->ifindex); - if (oi->state != OSPF6_INTERFACE_DR) - { - lsdesc->neighbor_interface_id = htonl (drouter->ifindex); - lsdesc->neighbor_router_id = drouter->router_id; - } - else - { - lsdesc->neighbor_interface_id = htonl (oi->interface->ifindex); - lsdesc->neighbor_router_id = oi->area->ospf6->router_id; - } - - lsdesc++; - } - else - { - assert (0); /* Unknown interface type */ + struct ospf6_area *oa; + + char buffer[OSPF6_MAX_LSASIZE]; + struct ospf6_lsa_header *lsa_header; + struct ospf6_lsa *lsa; + + u_int32_t link_state_id = 0; + struct listnode *node, *nnode; + struct listnode *j; + struct ospf6_interface *oi; + struct ospf6_neighbor *on, *drouter = NULL; + struct ospf6_router_lsa *router_lsa; + struct ospf6_router_lsdesc *lsdesc; + u_int16_t type; + u_int32_t router; + int count; + + oa = (struct ospf6_area *)THREAD_ARG(thread); + oa->thread_router_lsa = NULL; + + if (IS_OSPF6_DEBUG_ORIGINATE(ROUTER)) + zlog_debug("Originate Router-LSA for Area %s", oa->name); + + memset(buffer, 0, sizeof(buffer)); + lsa_header = (struct ospf6_lsa_header *)buffer; + router_lsa = + (struct ospf6_router_lsa *)((caddr_t)lsa_header + + sizeof(struct ospf6_lsa_header)); + + ospf6_router_lsa_options_set(oa, router_lsa); + + /* describe links for each interfaces */ + lsdesc = (struct ospf6_router_lsdesc + *)((caddr_t)router_lsa + + sizeof(struct ospf6_router_lsa)); + + for (ALL_LIST_ELEMENTS(oa->if_list, node, nnode, oi)) { + /* Interfaces in state Down or Loopback are not described */ + if (oi->state == OSPF6_INTERFACE_DOWN + || oi->state == OSPF6_INTERFACE_LOOPBACK) + continue; + + /* Nor are interfaces without any full adjacencies described */ + count = 0; + for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, j, on)) + if (on->state == OSPF6_NEIGHBOR_FULL) + count++; + + if (count == 0) + continue; + + /* Multiple Router-LSA instance according to size limit setting + */ + if ((oa->router_lsa_size_limit != 0) + && ((size_t)((char *)lsdesc - buffer) + + sizeof(struct ospf6_router_lsdesc) + > oa->router_lsa_size_limit)) { + if ((caddr_t)lsdesc + == (caddr_t)router_lsa + + sizeof(struct ospf6_router_lsa)) { + if (IS_OSPF6_DEBUG_ORIGINATE(ROUTER)) + zlog_debug( + "Size limit setting for Router-LSA too short"); + return 0; + } + + link_state_id++; + } + + /* Point-to-Point interfaces */ + if (oi->type == OSPF_IFTYPE_POINTOPOINT) { + for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, j, on)) { + if (on->state != OSPF6_NEIGHBOR_FULL) + continue; + + lsdesc->type = OSPF6_ROUTER_LSDESC_POINTTOPOINT; + lsdesc->metric = htons(oi->cost); + lsdesc->interface_id = + htonl(oi->interface->ifindex); + lsdesc->neighbor_interface_id = + htonl(on->ifindex); + lsdesc->neighbor_router_id = on->router_id; + + lsdesc++; + } + } + + /* Broadcast and NBMA interfaces */ + else if (oi->type == OSPF_IFTYPE_BROADCAST) { + /* If this router is not DR, + and If this router not fully adjacent with DR, + this interface is not transit yet: ignore. */ + if (oi->state != OSPF6_INTERFACE_DR) { + drouter = + ospf6_neighbor_lookup(oi->drouter, oi); + if (drouter == NULL + || drouter->state != OSPF6_NEIGHBOR_FULL) + continue; + } + + lsdesc->type = OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK; + lsdesc->metric = htons(oi->cost); + lsdesc->interface_id = htonl(oi->interface->ifindex); + if (oi->state != OSPF6_INTERFACE_DR) { + lsdesc->neighbor_interface_id = + htonl(drouter->ifindex); + lsdesc->neighbor_router_id = drouter->router_id; + } else { + lsdesc->neighbor_interface_id = + htonl(oi->interface->ifindex); + lsdesc->neighbor_router_id = + oi->area->ospf6->router_id; + } + + lsdesc++; + } else { + assert(0); /* Unknown interface type */ + } + + /* Virtual links */ + /* xxx */ + /* Point-to-Multipoint interfaces */ + /* xxx */ + } + + /* Fill LSA Header */ + lsa_header->age = 0; + lsa_header->type = htons(OSPF6_LSTYPE_ROUTER); + lsa_header->id = htonl(link_state_id); + lsa_header->adv_router = oa->ospf6->router_id; + lsa_header->seqnum = + ospf6_new_ls_seqnum(lsa_header->type, lsa_header->id, + lsa_header->adv_router, oa->lsdb); + lsa_header->length = htons((caddr_t)lsdesc - (caddr_t)buffer); + + /* LSA checksum */ + ospf6_lsa_checksum(lsa_header); + + /* create LSA */ + lsa = ospf6_lsa_create(lsa_header); + + /* Originate */ + ospf6_lsa_originate_area(lsa, oa); + + link_state_id++; + + /* Do premature-aging of rest, undesired Router-LSAs */ + type = ntohs(OSPF6_LSTYPE_ROUTER); + router = oa->ospf6->router_id; + count = 0; + for (ALL_LSDB_TYPED_ADVRTR(oa->lsdb, type, router, lsa)) { + if (ntohl(lsa->header->id) < link_state_id) + continue; + ospf6_lsa_purge(lsa); + count++; } - /* Virtual links */ - /* xxx */ - /* Point-to-Multipoint interfaces */ - /* xxx */ - } - - /* Fill LSA Header */ - lsa_header->age = 0; - lsa_header->type = htons (OSPF6_LSTYPE_ROUTER); - lsa_header->id = htonl (link_state_id); - lsa_header->adv_router = oa->ospf6->router_id; - lsa_header->seqnum = - ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id, - lsa_header->adv_router, oa->lsdb); - lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer); - - /* LSA checksum */ - ospf6_lsa_checksum (lsa_header); - - /* create LSA */ - lsa = ospf6_lsa_create (lsa_header); - - /* Originate */ - ospf6_lsa_originate_area (lsa, oa); - - link_state_id ++; - - /* Do premature-aging of rest, undesired Router-LSAs */ - type = ntohs (OSPF6_LSTYPE_ROUTER); - router = oa->ospf6->router_id; - count = 0; - for (ALL_LSDB_TYPED_ADVRTR(oa->lsdb, type, router, lsa)) - { - if (ntohl (lsa->header->id) < link_state_id) - continue; - ospf6_lsa_purge (lsa); - count++; - } - - /* - * Waiting till the LSA is actually removed from the database to trigger - * SPF delays network convergence. Unlike IPv4, for an ABR, when all - * interfaces associated with an area are gone, triggering an SPF right away - * helps convergence with inter-area routes. - */ - if (count && !link_state_id) - ospf6_spf_schedule (oa->ospf6, OSPF6_SPF_FLAGS_ROUTER_LSA_ORIGINATED); - - return 0; + /* + * Waiting till the LSA is actually removed from the database to trigger + * SPF delays network convergence. Unlike IPv4, for an ABR, when all + * interfaces associated with an area are gone, triggering an SPF right + * away + * helps convergence with inter-area routes. + */ + if (count && !link_state_id) + ospf6_spf_schedule(oa->ospf6, + OSPF6_SPF_FLAGS_ROUTER_LSA_ORIGINATED); + + return 0; } /*******************************/ /* RFC2740 3.4.3.2 Network-LSA */ /*******************************/ -static char * -ospf6_network_lsa_get_ar_id (struct ospf6_lsa *lsa, char *buf, int buflen, - int pos) +static char *ospf6_network_lsa_get_ar_id(struct ospf6_lsa *lsa, char *buf, + int buflen, int pos) { - char *start, *end, *current; - struct ospf6_network_lsa *network_lsa; - struct ospf6_network_lsdesc *lsdesc; - - if (lsa) - { - network_lsa = (struct ospf6_network_lsa *) - ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header)); - - start = (char *) network_lsa + sizeof (struct ospf6_network_lsa); - end = (char *) lsa->header + ntohs (lsa->header->length); - current = start + pos*(sizeof (struct ospf6_network_lsdesc)); - - if ((current + sizeof(struct ospf6_network_lsdesc)) <= end) - { - lsdesc = (struct ospf6_network_lsdesc *)current; - if (buf) - inet_ntop (AF_INET, &lsdesc->router_id, buf, buflen); + char *start, *end, *current; + struct ospf6_network_lsa *network_lsa; + struct ospf6_network_lsdesc *lsdesc; + + if (lsa) { + network_lsa = (struct ospf6_network_lsa + *)((caddr_t)lsa->header + + sizeof(struct ospf6_lsa_header)); + + start = (char *)network_lsa + sizeof(struct ospf6_network_lsa); + end = (char *)lsa->header + ntohs(lsa->header->length); + current = start + pos * (sizeof(struct ospf6_network_lsdesc)); + + if ((current + sizeof(struct ospf6_network_lsdesc)) <= end) { + lsdesc = (struct ospf6_network_lsdesc *)current; + if (buf) + inet_ntop(AF_INET, &lsdesc->router_id, buf, + buflen); + } else + return NULL; } - else - return NULL; - } - return (buf); + return (buf); } -static int -ospf6_network_lsa_show (struct vty *vty, struct ospf6_lsa *lsa) +static int ospf6_network_lsa_show(struct vty *vty, struct ospf6_lsa *lsa) { - char *start, *end, *current; - struct ospf6_network_lsa *network_lsa; - struct ospf6_network_lsdesc *lsdesc; - char buf[128], options[32]; - - network_lsa = (struct ospf6_network_lsa *) - ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header)); - - ospf6_options_printbuf (network_lsa->options, options, sizeof (options)); - vty_out (vty, " Options: %s\n", options); - - start = (char *) network_lsa + sizeof (struct ospf6_network_lsa); - end = (char *) lsa->header + ntohs (lsa->header->length); - for (current = start; current + sizeof (struct ospf6_network_lsdesc) <= end; - current += sizeof (struct ospf6_network_lsdesc)) - { - lsdesc = (struct ospf6_network_lsdesc *) current; - inet_ntop (AF_INET, &lsdesc->router_id, buf, sizeof (buf)); - vty_out (vty, " Attached Router: %s\n", buf); - } - return 0; + char *start, *end, *current; + struct ospf6_network_lsa *network_lsa; + struct ospf6_network_lsdesc *lsdesc; + char buf[128], options[32]; + + network_lsa = + (struct ospf6_network_lsa *)((caddr_t)lsa->header + + sizeof(struct ospf6_lsa_header)); + + ospf6_options_printbuf(network_lsa->options, options, sizeof(options)); + vty_out(vty, " Options: %s\n", options); + + start = (char *)network_lsa + sizeof(struct ospf6_network_lsa); + end = (char *)lsa->header + ntohs(lsa->header->length); + for (current = start; + current + sizeof(struct ospf6_network_lsdesc) <= end; + current += sizeof(struct ospf6_network_lsdesc)) { + lsdesc = (struct ospf6_network_lsdesc *)current; + inet_ntop(AF_INET, &lsdesc->router_id, buf, sizeof(buf)); + vty_out(vty, " Attached Router: %s\n", buf); + } + return 0; } -int -ospf6_network_lsa_originate (struct thread *thread) +int ospf6_network_lsa_originate(struct thread *thread) { - struct ospf6_interface *oi; - - char buffer [OSPF6_MAX_LSASIZE]; - struct ospf6_lsa_header *lsa_header; - - int count; - struct ospf6_lsa *old, *lsa; - struct ospf6_network_lsa *network_lsa; - struct ospf6_network_lsdesc *lsdesc; - struct ospf6_neighbor *on; - struct ospf6_link_lsa *link_lsa; - struct listnode *i; - u_int16_t type; - - 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), - oi->area->ospf6->router_id, oi->area->lsdb); - - /* Do not originate Network-LSA if not DR */ - if (oi->state != OSPF6_INTERFACE_DR) - { - if (old) - { - ospf6_lsa_purge (old); - /* - * Waiting till the LSA is actually removed from the database to - * trigger SPF delays network convergence. - */ - ospf6_spf_schedule (oi->area->ospf6, - OSPF6_SPF_FLAGS_NETWORK_LSA_ORIGINATED); + struct ospf6_interface *oi; + + char buffer[OSPF6_MAX_LSASIZE]; + struct ospf6_lsa_header *lsa_header; + + int count; + struct ospf6_lsa *old, *lsa; + struct ospf6_network_lsa *network_lsa; + struct ospf6_network_lsdesc *lsdesc; + struct ospf6_neighbor *on; + struct ospf6_link_lsa *link_lsa; + struct listnode *i; + u_int16_t type; + + 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), + oi->area->ospf6->router_id, oi->area->lsdb); + + /* Do not originate Network-LSA if not DR */ + if (oi->state != OSPF6_INTERFACE_DR) { + if (old) { + ospf6_lsa_purge(old); + /* + * Waiting till the LSA is actually removed from the + * database to + * trigger SPF delays network convergence. + */ + ospf6_spf_schedule( + oi->area->ospf6, + OSPF6_SPF_FLAGS_NETWORK_LSA_ORIGINATED); + } + return 0; + } + + if (IS_OSPF6_DEBUG_ORIGINATE(NETWORK)) + zlog_debug("Originate Network-LSA for Interface %s", + oi->interface->name); + + /* If none of neighbor is adjacent to us */ + count = 0; + + for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, i, on)) + if (on->state == OSPF6_NEIGHBOR_FULL) + count++; + + if (count == 0) { + if (IS_OSPF6_DEBUG_ORIGINATE(NETWORK)) + zlog_debug("Interface stub, ignore"); + if (old) + ospf6_lsa_purge(old); + return 0; } - return 0; - } - - if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK)) - zlog_debug ("Originate Network-LSA for Interface %s", oi->interface->name); - - /* If none of neighbor is adjacent to us */ - count = 0; - - for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on)) - if (on->state == OSPF6_NEIGHBOR_FULL) - count++; - - if (count == 0) - { - if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK)) - zlog_debug ("Interface stub, ignore"); - if (old) - ospf6_lsa_purge (old); - return 0; - } - - /* prepare buffer */ - memset (buffer, 0, sizeof (buffer)); - lsa_header = (struct ospf6_lsa_header *) buffer; - network_lsa = (struct ospf6_network_lsa *) - ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header)); - - /* Collect the interface's Link-LSAs to describe - network's optional capabilities */ - type = htons (OSPF6_LSTYPE_LINK); - for (ALL_LSDB_TYPED(oi->lsdb, type, lsa)) - { - link_lsa = (struct ospf6_link_lsa *) - ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header)); - network_lsa->options[0] |= link_lsa->options[0]; - network_lsa->options[1] |= link_lsa->options[1]; - network_lsa->options[2] |= link_lsa->options[2]; - } - - lsdesc = (struct ospf6_network_lsdesc *) - ((caddr_t) network_lsa + sizeof (struct ospf6_network_lsa)); - - /* set Link Description to the router itself */ - lsdesc->router_id = oi->area->ospf6->router_id; - lsdesc++; - - /* Walk through the neighbors */ - for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on)) - { - if (on->state != OSPF6_NEIGHBOR_FULL) - continue; - - /* set this neighbor's Router-ID to LSA */ - lsdesc->router_id = on->router_id; - lsdesc++; - } - - /* Fill LSA Header */ - lsa_header->age = 0; - lsa_header->type = htons (OSPF6_LSTYPE_NETWORK); - lsa_header->id = htonl (oi->interface->ifindex); - lsa_header->adv_router = oi->area->ospf6->router_id; - lsa_header->seqnum = - ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id, - lsa_header->adv_router, oi->area->lsdb); - lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer); - - /* LSA checksum */ - ospf6_lsa_checksum (lsa_header); - - /* create LSA */ - lsa = ospf6_lsa_create (lsa_header); - - /* Originate */ - ospf6_lsa_originate_area (lsa, oi->area); - - return 0; + + /* prepare buffer */ + memset(buffer, 0, sizeof(buffer)); + lsa_header = (struct ospf6_lsa_header *)buffer; + network_lsa = + (struct ospf6_network_lsa *)((caddr_t)lsa_header + + sizeof(struct ospf6_lsa_header)); + + /* Collect the interface's Link-LSAs to describe + network's optional capabilities */ + type = htons(OSPF6_LSTYPE_LINK); + for (ALL_LSDB_TYPED(oi->lsdb, type, lsa)) { + link_lsa = (struct ospf6_link_lsa + *)((caddr_t)lsa->header + + sizeof(struct ospf6_lsa_header)); + network_lsa->options[0] |= link_lsa->options[0]; + network_lsa->options[1] |= link_lsa->options[1]; + network_lsa->options[2] |= link_lsa->options[2]; + } + + lsdesc = (struct ospf6_network_lsdesc + *)((caddr_t)network_lsa + + sizeof(struct ospf6_network_lsa)); + + /* set Link Description to the router itself */ + lsdesc->router_id = oi->area->ospf6->router_id; + lsdesc++; + + /* Walk through the neighbors */ + for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, i, on)) { + if (on->state != OSPF6_NEIGHBOR_FULL) + continue; + + /* set this neighbor's Router-ID to LSA */ + lsdesc->router_id = on->router_id; + lsdesc++; + } + + /* Fill LSA Header */ + lsa_header->age = 0; + lsa_header->type = htons(OSPF6_LSTYPE_NETWORK); + lsa_header->id = htonl(oi->interface->ifindex); + lsa_header->adv_router = oi->area->ospf6->router_id; + lsa_header->seqnum = + ospf6_new_ls_seqnum(lsa_header->type, lsa_header->id, + lsa_header->adv_router, oi->area->lsdb); + lsa_header->length = htons((caddr_t)lsdesc - (caddr_t)buffer); + + /* LSA checksum */ + ospf6_lsa_checksum(lsa_header); + + /* create LSA */ + lsa = ospf6_lsa_create(lsa_header); + + /* Originate */ + ospf6_lsa_originate_area(lsa, oi->area); + + return 0; } @@ -548,1152 +538,1107 @@ ospf6_network_lsa_originate (struct thread *thread) /* RFC2740 3.4.3.6 Link-LSA */ /****************************/ -static char * -ospf6_link_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf, int buflen, - int pos) +static char *ospf6_link_lsa_get_prefix_str(struct ospf6_lsa *lsa, char *buf, + int buflen, int pos) { - char *start, *end, *current; - struct ospf6_link_lsa *link_lsa; - struct in6_addr in6; - struct ospf6_prefix *prefix; - int cnt = 0, prefixnum; - - if (lsa) - { - link_lsa = (struct ospf6_link_lsa *) - ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header)); - - if (pos == 0) { - inet_ntop (AF_INET6, &link_lsa->linklocal_addr, buf, buflen); - return (buf); - } - - prefixnum = ntohl (link_lsa->prefix_num); - if (pos > prefixnum) + char *start, *end, *current; + struct ospf6_link_lsa *link_lsa; + struct in6_addr in6; + struct ospf6_prefix *prefix; + int cnt = 0, prefixnum; + + if (lsa) { + link_lsa = (struct ospf6_link_lsa + *)((caddr_t)lsa->header + + sizeof(struct ospf6_lsa_header)); + + if (pos == 0) { + inet_ntop(AF_INET6, &link_lsa->linklocal_addr, buf, + buflen); + return (buf); + } + + prefixnum = ntohl(link_lsa->prefix_num); + if (pos > prefixnum) + return (NULL); + + start = (char *)link_lsa + sizeof(struct ospf6_link_lsa); + end = (char *)lsa->header + ntohs(lsa->header->length); + current = start; + + do { + prefix = (struct ospf6_prefix *)current; + if (prefix->prefix_length == 0 + || current + OSPF6_PREFIX_SIZE(prefix) > end) { + return (NULL); + } + + if (cnt < pos) { + current = + start + pos * OSPF6_PREFIX_SIZE(prefix); + cnt++; + } else { + memset(&in6, 0, sizeof(in6)); + memcpy(&in6, OSPF6_PREFIX_BODY(prefix), + OSPF6_PREFIX_SPACE( + prefix->prefix_length)); + inet_ntop(AF_INET6, &in6, buf, buflen); + return (buf); + } + } while (current <= end); + } return (NULL); - - start = (char *) link_lsa + sizeof (struct ospf6_link_lsa); - end = (char *) lsa->header + ntohs (lsa->header->length); - current = start; - - do - { - prefix = (struct ospf6_prefix *) current; - if (prefix->prefix_length == 0 || - current + OSPF6_PREFIX_SIZE (prefix) > end) - { - return (NULL); - } - - if (cnt < pos) - { - current = start + pos*OSPF6_PREFIX_SIZE(prefix); - cnt++; - } - else - { - memset (&in6, 0, sizeof (in6)); - memcpy (&in6, OSPF6_PREFIX_BODY (prefix), - OSPF6_PREFIX_SPACE (prefix->prefix_length)); - inet_ntop (AF_INET6, &in6, buf, buflen); - return (buf); - } - } while (current <= end); - } - return (NULL); } -static int -ospf6_link_lsa_show (struct vty *vty, struct ospf6_lsa *lsa) +static int ospf6_link_lsa_show(struct vty *vty, struct ospf6_lsa *lsa) { - char *start, *end, *current; - struct ospf6_link_lsa *link_lsa; - int prefixnum; - char buf[128], options[32]; - struct ospf6_prefix *prefix; - const char *p, *mc, *la, *nu; - struct in6_addr in6; - - link_lsa = (struct ospf6_link_lsa *) - ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header)); - - ospf6_options_printbuf (link_lsa->options, options, sizeof (options)); - inet_ntop (AF_INET6, &link_lsa->linklocal_addr, buf, sizeof (buf)); - prefixnum = ntohl (link_lsa->prefix_num); - - vty_out (vty, " Priority: %d Options: %s\n", - link_lsa->priority, options); - vty_out (vty, " LinkLocal Address: %s\n", buf); - vty_out (vty, " Number of Prefix: %d\n", prefixnum); - - start = (char *) link_lsa + sizeof (struct ospf6_link_lsa); - end = (char *) lsa->header + ntohs (lsa->header->length); - for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix)) - { - prefix = (struct ospf6_prefix *) current; - if (prefix->prefix_length == 0 || - current + OSPF6_PREFIX_SIZE (prefix) > end) - break; - - p = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_P) ? - "P" : "--"); - mc = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) ? - "MC" : "--"); - la = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) ? - "LA" : "--"); - nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ? - "NU" : "--"); - vty_out (vty, " Prefix Options: %s|%s|%s|%s\n", - p, mc, la, nu); - - memset (&in6, 0, sizeof (in6)); - memcpy (&in6, OSPF6_PREFIX_BODY (prefix), - OSPF6_PREFIX_SPACE (prefix->prefix_length)); - inet_ntop (AF_INET6, &in6, buf, sizeof (buf)); - vty_out (vty, " Prefix: %s/%d\n", - buf, prefix->prefix_length); - } - - return 0; + char *start, *end, *current; + struct ospf6_link_lsa *link_lsa; + int prefixnum; + char buf[128], options[32]; + struct ospf6_prefix *prefix; + const char *p, *mc, *la, *nu; + struct in6_addr in6; + + link_lsa = (struct ospf6_link_lsa *)((caddr_t)lsa->header + + sizeof(struct ospf6_lsa_header)); + + ospf6_options_printbuf(link_lsa->options, options, sizeof(options)); + inet_ntop(AF_INET6, &link_lsa->linklocal_addr, buf, sizeof(buf)); + prefixnum = ntohl(link_lsa->prefix_num); + + vty_out(vty, " Priority: %d Options: %s\n", link_lsa->priority, + options); + vty_out(vty, " LinkLocal Address: %s\n", buf); + vty_out(vty, " Number of Prefix: %d\n", prefixnum); + + start = (char *)link_lsa + sizeof(struct ospf6_link_lsa); + end = (char *)lsa->header + ntohs(lsa->header->length); + for (current = start; current < end; + current += OSPF6_PREFIX_SIZE(prefix)) { + prefix = (struct ospf6_prefix *)current; + if (prefix->prefix_length == 0 + || current + OSPF6_PREFIX_SIZE(prefix) > end) + break; + + p = (CHECK_FLAG(prefix->prefix_options, OSPF6_PREFIX_OPTION_P) + ? "P" + : "--"); + mc = (CHECK_FLAG(prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) + ? "MC" + : "--"); + la = (CHECK_FLAG(prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) + ? "LA" + : "--"); + nu = (CHECK_FLAG(prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) + ? "NU" + : "--"); + vty_out(vty, " Prefix Options: %s|%s|%s|%s\n", p, mc, la, + nu); + + memset(&in6, 0, sizeof(in6)); + memcpy(&in6, OSPF6_PREFIX_BODY(prefix), + OSPF6_PREFIX_SPACE(prefix->prefix_length)); + inet_ntop(AF_INET6, &in6, buf, sizeof(buf)); + vty_out(vty, " Prefix: %s/%d\n", buf, + prefix->prefix_length); + } + + return 0; } -int -ospf6_link_lsa_originate (struct thread *thread) +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; - - struct ospf6_link_lsa *link_lsa; - struct ospf6_route *route; - struct ospf6_prefix *op; - - 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), - htonl (oi->interface->ifindex), - oi->area->ospf6->router_id, oi->lsdb); - - if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE)) - { - if (old) - ospf6_lsa_purge (old); - return 0; - } - - if (IS_OSPF6_DEBUG_ORIGINATE (LINK)) - zlog_debug ("Originate Link-LSA for Interface %s", oi->interface->name); - - /* can't make Link-LSA if linklocal address not set */ - if (oi->linklocal_addr == NULL) - { - if (IS_OSPF6_DEBUG_ORIGINATE (LINK)) - zlog_debug ("No Linklocal address on %s, defer originating", - oi->interface->name); - if (old) - ospf6_lsa_purge (old); - return 0; - } - - /* prepare buffer */ - memset (buffer, 0, sizeof (buffer)); - lsa_header = (struct ospf6_lsa_header *) buffer; - link_lsa = (struct ospf6_link_lsa *) - ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header)); - - /* Fill Link-LSA */ - link_lsa->priority = oi->priority; - memcpy (link_lsa->options, oi->area->options, 3); - memcpy (&link_lsa->linklocal_addr, oi->linklocal_addr, - sizeof (struct in6_addr)); - link_lsa->prefix_num = htonl (oi->route_connected->count); - - op = (struct ospf6_prefix *) - ((caddr_t) link_lsa + sizeof (struct ospf6_link_lsa)); - - /* connected prefix to advertise */ - for (route = ospf6_route_head (oi->route_connected); route; - route = ospf6_route_next (route)) - { - op->prefix_length = route->prefix.prefixlen; - op->prefix_options = route->path.prefix_options; - op->prefix_metric = htons (0); - memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6, - OSPF6_PREFIX_SPACE (op->prefix_length)); - op = OSPF6_PREFIX_NEXT (op); - } - - /* Fill LSA Header */ - lsa_header->age = 0; - lsa_header->type = htons (OSPF6_LSTYPE_LINK); - lsa_header->id = htonl (oi->interface->ifindex); - lsa_header->adv_router = oi->area->ospf6->router_id; - lsa_header->seqnum = - ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id, - lsa_header->adv_router, oi->lsdb); - lsa_header->length = htons ((caddr_t) op - (caddr_t) buffer); - - /* LSA checksum */ - ospf6_lsa_checksum (lsa_header); - - /* create LSA */ - lsa = ospf6_lsa_create (lsa_header); - - /* Originate */ - ospf6_lsa_originate_interface (lsa, oi); - - return 0; + struct ospf6_interface *oi; + + char buffer[OSPF6_MAX_LSASIZE]; + struct ospf6_lsa_header *lsa_header; + struct ospf6_lsa *old, *lsa; + + struct ospf6_link_lsa *link_lsa; + struct ospf6_route *route; + struct ospf6_prefix *op; + + 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), + htonl(oi->interface->ifindex), + oi->area->ospf6->router_id, oi->lsdb); + + if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) { + if (old) + ospf6_lsa_purge(old); + return 0; + } + + if (IS_OSPF6_DEBUG_ORIGINATE(LINK)) + zlog_debug("Originate Link-LSA for Interface %s", + oi->interface->name); + + /* can't make Link-LSA if linklocal address not set */ + if (oi->linklocal_addr == NULL) { + if (IS_OSPF6_DEBUG_ORIGINATE(LINK)) + zlog_debug( + "No Linklocal address on %s, defer originating", + oi->interface->name); + if (old) + ospf6_lsa_purge(old); + return 0; + } + + /* prepare buffer */ + memset(buffer, 0, sizeof(buffer)); + lsa_header = (struct ospf6_lsa_header *)buffer; + link_lsa = (struct ospf6_link_lsa *)((caddr_t)lsa_header + + sizeof(struct ospf6_lsa_header)); + + /* Fill Link-LSA */ + link_lsa->priority = oi->priority; + memcpy(link_lsa->options, oi->area->options, 3); + memcpy(&link_lsa->linklocal_addr, oi->linklocal_addr, + sizeof(struct in6_addr)); + link_lsa->prefix_num = htonl(oi->route_connected->count); + + op = (struct ospf6_prefix *)((caddr_t)link_lsa + + sizeof(struct ospf6_link_lsa)); + + /* connected prefix to advertise */ + for (route = ospf6_route_head(oi->route_connected); route; + route = ospf6_route_next(route)) { + op->prefix_length = route->prefix.prefixlen; + op->prefix_options = route->path.prefix_options; + op->prefix_metric = htons(0); + memcpy(OSPF6_PREFIX_BODY(op), &route->prefix.u.prefix6, + OSPF6_PREFIX_SPACE(op->prefix_length)); + op = OSPF6_PREFIX_NEXT(op); + } + + /* Fill LSA Header */ + lsa_header->age = 0; + lsa_header->type = htons(OSPF6_LSTYPE_LINK); + lsa_header->id = htonl(oi->interface->ifindex); + lsa_header->adv_router = oi->area->ospf6->router_id; + lsa_header->seqnum = + ospf6_new_ls_seqnum(lsa_header->type, lsa_header->id, + lsa_header->adv_router, oi->lsdb); + lsa_header->length = htons((caddr_t)op - (caddr_t)buffer); + + /* LSA checksum */ + ospf6_lsa_checksum(lsa_header); + + /* create LSA */ + lsa = ospf6_lsa_create(lsa_header); + + /* Originate */ + ospf6_lsa_originate_interface(lsa, oi); + + return 0; } /*****************************************/ /* RFC2740 3.4.3.7 Intra-Area-Prefix-LSA */ /*****************************************/ -static char * -ospf6_intra_prefix_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf, - int buflen, int pos) +static char *ospf6_intra_prefix_lsa_get_prefix_str(struct ospf6_lsa *lsa, + char *buf, int buflen, + int pos) { - char *start, *end, *current; - struct ospf6_intra_prefix_lsa *intra_prefix_lsa; - struct in6_addr in6; - int prefixnum, cnt = 0; - struct ospf6_prefix *prefix; - - if (lsa) - { - intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *) - ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header)); - - prefixnum = ntohs (intra_prefix_lsa->prefix_num); - if (pos > prefixnum) - return (NULL); - - start = (char *) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa); - end = (char *) lsa->header + ntohs (lsa->header->length); - current = start; - - do - { - prefix = (struct ospf6_prefix *) current; - if (prefix->prefix_length == 0 || - current + OSPF6_PREFIX_SIZE (prefix) > end) - { - return NULL; - } - - if (cnt < pos) - { - current = start + pos*OSPF6_PREFIX_SIZE(prefix); - cnt++; - } - else - { - memset (&in6, 0, sizeof (in6)); - memcpy (&in6, OSPF6_PREFIX_BODY (prefix), - OSPF6_PREFIX_SPACE (prefix->prefix_length)); - inet_ntop (AF_INET6, &in6, buf, buflen); - sprintf(&buf[strlen(buf)], "/%d", prefix->prefix_length); - return (buf); - } - } while (current <= end); - } - return (buf); + char *start, *end, *current; + struct ospf6_intra_prefix_lsa *intra_prefix_lsa; + struct in6_addr in6; + int prefixnum, cnt = 0; + struct ospf6_prefix *prefix; + + if (lsa) { + intra_prefix_lsa = + (struct ospf6_intra_prefix_lsa + *)((caddr_t)lsa->header + + sizeof(struct ospf6_lsa_header)); + + prefixnum = ntohs(intra_prefix_lsa->prefix_num); + if (pos > prefixnum) + return (NULL); + + start = (char *)intra_prefix_lsa + + sizeof(struct ospf6_intra_prefix_lsa); + end = (char *)lsa->header + ntohs(lsa->header->length); + current = start; + + do { + prefix = (struct ospf6_prefix *)current; + if (prefix->prefix_length == 0 + || current + OSPF6_PREFIX_SIZE(prefix) > end) { + return NULL; + } + + if (cnt < pos) { + current = + start + pos * OSPF6_PREFIX_SIZE(prefix); + cnt++; + } else { + memset(&in6, 0, sizeof(in6)); + memcpy(&in6, OSPF6_PREFIX_BODY(prefix), + OSPF6_PREFIX_SPACE( + prefix->prefix_length)); + inet_ntop(AF_INET6, &in6, buf, buflen); + sprintf(&buf[strlen(buf)], "/%d", + prefix->prefix_length); + return (buf); + } + } while (current <= end); + } + return (buf); } -static int -ospf6_intra_prefix_lsa_show (struct vty *vty, struct ospf6_lsa *lsa) +static int ospf6_intra_prefix_lsa_show(struct vty *vty, struct ospf6_lsa *lsa) { - char *start, *end, *current; - struct ospf6_intra_prefix_lsa *intra_prefix_lsa; - int prefixnum; - char buf[128]; - struct ospf6_prefix *prefix; - char id[16], adv_router[16]; - const char *p, *mc, *la, *nu; - struct in6_addr in6; - - intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *) - ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header)); - - prefixnum = ntohs (intra_prefix_lsa->prefix_num); - - vty_out (vty, " Number of Prefix: %d\n", prefixnum); - - inet_ntop (AF_INET, &intra_prefix_lsa->ref_id, id, sizeof (id)); - inet_ntop (AF_INET, &intra_prefix_lsa->ref_adv_router, - adv_router, sizeof (adv_router)); - vty_out (vty, " Reference: %s Id: %s Adv: %s\n", - ospf6_lstype_name (intra_prefix_lsa->ref_type), id, adv_router); - - start = (char *) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa); - end = (char *) lsa->header + ntohs (lsa->header->length); - for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix)) - { - prefix = (struct ospf6_prefix *) current; - if (prefix->prefix_length == 0 || - current + OSPF6_PREFIX_SIZE (prefix) > end) - break; - - p = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_P) ? - "P" : "--"); - mc = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) ? - "MC" : "--"); - la = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) ? - "LA" : "--"); - nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ? - "NU" : "--"); - vty_out (vty, " Prefix Options: %s|%s|%s|%s\n", - p, mc, la, nu); - - memset (&in6, 0, sizeof (in6)); - memcpy (&in6, OSPF6_PREFIX_BODY (prefix), - OSPF6_PREFIX_SPACE (prefix->prefix_length)); - inet_ntop (AF_INET6, &in6, buf, sizeof (buf)); - vty_out (vty, " Prefix: %s/%d\n", - buf, prefix->prefix_length); - } - - return 0; + char *start, *end, *current; + struct ospf6_intra_prefix_lsa *intra_prefix_lsa; + int prefixnum; + char buf[128]; + struct ospf6_prefix *prefix; + char id[16], adv_router[16]; + const char *p, *mc, *la, *nu; + struct in6_addr in6; + + intra_prefix_lsa = (struct ospf6_intra_prefix_lsa + *)((caddr_t)lsa->header + + sizeof(struct ospf6_lsa_header)); + + prefixnum = ntohs(intra_prefix_lsa->prefix_num); + + vty_out(vty, " Number of Prefix: %d\n", prefixnum); + + inet_ntop(AF_INET, &intra_prefix_lsa->ref_id, id, sizeof(id)); + inet_ntop(AF_INET, &intra_prefix_lsa->ref_adv_router, adv_router, + sizeof(adv_router)); + vty_out(vty, " Reference: %s Id: %s Adv: %s\n", + ospf6_lstype_name(intra_prefix_lsa->ref_type), id, adv_router); + + start = (char *)intra_prefix_lsa + + sizeof(struct ospf6_intra_prefix_lsa); + end = (char *)lsa->header + ntohs(lsa->header->length); + for (current = start; current < end; + current += OSPF6_PREFIX_SIZE(prefix)) { + prefix = (struct ospf6_prefix *)current; + if (prefix->prefix_length == 0 + || current + OSPF6_PREFIX_SIZE(prefix) > end) + break; + + p = (CHECK_FLAG(prefix->prefix_options, OSPF6_PREFIX_OPTION_P) + ? "P" + : "--"); + mc = (CHECK_FLAG(prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) + ? "MC" + : "--"); + la = (CHECK_FLAG(prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) + ? "LA" + : "--"); + nu = (CHECK_FLAG(prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) + ? "NU" + : "--"); + vty_out(vty, " Prefix Options: %s|%s|%s|%s\n", p, mc, la, + nu); + + memset(&in6, 0, sizeof(in6)); + memcpy(&in6, OSPF6_PREFIX_BODY(prefix), + OSPF6_PREFIX_SPACE(prefix->prefix_length)); + inet_ntop(AF_INET6, &in6, buf, sizeof(buf)); + vty_out(vty, " Prefix: %s/%d\n", buf, + prefix->prefix_length); + } + + return 0; } -int -ospf6_intra_prefix_lsa_originate_stub (struct thread *thread) +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; - - struct ospf6_intra_prefix_lsa *intra_prefix_lsa; - struct ospf6_interface *oi; - struct ospf6_neighbor *on; - struct ospf6_route *route; - struct ospf6_prefix *op; - struct listnode *i, *j; - int full_count = 0; - unsigned short prefix_num = 0; - char buf[PREFIX2STR_BUFFER]; - 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 (! IS_AREA_ENABLED (oa)) - { - if (old) - ospf6_lsa_purge (old); - return 0; - } - - if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) - zlog_debug ("Originate Intra-Area-Prefix-LSA for area %s's stub prefix", - oa->name); - - /* prepare buffer */ - memset (buffer, 0, sizeof (buffer)); - lsa_header = (struct ospf6_lsa_header *) buffer; - intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *) - ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header)); - - /* Fill Intra-Area-Prefix-LSA */ - intra_prefix_lsa->ref_type = htons (OSPF6_LSTYPE_ROUTER); - intra_prefix_lsa->ref_id = htonl (0); - intra_prefix_lsa->ref_adv_router = oa->ospf6->router_id; - - route_advertise = ospf6_route_table_create (0, 0); - - for (ALL_LIST_ELEMENTS_RO (oa->if_list, i, oi)) - { - if (oi->state == OSPF6_INTERFACE_DOWN) - { - if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) - zlog_debug (" Interface %s is down, ignore", oi->interface->name); - continue; - } - - full_count = 0; - - for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on)) - if (on->state == OSPF6_NEIGHBOR_FULL) - full_count++; - - if (oi->state != OSPF6_INTERFACE_LOOPBACK && - oi->state != OSPF6_INTERFACE_POINTTOPOINT && - full_count != 0) - { - if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) - zlog_debug (" Interface %s is not stub, ignore", - oi->interface->name); - continue; - } - - if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) - zlog_debug (" Interface %s:", oi->interface->name); - - /* connected prefix to advertise */ - for (route = ospf6_route_head (oi->route_connected); route; - route = ospf6_route_best_next (route)) - { - if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) - { - prefix2str (&route->prefix, buf, sizeof (buf)); - zlog_debug (" include %s", buf); - } - ospf6_route_add (ospf6_route_copy (route), route_advertise); - } - } - - if (route_advertise->count == 0) - { - if (old) - ospf6_lsa_purge (old); - ospf6_route_table_delete (route_advertise); - return 0; - } - - /* put prefixes to advertise */ - prefix_num = 0; - op = (struct ospf6_prefix *) - ((caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa)); - for (route = ospf6_route_head (route_advertise); route; - route = ospf6_route_best_next (route)) - { - op->prefix_length = route->prefix.prefixlen; - op->prefix_options = route->path.prefix_options; - op->prefix_metric = htons (route->path.cost); - memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6, - OSPF6_PREFIX_SPACE (op->prefix_length)); - op = OSPF6_PREFIX_NEXT (op); - prefix_num++; - } - - ospf6_route_table_delete (route_advertise); - - if (prefix_num == 0) - { - if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) - zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise"); - return 0; - } - - intra_prefix_lsa->prefix_num = htons (prefix_num); - - /* Fill LSA Header */ - lsa_header->age = 0; - lsa_header->type = htons (OSPF6_LSTYPE_INTRA_PREFIX); - lsa_header->id = htonl (0); - lsa_header->adv_router = oa->ospf6->router_id; - lsa_header->seqnum = - ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id, - lsa_header->adv_router, oa->lsdb); - lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header); - - /* LSA checksum */ - ospf6_lsa_checksum (lsa_header); - - /* create LSA */ - lsa = ospf6_lsa_create (lsa_header); - - /* Originate */ - ospf6_lsa_originate_area (lsa, oa); - - return 0; + struct ospf6_area *oa; + + char buffer[OSPF6_MAX_LSASIZE]; + struct ospf6_lsa_header *lsa_header; + struct ospf6_lsa *old, *lsa; + + struct ospf6_intra_prefix_lsa *intra_prefix_lsa; + struct ospf6_interface *oi; + struct ospf6_neighbor *on; + struct ospf6_route *route; + struct ospf6_prefix *op; + struct listnode *i, *j; + int full_count = 0; + unsigned short prefix_num = 0; + char buf[PREFIX2STR_BUFFER]; + 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 (!IS_AREA_ENABLED(oa)) { + if (old) + ospf6_lsa_purge(old); + return 0; + } + + if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX)) + zlog_debug( + "Originate Intra-Area-Prefix-LSA for area %s's stub prefix", + oa->name); + + /* prepare buffer */ + memset(buffer, 0, sizeof(buffer)); + lsa_header = (struct ospf6_lsa_header *)buffer; + intra_prefix_lsa = (struct ospf6_intra_prefix_lsa + *)((caddr_t)lsa_header + + sizeof(struct ospf6_lsa_header)); + + /* Fill Intra-Area-Prefix-LSA */ + intra_prefix_lsa->ref_type = htons(OSPF6_LSTYPE_ROUTER); + intra_prefix_lsa->ref_id = htonl(0); + intra_prefix_lsa->ref_adv_router = oa->ospf6->router_id; + + route_advertise = ospf6_route_table_create(0, 0); + + for (ALL_LIST_ELEMENTS_RO(oa->if_list, i, oi)) { + if (oi->state == OSPF6_INTERFACE_DOWN) { + if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX)) + zlog_debug(" Interface %s is down, ignore", + oi->interface->name); + continue; + } + + full_count = 0; + + for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, j, on)) + if (on->state == OSPF6_NEIGHBOR_FULL) + full_count++; + + if (oi->state != OSPF6_INTERFACE_LOOPBACK + && oi->state != OSPF6_INTERFACE_POINTTOPOINT + && full_count != 0) { + if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX)) + zlog_debug(" Interface %s is not stub, ignore", + oi->interface->name); + continue; + } + + if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX)) + zlog_debug(" Interface %s:", oi->interface->name); + + /* connected prefix to advertise */ + for (route = ospf6_route_head(oi->route_connected); route; + route = ospf6_route_best_next(route)) { + if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX)) { + prefix2str(&route->prefix, buf, sizeof(buf)); + zlog_debug(" include %s", buf); + } + ospf6_route_add(ospf6_route_copy(route), + route_advertise); + } + } + + if (route_advertise->count == 0) { + if (old) + ospf6_lsa_purge(old); + ospf6_route_table_delete(route_advertise); + return 0; + } + + /* put prefixes to advertise */ + prefix_num = 0; + op = (struct ospf6_prefix *)((caddr_t)intra_prefix_lsa + + sizeof(struct ospf6_intra_prefix_lsa)); + for (route = ospf6_route_head(route_advertise); route; + route = ospf6_route_best_next(route)) { + op->prefix_length = route->prefix.prefixlen; + op->prefix_options = route->path.prefix_options; + op->prefix_metric = htons(route->path.cost); + memcpy(OSPF6_PREFIX_BODY(op), &route->prefix.u.prefix6, + OSPF6_PREFIX_SPACE(op->prefix_length)); + op = OSPF6_PREFIX_NEXT(op); + prefix_num++; + } + + ospf6_route_table_delete(route_advertise); + + if (prefix_num == 0) { + if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX)) + zlog_debug( + "Quit to Advertise Intra-Prefix: no route to advertise"); + return 0; + } + + intra_prefix_lsa->prefix_num = htons(prefix_num); + + /* Fill LSA Header */ + lsa_header->age = 0; + lsa_header->type = htons(OSPF6_LSTYPE_INTRA_PREFIX); + lsa_header->id = htonl(0); + lsa_header->adv_router = oa->ospf6->router_id; + lsa_header->seqnum = + ospf6_new_ls_seqnum(lsa_header->type, lsa_header->id, + lsa_header->adv_router, oa->lsdb); + lsa_header->length = htons((caddr_t)op - (caddr_t)lsa_header); + + /* LSA checksum */ + ospf6_lsa_checksum(lsa_header); + + /* create LSA */ + lsa = ospf6_lsa_create(lsa_header); + + /* Originate */ + ospf6_lsa_originate_area(lsa, oa); + + return 0; } -int -ospf6_intra_prefix_lsa_originate_transit (struct thread *thread) +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; - - struct ospf6_intra_prefix_lsa *intra_prefix_lsa; - struct ospf6_neighbor *on; - struct ospf6_route *route; - struct ospf6_prefix *op; - struct listnode *i; - int full_count = 0; - unsigned short prefix_num = 0; - struct ospf6_route_table *route_advertise; - struct ospf6_link_lsa *link_lsa; - char *start, *end, *current; - u_int16_t type; - char buf[PREFIX2STR_BUFFER]; - - 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), - htonl (oi->interface->ifindex), - oi->area->ospf6->router_id, oi->area->lsdb); - - if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE)) - { - if (old) - ospf6_lsa_purge (old); - return 0; - } - - if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) - zlog_debug ("Originate Intra-Area-Prefix-LSA for interface %s's prefix", - oi->interface->name); - - /* prepare buffer */ - memset (buffer, 0, sizeof (buffer)); - lsa_header = (struct ospf6_lsa_header *) buffer; - intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *) - ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header)); - - /* Fill Intra-Area-Prefix-LSA */ - intra_prefix_lsa->ref_type = htons (OSPF6_LSTYPE_NETWORK); - intra_prefix_lsa->ref_id = htonl (oi->interface->ifindex); - intra_prefix_lsa->ref_adv_router = oi->area->ospf6->router_id; - - if (oi->state != OSPF6_INTERFACE_DR) - { - if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) - zlog_debug (" Interface is not DR"); - if (old) - ospf6_lsa_purge (old); - return 0; - } - - full_count = 0; - for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on)) - if (on->state == OSPF6_NEIGHBOR_FULL) - full_count++; - - if (full_count == 0) - { - if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) - zlog_debug (" Interface is stub"); - if (old) - ospf6_lsa_purge (old); - return 0; - } - - /* connected prefix to advertise */ - route_advertise = ospf6_route_table_create (0, 0); - - type = ntohs (OSPF6_LSTYPE_LINK); - for (ALL_LSDB_TYPED(oi->lsdb, type, lsa)) - { - if (OSPF6_LSA_IS_MAXAGE (lsa)) - continue; - - if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) - zlog_debug (" include prefix from %s", lsa->name); - - if (lsa->header->adv_router != oi->area->ospf6->router_id) - { - on = ospf6_neighbor_lookup (lsa->header->adv_router, oi); - if (on == NULL || on->state != OSPF6_NEIGHBOR_FULL) - { - if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) - zlog_debug (" Neighbor not found or not Full, ignore"); - continue; - } - } - - link_lsa = (struct ospf6_link_lsa *) - ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header)); - - prefix_num = (unsigned short) ntohl (link_lsa->prefix_num); - start = (char *) link_lsa + sizeof (struct ospf6_link_lsa); - end = (char *) lsa->header + ntohs (lsa->header->length); - for (current = start; current < end && prefix_num; - current += OSPF6_PREFIX_SIZE (op)) - { - op = (struct ospf6_prefix *) current; - if (op->prefix_length == 0 || - current + OSPF6_PREFIX_SIZE (op) > end) - break; - - route = ospf6_route_create (); - - route->type = OSPF6_DEST_TYPE_NETWORK; - route->prefix.family = AF_INET6; - route->prefix.prefixlen = op->prefix_length; - memset (&route->prefix.u.prefix6, 0, sizeof (struct in6_addr)); - memcpy (&route->prefix.u.prefix6, OSPF6_PREFIX_BODY (op), - OSPF6_PREFIX_SPACE (op->prefix_length)); - - route->path.origin.type = lsa->header->type; - route->path.origin.id = lsa->header->id; - route->path.origin.adv_router = lsa->header->adv_router; - route->path.options[0] = link_lsa->options[0]; - route->path.options[1] = link_lsa->options[1]; - route->path.options[2] = link_lsa->options[2]; - route->path.prefix_options = op->prefix_options; - route->path.area_id = oi->area->area_id; - route->path.type = OSPF6_PATH_TYPE_INTRA; - - if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) - { - prefix2str (&route->prefix, buf, sizeof (buf)); - zlog_debug (" include %s", buf); - } - - ospf6_route_add (route, route_advertise); - prefix_num--; - } - if (current != end && IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) - zlog_debug ("Trailing garbage in %s", lsa->name); - } - - op = (struct ospf6_prefix *) - ((caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa)); - - prefix_num = 0; - for (route = ospf6_route_head (route_advertise); route; - route = ospf6_route_best_next (route)) - { - op->prefix_length = route->prefix.prefixlen; - op->prefix_options = route->path.prefix_options; - op->prefix_metric = htons (0); - memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6, - OSPF6_PREFIX_SPACE (op->prefix_length)); - op = OSPF6_PREFIX_NEXT (op); - prefix_num++; - } - - ospf6_route_table_delete (route_advertise); - - if (prefix_num == 0) - { - if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) - zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise"); - return 0; - } - - intra_prefix_lsa->prefix_num = htons (prefix_num); - - /* Fill LSA Header */ - lsa_header->age = 0; - lsa_header->type = htons (OSPF6_LSTYPE_INTRA_PREFIX); - lsa_header->id = htonl (oi->interface->ifindex); - lsa_header->adv_router = oi->area->ospf6->router_id; - lsa_header->seqnum = - ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id, - lsa_header->adv_router, oi->area->lsdb); - lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header); - - /* LSA checksum */ - ospf6_lsa_checksum (lsa_header); - - /* create LSA */ - lsa = ospf6_lsa_create (lsa_header); - - /* Originate */ - ospf6_lsa_originate_area (lsa, oi->area); - - return 0; + struct ospf6_interface *oi; + + char buffer[OSPF6_MAX_LSASIZE]; + struct ospf6_lsa_header *lsa_header; + struct ospf6_lsa *old, *lsa; + + struct ospf6_intra_prefix_lsa *intra_prefix_lsa; + struct ospf6_neighbor *on; + struct ospf6_route *route; + struct ospf6_prefix *op; + struct listnode *i; + int full_count = 0; + unsigned short prefix_num = 0; + struct ospf6_route_table *route_advertise; + struct ospf6_link_lsa *link_lsa; + char *start, *end, *current; + u_int16_t type; + char buf[PREFIX2STR_BUFFER]; + + 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), + htonl(oi->interface->ifindex), + oi->area->ospf6->router_id, oi->area->lsdb); + + if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) { + if (old) + ospf6_lsa_purge(old); + return 0; + } + + if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX)) + zlog_debug( + "Originate Intra-Area-Prefix-LSA for interface %s's prefix", + oi->interface->name); + + /* prepare buffer */ + memset(buffer, 0, sizeof(buffer)); + lsa_header = (struct ospf6_lsa_header *)buffer; + intra_prefix_lsa = (struct ospf6_intra_prefix_lsa + *)((caddr_t)lsa_header + + sizeof(struct ospf6_lsa_header)); + + /* Fill Intra-Area-Prefix-LSA */ + intra_prefix_lsa->ref_type = htons(OSPF6_LSTYPE_NETWORK); + intra_prefix_lsa->ref_id = htonl(oi->interface->ifindex); + intra_prefix_lsa->ref_adv_router = oi->area->ospf6->router_id; + + if (oi->state != OSPF6_INTERFACE_DR) { + if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX)) + zlog_debug(" Interface is not DR"); + if (old) + ospf6_lsa_purge(old); + return 0; + } + + full_count = 0; + for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, i, on)) + if (on->state == OSPF6_NEIGHBOR_FULL) + full_count++; + + if (full_count == 0) { + if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX)) + zlog_debug(" Interface is stub"); + if (old) + ospf6_lsa_purge(old); + return 0; + } + + /* connected prefix to advertise */ + route_advertise = ospf6_route_table_create(0, 0); + + type = ntohs(OSPF6_LSTYPE_LINK); + for (ALL_LSDB_TYPED(oi->lsdb, type, lsa)) { + if (OSPF6_LSA_IS_MAXAGE(lsa)) + continue; + + if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX)) + zlog_debug(" include prefix from %s", lsa->name); + + if (lsa->header->adv_router != oi->area->ospf6->router_id) { + on = ospf6_neighbor_lookup(lsa->header->adv_router, oi); + if (on == NULL || on->state != OSPF6_NEIGHBOR_FULL) { + if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX)) + zlog_debug( + " Neighbor not found or not Full, ignore"); + continue; + } + } + + link_lsa = (struct ospf6_link_lsa + *)((caddr_t)lsa->header + + sizeof(struct ospf6_lsa_header)); + + prefix_num = (unsigned short)ntohl(link_lsa->prefix_num); + start = (char *)link_lsa + sizeof(struct ospf6_link_lsa); + end = (char *)lsa->header + ntohs(lsa->header->length); + for (current = start; current < end && prefix_num; + current += OSPF6_PREFIX_SIZE(op)) { + op = (struct ospf6_prefix *)current; + if (op->prefix_length == 0 + || current + OSPF6_PREFIX_SIZE(op) > end) + break; + + route = ospf6_route_create(); + + route->type = OSPF6_DEST_TYPE_NETWORK; + route->prefix.family = AF_INET6; + route->prefix.prefixlen = op->prefix_length; + memset(&route->prefix.u.prefix6, 0, + sizeof(struct in6_addr)); + memcpy(&route->prefix.u.prefix6, OSPF6_PREFIX_BODY(op), + OSPF6_PREFIX_SPACE(op->prefix_length)); + + route->path.origin.type = lsa->header->type; + route->path.origin.id = lsa->header->id; + route->path.origin.adv_router = lsa->header->adv_router; + route->path.options[0] = link_lsa->options[0]; + route->path.options[1] = link_lsa->options[1]; + route->path.options[2] = link_lsa->options[2]; + route->path.prefix_options = op->prefix_options; + route->path.area_id = oi->area->area_id; + route->path.type = OSPF6_PATH_TYPE_INTRA; + + if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX)) { + prefix2str(&route->prefix, buf, sizeof(buf)); + zlog_debug(" include %s", buf); + } + + ospf6_route_add(route, route_advertise); + prefix_num--; + } + if (current != end && IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX)) + zlog_debug("Trailing garbage in %s", lsa->name); + } + + op = (struct ospf6_prefix *)((caddr_t)intra_prefix_lsa + + sizeof(struct ospf6_intra_prefix_lsa)); + + prefix_num = 0; + for (route = ospf6_route_head(route_advertise); route; + route = ospf6_route_best_next(route)) { + op->prefix_length = route->prefix.prefixlen; + op->prefix_options = route->path.prefix_options; + op->prefix_metric = htons(0); + memcpy(OSPF6_PREFIX_BODY(op), &route->prefix.u.prefix6, + OSPF6_PREFIX_SPACE(op->prefix_length)); + op = OSPF6_PREFIX_NEXT(op); + prefix_num++; + } + + ospf6_route_table_delete(route_advertise); + + if (prefix_num == 0) { + if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX)) + zlog_debug( + "Quit to Advertise Intra-Prefix: no route to advertise"); + return 0; + } + + intra_prefix_lsa->prefix_num = htons(prefix_num); + + /* Fill LSA Header */ + lsa_header->age = 0; + lsa_header->type = htons(OSPF6_LSTYPE_INTRA_PREFIX); + lsa_header->id = htonl(oi->interface->ifindex); + lsa_header->adv_router = oi->area->ospf6->router_id; + lsa_header->seqnum = + ospf6_new_ls_seqnum(lsa_header->type, lsa_header->id, + lsa_header->adv_router, oi->area->lsdb); + lsa_header->length = htons((caddr_t)op - (caddr_t)lsa_header); + + /* LSA checksum */ + ospf6_lsa_checksum(lsa_header); + + /* create LSA */ + lsa = ospf6_lsa_create(lsa_header); + + /* Originate */ + ospf6_lsa_originate_area(lsa, oi->area); + + return 0; } -void -ospf6_intra_prefix_lsa_add (struct ospf6_lsa *lsa) +void ospf6_intra_prefix_lsa_add(struct ospf6_lsa *lsa) { - struct ospf6_area *oa; - struct ospf6_intra_prefix_lsa *intra_prefix_lsa; - struct prefix ls_prefix; - struct ospf6_route *route, *ls_entry; - int prefix_num; - struct ospf6_prefix *op; - char *start, *current, *end; - char buf[PREFIX2STR_BUFFER]; - struct interface *ifp; - int direct_connect = 0; - - if (OSPF6_LSA_IS_MAXAGE (lsa)) - return; - - if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) - zlog_debug ("%s found", lsa->name); - - 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)) - ospf6_linkstate_prefix (intra_prefix_lsa->ref_adv_router, - htonl (0), &ls_prefix); - else if (intra_prefix_lsa->ref_type == htons (OSPF6_LSTYPE_NETWORK)) - ospf6_linkstate_prefix (intra_prefix_lsa->ref_adv_router, - intra_prefix_lsa->ref_id, &ls_prefix); - else - { - if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) - zlog_debug ("Unknown reference LS-type: %#hx", - ntohs (intra_prefix_lsa->ref_type)); - return; - } - - ls_entry = ospf6_route_lookup (&ls_prefix, oa->spf_table); - if (ls_entry == NULL) - { - if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) - { - ospf6_linkstate_prefix2str (&ls_prefix, buf, sizeof (buf)); - zlog_debug ("LS entry does not exist: %s", buf); - } - return; - } - - if (intra_prefix_lsa->ref_adv_router == oa->ospf6->router_id) - { - /* the intra-prefix are directly connected */ - direct_connect = 1; - } - - prefix_num = ntohs (intra_prefix_lsa->prefix_num); - start = (caddr_t) intra_prefix_lsa + - sizeof (struct ospf6_intra_prefix_lsa); - end = OSPF6_LSA_END (lsa->header); - for (current = start; current < end; current += OSPF6_PREFIX_SIZE (op)) - { - op = (struct ospf6_prefix *) current; - if (prefix_num == 0) - break; - if (end < current + OSPF6_PREFIX_SIZE (op)) - break; - - /* Appendix A.4.1.1 */ - if (CHECK_FLAG(op->prefix_options, OSPF6_PREFIX_OPTION_NU)) - { - if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) - { - ospf6_linkstate_prefix2str ((struct prefix *)OSPF6_PREFIX_BODY(op), - buf, sizeof (buf)); - zlog_debug ("%s: Skipping Prefix %s has NU option set", - __func__, buf); - } - continue; + struct ospf6_area *oa; + struct ospf6_intra_prefix_lsa *intra_prefix_lsa; + struct prefix ls_prefix; + struct ospf6_route *route, *ls_entry; + int prefix_num; + struct ospf6_prefix *op; + char *start, *current, *end; + char buf[PREFIX2STR_BUFFER]; + struct interface *ifp; + int direct_connect = 0; + + if (OSPF6_LSA_IS_MAXAGE(lsa)) + return; + + if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX)) + zlog_debug("%s found", lsa->name); + + 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)) + ospf6_linkstate_prefix(intra_prefix_lsa->ref_adv_router, + htonl(0), &ls_prefix); + else if (intra_prefix_lsa->ref_type == htons(OSPF6_LSTYPE_NETWORK)) + ospf6_linkstate_prefix(intra_prefix_lsa->ref_adv_router, + intra_prefix_lsa->ref_id, &ls_prefix); + else { + if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX)) + zlog_debug("Unknown reference LS-type: %#hx", + ntohs(intra_prefix_lsa->ref_type)); + return; + } + + ls_entry = ospf6_route_lookup(&ls_prefix, oa->spf_table); + if (ls_entry == NULL) { + if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX)) { + ospf6_linkstate_prefix2str(&ls_prefix, buf, + sizeof(buf)); + zlog_debug("LS entry does not exist: %s", buf); + } + return; + } + + if (intra_prefix_lsa->ref_adv_router == oa->ospf6->router_id) { + /* the intra-prefix are directly connected */ + direct_connect = 1; + } + + prefix_num = ntohs(intra_prefix_lsa->prefix_num); + start = (caddr_t)intra_prefix_lsa + + sizeof(struct ospf6_intra_prefix_lsa); + end = OSPF6_LSA_END(lsa->header); + for (current = start; current < end; current += OSPF6_PREFIX_SIZE(op)) { + op = (struct ospf6_prefix *)current; + if (prefix_num == 0) + break; + if (end < current + OSPF6_PREFIX_SIZE(op)) + break; + + /* Appendix A.4.1.1 */ + if (CHECK_FLAG(op->prefix_options, OSPF6_PREFIX_OPTION_NU)) { + if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX)) { + ospf6_linkstate_prefix2str( + (struct prefix *)OSPF6_PREFIX_BODY(op), + buf, sizeof(buf)); + zlog_debug( + "%s: Skipping Prefix %s has NU option set", + __func__, buf); + } + continue; + } + + route = ospf6_route_create(); + + memset(&route->prefix, 0, sizeof(struct prefix)); + route->prefix.family = AF_INET6; + route->prefix.prefixlen = op->prefix_length; + ospf6_prefix_in6_addr(&route->prefix.u.prefix6, op); + + route->type = OSPF6_DEST_TYPE_NETWORK; + route->path.origin.type = lsa->header->type; + route->path.origin.id = lsa->header->id; + route->path.origin.adv_router = lsa->header->adv_router; + route->path.prefix_options = op->prefix_options; + route->path.area_id = oa->area_id; + route->path.type = OSPF6_PATH_TYPE_INTRA; + route->path.metric_type = 1; + route->path.cost = + ls_entry->path.cost + ntohs(op->prefix_metric); + + if (direct_connect) { + ifp = if_lookup_prefix(&route->prefix, VRF_DEFAULT); + if (ifp) + ospf6_route_add_nexthop(route, ifp->ifindex, + NULL); + } else { + ospf6_route_copy_nexthops(route, ls_entry); + } + + if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX)) { + prefix2str(&route->prefix, buf, sizeof(buf)); + zlog_debug(" add %s", buf); + } + + ospf6_route_add(route, oa->route_table); + prefix_num--; } - route = ospf6_route_create (); - - memset (&route->prefix, 0, sizeof (struct prefix)); - route->prefix.family = AF_INET6; - route->prefix.prefixlen = op->prefix_length; - ospf6_prefix_in6_addr (&route->prefix.u.prefix6, op); - - route->type = OSPF6_DEST_TYPE_NETWORK; - route->path.origin.type = lsa->header->type; - route->path.origin.id = lsa->header->id; - route->path.origin.adv_router = lsa->header->adv_router; - route->path.prefix_options = op->prefix_options; - route->path.area_id = oa->area_id; - route->path.type = OSPF6_PATH_TYPE_INTRA; - route->path.metric_type = 1; - route->path.cost = ls_entry->path.cost + - ntohs (op->prefix_metric); - - if (direct_connect) - { - ifp = if_lookup_prefix(&route->prefix, VRF_DEFAULT); - if (ifp) - ospf6_route_add_nexthop (route, ifp->ifindex, NULL); - } - else - { - ospf6_route_copy_nexthops (route, ls_entry); - } - - if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) - { - prefix2str (&route->prefix, buf, sizeof (buf)); - zlog_debug (" add %s", buf); - } - - ospf6_route_add (route, oa->route_table); - prefix_num--; - } - - if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) - zlog_debug ("Trailing garbage ignored"); + if (current != end && IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX)) + zlog_debug("Trailing garbage ignored"); } -void -ospf6_intra_prefix_lsa_remove (struct ospf6_lsa *lsa) +void ospf6_intra_prefix_lsa_remove(struct ospf6_lsa *lsa) { - struct ospf6_area *oa; - struct ospf6_intra_prefix_lsa *intra_prefix_lsa; - struct prefix prefix; - struct ospf6_route *route, *nroute; - int prefix_num; - struct ospf6_prefix *op; - char *start, *current, *end; - char buf[PREFIX2STR_BUFFER]; - - if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) - zlog_debug ("%s disappearing", lsa->name); - - oa = OSPF6_AREA (lsa->lsdb->data); - - intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *) - OSPF6_LSA_HEADER_END (lsa->header); - - prefix_num = ntohs (intra_prefix_lsa->prefix_num); - start = (caddr_t) intra_prefix_lsa + - sizeof (struct ospf6_intra_prefix_lsa); - end = OSPF6_LSA_END (lsa->header); - for (current = start; current < end; current += OSPF6_PREFIX_SIZE (op)) - { - op = (struct ospf6_prefix *) current; - if (prefix_num == 0) - break; - if (end < current + OSPF6_PREFIX_SIZE (op)) - break; - prefix_num--; - - memset (&prefix, 0, sizeof (struct prefix)); - prefix.family = AF_INET6; - prefix.prefixlen = op->prefix_length; - ospf6_prefix_in6_addr (&prefix.u.prefix6, op); - - route = ospf6_route_lookup (&prefix, oa->route_table); - if (route == NULL) - continue; - - for (ospf6_route_lock (route); - route && ospf6_route_is_prefix (&prefix, route); - route = nroute) - { - nroute = ospf6_route_next (route); - if (route->type != OSPF6_DEST_TYPE_NETWORK) - continue; - if (route->path.area_id != oa->area_id) - continue; - if (route->path.type != OSPF6_PATH_TYPE_INTRA) - continue; - if (route->path.origin.type != lsa->header->type || - route->path.origin.id != lsa->header->id || - route->path.origin.adv_router != lsa->header->adv_router) - continue; - - if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) - { - prefix2str (&route->prefix, buf, sizeof (buf)); - zlog_debug ("remove %s", buf); - } - ospf6_route_remove (route, oa->route_table); - } - if (route) - ospf6_route_unlock (route); - } - - if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) - zlog_debug ("Trailing garbage ignored"); + struct ospf6_area *oa; + struct ospf6_intra_prefix_lsa *intra_prefix_lsa; + struct prefix prefix; + struct ospf6_route *route, *nroute; + int prefix_num; + struct ospf6_prefix *op; + char *start, *current, *end; + char buf[PREFIX2STR_BUFFER]; + + if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX)) + zlog_debug("%s disappearing", lsa->name); + + oa = OSPF6_AREA(lsa->lsdb->data); + + intra_prefix_lsa = + (struct ospf6_intra_prefix_lsa *)OSPF6_LSA_HEADER_END( + lsa->header); + + prefix_num = ntohs(intra_prefix_lsa->prefix_num); + start = (caddr_t)intra_prefix_lsa + + sizeof(struct ospf6_intra_prefix_lsa); + end = OSPF6_LSA_END(lsa->header); + for (current = start; current < end; current += OSPF6_PREFIX_SIZE(op)) { + op = (struct ospf6_prefix *)current; + if (prefix_num == 0) + break; + if (end < current + OSPF6_PREFIX_SIZE(op)) + break; + prefix_num--; + + memset(&prefix, 0, sizeof(struct prefix)); + prefix.family = AF_INET6; + prefix.prefixlen = op->prefix_length; + ospf6_prefix_in6_addr(&prefix.u.prefix6, op); + + route = ospf6_route_lookup(&prefix, oa->route_table); + if (route == NULL) + continue; + + for (ospf6_route_lock(route); + route && ospf6_route_is_prefix(&prefix, route); + route = nroute) { + nroute = ospf6_route_next(route); + if (route->type != OSPF6_DEST_TYPE_NETWORK) + continue; + if (route->path.area_id != oa->area_id) + continue; + if (route->path.type != OSPF6_PATH_TYPE_INTRA) + continue; + if (route->path.origin.type != lsa->header->type + || route->path.origin.id != lsa->header->id + || route->path.origin.adv_router + != lsa->header->adv_router) + continue; + + if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX)) { + prefix2str(&route->prefix, buf, sizeof(buf)); + zlog_debug("remove %s", buf); + } + ospf6_route_remove(route, oa->route_table); + } + if (route) + ospf6_route_unlock(route); + } + + if (current != end && IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX)) + zlog_debug("Trailing garbage ignored"); } -void -ospf6_intra_route_calculation (struct ospf6_area *oa) +void ospf6_intra_route_calculation(struct ospf6_area *oa) { - struct ospf6_route *route, *nroute; - u_int16_t type; - struct ospf6_lsa *lsa; - void (*hook_add) (struct ospf6_route *) = NULL; - void (*hook_remove) (struct ospf6_route *) = NULL; - - if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) - zlog_debug ("Re-examin intra-routes for area %s", oa->name); - - hook_add = oa->route_table->hook_add; - hook_remove = oa->route_table->hook_remove; - oa->route_table->hook_add = NULL; - oa->route_table->hook_remove = NULL; - - for (route = ospf6_route_head (oa->route_table); route; - route = ospf6_route_next (route)) - route->flag = OSPF6_ROUTE_REMOVE; - - type = htons (OSPF6_LSTYPE_INTRA_PREFIX); - for (ALL_LSDB_TYPED(oa->lsdb, type, lsa)) - ospf6_intra_prefix_lsa_add (lsa); - - oa->route_table->hook_add = hook_add; - oa->route_table->hook_remove = hook_remove; - - for (route = ospf6_route_head (oa->route_table); route; - route = nroute) - { - nroute = ospf6_route_next (route); - if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE) && - CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD)) - { - UNSET_FLAG (route->flag, OSPF6_ROUTE_REMOVE); - UNSET_FLAG (route->flag, OSPF6_ROUTE_ADD); - } - - if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE)) - ospf6_route_remove (route, oa->route_table); - else if (CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD) || - CHECK_FLAG (route->flag, OSPF6_ROUTE_CHANGE)) - { - if (hook_add) - (*hook_add) (route); - route->flag = 0; - } - else - { - /* Redo the summaries as things might have changed */ - ospf6_abr_originate_summary (route); - route->flag = 0; + struct ospf6_route *route, *nroute; + u_int16_t type; + struct ospf6_lsa *lsa; + void (*hook_add)(struct ospf6_route *) = NULL; + void (*hook_remove)(struct ospf6_route *) = NULL; + + if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX)) + zlog_debug("Re-examin intra-routes for area %s", oa->name); + + hook_add = oa->route_table->hook_add; + hook_remove = oa->route_table->hook_remove; + oa->route_table->hook_add = NULL; + oa->route_table->hook_remove = NULL; + + for (route = ospf6_route_head(oa->route_table); route; + route = ospf6_route_next(route)) + route->flag = OSPF6_ROUTE_REMOVE; + + type = htons(OSPF6_LSTYPE_INTRA_PREFIX); + for (ALL_LSDB_TYPED(oa->lsdb, type, lsa)) + ospf6_intra_prefix_lsa_add(lsa); + + oa->route_table->hook_add = hook_add; + oa->route_table->hook_remove = hook_remove; + + for (route = ospf6_route_head(oa->route_table); route; route = nroute) { + nroute = ospf6_route_next(route); + if (CHECK_FLAG(route->flag, OSPF6_ROUTE_REMOVE) + && CHECK_FLAG(route->flag, OSPF6_ROUTE_ADD)) { + UNSET_FLAG(route->flag, OSPF6_ROUTE_REMOVE); + UNSET_FLAG(route->flag, OSPF6_ROUTE_ADD); + } + + if (CHECK_FLAG(route->flag, OSPF6_ROUTE_REMOVE)) + ospf6_route_remove(route, oa->route_table); + else if (CHECK_FLAG(route->flag, OSPF6_ROUTE_ADD) + || CHECK_FLAG(route->flag, OSPF6_ROUTE_CHANGE)) { + if (hook_add) + (*hook_add)(route); + route->flag = 0; + } else { + /* Redo the summaries as things might have changed */ + ospf6_abr_originate_summary(route); + route->flag = 0; + } } - } - if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) - zlog_debug ("Re-examin intra-routes for area %s: Done", oa->name); + if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX)) + zlog_debug("Re-examin intra-routes for area %s: Done", + oa->name); } -static void -ospf6_brouter_debug_print (struct ospf6_route *brouter) +static void ospf6_brouter_debug_print(struct ospf6_route *brouter) { - u_int32_t brouter_id; - char brouter_name[16]; - char area_name[16]; - char destination[64]; - char installed[16], changed[16]; - struct timeval now, res; - char id[16], adv_router[16]; - char capa[16], options[16]; - - brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix); - inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name)); - inet_ntop (AF_INET, &brouter->path.area_id, area_name, sizeof (area_name)); - ospf6_linkstate_prefix2str (&brouter->prefix, destination, - sizeof (destination)); - - monotime(&now); - timersub (&now, &brouter->installed, &res); - timerstring (&res, installed, sizeof (installed)); - - monotime(&now); - timersub (&now, &brouter->changed, &res); - timerstring (&res, changed, sizeof (changed)); - - inet_ntop (AF_INET, &brouter->path.origin.id, id, sizeof (id)); - inet_ntop (AF_INET, &brouter->path.origin.adv_router, adv_router, - sizeof (adv_router)); - - ospf6_options_printbuf (brouter->path.options, options, sizeof (options)); - ospf6_capability_printbuf (brouter->path.router_bits, capa, sizeof (capa)); - - zlog_info ("Brouter: %s via area %s", brouter_name, area_name); - zlog_info (" memory: prev: %p this: %p next: %p parent rnode: %p", - (void *)brouter->prev, (void *)brouter, (void *)brouter->next, - (void *)brouter->rnode); - zlog_info (" type: %d prefix: %s installed: %s changed: %s", - brouter->type, destination, installed, changed); - zlog_info (" lock: %d flags: %s%s%s%s", brouter->lock, - (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_BEST) ? "B" : "-"), - (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD) ? "A" : "-"), - (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE) ? "R" : "-"), - (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE) ? "C" : "-")); - zlog_info (" path type: %s ls-origin %s id: %s adv-router %s", - OSPF6_PATH_TYPE_NAME (brouter->path.type), - ospf6_lstype_name (brouter->path.origin.type), - id, adv_router); - zlog_info (" options: %s router-bits: %s metric-type: %d metric: %d/%d", - options, capa, brouter->path.metric_type, - brouter->path.cost, brouter->path.u.cost_e2); + u_int32_t brouter_id; + char brouter_name[16]; + char area_name[16]; + char destination[64]; + char installed[16], changed[16]; + struct timeval now, res; + char id[16], adv_router[16]; + char capa[16], options[16]; + + brouter_id = ADV_ROUTER_IN_PREFIX(&brouter->prefix); + inet_ntop(AF_INET, &brouter_id, brouter_name, sizeof(brouter_name)); + inet_ntop(AF_INET, &brouter->path.area_id, area_name, + sizeof(area_name)); + ospf6_linkstate_prefix2str(&brouter->prefix, destination, + sizeof(destination)); + + monotime(&now); + timersub(&now, &brouter->installed, &res); + timerstring(&res, installed, sizeof(installed)); + + monotime(&now); + timersub(&now, &brouter->changed, &res); + timerstring(&res, changed, sizeof(changed)); + + inet_ntop(AF_INET, &brouter->path.origin.id, id, sizeof(id)); + inet_ntop(AF_INET, &brouter->path.origin.adv_router, adv_router, + sizeof(adv_router)); + + ospf6_options_printbuf(brouter->path.options, options, sizeof(options)); + ospf6_capability_printbuf(brouter->path.router_bits, capa, + sizeof(capa)); + + zlog_info("Brouter: %s via area %s", brouter_name, area_name); + zlog_info(" memory: prev: %p this: %p next: %p parent rnode: %p", + (void *)brouter->prev, (void *)brouter, (void *)brouter->next, + (void *)brouter->rnode); + zlog_info(" type: %d prefix: %s installed: %s changed: %s", + brouter->type, destination, installed, changed); + zlog_info(" lock: %d flags: %s%s%s%s", brouter->lock, + (CHECK_FLAG(brouter->flag, OSPF6_ROUTE_BEST) ? "B" : "-"), + (CHECK_FLAG(brouter->flag, OSPF6_ROUTE_ADD) ? "A" : "-"), + (CHECK_FLAG(brouter->flag, OSPF6_ROUTE_REMOVE) ? "R" : "-"), + (CHECK_FLAG(brouter->flag, OSPF6_ROUTE_CHANGE) ? "C" : "-")); + zlog_info(" path type: %s ls-origin %s id: %s adv-router %s", + OSPF6_PATH_TYPE_NAME(brouter->path.type), + ospf6_lstype_name(brouter->path.origin.type), id, adv_router); + zlog_info(" options: %s router-bits: %s metric-type: %d metric: %d/%d", + options, capa, brouter->path.metric_type, brouter->path.cost, + brouter->path.u.cost_e2); } -void -ospf6_intra_brouter_calculation (struct ospf6_area *oa) +void ospf6_intra_brouter_calculation(struct ospf6_area *oa) { - struct ospf6_route *brouter, *nbrouter, *copy; - void (*hook_add) (struct ospf6_route *) = NULL; - void (*hook_remove) (struct ospf6_route *) = NULL; - u_int32_t brouter_id; - char brouter_name[16]; - - if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id)) - zlog_info ("border-router calculation for area %s", oa->name); - - 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; - - /* withdraw the previous router entries for the area */ - for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter; - brouter = ospf6_route_next (brouter)) - { - brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix); - inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name)); - if (brouter->path.area_id != oa->area_id) - continue; - SET_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE); - - if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) || - IS_OSPF6_DEBUG_ROUTE (MEMORY)) - { - zlog_info ("%p: mark as removing: area %s brouter %s", - (void *)brouter, oa->name, brouter_name); - ospf6_brouter_debug_print (brouter); - } - } - - for (brouter = ospf6_route_head (oa->spf_table); brouter; - brouter = ospf6_route_next (brouter)) - { - brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix); - inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name)); - - if (brouter->type != OSPF6_DEST_TYPE_LINKSTATE) - continue; - if (ospf6_linkstate_prefix_id (&brouter->prefix) != htonl (0)) - continue; - if (! CHECK_FLAG (brouter->path.router_bits, OSPF6_ROUTER_BIT_E) && - ! CHECK_FLAG (brouter->path.router_bits, OSPF6_ROUTER_BIT_B)) - continue; - - if (! OSPF6_OPT_ISSET (brouter->path.options, OSPF6_OPT_V6) || - ! OSPF6_OPT_ISSET (brouter->path.options, OSPF6_OPT_R)) - continue; - - copy = ospf6_route_copy (brouter); - copy->type = OSPF6_DEST_TYPE_ROUTER; - copy->path.area_id = oa->area_id; - ospf6_route_add (copy, oa->ospf6->brouter_table); - - if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) || - IS_OSPF6_DEBUG_ROUTE (MEMORY)) - { - zlog_info ("%p: transfer: area %s brouter %s", - (void *)brouter, oa->name, brouter_name); - ospf6_brouter_debug_print (brouter); - } - } - - oa->ospf6->brouter_table->hook_add = hook_add; - oa->ospf6->brouter_table->hook_remove = hook_remove; - - for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter; - brouter = nbrouter) - { - nbrouter = ospf6_route_next (brouter); - brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix); - inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name)); - - if (brouter->path.area_id != oa->area_id) - continue; - - if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_WAS_REMOVED)) - continue; - - if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE) && - CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD)) - { - UNSET_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE); - UNSET_FLAG (brouter->flag, OSPF6_ROUTE_ADD); - } - - if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE)) - { - if (IS_OSPF6_DEBUG_BROUTER || - IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) || - IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id)) - zlog_info ("brouter %s disappears via area %s", - brouter_name, oa->name); - ospf6_route_remove (brouter, oa->ospf6->brouter_table); - brouter = NULL; - } - else if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD) || - CHECK_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE)) - { - if (IS_OSPF6_DEBUG_BROUTER || - IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) || - IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id)) - zlog_info ("brouter %s appears via area %s", - brouter_name, oa->name); - - /* newly added */ - if (hook_add) - (*hook_add) (brouter); - } - else - { - if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) || - IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id)) - zlog_info ("brouter %s still exists via area %s", - brouter_name, oa->name); - /* But re-originate summaries */ - ospf6_abr_originate_summary (brouter); - } - - if (brouter) - { - UNSET_FLAG (brouter->flag, OSPF6_ROUTE_ADD); - UNSET_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE); - } - } - - if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id)) - zlog_info ("border-router calculation for area %s: done", oa->name); + struct ospf6_route *brouter, *nbrouter, *copy; + void (*hook_add)(struct ospf6_route *) = NULL; + void (*hook_remove)(struct ospf6_route *) = NULL; + u_int32_t brouter_id; + char brouter_name[16]; + + if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID(oa->area_id)) + zlog_info("border-router calculation for area %s", oa->name); + + 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; + + /* withdraw the previous router entries for the area */ + for (brouter = ospf6_route_head(oa->ospf6->brouter_table); brouter; + brouter = ospf6_route_next(brouter)) { + brouter_id = ADV_ROUTER_IN_PREFIX(&brouter->prefix); + inet_ntop(AF_INET, &brouter_id, brouter_name, + sizeof(brouter_name)); + if (brouter->path.area_id != oa->area_id) + continue; + SET_FLAG(brouter->flag, OSPF6_ROUTE_REMOVE); + + if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID(brouter_id) + || IS_OSPF6_DEBUG_ROUTE(MEMORY)) { + zlog_info("%p: mark as removing: area %s brouter %s", + (void *)brouter, oa->name, brouter_name); + ospf6_brouter_debug_print(brouter); + } + } + + for (brouter = ospf6_route_head(oa->spf_table); brouter; + brouter = ospf6_route_next(brouter)) { + brouter_id = ADV_ROUTER_IN_PREFIX(&brouter->prefix); + inet_ntop(AF_INET, &brouter_id, brouter_name, + sizeof(brouter_name)); + + if (brouter->type != OSPF6_DEST_TYPE_LINKSTATE) + continue; + if (ospf6_linkstate_prefix_id(&brouter->prefix) != htonl(0)) + continue; + if (!CHECK_FLAG(brouter->path.router_bits, OSPF6_ROUTER_BIT_E) + && !CHECK_FLAG(brouter->path.router_bits, + OSPF6_ROUTER_BIT_B)) + continue; + + if (!OSPF6_OPT_ISSET(brouter->path.options, OSPF6_OPT_V6) + || !OSPF6_OPT_ISSET(brouter->path.options, OSPF6_OPT_R)) + continue; + + copy = ospf6_route_copy(brouter); + copy->type = OSPF6_DEST_TYPE_ROUTER; + copy->path.area_id = oa->area_id; + ospf6_route_add(copy, oa->ospf6->brouter_table); + + if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID(brouter_id) + || IS_OSPF6_DEBUG_ROUTE(MEMORY)) { + zlog_info("%p: transfer: area %s brouter %s", + (void *)brouter, oa->name, brouter_name); + ospf6_brouter_debug_print(brouter); + } + } + + oa->ospf6->brouter_table->hook_add = hook_add; + oa->ospf6->brouter_table->hook_remove = hook_remove; + + for (brouter = ospf6_route_head(oa->ospf6->brouter_table); brouter; + brouter = nbrouter) { + nbrouter = ospf6_route_next(brouter); + brouter_id = ADV_ROUTER_IN_PREFIX(&brouter->prefix); + inet_ntop(AF_INET, &brouter_id, brouter_name, + sizeof(brouter_name)); + + if (brouter->path.area_id != oa->area_id) + continue; + + if (CHECK_FLAG(brouter->flag, OSPF6_ROUTE_WAS_REMOVED)) + continue; + + if (CHECK_FLAG(brouter->flag, OSPF6_ROUTE_REMOVE) + && CHECK_FLAG(brouter->flag, OSPF6_ROUTE_ADD)) { + UNSET_FLAG(brouter->flag, OSPF6_ROUTE_REMOVE); + UNSET_FLAG(brouter->flag, OSPF6_ROUTE_ADD); + } + + if (CHECK_FLAG(brouter->flag, OSPF6_ROUTE_REMOVE)) { + if (IS_OSPF6_DEBUG_BROUTER + || IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID( + brouter_id) + || IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID( + oa->area_id)) + zlog_info("brouter %s disappears via area %s", + brouter_name, oa->name); + ospf6_route_remove(brouter, oa->ospf6->brouter_table); + brouter = NULL; + } else if (CHECK_FLAG(brouter->flag, OSPF6_ROUTE_ADD) + || CHECK_FLAG(brouter->flag, OSPF6_ROUTE_CHANGE)) { + if (IS_OSPF6_DEBUG_BROUTER + || IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID( + brouter_id) + || IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID( + oa->area_id)) + zlog_info("brouter %s appears via area %s", + brouter_name, oa->name); + + /* newly added */ + if (hook_add) + (*hook_add)(brouter); + } else { + if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID( + brouter_id) + || IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID( + oa->area_id)) + zlog_info("brouter %s still exists via area %s", + brouter_name, oa->name); + /* But re-originate summaries */ + ospf6_abr_originate_summary(brouter); + } + + if (brouter) { + UNSET_FLAG(brouter->flag, OSPF6_ROUTE_ADD); + UNSET_FLAG(brouter->flag, OSPF6_ROUTE_CHANGE); + } + } + + if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID(oa->area_id)) + zlog_info("border-router calculation for area %s: done", + oa->name); } -struct ospf6_lsa_handler router_handler = -{ - OSPF6_LSTYPE_ROUTER, - "Router", - "Rtr", - ospf6_router_lsa_show, - ospf6_router_lsa_get_nbr_id -}; - -struct ospf6_lsa_handler network_handler = -{ - OSPF6_LSTYPE_NETWORK, - "Network", - "Net", - ospf6_network_lsa_show, - ospf6_network_lsa_get_ar_id -}; - -struct ospf6_lsa_handler link_handler = -{ - OSPF6_LSTYPE_LINK, - "Link", - "Lnk", - ospf6_link_lsa_show, - ospf6_link_lsa_get_prefix_str -}; - -struct ospf6_lsa_handler intra_prefix_handler = -{ - OSPF6_LSTYPE_INTRA_PREFIX, - "Intra-Prefix", - "INP", - ospf6_intra_prefix_lsa_show, - ospf6_intra_prefix_lsa_get_prefix_str -}; - -void -ospf6_intra_init (void) +struct ospf6_lsa_handler router_handler = {OSPF6_LSTYPE_ROUTER, "Router", "Rtr", + ospf6_router_lsa_show, + ospf6_router_lsa_get_nbr_id}; + +struct ospf6_lsa_handler network_handler = {OSPF6_LSTYPE_NETWORK, "Network", + "Net", ospf6_network_lsa_show, + ospf6_network_lsa_get_ar_id}; + +struct ospf6_lsa_handler link_handler = {OSPF6_LSTYPE_LINK, "Link", "Lnk", + ospf6_link_lsa_show, + ospf6_link_lsa_get_prefix_str}; + +struct ospf6_lsa_handler intra_prefix_handler = { + OSPF6_LSTYPE_INTRA_PREFIX, "Intra-Prefix", "INP", + ospf6_intra_prefix_lsa_show, ospf6_intra_prefix_lsa_get_prefix_str}; + +void ospf6_intra_init(void) { - 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); + 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); } DEFUN (debug_ospf6_brouter, @@ -1704,8 +1649,8 @@ DEFUN (debug_ospf6_brouter, "Debug border router\n" ) { - OSPF6_DEBUG_BROUTER_ON (); - return CMD_SUCCESS; + OSPF6_DEBUG_BROUTER_ON(); + return CMD_SUCCESS; } DEFUN (no_debug_ospf6_brouter, @@ -1717,8 +1662,8 @@ DEFUN (no_debug_ospf6_brouter, "Debug border router\n" ) { - OSPF6_DEBUG_BROUTER_OFF (); - return CMD_SUCCESS; + OSPF6_DEBUG_BROUTER_OFF(); + return CMD_SUCCESS; } DEFUN (debug_ospf6_brouter_router, @@ -1731,11 +1676,11 @@ DEFUN (debug_ospf6_brouter_router, "Specify border-router's router-id\n" ) { - int idx_ipv4 = 4; - u_int32_t router_id; - inet_pton (AF_INET, argv[idx_ipv4]->arg, &router_id); - OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ON (router_id); - return CMD_SUCCESS; + int idx_ipv4 = 4; + u_int32_t router_id; + inet_pton(AF_INET, argv[idx_ipv4]->arg, &router_id); + OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ON(router_id); + return CMD_SUCCESS; } DEFUN (no_debug_ospf6_brouter_router, @@ -1748,8 +1693,8 @@ DEFUN (no_debug_ospf6_brouter_router, "Debug specific border router\n" ) { - OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF (); - return CMD_SUCCESS; + OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF(); + return CMD_SUCCESS; } DEFUN (debug_ospf6_brouter_area, @@ -1762,11 +1707,11 @@ DEFUN (debug_ospf6_brouter_area, "Specify Area-ID\n" ) { - int idx_ipv4 = 4; - u_int32_t area_id; - inet_pton (AF_INET, argv[idx_ipv4]->arg, &area_id); - OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ON (area_id); - return CMD_SUCCESS; + int idx_ipv4 = 4; + u_int32_t area_id; + inet_pton(AF_INET, argv[idx_ipv4]->arg, &area_id); + OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ON(area_id); + return CMD_SUCCESS; } DEFUN (no_debug_ospf6_brouter_area, @@ -1779,46 +1724,40 @@ DEFUN (no_debug_ospf6_brouter_area, "Debug border routers in specific Area\n" ) { - OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF (); - return CMD_SUCCESS; + OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF(); + return CMD_SUCCESS; } -int -config_write_ospf6_debug_brouter (struct vty *vty) +int config_write_ospf6_debug_brouter(struct vty *vty) { - char buf[16]; - if (IS_OSPF6_DEBUG_BROUTER) - vty_out (vty, "debug ospf6 border-routers\n"); - if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER) - { - inet_ntop (AF_INET, &conf_debug_ospf6_brouter_specific_router_id, - buf, sizeof (buf)); - vty_out (vty, "debug ospf6 border-routers router-id %s\n", buf); - } - if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA) - { - inet_ntop (AF_INET, &conf_debug_ospf6_brouter_specific_area_id, - buf, sizeof (buf)); - vty_out (vty, "debug ospf6 border-routers area-id %s\n", buf); - } - return 0; + char buf[16]; + if (IS_OSPF6_DEBUG_BROUTER) + vty_out(vty, "debug ospf6 border-routers\n"); + if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER) { + inet_ntop(AF_INET, &conf_debug_ospf6_brouter_specific_router_id, + buf, sizeof(buf)); + vty_out(vty, "debug ospf6 border-routers router-id %s\n", buf); + } + if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA) { + inet_ntop(AF_INET, &conf_debug_ospf6_brouter_specific_area_id, + buf, sizeof(buf)); + vty_out(vty, "debug ospf6 border-routers area-id %s\n", buf); + } + return 0; } -void -install_element_ospf6_debug_brouter (void) +void install_element_ospf6_debug_brouter(void) { - install_element (ENABLE_NODE, &debug_ospf6_brouter_cmd); - install_element (ENABLE_NODE, &debug_ospf6_brouter_router_cmd); - install_element (ENABLE_NODE, &debug_ospf6_brouter_area_cmd); - install_element (ENABLE_NODE, &no_debug_ospf6_brouter_cmd); - install_element (ENABLE_NODE, &no_debug_ospf6_brouter_router_cmd); - install_element (ENABLE_NODE, &no_debug_ospf6_brouter_area_cmd); - install_element (CONFIG_NODE, &debug_ospf6_brouter_cmd); - install_element (CONFIG_NODE, &debug_ospf6_brouter_router_cmd); - install_element (CONFIG_NODE, &debug_ospf6_brouter_area_cmd); - install_element (CONFIG_NODE, &no_debug_ospf6_brouter_cmd); - install_element (CONFIG_NODE, &no_debug_ospf6_brouter_router_cmd); - install_element (CONFIG_NODE, &no_debug_ospf6_brouter_area_cmd); + install_element(ENABLE_NODE, &debug_ospf6_brouter_cmd); + install_element(ENABLE_NODE, &debug_ospf6_brouter_router_cmd); + install_element(ENABLE_NODE, &debug_ospf6_brouter_area_cmd); + install_element(ENABLE_NODE, &no_debug_ospf6_brouter_cmd); + install_element(ENABLE_NODE, &no_debug_ospf6_brouter_router_cmd); + install_element(ENABLE_NODE, &no_debug_ospf6_brouter_area_cmd); + install_element(CONFIG_NODE, &debug_ospf6_brouter_cmd); + install_element(CONFIG_NODE, &debug_ospf6_brouter_router_cmd); + install_element(CONFIG_NODE, &debug_ospf6_brouter_area_cmd); + install_element(CONFIG_NODE, &no_debug_ospf6_brouter_cmd); + install_element(CONFIG_NODE, &no_debug_ospf6_brouter_router_cmd); + install_element(CONFIG_NODE, &no_debug_ospf6_brouter_area_cmd); } - - diff --git a/ospf6d/ospf6_intra.h b/ospf6d/ospf6_intra.h index 114784835..b511a9200 100644 --- a/ospf6d/ospf6_intra.h +++ b/ospf6d/ospf6_intra.h @@ -28,64 +28,65 @@ extern u_int32_t conf_debug_ospf6_brouter_specific_area_id; #define OSPF6_DEBUG_BROUTER_SUMMARY 0x01 #define OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER 0x02 #define OSPF6_DEBUG_BROUTER_SPECIFIC_AREA 0x04 -#define OSPF6_DEBUG_BROUTER_ON() \ - (conf_debug_ospf6_brouter |= OSPF6_DEBUG_BROUTER_SUMMARY) -#define OSPF6_DEBUG_BROUTER_OFF() \ - (conf_debug_ospf6_brouter &= ~OSPF6_DEBUG_BROUTER_SUMMARY) -#define IS_OSPF6_DEBUG_BROUTER \ - (conf_debug_ospf6_brouter & OSPF6_DEBUG_BROUTER_SUMMARY) - -#define OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ON(router_id) \ - do { \ - conf_debug_ospf6_brouter_specific_router_id = (router_id); \ - conf_debug_ospf6_brouter |= OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER; \ - } while (0) -#define OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF() \ - do { \ - conf_debug_ospf6_brouter_specific_router_id = 0; \ - conf_debug_ospf6_brouter &= ~OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER; \ - } while (0) -#define IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER \ - (conf_debug_ospf6_brouter & OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER) -#define IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID(router_id) \ - (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER && \ - conf_debug_ospf6_brouter_specific_router_id == (router_id)) - -#define OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ON(area_id) \ - do { \ - conf_debug_ospf6_brouter_specific_area_id = (area_id); \ - conf_debug_ospf6_brouter |= OSPF6_DEBUG_BROUTER_SPECIFIC_AREA; \ - } while (0) -#define OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF() \ - do { \ - conf_debug_ospf6_brouter_specific_area_id = 0; \ - conf_debug_ospf6_brouter &= ~OSPF6_DEBUG_BROUTER_SPECIFIC_AREA; \ - } while (0) -#define IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA \ - (conf_debug_ospf6_brouter & OSPF6_DEBUG_BROUTER_SPECIFIC_AREA) -#define IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID(area_id) \ - (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA && \ - conf_debug_ospf6_brouter_specific_area_id == (area_id)) +#define OSPF6_DEBUG_BROUTER_ON() \ + (conf_debug_ospf6_brouter |= OSPF6_DEBUG_BROUTER_SUMMARY) +#define OSPF6_DEBUG_BROUTER_OFF() \ + (conf_debug_ospf6_brouter &= ~OSPF6_DEBUG_BROUTER_SUMMARY) +#define IS_OSPF6_DEBUG_BROUTER \ + (conf_debug_ospf6_brouter & OSPF6_DEBUG_BROUTER_SUMMARY) + +#define OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ON(router_id) \ + do { \ + conf_debug_ospf6_brouter_specific_router_id = (router_id); \ + conf_debug_ospf6_brouter |= \ + OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER; \ + } while (0) +#define OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF() \ + do { \ + conf_debug_ospf6_brouter_specific_router_id = 0; \ + conf_debug_ospf6_brouter &= \ + ~OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER; \ + } while (0) +#define IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER \ + (conf_debug_ospf6_brouter & OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER) +#define IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID(router_id) \ + (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER \ + && conf_debug_ospf6_brouter_specific_router_id == (router_id)) + +#define OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ON(area_id) \ + do { \ + conf_debug_ospf6_brouter_specific_area_id = (area_id); \ + conf_debug_ospf6_brouter |= OSPF6_DEBUG_BROUTER_SPECIFIC_AREA; \ + } while (0) +#define OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF() \ + do { \ + conf_debug_ospf6_brouter_specific_area_id = 0; \ + conf_debug_ospf6_brouter &= \ + ~OSPF6_DEBUG_BROUTER_SPECIFIC_AREA; \ + } while (0) +#define IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA \ + (conf_debug_ospf6_brouter & OSPF6_DEBUG_BROUTER_SPECIFIC_AREA) +#define IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID(area_id) \ + (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA \ + && conf_debug_ospf6_brouter_specific_area_id == (area_id)) /* Router-LSA */ #define OSPF6_ROUTER_LSA_MIN_SIZE 4U -struct ospf6_router_lsa -{ - u_char bits; - u_char options[3]; - /* followed by ospf6_router_lsdesc(s) */ +struct ospf6_router_lsa { + u_char bits; + u_char options[3]; + /* followed by ospf6_router_lsdesc(s) */ }; /* Link State Description in Router-LSA */ #define OSPF6_ROUTER_LSDESC_FIX_SIZE 16U -struct ospf6_router_lsdesc -{ - u_char type; - u_char reserved; - u_int16_t metric; /* output cost */ - u_int32_t interface_id; - u_int32_t neighbor_interface_id; - u_int32_t neighbor_router_id; +struct ospf6_router_lsdesc { + u_char type; + u_char reserved; + u_int16_t metric; /* output cost */ + u_int32_t interface_id; + u_int32_t neighbor_interface_id; + u_int32_t neighbor_router_id; }; #define OSPF6_ROUTER_LSDESC_POINTTOPOINT 1 @@ -93,130 +94,134 @@ struct ospf6_router_lsdesc #define OSPF6_ROUTER_LSDESC_STUB_NETWORK 3 #define OSPF6_ROUTER_LSDESC_VIRTUAL_LINK 4 -enum stub_router_mode - { - OSPF6_NOT_STUB_ROUTER, - OSPF6_IS_STUB_ROUTER, - OSPF6_IS_STUB_ROUTER_V6, - }; - -#define ROUTER_LSDESC_IS_TYPE(t,x) \ - ((((struct ospf6_router_lsdesc *)(x))->type == \ - OSPF6_ROUTER_LSDESC_ ## t) ? 1 : 0) -#define ROUTER_LSDESC_GET_METRIC(x) \ - (ntohs (((struct ospf6_router_lsdesc *)(x))->metric)) -#define ROUTER_LSDESC_GET_IFID(x) \ - (ntohl (((struct ospf6_router_lsdesc *)(x))->interface_id)) -#define ROUTER_LSDESC_GET_NBR_IFID(x) \ - (ntohl (((struct ospf6_router_lsdesc *)(x))->neighbor_interface_id)) -#define ROUTER_LSDESC_GET_NBR_ROUTERID(x) \ - (((struct ospf6_router_lsdesc *)(x))->neighbor_router_id) +enum stub_router_mode { + OSPF6_NOT_STUB_ROUTER, + OSPF6_IS_STUB_ROUTER, + OSPF6_IS_STUB_ROUTER_V6, +}; + +#define ROUTER_LSDESC_IS_TYPE(t, x) \ + ((((struct ospf6_router_lsdesc *)(x))->type \ + == OSPF6_ROUTER_LSDESC_##t) \ + ? 1 \ + : 0) +#define ROUTER_LSDESC_GET_METRIC(x) \ + (ntohs(((struct ospf6_router_lsdesc *)(x))->metric)) +#define ROUTER_LSDESC_GET_IFID(x) \ + (ntohl(((struct ospf6_router_lsdesc *)(x))->interface_id)) +#define ROUTER_LSDESC_GET_NBR_IFID(x) \ + (ntohl(((struct ospf6_router_lsdesc *)(x))->neighbor_interface_id)) +#define ROUTER_LSDESC_GET_NBR_ROUTERID(x) \ + (((struct ospf6_router_lsdesc *)(x))->neighbor_router_id) /* Network-LSA */ #define OSPF6_NETWORK_LSA_MIN_SIZE 4U -struct ospf6_network_lsa -{ - u_char reserved; - u_char options[3]; - /* followed by ospf6_netowrk_lsd(s) */ +struct ospf6_network_lsa { + u_char reserved; + u_char options[3]; + /* followed by ospf6_netowrk_lsd(s) */ }; /* Link State Description in Router-LSA */ #define OSPF6_NETWORK_LSDESC_FIX_SIZE 4U -struct ospf6_network_lsdesc -{ - u_int32_t router_id; +struct ospf6_network_lsdesc { + u_int32_t router_id; }; -#define NETWORK_LSDESC_GET_NBR_ROUTERID(x) \ - (((struct ospf6_network_lsdesc *)(x))->router_id) +#define NETWORK_LSDESC_GET_NBR_ROUTERID(x) \ + (((struct ospf6_network_lsdesc *)(x))->router_id) /* Link-LSA */ #define OSPF6_LINK_LSA_MIN_SIZE 24U /* w/o 1st IPv6 prefix */ -struct ospf6_link_lsa -{ - u_char priority; - u_char options[3]; - struct in6_addr linklocal_addr; - u_int32_t prefix_num; - /* followed by ospf6 prefix(es) */ +struct ospf6_link_lsa { + u_char priority; + u_char options[3]; + struct in6_addr linklocal_addr; + u_int32_t prefix_num; + /* followed by ospf6 prefix(es) */ }; /* Intra-Area-Prefix-LSA */ #define OSPF6_INTRA_PREFIX_LSA_MIN_SIZE 12U /* w/o 1st IPv6 prefix */ -struct ospf6_intra_prefix_lsa -{ - u_int16_t prefix_num; - u_int16_t ref_type; - u_int32_t ref_id; - u_int32_t ref_adv_router; - /* followed by ospf6 prefix(es) */ +struct ospf6_intra_prefix_lsa { + u_int16_t prefix_num; + u_int16_t ref_type; + u_int32_t ref_id; + u_int32_t ref_adv_router; + /* followed by ospf6 prefix(es) */ }; -#define OSPF6_ROUTER_LSA_SCHEDULE(oa) \ - do { \ - if (CHECK_FLAG((oa)->flag, OSPF6_AREA_ENABLE)) \ - thread_add_event (master, ospf6_router_lsa_originate, oa, 0, &(oa)->thread_router_lsa); \ - } while (0) -#define OSPF6_NETWORK_LSA_SCHEDULE(oi) \ - do { \ - if (!CHECK_FLAG((oi)->flag, OSPF6_INTERFACE_DISABLE)) \ - thread_add_event (master, ospf6_network_lsa_originate, oi, 0, &(oi)->thread_network_lsa); \ - } while (0) -#define OSPF6_LINK_LSA_SCHEDULE(oi) \ - do { \ - if (!CHECK_FLAG((oi)->flag, OSPF6_INTERFACE_DISABLE)) \ - thread_add_event (master, ospf6_link_lsa_originate, oi, 0, &(oi)->thread_link_lsa); \ - } while (0) -#define OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oa) \ - do { \ - if (CHECK_FLAG((oa)->flag, OSPF6_AREA_ENABLE)) \ - thread_add_event (master, ospf6_intra_prefix_lsa_originate_stub, \ - oa, 0, &(oa)->thread_intra_prefix_lsa); \ - } while (0) -#define OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi) \ - do { \ - if (!CHECK_FLAG((oi)->flag, OSPF6_INTERFACE_DISABLE)) \ - thread_add_event (master, ospf6_intra_prefix_lsa_originate_transit, \ - oi, 0, &(oi)->thread_intra_prefix_lsa); \ - } 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) +#define OSPF6_ROUTER_LSA_SCHEDULE(oa) \ + do { \ + if (CHECK_FLAG((oa)->flag, OSPF6_AREA_ENABLE)) \ + thread_add_event(master, ospf6_router_lsa_originate, \ + oa, 0, &(oa)->thread_router_lsa); \ + } while (0) +#define OSPF6_NETWORK_LSA_SCHEDULE(oi) \ + do { \ + if (!CHECK_FLAG((oi)->flag, OSPF6_INTERFACE_DISABLE)) \ + thread_add_event(master, ospf6_network_lsa_originate, \ + oi, 0, &(oi)->thread_network_lsa); \ + } while (0) +#define OSPF6_LINK_LSA_SCHEDULE(oi) \ + do { \ + if (!CHECK_FLAG((oi)->flag, OSPF6_INTERFACE_DISABLE)) \ + thread_add_event(master, ospf6_link_lsa_originate, oi, \ + 0, &(oi)->thread_link_lsa); \ + } while (0) +#define OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oa) \ + do { \ + if (CHECK_FLAG((oa)->flag, OSPF6_AREA_ENABLE)) \ + thread_add_event( \ + master, ospf6_intra_prefix_lsa_originate_stub, \ + oa, 0, &(oa)->thread_intra_prefix_lsa); \ + } while (0) +#define OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi) \ + do { \ + if (!CHECK_FLAG((oi)->flag, OSPF6_INTERFACE_DISABLE)) \ + thread_add_event( \ + master, \ + ospf6_intra_prefix_lsa_originate_transit, oi, \ + 0, &(oi)->thread_intra_prefix_lsa); \ + } 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 */ -extern char *ospf6_router_lsdesc_lookup (u_char type, u_int32_t interface_id, - u_int32_t neighbor_interface_id, - u_int32_t neighbor_router_id, - struct ospf6_lsa *lsa); -extern char *ospf6_network_lsdesc_lookup (u_int32_t router_id, - struct ospf6_lsa *lsa); - -extern int ospf6_router_is_stub_router (struct ospf6_lsa *lsa); -extern int ospf6_router_lsa_originate (struct thread *); -extern int ospf6_network_lsa_originate (struct thread *); -extern int ospf6_link_lsa_originate (struct thread *); -extern int ospf6_intra_prefix_lsa_originate_transit (struct thread *); -extern int ospf6_intra_prefix_lsa_originate_stub (struct thread *); -extern void ospf6_intra_prefix_lsa_add (struct ospf6_lsa *lsa); -extern void ospf6_intra_prefix_lsa_remove (struct ospf6_lsa *lsa); - -extern void ospf6_intra_route_calculation (struct ospf6_area *oa); -extern void ospf6_intra_brouter_calculation (struct ospf6_area *oa); - -extern void ospf6_intra_init (void); - -extern int config_write_ospf6_debug_brouter (struct vty *vty); -extern void install_element_ospf6_debug_brouter (void); +extern char *ospf6_router_lsdesc_lookup(u_char type, u_int32_t interface_id, + u_int32_t neighbor_interface_id, + u_int32_t neighbor_router_id, + struct ospf6_lsa *lsa); +extern char *ospf6_network_lsdesc_lookup(u_int32_t router_id, + struct ospf6_lsa *lsa); + +extern int ospf6_router_is_stub_router(struct ospf6_lsa *lsa); +extern int ospf6_router_lsa_originate(struct thread *); +extern int ospf6_network_lsa_originate(struct thread *); +extern int ospf6_link_lsa_originate(struct thread *); +extern int ospf6_intra_prefix_lsa_originate_transit(struct thread *); +extern int ospf6_intra_prefix_lsa_originate_stub(struct thread *); +extern void ospf6_intra_prefix_lsa_add(struct ospf6_lsa *lsa); +extern void ospf6_intra_prefix_lsa_remove(struct ospf6_lsa *lsa); + +extern void ospf6_intra_route_calculation(struct ospf6_area *oa); +extern void ospf6_intra_brouter_calculation(struct ospf6_area *oa); + +extern void ospf6_intra_init(void); + +extern int config_write_ospf6_debug_brouter(struct vty *vty); +extern void install_element_ospf6_debug_brouter(void); #endif /* OSPF6_LSA_H */ - diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c index 7817448b7..329060a16 100644 --- a/ospf6d/ospf6_lsa.c +++ b/ospf6d/ospf6_lsa.c @@ -45,769 +45,718 @@ vector ospf6_lsa_handler_vector; -static int -ospf6_unknown_lsa_show (struct vty *vty, struct ospf6_lsa *lsa) +static int ospf6_unknown_lsa_show(struct vty *vty, struct ospf6_lsa *lsa) { - u_char *start, *end, *current; - char byte[4]; + u_char *start, *end, *current; + char byte[4]; - start = (u_char *) lsa->header + sizeof (struct ospf6_lsa_header); - end = (u_char *) lsa->header + ntohs (lsa->header->length); + start = (u_char *)lsa->header + sizeof(struct ospf6_lsa_header); + end = (u_char *)lsa->header + ntohs(lsa->header->length); - vty_out (vty, " Unknown contents:\n"); - for (current = start; current < end; current ++) - { - if ((current - start) % 16 == 0) - vty_out (vty, "\n "); - else if ((current - start) % 4 == 0) - vty_out (vty, " "); + vty_out(vty, " Unknown contents:\n"); + for (current = start; current < end; current++) { + if ((current - start) % 16 == 0) + vty_out(vty, "\n "); + else if ((current - start) % 4 == 0) + vty_out(vty, " "); - snprintf (byte, sizeof (byte), "%02x", *current); - vty_out (vty, "%s", byte); - } + snprintf(byte, sizeof(byte), "%02x", *current); + vty_out(vty, "%s", byte); + } - vty_out (vty, "\n\n"); - return 0; + vty_out(vty, "\n\n"); + return 0; } -struct ospf6_lsa_handler unknown_handler = -{ - OSPF6_LSTYPE_UNKNOWN, - "Unknown", - "Unk", - ospf6_unknown_lsa_show, - NULL -}; +struct ospf6_lsa_handler unknown_handler = { + OSPF6_LSTYPE_UNKNOWN, "Unknown", "Unk", ospf6_unknown_lsa_show, NULL}; -void -ospf6_install_lsa_handler (struct ospf6_lsa_handler *handler) +void ospf6_install_lsa_handler(struct ospf6_lsa_handler *handler) { - /* type in handler is host byte order */ - int index = handler->type & OSPF6_LSTYPE_FCODE_MASK; - vector_set_index (ospf6_lsa_handler_vector, index, handler); + /* type in handler is host byte order */ + int index = handler->type & OSPF6_LSTYPE_FCODE_MASK; + vector_set_index(ospf6_lsa_handler_vector, index, handler); } -struct ospf6_lsa_handler * -ospf6_get_lsa_handler (u_int16_t type) +struct ospf6_lsa_handler *ospf6_get_lsa_handler(u_int16_t type) { - struct ospf6_lsa_handler *handler = NULL; - unsigned int index = ntohs (type) & OSPF6_LSTYPE_FCODE_MASK; + struct ospf6_lsa_handler *handler = NULL; + unsigned int index = ntohs(type) & OSPF6_LSTYPE_FCODE_MASK; - if (index >= vector_active (ospf6_lsa_handler_vector)) - handler = &unknown_handler; - else - handler = vector_slot (ospf6_lsa_handler_vector, index); + if (index >= vector_active(ospf6_lsa_handler_vector)) + handler = &unknown_handler; + else + handler = vector_slot(ospf6_lsa_handler_vector, index); - if (handler == NULL) - handler = &unknown_handler; + if (handler == NULL) + handler = &unknown_handler; - return handler; + return handler; } -const char * -ospf6_lstype_name (u_int16_t type) +const char *ospf6_lstype_name(u_int16_t type) { - static char buf[8]; - struct ospf6_lsa_handler *handler; + static char buf[8]; + struct ospf6_lsa_handler *handler; - handler = ospf6_get_lsa_handler (type); - if (handler && handler != &unknown_handler) - return handler->name; + handler = ospf6_get_lsa_handler(type); + if (handler && handler != &unknown_handler) + return handler->name; - snprintf (buf, sizeof (buf), "0x%04hx", ntohs (type)); - return buf; + snprintf(buf, sizeof(buf), "0x%04hx", ntohs(type)); + return buf; } -const char * -ospf6_lstype_short_name (u_int16_t type) +const char *ospf6_lstype_short_name(u_int16_t type) { - static char buf[8]; - struct ospf6_lsa_handler *handler; + static char buf[8]; + struct ospf6_lsa_handler *handler; - handler = ospf6_get_lsa_handler (type); - if (handler && handler != &unknown_handler) - return handler->short_name; + handler = ospf6_get_lsa_handler(type); + if (handler && handler != &unknown_handler) + return handler->short_name; - snprintf (buf, sizeof (buf), "0x%04hx", ntohs (type)); - return buf; + snprintf(buf, sizeof(buf), "0x%04hx", ntohs(type)); + return buf; } -u_char -ospf6_lstype_debug (u_int16_t type) +u_char ospf6_lstype_debug(u_int16_t type) { - struct ospf6_lsa_handler *handler; - handler = ospf6_get_lsa_handler (type); - return handler->debug; + struct ospf6_lsa_handler *handler; + handler = ospf6_get_lsa_handler(type); + return handler->debug; } /* RFC2328: Section 13.2 */ -int -ospf6_lsa_is_differ (struct ospf6_lsa *lsa1, - struct ospf6_lsa *lsa2) +int ospf6_lsa_is_differ(struct ospf6_lsa *lsa1, struct ospf6_lsa *lsa2) { - int len; + int len; - assert (OSPF6_LSA_IS_SAME (lsa1, lsa2)); + assert(OSPF6_LSA_IS_SAME(lsa1, lsa2)); - /* XXX, Options ??? */ + /* XXX, Options ??? */ - ospf6_lsa_age_current (lsa1); - ospf6_lsa_age_current (lsa2); - if (ntohs (lsa1->header->age) == OSPF_LSA_MAXAGE && - ntohs (lsa2->header->age) != OSPF_LSA_MAXAGE) - return 1; - if (ntohs (lsa1->header->age) != OSPF_LSA_MAXAGE && - ntohs (lsa2->header->age) == OSPF_LSA_MAXAGE) - return 1; + ospf6_lsa_age_current(lsa1); + ospf6_lsa_age_current(lsa2); + if (ntohs(lsa1->header->age) == OSPF_LSA_MAXAGE + && ntohs(lsa2->header->age) != OSPF_LSA_MAXAGE) + return 1; + if (ntohs(lsa1->header->age) != OSPF_LSA_MAXAGE + && ntohs(lsa2->header->age) == OSPF_LSA_MAXAGE) + return 1; - /* compare body */ - if (ntohs (lsa1->header->length) != ntohs (lsa2->header->length)) - return 1; + /* compare body */ + if (ntohs(lsa1->header->length) != ntohs(lsa2->header->length)) + return 1; - len = ntohs (lsa1->header->length) - sizeof (struct ospf6_lsa_header); - return memcmp (lsa1->header + 1, lsa2->header + 1, len); + len = ntohs(lsa1->header->length) - sizeof(struct ospf6_lsa_header); + return memcmp(lsa1->header + 1, lsa2->header + 1, len); } -int -ospf6_lsa_is_changed (struct ospf6_lsa *lsa1, - struct ospf6_lsa *lsa2) +int ospf6_lsa_is_changed(struct ospf6_lsa *lsa1, struct ospf6_lsa *lsa2) { - int length; + int length; - if (OSPF6_LSA_IS_MAXAGE (lsa1) ^ OSPF6_LSA_IS_MAXAGE (lsa2)) - return 1; - if (ntohs (lsa1->header->length) != ntohs (lsa2->header->length)) - return 1; - /* Going beyond LSA headers to compare the payload only makes sense, when both LSAs aren't header-only. */ - if (CHECK_FLAG (lsa1->flag, OSPF6_LSA_HEADERONLY) != CHECK_FLAG (lsa2->flag, OSPF6_LSA_HEADERONLY)) - { - zlog_warn ("%s: only one of two (%s, %s) LSAs compared is header-only", __func__, lsa1->name, lsa2->name); - return 1; - } - if (CHECK_FLAG (lsa1->flag, OSPF6_LSA_HEADERONLY)) - return 0; + if (OSPF6_LSA_IS_MAXAGE(lsa1) ^ OSPF6_LSA_IS_MAXAGE(lsa2)) + return 1; + if (ntohs(lsa1->header->length) != ntohs(lsa2->header->length)) + return 1; + /* Going beyond LSA headers to compare the payload only makes sense, + * when both LSAs aren't header-only. */ + if (CHECK_FLAG(lsa1->flag, OSPF6_LSA_HEADERONLY) + != CHECK_FLAG(lsa2->flag, OSPF6_LSA_HEADERONLY)) { + zlog_warn( + "%s: only one of two (%s, %s) LSAs compared is header-only", + __func__, lsa1->name, lsa2->name); + return 1; + } + if (CHECK_FLAG(lsa1->flag, OSPF6_LSA_HEADERONLY)) + return 0; - length = OSPF6_LSA_SIZE (lsa1->header) - sizeof (struct ospf6_lsa_header); - /* Once upper layer verifies LSAs received, length underrun should become a warning. */ - if (length <= 0) - return 0; + length = OSPF6_LSA_SIZE(lsa1->header) - sizeof(struct ospf6_lsa_header); + /* Once upper layer verifies LSAs received, length underrun should + * become a warning. */ + if (length <= 0) + return 0; - return memcmp (OSPF6_LSA_HEADER_END (lsa1->header), - OSPF6_LSA_HEADER_END (lsa2->header), length); + return memcmp(OSPF6_LSA_HEADER_END(lsa1->header), + OSPF6_LSA_HEADER_END(lsa2->header), length); } /* ospf6 age functions */ /* calculate birth */ -static void -ospf6_lsa_age_set (struct ospf6_lsa *lsa) +static void ospf6_lsa_age_set(struct ospf6_lsa *lsa) { - struct timeval now; + struct timeval now; - assert (lsa && lsa->header); + assert(lsa && lsa->header); - monotime(&now); + monotime(&now); - lsa->birth.tv_sec = now.tv_sec - ntohs (lsa->header->age); - lsa->birth.tv_usec = now.tv_usec; + lsa->birth.tv_sec = now.tv_sec - ntohs(lsa->header->age); + lsa->birth.tv_usec = now.tv_usec; - return; + return; } /* this function calculates current age from its birth, then update age field of LSA header. return value is current age */ -u_int16_t -ospf6_lsa_age_current (struct ospf6_lsa *lsa) +u_int16_t ospf6_lsa_age_current(struct ospf6_lsa *lsa) { - struct timeval now; - u_int32_t ulage; - u_int16_t age; + struct timeval now; + u_int32_t ulage; + u_int16_t age; - assert (lsa); - assert (lsa->header); + assert(lsa); + assert(lsa->header); - /* current time */ - monotime(&now); + /* current time */ + monotime(&now); - if (ntohs (lsa->header->age) >= OSPF_LSA_MAXAGE) - { - /* ospf6_lsa_premature_aging () sets age to MAXAGE; when using - relative time, we cannot compare against lsa birth time, so - we catch this special case here. */ - lsa->header->age = htons (OSPF_LSA_MAXAGE); - return OSPF_LSA_MAXAGE; - } - /* calculate age */ - ulage = now.tv_sec - lsa->birth.tv_sec; + if (ntohs(lsa->header->age) >= OSPF_LSA_MAXAGE) { + /* ospf6_lsa_premature_aging () sets age to MAXAGE; when using + relative time, we cannot compare against lsa birth time, so + we catch this special case here. */ + lsa->header->age = htons(OSPF_LSA_MAXAGE); + return OSPF_LSA_MAXAGE; + } + /* calculate age */ + ulage = now.tv_sec - lsa->birth.tv_sec; - /* if over MAXAGE, set to it */ - age = (ulage > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : ulage); + /* if over MAXAGE, set to it */ + age = (ulage > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : ulage); - lsa->header->age = htons (age); - return age; + lsa->header->age = htons(age); + return age; } /* update age field of LSA header with adding InfTransDelay */ -void -ospf6_lsa_age_update_to_send (struct ospf6_lsa *lsa, u_int32_t transdelay) -{ - unsigned short age; - - age = ospf6_lsa_age_current (lsa) + transdelay; - if (age > OSPF_LSA_MAXAGE) - age = OSPF_LSA_MAXAGE; - lsa->header->age = htons (age); -} - -void -ospf6_lsa_premature_aging (struct ospf6_lsa *lsa) -{ - /* log */ - if (IS_OSPF6_DEBUG_LSA_TYPE (lsa->header->type)) - zlog_debug ("LSA: Premature aging: %s", lsa->name); - - THREAD_OFF (lsa->expire); - THREAD_OFF (lsa->refresh); - - /* - * We clear the LSA from the neighbor retx lists now because it - * will not get deleted later. Essentially, changing the age to - * MaxAge will prevent this LSA from being matched with its - * existing entries in the retx list thereby causing those entries - * to be silently replaced with its MaxAged version, but with ever - * increasing retx count causing this LSA to remain forever and - * for the MaxAge remover thread to be called forever too. - * - * The reason the previous entry silently disappears is that when - * entry is added to a neighbor's retx list, it replaces the existing - * entry. But since the ospf6_lsdb_add() routine is generic and not aware - * of the special semantics of retx count, the retx count is not - * decremented when its replaced. Attempting to add the incr and decr - * retx count routines as the hook_add and hook_remove for the retx lists - * have a problem because the hook_remove routine is called for MaxAge - * entries (as will be the case in a traditional LSDB, unlike in this case - * where an LSDB is used as an efficient tree structure to store all kinds - * of data) that are added instead of calling the hook_add routine. - */ - - ospf6_flood_clear (lsa); - - lsa->header->age = htons (OSPF_LSA_MAXAGE); - thread_execute (master, ospf6_lsa_expire, lsa, 0); +void ospf6_lsa_age_update_to_send(struct ospf6_lsa *lsa, u_int32_t transdelay) +{ + unsigned short age; + + age = ospf6_lsa_age_current(lsa) + transdelay; + if (age > OSPF_LSA_MAXAGE) + age = OSPF_LSA_MAXAGE; + lsa->header->age = htons(age); +} + +void ospf6_lsa_premature_aging(struct ospf6_lsa *lsa) +{ + /* log */ + if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type)) + zlog_debug("LSA: Premature aging: %s", lsa->name); + + THREAD_OFF(lsa->expire); + THREAD_OFF(lsa->refresh); + + /* + * We clear the LSA from the neighbor retx lists now because it + * will not get deleted later. Essentially, changing the age to + * MaxAge will prevent this LSA from being matched with its + * existing entries in the retx list thereby causing those entries + * to be silently replaced with its MaxAged version, but with ever + * increasing retx count causing this LSA to remain forever and + * for the MaxAge remover thread to be called forever too. + * + * The reason the previous entry silently disappears is that when + * entry is added to a neighbor's retx list, it replaces the existing + * entry. But since the ospf6_lsdb_add() routine is generic and not + * aware + * of the special semantics of retx count, the retx count is not + * decremented when its replaced. Attempting to add the incr and decr + * retx count routines as the hook_add and hook_remove for the retx + * lists + * have a problem because the hook_remove routine is called for MaxAge + * entries (as will be the case in a traditional LSDB, unlike in this + * case + * where an LSDB is used as an efficient tree structure to store all + * kinds + * of data) that are added instead of calling the hook_add routine. + */ + + ospf6_flood_clear(lsa); + + lsa->header->age = htons(OSPF_LSA_MAXAGE); + thread_execute(master, ospf6_lsa_expire, lsa, 0); } /* check which is more recent. if a is more recent, return -1; if the same, return 0; otherwise(b is more recent), return 1 */ -int -ospf6_lsa_compare (struct ospf6_lsa *a, struct ospf6_lsa *b) +int ospf6_lsa_compare(struct ospf6_lsa *a, struct ospf6_lsa *b) { - int32_t seqnuma, seqnumb; - u_int16_t cksuma, cksumb; - u_int16_t agea, ageb; + int32_t seqnuma, seqnumb; + u_int16_t cksuma, cksumb; + u_int16_t agea, ageb; + + assert(a && a->header); + assert(b && b->header); + assert(OSPF6_LSA_IS_SAME(a, b)); - assert (a && a->header); - assert (b && b->header); - assert (OSPF6_LSA_IS_SAME (a, b)); + seqnuma = (int32_t)ntohl(a->header->seqnum); + seqnumb = (int32_t)ntohl(b->header->seqnum); - seqnuma = (int32_t) ntohl (a->header->seqnum); - seqnumb = (int32_t) ntohl (b->header->seqnum); - - /* compare by sequence number */ - if (seqnuma > seqnumb) - return -1; - if (seqnuma < seqnumb) - return 1; - - /* Checksum */ - cksuma = ntohs (a->header->checksum); - cksumb = ntohs (b->header->checksum); - if (cksuma > cksumb) - return -1; - if (cksuma < cksumb) - return 0; - - /* Update Age */ - agea = ospf6_lsa_age_current (a); - ageb = ospf6_lsa_age_current (b); - - /* MaxAge check */ - if (agea == OSPF_LSA_MAXAGE && ageb != OSPF_LSA_MAXAGE) - return -1; - else if (agea != OSPF_LSA_MAXAGE && ageb == OSPF_LSA_MAXAGE) - return 1; - - /* Age check */ - if (agea > ageb && agea - ageb >= OSPF_LSA_MAXAGE_DIFF) - return 1; - else if (agea < ageb && ageb - agea >= OSPF_LSA_MAXAGE_DIFF) - return -1; - - /* neither recent */ - return 0; -} - -char * -ospf6_lsa_printbuf (struct ospf6_lsa *lsa, char *buf, int size) -{ - char id[16], adv_router[16]; - inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id)); - inet_ntop (AF_INET, &lsa->header->adv_router, adv_router, - sizeof (adv_router)); - snprintf (buf, size, "[%s Id:%s Adv:%s]", - ospf6_lstype_name (lsa->header->type), id, adv_router); - return buf; -} - -void -ospf6_lsa_header_print_raw (struct ospf6_lsa_header *header) -{ - char id[16], adv_router[16]; - inet_ntop (AF_INET, &header->id, id, sizeof (id)); - inet_ntop (AF_INET, &header->adv_router, adv_router, - sizeof (adv_router)); - zlog_debug (" [%s Id:%s Adv:%s]", - ospf6_lstype_name (header->type), id, adv_router); - zlog_debug (" Age: %4hu SeqNum: %#08lx Cksum: %04hx Len: %d", - ntohs (header->age), (u_long) ntohl (header->seqnum), - ntohs (header->checksum), ntohs (header->length)); -} - -void -ospf6_lsa_header_print (struct ospf6_lsa *lsa) -{ - ospf6_lsa_age_current (lsa); - ospf6_lsa_header_print_raw (lsa->header); -} - -void -ospf6_lsa_show_summary_header (struct vty *vty) -{ - vty_out (vty, "%-4s %-15s%-15s%4s %8s %30s\n", - "Type", "LSId", "AdvRouter", "Age", "SeqNum", - "Payload"); -} - -void -ospf6_lsa_show_summary (struct vty *vty, struct ospf6_lsa *lsa) -{ - char adv_router[16], id[16]; - int type; - struct ospf6_lsa_handler *handler; - char buf[64], tmpbuf[80]; - int cnt = 0; - - assert (lsa); - assert (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)); - - type = ntohs(lsa->header->type); - handler = ospf6_get_lsa_handler (lsa->header->type); - if ((type == OSPF6_LSTYPE_INTER_PREFIX) || - (type == OSPF6_LSTYPE_INTER_ROUTER) || - (type == OSPF6_LSTYPE_AS_EXTERNAL)) - { - vty_out (vty, "%-4s %-15s%-15s%4hu %8lx %30s\n", - ospf6_lstype_short_name (lsa->header->type), - id, adv_router, ospf6_lsa_age_current (lsa), - (u_long) ntohl (lsa->header->seqnum), - handler->get_prefix_str(lsa, buf, sizeof(buf), 0)); - } - else if (type != OSPF6_LSTYPE_UNKNOWN) - { - sprintf (tmpbuf, "%-4s %-15s%-15s%4hu %8lx", - ospf6_lstype_short_name (lsa->header->type), - id, adv_router, ospf6_lsa_age_current (lsa), - (u_long) ntohl (lsa->header->seqnum)); - - while (handler->get_prefix_str(lsa, buf, sizeof(buf), cnt) != NULL) - { - vty_out (vty, "%s %30s\n", tmpbuf, buf); - cnt++; + /* compare by sequence number */ + if (seqnuma > seqnumb) + return -1; + if (seqnuma < seqnumb) + return 1; + + /* Checksum */ + cksuma = ntohs(a->header->checksum); + cksumb = ntohs(b->header->checksum); + if (cksuma > cksumb) + return -1; + if (cksuma < cksumb) + return 0; + + /* Update Age */ + agea = ospf6_lsa_age_current(a); + ageb = ospf6_lsa_age_current(b); + + /* MaxAge check */ + if (agea == OSPF_LSA_MAXAGE && ageb != OSPF_LSA_MAXAGE) + return -1; + else if (agea != OSPF_LSA_MAXAGE && ageb == OSPF_LSA_MAXAGE) + return 1; + + /* Age check */ + if (agea > ageb && agea - ageb >= OSPF_LSA_MAXAGE_DIFF) + return 1; + else if (agea < ageb && ageb - agea >= OSPF_LSA_MAXAGE_DIFF) + return -1; + + /* neither recent */ + return 0; +} + +char *ospf6_lsa_printbuf(struct ospf6_lsa *lsa, char *buf, int size) +{ + char id[16], adv_router[16]; + inet_ntop(AF_INET, &lsa->header->id, id, sizeof(id)); + inet_ntop(AF_INET, &lsa->header->adv_router, adv_router, + sizeof(adv_router)); + snprintf(buf, size, "[%s Id:%s Adv:%s]", + ospf6_lstype_name(lsa->header->type), id, adv_router); + return buf; +} + +void ospf6_lsa_header_print_raw(struct ospf6_lsa_header *header) +{ + char id[16], adv_router[16]; + inet_ntop(AF_INET, &header->id, id, sizeof(id)); + inet_ntop(AF_INET, &header->adv_router, adv_router, sizeof(adv_router)); + zlog_debug(" [%s Id:%s Adv:%s]", ospf6_lstype_name(header->type), id, + adv_router); + zlog_debug(" Age: %4hu SeqNum: %#08lx Cksum: %04hx Len: %d", + ntohs(header->age), (u_long)ntohl(header->seqnum), + ntohs(header->checksum), ntohs(header->length)); +} + +void ospf6_lsa_header_print(struct ospf6_lsa *lsa) +{ + ospf6_lsa_age_current(lsa); + ospf6_lsa_header_print_raw(lsa->header); +} + +void ospf6_lsa_show_summary_header(struct vty *vty) +{ + vty_out(vty, "%-4s %-15s%-15s%4s %8s %30s\n", "Type", "LSId", + "AdvRouter", "Age", "SeqNum", "Payload"); +} + +void ospf6_lsa_show_summary(struct vty *vty, struct ospf6_lsa *lsa) +{ + char adv_router[16], id[16]; + int type; + struct ospf6_lsa_handler *handler; + char buf[64], tmpbuf[80]; + int cnt = 0; + + assert(lsa); + assert(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)); + + type = ntohs(lsa->header->type); + handler = ospf6_get_lsa_handler(lsa->header->type); + if ((type == OSPF6_LSTYPE_INTER_PREFIX) + || (type == OSPF6_LSTYPE_INTER_ROUTER) + || (type == OSPF6_LSTYPE_AS_EXTERNAL)) { + vty_out(vty, "%-4s %-15s%-15s%4hu %8lx %30s\n", + ospf6_lstype_short_name(lsa->header->type), id, + adv_router, ospf6_lsa_age_current(lsa), + (u_long)ntohl(lsa->header->seqnum), + handler->get_prefix_str(lsa, buf, sizeof(buf), 0)); + } else if (type != OSPF6_LSTYPE_UNKNOWN) { + sprintf(tmpbuf, "%-4s %-15s%-15s%4hu %8lx", + ospf6_lstype_short_name(lsa->header->type), id, + adv_router, ospf6_lsa_age_current(lsa), + (u_long)ntohl(lsa->header->seqnum)); + + while (handler->get_prefix_str(lsa, buf, sizeof(buf), cnt) + != NULL) { + vty_out(vty, "%s %30s\n", tmpbuf, buf); + cnt++; + } + } else { + vty_out(vty, "%-4s %-15s%-15s%4hu %8lx\n", + ospf6_lstype_short_name(lsa->header->type), id, + adv_router, ospf6_lsa_age_current(lsa), + (u_long)ntohl(lsa->header->seqnum)); } - } - else - { - vty_out (vty, "%-4s %-15s%-15s%4hu %8lx\n", - ospf6_lstype_short_name (lsa->header->type), - id, adv_router, ospf6_lsa_age_current (lsa), - (u_long) ntohl (lsa->header->seqnum)); - } -} - -void -ospf6_lsa_show_dump (struct vty *vty, struct ospf6_lsa *lsa) -{ - u_char *start, *end, *current; - char byte[4]; - - start = (u_char *) lsa->header; - end = (u_char *) lsa->header + ntohs (lsa->header->length); - - vty_out (vty, "\n"); - vty_out (vty, "%s:\n", lsa->name); - - for (current = start; current < end; current ++) - { - if ((current - start) % 16 == 0) - vty_out (vty, "\n "); - else if ((current - start) % 4 == 0) - vty_out (vty, " "); - - snprintf (byte, sizeof (byte), "%02x", *current); - vty_out (vty, "%s", byte); - } - - vty_out (vty, "\n\n"); - return; -} - -void -ospf6_lsa_show_internal (struct vty *vty, struct ospf6_lsa *lsa) -{ - char adv_router[64], id[64]; - - 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, "\n"); - vty_out (vty, "Age: %4hu Type: %s\n", ospf6_lsa_age_current (lsa), - ospf6_lstype_name (lsa->header->type)); - vty_out (vty, "Link State ID: %s\n", id); - vty_out (vty, "Advertising Router: %s\n", adv_router); - vty_out (vty, "LS Sequence Number: %#010lx\n", - (u_long) ntohl (lsa->header->seqnum)); - vty_out (vty, "CheckSum: %#06hx Length: %hu\n", - ntohs (lsa->header->checksum), - ntohs (lsa->header->length)); - vty_out (vty, "Flag: %x \n", lsa->flag); - vty_out (vty, "Lock: %d \n", lsa->lock); - vty_out (vty, "ReTx Count: %d\n", lsa->retrans_count); - vty_out (vty, "Threads: Expire: 0x%p, Refresh: 0x%p \n", - (void *)lsa->expire, (void *)lsa->refresh); - vty_out (vty, "\n"); - return; -} - -void -ospf6_lsa_show (struct vty *vty, struct ospf6_lsa *lsa) -{ - char adv_router[64], id[64]; - struct ospf6_lsa_handler *handler; - struct timeval now, res; - char duration[16]; - - 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)); - - monotime(&now); - timersub (&now, &lsa->installed, &res); - timerstring (&res, duration, sizeof (duration)); - - vty_out (vty, "Age: %4hu Type: %s\n", ospf6_lsa_age_current (lsa), - ospf6_lstype_name (lsa->header->type)); - vty_out (vty, "Link State ID: %s\n", id); - vty_out (vty, "Advertising Router: %s\n", adv_router); - vty_out (vty, "LS Sequence Number: %#010lx\n", - (u_long) ntohl (lsa->header->seqnum)); - vty_out (vty, "CheckSum: %#06hx Length: %hu\n", - ntohs (lsa->header->checksum), - ntohs (lsa->header->length)); - vty_out (vty, "Duration: %s\n", duration); - - handler = ospf6_get_lsa_handler (lsa->header->type); - if (handler->show == NULL) - handler = &unknown_handler; - (*handler->show) (vty, lsa); - - vty_out (vty, "\n"); +} + +void ospf6_lsa_show_dump(struct vty *vty, struct ospf6_lsa *lsa) +{ + u_char *start, *end, *current; + char byte[4]; + + start = (u_char *)lsa->header; + end = (u_char *)lsa->header + ntohs(lsa->header->length); + + vty_out(vty, "\n"); + vty_out(vty, "%s:\n", lsa->name); + + for (current = start; current < end; current++) { + if ((current - start) % 16 == 0) + vty_out(vty, "\n "); + else if ((current - start) % 4 == 0) + vty_out(vty, " "); + + snprintf(byte, sizeof(byte), "%02x", *current); + vty_out(vty, "%s", byte); + } + + vty_out(vty, "\n\n"); + return; +} + +void ospf6_lsa_show_internal(struct vty *vty, struct ospf6_lsa *lsa) +{ + char adv_router[64], id[64]; + + 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, "\n"); + vty_out(vty, "Age: %4hu Type: %s\n", ospf6_lsa_age_current(lsa), + ospf6_lstype_name(lsa->header->type)); + vty_out(vty, "Link State ID: %s\n", id); + vty_out(vty, "Advertising Router: %s\n", adv_router); + vty_out(vty, "LS Sequence Number: %#010lx\n", + (u_long)ntohl(lsa->header->seqnum)); + vty_out(vty, "CheckSum: %#06hx Length: %hu\n", + ntohs(lsa->header->checksum), ntohs(lsa->header->length)); + vty_out(vty, "Flag: %x \n", lsa->flag); + vty_out(vty, "Lock: %d \n", lsa->lock); + vty_out(vty, "ReTx Count: %d\n", lsa->retrans_count); + vty_out(vty, "Threads: Expire: 0x%p, Refresh: 0x%p \n", + (void *)lsa->expire, (void *)lsa->refresh); + vty_out(vty, "\n"); + return; +} + +void ospf6_lsa_show(struct vty *vty, struct ospf6_lsa *lsa) +{ + char adv_router[64], id[64]; + struct ospf6_lsa_handler *handler; + struct timeval now, res; + char duration[16]; + + 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)); + + monotime(&now); + timersub(&now, &lsa->installed, &res); + timerstring(&res, duration, sizeof(duration)); + + vty_out(vty, "Age: %4hu Type: %s\n", ospf6_lsa_age_current(lsa), + ospf6_lstype_name(lsa->header->type)); + vty_out(vty, "Link State ID: %s\n", id); + vty_out(vty, "Advertising Router: %s\n", adv_router); + vty_out(vty, "LS Sequence Number: %#010lx\n", + (u_long)ntohl(lsa->header->seqnum)); + vty_out(vty, "CheckSum: %#06hx Length: %hu\n", + ntohs(lsa->header->checksum), ntohs(lsa->header->length)); + vty_out(vty, "Duration: %s\n", duration); + + handler = ospf6_get_lsa_handler(lsa->header->type); + if (handler->show == NULL) + handler = &unknown_handler; + (*handler->show)(vty, lsa); + + vty_out(vty, "\n"); } /* OSPFv3 LSA creation/deletion function */ -struct ospf6_lsa * -ospf6_lsa_create (struct ospf6_lsa_header *header) +struct ospf6_lsa *ospf6_lsa_create(struct ospf6_lsa_header *header) { - struct ospf6_lsa *lsa = NULL; - struct ospf6_lsa_header *new_header = NULL; - u_int16_t lsa_size = 0; + struct ospf6_lsa *lsa = NULL; + struct ospf6_lsa_header *new_header = NULL; + u_int16_t lsa_size = 0; - /* size of the entire LSA */ - lsa_size = ntohs (header->length); /* XXX vulnerable */ + /* size of the entire LSA */ + lsa_size = ntohs(header->length); /* XXX vulnerable */ - /* allocate memory for this LSA */ - new_header = (struct ospf6_lsa_header *) - XMALLOC (MTYPE_OSPF6_LSA, lsa_size); + /* allocate memory for this LSA */ + new_header = + (struct ospf6_lsa_header *)XMALLOC(MTYPE_OSPF6_LSA, lsa_size); - /* copy LSA from original header */ - memcpy (new_header, header, lsa_size); + /* copy LSA from original header */ + memcpy(new_header, header, lsa_size); - /* LSA information structure */ - /* allocate memory */ - lsa = (struct ospf6_lsa *) - XCALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa)); + /* LSA information structure */ + /* allocate memory */ + lsa = (struct ospf6_lsa *)XCALLOC(MTYPE_OSPF6_LSA, + sizeof(struct ospf6_lsa)); - lsa->header = (struct ospf6_lsa_header *) new_header; + lsa->header = (struct ospf6_lsa_header *)new_header; - /* dump string */ - ospf6_lsa_printbuf (lsa, lsa->name, sizeof (lsa->name)); + /* dump string */ + ospf6_lsa_printbuf(lsa, lsa->name, sizeof(lsa->name)); - /* calculate birth of this lsa */ - ospf6_lsa_age_set (lsa); + /* calculate birth of this lsa */ + ospf6_lsa_age_set(lsa); - return lsa; + return lsa; } -struct ospf6_lsa * -ospf6_lsa_create_headeronly (struct ospf6_lsa_header *header) +struct ospf6_lsa *ospf6_lsa_create_headeronly(struct ospf6_lsa_header *header) { - struct ospf6_lsa *lsa = NULL; - struct ospf6_lsa_header *new_header = NULL; + struct ospf6_lsa *lsa = NULL; + struct ospf6_lsa_header *new_header = NULL; - /* allocate memory for this LSA */ - new_header = (struct ospf6_lsa_header *) - XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa_header)); + /* allocate memory for this LSA */ + new_header = (struct ospf6_lsa_header *)XMALLOC( + MTYPE_OSPF6_LSA, sizeof(struct ospf6_lsa_header)); - /* copy LSA from original header */ - memcpy (new_header, header, sizeof (struct ospf6_lsa_header)); + /* copy LSA from original header */ + memcpy(new_header, header, sizeof(struct ospf6_lsa_header)); - /* LSA information structure */ - /* allocate memory */ - lsa = (struct ospf6_lsa *) - XCALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa)); + /* LSA information structure */ + /* allocate memory */ + lsa = (struct ospf6_lsa *)XCALLOC(MTYPE_OSPF6_LSA, + sizeof(struct ospf6_lsa)); - lsa->header = (struct ospf6_lsa_header *) new_header; - SET_FLAG (lsa->flag, OSPF6_LSA_HEADERONLY); + lsa->header = (struct ospf6_lsa_header *)new_header; + SET_FLAG(lsa->flag, OSPF6_LSA_HEADERONLY); - /* dump string */ - ospf6_lsa_printbuf (lsa, lsa->name, sizeof (lsa->name)); + /* dump string */ + ospf6_lsa_printbuf(lsa, lsa->name, sizeof(lsa->name)); - /* calculate birth of this lsa */ - ospf6_lsa_age_set (lsa); + /* calculate birth of this lsa */ + ospf6_lsa_age_set(lsa); - return lsa; + return lsa; } -void -ospf6_lsa_delete (struct ospf6_lsa *lsa) +void ospf6_lsa_delete(struct ospf6_lsa *lsa) { - assert (lsa->lock == 0); + assert(lsa->lock == 0); - /* cancel threads */ - THREAD_OFF (lsa->expire); - THREAD_OFF (lsa->refresh); + /* cancel threads */ + THREAD_OFF(lsa->expire); + THREAD_OFF(lsa->refresh); - /* do free */ - XFREE (MTYPE_OSPF6_LSA, lsa->header); - XFREE (MTYPE_OSPF6_LSA, lsa); + /* do free */ + XFREE(MTYPE_OSPF6_LSA, lsa->header); + XFREE(MTYPE_OSPF6_LSA, lsa); } -struct ospf6_lsa * -ospf6_lsa_copy (struct ospf6_lsa *lsa) +struct ospf6_lsa *ospf6_lsa_copy(struct ospf6_lsa *lsa) { - struct ospf6_lsa *copy = NULL; + struct ospf6_lsa *copy = NULL; - ospf6_lsa_age_current (lsa); - if (CHECK_FLAG (lsa->flag, OSPF6_LSA_HEADERONLY)) - copy = ospf6_lsa_create_headeronly (lsa->header); - else - copy = ospf6_lsa_create (lsa->header); - assert (copy->lock == 0); + ospf6_lsa_age_current(lsa); + if (CHECK_FLAG(lsa->flag, OSPF6_LSA_HEADERONLY)) + copy = ospf6_lsa_create_headeronly(lsa->header); + else + copy = ospf6_lsa_create(lsa->header); + assert(copy->lock == 0); - copy->birth = lsa->birth; - copy->originated = lsa->originated; - copy->received = lsa->received; - copy->installed = lsa->installed; - copy->lsdb = lsa->lsdb; - copy->rn = NULL; + copy->birth = lsa->birth; + copy->originated = lsa->originated; + copy->received = lsa->received; + copy->installed = lsa->installed; + copy->lsdb = lsa->lsdb; + copy->rn = NULL; - return copy; + return copy; } /* increment reference counter of struct ospf6_lsa */ -void -ospf6_lsa_lock (struct ospf6_lsa *lsa) +void ospf6_lsa_lock(struct ospf6_lsa *lsa) { - lsa->lock++; - return; + lsa->lock++; + return; } /* decrement reference counter of struct ospf6_lsa */ -void -ospf6_lsa_unlock (struct ospf6_lsa *lsa) +void ospf6_lsa_unlock(struct ospf6_lsa *lsa) { - /* decrement reference counter */ - assert (lsa->lock > 0); - lsa->lock--; + /* decrement reference counter */ + assert(lsa->lock > 0); + lsa->lock--; - if (lsa->lock != 0) - return; + if (lsa->lock != 0) + return; - ospf6_lsa_delete (lsa); + ospf6_lsa_delete(lsa); } /* ospf6 lsa expiry */ -int -ospf6_lsa_expire (struct thread *thread) +int ospf6_lsa_expire(struct thread *thread) { - struct ospf6_lsa *lsa; + struct ospf6_lsa *lsa; - lsa = (struct ospf6_lsa *) THREAD_ARG (thread); + lsa = (struct ospf6_lsa *)THREAD_ARG(thread); - assert (lsa && lsa->header); - assert (OSPF6_LSA_IS_MAXAGE (lsa)); - assert (! lsa->refresh); + assert(lsa && lsa->header); + assert(OSPF6_LSA_IS_MAXAGE(lsa)); + assert(!lsa->refresh); - lsa->expire = (struct thread *) NULL; + lsa->expire = (struct thread *)NULL; - if (IS_OSPF6_DEBUG_LSA_TYPE (lsa->header->type)) - { - zlog_debug ("LSA Expire:"); - ospf6_lsa_header_print (lsa); - } + if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type)) { + zlog_debug("LSA Expire:"); + ospf6_lsa_header_print(lsa); + } - if (CHECK_FLAG (lsa->flag, OSPF6_LSA_HEADERONLY)) - return 0; /* dbexchange will do something ... */ + if (CHECK_FLAG(lsa->flag, OSPF6_LSA_HEADERONLY)) + return 0; /* dbexchange will do something ... */ - /* reinstall lsa */ - ospf6_install_lsa (lsa); + /* reinstall lsa */ + ospf6_install_lsa(lsa); - /* reflood lsa */ - ospf6_flood (NULL, lsa); + /* reflood lsa */ + ospf6_flood(NULL, lsa); - /* schedule maxage remover */ - ospf6_maxage_remove (ospf6); + /* schedule maxage remover */ + ospf6_maxage_remove(ospf6); - return 0; + return 0; } -int -ospf6_lsa_refresh (struct thread *thread) +int ospf6_lsa_refresh(struct thread *thread) { - struct ospf6_lsa *old, *self, *new; - struct ospf6_lsdb *lsdb_self; - - old = (struct ospf6_lsa *) THREAD_ARG (thread); - assert (old && old->header); - - old->refresh = (struct thread *) NULL; + struct ospf6_lsa *old, *self, *new; + struct ospf6_lsdb *lsdb_self; - 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) - { - if (IS_OSPF6_DEBUG_LSA_TYPE (old->header->type)) - zlog_debug ("Refresh: could not find self LSA, flush %s", old->name); - ospf6_lsa_premature_aging (old); - return 0; - } + old = (struct ospf6_lsa *)THREAD_ARG(thread); + assert(old && old->header); - /* 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); + old->refresh = (struct thread *)NULL; - new = ospf6_lsa_create (self->header); - new->lsdb = old->lsdb; - new->refresh = NULL; - thread_add_timer(master, ospf6_lsa_refresh, new, OSPF_LS_REFRESH_TIME, - &new->refresh); - - /* store it in the LSDB for self-originated LSAs */ - ospf6_lsdb_add (ospf6_lsa_copy (new), lsdb_self); + 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) { + if (IS_OSPF6_DEBUG_LSA_TYPE(old->header->type)) + zlog_debug("Refresh: could not find self LSA, flush %s", + old->name); + ospf6_lsa_premature_aging(old); + return 0; + } - if (IS_OSPF6_DEBUG_LSA_TYPE (new->header->type)) - { - zlog_debug ("LSA Refresh:"); - ospf6_lsa_header_print (new); - } + /* 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 = NULL; + thread_add_timer(master, ospf6_lsa_refresh, new, OSPF_LS_REFRESH_TIME, + &new->refresh); + + /* store it in the LSDB for self-originated LSAs */ + ospf6_lsdb_add(ospf6_lsa_copy(new), lsdb_self); + + if (IS_OSPF6_DEBUG_LSA_TYPE(new->header->type)) { + zlog_debug("LSA Refresh:"); + ospf6_lsa_header_print(new); + } - ospf6_install_lsa (new); - ospf6_flood (NULL, new); + ospf6_install_lsa(new); + ospf6_flood(NULL, new); - return 0; + return 0; } - /* Fletcher Checksum -- Refer to RFC1008. */ /* All the offsets are zero-based. The offsets in the RFC1008 are one-based. */ -unsigned short -ospf6_lsa_checksum (struct ospf6_lsa_header *lsa_header) +unsigned short ospf6_lsa_checksum(struct ospf6_lsa_header *lsa_header) { - u_char *buffer = (u_char *) &lsa_header->type; - int type_offset = buffer - (u_char *) &lsa_header->age; /* should be 2 */ + u_char *buffer = (u_char *)&lsa_header->type; + int type_offset = buffer - (u_char *)&lsa_header->age; /* should be 2 */ - /* Skip the AGE field */ - u_int16_t len = ntohs(lsa_header->length) - type_offset; + /* Skip the AGE field */ + u_int16_t len = ntohs(lsa_header->length) - type_offset; - /* Checksum offset starts from "type" field, not the beginning of the - lsa_header struct. The offset is 14, rather than 16. */ - int checksum_offset = (u_char *) &lsa_header->checksum - buffer; + /* Checksum offset starts from "type" field, not the beginning of the + lsa_header struct. The offset is 14, rather than 16. */ + int checksum_offset = (u_char *)&lsa_header->checksum - buffer; - return (unsigned short)fletcher_checksum(buffer, len, checksum_offset); + return (unsigned short)fletcher_checksum(buffer, len, checksum_offset); } -int -ospf6_lsa_checksum_valid (struct ospf6_lsa_header *lsa_header) +int ospf6_lsa_checksum_valid(struct ospf6_lsa_header *lsa_header) { - u_char *buffer = (u_char *) &lsa_header->type; - int type_offset = buffer - (u_char *) &lsa_header->age; /* should be 2 */ + u_char *buffer = (u_char *)&lsa_header->type; + int type_offset = buffer - (u_char *)&lsa_header->age; /* should be 2 */ - /* Skip the AGE field */ - u_int16_t len = ntohs(lsa_header->length) - type_offset; + /* Skip the AGE field */ + u_int16_t len = ntohs(lsa_header->length) - type_offset; - return (fletcher_checksum(buffer, len, FLETCHER_CHECKSUM_VALIDATE) == 0); + return (fletcher_checksum(buffer, len, FLETCHER_CHECKSUM_VALIDATE) + == 0); } -void -ospf6_lsa_init (void) +void ospf6_lsa_init(void) { - ospf6_lsa_handler_vector = vector_init (0); - ospf6_install_lsa_handler (&unknown_handler); + ospf6_lsa_handler_vector = vector_init(0); + ospf6_install_lsa_handler(&unknown_handler); } -void -ospf6_lsa_terminate (void) +void ospf6_lsa_terminate(void) { - vector_free (ospf6_lsa_handler_vector); + vector_free(ospf6_lsa_handler_vector); } -static char * -ospf6_lsa_handler_name (struct ospf6_lsa_handler *h) +static char *ospf6_lsa_handler_name(struct ospf6_lsa_handler *h) { - static char buf[64]; - unsigned int i; - unsigned int size = strlen (h->name); + static char buf[64]; + unsigned int i; + unsigned int size = strlen(h->name); - if (!strcmp(h->name, "unknown") && - h->type != OSPF6_LSTYPE_UNKNOWN) - { - snprintf (buf, sizeof (buf), "%#04hx", h->type); - return buf; - } + if (!strcmp(h->name, "unknown") && h->type != OSPF6_LSTYPE_UNKNOWN) { + snprintf(buf, sizeof(buf), "%#04hx", h->type); + return buf; + } - for (i = 0; i < MIN (size, sizeof (buf)); i++) - { - if (! islower ((unsigned char)h->name[i])) - buf[i] = tolower ((unsigned char)h->name[i]); - else - buf[i] = h->name[i]; - } - buf[size] = '\0'; - return buf; + for (i = 0; i < MIN(size, sizeof(buf)); i++) { + if (!islower((unsigned char)h->name[i])) + buf[i] = tolower((unsigned char)h->name[i]); + else + buf[i] = h->name[i]; + } + buf[size] = '\0'; + return buf; } DEFUN (debug_ospf6_lsa_type, @@ -828,39 +777,38 @@ DEFUN (debug_ospf6_lsa_type, "Dump LSAs\n" "Display LSA's internal information\n") { - int idx_lsa = 3; - int idx_type = 4; - unsigned int i; - struct ospf6_lsa_handler *handler = NULL; - - for (i = 0; i < vector_active (ospf6_lsa_handler_vector); i++) - { - handler = vector_slot (ospf6_lsa_handler_vector, i); - if (handler == NULL) - continue; - if (strncmp (argv[idx_lsa]->arg, ospf6_lsa_handler_name(handler), strlen(argv[idx_lsa]->arg)) == 0) - break; - if (! strcasecmp (argv[idx_lsa]->arg, handler->name)) - break; - handler = NULL; - } - - if (handler == NULL) - handler = &unknown_handler; - - if (argc == 5) - { - if (strmatch(argv[idx_type]->text, "originate")) - SET_FLAG (handler->debug, OSPF6_LSA_DEBUG_ORIGINATE); - else if (strmatch(argv[idx_type]->text, "examine")) - SET_FLAG (handler->debug, OSPF6_LSA_DEBUG_EXAMIN); - else if (strmatch(argv[idx_type]->text, "flooding")) - SET_FLAG (handler->debug, OSPF6_LSA_DEBUG_FLOOD); - } - else - SET_FLAG (handler->debug, OSPF6_LSA_DEBUG); - - return CMD_SUCCESS; + int idx_lsa = 3; + int idx_type = 4; + unsigned int i; + struct ospf6_lsa_handler *handler = NULL; + + for (i = 0; i < vector_active(ospf6_lsa_handler_vector); i++) { + handler = vector_slot(ospf6_lsa_handler_vector, i); + if (handler == NULL) + continue; + if (strncmp(argv[idx_lsa]->arg, ospf6_lsa_handler_name(handler), + strlen(argv[idx_lsa]->arg)) + == 0) + break; + if (!strcasecmp(argv[idx_lsa]->arg, handler->name)) + break; + handler = NULL; + } + + if (handler == NULL) + handler = &unknown_handler; + + if (argc == 5) { + if (strmatch(argv[idx_type]->text, "originate")) + SET_FLAG(handler->debug, OSPF6_LSA_DEBUG_ORIGINATE); + else if (strmatch(argv[idx_type]->text, "examine")) + SET_FLAG(handler->debug, OSPF6_LSA_DEBUG_EXAMIN); + else if (strmatch(argv[idx_type]->text, "flooding")) + SET_FLAG(handler->debug, OSPF6_LSA_DEBUG_FLOOD); + } else + SET_FLAG(handler->debug, OSPF6_LSA_DEBUG); + + return CMD_SUCCESS; } DEFUN (no_debug_ospf6_lsa_type, @@ -882,75 +830,69 @@ DEFUN (no_debug_ospf6_lsa_type, "Dump LSAs\n" "Display LSA's internal information\n") { - int idx_lsa = 4; - int idx_type = 5; - u_int i; - struct ospf6_lsa_handler *handler = NULL; - - for (i = 0; i < vector_active (ospf6_lsa_handler_vector); i++) - { - handler = vector_slot (ospf6_lsa_handler_vector, i); - if (handler == NULL) - continue; - if (strncmp (argv[idx_lsa]->arg, ospf6_lsa_handler_name(handler), strlen(argv[idx_lsa]->arg)) == 0) - break; - if (! strcasecmp (argv[idx_lsa]->arg, handler->name)) - break; - } - - if (handler == NULL) - return CMD_SUCCESS; - - if (argc == 6) - { - if (strmatch(argv[idx_type]->text, "originate")) - UNSET_FLAG (handler->debug, OSPF6_LSA_DEBUG_ORIGINATE); - if (strmatch(argv[idx_type]->text, "examine")) - UNSET_FLAG (handler->debug, OSPF6_LSA_DEBUG_EXAMIN); - if (strmatch(argv[idx_type]->text, "flooding")) - UNSET_FLAG (handler->debug, OSPF6_LSA_DEBUG_FLOOD); - } - else - UNSET_FLAG (handler->debug, OSPF6_LSA_DEBUG); - - return CMD_SUCCESS; -} - -void -install_element_ospf6_debug_lsa (void) -{ - install_element (ENABLE_NODE, &debug_ospf6_lsa_hex_cmd); - install_element (ENABLE_NODE, &no_debug_ospf6_lsa_hex_cmd); - install_element (CONFIG_NODE, &debug_ospf6_lsa_hex_cmd); - install_element (CONFIG_NODE, &no_debug_ospf6_lsa_hex_cmd); -} - -int -config_write_ospf6_debug_lsa (struct vty *vty) -{ - u_int i; - struct ospf6_lsa_handler *handler; - - for (i = 0; i < vector_active (ospf6_lsa_handler_vector); i++) - { - handler = vector_slot (ospf6_lsa_handler_vector, i); - if (handler == NULL) - continue; - if (CHECK_FLAG (handler->debug, OSPF6_LSA_DEBUG)) - vty_out (vty, "debug ospf6 lsa %s\n", - ospf6_lsa_handler_name (handler)); - if (CHECK_FLAG (handler->debug, OSPF6_LSA_DEBUG_ORIGINATE)) - vty_out (vty, "debug ospf6 lsa %s originate\n", - ospf6_lsa_handler_name (handler)); - if (CHECK_FLAG (handler->debug, OSPF6_LSA_DEBUG_EXAMIN)) - vty_out (vty, "debug ospf6 lsa %s examine\n", - ospf6_lsa_handler_name (handler)); - if (CHECK_FLAG (handler->debug, OSPF6_LSA_DEBUG_FLOOD)) - vty_out (vty, "debug ospf6 lsa %s flooding\n", - ospf6_lsa_handler_name (handler)); - } - - return 0; -} + int idx_lsa = 4; + int idx_type = 5; + u_int i; + struct ospf6_lsa_handler *handler = NULL; + + for (i = 0; i < vector_active(ospf6_lsa_handler_vector); i++) { + handler = vector_slot(ospf6_lsa_handler_vector, i); + if (handler == NULL) + continue; + if (strncmp(argv[idx_lsa]->arg, ospf6_lsa_handler_name(handler), + strlen(argv[idx_lsa]->arg)) + == 0) + break; + if (!strcasecmp(argv[idx_lsa]->arg, handler->name)) + break; + } + if (handler == NULL) + return CMD_SUCCESS; + + if (argc == 6) { + if (strmatch(argv[idx_type]->text, "originate")) + UNSET_FLAG(handler->debug, OSPF6_LSA_DEBUG_ORIGINATE); + if (strmatch(argv[idx_type]->text, "examine")) + UNSET_FLAG(handler->debug, OSPF6_LSA_DEBUG_EXAMIN); + if (strmatch(argv[idx_type]->text, "flooding")) + UNSET_FLAG(handler->debug, OSPF6_LSA_DEBUG_FLOOD); + } else + UNSET_FLAG(handler->debug, OSPF6_LSA_DEBUG); + + return CMD_SUCCESS; +} + +void install_element_ospf6_debug_lsa(void) +{ + install_element(ENABLE_NODE, &debug_ospf6_lsa_hex_cmd); + install_element(ENABLE_NODE, &no_debug_ospf6_lsa_hex_cmd); + install_element(CONFIG_NODE, &debug_ospf6_lsa_hex_cmd); + install_element(CONFIG_NODE, &no_debug_ospf6_lsa_hex_cmd); +} + +int config_write_ospf6_debug_lsa(struct vty *vty) +{ + u_int i; + struct ospf6_lsa_handler *handler; + + for (i = 0; i < vector_active(ospf6_lsa_handler_vector); i++) { + handler = vector_slot(ospf6_lsa_handler_vector, i); + if (handler == NULL) + continue; + if (CHECK_FLAG(handler->debug, OSPF6_LSA_DEBUG)) + vty_out(vty, "debug ospf6 lsa %s\n", + ospf6_lsa_handler_name(handler)); + if (CHECK_FLAG(handler->debug, OSPF6_LSA_DEBUG_ORIGINATE)) + vty_out(vty, "debug ospf6 lsa %s originate\n", + ospf6_lsa_handler_name(handler)); + if (CHECK_FLAG(handler->debug, OSPF6_LSA_DEBUG_EXAMIN)) + vty_out(vty, "debug ospf6 lsa %s examine\n", + ospf6_lsa_handler_name(handler)); + if (CHECK_FLAG(handler->debug, OSPF6_LSA_DEBUG_FLOOD)) + vty_out(vty, "debug ospf6 lsa %s flooding\n", + ospf6_lsa_handler_name(handler)); + } + return 0; +} diff --git a/ospf6d/ospf6_lsa.h b/ospf6d/ospf6_lsa.h index 36cf55986..ef63429fd 100644 --- a/ospf6d/ospf6_lsa.h +++ b/ospf6d/ospf6_lsa.h @@ -27,23 +27,22 @@ #define OSPF6_LSA_DEBUG_EXAMIN 0x04 #define OSPF6_LSA_DEBUG_FLOOD 0x08 -#define IS_OSPF6_DEBUG_LSA(name) \ - (ospf6_lstype_debug (htons (OSPF6_LSTYPE_ ## name)) & \ - OSPF6_LSA_DEBUG) -#define IS_OSPF6_DEBUG_ORIGINATE(name) \ - (ospf6_lstype_debug (htons (OSPF6_LSTYPE_ ## name)) & \ - OSPF6_LSA_DEBUG_ORIGINATE) -#define IS_OSPF6_DEBUG_EXAMIN(name) \ - (ospf6_lstype_debug (htons (OSPF6_LSTYPE_ ## name)) & \ - OSPF6_LSA_DEBUG_EXAMIN) -#define IS_OSPF6_DEBUG_LSA_TYPE(type) \ - (ospf6_lstype_debug (type) & OSPF6_LSA_DEBUG) -#define IS_OSPF6_DEBUG_ORIGINATE_TYPE(type) \ - (ospf6_lstype_debug (type) & OSPF6_LSA_DEBUG_ORIGINATE) -#define IS_OSPF6_DEBUG_EXAMIN_TYPE(type) \ - (ospf6_lstype_debug (type) & OSPF6_LSA_DEBUG_EXAMIN) -#define IS_OSPF6_DEBUG_FLOOD_TYPE(type) \ - (ospf6_lstype_debug (type) & OSPF6_LSA_DEBUG_FLOOD) +#define IS_OSPF6_DEBUG_LSA(name) \ + (ospf6_lstype_debug(htons(OSPF6_LSTYPE_##name)) & OSPF6_LSA_DEBUG) +#define IS_OSPF6_DEBUG_ORIGINATE(name) \ + (ospf6_lstype_debug(htons(OSPF6_LSTYPE_##name)) \ + & OSPF6_LSA_DEBUG_ORIGINATE) +#define IS_OSPF6_DEBUG_EXAMIN(name) \ + (ospf6_lstype_debug(htons(OSPF6_LSTYPE_##name)) \ + & OSPF6_LSA_DEBUG_EXAMIN) +#define IS_OSPF6_DEBUG_LSA_TYPE(type) \ + (ospf6_lstype_debug(type) & OSPF6_LSA_DEBUG) +#define IS_OSPF6_DEBUG_ORIGINATE_TYPE(type) \ + (ospf6_lstype_debug(type) & OSPF6_LSA_DEBUG_ORIGINATE) +#define IS_OSPF6_DEBUG_EXAMIN_TYPE(type) \ + (ospf6_lstype_debug(type) & OSPF6_LSA_DEBUG_EXAMIN) +#define IS_OSPF6_DEBUG_FLOOD_TYPE(type) \ + (ospf6_lstype_debug(type) & OSPF6_LSA_DEBUG_FLOOD) /* LSA definition */ @@ -74,66 +73,60 @@ #define OSPF6_SCOPE_RESERVED 0x6000 /* XXX U-bit handling should be treated here */ -#define OSPF6_LSA_SCOPE(type) \ - (ntohs (type) & OSPF6_LSTYPE_SCOPE_MASK) +#define OSPF6_LSA_SCOPE(type) (ntohs(type) & OSPF6_LSTYPE_SCOPE_MASK) /* LSA Header */ #define OSPF6_LSA_HEADER_SIZE 20U -struct ospf6_lsa_header -{ - u_int16_t age; /* LS age */ - u_int16_t type; /* LS type */ - u_int32_t id; /* Link State ID */ - u_int32_t adv_router; /* Advertising Router */ - u_int32_t seqnum; /* LS sequence number */ - u_int16_t checksum; /* LS checksum */ - u_int16_t length; /* LSA length */ +struct ospf6_lsa_header { + u_int16_t age; /* LS age */ + u_int16_t type; /* LS type */ + u_int32_t id; /* Link State ID */ + u_int32_t adv_router; /* Advertising Router */ + u_int32_t seqnum; /* LS sequence number */ + u_int16_t checksum; /* LS checksum */ + u_int16_t length; /* LSA length */ }; -#define OSPF6_LSA_HEADER_END(h) \ - ((caddr_t)(h) + sizeof (struct ospf6_lsa_header)) -#define OSPF6_LSA_SIZE(h) \ - (ntohs (((struct ospf6_lsa_header *) (h))->length)) -#define OSPF6_LSA_END(h) \ - ((caddr_t)(h) + ntohs (((struct ospf6_lsa_header *) (h))->length)) -#define OSPF6_LSA_IS_TYPE(t, L) \ - ((L)->header->type == htons (OSPF6_LSTYPE_ ## t) ? 1 : 0) -#define OSPF6_LSA_IS_SAME(L1, L2) \ - ((L1)->header->adv_router == (L2)->header->adv_router && \ - (L1)->header->id == (L2)->header->id && \ - (L1)->header->type == (L2)->header->type) -#define OSPF6_LSA_IS_MATCH(t, i, a, L) \ - ((L)->header->adv_router == (a) && (L)->header->id == (i) && \ - (L)->header->type == (t)) +#define OSPF6_LSA_HEADER_END(h) ((caddr_t)(h) + sizeof(struct ospf6_lsa_header)) +#define OSPF6_LSA_SIZE(h) (ntohs(((struct ospf6_lsa_header *)(h))->length)) +#define OSPF6_LSA_END(h) \ + ((caddr_t)(h) + ntohs(((struct ospf6_lsa_header *)(h))->length)) +#define OSPF6_LSA_IS_TYPE(t, L) \ + ((L)->header->type == htons(OSPF6_LSTYPE_##t) ? 1 : 0) +#define OSPF6_LSA_IS_SAME(L1, L2) \ + ((L1)->header->adv_router == (L2)->header->adv_router \ + && (L1)->header->id == (L2)->header->id \ + && (L1)->header->type == (L2)->header->type) +#define OSPF6_LSA_IS_MATCH(t, i, a, L) \ + ((L)->header->adv_router == (a) && (L)->header->id == (i) \ + && (L)->header->type == (t)) #define OSPF6_LSA_IS_DIFFER(L1, L2) ospf6_lsa_is_differ (L1, L2) #define OSPF6_LSA_IS_MAXAGE(L) (ospf6_lsa_age_current (L) == OSPF_LSA_MAXAGE) #define OSPF6_LSA_IS_CHANGED(L1, L2) ospf6_lsa_is_changed (L1, L2) #define OSPF6_LSA_IS_SEQWRAP(L) ((L)->header->seqnum == htonl(OSPF_MAX_SEQUENCE_NUMBER + 1)) +struct ospf6_lsa { + char name[64]; /* dump string */ -struct ospf6_lsa -{ - char name[64]; /* dump string */ + struct route_node *rn; - struct route_node *rn; + 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 originated; /* used by MinLSInterval check */ + struct timeval received; /* used by MinLSArrival check */ + struct timeval installed; - struct timeval birth; /* tv_sec when LS age 0 */ - struct timeval originated; /* used by MinLSInterval check */ - struct timeval received; /* used by MinLSArrival check */ - struct timeval installed; + struct thread *expire; + struct thread *refresh; /* For self-originated LSA */ - struct thread *expire; - struct thread *refresh; /* For self-originated LSA */ + int retrans_count; - int retrans_count; + struct ospf6_lsdb *lsdb; - struct ospf6_lsdb *lsdb; - - /* lsa instance */ - struct ospf6_lsa_header *header; + /* lsa instance */ + struct ospf6_lsa_header *header; }; #define OSPF6_LSA_HEADERONLY 0x01 @@ -143,119 +136,114 @@ struct ospf6_lsa #define OSPF6_LSA_UNAPPROVED 0x10 #define OSPF6_LSA_SEQWRAPPED 0x20 -struct ospf6_lsa_handler -{ - u_int16_t type; /* host byte order */ - const char *name; - const char *short_name; - int (*show) (struct vty *, struct ospf6_lsa *); - char *(*get_prefix_str) (struct ospf6_lsa *, char *buf, int buflen, int pos); - u_char debug; +struct ospf6_lsa_handler { + u_int16_t type; /* host byte order */ + const char *name; + const char *short_name; + int (*show)(struct vty *, struct ospf6_lsa *); + char *(*get_prefix_str)(struct ospf6_lsa *, char *buf, int buflen, + int pos); + u_char debug; }; extern struct ospf6_lsa_handler unknown_handler; -#define OSPF6_LSA_IS_KNOWN(type) \ - (ospf6_get_lsa_handler (type) != &unknown_handler ? 1 : 0) +#define OSPF6_LSA_IS_KNOWN(type) \ + (ospf6_get_lsa_handler(type) != &unknown_handler ? 1 : 0) extern vector ospf6_lsa_handler_vector; /* Macro for LSA Origination */ /* addr is (struct prefix *) */ -#define CONTINUE_IF_ADDRESS_LINKLOCAL(debug,addr) \ - if (IN6_IS_ADDR_LINKLOCAL (&(addr)->u.prefix6)) \ - { \ - char buf[PREFIX2STR_BUFFER]; \ - prefix2str (addr, buf, sizeof (buf)); \ - if (debug) \ - zlog_debug ("Filter out Linklocal: %s", buf); \ - continue; \ - } - -#define CONTINUE_IF_ADDRESS_UNSPECIFIED(debug,addr) \ - if (IN6_IS_ADDR_UNSPECIFIED (&(addr)->u.prefix6)) \ - { \ - char buf[PREFIX2STR_BUFFER]; \ - prefix2str (addr, buf, sizeof (buf)); \ - if (debug) \ - zlog_debug ("Filter out Unspecified: %s", buf);\ - continue; \ - } - -#define CONTINUE_IF_ADDRESS_LOOPBACK(debug,addr) \ - if (IN6_IS_ADDR_LOOPBACK (&(addr)->u.prefix6)) \ - { \ - char buf[PREFIX2STR_BUFFER]; \ - prefix2str (addr, buf, sizeof (buf)); \ - if (debug) \ - zlog_debug ("Filter out Loopback: %s", buf); \ - continue; \ - } - -#define CONTINUE_IF_ADDRESS_V4COMPAT(debug,addr) \ - if (IN6_IS_ADDR_V4COMPAT (&(addr)->u.prefix6)) \ - { \ - char buf[PREFIX2STR_BUFFER]; \ - prefix2str (addr, buf, sizeof (buf)); \ - if (debug) \ - zlog_debug ("Filter out V4Compat: %s", buf); \ - continue; \ - } - -#define CONTINUE_IF_ADDRESS_V4MAPPED(debug,addr) \ - if (IN6_IS_ADDR_V4MAPPED (&(addr)->u.prefix6)) \ - { \ - char buf[PREFIX2STR_BUFFER]; \ - prefix2str (addr, buf, sizeof (buf)); \ - if (debug) \ - zlog_debug ("Filter out V4Mapped: %s", buf); \ - continue; \ - } +#define CONTINUE_IF_ADDRESS_LINKLOCAL(debug, addr) \ + if (IN6_IS_ADDR_LINKLOCAL(&(addr)->u.prefix6)) { \ + char buf[PREFIX2STR_BUFFER]; \ + prefix2str(addr, buf, sizeof(buf)); \ + if (debug) \ + zlog_debug("Filter out Linklocal: %s", buf); \ + continue; \ + } + +#define CONTINUE_IF_ADDRESS_UNSPECIFIED(debug, addr) \ + if (IN6_IS_ADDR_UNSPECIFIED(&(addr)->u.prefix6)) { \ + char buf[PREFIX2STR_BUFFER]; \ + prefix2str(addr, buf, sizeof(buf)); \ + if (debug) \ + zlog_debug("Filter out Unspecified: %s", buf); \ + continue; \ + } + +#define CONTINUE_IF_ADDRESS_LOOPBACK(debug, addr) \ + if (IN6_IS_ADDR_LOOPBACK(&(addr)->u.prefix6)) { \ + char buf[PREFIX2STR_BUFFER]; \ + prefix2str(addr, buf, sizeof(buf)); \ + if (debug) \ + zlog_debug("Filter out Loopback: %s", buf); \ + continue; \ + } + +#define CONTINUE_IF_ADDRESS_V4COMPAT(debug, addr) \ + if (IN6_IS_ADDR_V4COMPAT(&(addr)->u.prefix6)) { \ + char buf[PREFIX2STR_BUFFER]; \ + prefix2str(addr, buf, sizeof(buf)); \ + if (debug) \ + zlog_debug("Filter out V4Compat: %s", buf); \ + continue; \ + } + +#define CONTINUE_IF_ADDRESS_V4MAPPED(debug, addr) \ + if (IN6_IS_ADDR_V4MAPPED(&(addr)->u.prefix6)) { \ + char buf[PREFIX2STR_BUFFER]; \ + prefix2str(addr, buf, sizeof(buf)); \ + if (debug) \ + zlog_debug("Filter out V4Mapped: %s", buf); \ + continue; \ + } /* Function Prototypes */ -extern const char *ospf6_lstype_name (u_int16_t type); -extern const char *ospf6_lstype_short_name (u_int16_t type); -extern u_char ospf6_lstype_debug (u_int16_t type); -extern int ospf6_lsa_is_differ (struct ospf6_lsa *lsa1, struct ospf6_lsa *lsa2); -extern int ospf6_lsa_is_changed (struct ospf6_lsa *lsa1, struct ospf6_lsa *lsa2); -extern u_int16_t ospf6_lsa_age_current (struct ospf6_lsa *); -extern void ospf6_lsa_age_update_to_send (struct ospf6_lsa *, u_int32_t); -extern void ospf6_lsa_premature_aging (struct ospf6_lsa *); -extern int ospf6_lsa_compare (struct ospf6_lsa *, struct ospf6_lsa *); - -extern char *ospf6_lsa_printbuf (struct ospf6_lsa *lsa, char *buf, int size); -extern void ospf6_lsa_header_print_raw (struct ospf6_lsa_header *header); -extern void ospf6_lsa_header_print (struct ospf6_lsa *lsa); -extern void ospf6_lsa_show_summary_header (struct vty *vty); -extern void ospf6_lsa_show_summary (struct vty *vty, struct ospf6_lsa *lsa); -extern void ospf6_lsa_show_dump (struct vty *vty, struct ospf6_lsa *lsa); -extern void ospf6_lsa_show_internal (struct vty *vty, struct ospf6_lsa *lsa); -extern void ospf6_lsa_show (struct vty *vty, struct ospf6_lsa *lsa); - -extern struct ospf6_lsa *ospf6_lsa_create (struct ospf6_lsa_header *header); -extern struct ospf6_lsa *ospf6_lsa_create_headeronly (struct ospf6_lsa_header *header); -extern void ospf6_lsa_delete (struct ospf6_lsa *lsa); -extern struct ospf6_lsa *ospf6_lsa_copy (struct ospf6_lsa *); - -extern void ospf6_lsa_lock (struct ospf6_lsa *); -extern void ospf6_lsa_unlock (struct ospf6_lsa *); - -extern int ospf6_lsa_expire (struct thread *); -extern int ospf6_lsa_refresh (struct thread *); - -extern unsigned short ospf6_lsa_checksum (struct ospf6_lsa_header *); -extern int ospf6_lsa_checksum_valid (struct ospf6_lsa_header *); -extern int ospf6_lsa_prohibited_duration (u_int16_t type, u_int32_t id, - u_int32_t adv_router, void *scope); - -extern void ospf6_install_lsa_handler (struct ospf6_lsa_handler *handler); -extern struct ospf6_lsa_handler *ospf6_get_lsa_handler (u_int16_t type); - -extern void ospf6_lsa_init (void); -extern void ospf6_lsa_terminate (void); - -extern int config_write_ospf6_debug_lsa (struct vty *vty); -extern void install_element_ospf6_debug_lsa (void); +extern const char *ospf6_lstype_name(u_int16_t type); +extern const char *ospf6_lstype_short_name(u_int16_t type); +extern u_char ospf6_lstype_debug(u_int16_t type); +extern int ospf6_lsa_is_differ(struct ospf6_lsa *lsa1, struct ospf6_lsa *lsa2); +extern int ospf6_lsa_is_changed(struct ospf6_lsa *lsa1, struct ospf6_lsa *lsa2); +extern u_int16_t ospf6_lsa_age_current(struct ospf6_lsa *); +extern void ospf6_lsa_age_update_to_send(struct ospf6_lsa *, u_int32_t); +extern void ospf6_lsa_premature_aging(struct ospf6_lsa *); +extern int ospf6_lsa_compare(struct ospf6_lsa *, struct ospf6_lsa *); + +extern char *ospf6_lsa_printbuf(struct ospf6_lsa *lsa, char *buf, int size); +extern void ospf6_lsa_header_print_raw(struct ospf6_lsa_header *header); +extern void ospf6_lsa_header_print(struct ospf6_lsa *lsa); +extern void ospf6_lsa_show_summary_header(struct vty *vty); +extern void ospf6_lsa_show_summary(struct vty *vty, struct ospf6_lsa *lsa); +extern void ospf6_lsa_show_dump(struct vty *vty, struct ospf6_lsa *lsa); +extern void ospf6_lsa_show_internal(struct vty *vty, struct ospf6_lsa *lsa); +extern void ospf6_lsa_show(struct vty *vty, struct ospf6_lsa *lsa); + +extern struct ospf6_lsa *ospf6_lsa_create(struct ospf6_lsa_header *header); +extern struct ospf6_lsa * +ospf6_lsa_create_headeronly(struct ospf6_lsa_header *header); +extern void ospf6_lsa_delete(struct ospf6_lsa *lsa); +extern struct ospf6_lsa *ospf6_lsa_copy(struct ospf6_lsa *); + +extern void ospf6_lsa_lock(struct ospf6_lsa *); +extern void ospf6_lsa_unlock(struct ospf6_lsa *); + +extern int ospf6_lsa_expire(struct thread *); +extern int ospf6_lsa_refresh(struct thread *); + +extern unsigned short ospf6_lsa_checksum(struct ospf6_lsa_header *); +extern int ospf6_lsa_checksum_valid(struct ospf6_lsa_header *); +extern int ospf6_lsa_prohibited_duration(u_int16_t type, u_int32_t id, + u_int32_t adv_router, void *scope); + +extern void ospf6_install_lsa_handler(struct ospf6_lsa_handler *handler); +extern struct ospf6_lsa_handler *ospf6_get_lsa_handler(u_int16_t type); + +extern void ospf6_lsa_init(void); +extern void ospf6_lsa_terminate(void); + +extern int config_write_ospf6_debug_lsa(struct vty *vty); +extern void install_element_ospf6_debug_lsa(void); #endif /* OSPF6_LSA_H */ - diff --git a/ospf6d/ospf6_lsdb.c b/ospf6d/ospf6_lsdb.c index ed0180065..23a33d312 100644 --- a/ospf6d/ospf6_lsdb.c +++ b/ospf6d/ospf6_lsdb.c @@ -34,454 +34,410 @@ #include "ospf6d.h" #include "bitfield.h" -struct ospf6_lsdb * -ospf6_lsdb_create (void *data) +struct ospf6_lsdb *ospf6_lsdb_create(void *data) { - struct ospf6_lsdb *lsdb; - - lsdb = XCALLOC (MTYPE_OSPF6_LSDB, sizeof (struct ospf6_lsdb)); - if (lsdb == NULL) - { - zlog_warn ("Can't malloc lsdb"); - return NULL; - } - memset (lsdb, 0, sizeof (struct ospf6_lsdb)); - - lsdb->data = data; - lsdb->table = route_table_init (); - return lsdb; + struct ospf6_lsdb *lsdb; + + lsdb = XCALLOC(MTYPE_OSPF6_LSDB, sizeof(struct ospf6_lsdb)); + if (lsdb == NULL) { + zlog_warn("Can't malloc lsdb"); + return NULL; + } + memset(lsdb, 0, sizeof(struct ospf6_lsdb)); + + lsdb->data = data; + lsdb->table = route_table_init(); + return lsdb; } -void -ospf6_lsdb_delete (struct ospf6_lsdb *lsdb) +void ospf6_lsdb_delete(struct ospf6_lsdb *lsdb) { - if (lsdb != NULL) - { - ospf6_lsdb_remove_all (lsdb); - route_table_finish (lsdb->table); - XFREE (MTYPE_OSPF6_LSDB, lsdb); - } + if (lsdb != NULL) { + ospf6_lsdb_remove_all(lsdb); + route_table_finish(lsdb->table); + XFREE(MTYPE_OSPF6_LSDB, lsdb); + } } -static void -ospf6_lsdb_set_key (struct prefix_ipv6 *key, const void *value, int len) +static void ospf6_lsdb_set_key(struct prefix_ipv6 *key, const void *value, + int len) { - assert (key->prefixlen % 8 == 0); + assert(key->prefixlen % 8 == 0); - memcpy ((caddr_t) &key->prefix + key->prefixlen / 8, - (caddr_t) value, len); - key->family = AF_INET6; - key->prefixlen += len * 8; + memcpy((caddr_t)&key->prefix + key->prefixlen / 8, (caddr_t)value, len); + key->family = AF_INET6; + key->prefixlen += len * 8; } #ifdef DEBUG -static void -_lsdb_count_assert (struct ospf6_lsdb *lsdb) +static void _lsdb_count_assert(struct ospf6_lsdb *lsdb) { - struct ospf6_lsa *debug; - unsigned int num = 0; - for (ALL_LSDB(lsdb, debug)) - num++; - - if (num == lsdb->count) - return; - - zlog_debug ("PANIC !! lsdb[%p]->count = %d, real = %d", - lsdb, lsdb->count, num); - for (ALL_LSDB(lsdb, debug)) - zlog_debug ("%p %p %s lsdb[%p]", debug->prev, debug->next, debug->name, - debug->lsdb); - zlog_debug ("DUMP END"); - - assert (num == lsdb->count); + struct ospf6_lsa *debug; + unsigned int num = 0; + for (ALL_LSDB(lsdb, debug)) + num++; + + if (num == lsdb->count) + return; + + zlog_debug("PANIC !! lsdb[%p]->count = %d, real = %d", lsdb, + lsdb->count, num); + for (ALL_LSDB(lsdb, debug)) + zlog_debug("%p %p %s lsdb[%p]", debug->prev, debug->next, + debug->name, debug->lsdb); + zlog_debug("DUMP END"); + + assert(num == lsdb->count); } #define ospf6_lsdb_count_assert(t) (_lsdb_count_assert (t)) -#else /*DEBUG*/ +#else /*DEBUG*/ #define ospf6_lsdb_count_assert(t) ((void) 0) #endif /*DEBUG*/ -void -ospf6_lsdb_add (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb) +void ospf6_lsdb_add(struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb) { - struct prefix_ipv6 key; - struct route_node *current; - struct ospf6_lsa *old = NULL; - - memset (&key, 0, sizeof (key)); - ospf6_lsdb_set_key (&key, &lsa->header->type, sizeof (lsa->header->type)); - ospf6_lsdb_set_key (&key, &lsa->header->adv_router, - sizeof (lsa->header->adv_router)); - ospf6_lsdb_set_key (&key, &lsa->header->id, sizeof (lsa->header->id)); - - current = route_node_get (lsdb->table, (struct prefix *) &key); - old = current->info; - current->info = lsa; - lsa->rn = current; - ospf6_lsa_lock (lsa); - - if (!old) - { - lsdb->count++; - - if (OSPF6_LSA_IS_MAXAGE (lsa)) - { - if (lsdb->hook_remove) - (*lsdb->hook_remove) (lsa); + struct prefix_ipv6 key; + struct route_node *current; + struct ospf6_lsa *old = NULL; + + memset(&key, 0, sizeof(key)); + ospf6_lsdb_set_key(&key, &lsa->header->type, sizeof(lsa->header->type)); + ospf6_lsdb_set_key(&key, &lsa->header->adv_router, + sizeof(lsa->header->adv_router)); + ospf6_lsdb_set_key(&key, &lsa->header->id, sizeof(lsa->header->id)); + + current = route_node_get(lsdb->table, (struct prefix *)&key); + old = current->info; + current->info = lsa; + lsa->rn = current; + ospf6_lsa_lock(lsa); + + if (!old) { + lsdb->count++; + + if (OSPF6_LSA_IS_MAXAGE(lsa)) { + if (lsdb->hook_remove) + (*lsdb->hook_remove)(lsa); + } else { + if (lsdb->hook_add) + (*lsdb->hook_add)(lsa); + } + } else { + if (OSPF6_LSA_IS_CHANGED(old, lsa)) { + if (OSPF6_LSA_IS_MAXAGE(lsa)) { + if (lsdb->hook_remove) { + (*lsdb->hook_remove)(old); + (*lsdb->hook_remove)(lsa); + } + } else if (OSPF6_LSA_IS_MAXAGE(old)) { + if (lsdb->hook_add) + (*lsdb->hook_add)(lsa); + } else { + if (lsdb->hook_remove) + (*lsdb->hook_remove)(old); + if (lsdb->hook_add) + (*lsdb->hook_add)(lsa); + } + } + ospf6_lsa_unlock(old); } - else - { - if (lsdb->hook_add) - (*lsdb->hook_add) (lsa); - } - } - else - { - if (OSPF6_LSA_IS_CHANGED (old, lsa)) - { - if (OSPF6_LSA_IS_MAXAGE (lsa)) - { - if (lsdb->hook_remove) - { - (*lsdb->hook_remove) (old); - (*lsdb->hook_remove) (lsa); - } - } - else if (OSPF6_LSA_IS_MAXAGE (old)) - { - if (lsdb->hook_add) - (*lsdb->hook_add) (lsa); - } - else - { - if (lsdb->hook_remove) - (*lsdb->hook_remove) (old); - if (lsdb->hook_add) - (*lsdb->hook_add) (lsa); - } - } - ospf6_lsa_unlock (old); - } - - ospf6_lsdb_count_assert (lsdb); + + ospf6_lsdb_count_assert(lsdb); } -void -ospf6_lsdb_remove (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb) +void ospf6_lsdb_remove(struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb) { - struct route_node *node; - struct prefix_ipv6 key; + struct route_node *node; + struct prefix_ipv6 key; - memset (&key, 0, sizeof (key)); - ospf6_lsdb_set_key (&key, &lsa->header->type, sizeof (lsa->header->type)); - ospf6_lsdb_set_key (&key, &lsa->header->adv_router, - sizeof (lsa->header->adv_router)); - ospf6_lsdb_set_key (&key, &lsa->header->id, sizeof (lsa->header->id)); + memset(&key, 0, sizeof(key)); + ospf6_lsdb_set_key(&key, &lsa->header->type, sizeof(lsa->header->type)); + ospf6_lsdb_set_key(&key, &lsa->header->adv_router, + sizeof(lsa->header->adv_router)); + ospf6_lsdb_set_key(&key, &lsa->header->id, sizeof(lsa->header->id)); - node = route_node_lookup (lsdb->table, (struct prefix *) &key); - assert (node && node->info == lsa); + node = route_node_lookup(lsdb->table, (struct prefix *)&key); + assert(node && node->info == lsa); - node->info = NULL; - lsdb->count--; + node->info = NULL; + lsdb->count--; - if (lsdb->hook_remove) - (*lsdb->hook_remove) (lsa); + if (lsdb->hook_remove) + (*lsdb->hook_remove)(lsa); - route_unlock_node (node); /* to free the lookup lock */ - route_unlock_node (node); /* to free the original lock */ - ospf6_lsa_unlock (lsa); + route_unlock_node(node); /* to free the lookup lock */ + route_unlock_node(node); /* to free the original lock */ + ospf6_lsa_unlock(lsa); - ospf6_lsdb_count_assert (lsdb); + ospf6_lsdb_count_assert(lsdb); } -struct ospf6_lsa * -ospf6_lsdb_lookup (u_int16_t type, u_int32_t id, u_int32_t adv_router, - struct ospf6_lsdb *lsdb) +struct ospf6_lsa *ospf6_lsdb_lookup(u_int16_t type, u_int32_t id, + u_int32_t adv_router, + struct ospf6_lsdb *lsdb) { - struct route_node *node; - struct prefix_ipv6 key; + struct route_node *node; + struct prefix_ipv6 key; - if (lsdb == NULL) - return NULL; + if (lsdb == NULL) + return NULL; - memset (&key, 0, sizeof (key)); - ospf6_lsdb_set_key (&key, &type, sizeof (type)); - ospf6_lsdb_set_key (&key, &adv_router, sizeof (adv_router)); - ospf6_lsdb_set_key (&key, &id, sizeof (id)); + memset(&key, 0, sizeof(key)); + ospf6_lsdb_set_key(&key, &type, sizeof(type)); + ospf6_lsdb_set_key(&key, &adv_router, sizeof(adv_router)); + ospf6_lsdb_set_key(&key, &id, sizeof(id)); - node = route_node_lookup (lsdb->table, (struct prefix *) &key); - if (node == NULL || node->info == NULL) - return NULL; + node = route_node_lookup(lsdb->table, (struct prefix *)&key); + if (node == NULL || node->info == NULL) + return NULL; - route_unlock_node (node); - return (struct ospf6_lsa *) node->info; + route_unlock_node(node); + return (struct ospf6_lsa *)node->info; } -struct ospf6_lsa * -ospf6_lsdb_lookup_next (u_int16_t type, u_int32_t id, u_int32_t adv_router, - struct ospf6_lsdb *lsdb) +struct ospf6_lsa *ospf6_lsdb_lookup_next(u_int16_t type, u_int32_t id, + u_int32_t adv_router, + struct ospf6_lsdb *lsdb) { - struct route_node *node; - struct prefix_ipv6 key; + struct route_node *node; + struct prefix_ipv6 key; - if (lsdb == NULL) - return NULL; + if (lsdb == NULL) + return NULL; - memset (&key, 0, sizeof (key)); - ospf6_lsdb_set_key (&key, &type, sizeof (type)); - ospf6_lsdb_set_key (&key, &adv_router, sizeof (adv_router)); - ospf6_lsdb_set_key (&key, &id, sizeof (id)); + memset(&key, 0, sizeof(key)); + ospf6_lsdb_set_key(&key, &type, sizeof(type)); + ospf6_lsdb_set_key(&key, &adv_router, sizeof(adv_router)); + ospf6_lsdb_set_key(&key, &id, sizeof(id)); - { - char buf[PREFIX2STR_BUFFER]; - prefix2str (&key, buf, sizeof (buf)); - zlog_debug ("lsdb_lookup_next: key: %s", buf); - } + { + char buf[PREFIX2STR_BUFFER]; + prefix2str(&key, buf, sizeof(buf)); + zlog_debug("lsdb_lookup_next: key: %s", buf); + } - node = route_table_get_next (lsdb->table, &key); + node = route_table_get_next(lsdb->table, &key); - /* skip to real existing entry */ - while (node && node->info == NULL) - node = route_next (node); + /* skip to real existing entry */ + while (node && node->info == NULL) + node = route_next(node); - if (! node) - return NULL; + if (!node) + return NULL; - route_unlock_node (node); - if (! node->info) - return NULL; + route_unlock_node(node); + if (!node->info) + return NULL; - return (struct ospf6_lsa *) node->info; + return (struct ospf6_lsa *)node->info; } -const struct route_node * -ospf6_lsdb_head (struct ospf6_lsdb *lsdb, - int argmode, uint16_t type, uint32_t adv_router, - struct ospf6_lsa **lsa) +const struct route_node *ospf6_lsdb_head(struct ospf6_lsdb *lsdb, int argmode, + uint16_t type, uint32_t adv_router, + struct ospf6_lsa **lsa) { - struct route_node *node, *end; - - *lsa = NULL; - - if (argmode > 0) - { - struct prefix_ipv6 key = { .family = AF_INET6, .prefixlen = 0 }; - - ospf6_lsdb_set_key (&key, &type, sizeof (type)); - if (argmode > 1) - ospf6_lsdb_set_key (&key, &adv_router, sizeof (adv_router)); - - node = route_table_get_next (lsdb->table, &key); - if (!node || !prefix_match((struct prefix *)&key, &node->p)) - return NULL; - - for (end = node; - end && end->parent && end->parent->p.prefixlen >= key.prefixlen; - end = end->parent) - ; - } - else - { - node = route_top (lsdb->table); - end = NULL; - } - - while (node && !node->info) - node = route_next_until(node, end); - - if (!node) - return NULL; - if (!node->info) - { - route_unlock_node(node); - return NULL; - } - - *lsa = node->info; - ospf6_lsa_lock (*lsa); - - return end; + struct route_node *node, *end; + + *lsa = NULL; + + if (argmode > 0) { + struct prefix_ipv6 key = {.family = AF_INET6, .prefixlen = 0}; + + ospf6_lsdb_set_key(&key, &type, sizeof(type)); + if (argmode > 1) + ospf6_lsdb_set_key(&key, &adv_router, + sizeof(adv_router)); + + node = route_table_get_next(lsdb->table, &key); + if (!node || !prefix_match((struct prefix *)&key, &node->p)) + return NULL; + + for (end = node; end && end->parent + && end->parent->p.prefixlen >= key.prefixlen; + end = end->parent) + ; + } else { + node = route_top(lsdb->table); + end = NULL; + } + + while (node && !node->info) + node = route_next_until(node, end); + + if (!node) + return NULL; + if (!node->info) { + route_unlock_node(node); + return NULL; + } + + *lsa = node->info; + ospf6_lsa_lock(*lsa); + + return end; } -struct ospf6_lsa * -ospf6_lsdb_next (const struct route_node *iterend, - struct ospf6_lsa *lsa) +struct ospf6_lsa *ospf6_lsdb_next(const struct route_node *iterend, + struct ospf6_lsa *lsa) { - struct route_node *node = lsa->rn; + struct route_node *node = lsa->rn; - ospf6_lsa_unlock(lsa); + ospf6_lsa_unlock(lsa); - do - node = route_next_until(node, iterend); - while (node && !node->info); + do + node = route_next_until(node, iterend); + while (node && !node->info); - if (node && node->info) - { - struct ospf6_lsa *next = node->info; - ospf6_lsa_lock (next); - return next; - } + if (node && node->info) { + struct ospf6_lsa *next = node->info; + ospf6_lsa_lock(next); + return next; + } - if (node) - route_unlock_node (node); - return NULL; + if (node) + route_unlock_node(node); + return NULL; } -void -ospf6_lsdb_remove_all (struct ospf6_lsdb *lsdb) +void ospf6_lsdb_remove_all(struct ospf6_lsdb *lsdb) { - struct ospf6_lsa *lsa; + struct ospf6_lsa *lsa; - if (lsdb == NULL) - return; + if (lsdb == NULL) + return; - for (ALL_LSDB(lsdb, lsa)) - ospf6_lsdb_remove (lsa, lsdb); + for (ALL_LSDB(lsdb, lsa)) + ospf6_lsdb_remove(lsa, lsdb); } -void -ospf6_lsdb_lsa_unlock (struct ospf6_lsa *lsa) +void ospf6_lsdb_lsa_unlock(struct ospf6_lsa *lsa) { - if (lsa != NULL) - { - if (lsa->rn != NULL) - route_unlock_node (lsa->rn); - ospf6_lsa_unlock (lsa); - } + if (lsa != NULL) { + if (lsa->rn != NULL) + route_unlock_node(lsa->rn); + ospf6_lsa_unlock(lsa); + } } -int -ospf6_lsdb_maxage_remover (struct ospf6_lsdb *lsdb) +int ospf6_lsdb_maxage_remover(struct ospf6_lsdb *lsdb) { - int reschedule = 0; - struct ospf6_lsa *lsa; - - for (ALL_LSDB(lsdb, lsa)) - { - if (! OSPF6_LSA_IS_MAXAGE (lsa)) - continue; - if (lsa->retrans_count != 0) - { - reschedule = 1; - continue; + int reschedule = 0; + struct ospf6_lsa *lsa; + + for (ALL_LSDB(lsdb, lsa)) { + if (!OSPF6_LSA_IS_MAXAGE(lsa)) + continue; + if (lsa->retrans_count != 0) { + reschedule = 1; + continue; + } + if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type)) + zlog_debug("Remove MaxAge %s", lsa->name); + if (CHECK_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED)) { + UNSET_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED); + /* + * lsa->header->age = 0; + */ + lsa->header->seqnum = + htonl(OSPF_MAX_SEQUENCE_NUMBER + 1); + ospf6_lsa_checksum(lsa->header); + + THREAD_OFF(lsa->refresh); + thread_execute(master, ospf6_lsa_refresh, lsa, 0); + } else { + ospf6_lsdb_remove(lsa, lsdb); + } } - if (IS_OSPF6_DEBUG_LSA_TYPE (lsa->header->type)) - zlog_debug ("Remove MaxAge %s", lsa->name); - if (CHECK_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED)) - { - UNSET_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED); - /* - * lsa->header->age = 0; - */ - lsa->header->seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER + 1); - ospf6_lsa_checksum (lsa->header); - - THREAD_OFF(lsa->refresh); - thread_execute (master, ospf6_lsa_refresh, lsa, 0); - } else { - ospf6_lsdb_remove (lsa, lsdb); - } - } - - return (reschedule); + + return (reschedule); } -void -ospf6_lsdb_show (struct vty *vty, enum ospf_lsdb_show_level level, - u_int16_t *type, u_int32_t *id, u_int32_t *adv_router, - struct ospf6_lsdb *lsdb) +void ospf6_lsdb_show(struct vty *vty, enum ospf_lsdb_show_level level, + u_int16_t *type, u_int32_t *id, u_int32_t *adv_router, + struct ospf6_lsdb *lsdb) { - struct ospf6_lsa *lsa; - const struct route_node *end = NULL; - void (*showfunc) (struct vty *, struct ospf6_lsa *) = NULL; - - switch (level) - { - case OSPF6_LSDB_SHOW_LEVEL_DETAIL: - showfunc = ospf6_lsa_show; - break; - case OSPF6_LSDB_SHOW_LEVEL_INTERNAL: - showfunc = ospf6_lsa_show_internal; - break; - case OSPF6_LSDB_SHOW_LEVEL_DUMP: - showfunc = ospf6_lsa_show_dump; - break; - case OSPF6_LSDB_SHOW_LEVEL_NORMAL: - default: - showfunc = ospf6_lsa_show_summary; - } - - if (type && id && adv_router) - { - lsa = ospf6_lsdb_lookup (*type, *id, *adv_router, lsdb); - if (lsa) - { - if (level == OSPF6_LSDB_SHOW_LEVEL_NORMAL) - ospf6_lsa_show (vty, lsa); - else - (*showfunc) (vty, lsa); - } - return; - } - - if (level == OSPF6_LSDB_SHOW_LEVEL_NORMAL) - ospf6_lsa_show_summary_header (vty); - - end = ospf6_lsdb_head(lsdb, !!type + !!(type && adv_router), - *type, *adv_router, &lsa); - while (lsa) - { - if ((! adv_router || lsa->header->adv_router == *adv_router) && - (! id || lsa->header->id == *id)) - (*showfunc) (vty, lsa); - - lsa = ospf6_lsdb_next (end, lsa); - } + struct ospf6_lsa *lsa; + const struct route_node *end = NULL; + void (*showfunc)(struct vty *, struct ospf6_lsa *) = NULL; + + switch (level) { + case OSPF6_LSDB_SHOW_LEVEL_DETAIL: + showfunc = ospf6_lsa_show; + break; + case OSPF6_LSDB_SHOW_LEVEL_INTERNAL: + showfunc = ospf6_lsa_show_internal; + break; + case OSPF6_LSDB_SHOW_LEVEL_DUMP: + showfunc = ospf6_lsa_show_dump; + break; + case OSPF6_LSDB_SHOW_LEVEL_NORMAL: + default: + showfunc = ospf6_lsa_show_summary; + } + + if (type && id && adv_router) { + lsa = ospf6_lsdb_lookup(*type, *id, *adv_router, lsdb); + if (lsa) { + if (level == OSPF6_LSDB_SHOW_LEVEL_NORMAL) + ospf6_lsa_show(vty, lsa); + else + (*showfunc)(vty, lsa); + } + return; + } + + if (level == OSPF6_LSDB_SHOW_LEVEL_NORMAL) + ospf6_lsa_show_summary_header(vty); + + end = ospf6_lsdb_head(lsdb, !!type + !!(type && adv_router), *type, + *adv_router, &lsa); + while (lsa) { + if ((!adv_router || lsa->header->adv_router == *adv_router) + && (!id || lsa->header->id == *id)) + (*showfunc)(vty, lsa); + + lsa = ospf6_lsdb_next(end, lsa); + } } -u_int32_t -ospf6_new_ls_id (u_int16_t type, u_int32_t adv_router, - struct ospf6_lsdb *lsdb) +u_int32_t ospf6_new_ls_id(u_int16_t type, u_int32_t adv_router, + struct ospf6_lsdb *lsdb) { - struct ospf6_lsa *lsa; - u_int32_t id = 1, tmp_id; - - /* This routine is curently invoked only for Inter-Prefix LSAs for - * non-summarized routes (no area/range). - */ - for (ALL_LSDB_TYPED_ADVRTR(lsdb, type, adv_router, lsa)) - { - tmp_id = ntohl (lsa->header->id); - if (tmp_id < id) - continue; - - if (tmp_id > id) - { - ospf6_lsdb_lsa_unlock (lsa); - break; - } - id++; - } - - return ((u_int32_t) htonl (id)); + struct ospf6_lsa *lsa; + u_int32_t id = 1, tmp_id; + + /* This routine is curently invoked only for Inter-Prefix LSAs for + * non-summarized routes (no area/range). + */ + for (ALL_LSDB_TYPED_ADVRTR(lsdb, type, adv_router, lsa)) { + tmp_id = ntohl(lsa->header->id); + if (tmp_id < id) + continue; + + if (tmp_id > id) { + ospf6_lsdb_lsa_unlock(lsa); + break; + } + id++; + } + + return ((u_int32_t)htonl(id)); } /* Decide new LS sequence number to originate. note return value is network byte order */ -u_int32_t -ospf6_new_ls_seqnum (u_int16_t type, u_int32_t id, u_int32_t adv_router, - struct ospf6_lsdb *lsdb) +u_int32_t ospf6_new_ls_seqnum(u_int16_t type, u_int32_t id, + u_int32_t adv_router, struct ospf6_lsdb *lsdb) { - struct ospf6_lsa *lsa; - signed long seqnum = 0; + struct ospf6_lsa *lsa; + signed long seqnum = 0; - /* if current database copy not found, return InitialSequenceNumber */ - lsa = ospf6_lsdb_lookup (type, id, adv_router, lsdb); - if (lsa == NULL) - seqnum = OSPF_INITIAL_SEQUENCE_NUMBER; - else - seqnum = (signed long) ntohl (lsa->header->seqnum) + 1; + /* if current database copy not found, return InitialSequenceNumber */ + lsa = ospf6_lsdb_lookup(type, id, adv_router, lsdb); + if (lsa == NULL) + seqnum = OSPF_INITIAL_SEQUENCE_NUMBER; + else + seqnum = (signed long)ntohl(lsa->header->seqnum) + 1; - return ((u_int32_t) htonl (seqnum)); + return ((u_int32_t)htonl(seqnum)); } - - diff --git a/ospf6d/ospf6_lsdb.h b/ospf6d/ospf6_lsdb.h index 0eb5322b4..41e54b5d8 100644 --- a/ospf6d/ospf6_lsdb.h +++ b/ospf6d/ospf6_lsdb.h @@ -25,76 +25,72 @@ #include "table.h" #include "ospf6_route.h" -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 *); - void (*hook_remove) (struct ospf6_lsa *); +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 *); + void (*hook_remove)(struct ospf6_lsa *); }; /* Function Prototypes */ -extern struct ospf6_lsdb *ospf6_lsdb_create (void *data); -extern void ospf6_lsdb_delete (struct ospf6_lsdb *lsdb); +extern struct ospf6_lsdb *ospf6_lsdb_create(void *data); +extern void ospf6_lsdb_delete(struct ospf6_lsdb *lsdb); -extern struct ospf6_lsa *ospf6_lsdb_lookup (u_int16_t type, u_int32_t id, - u_int32_t adv_router, - struct ospf6_lsdb *lsdb); -extern struct ospf6_lsa *ospf6_lsdb_lookup_next (u_int16_t type, u_int32_t id, - u_int32_t adv_router, - struct ospf6_lsdb *lsdb); +extern struct ospf6_lsa *ospf6_lsdb_lookup(u_int16_t type, u_int32_t id, + u_int32_t adv_router, + struct ospf6_lsdb *lsdb); +extern struct ospf6_lsa *ospf6_lsdb_lookup_next(u_int16_t type, u_int32_t id, + u_int32_t adv_router, + struct ospf6_lsdb *lsdb); -extern void ospf6_lsdb_add (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb); -extern void ospf6_lsdb_remove (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb); +extern void ospf6_lsdb_add(struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb); +extern void ospf6_lsdb_remove(struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb); -extern const struct route_node *ospf6_lsdb_head ( - struct ospf6_lsdb *lsdb, - int argmode, - uint16_t type, - uint32_t adv_router, - struct ospf6_lsa **lsa); -extern struct ospf6_lsa *ospf6_lsdb_next (const struct route_node *iterend, - struct ospf6_lsa *lsa); +extern const struct route_node *ospf6_lsdb_head(struct ospf6_lsdb *lsdb, + int argmode, uint16_t type, + uint32_t adv_router, + struct ospf6_lsa **lsa); +extern struct ospf6_lsa *ospf6_lsdb_next(const struct route_node *iterend, + struct ospf6_lsa *lsa); -#define ALL_LSDB_TYPED_ADVRTR(lsdb, type, adv_router, lsa) \ - const struct route_node *iterend = \ - ospf6_lsdb_head(lsdb, 2, type, adv_router, &lsa); \ - lsa; \ +#define ALL_LSDB_TYPED_ADVRTR(lsdb, type, adv_router, lsa) \ + const struct route_node *iterend = \ + ospf6_lsdb_head(lsdb, 2, type, adv_router, &lsa); \ + lsa; \ lsa = ospf6_lsdb_next(iterend, lsa) -#define ALL_LSDB_TYPED(lsdb, type, lsa) \ - const struct route_node *iterend = \ - ospf6_lsdb_head(lsdb, 1, type, 0, &lsa); \ - lsa; \ +#define ALL_LSDB_TYPED(lsdb, type, lsa) \ + const struct route_node *iterend = \ + ospf6_lsdb_head(lsdb, 1, type, 0, &lsa); \ + lsa; \ lsa = ospf6_lsdb_next(iterend, lsa) -#define ALL_LSDB(lsdb, lsa) \ - const struct route_node *iterend = \ - ospf6_lsdb_head(lsdb, 0, 0, 0, &lsa); \ - lsa; \ +#define ALL_LSDB(lsdb, lsa) \ + const struct route_node *iterend = \ + ospf6_lsdb_head(lsdb, 0, 0, 0, &lsa); \ + lsa; \ lsa = ospf6_lsdb_next(iterend, lsa) -extern void ospf6_lsdb_remove_all (struct ospf6_lsdb *lsdb); -extern void ospf6_lsdb_lsa_unlock (struct ospf6_lsa *lsa); +extern void ospf6_lsdb_remove_all(struct ospf6_lsdb *lsdb); +extern void ospf6_lsdb_lsa_unlock(struct ospf6_lsa *lsa); enum ospf_lsdb_show_level { - OSPF6_LSDB_SHOW_LEVEL_NORMAL = 0, - OSPF6_LSDB_SHOW_LEVEL_DETAIL, - OSPF6_LSDB_SHOW_LEVEL_INTERNAL, - OSPF6_LSDB_SHOW_LEVEL_DUMP, + OSPF6_LSDB_SHOW_LEVEL_NORMAL = 0, + OSPF6_LSDB_SHOW_LEVEL_DETAIL, + OSPF6_LSDB_SHOW_LEVEL_INTERNAL, + OSPF6_LSDB_SHOW_LEVEL_DUMP, }; -extern void ospf6_lsdb_show (struct vty *vty, - enum ospf_lsdb_show_level level, u_int16_t *type, - u_int32_t *id, u_int32_t *adv_router, - struct ospf6_lsdb *lsdb); +extern void ospf6_lsdb_show(struct vty *vty, enum ospf_lsdb_show_level level, + u_int16_t *type, u_int32_t *id, + u_int32_t *adv_router, struct ospf6_lsdb *lsdb); -extern u_int32_t ospf6_new_ls_id (u_int16_t type, u_int32_t adv_router, - struct ospf6_lsdb *lsdb); -extern u_int32_t ospf6_new_ls_seqnum (u_int16_t type, u_int32_t id, - u_int32_t adv_router, - struct ospf6_lsdb *lsdb); -extern int ospf6_lsdb_maxage_remover (struct ospf6_lsdb *lsdb); +extern u_int32_t ospf6_new_ls_id(u_int16_t type, u_int32_t adv_router, + struct ospf6_lsdb *lsdb); +extern u_int32_t ospf6_new_ls_seqnum(u_int16_t type, u_int32_t id, + u_int32_t adv_router, + struct ospf6_lsdb *lsdb); +extern int ospf6_lsdb_maxage_remover(struct ospf6_lsdb *lsdb); #endif /* OSPF6_LSDB_H */ diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c index 0a4a3a28c..28bb956c4 100644 --- a/ospf6d/ospf6_main.c +++ b/ospf6d/ospf6_main.c @@ -55,187 +55,163 @@ #define OSPF6_VTY_PORT 2606 /* ospf6d privileges */ -zebra_capabilities_t _caps_p [] = -{ - ZCAP_NET_RAW, - ZCAP_BIND -}; +zebra_capabilities_t _caps_p[] = {ZCAP_NET_RAW, ZCAP_BIND}; -struct zebra_privs_t ospf6d_privs = -{ +struct zebra_privs_t ospf6d_privs = { #if defined(FRR_USER) - .user = FRR_USER, + .user = FRR_USER, #endif #if defined FRR_GROUP - .group = FRR_GROUP, + .group = FRR_GROUP, #endif #ifdef VTY_GROUP - .vty_group = VTY_GROUP, + .vty_group = VTY_GROUP, #endif - .caps_p = _caps_p, - .cap_num_p = 2, - .cap_num_i = 0 -}; + .caps_p = _caps_p, + .cap_num_p = 2, + .cap_num_i = 0}; /* ospf6d options, we use GNU getopt library. */ -struct option longopts[] = -{ - { 0 } -}; +struct option longopts[] = {{0}}; /* Master of threads. */ struct thread_master *master; -static void __attribute__ ((noreturn)) -ospf6_exit (int status) +static void __attribute__((noreturn)) ospf6_exit(int status) { - struct listnode *node; - struct interface *ifp; + struct listnode *node; + struct interface *ifp; - if (ospf6) - ospf6_delete (ospf6); + if (ospf6) + ospf6_delete(ospf6); - bfd_gbl_exit(); + bfd_gbl_exit(); - for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) - if (ifp->info != NULL) - ospf6_interface_delete(ifp->info); + for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) + if (ifp->info != NULL) + ospf6_interface_delete(ifp->info); - ospf6_message_terminate (); - ospf6_asbr_terminate (); - ospf6_lsa_terminate (); + ospf6_message_terminate(); + ospf6_asbr_terminate(); + ospf6_lsa_terminate(); - vrf_terminate (); - vty_terminate (); - cmd_terminate (); + vrf_terminate(); + vty_terminate(); + cmd_terminate(); - if (zclient) - { - zclient_stop (zclient); - zclient_free (zclient); - } + if (zclient) { + zclient_stop(zclient); + zclient_free(zclient); + } - if (master) - thread_master_free (master); + if (master) + thread_master_free(master); - closezlog (); + closezlog(); - exit (status); + exit(status); } /* SIGHUP handler. */ -static void -sighup (void) +static void sighup(void) { - zlog_info ("SIGHUP received"); + zlog_info("SIGHUP received"); } /* SIGINT handler. */ -static void -sigint (void) +static void sigint(void) { - zlog_notice ("Terminating on signal SIGINT"); - ospf6_exit (0); + zlog_notice("Terminating on signal SIGINT"); + ospf6_exit(0); } /* SIGTERM handler. */ -static void -sigterm (void) +static void sigterm(void) { - zlog_notice ("Terminating on signal SIGTERM"); - ospf6_clean(); - ospf6_exit (0); + zlog_notice("Terminating on signal SIGTERM"); + ospf6_clean(); + ospf6_exit(0); } /* SIGUSR1 handler. */ -static void -sigusr1 (void) +static void sigusr1(void) { - zlog_info ("SIGUSR1 received"); - zlog_rotate(); + zlog_info("SIGUSR1 received"); + zlog_rotate(); } -struct quagga_signal_t ospf6_signals[] = -{ - { - .signal = SIGHUP, - .handler = &sighup, - }, - { - .signal = SIGINT, - .handler = &sigint, - }, - { - .signal = SIGTERM, - .handler = &sigterm, - }, - { - .signal = SIGUSR1, - .handler = &sigusr1, - }, +struct quagga_signal_t ospf6_signals[] = { + { + .signal = SIGHUP, + .handler = &sighup, + }, + { + .signal = SIGINT, + .handler = &sigint, + }, + { + .signal = SIGTERM, + .handler = &sigterm, + }, + { + .signal = SIGUSR1, + .handler = &sigusr1, + }, }; -FRR_DAEMON_INFO(ospf6d, OSPF6, - .vty_port = OSPF6_VTY_PORT, +FRR_DAEMON_INFO(ospf6d, OSPF6, .vty_port = OSPF6_VTY_PORT, - .proghelp = "Implementation of the OSPFv3 routing protocol.", + .proghelp = "Implementation of the OSPFv3 routing protocol.", - .signals = ospf6_signals, - .n_signals = array_size(ospf6_signals), + .signals = ospf6_signals, + .n_signals = array_size(ospf6_signals), - .privs = &ospf6d_privs, -) + .privs = &ospf6d_privs, ) /* Main routine of ospf6d. Treatment of argument and starting ospf finite state machine is handled here. */ -int -main (int argc, char *argv[], char *envp[]) +int main(int argc, char *argv[], char *envp[]) { - int opt; - - frr_preinit (&ospf6d_di, argc, argv); - frr_opt_add ("", longopts, ""); - - /* Command line argument treatment. */ - while (1) - { - opt = frr_getopt (argc, argv, NULL); - - if (opt == EOF) - break; - - switch (opt) - { - case 0: - break; - default: - frr_help_exit (1); - break; - } - } - - if (geteuid () != 0) - { - errno = EPERM; - perror (ospf6d_di.progname); - exit (1); - } - - /* thread master */ - master = frr_init (); - - vrf_init (NULL, NULL, NULL, NULL); - access_list_init (); - prefix_list_init (); - - /* initialize ospf6 */ - ospf6_init (); - - frr_config_fork (); - frr_run (master); - - /* Not reached. */ - ospf6_exit (0); -} + int opt; + + frr_preinit(&ospf6d_di, argc, argv); + frr_opt_add("", longopts, ""); + /* Command line argument treatment. */ + while (1) { + opt = frr_getopt(argc, argv, NULL); + if (opt == EOF) + break; + + switch (opt) { + case 0: + break; + default: + frr_help_exit(1); + break; + } + } + + if (geteuid() != 0) { + errno = EPERM; + perror(ospf6d_di.progname); + exit(1); + } + + /* thread master */ + master = frr_init(); + + vrf_init(NULL, NULL, NULL, NULL); + access_list_init(); + prefix_list_init(); + + /* initialize ospf6 */ + ospf6_init(); + + frr_config_fork(); + frr_run(master); + + /* Not reached. */ + ospf6_exit(0); +} diff --git a/ospf6d/ospf6_memory.c b/ospf6d/ospf6_memory.c index 35d03f7e4..133dc2cb3 100644 --- a/ospf6d/ospf6_memory.c +++ b/ospf6d/ospf6_memory.c @@ -26,18 +26,18 @@ #include "ospf6_memory.h" DEFINE_MGROUP(OSPF6D, "ospf6d") -DEFINE_MTYPE(OSPF6D, OSPF6_TOP, "OSPF6 top") -DEFINE_MTYPE(OSPF6D, OSPF6_AREA, "OSPF6 area") -DEFINE_MTYPE(OSPF6D, OSPF6_IF, "OSPF6 interface") -DEFINE_MTYPE(OSPF6D, OSPF6_NEIGHBOR, "OSPF6 neighbor") -DEFINE_MTYPE(OSPF6D, OSPF6_ROUTE, "OSPF6 route") -DEFINE_MTYPE(OSPF6D, OSPF6_PREFIX, "OSPF6 prefix") -DEFINE_MTYPE(OSPF6D, OSPF6_MESSAGE, "OSPF6 message") -DEFINE_MTYPE(OSPF6D, OSPF6_LSA, "OSPF6 LSA") -DEFINE_MTYPE(OSPF6D, OSPF6_LSA_SUMMARY, "OSPF6 LSA summary") -DEFINE_MTYPE(OSPF6D, OSPF6_LSDB, "OSPF6 LSA database") -DEFINE_MTYPE(OSPF6D, OSPF6_VERTEX, "OSPF6 vertex") -DEFINE_MTYPE(OSPF6D, OSPF6_SPFTREE, "OSPF6 SPF tree") -DEFINE_MTYPE(OSPF6D, OSPF6_NEXTHOP, "OSPF6 nexthop") -DEFINE_MTYPE(OSPF6D, OSPF6_EXTERNAL_INFO,"OSPF6 ext. info") -DEFINE_MTYPE(OSPF6D, OSPF6_OTHER, "OSPF6 other") +DEFINE_MTYPE(OSPF6D, OSPF6_TOP, "OSPF6 top") +DEFINE_MTYPE(OSPF6D, OSPF6_AREA, "OSPF6 area") +DEFINE_MTYPE(OSPF6D, OSPF6_IF, "OSPF6 interface") +DEFINE_MTYPE(OSPF6D, OSPF6_NEIGHBOR, "OSPF6 neighbor") +DEFINE_MTYPE(OSPF6D, OSPF6_ROUTE, "OSPF6 route") +DEFINE_MTYPE(OSPF6D, OSPF6_PREFIX, "OSPF6 prefix") +DEFINE_MTYPE(OSPF6D, OSPF6_MESSAGE, "OSPF6 message") +DEFINE_MTYPE(OSPF6D, OSPF6_LSA, "OSPF6 LSA") +DEFINE_MTYPE(OSPF6D, OSPF6_LSA_SUMMARY, "OSPF6 LSA summary") +DEFINE_MTYPE(OSPF6D, OSPF6_LSDB, "OSPF6 LSA database") +DEFINE_MTYPE(OSPF6D, OSPF6_VERTEX, "OSPF6 vertex") +DEFINE_MTYPE(OSPF6D, OSPF6_SPFTREE, "OSPF6 SPF tree") +DEFINE_MTYPE(OSPF6D, OSPF6_NEXTHOP, "OSPF6 nexthop") +DEFINE_MTYPE(OSPF6D, OSPF6_EXTERNAL_INFO, "OSPF6 ext. info") +DEFINE_MTYPE(OSPF6D, OSPF6_OTHER, "OSPF6 other") diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index 583ba2a02..aa5f05ce1 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -49,897 +49,872 @@ #include <netinet/ip6.h> unsigned char conf_debug_ospf6_message[6] = {0x03, 0, 0, 0, 0, 0}; -static const struct message ospf6_message_type_str [] = -{ - { OSPF6_MESSAGE_TYPE_HELLO, "Hello" }, - { OSPF6_MESSAGE_TYPE_DBDESC, "DbDesc" }, - { OSPF6_MESSAGE_TYPE_LSREQ, "LSReq" }, - { OSPF6_MESSAGE_TYPE_LSUPDATE, "LSUpdate" }, - { OSPF6_MESSAGE_TYPE_LSACK, "LSAck" }, - { 0 } -}; +static const struct message ospf6_message_type_str[] = { + {OSPF6_MESSAGE_TYPE_HELLO, "Hello"}, + {OSPF6_MESSAGE_TYPE_DBDESC, "DbDesc"}, + {OSPF6_MESSAGE_TYPE_LSREQ, "LSReq"}, + {OSPF6_MESSAGE_TYPE_LSUPDATE, "LSUpdate"}, + {OSPF6_MESSAGE_TYPE_LSACK, "LSAck"}, + {0}}; /* Minimum (besides the standard OSPF packet header) lengths for OSPF packets of particular types, offset is the "type" field. */ -const u_int16_t ospf6_packet_minlen[OSPF6_MESSAGE_TYPE_ALL] = -{ - 0, - OSPF6_HELLO_MIN_SIZE, - OSPF6_DB_DESC_MIN_SIZE, - OSPF6_LS_REQ_MIN_SIZE, - OSPF6_LS_UPD_MIN_SIZE, - OSPF6_LS_ACK_MIN_SIZE -}; +const u_int16_t ospf6_packet_minlen[OSPF6_MESSAGE_TYPE_ALL] = { + 0, + OSPF6_HELLO_MIN_SIZE, + OSPF6_DB_DESC_MIN_SIZE, + OSPF6_LS_REQ_MIN_SIZE, + OSPF6_LS_UPD_MIN_SIZE, + OSPF6_LS_ACK_MIN_SIZE}; /* Minimum (besides the standard LSA header) lengths for LSAs of particular types, offset is the "LSA function code" portion of "LSA type" field. */ -const u_int16_t ospf6_lsa_minlen[OSPF6_LSTYPE_SIZE] = -{ - 0, - /* 0x2001 */ OSPF6_ROUTER_LSA_MIN_SIZE, - /* 0x2002 */ OSPF6_NETWORK_LSA_MIN_SIZE, - /* 0x2003 */ OSPF6_INTER_PREFIX_LSA_MIN_SIZE, - /* 0x2004 */ OSPF6_INTER_ROUTER_LSA_FIX_SIZE, - /* 0x4005 */ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE, - /* 0x2006 */ 0, - /* 0x2007 */ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE, - /* 0x0008 */ OSPF6_LINK_LSA_MIN_SIZE, - /* 0x2009 */ OSPF6_INTRA_PREFIX_LSA_MIN_SIZE -}; +const u_int16_t ospf6_lsa_minlen[OSPF6_LSTYPE_SIZE] = { + 0, + /* 0x2001 */ OSPF6_ROUTER_LSA_MIN_SIZE, + /* 0x2002 */ OSPF6_NETWORK_LSA_MIN_SIZE, + /* 0x2003 */ OSPF6_INTER_PREFIX_LSA_MIN_SIZE, + /* 0x2004 */ OSPF6_INTER_ROUTER_LSA_FIX_SIZE, + /* 0x4005 */ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE, + /* 0x2006 */ 0, + /* 0x2007 */ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE, + /* 0x0008 */ OSPF6_LINK_LSA_MIN_SIZE, + /* 0x2009 */ OSPF6_INTRA_PREFIX_LSA_MIN_SIZE}; /* print functions */ -static void -ospf6_header_print (struct ospf6_header *oh) +static void ospf6_header_print(struct ospf6_header *oh) { - char router_id[16], area_id[16]; - inet_ntop (AF_INET, &oh->router_id, router_id, sizeof (router_id)); - inet_ntop (AF_INET, &oh->area_id, area_id, sizeof (area_id)); - - zlog_debug (" OSPFv%d Type:%d Len:%hu Router-ID:%s", - oh->version, oh->type, ntohs (oh->length), router_id); - zlog_debug (" Area-ID:%s Cksum:%hx Instance-ID:%d", - area_id, ntohs (oh->checksum), oh->instance_id); + char router_id[16], area_id[16]; + inet_ntop(AF_INET, &oh->router_id, router_id, sizeof(router_id)); + inet_ntop(AF_INET, &oh->area_id, area_id, sizeof(area_id)); + + zlog_debug(" OSPFv%d Type:%d Len:%hu Router-ID:%s", oh->version, + oh->type, ntohs(oh->length), router_id); + zlog_debug(" Area-ID:%s Cksum:%hx Instance-ID:%d", area_id, + ntohs(oh->checksum), oh->instance_id); } -void -ospf6_hello_print (struct ospf6_header *oh) +void ospf6_hello_print(struct ospf6_header *oh) { - struct ospf6_hello *hello; - char options[16]; - char drouter[16], bdrouter[16], neighbor[16]; - char *p; - - ospf6_header_print (oh); - assert (oh->type == OSPF6_MESSAGE_TYPE_HELLO); - - hello = (struct ospf6_hello *) - ((caddr_t) oh + sizeof (struct ospf6_header)); - - inet_ntop (AF_INET, &hello->drouter, drouter, sizeof (drouter)); - inet_ntop (AF_INET, &hello->bdrouter, bdrouter, sizeof (bdrouter)); - ospf6_options_printbuf (hello->options, options, sizeof (options)); - - zlog_debug (" I/F-Id:%ld Priority:%d Option:%s", - (u_long) ntohl (hello->interface_id), hello->priority, options); - zlog_debug (" HelloInterval:%hu DeadInterval:%hu", - ntohs (hello->hello_interval), ntohs (hello->dead_interval)); - zlog_debug (" DR:%s BDR:%s", drouter, bdrouter); - - for (p = (char *) ((caddr_t) hello + sizeof (struct ospf6_hello)); - p + sizeof (u_int32_t) <= OSPF6_MESSAGE_END (oh); - p += sizeof (u_int32_t)) - { - inet_ntop (AF_INET, (void *) p, neighbor, sizeof (neighbor)); - zlog_debug (" Neighbor: %s", neighbor); - } - - assert (p == OSPF6_MESSAGE_END (oh)); + struct ospf6_hello *hello; + char options[16]; + char drouter[16], bdrouter[16], neighbor[16]; + char *p; + + ospf6_header_print(oh); + assert(oh->type == OSPF6_MESSAGE_TYPE_HELLO); + + hello = (struct ospf6_hello *)((caddr_t)oh + + sizeof(struct ospf6_header)); + + inet_ntop(AF_INET, &hello->drouter, drouter, sizeof(drouter)); + inet_ntop(AF_INET, &hello->bdrouter, bdrouter, sizeof(bdrouter)); + ospf6_options_printbuf(hello->options, options, sizeof(options)); + + zlog_debug(" I/F-Id:%ld Priority:%d Option:%s", + (u_long)ntohl(hello->interface_id), hello->priority, + options); + zlog_debug(" HelloInterval:%hu DeadInterval:%hu", + ntohs(hello->hello_interval), ntohs(hello->dead_interval)); + zlog_debug(" DR:%s BDR:%s", drouter, bdrouter); + + for (p = (char *)((caddr_t)hello + sizeof(struct ospf6_hello)); + p + sizeof(u_int32_t) <= OSPF6_MESSAGE_END(oh); + p += sizeof(u_int32_t)) { + inet_ntop(AF_INET, (void *)p, neighbor, sizeof(neighbor)); + zlog_debug(" Neighbor: %s", neighbor); + } + + assert(p == OSPF6_MESSAGE_END(oh)); } -void -ospf6_dbdesc_print (struct ospf6_header *oh) +void ospf6_dbdesc_print(struct ospf6_header *oh) { - struct ospf6_dbdesc *dbdesc; - char options[16]; - char *p; + struct ospf6_dbdesc *dbdesc; + char options[16]; + char *p; - ospf6_header_print (oh); - assert (oh->type == OSPF6_MESSAGE_TYPE_DBDESC); + ospf6_header_print(oh); + assert(oh->type == OSPF6_MESSAGE_TYPE_DBDESC); - dbdesc = (struct ospf6_dbdesc *) - ((caddr_t) oh + sizeof (struct ospf6_header)); + dbdesc = (struct ospf6_dbdesc *)((caddr_t)oh + + sizeof(struct ospf6_header)); - ospf6_options_printbuf (dbdesc->options, options, sizeof (options)); + ospf6_options_printbuf(dbdesc->options, options, sizeof(options)); - zlog_debug (" MBZ: %#x Option: %s IfMTU: %hu", - dbdesc->reserved1, options, ntohs (dbdesc->ifmtu)); - zlog_debug (" MBZ: %#x Bits: %s%s%s SeqNum: %#lx", - dbdesc->reserved2, - (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) ? "I" : "-"), - (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) ? "M" : "-"), - (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) ? "m" : "s"), - (u_long) ntohl (dbdesc->seqnum)); + zlog_debug(" MBZ: %#x Option: %s IfMTU: %hu", dbdesc->reserved1, + options, ntohs(dbdesc->ifmtu)); + zlog_debug(" MBZ: %#x Bits: %s%s%s SeqNum: %#lx", dbdesc->reserved2, + (CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_IBIT) ? "I" : "-"), + (CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MBIT) ? "M" : "-"), + (CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MSBIT) ? "m" : "s"), + (u_long)ntohl(dbdesc->seqnum)); - for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc)); - p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh); - p += sizeof (struct ospf6_lsa_header)) - ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p); + for (p = (char *)((caddr_t)dbdesc + sizeof(struct ospf6_dbdesc)); + p + sizeof(struct ospf6_lsa_header) <= OSPF6_MESSAGE_END(oh); + p += sizeof(struct ospf6_lsa_header)) + ospf6_lsa_header_print_raw((struct ospf6_lsa_header *)p); - assert (p == OSPF6_MESSAGE_END (oh)); + assert(p == OSPF6_MESSAGE_END(oh)); } -void -ospf6_lsreq_print (struct ospf6_header *oh) +void ospf6_lsreq_print(struct ospf6_header *oh) { - char id[16], adv_router[16]; - char *p; - - ospf6_header_print (oh); - assert (oh->type == OSPF6_MESSAGE_TYPE_LSREQ); - - for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header)); - p + sizeof (struct ospf6_lsreq_entry) <= OSPF6_MESSAGE_END (oh); - p += sizeof (struct ospf6_lsreq_entry)) - { - struct ospf6_lsreq_entry *e = (struct ospf6_lsreq_entry *) p; - inet_ntop (AF_INET, &e->adv_router, adv_router, sizeof (adv_router)); - inet_ntop (AF_INET, &e->id, id, sizeof (id)); - zlog_debug (" [%s Id:%s Adv:%s]", - ospf6_lstype_name (e->type), id, adv_router); - } - - assert (p == OSPF6_MESSAGE_END (oh)); + char id[16], adv_router[16]; + char *p; + + ospf6_header_print(oh); + assert(oh->type == OSPF6_MESSAGE_TYPE_LSREQ); + + for (p = (char *)((caddr_t)oh + sizeof(struct ospf6_header)); + p + sizeof(struct ospf6_lsreq_entry) <= OSPF6_MESSAGE_END(oh); + p += sizeof(struct ospf6_lsreq_entry)) { + struct ospf6_lsreq_entry *e = (struct ospf6_lsreq_entry *)p; + inet_ntop(AF_INET, &e->adv_router, adv_router, + sizeof(adv_router)); + inet_ntop(AF_INET, &e->id, id, sizeof(id)); + zlog_debug(" [%s Id:%s Adv:%s]", ospf6_lstype_name(e->type), + id, adv_router); + } + + assert(p == OSPF6_MESSAGE_END(oh)); } -void -ospf6_lsupdate_print (struct ospf6_header *oh) +void ospf6_lsupdate_print(struct ospf6_header *oh) { - struct ospf6_lsupdate *lsupdate; - u_long num; - char *p; + struct ospf6_lsupdate *lsupdate; + u_long num; + char *p; - ospf6_header_print (oh); - assert (oh->type == OSPF6_MESSAGE_TYPE_LSUPDATE); + ospf6_header_print(oh); + assert(oh->type == OSPF6_MESSAGE_TYPE_LSUPDATE); - lsupdate = (struct ospf6_lsupdate *) - ((caddr_t) oh + sizeof (struct ospf6_header)); + lsupdate = (struct ospf6_lsupdate *)((caddr_t)oh + + sizeof(struct ospf6_header)); - num = ntohl (lsupdate->lsa_number); - zlog_debug (" Number of LSA: %ld", num); + num = ntohl(lsupdate->lsa_number); + zlog_debug(" Number of LSA: %ld", num); - for (p = (char *) ((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate)); - p < OSPF6_MESSAGE_END (oh) && - p + OSPF6_LSA_SIZE (p) <= OSPF6_MESSAGE_END (oh); - p += OSPF6_LSA_SIZE (p)) - { - ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p); - } + for (p = (char *)((caddr_t)lsupdate + sizeof(struct ospf6_lsupdate)); + p < OSPF6_MESSAGE_END(oh) + && p + OSPF6_LSA_SIZE(p) <= OSPF6_MESSAGE_END(oh); + p += OSPF6_LSA_SIZE(p)) { + ospf6_lsa_header_print_raw((struct ospf6_lsa_header *)p); + } - assert (p == OSPF6_MESSAGE_END (oh)); + assert(p == OSPF6_MESSAGE_END(oh)); } -void -ospf6_lsack_print (struct ospf6_header *oh) +void ospf6_lsack_print(struct ospf6_header *oh) { - char *p; + char *p; - ospf6_header_print (oh); - assert (oh->type == OSPF6_MESSAGE_TYPE_LSACK); + ospf6_header_print(oh); + assert(oh->type == OSPF6_MESSAGE_TYPE_LSACK); - for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header)); - p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh); - p += sizeof (struct ospf6_lsa_header)) - ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p); + for (p = (char *)((caddr_t)oh + sizeof(struct ospf6_header)); + p + sizeof(struct ospf6_lsa_header) <= OSPF6_MESSAGE_END(oh); + p += sizeof(struct ospf6_lsa_header)) + ospf6_lsa_header_print_raw((struct ospf6_lsa_header *)p); - assert (p == OSPF6_MESSAGE_END (oh)); + assert(p == OSPF6_MESSAGE_END(oh)); } -static void -ospf6_hello_recv (struct in6_addr *src, struct in6_addr *dst, - struct ospf6_interface *oi, struct ospf6_header *oh) +static void ospf6_hello_recv(struct in6_addr *src, struct in6_addr *dst, + struct ospf6_interface *oi, + struct ospf6_header *oh) { - struct ospf6_hello *hello; - struct ospf6_neighbor *on; - char *p; - int twoway = 0; - int neighborchange = 0; - int neighbor_ifindex_change = 0; - int backupseen = 0; - - hello = (struct ospf6_hello *) - ((caddr_t) oh + sizeof (struct ospf6_header)); - - /* HelloInterval check */ - if (ntohs (hello->hello_interval) != oi->hello_interval) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("HelloInterval mismatch"); - return; - } - - /* RouterDeadInterval check */ - if (ntohs (hello->dead_interval) != oi->dead_interval) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("RouterDeadInterval mismatch"); - return; - } - - /* E-bit check */ - if (OSPF6_OPT_ISSET (hello->options, OSPF6_OPT_E) != - OSPF6_OPT_ISSET (oi->area->options, OSPF6_OPT_E)) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("E-bit mismatch"); - return; - } - - /* Find neighbor, create if not exist */ - on = ospf6_neighbor_lookup (oh->router_id, oi); - if (on == NULL) - { - on = ospf6_neighbor_create (oh->router_id, oi); - on->prev_drouter = on->drouter = hello->drouter; - on->prev_bdrouter = on->bdrouter = hello->bdrouter; - on->priority = hello->priority; - } - - /* Always override neighbor's source address */ - memcpy (&on->linklocal_addr, src, sizeof (struct in6_addr)); - - /* Neighbor ifindex check */ - if (on->ifindex != (ifindex_t)ntohl (hello->interface_id)) - { - on->ifindex = ntohl (hello->interface_id); - neighbor_ifindex_change++; - } - - /* TwoWay check */ - for (p = (char *) ((caddr_t) hello + sizeof (struct ospf6_hello)); - p + sizeof (u_int32_t) <= OSPF6_MESSAGE_END (oh); - p += sizeof (u_int32_t)) - { - u_int32_t *router_id = (u_int32_t *) p; - - if (*router_id == oi->area->ospf6->router_id) - twoway++; - } - - assert (p == OSPF6_MESSAGE_END (oh)); - - /* RouterPriority check */ - if (on->priority != hello->priority) - { - on->priority = hello->priority; - neighborchange++; - } - - /* DR check */ - if (on->drouter != hello->drouter) - { - on->prev_drouter = on->drouter; - on->drouter = hello->drouter; - if (on->prev_drouter == on->router_id || on->drouter == on->router_id) - neighborchange++; - } - - /* BDR check */ - if (on->bdrouter != hello->bdrouter) - { - on->prev_bdrouter = on->bdrouter; - on->bdrouter = hello->bdrouter; - if (on->prev_bdrouter == on->router_id || on->bdrouter == on->router_id) - neighborchange++; - } - - /* BackupSeen check */ - if (oi->state == OSPF6_INTERFACE_WAITING) - { - if (hello->bdrouter == on->router_id) - backupseen++; - else if (hello->drouter == on->router_id && hello->bdrouter == htonl (0)) - backupseen++; - } - - /* Execute neighbor events */ - thread_execute (master, hello_received, on, 0); - if (twoway) - thread_execute (master, twoway_received, on, 0); - else - thread_execute (master, oneway_received, on, 0); - - /* Schedule interface events */ - if (backupseen) - thread_add_event (master, backup_seen, oi, 0, NULL); - if (neighborchange) - thread_add_event (master, neighbor_change, oi, 0, NULL); - - if (neighbor_ifindex_change && on->state == OSPF6_NEIGHBOR_FULL) - OSPF6_ROUTER_LSA_SCHEDULE (oi->area); + struct ospf6_hello *hello; + struct ospf6_neighbor *on; + char *p; + int twoway = 0; + int neighborchange = 0; + int neighbor_ifindex_change = 0; + int backupseen = 0; + + hello = (struct ospf6_hello *)((caddr_t)oh + + sizeof(struct ospf6_header)); + + /* HelloInterval check */ + if (ntohs(hello->hello_interval) != oi->hello_interval) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("HelloInterval mismatch"); + return; + } + + /* RouterDeadInterval check */ + if (ntohs(hello->dead_interval) != oi->dead_interval) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("RouterDeadInterval mismatch"); + return; + } + + /* E-bit check */ + if (OSPF6_OPT_ISSET(hello->options, OSPF6_OPT_E) + != OSPF6_OPT_ISSET(oi->area->options, OSPF6_OPT_E)) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("E-bit mismatch"); + return; + } + + /* Find neighbor, create if not exist */ + on = ospf6_neighbor_lookup(oh->router_id, oi); + if (on == NULL) { + on = ospf6_neighbor_create(oh->router_id, oi); + on->prev_drouter = on->drouter = hello->drouter; + on->prev_bdrouter = on->bdrouter = hello->bdrouter; + on->priority = hello->priority; + } + + /* Always override neighbor's source address */ + memcpy(&on->linklocal_addr, src, sizeof(struct in6_addr)); + + /* Neighbor ifindex check */ + if (on->ifindex != (ifindex_t)ntohl(hello->interface_id)) { + on->ifindex = ntohl(hello->interface_id); + neighbor_ifindex_change++; + } + + /* TwoWay check */ + for (p = (char *)((caddr_t)hello + sizeof(struct ospf6_hello)); + p + sizeof(u_int32_t) <= OSPF6_MESSAGE_END(oh); + p += sizeof(u_int32_t)) { + u_int32_t *router_id = (u_int32_t *)p; + + if (*router_id == oi->area->ospf6->router_id) + twoway++; + } + + assert(p == OSPF6_MESSAGE_END(oh)); + + /* RouterPriority check */ + if (on->priority != hello->priority) { + on->priority = hello->priority; + neighborchange++; + } + + /* DR check */ + if (on->drouter != hello->drouter) { + on->prev_drouter = on->drouter; + on->drouter = hello->drouter; + if (on->prev_drouter == on->router_id + || on->drouter == on->router_id) + neighborchange++; + } + + /* BDR check */ + if (on->bdrouter != hello->bdrouter) { + on->prev_bdrouter = on->bdrouter; + on->bdrouter = hello->bdrouter; + if (on->prev_bdrouter == on->router_id + || on->bdrouter == on->router_id) + neighborchange++; + } + + /* BackupSeen check */ + if (oi->state == OSPF6_INTERFACE_WAITING) { + if (hello->bdrouter == on->router_id) + backupseen++; + else if (hello->drouter == on->router_id + && hello->bdrouter == htonl(0)) + backupseen++; + } + + /* Execute neighbor events */ + thread_execute(master, hello_received, on, 0); + if (twoway) + thread_execute(master, twoway_received, on, 0); + else + thread_execute(master, oneway_received, on, 0); + + /* Schedule interface events */ + if (backupseen) + thread_add_event(master, backup_seen, oi, 0, NULL); + if (neighborchange) + thread_add_event(master, neighbor_change, oi, 0, NULL); + + if (neighbor_ifindex_change && on->state == OSPF6_NEIGHBOR_FULL) + OSPF6_ROUTER_LSA_SCHEDULE(oi->area); } -static void -ospf6_dbdesc_recv_master (struct ospf6_header *oh, - struct ospf6_neighbor *on) +static void ospf6_dbdesc_recv_master(struct ospf6_header *oh, + struct ospf6_neighbor *on) { - struct ospf6_dbdesc *dbdesc; - char *p; - - dbdesc = (struct ospf6_dbdesc *) - ((caddr_t) oh + sizeof (struct ospf6_header)); - - if (on->state < OSPF6_NEIGHBOR_INIT) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Neighbor state less than Init, ignore"); - return; - } - - switch (on->state) - { - case OSPF6_NEIGHBOR_TWOWAY: - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Neighbor state is 2-Way, ignore"); - return; - - case OSPF6_NEIGHBOR_INIT: - thread_execute (master, twoway_received, on, 0); - if (on->state != OSPF6_NEIGHBOR_EXSTART) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Neighbor state is not ExStart, ignore"); - return; - } - /* else fall through to ExStart */ - /* fallthru */ - case OSPF6_NEIGHBOR_EXSTART: - /* if neighbor obeys us as our slave, schedule negotiation_done - and process LSA Headers. Otherwise, ignore this message */ - if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) && - ! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) && - ntohl (dbdesc->seqnum) == on->dbdesc_seqnum) - { - /* execute NegotiationDone */ - thread_execute (master, negotiation_done, on, 0); - - /* Record neighbor options */ - memcpy (on->options, dbdesc->options, sizeof (on->options)); - } - else - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Negotiation failed"); - return; - } - /* fall through to exchange */ - - case OSPF6_NEIGHBOR_EXCHANGE: - if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc))) - { - /* Duplicated DatabaseDescription is dropped by master */ - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Duplicated dbdesc discarded by Master, ignore"); - return; - } - - if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT)) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Master/Slave bit mismatch"); - thread_add_event (master, seqnumber_mismatch, on, 0, NULL); - return; - } - - if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT)) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Initialize bit mismatch"); - thread_add_event (master, seqnumber_mismatch, on, 0, NULL); - return; - } - - if (memcmp (on->options, dbdesc->options, sizeof (on->options))) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Option field mismatch"); - thread_add_event (master, seqnumber_mismatch, on, 0, NULL); - return; - } - - if (ntohl (dbdesc->seqnum) != on->dbdesc_seqnum) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Sequence number mismatch (%#lx expected)", - (u_long) on->dbdesc_seqnum); - thread_add_event (master, seqnumber_mismatch, on, 0, NULL); - return; - } - break; - - case OSPF6_NEIGHBOR_LOADING: - case OSPF6_NEIGHBOR_FULL: - if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc))) - { - /* Duplicated DatabaseDescription is dropped by master */ - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Duplicated dbdesc discarded by Master, ignore"); - return; - } - - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Not duplicate dbdesc in state %s", - ospf6_neighbor_state_str[on->state]); - thread_add_event (master, seqnumber_mismatch, on, 0, NULL); - return; - - default: - assert (0); - break; - } - - /* Process LSA headers */ - for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc)); - p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh); - p += sizeof (struct ospf6_lsa_header)) - { - struct ospf6_lsa *his, *mine; - struct ospf6_lsdb *lsdb = NULL; - - his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p); - - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("%s", his->name); - - 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_debug ("Ignoring LSA of reserved scope"); - ospf6_lsa_delete (his); - continue; - break; - } - - if (ntohs (his->header->type) == OSPF6_LSTYPE_AS_EXTERNAL && - IS_AREA_STUB (on->ospf6_if->area)) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("SeqNumMismatch (E-bit mismatch), discard"); - ospf6_lsa_delete (his); - thread_add_event (master, seqnumber_mismatch, on, 0, NULL); - return; - } - - mine = ospf6_lsdb_lookup (his->header->type, his->header->id, - his->header->adv_router, lsdb); - if (mine == NULL) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Add request (No database copy)"); - ospf6_lsdb_add (ospf6_lsa_copy(his), on->request_list); - } - else if (ospf6_lsa_compare (his, mine) < 0) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Add request (Received MoreRecent)"); - ospf6_lsdb_add (ospf6_lsa_copy(his), on->request_list); - } - else - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Discard (Existing MoreRecent)"); - } - ospf6_lsa_delete (his); - } - - assert (p == OSPF6_MESSAGE_END (oh)); - - /* Increment sequence number */ - on->dbdesc_seqnum ++; - - /* schedule send lsreq */ - if (on->request_list->count) - thread_add_event (master, ospf6_lsreq_send, on, 0, &on->thread_send_lsreq); - - THREAD_OFF (on->thread_send_dbdesc); - - /* More bit check */ - if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) && - ! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT)) - thread_add_event (master, exchange_done, on, 0, NULL); - else { - on->thread_send_dbdesc = NULL; - thread_add_event(master, ospf6_dbdesc_send_newone, on, 0, - &on->thread_send_dbdesc); - } - - /* save last received dbdesc */ - memcpy (&on->dbdesc_last, dbdesc, sizeof (struct ospf6_dbdesc)); + struct ospf6_dbdesc *dbdesc; + char *p; + + dbdesc = (struct ospf6_dbdesc *)((caddr_t)oh + + sizeof(struct ospf6_header)); + + if (on->state < OSPF6_NEIGHBOR_INIT) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Neighbor state less than Init, ignore"); + return; + } + + switch (on->state) { + case OSPF6_NEIGHBOR_TWOWAY: + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Neighbor state is 2-Way, ignore"); + return; + + case OSPF6_NEIGHBOR_INIT: + thread_execute(master, twoway_received, on, 0); + if (on->state != OSPF6_NEIGHBOR_EXSTART) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug( + "Neighbor state is not ExStart, ignore"); + return; + } + /* else fall through to ExStart */ + /* fallthru */ + case OSPF6_NEIGHBOR_EXSTART: + /* if neighbor obeys us as our slave, schedule negotiation_done + and process LSA Headers. Otherwise, ignore this message */ + if (!CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MSBIT) + && !CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_IBIT) + && ntohl(dbdesc->seqnum) == on->dbdesc_seqnum) { + /* execute NegotiationDone */ + thread_execute(master, negotiation_done, on, 0); + + /* Record neighbor options */ + memcpy(on->options, dbdesc->options, + sizeof(on->options)); + } else { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Negotiation failed"); + return; + } + /* fall through to exchange */ + + case OSPF6_NEIGHBOR_EXCHANGE: + if (!memcmp(dbdesc, &on->dbdesc_last, + sizeof(struct ospf6_dbdesc))) { + /* Duplicated DatabaseDescription is dropped by master + */ + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug( + "Duplicated dbdesc discarded by Master, ignore"); + return; + } + + if (CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MSBIT)) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Master/Slave bit mismatch"); + thread_add_event(master, seqnumber_mismatch, on, 0, + NULL); + return; + } + + if (CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_IBIT)) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Initialize bit mismatch"); + thread_add_event(master, seqnumber_mismatch, on, 0, + NULL); + return; + } + + if (memcmp(on->options, dbdesc->options, sizeof(on->options))) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Option field mismatch"); + thread_add_event(master, seqnumber_mismatch, on, 0, + NULL); + return; + } + + if (ntohl(dbdesc->seqnum) != on->dbdesc_seqnum) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug( + "Sequence number mismatch (%#lx expected)", + (u_long)on->dbdesc_seqnum); + thread_add_event(master, seqnumber_mismatch, on, 0, + NULL); + return; + } + break; + + case OSPF6_NEIGHBOR_LOADING: + case OSPF6_NEIGHBOR_FULL: + if (!memcmp(dbdesc, &on->dbdesc_last, + sizeof(struct ospf6_dbdesc))) { + /* Duplicated DatabaseDescription is dropped by master + */ + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug( + "Duplicated dbdesc discarded by Master, ignore"); + return; + } + + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Not duplicate dbdesc in state %s", + ospf6_neighbor_state_str[on->state]); + thread_add_event(master, seqnumber_mismatch, on, 0, NULL); + return; + + default: + assert(0); + break; + } + + /* Process LSA headers */ + for (p = (char *)((caddr_t)dbdesc + sizeof(struct ospf6_dbdesc)); + p + sizeof(struct ospf6_lsa_header) <= OSPF6_MESSAGE_END(oh); + p += sizeof(struct ospf6_lsa_header)) { + struct ospf6_lsa *his, *mine; + struct ospf6_lsdb *lsdb = NULL; + + his = ospf6_lsa_create_headeronly((struct ospf6_lsa_header *)p); + + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("%s", his->name); + + 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_debug("Ignoring LSA of reserved scope"); + ospf6_lsa_delete(his); + continue; + break; + } + + if (ntohs(his->header->type) == OSPF6_LSTYPE_AS_EXTERNAL + && IS_AREA_STUB(on->ospf6_if->area)) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug( + "SeqNumMismatch (E-bit mismatch), discard"); + ospf6_lsa_delete(his); + thread_add_event(master, seqnumber_mismatch, on, 0, + NULL); + return; + } + + mine = ospf6_lsdb_lookup(his->header->type, his->header->id, + his->header->adv_router, lsdb); + if (mine == NULL) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Add request (No database copy)"); + ospf6_lsdb_add(ospf6_lsa_copy(his), on->request_list); + } else if (ospf6_lsa_compare(his, mine) < 0) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Add request (Received MoreRecent)"); + ospf6_lsdb_add(ospf6_lsa_copy(his), on->request_list); + } else { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Discard (Existing MoreRecent)"); + } + ospf6_lsa_delete(his); + } + + assert(p == OSPF6_MESSAGE_END(oh)); + + /* Increment sequence number */ + on->dbdesc_seqnum++; + + /* schedule send lsreq */ + if (on->request_list->count) + thread_add_event(master, ospf6_lsreq_send, on, 0, + &on->thread_send_lsreq); + + THREAD_OFF(on->thread_send_dbdesc); + + /* More bit check */ + if (!CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MBIT) + && !CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT)) + thread_add_event(master, exchange_done, on, 0, NULL); + else { + on->thread_send_dbdesc = NULL; + thread_add_event(master, ospf6_dbdesc_send_newone, on, 0, + &on->thread_send_dbdesc); + } + + /* save last received dbdesc */ + memcpy(&on->dbdesc_last, dbdesc, sizeof(struct ospf6_dbdesc)); } -static void -ospf6_dbdesc_recv_slave (struct ospf6_header *oh, - struct ospf6_neighbor *on) +static void ospf6_dbdesc_recv_slave(struct ospf6_header *oh, + struct ospf6_neighbor *on) { - struct ospf6_dbdesc *dbdesc; - char *p; - - dbdesc = (struct ospf6_dbdesc *) - ((caddr_t) oh + sizeof (struct ospf6_header)); - - if (on->state < OSPF6_NEIGHBOR_INIT) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Neighbor state less than Init, ignore"); - return; - } - - switch (on->state) - { - case OSPF6_NEIGHBOR_TWOWAY: - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Neighbor state is 2-Way, ignore"); - return; - - case OSPF6_NEIGHBOR_INIT: - thread_execute (master, twoway_received, on, 0); - if (on->state != OSPF6_NEIGHBOR_EXSTART) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Neighbor state is not ExStart, ignore"); - return; - } - /* else fall through to ExStart */ - /* fallthru */ - case OSPF6_NEIGHBOR_EXSTART: - /* If the neighbor is Master, act as Slave. Schedule negotiation_done - and process LSA Headers. Otherwise, ignore this message */ - if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) && - CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) && - CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) && - ntohs (oh->length) == sizeof (struct ospf6_header) + - sizeof (struct ospf6_dbdesc)) - { - /* set the master/slave bit to slave */ - UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT); - - /* set the DD sequence number to one specified by master */ - on->dbdesc_seqnum = ntohl (dbdesc->seqnum); - - /* schedule NegotiationDone */ - thread_execute (master, negotiation_done, on, 0); - - /* Record neighbor options */ - memcpy (on->options, dbdesc->options, sizeof (on->options)); - } - else - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Negotiation failed"); - return; - } - break; - - case OSPF6_NEIGHBOR_EXCHANGE: - if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc))) - { - /* Duplicated DatabaseDescription causes slave to retransmit */ - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Duplicated dbdesc causes retransmit"); - THREAD_OFF (on->thread_send_dbdesc); - on->thread_send_dbdesc = NULL; - thread_add_event(master, ospf6_dbdesc_send, on, 0, - &on->thread_send_dbdesc); - return; - } - - if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT)) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Master/Slave bit mismatch"); - thread_add_event (master, seqnumber_mismatch, on, 0, NULL); - return; - } - - if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT)) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Initialize bit mismatch"); - thread_add_event (master, seqnumber_mismatch, on, 0, NULL); - return; - } - - if (memcmp (on->options, dbdesc->options, sizeof (on->options))) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Option field mismatch"); - thread_add_event (master, seqnumber_mismatch, on, 0, NULL); - return; - } - - if (ntohl (dbdesc->seqnum) != on->dbdesc_seqnum + 1) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Sequence number mismatch (%#lx expected)", - (u_long) on->dbdesc_seqnum + 1); - thread_add_event (master, seqnumber_mismatch, on, 0, NULL); - return; - } - break; - - case OSPF6_NEIGHBOR_LOADING: - case OSPF6_NEIGHBOR_FULL: - if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc))) - { - /* Duplicated DatabaseDescription causes slave to retransmit */ - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Duplicated dbdesc causes retransmit"); - THREAD_OFF (on->thread_send_dbdesc); - thread_add_event (master, ospf6_dbdesc_send, on, 0, &on->thread_send_dbdesc); - return; - } - - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Not duplicate dbdesc in state %s", - ospf6_neighbor_state_str[on->state]); - thread_add_event (master, seqnumber_mismatch, on, 0, NULL); - return; - - default: - assert (0); - break; - } - - /* Process LSA headers */ - for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc)); - p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh); - p += sizeof (struct ospf6_lsa_header)) - { - struct ospf6_lsa *his, *mine; - struct ospf6_lsdb *lsdb = NULL; - - his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p); - - 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_debug ("Ignoring LSA of reserved scope"); - ospf6_lsa_delete (his); - continue; - break; - } - - 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_debug ("E-bit mismatch with LSA Headers"); - ospf6_lsa_delete (his); - thread_add_event (master, seqnumber_mismatch, on, 0, NULL); - return; - } - - 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 (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Add request-list: %s", his->name); - ospf6_lsdb_add (ospf6_lsa_copy(his), on->request_list); - } - ospf6_lsa_delete (his); - } - - assert (p == OSPF6_MESSAGE_END (oh)); - - /* Set sequence number to Master's */ - on->dbdesc_seqnum = ntohl (dbdesc->seqnum); - - /* schedule send lsreq */ - if (on->request_list->count) - thread_add_event (master, ospf6_lsreq_send, on, 0, &on->thread_send_lsreq); - - THREAD_OFF (on->thread_send_dbdesc); - thread_add_event (master, ospf6_dbdesc_send_newone, on, 0, &on->thread_send_dbdesc); - - /* save last received dbdesc */ - memcpy (&on->dbdesc_last, dbdesc, sizeof (struct ospf6_dbdesc)); + struct ospf6_dbdesc *dbdesc; + char *p; + + dbdesc = (struct ospf6_dbdesc *)((caddr_t)oh + + sizeof(struct ospf6_header)); + + if (on->state < OSPF6_NEIGHBOR_INIT) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Neighbor state less than Init, ignore"); + return; + } + + switch (on->state) { + case OSPF6_NEIGHBOR_TWOWAY: + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Neighbor state is 2-Way, ignore"); + return; + + case OSPF6_NEIGHBOR_INIT: + thread_execute(master, twoway_received, on, 0); + if (on->state != OSPF6_NEIGHBOR_EXSTART) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug( + "Neighbor state is not ExStart, ignore"); + return; + } + /* else fall through to ExStart */ + /* fallthru */ + case OSPF6_NEIGHBOR_EXSTART: + /* If the neighbor is Master, act as Slave. Schedule + negotiation_done + and process LSA Headers. Otherwise, ignore this message */ + if (CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_IBIT) + && CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MBIT) + && CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MSBIT) + && ntohs(oh->length) + == sizeof(struct ospf6_header) + + sizeof(struct ospf6_dbdesc)) { + /* set the master/slave bit to slave */ + UNSET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT); + + /* set the DD sequence number to one specified by master + */ + on->dbdesc_seqnum = ntohl(dbdesc->seqnum); + + /* schedule NegotiationDone */ + thread_execute(master, negotiation_done, on, 0); + + /* Record neighbor options */ + memcpy(on->options, dbdesc->options, + sizeof(on->options)); + } else { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Negotiation failed"); + return; + } + break; + + case OSPF6_NEIGHBOR_EXCHANGE: + if (!memcmp(dbdesc, &on->dbdesc_last, + sizeof(struct ospf6_dbdesc))) { + /* Duplicated DatabaseDescription causes slave to + * retransmit */ + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug( + "Duplicated dbdesc causes retransmit"); + THREAD_OFF(on->thread_send_dbdesc); + on->thread_send_dbdesc = NULL; + thread_add_event(master, ospf6_dbdesc_send, on, 0, + &on->thread_send_dbdesc); + return; + } + + if (!CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MSBIT)) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Master/Slave bit mismatch"); + thread_add_event(master, seqnumber_mismatch, on, 0, + NULL); + return; + } + + if (CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_IBIT)) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Initialize bit mismatch"); + thread_add_event(master, seqnumber_mismatch, on, 0, + NULL); + return; + } + + if (memcmp(on->options, dbdesc->options, sizeof(on->options))) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Option field mismatch"); + thread_add_event(master, seqnumber_mismatch, on, 0, + NULL); + return; + } + + if (ntohl(dbdesc->seqnum) != on->dbdesc_seqnum + 1) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug( + "Sequence number mismatch (%#lx expected)", + (u_long)on->dbdesc_seqnum + 1); + thread_add_event(master, seqnumber_mismatch, on, 0, + NULL); + return; + } + break; + + case OSPF6_NEIGHBOR_LOADING: + case OSPF6_NEIGHBOR_FULL: + if (!memcmp(dbdesc, &on->dbdesc_last, + sizeof(struct ospf6_dbdesc))) { + /* Duplicated DatabaseDescription causes slave to + * retransmit */ + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug( + "Duplicated dbdesc causes retransmit"); + THREAD_OFF(on->thread_send_dbdesc); + thread_add_event(master, ospf6_dbdesc_send, on, 0, + &on->thread_send_dbdesc); + return; + } + + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Not duplicate dbdesc in state %s", + ospf6_neighbor_state_str[on->state]); + thread_add_event(master, seqnumber_mismatch, on, 0, NULL); + return; + + default: + assert(0); + break; + } + + /* Process LSA headers */ + for (p = (char *)((caddr_t)dbdesc + sizeof(struct ospf6_dbdesc)); + p + sizeof(struct ospf6_lsa_header) <= OSPF6_MESSAGE_END(oh); + p += sizeof(struct ospf6_lsa_header)) { + struct ospf6_lsa *his, *mine; + struct ospf6_lsdb *lsdb = NULL; + + his = ospf6_lsa_create_headeronly((struct ospf6_lsa_header *)p); + + 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_debug("Ignoring LSA of reserved scope"); + ospf6_lsa_delete(his); + continue; + break; + } + + 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_debug("E-bit mismatch with LSA Headers"); + ospf6_lsa_delete(his); + thread_add_event(master, seqnumber_mismatch, on, 0, + NULL); + return; + } + + 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 (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Add request-list: %s", his->name); + ospf6_lsdb_add(ospf6_lsa_copy(his), on->request_list); + } + ospf6_lsa_delete(his); + } + + assert(p == OSPF6_MESSAGE_END(oh)); + + /* Set sequence number to Master's */ + on->dbdesc_seqnum = ntohl(dbdesc->seqnum); + + /* schedule send lsreq */ + if (on->request_list->count) + thread_add_event(master, ospf6_lsreq_send, on, 0, + &on->thread_send_lsreq); + + THREAD_OFF(on->thread_send_dbdesc); + thread_add_event(master, ospf6_dbdesc_send_newone, on, 0, + &on->thread_send_dbdesc); + + /* save last received dbdesc */ + memcpy(&on->dbdesc_last, dbdesc, sizeof(struct ospf6_dbdesc)); } -static void -ospf6_dbdesc_recv (struct in6_addr *src, struct in6_addr *dst, - struct ospf6_interface *oi, struct ospf6_header *oh) +static void ospf6_dbdesc_recv(struct in6_addr *src, struct in6_addr *dst, + struct ospf6_interface *oi, + struct ospf6_header *oh) { - struct ospf6_neighbor *on; - struct ospf6_dbdesc *dbdesc; - - on = ospf6_neighbor_lookup (oh->router_id, oi); - if (on == NULL) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Neighbor not found, ignore"); - return; - } - - dbdesc = (struct ospf6_dbdesc *) - ((caddr_t) oh + sizeof (struct ospf6_header)); - - /* Interface MTU check */ - if (!oi->mtu_ignore && ntohs (dbdesc->ifmtu) != oi->ifmtu) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("I/F MTU mismatch"); - return; - } - - if (dbdesc->reserved1 || dbdesc->reserved2) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Non-0 reserved field in %s's DbDesc, correct", - on->name); - dbdesc->reserved1 = 0; - dbdesc->reserved2 = 0; - } - - if (ntohl (oh->router_id) < ntohl (ospf6->router_id)) - ospf6_dbdesc_recv_master (oh, on); - else if (ntohl (ospf6->router_id) < ntohl (oh->router_id)) - ospf6_dbdesc_recv_slave (oh, on); - else - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Can't decide which is master, ignore"); - } + struct ospf6_neighbor *on; + struct ospf6_dbdesc *dbdesc; + + on = ospf6_neighbor_lookup(oh->router_id, oi); + if (on == NULL) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Neighbor not found, ignore"); + return; + } + + dbdesc = (struct ospf6_dbdesc *)((caddr_t)oh + + sizeof(struct ospf6_header)); + + /* Interface MTU check */ + if (!oi->mtu_ignore && ntohs(dbdesc->ifmtu) != oi->ifmtu) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("I/F MTU mismatch"); + return; + } + + if (dbdesc->reserved1 || dbdesc->reserved2) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug( + "Non-0 reserved field in %s's DbDesc, correct", + on->name); + dbdesc->reserved1 = 0; + dbdesc->reserved2 = 0; + } + + if (ntohl(oh->router_id) < ntohl(ospf6->router_id)) + ospf6_dbdesc_recv_master(oh, on); + else if (ntohl(ospf6->router_id) < ntohl(oh->router_id)) + ospf6_dbdesc_recv_slave(oh, on); + else { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Can't decide which is master, ignore"); + } } -static void -ospf6_lsreq_recv (struct in6_addr *src, struct in6_addr *dst, - struct ospf6_interface *oi, struct ospf6_header *oh) +static void ospf6_lsreq_recv(struct in6_addr *src, struct in6_addr *dst, + struct ospf6_interface *oi, + struct ospf6_header *oh) { - struct ospf6_neighbor *on; - char *p; - struct ospf6_lsreq_entry *e; - struct ospf6_lsdb *lsdb = NULL; - struct ospf6_lsa *lsa; - - on = ospf6_neighbor_lookup (oh->router_id, oi); - if (on == NULL) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Neighbor not found, ignore"); - return; - } - - if (on->state != OSPF6_NEIGHBOR_EXCHANGE && - on->state != OSPF6_NEIGHBOR_LOADING && - on->state != OSPF6_NEIGHBOR_FULL) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Neighbor state less than Exchange, ignore"); - return; - } - - /* Process each request */ - for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header)); - p + sizeof (struct ospf6_lsreq_entry) <= OSPF6_MESSAGE_END (oh); - p += sizeof (struct ospf6_lsreq_entry)) - { - e = (struct ospf6_lsreq_entry *) p; - - 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_debug ("Ignoring LSA of reserved scope"); - continue; - break; - } - - /* Find database copy */ - lsa = ospf6_lsdb_lookup (e->type, e->id, e->adv_router, lsdb); - if (lsa == NULL) - { - char id[16], adv_router[16]; - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - { - inet_ntop (AF_INET, &e->id, id, sizeof (id)); - inet_ntop (AF_INET, &e->adv_router, adv_router, - sizeof (adv_router)); - zlog_debug ("Can't find requested [%s Id:%s Adv:%s]", - ospf6_lstype_name (e->type), id, adv_router); - } - thread_add_event (master, bad_lsreq, on, 0, NULL); - return; - } - - ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->lsupdate_list); - } - - assert (p == OSPF6_MESSAGE_END (oh)); - - /* schedule send lsupdate */ - THREAD_OFF (on->thread_send_lsupdate); - thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0, &on->thread_send_lsupdate); + struct ospf6_neighbor *on; + char *p; + struct ospf6_lsreq_entry *e; + struct ospf6_lsdb *lsdb = NULL; + struct ospf6_lsa *lsa; + + on = ospf6_neighbor_lookup(oh->router_id, oi); + if (on == NULL) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Neighbor not found, ignore"); + return; + } + + if (on->state != OSPF6_NEIGHBOR_EXCHANGE + && on->state != OSPF6_NEIGHBOR_LOADING + && on->state != OSPF6_NEIGHBOR_FULL) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Neighbor state less than Exchange, ignore"); + return; + } + + /* Process each request */ + for (p = (char *)((caddr_t)oh + sizeof(struct ospf6_header)); + p + sizeof(struct ospf6_lsreq_entry) <= OSPF6_MESSAGE_END(oh); + p += sizeof(struct ospf6_lsreq_entry)) { + e = (struct ospf6_lsreq_entry *)p; + + 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_debug("Ignoring LSA of reserved scope"); + continue; + break; + } + + /* Find database copy */ + lsa = ospf6_lsdb_lookup(e->type, e->id, e->adv_router, lsdb); + if (lsa == NULL) { + char id[16], adv_router[16]; + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) { + inet_ntop(AF_INET, &e->id, id, sizeof(id)); + inet_ntop(AF_INET, &e->adv_router, adv_router, + sizeof(adv_router)); + zlog_debug( + "Can't find requested [%s Id:%s Adv:%s]", + ospf6_lstype_name(e->type), id, + adv_router); + } + thread_add_event(master, bad_lsreq, on, 0, NULL); + return; + } + + ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->lsupdate_list); + } + + assert(p == OSPF6_MESSAGE_END(oh)); + + /* schedule send lsupdate */ + THREAD_OFF(on->thread_send_lsupdate); + thread_add_event(master, ospf6_lsupdate_send_neighbor, on, 0, + &on->thread_send_lsupdate); } /* Verify, that the specified memory area contains exactly N valid IPv6 prefixes as specified by RFC5340, A.4.1. */ -static unsigned -ospf6_prefixes_examin -( - struct ospf6_prefix *current, /* start of buffer */ - unsigned length, - const u_int32_t req_num_pfxs /* always compared with the actual number of prefixes */ -) +static unsigned ospf6_prefixes_examin( + struct ospf6_prefix *current, /* start of buffer */ + unsigned length, + const u_int32_t req_num_pfxs /* always compared with the actual number + of prefixes */ + ) { - u_char requested_pfx_bytes; - u_int32_t real_num_pfxs = 0; - - while (length) - { - if (length < OSPF6_PREFIX_MIN_SIZE) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: undersized IPv6 prefix header", __func__); - return MSG_NG; - } - /* safe to look deeper */ - if (current->prefix_length > IPV6_MAX_BITLEN) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: invalid PrefixLength (%u bits)", __func__, current->prefix_length); - return MSG_NG; - } - /* covers both fixed- and variable-sized fields */ - requested_pfx_bytes = OSPF6_PREFIX_MIN_SIZE + OSPF6_PREFIX_SPACE (current->prefix_length); - if (requested_pfx_bytes > length) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: undersized IPv6 prefix", __func__); - return MSG_NG; - } - /* next prefix */ - length -= requested_pfx_bytes; - current = (struct ospf6_prefix *) ((caddr_t) current + requested_pfx_bytes); - real_num_pfxs++; - } - if (real_num_pfxs != req_num_pfxs) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: IPv6 prefix number mismatch (%u required, %u real)", - __func__, req_num_pfxs, real_num_pfxs); - return MSG_NG; - } - return MSG_OK; + u_char requested_pfx_bytes; + u_int32_t real_num_pfxs = 0; + + while (length) { + if (length < OSPF6_PREFIX_MIN_SIZE) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, + RECV)) + zlog_debug("%s: undersized IPv6 prefix header", + __func__); + return MSG_NG; + } + /* safe to look deeper */ + if (current->prefix_length > IPV6_MAX_BITLEN) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, + RECV)) + zlog_debug("%s: invalid PrefixLength (%u bits)", + __func__, current->prefix_length); + return MSG_NG; + } + /* covers both fixed- and variable-sized fields */ + requested_pfx_bytes = + OSPF6_PREFIX_MIN_SIZE + + OSPF6_PREFIX_SPACE(current->prefix_length); + if (requested_pfx_bytes > length) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, + RECV)) + zlog_debug("%s: undersized IPv6 prefix", + __func__); + return MSG_NG; + } + /* next prefix */ + length -= requested_pfx_bytes; + current = (struct ospf6_prefix *)((caddr_t)current + + requested_pfx_bytes); + real_num_pfxs++; + } + if (real_num_pfxs != req_num_pfxs) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug( + "%s: IPv6 prefix number mismatch (%u required, %u real)", + __func__, req_num_pfxs, real_num_pfxs); + return MSG_NG; + } + return MSG_OK; } /* Verify an LSA to have a valid length and dispatch further (where @@ -947,1374 +922,1378 @@ ospf6_prefixes_examin is properly sized/aligned within the LSA. Note that this function gets LSA type in network byte order, uses in host byte order and passes to ospf6_lstype_name() in network byte order again. */ -static unsigned -ospf6_lsa_examin (struct ospf6_lsa_header *lsah, const u_int16_t lsalen, const u_char headeronly) +static unsigned ospf6_lsa_examin(struct ospf6_lsa_header *lsah, + const u_int16_t lsalen, + const u_char headeronly) { - struct ospf6_intra_prefix_lsa *intra_prefix_lsa; - struct ospf6_as_external_lsa *as_external_lsa; - struct ospf6_link_lsa *link_lsa; - unsigned exp_length; - u_int8_t ltindex; - u_int16_t lsatype; - - /* In case an additional minimum length constraint is defined for current - LSA type, make sure that this constraint is met. */ - lsatype = ntohs (lsah->type); - ltindex = lsatype & OSPF6_LSTYPE_FCODE_MASK; - if - ( - ltindex < OSPF6_LSTYPE_SIZE && - ospf6_lsa_minlen[ltindex] && - lsalen < ospf6_lsa_minlen[ltindex] + OSPF6_LSA_HEADER_SIZE - ) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: undersized (%u B) LSA", __func__, lsalen); - return MSG_NG; - } - switch (lsatype) - { - case OSPF6_LSTYPE_ROUTER: - /* RFC5340 A.4.3, LSA header + OSPF6_ROUTER_LSA_MIN_SIZE bytes followed - by N>=0 interface descriptions. */ - if ((lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_ROUTER_LSA_MIN_SIZE) % OSPF6_ROUTER_LSDESC_FIX_SIZE) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: interface description alignment error", __func__); - return MSG_NG; - } - break; - case OSPF6_LSTYPE_NETWORK: - /* RFC5340 A.4.4, LSA header + OSPF6_NETWORK_LSA_MIN_SIZE bytes - followed by N>=0 attached router descriptions. */ - if ((lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_NETWORK_LSA_MIN_SIZE) % OSPF6_NETWORK_LSDESC_FIX_SIZE) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: router description alignment error", __func__); - return MSG_NG; - } - break; - case OSPF6_LSTYPE_INTER_PREFIX: - /* RFC5340 A.4.5, LSA header + OSPF6_INTER_PREFIX_LSA_MIN_SIZE bytes - followed by 3-4 fields of a single IPv6 prefix. */ - if (headeronly) - break; - return ospf6_prefixes_examin - ( - (struct ospf6_prefix *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE + OSPF6_INTER_PREFIX_LSA_MIN_SIZE), - lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_INTER_PREFIX_LSA_MIN_SIZE, - 1 - ); - case OSPF6_LSTYPE_INTER_ROUTER: - /* RFC5340 A.4.6, fixed-size LSA. */ - if (lsalen > OSPF6_LSA_HEADER_SIZE + OSPF6_INTER_ROUTER_LSA_FIX_SIZE) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: oversized (%u B) LSA", __func__, lsalen); - return MSG_NG; - } - break; - case OSPF6_LSTYPE_AS_EXTERNAL: /* RFC5340 A.4.7, same as A.4.8. */ - case OSPF6_LSTYPE_TYPE_7: - /* RFC5340 A.4.8, LSA header + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE bytes - followed by 3-4 fields of IPv6 prefix and 3 conditional LSA fields: - 16 bytes of forwarding address, 4 bytes of external route tag, - 4 bytes of referenced link state ID. */ - if (headeronly) - break; - as_external_lsa = (struct ospf6_as_external_lsa *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE); - exp_length = OSPF6_LSA_HEADER_SIZE + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE; - /* To find out if the last optional field (Referenced Link State ID) is - assumed in this LSA, we need to access fixed fields of the IPv6 - prefix before ospf6_prefix_examin() confirms its sizing. */ - if (exp_length + OSPF6_PREFIX_MIN_SIZE > lsalen) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: undersized (%u B) LSA header", __func__, lsalen); - return MSG_NG; - } - /* forwarding address */ - if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F)) - exp_length += 16; - /* external route tag */ - if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T)) - exp_length += 4; - /* referenced link state ID */ - if (as_external_lsa->prefix.u._prefix_referenced_lstype) - exp_length += 4; - /* All the fixed-size fields (mandatory and optional) must fit. I.e., - this check does not include any IPv6 prefix fields. */ - if (exp_length > lsalen) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: undersized (%u B) LSA header", __func__, lsalen); - return MSG_NG; - } - /* The last call completely covers the remainder (IPv6 prefix). */ - return ospf6_prefixes_examin - ( - (struct ospf6_prefix *) ((caddr_t) as_external_lsa + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE), - lsalen - exp_length, - 1 - ); - case OSPF6_LSTYPE_LINK: - /* RFC5340 A.4.9, LSA header + OSPF6_LINK_LSA_MIN_SIZE bytes followed - by N>=0 IPv6 prefix blocks (with N declared beforehand). */ - if (headeronly) - break; - link_lsa = (struct ospf6_link_lsa *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE); - return ospf6_prefixes_examin - ( - (struct ospf6_prefix *) ((caddr_t) link_lsa + OSPF6_LINK_LSA_MIN_SIZE), - lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_LINK_LSA_MIN_SIZE, - ntohl (link_lsa->prefix_num) /* 32 bits */ - ); - case OSPF6_LSTYPE_INTRA_PREFIX: - /* RFC5340 A.4.10, LSA header + OSPF6_INTRA_PREFIX_LSA_MIN_SIZE bytes - followed by N>=0 IPv6 prefixes (with N declared beforehand). */ - if (headeronly) - break; - intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE); - return ospf6_prefixes_examin - ( - (struct ospf6_prefix *) ((caddr_t) intra_prefix_lsa + OSPF6_INTRA_PREFIX_LSA_MIN_SIZE), - lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_INTRA_PREFIX_LSA_MIN_SIZE, - ntohs (intra_prefix_lsa->prefix_num) /* 16 bits */ - ); - } - /* No additional validation is possible for unknown LSA types, which are - themselves valid in OPSFv3, hence the default decision is to accept. */ - return MSG_OK; + struct ospf6_intra_prefix_lsa *intra_prefix_lsa; + struct ospf6_as_external_lsa *as_external_lsa; + struct ospf6_link_lsa *link_lsa; + unsigned exp_length; + u_int8_t ltindex; + u_int16_t lsatype; + + /* In case an additional minimum length constraint is defined for + current + LSA type, make sure that this constraint is met. */ + lsatype = ntohs(lsah->type); + ltindex = lsatype & OSPF6_LSTYPE_FCODE_MASK; + if (ltindex < OSPF6_LSTYPE_SIZE && ospf6_lsa_minlen[ltindex] + && lsalen < ospf6_lsa_minlen[ltindex] + OSPF6_LSA_HEADER_SIZE) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug("%s: undersized (%u B) LSA", __func__, + lsalen); + return MSG_NG; + } + switch (lsatype) { + case OSPF6_LSTYPE_ROUTER: + /* RFC5340 A.4.3, LSA header + OSPF6_ROUTER_LSA_MIN_SIZE bytes + followed + by N>=0 interface descriptions. */ + if ((lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_ROUTER_LSA_MIN_SIZE) + % OSPF6_ROUTER_LSDESC_FIX_SIZE) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, + RECV)) + zlog_debug( + "%s: interface description alignment error", + __func__); + return MSG_NG; + } + break; + case OSPF6_LSTYPE_NETWORK: + /* RFC5340 A.4.4, LSA header + OSPF6_NETWORK_LSA_MIN_SIZE bytes + followed by N>=0 attached router descriptions. */ + if ((lsalen - OSPF6_LSA_HEADER_SIZE + - OSPF6_NETWORK_LSA_MIN_SIZE) + % OSPF6_NETWORK_LSDESC_FIX_SIZE) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, + RECV)) + zlog_debug( + "%s: router description alignment error", + __func__); + return MSG_NG; + } + break; + case OSPF6_LSTYPE_INTER_PREFIX: + /* RFC5340 A.4.5, LSA header + OSPF6_INTER_PREFIX_LSA_MIN_SIZE + bytes + followed by 3-4 fields of a single IPv6 prefix. */ + if (headeronly) + break; + return ospf6_prefixes_examin( + (struct ospf6_prefix + *)((caddr_t)lsah + OSPF6_LSA_HEADER_SIZE + + OSPF6_INTER_PREFIX_LSA_MIN_SIZE), + lsalen - OSPF6_LSA_HEADER_SIZE + - OSPF6_INTER_PREFIX_LSA_MIN_SIZE, + 1); + case OSPF6_LSTYPE_INTER_ROUTER: + /* RFC5340 A.4.6, fixed-size LSA. */ + if (lsalen + > OSPF6_LSA_HEADER_SIZE + OSPF6_INTER_ROUTER_LSA_FIX_SIZE) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, + RECV)) + zlog_debug("%s: oversized (%u B) LSA", __func__, + lsalen); + return MSG_NG; + } + break; + case OSPF6_LSTYPE_AS_EXTERNAL: /* RFC5340 A.4.7, same as A.4.8. */ + case OSPF6_LSTYPE_TYPE_7: + /* RFC5340 A.4.8, LSA header + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE + bytes + followed by 3-4 fields of IPv6 prefix and 3 conditional LSA + fields: + 16 bytes of forwarding address, 4 bytes of external route + tag, + 4 bytes of referenced link state ID. */ + if (headeronly) + break; + as_external_lsa = + (struct ospf6_as_external_lsa + *)((caddr_t)lsah + OSPF6_LSA_HEADER_SIZE); + exp_length = + OSPF6_LSA_HEADER_SIZE + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE; + /* To find out if the last optional field (Referenced Link State + ID) is + assumed in this LSA, we need to access fixed fields of the + IPv6 + prefix before ospf6_prefix_examin() confirms its sizing. */ + if (exp_length + OSPF6_PREFIX_MIN_SIZE > lsalen) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, + RECV)) + zlog_debug("%s: undersized (%u B) LSA header", + __func__, lsalen); + return MSG_NG; + } + /* forwarding address */ + if (CHECK_FLAG(as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F)) + exp_length += 16; + /* external route tag */ + if (CHECK_FLAG(as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T)) + exp_length += 4; + /* referenced link state ID */ + if (as_external_lsa->prefix.u._prefix_referenced_lstype) + exp_length += 4; + /* All the fixed-size fields (mandatory and optional) must fit. + I.e., + this check does not include any IPv6 prefix fields. */ + if (exp_length > lsalen) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, + RECV)) + zlog_debug("%s: undersized (%u B) LSA header", + __func__, lsalen); + return MSG_NG; + } + /* The last call completely covers the remainder (IPv6 prefix). + */ + return ospf6_prefixes_examin( + (struct ospf6_prefix + *)((caddr_t)as_external_lsa + + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE), + lsalen - exp_length, 1); + case OSPF6_LSTYPE_LINK: + /* RFC5340 A.4.9, LSA header + OSPF6_LINK_LSA_MIN_SIZE bytes + followed + by N>=0 IPv6 prefix blocks (with N declared beforehand). */ + if (headeronly) + break; + link_lsa = (struct ospf6_link_lsa *)((caddr_t)lsah + + OSPF6_LSA_HEADER_SIZE); + return ospf6_prefixes_examin( + (struct ospf6_prefix *)((caddr_t)link_lsa + + OSPF6_LINK_LSA_MIN_SIZE), + lsalen - OSPF6_LSA_HEADER_SIZE + - OSPF6_LINK_LSA_MIN_SIZE, + ntohl(link_lsa->prefix_num) /* 32 bits */ + ); + case OSPF6_LSTYPE_INTRA_PREFIX: + /* RFC5340 A.4.10, LSA header + OSPF6_INTRA_PREFIX_LSA_MIN_SIZE + bytes + followed by N>=0 IPv6 prefixes (with N declared beforehand). + */ + if (headeronly) + break; + intra_prefix_lsa = + (struct ospf6_intra_prefix_lsa + *)((caddr_t)lsah + OSPF6_LSA_HEADER_SIZE); + return ospf6_prefixes_examin( + (struct ospf6_prefix + *)((caddr_t)intra_prefix_lsa + + OSPF6_INTRA_PREFIX_LSA_MIN_SIZE), + lsalen - OSPF6_LSA_HEADER_SIZE + - OSPF6_INTRA_PREFIX_LSA_MIN_SIZE, + ntohs(intra_prefix_lsa->prefix_num) /* 16 bits */ + ); + } + /* No additional validation is possible for unknown LSA types, which are + themselves valid in OPSFv3, hence the default decision is to accept. + */ + return MSG_OK; } /* Verify if the provided input buffer is a valid sequence of LSAs. This includes verification of LSA blocks length/alignment and dispatching of deeper-level checks. */ static unsigned -ospf6_lsaseq_examin -( - struct ospf6_lsa_header *lsah, /* start of buffered data */ - size_t length, - const u_char headeronly, - /* When declared_num_lsas is not 0, compare it to the real number of LSAs - and treat the difference as an error. */ - const u_int32_t declared_num_lsas -) +ospf6_lsaseq_examin(struct ospf6_lsa_header *lsah, /* start of buffered data */ + size_t length, const u_char headeronly, + /* When declared_num_lsas is not 0, compare it to the real + number of LSAs + and treat the difference as an error. */ + const u_int32_t declared_num_lsas) { - u_int32_t counted_lsas = 0; - - while (length) - { - u_int16_t lsalen; - if (length < OSPF6_LSA_HEADER_SIZE) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: undersized (%zu B) trailing (#%u) LSA header", - __func__, length, counted_lsas); - return MSG_NG; - } - /* save on ntohs() calls here and in the LSA validator */ - lsalen = OSPF6_LSA_SIZE (lsah); - if (lsalen < OSPF6_LSA_HEADER_SIZE) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: malformed LSA header #%u, declared length is %u B", - __func__, counted_lsas, lsalen); - return MSG_NG; - } - if (headeronly) - { - /* less checks here and in ospf6_lsa_examin() */ - if (MSG_OK != ospf6_lsa_examin (lsah, lsalen, 1)) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: anomaly in header-only %s LSA #%u", __func__, - ospf6_lstype_name (lsah->type), counted_lsas); - return MSG_NG; - } - lsah = (struct ospf6_lsa_header *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE); - length -= OSPF6_LSA_HEADER_SIZE; - } - else - { - /* make sure the input buffer is deep enough before further checks */ - if (lsalen > length) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: anomaly in %s LSA #%u: declared length is %u B, buffered length is %zu B", - __func__, ospf6_lstype_name (lsah->type), counted_lsas, lsalen, length); - return MSG_NG; - } - if (MSG_OK != ospf6_lsa_examin (lsah, lsalen, 0)) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: anomaly in %s LSA #%u", __func__, - ospf6_lstype_name (lsah->type), counted_lsas); - return MSG_NG; - } - lsah = (struct ospf6_lsa_header *) ((caddr_t) lsah + lsalen); - length -= lsalen; - } - counted_lsas++; - } - - if (declared_num_lsas && counted_lsas != declared_num_lsas) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: #LSAs declared (%u) does not match actual (%u)", - __func__, declared_num_lsas, counted_lsas); - return MSG_NG; - } - return MSG_OK; + u_int32_t counted_lsas = 0; + + while (length) { + u_int16_t lsalen; + if (length < OSPF6_LSA_HEADER_SIZE) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, + RECV)) + zlog_debug( + "%s: undersized (%zu B) trailing (#%u) LSA header", + __func__, length, counted_lsas); + return MSG_NG; + } + /* save on ntohs() calls here and in the LSA validator */ + lsalen = OSPF6_LSA_SIZE(lsah); + if (lsalen < OSPF6_LSA_HEADER_SIZE) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, + RECV)) + zlog_debug( + "%s: malformed LSA header #%u, declared length is %u B", + __func__, counted_lsas, lsalen); + return MSG_NG; + } + if (headeronly) { + /* less checks here and in ospf6_lsa_examin() */ + if (MSG_OK != ospf6_lsa_examin(lsah, lsalen, 1)) { + if (IS_OSPF6_DEBUG_MESSAGE( + OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug( + "%s: anomaly in header-only %s LSA #%u", + __func__, + ospf6_lstype_name(lsah->type), + counted_lsas); + return MSG_NG; + } + lsah = (struct ospf6_lsa_header + *)((caddr_t)lsah + + OSPF6_LSA_HEADER_SIZE); + length -= OSPF6_LSA_HEADER_SIZE; + } else { + /* make sure the input buffer is deep enough before + * further checks */ + if (lsalen > length) { + if (IS_OSPF6_DEBUG_MESSAGE( + OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug( + "%s: anomaly in %s LSA #%u: declared length is %u B, buffered length is %zu B", + __func__, + ospf6_lstype_name(lsah->type), + counted_lsas, lsalen, length); + return MSG_NG; + } + if (MSG_OK != ospf6_lsa_examin(lsah, lsalen, 0)) { + if (IS_OSPF6_DEBUG_MESSAGE( + OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug( + "%s: anomaly in %s LSA #%u", + __func__, + ospf6_lstype_name(lsah->type), + counted_lsas); + return MSG_NG; + } + lsah = (struct ospf6_lsa_header *)((caddr_t)lsah + + lsalen); + length -= lsalen; + } + counted_lsas++; + } + + if (declared_num_lsas && counted_lsas != declared_num_lsas) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug( + "%s: #LSAs declared (%u) does not match actual (%u)", + __func__, declared_num_lsas, counted_lsas); + return MSG_NG; + } + return MSG_OK; } /* Verify a complete OSPF packet for proper sizing/alignment. */ -static unsigned -ospf6_packet_examin (struct ospf6_header *oh, const unsigned bytesonwire) +static unsigned ospf6_packet_examin(struct ospf6_header *oh, + const unsigned bytesonwire) { - struct ospf6_lsupdate *lsupd; - unsigned test; - - /* length, 1st approximation */ - if (bytesonwire < OSPF6_HEADER_SIZE) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: undersized (%u B) packet", __func__, bytesonwire); - return MSG_NG; - } - /* Now it is safe to access header fields. */ - if (bytesonwire != ntohs (oh->length)) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: packet length error (%u real, %u declared)", - __func__, bytesonwire, ntohs (oh->length)); - return MSG_NG; - } - /* version check */ - if (oh->version != OSPFV3_VERSION) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: invalid (%u) protocol version", __func__, oh->version); - return MSG_NG; - } - /* length, 2nd approximation */ - if - ( - oh->type < OSPF6_MESSAGE_TYPE_ALL && - ospf6_packet_minlen[oh->type] && - bytesonwire < OSPF6_HEADER_SIZE + ospf6_packet_minlen[oh->type] - ) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: undersized (%u B) %s packet", __func__, - bytesonwire, lookup_msg(ospf6_message_type_str, oh->type, NULL)); - return MSG_NG; - } - /* type-specific deeper validation */ - switch (oh->type) - { - case OSPF6_MESSAGE_TYPE_HELLO: - /* RFC5340 A.3.2, packet header + OSPF6_HELLO_MIN_SIZE bytes followed - by N>=0 router-IDs. */ - if (0 == (bytesonwire - OSPF6_HEADER_SIZE - OSPF6_HELLO_MIN_SIZE) % 4) - return MSG_OK; - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: alignment error in %s packet", - __func__, lookup_msg(ospf6_message_type_str, oh->type, NULL)); - return MSG_NG; - case OSPF6_MESSAGE_TYPE_DBDESC: - /* RFC5340 A.3.3, packet header + OSPF6_DB_DESC_MIN_SIZE bytes followed - by N>=0 header-only LSAs. */ - test = ospf6_lsaseq_examin - ( - (struct ospf6_lsa_header *) ((caddr_t) oh + OSPF6_HEADER_SIZE + OSPF6_DB_DESC_MIN_SIZE), - bytesonwire - OSPF6_HEADER_SIZE - OSPF6_DB_DESC_MIN_SIZE, - 1, - 0 - ); - break; - case OSPF6_MESSAGE_TYPE_LSREQ: - /* RFC5340 A.3.4, packet header + N>=0 LS description blocks. */ - if (0 == (bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_REQ_MIN_SIZE) % OSPF6_LSREQ_LSDESC_FIX_SIZE) - return MSG_OK; - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: alignment error in %s packet", - __func__, lookup_msg(ospf6_message_type_str, oh->type, NULL)); - return MSG_NG; - case OSPF6_MESSAGE_TYPE_LSUPDATE: - /* RFC5340 A.3.5, packet header + OSPF6_LS_UPD_MIN_SIZE bytes followed - by N>=0 full LSAs (with N declared beforehand). */ - lsupd = (struct ospf6_lsupdate *) ((caddr_t) oh + OSPF6_HEADER_SIZE); - test = ospf6_lsaseq_examin - ( - (struct ospf6_lsa_header *) ((caddr_t) lsupd + OSPF6_LS_UPD_MIN_SIZE), - bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_UPD_MIN_SIZE, - 0, - ntohl (lsupd->lsa_number) /* 32 bits */ - ); - break; - case OSPF6_MESSAGE_TYPE_LSACK: - /* RFC5340 A.3.6, packet header + N>=0 header-only LSAs. */ - test = ospf6_lsaseq_examin - ( - (struct ospf6_lsa_header *) ((caddr_t) oh + OSPF6_HEADER_SIZE + OSPF6_LS_ACK_MIN_SIZE), - bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_ACK_MIN_SIZE, - 1, - 0 - ); - break; - default: - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: invalid (%u) message type", __func__, oh->type); - return MSG_NG; - } - if (test != MSG_OK && IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: anomaly in %s packet", __func__, lookup_msg(ospf6_message_type_str, oh->type, NULL)); - return test; + struct ospf6_lsupdate *lsupd; + unsigned test; + + /* length, 1st approximation */ + if (bytesonwire < OSPF6_HEADER_SIZE) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug("%s: undersized (%u B) packet", __func__, + bytesonwire); + return MSG_NG; + } + /* Now it is safe to access header fields. */ + if (bytesonwire != ntohs(oh->length)) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug( + "%s: packet length error (%u real, %u declared)", + __func__, bytesonwire, ntohs(oh->length)); + return MSG_NG; + } + /* version check */ + if (oh->version != OSPFV3_VERSION) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug("%s: invalid (%u) protocol version", + __func__, oh->version); + return MSG_NG; + } + /* length, 2nd approximation */ + if (oh->type < OSPF6_MESSAGE_TYPE_ALL && ospf6_packet_minlen[oh->type] + && bytesonwire + < OSPF6_HEADER_SIZE + ospf6_packet_minlen[oh->type]) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug("%s: undersized (%u B) %s packet", __func__, + bytesonwire, + lookup_msg(ospf6_message_type_str, oh->type, + NULL)); + return MSG_NG; + } + /* type-specific deeper validation */ + switch (oh->type) { + case OSPF6_MESSAGE_TYPE_HELLO: + /* RFC5340 A.3.2, packet header + OSPF6_HELLO_MIN_SIZE bytes + followed + by N>=0 router-IDs. */ + if (0 + == (bytesonwire - OSPF6_HEADER_SIZE - OSPF6_HELLO_MIN_SIZE) + % 4) + return MSG_OK; + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug("%s: alignment error in %s packet", __func__, + lookup_msg(ospf6_message_type_str, oh->type, + NULL)); + return MSG_NG; + case OSPF6_MESSAGE_TYPE_DBDESC: + /* RFC5340 A.3.3, packet header + OSPF6_DB_DESC_MIN_SIZE bytes + followed + by N>=0 header-only LSAs. */ + test = ospf6_lsaseq_examin( + (struct ospf6_lsa_header *)((caddr_t)oh + + OSPF6_HEADER_SIZE + + OSPF6_DB_DESC_MIN_SIZE), + bytesonwire - OSPF6_HEADER_SIZE + - OSPF6_DB_DESC_MIN_SIZE, + 1, 0); + break; + case OSPF6_MESSAGE_TYPE_LSREQ: + /* RFC5340 A.3.4, packet header + N>=0 LS description blocks. */ + if (0 + == (bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_REQ_MIN_SIZE) + % OSPF6_LSREQ_LSDESC_FIX_SIZE) + return MSG_OK; + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug("%s: alignment error in %s packet", __func__, + lookup_msg(ospf6_message_type_str, oh->type, + NULL)); + return MSG_NG; + case OSPF6_MESSAGE_TYPE_LSUPDATE: + /* RFC5340 A.3.5, packet header + OSPF6_LS_UPD_MIN_SIZE bytes + followed + by N>=0 full LSAs (with N declared beforehand). */ + lsupd = (struct ospf6_lsupdate *)((caddr_t)oh + + OSPF6_HEADER_SIZE); + test = ospf6_lsaseq_examin( + (struct ospf6_lsa_header *)((caddr_t)lsupd + + OSPF6_LS_UPD_MIN_SIZE), + bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_UPD_MIN_SIZE, + 0, ntohl(lsupd->lsa_number) /* 32 bits */ + ); + break; + case OSPF6_MESSAGE_TYPE_LSACK: + /* RFC5340 A.3.6, packet header + N>=0 header-only LSAs. */ + test = ospf6_lsaseq_examin( + (struct ospf6_lsa_header *)((caddr_t)oh + + OSPF6_HEADER_SIZE + + OSPF6_LS_ACK_MIN_SIZE), + bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_ACK_MIN_SIZE, + 1, 0); + break; + default: + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug("%s: invalid (%u) message type", __func__, + oh->type); + return MSG_NG; + } + if (test != MSG_OK + && IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug("%s: anomaly in %s packet", __func__, + lookup_msg(ospf6_message_type_str, oh->type, NULL)); + return test; } /* Verify particular fields of otherwise correct received OSPF packet to meet the requirements of RFC. */ -static int -ospf6_rxpacket_examin (struct ospf6_interface *oi, struct ospf6_header *oh, const unsigned bytesonwire) +static int ospf6_rxpacket_examin(struct ospf6_interface *oi, + struct ospf6_header *oh, + const unsigned bytesonwire) { - char buf[2][INET_ADDRSTRLEN]; - - if (MSG_OK != ospf6_packet_examin (oh, bytesonwire)) - return MSG_NG; - - /* Area-ID check */ - if (oh->area_id != oi->area->area_id) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - { - if (oh->area_id == OSPF_AREA_BACKBONE) - zlog_debug ("%s: Message may be via Virtual Link: not supported", __func__); - else - zlog_debug - ( - "%s: Area-ID mismatch (my %s, rcvd %s)", __func__, - inet_ntop (AF_INET, &oi->area->area_id, buf[0], INET_ADDRSTRLEN), - inet_ntop (AF_INET, &oh->area_id, buf[1], INET_ADDRSTRLEN) - ); - } - return MSG_NG; - } - - /* Instance-ID check */ - if (oh->instance_id != oi->instance_id) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("%s: Instance-ID mismatch (my %u, rcvd %u)", __func__, oi->instance_id, oh->instance_id); - return MSG_NG; - } - - /* Router-ID check */ - if (oh->router_id == oi->area->ospf6->router_id) - { - zlog_warn ("%s: Duplicate Router-ID (%s)", __func__, inet_ntop (AF_INET, &oh->router_id, buf[0], INET_ADDRSTRLEN)); - return MSG_NG; - } - return MSG_OK; + char buf[2][INET_ADDRSTRLEN]; + + if (MSG_OK != ospf6_packet_examin(oh, bytesonwire)) + return MSG_NG; + + /* Area-ID check */ + if (oh->area_id != oi->area->area_id) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) { + if (oh->area_id == OSPF_AREA_BACKBONE) + zlog_debug( + "%s: Message may be via Virtual Link: not supported", + __func__); + else + zlog_debug( + "%s: Area-ID mismatch (my %s, rcvd %s)", + __func__, + inet_ntop(AF_INET, &oi->area->area_id, + buf[0], INET_ADDRSTRLEN), + inet_ntop(AF_INET, &oh->area_id, buf[1], + INET_ADDRSTRLEN)); + } + return MSG_NG; + } + + /* Instance-ID check */ + if (oh->instance_id != oi->instance_id) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("%s: Instance-ID mismatch (my %u, rcvd %u)", + __func__, oi->instance_id, oh->instance_id); + return MSG_NG; + } + + /* Router-ID check */ + if (oh->router_id == oi->area->ospf6->router_id) { + zlog_warn("%s: Duplicate Router-ID (%s)", __func__, + inet_ntop(AF_INET, &oh->router_id, buf[0], + INET_ADDRSTRLEN)); + return MSG_NG; + } + return MSG_OK; } -static void -ospf6_lsupdate_recv (struct in6_addr *src, struct in6_addr *dst, - struct ospf6_interface *oi, struct ospf6_header *oh) +static void ospf6_lsupdate_recv(struct in6_addr *src, struct in6_addr *dst, + struct ospf6_interface *oi, + struct ospf6_header *oh) { - struct ospf6_neighbor *on; - struct ospf6_lsupdate *lsupdate; - char *p; - - on = ospf6_neighbor_lookup (oh->router_id, oi); - if (on == NULL) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Neighbor not found, ignore"); - return; - } - - if (on->state != OSPF6_NEIGHBOR_EXCHANGE && - on->state != OSPF6_NEIGHBOR_LOADING && - on->state != OSPF6_NEIGHBOR_FULL) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Neighbor state less than Exchange, ignore"); - return; - } - - lsupdate = (struct ospf6_lsupdate *) - ((caddr_t) oh + sizeof (struct ospf6_header)); - - /* Process LSAs */ - for (p = (char *) ((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate)); - p < OSPF6_MESSAGE_END (oh) && - p + OSPF6_LSA_SIZE (p) <= OSPF6_MESSAGE_END (oh); - p += OSPF6_LSA_SIZE (p)) - { - ospf6_receive_lsa (on, (struct ospf6_lsa_header *) p); - } - - assert (p == OSPF6_MESSAGE_END (oh)); + struct ospf6_neighbor *on; + struct ospf6_lsupdate *lsupdate; + char *p; + + on = ospf6_neighbor_lookup(oh->router_id, oi); + if (on == NULL) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Neighbor not found, ignore"); + return; + } + + if (on->state != OSPF6_NEIGHBOR_EXCHANGE + && on->state != OSPF6_NEIGHBOR_LOADING + && on->state != OSPF6_NEIGHBOR_FULL) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Neighbor state less than Exchange, ignore"); + return; + } + + lsupdate = (struct ospf6_lsupdate *)((caddr_t)oh + + sizeof(struct ospf6_header)); + /* Process LSAs */ + for (p = (char *)((caddr_t)lsupdate + sizeof(struct ospf6_lsupdate)); + p < OSPF6_MESSAGE_END(oh) + && p + OSPF6_LSA_SIZE(p) <= OSPF6_MESSAGE_END(oh); + p += OSPF6_LSA_SIZE(p)) { + ospf6_receive_lsa(on, (struct ospf6_lsa_header *)p); + } + + assert(p == OSPF6_MESSAGE_END(oh)); } -static void -ospf6_lsack_recv (struct in6_addr *src, struct in6_addr *dst, - struct ospf6_interface *oi, struct ospf6_header *oh) +static void ospf6_lsack_recv(struct in6_addr *src, struct in6_addr *dst, + struct ospf6_interface *oi, + struct ospf6_header *oh) { - struct ospf6_neighbor *on; - char *p; - struct ospf6_lsa *his, *mine; - struct ospf6_lsdb *lsdb = NULL; - - assert (oh->type == OSPF6_MESSAGE_TYPE_LSACK); - - on = ospf6_neighbor_lookup (oh->router_id, oi); - if (on == NULL) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Neighbor not found, ignore"); - return; - } - - if (on->state != OSPF6_NEIGHBOR_EXCHANGE && - on->state != OSPF6_NEIGHBOR_LOADING && - on->state != OSPF6_NEIGHBOR_FULL) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Neighbor state less than Exchange, ignore"); - return; - } - - for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header)); - p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh); - p += sizeof (struct ospf6_lsa_header)) - { - his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p); - - 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_debug ("Ignoring LSA of reserved scope"); - ospf6_lsa_delete (his); - continue; - break; - } - - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("%s acknowledged by %s", his->name, on->name); - - /* Find database copy */ - mine = ospf6_lsdb_lookup (his->header->type, his->header->id, - his->header->adv_router, lsdb); - if (mine == NULL) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("No database copy"); - ospf6_lsa_delete (his); - continue; - } - - /* Check if the LSA is on his retrans-list */ - mine = ospf6_lsdb_lookup (his->header->type, his->header->id, - his->header->adv_router, on->retrans_list); - if (mine == NULL) - { - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Not on %s's retrans-list", on->name); - ospf6_lsa_delete (his); - continue; - } - - if (ospf6_lsa_compare (his, mine) != 0) - { - /* Log this questionable acknowledgement, - and examine the next one. */ - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Questionable acknowledgement"); - ospf6_lsa_delete (his); - continue; - } - - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - zlog_debug ("Acknowledged, remove from %s's retrans-list", - on->name); - - ospf6_decrement_retrans_count (mine); - if (OSPF6_LSA_IS_MAXAGE (mine)) - ospf6_maxage_remove (on->ospf6_if->area->ospf6); - ospf6_lsdb_remove (mine, on->retrans_list); - ospf6_lsa_delete (his); - } - - assert (p == OSPF6_MESSAGE_END (oh)); + struct ospf6_neighbor *on; + char *p; + struct ospf6_lsa *his, *mine; + struct ospf6_lsdb *lsdb = NULL; + + assert(oh->type == OSPF6_MESSAGE_TYPE_LSACK); + + on = ospf6_neighbor_lookup(oh->router_id, oi); + if (on == NULL) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Neighbor not found, ignore"); + return; + } + + if (on->state != OSPF6_NEIGHBOR_EXCHANGE + && on->state != OSPF6_NEIGHBOR_LOADING + && on->state != OSPF6_NEIGHBOR_FULL) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Neighbor state less than Exchange, ignore"); + return; + } + + for (p = (char *)((caddr_t)oh + sizeof(struct ospf6_header)); + p + sizeof(struct ospf6_lsa_header) <= OSPF6_MESSAGE_END(oh); + p += sizeof(struct ospf6_lsa_header)) { + his = ospf6_lsa_create_headeronly((struct ospf6_lsa_header *)p); + + 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_debug("Ignoring LSA of reserved scope"); + ospf6_lsa_delete(his); + continue; + break; + } + + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("%s acknowledged by %s", his->name, + on->name); + + /* Find database copy */ + mine = ospf6_lsdb_lookup(his->header->type, his->header->id, + his->header->adv_router, lsdb); + if (mine == NULL) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("No database copy"); + ospf6_lsa_delete(his); + continue; + } + + /* Check if the LSA is on his retrans-list */ + mine = ospf6_lsdb_lookup(his->header->type, his->header->id, + his->header->adv_router, + on->retrans_list); + if (mine == NULL) { + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Not on %s's retrans-list", + on->name); + ospf6_lsa_delete(his); + continue; + } + + if (ospf6_lsa_compare(his, mine) != 0) { + /* Log this questionable acknowledgement, + and examine the next one. */ + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug("Questionable acknowledgement"); + ospf6_lsa_delete(his); + continue; + } + + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) + zlog_debug( + "Acknowledged, remove from %s's retrans-list", + on->name); + + ospf6_decrement_retrans_count(mine); + if (OSPF6_LSA_IS_MAXAGE(mine)) + ospf6_maxage_remove(on->ospf6_if->area->ospf6); + ospf6_lsdb_remove(mine, on->retrans_list); + ospf6_lsa_delete(his); + } + + assert(p == OSPF6_MESSAGE_END(oh)); } static u_char *recvbuf = NULL; static u_char *sendbuf = NULL; static unsigned int iobuflen = 0; -int -ospf6_iobuf_size (unsigned int size) +int ospf6_iobuf_size(unsigned int size) { - u_char *recvnew, *sendnew; - - if (size <= iobuflen) - return iobuflen; - - recvnew = XMALLOC (MTYPE_OSPF6_MESSAGE, size); - sendnew = XMALLOC (MTYPE_OSPF6_MESSAGE, size); - if (recvnew == NULL || sendnew == NULL) - { - if (recvnew) - XFREE (MTYPE_OSPF6_MESSAGE, recvnew); - if (sendnew) - XFREE (MTYPE_OSPF6_MESSAGE, sendnew); - zlog_debug ("Could not allocate I/O buffer of size %d.", size); - return iobuflen; - } - - if (recvbuf) - XFREE (MTYPE_OSPF6_MESSAGE, recvbuf); - if (sendbuf) - XFREE (MTYPE_OSPF6_MESSAGE, sendbuf); - recvbuf = recvnew; - sendbuf = sendnew; - iobuflen = size; - - return iobuflen; + u_char *recvnew, *sendnew; + + if (size <= iobuflen) + return iobuflen; + + recvnew = XMALLOC(MTYPE_OSPF6_MESSAGE, size); + sendnew = XMALLOC(MTYPE_OSPF6_MESSAGE, size); + if (recvnew == NULL || sendnew == NULL) { + if (recvnew) + XFREE(MTYPE_OSPF6_MESSAGE, recvnew); + if (sendnew) + XFREE(MTYPE_OSPF6_MESSAGE, sendnew); + zlog_debug("Could not allocate I/O buffer of size %d.", size); + return iobuflen; + } + + if (recvbuf) + XFREE(MTYPE_OSPF6_MESSAGE, recvbuf); + if (sendbuf) + XFREE(MTYPE_OSPF6_MESSAGE, sendbuf); + recvbuf = recvnew; + sendbuf = sendnew; + iobuflen = size; + + return iobuflen; } -void -ospf6_message_terminate (void) +void ospf6_message_terminate(void) { - if (recvbuf) - { - XFREE (MTYPE_OSPF6_MESSAGE, recvbuf); - recvbuf = NULL; - } - - if (sendbuf) - { - XFREE (MTYPE_OSPF6_MESSAGE, sendbuf); - sendbuf = NULL; - } - - iobuflen = 0; + if (recvbuf) { + XFREE(MTYPE_OSPF6_MESSAGE, recvbuf); + recvbuf = NULL; + } + + if (sendbuf) { + XFREE(MTYPE_OSPF6_MESSAGE, sendbuf); + sendbuf = NULL; + } + + iobuflen = 0; } -int -ospf6_receive (struct thread *thread) +int ospf6_receive(struct thread *thread) { - int sockfd; - unsigned int len; - char srcname[64], dstname[64]; - struct in6_addr src, dst; - ifindex_t ifindex; - struct iovec iovector[2]; - struct ospf6_interface *oi; - struct ospf6_header *oh; - - /* add next read thread */ - sockfd = THREAD_FD (thread); - thread_add_read (master, ospf6_receive, NULL, sockfd, NULL); - - /* initialize */ - memset (&src, 0, sizeof (src)); - memset (&dst, 0, sizeof (dst)); - ifindex = 0; - memset (recvbuf, 0, iobuflen); - iovector[0].iov_base = recvbuf; - iovector[0].iov_len = iobuflen; - iovector[1].iov_base = NULL; - iovector[1].iov_len = 0; - - /* receive message */ - len = ospf6_recvmsg (&src, &dst, &ifindex, iovector); - if (len > iobuflen) - { - zlog_err ("Excess message read"); - return 0; - } - - oi = ospf6_interface_lookup_by_ifindex (ifindex); - if (oi == NULL || oi->area == NULL || CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) - { - zlog_debug ("Message received on disabled interface"); - return 0; - } - if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE)) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - zlog_debug ("%s: Ignore message on passive interface %s", - __func__, oi->interface->name); - return 0; - } - - oh = (struct ospf6_header *) recvbuf; - if (ospf6_rxpacket_examin (oi, oh, len) != MSG_OK) - return 0; - - /* Being here means, that no sizing/alignment issues were detected in - the input packet. This renders the additional checks performed below - and also in the type-specific dispatching functions a dead code, - which can be dismissed in a cleanup-focused review round later. */ - - /* Log */ - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV)) - { - inet_ntop (AF_INET6, &src, srcname, sizeof (srcname)); - inet_ntop (AF_INET6, &dst, dstname, sizeof (dstname)); - zlog_debug ("%s received on %s", - lookup_msg(ospf6_message_type_str, oh->type, NULL), oi->interface->name); - zlog_debug (" src: %s", srcname); - zlog_debug (" dst: %s", dstname); - - switch (oh->type) - { - case OSPF6_MESSAGE_TYPE_HELLO: - ospf6_hello_print (oh); - break; - case OSPF6_MESSAGE_TYPE_DBDESC: - ospf6_dbdesc_print (oh); - break; - case OSPF6_MESSAGE_TYPE_LSREQ: - ospf6_lsreq_print (oh); - break; - case OSPF6_MESSAGE_TYPE_LSUPDATE: - ospf6_lsupdate_print (oh); - break; - case OSPF6_MESSAGE_TYPE_LSACK: - ospf6_lsack_print (oh); - break; - default: - assert (0); - } - } - - switch (oh->type) - { - case OSPF6_MESSAGE_TYPE_HELLO: - ospf6_hello_recv (&src, &dst, oi, oh); - break; - - case OSPF6_MESSAGE_TYPE_DBDESC: - ospf6_dbdesc_recv (&src, &dst, oi, oh); - break; - - case OSPF6_MESSAGE_TYPE_LSREQ: - ospf6_lsreq_recv (&src, &dst, oi, oh); - break; - - case OSPF6_MESSAGE_TYPE_LSUPDATE: - ospf6_lsupdate_recv (&src, &dst, oi, oh); - break; - - case OSPF6_MESSAGE_TYPE_LSACK: - ospf6_lsack_recv (&src, &dst, oi, oh); - break; - - default: - assert (0); - } - - return 0; + int sockfd; + unsigned int len; + char srcname[64], dstname[64]; + struct in6_addr src, dst; + ifindex_t ifindex; + struct iovec iovector[2]; + struct ospf6_interface *oi; + struct ospf6_header *oh; + + /* add next read thread */ + sockfd = THREAD_FD(thread); + thread_add_read(master, ospf6_receive, NULL, sockfd, NULL); + + /* initialize */ + memset(&src, 0, sizeof(src)); + memset(&dst, 0, sizeof(dst)); + ifindex = 0; + memset(recvbuf, 0, iobuflen); + iovector[0].iov_base = recvbuf; + iovector[0].iov_len = iobuflen; + iovector[1].iov_base = NULL; + iovector[1].iov_len = 0; + + /* receive message */ + len = ospf6_recvmsg(&src, &dst, &ifindex, iovector); + if (len > iobuflen) { + zlog_err("Excess message read"); + return 0; + } + + oi = ospf6_interface_lookup_by_ifindex(ifindex); + if (oi == NULL || oi->area == NULL + || CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) { + zlog_debug("Message received on disabled interface"); + return 0; + } + if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE)) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + zlog_debug("%s: Ignore message on passive interface %s", + __func__, oi->interface->name); + return 0; + } + + oh = (struct ospf6_header *)recvbuf; + if (ospf6_rxpacket_examin(oi, oh, len) != MSG_OK) + return 0; + + /* Being here means, that no sizing/alignment issues were detected in + the input packet. This renders the additional checks performed below + and also in the type-specific dispatching functions a dead code, + which can be dismissed in a cleanup-focused review round later. */ + + /* Log */ + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) { + inet_ntop(AF_INET6, &src, srcname, sizeof(srcname)); + inet_ntop(AF_INET6, &dst, dstname, sizeof(dstname)); + zlog_debug("%s received on %s", + lookup_msg(ospf6_message_type_str, oh->type, NULL), + oi->interface->name); + zlog_debug(" src: %s", srcname); + zlog_debug(" dst: %s", dstname); + + switch (oh->type) { + case OSPF6_MESSAGE_TYPE_HELLO: + ospf6_hello_print(oh); + break; + case OSPF6_MESSAGE_TYPE_DBDESC: + ospf6_dbdesc_print(oh); + break; + case OSPF6_MESSAGE_TYPE_LSREQ: + ospf6_lsreq_print(oh); + break; + case OSPF6_MESSAGE_TYPE_LSUPDATE: + ospf6_lsupdate_print(oh); + break; + case OSPF6_MESSAGE_TYPE_LSACK: + ospf6_lsack_print(oh); + break; + default: + assert(0); + } + } + + switch (oh->type) { + case OSPF6_MESSAGE_TYPE_HELLO: + ospf6_hello_recv(&src, &dst, oi, oh); + break; + + case OSPF6_MESSAGE_TYPE_DBDESC: + ospf6_dbdesc_recv(&src, &dst, oi, oh); + break; + + case OSPF6_MESSAGE_TYPE_LSREQ: + ospf6_lsreq_recv(&src, &dst, oi, oh); + break; + + case OSPF6_MESSAGE_TYPE_LSUPDATE: + ospf6_lsupdate_recv(&src, &dst, oi, oh); + break; + + case OSPF6_MESSAGE_TYPE_LSACK: + ospf6_lsack_recv(&src, &dst, oi, oh); + break; + + default: + assert(0); + } + + return 0; } -static void -ospf6_send (struct in6_addr *src, struct in6_addr *dst, - struct ospf6_interface *oi, struct ospf6_header *oh) +static void ospf6_send(struct in6_addr *src, struct in6_addr *dst, + struct ospf6_interface *oi, struct ospf6_header *oh) { - unsigned int len; - char srcname[64], dstname[64]; - struct iovec iovector[2]; - - /* initialize */ - iovector[0].iov_base = (caddr_t) oh; - iovector[0].iov_len = ntohs (oh->length); - iovector[1].iov_base = NULL; - iovector[1].iov_len = 0; - - /* fill OSPF header */ - oh->version = OSPFV3_VERSION; - /* message type must be set before */ - /* message length must be set before */ - oh->router_id = oi->area->ospf6->router_id; - oh->area_id = oi->area->area_id; - /* checksum is calculated by kernel */ - oh->instance_id = oi->instance_id; - oh->reserved = 0; - - /* Log */ - if (IS_OSPF6_DEBUG_MESSAGE (oh->type, SEND)) - { - inet_ntop (AF_INET6, dst, dstname, sizeof (dstname)); - if (src) - inet_ntop (AF_INET6, src, srcname, sizeof (srcname)); - else - memset (srcname, 0, sizeof (srcname)); - zlog_debug ("%s send on %s", - lookup_msg(ospf6_message_type_str, oh->type, NULL), oi->interface->name); - zlog_debug (" src: %s", srcname); - zlog_debug (" dst: %s", dstname); - - switch (oh->type) - { - case OSPF6_MESSAGE_TYPE_HELLO: - ospf6_hello_print (oh); - break; - case OSPF6_MESSAGE_TYPE_DBDESC: - ospf6_dbdesc_print (oh); - break; - case OSPF6_MESSAGE_TYPE_LSREQ: - ospf6_lsreq_print (oh); - break; - case OSPF6_MESSAGE_TYPE_LSUPDATE: - ospf6_lsupdate_print (oh); - break; - case OSPF6_MESSAGE_TYPE_LSACK: - ospf6_lsack_print (oh); - break; - default: - zlog_debug ("Unknown message"); - assert (0); - break; - } - } - - /* send message */ - len = ospf6_sendmsg (src, dst, &oi->interface->ifindex, iovector); - if (len != ntohs (oh->length)) - zlog_err ("Could not send entire message"); + unsigned int len; + char srcname[64], dstname[64]; + struct iovec iovector[2]; + + /* initialize */ + iovector[0].iov_base = (caddr_t)oh; + iovector[0].iov_len = ntohs(oh->length); + iovector[1].iov_base = NULL; + iovector[1].iov_len = 0; + + /* fill OSPF header */ + oh->version = OSPFV3_VERSION; + /* message type must be set before */ + /* message length must be set before */ + oh->router_id = oi->area->ospf6->router_id; + oh->area_id = oi->area->area_id; + /* checksum is calculated by kernel */ + oh->instance_id = oi->instance_id; + oh->reserved = 0; + + /* Log */ + if (IS_OSPF6_DEBUG_MESSAGE(oh->type, SEND)) { + inet_ntop(AF_INET6, dst, dstname, sizeof(dstname)); + if (src) + inet_ntop(AF_INET6, src, srcname, sizeof(srcname)); + else + memset(srcname, 0, sizeof(srcname)); + zlog_debug("%s send on %s", + lookup_msg(ospf6_message_type_str, oh->type, NULL), + oi->interface->name); + zlog_debug(" src: %s", srcname); + zlog_debug(" dst: %s", dstname); + + switch (oh->type) { + case OSPF6_MESSAGE_TYPE_HELLO: + ospf6_hello_print(oh); + break; + case OSPF6_MESSAGE_TYPE_DBDESC: + ospf6_dbdesc_print(oh); + break; + case OSPF6_MESSAGE_TYPE_LSREQ: + ospf6_lsreq_print(oh); + break; + case OSPF6_MESSAGE_TYPE_LSUPDATE: + ospf6_lsupdate_print(oh); + break; + case OSPF6_MESSAGE_TYPE_LSACK: + ospf6_lsack_print(oh); + break; + default: + zlog_debug("Unknown message"); + assert(0); + break; + } + } + + /* send message */ + len = ospf6_sendmsg(src, dst, &oi->interface->ifindex, iovector); + if (len != ntohs(oh->length)) + zlog_err("Could not send entire message"); } -static uint32_t -ospf6_packet_max(struct ospf6_interface *oi) +static uint32_t ospf6_packet_max(struct ospf6_interface *oi) { - assert (oi->ifmtu > sizeof (struct ip6_hdr)); - return oi->ifmtu - (sizeof (struct ip6_hdr)); + assert(oi->ifmtu > sizeof(struct ip6_hdr)); + return oi->ifmtu - (sizeof(struct ip6_hdr)); } -int -ospf6_hello_send (struct thread *thread) +int ospf6_hello_send(struct thread *thread) { - struct ospf6_interface *oi; - struct ospf6_header *oh; - struct ospf6_hello *hello; - u_char *p; - struct listnode *node, *nnode; - struct ospf6_neighbor *on; - - oi = (struct ospf6_interface *) THREAD_ARG (thread); - oi->thread_send_hello = (struct thread *) NULL; - - if (oi->state <= OSPF6_INTERFACE_DOWN) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO, SEND)) - zlog_debug ("Unable to send Hello on down interface %s", - oi->interface->name); - return 0; - } - - if (iobuflen == 0) - { - zlog_debug ("Unable to send Hello on interface %s iobuflen is 0", - oi->interface->name); - return 0; - } - - /* set next thread */ - thread_add_timer (master, ospf6_hello_send, oi, oi->hello_interval, &oi->thread_send_hello); - - memset (sendbuf, 0, iobuflen); - oh = (struct ospf6_header *) sendbuf; - hello = (struct ospf6_hello *)((caddr_t) oh + sizeof (struct ospf6_header)); - - hello->interface_id = htonl (oi->interface->ifindex); - hello->priority = oi->priority; - hello->options[0] = oi->area->options[0]; - hello->options[1] = oi->area->options[1]; - hello->options[2] = oi->area->options[2]; - hello->hello_interval = htons (oi->hello_interval); - hello->dead_interval = htons (oi->dead_interval); - hello->drouter = oi->drouter; - hello->bdrouter = oi->bdrouter; - - p = (u_char *)((caddr_t) hello + sizeof (struct ospf6_hello)); - - for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on)) - { - if (on->state < OSPF6_NEIGHBOR_INIT) - continue; - - if (p - sendbuf + sizeof (u_int32_t) > ospf6_packet_max(oi)) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO, SEND)) - zlog_debug ("sending Hello message: exceeds I/F MTU"); - break; - } - - memcpy (p, &on->router_id, sizeof (u_int32_t)); - p += sizeof (u_int32_t); - } - - oh->type = OSPF6_MESSAGE_TYPE_HELLO; - oh->length = htons (p - sendbuf); - - ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh); - return 0; + struct ospf6_interface *oi; + struct ospf6_header *oh; + struct ospf6_hello *hello; + u_char *p; + struct listnode *node, *nnode; + struct ospf6_neighbor *on; + + oi = (struct ospf6_interface *)THREAD_ARG(thread); + oi->thread_send_hello = (struct thread *)NULL; + + if (oi->state <= OSPF6_INTERFACE_DOWN) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_HELLO, SEND)) + zlog_debug("Unable to send Hello on down interface %s", + oi->interface->name); + return 0; + } + + if (iobuflen == 0) { + zlog_debug("Unable to send Hello on interface %s iobuflen is 0", + oi->interface->name); + return 0; + } + + /* set next thread */ + thread_add_timer(master, ospf6_hello_send, oi, oi->hello_interval, + &oi->thread_send_hello); + + memset(sendbuf, 0, iobuflen); + oh = (struct ospf6_header *)sendbuf; + hello = (struct ospf6_hello *)((caddr_t)oh + + sizeof(struct ospf6_header)); + + hello->interface_id = htonl(oi->interface->ifindex); + hello->priority = oi->priority; + hello->options[0] = oi->area->options[0]; + hello->options[1] = oi->area->options[1]; + hello->options[2] = oi->area->options[2]; + hello->hello_interval = htons(oi->hello_interval); + hello->dead_interval = htons(oi->dead_interval); + hello->drouter = oi->drouter; + hello->bdrouter = oi->bdrouter; + + p = (u_char *)((caddr_t)hello + sizeof(struct ospf6_hello)); + + for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) { + if (on->state < OSPF6_NEIGHBOR_INIT) + continue; + + if (p - sendbuf + sizeof(u_int32_t) > ospf6_packet_max(oi)) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_HELLO, + SEND)) + zlog_debug( + "sending Hello message: exceeds I/F MTU"); + break; + } + + memcpy(p, &on->router_id, sizeof(u_int32_t)); + p += sizeof(u_int32_t); + } + + oh->type = OSPF6_MESSAGE_TYPE_HELLO; + oh->length = htons(p - sendbuf); + + ospf6_send(oi->linklocal_addr, &allspfrouters6, oi, oh); + return 0; } -int -ospf6_dbdesc_send (struct thread *thread) +int ospf6_dbdesc_send(struct thread *thread) { - struct ospf6_neighbor *on; - struct ospf6_header *oh; - struct ospf6_dbdesc *dbdesc; - u_char *p; - struct ospf6_lsa *lsa; - struct in6_addr *dst; - - on = (struct ospf6_neighbor *) THREAD_ARG (thread); - on->thread_send_dbdesc = (struct thread *) NULL; - - if (on->state < OSPF6_NEIGHBOR_EXSTART) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_DBDESC, SEND)) - zlog_debug ("Quit to send DbDesc to neighbor %s state %s", - on->name, ospf6_neighbor_state_str[on->state]); - return 0; - } - - /* set next thread if master */ - if (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT)) - thread_add_timer (master, ospf6_dbdesc_send, on, - on->ospf6_if->rxmt_interval, - &on->thread_send_dbdesc); - - memset (sendbuf, 0, iobuflen); - oh = (struct ospf6_header *) sendbuf; - dbdesc = (struct ospf6_dbdesc *)((caddr_t) oh + - sizeof (struct ospf6_header)); - - /* if this is initial one, initialize sequence number for DbDesc */ - if (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT) && - (on->dbdesc_seqnum == 0)) - { - on->dbdesc_seqnum = monotime(NULL); - } - - dbdesc->options[0] = on->ospf6_if->area->options[0]; - dbdesc->options[1] = on->ospf6_if->area->options[1]; - dbdesc->options[2] = on->ospf6_if->area->options[2]; - dbdesc->ifmtu = htons (on->ospf6_if->ifmtu); - dbdesc->bits = on->dbdesc_bits; - dbdesc->seqnum = htonl (on->dbdesc_seqnum); - - /* if this is not initial one, set LSA headers in dbdesc */ - p = (u_char *)((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc)); - if (! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT)) - { - for (ALL_LSDB(on->dbdesc_list, lsa)) - { - ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay); - - /* MTU check */ - if (p - sendbuf + sizeof (struct ospf6_lsa_header) > - ospf6_packet_max(on->ospf6_if)) - { - ospf6_lsdb_lsa_unlock (lsa); - break; - } - memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header)); - p += sizeof (struct ospf6_lsa_header); - } - } - - oh->type = OSPF6_MESSAGE_TYPE_DBDESC; - oh->length = htons (p - sendbuf); - - - if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT) - dst = &allspfrouters6; - else - dst = &on->linklocal_addr; - - ospf6_send (on->ospf6_if->linklocal_addr, dst, on->ospf6_if, oh); - - return 0; + struct ospf6_neighbor *on; + struct ospf6_header *oh; + struct ospf6_dbdesc *dbdesc; + u_char *p; + struct ospf6_lsa *lsa; + struct in6_addr *dst; + + on = (struct ospf6_neighbor *)THREAD_ARG(thread); + on->thread_send_dbdesc = (struct thread *)NULL; + + if (on->state < OSPF6_NEIGHBOR_EXSTART) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_DBDESC, SEND)) + zlog_debug( + "Quit to send DbDesc to neighbor %s state %s", + on->name, ospf6_neighbor_state_str[on->state]); + return 0; + } + + /* set next thread if master */ + if (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT)) + thread_add_timer(master, ospf6_dbdesc_send, on, + on->ospf6_if->rxmt_interval, + &on->thread_send_dbdesc); + + memset(sendbuf, 0, iobuflen); + oh = (struct ospf6_header *)sendbuf; + dbdesc = (struct ospf6_dbdesc *)((caddr_t)oh + + sizeof(struct ospf6_header)); + + /* if this is initial one, initialize sequence number for DbDesc */ + if (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT) + && (on->dbdesc_seqnum == 0)) { + on->dbdesc_seqnum = monotime(NULL); + } + + dbdesc->options[0] = on->ospf6_if->area->options[0]; + dbdesc->options[1] = on->ospf6_if->area->options[1]; + dbdesc->options[2] = on->ospf6_if->area->options[2]; + dbdesc->ifmtu = htons(on->ospf6_if->ifmtu); + dbdesc->bits = on->dbdesc_bits; + dbdesc->seqnum = htonl(on->dbdesc_seqnum); + + /* if this is not initial one, set LSA headers in dbdesc */ + p = (u_char *)((caddr_t)dbdesc + sizeof(struct ospf6_dbdesc)); + if (!CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT)) { + for (ALL_LSDB(on->dbdesc_list, lsa)) { + ospf6_lsa_age_update_to_send(lsa, + on->ospf6_if->transdelay); + + /* MTU check */ + if (p - sendbuf + sizeof(struct ospf6_lsa_header) + > ospf6_packet_max(on->ospf6_if)) { + ospf6_lsdb_lsa_unlock(lsa); + break; + } + memcpy(p, lsa->header, sizeof(struct ospf6_lsa_header)); + p += sizeof(struct ospf6_lsa_header); + } + } + + oh->type = OSPF6_MESSAGE_TYPE_DBDESC; + oh->length = htons(p - sendbuf); + + + if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT) + dst = &allspfrouters6; + else + dst = &on->linklocal_addr; + + ospf6_send(on->ospf6_if->linklocal_addr, dst, on->ospf6_if, oh); + + return 0; } -int -ospf6_dbdesc_send_newone (struct thread *thread) +int ospf6_dbdesc_send_newone(struct thread *thread) { - struct ospf6_neighbor *on; - struct ospf6_lsa *lsa; - unsigned int size = 0; - - on = (struct ospf6_neighbor *) THREAD_ARG (thread); - ospf6_lsdb_remove_all (on->dbdesc_list); - - /* move LSAs from summary_list to dbdesc_list (within neighbor structure) - so that ospf6_send_dbdesc () can send those LSAs */ - size = sizeof (struct ospf6_lsa_header) + sizeof (struct ospf6_dbdesc); - for (ALL_LSDB(on->summary_list, lsa)) - { - if (size + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if)) - { - ospf6_lsdb_lsa_unlock (lsa); - break; - } - - ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->dbdesc_list); - ospf6_lsdb_remove (lsa, on->summary_list); - size += sizeof (struct ospf6_lsa_header); - } - - if (on->summary_list->count == 0) - UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT); - - /* If slave, More bit check must be done here */ - if (! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT) && /* Slave */ - ! CHECK_FLAG (on->dbdesc_last.bits, OSPF6_DBDESC_MBIT) && - ! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT)) - thread_add_event (master, exchange_done, on, 0, NULL); - - thread_execute (master, ospf6_dbdesc_send, on, 0); - return 0; + struct ospf6_neighbor *on; + struct ospf6_lsa *lsa; + unsigned int size = 0; + + on = (struct ospf6_neighbor *)THREAD_ARG(thread); + ospf6_lsdb_remove_all(on->dbdesc_list); + + /* move LSAs from summary_list to dbdesc_list (within neighbor + structure) + so that ospf6_send_dbdesc () can send those LSAs */ + size = sizeof(struct ospf6_lsa_header) + sizeof(struct ospf6_dbdesc); + for (ALL_LSDB(on->summary_list, lsa)) { + if (size + sizeof(struct ospf6_lsa_header) + > ospf6_packet_max(on->ospf6_if)) { + ospf6_lsdb_lsa_unlock(lsa); + break; + } + + ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->dbdesc_list); + ospf6_lsdb_remove(lsa, on->summary_list); + size += sizeof(struct ospf6_lsa_header); + } + + if (on->summary_list->count == 0) + UNSET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT); + + /* If slave, More bit check must be done here */ + if (!CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT) && /* Slave */ + !CHECK_FLAG(on->dbdesc_last.bits, OSPF6_DBDESC_MBIT) + && !CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT)) + thread_add_event(master, exchange_done, on, 0, NULL); + + thread_execute(master, ospf6_dbdesc_send, on, 0); + return 0; } -int -ospf6_lsreq_send (struct thread *thread) +int ospf6_lsreq_send(struct thread *thread) { - struct ospf6_neighbor *on; - struct ospf6_header *oh; - struct ospf6_lsreq_entry *e; - u_char *p; - struct ospf6_lsa *lsa, *last_req; - - on = (struct ospf6_neighbor *) THREAD_ARG (thread); - on->thread_send_lsreq = (struct thread *) NULL; - - /* LSReq will be sent only in ExStart or Loading */ - if (on->state != OSPF6_NEIGHBOR_EXCHANGE && - on->state != OSPF6_NEIGHBOR_LOADING) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSREQ, SEND)) - zlog_debug ("Quit to send LSReq to neighbor %s state %s", - on->name, ospf6_neighbor_state_str[on->state]); - return 0; - } - - /* schedule loading_done if request list is empty */ - if (on->request_list->count == 0) - { - thread_add_event (master, loading_done, on, 0, NULL); - return 0; - } - - memset (sendbuf, 0, iobuflen); - oh = (struct ospf6_header *) sendbuf; - last_req = NULL; - - /* set Request entries in lsreq */ - p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header)); - for (ALL_LSDB(on->request_list, lsa)) - { - /* MTU check */ - if (p - sendbuf + sizeof (struct ospf6_lsreq_entry) > ospf6_packet_max(on->ospf6_if)) - { - ospf6_lsdb_lsa_unlock (lsa); - break; - } - - e = (struct ospf6_lsreq_entry *) p; - e->type = lsa->header->type; - e->id = lsa->header->id; - e->adv_router = lsa->header->adv_router; - p += sizeof (struct ospf6_lsreq_entry); - last_req = lsa; - } - - if (last_req != NULL) - { - if (on->last_ls_req != NULL) - { - ospf6_lsa_unlock (on->last_ls_req); - } - ospf6_lsa_lock (last_req); - on->last_ls_req = last_req; - } - - oh->type = OSPF6_MESSAGE_TYPE_LSREQ; - oh->length = htons (p - sendbuf); - - if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT) - ospf6_send (on->ospf6_if->linklocal_addr, &allspfrouters6, - on->ospf6_if, oh); - else - ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr, - on->ospf6_if, oh); - - /* set next thread */ - if (on->request_list->count != 0) - { - on->thread_send_lsreq = NULL; - thread_add_timer(master, ospf6_lsreq_send, on, on->ospf6_if->rxmt_interval, - &on->thread_send_lsreq); - } - - return 0; + struct ospf6_neighbor *on; + struct ospf6_header *oh; + struct ospf6_lsreq_entry *e; + u_char *p; + struct ospf6_lsa *lsa, *last_req; + + on = (struct ospf6_neighbor *)THREAD_ARG(thread); + on->thread_send_lsreq = (struct thread *)NULL; + + /* LSReq will be sent only in ExStart or Loading */ + if (on->state != OSPF6_NEIGHBOR_EXCHANGE + && on->state != OSPF6_NEIGHBOR_LOADING) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSREQ, SEND)) + zlog_debug("Quit to send LSReq to neighbor %s state %s", + on->name, + ospf6_neighbor_state_str[on->state]); + return 0; + } + + /* schedule loading_done if request list is empty */ + if (on->request_list->count == 0) { + thread_add_event(master, loading_done, on, 0, NULL); + return 0; + } + + memset(sendbuf, 0, iobuflen); + oh = (struct ospf6_header *)sendbuf; + last_req = NULL; + + /* set Request entries in lsreq */ + p = (u_char *)((caddr_t)oh + sizeof(struct ospf6_header)); + for (ALL_LSDB(on->request_list, lsa)) { + /* MTU check */ + if (p - sendbuf + sizeof(struct ospf6_lsreq_entry) + > ospf6_packet_max(on->ospf6_if)) { + ospf6_lsdb_lsa_unlock(lsa); + break; + } + + e = (struct ospf6_lsreq_entry *)p; + e->type = lsa->header->type; + e->id = lsa->header->id; + e->adv_router = lsa->header->adv_router; + p += sizeof(struct ospf6_lsreq_entry); + last_req = lsa; + } + + if (last_req != NULL) { + if (on->last_ls_req != NULL) { + ospf6_lsa_unlock(on->last_ls_req); + } + ospf6_lsa_lock(last_req); + on->last_ls_req = last_req; + } + + oh->type = OSPF6_MESSAGE_TYPE_LSREQ; + oh->length = htons(p - sendbuf); + + if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT) + ospf6_send(on->ospf6_if->linklocal_addr, &allspfrouters6, + on->ospf6_if, oh); + else + ospf6_send(on->ospf6_if->linklocal_addr, &on->linklocal_addr, + on->ospf6_if, oh); + + /* set next thread */ + if (on->request_list->count != 0) { + on->thread_send_lsreq = NULL; + thread_add_timer(master, ospf6_lsreq_send, on, + on->ospf6_if->rxmt_interval, + &on->thread_send_lsreq); + } + + return 0; } -int -ospf6_lsupdate_send_neighbor (struct thread *thread) +int ospf6_lsupdate_send_neighbor(struct thread *thread) { - struct ospf6_neighbor *on; - struct ospf6_header *oh; - struct ospf6_lsupdate *lsupdate; - u_char *p; - int lsa_cnt; - struct ospf6_lsa *lsa; - - 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_debug ("LSUpdate to neighbor %s", on->name); - - if (on->state < OSPF6_NEIGHBOR_EXCHANGE) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND)) - zlog_debug ("Quit to send (neighbor state %s)", - ospf6_neighbor_state_str[on->state]); - return 0; - } - - memset (sendbuf, 0, iobuflen); - oh = (struct ospf6_header *) sendbuf; - lsupdate = (struct ospf6_lsupdate *) - ((caddr_t) oh + sizeof (struct ospf6_header)); - - p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate)); - lsa_cnt = 0; - - /* lsupdate_list lists those LSA which doesn't need to be - retransmitted. remove those from the list */ - for (ALL_LSDB(on->lsupdate_list, lsa)) - { - /* MTU check */ - if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header)) - > ospf6_packet_max(on->ospf6_if)) - { - ospf6_lsdb_lsa_unlock (lsa); - break; - } - - 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); - lsa_cnt++; - - assert (lsa->lock == 2); - ospf6_lsdb_remove (lsa, on->lsupdate_list); - } - - if (lsa_cnt) - { - oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE; - oh->length = htons (p - sendbuf); - lsupdate->lsa_number = htonl (lsa_cnt); - - if ((on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT) || - (on->ospf6_if->state == OSPF6_INTERFACE_DR) || - (on->ospf6_if->state == OSPF6_INTERFACE_BDR)) - ospf6_send (on->ospf6_if->linklocal_addr, &allspfrouters6, - on->ospf6_if, oh); - else - ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr, - on->ospf6_if, oh); - } - - /* The addresses used for retransmissions are different from those sent the - first time and so we need to separate them here. - */ - memset (sendbuf, 0, iobuflen); - oh = (struct ospf6_header *) sendbuf; - lsupdate = (struct ospf6_lsupdate *) - ((caddr_t) oh + sizeof (struct ospf6_header)); - p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate)); - lsa_cnt = 0; - - for (ALL_LSDB(on->retrans_list, lsa)) - { - /* MTU check */ - if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header)) - > ospf6_packet_max(on->ospf6_if)) - { - ospf6_lsdb_lsa_unlock (lsa); - break; - } - - 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); - lsa_cnt++; - } - - if (lsa_cnt) - { - oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE; - oh->length = htons (p - sendbuf); - lsupdate->lsa_number = htonl (lsa_cnt); - - if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT) - ospf6_send (on->ospf6_if->linklocal_addr, &allspfrouters6, - on->ospf6_if, oh); - else - ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr, - on->ospf6_if, oh); - } - - if (on->lsupdate_list->count != 0) { - on->thread_send_lsupdate = NULL; - thread_add_event(master, ospf6_lsupdate_send_neighbor, on, 0, - &on->thread_send_lsupdate); - } - else if (on->retrans_list->count != 0) { - on->thread_send_lsupdate = NULL; - thread_add_timer(master, ospf6_lsupdate_send_neighbor, on, on->ospf6_if->rxmt_interval, - &on->thread_send_lsupdate); - } - return 0; + struct ospf6_neighbor *on; + struct ospf6_header *oh; + struct ospf6_lsupdate *lsupdate; + u_char *p; + int lsa_cnt; + struct ospf6_lsa *lsa; + + 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_debug("LSUpdate to neighbor %s", on->name); + + if (on->state < OSPF6_NEIGHBOR_EXCHANGE) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE, SEND)) + zlog_debug("Quit to send (neighbor state %s)", + ospf6_neighbor_state_str[on->state]); + return 0; + } + + memset(sendbuf, 0, iobuflen); + oh = (struct ospf6_header *)sendbuf; + lsupdate = (struct ospf6_lsupdate *)((caddr_t)oh + + sizeof(struct ospf6_header)); + + p = (u_char *)((caddr_t)lsupdate + sizeof(struct ospf6_lsupdate)); + lsa_cnt = 0; + + /* lsupdate_list lists those LSA which doesn't need to be + retransmitted. remove those from the list */ + for (ALL_LSDB(on->lsupdate_list, lsa)) { + /* MTU check */ + if ((p - sendbuf + (unsigned int)OSPF6_LSA_SIZE(lsa->header)) + > ospf6_packet_max(on->ospf6_if)) { + ospf6_lsdb_lsa_unlock(lsa); + break; + } + + 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); + lsa_cnt++; + + assert(lsa->lock == 2); + ospf6_lsdb_remove(lsa, on->lsupdate_list); + } + + if (lsa_cnt) { + oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE; + oh->length = htons(p - sendbuf); + lsupdate->lsa_number = htonl(lsa_cnt); + + if ((on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT) + || (on->ospf6_if->state == OSPF6_INTERFACE_DR) + || (on->ospf6_if->state == OSPF6_INTERFACE_BDR)) + ospf6_send(on->ospf6_if->linklocal_addr, + &allspfrouters6, on->ospf6_if, oh); + else + ospf6_send(on->ospf6_if->linklocal_addr, + &on->linklocal_addr, on->ospf6_if, oh); + } + + /* The addresses used for retransmissions are different from those sent + the + first time and so we need to separate them here. + */ + memset(sendbuf, 0, iobuflen); + oh = (struct ospf6_header *)sendbuf; + lsupdate = (struct ospf6_lsupdate *)((caddr_t)oh + + sizeof(struct ospf6_header)); + p = (u_char *)((caddr_t)lsupdate + sizeof(struct ospf6_lsupdate)); + lsa_cnt = 0; + + for (ALL_LSDB(on->retrans_list, lsa)) { + /* MTU check */ + if ((p - sendbuf + (unsigned int)OSPF6_LSA_SIZE(lsa->header)) + > ospf6_packet_max(on->ospf6_if)) { + ospf6_lsdb_lsa_unlock(lsa); + break; + } + + 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); + lsa_cnt++; + } + + if (lsa_cnt) { + oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE; + oh->length = htons(p - sendbuf); + lsupdate->lsa_number = htonl(lsa_cnt); + + if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT) + ospf6_send(on->ospf6_if->linklocal_addr, + &allspfrouters6, on->ospf6_if, oh); + else + ospf6_send(on->ospf6_if->linklocal_addr, + &on->linklocal_addr, on->ospf6_if, oh); + } + + if (on->lsupdate_list->count != 0) { + on->thread_send_lsupdate = NULL; + thread_add_event(master, ospf6_lsupdate_send_neighbor, on, 0, + &on->thread_send_lsupdate); + } else if (on->retrans_list->count != 0) { + on->thread_send_lsupdate = NULL; + thread_add_timer(master, ospf6_lsupdate_send_neighbor, on, + on->ospf6_if->rxmt_interval, + &on->thread_send_lsupdate); + } + return 0; } -int -ospf6_lsupdate_send_interface (struct thread *thread) +int ospf6_lsupdate_send_interface(struct thread *thread) { - struct ospf6_interface *oi; - struct ospf6_header *oh; - struct ospf6_lsupdate *lsupdate; - u_char *p; - int lsa_cnt; - struct ospf6_lsa *lsa; - - oi = (struct ospf6_interface *) THREAD_ARG (thread); - oi->thread_send_lsupdate = (struct thread *) NULL; - - if (oi->state <= OSPF6_INTERFACE_WAITING) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND)) - zlog_debug ("Quit to send LSUpdate to interface %s state %s", - oi->interface->name, ospf6_interface_state_str[oi->state]); - return 0; - } - - /* if we have nothing to send, return */ - if (oi->lsupdate_list->count == 0) - return 0; - - memset (sendbuf, 0, iobuflen); - oh = (struct ospf6_header *) sendbuf; - lsupdate = (struct ospf6_lsupdate *)((caddr_t) oh + - sizeof (struct ospf6_header)); - - p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate)); - lsa_cnt = 0; - - for (ALL_LSDB(oi->lsupdate_list, lsa)) - { - /* MTU check */ - if ( (p - sendbuf + ((unsigned int)OSPF6_LSA_SIZE (lsa->header))) - > ospf6_packet_max(oi)) - { - ospf6_lsdb_lsa_unlock (lsa); - break; - } - - ospf6_lsa_age_update_to_send (lsa, oi->transdelay); - memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header)); - p += OSPF6_LSA_SIZE (lsa->header); - lsa_cnt++; - - assert (lsa->lock == 2); - ospf6_lsdb_remove (lsa, oi->lsupdate_list); - } - - if (lsa_cnt) - { - lsupdate->lsa_number = htonl (lsa_cnt); - - oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE; - oh->length = htons (p - sendbuf); - - if ((oi->state == OSPF6_INTERFACE_POINTTOPOINT) || - (oi->state == OSPF6_INTERFACE_DR) || - (oi->state == OSPF6_INTERFACE_BDR)) - ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh); - else - ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh); - - } - - if (oi->lsupdate_list->count > 0) - { - oi->thread_send_lsupdate = NULL; - thread_add_event(master, ospf6_lsupdate_send_interface, oi, 0, - &oi->thread_send_lsupdate); - } - - return 0; + struct ospf6_interface *oi; + struct ospf6_header *oh; + struct ospf6_lsupdate *lsupdate; + u_char *p; + int lsa_cnt; + struct ospf6_lsa *lsa; + + oi = (struct ospf6_interface *)THREAD_ARG(thread); + oi->thread_send_lsupdate = (struct thread *)NULL; + + if (oi->state <= OSPF6_INTERFACE_WAITING) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE, SEND)) + zlog_debug( + "Quit to send LSUpdate to interface %s state %s", + oi->interface->name, + ospf6_interface_state_str[oi->state]); + return 0; + } + + /* if we have nothing to send, return */ + if (oi->lsupdate_list->count == 0) + return 0; + + memset(sendbuf, 0, iobuflen); + oh = (struct ospf6_header *)sendbuf; + lsupdate = (struct ospf6_lsupdate *)((caddr_t)oh + + sizeof(struct ospf6_header)); + + p = (u_char *)((caddr_t)lsupdate + sizeof(struct ospf6_lsupdate)); + lsa_cnt = 0; + + for (ALL_LSDB(oi->lsupdate_list, lsa)) { + /* MTU check */ + if ((p - sendbuf + ((unsigned int)OSPF6_LSA_SIZE(lsa->header))) + > ospf6_packet_max(oi)) { + ospf6_lsdb_lsa_unlock(lsa); + break; + } + + ospf6_lsa_age_update_to_send(lsa, oi->transdelay); + memcpy(p, lsa->header, OSPF6_LSA_SIZE(lsa->header)); + p += OSPF6_LSA_SIZE(lsa->header); + lsa_cnt++; + + assert(lsa->lock == 2); + ospf6_lsdb_remove(lsa, oi->lsupdate_list); + } + + if (lsa_cnt) { + lsupdate->lsa_number = htonl(lsa_cnt); + + oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE; + oh->length = htons(p - sendbuf); + + if ((oi->state == OSPF6_INTERFACE_POINTTOPOINT) + || (oi->state == OSPF6_INTERFACE_DR) + || (oi->state == OSPF6_INTERFACE_BDR)) + ospf6_send(oi->linklocal_addr, &allspfrouters6, oi, oh); + else + ospf6_send(oi->linklocal_addr, &alldrouters6, oi, oh); + } + + if (oi->lsupdate_list->count > 0) { + oi->thread_send_lsupdate = NULL; + thread_add_event(master, ospf6_lsupdate_send_interface, oi, 0, + &oi->thread_send_lsupdate); + } + + return 0; } -int -ospf6_lsack_send_neighbor (struct thread *thread) +int ospf6_lsack_send_neighbor(struct thread *thread) { - struct ospf6_neighbor *on; - struct ospf6_header *oh; - u_char *p; - struct ospf6_lsa *lsa; - int lsa_cnt = 0; - - on = (struct ospf6_neighbor *) THREAD_ARG (thread); - on->thread_send_lsack = (struct thread *) NULL; - - if (on->state < OSPF6_NEIGHBOR_EXCHANGE) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSACK, SEND)) - zlog_debug ("Quit to send LSAck to neighbor %s state %s", - on->name, ospf6_neighbor_state_str[on->state]); - return 0; - } - - /* if we have nothing to send, return */ - if (on->lsack_list->count == 0) - return 0; - - memset (sendbuf, 0, iobuflen); - oh = (struct ospf6_header *) sendbuf; - - p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header)); - - for (ALL_LSDB(on->lsack_list, lsa)) - { - /* MTU check */ - if (p - sendbuf + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if)) - { - /* if we run out of packet size/space here, - better to try again soon. */ - THREAD_OFF (on->thread_send_lsack); - thread_add_event (master, ospf6_lsack_send_neighbor, on, 0, &on->thread_send_lsack); - - ospf6_lsdb_lsa_unlock (lsa); - break; - } - - ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay); - memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header)); - p += sizeof (struct ospf6_lsa_header); - - assert (lsa->lock == 2); - ospf6_lsdb_remove (lsa, on->lsack_list); - lsa_cnt++; - } - - if (lsa_cnt) - { - oh->type = OSPF6_MESSAGE_TYPE_LSACK; - oh->length = htons (p - sendbuf); - - ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr, - on->ospf6_if, oh); - } - - if (on->lsack_list->count > 0) - thread_add_event (master, ospf6_lsack_send_neighbor, on, 0, &on->thread_send_lsack); - - return 0; + struct ospf6_neighbor *on; + struct ospf6_header *oh; + u_char *p; + struct ospf6_lsa *lsa; + int lsa_cnt = 0; + + on = (struct ospf6_neighbor *)THREAD_ARG(thread); + on->thread_send_lsack = (struct thread *)NULL; + + if (on->state < OSPF6_NEIGHBOR_EXCHANGE) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSACK, SEND)) + zlog_debug("Quit to send LSAck to neighbor %s state %s", + on->name, + ospf6_neighbor_state_str[on->state]); + return 0; + } + + /* if we have nothing to send, return */ + if (on->lsack_list->count == 0) + return 0; + + memset(sendbuf, 0, iobuflen); + oh = (struct ospf6_header *)sendbuf; + + p = (u_char *)((caddr_t)oh + sizeof(struct ospf6_header)); + + for (ALL_LSDB(on->lsack_list, lsa)) { + /* MTU check */ + if (p - sendbuf + sizeof(struct ospf6_lsa_header) + > ospf6_packet_max(on->ospf6_if)) { + /* if we run out of packet size/space here, + better to try again soon. */ + THREAD_OFF(on->thread_send_lsack); + thread_add_event(master, ospf6_lsack_send_neighbor, on, + 0, &on->thread_send_lsack); + + ospf6_lsdb_lsa_unlock(lsa); + break; + } + + ospf6_lsa_age_update_to_send(lsa, on->ospf6_if->transdelay); + memcpy(p, lsa->header, sizeof(struct ospf6_lsa_header)); + p += sizeof(struct ospf6_lsa_header); + + assert(lsa->lock == 2); + ospf6_lsdb_remove(lsa, on->lsack_list); + lsa_cnt++; + } + + if (lsa_cnt) { + oh->type = OSPF6_MESSAGE_TYPE_LSACK; + oh->length = htons(p - sendbuf); + + ospf6_send(on->ospf6_if->linklocal_addr, &on->linklocal_addr, + on->ospf6_if, oh); + } + + if (on->lsack_list->count > 0) + thread_add_event(master, ospf6_lsack_send_neighbor, on, 0, + &on->thread_send_lsack); + + return 0; } -int -ospf6_lsack_send_interface (struct thread *thread) +int ospf6_lsack_send_interface(struct thread *thread) { - struct ospf6_interface *oi; - struct ospf6_header *oh; - u_char *p; - struct ospf6_lsa *lsa; - int lsa_cnt = 0; - - oi = (struct ospf6_interface *) THREAD_ARG (thread); - oi->thread_send_lsack = (struct thread *) NULL; - - if (oi->state <= OSPF6_INTERFACE_WAITING) - { - if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSACK, SEND)) - zlog_debug ("Quit to send LSAck to interface %s state %s", - oi->interface->name, ospf6_interface_state_str[oi->state]); - return 0; - } - - /* if we have nothing to send, return */ - if (oi->lsack_list->count == 0) - return 0; - - memset (sendbuf, 0, iobuflen); - oh = (struct ospf6_header *) sendbuf; - - p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header)); - - for (ALL_LSDB(oi->lsack_list, lsa)) - { - /* MTU check */ - if (p - sendbuf + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(oi)) - { - /* if we run out of packet size/space here, - better to try again soon. */ - THREAD_OFF (oi->thread_send_lsack); - thread_add_event (master, ospf6_lsack_send_interface, oi, 0, - &oi->thread_send_lsack); - - ospf6_lsdb_lsa_unlock (lsa); - break; - } - - ospf6_lsa_age_update_to_send (lsa, oi->transdelay); - memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header)); - p += sizeof (struct ospf6_lsa_header); - - assert (lsa->lock == 2); - ospf6_lsdb_remove (lsa, oi->lsack_list); - lsa_cnt++; - } - - if (lsa_cnt) - { - oh->type = OSPF6_MESSAGE_TYPE_LSACK; - oh->length = htons (p - sendbuf); - - if ((oi->state == OSPF6_INTERFACE_POINTTOPOINT) || - (oi->state == OSPF6_INTERFACE_DR) || - (oi->state == OSPF6_INTERFACE_BDR)) - ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh); - else - ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh); - } - - if (oi->lsack_list->count > 0) - thread_add_event (master, ospf6_lsack_send_interface, oi, 0, &oi->thread_send_lsack); - - return 0; + struct ospf6_interface *oi; + struct ospf6_header *oh; + u_char *p; + struct ospf6_lsa *lsa; + int lsa_cnt = 0; + + oi = (struct ospf6_interface *)THREAD_ARG(thread); + oi->thread_send_lsack = (struct thread *)NULL; + + if (oi->state <= OSPF6_INTERFACE_WAITING) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSACK, SEND)) + zlog_debug( + "Quit to send LSAck to interface %s state %s", + oi->interface->name, + ospf6_interface_state_str[oi->state]); + return 0; + } + + /* if we have nothing to send, return */ + if (oi->lsack_list->count == 0) + return 0; + + memset(sendbuf, 0, iobuflen); + oh = (struct ospf6_header *)sendbuf; + + p = (u_char *)((caddr_t)oh + sizeof(struct ospf6_header)); + + for (ALL_LSDB(oi->lsack_list, lsa)) { + /* MTU check */ + if (p - sendbuf + sizeof(struct ospf6_lsa_header) + > ospf6_packet_max(oi)) { + /* if we run out of packet size/space here, + better to try again soon. */ + THREAD_OFF(oi->thread_send_lsack); + thread_add_event(master, ospf6_lsack_send_interface, oi, + 0, &oi->thread_send_lsack); + + ospf6_lsdb_lsa_unlock(lsa); + break; + } + + ospf6_lsa_age_update_to_send(lsa, oi->transdelay); + memcpy(p, lsa->header, sizeof(struct ospf6_lsa_header)); + p += sizeof(struct ospf6_lsa_header); + + assert(lsa->lock == 2); + ospf6_lsdb_remove(lsa, oi->lsack_list); + lsa_cnt++; + } + + if (lsa_cnt) { + oh->type = OSPF6_MESSAGE_TYPE_LSACK; + oh->length = htons(p - sendbuf); + + if ((oi->state == OSPF6_INTERFACE_POINTTOPOINT) + || (oi->state == OSPF6_INTERFACE_DR) + || (oi->state == OSPF6_INTERFACE_BDR)) + ospf6_send(oi->linklocal_addr, &allspfrouters6, oi, oh); + else + ospf6_send(oi->linklocal_addr, &alldrouters6, oi, oh); + } + + if (oi->lsack_list->count > 0) + thread_add_event(master, ospf6_lsack_send_interface, oi, 0, + &oi->thread_send_lsack); + + return 0; } @@ -2335,44 +2314,42 @@ DEFUN (debug_ospf6_message, "Debug only sending message\n" "Debug only receiving message\n") { - int idx_packet = 3; - int idx_send_recv = 4; - unsigned char level = 0; - int type = 0; - int i; - - /* check type */ - if (! strncmp (argv[idx_packet]->arg, "u", 1)) - type = OSPF6_MESSAGE_TYPE_UNKNOWN; - else if (! strncmp (argv[idx_packet]->arg, "h", 1)) - type = OSPF6_MESSAGE_TYPE_HELLO; - else if (! strncmp (argv[idx_packet]->arg, "d", 1)) - type = OSPF6_MESSAGE_TYPE_DBDESC; - else if (! strncmp (argv[idx_packet]->arg, "lsr", 3)) - type = OSPF6_MESSAGE_TYPE_LSREQ; - else if (! strncmp (argv[idx_packet]->arg, "lsu", 3)) - type = OSPF6_MESSAGE_TYPE_LSUPDATE; - else if (! strncmp (argv[idx_packet]->arg, "lsa", 3)) - type = OSPF6_MESSAGE_TYPE_LSACK; - else if (! strncmp (argv[idx_packet]->arg, "a", 1)) - type = OSPF6_MESSAGE_TYPE_ALL; - - if (argc == 4) - level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV; - else if (! strncmp (argv[idx_send_recv]->arg, "s", 1)) - level = OSPF6_DEBUG_MESSAGE_SEND; - else if (! strncmp (argv[idx_send_recv]->arg, "r", 1)) - level = OSPF6_DEBUG_MESSAGE_RECV; - - if (type == OSPF6_MESSAGE_TYPE_ALL) - { - for (i = 0; i < 6; i++) - OSPF6_DEBUG_MESSAGE_ON (i, level); - } - else - OSPF6_DEBUG_MESSAGE_ON (type, level); - - return CMD_SUCCESS; + int idx_packet = 3; + int idx_send_recv = 4; + unsigned char level = 0; + int type = 0; + int i; + + /* check type */ + if (!strncmp(argv[idx_packet]->arg, "u", 1)) + type = OSPF6_MESSAGE_TYPE_UNKNOWN; + else if (!strncmp(argv[idx_packet]->arg, "h", 1)) + type = OSPF6_MESSAGE_TYPE_HELLO; + else if (!strncmp(argv[idx_packet]->arg, "d", 1)) + type = OSPF6_MESSAGE_TYPE_DBDESC; + else if (!strncmp(argv[idx_packet]->arg, "lsr", 3)) + type = OSPF6_MESSAGE_TYPE_LSREQ; + else if (!strncmp(argv[idx_packet]->arg, "lsu", 3)) + type = OSPF6_MESSAGE_TYPE_LSUPDATE; + else if (!strncmp(argv[idx_packet]->arg, "lsa", 3)) + type = OSPF6_MESSAGE_TYPE_LSACK; + else if (!strncmp(argv[idx_packet]->arg, "a", 1)) + type = OSPF6_MESSAGE_TYPE_ALL; + + if (argc == 4) + level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV; + else if (!strncmp(argv[idx_send_recv]->arg, "s", 1)) + level = OSPF6_DEBUG_MESSAGE_SEND; + else if (!strncmp(argv[idx_send_recv]->arg, "r", 1)) + level = OSPF6_DEBUG_MESSAGE_RECV; + + if (type == OSPF6_MESSAGE_TYPE_ALL) { + for (i = 0; i < 6; i++) + OSPF6_DEBUG_MESSAGE_ON(i, level); + } else + OSPF6_DEBUG_MESSAGE_ON(type, level); + + return CMD_SUCCESS; } DEFUN (no_debug_ospf6_message, @@ -2392,110 +2369,100 @@ DEFUN (no_debug_ospf6_message, "Debug only sending message\n" "Debug only receiving message\n") { - int idx_packet = 4; - int idx_send_recv = 5; - unsigned char level = 0; - int type = 0; - int i; - - /* check type */ - if (! strncmp (argv[idx_packet]->arg, "u", 1)) - type = OSPF6_MESSAGE_TYPE_UNKNOWN; - else if (! strncmp (argv[idx_packet]->arg, "h", 1)) - type = OSPF6_MESSAGE_TYPE_HELLO; - else if (! strncmp (argv[idx_packet]->arg, "d", 1)) - type = OSPF6_MESSAGE_TYPE_DBDESC; - else if (! strncmp (argv[idx_packet]->arg, "lsr", 3)) - type = OSPF6_MESSAGE_TYPE_LSREQ; - else if (! strncmp (argv[idx_packet]->arg, "lsu", 3)) - type = OSPF6_MESSAGE_TYPE_LSUPDATE; - else if (! strncmp (argv[idx_packet]->arg, "lsa", 3)) - type = OSPF6_MESSAGE_TYPE_LSACK; - else if (! strncmp (argv[idx_packet]->arg, "a", 1)) - type = OSPF6_MESSAGE_TYPE_ALL; - - if (argc == 5) - level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV; - else if (! strncmp (argv[idx_send_recv]->arg, "s", 1)) - level = OSPF6_DEBUG_MESSAGE_SEND; - else if (! strncmp (argv[idx_send_recv]->arg, "r", 1)) - level = OSPF6_DEBUG_MESSAGE_RECV; - - if (type == OSPF6_MESSAGE_TYPE_ALL) - { - for (i = 0; i < 6; i++) - OSPF6_DEBUG_MESSAGE_OFF (i, level); - } - else - OSPF6_DEBUG_MESSAGE_OFF (type, level); - - return CMD_SUCCESS; + int idx_packet = 4; + int idx_send_recv = 5; + unsigned char level = 0; + int type = 0; + int i; + + /* check type */ + if (!strncmp(argv[idx_packet]->arg, "u", 1)) + type = OSPF6_MESSAGE_TYPE_UNKNOWN; + else if (!strncmp(argv[idx_packet]->arg, "h", 1)) + type = OSPF6_MESSAGE_TYPE_HELLO; + else if (!strncmp(argv[idx_packet]->arg, "d", 1)) + type = OSPF6_MESSAGE_TYPE_DBDESC; + else if (!strncmp(argv[idx_packet]->arg, "lsr", 3)) + type = OSPF6_MESSAGE_TYPE_LSREQ; + else if (!strncmp(argv[idx_packet]->arg, "lsu", 3)) + type = OSPF6_MESSAGE_TYPE_LSUPDATE; + else if (!strncmp(argv[idx_packet]->arg, "lsa", 3)) + type = OSPF6_MESSAGE_TYPE_LSACK; + else if (!strncmp(argv[idx_packet]->arg, "a", 1)) + type = OSPF6_MESSAGE_TYPE_ALL; + + if (argc == 5) + level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV; + else if (!strncmp(argv[idx_send_recv]->arg, "s", 1)) + level = OSPF6_DEBUG_MESSAGE_SEND; + else if (!strncmp(argv[idx_send_recv]->arg, "r", 1)) + level = OSPF6_DEBUG_MESSAGE_RECV; + + if (type == OSPF6_MESSAGE_TYPE_ALL) { + for (i = 0; i < 6; i++) + OSPF6_DEBUG_MESSAGE_OFF(i, level); + } else + OSPF6_DEBUG_MESSAGE_OFF(type, level); + + return CMD_SUCCESS; } -int -config_write_ospf6_debug_message (struct vty *vty) +int config_write_ospf6_debug_message(struct vty *vty) { - const char *type_str[] = {"unknown", "hello", "dbdesc", - "lsreq", "lsupdate", "lsack"}; - unsigned char s = 0, r = 0; - int i; - - for (i = 0; i < 6; i++) - { - if (IS_OSPF6_DEBUG_MESSAGE (i, SEND)) - s |= 1 << i; - if (IS_OSPF6_DEBUG_MESSAGE (i, RECV)) - r |= 1 << i; - } - - if (s == 0x3f && r == 0x3f) - { - vty_out (vty, "debug ospf6 message all\n"); - return 0; - } - - if (s == 0x3f && r == 0) - { - vty_out (vty, "debug ospf6 message all send\n"); - return 0; - } - else if (s == 0 && r == 0x3f) - { - vty_out (vty, "debug ospf6 message all recv\n"); - return 0; - } - - /* Unknown message is logged by default */ - if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, SEND) && - ! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - vty_out (vty, "no debug ospf6 message unknown\n"); - else if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, SEND)) - vty_out (vty, "no debug ospf6 message unknown send\n"); - else if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) - vty_out (vty, "no debug ospf6 message unknown recv\n"); - - for (i = 1; i < 6; i++) - { - if (IS_OSPF6_DEBUG_MESSAGE (i, SEND) && - IS_OSPF6_DEBUG_MESSAGE (i, RECV)) - vty_out (vty, "debug ospf6 message %s\n", type_str[i]); - else if (IS_OSPF6_DEBUG_MESSAGE (i, SEND)) - vty_out (vty, "debug ospf6 message %s send\n", type_str[i]); - else if (IS_OSPF6_DEBUG_MESSAGE (i, RECV)) - vty_out (vty, "debug ospf6 message %s recv\n", type_str[i]); - } - - return 0; + const char *type_str[] = {"unknown", "hello", "dbdesc", + "lsreq", "lsupdate", "lsack"}; + unsigned char s = 0, r = 0; + int i; + + for (i = 0; i < 6; i++) { + if (IS_OSPF6_DEBUG_MESSAGE(i, SEND)) + s |= 1 << i; + if (IS_OSPF6_DEBUG_MESSAGE(i, RECV)) + r |= 1 << i; + } + + if (s == 0x3f && r == 0x3f) { + vty_out(vty, "debug ospf6 message all\n"); + return 0; + } + + if (s == 0x3f && r == 0) { + vty_out(vty, "debug ospf6 message all send\n"); + return 0; + } else if (s == 0 && r == 0x3f) { + vty_out(vty, "debug ospf6 message all recv\n"); + return 0; + } + + /* Unknown message is logged by default */ + if (!IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, SEND) + && !IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + vty_out(vty, "no debug ospf6 message unknown\n"); + else if (!IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, SEND)) + vty_out(vty, "no debug ospf6 message unknown send\n"); + else if (!IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV)) + vty_out(vty, "no debug ospf6 message unknown recv\n"); + + for (i = 1; i < 6; i++) { + if (IS_OSPF6_DEBUG_MESSAGE(i, SEND) + && IS_OSPF6_DEBUG_MESSAGE(i, RECV)) + vty_out(vty, "debug ospf6 message %s\n", type_str[i]); + else if (IS_OSPF6_DEBUG_MESSAGE(i, SEND)) + vty_out(vty, "debug ospf6 message %s send\n", + type_str[i]); + else if (IS_OSPF6_DEBUG_MESSAGE(i, RECV)) + vty_out(vty, "debug ospf6 message %s recv\n", + type_str[i]); + } + + return 0; } -void -install_element_ospf6_debug_message (void) +void install_element_ospf6_debug_message(void) { - install_element (ENABLE_NODE, &debug_ospf6_message_cmd); - install_element (ENABLE_NODE, &no_debug_ospf6_message_cmd); - install_element (CONFIG_NODE, &debug_ospf6_message_cmd); - install_element (CONFIG_NODE, &no_debug_ospf6_message_cmd); + install_element(ENABLE_NODE, &debug_ospf6_message_cmd); + install_element(ENABLE_NODE, &no_debug_ospf6_message_cmd); + install_element(CONFIG_NODE, &debug_ospf6_message_cmd); + install_element(CONFIG_NODE, &no_debug_ospf6_message_cmd); } - - diff --git a/ospf6d/ospf6_message.h b/ospf6d/ospf6_message.h index b0107dfff..d867bd025 100644 --- a/ospf6d/ospf6_message.h +++ b/ospf6d/ospf6_message.h @@ -27,12 +27,12 @@ extern unsigned char conf_debug_ospf6_message[]; #define OSPF6_DEBUG_MESSAGE_SEND 0x01 #define OSPF6_DEBUG_MESSAGE_RECV 0x02 -#define OSPF6_DEBUG_MESSAGE_ON(type, level) \ - (conf_debug_ospf6_message[type] |= (level)) -#define OSPF6_DEBUG_MESSAGE_OFF(type, level) \ - (conf_debug_ospf6_message[type] &= ~(level)) -#define IS_OSPF6_DEBUG_MESSAGE(t, e) \ - (conf_debug_ospf6_message[t] & OSPF6_DEBUG_MESSAGE_ ## e) +#define OSPF6_DEBUG_MESSAGE_ON(type, level) \ + (conf_debug_ospf6_message[type] |= (level)) +#define OSPF6_DEBUG_MESSAGE_OFF(type, level) \ + (conf_debug_ospf6_message[type] &= ~(level)) +#define IS_OSPF6_DEBUG_MESSAGE(t, e) \ + (conf_debug_ospf6_message[t] & OSPF6_DEBUG_MESSAGE_##e) /* Type */ #define OSPF6_MESSAGE_TYPE_UNKNOWN 0x0 @@ -45,45 +45,42 @@ extern unsigned char conf_debug_ospf6_message[]; /* OSPFv3 packet header */ #define OSPF6_HEADER_SIZE 16U -struct ospf6_header -{ - u_char version; - u_char type; - u_int16_t length; - u_int32_t router_id; - u_int32_t area_id; - u_int16_t checksum; - u_char instance_id; - u_char reserved; +struct ospf6_header { + u_char version; + u_char type; + u_int16_t length; + u_int32_t router_id; + u_int32_t area_id; + u_int16_t checksum; + u_char instance_id; + u_char reserved; }; #define OSPF6_MESSAGE_END(H) ((caddr_t) (H) + ntohs ((H)->length)) /* Hello */ #define OSPF6_HELLO_MIN_SIZE 20U -struct ospf6_hello -{ - ifindex_t interface_id; - u_char priority; - u_char options[3]; - u_int16_t hello_interval; - u_int16_t dead_interval; - u_int32_t drouter; - u_int32_t bdrouter; - /* Followed by Router-IDs */ +struct ospf6_hello { + ifindex_t interface_id; + u_char priority; + u_char options[3]; + u_int16_t hello_interval; + u_int16_t dead_interval; + u_int32_t drouter; + u_int32_t bdrouter; + /* Followed by Router-IDs */ }; /* Database Description */ #define OSPF6_DB_DESC_MIN_SIZE 12U -struct ospf6_dbdesc -{ - u_char reserved1; - u_char options[3]; - u_int16_t ifmtu; - u_char reserved2; - u_char bits; - u_int32_t seqnum; - /* Followed by LSA Headers */ +struct ospf6_dbdesc { + u_char reserved1; + u_char options[3]; + u_int16_t ifmtu; + u_char reserved2; + u_char bits; + u_int32_t seqnum; + /* Followed by LSA Headers */ }; #define OSPF6_DBDESC_MSBIT (0x01) /* master/slave bit */ @@ -94,20 +91,18 @@ struct ospf6_dbdesc #define OSPF6_LS_REQ_MIN_SIZE 0U /* It is just a sequence of entries below */ #define OSPF6_LSREQ_LSDESC_FIX_SIZE 12U -struct ospf6_lsreq_entry -{ - u_int16_t reserved; /* Must Be Zero */ - u_int16_t type; /* LS type */ - u_int32_t id; /* Link State ID */ - u_int32_t adv_router; /* Advertising Router */ +struct ospf6_lsreq_entry { + u_int16_t reserved; /* Must Be Zero */ + u_int16_t type; /* LS type */ + u_int32_t id; /* Link State ID */ + u_int32_t adv_router; /* Advertising Router */ }; /* Link State Update */ #define OSPF6_LS_UPD_MIN_SIZE 4U -struct ospf6_lsupdate -{ - u_int32_t lsa_number; - /* Followed by LSAs */ +struct ospf6_lsupdate { + u_int32_t lsa_number; + /* Followed by LSAs */ }; /* Link State Acknowledgement */ @@ -115,27 +110,26 @@ struct ospf6_lsupdate /* It is just a sequence of LSA Headers */ /* Function definition */ -extern void ospf6_hello_print (struct ospf6_header *); -extern void ospf6_dbdesc_print (struct ospf6_header *); -extern void ospf6_lsreq_print (struct ospf6_header *); -extern void ospf6_lsupdate_print (struct ospf6_header *); -extern void ospf6_lsack_print (struct ospf6_header *); - -extern int ospf6_iobuf_size (unsigned int size); -extern void ospf6_message_terminate (void); -extern int ospf6_receive (struct thread *thread); - -extern int ospf6_hello_send (struct thread *thread); -extern int ospf6_dbdesc_send (struct thread *thread); -extern int ospf6_dbdesc_send_newone (struct thread *thread); -extern int ospf6_lsreq_send (struct thread *thread); -extern int ospf6_lsupdate_send_interface (struct thread *thread); -extern int ospf6_lsupdate_send_neighbor (struct thread *thread); -extern int ospf6_lsack_send_interface (struct thread *thread); -extern int ospf6_lsack_send_neighbor (struct thread *thread); - -extern int config_write_ospf6_debug_message (struct vty *); -extern void install_element_ospf6_debug_message (void); +extern void ospf6_hello_print(struct ospf6_header *); +extern void ospf6_dbdesc_print(struct ospf6_header *); +extern void ospf6_lsreq_print(struct ospf6_header *); +extern void ospf6_lsupdate_print(struct ospf6_header *); +extern void ospf6_lsack_print(struct ospf6_header *); + +extern int ospf6_iobuf_size(unsigned int size); +extern void ospf6_message_terminate(void); +extern int ospf6_receive(struct thread *thread); + +extern int ospf6_hello_send(struct thread *thread); +extern int ospf6_dbdesc_send(struct thread *thread); +extern int ospf6_dbdesc_send_newone(struct thread *thread); +extern int ospf6_lsreq_send(struct thread *thread); +extern int ospf6_lsupdate_send_interface(struct thread *thread); +extern int ospf6_lsupdate_send_neighbor(struct thread *thread); +extern int ospf6_lsack_send_interface(struct thread *thread); +extern int ospf6_lsack_send_neighbor(struct thread *thread); + +extern int config_write_ospf6_debug_message(struct vty *); +extern void install_element_ospf6_debug_message(void); #endif /* OSPF6_MESSAGE_H */ - diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c index d0a97eea4..a21da0748 100644 --- a/ospf6d/ospf6_neighbor.c +++ b/ospf6d/ospf6_neighbor.c @@ -46,751 +46,712 @@ #include "ospf6_zebra.h" DEFINE_HOOK(ospf6_neighbor_change, - (struct ospf6_neighbor *on, int state, int next_state), - (on, state, next_state)) + (struct ospf6_neighbor * on, int state, int next_state), + (on, state, next_state)) unsigned char conf_debug_ospf6_neighbor = 0; -const char *ospf6_neighbor_state_str[] = -{ "None", "Down", "Attempt", "Init", "Twoway", "ExStart", "ExChange", - "Loading", "Full", NULL }; +const char *ospf6_neighbor_state_str[] = { + "None", "Down", "Attempt", "Init", "Twoway", + "ExStart", "ExChange", "Loading", "Full", NULL}; -int -ospf6_neighbor_cmp (void *va, void *vb) +int 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) ? -1 : 1); + 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) ? -1 : 1); } -struct ospf6_neighbor * -ospf6_neighbor_lookup (u_int32_t router_id, - struct ospf6_interface *oi) +struct ospf6_neighbor *ospf6_neighbor_lookup(u_int32_t router_id, + struct ospf6_interface *oi) { - struct listnode *n; - struct ospf6_neighbor *on; - - for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, n, on)) - if (on->router_id == router_id) - return on; - - return (struct ospf6_neighbor *) NULL; + struct listnode *n; + struct ospf6_neighbor *on; + + for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, n, on)) + if (on->router_id == router_id) + return on; + + return (struct ospf6_neighbor *)NULL; } /* create ospf6_neighbor */ -struct ospf6_neighbor * -ospf6_neighbor_create (u_int32_t router_id, struct ospf6_interface *oi) +struct ospf6_neighbor *ospf6_neighbor_create(u_int32_t router_id, + struct ospf6_interface *oi) { - struct ospf6_neighbor *on; - char buf[16]; - - on = (struct ospf6_neighbor *) - XMALLOC (MTYPE_OSPF6_NEIGHBOR, sizeof (struct ospf6_neighbor)); - if (on == NULL) - { - zlog_warn ("neighbor: malloc failed"); - return NULL; - } - - memset (on, 0, sizeof (struct ospf6_neighbor)); - inet_ntop (AF_INET, &router_id, buf, sizeof (buf)); - snprintf (on->name, sizeof (on->name), "%s%%%s", - buf, oi->interface->name); - on->ospf6_if = oi; - on->state = OSPF6_NEIGHBOR_DOWN; - on->state_change = 0; - monotime(&on->last_changed); - on->router_id = router_id; - - 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); - on->lsupdate_list = ospf6_lsdb_create (on); - on->lsack_list = ospf6_lsdb_create (on); - - listnode_add_sort (oi->neighbor_list, on); - - ospf6_bfd_info_nbr_create(oi, on); - return on; + struct ospf6_neighbor *on; + char buf[16]; + + on = (struct ospf6_neighbor *)XMALLOC(MTYPE_OSPF6_NEIGHBOR, + sizeof(struct ospf6_neighbor)); + if (on == NULL) { + zlog_warn("neighbor: malloc failed"); + return NULL; + } + + memset(on, 0, sizeof(struct ospf6_neighbor)); + inet_ntop(AF_INET, &router_id, buf, sizeof(buf)); + snprintf(on->name, sizeof(on->name), "%s%%%s", buf, + oi->interface->name); + on->ospf6_if = oi; + on->state = OSPF6_NEIGHBOR_DOWN; + on->state_change = 0; + monotime(&on->last_changed); + on->router_id = router_id; + + 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); + on->lsupdate_list = ospf6_lsdb_create(on); + on->lsack_list = ospf6_lsdb_create(on); + + listnode_add_sort(oi->neighbor_list, on); + + ospf6_bfd_info_nbr_create(oi, on); + return on; } -void -ospf6_neighbor_delete (struct ospf6_neighbor *on) +void ospf6_neighbor_delete(struct ospf6_neighbor *on) { - struct ospf6_lsa *lsa; + struct ospf6_lsa *lsa; - ospf6_lsdb_remove_all (on->summary_list); - ospf6_lsdb_remove_all (on->request_list); - for (ALL_LSDB(on->retrans_list, lsa)) - { - ospf6_decrement_retrans_count (lsa); - ospf6_lsdb_remove (lsa, on->retrans_list); - } + ospf6_lsdb_remove_all(on->summary_list); + ospf6_lsdb_remove_all(on->request_list); + for (ALL_LSDB(on->retrans_list, lsa)) { + ospf6_decrement_retrans_count(lsa); + ospf6_lsdb_remove(lsa, on->retrans_list); + } - ospf6_lsdb_remove_all (on->dbdesc_list); - ospf6_lsdb_remove_all (on->lsupdate_list); - ospf6_lsdb_remove_all (on->lsack_list); + ospf6_lsdb_remove_all(on->dbdesc_list); + ospf6_lsdb_remove_all(on->lsupdate_list); + ospf6_lsdb_remove_all(on->lsack_list); - ospf6_lsdb_delete (on->summary_list); - ospf6_lsdb_delete (on->request_list); - ospf6_lsdb_delete (on->retrans_list); + ospf6_lsdb_delete(on->summary_list); + ospf6_lsdb_delete(on->request_list); + ospf6_lsdb_delete(on->retrans_list); - ospf6_lsdb_delete (on->dbdesc_list); - ospf6_lsdb_delete (on->lsupdate_list); - ospf6_lsdb_delete (on->lsack_list); + ospf6_lsdb_delete(on->dbdesc_list); + ospf6_lsdb_delete(on->lsupdate_list); + ospf6_lsdb_delete(on->lsack_list); - THREAD_OFF (on->inactivity_timer); + THREAD_OFF(on->inactivity_timer); - THREAD_OFF (on->thread_send_dbdesc); - THREAD_OFF (on->thread_send_lsreq); - THREAD_OFF (on->thread_send_lsupdate); - THREAD_OFF (on->thread_send_lsack); + THREAD_OFF(on->thread_send_dbdesc); + THREAD_OFF(on->thread_send_lsreq); + THREAD_OFF(on->thread_send_lsupdate); + THREAD_OFF(on->thread_send_lsack); - ospf6_bfd_reg_dereg_nbr(on, ZEBRA_BFD_DEST_DEREGISTER); - XFREE (MTYPE_OSPF6_NEIGHBOR, on); + ospf6_bfd_reg_dereg_nbr(on, ZEBRA_BFD_DEST_DEREGISTER); + XFREE(MTYPE_OSPF6_NEIGHBOR, on); } -static void -ospf6_neighbor_state_change (u_char next_state, struct ospf6_neighbor *on, int event) +static void ospf6_neighbor_state_change(u_char next_state, + struct ospf6_neighbor *on, int event) { - u_char prev_state; - - prev_state = on->state; - on->state = next_state; - - if (prev_state == next_state) - return; - - on->state_change++; - monotime(&on->last_changed); - - /* log */ - if (IS_OSPF6_DEBUG_NEIGHBOR (STATE)) - { - zlog_debug ("Neighbor state change %s: [%s]->[%s] (%s)", on->name, - ospf6_neighbor_state_str[prev_state], - ospf6_neighbor_state_str[next_state], - ospf6_neighbor_event_string(event)); - } - - /* Optionally notify about adjacency changes */ - if (CHECK_FLAG(on->ospf6_if->area->ospf6->config_flags, - OSPF6_LOG_ADJACENCY_CHANGES) && - (CHECK_FLAG(on->ospf6_if->area->ospf6->config_flags, - OSPF6_LOG_ADJACENCY_DETAIL) || - (next_state == OSPF6_NEIGHBOR_FULL) || (next_state < prev_state))) - zlog_notice("AdjChg: Nbr %s: %s -> %s (%s)", on->name, - ospf6_neighbor_state_str[prev_state], - ospf6_neighbor_state_str[next_state], - ospf6_neighbor_event_string(event)); - - if (prev_state == OSPF6_NEIGHBOR_FULL || next_state == OSPF6_NEIGHBOR_FULL) - { - OSPF6_ROUTER_LSA_SCHEDULE (on->ospf6_if->area); - if (on->ospf6_if->state == OSPF6_INTERFACE_DR) - { - OSPF6_NETWORK_LSA_SCHEDULE (on->ospf6_if); - OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (on->ospf6_if); - } - OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (on->ospf6_if->area); - } - - if ((prev_state == OSPF6_NEIGHBOR_EXCHANGE || - prev_state == OSPF6_NEIGHBOR_LOADING) && - (next_state != OSPF6_NEIGHBOR_EXCHANGE && - next_state != OSPF6_NEIGHBOR_LOADING)) - ospf6_maxage_remove (on->ospf6_if->area->ospf6); - - hook_call(ospf6_neighbor_change, on, next_state, prev_state); - ospf6_bfd_trigger_event(on, prev_state, next_state); + u_char prev_state; + + prev_state = on->state; + on->state = next_state; + + if (prev_state == next_state) + return; + + on->state_change++; + monotime(&on->last_changed); + + /* log */ + if (IS_OSPF6_DEBUG_NEIGHBOR(STATE)) { + zlog_debug("Neighbor state change %s: [%s]->[%s] (%s)", + on->name, ospf6_neighbor_state_str[prev_state], + ospf6_neighbor_state_str[next_state], + ospf6_neighbor_event_string(event)); + } + + /* Optionally notify about adjacency changes */ + if (CHECK_FLAG(on->ospf6_if->area->ospf6->config_flags, + OSPF6_LOG_ADJACENCY_CHANGES) + && (CHECK_FLAG(on->ospf6_if->area->ospf6->config_flags, + OSPF6_LOG_ADJACENCY_DETAIL) + || (next_state == OSPF6_NEIGHBOR_FULL) + || (next_state < prev_state))) + zlog_notice("AdjChg: Nbr %s: %s -> %s (%s)", on->name, + ospf6_neighbor_state_str[prev_state], + ospf6_neighbor_state_str[next_state], + ospf6_neighbor_event_string(event)); + + if (prev_state == OSPF6_NEIGHBOR_FULL + || next_state == OSPF6_NEIGHBOR_FULL) { + OSPF6_ROUTER_LSA_SCHEDULE(on->ospf6_if->area); + if (on->ospf6_if->state == OSPF6_INTERFACE_DR) { + OSPF6_NETWORK_LSA_SCHEDULE(on->ospf6_if); + OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(on->ospf6_if); + } + OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(on->ospf6_if->area); + } + + if ((prev_state == OSPF6_NEIGHBOR_EXCHANGE + || prev_state == OSPF6_NEIGHBOR_LOADING) + && (next_state != OSPF6_NEIGHBOR_EXCHANGE + && next_state != OSPF6_NEIGHBOR_LOADING)) + ospf6_maxage_remove(on->ospf6_if->area->ospf6); + + hook_call(ospf6_neighbor_change, on, next_state, prev_state); + ospf6_bfd_trigger_event(on, prev_state, next_state); } /* RFC2328 section 10.4 */ -static int -need_adjacency (struct ospf6_neighbor *on) +static int need_adjacency(struct ospf6_neighbor *on) { - if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT || - on->ospf6_if->state == OSPF6_INTERFACE_DR || - on->ospf6_if->state == OSPF6_INTERFACE_BDR) - return 1; + if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT + || on->ospf6_if->state == OSPF6_INTERFACE_DR + || on->ospf6_if->state == OSPF6_INTERFACE_BDR) + return 1; - if (on->ospf6_if->drouter == on->router_id || - on->ospf6_if->bdrouter == on->router_id) - return 1; + if (on->ospf6_if->drouter == on->router_id + || on->ospf6_if->bdrouter == on->router_id) + return 1; - return 0; + return 0; } -int -hello_received (struct thread *thread) +int hello_received(struct thread *thread) { - struct ospf6_neighbor *on; + struct ospf6_neighbor *on; - on = (struct ospf6_neighbor *) THREAD_ARG (thread); - assert (on); + on = (struct ospf6_neighbor *)THREAD_ARG(thread); + assert(on); - if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT)) - zlog_debug ("Neighbor Event %s: *HelloReceived*", on->name); + if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) + zlog_debug("Neighbor Event %s: *HelloReceived*", on->name); - /* reset Inactivity Timer */ - THREAD_OFF (on->inactivity_timer); - on->inactivity_timer = NULL; - thread_add_timer(master, inactivity_timer, on, on->ospf6_if->dead_interval, - &on->inactivity_timer); + /* reset Inactivity Timer */ + THREAD_OFF(on->inactivity_timer); + on->inactivity_timer = NULL; + thread_add_timer(master, inactivity_timer, on, + on->ospf6_if->dead_interval, &on->inactivity_timer); - if (on->state <= OSPF6_NEIGHBOR_DOWN) - ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on, - OSPF6_NEIGHBOR_EVENT_HELLO_RCVD); + if (on->state <= OSPF6_NEIGHBOR_DOWN) + ospf6_neighbor_state_change(OSPF6_NEIGHBOR_INIT, on, + OSPF6_NEIGHBOR_EVENT_HELLO_RCVD); - return 0; + return 0; } -int -twoway_received (struct thread *thread) +int twoway_received(struct thread *thread) { - struct ospf6_neighbor *on; + struct ospf6_neighbor *on; - on = (struct ospf6_neighbor *) THREAD_ARG (thread); - assert (on); + on = (struct ospf6_neighbor *)THREAD_ARG(thread); + assert(on); - if (on->state > OSPF6_NEIGHBOR_INIT) - return 0; + if (on->state > OSPF6_NEIGHBOR_INIT) + return 0; - if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT)) - zlog_debug ("Neighbor Event %s: *2Way-Received*", on->name); + if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) + zlog_debug("Neighbor Event %s: *2Way-Received*", on->name); - thread_add_event(master, neighbor_change, on->ospf6_if, 0, NULL); + thread_add_event(master, neighbor_change, on->ospf6_if, 0, NULL); - if (! need_adjacency (on)) - { - ospf6_neighbor_state_change (OSPF6_NEIGHBOR_TWOWAY, on, - OSPF6_NEIGHBOR_EVENT_TWOWAY_RCVD); - return 0; - } + if (!need_adjacency(on)) { + ospf6_neighbor_state_change(OSPF6_NEIGHBOR_TWOWAY, on, + OSPF6_NEIGHBOR_EVENT_TWOWAY_RCVD); + return 0; + } - ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on, - OSPF6_NEIGHBOR_EVENT_TWOWAY_RCVD); - SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT); - SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT); - SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT); + ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXSTART, on, + OSPF6_NEIGHBOR_EVENT_TWOWAY_RCVD); + SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT); + SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT); + SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT); - THREAD_OFF (on->thread_send_dbdesc); - on->thread_send_dbdesc = NULL; - thread_add_event(master, ospf6_dbdesc_send, on, 0, &on->thread_send_dbdesc); + THREAD_OFF(on->thread_send_dbdesc); + on->thread_send_dbdesc = NULL; + thread_add_event(master, ospf6_dbdesc_send, on, 0, + &on->thread_send_dbdesc); - return 0; + return 0; } -int -negotiation_done (struct thread *thread) +int negotiation_done(struct thread *thread) { - struct ospf6_neighbor *on; - struct ospf6_lsa *lsa; - - on = (struct ospf6_neighbor *) THREAD_ARG (thread); - assert (on); - - if (on->state != OSPF6_NEIGHBOR_EXSTART) - return 0; - - if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT)) - zlog_debug ("Neighbor Event %s: *NegotiationDone*", on->name); - - /* clear ls-list */ - ospf6_lsdb_remove_all (on->summary_list); - ospf6_lsdb_remove_all (on->request_list); - for (ALL_LSDB(on->retrans_list, lsa)) - { - ospf6_decrement_retrans_count (lsa); - ospf6_lsdb_remove (lsa, on->retrans_list); - } - - /* Interface scoped LSAs */ - for (ALL_LSDB(on->ospf6_if->lsdb, lsa)) - { - if (OSPF6_LSA_IS_MAXAGE (lsa)) - { - ospf6_increment_retrans_count (lsa); - ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list); - } - else - ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list); - } - - /* Area scoped LSAs */ - for (ALL_LSDB(on->ospf6_if->area->lsdb, lsa)) - { - if (OSPF6_LSA_IS_MAXAGE (lsa)) - { - ospf6_increment_retrans_count (lsa); - ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list); - } - else - ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list); - } - - /* AS scoped LSAs */ - for (ALL_LSDB(on->ospf6_if->area->ospf6->lsdb, lsa)) - { - if (OSPF6_LSA_IS_MAXAGE (lsa)) - { - ospf6_increment_retrans_count (lsa); - ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list); - } - else - ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list); - } - - UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT); - ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXCHANGE, on, - OSPF6_NEIGHBOR_EVENT_NEGOTIATION_DONE); - - return 0; + struct ospf6_neighbor *on; + struct ospf6_lsa *lsa; + + on = (struct ospf6_neighbor *)THREAD_ARG(thread); + assert(on); + + if (on->state != OSPF6_NEIGHBOR_EXSTART) + return 0; + + if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) + zlog_debug("Neighbor Event %s: *NegotiationDone*", on->name); + + /* clear ls-list */ + ospf6_lsdb_remove_all(on->summary_list); + ospf6_lsdb_remove_all(on->request_list); + for (ALL_LSDB(on->retrans_list, lsa)) { + ospf6_decrement_retrans_count(lsa); + ospf6_lsdb_remove(lsa, on->retrans_list); + } + + /* Interface scoped LSAs */ + for (ALL_LSDB(on->ospf6_if->lsdb, lsa)) { + if (OSPF6_LSA_IS_MAXAGE(lsa)) { + ospf6_increment_retrans_count(lsa); + ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list); + } else + ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->summary_list); + } + + /* Area scoped LSAs */ + for (ALL_LSDB(on->ospf6_if->area->lsdb, lsa)) { + if (OSPF6_LSA_IS_MAXAGE(lsa)) { + ospf6_increment_retrans_count(lsa); + ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list); + } else + ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->summary_list); + } + + /* AS scoped LSAs */ + for (ALL_LSDB(on->ospf6_if->area->ospf6->lsdb, lsa)) { + if (OSPF6_LSA_IS_MAXAGE(lsa)) { + ospf6_increment_retrans_count(lsa); + ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list); + } else + ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->summary_list); + } + + UNSET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT); + ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXCHANGE, on, + OSPF6_NEIGHBOR_EVENT_NEGOTIATION_DONE); + + return 0; } -int -exchange_done (struct thread *thread) +int exchange_done(struct thread *thread) { - struct ospf6_neighbor *on; + struct ospf6_neighbor *on; - on = (struct ospf6_neighbor *) THREAD_ARG (thread); - assert (on); + on = (struct ospf6_neighbor *)THREAD_ARG(thread); + assert(on); - if (on->state != OSPF6_NEIGHBOR_EXCHANGE) - return 0; + if (on->state != OSPF6_NEIGHBOR_EXCHANGE) + return 0; - if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT)) - zlog_debug ("Neighbor Event %s: *ExchangeDone*", on->name); + if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) + zlog_debug("Neighbor Event %s: *ExchangeDone*", on->name); - THREAD_OFF (on->thread_send_dbdesc); - ospf6_lsdb_remove_all (on->dbdesc_list); + THREAD_OFF(on->thread_send_dbdesc); + ospf6_lsdb_remove_all(on->dbdesc_list); -/* XXX - thread_add_timer (master, ospf6_neighbor_last_dbdesc_release, on, - on->ospf6_if->dead_interval); -*/ + /* XXX + thread_add_timer (master, ospf6_neighbor_last_dbdesc_release, on, + on->ospf6_if->dead_interval); + */ - if (on->request_list->count == 0) - ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on, - OSPF6_NEIGHBOR_EVENT_EXCHANGE_DONE); - else - { - ospf6_neighbor_state_change (OSPF6_NEIGHBOR_LOADING, on, - OSPF6_NEIGHBOR_EVENT_EXCHANGE_DONE); + if (on->request_list->count == 0) + ospf6_neighbor_state_change(OSPF6_NEIGHBOR_FULL, on, + OSPF6_NEIGHBOR_EVENT_EXCHANGE_DONE); + else { + ospf6_neighbor_state_change(OSPF6_NEIGHBOR_LOADING, on, + OSPF6_NEIGHBOR_EVENT_EXCHANGE_DONE); - thread_add_event(master, ospf6_lsreq_send, on, 0, - &on->thread_send_lsreq); - } + thread_add_event(master, ospf6_lsreq_send, on, 0, + &on->thread_send_lsreq); + } - return 0; + return 0; } /* Check loading state. */ -void -ospf6_check_nbr_loading (struct ospf6_neighbor *on) +void ospf6_check_nbr_loading(struct ospf6_neighbor *on) { - /* RFC2328 Section 10.9: When the neighbor responds to these requests - with the proper Link State Update packet(s), the Link state request - list is truncated and a new Link State Request packet is sent. - */ - if ((on->state == OSPF6_NEIGHBOR_LOADING) || - (on->state == OSPF6_NEIGHBOR_EXCHANGE)) - { - if (on->request_list->count == 0) - thread_add_event(master, loading_done, on, 0, NULL); - else if (on->last_ls_req == NULL) - { - if (on->thread_send_lsreq != NULL) - THREAD_OFF (on->thread_send_lsreq); - on->thread_send_lsreq = NULL; - thread_add_event(master, ospf6_lsreq_send, on, 0, - &on->thread_send_lsreq); + /* RFC2328 Section 10.9: When the neighbor responds to these requests + with the proper Link State Update packet(s), the Link state request + list is truncated and a new Link State Request packet is sent. + */ + if ((on->state == OSPF6_NEIGHBOR_LOADING) + || (on->state == OSPF6_NEIGHBOR_EXCHANGE)) { + if (on->request_list->count == 0) + thread_add_event(master, loading_done, on, 0, NULL); + else if (on->last_ls_req == NULL) { + if (on->thread_send_lsreq != NULL) + THREAD_OFF(on->thread_send_lsreq); + on->thread_send_lsreq = NULL; + thread_add_event(master, ospf6_lsreq_send, on, 0, + &on->thread_send_lsreq); + } } - } } -int -loading_done (struct thread *thread) +int loading_done(struct thread *thread) { - struct ospf6_neighbor *on; + struct ospf6_neighbor *on; - on = (struct ospf6_neighbor *) THREAD_ARG (thread); - assert (on); + on = (struct ospf6_neighbor *)THREAD_ARG(thread); + assert(on); - if (on->state != OSPF6_NEIGHBOR_LOADING) - return 0; + if (on->state != OSPF6_NEIGHBOR_LOADING) + return 0; - if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT)) - zlog_debug ("Neighbor Event %s: *LoadingDone*", on->name); + if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) + zlog_debug("Neighbor Event %s: *LoadingDone*", on->name); - assert (on->request_list->count == 0); + assert(on->request_list->count == 0); - ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on, - OSPF6_NEIGHBOR_EVENT_LOADING_DONE); + ospf6_neighbor_state_change(OSPF6_NEIGHBOR_FULL, on, + OSPF6_NEIGHBOR_EVENT_LOADING_DONE); - return 0; + return 0; } -int -adj_ok (struct thread *thread) +int adj_ok(struct thread *thread) { - struct ospf6_neighbor *on; - struct ospf6_lsa *lsa; - - on = (struct ospf6_neighbor *) THREAD_ARG (thread); - assert (on); - - if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT)) - zlog_debug ("Neighbor Event %s: *AdjOK?*", on->name); - - if (on->state == OSPF6_NEIGHBOR_TWOWAY && need_adjacency (on)) - { - ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on, - OSPF6_NEIGHBOR_EVENT_ADJ_OK); - SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT); - SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT); - SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT); - - THREAD_OFF (on->thread_send_dbdesc); - on->thread_send_dbdesc = NULL; - thread_add_event(master, ospf6_dbdesc_send, on, 0, - &on->thread_send_dbdesc); - - } - else if (on->state >= OSPF6_NEIGHBOR_EXSTART && - ! need_adjacency (on)) - { - ospf6_neighbor_state_change (OSPF6_NEIGHBOR_TWOWAY, on, - OSPF6_NEIGHBOR_EVENT_ADJ_OK); - ospf6_lsdb_remove_all (on->summary_list); - ospf6_lsdb_remove_all (on->request_list); - for (ALL_LSDB(on->retrans_list, lsa)) - { - ospf6_decrement_retrans_count (lsa); - ospf6_lsdb_remove (lsa, on->retrans_list); - } - } - - return 0; + struct ospf6_neighbor *on; + struct ospf6_lsa *lsa; + + on = (struct ospf6_neighbor *)THREAD_ARG(thread); + assert(on); + + if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) + zlog_debug("Neighbor Event %s: *AdjOK?*", on->name); + + if (on->state == OSPF6_NEIGHBOR_TWOWAY && need_adjacency(on)) { + ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXSTART, on, + OSPF6_NEIGHBOR_EVENT_ADJ_OK); + SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT); + SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT); + SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT); + + THREAD_OFF(on->thread_send_dbdesc); + on->thread_send_dbdesc = NULL; + thread_add_event(master, ospf6_dbdesc_send, on, 0, + &on->thread_send_dbdesc); + + } else if (on->state >= OSPF6_NEIGHBOR_EXSTART && !need_adjacency(on)) { + ospf6_neighbor_state_change(OSPF6_NEIGHBOR_TWOWAY, on, + OSPF6_NEIGHBOR_EVENT_ADJ_OK); + ospf6_lsdb_remove_all(on->summary_list); + ospf6_lsdb_remove_all(on->request_list); + for (ALL_LSDB(on->retrans_list, lsa)) { + ospf6_decrement_retrans_count(lsa); + ospf6_lsdb_remove(lsa, on->retrans_list); + } + } + + return 0; } -int -seqnumber_mismatch (struct thread *thread) +int seqnumber_mismatch(struct thread *thread) { - struct ospf6_neighbor *on; - struct ospf6_lsa *lsa; + struct ospf6_neighbor *on; + struct ospf6_lsa *lsa; - on = (struct ospf6_neighbor *) THREAD_ARG (thread); - assert (on); + on = (struct ospf6_neighbor *)THREAD_ARG(thread); + assert(on); - if (on->state < OSPF6_NEIGHBOR_EXCHANGE) - return 0; + if (on->state < OSPF6_NEIGHBOR_EXCHANGE) + return 0; - if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT)) - zlog_debug ("Neighbor Event %s: *SeqNumberMismatch*", on->name); + if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) + zlog_debug("Neighbor Event %s: *SeqNumberMismatch*", on->name); - ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on, - OSPF6_NEIGHBOR_EVENT_SEQNUMBER_MISMATCH); - SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT); - SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT); - SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT); + ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXSTART, on, + OSPF6_NEIGHBOR_EVENT_SEQNUMBER_MISMATCH); + SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT); + SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT); + SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT); - ospf6_lsdb_remove_all (on->summary_list); - ospf6_lsdb_remove_all (on->request_list); - for (ALL_LSDB(on->retrans_list, lsa)) - { - ospf6_decrement_retrans_count (lsa); - ospf6_lsdb_remove (lsa, on->retrans_list); - } + ospf6_lsdb_remove_all(on->summary_list); + ospf6_lsdb_remove_all(on->request_list); + for (ALL_LSDB(on->retrans_list, lsa)) { + ospf6_decrement_retrans_count(lsa); + ospf6_lsdb_remove(lsa, on->retrans_list); + } - THREAD_OFF (on->thread_send_dbdesc); - on->dbdesc_seqnum++; /* Incr seqnum as per RFC2328, sec 10.3 */ + THREAD_OFF(on->thread_send_dbdesc); + on->dbdesc_seqnum++; /* Incr seqnum as per RFC2328, sec 10.3 */ - on->thread_send_dbdesc = NULL; - thread_add_event(master, ospf6_dbdesc_send, on, 0, &on->thread_send_dbdesc); + on->thread_send_dbdesc = NULL; + thread_add_event(master, ospf6_dbdesc_send, on, 0, + &on->thread_send_dbdesc); - return 0; + return 0; } -int -bad_lsreq (struct thread *thread) +int bad_lsreq(struct thread *thread) { - struct ospf6_neighbor *on; - struct ospf6_lsa *lsa; + struct ospf6_neighbor *on; + struct ospf6_lsa *lsa; - on = (struct ospf6_neighbor *) THREAD_ARG (thread); - assert (on); + on = (struct ospf6_neighbor *)THREAD_ARG(thread); + assert(on); - if (on->state < OSPF6_NEIGHBOR_EXCHANGE) - return 0; + if (on->state < OSPF6_NEIGHBOR_EXCHANGE) + return 0; - if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT)) - zlog_debug ("Neighbor Event %s: *BadLSReq*", on->name); + if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) + zlog_debug("Neighbor Event %s: *BadLSReq*", on->name); - ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on, - OSPF6_NEIGHBOR_EVENT_BAD_LSREQ); - SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT); - SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT); - SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT); + ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXSTART, on, + OSPF6_NEIGHBOR_EVENT_BAD_LSREQ); + SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT); + SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT); + SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT); - ospf6_lsdb_remove_all (on->summary_list); - ospf6_lsdb_remove_all (on->request_list); - for (ALL_LSDB(on->retrans_list, lsa)) - { - ospf6_decrement_retrans_count (lsa); - ospf6_lsdb_remove (lsa, on->retrans_list); - } + ospf6_lsdb_remove_all(on->summary_list); + ospf6_lsdb_remove_all(on->request_list); + for (ALL_LSDB(on->retrans_list, lsa)) { + ospf6_decrement_retrans_count(lsa); + ospf6_lsdb_remove(lsa, on->retrans_list); + } - THREAD_OFF (on->thread_send_dbdesc); - on->dbdesc_seqnum++; /* Incr seqnum as per RFC2328, sec 10.3 */ + THREAD_OFF(on->thread_send_dbdesc); + on->dbdesc_seqnum++; /* Incr seqnum as per RFC2328, sec 10.3 */ - on->thread_send_dbdesc = NULL; - thread_add_event(master, ospf6_dbdesc_send, on, 0, &on->thread_send_dbdesc); + on->thread_send_dbdesc = NULL; + thread_add_event(master, ospf6_dbdesc_send, on, 0, + &on->thread_send_dbdesc); - return 0; + return 0; } -int -oneway_received (struct thread *thread) +int oneway_received(struct thread *thread) { - struct ospf6_neighbor *on; - struct ospf6_lsa *lsa; + struct ospf6_neighbor *on; + struct ospf6_lsa *lsa; - on = (struct ospf6_neighbor *) THREAD_ARG (thread); - assert (on); + on = (struct ospf6_neighbor *)THREAD_ARG(thread); + assert(on); - if (on->state < OSPF6_NEIGHBOR_TWOWAY) - return 0; + if (on->state < OSPF6_NEIGHBOR_TWOWAY) + return 0; - if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT)) - zlog_debug ("Neighbor Event %s: *1Way-Received*", on->name); + if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) + zlog_debug("Neighbor Event %s: *1Way-Received*", on->name); - ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on, - OSPF6_NEIGHBOR_EVENT_ONEWAY_RCVD); - thread_add_event(master, neighbor_change, on->ospf6_if, 0, NULL); + ospf6_neighbor_state_change(OSPF6_NEIGHBOR_INIT, on, + OSPF6_NEIGHBOR_EVENT_ONEWAY_RCVD); + thread_add_event(master, neighbor_change, on->ospf6_if, 0, NULL); - ospf6_lsdb_remove_all (on->summary_list); - ospf6_lsdb_remove_all (on->request_list); - for (ALL_LSDB(on->retrans_list, lsa)) - { - ospf6_decrement_retrans_count (lsa); - ospf6_lsdb_remove (lsa, on->retrans_list); - } + ospf6_lsdb_remove_all(on->summary_list); + ospf6_lsdb_remove_all(on->request_list); + for (ALL_LSDB(on->retrans_list, lsa)) { + ospf6_decrement_retrans_count(lsa); + ospf6_lsdb_remove(lsa, on->retrans_list); + } - THREAD_OFF (on->thread_send_dbdesc); - THREAD_OFF (on->thread_send_lsreq); - THREAD_OFF (on->thread_send_lsupdate); - THREAD_OFF (on->thread_send_lsack); + THREAD_OFF(on->thread_send_dbdesc); + THREAD_OFF(on->thread_send_lsreq); + THREAD_OFF(on->thread_send_lsupdate); + THREAD_OFF(on->thread_send_lsack); - return 0; + return 0; } -int -inactivity_timer (struct thread *thread) +int inactivity_timer(struct thread *thread) { - struct ospf6_neighbor *on; + struct ospf6_neighbor *on; - on = (struct ospf6_neighbor *) THREAD_ARG (thread); - assert (on); + on = (struct ospf6_neighbor *)THREAD_ARG(thread); + assert(on); - if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT)) - zlog_debug ("Neighbor Event %s: *InactivityTimer*", on->name); + if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) + zlog_debug("Neighbor Event %s: *InactivityTimer*", on->name); - on->inactivity_timer = NULL; - on->drouter = on->prev_drouter = 0; - on->bdrouter = on->prev_bdrouter = 0; + on->inactivity_timer = NULL; + on->drouter = on->prev_drouter = 0; + on->bdrouter = on->prev_bdrouter = 0; - ospf6_neighbor_state_change (OSPF6_NEIGHBOR_DOWN, on, - OSPF6_NEIGHBOR_EVENT_INACTIVITY_TIMER); - thread_add_event(master, neighbor_change, on->ospf6_if, 0, NULL); + ospf6_neighbor_state_change(OSPF6_NEIGHBOR_DOWN, on, + OSPF6_NEIGHBOR_EVENT_INACTIVITY_TIMER); + thread_add_event(master, neighbor_change, on->ospf6_if, 0, NULL); - listnode_delete (on->ospf6_if->neighbor_list, on); - ospf6_neighbor_delete (on); + listnode_delete(on->ospf6_if->neighbor_list, on); + ospf6_neighbor_delete(on); - return 0; + return 0; } - /* vty functions */ /* show neighbor structure */ -static void -ospf6_neighbor_show (struct vty *vty, struct ospf6_neighbor *on) +static void ospf6_neighbor_show(struct vty *vty, struct ospf6_neighbor *on) { - char router_id[16]; - char duration[16]; - struct timeval res; - char nstate[16]; - char deadtime[16]; - long h, m, s; - - /* Router-ID (Name) */ - inet_ntop (AF_INET, &on->router_id, router_id, sizeof (router_id)); + char router_id[16]; + char duration[16]; + struct timeval res; + char nstate[16]; + char deadtime[16]; + long h, m, s; + + /* Router-ID (Name) */ + inet_ntop(AF_INET, &on->router_id, router_id, sizeof(router_id)); #ifdef HAVE_GETNAMEINFO - { - } + { + } #endif /*HAVE_GETNAMEINFO*/ - /* Dead time */ - h = m = s = 0; - if (on->inactivity_timer) - { - s = monotime_until(&on->inactivity_timer->u.sands, NULL) / 1000000LL; - h = s / 3600; - s -= h * 3600; - m = s / 60; - s -= m * 60; - } - snprintf (deadtime, sizeof (deadtime), "%02ld:%02ld:%02ld", h, m, s); - - /* Neighbor State */ - if (if_is_pointopoint (on->ospf6_if->interface)) - snprintf (nstate, sizeof (nstate), "PointToPoint"); - else - { - if (on->router_id == on->drouter) - snprintf (nstate, sizeof (nstate), "DR"); - else if (on->router_id == on->bdrouter) - snprintf (nstate, sizeof (nstate), "BDR"); - else - snprintf (nstate, sizeof (nstate), "DROther"); - } - - /* Duration */ - monotime_since(&on->last_changed, &res); - timerstring (&res, duration, sizeof (duration)); - - /* - vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]\n", - "Neighbor ID", "Pri", "DeadTime", "State", "", "Duration", - "I/F", "State"); - */ - - vty_out (vty, "%-15s %3d %11s %8s/%-12s %11s %s[%s]\n", - router_id, on->priority, deadtime, - ospf6_neighbor_state_str[on->state], nstate, duration, - on->ospf6_if->interface->name, - ospf6_interface_state_str[on->ospf6_if->state]); + /* Dead time */ + h = m = s = 0; + if (on->inactivity_timer) { + s = monotime_until(&on->inactivity_timer->u.sands, NULL) + / 1000000LL; + h = s / 3600; + s -= h * 3600; + m = s / 60; + s -= m * 60; + } + snprintf(deadtime, sizeof(deadtime), "%02ld:%02ld:%02ld", h, m, s); + + /* Neighbor State */ + if (if_is_pointopoint(on->ospf6_if->interface)) + snprintf(nstate, sizeof(nstate), "PointToPoint"); + else { + if (on->router_id == on->drouter) + snprintf(nstate, sizeof(nstate), "DR"); + else if (on->router_id == on->bdrouter) + snprintf(nstate, sizeof(nstate), "BDR"); + else + snprintf(nstate, sizeof(nstate), "DROther"); + } + + /* Duration */ + monotime_since(&on->last_changed, &res); + timerstring(&res, duration, sizeof(duration)); + + /* + vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]\n", + "Neighbor ID", "Pri", "DeadTime", "State", "", "Duration", + "I/F", "State"); + */ + + vty_out(vty, "%-15s %3d %11s %8s/%-12s %11s %s[%s]\n", router_id, + on->priority, deadtime, ospf6_neighbor_state_str[on->state], + nstate, duration, on->ospf6_if->interface->name, + ospf6_interface_state_str[on->ospf6_if->state]); } -static void -ospf6_neighbor_show_drchoice (struct vty *vty, struct ospf6_neighbor *on) +static void ospf6_neighbor_show_drchoice(struct vty *vty, + struct ospf6_neighbor *on) { - char router_id[16]; - char drouter[16], bdrouter[16]; - char duration[16]; - struct timeval now, res; - -/* - vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]\n", - "RouterID", "State", "Duration", "DR", "BDR", "I/F", - "State"); -*/ - - inet_ntop (AF_INET, &on->router_id, router_id, sizeof (router_id)); - inet_ntop (AF_INET, &on->drouter, drouter, sizeof (drouter)); - inet_ntop (AF_INET, &on->bdrouter, bdrouter, sizeof (bdrouter)); - - monotime(&now); - timersub (&now, &on->last_changed, &res); - timerstring (&res, duration, sizeof (duration)); - - vty_out (vty, "%-15s %8s/%-11s %-15s %-15s %s[%s]\n", - router_id, ospf6_neighbor_state_str[on->state], - duration, drouter, bdrouter, on->ospf6_if->interface->name, - ospf6_interface_state_str[on->ospf6_if->state]); + char router_id[16]; + char drouter[16], bdrouter[16]; + char duration[16]; + struct timeval now, res; + + /* + vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]\n", + "RouterID", "State", "Duration", "DR", "BDR", "I/F", + "State"); + */ + + inet_ntop(AF_INET, &on->router_id, router_id, sizeof(router_id)); + inet_ntop(AF_INET, &on->drouter, drouter, sizeof(drouter)); + inet_ntop(AF_INET, &on->bdrouter, bdrouter, sizeof(bdrouter)); + + monotime(&now); + timersub(&now, &on->last_changed, &res); + timerstring(&res, duration, sizeof(duration)); + + vty_out(vty, "%-15s %8s/%-11s %-15s %-15s %s[%s]\n", router_id, + ospf6_neighbor_state_str[on->state], duration, drouter, + bdrouter, on->ospf6_if->interface->name, + ospf6_interface_state_str[on->ospf6_if->state]); } -static void -ospf6_neighbor_show_detail (struct vty *vty, struct ospf6_neighbor *on) +static void ospf6_neighbor_show_detail(struct vty *vty, + struct ospf6_neighbor *on) { - char drouter[16], bdrouter[16]; - char linklocal_addr[64], duration[32]; - struct timeval now, res; - struct ospf6_lsa *lsa; - - inet_ntop (AF_INET6, &on->linklocal_addr, linklocal_addr, - sizeof (linklocal_addr)); - inet_ntop (AF_INET, &on->drouter, drouter, sizeof (drouter)); - inet_ntop (AF_INET, &on->bdrouter, bdrouter, sizeof (bdrouter)); - - monotime(&now); - timersub (&now, &on->last_changed, &res); - timerstring (&res, duration, sizeof (duration)); - - vty_out (vty, " Neighbor %s\n", on->name); - vty_out (vty, " Area %s via interface %s (ifindex %d)\n", - on->ospf6_if->area->name, - on->ospf6_if->interface->name, - on->ospf6_if->interface->ifindex); - vty_out (vty, " His IfIndex: %d Link-local address: %s\n", - on->ifindex, linklocal_addr); - vty_out (vty, " State %s for a duration of %s\n", - ospf6_neighbor_state_str[on->state], duration); - vty_out (vty, " His choice of DR/BDR %s/%s, Priority %d\n", - drouter, bdrouter, on->priority); - vty_out (vty, " DbDesc status: %s%s%s SeqNum: %#lx\n", - (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT) ? "Initial " : ""), - (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT) ? "More " : ""), - (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT) ? - "Master" : "Slave"), (u_long) ntohl (on->dbdesc_seqnum)); - - vty_out (vty, " Summary-List: %d LSAs\n", on->summary_list->count); - for (ALL_LSDB(on->summary_list, lsa)) - vty_out (vty, " %s\n", lsa->name); - - vty_out (vty, " Request-List: %d LSAs\n", on->request_list->count); - for (ALL_LSDB(on->request_list, lsa)) - vty_out (vty, " %s\n", lsa->name); - - vty_out (vty, " Retrans-List: %d LSAs\n", on->retrans_list->count); - for (ALL_LSDB(on->retrans_list, lsa)) - vty_out (vty, " %s\n", lsa->name); - - timerclear (&res); - if (on->thread_send_dbdesc) - timersub (&on->thread_send_dbdesc->u.sands, &now, &res); - timerstring (&res, duration, sizeof (duration)); - vty_out (vty, " %d Pending LSAs for DbDesc in Time %s [thread %s]\n", - on->dbdesc_list->count, duration, - (on->thread_send_dbdesc ? "on" : "off")); - for (ALL_LSDB(on->dbdesc_list, lsa)) - vty_out (vty, " %s\n", lsa->name); - - timerclear (&res); - if (on->thread_send_lsreq) - timersub (&on->thread_send_lsreq->u.sands, &now, &res); - timerstring (&res, duration, sizeof (duration)); - vty_out (vty, " %d Pending LSAs for LSReq in Time %s [thread %s]\n", - on->request_list->count, duration, - (on->thread_send_lsreq ? "on" : "off")); - for (ALL_LSDB(on->request_list, lsa)) - vty_out (vty, " %s\n", lsa->name); - - timerclear (&res); - if (on->thread_send_lsupdate) - timersub (&on->thread_send_lsupdate->u.sands, &now, &res); - timerstring (&res, duration, sizeof (duration)); - vty_out (vty, " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n", - on->lsupdate_list->count, duration, - (on->thread_send_lsupdate ? "on" : "off")); - for (ALL_LSDB(on->lsupdate_list, lsa)) - vty_out (vty, " %s\n", lsa->name); - - timerclear (&res); - if (on->thread_send_lsack) - timersub (&on->thread_send_lsack->u.sands, &now, &res); - timerstring (&res, duration, sizeof (duration)); - vty_out (vty, " %d Pending LSAs for LSAck in Time %s [thread %s]\n", - on->lsack_list->count, duration, - (on->thread_send_lsack ? "on" : "off")); - for (ALL_LSDB(on->lsack_list, lsa)) - vty_out (vty, " %s\n", lsa->name); - - ospf6_bfd_show_info(vty, on->bfd_info, 0); + char drouter[16], bdrouter[16]; + char linklocal_addr[64], duration[32]; + struct timeval now, res; + struct ospf6_lsa *lsa; + + inet_ntop(AF_INET6, &on->linklocal_addr, linklocal_addr, + sizeof(linklocal_addr)); + inet_ntop(AF_INET, &on->drouter, drouter, sizeof(drouter)); + inet_ntop(AF_INET, &on->bdrouter, bdrouter, sizeof(bdrouter)); + + monotime(&now); + timersub(&now, &on->last_changed, &res); + timerstring(&res, duration, sizeof(duration)); + + vty_out(vty, " Neighbor %s\n", on->name); + vty_out(vty, " Area %s via interface %s (ifindex %d)\n", + on->ospf6_if->area->name, on->ospf6_if->interface->name, + on->ospf6_if->interface->ifindex); + vty_out(vty, " His IfIndex: %d Link-local address: %s\n", + on->ifindex, linklocal_addr); + vty_out(vty, " State %s for a duration of %s\n", + ospf6_neighbor_state_str[on->state], duration); + vty_out(vty, " His choice of DR/BDR %s/%s, Priority %d\n", drouter, + bdrouter, on->priority); + vty_out(vty, " DbDesc status: %s%s%s SeqNum: %#lx\n", + (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT) ? "Initial " + : ""), + (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT) ? "More " : ""), + (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT) ? "Master" + : "Slave"), + (u_long)ntohl(on->dbdesc_seqnum)); + + vty_out(vty, " Summary-List: %d LSAs\n", on->summary_list->count); + for (ALL_LSDB(on->summary_list, lsa)) + vty_out(vty, " %s\n", lsa->name); + + vty_out(vty, " Request-List: %d LSAs\n", on->request_list->count); + for (ALL_LSDB(on->request_list, lsa)) + vty_out(vty, " %s\n", lsa->name); + + vty_out(vty, " Retrans-List: %d LSAs\n", on->retrans_list->count); + for (ALL_LSDB(on->retrans_list, lsa)) + vty_out(vty, " %s\n", lsa->name); + + timerclear(&res); + if (on->thread_send_dbdesc) + timersub(&on->thread_send_dbdesc->u.sands, &now, &res); + timerstring(&res, duration, sizeof(duration)); + vty_out(vty, " %d Pending LSAs for DbDesc in Time %s [thread %s]\n", + on->dbdesc_list->count, duration, + (on->thread_send_dbdesc ? "on" : "off")); + for (ALL_LSDB(on->dbdesc_list, lsa)) + vty_out(vty, " %s\n", lsa->name); + + timerclear(&res); + if (on->thread_send_lsreq) + timersub(&on->thread_send_lsreq->u.sands, &now, &res); + timerstring(&res, duration, sizeof(duration)); + vty_out(vty, " %d Pending LSAs for LSReq in Time %s [thread %s]\n", + on->request_list->count, duration, + (on->thread_send_lsreq ? "on" : "off")); + for (ALL_LSDB(on->request_list, lsa)) + vty_out(vty, " %s\n", lsa->name); + + timerclear(&res); + if (on->thread_send_lsupdate) + timersub(&on->thread_send_lsupdate->u.sands, &now, &res); + timerstring(&res, duration, sizeof(duration)); + vty_out(vty, + " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n", + on->lsupdate_list->count, duration, + (on->thread_send_lsupdate ? "on" : "off")); + for (ALL_LSDB(on->lsupdate_list, lsa)) + vty_out(vty, " %s\n", lsa->name); + + timerclear(&res); + if (on->thread_send_lsack) + timersub(&on->thread_send_lsack->u.sands, &now, &res); + timerstring(&res, duration, sizeof(duration)); + vty_out(vty, " %d Pending LSAs for LSAck in Time %s [thread %s]\n", + on->lsack_list->count, duration, + (on->thread_send_lsack ? "on" : "off")); + for (ALL_LSDB(on->lsack_list, lsa)) + vty_out(vty, " %s\n", lsa->name); + + ospf6_bfd_show_info(vty, on->bfd_info, 0); } DEFUN (show_ipv6_ospf6_neighbor, @@ -803,39 +764,37 @@ DEFUN (show_ipv6_ospf6_neighbor, "Display details\n" "Display DR choices\n") { - int idx_type = 4; - struct ospf6_neighbor *on; - struct ospf6_interface *oi; - struct ospf6_area *oa; - struct listnode *i, *j, *k; - void (*showfunc) (struct vty *, struct ospf6_neighbor *); - - OSPF6_CMD_CHECK_RUNNING (); - showfunc = ospf6_neighbor_show; - - if (argc == 5) - { - if (! strncmp (argv[idx_type]->arg, "de", 2)) - showfunc = ospf6_neighbor_show_detail; - else if (! strncmp (argv[idx_type]->arg, "dr", 2)) - showfunc = ospf6_neighbor_show_drchoice; - } - - if (showfunc == ospf6_neighbor_show) - vty_out (vty, "%-15s %3s %11s %8s/%-12s %11s %s[%s]\n", - "Neighbor ID", "Pri", "DeadTime", "State", "IfState", "Duration", - "I/F", "State"); - else if (showfunc == ospf6_neighbor_show_drchoice) - vty_out (vty, "%-15s %8s/%-11s %-15s %-15s %s[%s]\n", - "RouterID", "State", "Duration", "DR", "BDR", "I/F", - "State"); - - for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, i, oa)) - for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi)) - for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, k, on)) - (*showfunc) (vty, on); - - return CMD_SUCCESS; + int idx_type = 4; + struct ospf6_neighbor *on; + struct ospf6_interface *oi; + struct ospf6_area *oa; + struct listnode *i, *j, *k; + void (*showfunc)(struct vty *, struct ospf6_neighbor *); + + OSPF6_CMD_CHECK_RUNNING(); + showfunc = ospf6_neighbor_show; + + if (argc == 5) { + if (!strncmp(argv[idx_type]->arg, "de", 2)) + showfunc = ospf6_neighbor_show_detail; + else if (!strncmp(argv[idx_type]->arg, "dr", 2)) + showfunc = ospf6_neighbor_show_drchoice; + } + + if (showfunc == ospf6_neighbor_show) + vty_out(vty, "%-15s %3s %11s %8s/%-12s %11s %s[%s]\n", + "Neighbor ID", "Pri", "DeadTime", "State", "IfState", + "Duration", "I/F", "State"); + else if (showfunc == ospf6_neighbor_show_drchoice) + vty_out(vty, "%-15s %8s/%-11s %-15s %-15s %s[%s]\n", "RouterID", + "State", "Duration", "DR", "BDR", "I/F", "State"); + + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) + for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) + for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, k, on)) + (*showfunc)(vty, on); + + return CMD_SUCCESS; } @@ -849,36 +808,35 @@ DEFUN (show_ipv6_ospf6_neighbor_one, "Specify Router-ID as IPv4 address notation\n" ) { - int idx_ipv4 = 4; - struct ospf6_neighbor *on; - struct ospf6_interface *oi; - struct ospf6_area *oa; - struct listnode *i, *j, *k; - void (*showfunc) (struct vty *, struct ospf6_neighbor *); - u_int32_t router_id; - - OSPF6_CMD_CHECK_RUNNING (); - showfunc = ospf6_neighbor_show_detail; - - if ((inet_pton (AF_INET, argv[idx_ipv4]->arg, &router_id)) != 1) - { - vty_out (vty, "Router-ID is not parsable: %s\n", argv[idx_ipv4]->arg); - return CMD_SUCCESS; - } - - for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, i, oa)) - for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi)) - for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, k, on)) - (*showfunc) (vty, on); - - return CMD_SUCCESS; + int idx_ipv4 = 4; + struct ospf6_neighbor *on; + struct ospf6_interface *oi; + struct ospf6_area *oa; + struct listnode *i, *j, *k; + void (*showfunc)(struct vty *, struct ospf6_neighbor *); + u_int32_t router_id; + + OSPF6_CMD_CHECK_RUNNING(); + showfunc = ospf6_neighbor_show_detail; + + if ((inet_pton(AF_INET, argv[idx_ipv4]->arg, &router_id)) != 1) { + vty_out(vty, "Router-ID is not parsable: %s\n", + argv[idx_ipv4]->arg); + return CMD_SUCCESS; + } + + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) + for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) + for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, k, on)) + (*showfunc)(vty, on); + + return CMD_SUCCESS; } -void -ospf6_neighbor_init (void) +void ospf6_neighbor_init(void) { - install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_one_cmd); + install_element(VIEW_NODE, &show_ipv6_ospf6_neighbor_cmd); + install_element(VIEW_NODE, &show_ipv6_ospf6_neighbor_one_cmd); } DEFUN (debug_ospf6_neighbor, @@ -890,21 +848,19 @@ DEFUN (debug_ospf6_neighbor, "Debug OSPFv3 Neighbor State Change\n" "Debug OSPFv3 Neighbor Event\n") { - int idx_type = 3; - unsigned char level = 0; - - if (argc == 4) - { - if (! strncmp (argv[idx_type]->arg, "s", 1)) - level = OSPF6_DEBUG_NEIGHBOR_STATE; - else if (! strncmp (argv[idx_type]->arg, "e", 1)) - level = OSPF6_DEBUG_NEIGHBOR_EVENT; - } - else - level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT; - - OSPF6_DEBUG_NEIGHBOR_ON (level); - return CMD_SUCCESS; + int idx_type = 3; + unsigned char level = 0; + + if (argc == 4) { + if (!strncmp(argv[idx_type]->arg, "s", 1)) + level = OSPF6_DEBUG_NEIGHBOR_STATE; + else if (!strncmp(argv[idx_type]->arg, "e", 1)) + level = OSPF6_DEBUG_NEIGHBOR_EVENT; + } else + level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT; + + OSPF6_DEBUG_NEIGHBOR_ON(level); + return CMD_SUCCESS; } @@ -918,21 +874,19 @@ DEFUN (no_debug_ospf6_neighbor, "Debug OSPFv3 Neighbor State Change\n" "Debug OSPFv3 Neighbor Event\n") { - int idx_type = 4; - unsigned char level = 0; - - if (argc == 5) - { - if (! strncmp (argv[idx_type]->arg, "s", 1)) - level = OSPF6_DEBUG_NEIGHBOR_STATE; - if (! strncmp (argv[idx_type]->arg, "e", 1)) - level = OSPF6_DEBUG_NEIGHBOR_EVENT; - } - else - level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT; - - OSPF6_DEBUG_NEIGHBOR_OFF (level); - return CMD_SUCCESS; + int idx_type = 4; + unsigned char level = 0; + + if (argc == 5) { + if (!strncmp(argv[idx_type]->arg, "s", 1)) + level = OSPF6_DEBUG_NEIGHBOR_STATE; + if (!strncmp(argv[idx_type]->arg, "e", 1)) + level = OSPF6_DEBUG_NEIGHBOR_EVENT; + } else + level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT; + + OSPF6_DEBUG_NEIGHBOR_OFF(level); + return CMD_SUCCESS; } @@ -943,66 +897,61 @@ DEFUN (no_debug_ospf6, DEBUG_STR OSPF6_STR) { - u_int i; - struct ospf6_lsa_handler *handler = NULL; - - OSPF6_DEBUG_ABR_OFF (); - OSPF6_DEBUG_ASBR_OFF (); - OSPF6_DEBUG_BROUTER_OFF (); - OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF (); - OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF (); - OSPF6_DEBUG_FLOODING_OFF (); - OSPF6_DEBUG_INTERFACE_OFF (); - - for (i = 0; i < vector_active (ospf6_lsa_handler_vector); i++) - { - handler = vector_slot (ospf6_lsa_handler_vector, i); - - if (handler != NULL) - { - UNSET_FLAG (handler->debug, OSPF6_LSA_DEBUG); - } - } - - for (i = 0; i < 6; i++) - OSPF6_DEBUG_MESSAGE_OFF (i, OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT); - - OSPF6_DEBUG_NEIGHBOR_OFF (OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT); - OSPF6_DEBUG_ROUTE_OFF (OSPF6_DEBUG_ROUTE_TABLE); - OSPF6_DEBUG_ROUTE_OFF (OSPF6_DEBUG_ROUTE_INTRA); - OSPF6_DEBUG_ROUTE_OFF (OSPF6_DEBUG_ROUTE_INTER); - OSPF6_DEBUG_ROUTE_OFF (OSPF6_DEBUG_ROUTE_MEMORY); - OSPF6_DEBUG_SPF_OFF (OSPF6_DEBUG_SPF_PROCESS); - OSPF6_DEBUG_SPF_OFF (OSPF6_DEBUG_SPF_TIME); - OSPF6_DEBUG_SPF_OFF (OSPF6_DEBUG_SPF_DATABASE); - OSPF6_DEBUG_ZEBRA_OFF (OSPF6_DEBUG_ZEBRA_SEND | OSPF6_DEBUG_ZEBRA_RECV); - - return CMD_SUCCESS; + u_int i; + struct ospf6_lsa_handler *handler = NULL; + + OSPF6_DEBUG_ABR_OFF(); + OSPF6_DEBUG_ASBR_OFF(); + OSPF6_DEBUG_BROUTER_OFF(); + OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF(); + OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF(); + OSPF6_DEBUG_FLOODING_OFF(); + OSPF6_DEBUG_INTERFACE_OFF(); + + for (i = 0; i < vector_active(ospf6_lsa_handler_vector); i++) { + handler = vector_slot(ospf6_lsa_handler_vector, i); + + if (handler != NULL) { + UNSET_FLAG(handler->debug, OSPF6_LSA_DEBUG); + } + } + + for (i = 0; i < 6; i++) + OSPF6_DEBUG_MESSAGE_OFF(i, + OSPF6_DEBUG_NEIGHBOR_STATE + | OSPF6_DEBUG_NEIGHBOR_EVENT); + + OSPF6_DEBUG_NEIGHBOR_OFF(OSPF6_DEBUG_NEIGHBOR_STATE + | OSPF6_DEBUG_NEIGHBOR_EVENT); + OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_TABLE); + OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_INTRA); + OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_INTER); + OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_MEMORY); + OSPF6_DEBUG_SPF_OFF(OSPF6_DEBUG_SPF_PROCESS); + OSPF6_DEBUG_SPF_OFF(OSPF6_DEBUG_SPF_TIME); + OSPF6_DEBUG_SPF_OFF(OSPF6_DEBUG_SPF_DATABASE); + OSPF6_DEBUG_ZEBRA_OFF(OSPF6_DEBUG_ZEBRA_SEND | OSPF6_DEBUG_ZEBRA_RECV); + + return CMD_SUCCESS; } -int -config_write_ospf6_debug_neighbor (struct vty *vty) +int config_write_ospf6_debug_neighbor(struct vty *vty) { - if (IS_OSPF6_DEBUG_NEIGHBOR (STATE) && - IS_OSPF6_DEBUG_NEIGHBOR (EVENT)) - vty_out (vty, "debug ospf6 neighbor\n"); - else if (IS_OSPF6_DEBUG_NEIGHBOR (STATE)) - vty_out (vty, "debug ospf6 neighbor state\n"); - else if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT)) - vty_out (vty, "debug ospf6 neighbor event\n"); - return 0; + if (IS_OSPF6_DEBUG_NEIGHBOR(STATE) && IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) + vty_out(vty, "debug ospf6 neighbor\n"); + else if (IS_OSPF6_DEBUG_NEIGHBOR(STATE)) + vty_out(vty, "debug ospf6 neighbor state\n"); + else if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) + vty_out(vty, "debug ospf6 neighbor event\n"); + return 0; } -void -install_element_ospf6_debug_neighbor (void) +void install_element_ospf6_debug_neighbor(void) { - install_element (ENABLE_NODE, &debug_ospf6_neighbor_cmd); - install_element (ENABLE_NODE, &no_debug_ospf6_neighbor_cmd); - install_element (ENABLE_NODE, &no_debug_ospf6_cmd); - install_element (CONFIG_NODE, &debug_ospf6_neighbor_cmd); - install_element (CONFIG_NODE, &no_debug_ospf6_neighbor_cmd); - install_element (CONFIG_NODE, &no_debug_ospf6_cmd); + install_element(ENABLE_NODE, &debug_ospf6_neighbor_cmd); + install_element(ENABLE_NODE, &no_debug_ospf6_neighbor_cmd); + install_element(ENABLE_NODE, &no_debug_ospf6_cmd); + install_element(CONFIG_NODE, &debug_ospf6_neighbor_cmd); + install_element(CONFIG_NODE, &no_debug_ospf6_neighbor_cmd); + install_element(CONFIG_NODE, &no_debug_ospf6_cmd); } - - - diff --git a/ospf6d/ospf6_neighbor.h b/ospf6d/ospf6_neighbor.h index 3ff341933..529f586f1 100644 --- a/ospf6d/ospf6_neighbor.h +++ b/ospf6d/ospf6_neighbor.h @@ -27,79 +27,76 @@ extern unsigned char conf_debug_ospf6_neighbor; #define OSPF6_DEBUG_NEIGHBOR_STATE 0x01 #define OSPF6_DEBUG_NEIGHBOR_EVENT 0x02 -#define OSPF6_DEBUG_NEIGHBOR_ON(level) \ - (conf_debug_ospf6_neighbor |= (level)) -#define OSPF6_DEBUG_NEIGHBOR_OFF(level) \ - (conf_debug_ospf6_neighbor &= ~(level)) -#define IS_OSPF6_DEBUG_NEIGHBOR(level) \ - (conf_debug_ospf6_neighbor & OSPF6_DEBUG_NEIGHBOR_ ## level) +#define OSPF6_DEBUG_NEIGHBOR_ON(level) (conf_debug_ospf6_neighbor |= (level)) +#define OSPF6_DEBUG_NEIGHBOR_OFF(level) (conf_debug_ospf6_neighbor &= ~(level)) +#define IS_OSPF6_DEBUG_NEIGHBOR(level) \ + (conf_debug_ospf6_neighbor & OSPF6_DEBUG_NEIGHBOR_##level) /* Neighbor structure */ -struct ospf6_neighbor -{ - /* Neighbor Router ID String */ - char name[32]; +struct ospf6_neighbor { + /* Neighbor Router ID String */ + char name[32]; - /* OSPFv3 Interface this neighbor belongs to */ - struct ospf6_interface *ospf6_if; + /* OSPFv3 Interface this neighbor belongs to */ + struct ospf6_interface *ospf6_if; - /* Neighbor state */ - u_char state; + /* Neighbor state */ + u_char state; - /* timestamp of last changing state */ - u_int32_t state_change; - struct timeval last_changed; + /* timestamp of last changing state */ + u_int32_t state_change; + struct timeval last_changed; - /* Neighbor Router ID */ - u_int32_t router_id; + /* Neighbor Router ID */ + u_int32_t router_id; - /* Neighbor Interface ID */ - ifindex_t ifindex; + /* Neighbor Interface ID */ + ifindex_t ifindex; - /* Router Priority of this neighbor */ - u_char priority; + /* Router Priority of this neighbor */ + u_char priority; - u_int32_t drouter; - u_int32_t bdrouter; - u_int32_t prev_drouter; - u_int32_t prev_bdrouter; + u_int32_t drouter; + u_int32_t bdrouter; + u_int32_t prev_drouter; + u_int32_t prev_bdrouter; - /* Options field (Capability) */ - char options[3]; + /* Options field (Capability) */ + char options[3]; - /* IPaddr of I/F on our side link */ - struct in6_addr linklocal_addr; + /* IPaddr of I/F on our side link */ + struct in6_addr linklocal_addr; - /* For Database Exchange */ - u_char dbdesc_bits; - u_int32_t dbdesc_seqnum; - /* Last received Database Description packet */ - struct ospf6_dbdesc dbdesc_last; + /* For Database Exchange */ + u_char dbdesc_bits; + u_int32_t dbdesc_seqnum; + /* Last received Database Description packet */ + struct ospf6_dbdesc dbdesc_last; - /* LS-list */ - struct ospf6_lsdb *summary_list; - struct ospf6_lsdb *request_list; - struct ospf6_lsdb *retrans_list; + /* LS-list */ + struct ospf6_lsdb *summary_list; + struct ospf6_lsdb *request_list; + struct ospf6_lsdb *retrans_list; - /* LSA list for message transmission */ - struct ospf6_lsdb *dbdesc_list; - struct ospf6_lsdb *lsreq_list; - struct ospf6_lsdb *lsupdate_list; - struct ospf6_lsdb *lsack_list; + /* LSA list for message transmission */ + struct ospf6_lsdb *dbdesc_list; + struct ospf6_lsdb *lsreq_list; + struct ospf6_lsdb *lsupdate_list; + struct ospf6_lsdb *lsack_list; - struct ospf6_lsa *last_ls_req; + struct ospf6_lsa *last_ls_req; - /* Inactivity timer */ - struct thread *inactivity_timer; + /* Inactivity timer */ + struct thread *inactivity_timer; - /* Thread for sending message */ - struct thread *thread_send_dbdesc; - struct thread *thread_send_lsreq; - struct thread *thread_send_lsupdate; - struct thread *thread_send_lsack; + /* Thread for sending message */ + struct thread *thread_send_dbdesc; + struct thread *thread_send_lsreq; + struct thread *thread_send_lsupdate; + struct thread *thread_send_lsack; - /* BFD information */ - void *bfd_info; + /* BFD information */ + void *bfd_info; }; /* Neighbor state */ @@ -126,62 +123,53 @@ struct ospf6_neighbor #define OSPF6_NEIGHBOR_EVENT_INACTIVITY_TIMER 10 #define OSPF6_NEIGHBOR_EVENT_MAX_EVENT 11 -static const char *ospf6_neighbor_event_str[] = - { - "NoEvent", - "HelloReceived", - "2-WayReceived", - "NegotiationDone", - "ExchangeDone", - "LoadingDone", - "AdjOK?", - "SeqNumberMismatch", - "BadLSReq", - "1-WayReceived", - "InactivityTimer", - }; - -static inline const char *ospf6_neighbor_event_string (int event) +static const char *ospf6_neighbor_event_str[] = { + "NoEvent", "HelloReceived", "2-WayReceived", "NegotiationDone", + "ExchangeDone", "LoadingDone", "AdjOK?", "SeqNumberMismatch", + "BadLSReq", "1-WayReceived", "InactivityTimer", +}; + +static inline const char *ospf6_neighbor_event_string(int event) { - #define OSPF6_NEIGHBOR_UNKNOWN_EVENT_STRING "UnknownEvent" +#define OSPF6_NEIGHBOR_UNKNOWN_EVENT_STRING "UnknownEvent" - if (event < OSPF6_NEIGHBOR_EVENT_MAX_EVENT) - return ospf6_neighbor_event_str[event]; - return OSPF6_NEIGHBOR_UNKNOWN_EVENT_STRING; + if (event < OSPF6_NEIGHBOR_EVENT_MAX_EVENT) + return ospf6_neighbor_event_str[event]; + return OSPF6_NEIGHBOR_UNKNOWN_EVENT_STRING; } extern const char *ospf6_neighbor_state_str[]; /* Function Prototypes */ -int ospf6_neighbor_cmp (void *va, void *vb); -void ospf6_neighbor_dbex_init (struct ospf6_neighbor *on); +int ospf6_neighbor_cmp(void *va, void *vb); +void ospf6_neighbor_dbex_init(struct ospf6_neighbor *on); -struct ospf6_neighbor *ospf6_neighbor_lookup (u_int32_t, - struct ospf6_interface *); -struct ospf6_neighbor *ospf6_neighbor_create (u_int32_t, - struct ospf6_interface *); -void ospf6_neighbor_delete (struct ospf6_neighbor *); +struct ospf6_neighbor *ospf6_neighbor_lookup(u_int32_t, + struct ospf6_interface *); +struct ospf6_neighbor *ospf6_neighbor_create(u_int32_t, + struct ospf6_interface *); +void ospf6_neighbor_delete(struct ospf6_neighbor *); /* Neighbor event */ -extern int hello_received (struct thread *); -extern int twoway_received (struct thread *); -extern int negotiation_done (struct thread *); -extern int exchange_done (struct thread *); -extern int loading_done (struct thread *); -extern int adj_ok (struct thread *); -extern int seqnumber_mismatch (struct thread *); -extern int bad_lsreq (struct thread *); -extern int oneway_received (struct thread *); -extern int inactivity_timer (struct thread *); -extern void ospf6_check_nbr_loading (struct ospf6_neighbor *); - -extern void ospf6_neighbor_init (void); -extern int config_write_ospf6_debug_neighbor (struct vty *vty); -extern void install_element_ospf6_debug_neighbor (void); +extern int hello_received(struct thread *); +extern int twoway_received(struct thread *); +extern int negotiation_done(struct thread *); +extern int exchange_done(struct thread *); +extern int loading_done(struct thread *); +extern int adj_ok(struct thread *); +extern int seqnumber_mismatch(struct thread *); +extern int bad_lsreq(struct thread *); +extern int oneway_received(struct thread *); +extern int inactivity_timer(struct thread *); +extern void ospf6_check_nbr_loading(struct ospf6_neighbor *); + +extern void ospf6_neighbor_init(void); +extern int config_write_ospf6_debug_neighbor(struct vty *vty); +extern void install_element_ospf6_debug_neighbor(void); DECLARE_HOOK(ospf6_neighbor_change, - (struct ospf6_neighbor *on, int state, int next_state), - (on, state, next_state)) + (struct ospf6_neighbor * on, int state, int next_state), + (on, state, next_state)) #endif /* OSPF6_NEIGHBOR_H */ diff --git a/ospf6d/ospf6_network.c b/ospf6d/ospf6_network.c index 9e7dd06bd..4d9c25944 100644 --- a/ospf6d/ospf6_network.c +++ b/ospf6d/ospf6_network.c @@ -32,237 +32,225 @@ extern struct zebra_privs_t ospf6d_privs; -int ospf6_sock; +int ospf6_sock; struct in6_addr allspfrouters6; struct in6_addr alldrouters6; /* setsockopt MulticastLoop to off */ -static void -ospf6_reset_mcastloop (void) +static void ospf6_reset_mcastloop(void) { - u_int off = 0; - if (setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, - &off, sizeof (u_int)) < 0) - zlog_warn ("Network: reset IPV6_MULTICAST_LOOP failed: %s", - safe_strerror (errno)); + u_int off = 0; + if (setsockopt(ospf6_sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &off, + sizeof(u_int)) + < 0) + zlog_warn("Network: reset IPV6_MULTICAST_LOOP failed: %s", + safe_strerror(errno)); } -static void -ospf6_set_pktinfo (void) +static void ospf6_set_pktinfo(void) { - setsockopt_ipv6_pktinfo (ospf6_sock, 1); + setsockopt_ipv6_pktinfo(ospf6_sock, 1); } -static void -ospf6_set_transport_class (void) +static void ospf6_set_transport_class(void) { #ifdef IPTOS_PREC_INTERNETCONTROL - setsockopt_ipv6_tclass (ospf6_sock, IPTOS_PREC_INTERNETCONTROL); + setsockopt_ipv6_tclass(ospf6_sock, IPTOS_PREC_INTERNETCONTROL); #endif } -static void -ospf6_set_checksum (void) +static void ospf6_set_checksum(void) { - int offset = 12; + int offset = 12; #ifndef DISABLE_IPV6_CHECKSUM - if (setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_CHECKSUM, - &offset, sizeof (offset)) < 0) - zlog_warn ("Network: set IPV6_CHECKSUM failed: %s", safe_strerror (errno)); + if (setsockopt(ospf6_sock, IPPROTO_IPV6, IPV6_CHECKSUM, &offset, + sizeof(offset)) + < 0) + zlog_warn("Network: set IPV6_CHECKSUM failed: %s", + safe_strerror(errno)); #else - zlog_warn ("Network: Don't set IPV6_CHECKSUM"); + zlog_warn("Network: Don't set IPV6_CHECKSUM"); #endif /* DISABLE_IPV6_CHECKSUM */ } /* Make ospf6d's server socket. */ -int -ospf6_serv_sock (void) +int ospf6_serv_sock(void) { - if (ospf6d_privs.change (ZPRIVS_RAISE)) - zlog_err ("ospf6_serv_sock: could not raise privs"); - - ospf6_sock = socket (AF_INET6, SOCK_RAW, IPPROTO_OSPFIGP); - if (ospf6_sock < 0) - { - zlog_warn ("Network: can't create OSPF6 socket."); - if (ospf6d_privs.change (ZPRIVS_LOWER)) - zlog_err ("ospf_sock_init: could not lower privs"); - return -1; - } - if (ospf6d_privs.change (ZPRIVS_LOWER)) - zlog_err ("ospf_sock_init: could not lower privs"); - - /* set socket options */ + if (ospf6d_privs.change(ZPRIVS_RAISE)) + zlog_err("ospf6_serv_sock: could not raise privs"); + + ospf6_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_OSPFIGP); + if (ospf6_sock < 0) { + zlog_warn("Network: can't create OSPF6 socket."); + if (ospf6d_privs.change(ZPRIVS_LOWER)) + zlog_err("ospf_sock_init: could not lower privs"); + return -1; + } + if (ospf6d_privs.change(ZPRIVS_LOWER)) + zlog_err("ospf_sock_init: could not lower privs"); + +/* set socket options */ #if 1 - sockopt_reuseaddr (ospf6_sock); + sockopt_reuseaddr(ospf6_sock); #else - ospf6_set_reuseaddr (); + ospf6_set_reuseaddr(); #endif /*1*/ - ospf6_reset_mcastloop (); - ospf6_set_pktinfo (); - ospf6_set_transport_class (); - ospf6_set_checksum (); + ospf6_reset_mcastloop(); + ospf6_set_pktinfo(); + ospf6_set_transport_class(); + ospf6_set_checksum(); - /* setup global in6_addr, allspf6 and alldr6 for later use */ - inet_pton (AF_INET6, ALLSPFROUTERS6, &allspfrouters6); - inet_pton (AF_INET6, ALLDROUTERS6, &alldrouters6); + /* setup global in6_addr, allspf6 and alldr6 for later use */ + inet_pton(AF_INET6, ALLSPFROUTERS6, &allspfrouters6); + inet_pton(AF_INET6, ALLDROUTERS6, &alldrouters6); - return 0; + return 0; } /* ospf6 set socket option */ -int -ospf6_sso (ifindex_t ifindex, struct in6_addr *group, int option) +int ospf6_sso(ifindex_t ifindex, struct in6_addr *group, int option) { - struct ipv6_mreq mreq6; - int ret; - int bufsize = (8 * 1024 * 1024); - - assert (ifindex); - mreq6.ipv6mr_interface = ifindex; - memcpy (&mreq6.ipv6mr_multiaddr, group, sizeof (struct in6_addr)); - - ret = setsockopt (ospf6_sock, IPPROTO_IPV6, option, - &mreq6, sizeof (mreq6)); - if (ret < 0) - { - zlog_err ("Network: setsockopt (%d) on ifindex %d failed: %s", - option, ifindex, safe_strerror (errno)); - return ret; - } - - setsockopt_so_sendbuf (ospf6_sock, bufsize); - setsockopt_so_recvbuf (ospf6_sock, bufsize); - - return 0; + struct ipv6_mreq mreq6; + int ret; + int bufsize = (8 * 1024 * 1024); + + assert(ifindex); + mreq6.ipv6mr_interface = ifindex; + memcpy(&mreq6.ipv6mr_multiaddr, group, sizeof(struct in6_addr)); + + ret = setsockopt(ospf6_sock, IPPROTO_IPV6, option, &mreq6, + sizeof(mreq6)); + if (ret < 0) { + zlog_err("Network: setsockopt (%d) on ifindex %d failed: %s", + option, ifindex, safe_strerror(errno)); + return ret; + } + + setsockopt_so_sendbuf(ospf6_sock, bufsize); + setsockopt_so_recvbuf(ospf6_sock, bufsize); + + return 0; } -static int -iov_count (struct iovec *iov) +static int iov_count(struct iovec *iov) { - int i; - for (i = 0; iov[i].iov_base; i++) - ; - return i; + int i; + for (i = 0; iov[i].iov_base; i++) + ; + return i; } -static int -iov_totallen (struct iovec *iov) +static int iov_totallen(struct iovec *iov) { - int i; - int totallen = 0; - for (i = 0; iov[i].iov_base; i++) - totallen += iov[i].iov_len; - return totallen; + int i; + int totallen = 0; + for (i = 0; iov[i].iov_base; i++) + totallen += iov[i].iov_len; + return totallen; } -int -ospf6_sendmsg (struct in6_addr *src, struct in6_addr *dst, - ifindex_t *ifindex, struct iovec *message) +int ospf6_sendmsg(struct in6_addr *src, struct in6_addr *dst, + ifindex_t *ifindex, struct iovec *message) { - int retval; - struct msghdr smsghdr; - struct cmsghdr *scmsgp; - union - { - struct cmsghdr hdr; - u_char buf[CMSG_SPACE (sizeof (struct in6_pktinfo))]; - } cmsgbuf; - struct in6_pktinfo *pktinfo; - struct sockaddr_in6 dst_sin6; - - assert (dst); - assert (*ifindex); - - scmsgp = (struct cmsghdr *)&cmsgbuf; - pktinfo = (struct in6_pktinfo *)(CMSG_DATA(scmsgp)); - memset (&dst_sin6, 0, sizeof (struct sockaddr_in6)); - - /* source address */ - pktinfo->ipi6_ifindex = *ifindex; - if (src) - memcpy (&pktinfo->ipi6_addr, src, sizeof (struct in6_addr)); - else - memset (&pktinfo->ipi6_addr, 0, sizeof (struct in6_addr)); - - /* destination address */ - dst_sin6.sin6_family = AF_INET6; + int retval; + struct msghdr smsghdr; + struct cmsghdr *scmsgp; + union { + struct cmsghdr hdr; + u_char buf[CMSG_SPACE(sizeof(struct in6_pktinfo))]; + } cmsgbuf; + struct in6_pktinfo *pktinfo; + struct sockaddr_in6 dst_sin6; + + assert(dst); + assert(*ifindex); + + scmsgp = (struct cmsghdr *)&cmsgbuf; + pktinfo = (struct in6_pktinfo *)(CMSG_DATA(scmsgp)); + memset(&dst_sin6, 0, sizeof(struct sockaddr_in6)); + + /* source address */ + pktinfo->ipi6_ifindex = *ifindex; + if (src) + memcpy(&pktinfo->ipi6_addr, src, sizeof(struct in6_addr)); + else + memset(&pktinfo->ipi6_addr, 0, sizeof(struct in6_addr)); + + /* destination address */ + dst_sin6.sin6_family = AF_INET6; #ifdef SIN6_LEN - dst_sin6.sin6_len = sizeof (struct sockaddr_in6); + dst_sin6.sin6_len = sizeof(struct sockaddr_in6); #endif /*SIN6_LEN*/ - memcpy (&dst_sin6.sin6_addr, dst, sizeof (struct in6_addr)); - dst_sin6.sin6_scope_id = *ifindex; - - /* send control msg */ - scmsgp->cmsg_level = IPPROTO_IPV6; - scmsgp->cmsg_type = IPV6_PKTINFO; - scmsgp->cmsg_len = CMSG_LEN (sizeof (struct in6_pktinfo)); - /* scmsgp = CMSG_NXTHDR (&smsghdr, scmsgp); */ - - /* send msg hdr */ - memset (&smsghdr, 0, sizeof (smsghdr)); - smsghdr.msg_iov = message; - smsghdr.msg_iovlen = iov_count (message); - smsghdr.msg_name = (caddr_t) &dst_sin6; - smsghdr.msg_namelen = sizeof (struct sockaddr_in6); - smsghdr.msg_control = (caddr_t) &cmsgbuf.buf; - smsghdr.msg_controllen = sizeof(cmsgbuf.buf); - - retval = sendmsg (ospf6_sock, &smsghdr, 0); - if (retval != iov_totallen (message)) - zlog_warn ("sendmsg failed: ifindex: %d: %s (%d)", - *ifindex, safe_strerror (errno), errno); - - return retval; + memcpy(&dst_sin6.sin6_addr, dst, sizeof(struct in6_addr)); + dst_sin6.sin6_scope_id = *ifindex; + + /* send control msg */ + scmsgp->cmsg_level = IPPROTO_IPV6; + scmsgp->cmsg_type = IPV6_PKTINFO; + scmsgp->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); + /* scmsgp = CMSG_NXTHDR (&smsghdr, scmsgp); */ + + /* send msg hdr */ + memset(&smsghdr, 0, sizeof(smsghdr)); + smsghdr.msg_iov = message; + smsghdr.msg_iovlen = iov_count(message); + smsghdr.msg_name = (caddr_t)&dst_sin6; + smsghdr.msg_namelen = sizeof(struct sockaddr_in6); + smsghdr.msg_control = (caddr_t)&cmsgbuf.buf; + smsghdr.msg_controllen = sizeof(cmsgbuf.buf); + + retval = sendmsg(ospf6_sock, &smsghdr, 0); + if (retval != iov_totallen(message)) + zlog_warn("sendmsg failed: ifindex: %d: %s (%d)", *ifindex, + safe_strerror(errno), errno); + + return retval; } -int -ospf6_recvmsg (struct in6_addr *src, struct in6_addr *dst, - ifindex_t *ifindex, struct iovec *message) +int ospf6_recvmsg(struct in6_addr *src, struct in6_addr *dst, + ifindex_t *ifindex, struct iovec *message) { - int retval; - struct msghdr rmsghdr; - struct cmsghdr *rcmsgp; - u_char cmsgbuf[CMSG_SPACE(sizeof (struct in6_pktinfo))]; - struct in6_pktinfo *pktinfo; - struct sockaddr_in6 src_sin6; - - rcmsgp = (struct cmsghdr *)cmsgbuf; - pktinfo = (struct in6_pktinfo *)(CMSG_DATA(rcmsgp)); - memset (&src_sin6, 0, sizeof (struct sockaddr_in6)); - - /* receive control msg */ - rcmsgp->cmsg_level = IPPROTO_IPV6; - rcmsgp->cmsg_type = IPV6_PKTINFO; - rcmsgp->cmsg_len = CMSG_LEN (sizeof (struct in6_pktinfo)); - /* rcmsgp = CMSG_NXTHDR (&rmsghdr, rcmsgp); */ - - /* receive msg hdr */ - memset (&rmsghdr, 0, sizeof (rmsghdr)); - rmsghdr.msg_iov = message; - rmsghdr.msg_iovlen = iov_count (message); - rmsghdr.msg_name = (caddr_t) &src_sin6; - rmsghdr.msg_namelen = sizeof (struct sockaddr_in6); - rmsghdr.msg_control = (caddr_t) cmsgbuf; - rmsghdr.msg_controllen = sizeof (cmsgbuf); - - retval = recvmsg (ospf6_sock, &rmsghdr, 0); - if (retval < 0) - zlog_warn ("recvmsg failed: %s", safe_strerror (errno)); - else if (retval == iov_totallen (message)) - zlog_warn ("recvmsg read full buffer size: %d", retval); - - /* source address */ - assert (src); - memcpy (src, &src_sin6.sin6_addr, sizeof (struct in6_addr)); - - /* destination address */ - if (ifindex) - *ifindex = pktinfo->ipi6_ifindex; - if (dst) - memcpy (dst, &pktinfo->ipi6_addr, sizeof (struct in6_addr)); - - return retval; + int retval; + struct msghdr rmsghdr; + struct cmsghdr *rcmsgp; + u_char cmsgbuf[CMSG_SPACE(sizeof(struct in6_pktinfo))]; + struct in6_pktinfo *pktinfo; + struct sockaddr_in6 src_sin6; + + rcmsgp = (struct cmsghdr *)cmsgbuf; + pktinfo = (struct in6_pktinfo *)(CMSG_DATA(rcmsgp)); + memset(&src_sin6, 0, sizeof(struct sockaddr_in6)); + + /* receive control msg */ + rcmsgp->cmsg_level = IPPROTO_IPV6; + rcmsgp->cmsg_type = IPV6_PKTINFO; + rcmsgp->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); + /* rcmsgp = CMSG_NXTHDR (&rmsghdr, rcmsgp); */ + + /* receive msg hdr */ + memset(&rmsghdr, 0, sizeof(rmsghdr)); + rmsghdr.msg_iov = message; + rmsghdr.msg_iovlen = iov_count(message); + rmsghdr.msg_name = (caddr_t)&src_sin6; + rmsghdr.msg_namelen = sizeof(struct sockaddr_in6); + rmsghdr.msg_control = (caddr_t)cmsgbuf; + rmsghdr.msg_controllen = sizeof(cmsgbuf); + + retval = recvmsg(ospf6_sock, &rmsghdr, 0); + if (retval < 0) + zlog_warn("recvmsg failed: %s", safe_strerror(errno)); + else if (retval == iov_totallen(message)) + zlog_warn("recvmsg read full buffer size: %d", retval); + + /* source address */ + assert(src); + memcpy(src, &src_sin6.sin6_addr, sizeof(struct in6_addr)); + + /* destination address */ + if (ifindex) + *ifindex = pktinfo->ipi6_ifindex; + if (dst) + memcpy(dst, &pktinfo->ipi6_addr, sizeof(struct in6_addr)); + + return retval; } - - diff --git a/ospf6d/ospf6_network.h b/ospf6d/ospf6_network.h index 690901ca0..7c7c155fb 100644 --- a/ospf6d/ospf6_network.h +++ b/ospf6d/ospf6_network.h @@ -21,19 +21,16 @@ #ifndef OSPF6_NETWORK_H #define OSPF6_NETWORK_H - - extern int ospf6_sock; extern struct in6_addr allspfrouters6; extern struct in6_addr alldrouters6; -extern int ospf6_serv_sock (void); -extern int ospf6_sso (ifindex_t ifindex, struct in6_addr *group, int option); +extern int ospf6_serv_sock(void); +extern int ospf6_sso(ifindex_t ifindex, struct in6_addr *group, int option); -extern int ospf6_sendmsg (struct in6_addr *, struct in6_addr *, - ifindex_t *, struct iovec *); -extern int ospf6_recvmsg (struct in6_addr *, struct in6_addr *, - ifindex_t *, struct iovec *); +extern int ospf6_sendmsg(struct in6_addr *, struct in6_addr *, ifindex_t *, + struct iovec *); +extern int ospf6_recvmsg(struct in6_addr *, struct in6_addr *, ifindex_t *, + struct iovec *); #endif /* OSPF6_NETWORK_H */ - diff --git a/ospf6d/ospf6_proto.c b/ospf6d/ospf6_proto.c index 1538c891c..d0ab67655 100644 --- a/ospf6d/ospf6_proto.c +++ b/ospf6d/ospf6_proto.c @@ -24,60 +24,53 @@ #include "ospf6_proto.h" -void -ospf6_prefix_apply_mask (struct ospf6_prefix *op) +void ospf6_prefix_apply_mask(struct ospf6_prefix *op) { - u_char *pnt, mask; - int index, offset; + u_char *pnt, mask; + int index, offset; - pnt = (u_char *)((caddr_t) op + sizeof (struct ospf6_prefix)); - index = op->prefix_length / 8; - offset = op->prefix_length % 8; - mask = 0xff << (8 - offset); + pnt = (u_char *)((caddr_t)op + sizeof(struct ospf6_prefix)); + index = op->prefix_length / 8; + offset = op->prefix_length % 8; + mask = 0xff << (8 - offset); - if (index > 16) - { - zlog_warn ("Prefix length too long: %d", op->prefix_length); - return; - } + if (index > 16) { + zlog_warn("Prefix length too long: %d", op->prefix_length); + return; + } - /* nonzero mask means no check for this byte because if it contains - * prefix bits it must be there for us to write */ - if (mask) - pnt[index++] &= mask; + /* nonzero mask means no check for this byte because if it contains + * prefix bits it must be there for us to write */ + if (mask) + pnt[index++] &= mask; - while (index < OSPF6_PREFIX_SPACE (op->prefix_length)) - pnt[index++] = 0; + while (index < OSPF6_PREFIX_SPACE(op->prefix_length)) + pnt[index++] = 0; } -void -ospf6_prefix_options_printbuf (u_int8_t prefix_options, char *buf, int size) +void ospf6_prefix_options_printbuf(u_int8_t prefix_options, char *buf, int size) { - snprintf (buf, size, "xxx"); + snprintf(buf, size, "xxx"); } -void -ospf6_capability_printbuf (char capability, char *buf, int size) +void ospf6_capability_printbuf(char capability, char *buf, int size) { - char w, v, e, b; - w = (capability & OSPF6_ROUTER_BIT_W ? 'W' : '-'); - v = (capability & OSPF6_ROUTER_BIT_V ? 'V' : '-'); - e = (capability & OSPF6_ROUTER_BIT_E ? 'E' : '-'); - b = (capability & OSPF6_ROUTER_BIT_B ? 'B' : '-'); - snprintf (buf, size, "----%c%c%c%c", w, v, e, b); + char w, v, e, b; + w = (capability & OSPF6_ROUTER_BIT_W ? 'W' : '-'); + v = (capability & OSPF6_ROUTER_BIT_V ? 'V' : '-'); + e = (capability & OSPF6_ROUTER_BIT_E ? 'E' : '-'); + b = (capability & OSPF6_ROUTER_BIT_B ? 'B' : '-'); + snprintf(buf, size, "----%c%c%c%c", w, v, e, b); } -void -ospf6_options_printbuf (u_char *options, char *buf, int size) +void ospf6_options_printbuf(u_char *options, char *buf, int size) { - const char *dc, *r, *n, *mc, *e, *v6; - dc = (OSPF6_OPT_ISSET (options, OSPF6_OPT_DC) ? "DC" : "--"); - r = (OSPF6_OPT_ISSET (options, OSPF6_OPT_R) ? "R" : "-" ); - n = (OSPF6_OPT_ISSET (options, OSPF6_OPT_N) ? "N" : "-" ); - mc = (OSPF6_OPT_ISSET (options, OSPF6_OPT_MC) ? "MC" : "--"); - e = (OSPF6_OPT_ISSET (options, OSPF6_OPT_E) ? "E" : "-" ); - v6 = (OSPF6_OPT_ISSET (options, OSPF6_OPT_V6) ? "V6" : "--"); - snprintf (buf, size, "%s|%s|%s|%s|%s|%s", dc, r, n, mc, e, v6); + const char *dc, *r, *n, *mc, *e, *v6; + dc = (OSPF6_OPT_ISSET(options, OSPF6_OPT_DC) ? "DC" : "--"); + r = (OSPF6_OPT_ISSET(options, OSPF6_OPT_R) ? "R" : "-"); + n = (OSPF6_OPT_ISSET(options, OSPF6_OPT_N) ? "N" : "-"); + mc = (OSPF6_OPT_ISSET(options, OSPF6_OPT_MC) ? "MC" : "--"); + e = (OSPF6_OPT_ISSET(options, OSPF6_OPT_E) ? "E" : "-"); + v6 = (OSPF6_OPT_ISSET(options, OSPF6_OPT_V6) ? "V6" : "--"); + snprintf(buf, size, "%s|%s|%s|%s|%s|%s", dc, r, n, mc, e, v6); } - - diff --git a/ospf6d/ospf6_proto.h b/ospf6d/ospf6_proto.h index e4f29aa3e..174b5a4f0 100644 --- a/ospf6d/ospf6_proto.h +++ b/ospf6d/ospf6_proto.h @@ -52,17 +52,16 @@ /* OSPF6 Prefix */ #define OSPF6_PREFIX_MIN_SIZE 4U /* .length == 0 */ -struct ospf6_prefix -{ - u_int8_t prefix_length; - u_int8_t prefix_options; - union { - u_int16_t _prefix_metric; - u_int16_t _prefix_referenced_lstype; - } u; +struct ospf6_prefix { + u_int8_t prefix_length; + u_int8_t prefix_options; + union { + u_int16_t _prefix_metric; + u_int16_t _prefix_referenced_lstype; + } u; #define prefix_metric u._prefix_metric #define prefix_refer_lstype u._prefix_referenced_lstype - /* followed by one address_prefix */ + /* followed by one address_prefix */ }; #define OSPF6_PREFIX_OPTION_NU (1 << 0) /* No Unicast */ @@ -77,24 +76,24 @@ struct ospf6_prefix #define OSPF6_PREFIX_SPACE(x) ((((x) + 31) / 32) * 4) /* size_t OSPF6_PREFIX_SIZE (struct ospf6_prefix *); */ -#define OSPF6_PREFIX_SIZE(x) \ - (OSPF6_PREFIX_SPACE ((x)->prefix_length) + sizeof (struct ospf6_prefix)) +#define OSPF6_PREFIX_SIZE(x) \ + (OSPF6_PREFIX_SPACE((x)->prefix_length) + sizeof(struct ospf6_prefix)) /* struct ospf6_prefix *OSPF6_PREFIX_NEXT (struct ospf6_prefix *); */ -#define OSPF6_PREFIX_NEXT(x) \ - ((struct ospf6_prefix *)((caddr_t)(x) + OSPF6_PREFIX_SIZE (x))) - -#define ospf6_prefix_in6_addr(in6, op) \ -do { \ - memset (in6, 0, sizeof (struct in6_addr)); \ - memcpy (in6, (caddr_t) (op) + sizeof (struct ospf6_prefix), \ - OSPF6_PREFIX_SPACE ((op)->prefix_length)); \ -} while (0) - -extern void ospf6_prefix_apply_mask (struct ospf6_prefix *op); -extern void ospf6_prefix_options_printbuf (u_int8_t prefix_options, - char *buf, int size); -extern void ospf6_capability_printbuf (char capability, char *buf, int size); -extern void ospf6_options_printbuf (u_char *options, char *buf, int size); +#define OSPF6_PREFIX_NEXT(x) \ + ((struct ospf6_prefix *)((caddr_t)(x) + OSPF6_PREFIX_SIZE(x))) + +#define ospf6_prefix_in6_addr(in6, op) \ + do { \ + memset(in6, 0, sizeof(struct in6_addr)); \ + memcpy(in6, (caddr_t)(op) + sizeof(struct ospf6_prefix), \ + OSPF6_PREFIX_SPACE((op)->prefix_length)); \ + } while (0) + +extern void ospf6_prefix_apply_mask(struct ospf6_prefix *op); +extern void ospf6_prefix_options_printbuf(u_int8_t prefix_options, char *buf, + int size); +extern void ospf6_capability_printbuf(char capability, char *buf, int size); +extern void ospf6_options_printbuf(u_char *options, char *buf, int size); #endif /* OSPF6_PROTO_H */ diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index d223651f4..5e8fd0e15 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -40,1522 +40,1409 @@ unsigned char conf_debug_ospf6_route = 0; -static char * -ospf6_route_table_name (struct ospf6_route_table *table) +static char *ospf6_route_table_name(struct ospf6_route_table *table) { - static char name[64]; - switch (table->scope_type) - { - case OSPF6_SCOPE_TYPE_GLOBAL: - { - switch (table->table_type) - { - case OSPF6_TABLE_TYPE_ROUTES: - snprintf (name, sizeof (name), "global route table"); - break; - case OSPF6_TABLE_TYPE_BORDER_ROUTERS: - snprintf (name, sizeof (name), "global brouter table"); - break; - case OSPF6_TABLE_TYPE_EXTERNAL_ROUTES: - snprintf (name, sizeof (name), "global external table"); - break; - default: - snprintf (name, sizeof (name), "global unknown table"); - break; - } - } - break; - - case OSPF6_SCOPE_TYPE_AREA: - { - struct ospf6_area *oa = (struct ospf6_area *) table->scope; - switch (table->table_type) - { - case OSPF6_TABLE_TYPE_SPF_RESULTS: - snprintf (name, sizeof (name), - "area %s spf table", oa->name); - break; - case OSPF6_TABLE_TYPE_ROUTES: - snprintf (name, sizeof (name), - "area %s route table", oa->name); - break; - case OSPF6_TABLE_TYPE_PREFIX_RANGES: - snprintf (name, sizeof (name), - "area %s range table", oa->name); - break; - case OSPF6_TABLE_TYPE_SUMMARY_PREFIXES: - snprintf (name, sizeof (name), - "area %s summary prefix table", oa->name); - break; - case OSPF6_TABLE_TYPE_SUMMARY_ROUTERS: - snprintf (name, sizeof (name), - "area %s summary router table", oa->name); - break; - default: - snprintf (name, sizeof (name), - "area %s unknown table", oa->name); - break; - } - } - break; - - case OSPF6_SCOPE_TYPE_INTERFACE: - { - struct ospf6_interface *oi = (struct ospf6_interface *) table->scope; - switch (table->table_type) - { - case OSPF6_TABLE_TYPE_CONNECTED_ROUTES: - snprintf (name, sizeof (name), "interface %s connected table", - oi->interface->name); - break; - default: - snprintf (name, sizeof (name), "interface %s unknown table", - oi->interface->name); - break; - } - } - break; - - default: - { - switch (table->table_type) - { - case OSPF6_TABLE_TYPE_SPF_RESULTS: - snprintf (name, sizeof (name), "temporary spf table"); - break; - default: - snprintf (name, sizeof (name), "temporary unknown table"); - break; - } - } - break; - } - return name; + static char name[64]; + switch (table->scope_type) { + case OSPF6_SCOPE_TYPE_GLOBAL: { + switch (table->table_type) { + case OSPF6_TABLE_TYPE_ROUTES: + snprintf(name, sizeof(name), "global route table"); + break; + case OSPF6_TABLE_TYPE_BORDER_ROUTERS: + snprintf(name, sizeof(name), "global brouter table"); + break; + case OSPF6_TABLE_TYPE_EXTERNAL_ROUTES: + snprintf(name, sizeof(name), "global external table"); + break; + default: + snprintf(name, sizeof(name), "global unknown table"); + break; + } + } break; + + case OSPF6_SCOPE_TYPE_AREA: { + struct ospf6_area *oa = (struct ospf6_area *)table->scope; + switch (table->table_type) { + case OSPF6_TABLE_TYPE_SPF_RESULTS: + snprintf(name, sizeof(name), "area %s spf table", + oa->name); + break; + case OSPF6_TABLE_TYPE_ROUTES: + snprintf(name, sizeof(name), "area %s route table", + oa->name); + break; + case OSPF6_TABLE_TYPE_PREFIX_RANGES: + snprintf(name, sizeof(name), "area %s range table", + oa->name); + break; + case OSPF6_TABLE_TYPE_SUMMARY_PREFIXES: + snprintf(name, sizeof(name), + "area %s summary prefix table", oa->name); + break; + case OSPF6_TABLE_TYPE_SUMMARY_ROUTERS: + snprintf(name, sizeof(name), + "area %s summary router table", oa->name); + break; + default: + snprintf(name, sizeof(name), "area %s unknown table", + oa->name); + break; + } + } break; + + case OSPF6_SCOPE_TYPE_INTERFACE: { + struct ospf6_interface *oi = + (struct ospf6_interface *)table->scope; + switch (table->table_type) { + case OSPF6_TABLE_TYPE_CONNECTED_ROUTES: + snprintf(name, sizeof(name), + "interface %s connected table", + oi->interface->name); + break; + default: + snprintf(name, sizeof(name), + "interface %s unknown table", + oi->interface->name); + break; + } + } break; + + default: { + switch (table->table_type) { + case OSPF6_TABLE_TYPE_SPF_RESULTS: + snprintf(name, sizeof(name), "temporary spf table"); + break; + default: + snprintf(name, sizeof(name), "temporary unknown table"); + break; + } + } break; + } + return name; } -void -ospf6_linkstate_prefix (u_int32_t adv_router, u_int32_t id, - struct prefix *prefix) +void ospf6_linkstate_prefix(u_int32_t adv_router, u_int32_t id, + struct prefix *prefix) { - memset (prefix, 0, sizeof (struct prefix)); - prefix->family = AF_INET6; - prefix->prefixlen = 64; - memcpy (&prefix->u.prefix6.s6_addr[0], &adv_router, 4); - memcpy (&prefix->u.prefix6.s6_addr[4], &id, 4); + memset(prefix, 0, sizeof(struct prefix)); + prefix->family = AF_INET6; + prefix->prefixlen = 64; + memcpy(&prefix->u.prefix6.s6_addr[0], &adv_router, 4); + memcpy(&prefix->u.prefix6.s6_addr[4], &id, 4); } -void -ospf6_linkstate_prefix2str (struct prefix *prefix, char *buf, int size) +void ospf6_linkstate_prefix2str(struct prefix *prefix, char *buf, int size) { - u_int32_t adv_router, id; - char adv_router_str[16], id_str[16]; - memcpy (&adv_router, &prefix->u.prefix6.s6_addr[0], 4); - memcpy (&id, &prefix->u.prefix6.s6_addr[4], 4); - inet_ntop (AF_INET, &adv_router, adv_router_str, sizeof (adv_router_str)); - inet_ntop (AF_INET, &id, id_str, sizeof (id_str)); - if (ntohl (id)) - snprintf (buf, size, "%s Net-ID: %s", adv_router_str, id_str); - else - snprintf (buf, size, "%s", adv_router_str); + u_int32_t adv_router, id; + char adv_router_str[16], id_str[16]; + memcpy(&adv_router, &prefix->u.prefix6.s6_addr[0], 4); + memcpy(&id, &prefix->u.prefix6.s6_addr[4], 4); + inet_ntop(AF_INET, &adv_router, adv_router_str, sizeof(adv_router_str)); + inet_ntop(AF_INET, &id, id_str, sizeof(id_str)); + if (ntohl(id)) + snprintf(buf, size, "%s Net-ID: %s", adv_router_str, id_str); + else + snprintf(buf, size, "%s", adv_router_str); } /* Global strings for logging */ -const char *ospf6_dest_type_str[OSPF6_DEST_TYPE_MAX] = -{ "Unknown", "Router", "Network", "Discard", "Linkstate", "AddressRange", }; +const char *ospf6_dest_type_str[OSPF6_DEST_TYPE_MAX] = { + "Unknown", "Router", "Network", "Discard", "Linkstate", "AddressRange", +}; -const char *ospf6_dest_type_substr[OSPF6_DEST_TYPE_MAX] = -{ "?", "R", "N", "D", "L", "A", }; +const char *ospf6_dest_type_substr[OSPF6_DEST_TYPE_MAX] = { + "?", "R", "N", "D", "L", "A", +}; -const char *ospf6_path_type_str[OSPF6_PATH_TYPE_MAX] = -{ "Unknown", "Intra-Area", "Inter-Area", "External-1", "External-2", }; +const char *ospf6_path_type_str[OSPF6_PATH_TYPE_MAX] = { + "Unknown", "Intra-Area", "Inter-Area", "External-1", "External-2", +}; -const char *ospf6_path_type_substr[OSPF6_PATH_TYPE_MAX] = -{ "??", "IA", "IE", "E1", "E2", }; +const char *ospf6_path_type_substr[OSPF6_PATH_TYPE_MAX] = { + "??", "IA", "IE", "E1", "E2", +}; -struct ospf6_nexthop * -ospf6_nexthop_create (void) +struct ospf6_nexthop *ospf6_nexthop_create(void) { - struct ospf6_nexthop *nh; + struct ospf6_nexthop *nh; - nh = XCALLOC (MTYPE_OSPF6_NEXTHOP, sizeof (struct ospf6_nexthop)); - return nh; + nh = XCALLOC(MTYPE_OSPF6_NEXTHOP, sizeof(struct ospf6_nexthop)); + return nh; } -void -ospf6_nexthop_delete (struct ospf6_nexthop *nh) +void ospf6_nexthop_delete(struct ospf6_nexthop *nh) { - if (nh) - XFREE (MTYPE_OSPF6_NEXTHOP, nh); + if (nh) + XFREE(MTYPE_OSPF6_NEXTHOP, nh); } -void -ospf6_free_nexthops (struct list *nh_list) +void ospf6_free_nexthops(struct list *nh_list) { - struct ospf6_nexthop *nh; - struct listnode *node, *nnode; - - if (nh_list) - { - for (ALL_LIST_ELEMENTS (nh_list, node, nnode, nh)) - ospf6_nexthop_delete (nh); - } + struct ospf6_nexthop *nh; + struct listnode *node, *nnode; + + if (nh_list) { + for (ALL_LIST_ELEMENTS(nh_list, node, nnode, nh)) + ospf6_nexthop_delete(nh); + } } -void -ospf6_clear_nexthops (struct list *nh_list) +void ospf6_clear_nexthops(struct list *nh_list) { - struct listnode *node; - struct ospf6_nexthop *nh; - - if (nh_list) - { - for (ALL_LIST_ELEMENTS_RO (nh_list, node, nh)) - ospf6_nexthop_clear (nh); - } + struct listnode *node; + struct ospf6_nexthop *nh; + + if (nh_list) { + for (ALL_LIST_ELEMENTS_RO(nh_list, node, nh)) + ospf6_nexthop_clear(nh); + } } static struct ospf6_nexthop * -ospf6_route_find_nexthop (struct list *nh_list, struct ospf6_nexthop *nh_match) +ospf6_route_find_nexthop(struct list *nh_list, struct ospf6_nexthop *nh_match) { - struct listnode *node; - struct ospf6_nexthop *nh; - - if (nh_list && nh_match) - { - for (ALL_LIST_ELEMENTS_RO (nh_list, node, nh)) - { - if (ospf6_nexthop_is_same (nh, nh_match)) - return (nh); + struct listnode *node; + struct ospf6_nexthop *nh; + + if (nh_list && nh_match) { + for (ALL_LIST_ELEMENTS_RO(nh_list, node, nh)) { + if (ospf6_nexthop_is_same(nh, nh_match)) + return (nh); + } } - } - return (NULL); + return (NULL); } -void -ospf6_copy_nexthops (struct list *dst, struct list *src) +void ospf6_copy_nexthops(struct list *dst, struct list *src) { - struct ospf6_nexthop *nh_new, *nh; - struct listnode *node; - - if (dst && src) - { - for (ALL_LIST_ELEMENTS_RO (src, node, nh)) - { - if (ospf6_nexthop_is_set (nh)) - { - nh_new = ospf6_nexthop_create (); - ospf6_nexthop_copy (nh_new, nh); - listnode_add (dst, nh_new); - } + struct ospf6_nexthop *nh_new, *nh; + struct listnode *node; + + if (dst && src) { + for (ALL_LIST_ELEMENTS_RO(src, node, nh)) { + if (ospf6_nexthop_is_set(nh)) { + nh_new = ospf6_nexthop_create(); + ospf6_nexthop_copy(nh_new, nh); + listnode_add(dst, nh_new); + } + } } - } } -void -ospf6_merge_nexthops (struct list *dst, struct list *src) +void ospf6_merge_nexthops(struct list *dst, struct list *src) { - struct listnode *node; - struct ospf6_nexthop *nh, *nh_new; - - if (src && dst) - { - for (ALL_LIST_ELEMENTS_RO (src, node, nh)) - { - if (!ospf6_route_find_nexthop (dst, nh)) - { - nh_new = ospf6_nexthop_create (); - ospf6_nexthop_copy (nh_new, nh); - listnode_add (dst, nh_new); - } + struct listnode *node; + struct ospf6_nexthop *nh, *nh_new; + + if (src && dst) { + for (ALL_LIST_ELEMENTS_RO(src, node, nh)) { + if (!ospf6_route_find_nexthop(dst, nh)) { + nh_new = ospf6_nexthop_create(); + ospf6_nexthop_copy(nh_new, nh); + listnode_add(dst, nh_new); + } + } } - } } -int -ospf6_route_cmp_nexthops (struct ospf6_route *a, struct ospf6_route *b) +int ospf6_route_cmp_nexthops(struct ospf6_route *a, struct ospf6_route *b) { - struct listnode *anode, *bnode; - struct ospf6_nexthop *anh, *bnh; - - if (a && b) - { - if (listcount(a->nh_list) == listcount(b->nh_list)) - { - for (ALL_LIST_ELEMENTS_RO (a->nh_list, anode, anh)) - { - for (ALL_LIST_ELEMENTS_RO (b->nh_list, bnode, bnh)) - if (!ospf6_nexthop_is_same (anh, bnh)) - return (1); - } - return (0); + struct listnode *anode, *bnode; + struct ospf6_nexthop *anh, *bnh; + + if (a && b) { + if (listcount(a->nh_list) == listcount(b->nh_list)) { + for (ALL_LIST_ELEMENTS_RO(a->nh_list, anode, anh)) { + for (ALL_LIST_ELEMENTS_RO(b->nh_list, bnode, + bnh)) + if (!ospf6_nexthop_is_same(anh, bnh)) + return (1); + } + return (0); + } else + return (1); } - else + /* One of the routes doesn't exist ? */ return (1); - } - /* One of the routes doesn't exist ? */ - return (1); } -int -ospf6_num_nexthops (struct list *nh_list) +int ospf6_num_nexthops(struct list *nh_list) { - return (listcount(nh_list)); + return (listcount(nh_list)); } -void -ospf6_add_nexthop (struct list *nh_list, int ifindex, - struct in6_addr *addr) +void ospf6_add_nexthop(struct list *nh_list, int ifindex, struct in6_addr *addr) { - struct ospf6_nexthop *nh; - struct ospf6_nexthop nh_match; - - if (nh_list) - { - nh_match.ifindex = ifindex; - if (addr != NULL) - memcpy (&nh_match.address, addr, sizeof (struct in6_addr)); - else - memset (&nh_match.address, 0, sizeof (struct in6_addr)); - - if (!ospf6_route_find_nexthop (nh_list, &nh_match)) - { - nh = ospf6_nexthop_create(); - ospf6_nexthop_copy (nh, &nh_match); - listnode_add (nh_list, nh); + struct ospf6_nexthop *nh; + struct ospf6_nexthop nh_match; + + if (nh_list) { + nh_match.ifindex = ifindex; + if (addr != NULL) + memcpy(&nh_match.address, addr, + sizeof(struct in6_addr)); + else + memset(&nh_match.address, 0, sizeof(struct in6_addr)); + + if (!ospf6_route_find_nexthop(nh_list, &nh_match)) { + nh = ospf6_nexthop_create(); + ospf6_nexthop_copy(nh, &nh_match); + listnode_add(nh_list, nh); + } } - } } -void -ospf6_route_zebra_copy_nexthops (struct ospf6_route *route, - ifindex_t *ifindexes, - struct in6_addr **nexthop_addr, - int entries) +void ospf6_route_zebra_copy_nexthops(struct ospf6_route *route, + ifindex_t *ifindexes, + struct in6_addr **nexthop_addr, + int entries) { - struct ospf6_nexthop *nh; - struct listnode *node; - char buf[64]; - int i; - - if (route) - { - i = 0; - for (ALL_LIST_ELEMENTS_RO (route->nh_list, node, nh)) - { - if (IS_OSPF6_DEBUG_ZEBRA (SEND)) - { - const char *ifname; - inet_ntop (AF_INET6, &nh->address, buf, sizeof (buf)); - ifname = ifindex2ifname (nh->ifindex, VRF_DEFAULT); - zlog_debug (" nexthop: %s%%%.*s(%d)", buf, IFNAMSIZ, ifname, - nh->ifindex); - } - if (i < entries) - { - nexthop_addr[i] = &nh->address; - ifindexes[i] = nh->ifindex; - i++; - } - else - { - return; - } + struct ospf6_nexthop *nh; + struct listnode *node; + char buf[64]; + int i; + + if (route) { + i = 0; + for (ALL_LIST_ELEMENTS_RO(route->nh_list, node, nh)) { + if (IS_OSPF6_DEBUG_ZEBRA(SEND)) { + const char *ifname; + inet_ntop(AF_INET6, &nh->address, buf, + sizeof(buf)); + ifname = ifindex2ifname(nh->ifindex, + VRF_DEFAULT); + zlog_debug(" nexthop: %s%%%.*s(%d)", buf, + IFNAMSIZ, ifname, nh->ifindex); + } + if (i < entries) { + nexthop_addr[i] = &nh->address; + ifindexes[i] = nh->ifindex; + i++; + } else { + return; + } + } } - } } -int -ospf6_route_get_first_nh_index (struct ospf6_route *route) +int ospf6_route_get_first_nh_index(struct ospf6_route *route) { - struct ospf6_nexthop *nh; + struct ospf6_nexthop *nh; - if (route) - { - if ((nh = (struct ospf6_nexthop *)listhead (route->nh_list))) - return (nh->ifindex); - } + if (route) { + if ((nh = (struct ospf6_nexthop *)listhead(route->nh_list))) + return (nh->ifindex); + } - return (-1); + return (-1); } -struct ospf6_route * -ospf6_route_create (void) +struct ospf6_route *ospf6_route_create(void) { - struct ospf6_route *route; - route = XCALLOC (MTYPE_OSPF6_ROUTE, sizeof (struct ospf6_route)); - route->nh_list = list_new(); - return route; + struct ospf6_route *route; + route = XCALLOC(MTYPE_OSPF6_ROUTE, sizeof(struct ospf6_route)); + route->nh_list = list_new(); + return route; } -void -ospf6_route_delete (struct ospf6_route *route) +void ospf6_route_delete(struct ospf6_route *route) { - if (route) - { - ospf6_free_nexthops (route->nh_list); - list_free (route->nh_list); - XFREE (MTYPE_OSPF6_ROUTE, route); - } + if (route) { + ospf6_free_nexthops(route->nh_list); + list_free(route->nh_list); + XFREE(MTYPE_OSPF6_ROUTE, route); + } } -struct ospf6_route * -ospf6_route_copy (struct ospf6_route *route) +struct ospf6_route *ospf6_route_copy(struct ospf6_route *route) { - struct ospf6_route *new; - - new = ospf6_route_create (); - new->type = route->type; - memcpy (&new->prefix, &route->prefix, sizeof (struct prefix)); - new->installed = route->installed; - new->changed = route->changed; - new->flag = route->flag; - new->route_option = route->route_option; - new->linkstate_id = route->linkstate_id; - new->path = route->path; - ospf6_copy_nexthops (new->nh_list, route->nh_list); - new->rnode = NULL; - new->prev = NULL; - new->next = NULL; - new->table = NULL; - new->lock = 0; - return new; + struct ospf6_route *new; + + new = ospf6_route_create(); + new->type = route->type; + memcpy(&new->prefix, &route->prefix, sizeof(struct prefix)); + new->installed = route->installed; + new->changed = route->changed; + new->flag = route->flag; + new->route_option = route->route_option; + new->linkstate_id = route->linkstate_id; + new->path = route->path; + ospf6_copy_nexthops(new->nh_list, route->nh_list); + new->rnode = NULL; + new->prev = NULL; + new->next = NULL; + new->table = NULL; + new->lock = 0; + return new; } -void -ospf6_route_lock (struct ospf6_route *route) +void ospf6_route_lock(struct ospf6_route *route) { - route->lock++; + route->lock++; } -void -ospf6_route_unlock (struct ospf6_route *route) +void ospf6_route_unlock(struct ospf6_route *route) { - assert (route->lock > 0); - route->lock--; - if (route->lock == 0) - { - /* Can't detach from the table until here - because ospf6_route_next () will use - the 'route->table' pointer for logging */ - route->table = NULL; - ospf6_route_delete (route); - } + assert(route->lock > 0); + route->lock--; + if (route->lock == 0) { + /* Can't detach from the table until here + because ospf6_route_next () will use + the 'route->table' pointer for logging */ + route->table = NULL; + ospf6_route_delete(route); + } } /* Route compare function. If ra is more preferred, it returns less than 0. If rb is more preferred returns greater than 0. Otherwise (neither one is preferred), returns 0 */ -int -ospf6_route_cmp (struct ospf6_route *ra, struct ospf6_route *rb) +int ospf6_route_cmp(struct ospf6_route *ra, struct ospf6_route *rb) { - assert (ospf6_route_is_same (ra, rb)); - assert (OSPF6_PATH_TYPE_NONE < ra->path.type && - ra->path.type < OSPF6_PATH_TYPE_MAX); - assert (OSPF6_PATH_TYPE_NONE < rb->path.type && - rb->path.type < OSPF6_PATH_TYPE_MAX); - - if (ra->type != rb->type) - return (ra->type - rb->type); - - if (ra->path.area_id != rb->path.area_id) - return (ntohl (ra->path.area_id) - ntohl (rb->path.area_id)); - - if (ra->path.type != rb->path.type) - return (ra->path.type - rb->path.type); - - if (ra->path.type == OSPF6_PATH_TYPE_EXTERNAL2) - { - if (ra->path.u.cost_e2 != rb->path.u.cost_e2) - return (ra->path.u.cost_e2 - rb->path.u.cost_e2); - } - else - { - if (ra->path.cost != rb->path.cost) - return (ra->path.cost - rb->path.cost); - } - - return 0; + assert(ospf6_route_is_same(ra, rb)); + assert(OSPF6_PATH_TYPE_NONE < ra->path.type + && ra->path.type < OSPF6_PATH_TYPE_MAX); + assert(OSPF6_PATH_TYPE_NONE < rb->path.type + && rb->path.type < OSPF6_PATH_TYPE_MAX); + + if (ra->type != rb->type) + return (ra->type - rb->type); + + if (ra->path.area_id != rb->path.area_id) + return (ntohl(ra->path.area_id) - ntohl(rb->path.area_id)); + + if (ra->path.type != rb->path.type) + return (ra->path.type - rb->path.type); + + if (ra->path.type == OSPF6_PATH_TYPE_EXTERNAL2) { + if (ra->path.u.cost_e2 != rb->path.u.cost_e2) + return (ra->path.u.cost_e2 - rb->path.u.cost_e2); + } else { + if (ra->path.cost != rb->path.cost) + return (ra->path.cost - rb->path.cost); + } + + return 0; } -struct ospf6_route * -ospf6_route_lookup (struct prefix *prefix, - struct ospf6_route_table *table) +struct ospf6_route *ospf6_route_lookup(struct prefix *prefix, + struct ospf6_route_table *table) { - struct route_node *node; - struct ospf6_route *route; + struct route_node *node; + struct ospf6_route *route; - node = route_node_lookup (table->table, prefix); - if (node == NULL) - return NULL; + node = route_node_lookup(table->table, prefix); + if (node == NULL) + return NULL; - route = (struct ospf6_route *) node->info; - return route; + route = (struct ospf6_route *)node->info; + return route; } struct ospf6_route * -ospf6_route_lookup_identical (struct ospf6_route *route, - struct ospf6_route_table *table) +ospf6_route_lookup_identical(struct ospf6_route *route, + struct ospf6_route_table *table) { - struct ospf6_route *target; - - for (target = ospf6_route_lookup (&route->prefix, table); - target; target = target->next) - { - if (ospf6_route_is_identical (target, route)) - return target; - } - return NULL; + struct ospf6_route *target; + + for (target = ospf6_route_lookup(&route->prefix, table); target; + target = target->next) { + if (ospf6_route_is_identical(target, route)) + return target; + } + return NULL; } struct ospf6_route * -ospf6_route_lookup_bestmatch (struct prefix *prefix, - struct ospf6_route_table *table) +ospf6_route_lookup_bestmatch(struct prefix *prefix, + struct ospf6_route_table *table) { - struct route_node *node; - struct ospf6_route *route; + struct route_node *node; + struct ospf6_route *route; - node = route_node_match (table->table, prefix); - if (node == NULL) - return NULL; - route_unlock_node (node); + node = route_node_match(table->table, prefix); + if (node == NULL) + return NULL; + route_unlock_node(node); - route = (struct ospf6_route *) node->info; - return route; + route = (struct ospf6_route *)node->info; + return route; } #ifdef DEBUG -static void -route_table_assert (struct ospf6_route_table *table) +static void route_table_assert(struct ospf6_route_table *table) { - struct ospf6_route *prev, *r, *next; - char buf[PREFIX2STR_BUFFER]; - unsigned int link_error = 0, num = 0; - - r = ospf6_route_head (table); - prev = NULL; - while (r) - { - if (r->prev != prev) - link_error++; - - next = ospf6_route_next (r); - - if (r->next != next) - link_error++; - - prev = r; - r = next; - } - - for (r = ospf6_route_head (table); r; r = ospf6_route_next (r)) - num++; - - if (link_error == 0 && num == table->count) - return; - - zlog_err ("PANIC !!"); - zlog_err ("Something has gone wrong with ospf6_route_table[%p]", table); - zlog_debug ("table count = %d, real number = %d", table->count, num); - zlog_debug ("DUMP START"); - for (r = ospf6_route_head (table); r; r = ospf6_route_next (r)) - { - prefix2str (&r->prefix, buf, sizeof (buf)); - zlog_info ("%p<-[%p]->%p : %s", r->prev, r, r->next, buf); - } - zlog_debug ("DUMP END"); - - assert (link_error == 0 && num == table->count); + struct ospf6_route *prev, *r, *next; + char buf[PREFIX2STR_BUFFER]; + unsigned int link_error = 0, num = 0; + + r = ospf6_route_head(table); + prev = NULL; + while (r) { + if (r->prev != prev) + link_error++; + + next = ospf6_route_next(r); + + if (r->next != next) + link_error++; + + prev = r; + r = next; + } + + for (r = ospf6_route_head(table); r; r = ospf6_route_next(r)) + num++; + + if (link_error == 0 && num == table->count) + return; + + zlog_err("PANIC !!"); + zlog_err("Something has gone wrong with ospf6_route_table[%p]", table); + zlog_debug("table count = %d, real number = %d", table->count, num); + zlog_debug("DUMP START"); + for (r = ospf6_route_head(table); r; r = ospf6_route_next(r)) { + prefix2str(&r->prefix, buf, sizeof(buf)); + zlog_info("%p<-[%p]->%p : %s", r->prev, r, r->next, buf); + } + zlog_debug("DUMP END"); + + assert(link_error == 0 && num == table->count); } #define ospf6_route_table_assert(t) (route_table_assert (t)) #else #define ospf6_route_table_assert(t) ((void) 0) #endif /*DEBUG*/ -struct ospf6_route * -ospf6_route_add (struct ospf6_route *route, - struct ospf6_route_table *table) +struct ospf6_route *ospf6_route_add(struct ospf6_route *route, + struct ospf6_route_table *table) { - struct route_node *node, *nextnode, *prevnode; - struct ospf6_route *current = NULL; - struct ospf6_route *prev = NULL, *old = NULL, *next = NULL; - char buf[PREFIX2STR_BUFFER]; - struct timeval now; - - assert (route->rnode == NULL); - assert (route->lock == 0); - assert (route->next == NULL); - assert (route->prev == NULL); - - if (route->type == OSPF6_DEST_TYPE_LINKSTATE) - ospf6_linkstate_prefix2str (&route->prefix, buf, sizeof (buf)); - else - prefix2str (&route->prefix, buf, sizeof (buf)); - - if (IS_OSPF6_DEBUG_ROUTE (MEMORY)) - zlog_debug ("%s %p: route add %p: %s", ospf6_route_table_name (table), - (void *)table, (void *)route, buf); - else if (IS_OSPF6_DEBUG_ROUTE (TABLE)) - zlog_debug ("%s: route add: %s", ospf6_route_table_name (table), buf); - - monotime(&now); - - node = route_node_get (table->table, &route->prefix); - route->rnode = node; - - /* find place to insert */ - for (current = node->info; current; current = current->next) - { - if (! ospf6_route_is_same (current, route)) - next = current; - else if (current->type != route->type) - prev = current; - else if (ospf6_route_is_same_origin (current, route)) - old = current; - else if (ospf6_route_cmp (current, route) > 0) - next = current; - else - prev = current; - - if (old || next) - break; - } - - if (old) - { - /* if route does not actually change, return unchanged */ - if (ospf6_route_is_identical (old, route)) - { - if (IS_OSPF6_DEBUG_ROUTE (MEMORY)) - zlog_debug ("%s %p: route add %p: needless update of %p", - ospf6_route_table_name (table), - (void *)table, (void *)route, (void *)old); - else if (IS_OSPF6_DEBUG_ROUTE (TABLE)) - zlog_debug ("%s: route add: needless update", - ospf6_route_table_name (table)); - - ospf6_route_delete (route); - SET_FLAG (old->flag, OSPF6_ROUTE_ADD); - ospf6_route_table_assert (table); - - return old; - } - - if (IS_OSPF6_DEBUG_ROUTE (MEMORY)) - zlog_debug ("%s %p: route add %p: update of %p", - ospf6_route_table_name (table), - (void *)table, (void *)route, (void *)old); - else if (IS_OSPF6_DEBUG_ROUTE (TABLE)) - zlog_debug ("%s: route add: update", - ospf6_route_table_name (table)); - - /* replace old one if exists */ - if (node->info == old) - { - node->info = route; - SET_FLAG (route->flag, OSPF6_ROUTE_BEST); - } - - if (old->prev) - old->prev->next = route; - route->prev = old->prev; - if (old->next) - old->next->prev = route; - route->next = old->next; - - route->installed = old->installed; - route->changed = now; - assert (route->table == NULL); - route->table = table; - - ospf6_route_unlock (old); /* will be deleted later */ - ospf6_route_lock (route); - - SET_FLAG (route->flag, OSPF6_ROUTE_CHANGE); - ospf6_route_table_assert (table); - - if (table->hook_add) - (*table->hook_add) (route); - - return route; - } - - /* insert if previous or next node found */ - if (prev || next) - { - if (IS_OSPF6_DEBUG_ROUTE (MEMORY)) - zlog_debug ("%s %p: route add %p: another path: prev %p, next %p", - ospf6_route_table_name (table), - (void *)table, (void *)route, (void *)prev, (void *)next); - else if (IS_OSPF6_DEBUG_ROUTE (TABLE)) - zlog_debug ("%s: route add: another path found", - ospf6_route_table_name (table)); - - if (prev == NULL) - prev = next->prev; - if (next == NULL) - next = prev->next; - - if (prev) - prev->next = route; - route->prev = prev; - if (next) - next->prev = route; - route->next = next; - - if (node->info == next) - { - assert (next->rnode == node); - node->info = route; - UNSET_FLAG (next->flag, OSPF6_ROUTE_BEST); - SET_FLAG (route->flag, OSPF6_ROUTE_BEST); - if (IS_OSPF6_DEBUG_ROUTE (MEMORY)) - zlog_info ("%s %p: route add %p: replacing previous best: %p", - ospf6_route_table_name (table), - (void *)table, (void *)route, (void *)next); - } - - route->installed = now; - route->changed = now; - assert (route->table == NULL); - route->table = table; - - ospf6_route_lock (route); - table->count++; - ospf6_route_table_assert (table); - - SET_FLAG (route->flag, OSPF6_ROUTE_ADD); - if (table->hook_add) - (*table->hook_add) (route); - - return route; - } - - /* Else, this is the brand new route regarding to the prefix */ - if (IS_OSPF6_DEBUG_ROUTE (MEMORY)) - zlog_debug ("%s %p: route add %p: brand new route", - ospf6_route_table_name (table), (void *)table, (void *)route); - else if (IS_OSPF6_DEBUG_ROUTE (TABLE)) - zlog_debug ("%s: route add: brand new route", - ospf6_route_table_name (table)); - - assert (node->info == NULL); - node->info = route; - SET_FLAG (route->flag, OSPF6_ROUTE_BEST); - ospf6_route_lock (route); - route->installed = now; - route->changed = now; - assert (route->table == NULL); - route->table = table; - - /* lookup real existing next route */ - nextnode = node; - route_lock_node (nextnode); - do { - nextnode = route_next (nextnode); - } while (nextnode && nextnode->info == NULL); - - /* set next link */ - if (nextnode == NULL) - route->next = NULL; - else - { - route_unlock_node (nextnode); - - next = nextnode->info; - route->next = next; - next->prev = route; - } - - /* lookup real existing prev route */ - prevnode = node; - route_lock_node (prevnode); - do { - prevnode = route_prev (prevnode); - } while (prevnode && prevnode->info == NULL); - - /* set prev link */ - if (prevnode == NULL) - route->prev = NULL; - else - { - route_unlock_node (prevnode); - - prev = prevnode->info; - while (prev->next && ospf6_route_is_same (prev, prev->next)) - prev = prev->next; - route->prev = prev; - prev->next = route; - } - - table->count++; - ospf6_route_table_assert (table); - - SET_FLAG (route->flag, OSPF6_ROUTE_ADD); - if (table->hook_add) - (*table->hook_add) (route); - - return route; -} + struct route_node *node, *nextnode, *prevnode; + struct ospf6_route *current = NULL; + struct ospf6_route *prev = NULL, *old = NULL, *next = NULL; + char buf[PREFIX2STR_BUFFER]; + struct timeval now; + + assert(route->rnode == NULL); + assert(route->lock == 0); + assert(route->next == NULL); + assert(route->prev == NULL); + + if (route->type == OSPF6_DEST_TYPE_LINKSTATE) + ospf6_linkstate_prefix2str(&route->prefix, buf, sizeof(buf)); + else + prefix2str(&route->prefix, buf, sizeof(buf)); + + if (IS_OSPF6_DEBUG_ROUTE(MEMORY)) + zlog_debug("%s %p: route add %p: %s", + ospf6_route_table_name(table), (void *)table, + (void *)route, buf); + else if (IS_OSPF6_DEBUG_ROUTE(TABLE)) + zlog_debug("%s: route add: %s", ospf6_route_table_name(table), + buf); + + monotime(&now); + + node = route_node_get(table->table, &route->prefix); + route->rnode = node; + + /* find place to insert */ + for (current = node->info; current; current = current->next) { + if (!ospf6_route_is_same(current, route)) + next = current; + else if (current->type != route->type) + prev = current; + else if (ospf6_route_is_same_origin(current, route)) + old = current; + else if (ospf6_route_cmp(current, route) > 0) + next = current; + else + prev = current; + + if (old || next) + break; + } -void -ospf6_route_remove (struct ospf6_route *route, - struct ospf6_route_table *table) -{ - struct route_node *node; - struct ospf6_route *current; - char buf[PREFIX2STR_BUFFER]; - - if (route->type == OSPF6_DEST_TYPE_LINKSTATE) - ospf6_linkstate_prefix2str (&route->prefix, buf, sizeof (buf)); - else - prefix2str (&route->prefix, buf, sizeof (buf)); - - if (IS_OSPF6_DEBUG_ROUTE (MEMORY)) - zlog_debug ("%s %p: route remove %p: %s", - ospf6_route_table_name (table), - (void *)table, (void *)route, buf); - else if (IS_OSPF6_DEBUG_ROUTE (TABLE)) - zlog_debug ("%s: route remove: %s", ospf6_route_table_name (table), buf); - - node = route_node_lookup (table->table, &route->prefix); - assert (node); - - /* find the route to remove, making sure that the route pointer - is from the route table. */ - current = node->info; - while (current && ospf6_route_is_same (current, route)) - { - if (current == route) - break; - current = current->next; - } - assert (current == route); - - /* adjust doubly linked list */ - if (route->prev) - route->prev->next = route->next; - if (route->next) - route->next->prev = route->prev; - - if (node->info == route) - { - if (route->next && route->next->rnode == node) - { - node->info = route->next; - SET_FLAG (route->next->flag, OSPF6_ROUTE_BEST); - } - else - node->info = NULL; /* should unlock route_node here ? */ - } - - table->count--; - ospf6_route_table_assert (table); - - SET_FLAG (route->flag, OSPF6_ROUTE_WAS_REMOVED); - - if (table->hook_remove) - (*table->hook_remove) (route); - - ospf6_route_unlock (route); + if (old) { + /* if route does not actually change, return unchanged */ + if (ospf6_route_is_identical(old, route)) { + if (IS_OSPF6_DEBUG_ROUTE(MEMORY)) + zlog_debug( + "%s %p: route add %p: needless update of %p", + ospf6_route_table_name(table), + (void *)table, (void *)route, + (void *)old); + else if (IS_OSPF6_DEBUG_ROUTE(TABLE)) + zlog_debug("%s: route add: needless update", + ospf6_route_table_name(table)); + + ospf6_route_delete(route); + SET_FLAG(old->flag, OSPF6_ROUTE_ADD); + ospf6_route_table_assert(table); + + return old; + } + + if (IS_OSPF6_DEBUG_ROUTE(MEMORY)) + zlog_debug("%s %p: route add %p: update of %p", + ospf6_route_table_name(table), (void *)table, + (void *)route, (void *)old); + else if (IS_OSPF6_DEBUG_ROUTE(TABLE)) + zlog_debug("%s: route add: update", + ospf6_route_table_name(table)); + + /* replace old one if exists */ + if (node->info == old) { + node->info = route; + SET_FLAG(route->flag, OSPF6_ROUTE_BEST); + } + + if (old->prev) + old->prev->next = route; + route->prev = old->prev; + if (old->next) + old->next->prev = route; + route->next = old->next; + + route->installed = old->installed; + route->changed = now; + assert(route->table == NULL); + route->table = table; + + ospf6_route_unlock(old); /* will be deleted later */ + ospf6_route_lock(route); + + SET_FLAG(route->flag, OSPF6_ROUTE_CHANGE); + ospf6_route_table_assert(table); + + if (table->hook_add) + (*table->hook_add)(route); + + return route; + } + + /* insert if previous or next node found */ + if (prev || next) { + if (IS_OSPF6_DEBUG_ROUTE(MEMORY)) + zlog_debug( + "%s %p: route add %p: another path: prev %p, next %p", + ospf6_route_table_name(table), (void *)table, + (void *)route, (void *)prev, (void *)next); + else if (IS_OSPF6_DEBUG_ROUTE(TABLE)) + zlog_debug("%s: route add: another path found", + ospf6_route_table_name(table)); + + if (prev == NULL) + prev = next->prev; + if (next == NULL) + next = prev->next; + + if (prev) + prev->next = route; + route->prev = prev; + if (next) + next->prev = route; + route->next = next; + + if (node->info == next) { + assert(next->rnode == node); + node->info = route; + UNSET_FLAG(next->flag, OSPF6_ROUTE_BEST); + SET_FLAG(route->flag, OSPF6_ROUTE_BEST); + if (IS_OSPF6_DEBUG_ROUTE(MEMORY)) + zlog_info( + "%s %p: route add %p: replacing previous best: %p", + ospf6_route_table_name(table), + (void *)table, (void *)route, + (void *)next); + } + + route->installed = now; + route->changed = now; + assert(route->table == NULL); + route->table = table; + + ospf6_route_lock(route); + table->count++; + ospf6_route_table_assert(table); + + SET_FLAG(route->flag, OSPF6_ROUTE_ADD); + if (table->hook_add) + (*table->hook_add)(route); + + return route; + } + + /* Else, this is the brand new route regarding to the prefix */ + if (IS_OSPF6_DEBUG_ROUTE(MEMORY)) + zlog_debug("%s %p: route add %p: brand new route", + ospf6_route_table_name(table), (void *)table, + (void *)route); + else if (IS_OSPF6_DEBUG_ROUTE(TABLE)) + zlog_debug("%s: route add: brand new route", + ospf6_route_table_name(table)); + + assert(node->info == NULL); + node->info = route; + SET_FLAG(route->flag, OSPF6_ROUTE_BEST); + ospf6_route_lock(route); + route->installed = now; + route->changed = now; + assert(route->table == NULL); + route->table = table; + + /* lookup real existing next route */ + nextnode = node; + route_lock_node(nextnode); + do { + nextnode = route_next(nextnode); + } while (nextnode && nextnode->info == NULL); + + /* set next link */ + if (nextnode == NULL) + route->next = NULL; + else { + route_unlock_node(nextnode); + + next = nextnode->info; + route->next = next; + next->prev = route; + } + + /* lookup real existing prev route */ + prevnode = node; + route_lock_node(prevnode); + do { + prevnode = route_prev(prevnode); + } while (prevnode && prevnode->info == NULL); + + /* set prev link */ + if (prevnode == NULL) + route->prev = NULL; + else { + route_unlock_node(prevnode); + + prev = prevnode->info; + while (prev->next && ospf6_route_is_same(prev, prev->next)) + prev = prev->next; + route->prev = prev; + prev->next = route; + } + + table->count++; + ospf6_route_table_assert(table); + + SET_FLAG(route->flag, OSPF6_ROUTE_ADD); + if (table->hook_add) + (*table->hook_add)(route); + + return route; } -struct ospf6_route * -ospf6_route_head (struct ospf6_route_table *table) +void ospf6_route_remove(struct ospf6_route *route, + struct ospf6_route_table *table) { - struct route_node *node; - struct ospf6_route *route; - - node = route_top (table->table); - if (node == NULL) - return NULL; + struct route_node *node; + struct ospf6_route *current; + char buf[PREFIX2STR_BUFFER]; + + if (route->type == OSPF6_DEST_TYPE_LINKSTATE) + ospf6_linkstate_prefix2str(&route->prefix, buf, sizeof(buf)); + else + prefix2str(&route->prefix, buf, sizeof(buf)); + + if (IS_OSPF6_DEBUG_ROUTE(MEMORY)) + zlog_debug("%s %p: route remove %p: %s", + ospf6_route_table_name(table), (void *)table, + (void *)route, buf); + else if (IS_OSPF6_DEBUG_ROUTE(TABLE)) + zlog_debug("%s: route remove: %s", + ospf6_route_table_name(table), buf); + + node = route_node_lookup(table->table, &route->prefix); + assert(node); + + /* find the route to remove, making sure that the route pointer + is from the route table. */ + current = node->info; + while (current && ospf6_route_is_same(current, route)) { + if (current == route) + break; + current = current->next; + } + assert(current == route); + + /* adjust doubly linked list */ + if (route->prev) + route->prev->next = route->next; + if (route->next) + route->next->prev = route->prev; + + if (node->info == route) { + if (route->next && route->next->rnode == node) { + node->info = route->next; + SET_FLAG(route->next->flag, OSPF6_ROUTE_BEST); + } else + node->info = NULL; /* should unlock route_node here ? */ + } - /* skip to the real existing entry */ - while (node && node->info == NULL) - node = route_next (node); - if (node == NULL) - return NULL; + table->count--; + ospf6_route_table_assert(table); - route_unlock_node (node); - assert (node->info); + SET_FLAG(route->flag, OSPF6_ROUTE_WAS_REMOVED); - route = (struct ospf6_route *) node->info; - assert (route->prev == NULL); - assert (route->table == table); - ospf6_route_lock (route); + if (table->hook_remove) + (*table->hook_remove)(route); - if (IS_OSPF6_DEBUG_ROUTE (MEMORY)) - zlog_info ("%s %p: route head: %p<-[%p]->%p", - ospf6_route_table_name (table), (void *)table, - (void *)route->prev, (void *)route, (void *)route->next); + ospf6_route_unlock(route); +} - return route; +struct ospf6_route *ospf6_route_head(struct ospf6_route_table *table) +{ + struct route_node *node; + struct ospf6_route *route; + + node = route_top(table->table); + if (node == NULL) + return NULL; + + /* skip to the real existing entry */ + while (node && node->info == NULL) + node = route_next(node); + if (node == NULL) + return NULL; + + route_unlock_node(node); + assert(node->info); + + route = (struct ospf6_route *)node->info; + assert(route->prev == NULL); + assert(route->table == table); + ospf6_route_lock(route); + + if (IS_OSPF6_DEBUG_ROUTE(MEMORY)) + zlog_info("%s %p: route head: %p<-[%p]->%p", + ospf6_route_table_name(table), (void *)table, + (void *)route->prev, (void *)route, + (void *)route->next); + + return route; } -struct ospf6_route * -ospf6_route_next (struct ospf6_route *route) +struct ospf6_route *ospf6_route_next(struct ospf6_route *route) { - struct ospf6_route *next = route->next; + struct ospf6_route *next = route->next; - if (IS_OSPF6_DEBUG_ROUTE (MEMORY)) - zlog_info ("%s %p: route next: %p<-[%p]->%p", - ospf6_route_table_name (route->table), (void *)route->table, - (void *)route->prev, (void *)route, (void *)route->next); + if (IS_OSPF6_DEBUG_ROUTE(MEMORY)) + zlog_info("%s %p: route next: %p<-[%p]->%p", + ospf6_route_table_name(route->table), + (void *)route->table, (void *)route->prev, + (void *)route, (void *)route->next); - ospf6_route_unlock (route); - if (next) - ospf6_route_lock (next); + ospf6_route_unlock(route); + if (next) + ospf6_route_lock(next); - return next; + return next; } -struct ospf6_route * -ospf6_route_best_next (struct ospf6_route *route) +struct ospf6_route *ospf6_route_best_next(struct ospf6_route *route) { - struct route_node *rnode; - struct ospf6_route *next; - - ospf6_route_unlock (route); - - rnode = route->rnode; - route_lock_node (rnode); - rnode = route_next (rnode); - while (rnode && rnode->info == NULL) - rnode = route_next (rnode); - if (rnode == NULL) - return NULL; - route_unlock_node (rnode); - - assert (rnode->info); - next = (struct ospf6_route *) rnode->info; - ospf6_route_lock (next); - return next; + struct route_node *rnode; + struct ospf6_route *next; + + ospf6_route_unlock(route); + + rnode = route->rnode; + route_lock_node(rnode); + rnode = route_next(rnode); + while (rnode && rnode->info == NULL) + rnode = route_next(rnode); + if (rnode == NULL) + return NULL; + route_unlock_node(rnode); + + assert(rnode->info); + next = (struct ospf6_route *)rnode->info; + ospf6_route_lock(next); + return next; } -struct ospf6_route * -ospf6_route_match_head (struct prefix *prefix, - struct ospf6_route_table *table) +struct ospf6_route *ospf6_route_match_head(struct prefix *prefix, + struct ospf6_route_table *table) { - struct route_node *node; - struct ospf6_route *route; - - /* Walk down tree. */ - node = table->table->top; - while (node && node->p.prefixlen < prefix->prefixlen && - prefix_match (&node->p, prefix)) - node = node->link[prefix_bit(&prefix->u.prefix, node->p.prefixlen)]; - - if (node) - route_lock_node (node); - while (node && node->info == NULL) - node = route_next (node); - if (node == NULL) - return NULL; - route_unlock_node (node); - - if (! prefix_match (prefix, &node->p)) - return NULL; - - route = node->info; - ospf6_route_lock (route); - return route; + struct route_node *node; + struct ospf6_route *route; + + /* Walk down tree. */ + node = table->table->top; + while (node && node->p.prefixlen < prefix->prefixlen + && prefix_match(&node->p, prefix)) + node = node->link[prefix_bit(&prefix->u.prefix, + node->p.prefixlen)]; + + if (node) + route_lock_node(node); + while (node && node->info == NULL) + node = route_next(node); + if (node == NULL) + return NULL; + route_unlock_node(node); + + if (!prefix_match(prefix, &node->p)) + return NULL; + + route = node->info; + ospf6_route_lock(route); + return route; } -struct ospf6_route * -ospf6_route_match_next (struct prefix *prefix, - struct ospf6_route *route) +struct ospf6_route *ospf6_route_match_next(struct prefix *prefix, + struct ospf6_route *route) { - struct ospf6_route *next; + struct ospf6_route *next; - next = ospf6_route_next (route); - if (next && ! prefix_match (prefix, &next->prefix)) - { - ospf6_route_unlock (next); - next = NULL; - } + next = ospf6_route_next(route); + if (next && !prefix_match(prefix, &next->prefix)) { + ospf6_route_unlock(next); + next = NULL; + } - return next; + return next; } -void -ospf6_route_remove_all (struct ospf6_route_table *table) +void ospf6_route_remove_all(struct ospf6_route_table *table) { - struct ospf6_route *route; - for (route = ospf6_route_head (table); route; - route = ospf6_route_next (route)) - ospf6_route_remove (route, table); + struct ospf6_route *route; + for (route = ospf6_route_head(table); route; + route = ospf6_route_next(route)) + ospf6_route_remove(route, table); } -struct ospf6_route_table * -ospf6_route_table_create (int s, int t) +struct ospf6_route_table *ospf6_route_table_create(int s, int t) { - struct ospf6_route_table *new; - new = XCALLOC (MTYPE_OSPF6_ROUTE, sizeof (struct ospf6_route_table)); - new->table = route_table_init (); - new->scope_type = s; - new->table_type = t; - return new; + struct ospf6_route_table *new; + new = XCALLOC(MTYPE_OSPF6_ROUTE, sizeof(struct ospf6_route_table)); + new->table = route_table_init(); + new->scope_type = s; + new->table_type = t; + return new; } -void -ospf6_route_table_delete (struct ospf6_route_table *table) +void ospf6_route_table_delete(struct ospf6_route_table *table) { - ospf6_route_remove_all (table); - route_table_finish (table->table); - XFREE (MTYPE_OSPF6_ROUTE, table); + ospf6_route_remove_all(table); + route_table_finish(table->table); + XFREE(MTYPE_OSPF6_ROUTE, table); } /* VTY commands */ -void -ospf6_route_show (struct vty *vty, struct ospf6_route *route) +void ospf6_route_show(struct vty *vty, struct ospf6_route *route) { - int i; - char destination[PREFIX2STR_BUFFER], nexthop[64]; - char duration[16]; - const char *ifname; - struct timeval now, res; - struct listnode *node; - struct ospf6_nexthop *nh; - - monotime(&now); - timersub (&now, &route->changed, &res); - timerstring (&res, duration, sizeof (duration)); - - /* destination */ - if (route->type == OSPF6_DEST_TYPE_LINKSTATE) - ospf6_linkstate_prefix2str (&route->prefix, destination, - sizeof (destination)); - else if (route->type == OSPF6_DEST_TYPE_ROUTER) - inet_ntop (route->prefix.family, &route->prefix.u.prefix, - destination, sizeof (destination)); - else - prefix2str (&route->prefix, destination, sizeof (destination)); - - i = 0; - for (ALL_LIST_ELEMENTS_RO (route->nh_list, node, nh)) - { - /* nexthop */ - inet_ntop (AF_INET6, &nh->address, nexthop, - sizeof (nexthop)); - ifname = ifindex2ifname (nh->ifindex, VRF_DEFAULT); - - if (!i) - { - vty_out (vty, "%c%1s %2s %-30s %-25s %6.*s %s\n", - (ospf6_route_is_best (route) ? '*' : ' '), - OSPF6_DEST_TYPE_SUBSTR (route->type), - OSPF6_PATH_TYPE_SUBSTR (route->path.type), - destination, nexthop, IFNAMSIZ, ifname, duration); - i++; + int i; + char destination[PREFIX2STR_BUFFER], nexthop[64]; + char duration[16]; + const char *ifname; + struct timeval now, res; + struct listnode *node; + struct ospf6_nexthop *nh; + + monotime(&now); + timersub(&now, &route->changed, &res); + timerstring(&res, duration, sizeof(duration)); + + /* destination */ + if (route->type == OSPF6_DEST_TYPE_LINKSTATE) + ospf6_linkstate_prefix2str(&route->prefix, destination, + sizeof(destination)); + else if (route->type == OSPF6_DEST_TYPE_ROUTER) + inet_ntop(route->prefix.family, &route->prefix.u.prefix, + destination, sizeof(destination)); + else + prefix2str(&route->prefix, destination, sizeof(destination)); + + i = 0; + for (ALL_LIST_ELEMENTS_RO(route->nh_list, node, nh)) { + /* nexthop */ + inet_ntop(AF_INET6, &nh->address, nexthop, sizeof(nexthop)); + ifname = ifindex2ifname(nh->ifindex, VRF_DEFAULT); + + if (!i) { + vty_out(vty, "%c%1s %2s %-30s %-25s %6.*s %s\n", + (ospf6_route_is_best(route) ? '*' : ' '), + OSPF6_DEST_TYPE_SUBSTR(route->type), + OSPF6_PATH_TYPE_SUBSTR(route->path.type), + destination, nexthop, IFNAMSIZ, ifname, + duration); + i++; + } else + vty_out(vty, "%c%1s %2s %-30s %-25s %6.*s %s\n", ' ', + "", "", "", nexthop, IFNAMSIZ, ifname, ""); } - else - vty_out (vty, "%c%1s %2s %-30s %-25s %6.*s %s\n", - ' ', "", "", "", nexthop, IFNAMSIZ, ifname, ""); - } } -void -ospf6_route_show_detail (struct vty *vty, struct ospf6_route *route) +void ospf6_route_show_detail(struct vty *vty, struct ospf6_route *route) { - const char *ifname; - char destination[PREFIX2STR_BUFFER], nexthop[64]; - char area_id[16], id[16], adv_router[16], capa[16], options[16]; - struct timeval now, res; - char duration[16]; - struct listnode *node; - struct ospf6_nexthop *nh; - - monotime(&now); - - /* destination */ - if (route->type == OSPF6_DEST_TYPE_LINKSTATE) - ospf6_linkstate_prefix2str (&route->prefix, destination, - sizeof (destination)); - else if (route->type == OSPF6_DEST_TYPE_ROUTER) - inet_ntop (route->prefix.family, &route->prefix.u.prefix, - destination, sizeof (destination)); - else - prefix2str (&route->prefix, destination, sizeof (destination)); - vty_out (vty, "Destination: %s\n", destination); - - /* destination type */ - vty_out (vty, "Destination type: %s\n", - OSPF6_DEST_TYPE_NAME (route->type)); - - /* Time */ - timersub (&now, &route->installed, &res); - timerstring (&res, duration, sizeof (duration)); - vty_out (vty, "Installed Time: %s ago\n", duration); - - timersub (&now, &route->changed, &res); - timerstring (&res, duration, sizeof (duration)); - vty_out (vty, " Changed Time: %s ago\n", duration); - - /* Debugging info */ - vty_out (vty, "Lock: %d Flags: %s%s%s%s\n", route->lock, - (CHECK_FLAG (route->flag, OSPF6_ROUTE_BEST) ? "B" : "-"), - (CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD) ? "A" : "-"), - (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE) ? "R" : "-"), - (CHECK_FLAG (route->flag, OSPF6_ROUTE_CHANGE) ? "C" : "-")); - vty_out (vty, "Memory: prev: %p this: %p next: %p\n", - (void *)route->prev, (void *)route, (void *)route->next); - - /* Path section */ - - /* Area-ID */ - inet_ntop (AF_INET, &route->path.area_id, area_id, sizeof (area_id)); - vty_out (vty, "Associated Area: %s\n", area_id); - - /* Path type */ - vty_out (vty, "Path Type: %s\n", - OSPF6_PATH_TYPE_NAME (route->path.type)); - - /* LS Origin */ - inet_ntop (AF_INET, &route->path.origin.id, id, sizeof (id)); - inet_ntop (AF_INET, &route->path.origin.adv_router, adv_router, - sizeof (adv_router)); - vty_out (vty, "LS Origin: %s Id: %s Adv: %s\n", - ospf6_lstype_name (route->path.origin.type), - id, adv_router); - - /* Options */ - ospf6_options_printbuf (route->path.options, options, sizeof (options)); - vty_out (vty, "Options: %s\n", options); - - /* Router Bits */ - ospf6_capability_printbuf (route->path.router_bits, capa, sizeof (capa)); - vty_out (vty, "Router Bits: %s\n", capa); - - /* Prefix Options */ - vty_out (vty, "Prefix Options: xxx\n"); - - /* Metrics */ - vty_out (vty, "Metric Type: %d\n", route->path.metric_type); - vty_out (vty, "Metric: %d (%d)\n", - route->path.cost, route->path.u.cost_e2); - - /* Nexthops */ - vty_out (vty, "Nexthop:\n"); - for (ALL_LIST_ELEMENTS_RO (route->nh_list, node, nh)) - { - /* nexthop */ - inet_ntop (AF_INET6, &nh->address, nexthop, sizeof (nexthop)); - ifname = ifindex2ifname (nh->ifindex, VRF_DEFAULT); - vty_out (vty, " %s %.*s\n", nexthop, IFNAMSIZ, ifname); - } - vty_out (vty, "\n"); + const char *ifname; + char destination[PREFIX2STR_BUFFER], nexthop[64]; + char area_id[16], id[16], adv_router[16], capa[16], options[16]; + struct timeval now, res; + char duration[16]; + struct listnode *node; + struct ospf6_nexthop *nh; + + monotime(&now); + + /* destination */ + if (route->type == OSPF6_DEST_TYPE_LINKSTATE) + ospf6_linkstate_prefix2str(&route->prefix, destination, + sizeof(destination)); + else if (route->type == OSPF6_DEST_TYPE_ROUTER) + inet_ntop(route->prefix.family, &route->prefix.u.prefix, + destination, sizeof(destination)); + else + prefix2str(&route->prefix, destination, sizeof(destination)); + vty_out(vty, "Destination: %s\n", destination); + + /* destination type */ + vty_out(vty, "Destination type: %s\n", + OSPF6_DEST_TYPE_NAME(route->type)); + + /* Time */ + timersub(&now, &route->installed, &res); + timerstring(&res, duration, sizeof(duration)); + vty_out(vty, "Installed Time: %s ago\n", duration); + + timersub(&now, &route->changed, &res); + timerstring(&res, duration, sizeof(duration)); + vty_out(vty, " Changed Time: %s ago\n", duration); + + /* Debugging info */ + vty_out(vty, "Lock: %d Flags: %s%s%s%s\n", route->lock, + (CHECK_FLAG(route->flag, OSPF6_ROUTE_BEST) ? "B" : "-"), + (CHECK_FLAG(route->flag, OSPF6_ROUTE_ADD) ? "A" : "-"), + (CHECK_FLAG(route->flag, OSPF6_ROUTE_REMOVE) ? "R" : "-"), + (CHECK_FLAG(route->flag, OSPF6_ROUTE_CHANGE) ? "C" : "-")); + vty_out(vty, "Memory: prev: %p this: %p next: %p\n", + (void *)route->prev, (void *)route, (void *)route->next); + + /* Path section */ + + /* Area-ID */ + inet_ntop(AF_INET, &route->path.area_id, area_id, sizeof(area_id)); + vty_out(vty, "Associated Area: %s\n", area_id); + + /* Path type */ + vty_out(vty, "Path Type: %s\n", OSPF6_PATH_TYPE_NAME(route->path.type)); + + /* LS Origin */ + inet_ntop(AF_INET, &route->path.origin.id, id, sizeof(id)); + inet_ntop(AF_INET, &route->path.origin.adv_router, adv_router, + sizeof(adv_router)); + vty_out(vty, "LS Origin: %s Id: %s Adv: %s\n", + ospf6_lstype_name(route->path.origin.type), id, adv_router); + + /* Options */ + ospf6_options_printbuf(route->path.options, options, sizeof(options)); + vty_out(vty, "Options: %s\n", options); + + /* Router Bits */ + ospf6_capability_printbuf(route->path.router_bits, capa, sizeof(capa)); + vty_out(vty, "Router Bits: %s\n", capa); + + /* Prefix Options */ + vty_out(vty, "Prefix Options: xxx\n"); + + /* Metrics */ + vty_out(vty, "Metric Type: %d\n", route->path.metric_type); + vty_out(vty, "Metric: %d (%d)\n", route->path.cost, + route->path.u.cost_e2); + + /* Nexthops */ + vty_out(vty, "Nexthop:\n"); + for (ALL_LIST_ELEMENTS_RO(route->nh_list, node, nh)) { + /* nexthop */ + inet_ntop(AF_INET6, &nh->address, nexthop, sizeof(nexthop)); + ifname = ifindex2ifname(nh->ifindex, VRF_DEFAULT); + vty_out(vty, " %s %.*s\n", nexthop, IFNAMSIZ, ifname); + } + vty_out(vty, "\n"); } -static void -ospf6_route_show_table_summary (struct vty *vty, - struct ospf6_route_table *table) +static void ospf6_route_show_table_summary(struct vty *vty, + struct ospf6_route_table *table) { - struct ospf6_route *route, *prev = NULL; - int i, pathtype[OSPF6_PATH_TYPE_MAX]; - unsigned int number = 0; - int nh_count =0 , nhinval = 0, ecmp = 0; - int alternative = 0, destination = 0; - - for (i = 0; i < OSPF6_PATH_TYPE_MAX; i++) - pathtype[i] = 0; - - for (route = ospf6_route_head (table); route; - route = ospf6_route_next (route)) - { - if (prev == NULL || ! ospf6_route_is_same (prev, route)) - destination++; - else - alternative++; - nh_count = ospf6_num_nexthops (route->nh_list); - if (!nh_count) - nhinval++; - else if (nh_count > 1) - ecmp++; - pathtype[route->path.type]++; - number++; - - prev = route; - } - - assert (number == table->count); - - vty_out (vty, "Number of OSPFv3 routes: %d\n", number); - vty_out (vty, "Number of Destination: %d\n", destination); - vty_out (vty, "Number of Alternative routes: %d\n", alternative); - vty_out (vty, "Number of Equal Cost Multi Path: %d\n", ecmp); - for (i = OSPF6_PATH_TYPE_INTRA; i <= OSPF6_PATH_TYPE_EXTERNAL2; i++) - { - vty_out (vty, "Number of %s routes: %d\n", - OSPF6_PATH_TYPE_NAME (i), pathtype[i]); - } + struct ospf6_route *route, *prev = NULL; + int i, pathtype[OSPF6_PATH_TYPE_MAX]; + unsigned int number = 0; + int nh_count = 0, nhinval = 0, ecmp = 0; + int alternative = 0, destination = 0; + + for (i = 0; i < OSPF6_PATH_TYPE_MAX; i++) + pathtype[i] = 0; + + for (route = ospf6_route_head(table); route; + route = ospf6_route_next(route)) { + if (prev == NULL || !ospf6_route_is_same(prev, route)) + destination++; + else + alternative++; + nh_count = ospf6_num_nexthops(route->nh_list); + if (!nh_count) + nhinval++; + else if (nh_count > 1) + ecmp++; + pathtype[route->path.type]++; + number++; + + prev = route; + } + + assert(number == table->count); + + vty_out(vty, "Number of OSPFv3 routes: %d\n", number); + vty_out(vty, "Number of Destination: %d\n", destination); + vty_out(vty, "Number of Alternative routes: %d\n", alternative); + vty_out(vty, "Number of Equal Cost Multi Path: %d\n", ecmp); + for (i = OSPF6_PATH_TYPE_INTRA; i <= OSPF6_PATH_TYPE_EXTERNAL2; i++) { + vty_out(vty, "Number of %s routes: %d\n", + OSPF6_PATH_TYPE_NAME(i), pathtype[i]); + } } -static void -ospf6_route_show_table_prefix (struct vty *vty, - struct prefix *prefix, - struct ospf6_route_table *table) +static void ospf6_route_show_table_prefix(struct vty *vty, + struct prefix *prefix, + struct ospf6_route_table *table) { - struct ospf6_route *route; - - route = ospf6_route_lookup (prefix, table); - if (route == NULL) - return; - - ospf6_route_lock (route); - while (route && ospf6_route_is_prefix (prefix, route)) - { - /* Specifying a prefix will always display details */ - ospf6_route_show_detail (vty, route); - route = ospf6_route_next (route); - } - if (route) - ospf6_route_unlock (route); + struct ospf6_route *route; + + route = ospf6_route_lookup(prefix, table); + if (route == NULL) + return; + + ospf6_route_lock(route); + while (route && ospf6_route_is_prefix(prefix, route)) { + /* Specifying a prefix will always display details */ + ospf6_route_show_detail(vty, route); + route = ospf6_route_next(route); + } + if (route) + ospf6_route_unlock(route); } -static void -ospf6_route_show_table_address (struct vty *vty, - struct prefix *prefix, - struct ospf6_route_table *table) +static void ospf6_route_show_table_address(struct vty *vty, + struct prefix *prefix, + struct ospf6_route_table *table) { - struct ospf6_route *route; - - route = ospf6_route_lookup_bestmatch (prefix, table); - if (route == NULL) - return; - - prefix = &route->prefix; - ospf6_route_lock (route); - while (route && ospf6_route_is_prefix (prefix, route)) - { - /* Specifying a prefix will always display details */ - ospf6_route_show_detail (vty, route); - route = ospf6_route_next (route); - } - if (route) - ospf6_route_unlock (route); + struct ospf6_route *route; + + route = ospf6_route_lookup_bestmatch(prefix, table); + if (route == NULL) + return; + + prefix = &route->prefix; + ospf6_route_lock(route); + while (route && ospf6_route_is_prefix(prefix, route)) { + /* Specifying a prefix will always display details */ + ospf6_route_show_detail(vty, route); + route = ospf6_route_next(route); + } + if (route) + ospf6_route_unlock(route); } -static void -ospf6_route_show_table_match (struct vty *vty, int detail, - struct prefix *prefix, - struct ospf6_route_table *table) +static void ospf6_route_show_table_match(struct vty *vty, int detail, + struct prefix *prefix, + struct ospf6_route_table *table) { - struct ospf6_route *route; - assert (prefix->family); - - route = ospf6_route_match_head (prefix, table); - while (route) - { - if (detail) - ospf6_route_show_detail (vty, route); - else - ospf6_route_show (vty, route); - route = ospf6_route_match_next (prefix, route); - } + struct ospf6_route *route; + assert(prefix->family); + + route = ospf6_route_match_head(prefix, table); + while (route) { + if (detail) + ospf6_route_show_detail(vty, route); + else + ospf6_route_show(vty, route); + route = ospf6_route_match_next(prefix, route); + } } -static void -ospf6_route_show_table_type (struct vty *vty, int detail, u_char type, - struct ospf6_route_table *table) +static void ospf6_route_show_table_type(struct vty *vty, int detail, + u_char type, + struct ospf6_route_table *table) { - struct ospf6_route *route; - - route = ospf6_route_head (table); - while (route) - { - if (route->path.type == type) - { - if (detail) - ospf6_route_show_detail (vty, route); - else - ospf6_route_show (vty, route); - } - route = ospf6_route_next (route); - } + struct ospf6_route *route; + + route = ospf6_route_head(table); + while (route) { + if (route->path.type == type) { + if (detail) + ospf6_route_show_detail(vty, route); + else + ospf6_route_show(vty, route); + } + route = ospf6_route_next(route); + } } -static void -ospf6_route_show_table (struct vty *vty, int detail, - struct ospf6_route_table *table) +static void ospf6_route_show_table(struct vty *vty, int detail, + struct ospf6_route_table *table) { - struct ospf6_route *route; - - route = ospf6_route_head (table); - while (route) - { - if (detail) - ospf6_route_show_detail (vty, route); - else - ospf6_route_show (vty, route); - route = ospf6_route_next (route); - } + struct ospf6_route *route; + + route = ospf6_route_head(table); + while (route) { + if (detail) + ospf6_route_show_detail(vty, route); + else + ospf6_route_show(vty, route); + route = ospf6_route_next(route); + } } -int -ospf6_route_table_show (struct vty *vty, int argc_start, int argc, struct cmd_token **argv, - struct ospf6_route_table *table) +int ospf6_route_table_show(struct vty *vty, int argc_start, int argc, + struct cmd_token **argv, + struct ospf6_route_table *table) { - int summary = 0; - int match = 0; - int detail = 0; - int slash = 0; - int isprefix = 0; - int i, ret; - struct prefix prefix; - u_char type = 0; - - memset (&prefix, 0, sizeof (struct prefix)); - - for (i = argc_start; i < argc; i++) - { - if (strmatch(argv[i]->text, "summary")) - { - summary++; - continue; - } - - if (strmatch(argv[i]->text, "intra-area")) - { - type = OSPF6_PATH_TYPE_INTRA; - continue; - } - - if (strmatch(argv[i]->text, "inter-area")) - { - type = OSPF6_PATH_TYPE_INTER; - continue; - } - - if (strmatch(argv[i]->text, "external-1")) - { - type = OSPF6_PATH_TYPE_EXTERNAL1; - continue; - } - - if (strmatch(argv[i]->text, "external-2")) - { - type = OSPF6_PATH_TYPE_EXTERNAL2; - continue; - } - - if (strmatch(argv[i]->text, "detail")) - { - detail++; - continue; - } - - if (strmatch(argv[i]->text, "match")) - { - match++; - continue; - } - - ret = str2prefix (argv[i]->arg, &prefix); - if (ret == 1 && prefix.family == AF_INET6) - { - isprefix++; - if (strchr (argv[i]->arg, '/')) - slash++; - continue; - } - - vty_out (vty, "Malformed argument: %s\n", argv[i]->arg); - return CMD_SUCCESS; - } - - /* Give summary of this route table */ - if (summary) - { - ospf6_route_show_table_summary (vty, table); - return CMD_SUCCESS; - } - - /* Give exact prefix-match route */ - if (isprefix && ! match) - { - /* If exact address, give best matching route */ - if (! slash) - ospf6_route_show_table_address (vty, &prefix, table); - else - ospf6_route_show_table_prefix (vty, &prefix, table); - - return CMD_SUCCESS; - } - - if (match) - ospf6_route_show_table_match (vty, detail, &prefix, table); - else if (type) - ospf6_route_show_table_type (vty, detail, type, table); - else - ospf6_route_show_table (vty, detail, table); - - return CMD_SUCCESS; + int summary = 0; + int match = 0; + int detail = 0; + int slash = 0; + int isprefix = 0; + int i, ret; + struct prefix prefix; + u_char type = 0; + + memset(&prefix, 0, sizeof(struct prefix)); + + for (i = argc_start; i < argc; i++) { + if (strmatch(argv[i]->text, "summary")) { + summary++; + continue; + } + + if (strmatch(argv[i]->text, "intra-area")) { + type = OSPF6_PATH_TYPE_INTRA; + continue; + } + + if (strmatch(argv[i]->text, "inter-area")) { + type = OSPF6_PATH_TYPE_INTER; + continue; + } + + if (strmatch(argv[i]->text, "external-1")) { + type = OSPF6_PATH_TYPE_EXTERNAL1; + continue; + } + + if (strmatch(argv[i]->text, "external-2")) { + type = OSPF6_PATH_TYPE_EXTERNAL2; + continue; + } + + if (strmatch(argv[i]->text, "detail")) { + detail++; + continue; + } + + if (strmatch(argv[i]->text, "match")) { + match++; + continue; + } + + ret = str2prefix(argv[i]->arg, &prefix); + if (ret == 1 && prefix.family == AF_INET6) { + isprefix++; + if (strchr(argv[i]->arg, '/')) + slash++; + continue; + } + + vty_out(vty, "Malformed argument: %s\n", argv[i]->arg); + return CMD_SUCCESS; + } + + /* Give summary of this route table */ + if (summary) { + ospf6_route_show_table_summary(vty, table); + return CMD_SUCCESS; + } + + /* Give exact prefix-match route */ + if (isprefix && !match) { + /* If exact address, give best matching route */ + if (!slash) + ospf6_route_show_table_address(vty, &prefix, table); + else + ospf6_route_show_table_prefix(vty, &prefix, table); + + return CMD_SUCCESS; + } + + if (match) + ospf6_route_show_table_match(vty, detail, &prefix, table); + else if (type) + ospf6_route_show_table_type(vty, detail, type, table); + else + ospf6_route_show_table(vty, detail, table); + + return CMD_SUCCESS; } -static void -ospf6_linkstate_show_header (struct vty *vty) +static void ospf6_linkstate_show_header(struct vty *vty) { - vty_out (vty, "%-7s %-15s %-15s %-8s %-14s %s\n", - "Type", "Router-ID", "Net-ID", "Rtr-Bits", "Options", "Cost"); + vty_out(vty, "%-7s %-15s %-15s %-8s %-14s %s\n", "Type", "Router-ID", + "Net-ID", "Rtr-Bits", "Options", "Cost"); } -static void -ospf6_linkstate_show (struct vty *vty, struct ospf6_route *route) +static void ospf6_linkstate_show(struct vty *vty, struct ospf6_route *route) { - u_int32_t router, id; - char routername[16], idname[16], rbits[16], options[16]; - - router = ospf6_linkstate_prefix_adv_router (&route->prefix); - inet_ntop (AF_INET, &router, routername, sizeof (routername)); - id = ospf6_linkstate_prefix_id (&route->prefix); - inet_ntop (AF_INET, &id, idname, sizeof (idname)); - - ospf6_capability_printbuf (route->path.router_bits, rbits, sizeof (rbits)); - ospf6_options_printbuf (route->path.options, options, sizeof (options)); - - if (ntohl (id)) - vty_out (vty, "%-7s %-15s %-15s %-8s %-14s %lu\n", - "Network", routername, idname, rbits, options, - (unsigned long) route->path.cost); - else - vty_out (vty, "%-7s %-15s %-15s %-8s %-14s %lu\n", - "Router", routername, idname, rbits, options, - (unsigned long) route->path.cost); + u_int32_t router, id; + char routername[16], idname[16], rbits[16], options[16]; + + router = ospf6_linkstate_prefix_adv_router(&route->prefix); + inet_ntop(AF_INET, &router, routername, sizeof(routername)); + id = ospf6_linkstate_prefix_id(&route->prefix); + inet_ntop(AF_INET, &id, idname, sizeof(idname)); + + ospf6_capability_printbuf(route->path.router_bits, rbits, + sizeof(rbits)); + ospf6_options_printbuf(route->path.options, options, sizeof(options)); + + if (ntohl(id)) + vty_out(vty, "%-7s %-15s %-15s %-8s %-14s %lu\n", "Network", + routername, idname, rbits, options, + (unsigned long)route->path.cost); + else + vty_out(vty, "%-7s %-15s %-15s %-8s %-14s %lu\n", "Router", + routername, idname, rbits, options, + (unsigned long)route->path.cost); } -static void -ospf6_linkstate_show_table_exact (struct vty *vty, - struct prefix *prefix, - struct ospf6_route_table *table) +static void ospf6_linkstate_show_table_exact(struct vty *vty, + struct prefix *prefix, + struct ospf6_route_table *table) { - struct ospf6_route *route; - - route = ospf6_route_lookup (prefix, table); - if (route == NULL) - return; - - ospf6_route_lock (route); - while (route && ospf6_route_is_prefix (prefix, route)) - { - /* Specifying a prefix will always display details */ - ospf6_route_show_detail (vty, route); - route = ospf6_route_next (route); - } - if (route) - ospf6_route_unlock (route); + struct ospf6_route *route; + + route = ospf6_route_lookup(prefix, table); + if (route == NULL) + return; + + ospf6_route_lock(route); + while (route && ospf6_route_is_prefix(prefix, route)) { + /* Specifying a prefix will always display details */ + ospf6_route_show_detail(vty, route); + route = ospf6_route_next(route); + } + if (route) + ospf6_route_unlock(route); } -static void -ospf6_linkstate_show_table (struct vty *vty, int detail, - struct ospf6_route_table *table) +static void ospf6_linkstate_show_table(struct vty *vty, int detail, + struct ospf6_route_table *table) { - struct ospf6_route *route; - - if (! detail) - ospf6_linkstate_show_header (vty); - - route = ospf6_route_head (table); - while (route) - { - if (detail) - ospf6_route_show_detail (vty, route); - else - ospf6_linkstate_show (vty, route); - route = ospf6_route_next (route); - } + struct ospf6_route *route; + + if (!detail) + ospf6_linkstate_show_header(vty); + + route = ospf6_route_head(table); + while (route) { + if (detail) + ospf6_route_show_detail(vty, route); + else + ospf6_linkstate_show(vty, route); + route = ospf6_route_next(route); + } } -int -ospf6_linkstate_table_show (struct vty *vty, int idx_ipv4, int argc, - struct cmd_token **argv, - struct ospf6_route_table *table) +int ospf6_linkstate_table_show(struct vty *vty, int idx_ipv4, int argc, + struct cmd_token **argv, + struct ospf6_route_table *table) { - int detail = 0; - int is_id = 0; - int is_router = 0; - int i, ret; - struct prefix router, id, prefix; - - memset (&router, 0, sizeof (struct prefix)); - memset (&id, 0, sizeof (struct prefix)); - memset (&prefix, 0, sizeof (struct prefix)); - - for (i = idx_ipv4; i < argc; i++) - { - if (strmatch(argv[i]->text, "detail")) - { - detail++; - continue; - } - - if (! is_router) - { - ret = str2prefix (argv[i]->arg, &router); - if (ret == 1 && router.family == AF_INET) - { - is_router++; - continue; - } - vty_out (vty, "Malformed argument: %s\n", argv[i]->arg); - return CMD_SUCCESS; - } - - if (! is_id) - { - ret = str2prefix (argv[i]->arg, &id); - if (ret == 1 && id.family == AF_INET) - { - is_id++; - continue; - } - vty_out (vty, "Malformed argument: %s\n", argv[i]->arg); - return CMD_SUCCESS; - } - - vty_out (vty, "Malformed argument: %s\n", argv[i]->arg); - return CMD_SUCCESS; - } - - if (is_router) - ospf6_linkstate_prefix (router.u.prefix4.s_addr, - id.u.prefix4.s_addr, &prefix); - - if (prefix.family) - ospf6_linkstate_show_table_exact (vty, &prefix, table); - else - ospf6_linkstate_show_table (vty, detail, table); - - return CMD_SUCCESS; + int detail = 0; + int is_id = 0; + int is_router = 0; + int i, ret; + struct prefix router, id, prefix; + + memset(&router, 0, sizeof(struct prefix)); + memset(&id, 0, sizeof(struct prefix)); + memset(&prefix, 0, sizeof(struct prefix)); + + for (i = idx_ipv4; i < argc; i++) { + if (strmatch(argv[i]->text, "detail")) { + detail++; + continue; + } + + if (!is_router) { + ret = str2prefix(argv[i]->arg, &router); + if (ret == 1 && router.family == AF_INET) { + is_router++; + continue; + } + vty_out(vty, "Malformed argument: %s\n", argv[i]->arg); + return CMD_SUCCESS; + } + + if (!is_id) { + ret = str2prefix(argv[i]->arg, &id); + if (ret == 1 && id.family == AF_INET) { + is_id++; + continue; + } + vty_out(vty, "Malformed argument: %s\n", argv[i]->arg); + return CMD_SUCCESS; + } + + vty_out(vty, "Malformed argument: %s\n", argv[i]->arg); + return CMD_SUCCESS; + } + + if (is_router) + ospf6_linkstate_prefix(router.u.prefix4.s_addr, + id.u.prefix4.s_addr, &prefix); + + if (prefix.family) + ospf6_linkstate_show_table_exact(vty, &prefix, table); + else + ospf6_linkstate_show_table(vty, detail, table); + + return CMD_SUCCESS; } -void -ospf6_brouter_show_header (struct vty *vty) +void ospf6_brouter_show_header(struct vty *vty) { - vty_out (vty, "%-15s %-8s %-14s %-10s %-15s\n", - "Router-ID", "Rtr-Bits", "Options", "Path-Type", "Area"); + vty_out(vty, "%-15s %-8s %-14s %-10s %-15s\n", "Router-ID", "Rtr-Bits", + "Options", "Path-Type", "Area"); } -void -ospf6_brouter_show (struct vty *vty, struct ospf6_route *route) +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\n", - "Router-ID", "Rtr-Bits", "Options", "Path-Type", "Area"); */ - vty_out (vty, "%-15s %-8s %-14s %-10s %-15s\n", - adv, rbits, options, OSPF6_PATH_TYPE_NAME (route->path.type), - area); + 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\n", + "Router-ID", "Rtr-Bits", "Options", "Path-Type", "Area"); */ + vty_out(vty, "%-15s %-8s %-14s %-10s %-15s\n", adv, rbits, options, + OSPF6_PATH_TYPE_NAME(route->path.type), area); } DEFUN (debug_ospf6_route, @@ -1570,19 +1457,19 @@ DEFUN (debug_ospf6_route, "Debug route memory use\n" ) { - int idx_type = 3; - unsigned char level = 0; - - if (! strncmp (argv[idx_type]->arg, "table", 5)) - level = OSPF6_DEBUG_ROUTE_TABLE; - else if (! strncmp (argv[idx_type]->arg, "intra", 5)) - level = OSPF6_DEBUG_ROUTE_INTRA; - else if (! strncmp (argv[idx_type]->arg, "inter", 5)) - level = OSPF6_DEBUG_ROUTE_INTER; - else if (! strncmp (argv[idx_type]->arg, "memor", 5)) - level = OSPF6_DEBUG_ROUTE_MEMORY; - OSPF6_DEBUG_ROUTE_ON (level); - return CMD_SUCCESS; + int idx_type = 3; + unsigned char level = 0; + + if (!strncmp(argv[idx_type]->arg, "table", 5)) + level = OSPF6_DEBUG_ROUTE_TABLE; + else if (!strncmp(argv[idx_type]->arg, "intra", 5)) + level = OSPF6_DEBUG_ROUTE_INTRA; + else if (!strncmp(argv[idx_type]->arg, "inter", 5)) + level = OSPF6_DEBUG_ROUTE_INTER; + else if (!strncmp(argv[idx_type]->arg, "memor", 5)) + level = OSPF6_DEBUG_ROUTE_MEMORY; + OSPF6_DEBUG_ROUTE_ON(level); + return CMD_SUCCESS; } DEFUN (no_debug_ospf6_route, @@ -1597,41 +1484,36 @@ DEFUN (no_debug_ospf6_route, "Debug inter-area route calculation\n" "Debug route memory use\n") { - int idx_type = 4; - unsigned char level = 0; - - if (! strncmp (argv[idx_type]->arg, "table", 5)) - level = OSPF6_DEBUG_ROUTE_TABLE; - else if (! strncmp (argv[idx_type]->arg, "intra", 5)) - level = OSPF6_DEBUG_ROUTE_INTRA; - else if (! strncmp (argv[idx_type]->arg, "inter", 5)) - level = OSPF6_DEBUG_ROUTE_INTER; - else if (! strncmp (argv[idx_type]->arg, "memor", 5)) - level = OSPF6_DEBUG_ROUTE_MEMORY; - OSPF6_DEBUG_ROUTE_OFF (level); - return CMD_SUCCESS; + int idx_type = 4; + unsigned char level = 0; + + if (!strncmp(argv[idx_type]->arg, "table", 5)) + level = OSPF6_DEBUG_ROUTE_TABLE; + else if (!strncmp(argv[idx_type]->arg, "intra", 5)) + level = OSPF6_DEBUG_ROUTE_INTRA; + else if (!strncmp(argv[idx_type]->arg, "inter", 5)) + level = OSPF6_DEBUG_ROUTE_INTER; + else if (!strncmp(argv[idx_type]->arg, "memor", 5)) + level = OSPF6_DEBUG_ROUTE_MEMORY; + OSPF6_DEBUG_ROUTE_OFF(level); + return CMD_SUCCESS; } -int -config_write_ospf6_debug_route (struct vty *vty) +int config_write_ospf6_debug_route(struct vty *vty) { - if (IS_OSPF6_DEBUG_ROUTE (TABLE)) - vty_out (vty, "debug ospf6 route table\n"); - if (IS_OSPF6_DEBUG_ROUTE (INTRA)) - vty_out (vty, "debug ospf6 route intra-area\n"); - if (IS_OSPF6_DEBUG_ROUTE (INTER)) - vty_out (vty, "debug ospf6 route inter-area\n"); - return 0; + if (IS_OSPF6_DEBUG_ROUTE(TABLE)) + vty_out(vty, "debug ospf6 route table\n"); + if (IS_OSPF6_DEBUG_ROUTE(INTRA)) + vty_out(vty, "debug ospf6 route intra-area\n"); + if (IS_OSPF6_DEBUG_ROUTE(INTER)) + vty_out(vty, "debug ospf6 route inter-area\n"); + return 0; } -void -install_element_ospf6_debug_route (void) +void install_element_ospf6_debug_route(void) { - install_element (ENABLE_NODE, &debug_ospf6_route_cmd); - install_element (ENABLE_NODE, &no_debug_ospf6_route_cmd); - install_element (CONFIG_NODE, &debug_ospf6_route_cmd); - install_element (CONFIG_NODE, &no_debug_ospf6_route_cmd); + install_element(ENABLE_NODE, &debug_ospf6_route_cmd); + install_element(ENABLE_NODE, &no_debug_ospf6_route_cmd); + install_element(CONFIG_NODE, &debug_ospf6_route_cmd); + install_element(CONFIG_NODE, &no_debug_ospf6_route_cmd); } - - - diff --git a/ospf6d/ospf6_route.h b/ospf6d/ospf6_route.h index 7cf69a26e..69d275f8b 100644 --- a/ospf6d/ospf6_route.h +++ b/ospf6d/ospf6_route.h @@ -31,77 +31,70 @@ extern unsigned char conf_debug_ospf6_route; #define OSPF6_DEBUG_ROUTE_INTRA 0x02 #define OSPF6_DEBUG_ROUTE_INTER 0x04 #define OSPF6_DEBUG_ROUTE_MEMORY 0x80 -#define OSPF6_DEBUG_ROUTE_ON(level) \ - (conf_debug_ospf6_route |= (level)) -#define OSPF6_DEBUG_ROUTE_OFF(level) \ - (conf_debug_ospf6_route &= ~(level)) -#define IS_OSPF6_DEBUG_ROUTE(e) \ - (conf_debug_ospf6_route & OSPF6_DEBUG_ROUTE_ ## e) +#define OSPF6_DEBUG_ROUTE_ON(level) (conf_debug_ospf6_route |= (level)) +#define OSPF6_DEBUG_ROUTE_OFF(level) (conf_debug_ospf6_route &= ~(level)) +#define IS_OSPF6_DEBUG_ROUTE(e) (conf_debug_ospf6_route & OSPF6_DEBUG_ROUTE_##e) /* Nexthop */ -struct ospf6_nexthop -{ - /* Interface index */ - ifindex_t ifindex; +struct ospf6_nexthop { + /* Interface index */ + ifindex_t ifindex; - /* IP address, if any */ - struct in6_addr address; + /* IP address, if any */ + struct in6_addr address; }; -#define ospf6_nexthop_is_set(x) \ - ((x)->ifindex || ! IN6_IS_ADDR_UNSPECIFIED (&(x)->address)) -#define ospf6_nexthop_is_same(a,b) \ - ((a)->ifindex == (b)->ifindex && \ - IN6_ARE_ADDR_EQUAL (&(a)->address, &(b)->address)) -#define ospf6_nexthop_clear(x) \ - do { \ - (x)->ifindex = 0; \ - memset (&(x)->address, 0, sizeof (struct in6_addr)); \ - } while (0) -#define ospf6_nexthop_copy(a, b) \ - do { \ - (a)->ifindex = (b)->ifindex; \ - memcpy (&(a)->address, &(b)->address, \ - sizeof (struct in6_addr)); \ - } while (0) +#define ospf6_nexthop_is_set(x) \ + ((x)->ifindex || !IN6_IS_ADDR_UNSPECIFIED(&(x)->address)) +#define ospf6_nexthop_is_same(a, b) \ + ((a)->ifindex == (b)->ifindex \ + && IN6_ARE_ADDR_EQUAL(&(a)->address, &(b)->address)) +#define ospf6_nexthop_clear(x) \ + do { \ + (x)->ifindex = 0; \ + memset(&(x)->address, 0, sizeof(struct in6_addr)); \ + } while (0) +#define ospf6_nexthop_copy(a, b) \ + do { \ + (a)->ifindex = (b)->ifindex; \ + memcpy(&(a)->address, &(b)->address, sizeof(struct in6_addr)); \ + } while (0) /* Path */ -struct ospf6_ls_origin -{ - u_int16_t type; - u_int32_t id; - u_int32_t adv_router; +struct ospf6_ls_origin { + u_int16_t type; + u_int32_t id; + u_int32_t adv_router; }; -struct ospf6_path -{ - /* Link State Origin */ - struct ospf6_ls_origin origin; +struct ospf6_path { + /* Link State Origin */ + struct ospf6_ls_origin origin; - /* Router bits */ - u_char router_bits; + /* Router bits */ + u_char router_bits; - /* Optional Capabilities */ - u_char options[3]; + /* Optional Capabilities */ + u_char options[3]; - /* Prefix Options */ - u_char prefix_options; + /* Prefix Options */ + u_char prefix_options; - /* Associated Area */ - u_int32_t area_id; + /* Associated Area */ + u_int32_t area_id; - /* Path-type */ - u_char type; - u_char subtype; /* only used for redistribute i.e ZEBRA_ROUTE_XXX */ + /* Path-type */ + u_char type; + u_char subtype; /* only used for redistribute i.e ZEBRA_ROUTE_XXX */ - /* Cost */ - u_int8_t metric_type; - u_int32_t cost; - union { - u_int32_t cost_e2; - u_int32_t cost_config; - } u; - u_int32_t tag; + /* Cost */ + u_int8_t metric_type; + u_int32_t cost; + union { + u_int32_t cost_e2; + u_int32_t cost_config; + } u; + u_int32_t tag; }; #define OSPF6_PATH_TYPE_NONE 0 @@ -120,44 +113,43 @@ struct ospf6_path #include "table.h" #include "bitfield.h" -struct ospf6_route -{ - struct route_node *rnode; - struct ospf6_route_table *table; - struct ospf6_route *prev; - struct ospf6_route *next; +struct ospf6_route { + struct route_node *rnode; + struct ospf6_route_table *table; + struct ospf6_route *prev; + struct ospf6_route *next; - unsigned int lock; + unsigned int lock; - /* Destination Type */ - u_char type; + /* Destination Type */ + u_char type; - /* XXX: It would likely be better to use separate struct in_addr's - * for the advertising router-ID and prefix IDs, instead of stuffing them - * into one. See also XXX below. - */ - /* Destination ID */ - struct prefix prefix; + /* XXX: It would likely be better to use separate struct in_addr's + * for the advertising router-ID and prefix IDs, instead of stuffing + * them + * into one. See also XXX below. + */ + /* Destination ID */ + struct prefix prefix; - /* Time */ - struct timeval installed; - struct timeval changed; + /* Time */ + struct timeval installed; + struct timeval changed; - /* flag */ - u_char flag; + /* flag */ + u_char flag; - /* route option */ - void *route_option; + /* route option */ + void *route_option; - /* link state id for advertising */ - u_int32_t linkstate_id; + /* link state id for advertising */ + u_int32_t linkstate_id; - /* path */ - struct ospf6_path path; - - /* nexthop */ - struct list *nh_list; + /* path */ + struct ospf6_path path; + /* nexthop */ + struct list *nh_list; }; #define OSPF6_DEST_TYPE_NONE 0 @@ -177,23 +169,22 @@ struct ospf6_route #define OSPF6_ROUTE_WAS_REMOVED 0x40 #define OSPF6_ROUTE_BLACKHOLE_ADDED 0x80 -struct ospf6_route_table -{ - int scope_type; - int table_type; - void *scope; +struct ospf6_route_table { + int scope_type; + int table_type; + void *scope; - /* patricia tree */ - struct route_table *table; + /* patricia tree */ + struct route_table *table; - u_int32_t count; + u_int32_t count; - bitfield_t idspace; + bitfield_t idspace; - /* hooks */ - void (*hook_add) (struct ospf6_route *); - void (*hook_change) (struct ospf6_route *); - void (*hook_remove) (struct ospf6_route *); + /* hooks */ + void (*hook_add)(struct ospf6_route *); + void (*hook_change)(struct ospf6_route *); + void (*hook_remove)(struct ospf6_route *); }; #define OSPF6_SCOPE_TYPE_NONE 0 @@ -211,138 +202,135 @@ struct ospf6_route_table #define OSPF6_TABLE_TYPE_SUMMARY_PREFIXES 7 #define OSPF6_TABLE_TYPE_SUMMARY_ROUTERS 8 -#define OSPF6_ROUTE_TABLE_CREATE(s, t) \ - ospf6_route_table_create (OSPF6_SCOPE_TYPE_ ## s, \ - OSPF6_TABLE_TYPE_ ## t) +#define OSPF6_ROUTE_TABLE_CREATE(s, t) \ + ospf6_route_table_create(OSPF6_SCOPE_TYPE_##s, OSPF6_TABLE_TYPE_##t) extern const char *ospf6_dest_type_str[OSPF6_DEST_TYPE_MAX]; extern const char *ospf6_dest_type_substr[OSPF6_DEST_TYPE_MAX]; -#define OSPF6_DEST_TYPE_NAME(x) \ - (0 < (x) && (x) < OSPF6_DEST_TYPE_MAX ? \ - ospf6_dest_type_str[(x)] : ospf6_dest_type_str[0]) -#define OSPF6_DEST_TYPE_SUBSTR(x) \ - (0 < (x) && (x) < OSPF6_DEST_TYPE_MAX ? \ - ospf6_dest_type_substr[(x)] : ospf6_dest_type_substr[0]) +#define OSPF6_DEST_TYPE_NAME(x) \ + (0 < (x) && (x) < OSPF6_DEST_TYPE_MAX ? ospf6_dest_type_str[(x)] \ + : ospf6_dest_type_str[0]) +#define OSPF6_DEST_TYPE_SUBSTR(x) \ + (0 < (x) && (x) < OSPF6_DEST_TYPE_MAX ? ospf6_dest_type_substr[(x)] \ + : ospf6_dest_type_substr[0]) extern const char *ospf6_path_type_str[OSPF6_PATH_TYPE_MAX]; extern const char *ospf6_path_type_substr[OSPF6_PATH_TYPE_MAX]; -#define OSPF6_PATH_TYPE_NAME(x) \ - (0 < (x) && (x) < OSPF6_PATH_TYPE_MAX ? \ - ospf6_path_type_str[(x)] : ospf6_path_type_str[0]) -#define OSPF6_PATH_TYPE_SUBSTR(x) \ - (0 < (x) && (x) < OSPF6_PATH_TYPE_MAX ? \ - ospf6_path_type_substr[(x)] : ospf6_path_type_substr[0]) +#define OSPF6_PATH_TYPE_NAME(x) \ + (0 < (x) && (x) < OSPF6_PATH_TYPE_MAX ? ospf6_path_type_str[(x)] \ + : ospf6_path_type_str[0]) +#define OSPF6_PATH_TYPE_SUBSTR(x) \ + (0 < (x) && (x) < OSPF6_PATH_TYPE_MAX ? ospf6_path_type_substr[(x)] \ + : ospf6_path_type_substr[0]) #define OSPF6_ROUTE_ADDRESS_STR "Display the route bestmatches the address\n" #define OSPF6_ROUTE_PREFIX_STR "Display the route\n" #define OSPF6_ROUTE_MATCH_STR "Display the route matches the prefix\n" -#define ospf6_route_is_prefix(p, r) \ - (memcmp (p, &(r)->prefix, sizeof (struct prefix)) == 0) -#define ospf6_route_is_same(ra, rb) \ - (prefix_same (&(ra)->prefix, &(rb)->prefix)) -#define ospf6_route_is_same_origin(ra, rb) \ - ((ra)->path.area_id == (rb)->path.area_id && \ - memcmp (&(ra)->path.origin, &(rb)->path.origin, \ - sizeof (struct ospf6_ls_origin)) == 0) -#define ospf6_route_is_identical(ra, rb) \ - ((ra)->type == (rb)->type && \ - memcmp (&(ra)->prefix, &(rb)->prefix, sizeof (struct prefix)) == 0 && \ - memcmp (&(ra)->path, &(rb)->path, sizeof (struct ospf6_path)) == 0 && \ - ospf6_route_cmp_nexthops (ra, rb) == 0) +#define ospf6_route_is_prefix(p, r) \ + (memcmp(p, &(r)->prefix, sizeof(struct prefix)) == 0) +#define ospf6_route_is_same(ra, rb) (prefix_same(&(ra)->prefix, &(rb)->prefix)) +#define ospf6_route_is_same_origin(ra, rb) \ + ((ra)->path.area_id == (rb)->path.area_id \ + && memcmp(&(ra)->path.origin, &(rb)->path.origin, \ + sizeof(struct ospf6_ls_origin)) \ + == 0) +#define ospf6_route_is_identical(ra, rb) \ + ((ra)->type == (rb)->type \ + && memcmp(&(ra)->prefix, &(rb)->prefix, sizeof(struct prefix)) == 0 \ + && memcmp(&(ra)->path, &(rb)->path, sizeof(struct ospf6_path)) == 0 \ + && ospf6_route_cmp_nexthops(ra, rb) == 0) #define ospf6_route_is_best(r) (CHECK_FLAG ((r)->flag, OSPF6_ROUTE_BEST)) -#define ospf6_linkstate_prefix_adv_router(x) \ - ((x)->u.lp.id.s_addr) -#define ospf6_linkstate_prefix_id(x) \ - ((x)->u.lp.adv_router.s_addr) +#define ospf6_linkstate_prefix_adv_router(x) ((x)->u.lp.id.s_addr) +#define ospf6_linkstate_prefix_id(x) ((x)->u.lp.adv_router.s_addr) -#define ADV_ROUTER_IN_PREFIX(x) \ - ((x)->u.lp.id.s_addr) +#define ADV_ROUTER_IN_PREFIX(x) ((x)->u.lp.id.s_addr) /* Function prototype */ -extern void ospf6_linkstate_prefix (u_int32_t adv_router, u_int32_t id, - struct prefix *prefix); -extern void ospf6_linkstate_prefix2str (struct prefix *prefix, char *buf, - int size); - -extern struct ospf6_nexthop *ospf6_nexthop_create (void); -extern void ospf6_nexthop_delete (struct ospf6_nexthop *nh); -extern void ospf6_free_nexthops (struct list *nh_list); -extern void ospf6_clear_nexthops (struct list *nh_list); -extern int ospf6_num_nexthops (struct list *nh_list); -extern void ospf6_copy_nexthops (struct list *dst, struct list *src); -extern void ospf6_merge_nexthops (struct list *dst, struct list *src); -extern void ospf6_add_nexthop (struct list *nh_list, int ifindex, - struct in6_addr *addr); -extern int ospf6_num_nexthops (struct list *nh_list); -extern int ospf6_route_cmp_nexthops (struct ospf6_route *a, - struct ospf6_route *b); -extern void ospf6_route_zebra_copy_nexthops (struct ospf6_route *route, - ifindex_t *ifindices, - struct in6_addr **addr, - int entries); -extern int ospf6_route_get_first_nh_index (struct ospf6_route *route); +extern void ospf6_linkstate_prefix(u_int32_t adv_router, u_int32_t id, + struct prefix *prefix); +extern void ospf6_linkstate_prefix2str(struct prefix *prefix, char *buf, + int size); + +extern struct ospf6_nexthop *ospf6_nexthop_create(void); +extern void ospf6_nexthop_delete(struct ospf6_nexthop *nh); +extern void ospf6_free_nexthops(struct list *nh_list); +extern void ospf6_clear_nexthops(struct list *nh_list); +extern int ospf6_num_nexthops(struct list *nh_list); +extern void ospf6_copy_nexthops(struct list *dst, struct list *src); +extern void ospf6_merge_nexthops(struct list *dst, struct list *src); +extern void ospf6_add_nexthop(struct list *nh_list, int ifindex, + struct in6_addr *addr); +extern int ospf6_num_nexthops(struct list *nh_list); +extern int ospf6_route_cmp_nexthops(struct ospf6_route *a, + struct ospf6_route *b); +extern void ospf6_route_zebra_copy_nexthops(struct ospf6_route *route, + ifindex_t *ifindices, + struct in6_addr **addr, + int entries); +extern int ospf6_route_get_first_nh_index(struct ospf6_route *route); /* Hide abstraction of nexthop implementation in route from outsiders */ #define ospf6_route_copy_nexthops(dst, src) ospf6_copy_nexthops(dst->nh_list, src->nh_list) #define ospf6_route_merge_nexthops(dst, src) ospf6_merge_nexthops(dst->nh_list, src->nh_list) #define ospf6_route_num_nexthops(route) ospf6_num_nexthops(route->nh_list) -#define ospf6_route_add_nexthop(route, ifindex, addr) \ - ospf6_add_nexthop(route->nh_list, ifindex, addr) - -extern struct ospf6_route *ospf6_route_create (void); -extern void ospf6_route_delete (struct ospf6_route *); -extern struct ospf6_route *ospf6_route_copy (struct ospf6_route *route); -extern int ospf6_route_cmp (struct ospf6_route *ra, struct ospf6_route *rb); - -extern void ospf6_route_lock (struct ospf6_route *route); -extern void ospf6_route_unlock (struct ospf6_route *route); - -extern struct ospf6_route *ospf6_route_lookup (struct prefix *prefix, - struct ospf6_route_table *table); -extern struct ospf6_route *ospf6_route_lookup_identical (struct ospf6_route *route, - struct ospf6_route_table *table); -extern struct ospf6_route *ospf6_route_lookup_bestmatch (struct prefix *prefix, - struct ospf6_route_table *table); - -extern struct ospf6_route *ospf6_route_add (struct ospf6_route *route, - struct ospf6_route_table *table); -extern void ospf6_route_remove (struct ospf6_route *route, - struct ospf6_route_table *table); - -extern struct ospf6_route *ospf6_route_head (struct ospf6_route_table *table); -extern struct ospf6_route *ospf6_route_next (struct ospf6_route *route); -extern struct ospf6_route *ospf6_route_best_next (struct ospf6_route *route); - -extern struct ospf6_route *ospf6_route_match_head (struct prefix *prefix, - struct ospf6_route_table *table); -extern struct ospf6_route *ospf6_route_match_next (struct prefix *prefix, - struct ospf6_route *route); - -extern void ospf6_route_remove_all (struct ospf6_route_table *); -extern struct ospf6_route_table *ospf6_route_table_create (int s, int t); -extern void ospf6_route_table_delete (struct ospf6_route_table *); -extern void ospf6_route_dump (struct ospf6_route_table *table); - - -extern void ospf6_route_show (struct vty *vty, struct ospf6_route *route); -extern void ospf6_route_show_detail (struct vty *vty, struct ospf6_route *route); - -extern int ospf6_route_table_show (struct vty *, int, int, struct cmd_token **, - struct ospf6_route_table *); -extern int ospf6_linkstate_table_show (struct vty *vty, int idx_ipv4, int argc, - struct cmd_token **argv, - struct ospf6_route_table *table); - -extern void ospf6_brouter_show_header (struct vty *vty); -extern void ospf6_brouter_show (struct vty *vty, struct ospf6_route *route); - -extern int config_write_ospf6_debug_route (struct vty *vty); -extern void install_element_ospf6_debug_route (void); -extern void ospf6_route_init (void); -extern void ospf6_clean (void); +#define ospf6_route_add_nexthop(route, ifindex, addr) \ + ospf6_add_nexthop(route->nh_list, ifindex, addr) + +extern struct ospf6_route *ospf6_route_create(void); +extern void ospf6_route_delete(struct ospf6_route *); +extern struct ospf6_route *ospf6_route_copy(struct ospf6_route *route); +extern int ospf6_route_cmp(struct ospf6_route *ra, struct ospf6_route *rb); + +extern void ospf6_route_lock(struct ospf6_route *route); +extern void ospf6_route_unlock(struct ospf6_route *route); + +extern struct ospf6_route *ospf6_route_lookup(struct prefix *prefix, + struct ospf6_route_table *table); +extern struct ospf6_route * +ospf6_route_lookup_identical(struct ospf6_route *route, + struct ospf6_route_table *table); +extern struct ospf6_route * +ospf6_route_lookup_bestmatch(struct prefix *prefix, + struct ospf6_route_table *table); + +extern struct ospf6_route *ospf6_route_add(struct ospf6_route *route, + struct ospf6_route_table *table); +extern void ospf6_route_remove(struct ospf6_route *route, + struct ospf6_route_table *table); + +extern struct ospf6_route *ospf6_route_head(struct ospf6_route_table *table); +extern struct ospf6_route *ospf6_route_next(struct ospf6_route *route); +extern struct ospf6_route *ospf6_route_best_next(struct ospf6_route *route); + +extern struct ospf6_route * +ospf6_route_match_head(struct prefix *prefix, struct ospf6_route_table *table); +extern struct ospf6_route *ospf6_route_match_next(struct prefix *prefix, + struct ospf6_route *route); + +extern void ospf6_route_remove_all(struct ospf6_route_table *); +extern struct ospf6_route_table *ospf6_route_table_create(int s, int t); +extern void ospf6_route_table_delete(struct ospf6_route_table *); +extern void ospf6_route_dump(struct ospf6_route_table *table); + + +extern void ospf6_route_show(struct vty *vty, struct ospf6_route *route); +extern void ospf6_route_show_detail(struct vty *vty, struct ospf6_route *route); + +extern int ospf6_route_table_show(struct vty *, int, int, struct cmd_token **, + struct ospf6_route_table *); +extern int ospf6_linkstate_table_show(struct vty *vty, int idx_ipv4, int argc, + struct cmd_token **argv, + struct ospf6_route_table *table); + +extern void ospf6_brouter_show_header(struct vty *vty); +extern void ospf6_brouter_show(struct vty *vty, struct ospf6_route *route); + +extern int config_write_ospf6_debug_route(struct vty *vty); +extern void install_element_ospf6_debug_route(void); +extern void ospf6_route_init(void); +extern void ospf6_clean(void); #endif /* OSPF6_ROUTE_H */ - diff --git a/ospf6d/ospf6_snmp.c b/ospf6d/ospf6_snmp.c index 29327bd38..0b399bad1 100644 --- a/ospf6d/ospf6_snmp.c +++ b/ospf6d/ospf6_snmp.c @@ -205,1007 +205,1208 @@ SNMP_LOCAL_VARIABLES /* OSPFv3-MIB instances. */ -static oid ospfv3_oid [] = { OSPFv3MIB }; -static oid ospfv3_trap_oid [] = { OSPFv3MIB, 0 }; +static oid ospfv3_oid[] = {OSPFv3MIB}; +static oid ospfv3_trap_oid[] = {OSPFv3MIB, 0}; /* Hook functions. */ -static u_char *ospfv3GeneralGroup (struct variable *, oid *, size_t *, - int, size_t *, WriteMethod **); -static u_char *ospfv3AreaEntry (struct variable *, oid *, size_t *, - int, size_t *, WriteMethod **); -static u_char *ospfv3WwLsdbEntry (struct variable *, oid *, size_t *, - int, size_t *, WriteMethod **); -static u_char *ospfv3NbrEntry (struct variable *, oid *, size_t *, - int, size_t *, WriteMethod **); -static u_char *ospfv3IfEntry (struct variable *, oid *, size_t *, - int, size_t *, WriteMethod **); - -static struct variable ospfv3_variables[] = -{ - /* OSPF general variables */ - {OSPFv3ROUTERID, UNSIGNED, RWRITE, ospfv3GeneralGroup, - 3, {1, 1, 1}}, - {OSPFv3ADMINSTAT, INTEGER, RWRITE, ospfv3GeneralGroup, - 3, {1, 1, 2}}, - {OSPFv3VERSIONNUMBER, INTEGER, RONLY, ospfv3GeneralGroup, - 3, {1, 1, 3}}, - {OSPFv3AREABDRRTRSTATUS, INTEGER, RONLY, ospfv3GeneralGroup, - 3, {1, 1, 4}}, - {OSPFv3ASBDRRTRSTATUS, INTEGER, RWRITE, ospfv3GeneralGroup, - 3, {1, 1, 5}}, - {OSPFv3ASSCOPELSACOUNT, GAUGE, RONLY, ospfv3GeneralGroup, - 3, {1, 1, 6}}, - {OSPFv3ASSCOPELSACHECKSUMSUM,UNSIGNED, RONLY, ospfv3GeneralGroup, - 3, {1, 1, 7}}, - {OSPFv3ORIGINATENEWLSAS, COUNTER, RONLY, ospfv3GeneralGroup, - 3, {1, 1, 8}}, - {OSPFv3RXNEWLSAS, COUNTER, RONLY, ospfv3GeneralGroup, - 3, {1, 1, 9}}, - {OSPFv3EXTLSACOUNT, GAUGE, RONLY, ospfv3GeneralGroup, - 3, {1, 1, 10}}, - {OSPFv3EXTAREALSDBLIMIT, INTEGER, RWRITE, ospfv3GeneralGroup, - 3, {1, 1, 11}}, - {OSPFv3EXITOVERFLOWINTERVAL, UNSIGNED, RWRITE, ospfv3GeneralGroup, - 3, {1, 1, 12}}, - {OSPFv3DEMANDEXTENSIONS, INTEGER, RWRITE, ospfv3GeneralGroup, - 3, {1, 1, 13}}, - {OSPFv3REFERENCEBANDWIDTH, UNSIGNED, RWRITE, ospfv3GeneralGroup, - 3, {1, 1, 14}}, - {OSPFv3RESTARTSUPPORT, INTEGER, RWRITE, ospfv3GeneralGroup, - 3, {1, 1, 15}}, - {OSPFv3RESTARTINTERVAL, UNSIGNED, RWRITE, ospfv3GeneralGroup, - 3, {1, 1, 16}}, - {OSPFv3RESTARTSTRICTLSACHECKING, INTEGER, RWRITE, ospfv3GeneralGroup, - 3, {1, 1, 17}}, - {OSPFv3RESTARTSTATUS, INTEGER, RONLY, ospfv3GeneralGroup, - 3, {1, 1, 18}}, - {OSPFv3RESTARTAGE, UNSIGNED, RONLY, ospfv3GeneralGroup, - 3, {1, 1, 19}}, - {OSPFv3RESTARTEXITREASON, INTEGER, RONLY, ospfv3GeneralGroup, - 3, {1, 1, 20}}, - {OSPFv3NOTIFICATIONENABLE, INTEGER, RWRITE, ospfv3GeneralGroup, - 3, {1, 1, 21}}, - {OSPFv3STUBROUTERSUPPORT, INTEGER, RONLY, ospfv3GeneralGroup, - 3, {1, 1, 22}}, - {OSPFv3STUBROUTERADVERTISEMENT, INTEGER, RWRITE, ospfv3GeneralGroup, - 3, {1, 1, 23}}, - {OSPFv3DISCONTINUITYTIME, TIMETICKS, RONLY, ospfv3GeneralGroup, - 3, {1, 1, 24}}, - {OSPFv3RESTARTTIME, TIMETICKS, RONLY, ospfv3GeneralGroup, - 3, {1, 1, 25}}, - - /* OSPFv3 Area Data Structure */ - {OSPFv3IMPORTASEXTERN, INTEGER, RWRITE, ospfv3AreaEntry, - 4, {1, 2, 1, 2}}, - {OSPFv3AREASPFRUNS, COUNTER, RONLY, ospfv3AreaEntry, - 4, {1, 2, 1, 3}}, - {OSPFv3AREABDRRTRCOUNT, GAUGE, RONLY, ospfv3AreaEntry, - 4, {1, 2, 1, 4}}, - {OSPFv3AREAASBDRRTRCOUNT, GAUGE, RONLY, ospfv3AreaEntry, - 4, {1, 2, 1, 5}}, - {OSPFv3AREASCOPELSACOUNT, GAUGE, RONLY, ospfv3AreaEntry, - 4, {1, 2, 1, 6}}, - {OSPFv3AREASCOPELSACKSUMSUM, UNSIGNED, RONLY, ospfv3AreaEntry, - 4, {1, 2, 1, 7}}, - {OSPFv3AREASUMMARY, INTEGER, RWRITE, ospfv3AreaEntry, - 4, {1, 2, 1, 8}}, - {OSPFv3AREAROWSTATUS, INTEGER, RWRITE, ospfv3AreaEntry, - 4, {1, 2, 1, 9}}, - {OSPFv3AREASTUBMETRIC, INTEGER, RWRITE, ospfv3AreaEntry, - 4, {1, 2, 1, 10}}, - {OSPFv3AREANSSATRANSLATORROLE, INTEGER, RWRITE, ospfv3AreaEntry, - 4, {1, 2, 1, 11}}, - {OSPFv3AREANSSATRANSLATORSTATE, INTEGER, RONLY, ospfv3AreaEntry, - 4, {1, 2, 1, 12}}, - {OSPFv3AREANSSATRANSLATORSTABINTERVAL, UNSIGNED, RWRITE, ospfv3AreaEntry, - 4, {1, 2, 1, 13}}, - {OSPFv3AREANSSATRANSLATOREVENTS, COUNTER, RONLY, ospfv3AreaEntry, - 4, {1, 2, 1, 14}}, - {OSPFv3AREASTUBMETRICTYPE, INTEGER, RWRITE, ospfv3AreaEntry, - 4, {1, 2, 1, 15}}, - {OSPFv3AREATEENABLED, INTEGER, RWRITE, ospfv3AreaEntry, - 4, {1, 2, 1, 16}}, - - /* OSPFv3 AS LSDB */ - {OSPFv3WWLSDBSEQUENCE | OSPFv3WWASTABLE, INTEGER, RONLY, ospfv3WwLsdbEntry, - 4, {1, 3, 1, 4}}, - {OSPFv3WWLSDBAGE | OSPFv3WWASTABLE, UNSIGNED, RONLY, ospfv3WwLsdbEntry, - 4, {1, 3, 1, 5}}, - {OSPFv3WWLSDBCHECKSUM | OSPFv3WWASTABLE, INTEGER, RONLY, ospfv3WwLsdbEntry, - 4, {1, 3, 1, 6}}, - {OSPFv3WWLSDBADVERTISEMENT | OSPFv3WWASTABLE, STRING, RONLY, ospfv3WwLsdbEntry, - 4, {1, 3, 1, 7}}, - {OSPFv3WWLSDBTYPEKNOWN | OSPFv3WWASTABLE, INTEGER, RONLY, ospfv3WwLsdbEntry, - 4, {1, 3, 1, 8}}, - - /* OSPFv3 Area LSDB */ - {OSPFv3WWLSDBSEQUENCE | OSPFv3WWAREATABLE, INTEGER, RONLY, ospfv3WwLsdbEntry, - 4, {1, 4, 1, 5}}, - {OSPFv3WWLSDBAGE | OSPFv3WWAREATABLE, UNSIGNED, RONLY, ospfv3WwLsdbEntry, - 4, {1, 4, 1, 6}}, - {OSPFv3WWLSDBCHECKSUM | OSPFv3WWAREATABLE, INTEGER, RONLY, ospfv3WwLsdbEntry, - 4, {1, 4, 1, 7}}, - {OSPFv3WWLSDBADVERTISEMENT | OSPFv3WWAREATABLE, STRING, RONLY, ospfv3WwLsdbEntry, - 4, {1, 4, 1, 8}}, - {OSPFv3WWLSDBTYPEKNOWN | OSPFv3WWAREATABLE, INTEGER, RONLY, ospfv3WwLsdbEntry, - 4, {1, 4, 1, 9}}, - - /* OSPFv3 Link LSDB */ - {OSPFv3WWLSDBSEQUENCE | OSPFv3WWLINKTABLE, INTEGER, RONLY, ospfv3WwLsdbEntry, - 4, {1, 5, 1, 6}}, - {OSPFv3WWLSDBAGE | OSPFv3WWLINKTABLE, UNSIGNED, RONLY, ospfv3WwLsdbEntry, - 4, {1, 5, 1, 7}}, - {OSPFv3WWLSDBCHECKSUM | OSPFv3WWLINKTABLE, INTEGER, RONLY, ospfv3WwLsdbEntry, - 4, {1, 5, 1, 8}}, - {OSPFv3WWLSDBADVERTISEMENT | OSPFv3WWLINKTABLE, STRING, RONLY, ospfv3WwLsdbEntry, - 4, {1, 5, 1, 9}}, - {OSPFv3WWLSDBTYPEKNOWN | OSPFv3WWLINKTABLE, INTEGER, RONLY, ospfv3WwLsdbEntry, - 4, {1, 5, 1, 10}}, - - /* OSPFv3 interfaces */ - {OSPFv3IFAREAID, UNSIGNED, RONLY, ospfv3IfEntry, - 4, {1, 7, 1, 3}}, - {OSPFv3IFTYPE, INTEGER, RONLY, ospfv3IfEntry, - 4, {1, 7, 1, 4}}, - {OSPFv3IFADMINSTATUS, INTEGER, RONLY, ospfv3IfEntry, - 4, {1, 7, 1, 5}}, - {OSPFv3IFRTRPRIORITY, INTEGER, RONLY, ospfv3IfEntry, - 4, {1, 7, 1, 6}}, - {OSPFv3IFTRANSITDELAY, UNSIGNED, RONLY, ospfv3IfEntry, - 4, {1, 7, 1, 7}}, - {OSPFv3IFRETRANSINTERVAL, UNSIGNED, RONLY, ospfv3IfEntry, - 4, {1, 7, 1, 8}}, - {OSPFv3IFHELLOINTERVAL, INTEGER, RONLY, ospfv3IfEntry, - 4, {1, 7, 1, 9}}, - {OSPFv3IFRTRDEADINTERVAL, UNSIGNED, RONLY, ospfv3IfEntry, - 4, {1, 7, 1, 10}}, - {OSPFv3IFPOLLINTERVAL, UNSIGNED, RONLY, ospfv3IfEntry, - 4, {1, 7, 1, 11}}, - {OSPFv3IFSTATE, INTEGER, RONLY, ospfv3IfEntry, - 4, {1, 7, 1, 12}}, - {OSPFv3IFDESIGNATEDROUTER, UNSIGNED, RONLY, ospfv3IfEntry, - 4, {1, 7, 1, 13}}, - {OSPFv3IFBACKUPDESIGNATEDROUTER, UNSIGNED, RONLY, ospfv3IfEntry, - 4, {1, 7, 1, 14}}, - {OSPFv3IFEVENTS, COUNTER, RONLY, ospfv3IfEntry, - 4, {1, 7, 1, 15}}, - {OSPFv3IFROWSTATUS, INTEGER, RONLY, ospfv3IfEntry, - 4, {1, 7, 1, 16}}, - {OSPFv3IFDEMAND, INTEGER, RONLY, ospfv3IfEntry, - 4, {1, 7, 1, 17}}, - {OSPFv3IFMETRICVALUE, INTEGER, RONLY, ospfv3IfEntry, - 4, {1, 7, 1, 18}}, - {OSPFv3IFLINKSCOPELSACOUNT, GAUGE, RONLY, ospfv3IfEntry, - 4, {1, 7, 1, 19}}, - {OSPFv3IFLINKLSACKSUMSUM, UNSIGNED, RONLY, ospfv3IfEntry, - 4, {1, 7, 1, 20}}, - {OSPFv3IFDEMANDNBRPROBE, INTEGER, RONLY, ospfv3IfEntry, - 4, {1, 7, 1, 21}}, - {OSPFv3IFDEMANDNBRPROBERETRANSLIMIT, UNSIGNED, RONLY, ospfv3IfEntry, - 4, {1, 7, 1, 22}}, - {OSPFv3IFDEMANDNBRPROBEINTERVAL, UNSIGNED, RONLY, ospfv3IfEntry, - 4, {1, 7, 1, 23}}, - {OSPFv3IFTEDISABLED, INTEGER, RONLY, ospfv3IfEntry, - 4, {1, 7, 1, 24}}, - {OSPFv3IFLINKLSASUPPRESSION, INTEGER, RONLY, ospfv3IfEntry, - 4, {1, 7, 1, 25}}, - - /* OSPFv3 neighbors */ - {OSPFv3NBRADDRESSTYPE, INTEGER, RONLY, ospfv3NbrEntry, - 4, {1, 9, 1, 4}}, - {OSPFv3NBRADDRESS, STRING, RONLY, ospfv3NbrEntry, - 4, {1, 9, 1, 5}}, - {OSPFv3NBROPTIONS, INTEGER, RONLY, ospfv3NbrEntry, - 4, {1, 9, 1, 6}}, - {OSPFv3NBRPRIORITY, INTEGER, RONLY, ospfv3NbrEntry, - 4, {1, 9, 1, 7}}, - {OSPFv3NBRSTATE, INTEGER, RONLY, ospfv3NbrEntry, - 4, {1, 9, 1, 8}}, - {OSPFv3NBREVENTS, COUNTER, RONLY, ospfv3NbrEntry, - 4, {1, 9, 1, 9}}, - {OSPFv3NBRLSRETRANSQLEN, GAUGE, RONLY, ospfv3NbrEntry, - 4, {1, 9, 1, 10}}, - {OSPFv3NBRHELLOSUPPRESSED, INTEGER, RONLY, ospfv3NbrEntry, - 4, {1, 9, 1, 11}}, - {OSPFv3NBRIFID, INTEGER, RONLY, ospfv3NbrEntry, - 4, {1, 9, 1, 12}}, - {OSPFv3NBRRESTARTHELPERSTATUS, INTEGER, RONLY, ospfv3NbrEntry, - 4, {1, 9, 1, 13}}, - {OSPFv3NBRRESTARTHELPERAGE, UNSIGNED, RONLY, ospfv3NbrEntry, - 4, {1, 9, 1, 14}}, - {OSPFv3NBRRESTARTHELPEREXITREASON, INTEGER, RONLY, ospfv3NbrEntry, - 4, {1, 9, 1, 15}}, +static u_char *ospfv3GeneralGroup(struct variable *, oid *, size_t *, int, + size_t *, WriteMethod **); +static u_char *ospfv3AreaEntry(struct variable *, oid *, size_t *, int, + size_t *, WriteMethod **); +static u_char *ospfv3WwLsdbEntry(struct variable *, oid *, size_t *, int, + size_t *, WriteMethod **); +static u_char *ospfv3NbrEntry(struct variable *, oid *, size_t *, int, size_t *, + WriteMethod **); +static u_char *ospfv3IfEntry(struct variable *, oid *, size_t *, int, size_t *, + WriteMethod **); + +static struct variable ospfv3_variables[] = { + /* OSPF general variables */ + {OSPFv3ROUTERID, UNSIGNED, RWRITE, ospfv3GeneralGroup, 3, {1, 1, 1}}, + {OSPFv3ADMINSTAT, INTEGER, RWRITE, ospfv3GeneralGroup, 3, {1, 1, 2}}, + {OSPFv3VERSIONNUMBER, INTEGER, RONLY, ospfv3GeneralGroup, 3, {1, 1, 3}}, + {OSPFv3AREABDRRTRSTATUS, + INTEGER, + RONLY, + ospfv3GeneralGroup, + 3, + {1, 1, 4}}, + {OSPFv3ASBDRRTRSTATUS, + INTEGER, + RWRITE, + ospfv3GeneralGroup, + 3, + {1, 1, 5}}, + {OSPFv3ASSCOPELSACOUNT, GAUGE, RONLY, ospfv3GeneralGroup, 3, {1, 1, 6}}, + {OSPFv3ASSCOPELSACHECKSUMSUM, + UNSIGNED, + RONLY, + ospfv3GeneralGroup, + 3, + {1, 1, 7}}, + {OSPFv3ORIGINATENEWLSAS, + COUNTER, + RONLY, + ospfv3GeneralGroup, + 3, + {1, 1, 8}}, + {OSPFv3RXNEWLSAS, COUNTER, RONLY, ospfv3GeneralGroup, 3, {1, 1, 9}}, + {OSPFv3EXTLSACOUNT, GAUGE, RONLY, ospfv3GeneralGroup, 3, {1, 1, 10}}, + {OSPFv3EXTAREALSDBLIMIT, + INTEGER, + RWRITE, + ospfv3GeneralGroup, + 3, + {1, 1, 11}}, + {OSPFv3EXITOVERFLOWINTERVAL, + UNSIGNED, + RWRITE, + ospfv3GeneralGroup, + 3, + {1, 1, 12}}, + {OSPFv3DEMANDEXTENSIONS, + INTEGER, + RWRITE, + ospfv3GeneralGroup, + 3, + {1, 1, 13}}, + {OSPFv3REFERENCEBANDWIDTH, + UNSIGNED, + RWRITE, + ospfv3GeneralGroup, + 3, + {1, 1, 14}}, + {OSPFv3RESTARTSUPPORT, + INTEGER, + RWRITE, + ospfv3GeneralGroup, + 3, + {1, 1, 15}}, + {OSPFv3RESTARTINTERVAL, + UNSIGNED, + RWRITE, + ospfv3GeneralGroup, + 3, + {1, 1, 16}}, + {OSPFv3RESTARTSTRICTLSACHECKING, + INTEGER, + RWRITE, + ospfv3GeneralGroup, + 3, + {1, 1, 17}}, + {OSPFv3RESTARTSTATUS, + INTEGER, + RONLY, + ospfv3GeneralGroup, + 3, + {1, 1, 18}}, + {OSPFv3RESTARTAGE, UNSIGNED, RONLY, ospfv3GeneralGroup, 3, {1, 1, 19}}, + {OSPFv3RESTARTEXITREASON, + INTEGER, + RONLY, + ospfv3GeneralGroup, + 3, + {1, 1, 20}}, + {OSPFv3NOTIFICATIONENABLE, + INTEGER, + RWRITE, + ospfv3GeneralGroup, + 3, + {1, 1, 21}}, + {OSPFv3STUBROUTERSUPPORT, + INTEGER, + RONLY, + ospfv3GeneralGroup, + 3, + {1, 1, 22}}, + {OSPFv3STUBROUTERADVERTISEMENT, + INTEGER, + RWRITE, + ospfv3GeneralGroup, + 3, + {1, 1, 23}}, + {OSPFv3DISCONTINUITYTIME, + TIMETICKS, + RONLY, + ospfv3GeneralGroup, + 3, + {1, 1, 24}}, + {OSPFv3RESTARTTIME, + TIMETICKS, + RONLY, + ospfv3GeneralGroup, + 3, + {1, 1, 25}}, + + /* OSPFv3 Area Data Structure */ + {OSPFv3IMPORTASEXTERN, + INTEGER, + RWRITE, + ospfv3AreaEntry, + 4, + {1, 2, 1, 2}}, + {OSPFv3AREASPFRUNS, COUNTER, RONLY, ospfv3AreaEntry, 4, {1, 2, 1, 3}}, + {OSPFv3AREABDRRTRCOUNT, GAUGE, RONLY, ospfv3AreaEntry, 4, {1, 2, 1, 4}}, + {OSPFv3AREAASBDRRTRCOUNT, + GAUGE, + RONLY, + ospfv3AreaEntry, + 4, + {1, 2, 1, 5}}, + {OSPFv3AREASCOPELSACOUNT, + GAUGE, + RONLY, + ospfv3AreaEntry, + 4, + {1, 2, 1, 6}}, + {OSPFv3AREASCOPELSACKSUMSUM, + UNSIGNED, + RONLY, + ospfv3AreaEntry, + 4, + {1, 2, 1, 7}}, + {OSPFv3AREASUMMARY, INTEGER, RWRITE, ospfv3AreaEntry, 4, {1, 2, 1, 8}}, + {OSPFv3AREAROWSTATUS, + INTEGER, + RWRITE, + ospfv3AreaEntry, + 4, + {1, 2, 1, 9}}, + {OSPFv3AREASTUBMETRIC, + INTEGER, + RWRITE, + ospfv3AreaEntry, + 4, + {1, 2, 1, 10}}, + {OSPFv3AREANSSATRANSLATORROLE, + INTEGER, + RWRITE, + ospfv3AreaEntry, + 4, + {1, 2, 1, 11}}, + {OSPFv3AREANSSATRANSLATORSTATE, + INTEGER, + RONLY, + ospfv3AreaEntry, + 4, + {1, 2, 1, 12}}, + {OSPFv3AREANSSATRANSLATORSTABINTERVAL, + UNSIGNED, + RWRITE, + ospfv3AreaEntry, + 4, + {1, 2, 1, 13}}, + {OSPFv3AREANSSATRANSLATOREVENTS, + COUNTER, + RONLY, + ospfv3AreaEntry, + 4, + {1, 2, 1, 14}}, + {OSPFv3AREASTUBMETRICTYPE, + INTEGER, + RWRITE, + ospfv3AreaEntry, + 4, + {1, 2, 1, 15}}, + {OSPFv3AREATEENABLED, + INTEGER, + RWRITE, + ospfv3AreaEntry, + 4, + {1, 2, 1, 16}}, + + /* OSPFv3 AS LSDB */ + {OSPFv3WWLSDBSEQUENCE | OSPFv3WWASTABLE, + INTEGER, + RONLY, + ospfv3WwLsdbEntry, + 4, + {1, 3, 1, 4}}, + {OSPFv3WWLSDBAGE | OSPFv3WWASTABLE, + UNSIGNED, + RONLY, + ospfv3WwLsdbEntry, + 4, + {1, 3, 1, 5}}, + {OSPFv3WWLSDBCHECKSUM | OSPFv3WWASTABLE, + INTEGER, + RONLY, + ospfv3WwLsdbEntry, + 4, + {1, 3, 1, 6}}, + {OSPFv3WWLSDBADVERTISEMENT | OSPFv3WWASTABLE, + STRING, + RONLY, + ospfv3WwLsdbEntry, + 4, + {1, 3, 1, 7}}, + {OSPFv3WWLSDBTYPEKNOWN | OSPFv3WWASTABLE, + INTEGER, + RONLY, + ospfv3WwLsdbEntry, + 4, + {1, 3, 1, 8}}, + + /* OSPFv3 Area LSDB */ + {OSPFv3WWLSDBSEQUENCE | OSPFv3WWAREATABLE, + INTEGER, + RONLY, + ospfv3WwLsdbEntry, + 4, + {1, 4, 1, 5}}, + {OSPFv3WWLSDBAGE | OSPFv3WWAREATABLE, + UNSIGNED, + RONLY, + ospfv3WwLsdbEntry, + 4, + {1, 4, 1, 6}}, + {OSPFv3WWLSDBCHECKSUM | OSPFv3WWAREATABLE, + INTEGER, + RONLY, + ospfv3WwLsdbEntry, + 4, + {1, 4, 1, 7}}, + {OSPFv3WWLSDBADVERTISEMENT | OSPFv3WWAREATABLE, + STRING, + RONLY, + ospfv3WwLsdbEntry, + 4, + {1, 4, 1, 8}}, + {OSPFv3WWLSDBTYPEKNOWN | OSPFv3WWAREATABLE, + INTEGER, + RONLY, + ospfv3WwLsdbEntry, + 4, + {1, 4, 1, 9}}, + + /* OSPFv3 Link LSDB */ + {OSPFv3WWLSDBSEQUENCE | OSPFv3WWLINKTABLE, + INTEGER, + RONLY, + ospfv3WwLsdbEntry, + 4, + {1, 5, 1, 6}}, + {OSPFv3WWLSDBAGE | OSPFv3WWLINKTABLE, + UNSIGNED, + RONLY, + ospfv3WwLsdbEntry, + 4, + {1, 5, 1, 7}}, + {OSPFv3WWLSDBCHECKSUM | OSPFv3WWLINKTABLE, + INTEGER, + RONLY, + ospfv3WwLsdbEntry, + 4, + {1, 5, 1, 8}}, + {OSPFv3WWLSDBADVERTISEMENT | OSPFv3WWLINKTABLE, + STRING, + RONLY, + ospfv3WwLsdbEntry, + 4, + {1, 5, 1, 9}}, + {OSPFv3WWLSDBTYPEKNOWN | OSPFv3WWLINKTABLE, + INTEGER, + RONLY, + ospfv3WwLsdbEntry, + 4, + {1, 5, 1, 10}}, + + /* OSPFv3 interfaces */ + {OSPFv3IFAREAID, UNSIGNED, RONLY, ospfv3IfEntry, 4, {1, 7, 1, 3}}, + {OSPFv3IFTYPE, INTEGER, RONLY, ospfv3IfEntry, 4, {1, 7, 1, 4}}, + {OSPFv3IFADMINSTATUS, INTEGER, RONLY, ospfv3IfEntry, 4, {1, 7, 1, 5}}, + {OSPFv3IFRTRPRIORITY, INTEGER, RONLY, ospfv3IfEntry, 4, {1, 7, 1, 6}}, + {OSPFv3IFTRANSITDELAY, UNSIGNED, RONLY, ospfv3IfEntry, 4, {1, 7, 1, 7}}, + {OSPFv3IFRETRANSINTERVAL, + UNSIGNED, + RONLY, + ospfv3IfEntry, + 4, + {1, 7, 1, 8}}, + {OSPFv3IFHELLOINTERVAL, INTEGER, RONLY, ospfv3IfEntry, 4, {1, 7, 1, 9}}, + {OSPFv3IFRTRDEADINTERVAL, + UNSIGNED, + RONLY, + ospfv3IfEntry, + 4, + {1, 7, 1, 10}}, + {OSPFv3IFPOLLINTERVAL, + UNSIGNED, + RONLY, + ospfv3IfEntry, + 4, + {1, 7, 1, 11}}, + {OSPFv3IFSTATE, INTEGER, RONLY, ospfv3IfEntry, 4, {1, 7, 1, 12}}, + {OSPFv3IFDESIGNATEDROUTER, + UNSIGNED, + RONLY, + ospfv3IfEntry, + 4, + {1, 7, 1, 13}}, + {OSPFv3IFBACKUPDESIGNATEDROUTER, + UNSIGNED, + RONLY, + ospfv3IfEntry, + 4, + {1, 7, 1, 14}}, + {OSPFv3IFEVENTS, COUNTER, RONLY, ospfv3IfEntry, 4, {1, 7, 1, 15}}, + {OSPFv3IFROWSTATUS, INTEGER, RONLY, ospfv3IfEntry, 4, {1, 7, 1, 16}}, + {OSPFv3IFDEMAND, INTEGER, RONLY, ospfv3IfEntry, 4, {1, 7, 1, 17}}, + {OSPFv3IFMETRICVALUE, INTEGER, RONLY, ospfv3IfEntry, 4, {1, 7, 1, 18}}, + {OSPFv3IFLINKSCOPELSACOUNT, + GAUGE, + RONLY, + ospfv3IfEntry, + 4, + {1, 7, 1, 19}}, + {OSPFv3IFLINKLSACKSUMSUM, + UNSIGNED, + RONLY, + ospfv3IfEntry, + 4, + {1, 7, 1, 20}}, + {OSPFv3IFDEMANDNBRPROBE, + INTEGER, + RONLY, + ospfv3IfEntry, + 4, + {1, 7, 1, 21}}, + {OSPFv3IFDEMANDNBRPROBERETRANSLIMIT, + UNSIGNED, + RONLY, + ospfv3IfEntry, + 4, + {1, 7, 1, 22}}, + {OSPFv3IFDEMANDNBRPROBEINTERVAL, + UNSIGNED, + RONLY, + ospfv3IfEntry, + 4, + {1, 7, 1, 23}}, + {OSPFv3IFTEDISABLED, INTEGER, RONLY, ospfv3IfEntry, 4, {1, 7, 1, 24}}, + {OSPFv3IFLINKLSASUPPRESSION, + INTEGER, + RONLY, + ospfv3IfEntry, + 4, + {1, 7, 1, 25}}, + + /* OSPFv3 neighbors */ + {OSPFv3NBRADDRESSTYPE, INTEGER, RONLY, ospfv3NbrEntry, 4, {1, 9, 1, 4}}, + {OSPFv3NBRADDRESS, STRING, RONLY, ospfv3NbrEntry, 4, {1, 9, 1, 5}}, + {OSPFv3NBROPTIONS, INTEGER, RONLY, ospfv3NbrEntry, 4, {1, 9, 1, 6}}, + {OSPFv3NBRPRIORITY, INTEGER, RONLY, ospfv3NbrEntry, 4, {1, 9, 1, 7}}, + {OSPFv3NBRSTATE, INTEGER, RONLY, ospfv3NbrEntry, 4, {1, 9, 1, 8}}, + {OSPFv3NBREVENTS, COUNTER, RONLY, ospfv3NbrEntry, 4, {1, 9, 1, 9}}, + {OSPFv3NBRLSRETRANSQLEN, + GAUGE, + RONLY, + ospfv3NbrEntry, + 4, + {1, 9, 1, 10}}, + {OSPFv3NBRHELLOSUPPRESSED, + INTEGER, + RONLY, + ospfv3NbrEntry, + 4, + {1, 9, 1, 11}}, + {OSPFv3NBRIFID, INTEGER, RONLY, ospfv3NbrEntry, 4, {1, 9, 1, 12}}, + {OSPFv3NBRRESTARTHELPERSTATUS, + INTEGER, + RONLY, + ospfv3NbrEntry, + 4, + {1, 9, 1, 13}}, + {OSPFv3NBRRESTARTHELPERAGE, + UNSIGNED, + RONLY, + ospfv3NbrEntry, + 4, + {1, 9, 1, 14}}, + {OSPFv3NBRRESTARTHELPEREXITREASON, + INTEGER, + RONLY, + ospfv3NbrEntry, + 4, + {1, 9, 1, 15}}, }; -static u_char * -ospfv3GeneralGroup (struct variable *v, oid *name, size_t *length, - int exact, size_t *var_len, WriteMethod **write_method) +static u_char *ospfv3GeneralGroup(struct variable *v, oid *name, size_t *length, + int exact, size_t *var_len, + WriteMethod **write_method) { - u_int16_t sum; - u_int32_t count; - struct ospf6_lsa *lsa = NULL; - - /* Check whether the instance identifier is valid */ - if (smux_header_generic (v, name, length, exact, var_len, write_method) - == MATCH_FAILED) - return NULL; - - /* Return the current value of the variable */ - switch (v->magic) - { - case OSPFv3ROUTERID: - /* Router-ID of this OSPF instance. */ - if (ospf6) - return SNMP_INTEGER (ntohl (ospf6->router_id)); - return SNMP_INTEGER (0); - case OSPFv3ADMINSTAT: - if (ospf6) - return SNMP_INTEGER (CHECK_FLAG (ospf6->flag, OSPF6_DISABLED)? - OSPF_STATUS_DISABLED:OSPF_STATUS_ENABLED); - return SNMP_INTEGER (OSPF_STATUS_DISABLED); - case OSPFv3VERSIONNUMBER: - return SNMP_INTEGER (3); - case OSPFv3AREABDRRTRSTATUS: - if (ospf6) - return SNMP_INTEGER (ospf6_is_router_abr (ospf6)?SNMP_TRUE:SNMP_FALSE); - return SNMP_INTEGER (SNMP_FALSE); - case OSPFv3ASBDRRTRSTATUS: - if (ospf6) - return SNMP_INTEGER (ospf6_asbr_is_asbr (ospf6)?SNMP_TRUE:SNMP_FALSE); - return SNMP_INTEGER (SNMP_FALSE); - case OSPFv3ASSCOPELSACOUNT: - if (ospf6) - return SNMP_INTEGER (ospf6->lsdb->count); - return SNMP_INTEGER (0); - case OSPFv3ASSCOPELSACHECKSUMSUM: - if (ospf6) - { - sum = 0; - for (ALL_LSDB(ospf6->lsdb, lsa)) - sum += ntohs (lsa->header->checksum); - return SNMP_INTEGER (sum); - } - return SNMP_INTEGER (0); - case OSPFv3ORIGINATENEWLSAS: - return SNMP_INTEGER (0); /* Don't know where to get this value... */ - case OSPFv3RXNEWLSAS: - return SNMP_INTEGER (0); /* Don't know where to get this value... */ - case OSPFv3EXTLSACOUNT: - if (ospf6) - { - count = 0; - for (ALL_LSDB_TYPED(ospf6->lsdb, htons (OSPF6_LSTYPE_AS_EXTERNAL), lsa)) - count += 1; - return SNMP_INTEGER (count); - } - return SNMP_INTEGER (0); - case OSPFv3EXTAREALSDBLIMIT: - return SNMP_INTEGER (-1); - case OSPFv3EXITOVERFLOWINTERVAL: - return SNMP_INTEGER (0); /* Not supported */ - case OSPFv3DEMANDEXTENSIONS: - return SNMP_INTEGER (0); /* Not supported */ - case OSPFv3REFERENCEBANDWIDTH: - if (ospf6) - return SNMP_INTEGER (ospf6->ref_bandwidth); - /* Otherwise, like for "not implemented". */ - /* fallthru */ - case OSPFv3RESTARTSUPPORT: - case OSPFv3RESTARTINTERVAL: - case OSPFv3RESTARTSTRICTLSACHECKING: - case OSPFv3RESTARTSTATUS: - case OSPFv3RESTARTAGE: - case OSPFv3RESTARTEXITREASON: - case OSPFv3NOTIFICATIONENABLE: - case OSPFv3STUBROUTERSUPPORT: - case OSPFv3STUBROUTERADVERTISEMENT: - case OSPFv3DISCONTINUITYTIME: - case OSPFv3RESTARTTIME: - /* TODO: Not implemented */ - return NULL; - } - return NULL; + u_int16_t sum; + u_int32_t count; + struct ospf6_lsa *lsa = NULL; + + /* Check whether the instance identifier is valid */ + if (smux_header_generic(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + + /* Return the current value of the variable */ + switch (v->magic) { + case OSPFv3ROUTERID: + /* Router-ID of this OSPF instance. */ + if (ospf6) + return SNMP_INTEGER(ntohl(ospf6->router_id)); + return SNMP_INTEGER(0); + case OSPFv3ADMINSTAT: + if (ospf6) + return SNMP_INTEGER( + CHECK_FLAG(ospf6->flag, OSPF6_DISABLED) + ? OSPF_STATUS_DISABLED + : OSPF_STATUS_ENABLED); + return SNMP_INTEGER(OSPF_STATUS_DISABLED); + case OSPFv3VERSIONNUMBER: + return SNMP_INTEGER(3); + case OSPFv3AREABDRRTRSTATUS: + if (ospf6) + return SNMP_INTEGER(ospf6_is_router_abr(ospf6) + ? SNMP_TRUE + : SNMP_FALSE); + return SNMP_INTEGER(SNMP_FALSE); + case OSPFv3ASBDRRTRSTATUS: + if (ospf6) + return SNMP_INTEGER(ospf6_asbr_is_asbr(ospf6) + ? SNMP_TRUE + : SNMP_FALSE); + return SNMP_INTEGER(SNMP_FALSE); + case OSPFv3ASSCOPELSACOUNT: + if (ospf6) + return SNMP_INTEGER(ospf6->lsdb->count); + return SNMP_INTEGER(0); + case OSPFv3ASSCOPELSACHECKSUMSUM: + if (ospf6) { + sum = 0; + for (ALL_LSDB(ospf6->lsdb, lsa)) + sum += ntohs(lsa->header->checksum); + return SNMP_INTEGER(sum); + } + return SNMP_INTEGER(0); + case OSPFv3ORIGINATENEWLSAS: + return SNMP_INTEGER( + 0); /* Don't know where to get this value... */ + case OSPFv3RXNEWLSAS: + return SNMP_INTEGER( + 0); /* Don't know where to get this value... */ + case OSPFv3EXTLSACOUNT: + if (ospf6) { + count = 0; + for (ALL_LSDB_TYPED(ospf6->lsdb, + htons(OSPF6_LSTYPE_AS_EXTERNAL), + lsa)) + count += 1; + return SNMP_INTEGER(count); + } + return SNMP_INTEGER(0); + case OSPFv3EXTAREALSDBLIMIT: + return SNMP_INTEGER(-1); + case OSPFv3EXITOVERFLOWINTERVAL: + return SNMP_INTEGER(0); /* Not supported */ + case OSPFv3DEMANDEXTENSIONS: + return SNMP_INTEGER(0); /* Not supported */ + case OSPFv3REFERENCEBANDWIDTH: + if (ospf6) + return SNMP_INTEGER(ospf6->ref_bandwidth); + /* Otherwise, like for "not implemented". */ + /* fallthru */ + case OSPFv3RESTARTSUPPORT: + case OSPFv3RESTARTINTERVAL: + case OSPFv3RESTARTSTRICTLSACHECKING: + case OSPFv3RESTARTSTATUS: + case OSPFv3RESTARTAGE: + case OSPFv3RESTARTEXITREASON: + case OSPFv3NOTIFICATIONENABLE: + case OSPFv3STUBROUTERSUPPORT: + case OSPFv3STUBROUTERADVERTISEMENT: + case OSPFv3DISCONTINUITYTIME: + case OSPFv3RESTARTTIME: + /* TODO: Not implemented */ + return NULL; + } + return NULL; } -static u_char * -ospfv3AreaEntry (struct variable *v, oid *name, size_t *length, - int exact, size_t *var_len, WriteMethod **write_method) +static u_char *ospfv3AreaEntry(struct variable *v, oid *name, size_t *length, + int exact, size_t *var_len, + WriteMethod **write_method) { - struct ospf6_area *oa, *area = NULL; - struct ospf6_lsa *lsa = NULL; - u_int32_t area_id = 0; - u_int32_t count; - u_int16_t sum; - struct listnode *node; - unsigned int len; - char a[16]; - struct ospf6_route *ro; - - if (ospf6 == NULL) - return NULL; - - if (smux_header_table(v, name, length, exact, var_len, write_method) - == MATCH_FAILED) - return NULL; - - len = *length - v->namelen; - len = (len >= 1 ? 1 : 0); - if (exact && len != 1) - return NULL; - if (len) - area_id = htonl (name[v->namelen]); - - inet_ntop (AF_INET, &area_id, a, sizeof (a)); - zlog_debug ("SNMP access by area: %s, exact=%d len=%d length=%lu", - a, exact, len, (u_long)*length); - - for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa)) - { - if (area == NULL) - { - if (len == 0) /* return first area entry */ - area = oa; - else if (exact && ntohl (oa->area_id) == ntohl (area_id)) - area = oa; - else if (ntohl (oa->area_id) > ntohl (area_id)) - area = oa; - } - } - - if (area == NULL) - return NULL; - - *length = v->namelen + 1; - name[v->namelen] = ntohl (area->area_id); - - inet_ntop (AF_INET, &area->area_id, a, sizeof (a)); - zlog_debug ("SNMP found area: %s, exact=%d len=%d length=%lu", - a, exact, len, (u_long)*length); - - switch (v->magic) - { - case OSPFv3IMPORTASEXTERN: - /* No NSSA support */ - return SNMP_INTEGER (IS_AREA_STUB(area)?2:1); - case OSPFv3AREASPFRUNS: - return SNMP_INTEGER (area->spf_calculation); - case OSPFv3AREABDRRTRCOUNT: - case OSPFv3AREAASBDRRTRCOUNT: - count = 0; - for (ro = ospf6_route_head (ospf6->brouter_table); ro; - ro = ospf6_route_next (ro)) - { - if (ntohl (ro->path.area_id) != ntohl (area->area_id)) continue; - if (v->magic == OSPFv3AREABDRRTRCOUNT && - CHECK_FLAG (ro->path.router_bits, OSPF6_ROUTER_BIT_B)) - count++; - if (v->magic == OSPFv3AREAASBDRRTRCOUNT && - CHECK_FLAG (ro->path.router_bits, OSPF6_ROUTER_BIT_E)) - count++; - } - return SNMP_INTEGER (count); - case OSPFv3AREASCOPELSACOUNT: - return SNMP_INTEGER (area->lsdb->count); - case OSPFv3AREASCOPELSACKSUMSUM: - sum = 0; - for (ALL_LSDB(area->lsdb, lsa)) - sum += ntohs (lsa->header->checksum); - return SNMP_INTEGER (sum); - case OSPFv3AREASUMMARY: - return SNMP_INTEGER (2); /* sendAreaSummary */ - case OSPFv3AREAROWSTATUS: - return SNMP_INTEGER (1); /* Active */ - case OSPFv3AREASTUBMETRIC: - case OSPFv3AREANSSATRANSLATORROLE: - case OSPFv3AREANSSATRANSLATORSTATE: - case OSPFv3AREANSSATRANSLATORSTABINTERVAL: - case OSPFv3AREANSSATRANSLATOREVENTS: - case OSPFv3AREASTUBMETRICTYPE: - case OSPFv3AREATEENABLED: - /* Not implemented. */ - return NULL; - } - return NULL; + struct ospf6_area *oa, *area = NULL; + struct ospf6_lsa *lsa = NULL; + u_int32_t area_id = 0; + u_int32_t count; + u_int16_t sum; + struct listnode *node; + unsigned int len; + char a[16]; + struct ospf6_route *ro; + + if (ospf6 == NULL) + return NULL; + + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + + len = *length - v->namelen; + len = (len >= 1 ? 1 : 0); + if (exact && len != 1) + return NULL; + if (len) + area_id = htonl(name[v->namelen]); + + inet_ntop(AF_INET, &area_id, a, sizeof(a)); + zlog_debug("SNMP access by area: %s, exact=%d len=%d length=%lu", a, + exact, len, (u_long)*length); + + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) { + if (area == NULL) { + if (len == 0) /* return first area entry */ + area = oa; + else if (exact && ntohl(oa->area_id) == ntohl(area_id)) + area = oa; + else if (ntohl(oa->area_id) > ntohl(area_id)) + area = oa; + } + } + + if (area == NULL) + return NULL; + + *length = v->namelen + 1; + name[v->namelen] = ntohl(area->area_id); + + inet_ntop(AF_INET, &area->area_id, a, sizeof(a)); + zlog_debug("SNMP found area: %s, exact=%d len=%d length=%lu", a, exact, + len, (u_long)*length); + + switch (v->magic) { + case OSPFv3IMPORTASEXTERN: + /* No NSSA support */ + return SNMP_INTEGER(IS_AREA_STUB(area) ? 2 : 1); + case OSPFv3AREASPFRUNS: + return SNMP_INTEGER(area->spf_calculation); + case OSPFv3AREABDRRTRCOUNT: + case OSPFv3AREAASBDRRTRCOUNT: + count = 0; + for (ro = ospf6_route_head(ospf6->brouter_table); ro; + ro = ospf6_route_next(ro)) { + if (ntohl(ro->path.area_id) != ntohl(area->area_id)) + continue; + if (v->magic == OSPFv3AREABDRRTRCOUNT + && CHECK_FLAG(ro->path.router_bits, + OSPF6_ROUTER_BIT_B)) + count++; + if (v->magic == OSPFv3AREAASBDRRTRCOUNT + && CHECK_FLAG(ro->path.router_bits, + OSPF6_ROUTER_BIT_E)) + count++; + } + return SNMP_INTEGER(count); + case OSPFv3AREASCOPELSACOUNT: + return SNMP_INTEGER(area->lsdb->count); + case OSPFv3AREASCOPELSACKSUMSUM: + sum = 0; + for (ALL_LSDB(area->lsdb, lsa)) + sum += ntohs(lsa->header->checksum); + return SNMP_INTEGER(sum); + case OSPFv3AREASUMMARY: + return SNMP_INTEGER(2); /* sendAreaSummary */ + case OSPFv3AREAROWSTATUS: + return SNMP_INTEGER(1); /* Active */ + case OSPFv3AREASTUBMETRIC: + case OSPFv3AREANSSATRANSLATORROLE: + case OSPFv3AREANSSATRANSLATORSTATE: + case OSPFv3AREANSSATRANSLATORSTABINTERVAL: + case OSPFv3AREANSSATRANSLATOREVENTS: + case OSPFv3AREASTUBMETRICTYPE: + case OSPFv3AREATEENABLED: + /* Not implemented. */ + return NULL; + } + return NULL; } -static int -if_icmp_func (struct interface *ifp1, struct interface *ifp2) +static int if_icmp_func(struct interface *ifp1, struct interface *ifp2) { - return (ifp1->ifindex - ifp2->ifindex); + return (ifp1->ifindex - ifp2->ifindex); } -static u_char * -ospfv3WwLsdbEntry (struct variable *v, oid *name, size_t *length, - int exact, size_t *var_len, WriteMethod **write_method) +static u_char *ospfv3WwLsdbEntry(struct variable *v, oid *name, size_t *length, + int exact, size_t *var_len, + WriteMethod **write_method) { - struct ospf6_lsa *lsa = NULL; - ifindex_t ifindex; - uint32_t area_id, id, instid, adv_router; - u_int16_t type; - int len; - oid *offset; - int offsetlen; - struct ospf6_area *oa = NULL; - struct listnode *node; - struct interface *iif; - struct ospf6_interface *oi = NULL; - struct list *ifslist; - - if (smux_header_table(v, name, length, exact, var_len, write_method) - == MATCH_FAILED) - return NULL; - - instid = ifindex = area_id = type = id = adv_router = 0; - - /* Check OSPFv3 instance. */ - if (ospf6 == NULL) - return NULL; - - /* Get variable length. */ - offset = name + v->namelen; - offsetlen = *length - v->namelen; - - if (exact && (v->magic & OSPFv3WWASTABLE) && offsetlen != 3) - return NULL; - if (exact && (v->magic & OSPFv3WWAREATABLE) && offsetlen != 4) - return NULL; - if (exact && (v->magic & OSPFv3WWLINKTABLE) && offsetlen != 5) - return NULL; - - if (v->magic & OSPFv3WWLINKTABLE) - { - /* Parse ifindex */ - len = (offsetlen < 1 ? 0 : 1); - if (len) - ifindex = *offset; - offset += len; - offsetlen -= len; - - /* Parse instance ID */ - len = (offsetlen < 1 ? 0 : 1); - if (len) - instid = *offset; - offset += len; - offsetlen -= len; - } - else if (v->magic & OSPFv3WWAREATABLE) - { - /* Parse area-id */ - len = (offsetlen < 1 ? 0 : 1); - if (len) - area_id = htonl (*offset); - offset += len; - offsetlen -= len; - } - - /* Parse type */ - len = (offsetlen < 1 ? 0 : 1); - if (len) - type = htons (*offset); - offset += len; - offsetlen -= len; - - /* Parse Router-ID */ - len = (offsetlen < 1 ? 0 : 1); - if (len) - adv_router = htonl (*offset); - offset += len; - offsetlen -= len; - - /* Parse LS-ID */ - len = (offsetlen < 1 ? 0 : 1); - if (len) - id = htonl (*offset); - offset += len; - offsetlen -= len; - - if (exact) - { - if (v->magic & OSPFv3WWASTABLE) - { - lsa = ospf6_lsdb_lookup (type, id, adv_router, ospf6->lsdb); - } - else if (v->magic & OSPFv3WWAREATABLE) - { - oa = ospf6_area_lookup (area_id, ospf6); - if (!oa) return NULL; - lsa = ospf6_lsdb_lookup (type, id, adv_router, oa->lsdb); - } - else if (v->magic & OSPFv3WWLINKTABLE) - { - oi = ospf6_interface_lookup_by_ifindex (ifindex); - if (!oi || oi->instance_id != instid) return NULL; - lsa = ospf6_lsdb_lookup (type, id, adv_router, oi->lsdb); - } - } - else - { - if (v->magic & OSPFv3WWASTABLE) - { - if (ospf6->lsdb->count) - lsa = ospf6_lsdb_lookup_next (type, id, adv_router, - ospf6->lsdb); + struct ospf6_lsa *lsa = NULL; + ifindex_t ifindex; + uint32_t area_id, id, instid, adv_router; + u_int16_t type; + int len; + oid *offset; + int offsetlen; + struct ospf6_area *oa = NULL; + struct listnode *node; + struct interface *iif; + struct ospf6_interface *oi = NULL; + struct list *ifslist; + + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + + instid = ifindex = area_id = type = id = adv_router = 0; + + /* Check OSPFv3 instance. */ + if (ospf6 == NULL) + return NULL; + + /* Get variable length. */ + offset = name + v->namelen; + offsetlen = *length - v->namelen; + + if (exact && (v->magic & OSPFv3WWASTABLE) && offsetlen != 3) + return NULL; + if (exact && (v->magic & OSPFv3WWAREATABLE) && offsetlen != 4) + return NULL; + if (exact && (v->magic & OSPFv3WWLINKTABLE) && offsetlen != 5) + return NULL; + + if (v->magic & OSPFv3WWLINKTABLE) { + /* Parse ifindex */ + len = (offsetlen < 1 ? 0 : 1); + if (len) + ifindex = *offset; + offset += len; + offsetlen -= len; + + /* Parse instance ID */ + len = (offsetlen < 1 ? 0 : 1); + if (len) + instid = *offset; + offset += len; + offsetlen -= len; + } else if (v->magic & OSPFv3WWAREATABLE) { + /* Parse area-id */ + len = (offsetlen < 1 ? 0 : 1); + if (len) + area_id = htonl(*offset); + offset += len; + offsetlen -= len; } - else if (v->magic & OSPFv3WWAREATABLE) - for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa)) - { - if (oa->area_id < area_id) - continue; - - if (oa->lsdb->count) - lsa = ospf6_lsdb_lookup_next (type, id, adv_router, - oa->lsdb); - if (lsa) break; - type = 0; - id = 0; - adv_router = 0; - } - else if (v->magic & OSPFv3WWLINKTABLE) - { - /* We build a sorted list of interfaces */ - ifslist = list_new (); - if (!ifslist) return NULL; - ifslist->cmp = (int (*)(void *, void *))if_icmp_func; - for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, iif)) - listnode_add_sort (ifslist, iif); - - for (ALL_LIST_ELEMENTS_RO (ifslist, node, iif)) - { - if (!iif->ifindex) continue; - oi = ospf6_interface_lookup_by_ifindex (iif->ifindex); - if (!oi) continue; - if (iif->ifindex < ifindex) continue; - if (oi->instance_id < instid) continue; - - if (oi->lsdb->count) - lsa = ospf6_lsdb_lookup_next (type, id, adv_router, - oi->lsdb); - if (lsa) break; - type = 0; - id = 0; - adv_router = 0; - oi = NULL; - } - - list_delete_all_node (ifslist); - } - } - - if (! lsa) - return NULL; - - /* Add indexes */ - if (v->magic & OSPFv3WWASTABLE) - { - *length = v->namelen + 3; - offset = name + v->namelen; - } - else if (v->magic & OSPFv3WWAREATABLE) - { - *length = v->namelen + 4; - offset = name + v->namelen; - *offset = ntohl (oa->area_id); - offset++; - } - else if (v->magic & OSPFv3WWLINKTABLE) - { - *length = v->namelen + 5; - offset = name + v->namelen; - *offset = oi->interface->ifindex; - offset++; - *offset = oi->instance_id; - offset++; - } - *offset = ntohs (lsa->header->type); - offset++; - *offset = ntohl (lsa->header->adv_router); - offset++; - *offset = ntohl (lsa->header->id); - offset++; - - /* Return the current value of the variable */ - switch (v->magic & OSPFv3WWCOLUMN) - { - case OSPFv3WWLSDBSEQUENCE: - return SNMP_INTEGER (ntohl (lsa->header->seqnum)); - break; - case OSPFv3WWLSDBAGE: - ospf6_lsa_age_current (lsa); - return SNMP_INTEGER (ntohs (lsa->header->age)); - break; - case OSPFv3WWLSDBCHECKSUM: - return SNMP_INTEGER (ntohs (lsa->header->checksum)); - break; - case OSPFv3WWLSDBADVERTISEMENT: - *var_len = ntohs (lsa->header->length); - return (u_char *) lsa->header; - break; - case OSPFv3WWLSDBTYPEKNOWN: - return SNMP_INTEGER (OSPF6_LSA_IS_KNOWN (lsa->header->type) ? - SNMP_TRUE : SNMP_FALSE); - break; - } - return NULL; + + /* Parse type */ + len = (offsetlen < 1 ? 0 : 1); + if (len) + type = htons(*offset); + offset += len; + offsetlen -= len; + + /* Parse Router-ID */ + len = (offsetlen < 1 ? 0 : 1); + if (len) + adv_router = htonl(*offset); + offset += len; + offsetlen -= len; + + /* Parse LS-ID */ + len = (offsetlen < 1 ? 0 : 1); + if (len) + id = htonl(*offset); + offset += len; + offsetlen -= len; + + if (exact) { + if (v->magic & OSPFv3WWASTABLE) { + lsa = ospf6_lsdb_lookup(type, id, adv_router, + ospf6->lsdb); + } else if (v->magic & OSPFv3WWAREATABLE) { + oa = ospf6_area_lookup(area_id, ospf6); + if (!oa) + return NULL; + lsa = ospf6_lsdb_lookup(type, id, adv_router, oa->lsdb); + } else if (v->magic & OSPFv3WWLINKTABLE) { + oi = ospf6_interface_lookup_by_ifindex(ifindex); + if (!oi || oi->instance_id != instid) + return NULL; + lsa = ospf6_lsdb_lookup(type, id, adv_router, oi->lsdb); + } + } else { + if (v->magic & OSPFv3WWASTABLE) { + if (ospf6->lsdb->count) + lsa = ospf6_lsdb_lookup_next( + type, id, adv_router, ospf6->lsdb); + } else if (v->magic & OSPFv3WWAREATABLE) + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) { + if (oa->area_id < area_id) + continue; + + if (oa->lsdb->count) + lsa = ospf6_lsdb_lookup_next( + type, id, adv_router, oa->lsdb); + if (lsa) + break; + type = 0; + id = 0; + adv_router = 0; + } + else if (v->magic & OSPFv3WWLINKTABLE) { + /* We build a sorted list of interfaces */ + ifslist = list_new(); + if (!ifslist) + return NULL; + ifslist->cmp = (int (*)(void *, void *))if_icmp_func; + for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, + iif)) + listnode_add_sort(ifslist, iif); + + for (ALL_LIST_ELEMENTS_RO(ifslist, node, iif)) { + if (!iif->ifindex) + continue; + oi = ospf6_interface_lookup_by_ifindex( + iif->ifindex); + if (!oi) + continue; + if (iif->ifindex < ifindex) + continue; + if (oi->instance_id < instid) + continue; + + if (oi->lsdb->count) + lsa = ospf6_lsdb_lookup_next( + type, id, adv_router, oi->lsdb); + if (lsa) + break; + type = 0; + id = 0; + adv_router = 0; + oi = NULL; + } + + list_delete_all_node(ifslist); + } + } + + if (!lsa) + return NULL; + + /* Add indexes */ + if (v->magic & OSPFv3WWASTABLE) { + *length = v->namelen + 3; + offset = name + v->namelen; + } else if (v->magic & OSPFv3WWAREATABLE) { + *length = v->namelen + 4; + offset = name + v->namelen; + *offset = ntohl(oa->area_id); + offset++; + } else if (v->magic & OSPFv3WWLINKTABLE) { + *length = v->namelen + 5; + offset = name + v->namelen; + *offset = oi->interface->ifindex; + offset++; + *offset = oi->instance_id; + offset++; + } + *offset = ntohs(lsa->header->type); + offset++; + *offset = ntohl(lsa->header->adv_router); + offset++; + *offset = ntohl(lsa->header->id); + offset++; + + /* Return the current value of the variable */ + switch (v->magic & OSPFv3WWCOLUMN) { + case OSPFv3WWLSDBSEQUENCE: + return SNMP_INTEGER(ntohl(lsa->header->seqnum)); + break; + case OSPFv3WWLSDBAGE: + ospf6_lsa_age_current(lsa); + return SNMP_INTEGER(ntohs(lsa->header->age)); + break; + case OSPFv3WWLSDBCHECKSUM: + return SNMP_INTEGER(ntohs(lsa->header->checksum)); + break; + case OSPFv3WWLSDBADVERTISEMENT: + *var_len = ntohs(lsa->header->length); + return (u_char *)lsa->header; + break; + case OSPFv3WWLSDBTYPEKNOWN: + return SNMP_INTEGER(OSPF6_LSA_IS_KNOWN(lsa->header->type) + ? SNMP_TRUE + : SNMP_FALSE); + break; + } + return NULL; } -static u_char * -ospfv3IfEntry (struct variable *v, oid *name, size_t *length, - int exact, size_t *var_len, WriteMethod **write_method) +static u_char *ospfv3IfEntry(struct variable *v, oid *name, size_t *length, + int exact, size_t *var_len, + WriteMethod **write_method) { - ifindex_t ifindex = 0; - unsigned int instid = 0; - struct ospf6_interface *oi = NULL; - struct ospf6_lsa *lsa = NULL; - struct interface *iif; - struct listnode *i; - struct list *ifslist; - oid *offset; - int offsetlen, len; - u_int32_t sum; - - if (smux_header_table (v, name, length, exact, var_len, write_method) - == MATCH_FAILED) - return NULL; - - /* Check OSPFv3 instance. */ - if (ospf6 == NULL) - return NULL; - - /* Get variable length. */ - offset = name + v->namelen; - offsetlen = *length - v->namelen; - - if (exact && offsetlen != 2) - return NULL; - - /* Parse if index */ - len = (offsetlen < 1 ? 0 : 1); - if (len) - ifindex = *offset; - offset += len; - offsetlen -= len; - - /* Parse instance ID */ - len = (offsetlen < 1 ? 0 : 1); - if (len) - instid = *offset; - offset += len; - offsetlen -= len; - - if (exact) - { - oi = ospf6_interface_lookup_by_ifindex (ifindex); - if (!oi || oi->instance_id != instid) return NULL; - } - else - { - /* We build a sorted list of interfaces */ - ifslist = list_new (); - if (!ifslist) return NULL; - ifslist->cmp = (int (*)(void *, void *))if_icmp_func; - for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), i, iif)) - listnode_add_sort (ifslist, iif); - - for (ALL_LIST_ELEMENTS_RO (ifslist, i, iif)) - { - if (!iif->ifindex) continue; - oi = ospf6_interface_lookup_by_ifindex (iif->ifindex); - if (!oi) continue; - if (iif->ifindex > ifindex || - (iif->ifindex == ifindex && - (oi->instance_id > instid))) - break; - oi = NULL; - } - - list_delete_all_node (ifslist); - } - - if (!oi) return NULL; - - /* Add Index (IfIndex, IfInstId) */ - *length = v->namelen + 2; - offset = name + v->namelen; - *offset = oi->interface->ifindex; - offset++; - *offset = oi->instance_id; - offset++; - - /* Return the current value of the variable */ - switch (v->magic) - { - case OSPFv3IFAREAID: - if (oi->area) - return SNMP_INTEGER (ntohl (oi->area->area_id)); - break; - case OSPFv3IFTYPE: - if (if_is_broadcast (oi->interface)) - return SNMP_INTEGER (1); - else if (if_is_pointopoint (oi->interface)) - return SNMP_INTEGER (3); - else break; /* Unknown, don't put anything */ - case OSPFv3IFADMINSTATUS: - if (oi->area) - return SNMP_INTEGER (OSPF_STATUS_ENABLED); - return SNMP_INTEGER (OSPF_STATUS_DISABLED); - case OSPFv3IFRTRPRIORITY: - return SNMP_INTEGER (oi->priority); - case OSPFv3IFTRANSITDELAY: - return SNMP_INTEGER (oi->transdelay); - case OSPFv3IFRETRANSINTERVAL: - return SNMP_INTEGER (oi->rxmt_interval); - case OSPFv3IFHELLOINTERVAL: - return SNMP_INTEGER (oi->hello_interval); - case OSPFv3IFRTRDEADINTERVAL: - return SNMP_INTEGER (oi->dead_interval); - case OSPFv3IFPOLLINTERVAL: - /* No support for NBMA */ - break; - case OSPFv3IFSTATE: - return SNMP_INTEGER (oi->state); - case OSPFv3IFDESIGNATEDROUTER: - return SNMP_INTEGER (ntohl (oi->drouter)); - case OSPFv3IFBACKUPDESIGNATEDROUTER: - return SNMP_INTEGER (ntohl (oi->bdrouter)); - case OSPFv3IFEVENTS: - return SNMP_INTEGER (oi->state_change); - case OSPFv3IFROWSTATUS: - return SNMP_INTEGER (1); - case OSPFv3IFDEMAND: - return SNMP_INTEGER (SNMP_FALSE); - case OSPFv3IFMETRICVALUE: - return SNMP_INTEGER (oi->cost); - case OSPFv3IFLINKSCOPELSACOUNT: - return SNMP_INTEGER (oi->lsdb->count); - case OSPFv3IFLINKLSACKSUMSUM: - sum = 0; - for (ALL_LSDB(oi->lsdb, lsa)) - sum += ntohs (lsa->header->checksum); - return SNMP_INTEGER (sum); - case OSPFv3IFDEMANDNBRPROBE: - case OSPFv3IFDEMANDNBRPROBERETRANSLIMIT: - case OSPFv3IFDEMANDNBRPROBEINTERVAL: - case OSPFv3IFTEDISABLED: - case OSPFv3IFLINKLSASUPPRESSION: - /* Not implemented. Only works if all the last ones are not - implemented! */ - return NULL; - } - - /* Try an internal getnext. Some columns are missing in this table. */ - if (!exact && (name[*length-1] < MAX_SUBID)) - return ospfv3IfEntry(v, name, length, - exact, var_len, write_method); - return NULL; + ifindex_t ifindex = 0; + unsigned int instid = 0; + struct ospf6_interface *oi = NULL; + struct ospf6_lsa *lsa = NULL; + struct interface *iif; + struct listnode *i; + struct list *ifslist; + oid *offset; + int offsetlen, len; + u_int32_t sum; + + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + + /* Check OSPFv3 instance. */ + if (ospf6 == NULL) + return NULL; + + /* Get variable length. */ + offset = name + v->namelen; + offsetlen = *length - v->namelen; + + if (exact && offsetlen != 2) + return NULL; + + /* Parse if index */ + len = (offsetlen < 1 ? 0 : 1); + if (len) + ifindex = *offset; + offset += len; + offsetlen -= len; + + /* Parse instance ID */ + len = (offsetlen < 1 ? 0 : 1); + if (len) + instid = *offset; + offset += len; + offsetlen -= len; + + if (exact) { + oi = ospf6_interface_lookup_by_ifindex(ifindex); + if (!oi || oi->instance_id != instid) + return NULL; + } else { + /* We build a sorted list of interfaces */ + ifslist = list_new(); + if (!ifslist) + return NULL; + ifslist->cmp = (int (*)(void *, void *))if_icmp_func; + for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), i, iif)) + listnode_add_sort(ifslist, iif); + + for (ALL_LIST_ELEMENTS_RO(ifslist, i, iif)) { + if (!iif->ifindex) + continue; + oi = ospf6_interface_lookup_by_ifindex(iif->ifindex); + if (!oi) + continue; + if (iif->ifindex > ifindex + || (iif->ifindex == ifindex + && (oi->instance_id > instid))) + break; + oi = NULL; + } + + list_delete_all_node(ifslist); + } + + if (!oi) + return NULL; + + /* Add Index (IfIndex, IfInstId) */ + *length = v->namelen + 2; + offset = name + v->namelen; + *offset = oi->interface->ifindex; + offset++; + *offset = oi->instance_id; + offset++; + + /* Return the current value of the variable */ + switch (v->magic) { + case OSPFv3IFAREAID: + if (oi->area) + return SNMP_INTEGER(ntohl(oi->area->area_id)); + break; + case OSPFv3IFTYPE: + if (if_is_broadcast(oi->interface)) + return SNMP_INTEGER(1); + else if (if_is_pointopoint(oi->interface)) + return SNMP_INTEGER(3); + else + break; /* Unknown, don't put anything */ + case OSPFv3IFADMINSTATUS: + if (oi->area) + return SNMP_INTEGER(OSPF_STATUS_ENABLED); + return SNMP_INTEGER(OSPF_STATUS_DISABLED); + case OSPFv3IFRTRPRIORITY: + return SNMP_INTEGER(oi->priority); + case OSPFv3IFTRANSITDELAY: + return SNMP_INTEGER(oi->transdelay); + case OSPFv3IFRETRANSINTERVAL: + return SNMP_INTEGER(oi->rxmt_interval); + case OSPFv3IFHELLOINTERVAL: + return SNMP_INTEGER(oi->hello_interval); + case OSPFv3IFRTRDEADINTERVAL: + return SNMP_INTEGER(oi->dead_interval); + case OSPFv3IFPOLLINTERVAL: + /* No support for NBMA */ + break; + case OSPFv3IFSTATE: + return SNMP_INTEGER(oi->state); + case OSPFv3IFDESIGNATEDROUTER: + return SNMP_INTEGER(ntohl(oi->drouter)); + case OSPFv3IFBACKUPDESIGNATEDROUTER: + return SNMP_INTEGER(ntohl(oi->bdrouter)); + case OSPFv3IFEVENTS: + return SNMP_INTEGER(oi->state_change); + case OSPFv3IFROWSTATUS: + return SNMP_INTEGER(1); + case OSPFv3IFDEMAND: + return SNMP_INTEGER(SNMP_FALSE); + case OSPFv3IFMETRICVALUE: + return SNMP_INTEGER(oi->cost); + case OSPFv3IFLINKSCOPELSACOUNT: + return SNMP_INTEGER(oi->lsdb->count); + case OSPFv3IFLINKLSACKSUMSUM: + sum = 0; + for (ALL_LSDB(oi->lsdb, lsa)) + sum += ntohs(lsa->header->checksum); + return SNMP_INTEGER(sum); + case OSPFv3IFDEMANDNBRPROBE: + case OSPFv3IFDEMANDNBRPROBERETRANSLIMIT: + case OSPFv3IFDEMANDNBRPROBEINTERVAL: + case OSPFv3IFTEDISABLED: + case OSPFv3IFLINKLSASUPPRESSION: + /* Not implemented. Only works if all the last ones are not + implemented! */ + return NULL; + } + + /* Try an internal getnext. Some columns are missing in this table. */ + if (!exact && (name[*length - 1] < MAX_SUBID)) + return ospfv3IfEntry(v, name, length, exact, var_len, + write_method); + return NULL; } -static u_char * -ospfv3NbrEntry (struct variable *v, oid *name, size_t *length, - int exact, size_t *var_len, WriteMethod **write_method) +static u_char *ospfv3NbrEntry(struct variable *v, oid *name, size_t *length, + int exact, size_t *var_len, + WriteMethod **write_method) { - ifindex_t ifindex = 0; - unsigned int instid, rtrid; - struct ospf6_interface *oi = NULL; - struct ospf6_neighbor *on = NULL; - struct interface *iif; - struct listnode *i, *j; - struct list *ifslist; - oid *offset; - int offsetlen, len; - - if (smux_header_table (v, name, length, exact, var_len, write_method) - == MATCH_FAILED) - return NULL; - - instid = rtrid = 0; - - /* Check OSPFv3 instance. */ - if (ospf6 == NULL) - return NULL; - - /* Get variable length. */ - offset = name + v->namelen; - offsetlen = *length - v->namelen; - - if (exact && offsetlen != 3) - return NULL; - - /* Parse if index */ - len = (offsetlen < 1 ? 0 : 1); - if (len) - ifindex = *offset; - offset += len; - offsetlen -= len; - - /* Parse instance ID */ - len = (offsetlen < 1 ? 0 : 1); - if (len) - instid = *offset; - offset += len; - offsetlen -= len; - - /* Parse router ID */ - len = (offsetlen < 1 ? 0 : 1); - if (len) - rtrid = htonl (*offset); - offset += len; - offsetlen -= len; - - if (exact) - { - oi = ospf6_interface_lookup_by_ifindex (ifindex); - if (!oi || oi->instance_id != instid) return NULL; - on = ospf6_neighbor_lookup (rtrid, oi); - } - else - { - /* We build a sorted list of interfaces */ - ifslist = list_new (); - if (!ifslist) return NULL; - ifslist->cmp = (int (*)(void *, void *))if_icmp_func; - for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), i, iif)) - listnode_add_sort (ifslist, iif); - - for (ALL_LIST_ELEMENTS_RO (ifslist, i, iif)) - { - if (!iif->ifindex) continue; - oi = ospf6_interface_lookup_by_ifindex (iif->ifindex); - if (!oi) continue; - for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on)) { - if (iif->ifindex > ifindex || - (iif->ifindex == ifindex && - (oi->instance_id > instid || - (oi->instance_id == instid && - ntohl (on->router_id) > ntohl (rtrid))))) - break; - } - if (on) break; - oi = NULL; - on = NULL; - } - - list_delete_all_node (ifslist); - } - - if (!oi || !on) return NULL; - - /* Add Index (IfIndex, IfInstId, RtrId) */ - *length = v->namelen + 3; - offset = name + v->namelen; - *offset = oi->interface->ifindex; - offset++; - *offset = oi->instance_id; - offset++; - *offset = ntohl (on->router_id); - offset++; - - /* Return the current value of the variable */ - switch (v->magic) - { - case OSPFv3NBRADDRESSTYPE: - return SNMP_INTEGER (2); /* IPv6 only */ - case OSPFv3NBRADDRESS: - *var_len = sizeof (struct in6_addr); - return (u_char *) &on->linklocal_addr; - case OSPFv3NBROPTIONS: - return SNMP_INTEGER (on->options[2]); - case OSPFv3NBRPRIORITY: - return SNMP_INTEGER (on->priority); - case OSPFv3NBRSTATE: - return SNMP_INTEGER (on->state); - case OSPFv3NBREVENTS: - return SNMP_INTEGER (on->state_change); - case OSPFv3NBRLSRETRANSQLEN: - return SNMP_INTEGER (on->retrans_list->count); - case OSPFv3NBRHELLOSUPPRESSED: - return SNMP_INTEGER (SNMP_FALSE); - case OSPFv3NBRIFID: - return SNMP_INTEGER (on->ifindex); - case OSPFv3NBRRESTARTHELPERSTATUS: - case OSPFv3NBRRESTARTHELPERAGE: - case OSPFv3NBRRESTARTHELPEREXITREASON: - /* Not implemented. Only works if all the last ones are not - implemented! */ - return NULL; - } - - return NULL; + ifindex_t ifindex = 0; + unsigned int instid, rtrid; + struct ospf6_interface *oi = NULL; + struct ospf6_neighbor *on = NULL; + struct interface *iif; + struct listnode *i, *j; + struct list *ifslist; + oid *offset; + int offsetlen, len; + + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + + instid = rtrid = 0; + + /* Check OSPFv3 instance. */ + if (ospf6 == NULL) + return NULL; + + /* Get variable length. */ + offset = name + v->namelen; + offsetlen = *length - v->namelen; + + if (exact && offsetlen != 3) + return NULL; + + /* Parse if index */ + len = (offsetlen < 1 ? 0 : 1); + if (len) + ifindex = *offset; + offset += len; + offsetlen -= len; + + /* Parse instance ID */ + len = (offsetlen < 1 ? 0 : 1); + if (len) + instid = *offset; + offset += len; + offsetlen -= len; + + /* Parse router ID */ + len = (offsetlen < 1 ? 0 : 1); + if (len) + rtrid = htonl(*offset); + offset += len; + offsetlen -= len; + + if (exact) { + oi = ospf6_interface_lookup_by_ifindex(ifindex); + if (!oi || oi->instance_id != instid) + return NULL; + on = ospf6_neighbor_lookup(rtrid, oi); + } else { + /* We build a sorted list of interfaces */ + ifslist = list_new(); + if (!ifslist) + return NULL; + ifslist->cmp = (int (*)(void *, void *))if_icmp_func; + for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), i, iif)) + listnode_add_sort(ifslist, iif); + + for (ALL_LIST_ELEMENTS_RO(ifslist, i, iif)) { + if (!iif->ifindex) + continue; + oi = ospf6_interface_lookup_by_ifindex(iif->ifindex); + if (!oi) + continue; + for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, j, on)) { + if (iif->ifindex > ifindex + || (iif->ifindex == ifindex + && (oi->instance_id > instid + || (oi->instance_id == instid + && ntohl(on->router_id) + > ntohl(rtrid))))) + break; + } + if (on) + break; + oi = NULL; + on = NULL; + } + + list_delete_all_node(ifslist); + } + + if (!oi || !on) + return NULL; + + /* Add Index (IfIndex, IfInstId, RtrId) */ + *length = v->namelen + 3; + offset = name + v->namelen; + *offset = oi->interface->ifindex; + offset++; + *offset = oi->instance_id; + offset++; + *offset = ntohl(on->router_id); + offset++; + + /* Return the current value of the variable */ + switch (v->magic) { + case OSPFv3NBRADDRESSTYPE: + return SNMP_INTEGER(2); /* IPv6 only */ + case OSPFv3NBRADDRESS: + *var_len = sizeof(struct in6_addr); + return (u_char *)&on->linklocal_addr; + case OSPFv3NBROPTIONS: + return SNMP_INTEGER(on->options[2]); + case OSPFv3NBRPRIORITY: + return SNMP_INTEGER(on->priority); + case OSPFv3NBRSTATE: + return SNMP_INTEGER(on->state); + case OSPFv3NBREVENTS: + return SNMP_INTEGER(on->state_change); + case OSPFv3NBRLSRETRANSQLEN: + return SNMP_INTEGER(on->retrans_list->count); + case OSPFv3NBRHELLOSUPPRESSED: + return SNMP_INTEGER(SNMP_FALSE); + case OSPFv3NBRIFID: + return SNMP_INTEGER(on->ifindex); + case OSPFv3NBRRESTARTHELPERSTATUS: + case OSPFv3NBRRESTARTHELPERAGE: + case OSPFv3NBRRESTARTHELPEREXITREASON: + /* Not implemented. Only works if all the last ones are not + implemented! */ + return NULL; + } + + return NULL; } /* OSPF Traps. */ #define NBRSTATECHANGE 2 #define IFSTATECHANGE 10 -static struct trap_object ospf6NbrTrapList[] = -{ - {-3, {1, 1, OSPFv3ROUTERID}}, - {4, {1, 9, 1, OSPFv3NBRADDRESSTYPE}}, - {4, {1, 9, 1, OSPFv3NBRADDRESS}}, - {4, {1, 9, 1, OSPFv3NBRSTATE}} -}; +static struct trap_object ospf6NbrTrapList[] = { + {-3, {1, 1, OSPFv3ROUTERID}}, + {4, {1, 9, 1, OSPFv3NBRADDRESSTYPE}}, + {4, {1, 9, 1, OSPFv3NBRADDRESS}}, + {4, {1, 9, 1, OSPFv3NBRSTATE}}}; -static struct trap_object ospf6IfTrapList[] = -{ - {-3, {1, 1, OSPFv3ROUTERID}}, - {4, {1, 7, 1, OSPFv3IFSTATE}}, - {4, {1, 7, 1, OSPFv3IFADMINSTATUS}}, - {4, {1, 7, 1, OSPFv3IFAREAID}} -}; +static struct trap_object ospf6IfTrapList[] = { + {-3, {1, 1, OSPFv3ROUTERID}}, + {4, {1, 7, 1, OSPFv3IFSTATE}}, + {4, {1, 7, 1, OSPFv3IFADMINSTATUS}}, + {4, {1, 7, 1, OSPFv3IFAREAID}}}; -static int -ospf6TrapNbrStateChange (struct ospf6_neighbor *on, - int next_state, int prev_state) +static int ospf6TrapNbrStateChange(struct ospf6_neighbor *on, int next_state, + int prev_state) { - oid index[3]; - - /* Terminal state or regression */ - if ((next_state != OSPF6_NEIGHBOR_FULL) && - (next_state != OSPF6_NEIGHBOR_TWOWAY) && - (next_state >= prev_state)) - return 0; - - index[0] = on->ospf6_if->interface->ifindex; - index[1] = on->ospf6_if->instance_id; - index[2] = ntohl (on->router_id); - - smux_trap (ospfv3_variables, sizeof ospfv3_variables / sizeof (struct variable), - ospfv3_trap_oid, sizeof ospfv3_trap_oid / sizeof (oid), - ospfv3_oid, sizeof ospfv3_oid / sizeof (oid), - index, 3, - ospf6NbrTrapList, - sizeof ospf6NbrTrapList / sizeof (struct trap_object), - NBRSTATECHANGE); - return 0; + oid index[3]; + + /* Terminal state or regression */ + if ((next_state != OSPF6_NEIGHBOR_FULL) + && (next_state != OSPF6_NEIGHBOR_TWOWAY) + && (next_state >= prev_state)) + return 0; + + index[0] = on->ospf6_if->interface->ifindex; + index[1] = on->ospf6_if->instance_id; + index[2] = ntohl(on->router_id); + + smux_trap(ospfv3_variables, + sizeof ospfv3_variables / sizeof(struct variable), + ospfv3_trap_oid, sizeof ospfv3_trap_oid / sizeof(oid), + ospfv3_oid, sizeof ospfv3_oid / sizeof(oid), index, 3, + ospf6NbrTrapList, + sizeof ospf6NbrTrapList / sizeof(struct trap_object), + NBRSTATECHANGE); + return 0; } -static int -ospf6TrapIfStateChange (struct ospf6_interface *oi, - int next_state, int prev_state) +static int ospf6TrapIfStateChange(struct ospf6_interface *oi, int next_state, + int prev_state) { - oid index[2]; - - /* Terminal state or regression */ - if ((next_state != OSPF6_INTERFACE_POINTTOPOINT) && - (next_state != OSPF6_INTERFACE_DROTHER) && - (next_state != OSPF6_INTERFACE_BDR) && - (next_state != OSPF6_INTERFACE_DR) && - (next_state >= prev_state)) - return 0; - - index[0] = oi->interface->ifindex; - index[1] = oi->instance_id; - - smux_trap (ospfv3_variables, sizeof ospfv3_variables / sizeof (struct variable), - ospfv3_trap_oid, sizeof ospfv3_trap_oid / sizeof (oid), - ospfv3_oid, sizeof ospfv3_oid / sizeof (oid), - index, 2, - ospf6IfTrapList, - sizeof ospf6IfTrapList / sizeof (struct trap_object), - IFSTATECHANGE); - return 0; + oid index[2]; + + /* Terminal state or regression */ + if ((next_state != OSPF6_INTERFACE_POINTTOPOINT) + && (next_state != OSPF6_INTERFACE_DROTHER) + && (next_state != OSPF6_INTERFACE_BDR) + && (next_state != OSPF6_INTERFACE_DR) && (next_state >= prev_state)) + return 0; + + index[0] = oi->interface->ifindex; + index[1] = oi->instance_id; + + smux_trap(ospfv3_variables, + sizeof ospfv3_variables / sizeof(struct variable), + ospfv3_trap_oid, sizeof ospfv3_trap_oid / sizeof(oid), + ospfv3_oid, sizeof ospfv3_oid / sizeof(oid), index, 2, + ospf6IfTrapList, + sizeof ospf6IfTrapList / sizeof(struct trap_object), + IFSTATECHANGE); + return 0; } /* Register OSPFv3-MIB. */ -static int -ospf6_snmp_init (struct thread_master *master) +static int ospf6_snmp_init(struct thread_master *master) { - smux_init (master); - REGISTER_MIB ("OSPFv3MIB", ospfv3_variables, variable, ospfv3_oid); - return 0; + smux_init(master); + REGISTER_MIB("OSPFv3MIB", ospfv3_variables, variable, ospfv3_oid); + return 0; } -static int -ospf6_snmp_module_init (void) +static int ospf6_snmp_module_init(void) { - hook_register(ospf6_interface_change, ospf6TrapIfStateChange); - hook_register(ospf6_neighbor_change, ospf6TrapNbrStateChange); - hook_register(frr_late_init, ospf6_snmp_init); - return 0; + hook_register(ospf6_interface_change, ospf6TrapIfStateChange); + hook_register(ospf6_neighbor_change, ospf6TrapNbrStateChange); + hook_register(frr_late_init, ospf6_snmp_init); + return 0; } -FRR_MODULE_SETUP( - .name = "ospf6d_snmp", - .version = FRR_VERSION, - .description = "ospf6d AgentX SNMP module", - .init = ospf6_snmp_module_init, -) +FRR_MODULE_SETUP(.name = "ospf6d_snmp", .version = FRR_VERSION, + .description = "ospf6d AgentX SNMP module", + .init = ospf6_snmp_module_init, ) diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c index 8d2e244c8..86f893bc6 100644 --- a/ospf6d/ospf6_spf.c +++ b/ospf6d/ospf6_spf.c @@ -45,721 +45,688 @@ unsigned char conf_debug_ospf6_spf = 0; -static void -ospf6_spf_copy_nexthops_to_route (struct ospf6_route *rt, - struct ospf6_vertex *v) +static void ospf6_spf_copy_nexthops_to_route(struct ospf6_route *rt, + struct ospf6_vertex *v) { - if (rt && v) - ospf6_copy_nexthops (rt->nh_list, v->nh_list); + if (rt && v) + ospf6_copy_nexthops(rt->nh_list, v->nh_list); } -static void -ospf6_spf_merge_nexthops_to_route (struct ospf6_route *rt, - struct ospf6_vertex *v) +static void ospf6_spf_merge_nexthops_to_route(struct ospf6_route *rt, + struct ospf6_vertex *v) { - if (rt && v) - ospf6_merge_nexthops (rt->nh_list, v->nh_list); + if (rt && v) + ospf6_merge_nexthops(rt->nh_list, v->nh_list); } -static unsigned int -ospf6_spf_get_ifindex_from_nh (struct ospf6_vertex *v) +static unsigned int ospf6_spf_get_ifindex_from_nh(struct ospf6_vertex *v) { - struct ospf6_nexthop *nh; - struct listnode *node; - - if (v) - { - node = listhead(v->nh_list); - if (node) - { - nh = listgetdata (node); - if (nh) - return (nh->ifindex); + struct ospf6_nexthop *nh; + struct listnode *node; + + if (v) { + node = listhead(v->nh_list); + if (node) { + nh = listgetdata(node); + if (nh) + return (nh->ifindex); + } } - } - return 0; + return 0; } -static int -ospf6_vertex_cmp (void *a, void *b) +static int ospf6_vertex_cmp(void *a, void *b) { - struct ospf6_vertex *va = (struct ospf6_vertex *) a; - struct ospf6_vertex *vb = (struct ospf6_vertex *) b; + struct ospf6_vertex *va = (struct ospf6_vertex *)a; + struct ospf6_vertex *vb = (struct ospf6_vertex *)b; - /* ascending order */ - if (va->cost != vb->cost) - return (va->cost - vb->cost); - return (va->hops - vb->hops); + /* ascending order */ + if (va->cost != vb->cost) + return (va->cost - vb->cost); + return (va->hops - vb->hops); } -static int -ospf6_vertex_id_cmp (void *a, void *b) +static int ospf6_vertex_id_cmp(void *a, void *b) { - struct ospf6_vertex *va = (struct ospf6_vertex *) a; - struct ospf6_vertex *vb = (struct ospf6_vertex *) b; - int ret = 0; - - ret = ntohl (ospf6_linkstate_prefix_adv_router (&va->vertex_id)) - - ntohl (ospf6_linkstate_prefix_adv_router (&vb->vertex_id)); - if (ret) - return ret; - - ret = ntohl (ospf6_linkstate_prefix_id (&va->vertex_id)) - - ntohl (ospf6_linkstate_prefix_id (&vb->vertex_id)); - return ret; + struct ospf6_vertex *va = (struct ospf6_vertex *)a; + struct ospf6_vertex *vb = (struct ospf6_vertex *)b; + int ret = 0; + + ret = ntohl(ospf6_linkstate_prefix_adv_router(&va->vertex_id)) + - ntohl(ospf6_linkstate_prefix_adv_router(&vb->vertex_id)); + if (ret) + return ret; + + ret = ntohl(ospf6_linkstate_prefix_id(&va->vertex_id)) + - ntohl(ospf6_linkstate_prefix_id(&vb->vertex_id)); + return ret; } -static struct ospf6_vertex * -ospf6_vertex_create (struct ospf6_lsa *lsa) +static struct ospf6_vertex *ospf6_vertex_create(struct ospf6_lsa *lsa) { - struct ospf6_vertex *v; + struct ospf6_vertex *v; - v = (struct ospf6_vertex *) - XMALLOC (MTYPE_OSPF6_VERTEX, sizeof (struct ospf6_vertex)); + v = (struct ospf6_vertex *)XMALLOC(MTYPE_OSPF6_VERTEX, + sizeof(struct ospf6_vertex)); - /* type */ - if (ntohs (lsa->header->type) == OSPF6_LSTYPE_ROUTER) - v->type = OSPF6_VERTEX_TYPE_ROUTER; - else if (ntohs (lsa->header->type) == OSPF6_LSTYPE_NETWORK) - v->type = OSPF6_VERTEX_TYPE_NETWORK; - else - assert (0); + /* type */ + if (ntohs(lsa->header->type) == OSPF6_LSTYPE_ROUTER) + v->type = OSPF6_VERTEX_TYPE_ROUTER; + else if (ntohs(lsa->header->type) == OSPF6_LSTYPE_NETWORK) + v->type = OSPF6_VERTEX_TYPE_NETWORK; + else + assert(0); - /* vertex_id */ - ospf6_linkstate_prefix (lsa->header->adv_router, lsa->header->id, - &v->vertex_id); + /* vertex_id */ + ospf6_linkstate_prefix(lsa->header->adv_router, lsa->header->id, + &v->vertex_id); - /* name */ - ospf6_linkstate_prefix2str (&v->vertex_id, v->name, sizeof (v->name)); + /* name */ + ospf6_linkstate_prefix2str(&v->vertex_id, v->name, sizeof(v->name)); - if (IS_OSPF6_DEBUG_SPF (PROCESS)) - zlog_debug ("%s: Creating vertex %s of type %s", __func__, v->name, - ((ntohs (lsa->header->type) == OSPF6_LSTYPE_ROUTER) ? "Router" : "N/W")); + if (IS_OSPF6_DEBUG_SPF(PROCESS)) + zlog_debug("%s: Creating vertex %s of type %s", __func__, + v->name, + ((ntohs(lsa->header->type) == OSPF6_LSTYPE_ROUTER) + ? "Router" + : "N/W")); - /* Associated LSA */ - v->lsa = lsa; + /* Associated LSA */ + v->lsa = lsa; - /* capability bits + options */ - v->capability = *(u_char *)(OSPF6_LSA_HEADER_END (lsa->header)); - v->options[0] = *(u_char *)(OSPF6_LSA_HEADER_END (lsa->header) + 1); - v->options[1] = *(u_char *)(OSPF6_LSA_HEADER_END (lsa->header) + 2); - v->options[2] = *(u_char *)(OSPF6_LSA_HEADER_END (lsa->header) + 3); + /* capability bits + options */ + v->capability = *(u_char *)(OSPF6_LSA_HEADER_END(lsa->header)); + v->options[0] = *(u_char *)(OSPF6_LSA_HEADER_END(lsa->header) + 1); + v->options[1] = *(u_char *)(OSPF6_LSA_HEADER_END(lsa->header) + 2); + v->options[2] = *(u_char *)(OSPF6_LSA_HEADER_END(lsa->header) + 3); - v->nh_list = list_new(); + v->nh_list = list_new(); - v->parent = NULL; - v->child_list = list_new (); - v->child_list->cmp = ospf6_vertex_id_cmp; + v->parent = NULL; + v->child_list = list_new(); + v->child_list->cmp = ospf6_vertex_id_cmp; - return v; + return v; } -static void -ospf6_vertex_delete (struct ospf6_vertex *v) +static void ospf6_vertex_delete(struct ospf6_vertex *v) { - list_delete(v->nh_list); - list_delete (v->child_list); - XFREE (MTYPE_OSPF6_VERTEX, v); + list_delete(v->nh_list); + list_delete(v->child_list); + XFREE(MTYPE_OSPF6_VERTEX, v); } -static struct ospf6_lsa * -ospf6_lsdesc_lsa (caddr_t lsdesc, struct ospf6_vertex *v) +static struct ospf6_lsa *ospf6_lsdesc_lsa(caddr_t lsdesc, + struct ospf6_vertex *v) { - struct ospf6_lsa *lsa; - u_int16_t type = 0; - u_int32_t id = 0, adv_router = 0; - - if (VERTEX_IS_TYPE (NETWORK, v)) - { - type = htons (OSPF6_LSTYPE_ROUTER); - id = htonl (0); - adv_router = NETWORK_LSDESC_GET_NBR_ROUTERID (lsdesc); - } - else - { - if (ROUTER_LSDESC_IS_TYPE (POINTTOPOINT, lsdesc)) - { - type = htons (OSPF6_LSTYPE_ROUTER); - id = htonl (0); - adv_router = ROUTER_LSDESC_GET_NBR_ROUTERID (lsdesc); - } - else if (ROUTER_LSDESC_IS_TYPE (TRANSIT_NETWORK, lsdesc)) - { - type = htons (OSPF6_LSTYPE_NETWORK); - id = htonl (ROUTER_LSDESC_GET_NBR_IFID (lsdesc)); - adv_router = ROUTER_LSDESC_GET_NBR_ROUTERID (lsdesc); - } - } - - lsa = ospf6_lsdb_lookup (type, id, adv_router, v->area->lsdb); - - if (IS_OSPF6_DEBUG_SPF (PROCESS)) - { - char ibuf[16], abuf[16]; - inet_ntop (AF_INET, &id, ibuf, sizeof (ibuf)); - inet_ntop (AF_INET, &adv_router, abuf, sizeof (abuf)); - if (lsa) - zlog_debug (" Link to: %s", lsa->name); - else - zlog_debug (" Link to: [%s Id:%s Adv:%s] No LSA", - ospf6_lstype_name (type), ibuf, abuf); - } - - return lsa; + struct ospf6_lsa *lsa; + u_int16_t type = 0; + u_int32_t id = 0, adv_router = 0; + + if (VERTEX_IS_TYPE(NETWORK, v)) { + type = htons(OSPF6_LSTYPE_ROUTER); + id = htonl(0); + adv_router = NETWORK_LSDESC_GET_NBR_ROUTERID(lsdesc); + } else { + if (ROUTER_LSDESC_IS_TYPE(POINTTOPOINT, lsdesc)) { + type = htons(OSPF6_LSTYPE_ROUTER); + id = htonl(0); + adv_router = ROUTER_LSDESC_GET_NBR_ROUTERID(lsdesc); + } else if (ROUTER_LSDESC_IS_TYPE(TRANSIT_NETWORK, lsdesc)) { + type = htons(OSPF6_LSTYPE_NETWORK); + id = htonl(ROUTER_LSDESC_GET_NBR_IFID(lsdesc)); + adv_router = ROUTER_LSDESC_GET_NBR_ROUTERID(lsdesc); + } + } + + lsa = ospf6_lsdb_lookup(type, id, adv_router, v->area->lsdb); + + if (IS_OSPF6_DEBUG_SPF(PROCESS)) { + char ibuf[16], abuf[16]; + inet_ntop(AF_INET, &id, ibuf, sizeof(ibuf)); + inet_ntop(AF_INET, &adv_router, abuf, sizeof(abuf)); + if (lsa) + zlog_debug(" Link to: %s", lsa->name); + else + zlog_debug(" Link to: [%s Id:%s Adv:%s] No LSA", + ospf6_lstype_name(type), ibuf, abuf); + } + + return lsa; } -static char * -ospf6_lsdesc_backlink (struct ospf6_lsa *lsa, - caddr_t lsdesc, struct ospf6_vertex *v) +static char *ospf6_lsdesc_backlink(struct ospf6_lsa *lsa, caddr_t lsdesc, + struct ospf6_vertex *v) { - caddr_t backlink, found = NULL; - int size; - - size = (OSPF6_LSA_IS_TYPE (ROUTER, lsa) ? - sizeof (struct ospf6_router_lsdesc) : - sizeof (struct ospf6_network_lsdesc)); - for (backlink = OSPF6_LSA_HEADER_END (lsa->header) + 4; - backlink + size <= OSPF6_LSA_END (lsa->header); backlink += size) - { - assert (! (OSPF6_LSA_IS_TYPE (NETWORK, lsa) && - VERTEX_IS_TYPE (NETWORK, v))); - - if (OSPF6_LSA_IS_TYPE (NETWORK, lsa) && - NETWORK_LSDESC_GET_NBR_ROUTERID (backlink) - == v->lsa->header->adv_router) - found = backlink; - else if (VERTEX_IS_TYPE (NETWORK, v) && - ROUTER_LSDESC_IS_TYPE (TRANSIT_NETWORK, backlink) && - ROUTER_LSDESC_GET_NBR_ROUTERID (backlink) - == v->lsa->header->adv_router && - ROUTER_LSDESC_GET_NBR_IFID (backlink) - == ntohl (v->lsa->header->id)) - found = backlink; - else - { - if (! ROUTER_LSDESC_IS_TYPE (POINTTOPOINT, backlink) || - ! ROUTER_LSDESC_IS_TYPE (POINTTOPOINT, lsdesc)) - continue; - if (ROUTER_LSDESC_GET_NBR_IFID (backlink) != - ROUTER_LSDESC_GET_IFID (lsdesc) || - ROUTER_LSDESC_GET_NBR_IFID (lsdesc) != - ROUTER_LSDESC_GET_IFID (backlink)) - continue; - if (ROUTER_LSDESC_GET_NBR_ROUTERID (backlink) != - v->lsa->header->adv_router || - ROUTER_LSDESC_GET_NBR_ROUTERID (lsdesc) != - lsa->header->adv_router) - continue; - found = backlink; - } - } - - if (IS_OSPF6_DEBUG_SPF (PROCESS)) - zlog_debug (" Backlink %s", (found ? "OK" : "FAIL")); - - return found; + caddr_t backlink, found = NULL; + int size; + + size = (OSPF6_LSA_IS_TYPE(ROUTER, lsa) + ? sizeof(struct ospf6_router_lsdesc) + : sizeof(struct ospf6_network_lsdesc)); + for (backlink = OSPF6_LSA_HEADER_END(lsa->header) + 4; + backlink + size <= OSPF6_LSA_END(lsa->header); backlink += size) { + assert(!(OSPF6_LSA_IS_TYPE(NETWORK, lsa) + && VERTEX_IS_TYPE(NETWORK, v))); + + if (OSPF6_LSA_IS_TYPE(NETWORK, lsa) + && NETWORK_LSDESC_GET_NBR_ROUTERID(backlink) + == v->lsa->header->adv_router) + found = backlink; + else if (VERTEX_IS_TYPE(NETWORK, v) + && ROUTER_LSDESC_IS_TYPE(TRANSIT_NETWORK, backlink) + && ROUTER_LSDESC_GET_NBR_ROUTERID(backlink) + == v->lsa->header->adv_router + && ROUTER_LSDESC_GET_NBR_IFID(backlink) + == ntohl(v->lsa->header->id)) + found = backlink; + else { + if (!ROUTER_LSDESC_IS_TYPE(POINTTOPOINT, backlink) + || !ROUTER_LSDESC_IS_TYPE(POINTTOPOINT, lsdesc)) + continue; + if (ROUTER_LSDESC_GET_NBR_IFID(backlink) + != ROUTER_LSDESC_GET_IFID(lsdesc) + || ROUTER_LSDESC_GET_NBR_IFID(lsdesc) + != ROUTER_LSDESC_GET_IFID(backlink)) + continue; + if (ROUTER_LSDESC_GET_NBR_ROUTERID(backlink) + != v->lsa->header->adv_router + || ROUTER_LSDESC_GET_NBR_ROUTERID(lsdesc) + != lsa->header->adv_router) + continue; + found = backlink; + } + } + + if (IS_OSPF6_DEBUG_SPF(PROCESS)) + zlog_debug(" Backlink %s", (found ? "OK" : "FAIL")); + + return found; } -static void -ospf6_nexthop_calc (struct ospf6_vertex *w, struct ospf6_vertex *v, - caddr_t lsdesc) +static void ospf6_nexthop_calc(struct ospf6_vertex *w, struct ospf6_vertex *v, + caddr_t lsdesc) { - int i; - ifindex_t ifindex; - struct ospf6_interface *oi; - u_int16_t type; - u_int32_t adv_router; - struct ospf6_lsa *lsa; - struct ospf6_link_lsa *link_lsa; - char buf[64]; - - assert (VERTEX_IS_TYPE (ROUTER, w)); - ifindex = (VERTEX_IS_TYPE (NETWORK, v) ? ospf6_spf_get_ifindex_from_nh (v) : - ROUTER_LSDESC_GET_IFID (lsdesc)); - if (ifindex == 0) - { - zlog_err ("No nexthop ifindex at vertex %s", v->name); - return; - } - - oi = ospf6_interface_lookup_by_ifindex (ifindex); - if (oi == NULL) - { - if (IS_OSPF6_DEBUG_SPF (PROCESS)) - zlog_debug ("Can't find interface in SPF: ifindex %d", ifindex); - return; - } - - type = htons (OSPF6_LSTYPE_LINK); - adv_router = (VERTEX_IS_TYPE (NETWORK, v) ? - NETWORK_LSDESC_GET_NBR_ROUTERID (lsdesc) : - ROUTER_LSDESC_GET_NBR_ROUTERID (lsdesc)); - - i = 0; - for (ALL_LSDB_TYPED_ADVRTR(oi->lsdb, type, adv_router, lsa)) - { - if (VERTEX_IS_TYPE (ROUTER, v) && - htonl (ROUTER_LSDESC_GET_NBR_IFID (lsdesc)) != lsa->header->id) - continue; - - link_lsa = (struct ospf6_link_lsa *) OSPF6_LSA_HEADER_END (lsa->header); - if (IS_OSPF6_DEBUG_SPF (PROCESS)) - { - inet_ntop (AF_INET6, &link_lsa->linklocal_addr, buf, sizeof (buf)); - zlog_debug (" nexthop %s from %s", buf, lsa->name); - } - - ospf6_add_nexthop (w->nh_list, ifindex, &link_lsa->linklocal_addr); - i++; - } - - if (i == 0 && IS_OSPF6_DEBUG_SPF (PROCESS)) - zlog_debug ("No nexthop for %s found", w->name); + int i; + ifindex_t ifindex; + struct ospf6_interface *oi; + u_int16_t type; + u_int32_t adv_router; + struct ospf6_lsa *lsa; + struct ospf6_link_lsa *link_lsa; + char buf[64]; + + assert(VERTEX_IS_TYPE(ROUTER, w)); + ifindex = (VERTEX_IS_TYPE(NETWORK, v) ? ospf6_spf_get_ifindex_from_nh(v) + : ROUTER_LSDESC_GET_IFID(lsdesc)); + if (ifindex == 0) { + zlog_err("No nexthop ifindex at vertex %s", v->name); + return; + } + + oi = ospf6_interface_lookup_by_ifindex(ifindex); + if (oi == NULL) { + if (IS_OSPF6_DEBUG_SPF(PROCESS)) + zlog_debug("Can't find interface in SPF: ifindex %d", + ifindex); + return; + } + + type = htons(OSPF6_LSTYPE_LINK); + adv_router = (VERTEX_IS_TYPE(NETWORK, v) + ? NETWORK_LSDESC_GET_NBR_ROUTERID(lsdesc) + : ROUTER_LSDESC_GET_NBR_ROUTERID(lsdesc)); + + i = 0; + for (ALL_LSDB_TYPED_ADVRTR(oi->lsdb, type, adv_router, lsa)) { + if (VERTEX_IS_TYPE(ROUTER, v) + && htonl(ROUTER_LSDESC_GET_NBR_IFID(lsdesc)) + != lsa->header->id) + continue; + + link_lsa = (struct ospf6_link_lsa *)OSPF6_LSA_HEADER_END( + lsa->header); + if (IS_OSPF6_DEBUG_SPF(PROCESS)) { + inet_ntop(AF_INET6, &link_lsa->linklocal_addr, buf, + sizeof(buf)); + zlog_debug(" nexthop %s from %s", buf, lsa->name); + } + + ospf6_add_nexthop(w->nh_list, ifindex, + &link_lsa->linklocal_addr); + i++; + } + + if (i == 0 && IS_OSPF6_DEBUG_SPF(PROCESS)) + zlog_debug("No nexthop for %s found", w->name); } -static int -ospf6_spf_install (struct ospf6_vertex *v, - struct ospf6_route_table *result_table) +static int ospf6_spf_install(struct ospf6_vertex *v, + struct ospf6_route_table *result_table) { - struct ospf6_route *route, *parent_route; - struct ospf6_vertex *prev; - - if (IS_OSPF6_DEBUG_SPF (PROCESS)) - zlog_debug ("SPF install %s hops %d cost %d", - v->name, v->hops, v->cost); - - route = ospf6_route_lookup (&v->vertex_id, result_table); - if (route && route->path.cost < v->cost) - { - if (IS_OSPF6_DEBUG_SPF (PROCESS)) - zlog_debug (" already installed with lower cost (%d), ignore", - route->path.cost); - ospf6_vertex_delete (v); - return -1; - } - else if (route && route->path.cost == v->cost) - { - if (IS_OSPF6_DEBUG_SPF (PROCESS)) - zlog_debug (" another path found, merge"); - - ospf6_spf_merge_nexthops_to_route (route, v); - - prev = (struct ospf6_vertex *) route->route_option; - assert (prev->hops <= v->hops); - ospf6_vertex_delete (v); - - return -1; - } - - /* 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 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 (); - memcpy (&route->prefix, &v->vertex_id, sizeof (struct prefix)); - route->type = OSPF6_DEST_TYPE_LINKSTATE; - route->path.type = OSPF6_PATH_TYPE_INTRA; - route->path.origin.type = v->lsa->header->type; - route->path.origin.id = v->lsa->header->id; - route->path.origin.adv_router = v->lsa->header->adv_router; - route->path.metric_type = 1; - route->path.cost = v->cost; - route->path.u.cost_e2 = v->hops; - route->path.router_bits = v->capability; - route->path.options[0] = v->options[0]; - route->path.options[1] = v->options[1]; - route->path.options[2] = v->options[2]; - - ospf6_spf_copy_nexthops_to_route (route, v); - - /* - * The SPF logic implementation does not transfer the multipathing properties - * of a parent to a child node. Thus if there was a 3-way multipath to a - * node's parent and a single hop from the parent to the child, the logic of - * creating new vertices and computing next hops prevents there from being 3 - * paths to the child node. This is primarily because the resolution of - * multipath is done in this routine, not in the main spf loop. - * - * The following logic addresses that problem by merging the parent's nexthop - * information with the child's, if the parent is not the root of the tree. - * This is based on the assumption that before a node's route is installed, - * its parent's route's nexthops have already been installed. - */ - if (v->parent && v->parent->hops) - { - parent_route = ospf6_route_lookup (&v->parent->vertex_id, result_table); - if (parent_route) - { - ospf6_route_merge_nexthops (route, parent_route); + struct ospf6_route *route, *parent_route; + struct ospf6_vertex *prev; + + if (IS_OSPF6_DEBUG_SPF(PROCESS)) + zlog_debug("SPF install %s hops %d cost %d", v->name, v->hops, + v->cost); + + route = ospf6_route_lookup(&v->vertex_id, result_table); + if (route && route->path.cost < v->cost) { + if (IS_OSPF6_DEBUG_SPF(PROCESS)) + zlog_debug( + " already installed with lower cost (%d), ignore", + route->path.cost); + ospf6_vertex_delete(v); + return -1; + } else if (route && route->path.cost == v->cost) { + if (IS_OSPF6_DEBUG_SPF(PROCESS)) + zlog_debug(" another path found, merge"); + + ospf6_spf_merge_nexthops_to_route(route, v); + + prev = (struct ospf6_vertex *)route->route_option; + assert(prev->hops <= v->hops); + ospf6_vertex_delete(v); + + return -1; } - } - if (v->parent) - listnode_add_sort (v->parent->child_list, v); - route->route_option = 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 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(); + memcpy(&route->prefix, &v->vertex_id, sizeof(struct prefix)); + route->type = OSPF6_DEST_TYPE_LINKSTATE; + route->path.type = OSPF6_PATH_TYPE_INTRA; + route->path.origin.type = v->lsa->header->type; + route->path.origin.id = v->lsa->header->id; + route->path.origin.adv_router = v->lsa->header->adv_router; + route->path.metric_type = 1; + route->path.cost = v->cost; + route->path.u.cost_e2 = v->hops; + route->path.router_bits = v->capability; + route->path.options[0] = v->options[0]; + route->path.options[1] = v->options[1]; + route->path.options[2] = v->options[2]; + + ospf6_spf_copy_nexthops_to_route(route, v); + + /* + * The SPF logic implementation does not transfer the multipathing + * properties + * of a parent to a child node. Thus if there was a 3-way multipath to a + * node's parent and a single hop from the parent to the child, the + * logic of + * creating new vertices and computing next hops prevents there from + * being 3 + * paths to the child node. This is primarily because the resolution of + * multipath is done in this routine, not in the main spf loop. + * + * The following logic addresses that problem by merging the parent's + * nexthop + * information with the child's, if the parent is not the root of the + * tree. + * This is based on the assumption that before a node's route is + * installed, + * its parent's route's nexthops have already been installed. + */ + if (v->parent && v->parent->hops) { + parent_route = + ospf6_route_lookup(&v->parent->vertex_id, result_table); + if (parent_route) { + ospf6_route_merge_nexthops(route, parent_route); + } + } + + if (v->parent) + listnode_add_sort(v->parent->child_list, v); + route->route_option = v; - ospf6_route_add (route, result_table); - return 0; + ospf6_route_add(route, result_table); + return 0; } -void -ospf6_spf_table_finish (struct ospf6_route_table *result_table) +void ospf6_spf_table_finish(struct ospf6_route_table *result_table) { - struct ospf6_route *route, *nroute; - struct ospf6_vertex *v; - for (route = ospf6_route_head (result_table); route; - route = nroute) - { - nroute = ospf6_route_next (route); - v = (struct ospf6_vertex *) route->route_option; - ospf6_vertex_delete (v); - ospf6_route_remove (route, result_table); - } + struct ospf6_route *route, *nroute; + struct ospf6_vertex *v; + for (route = ospf6_route_head(result_table); route; route = nroute) { + nroute = ospf6_route_next(route); + v = (struct ospf6_vertex *)route->route_option; + ospf6_vertex_delete(v); + ospf6_route_remove(route, result_table); + } } -static const char *ospf6_spf_reason_str[] = - { - "R+", - "R-", - "N+", - "N-", - "L+", - "L-", - "R*", - "N*", - }; - -void ospf6_spf_reason_string (unsigned int reason, char *buf, int size) +static const char *ospf6_spf_reason_str[] = { + "R+", "R-", "N+", "N-", "L+", "L-", "R*", "N*", +}; + +void ospf6_spf_reason_string(unsigned int reason, char *buf, int size) { - unsigned int bit; - int len = 0; - - if (!buf) - return; - - for (bit = 0; bit < array_size(ospf6_spf_reason_str); bit++) - { - if ((reason & (1 << bit)) && (len < size)) - { - len += snprintf((buf + len), (size - len), "%s%s", - (len > 0) ? ", " : "", ospf6_spf_reason_str[bit]); + unsigned int bit; + int len = 0; + + if (!buf) + return; + + for (bit = 0; bit < array_size(ospf6_spf_reason_str); bit++) { + if ((reason & (1 << bit)) && (len < size)) { + len += snprintf((buf + len), (size - len), "%s%s", + (len > 0) ? ", " : "", + ospf6_spf_reason_str[bit]); + } } - } } /* 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, - struct ospf6_area *oa) +void ospf6_spf_calculation(u_int32_t router_id, + struct ospf6_route_table *result_table, + struct ospf6_area *oa) { - struct pqueue *candidate_list; - struct ospf6_vertex *root, *v, *w; - int size; - caddr_t lsdesc; - struct ospf6_lsa *lsa; - struct in6_addr address; - - ospf6_spf_table_finish (result_table); - - /* Install the calculating router itself as the root of the SPF tree */ - /* construct root vertex */ - lsa = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_ROUTER), htonl (0), - router_id, oa->lsdb_self); - if (lsa == NULL) - { - if (IS_OSPF6_DEBUG_SPF (PROCESS)) - zlog_debug ("%s: No router LSA for area %s\n", - __func__, oa->name); - return; - } - - /* initialize */ - candidate_list = pqueue_create (); - candidate_list->cmp = ospf6_vertex_cmp; - - root = ospf6_vertex_create (lsa); - root->area = oa; - root->cost = 0; - root->hops = 0; - inet_pton (AF_INET6, "::1", &address); - - /* Actually insert root to the candidate-list as the only candidate */ - pqueue_enqueue (root, candidate_list); - - /* Iterate until candidate-list becomes empty */ - while (candidate_list->size) - { - /* get closest candidate from priority queue */ - v = pqueue_dequeue (candidate_list); - - /* installing may result in merging or rejecting of the vertex */ - if (ospf6_spf_install (v, result_table) < 0) - continue; - - /* Skip overloaded routers */ - if ((OSPF6_LSA_IS_TYPE (ROUTER, v->lsa) && - ospf6_router_is_stub_router (v->lsa))) - continue; - - /* For each LS description in the just-added vertex V's LSA */ - size = (VERTEX_IS_TYPE (ROUTER, v) ? - sizeof (struct ospf6_router_lsdesc) : - sizeof (struct ospf6_network_lsdesc)); - for (lsdesc = OSPF6_LSA_HEADER_END (v->lsa->header) + 4; - lsdesc + size <= OSPF6_LSA_END (v->lsa->header); lsdesc += size) - { - lsa = ospf6_lsdesc_lsa (lsdesc, v); - if (lsa == NULL) - continue; - - if (OSPF6_LSA_IS_MAXAGE (lsa)) - continue; - - if (! ospf6_lsdesc_backlink (lsa, lsdesc, v)) - continue; - - w = ospf6_vertex_create (lsa); - w->area = oa; - w->parent = v; - if (VERTEX_IS_TYPE (ROUTER, v)) - { - w->cost = v->cost + ROUTER_LSDESC_GET_METRIC (lsdesc); - w->hops = v->hops + (VERTEX_IS_TYPE (NETWORK, w) ? 0 : 1); - } - else /* NETWORK */ - { - w->cost = v->cost; - w->hops = v->hops + 1; - } - - /* nexthop calculation */ - if (w->hops == 0) - ospf6_add_nexthop (w->nh_list, ROUTER_LSDESC_GET_IFID (lsdesc), NULL); - else if (w->hops == 1 && v->hops == 0) - ospf6_nexthop_calc (w, v, lsdesc); - else - { - ospf6_copy_nexthops (w->nh_list, v->nh_list); - } - - /* add new candidate to the candidate_list */ - if (IS_OSPF6_DEBUG_SPF (PROCESS)) - zlog_debug (" New candidate: %s hops %d cost %d", - w->name, w->hops, w->cost); - pqueue_enqueue (w, candidate_list); - } - } - - pqueue_delete (candidate_list); - - oa->spf_calculation++; + struct pqueue *candidate_list; + struct ospf6_vertex *root, *v, *w; + int size; + caddr_t lsdesc; + struct ospf6_lsa *lsa; + struct in6_addr address; + + ospf6_spf_table_finish(result_table); + + /* Install the calculating router itself as the root of the SPF tree */ + /* construct root vertex */ + lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_ROUTER), htonl(0), router_id, + oa->lsdb_self); + if (lsa == NULL) { + if (IS_OSPF6_DEBUG_SPF(PROCESS)) + zlog_debug("%s: No router LSA for area %s\n", __func__, + oa->name); + return; + } + + /* initialize */ + candidate_list = pqueue_create(); + candidate_list->cmp = ospf6_vertex_cmp; + + root = ospf6_vertex_create(lsa); + root->area = oa; + root->cost = 0; + root->hops = 0; + inet_pton(AF_INET6, "::1", &address); + + /* Actually insert root to the candidate-list as the only candidate */ + pqueue_enqueue(root, candidate_list); + + /* Iterate until candidate-list becomes empty */ + while (candidate_list->size) { + /* get closest candidate from priority queue */ + v = pqueue_dequeue(candidate_list); + + /* installing may result in merging or rejecting of the vertex + */ + if (ospf6_spf_install(v, result_table) < 0) + continue; + + /* Skip overloaded routers */ + if ((OSPF6_LSA_IS_TYPE(ROUTER, v->lsa) + && ospf6_router_is_stub_router(v->lsa))) + continue; + + /* For each LS description in the just-added vertex V's LSA */ + size = (VERTEX_IS_TYPE(ROUTER, v) + ? sizeof(struct ospf6_router_lsdesc) + : sizeof(struct ospf6_network_lsdesc)); + for (lsdesc = OSPF6_LSA_HEADER_END(v->lsa->header) + 4; + lsdesc + size <= OSPF6_LSA_END(v->lsa->header); + lsdesc += size) { + lsa = ospf6_lsdesc_lsa(lsdesc, v); + if (lsa == NULL) + continue; + + if (OSPF6_LSA_IS_MAXAGE(lsa)) + continue; + + if (!ospf6_lsdesc_backlink(lsa, lsdesc, v)) + continue; + + w = ospf6_vertex_create(lsa); + w->area = oa; + w->parent = v; + if (VERTEX_IS_TYPE(ROUTER, v)) { + w->cost = v->cost + + ROUTER_LSDESC_GET_METRIC(lsdesc); + w->hops = + v->hops + + (VERTEX_IS_TYPE(NETWORK, w) ? 0 : 1); + } else /* NETWORK */ + { + w->cost = v->cost; + w->hops = v->hops + 1; + } + + /* nexthop calculation */ + if (w->hops == 0) + ospf6_add_nexthop( + w->nh_list, + ROUTER_LSDESC_GET_IFID(lsdesc), NULL); + else if (w->hops == 1 && v->hops == 0) + ospf6_nexthop_calc(w, v, lsdesc); + else { + ospf6_copy_nexthops(w->nh_list, v->nh_list); + } + + /* add new candidate to the candidate_list */ + if (IS_OSPF6_DEBUG_SPF(PROCESS)) + zlog_debug( + " New candidate: %s hops %d cost %d", + w->name, w->hops, w->cost); + pqueue_enqueue(w, candidate_list); + } + } + + pqueue_delete(candidate_list); + + oa->spf_calculation++; } -static void -ospf6_spf_log_database (struct ospf6_area *oa) +static void ospf6_spf_log_database(struct ospf6_area *oa) { - char *p, *end, buffer[256]; - struct listnode *node; - struct ospf6_interface *oi; - - p = buffer; - end = buffer + sizeof (buffer); - - snprintf (p, end - p, "SPF on DB (#LSAs):"); - p = (buffer + strlen (buffer) < end ? buffer + strlen (buffer) : end); - snprintf (p, end - p, " Area %s: %d", oa->name, oa->lsdb->count); - p = (buffer + strlen (buffer) < end ? buffer + strlen (buffer) : end); - - for (ALL_LIST_ELEMENTS_RO (oa->if_list, node, oi)) - { - snprintf (p, end - p, " I/F %s: %d", - oi->interface->name, oi->lsdb->count); - p = (buffer + strlen (buffer) < end ? buffer + strlen (buffer) : end); - } - - zlog_debug ("%s", buffer); + char *p, *end, buffer[256]; + struct listnode *node; + struct ospf6_interface *oi; + + p = buffer; + end = buffer + sizeof(buffer); + + snprintf(p, end - p, "SPF on DB (#LSAs):"); + p = (buffer + strlen(buffer) < end ? buffer + strlen(buffer) : end); + snprintf(p, end - p, " Area %s: %d", oa->name, oa->lsdb->count); + p = (buffer + strlen(buffer) < end ? buffer + strlen(buffer) : end); + + for (ALL_LIST_ELEMENTS_RO(oa->if_list, node, oi)) { + snprintf(p, end - p, " I/F %s: %d", oi->interface->name, + oi->lsdb->count); + p = (buffer + strlen(buffer) < end ? buffer + strlen(buffer) + : end); + } + + zlog_debug("%s", buffer); } -static int -ospf6_spf_calculation_thread (struct thread *t) +static int ospf6_spf_calculation_thread(struct thread *t) { - struct ospf6_area *oa; - struct ospf6 *ospf6; - struct timeval start, end, runtime; - struct listnode *node; - int areas_processed = 0; - char rbuf[32]; - - ospf6 = (struct ospf6 *)THREAD_ARG (t); - ospf6->t_spf_calc = NULL; - - /* execute SPF calculation */ - monotime(&start); - - if (ospf6_is_router_abr (ospf6)) - ospf6_abr_range_reset_cost (ospf6); - - for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) - { - - if (oa == ospf6->backbone) - continue; - - if (IS_OSPF6_DEBUG_SPF (PROCESS)) - zlog_debug ("SPF calculation for Area %s", oa->name); - if (IS_OSPF6_DEBUG_SPF (DATABASE)) - ospf6_spf_log_database (oa); - - ospf6_spf_calculation (ospf6->router_id, oa->spf_table, oa); - ospf6_intra_route_calculation (oa); - ospf6_intra_brouter_calculation (oa); - - areas_processed++; - } - - if (ospf6->backbone) - { - if (IS_OSPF6_DEBUG_SPF (PROCESS)) - zlog_debug ("SPF calculation for Backbone area %s", - ospf6->backbone->name); - if (IS_OSPF6_DEBUG_SPF (DATABASE)) - ospf6_spf_log_database(ospf6->backbone); - - ospf6_spf_calculation(ospf6->router_id, ospf6->backbone->spf_table, - ospf6->backbone); - ospf6_intra_route_calculation(ospf6->backbone); - ospf6_intra_brouter_calculation(ospf6->backbone); - areas_processed++; - } - - if (ospf6_is_router_abr (ospf6)) - ospf6_abr_defaults_to_stub (ospf6); - - monotime(&end); - timersub (&end, &start, &runtime); - - ospf6->ts_spf_duration = runtime; - - ospf6_spf_reason_string(ospf6->spf_reason, rbuf, sizeof(rbuf)); - - if (IS_OSPF6_DEBUG_SPF (PROCESS) || IS_OSPF6_DEBUG_SPF (TIME)) - zlog_debug ("SPF runtime: %lld sec %lld usec", - (long long)runtime.tv_sec, (long long)runtime.tv_usec); - - zlog_info("SPF processing: # Areas: %d, SPF runtime: %lld sec %lld usec, " - "Reason: %s\n", areas_processed, - (long long)runtime.tv_sec, (long long)runtime.tv_usec, - rbuf); - ospf6->last_spf_reason = ospf6->spf_reason; - ospf6_reset_spf_reason(ospf6); - return 0; + struct ospf6_area *oa; + struct ospf6 *ospf6; + struct timeval start, end, runtime; + struct listnode *node; + int areas_processed = 0; + char rbuf[32]; + + ospf6 = (struct ospf6 *)THREAD_ARG(t); + ospf6->t_spf_calc = NULL; + + /* execute SPF calculation */ + monotime(&start); + + if (ospf6_is_router_abr(ospf6)) + ospf6_abr_range_reset_cost(ospf6); + + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) { + + if (oa == ospf6->backbone) + continue; + + if (IS_OSPF6_DEBUG_SPF(PROCESS)) + zlog_debug("SPF calculation for Area %s", oa->name); + if (IS_OSPF6_DEBUG_SPF(DATABASE)) + ospf6_spf_log_database(oa); + + ospf6_spf_calculation(ospf6->router_id, oa->spf_table, oa); + ospf6_intra_route_calculation(oa); + ospf6_intra_brouter_calculation(oa); + + areas_processed++; + } + + if (ospf6->backbone) { + if (IS_OSPF6_DEBUG_SPF(PROCESS)) + zlog_debug("SPF calculation for Backbone area %s", + ospf6->backbone->name); + if (IS_OSPF6_DEBUG_SPF(DATABASE)) + ospf6_spf_log_database(ospf6->backbone); + + ospf6_spf_calculation(ospf6->router_id, + ospf6->backbone->spf_table, + ospf6->backbone); + ospf6_intra_route_calculation(ospf6->backbone); + ospf6_intra_brouter_calculation(ospf6->backbone); + areas_processed++; + } + + if (ospf6_is_router_abr(ospf6)) + ospf6_abr_defaults_to_stub(ospf6); + + monotime(&end); + timersub(&end, &start, &runtime); + + ospf6->ts_spf_duration = runtime; + + ospf6_spf_reason_string(ospf6->spf_reason, rbuf, sizeof(rbuf)); + + if (IS_OSPF6_DEBUG_SPF(PROCESS) || IS_OSPF6_DEBUG_SPF(TIME)) + zlog_debug("SPF runtime: %lld sec %lld usec", + (long long)runtime.tv_sec, + (long long)runtime.tv_usec); + + zlog_info( + "SPF processing: # Areas: %d, SPF runtime: %lld sec %lld usec, " + "Reason: %s\n", + areas_processed, (long long)runtime.tv_sec, + (long long)runtime.tv_usec, rbuf); + ospf6->last_spf_reason = ospf6->spf_reason; + ospf6_reset_spf_reason(ospf6); + return 0; } /* Add schedule for SPF calculation. To avoid frequenst SPF calc, we set timer for SPF calc. */ -void -ospf6_spf_schedule (struct ospf6 *ospf6, unsigned int reason) +void ospf6_spf_schedule(struct ospf6 *ospf6, unsigned int reason) { - unsigned long delay, elapsed, ht; - - ospf6_set_spf_reason(ospf6, reason); - - if (IS_OSPF6_DEBUG_SPF(PROCESS) || IS_OSPF6_DEBUG_SPF (TIME)) - { - char rbuf[32]; - ospf6_spf_reason_string(reason, rbuf, sizeof(rbuf)); - zlog_debug ("SPF: calculation timer scheduled (reason %s)", rbuf); - } - - /* OSPF instance does not exist. */ - if (ospf6 == NULL) - return; - - /* SPF calculation timer is already scheduled. */ - if (ospf6->t_spf_calc) - { - if (IS_OSPF6_DEBUG_SPF(PROCESS) || IS_OSPF6_DEBUG_SPF (TIME)) - zlog_debug ("SPF: calculation timer is already scheduled: %p", - (void *)ospf6->t_spf_calc); - return; - } - - elapsed = monotime_since(&ospf6->ts_spf, NULL) / 1000LL; - ht = ospf6->spf_holdtime * ospf6->spf_hold_multiplier; - - if (ht > ospf6->spf_max_holdtime) - ht = ospf6->spf_max_holdtime; - - /* Get SPF calculation delay time. */ - if (elapsed < ht) - { - /* Got an event within the hold time of last SPF. We need to - * increase the hold_multiplier, if it's not already at/past - * maximum value, and wasn't already increased.. - */ - if (ht < ospf6->spf_max_holdtime) - ospf6->spf_hold_multiplier++; - - /* always honour the SPF initial delay */ - if ( (ht - elapsed) < ospf6->spf_delay) - delay = ospf6->spf_delay; - else - delay = ht - elapsed; - } - else - { - /* Event is past required hold-time of last SPF */ - delay = ospf6->spf_delay; - ospf6->spf_hold_multiplier = 1; - } - - if (IS_OSPF6_DEBUG_SPF(PROCESS) || IS_OSPF6_DEBUG_SPF (TIME)) - zlog_debug ("SPF: calculation timer delay = %ld", delay); - - zlog_info ("SPF: Scheduled in %ld msec", delay); - - ospf6->t_spf_calc = NULL; - thread_add_timer_msec(master, ospf6_spf_calculation_thread, ospf6, delay, - &ospf6->t_spf_calc); + unsigned long delay, elapsed, ht; + + ospf6_set_spf_reason(ospf6, reason); + + if (IS_OSPF6_DEBUG_SPF(PROCESS) || IS_OSPF6_DEBUG_SPF(TIME)) { + char rbuf[32]; + ospf6_spf_reason_string(reason, rbuf, sizeof(rbuf)); + zlog_debug("SPF: calculation timer scheduled (reason %s)", + rbuf); + } + + /* OSPF instance does not exist. */ + if (ospf6 == NULL) + return; + + /* SPF calculation timer is already scheduled. */ + if (ospf6->t_spf_calc) { + if (IS_OSPF6_DEBUG_SPF(PROCESS) || IS_OSPF6_DEBUG_SPF(TIME)) + zlog_debug( + "SPF: calculation timer is already scheduled: %p", + (void *)ospf6->t_spf_calc); + return; + } + + elapsed = monotime_since(&ospf6->ts_spf, NULL) / 1000LL; + ht = ospf6->spf_holdtime * ospf6->spf_hold_multiplier; + + if (ht > ospf6->spf_max_holdtime) + ht = ospf6->spf_max_holdtime; + + /* Get SPF calculation delay time. */ + if (elapsed < ht) { + /* Got an event within the hold time of last SPF. We need to + * increase the hold_multiplier, if it's not already at/past + * maximum value, and wasn't already increased.. + */ + if (ht < ospf6->spf_max_holdtime) + ospf6->spf_hold_multiplier++; + + /* always honour the SPF initial delay */ + if ((ht - elapsed) < ospf6->spf_delay) + delay = ospf6->spf_delay; + else + delay = ht - elapsed; + } else { + /* Event is past required hold-time of last SPF */ + delay = ospf6->spf_delay; + ospf6->spf_hold_multiplier = 1; + } + + if (IS_OSPF6_DEBUG_SPF(PROCESS) || IS_OSPF6_DEBUG_SPF(TIME)) + zlog_debug("SPF: calculation timer delay = %ld", delay); + + zlog_info("SPF: Scheduled in %ld msec", delay); + + ospf6->t_spf_calc = NULL; + thread_add_timer_msec(master, ospf6_spf_calculation_thread, ospf6, + delay, &ospf6->t_spf_calc); } -void -ospf6_spf_display_subtree (struct vty *vty, const char *prefix, int rest, - struct ospf6_vertex *v) +void ospf6_spf_display_subtree(struct vty *vty, const char *prefix, int rest, + struct ospf6_vertex *v) { - struct listnode *node, *nnode; - struct ospf6_vertex *c; - char *next_prefix; - int len; - int restnum; - - /* "prefix" is the space prefix of the display line */ - vty_out (vty, "%s+-%s [%d]\n", prefix, v->name, v->cost); - - len = strlen (prefix) + 4; - next_prefix = (char *) malloc (len); - if (next_prefix == NULL) - { - vty_out (vty, "malloc failed\n"); - return; - } - snprintf (next_prefix, len, "%s%s", prefix, (rest ? "| " : " ")); - - restnum = listcount (v->child_list); - for (ALL_LIST_ELEMENTS (v->child_list, node, nnode, c)) - { - restnum--; - ospf6_spf_display_subtree (vty, next_prefix, restnum, c); - } - - free (next_prefix); + struct listnode *node, *nnode; + struct ospf6_vertex *c; + char *next_prefix; + int len; + int restnum; + + /* "prefix" is the space prefix of the display line */ + vty_out(vty, "%s+-%s [%d]\n", prefix, v->name, v->cost); + + len = strlen(prefix) + 4; + next_prefix = (char *)malloc(len); + if (next_prefix == NULL) { + vty_out(vty, "malloc failed\n"); + return; + } + snprintf(next_prefix, len, "%s%s", prefix, (rest ? "| " : " ")); + + restnum = listcount(v->child_list); + for (ALL_LIST_ELEMENTS(v->child_list, node, nnode, c)) { + restnum--; + ospf6_spf_display_subtree(vty, next_prefix, restnum, c); + } + + free(next_prefix); } DEFUN (debug_ospf6_spf_process, @@ -771,10 +738,10 @@ DEFUN (debug_ospf6_spf_process, "Debug Detailed SPF Process\n" ) { - unsigned char level = 0; - level = OSPF6_DEBUG_SPF_PROCESS; - OSPF6_DEBUG_SPF_ON (level); - return CMD_SUCCESS; + unsigned char level = 0; + level = OSPF6_DEBUG_SPF_PROCESS; + OSPF6_DEBUG_SPF_ON(level); + return CMD_SUCCESS; } DEFUN (debug_ospf6_spf_time, @@ -786,10 +753,10 @@ DEFUN (debug_ospf6_spf_time, "Measure time taken by SPF Calculation\n" ) { - unsigned char level = 0; - level = OSPF6_DEBUG_SPF_TIME; - OSPF6_DEBUG_SPF_ON (level); - return CMD_SUCCESS; + unsigned char level = 0; + level = OSPF6_DEBUG_SPF_TIME; + OSPF6_DEBUG_SPF_ON(level); + return CMD_SUCCESS; } DEFUN (debug_ospf6_spf_database, @@ -801,10 +768,10 @@ DEFUN (debug_ospf6_spf_database, "Log number of LSAs at SPF Calculation time\n" ) { - unsigned char level = 0; - level = OSPF6_DEBUG_SPF_DATABASE; - OSPF6_DEBUG_SPF_ON (level); - return CMD_SUCCESS; + unsigned char level = 0; + level = OSPF6_DEBUG_SPF_DATABASE; + OSPF6_DEBUG_SPF_ON(level); + return CMD_SUCCESS; } DEFUN (no_debug_ospf6_spf_process, @@ -817,10 +784,10 @@ DEFUN (no_debug_ospf6_spf_process, "Quit Debugging Detailed SPF Process\n" ) { - unsigned char level = 0; - level = OSPF6_DEBUG_SPF_PROCESS; - OSPF6_DEBUG_SPF_OFF (level); - return CMD_SUCCESS; + unsigned char level = 0; + level = OSPF6_DEBUG_SPF_PROCESS; + OSPF6_DEBUG_SPF_OFF(level); + return CMD_SUCCESS; } DEFUN (no_debug_ospf6_spf_time, @@ -833,10 +800,10 @@ DEFUN (no_debug_ospf6_spf_time, "Quit Measuring time taken by SPF Calculation\n" ) { - unsigned char level = 0; - level = OSPF6_DEBUG_SPF_TIME; - OSPF6_DEBUG_SPF_OFF (level); - return CMD_SUCCESS; + unsigned char level = 0; + level = OSPF6_DEBUG_SPF_TIME; + OSPF6_DEBUG_SPF_OFF(level); + return CMD_SUCCESS; } DEFUN (no_debug_ospf6_spf_database, @@ -849,24 +816,22 @@ DEFUN (no_debug_ospf6_spf_database, "Quit Logging number of LSAs at SPF Calculation time\n" ) { - unsigned char level = 0; - level = OSPF6_DEBUG_SPF_DATABASE; - OSPF6_DEBUG_SPF_OFF (level); - return CMD_SUCCESS; + unsigned char level = 0; + level = OSPF6_DEBUG_SPF_DATABASE; + OSPF6_DEBUG_SPF_OFF(level); + return CMD_SUCCESS; } -static int -ospf6_timers_spf_set (struct vty *vty, unsigned int delay, - unsigned int hold, - unsigned int max) +static int ospf6_timers_spf_set(struct vty *vty, unsigned int delay, + unsigned int hold, unsigned int max) { - VTY_DECLVAR_CONTEXT(ospf6, ospf); + VTY_DECLVAR_CONTEXT(ospf6, ospf); - ospf->spf_delay = delay; - ospf->spf_holdtime = hold; - ospf->spf_max_holdtime = max; + ospf->spf_delay = delay; + ospf->spf_holdtime = hold; + ospf->spf_max_holdtime = max; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (ospf6_timers_throttle_spf, @@ -879,16 +844,16 @@ DEFUN (ospf6_timers_throttle_spf, "Initial hold time (msec) between consecutive SPF calculations\n" "Maximum hold time (msec)\n") { - int idx_number = 3; - int idx_number_2 = 4; - int idx_number_3 = 5; - unsigned int delay, hold, max; + int idx_number = 3; + int idx_number_2 = 4; + int idx_number_3 = 5; + unsigned int delay, hold, max; - delay = strtoul(argv[idx_number]->arg, NULL, 10); - hold = strtoul(argv[idx_number_2]->arg, NULL, 10); - max = strtoul(argv[idx_number_3]->arg, NULL, 10); + delay = strtoul(argv[idx_number]->arg, NULL, 10); + hold = strtoul(argv[idx_number_2]->arg, NULL, 10); + max = strtoul(argv[idx_number_3]->arg, NULL, 10); - return ospf6_timers_spf_set (vty, delay, hold, max); + return ospf6_timers_spf_set(vty, delay, hold, max); } DEFUN (no_ospf6_timers_throttle_spf, @@ -902,58 +867,52 @@ DEFUN (no_ospf6_timers_throttle_spf, "Initial hold time (msec) between consecutive SPF calculations\n" "Maximum hold time (msec)\n") { - return ospf6_timers_spf_set (vty, - OSPF_SPF_DELAY_DEFAULT, - OSPF_SPF_HOLDTIME_DEFAULT, - OSPF_SPF_MAX_HOLDTIME_DEFAULT); + return ospf6_timers_spf_set(vty, OSPF_SPF_DELAY_DEFAULT, + OSPF_SPF_HOLDTIME_DEFAULT, + OSPF_SPF_MAX_HOLDTIME_DEFAULT); } -int -config_write_ospf6_debug_spf (struct vty *vty) +int config_write_ospf6_debug_spf(struct vty *vty) { - if (IS_OSPF6_DEBUG_SPF (PROCESS)) - vty_out (vty, "debug ospf6 spf process\n"); - if (IS_OSPF6_DEBUG_SPF (TIME)) - vty_out (vty, "debug ospf6 spf time\n"); - if (IS_OSPF6_DEBUG_SPF (DATABASE)) - vty_out (vty, "debug ospf6 spf database\n"); - return 0; + if (IS_OSPF6_DEBUG_SPF(PROCESS)) + vty_out(vty, "debug ospf6 spf process\n"); + if (IS_OSPF6_DEBUG_SPF(TIME)) + vty_out(vty, "debug ospf6 spf time\n"); + if (IS_OSPF6_DEBUG_SPF(DATABASE)) + vty_out(vty, "debug ospf6 spf database\n"); + return 0; } -void -ospf6_spf_config_write (struct vty *vty) +void ospf6_spf_config_write(struct vty *vty) { - if (ospf6->spf_delay != OSPF_SPF_DELAY_DEFAULT || - ospf6->spf_holdtime != OSPF_SPF_HOLDTIME_DEFAULT || - ospf6->spf_max_holdtime != OSPF_SPF_MAX_HOLDTIME_DEFAULT) - vty_out (vty, " timers throttle spf %d %d %d\n", - ospf6->spf_delay, ospf6->spf_holdtime, - ospf6->spf_max_holdtime); - + if (ospf6->spf_delay != OSPF_SPF_DELAY_DEFAULT + || ospf6->spf_holdtime != OSPF_SPF_HOLDTIME_DEFAULT + || ospf6->spf_max_holdtime != OSPF_SPF_MAX_HOLDTIME_DEFAULT) + vty_out(vty, " timers throttle spf %d %d %d\n", + ospf6->spf_delay, ospf6->spf_holdtime, + ospf6->spf_max_holdtime); } -void -install_element_ospf6_debug_spf (void) +void install_element_ospf6_debug_spf(void) { - install_element (ENABLE_NODE, &debug_ospf6_spf_process_cmd); - install_element (ENABLE_NODE, &debug_ospf6_spf_time_cmd); - install_element (ENABLE_NODE, &debug_ospf6_spf_database_cmd); - install_element (ENABLE_NODE, &no_debug_ospf6_spf_process_cmd); - install_element (ENABLE_NODE, &no_debug_ospf6_spf_time_cmd); - install_element (ENABLE_NODE, &no_debug_ospf6_spf_database_cmd); - install_element (CONFIG_NODE, &debug_ospf6_spf_process_cmd); - install_element (CONFIG_NODE, &debug_ospf6_spf_time_cmd); - install_element (CONFIG_NODE, &debug_ospf6_spf_database_cmd); - install_element (CONFIG_NODE, &no_debug_ospf6_spf_process_cmd); - install_element (CONFIG_NODE, &no_debug_ospf6_spf_time_cmd); - install_element (CONFIG_NODE, &no_debug_ospf6_spf_database_cmd); + install_element(ENABLE_NODE, &debug_ospf6_spf_process_cmd); + install_element(ENABLE_NODE, &debug_ospf6_spf_time_cmd); + install_element(ENABLE_NODE, &debug_ospf6_spf_database_cmd); + install_element(ENABLE_NODE, &no_debug_ospf6_spf_process_cmd); + install_element(ENABLE_NODE, &no_debug_ospf6_spf_time_cmd); + install_element(ENABLE_NODE, &no_debug_ospf6_spf_database_cmd); + install_element(CONFIG_NODE, &debug_ospf6_spf_process_cmd); + install_element(CONFIG_NODE, &debug_ospf6_spf_time_cmd); + install_element(CONFIG_NODE, &debug_ospf6_spf_database_cmd); + install_element(CONFIG_NODE, &no_debug_ospf6_spf_process_cmd); + install_element(CONFIG_NODE, &no_debug_ospf6_spf_time_cmd); + install_element(CONFIG_NODE, &no_debug_ospf6_spf_database_cmd); } -void -ospf6_spf_init (void) +void ospf6_spf_init(void) { - install_element (OSPF6_NODE, &ospf6_timers_throttle_spf_cmd); - install_element (OSPF6_NODE, &no_ospf6_timers_throttle_spf_cmd); + install_element(OSPF6_NODE, &ospf6_timers_throttle_spf_cmd); + install_element(OSPF6_NODE, &no_ospf6_timers_throttle_spf_cmd); } diff --git a/ospf6d/ospf6_spf.h b/ospf6d/ospf6_spf.h index 87a86c0ac..2246e2dfc 100644 --- a/ospf6d/ospf6_spf.h +++ b/ospf6d/ospf6_spf.h @@ -28,55 +28,51 @@ extern unsigned char conf_debug_ospf6_spf; #define OSPF6_DEBUG_SPF_PROCESS 0x01 #define OSPF6_DEBUG_SPF_TIME 0x02 #define OSPF6_DEBUG_SPF_DATABASE 0x04 -#define OSPF6_DEBUG_SPF_ON(level) \ - (conf_debug_ospf6_spf |= (level)) -#define OSPF6_DEBUG_SPF_OFF(level) \ - (conf_debug_ospf6_spf &= ~(level)) -#define IS_OSPF6_DEBUG_SPF(level) \ - (conf_debug_ospf6_spf & OSPF6_DEBUG_SPF_ ## level) +#define OSPF6_DEBUG_SPF_ON(level) (conf_debug_ospf6_spf |= (level)) +#define OSPF6_DEBUG_SPF_OFF(level) (conf_debug_ospf6_spf &= ~(level)) +#define IS_OSPF6_DEBUG_SPF(level) \ + (conf_debug_ospf6_spf & OSPF6_DEBUG_SPF_##level) /* Transit Vertex */ -struct ospf6_vertex -{ - /* type of this vertex */ - u_int8_t type; +struct ospf6_vertex { + /* type of this vertex */ + u_int8_t type; - /* Vertex Identifier */ - struct prefix vertex_id; + /* Vertex Identifier */ + struct prefix vertex_id; - /* Identifier String */ - char name[128]; + /* Identifier String */ + char name[128]; - /* Associated Area */ - struct ospf6_area *area; + /* Associated Area */ + struct ospf6_area *area; - /* Associated LSA */ - struct ospf6_lsa *lsa; + /* Associated LSA */ + struct ospf6_lsa *lsa; - /* Distance from Root (i.e. Cost) */ - u_int32_t cost; + /* Distance from Root (i.e. Cost) */ + u_int32_t cost; - /* Router hops to this node */ - u_char hops; + /* Router hops to this node */ + u_char hops; - /* capability bits */ - u_char capability; + /* capability bits */ + u_char capability; - /* Optional capabilities */ - u_char options[3]; + /* Optional capabilities */ + u_char options[3]; - /* For tree display */ - struct ospf6_vertex *parent; - struct list *child_list; + /* For tree display */ + struct ospf6_vertex *parent; + struct list *child_list; - /* nexthops to this node */ - struct list *nh_list; + /* nexthops to this node */ + struct list *nh_list; }; #define OSPF6_VERTEX_TYPE_ROUTER 0x01 #define OSPF6_VERTEX_TYPE_NETWORK 0x02 -#define VERTEX_IS_TYPE(t, v) \ - ((v)->type == OSPF6_VERTEX_TYPE_ ## t ? 1 : 0) +#define VERTEX_IS_TYPE(t, v) ((v)->type == OSPF6_VERTEX_TYPE_##t ? 1 : 0) /* What triggered the SPF? */ #define OSPF6_SPF_FLAGS_ROUTER_LSA_ADDED (1 << 0) @@ -88,76 +84,69 @@ struct ospf6_vertex #define OSPF6_SPF_FLAGS_ROUTER_LSA_ORIGINATED (1 << 6) #define OSPF6_SPF_FLAGS_NETWORK_LSA_ORIGINATED (1 << 7) -static inline void -ospf6_set_spf_reason (struct ospf6* ospf, unsigned int reason) +static inline void ospf6_set_spf_reason(struct ospf6 *ospf, unsigned int reason) { - ospf->spf_reason |= reason; + ospf->spf_reason |= reason; } -static inline void -ospf6_reset_spf_reason (struct ospf6 *ospf) +static inline void ospf6_reset_spf_reason(struct ospf6 *ospf) { - ospf->spf_reason = 0; + ospf->spf_reason = 0; } -static inline unsigned int -ospf6_lsadd_to_spf_reason (struct ospf6_lsa *lsa) +static inline unsigned int ospf6_lsadd_to_spf_reason(struct ospf6_lsa *lsa) { - unsigned int reason = 0; - - switch (ntohs (lsa->header->type)) - { - case OSPF6_LSTYPE_ROUTER: - reason = OSPF6_SPF_FLAGS_ROUTER_LSA_ADDED; - break; - case OSPF6_LSTYPE_NETWORK: - reason = OSPF6_SPF_FLAGS_NETWORK_LSA_ADDED; - break; - case OSPF6_LSTYPE_LINK: - reason = OSPF6_SPF_FLAGS_LINK_LSA_ADDED; - break; - default: - break; - } - return (reason); + unsigned int reason = 0; + + switch (ntohs(lsa->header->type)) { + case OSPF6_LSTYPE_ROUTER: + reason = OSPF6_SPF_FLAGS_ROUTER_LSA_ADDED; + break; + case OSPF6_LSTYPE_NETWORK: + reason = OSPF6_SPF_FLAGS_NETWORK_LSA_ADDED; + break; + case OSPF6_LSTYPE_LINK: + reason = OSPF6_SPF_FLAGS_LINK_LSA_ADDED; + break; + default: + break; + } + return (reason); } -static inline unsigned int -ospf6_lsremove_to_spf_reason (struct ospf6_lsa *lsa) +static inline unsigned int ospf6_lsremove_to_spf_reason(struct ospf6_lsa *lsa) { - unsigned int reason = 0; - - switch (ntohs (lsa->header->type)) - { - case OSPF6_LSTYPE_ROUTER: - reason = OSPF6_SPF_FLAGS_ROUTER_LSA_REMOVED; - break; - case OSPF6_LSTYPE_NETWORK: - reason = OSPF6_SPF_FLAGS_NETWORK_LSA_REMOVED; - break; - case OSPF6_LSTYPE_LINK: - reason = OSPF6_SPF_FLAGS_LINK_LSA_REMOVED; - break; - default: - break; - } - return (reason); + unsigned int reason = 0; + + switch (ntohs(lsa->header->type)) { + case OSPF6_LSTYPE_ROUTER: + reason = OSPF6_SPF_FLAGS_ROUTER_LSA_REMOVED; + break; + case OSPF6_LSTYPE_NETWORK: + reason = OSPF6_SPF_FLAGS_NETWORK_LSA_REMOVED; + break; + case OSPF6_LSTYPE_LINK: + reason = OSPF6_SPF_FLAGS_LINK_LSA_REMOVED; + break; + default: + break; + } + return (reason); } -extern void ospf6_spf_table_finish (struct ospf6_route_table *result_table); -extern void ospf6_spf_calculation (u_int32_t router_id, - struct ospf6_route_table *result_table, - struct ospf6_area *oa); -extern void ospf6_spf_schedule (struct ospf6 *ospf, unsigned int reason); +extern void ospf6_spf_table_finish(struct ospf6_route_table *result_table); +extern void ospf6_spf_calculation(u_int32_t router_id, + struct ospf6_route_table *result_table, + struct ospf6_area *oa); +extern void ospf6_spf_schedule(struct ospf6 *ospf, unsigned int reason); -extern void ospf6_spf_display_subtree (struct vty *vty, const char *prefix, - int rest, struct ospf6_vertex *v); +extern void ospf6_spf_display_subtree(struct vty *vty, const char *prefix, + int rest, struct ospf6_vertex *v); -extern void ospf6_spf_config_write (struct vty *vty); -extern int config_write_ospf6_debug_spf (struct vty *vty); -extern void install_element_ospf6_debug_spf (void); -extern void ospf6_spf_init (void); -extern void ospf6_spf_reason_string (unsigned int reason, char *buf, int size); +extern void ospf6_spf_config_write(struct vty *vty); +extern int config_write_ospf6_debug_spf(struct vty *vty); +extern void install_element_ospf6_debug_spf(void); +extern void ospf6_spf_init(void); +extern void ospf6_spf_reason_string(unsigned int reason, char *buf, int size); #endif /* OSPF6_SPF_H */ - diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index 9e0b86b7b..387690bc8 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -54,240 +54,218 @@ DEFINE_QOBJ_TYPE(ospf6) /* global ospf6d variable */ struct ospf6 *ospf6; -static void ospf6_disable (struct ospf6 *o); +static void ospf6_disable(struct ospf6 *o); -static void -ospf6_top_lsdb_hook_add (struct ospf6_lsa *lsa) +static void ospf6_top_lsdb_hook_add(struct ospf6_lsa *lsa) { - switch (ntohs (lsa->header->type)) - { - case OSPF6_LSTYPE_AS_EXTERNAL: - ospf6_asbr_lsa_add (lsa); - break; - - default: - break; - } + switch (ntohs(lsa->header->type)) { + case OSPF6_LSTYPE_AS_EXTERNAL: + ospf6_asbr_lsa_add(lsa); + break; + + default: + break; + } } -static void -ospf6_top_lsdb_hook_remove (struct ospf6_lsa *lsa) +static void ospf6_top_lsdb_hook_remove(struct ospf6_lsa *lsa) { - switch (ntohs (lsa->header->type)) - { - case OSPF6_LSTYPE_AS_EXTERNAL: - ospf6_asbr_lsa_remove (lsa); - break; - - default: - break; - } + switch (ntohs(lsa->header->type)) { + case OSPF6_LSTYPE_AS_EXTERNAL: + ospf6_asbr_lsa_remove(lsa); + break; + + default: + break; + } } -static void -ospf6_top_route_hook_add (struct ospf6_route *route) +static void ospf6_top_route_hook_add(struct ospf6_route *route) { - ospf6_abr_originate_summary (route); - ospf6_zebra_route_update_add (route); + ospf6_abr_originate_summary(route); + ospf6_zebra_route_update_add(route); } -static void -ospf6_top_route_hook_remove (struct ospf6_route *route) +static void ospf6_top_route_hook_remove(struct ospf6_route *route) { - route->flag |= OSPF6_ROUTE_REMOVE; - ospf6_abr_originate_summary (route); - ospf6_zebra_route_update_remove (route); + route->flag |= OSPF6_ROUTE_REMOVE; + ospf6_abr_originate_summary(route); + ospf6_zebra_route_update_remove(route); } -static void -ospf6_top_brouter_hook_add (struct ospf6_route *route) +static void ospf6_top_brouter_hook_add(struct ospf6_route *route) { - ospf6_abr_examin_brouter (ADV_ROUTER_IN_PREFIX (&route->prefix)); - ospf6_asbr_lsentry_add (route); - ospf6_abr_originate_summary (route); + ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix)); + ospf6_asbr_lsentry_add(route); + ospf6_abr_originate_summary(route); } -static void -ospf6_top_brouter_hook_remove (struct ospf6_route *route) +static void ospf6_top_brouter_hook_remove(struct ospf6_route *route) { - route->flag |= OSPF6_ROUTE_REMOVE; - ospf6_abr_examin_brouter (ADV_ROUTER_IN_PREFIX (&route->prefix)); - ospf6_asbr_lsentry_remove (route); - ospf6_abr_originate_summary (route); + route->flag |= OSPF6_ROUTE_REMOVE; + ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix)); + ospf6_asbr_lsentry_remove(route); + ospf6_abr_originate_summary(route); } -static struct ospf6 * -ospf6_create (void) +static struct ospf6 *ospf6_create(void) { - struct ospf6 *o; + struct ospf6 *o; - o = XCALLOC (MTYPE_OSPF6_TOP, sizeof (struct ospf6)); + o = XCALLOC(MTYPE_OSPF6_TOP, sizeof(struct ospf6)); - /* initialize */ - monotime(&o->starttime); - o->area_list = list_new (); - o->area_list->cmp = ospf6_area_cmp; - 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; + /* initialize */ + monotime(&o->starttime); + o->area_list = list_new(); + o->area_list->cmp = ospf6_area_cmp; + 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; - o->spf_delay = OSPF_SPF_DELAY_DEFAULT; - o->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT; - o->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT; - o->spf_hold_multiplier = 1; + o->spf_delay = OSPF_SPF_DELAY_DEFAULT; + o->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT; + o->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT; + o->spf_hold_multiplier = 1; - /* LSA timers value init */ - o->lsa_minarrival = OSPF_MIN_LS_ARRIVAL; + /* LSA timers value init */ + o->lsa_minarrival = OSPF_MIN_LS_ARRIVAL; - o->route_table = OSPF6_ROUTE_TABLE_CREATE (GLOBAL, ROUTES); - o->route_table->scope = o; - o->route_table->hook_add = ospf6_top_route_hook_add; - o->route_table->hook_remove = ospf6_top_route_hook_remove; + o->route_table = OSPF6_ROUTE_TABLE_CREATE(GLOBAL, ROUTES); + o->route_table->scope = o; + o->route_table->hook_add = ospf6_top_route_hook_add; + o->route_table->hook_remove = ospf6_top_route_hook_remove; - o->brouter_table = OSPF6_ROUTE_TABLE_CREATE (GLOBAL, BORDER_ROUTERS); - o->brouter_table->scope = o; - o->brouter_table->hook_add = ospf6_top_brouter_hook_add; - o->brouter_table->hook_remove = ospf6_top_brouter_hook_remove; + o->brouter_table = OSPF6_ROUTE_TABLE_CREATE(GLOBAL, BORDER_ROUTERS); + o->brouter_table->scope = o; + 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 (GLOBAL, EXTERNAL_ROUTES); - o->external_table->scope = o; + o->external_table = OSPF6_ROUTE_TABLE_CREATE(GLOBAL, EXTERNAL_ROUTES); + o->external_table->scope = o; - o->external_id_table = route_table_init (); + o->external_id_table = route_table_init(); - o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH; + o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH; - o->distance_table = route_table_init (); + o->distance_table = route_table_init(); - /* Enable "log-adjacency-changes" */ +/* Enable "log-adjacency-changes" */ #if DFLT_OSPF6_LOG_ADJACENCY_CHANGES - SET_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES); + SET_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES); #endif - QOBJ_REG (o, ospf6); + QOBJ_REG(o, ospf6); - return o; + return o; } -void -ospf6_delete (struct ospf6 *o) +void ospf6_delete(struct ospf6 *o) { - struct listnode *node, *nnode; - struct ospf6_area *oa; + struct listnode *node, *nnode; + struct ospf6_area *oa; - QOBJ_UNREG (o); - ospf6_disable (ospf6); + QOBJ_UNREG(o); + ospf6_disable(ospf6); - for (ALL_LIST_ELEMENTS (o->area_list, node, nnode, oa)) - ospf6_area_delete (oa); + for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa)) + ospf6_area_delete(oa); - list_delete (o->area_list); + list_delete(o->area_list); - ospf6_lsdb_delete (o->lsdb); - ospf6_lsdb_delete (o->lsdb_self); + ospf6_lsdb_delete(o->lsdb); + ospf6_lsdb_delete(o->lsdb_self); - ospf6_route_table_delete (o->route_table); - ospf6_route_table_delete (o->brouter_table); + ospf6_route_table_delete(o->route_table); + ospf6_route_table_delete(o->brouter_table); - ospf6_route_table_delete (o->external_table); - route_table_finish (o->external_id_table); + ospf6_route_table_delete(o->external_table); + route_table_finish(o->external_id_table); - ospf6_distance_reset (o); - route_table_finish (o->distance_table); + ospf6_distance_reset(o); + route_table_finish(o->distance_table); - XFREE (MTYPE_OSPF6_TOP, o); + XFREE(MTYPE_OSPF6_TOP, o); } -static void -ospf6_disable (struct ospf6 *o) +static void ospf6_disable(struct ospf6 *o) { - struct listnode *node, *nnode; - struct ospf6_area *oa; - - if (! CHECK_FLAG (o->flag, OSPF6_DISABLED)) - { - SET_FLAG (o->flag, OSPF6_DISABLED); - - for (ALL_LIST_ELEMENTS (o->area_list, node, nnode, oa)) - ospf6_area_disable (oa); - - /* XXX: This also changes persistent settings */ - ospf6_asbr_redistribute_reset(); - - ospf6_lsdb_remove_all (o->lsdb); - ospf6_route_remove_all (o->route_table); - ospf6_route_remove_all (o->brouter_table); - - THREAD_OFF(o->maxage_remover); - THREAD_OFF(o->t_spf_calc); - THREAD_OFF(o->t_ase_calc); - } + struct listnode *node, *nnode; + struct ospf6_area *oa; + + if (!CHECK_FLAG(o->flag, OSPF6_DISABLED)) { + SET_FLAG(o->flag, OSPF6_DISABLED); + + for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa)) + ospf6_area_disable(oa); + + /* XXX: This also changes persistent settings */ + ospf6_asbr_redistribute_reset(); + + ospf6_lsdb_remove_all(o->lsdb); + ospf6_route_remove_all(o->route_table); + ospf6_route_remove_all(o->brouter_table); + + THREAD_OFF(o->maxage_remover); + THREAD_OFF(o->t_spf_calc); + THREAD_OFF(o->t_ase_calc); + } } -static int -ospf6_maxage_remover (struct thread *thread) +static int ospf6_maxage_remover(struct thread *thread) { - struct ospf6 *o = (struct ospf6 *) THREAD_ARG (thread); - struct ospf6_area *oa; - struct ospf6_interface *oi; - struct ospf6_neighbor *on; - struct listnode *i, *j, *k; - int reschedule = 0; - - o->maxage_remover = (struct thread *) NULL; - - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi)) - { - for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, k, on)) - { - if (on->state != OSPF6_NEIGHBOR_EXCHANGE && - on->state != OSPF6_NEIGHBOR_LOADING) - continue; - - ospf6_maxage_remove (o); - return 0; - } - } - } - - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi)) - { - if (ospf6_lsdb_maxage_remover (oi->lsdb)) - { - reschedule = 1; - } + struct ospf6 *o = (struct ospf6 *)THREAD_ARG(thread); + struct ospf6_area *oa; + struct ospf6_interface *oi; + struct ospf6_neighbor *on; + struct listnode *i, *j, *k; + int reschedule = 0; + + o->maxage_remover = (struct thread *)NULL; + + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { + for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, k, on)) { + if (on->state != OSPF6_NEIGHBOR_EXCHANGE + && on->state != OSPF6_NEIGHBOR_LOADING) + continue; + + ospf6_maxage_remove(o); + return 0; + } + } } - - if (ospf6_lsdb_maxage_remover (oa->lsdb)) - { - reschedule = 1; + + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { + if (ospf6_lsdb_maxage_remover(oi->lsdb)) { + reschedule = 1; + } + } + + if (ospf6_lsdb_maxage_remover(oa->lsdb)) { + reschedule = 1; + } } - } - if (ospf6_lsdb_maxage_remover (o->lsdb)) - { - reschedule = 1; - } + if (ospf6_lsdb_maxage_remover(o->lsdb)) { + reschedule = 1; + } - if (reschedule) - { - ospf6_maxage_remove (o); - } + if (reschedule) { + ospf6_maxage_remove(o); + } - return 0; + return 0; } -void -ospf6_maxage_remove (struct ospf6 *o) +void ospf6_maxage_remove(struct ospf6 *o) { - if (o) - thread_add_timer(master, ospf6_maxage_remover, o, OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT, - &o->maxage_remover); + if (o) + thread_add_timer(master, ospf6_maxage_remover, o, + OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT, + &o->maxage_remover); } /* start ospf6 */ @@ -297,13 +275,13 @@ DEFUN_NOSH (router_ospf6, ROUTER_STR OSPF6_STR) { - if (ospf6 == NULL) - ospf6 = ospf6_create (); + if (ospf6 == NULL) + ospf6 = ospf6_create(); - /* set current ospf point. */ - VTY_PUSH_CONTEXT(OSPF6_NODE, ospf6); + /* set current ospf point. */ + VTY_PUSH_CONTEXT(OSPF6_NODE, ospf6); - return CMD_SUCCESS; + return CMD_SUCCESS; } /* stop ospf6 */ @@ -314,18 +292,17 @@ DEFUN (no_router_ospf6, ROUTER_STR OSPF6_STR) { - if (ospf6 == NULL) - vty_out (vty, "OSPFv3 is not configured\n"); - else - { - ospf6_delete (ospf6); - ospf6 = NULL; - } + if (ospf6 == NULL) + vty_out(vty, "OSPFv3 is not configured\n"); + else { + ospf6_delete(ospf6); + ospf6 = NULL; + } - /* return to config node . */ - VTY_PUSH_CONTEXT_NULL(CONFIG_NODE); + /* return to config node . */ + VTY_PUSH_CONTEXT_NULL(CONFIG_NODE); - return CMD_SUCCESS; + return CMD_SUCCESS; } /* change Router_ID commands. */ @@ -335,23 +312,23 @@ DEFUN (ospf6_router_id, "Configure OSPF Router-ID\n" V4NOTATION_STR) { - VTY_DECLVAR_CONTEXT(ospf6, o); - int idx_ipv4 = 1; - int ret; - u_int32_t router_id; - - ret = inet_pton (AF_INET, argv[idx_ipv4]->arg, &router_id); - if (ret == 0) - { - vty_out (vty, "malformed OSPF Router-ID: %s\n", argv[idx_ipv4]->arg); - return CMD_SUCCESS; - } + VTY_DECLVAR_CONTEXT(ospf6, o); + int idx_ipv4 = 1; + int ret; + u_int32_t router_id; + + ret = inet_pton(AF_INET, argv[idx_ipv4]->arg, &router_id); + if (ret == 0) { + vty_out(vty, "malformed OSPF Router-ID: %s\n", + argv[idx_ipv4]->arg); + return CMD_SUCCESS; + } - o->router_id_static = router_id; - if (o->router_id == 0) - o->router_id = router_id; + o->router_id_static = router_id; + if (o->router_id == 0) + o->router_id = router_id; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (ospf6_log_adjacency_changes, @@ -359,11 +336,11 @@ DEFUN (ospf6_log_adjacency_changes, "log-adjacency-changes", "Log changes in adjacency state\n") { - VTY_DECLVAR_CONTEXT(ospf6, ospf6); + VTY_DECLVAR_CONTEXT(ospf6, ospf6); - SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES); - UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL); - return CMD_SUCCESS; + SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES); + UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL); + return CMD_SUCCESS; } DEFUN (ospf6_log_adjacency_changes_detail, @@ -372,11 +349,11 @@ DEFUN (ospf6_log_adjacency_changes_detail, "Log changes in adjacency state\n" "Log all state changes\n") { - VTY_DECLVAR_CONTEXT(ospf6, ospf6); + VTY_DECLVAR_CONTEXT(ospf6, ospf6); - SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES); - SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL); - return CMD_SUCCESS; + SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES); + SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL); + return CMD_SUCCESS; } DEFUN (no_ospf6_log_adjacency_changes, @@ -385,11 +362,11 @@ DEFUN (no_ospf6_log_adjacency_changes, NO_STR "Log changes in adjacency state\n") { - VTY_DECLVAR_CONTEXT(ospf6, ospf6); + VTY_DECLVAR_CONTEXT(ospf6, ospf6); - UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL); - UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES); - return CMD_SUCCESS; + UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL); + UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES); + return CMD_SUCCESS; } DEFUN (no_ospf6_log_adjacency_changes_detail, @@ -399,10 +376,10 @@ DEFUN (no_ospf6_log_adjacency_changes_detail, "Log changes in adjacency state\n" "Log all state changes\n") { - VTY_DECLVAR_CONTEXT(ospf6, ospf6); + VTY_DECLVAR_CONTEXT(ospf6, ospf6); - UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL); - return CMD_SUCCESS; + UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL); + return CMD_SUCCESS; } DEFUN (ospf6_timers_lsa, @@ -413,14 +390,14 @@ DEFUN (ospf6_timers_lsa, "Minimum delay in receiving new version of a LSA\n" "Delay in milliseconds\n") { - VTY_DECLVAR_CONTEXT(ospf6, ospf); - int idx_number = 3; - unsigned int minarrival; + VTY_DECLVAR_CONTEXT(ospf6, ospf); + int idx_number = 3; + unsigned int minarrival; - minarrival = strtoul(argv[idx_number]->arg, NULL, 10); - ospf->lsa_minarrival = minarrival; + minarrival = strtoul(argv[idx_number]->arg, NULL, 10); + ospf->lsa_minarrival = minarrival; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ospf6_timers_lsa, @@ -432,22 +409,21 @@ DEFUN (no_ospf6_timers_lsa, "Minimum delay in receiving new version of a LSA\n" "Delay in milliseconds\n") { - VTY_DECLVAR_CONTEXT(ospf6, ospf); - int idx_number = 4; - unsigned int minarrival; + VTY_DECLVAR_CONTEXT(ospf6, ospf); + int idx_number = 4; + unsigned int minarrival; - if (argc == 5) - { - minarrival = strtoul(argv[idx_number]->arg, NULL, 10); + if (argc == 5) { + minarrival = strtoul(argv[idx_number]->arg, NULL, 10); - if (ospf->lsa_minarrival != minarrival || - minarrival == OSPF_MIN_LS_ARRIVAL) - return CMD_SUCCESS; - } + if (ospf->lsa_minarrival != minarrival + || minarrival == OSPF_MIN_LS_ARRIVAL) + return CMD_SUCCESS; + } - ospf->lsa_minarrival = OSPF_MIN_LS_ARRIVAL; + ospf->lsa_minarrival = OSPF_MIN_LS_ARRIVAL; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -457,11 +433,11 @@ DEFUN (ospf6_distance, "Administrative distance\n" "OSPF6 Administrative distance\n") { - VTY_DECLVAR_CONTEXT(ospf6, o); + VTY_DECLVAR_CONTEXT(ospf6, o); - o->distance_all = atoi (argv[1]->arg); + o->distance_all = atoi(argv[1]->arg); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ospf6_distance, @@ -471,11 +447,11 @@ DEFUN (no_ospf6_distance, "Administrative distance\n" "OSPF6 Administrative distance\n") { - VTY_DECLVAR_CONTEXT(ospf6, o); + VTY_DECLVAR_CONTEXT(ospf6, o); - o->distance_all = 0; + o->distance_all = 0; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (ospf6_distance_ospf6, @@ -490,19 +466,19 @@ DEFUN (ospf6_distance_ospf6, "External routes\n" "Distance for external routes\n") { - VTY_DECLVAR_CONTEXT(ospf6, o); - int idx = 0; + VTY_DECLVAR_CONTEXT(ospf6, o); + int idx = 0; + + if (argv_find(argv, argc, "intra-area", &idx)) + o->distance_intra = atoi(argv[idx + 1]->arg); + idx = 0; + if (argv_find(argv, argc, "inter-area", &idx)) + o->distance_inter = atoi(argv[idx + 1]->arg); + idx = 0; + if (argv_find(argv, argc, "external", &idx)) + o->distance_external = atoi(argv[idx + 1]->arg); - if (argv_find (argv, argc, "intra-area", &idx)) - o->distance_intra = atoi(argv[idx + 1]->arg); - idx = 0; - if (argv_find (argv, argc, "inter-area", &idx)) - o->distance_inter = atoi(argv[idx + 1]->arg); - idx = 0; - if (argv_find (argv, argc, "external", &idx)) - o->distance_external = atoi(argv[idx + 1]->arg); - - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ospf6_distance_ospf6, @@ -518,17 +494,17 @@ DEFUN (no_ospf6_distance_ospf6, "External routes\n" "Distance for external routes\n") { - VTY_DECLVAR_CONTEXT(ospf6, o); - int idx = 0; + VTY_DECLVAR_CONTEXT(ospf6, o); + int idx = 0; - if (argv_find (argv, argc, "intra-area", &idx) || argc == 3) - idx = o->distance_intra = 0; - if (argv_find (argv, argc, "inter-area", &idx) || argc == 3) - idx = o->distance_inter = 0; - if (argv_find (argv, argc, "external", &idx) || argc == 3) - o->distance_external = 0; + if (argv_find(argv, argc, "intra-area", &idx) || argc == 3) + idx = o->distance_intra = 0; + if (argv_find(argv, argc, "inter-area", &idx) || argc == 3) + idx = o->distance_inter = 0; + if (argv_find(argv, argc, "external", &idx) || argc == 3) + o->distance_external = 0; - return CMD_SUCCESS; + return CMD_SUCCESS; } #if 0 @@ -573,56 +549,54 @@ DEFUN (ospf6_interface_area, "OSPF6 area ID in IPv4 address notation\n" ) { - VTY_DECLVAR_CONTEXT(ospf6, o); - int idx_ifname = 1; - int idx_ipv4 = 3; - struct ospf6_area *oa; - struct ospf6_interface *oi; - struct interface *ifp; - u_int32_t area_id; - - /* find/create ospf6 interface */ - ifp = if_get_by_name (argv[idx_ifname]->arg, VRF_DEFAULT); - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) - oi = ospf6_interface_create (ifp); - if (oi->area) - { - vty_out (vty, "%s already attached to Area %s\n", - oi->interface->name, oi->area->name); - return CMD_SUCCESS; - } - - /* parse Area-ID */ - if (inet_pton (AF_INET, argv[idx_ipv4]->arg, &area_id) != 1) - { - vty_out (vty, "Invalid Area-ID: %s\n", argv[idx_ipv4]->arg); - return CMD_SUCCESS; - } - - /* find/create ospf6 area */ - oa = ospf6_area_lookup (area_id, o); - if (oa == NULL) - oa = ospf6_area_create (area_id, o, OSPF6_AREA_FMT_DOTTEDQUAD); - - /* attach interface to area */ - listnode_add (oa->if_list, oi); /* sort ?? */ - oi->area = oa; - - SET_FLAG (oa->flag, OSPF6_AREA_ENABLE); - - /* ospf6 process is currently disabled, not much more to do */ - if (CHECK_FLAG (o->flag, OSPF6_DISABLED)) - return CMD_SUCCESS; - - /* start up */ - ospf6_interface_enable (oi); - - /* If the router is ABR, originate summary routes */ - if (ospf6_is_router_abr (o)) - ospf6_abr_enable_area (oa); + VTY_DECLVAR_CONTEXT(ospf6, o); + int idx_ifname = 1; + int idx_ipv4 = 3; + struct ospf6_area *oa; + struct ospf6_interface *oi; + struct interface *ifp; + u_int32_t area_id; + + /* find/create ospf6 interface */ + ifp = if_get_by_name(argv[idx_ifname]->arg, VRF_DEFAULT); + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) + oi = ospf6_interface_create(ifp); + if (oi->area) { + vty_out(vty, "%s already attached to Area %s\n", + oi->interface->name, oi->area->name); + return CMD_SUCCESS; + } - return CMD_SUCCESS; + /* parse Area-ID */ + if (inet_pton(AF_INET, argv[idx_ipv4]->arg, &area_id) != 1) { + vty_out(vty, "Invalid Area-ID: %s\n", argv[idx_ipv4]->arg); + return CMD_SUCCESS; + } + + /* find/create ospf6 area */ + oa = ospf6_area_lookup(area_id, o); + if (oa == NULL) + oa = ospf6_area_create(area_id, o, OSPF6_AREA_FMT_DOTTEDQUAD); + + /* attach interface to area */ + listnode_add(oa->if_list, oi); /* sort ?? */ + oi->area = oa; + + SET_FLAG(oa->flag, OSPF6_AREA_ENABLE); + + /* ospf6 process is currently disabled, not much more to do */ + if (CHECK_FLAG(o->flag, OSPF6_DISABLED)) + return CMD_SUCCESS; + + /* start up */ + ospf6_interface_enable(oi); + + /* If the router is ABR, originate summary routes */ + if (ospf6_is_router_abr(o)) + ospf6_abr_enable_area(oa); + + return CMD_SUCCESS; } DEFUN (no_ospf6_interface_area, @@ -635,62 +609,56 @@ DEFUN (no_ospf6_interface_area, "OSPF6 area ID in IPv4 address notation\n" ) { - int idx_ifname = 2; - int idx_ipv4 = 4; - struct ospf6_interface *oi; - struct ospf6_area *oa; - struct interface *ifp; - u_int32_t area_id; - - ifp = if_lookup_by_name (argv[idx_ifname]->arg, VRF_DEFAULT); - if (ifp == NULL) - { - vty_out (vty, "No such interface %s\n", argv[idx_ifname]->arg); - return CMD_SUCCESS; - } - - oi = (struct ospf6_interface *) ifp->info; - if (oi == NULL) - { - vty_out (vty, "Interface %s not enabled\n", ifp->name); - return CMD_SUCCESS; - } - - /* parse Area-ID */ - if (inet_pton (AF_INET, argv[idx_ipv4]->arg, &area_id) != 1) - { - vty_out (vty, "Invalid Area-ID: %s\n", argv[idx_ipv4]->arg); - return CMD_SUCCESS; - } - - /* Verify Area */ - if (oi->area == NULL) - { - vty_out (vty, "No such Area-ID: %s\n", argv[idx_ipv4]->arg); - return CMD_SUCCESS; - } - - if (oi->area->area_id != area_id) - { - vty_out (vty, "Wrong Area-ID: %s is attached to area %s\n", - oi->interface->name, oi->area->name); - return CMD_SUCCESS; - } - - 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); - ospf6_abr_disable_area (oa); - } + int idx_ifname = 2; + int idx_ipv4 = 4; + struct ospf6_interface *oi; + struct ospf6_area *oa; + struct interface *ifp; + u_int32_t area_id; + + ifp = if_lookup_by_name(argv[idx_ifname]->arg, VRF_DEFAULT); + if (ifp == NULL) { + vty_out(vty, "No such interface %s\n", argv[idx_ifname]->arg); + return CMD_SUCCESS; + } - return CMD_SUCCESS; + oi = (struct ospf6_interface *)ifp->info; + if (oi == NULL) { + vty_out(vty, "Interface %s not enabled\n", ifp->name); + return CMD_SUCCESS; + } + + /* parse Area-ID */ + if (inet_pton(AF_INET, argv[idx_ipv4]->arg, &area_id) != 1) { + vty_out(vty, "Invalid Area-ID: %s\n", argv[idx_ipv4]->arg); + return CMD_SUCCESS; + } + + /* Verify Area */ + if (oi->area == NULL) { + vty_out(vty, "No such Area-ID: %s\n", argv[idx_ipv4]->arg); + return CMD_SUCCESS; + } + + if (oi->area->area_id != area_id) { + vty_out(vty, "Wrong Area-ID: %s is attached to area %s\n", + oi->interface->name, oi->area->name); + return CMD_SUCCESS; + } + + 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); + ospf6_abr_disable_area(oa); + } + + return CMD_SUCCESS; } DEFUN (ospf6_stub_router_admin, @@ -699,21 +667,19 @@ DEFUN (ospf6_stub_router_admin, "Make router a stub router\n" "Administratively applied, for an indefinite period\n") { - struct listnode *node; - struct ospf6_area *oa; - - if (!CHECK_FLAG (ospf6->flag, OSPF6_STUB_ROUTER)) - { - for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa)) - { - OSPF6_OPT_CLEAR (oa->options, OSPF6_OPT_V6); - OSPF6_OPT_CLEAR (oa->options, OSPF6_OPT_R); - OSPF6_ROUTER_LSA_SCHEDULE (oa); + struct listnode *node; + struct ospf6_area *oa; + + if (!CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) { + OSPF6_OPT_CLEAR(oa->options, OSPF6_OPT_V6); + OSPF6_OPT_CLEAR(oa->options, OSPF6_OPT_R); + OSPF6_ROUTER_LSA_SCHEDULE(oa); + } + SET_FLAG(ospf6->flag, OSPF6_STUB_ROUTER); } - SET_FLAG (ospf6->flag, OSPF6_STUB_ROUTER); - } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ospf6_stub_router_admin, @@ -723,21 +689,19 @@ DEFUN (no_ospf6_stub_router_admin, "Make router a stub router\n" "Administratively applied, for an indefinite period\n") { - struct listnode *node; - struct ospf6_area *oa; - - if (CHECK_FLAG (ospf6->flag, OSPF6_STUB_ROUTER)) - { - for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa)) - { - OSPF6_OPT_SET (oa->options, OSPF6_OPT_V6); - OSPF6_OPT_SET (oa->options, OSPF6_OPT_R); - OSPF6_ROUTER_LSA_SCHEDULE (oa); + struct listnode *node; + struct ospf6_area *oa; + + if (CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) { + OSPF6_OPT_SET(oa->options, OSPF6_OPT_V6); + OSPF6_OPT_SET(oa->options, OSPF6_OPT_R); + OSPF6_ROUTER_LSA_SCHEDULE(oa); + } + UNSET_FLAG(ospf6->flag, OSPF6_STUB_ROUTER); } - UNSET_FLAG (ospf6->flag, OSPF6_STUB_ROUTER); - } - return CMD_SUCCESS; + return CMD_SUCCESS; } #if 0 @@ -788,81 +752,75 @@ DEFUN (no_ospf6_stub_router_shutdown, } #endif -static void -ospf6_show (struct vty *vty, struct ospf6 *o) +static void ospf6_show(struct vty *vty, struct ospf6 *o) { - struct listnode *n; - struct ospf6_area *oa; - char router_id[16], duration[32]; - struct timeval now, running, result; - char buf[32], rbuf[32]; - - /* process id, router id */ - inet_ntop (AF_INET, &o->router_id, router_id, sizeof (router_id)); - vty_out (vty, " OSPFv3 Routing Process (0) with Router-ID %s\n", - router_id); - - /* running time */ - monotime(&now); - timersub (&now, &o->starttime, &running); - timerstring (&running, duration, sizeof (duration)); - vty_out (vty, " Running %s\n", duration); - - /* Redistribute configuration */ - /* XXX */ - - vty_out (vty, " LSA minimum arrival %d msecs\n",o->lsa_minarrival); - - /* Show SPF parameters */ - vty_out(vty, " Initial SPF scheduling delay %d millisec(s)\n" - " Minimum hold time between consecutive SPFs %d millsecond(s)\n" - " Maximum hold time between consecutive SPFs %d millsecond(s)\n" - " Hold time multiplier is currently %d\n", - o->spf_delay, - o->spf_holdtime, - o->spf_max_holdtime, - o->spf_hold_multiplier); - - vty_out(vty, " SPF algorithm "); - if (o->ts_spf.tv_sec || o->ts_spf.tv_usec) - { - timersub(&now, &o->ts_spf, &result); - timerstring(&result, buf, sizeof(buf)); - ospf6_spf_reason_string(o->last_spf_reason, rbuf, sizeof(rbuf)); - vty_out(vty, "last executed %s ago, reason %s\n", buf, rbuf); - vty_out (vty, " Last SPF duration %lld sec %lld usec\n", - (long long)o->ts_spf_duration.tv_sec, - (long long)o->ts_spf_duration.tv_usec); - } - else - vty_out(vty, "has not been run$\n"); - threadtimer_string(now, o->t_spf_calc, buf, sizeof(buf)); - vty_out (vty, " SPF timer %s%s\n", - (o->t_spf_calc ? "due in " : "is "), buf); - - if (CHECK_FLAG (o->flag, OSPF6_STUB_ROUTER)) - vty_out (vty, " Router Is Stub Router\n"); - - /* LSAs */ - vty_out (vty, " Number of AS scoped LSAs is %u\n", - o->lsdb->count); - - /* Areas */ - vty_out (vty, " Number of areas in this router is %u\n", - listcount (o->area_list)); - - if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES)) - { - if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_DETAIL)) - vty_out (vty, " All adjacency changes are logged\n"); - else - vty_out (vty, " Adjacency changes are logged\n"); - } - - vty_out (vty, "\n"); - - for (ALL_LIST_ELEMENTS_RO (o->area_list, n, oa)) - ospf6_area_show (vty, oa); + struct listnode *n; + struct ospf6_area *oa; + char router_id[16], duration[32]; + struct timeval now, running, result; + char buf[32], rbuf[32]; + + /* process id, router id */ + inet_ntop(AF_INET, &o->router_id, router_id, sizeof(router_id)); + vty_out(vty, " OSPFv3 Routing Process (0) with Router-ID %s\n", + router_id); + + /* running time */ + monotime(&now); + timersub(&now, &o->starttime, &running); + timerstring(&running, duration, sizeof(duration)); + vty_out(vty, " Running %s\n", duration); + + /* Redistribute configuration */ + /* XXX */ + + vty_out(vty, " LSA minimum arrival %d msecs\n", o->lsa_minarrival); + + /* Show SPF parameters */ + vty_out(vty, + " Initial SPF scheduling delay %d millisec(s)\n" + " Minimum hold time between consecutive SPFs %d millsecond(s)\n" + " Maximum hold time between consecutive SPFs %d millsecond(s)\n" + " Hold time multiplier is currently %d\n", + o->spf_delay, o->spf_holdtime, o->spf_max_holdtime, + o->spf_hold_multiplier); + + vty_out(vty, " SPF algorithm "); + if (o->ts_spf.tv_sec || o->ts_spf.tv_usec) { + timersub(&now, &o->ts_spf, &result); + timerstring(&result, buf, sizeof(buf)); + ospf6_spf_reason_string(o->last_spf_reason, rbuf, sizeof(rbuf)); + vty_out(vty, "last executed %s ago, reason %s\n", buf, rbuf); + vty_out(vty, " Last SPF duration %lld sec %lld usec\n", + (long long)o->ts_spf_duration.tv_sec, + (long long)o->ts_spf_duration.tv_usec); + } else + vty_out(vty, "has not been run$\n"); + threadtimer_string(now, o->t_spf_calc, buf, sizeof(buf)); + vty_out(vty, " SPF timer %s%s\n", (o->t_spf_calc ? "due in " : "is "), + buf); + + if (CHECK_FLAG(o->flag, OSPF6_STUB_ROUTER)) + vty_out(vty, " Router Is Stub Router\n"); + + /* LSAs */ + vty_out(vty, " Number of AS scoped LSAs is %u\n", o->lsdb->count); + + /* Areas */ + vty_out(vty, " Number of areas in this router is %u\n", + listcount(o->area_list)); + + if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES)) { + if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_DETAIL)) + vty_out(vty, " All adjacency changes are logged\n"); + else + vty_out(vty, " Adjacency changes are logged\n"); + } + + vty_out(vty, "\n"); + + for (ALL_LIST_ELEMENTS_RO(o->area_list, n, oa)) + ospf6_area_show(vty, oa); } /* show top level structures */ @@ -873,10 +831,10 @@ DEFUN (show_ipv6_ospf6, IP6_STR OSPF6_STR) { - OSPF6_CMD_CHECK_RUNNING (); + OSPF6_CMD_CHECK_RUNNING(); - ospf6_show (vty, ospf6); - return CMD_SUCCESS; + ospf6_show(vty, ospf6); + return CMD_SUCCESS; } DEFUN (show_ipv6_ospf6_route, @@ -895,10 +853,10 @@ DEFUN (show_ipv6_ospf6_route, "Detailed information\n" "Summary of route table\n") { - OSPF6_CMD_CHECK_RUNNING (); + OSPF6_CMD_CHECK_RUNNING(); - ospf6_route_table_show (vty, 4, argc, argv, ospf6->route_table); - return CMD_SUCCESS; + ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table); + return CMD_SUCCESS; } DEFUN (show_ipv6_ospf6_route_match, @@ -912,10 +870,10 @@ DEFUN (show_ipv6_ospf6_route_match, "Display routes which match the specified route\n" "Display routes longer than the specified route\n") { - OSPF6_CMD_CHECK_RUNNING (); + OSPF6_CMD_CHECK_RUNNING(); - ospf6_route_table_show (vty, 4, argc, argv, ospf6->route_table); - return CMD_SUCCESS; + ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table); + return CMD_SUCCESS; } DEFUN (show_ipv6_ospf6_route_match_detail, @@ -930,14 +888,13 @@ DEFUN (show_ipv6_ospf6_route_match_detail, "Detailed information\n" ) { - OSPF6_CMD_CHECK_RUNNING (); + OSPF6_CMD_CHECK_RUNNING(); - ospf6_route_table_show (vty, 4, argc, argv, ospf6->route_table); - return CMD_SUCCESS; + ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table); + return CMD_SUCCESS; } - DEFUN (show_ipv6_ospf6_route_type_detail, show_ipv6_ospf6_route_type_detail_cmd, "show ipv6 ospf6 route <intra-area|inter-area|external-1|external-2> detail", @@ -952,153 +909,143 @@ DEFUN (show_ipv6_ospf6_route_type_detail, "Detailed information\n" ) { - OSPF6_CMD_CHECK_RUNNING (); + OSPF6_CMD_CHECK_RUNNING(); - ospf6_route_table_show (vty, 4, argc, argv, ospf6->route_table); - return CMD_SUCCESS; + ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table); + return CMD_SUCCESS; } -static void -ospf6_stub_router_config_write (struct vty *vty) +static void ospf6_stub_router_config_write(struct vty *vty) { - if (CHECK_FLAG (ospf6->flag, OSPF6_STUB_ROUTER)) - { - vty_out (vty, " stub-router administrative\n"); - } - return; + if (CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) { + vty_out(vty, " stub-router administrative\n"); + } + return; } -static int -ospf6_distance_config_write (struct vty *vty) +static int ospf6_distance_config_write(struct vty *vty) { - struct route_node *rn; - struct ospf6_distance *odistance; - - if (ospf6->distance_all) - vty_out (vty, " distance %u\n", ospf6->distance_all); - - if (ospf6->distance_intra - || ospf6->distance_inter - || ospf6->distance_external) - { - vty_out (vty, " distance ospf6"); - - if (ospf6->distance_intra) - vty_out (vty, " intra-area %u", ospf6->distance_intra); - if (ospf6->distance_inter) - vty_out (vty, " inter-area %u", ospf6->distance_inter); - if (ospf6->distance_external) - vty_out (vty, " external %u", ospf6->distance_external); - - vty_out (vty, "\n"); - } - - for (rn = route_top (ospf6->distance_table); rn; rn = route_next (rn)) - if ((odistance = rn->info) != NULL) - { - char buf[PREFIX_STRLEN]; - - vty_out (vty, " distance %u %s %s\n", odistance->distance, - prefix2str (&rn->p, buf, sizeof (buf)), - odistance->access_list ? odistance->access_list : ""); - } - return 0; + struct route_node *rn; + struct ospf6_distance *odistance; + + if (ospf6->distance_all) + vty_out(vty, " distance %u\n", ospf6->distance_all); + + if (ospf6->distance_intra || ospf6->distance_inter + || ospf6->distance_external) { + vty_out(vty, " distance ospf6"); + + if (ospf6->distance_intra) + vty_out(vty, " intra-area %u", ospf6->distance_intra); + if (ospf6->distance_inter) + vty_out(vty, " inter-area %u", ospf6->distance_inter); + if (ospf6->distance_external) + vty_out(vty, " external %u", ospf6->distance_external); + + vty_out(vty, "\n"); + } + + for (rn = route_top(ospf6->distance_table); rn; rn = route_next(rn)) + if ((odistance = rn->info) != NULL) { + char buf[PREFIX_STRLEN]; + + vty_out(vty, " distance %u %s %s\n", + odistance->distance, + prefix2str(&rn->p, buf, sizeof(buf)), + odistance->access_list ? odistance->access_list + : ""); + } + return 0; } /* OSPF configuration write function. */ -static int -config_write_ospf6 (struct vty *vty) +static int config_write_ospf6(struct vty *vty) { - char router_id[16]; - struct listnode *j, *k; - struct ospf6_area *oa; - struct ospf6_interface *oi; - - /* OSPFv3 configuration. */ - if (ospf6 == NULL) - return CMD_SUCCESS; - - inet_ntop (AF_INET, &ospf6->router_id_static, router_id, sizeof (router_id)); - vty_out (vty, "router ospf6\n"); - if (ospf6->router_id_static != 0) - vty_out (vty, " router-id %s\n", router_id); - - /* log-adjacency-changes flag print. */ - if (CHECK_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES)) - { - if (CHECK_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL)) - vty_out (vty, " log-adjacency-changes detail\n"); - else if (!DFLT_OSPF6_LOG_ADJACENCY_CHANGES) - vty_out (vty, " log-adjacency-changes\n"); - } - else if (DFLT_OSPF6_LOG_ADJACENCY_CHANGES) - { - vty_out (vty, " no log-adjacency-changes\n"); - } - - if (ospf6->ref_bandwidth != OSPF6_REFERENCE_BANDWIDTH) - vty_out (vty, " auto-cost reference-bandwidth %d\n", ospf6->ref_bandwidth); - - /* LSA timers print. */ - if (ospf6->lsa_minarrival != OSPF_MIN_LS_ARRIVAL) - vty_out (vty, " timers lsa min-arrival %d\n",ospf6->lsa_minarrival); - - ospf6_stub_router_config_write (vty); - ospf6_redistribute_config_write (vty); - ospf6_area_config_write (vty); - ospf6_spf_config_write (vty); - ospf6_distance_config_write (vty); - - for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, j, oa)) - { - for (ALL_LIST_ELEMENTS_RO (oa->if_list, k, oi)) - vty_out (vty, " interface %s area %s\n", - oi->interface->name, oa->name); - } - vty_out (vty, "!\n"); - return 0; + char router_id[16]; + struct listnode *j, *k; + struct ospf6_area *oa; + struct ospf6_interface *oi; + + /* OSPFv3 configuration. */ + if (ospf6 == NULL) + return CMD_SUCCESS; + + inet_ntop(AF_INET, &ospf6->router_id_static, router_id, + sizeof(router_id)); + vty_out(vty, "router ospf6\n"); + if (ospf6->router_id_static != 0) + vty_out(vty, " router-id %s\n", router_id); + + /* log-adjacency-changes flag print. */ + if (CHECK_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES)) { + if (CHECK_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL)) + vty_out(vty, " log-adjacency-changes detail\n"); + else if (!DFLT_OSPF6_LOG_ADJACENCY_CHANGES) + vty_out(vty, " log-adjacency-changes\n"); + } else if (DFLT_OSPF6_LOG_ADJACENCY_CHANGES) { + vty_out(vty, " no log-adjacency-changes\n"); + } + + if (ospf6->ref_bandwidth != OSPF6_REFERENCE_BANDWIDTH) + vty_out(vty, " auto-cost reference-bandwidth %d\n", + ospf6->ref_bandwidth); + + /* LSA timers print. */ + if (ospf6->lsa_minarrival != OSPF_MIN_LS_ARRIVAL) + vty_out(vty, " timers lsa min-arrival %d\n", + ospf6->lsa_minarrival); + + ospf6_stub_router_config_write(vty); + ospf6_redistribute_config_write(vty); + ospf6_area_config_write(vty); + ospf6_spf_config_write(vty); + ospf6_distance_config_write(vty); + + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, j, oa)) { + for (ALL_LIST_ELEMENTS_RO(oa->if_list, k, oi)) + vty_out(vty, " interface %s area %s\n", + oi->interface->name, oa->name); + } + vty_out(vty, "!\n"); + return 0; } /* OSPF6 node structure. */ -static struct cmd_node ospf6_node = -{ - OSPF6_NODE, - "%s(config-ospf6)# ", - 1 /* VTYSH */ +static struct cmd_node ospf6_node = { + OSPF6_NODE, "%s(config-ospf6)# ", 1 /* VTYSH */ }; /* Install ospf related commands. */ -void -ospf6_top_init (void) +void ospf6_top_init(void) { - /* Install ospf6 top node. */ - install_node (&ospf6_node, config_write_ospf6); - - install_element (VIEW_NODE, &show_ipv6_ospf6_cmd); - install_element (CONFIG_NODE, &router_ospf6_cmd); - install_element (CONFIG_NODE, &no_router_ospf6_cmd); - - install_element (VIEW_NODE, &show_ipv6_ospf6_route_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_route_match_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_route_match_detail_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_route_type_detail_cmd); - - install_default (OSPF6_NODE); - install_element (OSPF6_NODE, &ospf6_router_id_cmd); - install_element (OSPF6_NODE, &ospf6_log_adjacency_changes_cmd); - install_element (OSPF6_NODE, &ospf6_log_adjacency_changes_detail_cmd); - install_element (OSPF6_NODE, &no_ospf6_log_adjacency_changes_cmd); - install_element (OSPF6_NODE, &no_ospf6_log_adjacency_changes_detail_cmd); - - /* LSA timers commands */ - install_element (OSPF6_NODE, &ospf6_timers_lsa_cmd); - install_element (OSPF6_NODE, &no_ospf6_timers_lsa_cmd); - - install_element (OSPF6_NODE, &ospf6_interface_area_cmd); - install_element (OSPF6_NODE, &no_ospf6_interface_area_cmd); - install_element (OSPF6_NODE, &ospf6_stub_router_admin_cmd); - install_element (OSPF6_NODE, &no_ospf6_stub_router_admin_cmd); - /* For a later time */ + /* Install ospf6 top node. */ + install_node(&ospf6_node, config_write_ospf6); + + install_element(VIEW_NODE, &show_ipv6_ospf6_cmd); + install_element(CONFIG_NODE, &router_ospf6_cmd); + install_element(CONFIG_NODE, &no_router_ospf6_cmd); + + install_element(VIEW_NODE, &show_ipv6_ospf6_route_cmd); + install_element(VIEW_NODE, &show_ipv6_ospf6_route_match_cmd); + install_element(VIEW_NODE, &show_ipv6_ospf6_route_match_detail_cmd); + install_element(VIEW_NODE, &show_ipv6_ospf6_route_type_detail_cmd); + + install_default(OSPF6_NODE); + install_element(OSPF6_NODE, &ospf6_router_id_cmd); + install_element(OSPF6_NODE, &ospf6_log_adjacency_changes_cmd); + install_element(OSPF6_NODE, &ospf6_log_adjacency_changes_detail_cmd); + install_element(OSPF6_NODE, &no_ospf6_log_adjacency_changes_cmd); + install_element(OSPF6_NODE, &no_ospf6_log_adjacency_changes_detail_cmd); + + /* LSA timers commands */ + install_element(OSPF6_NODE, &ospf6_timers_lsa_cmd); + install_element(OSPF6_NODE, &no_ospf6_timers_lsa_cmd); + + install_element(OSPF6_NODE, &ospf6_interface_area_cmd); + install_element(OSPF6_NODE, &no_ospf6_interface_area_cmd); + install_element(OSPF6_NODE, &ospf6_stub_router_admin_cmd); + install_element(OSPF6_NODE, &no_ospf6_stub_router_admin_cmd); +/* For a later time */ #if 0 install_element (OSPF6_NODE, &ospf6_stub_router_startup_cmd); install_element (OSPF6_NODE, &no_ospf6_stub_router_startup_cmd); @@ -1106,10 +1053,10 @@ ospf6_top_init (void) install_element (OSPF6_NODE, &no_ospf6_stub_router_shutdown_cmd); #endif - install_element (OSPF6_NODE, &ospf6_distance_cmd); - install_element (OSPF6_NODE, &no_ospf6_distance_cmd); - install_element (OSPF6_NODE, &ospf6_distance_ospf6_cmd); - install_element (OSPF6_NODE, &no_ospf6_distance_ospf6_cmd); + install_element(OSPF6_NODE, &ospf6_distance_cmd); + install_element(OSPF6_NODE, &no_ospf6_distance_cmd); + install_element(OSPF6_NODE, &ospf6_distance_ospf6_cmd); + install_element(OSPF6_NODE, &no_ospf6_distance_ospf6_cmd); #if 0 install_element (OSPF6_NODE, &ospf6_distance_source_cmd); install_element (OSPF6_NODE, &no_ospf6_distance_source_cmd); diff --git a/ospf6d/ospf6_top.h b/ospf6d/ospf6_top.h index 5e101520d..d8d34d0f3 100644 --- a/ospf6d/ospf6_top.h +++ b/ospf6d/ospf6_top.h @@ -25,76 +25,75 @@ #include "routemap.h" /* OSPFv3 top level data structure */ -struct ospf6 -{ - /* my router id */ - u_int32_t router_id; +struct ospf6 { + /* my router id */ + u_int32_t router_id; - /* static router id */ - u_int32_t router_id_static; + /* static router id */ + u_int32_t router_id_static; - /* start time */ - struct timeval starttime; + /* start time */ + struct timeval starttime; - /* list of areas */ - struct list *area_list; - struct ospf6_area *backbone; + /* list of areas */ + struct list *area_list; + struct ospf6_area *backbone; - /* AS scope link state database */ - struct ospf6_lsdb *lsdb; - struct ospf6_lsdb *lsdb_self; + /* AS scope link state database */ + struct ospf6_lsdb *lsdb; + struct ospf6_lsdb *lsdb_self; - struct ospf6_route_table *route_table; - struct ospf6_route_table *brouter_table; + struct ospf6_route_table *route_table; + struct ospf6_route_table *brouter_table; - struct ospf6_route_table *external_table; - struct route_table *external_id_table; - u_int32_t external_id; + struct ospf6_route_table *external_table; + struct route_table *external_id_table; + u_int32_t external_id; - /* redistribute route-map */ - struct - { - char *name; - struct route_map *map; - } rmap[ZEBRA_ROUTE_MAX]; + /* redistribute route-map */ + struct { + char *name; + struct route_map *map; + } rmap[ZEBRA_ROUTE_MAX]; - u_char flag; + u_char flag; - /* Configured flags */ - u_char config_flags; + /* Configured flags */ + u_char config_flags; #define OSPF6_LOG_ADJACENCY_CHANGES (1 << 0) #define OSPF6_LOG_ADJACENCY_DETAIL (1 << 1) - /* LSA timer parameters */ - unsigned int lsa_minarrival; /* LSA minimum arrival in milliseconds. */ + /* LSA timer parameters */ + unsigned int lsa_minarrival; /* LSA minimum arrival in milliseconds. */ - /* SPF parameters */ - unsigned int spf_delay; /* SPF delay time. */ - unsigned int spf_holdtime; /* SPF hold time. */ - unsigned int spf_max_holdtime; /* SPF maximum-holdtime */ - unsigned int spf_hold_multiplier; /* Adaptive multiplier for hold time */ - unsigned int spf_reason; /* reason bits while scheduling SPF */ + /* SPF parameters */ + unsigned int spf_delay; /* SPF delay time. */ + unsigned int spf_holdtime; /* SPF hold time. */ + unsigned int spf_max_holdtime; /* SPF maximum-holdtime */ + unsigned int + spf_hold_multiplier; /* Adaptive multiplier for hold time */ + unsigned int spf_reason; /* reason bits while scheduling SPF */ - struct timeval ts_spf; /* SPF calculation time stamp. */ - struct timeval ts_spf_duration; /* Execution time of last SPF */ - unsigned int last_spf_reason; /* Last SPF reason */ + struct timeval ts_spf; /* SPF calculation time stamp. */ + struct timeval ts_spf_duration; /* Execution time of last SPF */ + unsigned int last_spf_reason; /* Last SPF reason */ - /* Threads */ - struct thread *t_spf_calc; /* SPF calculation timer. */ - struct thread *t_ase_calc; /* ASE calculation timer. */ - struct thread *maxage_remover; + /* Threads */ + struct thread *t_spf_calc; /* SPF calculation timer. */ + struct thread *t_ase_calc; /* ASE calculation timer. */ + struct thread *maxage_remover; - u_int32_t ref_bandwidth; + u_int32_t ref_bandwidth; - /* Distance parameters */ - u_char distance_all; - u_char distance_intra; - u_char distance_inter; - u_char distance_external; + /* Distance parameters */ + u_char distance_all; + u_char distance_intra; + u_char distance_inter; + u_char distance_external; - struct route_table *distance_table; + struct route_table *distance_table; - QOBJ_FIELDS + QOBJ_FIELDS }; DECLARE_QOBJ_TYPE(ospf6) @@ -105,11 +104,9 @@ DECLARE_QOBJ_TYPE(ospf6) extern struct ospf6 *ospf6; /* prototypes */ -extern void ospf6_top_init (void); -extern void ospf6_delete (struct ospf6 *o); +extern void ospf6_top_init(void); +extern void ospf6_delete(struct ospf6 *o); -extern void ospf6_maxage_remove (struct ospf6 *o); +extern void ospf6_maxage_remove(struct ospf6 *o); #endif /* OSPF6_TOP_H */ - - diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index ddd2f3f1b..d33f41730 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -39,7 +39,7 @@ #include "ospf6_zebra.h" #include "ospf6d.h" -DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_DISTANCE, "OSPF6 distance") +DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_DISTANCE, "OSPF6 distance") unsigned char conf_debug_ospf6_zebra = 0; @@ -49,79 +49,75 @@ struct zclient *zclient = NULL; struct in_addr router_id_zebra; /* Router-id update message from zebra. */ -static int -ospf6_router_id_update_zebra (int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int ospf6_router_id_update_zebra(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct prefix router_id; - struct ospf6 *o = ospf6; + struct prefix router_id; + struct ospf6 *o = ospf6; - zebra_router_id_update_read(zclient->ibuf,&router_id); - router_id_zebra = router_id.u.prefix4; + zebra_router_id_update_read(zclient->ibuf, &router_id); + router_id_zebra = router_id.u.prefix4; - if (o == NULL) - return 0; + if (o == NULL) + return 0; - if (o->router_id == 0) - o->router_id = (u_int32_t) router_id_zebra.s_addr; + if (o->router_id == 0) + o->router_id = (u_int32_t)router_id_zebra.s_addr; - return 0; + return 0; } /* redistribute function */ -void -ospf6_zebra_redistribute (int type) +void ospf6_zebra_redistribute(int type) { - if (vrf_bitmap_check (zclient->redist[AFI_IP6][type], VRF_DEFAULT)) - return; - vrf_bitmap_set (zclient->redist[AFI_IP6][type], VRF_DEFAULT); + if (vrf_bitmap_check(zclient->redist[AFI_IP6][type], VRF_DEFAULT)) + return; + vrf_bitmap_set(zclient->redist[AFI_IP6][type], VRF_DEFAULT); - if (zclient->sock > 0) - zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0, - VRF_DEFAULT); + if (zclient->sock > 0) + zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, + AFI_IP6, type, 0, VRF_DEFAULT); } -void -ospf6_zebra_no_redistribute (int type) +void ospf6_zebra_no_redistribute(int type) { - if (!vrf_bitmap_check (zclient->redist[AFI_IP6][type], VRF_DEFAULT)) - return; - vrf_bitmap_unset (zclient->redist[AFI_IP6][type], VRF_DEFAULT); - if (zclient->sock > 0) - zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP6, type, - 0, VRF_DEFAULT); + if (!vrf_bitmap_check(zclient->redist[AFI_IP6][type], VRF_DEFAULT)) + return; + vrf_bitmap_unset(zclient->redist[AFI_IP6][type], VRF_DEFAULT); + if (zclient->sock > 0) + zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient, + AFI_IP6, type, 0, VRF_DEFAULT); } /* Inteface addition message from zebra. */ -static int -ospf6_zebra_if_add (int command, struct zclient *zclient, zebra_size_t length, - vrf_id_t vrf_id) +static int ospf6_zebra_if_add(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct interface *ifp; - - ifp = zebra_interface_add_read (zclient->ibuf, vrf_id); - if (IS_OSPF6_DEBUG_ZEBRA (RECV)) - zlog_debug ("Zebra Interface add: %s index %d mtu %d", - ifp->name, ifp->ifindex, ifp->mtu6); - ospf6_interface_if_add (ifp); - return 0; + struct interface *ifp; + + ifp = zebra_interface_add_read(zclient->ibuf, vrf_id); + if (IS_OSPF6_DEBUG_ZEBRA(RECV)) + zlog_debug("Zebra Interface add: %s index %d mtu %d", ifp->name, + ifp->ifindex, ifp->mtu6); + ospf6_interface_if_add(ifp); + return 0; } -static int -ospf6_zebra_if_del (int command, struct zclient *zclient, zebra_size_t length, - vrf_id_t vrf_id) +static int ospf6_zebra_if_del(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct interface *ifp; + struct interface *ifp; - if (!(ifp = zebra_interface_state_read (zclient->ibuf, vrf_id))) - return 0; + if (!(ifp = zebra_interface_state_read(zclient->ibuf, vrf_id))) + return 0; - if (if_is_up (ifp)) - zlog_warn ("Zebra: got delete of %s, but interface is still up", ifp->name); + if (if_is_up(ifp)) + zlog_warn("Zebra: got delete of %s, but interface is still up", + ifp->name); - if (IS_OSPF6_DEBUG_ZEBRA (RECV)) - zlog_debug ("Zebra Interface delete: %s index %d mtu %d", - ifp->name, ifp->ifindex, ifp->mtu6); + if (IS_OSPF6_DEBUG_ZEBRA(RECV)) + zlog_debug("Zebra Interface delete: %s index %d mtu %d", + ifp->name, ifp->ifindex, ifp->mtu6); #if 0 /* XXX: ospf6_interface_if_del is not the right way to handle this, @@ -130,178 +126,180 @@ ospf6_zebra_if_del (int command, struct zclient *zclient, zebra_size_t length, ospf6_interface_if_del (ifp); #endif /*0*/ - ifp->ifindex = IFINDEX_DELETED; - return 0; + ifp->ifindex = IFINDEX_DELETED; + return 0; } -static int -ospf6_zebra_if_state_update (int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int ospf6_zebra_if_state_update(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct interface *ifp; - - ifp = zebra_interface_state_read (zclient->ibuf, vrf_id); - if (ifp == NULL) - return 0; - - if (IS_OSPF6_DEBUG_ZEBRA (RECV)) - zlog_debug ("Zebra Interface state change: " - "%s index %d flags %llx metric %d mtu %d bandwidth %d", - ifp->name, ifp->ifindex, (unsigned long long)ifp->flags, - ifp->metric, ifp->mtu6, ifp->bandwidth); - - ospf6_interface_state_update (ifp); - return 0; + struct interface *ifp; + + ifp = zebra_interface_state_read(zclient->ibuf, vrf_id); + if (ifp == NULL) + return 0; + + if (IS_OSPF6_DEBUG_ZEBRA(RECV)) + zlog_debug( + "Zebra Interface state change: " + "%s index %d flags %llx metric %d mtu %d bandwidth %d", + ifp->name, ifp->ifindex, (unsigned long long)ifp->flags, + ifp->metric, ifp->mtu6, ifp->bandwidth); + + ospf6_interface_state_update(ifp); + return 0; } -static int -ospf6_zebra_if_address_update_add (int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int ospf6_zebra_if_address_update_add(int command, + struct zclient *zclient, + zebra_size_t length, + vrf_id_t vrf_id) { - struct connected *c; - char buf[128]; - - c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD, zclient->ibuf, - vrf_id); - if (c == NULL) - return 0; - - if (IS_OSPF6_DEBUG_ZEBRA (RECV)) - zlog_debug ("Zebra Interface address add: %s %5s %s/%d", - c->ifp->name, prefix_family_str (c->address), - inet_ntop (c->address->family, &c->address->u.prefix, - buf, sizeof (buf)), c->address->prefixlen); - - if (c->address->family == AF_INET6) - { - ospf6_interface_state_update (c->ifp); - ospf6_interface_connected_route_update (c->ifp); - } - return 0; + struct connected *c; + char buf[128]; + + c = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD, + zclient->ibuf, vrf_id); + if (c == NULL) + return 0; + + if (IS_OSPF6_DEBUG_ZEBRA(RECV)) + zlog_debug("Zebra Interface address add: %s %5s %s/%d", + c->ifp->name, prefix_family_str(c->address), + inet_ntop(c->address->family, &c->address->u.prefix, + buf, sizeof(buf)), + c->address->prefixlen); + + if (c->address->family == AF_INET6) { + ospf6_interface_state_update(c->ifp); + ospf6_interface_connected_route_update(c->ifp); + } + return 0; } -static int -ospf6_zebra_if_address_update_delete (int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int ospf6_zebra_if_address_update_delete(int command, + struct zclient *zclient, + zebra_size_t length, + vrf_id_t vrf_id) { - struct connected *c; - char buf[128]; + struct connected *c; + char buf[128]; + + c = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE, + zclient->ibuf, vrf_id); + if (c == NULL) + return 0; + + if (IS_OSPF6_DEBUG_ZEBRA(RECV)) + zlog_debug("Zebra Interface address delete: %s %5s %s/%d", + c->ifp->name, prefix_family_str(c->address), + inet_ntop(c->address->family, &c->address->u.prefix, + buf, sizeof(buf)), + c->address->prefixlen); + + if (c->address->family == AF_INET6) { + ospf6_interface_connected_route_update(c->ifp); + ospf6_interface_state_update(c->ifp); + } - c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE, zclient->ibuf, - vrf_id); - if (c == NULL) - return 0; + connected_free(c); - if (IS_OSPF6_DEBUG_ZEBRA (RECV)) - zlog_debug ("Zebra Interface address delete: %s %5s %s/%d", - c->ifp->name, prefix_family_str (c->address), - inet_ntop (c->address->family, &c->address->u.prefix, - buf, sizeof (buf)), c->address->prefixlen); + return 0; +} - if (c->address->family == AF_INET6) - { - ospf6_interface_connected_route_update (c->ifp); - ospf6_interface_state_update (c->ifp); - } +static int ospf6_zebra_read_ipv6(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) +{ + struct stream *s; + struct zapi_ipv6 api; + unsigned long ifindex; + struct prefix p, src_p; + struct in6_addr *nexthop; + + if (ospf6 == NULL) + return 0; + + s = zclient->ibuf; + ifindex = 0; + nexthop = NULL; + memset(&api, 0, sizeof(api)); + + /* Type, flags, message. */ + api.type = stream_getc(s); + api.instance = stream_getw(s); + api.flags = stream_getl(s); + api.message = stream_getc(s); + + /* IPv6 prefix. */ + memset(&p, 0, sizeof(struct prefix)); + p.family = AF_INET6; + p.prefixlen = MIN(IPV6_MAX_PREFIXLEN, stream_getc(s)); + stream_get(&p.u.prefix6, s, PSIZE(p.prefixlen)); + + memset(&src_p, 0, sizeof(struct prefix)); + src_p.family = AF_INET6; + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) { + src_p.prefixlen = stream_getc(s); + stream_get(&src_p.u.prefix6, s, PSIZE(src_p.prefixlen)); + } + + if (src_p.prefixlen) + /* we completely ignore srcdest routes for now. */ + return 0; + + /* Nexthop, ifindex, distance, metric. */ + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { + api.nexthop_num = stream_getc(s); + nexthop = (struct in6_addr *)malloc(api.nexthop_num + * sizeof(struct in6_addr)); + stream_get(nexthop, s, + api.nexthop_num * sizeof(struct in6_addr)); + } + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) { + api.ifindex_num = stream_getc(s); + ifindex = stream_getl(s); + } + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) + api.distance = stream_getc(s); + else + api.distance = 0; + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) + api.metric = stream_getl(s); + else + api.metric = 0; + + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_TAG)) + api.tag = stream_getl(s); + else + api.tag = 0; + + if (IS_OSPF6_DEBUG_ZEBRA(RECV)) { + char prefixstr[PREFIX2STR_BUFFER], nexthopstr[128]; + prefix2str((struct prefix *)&p, prefixstr, sizeof(prefixstr)); + if (nexthop) + inet_ntop(AF_INET6, nexthop, nexthopstr, + sizeof(nexthopstr)); + else + snprintf(nexthopstr, sizeof(nexthopstr), "::"); + + zlog_debug( + "Zebra Receive route %s: %s %s nexthop %s ifindex %ld tag %" ROUTE_TAG_PRI, + (command == ZEBRA_REDISTRIBUTE_IPV6_ADD ? "add" + : "delete"), + zebra_route_string(api.type), prefixstr, nexthopstr, + ifindex, api.tag); + } - connected_free (c); + if (command == ZEBRA_REDISTRIBUTE_IPV6_ADD) + ospf6_asbr_redistribute_add(api.type, ifindex, &p, + api.nexthop_num, nexthop, api.tag); + else + ospf6_asbr_redistribute_remove(api.type, ifindex, &p); - return 0; -} + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) + free(nexthop); -static int -ospf6_zebra_read_ipv6 (int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) -{ - struct stream *s; - struct zapi_ipv6 api; - unsigned long ifindex; - struct prefix p, src_p; - struct in6_addr *nexthop; - - if (ospf6 == NULL) - return 0; - - s = zclient->ibuf; - ifindex = 0; - nexthop = NULL; - memset (&api, 0, sizeof (api)); - - /* Type, flags, message. */ - api.type = stream_getc (s); - api.instance = stream_getw (s); - api.flags = stream_getl (s); - api.message = stream_getc (s); - - /* IPv6 prefix. */ - memset (&p, 0, sizeof (struct prefix)); - p.family = AF_INET6; - p.prefixlen = MIN(IPV6_MAX_PREFIXLEN, stream_getc (s)); - stream_get (&p.u.prefix6, s, PSIZE (p.prefixlen)); - - memset (&src_p, 0, sizeof (struct prefix)); - src_p.family = AF_INET6; - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_SRCPFX)) - { - src_p.prefixlen = stream_getc (s); - stream_get (&src_p.u.prefix6, s, PSIZE (src_p.prefixlen)); - } - - if (src_p.prefixlen) - /* we completely ignore srcdest routes for now. */ - return 0; - - /* Nexthop, ifindex, distance, metric. */ - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) - { - api.nexthop_num = stream_getc (s); - nexthop = (struct in6_addr *) - malloc (api.nexthop_num * sizeof (struct in6_addr)); - stream_get (nexthop, s, api.nexthop_num * sizeof (struct in6_addr)); - } - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) - { - api.ifindex_num = stream_getc (s); - ifindex = stream_getl (s); - } - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE)) - api.distance = stream_getc (s); - else - api.distance = 0; - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) - api.metric = stream_getl (s); - else - api.metric = 0; - - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG)) - api.tag = stream_getl (s); - else - api.tag = 0; - - if (IS_OSPF6_DEBUG_ZEBRA (RECV)) - { - char prefixstr[PREFIX2STR_BUFFER], nexthopstr[128]; - prefix2str ((struct prefix *)&p, prefixstr, sizeof (prefixstr)); - if (nexthop) - inet_ntop (AF_INET6, nexthop, nexthopstr, sizeof (nexthopstr)); - else - snprintf (nexthopstr, sizeof (nexthopstr), "::"); - - zlog_debug ("Zebra Receive route %s: %s %s nexthop %s ifindex %ld tag %"ROUTE_TAG_PRI, - (command == ZEBRA_REDISTRIBUTE_IPV6_ADD ? "add" : "delete"), - zebra_route_string(api.type), prefixstr, nexthopstr, ifindex, api.tag); - } - - if (command == ZEBRA_REDISTRIBUTE_IPV6_ADD) - ospf6_asbr_redistribute_add (api.type, ifindex, &p, - api.nexthop_num, nexthop, api.tag); - else - ospf6_asbr_redistribute_remove (api.type, ifindex, &p); - - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) - free (nexthop); - - return 0; + return 0; } DEFUN (show_zebra, @@ -312,292 +310,270 @@ DEFUN (show_zebra, OSPF6_STR "Zebra information\n") { - int i; - if (zclient == NULL) - { - vty_out (vty, "Not connected to zebra\n"); - return CMD_SUCCESS; - } - - vty_out (vty, "Zebra Infomation\n"); - vty_out (vty, " enable: %d fail: %d\n", - zclient->enable, zclient->fail); - vty_out (vty, " redistribute default: %d\n", - vrf_bitmap_check (zclient->default_information, VRF_DEFAULT)); - vty_out (vty, " redistribute:"); - for (i = 0; i < ZEBRA_ROUTE_MAX; i++) - { - if (vrf_bitmap_check (zclient->redist[AFI_IP6][i], VRF_DEFAULT)) - vty_out (vty, " %s", zebra_route_string(i)); - } - vty_out (vty, "\n"); - return CMD_SUCCESS; + int i; + if (zclient == NULL) { + vty_out(vty, "Not connected to zebra\n"); + return CMD_SUCCESS; + } + + vty_out(vty, "Zebra Infomation\n"); + vty_out(vty, " enable: %d fail: %d\n", zclient->enable, zclient->fail); + vty_out(vty, " redistribute default: %d\n", + vrf_bitmap_check(zclient->default_information, VRF_DEFAULT)); + vty_out(vty, " redistribute:"); + for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { + if (vrf_bitmap_check(zclient->redist[AFI_IP6][i], VRF_DEFAULT)) + vty_out(vty, " %s", zebra_route_string(i)); + } + vty_out(vty, "\n"); + return CMD_SUCCESS; } /* Zebra configuration write function. */ -static int -config_write_ospf6_zebra (struct vty *vty) +static int config_write_ospf6_zebra(struct vty *vty) { - if (! zclient->enable) - { - vty_out (vty, "no router zebra\n"); - vty_out (vty, "!\n"); - } - else if (! vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], - VRF_DEFAULT)) - { - vty_out (vty, "router zebra\n"); - vty_out (vty, " no redistribute ospf6\n"); - vty_out (vty, "!\n"); - } - return 0; + if (!zclient->enable) { + vty_out(vty, "no router zebra\n"); + vty_out(vty, "!\n"); + } else if (!vrf_bitmap_check( + zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], + VRF_DEFAULT)) { + vty_out(vty, "router zebra\n"); + vty_out(vty, " no redistribute ospf6\n"); + vty_out(vty, "!\n"); + } + return 0; } /* Zebra node structure. */ -static struct cmd_node zebra_node = -{ - ZEBRA_NODE, - "%s(config-zebra)# ", +static struct cmd_node zebra_node = { + ZEBRA_NODE, "%s(config-zebra)# ", }; #define ADD 0 #define REM 1 -static void -ospf6_zebra_route_update (int type, struct ospf6_route *request) +static void ospf6_zebra_route_update(int type, struct ospf6_route *request) { - struct zapi_ipv6 api; - char buf[PREFIX2STR_BUFFER]; - int nhcount; - struct in6_addr **nexthops; - ifindex_t *ifindexes; - int ret = 0; - struct prefix_ipv6 *dest; - - if (IS_OSPF6_DEBUG_ZEBRA (SEND)) - { - prefix2str (&request->prefix, buf, sizeof (buf)); - zlog_debug ("Send %s route: %s", - (type == REM ? "remove" : "add"), buf); - } - - if (zclient->sock < 0) - { - if (IS_OSPF6_DEBUG_ZEBRA (SEND)) - zlog_debug (" Not connected to Zebra"); - return; - } - - if (request->path.origin.adv_router == ospf6->router_id && - (request->path.type == OSPF6_PATH_TYPE_EXTERNAL1 || - request->path.type == OSPF6_PATH_TYPE_EXTERNAL2)) - { - if (IS_OSPF6_DEBUG_ZEBRA (SEND)) - zlog_debug (" Ignore self-originated external route"); - return; - } - - /* If removing is the best path and if there's another path, - treat this request as add the secondary path */ - if (type == REM && ospf6_route_is_best (request) && - request->next && ospf6_route_is_same (request, request->next)) - { - if (IS_OSPF6_DEBUG_ZEBRA (SEND)) - zlog_debug (" Best-path removal resulted Sencondary addition"); - type = ADD; - request = request->next; - } - - /* Only the best path will be sent to zebra. */ - if (! ospf6_route_is_best (request)) - { - /* this is not preferred best route, ignore */ - if (IS_OSPF6_DEBUG_ZEBRA (SEND)) - zlog_debug (" Ignore non-best route"); - return; - } - - nhcount = ospf6_route_num_nexthops (request); - if (nhcount == 0) - { - if (IS_OSPF6_DEBUG_ZEBRA (SEND)) - zlog_debug (" No nexthop, ignore"); - return; - } - - /* allocate memory for nexthop_list */ - nexthops = XCALLOC (MTYPE_OSPF6_OTHER, - nhcount * sizeof (struct in6_addr *)); - if (nexthops == NULL) - { - zlog_warn ("Can't send route to zebra: malloc failed"); - return; - } - - /* allocate memory for ifindex_list */ - ifindexes = XCALLOC (MTYPE_OSPF6_OTHER, - nhcount * sizeof (ifindex_t)); - if (ifindexes == NULL) - { - zlog_warn ("Can't send route to zebra: malloc failed"); - XFREE (MTYPE_OSPF6_OTHER, nexthops); - return; - } - - ospf6_route_zebra_copy_nexthops (request, ifindexes, nexthops, nhcount); - - api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_OSPF6; - api.instance = 0; - api.flags = 0; - api.message = 0; - api.safi = SAFI_UNICAST; - SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = nhcount; - api.nexthop = nexthops; - SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX); - api.ifindex_num = nhcount; - api.ifindex = ifindexes; - SET_FLAG (api.message, ZAPI_MESSAGE_METRIC); - api.metric = (request->path.metric_type == 2 ? - request->path.u.cost_e2 : request->path.cost); - if (request->path.tag) - { - SET_FLAG (api.message, ZAPI_MESSAGE_TAG); - api.tag = request->path.tag; - } - - dest = (struct prefix_ipv6 *) &request->prefix; - - SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE); - api.distance = ospf6_distance_apply (dest, request); - - if (type == REM) - ret = zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, dest, NULL, &api); - else - ret = zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, dest, NULL, &api); - - if (ret < 0) - zlog_err ("zapi_ipv6_route() %s failed: %s", - (type == REM ? "delete" : "add"), safe_strerror (errno)); - - XFREE (MTYPE_OSPF6_OTHER, nexthops); - XFREE (MTYPE_OSPF6_OTHER, ifindexes); - - return; + struct zapi_ipv6 api; + char buf[PREFIX2STR_BUFFER]; + int nhcount; + struct in6_addr **nexthops; + ifindex_t *ifindexes; + int ret = 0; + struct prefix_ipv6 *dest; + + if (IS_OSPF6_DEBUG_ZEBRA(SEND)) { + prefix2str(&request->prefix, buf, sizeof(buf)); + zlog_debug("Send %s route: %s", + (type == REM ? "remove" : "add"), buf); + } + + if (zclient->sock < 0) { + if (IS_OSPF6_DEBUG_ZEBRA(SEND)) + zlog_debug(" Not connected to Zebra"); + return; + } + + if (request->path.origin.adv_router == ospf6->router_id + && (request->path.type == OSPF6_PATH_TYPE_EXTERNAL1 + || request->path.type == OSPF6_PATH_TYPE_EXTERNAL2)) { + if (IS_OSPF6_DEBUG_ZEBRA(SEND)) + zlog_debug(" Ignore self-originated external route"); + return; + } + + /* If removing is the best path and if there's another path, + treat this request as add the secondary path */ + if (type == REM && ospf6_route_is_best(request) && request->next + && ospf6_route_is_same(request, request->next)) { + if (IS_OSPF6_DEBUG_ZEBRA(SEND)) + zlog_debug( + " Best-path removal resulted Sencondary addition"); + type = ADD; + request = request->next; + } + + /* Only the best path will be sent to zebra. */ + if (!ospf6_route_is_best(request)) { + /* this is not preferred best route, ignore */ + if (IS_OSPF6_DEBUG_ZEBRA(SEND)) + zlog_debug(" Ignore non-best route"); + return; + } + + nhcount = ospf6_route_num_nexthops(request); + if (nhcount == 0) { + if (IS_OSPF6_DEBUG_ZEBRA(SEND)) + zlog_debug(" No nexthop, ignore"); + return; + } + + /* allocate memory for nexthop_list */ + nexthops = + XCALLOC(MTYPE_OSPF6_OTHER, nhcount * sizeof(struct in6_addr *)); + if (nexthops == NULL) { + zlog_warn("Can't send route to zebra: malloc failed"); + return; + } + + /* allocate memory for ifindex_list */ + ifindexes = XCALLOC(MTYPE_OSPF6_OTHER, nhcount * sizeof(ifindex_t)); + if (ifindexes == NULL) { + zlog_warn("Can't send route to zebra: malloc failed"); + XFREE(MTYPE_OSPF6_OTHER, nexthops); + return; + } + + ospf6_route_zebra_copy_nexthops(request, ifindexes, nexthops, nhcount); + + api.vrf_id = VRF_DEFAULT; + api.type = ZEBRA_ROUTE_OSPF6; + api.instance = 0; + api.flags = 0; + api.message = 0; + api.safi = SAFI_UNICAST; + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + api.nexthop_num = nhcount; + api.nexthop = nexthops; + SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); + api.ifindex_num = nhcount; + api.ifindex = ifindexes; + SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); + api.metric = (request->path.metric_type == 2 ? request->path.u.cost_e2 + : request->path.cost); + if (request->path.tag) { + SET_FLAG(api.message, ZAPI_MESSAGE_TAG); + api.tag = request->path.tag; + } + + dest = (struct prefix_ipv6 *)&request->prefix; + + SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE); + api.distance = ospf6_distance_apply(dest, request); + + if (type == REM) + ret = zapi_ipv6_route(ZEBRA_IPV6_ROUTE_DELETE, zclient, dest, + NULL, &api); + else + ret = zapi_ipv6_route(ZEBRA_IPV6_ROUTE_ADD, zclient, dest, NULL, + &api); + + if (ret < 0) + zlog_err("zapi_ipv6_route() %s failed: %s", + (type == REM ? "delete" : "add"), + safe_strerror(errno)); + + XFREE(MTYPE_OSPF6_OTHER, nexthops); + XFREE(MTYPE_OSPF6_OTHER, ifindexes); + + return; } -void -ospf6_zebra_route_update_add (struct ospf6_route *request) +void ospf6_zebra_route_update_add(struct ospf6_route *request) { - if (! vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], - VRF_DEFAULT)) - { - ospf6->route_table->hook_add = NULL; - ospf6->route_table->hook_remove = NULL; - return; - } - ospf6_zebra_route_update (ADD, request); + if (!vrf_bitmap_check(zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], + VRF_DEFAULT)) { + ospf6->route_table->hook_add = NULL; + ospf6->route_table->hook_remove = NULL; + return; + } + ospf6_zebra_route_update(ADD, request); } -void -ospf6_zebra_route_update_remove (struct ospf6_route *request) +void ospf6_zebra_route_update_remove(struct ospf6_route *request) { - if (! vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], - VRF_DEFAULT)) - { - ospf6->route_table->hook_add = NULL; - ospf6->route_table->hook_remove = NULL; - return; - } - ospf6_zebra_route_update (REM, request); + if (!vrf_bitmap_check(zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], + VRF_DEFAULT)) { + ospf6->route_table->hook_add = NULL; + ospf6->route_table->hook_remove = NULL; + return; + } + ospf6_zebra_route_update(REM, request); } -void -ospf6_zebra_add_discard (struct ospf6_route *request) +void ospf6_zebra_add_discard(struct ospf6_route *request) { - struct zapi_ipv6 api; - char buf[INET6_ADDRSTRLEN]; - struct prefix_ipv6 *dest; - - if (vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], - VRF_DEFAULT)) - { - if (!CHECK_FLAG (request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) - { - api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_OSPF6; - api.flags = ZEBRA_FLAG_BLACKHOLE; - api.instance = 0; - api.message = 0; - api.safi = SAFI_UNICAST; - SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = 0; - api.ifindex_num = 0; - - dest = (struct prefix_ipv6 *) &request->prefix; - - zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, dest, NULL, &api); - - if (IS_OSPF6_DEBUG_ZEBRA (SEND)) - zlog_debug ("Zebra: Route add discard %s/%d", - inet_ntop (AF_INET6, &dest->prefix, - buf, INET6_ADDRSTRLEN), - dest->prefixlen); - SET_FLAG (request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED); + struct zapi_ipv6 api; + char buf[INET6_ADDRSTRLEN]; + struct prefix_ipv6 *dest; + + if (vrf_bitmap_check(zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], + VRF_DEFAULT)) { + if (!CHECK_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) { + api.vrf_id = VRF_DEFAULT; + api.type = ZEBRA_ROUTE_OSPF6; + api.flags = ZEBRA_FLAG_BLACKHOLE; + api.instance = 0; + api.message = 0; + api.safi = SAFI_UNICAST; + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + api.nexthop_num = 0; + api.ifindex_num = 0; + + dest = (struct prefix_ipv6 *)&request->prefix; + + zapi_ipv6_route(ZEBRA_IPV6_ROUTE_ADD, zclient, dest, + NULL, &api); + + if (IS_OSPF6_DEBUG_ZEBRA(SEND)) + zlog_debug("Zebra: Route add discard %s/%d", + inet_ntop(AF_INET6, &dest->prefix, + buf, INET6_ADDRSTRLEN), + dest->prefixlen); + SET_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED); + } else { + dest = (struct prefix_ipv6 *)&request->prefix; + + if (IS_OSPF6_DEBUG_ZEBRA(SEND)) + zlog_debug( + "Zebra: Blackhole route present already %s/%d", + inet_ntop(AF_INET6, &dest->prefix, buf, + INET6_ADDRSTRLEN), + dest->prefixlen); + } } - else - { - dest = (struct prefix_ipv6 *) &request->prefix; - - if (IS_OSPF6_DEBUG_ZEBRA (SEND)) - zlog_debug ("Zebra: Blackhole route present already %s/%d", - inet_ntop (AF_INET6, &dest->prefix, - buf, INET6_ADDRSTRLEN), - dest->prefixlen); - } - } } -void -ospf6_zebra_delete_discard (struct ospf6_route *request) +void ospf6_zebra_delete_discard(struct ospf6_route *request) { - struct zapi_ipv6 api; - char buf[INET6_ADDRSTRLEN]; - struct prefix_ipv6 *dest; - - if (vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], VRF_DEFAULT)) - { - if (CHECK_FLAG (request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) - { - api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_OSPF6; - api.flags = ZEBRA_FLAG_BLACKHOLE; - api.instance = 0; - api.message = 0; - api.safi = SAFI_UNICAST; - SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = 0; - api.ifindex_num = 0; - - dest = (struct prefix_ipv6 *) &request->prefix; - - zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, dest, NULL, &api); - - if (IS_OSPF6_DEBUG_ZEBRA (SEND)) - zlog_debug ("Zebra: Route delete discard %s/%d", - inet_ntop (AF_INET6, &dest->prefix, buf, - INET6_ADDRSTRLEN), dest->prefixlen); - UNSET_FLAG (request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED); - } - else - { - dest = (struct prefix_ipv6 *) &request->prefix; - if (IS_OSPF6_DEBUG_ZEBRA (SEND)) - zlog_debug ("Zebra: Blackhole route already deleted %s/%d", - inet_ntop (AF_INET6, &dest->prefix, buf, - INET6_ADDRSTRLEN), dest->prefixlen); + struct zapi_ipv6 api; + char buf[INET6_ADDRSTRLEN]; + struct prefix_ipv6 *dest; + + if (vrf_bitmap_check(zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], + VRF_DEFAULT)) { + if (CHECK_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) { + api.vrf_id = VRF_DEFAULT; + api.type = ZEBRA_ROUTE_OSPF6; + api.flags = ZEBRA_FLAG_BLACKHOLE; + api.instance = 0; + api.message = 0; + api.safi = SAFI_UNICAST; + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + api.nexthop_num = 0; + api.ifindex_num = 0; + + dest = (struct prefix_ipv6 *)&request->prefix; + + zapi_ipv6_route(ZEBRA_IPV6_ROUTE_DELETE, zclient, dest, + NULL, &api); + + if (IS_OSPF6_DEBUG_ZEBRA(SEND)) + zlog_debug("Zebra: Route delete discard %s/%d", + inet_ntop(AF_INET6, &dest->prefix, + buf, INET6_ADDRSTRLEN), + dest->prefixlen); + UNSET_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED); + } else { + dest = (struct prefix_ipv6 *)&request->prefix; + if (IS_OSPF6_DEBUG_ZEBRA(SEND)) + zlog_debug( + "Zebra: Blackhole route already deleted %s/%d", + inet_ntop(AF_INET6, &dest->prefix, buf, + INET6_ADDRSTRLEN), + dest->prefixlen); + } } - } } DEFUN (redistribute_ospf6, @@ -606,25 +582,27 @@ DEFUN (redistribute_ospf6, "Redistribute control\n" "OSPF6 route\n") { - struct ospf6_route *route; + struct ospf6_route *route; - if (vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], VRF_DEFAULT)) - return CMD_SUCCESS; + if (vrf_bitmap_check(zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], + VRF_DEFAULT)) + return CMD_SUCCESS; - vrf_bitmap_set (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], VRF_DEFAULT); + vrf_bitmap_set(zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], + VRF_DEFAULT); - if (ospf6 == NULL) - return CMD_SUCCESS; + if (ospf6 == NULL) + return CMD_SUCCESS; - /* send ospf6 route to zebra route table */ - for (route = ospf6_route_head (ospf6->route_table); route; - route = ospf6_route_next (route)) - ospf6_zebra_route_update_add (route); + /* send ospf6 route to zebra route table */ + for (route = ospf6_route_head(ospf6->route_table); route; + route = ospf6_route_next(route)) + ospf6_zebra_route_update_add(route); - ospf6->route_table->hook_add = ospf6_zebra_route_update_add; - ospf6->route_table->hook_remove = ospf6_zebra_route_update_remove; + ospf6->route_table->hook_add = ospf6_zebra_route_update_add; + ospf6->route_table->hook_remove = ospf6_zebra_route_update_remove; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_redistribute_ospf6, @@ -634,212 +612,197 @@ DEFUN (no_redistribute_ospf6, "Redistribute control\n" "OSPF6 route\n") { - struct ospf6_route *route; + struct ospf6_route *route; - if (! vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], VRF_DEFAULT)) - return CMD_SUCCESS; + if (!vrf_bitmap_check(zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], + VRF_DEFAULT)) + return CMD_SUCCESS; - vrf_bitmap_unset (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], VRF_DEFAULT); + vrf_bitmap_unset(zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], + VRF_DEFAULT); - if (ospf6 == NULL) - return CMD_SUCCESS; + if (ospf6 == NULL) + return CMD_SUCCESS; - ospf6->route_table->hook_add = NULL; - ospf6->route_table->hook_remove = NULL; + ospf6->route_table->hook_add = NULL; + ospf6->route_table->hook_remove = NULL; - /* withdraw ospf6 route from zebra route table */ - for (route = ospf6_route_head (ospf6->route_table); route; - route = ospf6_route_next (route)) - ospf6_zebra_route_update_remove (route); + /* withdraw ospf6 route from zebra route table */ + for (route = ospf6_route_head(ospf6->route_table); route; + route = ospf6_route_next(route)) + ospf6_zebra_route_update_remove(route); - return CMD_SUCCESS; + return CMD_SUCCESS; } -static struct ospf6_distance * -ospf6_distance_new (void) +static struct ospf6_distance *ospf6_distance_new(void) { - return XCALLOC (MTYPE_OSPF6_DISTANCE, sizeof (struct ospf6_distance)); + return XCALLOC(MTYPE_OSPF6_DISTANCE, sizeof(struct ospf6_distance)); } -static void -ospf6_distance_free (struct ospf6_distance *odistance) +static void ospf6_distance_free(struct ospf6_distance *odistance) { - XFREE (MTYPE_OSPF6_DISTANCE, odistance); + XFREE(MTYPE_OSPF6_DISTANCE, odistance); } -int -ospf6_distance_set (struct vty *vty, struct ospf6 *o, - const char *distance_str, - const char *ip_str, - const char *access_list_str) +int ospf6_distance_set(struct vty *vty, struct ospf6 *o, + const char *distance_str, const char *ip_str, + const char *access_list_str) { - int ret; - struct prefix_ipv6 p; - u_char distance; - struct route_node *rn; - struct ospf6_distance *odistance; - - ret = str2prefix_ipv6 (ip_str, &p); - if (ret == 0) - { - vty_out (vty, "Malformed prefix\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - distance = atoi (distance_str); - - /* Get OSPF6 distance node. */ - rn = route_node_get (o->distance_table, (struct prefix *) &p); - if (rn->info) - { - odistance = rn->info; - route_unlock_node (rn); - } - else - { - odistance = ospf6_distance_new (); - rn->info = odistance; - } - - /* Set distance value. */ - odistance->distance = distance; - - /* Reset access-list configuration. */ - if (odistance->access_list) - { - free (odistance->access_list); - odistance->access_list = NULL; - } - if (access_list_str) - odistance->access_list = strdup (access_list_str); - - return CMD_SUCCESS; + int ret; + struct prefix_ipv6 p; + u_char distance; + struct route_node *rn; + struct ospf6_distance *odistance; + + ret = str2prefix_ipv6(ip_str, &p); + if (ret == 0) { + vty_out(vty, "Malformed prefix\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + distance = atoi(distance_str); + + /* Get OSPF6 distance node. */ + rn = route_node_get(o->distance_table, (struct prefix *)&p); + if (rn->info) { + odistance = rn->info; + route_unlock_node(rn); + } else { + odistance = ospf6_distance_new(); + rn->info = odistance; + } + + /* Set distance value. */ + odistance->distance = distance; + + /* Reset access-list configuration. */ + if (odistance->access_list) { + free(odistance->access_list); + odistance->access_list = NULL; + } + if (access_list_str) + odistance->access_list = strdup(access_list_str); + + return CMD_SUCCESS; } -int -ospf6_distance_unset (struct vty *vty, struct ospf6 *o, - const char *distance_str, - const char *ip_str, - const char *access_list_str) +int ospf6_distance_unset(struct vty *vty, struct ospf6 *o, + const char *distance_str, const char *ip_str, + const char *access_list_str) { - int ret; - struct prefix_ipv6 p; - struct route_node *rn; - struct ospf6_distance *odistance; - - ret = str2prefix_ipv6 (ip_str, &p); - if (ret == 0) - { - vty_out (vty, "Malformed prefix\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - rn = route_node_lookup (o->distance_table, (struct prefix *) &p); - if (!rn) - { - vty_out (vty, "Cant't find specified prefix\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - odistance = rn->info; - - if (odistance->access_list) - free (odistance->access_list); - ospf6_distance_free (odistance); - - rn->info = NULL; - route_unlock_node (rn); - route_unlock_node (rn); - - return CMD_SUCCESS; + int ret; + struct prefix_ipv6 p; + struct route_node *rn; + struct ospf6_distance *odistance; + + ret = str2prefix_ipv6(ip_str, &p); + if (ret == 0) { + vty_out(vty, "Malformed prefix\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + rn = route_node_lookup(o->distance_table, (struct prefix *)&p); + if (!rn) { + vty_out(vty, "Cant't find specified prefix\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + odistance = rn->info; + + if (odistance->access_list) + free(odistance->access_list); + ospf6_distance_free(odistance); + + rn->info = NULL; + route_unlock_node(rn); + route_unlock_node(rn); + + return CMD_SUCCESS; } -void -ospf6_distance_reset (struct ospf6 *o) +void ospf6_distance_reset(struct ospf6 *o) { - struct route_node *rn; - struct ospf6_distance *odistance; - - for (rn = route_top (o->distance_table); rn; rn = route_next (rn)) - if ((odistance = rn->info) != NULL) - { - if (odistance->access_list) - free (odistance->access_list); - ospf6_distance_free (odistance); - rn->info = NULL; - route_unlock_node (rn); - } + struct route_node *rn; + struct ospf6_distance *odistance; + + for (rn = route_top(o->distance_table); rn; rn = route_next(rn)) + if ((odistance = rn->info) != NULL) { + if (odistance->access_list) + free(odistance->access_list); + ospf6_distance_free(odistance); + rn->info = NULL; + route_unlock_node(rn); + } } -u_char -ospf6_distance_apply (struct prefix_ipv6 *p, struct ospf6_route *or) +u_char ospf6_distance_apply(struct prefix_ipv6 *p, struct ospf6_route * or) { - struct ospf6 *o; + struct ospf6 *o; - o = ospf6; - if (o == NULL) - return 0; + o = ospf6; + if (o == NULL) + return 0; - if (o->distance_intra) - if (or->path.type == OSPF6_PATH_TYPE_INTRA) - return o->distance_intra; + if (o->distance_intra) + if (or->path.type == OSPF6_PATH_TYPE_INTRA) + return o->distance_intra; - if (o->distance_inter) - if (or->path.type == OSPF6_PATH_TYPE_INTER) - return o->distance_inter; + if (o->distance_inter) + if (or->path.type == OSPF6_PATH_TYPE_INTER) + return o->distance_inter; - if (o->distance_external) - if(or->path.type == OSPF6_PATH_TYPE_EXTERNAL1 - || or->path.type == OSPF6_PATH_TYPE_EXTERNAL2) - return o->distance_external; + if (o->distance_external) + if (or->path.type == OSPF6_PATH_TYPE_EXTERNAL1 || + or->path.type == OSPF6_PATH_TYPE_EXTERNAL2) + return o->distance_external; - if (o->distance_all) - return o->distance_all; + if (o->distance_all) + return o->distance_all; - return 0; + return 0; } -static void -ospf6_zebra_connected (struct zclient *zclient) +static void ospf6_zebra_connected(struct zclient *zclient) { - /* Send the client registration */ - bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER); + /* Send the client registration */ + bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER); - zclient_send_reg_requests (zclient, VRF_DEFAULT); + zclient_send_reg_requests(zclient, VRF_DEFAULT); } -void -ospf6_zebra_init (struct thread_master *master) +void ospf6_zebra_init(struct thread_master *master) { - /* Allocate zebra structure. */ - zclient = zclient_new(master); - zclient_init (zclient, ZEBRA_ROUTE_OSPF6, 0); - zclient->zebra_connected = ospf6_zebra_connected; - zclient->router_id_update = ospf6_router_id_update_zebra; - zclient->interface_add = ospf6_zebra_if_add; - zclient->interface_delete = ospf6_zebra_if_del; - zclient->interface_up = ospf6_zebra_if_state_update; - zclient->interface_down = ospf6_zebra_if_state_update; - zclient->interface_address_add = ospf6_zebra_if_address_update_add; - zclient->interface_address_delete = ospf6_zebra_if_address_update_delete; - zclient->redistribute_route_ipv4_add = NULL; - zclient->redistribute_route_ipv4_del = NULL; - zclient->redistribute_route_ipv6_add = ospf6_zebra_read_ipv6; - zclient->redistribute_route_ipv6_del = ospf6_zebra_read_ipv6; - - /* redistribute connected route by default */ - /* ospf6_zebra_redistribute (ZEBRA_ROUTE_CONNECT); */ - - /* Install zebra node. */ - install_node (&zebra_node, config_write_ospf6_zebra); - - /* Install command element for zebra node. */ - install_element (VIEW_NODE, &show_ospf6_zebra_cmd); - install_default (ZEBRA_NODE); - install_element (ZEBRA_NODE, &redistribute_ospf6_cmd); - install_element (ZEBRA_NODE, &no_redistribute_ospf6_cmd); - - return; + /* Allocate zebra structure. */ + zclient = zclient_new(master); + zclient_init(zclient, ZEBRA_ROUTE_OSPF6, 0); + zclient->zebra_connected = ospf6_zebra_connected; + zclient->router_id_update = ospf6_router_id_update_zebra; + zclient->interface_add = ospf6_zebra_if_add; + zclient->interface_delete = ospf6_zebra_if_del; + zclient->interface_up = ospf6_zebra_if_state_update; + zclient->interface_down = ospf6_zebra_if_state_update; + zclient->interface_address_add = ospf6_zebra_if_address_update_add; + zclient->interface_address_delete = + ospf6_zebra_if_address_update_delete; + zclient->redistribute_route_ipv4_add = NULL; + zclient->redistribute_route_ipv4_del = NULL; + zclient->redistribute_route_ipv6_add = ospf6_zebra_read_ipv6; + zclient->redistribute_route_ipv6_del = ospf6_zebra_read_ipv6; + + /* redistribute connected route by default */ + /* ospf6_zebra_redistribute (ZEBRA_ROUTE_CONNECT); */ + + /* Install zebra node. */ + install_node(&zebra_node, config_write_ospf6_zebra); + + /* Install command element for zebra node. */ + install_element(VIEW_NODE, &show_ospf6_zebra_cmd); + install_default(ZEBRA_NODE); + install_element(ZEBRA_NODE, &redistribute_ospf6_cmd); + install_element(ZEBRA_NODE, &no_redistribute_ospf6_cmd); + + return; } /* Debug */ @@ -854,21 +817,19 @@ DEFUN (debug_ospf6_zebra_sendrecv, "Debug Receiving zebra\n" ) { - int idx_send_recv = 3; - unsigned char level = 0; - - if (argc == 4) - { - if (strmatch(argv[idx_send_recv]->text, "send")) - level = OSPF6_DEBUG_ZEBRA_SEND; - else if (strmatch(argv[idx_send_recv]->text, "recv")) - level = OSPF6_DEBUG_ZEBRA_RECV; - } - else - level = OSPF6_DEBUG_ZEBRA_SEND | OSPF6_DEBUG_ZEBRA_RECV; - - OSPF6_DEBUG_ZEBRA_ON (level); - return CMD_SUCCESS; + int idx_send_recv = 3; + unsigned char level = 0; + + if (argc == 4) { + if (strmatch(argv[idx_send_recv]->text, "send")) + level = OSPF6_DEBUG_ZEBRA_SEND; + else if (strmatch(argv[idx_send_recv]->text, "recv")) + level = OSPF6_DEBUG_ZEBRA_RECV; + } else + level = OSPF6_DEBUG_ZEBRA_SEND | OSPF6_DEBUG_ZEBRA_RECV; + + OSPF6_DEBUG_ZEBRA_ON(level); + return CMD_SUCCESS; } DEFUN (no_debug_ospf6_zebra_sendrecv, @@ -882,46 +843,39 @@ DEFUN (no_debug_ospf6_zebra_sendrecv, "Debug Receiving zebra\n" ) { - int idx_send_recv = 4; - unsigned char level = 0; - - if (argc == 5) - { - if (strmatch(argv[idx_send_recv]->text, "send")) - level = OSPF6_DEBUG_ZEBRA_SEND; - else if (strmatch(argv[idx_send_recv]->text, "recv")) - level = OSPF6_DEBUG_ZEBRA_RECV; - } - else - level = OSPF6_DEBUG_ZEBRA_SEND | OSPF6_DEBUG_ZEBRA_RECV; - - OSPF6_DEBUG_ZEBRA_OFF (level); - return CMD_SUCCESS; + int idx_send_recv = 4; + unsigned char level = 0; + + if (argc == 5) { + if (strmatch(argv[idx_send_recv]->text, "send")) + level = OSPF6_DEBUG_ZEBRA_SEND; + else if (strmatch(argv[idx_send_recv]->text, "recv")) + level = OSPF6_DEBUG_ZEBRA_RECV; + } else + level = OSPF6_DEBUG_ZEBRA_SEND | OSPF6_DEBUG_ZEBRA_RECV; + + OSPF6_DEBUG_ZEBRA_OFF(level); + return CMD_SUCCESS; } -int -config_write_ospf6_debug_zebra (struct vty *vty) +int config_write_ospf6_debug_zebra(struct vty *vty) { - if (IS_OSPF6_DEBUG_ZEBRA (SEND) && IS_OSPF6_DEBUG_ZEBRA (RECV)) - vty_out (vty, "debug ospf6 zebra\n"); - else - { - if (IS_OSPF6_DEBUG_ZEBRA (SEND)) - vty_out (vty, "debug ospf6 zebra send\n"); - if (IS_OSPF6_DEBUG_ZEBRA (RECV)) - vty_out (vty, "debug ospf6 zebra recv\n"); - } - return 0; + if (IS_OSPF6_DEBUG_ZEBRA(SEND) && IS_OSPF6_DEBUG_ZEBRA(RECV)) + vty_out(vty, "debug ospf6 zebra\n"); + else { + if (IS_OSPF6_DEBUG_ZEBRA(SEND)) + vty_out(vty, "debug ospf6 zebra send\n"); + if (IS_OSPF6_DEBUG_ZEBRA(RECV)) + vty_out(vty, "debug ospf6 zebra recv\n"); + } + return 0; } -void -install_element_ospf6_debug_zebra (void) +void install_element_ospf6_debug_zebra(void) { - install_element (ENABLE_NODE, &debug_ospf6_zebra_sendrecv_cmd); - install_element (ENABLE_NODE, &no_debug_ospf6_zebra_sendrecv_cmd); - install_element (CONFIG_NODE, &debug_ospf6_zebra_sendrecv_cmd); - install_element (CONFIG_NODE, &no_debug_ospf6_zebra_sendrecv_cmd); + install_element(ENABLE_NODE, &debug_ospf6_zebra_sendrecv_cmd); + install_element(ENABLE_NODE, &no_debug_ospf6_zebra_sendrecv_cmd); + install_element(CONFIG_NODE, &debug_ospf6_zebra_sendrecv_cmd); + install_element(CONFIG_NODE, &no_debug_ospf6_zebra_sendrecv_cmd); } - - diff --git a/ospf6d/ospf6_zebra.h b/ospf6d/ospf6_zebra.h index f7f808c86..8ab999336 100644 --- a/ospf6d/ospf6_zebra.h +++ b/ospf6d/ospf6_zebra.h @@ -27,46 +27,42 @@ extern unsigned char conf_debug_ospf6_zebra; #define OSPF6_DEBUG_ZEBRA_SEND 0x01 #define OSPF6_DEBUG_ZEBRA_RECV 0x02 -#define OSPF6_DEBUG_ZEBRA_ON(level) \ - (conf_debug_ospf6_zebra |= level) -#define OSPF6_DEBUG_ZEBRA_OFF(level) \ - (conf_debug_ospf6_zebra &= ~(level)) -#define IS_OSPF6_DEBUG_ZEBRA(e) \ - (conf_debug_ospf6_zebra & OSPF6_DEBUG_ZEBRA_ ## e) +#define OSPF6_DEBUG_ZEBRA_ON(level) (conf_debug_ospf6_zebra |= level) +#define OSPF6_DEBUG_ZEBRA_OFF(level) (conf_debug_ospf6_zebra &= ~(level)) +#define IS_OSPF6_DEBUG_ZEBRA(e) (conf_debug_ospf6_zebra & OSPF6_DEBUG_ZEBRA_##e) /* OSPF6 distance */ -struct ospf6_distance -{ - /* Distance value for the IP source prefix */ - u_char distance; +struct ospf6_distance { + /* Distance value for the IP source prefix */ + u_char distance; - /* Name of the access-list to be matched */ - char *access_list; + /* Name of the access-list to be matched */ + char *access_list; }; extern struct zclient *zclient; -extern void ospf6_zebra_route_update_add (struct ospf6_route *request); -extern void ospf6_zebra_route_update_remove (struct ospf6_route *request); +extern void ospf6_zebra_route_update_add(struct ospf6_route *request); +extern void ospf6_zebra_route_update_remove(struct ospf6_route *request); -extern void ospf6_zebra_redistribute (int); -extern void ospf6_zebra_no_redistribute (int); -#define ospf6_zebra_is_redistribute(type) \ - vrf_bitmap_check (zclient->redist[AFI_IP6][type], VRF_DEFAULT) -extern void ospf6_zebra_init (struct thread_master *); -extern void ospf6_zebra_add_discard (struct ospf6_route *request); -extern void ospf6_zebra_delete_discard (struct ospf6_route *request); +extern void ospf6_zebra_redistribute(int); +extern void ospf6_zebra_no_redistribute(int); +#define ospf6_zebra_is_redistribute(type) \ + vrf_bitmap_check(zclient->redist[AFI_IP6][type], VRF_DEFAULT) +extern void ospf6_zebra_init(struct thread_master *); +extern void ospf6_zebra_add_discard(struct ospf6_route *request); +extern void ospf6_zebra_delete_discard(struct ospf6_route *request); struct ospf6; -extern void ospf6_distance_reset (struct ospf6 *); -extern u_char ospf6_distance_apply (struct prefix_ipv6 *, struct ospf6_route *); +extern void ospf6_distance_reset(struct ospf6 *); +extern u_char ospf6_distance_apply(struct prefix_ipv6 *, struct ospf6_route *); -extern int ospf6_distance_set (struct vty *, struct ospf6 *, const char *, - const char *, const char *); -extern int ospf6_distance_unset (struct vty *, struct ospf6 *, const char *, - const char *, const char *); +extern int ospf6_distance_set(struct vty *, struct ospf6 *, const char *, + const char *, const char *); +extern int ospf6_distance_unset(struct vty *, struct ospf6 *, const char *, + const char *, const char *); -extern int config_write_ospf6_debug_zebra (struct vty *vty); -extern void install_element_ospf6_debug_zebra (void); +extern int config_write_ospf6_debug_zebra(struct vty *vty); +extern void install_element_ospf6_debug_zebra(void); #endif /*OSPF6_ZEBRA_H*/ diff --git a/ospf6d/ospf6d.c b/ospf6d/ospf6d.c index c4a499031..6b47fca57 100644 --- a/ospf6d/ospf6d.c +++ b/ospf6d/ospf6d.c @@ -46,31 +46,28 @@ char ospf6_daemon_version[] = OSPF6_DAEMON_VERSION; -struct route_node * -route_prev (struct route_node *node) +struct route_node *route_prev(struct route_node *node) { - struct route_node *end; - struct route_node *prev = NULL; - - end = node; - node = node->parent; - if (node) - route_lock_node (node); - while (node) - { - prev = node; - node = route_next (node); - if (node == end) - { - route_unlock_node (node); - node = NULL; - } - } - route_unlock_node (end); - if (prev) - route_lock_node (prev); - - return prev; + struct route_node *end; + struct route_node *prev = NULL; + + end = node; + node = node->parent; + if (node) + route_lock_node(node); + while (node) { + prev = node; + node = route_next(node); + if (node == end) { + route_unlock_node(node); + node = NULL; + } + } + route_unlock_node(end); + if (prev) + route_lock_node(prev); + + return prev; } @@ -83,86 +80,76 @@ DEFUN (show_version_ospf6, "Display ospf6d version\n" ) { - vty_out (vty, "Zebra OSPF6d Version: %s\n", - ospf6_daemon_version); + vty_out(vty, "Zebra OSPF6d Version: %s\n", ospf6_daemon_version); - return CMD_SUCCESS; + return CMD_SUCCESS; } -static struct cmd_node debug_node = -{ - DEBUG_NODE, - "", - 1 /* VTYSH */ +static struct cmd_node debug_node = { + DEBUG_NODE, "", 1 /* VTYSH */ }; -static int -config_write_ospf6_debug (struct vty *vty) +static int config_write_ospf6_debug(struct vty *vty) { - config_write_ospf6_debug_message (vty); - config_write_ospf6_debug_lsa (vty); - config_write_ospf6_debug_zebra (vty); - config_write_ospf6_debug_interface (vty); - config_write_ospf6_debug_neighbor (vty); - config_write_ospf6_debug_spf (vty); - config_write_ospf6_debug_route (vty); - config_write_ospf6_debug_brouter (vty); - config_write_ospf6_debug_asbr (vty); - config_write_ospf6_debug_abr (vty); - config_write_ospf6_debug_flood (vty); - vty_out (vty, "!\n"); - return 0; + config_write_ospf6_debug_message(vty); + config_write_ospf6_debug_lsa(vty); + config_write_ospf6_debug_zebra(vty); + config_write_ospf6_debug_interface(vty); + config_write_ospf6_debug_neighbor(vty); + config_write_ospf6_debug_spf(vty); + config_write_ospf6_debug_route(vty); + config_write_ospf6_debug_brouter(vty); + config_write_ospf6_debug_asbr(vty); + config_write_ospf6_debug_abr(vty); + config_write_ospf6_debug_flood(vty); + vty_out(vty, "!\n"); + return 0; } -#define AREA_LSDB_TITLE_FORMAT \ - "\n Area Scoped Link State Database (Area %s)\n\n" -#define IF_LSDB_TITLE_FORMAT \ - "\n I/F Scoped Link State Database (I/F %s in Area %s)\n\n" -#define AS_LSDB_TITLE_FORMAT \ - "\n AS Scoped Link State Database\n\n" +#define AREA_LSDB_TITLE_FORMAT \ + "\n Area Scoped Link State Database (Area %s)\n\n" +#define IF_LSDB_TITLE_FORMAT \ + "\n I/F Scoped Link State Database (I/F %s in Area %s)\n\n" +#define AS_LSDB_TITLE_FORMAT "\n AS Scoped Link State Database\n\n" -static int -parse_show_level (int idx_level, int argc, struct cmd_token **argv) +static int parse_show_level(int idx_level, int argc, struct cmd_token **argv) { - int level = OSPF6_LSDB_SHOW_LEVEL_NORMAL; - - if (argc > idx_level) - { - if (strmatch (argv[idx_level]->text, "detail")) - level = OSPF6_LSDB_SHOW_LEVEL_DETAIL; - else if (strmatch (argv[idx_level]->text, "dump")) - level = OSPF6_LSDB_SHOW_LEVEL_DUMP; - else if (strmatch (argv[idx_level]->text, "internal")) - level = OSPF6_LSDB_SHOW_LEVEL_INTERNAL; - } - - return level; + int level = OSPF6_LSDB_SHOW_LEVEL_NORMAL; + + if (argc > idx_level) { + if (strmatch(argv[idx_level]->text, "detail")) + level = OSPF6_LSDB_SHOW_LEVEL_DETAIL; + else if (strmatch(argv[idx_level]->text, "dump")) + level = OSPF6_LSDB_SHOW_LEVEL_DUMP; + else if (strmatch(argv[idx_level]->text, "internal")) + level = OSPF6_LSDB_SHOW_LEVEL_INTERNAL; + } + + return level; } -static u_int16_t -parse_type_spec (int idx_lsa, int argc, struct cmd_token **argv) +static u_int16_t parse_type_spec(int idx_lsa, int argc, struct cmd_token **argv) { - u_int16_t type = 0; - - if (argc > idx_lsa) - { - if (strmatch (argv[idx_lsa]->text, "router")) - type = htons (OSPF6_LSTYPE_ROUTER); - else if (strmatch (argv[idx_lsa]->text, "network")) - type = htons (OSPF6_LSTYPE_NETWORK); - else if (strmatch (argv[idx_lsa]->text, "as-external")) - type = htons (OSPF6_LSTYPE_AS_EXTERNAL); - else if (strmatch (argv[idx_lsa]->text, "intra-prefix")) - type = htons (OSPF6_LSTYPE_INTRA_PREFIX); - else if (strmatch (argv[idx_lsa]->text, "inter-router")) - type = htons (OSPF6_LSTYPE_INTER_ROUTER); - else if (strmatch (argv[idx_lsa]->text, "inter-prefix")) - type = htons (OSPF6_LSTYPE_INTER_PREFIX); - else if (strmatch (argv[idx_lsa]->text, "link")) - type = htons (OSPF6_LSTYPE_LINK); - } - - return type; + u_int16_t type = 0; + + if (argc > idx_lsa) { + if (strmatch(argv[idx_lsa]->text, "router")) + type = htons(OSPF6_LSTYPE_ROUTER); + else if (strmatch(argv[idx_lsa]->text, "network")) + type = htons(OSPF6_LSTYPE_NETWORK); + else if (strmatch(argv[idx_lsa]->text, "as-external")) + type = htons(OSPF6_LSTYPE_AS_EXTERNAL); + else if (strmatch(argv[idx_lsa]->text, "intra-prefix")) + type = htons(OSPF6_LSTYPE_INTRA_PREFIX); + else if (strmatch(argv[idx_lsa]->text, "inter-router")) + type = htons(OSPF6_LSTYPE_INTER_ROUTER); + else if (strmatch(argv[idx_lsa]->text, "inter-prefix")) + type = htons(OSPF6_LSTYPE_INTER_PREFIX); + else if (strmatch(argv[idx_lsa]->text, "link")) + type = htons(OSPF6_LSTYPE_LINK); + } + + return type; } DEFUN (show_ipv6_ospf6_database, @@ -176,38 +163,35 @@ DEFUN (show_ipv6_ospf6_database, "Dump LSAs\n" "Display LSA's internal information\n") { - int idx_level = 4; - int level; - struct listnode *i, *j; - struct ospf6 *o = ospf6; - struct ospf6_area *oa; - struct ospf6_interface *oi; - - OSPF6_CMD_CHECK_RUNNING (); - - level = parse_show_level (idx_level, argc, argv); - - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - vty_out (vty, AREA_LSDB_TITLE_FORMAT, oa->name); - ospf6_lsdb_show (vty, level, NULL, NULL, NULL, oa->lsdb); - } - - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi)) - { - vty_out (vty, IF_LSDB_TITLE_FORMAT, - oi->interface->name, oa->name); - ospf6_lsdb_show (vty, level, NULL, NULL, NULL, oi->lsdb); - } - } - - vty_out (vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show (vty, level, NULL, NULL, NULL, o->lsdb); - - vty_out (vty, "\n"); - return CMD_SUCCESS; + int idx_level = 4; + int level; + struct listnode *i, *j; + struct ospf6 *o = ospf6; + struct ospf6_area *oa; + struct ospf6_interface *oi; + + OSPF6_CMD_CHECK_RUNNING(); + + level = parse_show_level(idx_level, argc, argv); + + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); + ospf6_lsdb_show(vty, level, NULL, NULL, NULL, oa->lsdb); + } + + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { + vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name, + oa->name); + ospf6_lsdb_show(vty, level, NULL, NULL, NULL, oi->lsdb); + } + } + + vty_out(vty, AS_LSDB_TITLE_FORMAT); + ospf6_lsdb_show(vty, level, NULL, NULL, NULL, o->lsdb); + + vty_out(vty, "\n"); + return CMD_SUCCESS; } DEFUN (show_ipv6_ospf6_database_type, @@ -231,54 +215,52 @@ DEFUN (show_ipv6_ospf6_database_type, "Display LSA's internal information\n" ) { - int idx_lsa = 4; - int idx_level = 5; - int level; - struct listnode *i, *j; - struct ospf6 *o = ospf6; - struct ospf6_area *oa; - struct ospf6_interface *oi; - u_int16_t type = 0; - - OSPF6_CMD_CHECK_RUNNING (); - - type = parse_type_spec (idx_lsa, argc, argv); - level = parse_show_level (idx_level, argc, argv); - - switch (OSPF6_LSA_SCOPE (type)) - { - case OSPF6_SCOPE_AREA: - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - vty_out (vty, AREA_LSDB_TITLE_FORMAT, oa->name); - ospf6_lsdb_show (vty, level, &type, NULL, NULL, oa->lsdb); - } - break; - - case OSPF6_SCOPE_LINKLOCAL: - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi)) - { - vty_out (vty, IF_LSDB_TITLE_FORMAT, - oi->interface->name, oa->name); - ospf6_lsdb_show (vty, level, &type, NULL, NULL, oi->lsdb); - } - } - break; - - case OSPF6_SCOPE_AS: - vty_out (vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show (vty, level, &type, NULL, NULL, o->lsdb); - break; - - default: - assert (0); - break; - } - - vty_out (vty, "\n"); - return CMD_SUCCESS; + int idx_lsa = 4; + int idx_level = 5; + int level; + struct listnode *i, *j; + struct ospf6 *o = ospf6; + struct ospf6_area *oa; + struct ospf6_interface *oi; + u_int16_t type = 0; + + OSPF6_CMD_CHECK_RUNNING(); + + type = parse_type_spec(idx_lsa, argc, argv); + level = parse_show_level(idx_level, argc, argv); + + switch (OSPF6_LSA_SCOPE(type)) { + case OSPF6_SCOPE_AREA: + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); + ospf6_lsdb_show(vty, level, &type, NULL, NULL, + oa->lsdb); + } + break; + + case OSPF6_SCOPE_LINKLOCAL: + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { + vty_out(vty, IF_LSDB_TITLE_FORMAT, + oi->interface->name, oa->name); + ospf6_lsdb_show(vty, level, &type, NULL, NULL, + oi->lsdb); + } + } + break; + + case OSPF6_SCOPE_AS: + vty_out(vty, AS_LSDB_TITLE_FORMAT); + ospf6_lsdb_show(vty, level, &type, NULL, NULL, o->lsdb); + break; + + default: + assert(0); + break; + } + + vty_out(vty, "\n"); + return CMD_SUCCESS; } DEFUN (show_ipv6_ospf6_database_id, @@ -295,43 +277,40 @@ DEFUN (show_ipv6_ospf6_database_id, "Dump LSAs\n" "Display LSA's internal information\n") { - int idx_ipv4 = 5; - int idx_level = 6; - int level; - struct listnode *i, *j; - struct ospf6 *o = ospf6; - struct ospf6_area *oa; - struct ospf6_interface *oi; - u_int32_t id = 0; - - OSPF6_CMD_CHECK_RUNNING (); - - if (argv[idx_ipv4]->type == IPV4_TKN) - inet_pton (AF_INET, argv[idx_ipv4]->arg, &id); - - level = parse_show_level (idx_level, argc, argv); - - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - vty_out (vty, AREA_LSDB_TITLE_FORMAT, oa->name); - ospf6_lsdb_show (vty, level, NULL, &id, NULL, oa->lsdb); - } - - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi)) - { - vty_out (vty, IF_LSDB_TITLE_FORMAT, - oi->interface->name, oa->name); - ospf6_lsdb_show (vty, level, NULL, &id, NULL, oi->lsdb); - } - } - - vty_out (vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show (vty, level, NULL, &id, NULL, o->lsdb); - - vty_out (vty, "\n"); - return CMD_SUCCESS; + int idx_ipv4 = 5; + int idx_level = 6; + int level; + struct listnode *i, *j; + struct ospf6 *o = ospf6; + struct ospf6_area *oa; + struct ospf6_interface *oi; + u_int32_t id = 0; + + OSPF6_CMD_CHECK_RUNNING(); + + if (argv[idx_ipv4]->type == IPV4_TKN) + inet_pton(AF_INET, argv[idx_ipv4]->arg, &id); + + level = parse_show_level(idx_level, argc, argv); + + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); + ospf6_lsdb_show(vty, level, NULL, &id, NULL, oa->lsdb); + } + + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { + vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name, + oa->name); + ospf6_lsdb_show(vty, level, NULL, &id, NULL, oi->lsdb); + } + } + + vty_out(vty, AS_LSDB_TITLE_FORMAT); + ospf6_lsdb_show(vty, level, NULL, &id, NULL, o->lsdb); + + vty_out(vty, "\n"); + return CMD_SUCCESS; } DEFUN (show_ipv6_ospf6_database_router, @@ -349,40 +328,38 @@ DEFUN (show_ipv6_ospf6_database_router, "Dump LSAs\n" "Display LSA's internal information\n") { - int idx_ipv4 = 6; - int idx_level = 7; - int level; - struct listnode *i, *j; - struct ospf6 *o = ospf6; - struct ospf6_area *oa; - struct ospf6_interface *oi; - u_int32_t adv_router = 0; - - OSPF6_CMD_CHECK_RUNNING (); - inet_pton (AF_INET, argv[idx_ipv4]->arg, &adv_router); - level = parse_show_level (idx_level, argc, argv); - - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - vty_out (vty, AREA_LSDB_TITLE_FORMAT, oa->name); - ospf6_lsdb_show (vty, level, NULL, NULL, &adv_router, oa->lsdb); - } - - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi)) - { - vty_out (vty, IF_LSDB_TITLE_FORMAT, - oi->interface->name, oa->name); - ospf6_lsdb_show (vty, level, NULL, NULL, &adv_router, oi->lsdb); - } - } - - vty_out (vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show (vty, level, NULL, NULL, &adv_router, o->lsdb); - - vty_out (vty, "\n"); - return CMD_SUCCESS; + int idx_ipv4 = 6; + int idx_level = 7; + int level; + struct listnode *i, *j; + struct ospf6 *o = ospf6; + struct ospf6_area *oa; + struct ospf6_interface *oi; + u_int32_t adv_router = 0; + + OSPF6_CMD_CHECK_RUNNING(); + inet_pton(AF_INET, argv[idx_ipv4]->arg, &adv_router); + level = parse_show_level(idx_level, argc, argv); + + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); + ospf6_lsdb_show(vty, level, NULL, NULL, &adv_router, oa->lsdb); + } + + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { + vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name, + oa->name); + ospf6_lsdb_show(vty, level, NULL, NULL, &adv_router, + oi->lsdb); + } + } + + vty_out(vty, AS_LSDB_TITLE_FORMAT); + ospf6_lsdb_show(vty, level, NULL, NULL, &adv_router, o->lsdb); + + vty_out(vty, "\n"); + return CMD_SUCCESS; } DEFUN (show_ipv6_ospf6_database_type_id, @@ -408,57 +385,54 @@ DEFUN (show_ipv6_ospf6_database_type_id, "Display LSA's internal information\n" ) { - int idx_lsa = 4; - int idx_ipv4 = 6; - int idx_level = 7; - int level; - struct listnode *i, *j; - struct ospf6 *o = ospf6; - struct ospf6_area *oa; - struct ospf6_interface *oi; - u_int16_t type = 0; - u_int32_t id = 0; - - OSPF6_CMD_CHECK_RUNNING (); - - type = parse_type_spec (idx_lsa, argc, argv); - inet_pton (AF_INET, argv[idx_ipv4]->arg, &id); - level = parse_show_level (idx_level, argc, argv); - - switch (OSPF6_LSA_SCOPE (type)) - { - case OSPF6_SCOPE_AREA: - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - vty_out (vty, AREA_LSDB_TITLE_FORMAT, oa->name); - ospf6_lsdb_show (vty, level, &type, &id, NULL, oa->lsdb); - } - break; - - case OSPF6_SCOPE_LINKLOCAL: - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi)) - { - vty_out (vty, IF_LSDB_TITLE_FORMAT, - oi->interface->name, oa->name); - ospf6_lsdb_show (vty, level, &type, &id, NULL, oi->lsdb); - } - } - break; - - case OSPF6_SCOPE_AS: - vty_out (vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show (vty, level, &type, &id, NULL, o->lsdb); - break; - - default: - assert (0); - break; - } - - vty_out (vty, "\n"); - return CMD_SUCCESS; + int idx_lsa = 4; + int idx_ipv4 = 6; + int idx_level = 7; + int level; + struct listnode *i, *j; + struct ospf6 *o = ospf6; + struct ospf6_area *oa; + struct ospf6_interface *oi; + u_int16_t type = 0; + u_int32_t id = 0; + + OSPF6_CMD_CHECK_RUNNING(); + + type = parse_type_spec(idx_lsa, argc, argv); + inet_pton(AF_INET, argv[idx_ipv4]->arg, &id); + level = parse_show_level(idx_level, argc, argv); + + switch (OSPF6_LSA_SCOPE(type)) { + case OSPF6_SCOPE_AREA: + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); + ospf6_lsdb_show(vty, level, &type, &id, NULL, oa->lsdb); + } + break; + + case OSPF6_SCOPE_LINKLOCAL: + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { + vty_out(vty, IF_LSDB_TITLE_FORMAT, + oi->interface->name, oa->name); + ospf6_lsdb_show(vty, level, &type, &id, NULL, + oi->lsdb); + } + } + break; + + case OSPF6_SCOPE_AS: + vty_out(vty, AS_LSDB_TITLE_FORMAT); + ospf6_lsdb_show(vty, level, &type, &id, NULL, o->lsdb); + break; + + default: + assert(0); + break; + } + + vty_out(vty, "\n"); + return CMD_SUCCESS; } DEFUN (show_ipv6_ospf6_database_type_router, @@ -485,57 +459,55 @@ DEFUN (show_ipv6_ospf6_database_type_router, "Display LSA's internal information\n" ) { - int idx_lsa = 4; - int idx_ipv4 = 6; - int idx_level = 7; - int level; - struct listnode *i, *j; - struct ospf6 *o = ospf6; - struct ospf6_area *oa; - struct ospf6_interface *oi; - u_int16_t type = 0; - u_int32_t adv_router = 0; - - OSPF6_CMD_CHECK_RUNNING (); - - type = parse_type_spec (idx_lsa, argc, argv); - inet_pton (AF_INET, argv[idx_ipv4]->arg, &adv_router); - level = parse_show_level (idx_level, argc, argv); - - switch (OSPF6_LSA_SCOPE (type)) - { - case OSPF6_SCOPE_AREA: - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - vty_out (vty, AREA_LSDB_TITLE_FORMAT, oa->name); - ospf6_lsdb_show (vty, level, &type, NULL, &adv_router, oa->lsdb); - } - break; - - case OSPF6_SCOPE_LINKLOCAL: - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi)) - { - vty_out (vty, IF_LSDB_TITLE_FORMAT, - oi->interface->name, oa->name); - ospf6_lsdb_show (vty, level, &type, NULL, &adv_router, oi->lsdb); - } - } - break; - - case OSPF6_SCOPE_AS: - vty_out (vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show (vty, level, &type, NULL, &adv_router, o->lsdb); - break; - - default: - assert (0); - break; - } - - vty_out (vty, "\n"); - return CMD_SUCCESS; + int idx_lsa = 4; + int idx_ipv4 = 6; + int idx_level = 7; + int level; + struct listnode *i, *j; + struct ospf6 *o = ospf6; + struct ospf6_area *oa; + struct ospf6_interface *oi; + u_int16_t type = 0; + u_int32_t adv_router = 0; + + OSPF6_CMD_CHECK_RUNNING(); + + type = parse_type_spec(idx_lsa, argc, argv); + inet_pton(AF_INET, argv[idx_ipv4]->arg, &adv_router); + level = parse_show_level(idx_level, argc, argv); + + switch (OSPF6_LSA_SCOPE(type)) { + case OSPF6_SCOPE_AREA: + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); + ospf6_lsdb_show(vty, level, &type, NULL, &adv_router, + oa->lsdb); + } + break; + + case OSPF6_SCOPE_LINKLOCAL: + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { + vty_out(vty, IF_LSDB_TITLE_FORMAT, + oi->interface->name, oa->name); + ospf6_lsdb_show(vty, level, &type, NULL, + &adv_router, oi->lsdb); + } + } + break; + + case OSPF6_SCOPE_AS: + vty_out(vty, AS_LSDB_TITLE_FORMAT); + ospf6_lsdb_show(vty, level, &type, NULL, &adv_router, o->lsdb); + break; + + default: + assert(0); + break; + } + + vty_out(vty, "\n"); + return CMD_SUCCESS; } @@ -554,43 +526,41 @@ DEFUN (show_ipv6_ospf6_database_id_router, "Display LSA's internal information\n" ) { - int idx_ls_id = 5; - int idx_adv_rtr = 6; - int idx_level = 7; - int level; - struct listnode *i, *j; - struct ospf6 *o = ospf6; - struct ospf6_area *oa; - struct ospf6_interface *oi; - u_int32_t id = 0; - u_int32_t adv_router = 0; - - OSPF6_CMD_CHECK_RUNNING (); - inet_pton (AF_INET, argv[idx_ls_id]->arg, &id); - inet_pton (AF_INET, argv[idx_adv_rtr]->arg, &adv_router); - level = parse_show_level (idx_level, argc, argv); - - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - vty_out (vty, AREA_LSDB_TITLE_FORMAT, oa->name); - ospf6_lsdb_show (vty, level, NULL, &id, &adv_router, oa->lsdb); - } - - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi)) - { - vty_out (vty, IF_LSDB_TITLE_FORMAT, - oi->interface->name, oa->name); - ospf6_lsdb_show (vty, level, NULL, &id, &adv_router, oi->lsdb); - } - } - - vty_out (vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show (vty, level, NULL, &id, &adv_router, o->lsdb); - - vty_out (vty, "\n"); - return CMD_SUCCESS; + int idx_ls_id = 5; + int idx_adv_rtr = 6; + int idx_level = 7; + int level; + struct listnode *i, *j; + struct ospf6 *o = ospf6; + struct ospf6_area *oa; + struct ospf6_interface *oi; + u_int32_t id = 0; + u_int32_t adv_router = 0; + + OSPF6_CMD_CHECK_RUNNING(); + inet_pton(AF_INET, argv[idx_ls_id]->arg, &id); + inet_pton(AF_INET, argv[idx_adv_rtr]->arg, &adv_router); + level = parse_show_level(idx_level, argc, argv); + + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); + ospf6_lsdb_show(vty, level, NULL, &id, &adv_router, oa->lsdb); + } + + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { + vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name, + oa->name); + ospf6_lsdb_show(vty, level, NULL, &id, &adv_router, + oi->lsdb); + } + } + + vty_out(vty, AS_LSDB_TITLE_FORMAT); + ospf6_lsdb_show(vty, level, NULL, &id, &adv_router, o->lsdb); + + vty_out(vty, "\n"); + return CMD_SUCCESS; } @@ -609,43 +579,41 @@ DEFUN (show_ipv6_ospf6_database_adv_router_linkstate_id, "Dump LSAs\n" "Display LSA's internal information\n") { - int idx_adv_rtr = 5; - int idx_ls_id = 7; - int idx_level = 8; - int level; - struct listnode *i, *j; - struct ospf6 *o = ospf6; - struct ospf6_area *oa; - struct ospf6_interface *oi; - u_int32_t id = 0; - u_int32_t adv_router = 0; - - OSPF6_CMD_CHECK_RUNNING (); - inet_pton (AF_INET, argv[idx_adv_rtr]->arg, &adv_router); - inet_pton (AF_INET, argv[idx_ls_id]->arg, &id); - level = parse_show_level (idx_level, argc, argv); - - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - vty_out (vty, AREA_LSDB_TITLE_FORMAT, oa->name); - ospf6_lsdb_show (vty, level, NULL, &id, &adv_router, oa->lsdb); - } - - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi)) - { - vty_out (vty, IF_LSDB_TITLE_FORMAT, - oi->interface->name, oa->name); - ospf6_lsdb_show (vty, level, NULL, &id, &adv_router, oi->lsdb); - } - } - - vty_out (vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show (vty, level, NULL, &id, &adv_router, o->lsdb); - - vty_out (vty, "\n"); - return CMD_SUCCESS; + int idx_adv_rtr = 5; + int idx_ls_id = 7; + int idx_level = 8; + int level; + struct listnode *i, *j; + struct ospf6 *o = ospf6; + struct ospf6_area *oa; + struct ospf6_interface *oi; + u_int32_t id = 0; + u_int32_t adv_router = 0; + + OSPF6_CMD_CHECK_RUNNING(); + inet_pton(AF_INET, argv[idx_adv_rtr]->arg, &adv_router); + inet_pton(AF_INET, argv[idx_ls_id]->arg, &id); + level = parse_show_level(idx_level, argc, argv); + + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); + ospf6_lsdb_show(vty, level, NULL, &id, &adv_router, oa->lsdb); + } + + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { + vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name, + oa->name); + ospf6_lsdb_show(vty, level, NULL, &id, &adv_router, + oi->lsdb); + } + } + + vty_out(vty, AS_LSDB_TITLE_FORMAT); + ospf6_lsdb_show(vty, level, NULL, &id, &adv_router, o->lsdb); + + vty_out(vty, "\n"); + return CMD_SUCCESS; } DEFUN (show_ipv6_ospf6_database_type_id_router, @@ -669,60 +637,58 @@ DEFUN (show_ipv6_ospf6_database_type_id_router, "Dump LSAs\n" "Display LSA's internal information\n") { - int idx_lsa = 4; - int idx_ls_id = 5; - int idx_adv_rtr = 6; - int idx_level = 7; - int level; - struct listnode *i, *j; - struct ospf6 *o = ospf6; - struct ospf6_area *oa; - struct ospf6_interface *oi; - u_int16_t type = 0; - u_int32_t id = 0; - u_int32_t adv_router = 0; - - OSPF6_CMD_CHECK_RUNNING (); - - type = parse_type_spec (idx_lsa, argc, argv); - inet_pton (AF_INET, argv[idx_ls_id]->arg, &id); - inet_pton (AF_INET, argv[idx_adv_rtr]->arg, &adv_router); - level = parse_show_level (idx_level, argc, argv); - - switch (OSPF6_LSA_SCOPE (type)) - { - case OSPF6_SCOPE_AREA: - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - vty_out (vty, AREA_LSDB_TITLE_FORMAT, oa->name); - ospf6_lsdb_show (vty, level, &type, &id, &adv_router, oa->lsdb); - } - break; - - case OSPF6_SCOPE_LINKLOCAL: - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi)) - { - vty_out (vty, IF_LSDB_TITLE_FORMAT, - oi->interface->name, oa->name); - ospf6_lsdb_show (vty, level, &type, &id, &adv_router, oi->lsdb); - } - } - break; - - case OSPF6_SCOPE_AS: - vty_out (vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show (vty, level, &type, &id, &adv_router, o->lsdb); - break; - - default: - assert (0); - break; - } - - vty_out (vty, "\n"); - return CMD_SUCCESS; + int idx_lsa = 4; + int idx_ls_id = 5; + int idx_adv_rtr = 6; + int idx_level = 7; + int level; + struct listnode *i, *j; + struct ospf6 *o = ospf6; + struct ospf6_area *oa; + struct ospf6_interface *oi; + u_int16_t type = 0; + u_int32_t id = 0; + u_int32_t adv_router = 0; + + OSPF6_CMD_CHECK_RUNNING(); + + type = parse_type_spec(idx_lsa, argc, argv); + inet_pton(AF_INET, argv[idx_ls_id]->arg, &id); + inet_pton(AF_INET, argv[idx_adv_rtr]->arg, &adv_router); + level = parse_show_level(idx_level, argc, argv); + + switch (OSPF6_LSA_SCOPE(type)) { + case OSPF6_SCOPE_AREA: + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); + ospf6_lsdb_show(vty, level, &type, &id, &adv_router, + oa->lsdb); + } + break; + + case OSPF6_SCOPE_LINKLOCAL: + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { + vty_out(vty, IF_LSDB_TITLE_FORMAT, + oi->interface->name, oa->name); + ospf6_lsdb_show(vty, level, &type, &id, + &adv_router, oi->lsdb); + } + } + break; + + case OSPF6_SCOPE_AS: + vty_out(vty, AS_LSDB_TITLE_FORMAT); + ospf6_lsdb_show(vty, level, &type, &id, &adv_router, o->lsdb); + break; + + default: + assert(0); + break; + } + + vty_out(vty, "\n"); + return CMD_SUCCESS; } @@ -749,60 +715,58 @@ DEFUN (show_ipv6_ospf6_database_type_adv_router_linkstate_id, "Dump LSAs\n" "Display LSA's internal information\n") { - int idx_lsa = 4; - int idx_adv_rtr = 6; - int idx_ls_id = 8; - int idx_level = 9; - int level; - struct listnode *i, *j; - struct ospf6 *o = ospf6; - struct ospf6_area *oa; - struct ospf6_interface *oi; - u_int16_t type = 0; - u_int32_t id = 0; - u_int32_t adv_router = 0; - - OSPF6_CMD_CHECK_RUNNING (); - - type = parse_type_spec (idx_lsa, argc, argv); - inet_pton (AF_INET, argv[idx_adv_rtr]->arg, &adv_router); - inet_pton (AF_INET, argv[idx_ls_id]->arg, &id); - level = parse_show_level (idx_level, argc, argv); - - switch (OSPF6_LSA_SCOPE (type)) - { - case OSPF6_SCOPE_AREA: - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - vty_out (vty, AREA_LSDB_TITLE_FORMAT, oa->name); - ospf6_lsdb_show (vty, level, &type, &id, &adv_router, oa->lsdb); - } - break; - - case OSPF6_SCOPE_LINKLOCAL: - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi)) - { - vty_out (vty, IF_LSDB_TITLE_FORMAT, - oi->interface->name, oa->name); - ospf6_lsdb_show (vty, level, &type, &id, &adv_router, oi->lsdb); - } - } - break; - - case OSPF6_SCOPE_AS: - vty_out (vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show (vty, level, &type, &id, &adv_router, o->lsdb); - break; - - default: - assert (0); - break; - } - - vty_out (vty, "\n"); - return CMD_SUCCESS; + int idx_lsa = 4; + int idx_adv_rtr = 6; + int idx_ls_id = 8; + int idx_level = 9; + int level; + struct listnode *i, *j; + struct ospf6 *o = ospf6; + struct ospf6_area *oa; + struct ospf6_interface *oi; + u_int16_t type = 0; + u_int32_t id = 0; + u_int32_t adv_router = 0; + + OSPF6_CMD_CHECK_RUNNING(); + + type = parse_type_spec(idx_lsa, argc, argv); + inet_pton(AF_INET, argv[idx_adv_rtr]->arg, &adv_router); + inet_pton(AF_INET, argv[idx_ls_id]->arg, &id); + level = parse_show_level(idx_level, argc, argv); + + switch (OSPF6_LSA_SCOPE(type)) { + case OSPF6_SCOPE_AREA: + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); + ospf6_lsdb_show(vty, level, &type, &id, &adv_router, + oa->lsdb); + } + break; + + case OSPF6_SCOPE_LINKLOCAL: + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { + vty_out(vty, IF_LSDB_TITLE_FORMAT, + oi->interface->name, oa->name); + ospf6_lsdb_show(vty, level, &type, &id, + &adv_router, oi->lsdb); + } + } + break; + + case OSPF6_SCOPE_AS: + vty_out(vty, AS_LSDB_TITLE_FORMAT); + ospf6_lsdb_show(vty, level, &type, &id, &adv_router, o->lsdb); + break; + + default: + assert(0); + break; + } + + vty_out(vty, "\n"); + return CMD_SUCCESS; } DEFUN (show_ipv6_ospf6_database_self_originated, @@ -817,39 +781,37 @@ DEFUN (show_ipv6_ospf6_database_self_originated, "Dump LSAs\n" "Display LSA's internal information\n") { - int idx_level = 5; - int level; - struct listnode *i, *j; - struct ospf6 *o = ospf6; - struct ospf6_area *oa; - struct ospf6_interface *oi; - u_int32_t adv_router = 0; - - OSPF6_CMD_CHECK_RUNNING (); - level = parse_show_level (idx_level, argc, argv); - adv_router = o->router_id; - - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - vty_out (vty, AREA_LSDB_TITLE_FORMAT, oa->name); - ospf6_lsdb_show (vty, level, NULL, NULL, &adv_router, oa->lsdb); - } - - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi)) - { - vty_out (vty, IF_LSDB_TITLE_FORMAT, - oi->interface->name, oa->name); - ospf6_lsdb_show (vty, level, NULL, NULL, &adv_router, oi->lsdb); - } - } - - vty_out (vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show (vty, level, NULL, NULL, &adv_router, o->lsdb); - - vty_out (vty, "\n"); - return CMD_SUCCESS; + int idx_level = 5; + int level; + struct listnode *i, *j; + struct ospf6 *o = ospf6; + struct ospf6_area *oa; + struct ospf6_interface *oi; + u_int32_t adv_router = 0; + + OSPF6_CMD_CHECK_RUNNING(); + level = parse_show_level(idx_level, argc, argv); + adv_router = o->router_id; + + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); + ospf6_lsdb_show(vty, level, NULL, NULL, &adv_router, oa->lsdb); + } + + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { + vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name, + oa->name); + ospf6_lsdb_show(vty, level, NULL, NULL, &adv_router, + oi->lsdb); + } + } + + vty_out(vty, AS_LSDB_TITLE_FORMAT); + ospf6_lsdb_show(vty, level, NULL, NULL, &adv_router, o->lsdb); + + vty_out(vty, "\n"); + return CMD_SUCCESS; } @@ -874,57 +836,55 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated, "Dump LSAs\n" "Display LSA's internal information\n") { - int idx_lsa = 4; - int idx_level = 6; - int level; - struct listnode *i, *j; - struct ospf6 *o = ospf6; - struct ospf6_area *oa; - struct ospf6_interface *oi; - u_int16_t type = 0; - u_int32_t adv_router = 0; - - OSPF6_CMD_CHECK_RUNNING (); - - type = parse_type_spec (idx_lsa, argc, argv); - level = parse_show_level (idx_level, argc, argv); - - adv_router = o->router_id; - - switch (OSPF6_LSA_SCOPE (type)) - { - case OSPF6_SCOPE_AREA: - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - vty_out (vty, AREA_LSDB_TITLE_FORMAT, oa->name); - ospf6_lsdb_show (vty, level, &type, NULL, &adv_router, oa->lsdb); - } - break; - - case OSPF6_SCOPE_LINKLOCAL: - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi)) - { - vty_out (vty, IF_LSDB_TITLE_FORMAT, - oi->interface->name, oa->name); - ospf6_lsdb_show (vty, level, &type, NULL, &adv_router, oi->lsdb); - } - } - break; - - case OSPF6_SCOPE_AS: - vty_out (vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show (vty, level, &type, NULL, &adv_router, o->lsdb); - break; - - default: - assert (0); - break; - } - - vty_out (vty, "\n"); - return CMD_SUCCESS; + int idx_lsa = 4; + int idx_level = 6; + int level; + struct listnode *i, *j; + struct ospf6 *o = ospf6; + struct ospf6_area *oa; + struct ospf6_interface *oi; + u_int16_t type = 0; + u_int32_t adv_router = 0; + + OSPF6_CMD_CHECK_RUNNING(); + + type = parse_type_spec(idx_lsa, argc, argv); + level = parse_show_level(idx_level, argc, argv); + + adv_router = o->router_id; + + switch (OSPF6_LSA_SCOPE(type)) { + case OSPF6_SCOPE_AREA: + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); + ospf6_lsdb_show(vty, level, &type, NULL, &adv_router, + oa->lsdb); + } + break; + + case OSPF6_SCOPE_LINKLOCAL: + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { + vty_out(vty, IF_LSDB_TITLE_FORMAT, + oi->interface->name, oa->name); + ospf6_lsdb_show(vty, level, &type, NULL, + &adv_router, oi->lsdb); + } + } + break; + + case OSPF6_SCOPE_AS: + vty_out(vty, AS_LSDB_TITLE_FORMAT); + ospf6_lsdb_show(vty, level, &type, NULL, &adv_router, o->lsdb); + break; + + default: + assert(0); + break; + } + + vty_out(vty, "\n"); + return CMD_SUCCESS; } DEFUN (show_ipv6_ospf6_database_type_self_originated_linkstate_id, @@ -950,59 +910,57 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated_linkstate_id, "Dump LSAs\n" "Display LSA's internal information\n") { - int idx_lsa = 4; - int idx_ls_id = 7; - int idx_level = 8; - int level; - struct listnode *i, *j; - struct ospf6 *o = ospf6; - struct ospf6_area *oa; - struct ospf6_interface *oi; - u_int16_t type = 0; - u_int32_t adv_router = 0; - u_int32_t id = 0; - - OSPF6_CMD_CHECK_RUNNING (); - - type = parse_type_spec (idx_lsa, argc, argv); - inet_pton (AF_INET, argv[idx_ls_id]->arg, &id); - level = parse_show_level (idx_level, argc, argv); - adv_router = o->router_id; - - switch (OSPF6_LSA_SCOPE (type)) - { - case OSPF6_SCOPE_AREA: - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - vty_out (vty, AREA_LSDB_TITLE_FORMAT, oa->name); - ospf6_lsdb_show (vty, level, &type, &id, &adv_router, oa->lsdb); - } - break; - - case OSPF6_SCOPE_LINKLOCAL: - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi)) - { - vty_out (vty, IF_LSDB_TITLE_FORMAT, - oi->interface->name, oa->name); - ospf6_lsdb_show (vty, level, &type, &id, &adv_router, oi->lsdb); - } - } - break; - - case OSPF6_SCOPE_AS: - vty_out (vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show (vty, level, &type, &id, &adv_router, o->lsdb); - break; - - default: - assert (0); - break; - } - - vty_out (vty, "\n"); - return CMD_SUCCESS; + int idx_lsa = 4; + int idx_ls_id = 7; + int idx_level = 8; + int level; + struct listnode *i, *j; + struct ospf6 *o = ospf6; + struct ospf6_area *oa; + struct ospf6_interface *oi; + u_int16_t type = 0; + u_int32_t adv_router = 0; + u_int32_t id = 0; + + OSPF6_CMD_CHECK_RUNNING(); + + type = parse_type_spec(idx_lsa, argc, argv); + inet_pton(AF_INET, argv[idx_ls_id]->arg, &id); + level = parse_show_level(idx_level, argc, argv); + adv_router = o->router_id; + + switch (OSPF6_LSA_SCOPE(type)) { + case OSPF6_SCOPE_AREA: + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); + ospf6_lsdb_show(vty, level, &type, &id, &adv_router, + oa->lsdb); + } + break; + + case OSPF6_SCOPE_LINKLOCAL: + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { + vty_out(vty, IF_LSDB_TITLE_FORMAT, + oi->interface->name, oa->name); + ospf6_lsdb_show(vty, level, &type, &id, + &adv_router, oi->lsdb); + } + } + break; + + case OSPF6_SCOPE_AS: + vty_out(vty, AS_LSDB_TITLE_FORMAT); + ospf6_lsdb_show(vty, level, &type, &id, &adv_router, o->lsdb); + break; + + default: + assert(0); + break; + } + + vty_out(vty, "\n"); + return CMD_SUCCESS; } DEFUN (show_ipv6_ospf6_database_type_id_self_originated, @@ -1027,59 +985,57 @@ DEFUN (show_ipv6_ospf6_database_type_id_self_originated, "Dump LSAs\n" "Display LSA's internal information\n") { - int idx_lsa = 4; - int idx_ls_id = 5; - int idx_level = 7; - int level; - struct listnode *i, *j; - struct ospf6 *o = ospf6; - struct ospf6_area *oa; - struct ospf6_interface *oi; - u_int16_t type = 0; - u_int32_t adv_router = 0; - u_int32_t id = 0; - - OSPF6_CMD_CHECK_RUNNING (); - - type = parse_type_spec (idx_lsa, argc, argv); - inet_pton (AF_INET, argv[idx_ls_id]->arg, &id); - level = parse_show_level (idx_level, argc, argv); - adv_router = o->router_id; - - switch (OSPF6_LSA_SCOPE (type)) - { - case OSPF6_SCOPE_AREA: - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - vty_out (vty, AREA_LSDB_TITLE_FORMAT, oa->name); - ospf6_lsdb_show (vty, level, &type, &id, &adv_router, oa->lsdb); - } - break; - - case OSPF6_SCOPE_LINKLOCAL: - for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa)) - { - for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi)) - { - vty_out (vty, IF_LSDB_TITLE_FORMAT, - oi->interface->name, oa->name); - ospf6_lsdb_show (vty, level, &type, &id, &adv_router, oi->lsdb); - } - } - break; - - case OSPF6_SCOPE_AS: - vty_out (vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show (vty, level, &type, &id, &adv_router, o->lsdb); - break; - - default: - assert (0); - break; - } - - vty_out (vty, "\n"); - return CMD_SUCCESS; + int idx_lsa = 4; + int idx_ls_id = 5; + int idx_level = 7; + int level; + struct listnode *i, *j; + struct ospf6 *o = ospf6; + struct ospf6_area *oa; + struct ospf6_interface *oi; + u_int16_t type = 0; + u_int32_t adv_router = 0; + u_int32_t id = 0; + + OSPF6_CMD_CHECK_RUNNING(); + + type = parse_type_spec(idx_lsa, argc, argv); + inet_pton(AF_INET, argv[idx_ls_id]->arg, &id); + level = parse_show_level(idx_level, argc, argv); + adv_router = o->router_id; + + switch (OSPF6_LSA_SCOPE(type)) { + case OSPF6_SCOPE_AREA: + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); + ospf6_lsdb_show(vty, level, &type, &id, &adv_router, + oa->lsdb); + } + break; + + case OSPF6_SCOPE_LINKLOCAL: + for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { + vty_out(vty, IF_LSDB_TITLE_FORMAT, + oi->interface->name, oa->name); + ospf6_lsdb_show(vty, level, &type, &id, + &adv_router, oi->lsdb); + } + } + break; + + case OSPF6_SCOPE_AS: + vty_out(vty, AS_LSDB_TITLE_FORMAT); + ospf6_lsdb_show(vty, level, &type, &id, &adv_router, o->lsdb); + break; + + default: + assert(0); + break; + } + + vty_out(vty, "\n"); + return CMD_SUCCESS; } DEFUN (show_ipv6_ospf6_border_routers, @@ -1092,47 +1048,42 @@ DEFUN (show_ipv6_ospf6_border_routers, "Router ID\n" "Show detailed output\n") { - int idx_ipv4 = 4; - u_int32_t adv_router; - struct ospf6_route *ro; - struct prefix prefix; - - OSPF6_CMD_CHECK_RUNNING (); - - if (argc == 5) - { - if (strmatch (argv[idx_ipv4]->text, "detail")) - { - for (ro = ospf6_route_head (ospf6->brouter_table); ro; - ro = ospf6_route_next (ro)) - ospf6_route_show_detail (vty, ro); - } - else - { - inet_pton (AF_INET, argv[idx_ipv4]->arg, &adv_router); - - ospf6_linkstate_prefix (adv_router, 0, &prefix); - ro = ospf6_route_lookup (&prefix, ospf6->brouter_table); - if (!ro) - { - vty_out (vty, "No Route found for Router ID: %s\n", argv[4]->arg); - return CMD_SUCCESS; - } - - ospf6_route_show_detail (vty, ro); - return CMD_SUCCESS; - } - } - else - { - ospf6_brouter_show_header (vty); - - for (ro = ospf6_route_head (ospf6->brouter_table); ro; - ro = ospf6_route_next (ro)) - ospf6_brouter_show (vty, ro); - } - - return CMD_SUCCESS; + int idx_ipv4 = 4; + u_int32_t adv_router; + struct ospf6_route *ro; + struct prefix prefix; + + OSPF6_CMD_CHECK_RUNNING(); + + if (argc == 5) { + if (strmatch(argv[idx_ipv4]->text, "detail")) { + for (ro = ospf6_route_head(ospf6->brouter_table); ro; + ro = ospf6_route_next(ro)) + ospf6_route_show_detail(vty, ro); + } else { + inet_pton(AF_INET, argv[idx_ipv4]->arg, &adv_router); + + ospf6_linkstate_prefix(adv_router, 0, &prefix); + ro = ospf6_route_lookup(&prefix, ospf6->brouter_table); + if (!ro) { + vty_out(vty, + "No Route found for Router ID: %s\n", + argv[4]->arg); + return CMD_SUCCESS; + } + + ospf6_route_show_detail(vty, ro); + return CMD_SUCCESS; + } + } else { + ospf6_brouter_show_header(vty); + + for (ro = ospf6_route_head(ospf6->brouter_table); ro; + ro = ospf6_route_next(ro)) + ospf6_brouter_show(vty, ro); + } + + return CMD_SUCCESS; } @@ -1149,24 +1100,23 @@ DEFUN (show_ipv6_ospf6_linkstate, "Specify Router ID as IPv4 address notation\n" "Specify Link state ID as IPv4 address notation\n") { - int idx_ipv4 = 4; - struct listnode *node; - struct ospf6_area *oa; + int idx_ipv4 = 4; + struct listnode *node; + struct ospf6_area *oa; - OSPF6_CMD_CHECK_RUNNING (); + OSPF6_CMD_CHECK_RUNNING(); - for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa)) - { - vty_out (vty, "\n SPF Result in Area %s\n\n", oa->name); - ospf6_linkstate_table_show (vty, idx_ipv4, argc, argv, oa->spf_table); - } + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) { + vty_out(vty, "\n SPF Result in Area %s\n\n", oa->name); + ospf6_linkstate_table_show(vty, idx_ipv4, argc, argv, + oa->spf_table); + } - vty_out (vty, "\n"); - return CMD_SUCCESS; + vty_out(vty, "\n"); + return CMD_SUCCESS; } - DEFUN (show_ipv6_ospf6_linkstate_detail, show_ipv6_ospf6_linkstate_detail_cmd, "show ipv6 ospf6 linkstate detail", @@ -1176,89 +1126,96 @@ DEFUN (show_ipv6_ospf6_linkstate_detail, "Display linkstate routing table\n" "Display detailed information\n") { - int idx_detail = 4; - struct listnode *node; - struct ospf6_area *oa; + int idx_detail = 4; + struct listnode *node; + struct ospf6_area *oa; - OSPF6_CMD_CHECK_RUNNING (); + OSPF6_CMD_CHECK_RUNNING(); - for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa)) - { - vty_out (vty, "\n SPF Result in Area %s\n\n", oa->name); - ospf6_linkstate_table_show (vty, idx_detail, argc, argv, oa->spf_table); - } + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) { + vty_out(vty, "\n SPF Result in Area %s\n\n", oa->name); + ospf6_linkstate_table_show(vty, idx_detail, argc, argv, + oa->spf_table); + } - vty_out (vty, "\n"); - return CMD_SUCCESS; + vty_out(vty, "\n"); + return CMD_SUCCESS; } /* Install ospf related commands. */ -void -ospf6_init (void) +void ospf6_init(void) { - ospf6_top_init (); - ospf6_area_init (); - ospf6_interface_init (); - ospf6_neighbor_init (); - ospf6_zebra_init(master); - - ospf6_lsa_init (); - ospf6_spf_init (); - ospf6_intra_init (); - ospf6_asbr_init (); - ospf6_abr_init (); - - ospf6_bfd_init(); - install_node (&debug_node, config_write_ospf6_debug); - - install_element_ospf6_debug_message (); - install_element_ospf6_debug_lsa (); - install_element_ospf6_debug_interface (); - install_element_ospf6_debug_neighbor (); - install_element_ospf6_debug_zebra (); - install_element_ospf6_debug_spf (); - install_element_ospf6_debug_route (); - install_element_ospf6_debug_brouter (); - install_element_ospf6_debug_asbr (); - install_element_ospf6_debug_abr (); - install_element_ospf6_debug_flood (); - - install_element_ospf6_clear_interface (); - - install_element (VIEW_NODE, &show_version_ospf6_cmd); - - install_element (VIEW_NODE, &show_ipv6_ospf6_border_routers_cmd); - - install_element (VIEW_NODE, &show_ipv6_ospf6_linkstate_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_linkstate_detail_cmd); - - install_element (VIEW_NODE, &show_ipv6_ospf6_database_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_database_type_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_database_id_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_database_router_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_database_type_id_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_database_type_router_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_database_adv_router_linkstate_id_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_database_id_router_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_database_type_id_router_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_database_type_adv_router_linkstate_id_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_database_self_originated_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_database_type_self_originated_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_database_type_id_self_originated_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_database_type_self_originated_linkstate_id_cmd); - - /* Make ospf protocol socket. */ - ospf6_serv_sock (); - thread_add_read(master, ospf6_receive, NULL, ospf6_sock, NULL); + ospf6_top_init(); + ospf6_area_init(); + ospf6_interface_init(); + ospf6_neighbor_init(); + ospf6_zebra_init(master); + + ospf6_lsa_init(); + ospf6_spf_init(); + ospf6_intra_init(); + ospf6_asbr_init(); + ospf6_abr_init(); + + ospf6_bfd_init(); + install_node(&debug_node, config_write_ospf6_debug); + + install_element_ospf6_debug_message(); + install_element_ospf6_debug_lsa(); + install_element_ospf6_debug_interface(); + install_element_ospf6_debug_neighbor(); + install_element_ospf6_debug_zebra(); + install_element_ospf6_debug_spf(); + install_element_ospf6_debug_route(); + install_element_ospf6_debug_brouter(); + install_element_ospf6_debug_asbr(); + install_element_ospf6_debug_abr(); + install_element_ospf6_debug_flood(); + + install_element_ospf6_clear_interface(); + + install_element(VIEW_NODE, &show_version_ospf6_cmd); + + install_element(VIEW_NODE, &show_ipv6_ospf6_border_routers_cmd); + + install_element(VIEW_NODE, &show_ipv6_ospf6_linkstate_cmd); + install_element(VIEW_NODE, &show_ipv6_ospf6_linkstate_detail_cmd); + + install_element(VIEW_NODE, &show_ipv6_ospf6_database_cmd); + install_element(VIEW_NODE, &show_ipv6_ospf6_database_type_cmd); + install_element(VIEW_NODE, &show_ipv6_ospf6_database_id_cmd); + install_element(VIEW_NODE, &show_ipv6_ospf6_database_router_cmd); + install_element(VIEW_NODE, &show_ipv6_ospf6_database_type_id_cmd); + install_element(VIEW_NODE, &show_ipv6_ospf6_database_type_router_cmd); + install_element(VIEW_NODE, + &show_ipv6_ospf6_database_adv_router_linkstate_id_cmd); + install_element(VIEW_NODE, &show_ipv6_ospf6_database_id_router_cmd); + install_element(VIEW_NODE, + &show_ipv6_ospf6_database_type_id_router_cmd); + install_element( + VIEW_NODE, + &show_ipv6_ospf6_database_type_adv_router_linkstate_id_cmd); + install_element(VIEW_NODE, + &show_ipv6_ospf6_database_self_originated_cmd); + install_element(VIEW_NODE, + &show_ipv6_ospf6_database_type_self_originated_cmd); + install_element(VIEW_NODE, + &show_ipv6_ospf6_database_type_id_self_originated_cmd); + install_element( + VIEW_NODE, + &show_ipv6_ospf6_database_type_self_originated_linkstate_id_cmd); + + /* Make ospf protocol socket. */ + ospf6_serv_sock(); + thread_add_read(master, ospf6_receive, NULL, ospf6_sock, NULL); } -void -ospf6_clean (void) +void ospf6_clean(void) { - if (!ospf6) - return; - if (ospf6->route_table) - ospf6_route_remove_all (ospf6->route_table); - if (ospf6->brouter_table) - ospf6_route_remove_all (ospf6->brouter_table); + if (!ospf6) + return; + if (ospf6->route_table) + ospf6_route_remove_all(ospf6->route_table); + if (ospf6->brouter_table) + ospf6_route_remove_all(ospf6->brouter_table); } diff --git a/ospf6d/ospf6d.h b/ospf6d/ospf6d.h index 2da11d0ab..1515c3ad0 100644 --- a/ospf6d/ospf6d.h +++ b/ospf6d/ospf6d.h @@ -57,31 +57,31 @@ extern struct thread_master *master; #define OSPF6_NEIGHBOR(x) ((struct ospf6_neighbor *) (x)) /* operation on timeval structure */ -#define timerstring(tv, buf, size) \ - do { \ - if ((tv)->tv_sec / 60 / 60 / 24) \ - snprintf (buf, size, "%lldd%02lld:%02lld:%02lld", \ - (tv)->tv_sec / 60LL / 60 / 24, \ - (tv)->tv_sec / 60LL / 60 % 24, \ - (tv)->tv_sec / 60LL % 60, \ - (tv)->tv_sec % 60LL); \ - else \ - snprintf (buf, size, "%02lld:%02lld:%02lld", \ - (tv)->tv_sec / 60LL / 60 % 24, \ - (tv)->tv_sec / 60LL % 60, \ - (tv)->tv_sec % 60LL); \ - } while (0) - -#define threadtimer_string(now, t, buf, size) \ - do { \ - struct timeval result; \ - if (!t) \ - snprintf(buf, size, "inactive"); \ - else { \ - timersub(&t->u.sands, &now, &result); \ - timerstring(&result, buf, size); \ - } \ -} while (0) +#define timerstring(tv, buf, size) \ + do { \ + if ((tv)->tv_sec / 60 / 60 / 24) \ + snprintf(buf, size, "%lldd%02lld:%02lld:%02lld", \ + (tv)->tv_sec / 60LL / 60 / 24, \ + (tv)->tv_sec / 60LL / 60 % 24, \ + (tv)->tv_sec / 60LL % 60, \ + (tv)->tv_sec % 60LL); \ + else \ + snprintf(buf, size, "%02lld:%02lld:%02lld", \ + (tv)->tv_sec / 60LL / 60 % 24, \ + (tv)->tv_sec / 60LL % 60, \ + (tv)->tv_sec % 60LL); \ + } while (0) + +#define threadtimer_string(now, t, buf, size) \ + do { \ + struct timeval result; \ + if (!t) \ + snprintf(buf, size, "inactive"); \ + else { \ + timersub(&t->u.sands, &now, &result); \ + timerstring(&result, buf, size); \ + } \ + } while (0) /* for commands */ #define OSPF6_AREA_STR "Area information\n" @@ -90,20 +90,17 @@ extern struct thread_master *master; #define OSPF6_ROUTER_ID_STR "Specify Router-ID\n" #define OSPF6_LS_ID_STR "Specify Link State ID\n" -#define OSPF6_CMD_CHECK_RUNNING() \ - if (ospf6 == NULL) \ - { \ - vty_out (vty, "OSPFv3 is not running\n"); \ - return CMD_SUCCESS; \ - } +#define OSPF6_CMD_CHECK_RUNNING() \ + if (ospf6 == NULL) { \ + vty_out(vty, "OSPFv3 is not running\n"); \ + return CMD_SUCCESS; \ + } /* Function Prototypes */ -extern struct route_node *route_prev (struct route_node *node); +extern struct route_node *route_prev(struct route_node *node); -extern void ospf6_debug (void); -extern void ospf6_init (void); +extern void ospf6_debug(void); +extern void ospf6_init(void); #endif /* OSPF6D_H */ - - |