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 /ospfd | |
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 'ospfd')
56 files changed, 37799 insertions, 38794 deletions
diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c index 06038fed7..c6d4364fa 100644 --- a/ospfd/ospf_abr.c +++ b/ospfd/ospf_abr.c @@ -50,1667 +50,1648 @@ #include "ospfd/ospf_zebra.h" #include "ospfd/ospf_dump.h" -static struct ospf_area_range * -ospf_area_range_new (struct prefix_ipv4 *p) +static struct ospf_area_range *ospf_area_range_new(struct prefix_ipv4 *p) { - struct ospf_area_range *range; + struct ospf_area_range *range; - range = XCALLOC (MTYPE_OSPF_AREA_RANGE, sizeof (struct ospf_area_range)); - range->addr = p->prefix; - range->masklen = p->prefixlen; - range->cost_config = OSPF_AREA_RANGE_COST_UNSPEC; + range = XCALLOC(MTYPE_OSPF_AREA_RANGE, sizeof(struct ospf_area_range)); + range->addr = p->prefix; + range->masklen = p->prefixlen; + range->cost_config = OSPF_AREA_RANGE_COST_UNSPEC; - return range; + return range; } -static void -ospf_area_range_free (struct ospf_area_range *range) +static void ospf_area_range_free(struct ospf_area_range *range) { - XFREE (MTYPE_OSPF_AREA_RANGE, range); + XFREE(MTYPE_OSPF_AREA_RANGE, range); } -static void -ospf_area_range_add (struct ospf_area *area, struct ospf_area_range *range) +static void ospf_area_range_add(struct ospf_area *area, + struct ospf_area_range *range) { - struct route_node *rn; - struct prefix_ipv4 p; - - p.family = AF_INET; - p.prefixlen = range->masklen; - p.prefix = range->addr; - - rn = route_node_get (area->ranges, (struct prefix *)&p); - if (rn->info) - route_unlock_node (rn); - else - rn->info = range; + struct route_node *rn; + struct prefix_ipv4 p; + + p.family = AF_INET; + p.prefixlen = range->masklen; + p.prefix = range->addr; + + rn = route_node_get(area->ranges, (struct prefix *)&p); + if (rn->info) + route_unlock_node(rn); + else + rn->info = range; } -static void -ospf_area_range_delete (struct ospf_area *area, struct route_node *rn) +static void ospf_area_range_delete(struct ospf_area *area, + struct route_node *rn) { - struct ospf_area_range *range = rn->info; + struct ospf_area_range *range = rn->info; - if (range->specifics != 0) - ospf_delete_discard_route (area->ospf->new_table, - (struct prefix_ipv4 *) &rn->p); + if (range->specifics != 0) + ospf_delete_discard_route(area->ospf->new_table, + (struct prefix_ipv4 *)&rn->p); - ospf_area_range_free (range); - rn->info = NULL; - route_unlock_node (rn); - route_unlock_node (rn); + ospf_area_range_free(range); + rn->info = NULL; + route_unlock_node(rn); + route_unlock_node(rn); } -struct ospf_area_range * -ospf_area_range_lookup (struct ospf_area *area, struct prefix_ipv4 *p) +struct ospf_area_range *ospf_area_range_lookup(struct ospf_area *area, + struct prefix_ipv4 *p) { - struct route_node *rn; - - rn = route_node_lookup (area->ranges, (struct prefix *)p); - if (rn) - { - route_unlock_node (rn); - return rn->info; - } - return NULL; + struct route_node *rn; + + rn = route_node_lookup(area->ranges, (struct prefix *)p); + if (rn) { + route_unlock_node(rn); + return rn->info; + } + return NULL; } -struct ospf_area_range * -ospf_area_range_lookup_next (struct ospf_area *area, - struct in_addr *range_net, - int first) +struct ospf_area_range *ospf_area_range_lookup_next(struct ospf_area *area, + struct in_addr *range_net, + int first) { - struct route_node *rn; - struct prefix_ipv4 p; - struct ospf_area_range *find; - - p.family = AF_INET; - p.prefixlen = IPV4_MAX_BITLEN; - p.prefix = *range_net; - - if (first) - rn = route_top (area->ranges); - else - { - rn = route_node_get (area->ranges, (struct prefix *) &p); - rn = route_next (rn); - } - - for (; rn; rn = route_next (rn)) - if (rn->info) - break; - - if (rn && rn->info) - { - find = rn->info; - *range_net = rn->p.u.prefix4; - route_unlock_node (rn); - return find; - } - return NULL; + struct route_node *rn; + struct prefix_ipv4 p; + struct ospf_area_range *find; + + p.family = AF_INET; + p.prefixlen = IPV4_MAX_BITLEN; + p.prefix = *range_net; + + if (first) + rn = route_top(area->ranges); + else { + rn = route_node_get(area->ranges, (struct prefix *)&p); + rn = route_next(rn); + } + + for (; rn; rn = route_next(rn)) + if (rn->info) + break; + + if (rn && rn->info) { + find = rn->info; + *range_net = rn->p.u.prefix4; + route_unlock_node(rn); + return find; + } + return NULL; } -static struct ospf_area_range * -ospf_area_range_match (struct ospf_area *area, struct prefix_ipv4 *p) +static struct ospf_area_range *ospf_area_range_match(struct ospf_area *area, + struct prefix_ipv4 *p) { - struct route_node *node; - - node = route_node_match (area->ranges, (struct prefix *) p); - if (node) - { - route_unlock_node (node); - return node->info; - } - return NULL; + struct route_node *node; + + node = route_node_match(area->ranges, (struct prefix *)p); + if (node) { + route_unlock_node(node); + return node->info; + } + return NULL; } -struct ospf_area_range * -ospf_area_range_match_any (struct ospf *ospf, struct prefix_ipv4 *p) +struct ospf_area_range *ospf_area_range_match_any(struct ospf *ospf, + struct prefix_ipv4 *p) { - struct ospf_area_range *range; - struct ospf_area *area; - struct listnode *node; + struct ospf_area_range *range; + struct ospf_area *area; + struct listnode *node; - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - if ((range = ospf_area_range_match (area, p))) - return range; + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) + if ((range = ospf_area_range_match(area, p))) + return range; - return NULL; + return NULL; } -int -ospf_area_range_active (struct ospf_area_range *range) +int ospf_area_range_active(struct ospf_area_range *range) { - return range->specifics; + return range->specifics; } -static int -ospf_area_actively_attached (struct ospf_area *area) +static int ospf_area_actively_attached(struct ospf_area *area) { - return area->act_ints; + return area->act_ints; } -int -ospf_area_range_set (struct ospf *ospf, struct in_addr area_id, - struct prefix_ipv4 *p, int advertise) +int ospf_area_range_set(struct ospf *ospf, struct in_addr area_id, + struct prefix_ipv4 *p, int advertise) { - struct ospf_area *area; - struct ospf_area_range *range; - - area = ospf_area_get (ospf, area_id); - if (area == NULL) - return 0; - - range = ospf_area_range_lookup (area, p); - if (range != NULL) - { - if ((CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE) - && !CHECK_FLAG (advertise, OSPF_AREA_RANGE_ADVERTISE)) - || (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE) - && CHECK_FLAG (advertise, OSPF_AREA_RANGE_ADVERTISE))) - ospf_schedule_abr_task (ospf); - } - else - { - range = ospf_area_range_new (p); - ospf_area_range_add (area, range); - ospf_schedule_abr_task (ospf); - } - - if (CHECK_FLAG (advertise, OSPF_AREA_RANGE_ADVERTISE)) - SET_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE); - else - UNSET_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE); - - return 1; + struct ospf_area *area; + struct ospf_area_range *range; + + area = ospf_area_get(ospf, area_id); + if (area == NULL) + return 0; + + range = ospf_area_range_lookup(area, p); + if (range != NULL) { + if ((CHECK_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE) + && !CHECK_FLAG(advertise, OSPF_AREA_RANGE_ADVERTISE)) + || (!CHECK_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE) + && CHECK_FLAG(advertise, OSPF_AREA_RANGE_ADVERTISE))) + ospf_schedule_abr_task(ospf); + } else { + range = ospf_area_range_new(p); + ospf_area_range_add(area, range); + ospf_schedule_abr_task(ospf); + } + + if (CHECK_FLAG(advertise, OSPF_AREA_RANGE_ADVERTISE)) + SET_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE); + else + UNSET_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE); + + return 1; } -int -ospf_area_range_cost_set (struct ospf *ospf, struct in_addr area_id, - struct prefix_ipv4 *p, u_int32_t cost) +int ospf_area_range_cost_set(struct ospf *ospf, struct in_addr area_id, + struct prefix_ipv4 *p, u_int32_t cost) { - struct ospf_area *area; - struct ospf_area_range *range; + struct ospf_area *area; + struct ospf_area_range *range; - area = ospf_area_get (ospf, area_id); - if (area == NULL) - return 0; + area = ospf_area_get(ospf, area_id); + if (area == NULL) + return 0; - range = ospf_area_range_lookup (area, p); - if (range == NULL) - return 0; + range = ospf_area_range_lookup(area, p); + if (range == NULL) + return 0; - if (range->cost_config != cost) - { - range->cost_config = cost; - if (ospf_area_range_active (range)) - ospf_schedule_abr_task (ospf); - } + if (range->cost_config != cost) { + range->cost_config = cost; + if (ospf_area_range_active(range)) + ospf_schedule_abr_task(ospf); + } - return 1; + return 1; } -int -ospf_area_range_unset (struct ospf *ospf, struct in_addr area_id, - struct prefix_ipv4 *p) +int ospf_area_range_unset(struct ospf *ospf, struct in_addr area_id, + struct prefix_ipv4 *p) { - struct ospf_area *area; - struct route_node *rn; + struct ospf_area *area; + struct route_node *rn; - area = ospf_area_lookup_by_area_id (ospf, area_id); - if (area == NULL) - return 0; + area = ospf_area_lookup_by_area_id(ospf, area_id); + if (area == NULL) + return 0; - rn = route_node_lookup (area->ranges, (struct prefix*)p); - if (rn == NULL) - return 0; + rn = route_node_lookup(area->ranges, (struct prefix *)p); + if (rn == NULL) + return 0; - if (ospf_area_range_active (rn->info)) - ospf_schedule_abr_task (ospf); + if (ospf_area_range_active(rn->info)) + ospf_schedule_abr_task(ospf); - ospf_area_range_delete (area, rn); + ospf_area_range_delete(area, rn); - return 1; + return 1; } -int -ospf_area_range_substitute_set (struct ospf *ospf, struct in_addr area_id, - struct prefix_ipv4 *p, struct prefix_ipv4 *s) +int ospf_area_range_substitute_set(struct ospf *ospf, struct in_addr area_id, + struct prefix_ipv4 *p, struct prefix_ipv4 *s) { - struct ospf_area *area; - struct ospf_area_range *range; - - area = ospf_area_get (ospf, area_id); - range = ospf_area_range_lookup (area, p); - - if (range != NULL) - { - if (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE) || - !CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE)) - ospf_schedule_abr_task (ospf); - } - else - { - range = ospf_area_range_new (p); - ospf_area_range_add (area, range); - ospf_schedule_abr_task (ospf); - } - - SET_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE); - SET_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE); - range->subst_addr = s->prefix; - range->subst_masklen = s->prefixlen; - - return 1; + struct ospf_area *area; + struct ospf_area_range *range; + + area = ospf_area_get(ospf, area_id); + range = ospf_area_range_lookup(area, p); + + if (range != NULL) { + if (!CHECK_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE) + || !CHECK_FLAG(range->flags, OSPF_AREA_RANGE_SUBSTITUTE)) + ospf_schedule_abr_task(ospf); + } else { + range = ospf_area_range_new(p); + ospf_area_range_add(area, range); + ospf_schedule_abr_task(ospf); + } + + SET_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE); + SET_FLAG(range->flags, OSPF_AREA_RANGE_SUBSTITUTE); + range->subst_addr = s->prefix; + range->subst_masklen = s->prefixlen; + + return 1; } -int -ospf_area_range_substitute_unset (struct ospf *ospf, struct in_addr area_id, - struct prefix_ipv4 *p) +int ospf_area_range_substitute_unset(struct ospf *ospf, struct in_addr area_id, + struct prefix_ipv4 *p) { - struct ospf_area *area; - struct ospf_area_range *range; + struct ospf_area *area; + struct ospf_area_range *range; - area = ospf_area_lookup_by_area_id (ospf, area_id); - if (area == NULL) - return 0; + area = ospf_area_lookup_by_area_id(ospf, area_id); + if (area == NULL) + return 0; - range = ospf_area_range_lookup (area, p); - if (range == NULL) - return 0; + range = ospf_area_range_lookup(area, p); + if (range == NULL) + return 0; - if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE)) - if (ospf_area_range_active (range)) - ospf_schedule_abr_task (ospf); + if (CHECK_FLAG(range->flags, OSPF_AREA_RANGE_SUBSTITUTE)) + if (ospf_area_range_active(range)) + ospf_schedule_abr_task(ospf); - UNSET_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE); - range->subst_addr.s_addr = 0; - range->subst_masklen = 0; + UNSET_FLAG(range->flags, OSPF_AREA_RANGE_SUBSTITUTE); + range->subst_addr.s_addr = 0; + range->subst_masklen = 0; - return 1; + return 1; } -int -ospf_act_bb_connection (struct ospf *ospf) +int ospf_act_bb_connection(struct ospf *ospf) { - if (ospf->backbone == NULL) - return 0; + if (ospf->backbone == NULL) + return 0; - return ospf->backbone->full_nbrs; + return ospf->backbone->full_nbrs; } /* Determine whether this router is elected translator or not for area */ -static int -ospf_abr_nssa_am_elected (struct ospf_area *area) +static int ospf_abr_nssa_am_elected(struct ospf_area *area) { - struct route_node *rn; - struct ospf_lsa *lsa; - struct router_lsa *rlsa; - struct in_addr *best = NULL; - - LSDB_LOOP ( ROUTER_LSDB (area), rn, lsa) - { - /* sanity checks */ - if (!lsa - || (lsa->data->type != OSPF_ROUTER_LSA) - || IS_LSA_SELF (lsa)) - continue; - - rlsa = (struct router_lsa *) lsa->data; - - /* ignore non-ABR routers */ - if (!IS_ROUTER_LSA_BORDER (rlsa)) - continue; - - /* Router has Nt flag - always translate */ - if (IS_ROUTER_LSA_NT (rlsa)) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_nssa_am_elected: " - "router %s asserts Nt", - inet_ntoa (lsa->data->id) ); - return 0; - } - - if (best == NULL) - best = &lsa->data->id; - else - if (IPV4_ADDR_CMP (&best->s_addr, &lsa->data->id.s_addr) < 0) - best = &lsa->data->id; - } - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_nssa_am_elected: best electable ABR is: %s", - (best) ? inet_ntoa (*best) : "<none>" ); - - if (best == NULL) - return 1; - - if (IPV4_ADDR_CMP (&best->s_addr, &area->ospf->router_id.s_addr) < 0) - return 1; - else - return 0; + struct route_node *rn; + struct ospf_lsa *lsa; + struct router_lsa *rlsa; + struct in_addr *best = NULL; + + LSDB_LOOP(ROUTER_LSDB(area), rn, lsa) + { + /* sanity checks */ + if (!lsa || (lsa->data->type != OSPF_ROUTER_LSA) + || IS_LSA_SELF(lsa)) + continue; + + rlsa = (struct router_lsa *)lsa->data; + + /* ignore non-ABR routers */ + if (!IS_ROUTER_LSA_BORDER(rlsa)) + continue; + + /* Router has Nt flag - always translate */ + if (IS_ROUTER_LSA_NT(rlsa)) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_nssa_am_elected: " + "router %s asserts Nt", + inet_ntoa(lsa->data->id)); + return 0; + } + + if (best == NULL) + best = &lsa->data->id; + else if (IPV4_ADDR_CMP(&best->s_addr, &lsa->data->id.s_addr) + < 0) + best = &lsa->data->id; + } + + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_nssa_am_elected: best electable ABR is: %s", + (best) ? inet_ntoa(*best) : "<none>"); + + if (best == NULL) + return 1; + + if (IPV4_ADDR_CMP(&best->s_addr, &area->ospf->router_id.s_addr) < 0) + return 1; + else + return 0; } /* Check NSSA ABR status * assumes there are nssa areas */ -static void -ospf_abr_nssa_check_status (struct ospf *ospf) +static void ospf_abr_nssa_check_status(struct ospf *ospf) { - struct ospf_area *area; - struct listnode *lnode, *nnode; - - for (ALL_LIST_ELEMENTS (ospf->areas, lnode, nnode, area)) - { - u_char old_state = area->NSSATranslatorState; - - if (area->external_routing != OSPF_AREA_NSSA) - continue; - - if (IS_DEBUG_OSPF (nssa, NSSA)) - zlog_debug ("ospf_abr_nssa_check_status: " - "checking area %s", - inet_ntoa (area->area_id)); - - if (!IS_OSPF_ABR (area->ospf)) - { - if (IS_DEBUG_OSPF (nssa, NSSA)) - zlog_debug ("ospf_abr_nssa_check_status: " - "not ABR"); - area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED; - } - else - { - switch (area->NSSATranslatorRole) - { - case OSPF_NSSA_ROLE_NEVER: - /* We never Translate Type-7 LSA. */ - /* TODO: check previous state and flush? */ - if (IS_DEBUG_OSPF (nssa, NSSA)) - zlog_debug ("ospf_abr_nssa_check_status: " - "never translate"); - area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED; - break; - - case OSPF_NSSA_ROLE_ALWAYS: - /* We always translate if we are an ABR - * TODO: originate new LSAs if state change? - * or let the nssa abr task take care of it? - */ - if (IS_DEBUG_OSPF (nssa, NSSA)) - zlog_debug ("ospf_abr_nssa_check_status: " - "translate always"); - area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_ENABLED; - break; - - case OSPF_NSSA_ROLE_CANDIDATE: - /* We are a candidate for Translation */ - if (ospf_abr_nssa_am_elected (area) > 0) - { - area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_ENABLED; - if (IS_DEBUG_OSPF (nssa, NSSA)) - zlog_debug ("ospf_abr_nssa_check_status: " - "elected translator"); - } - else - { - area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED; - if (IS_DEBUG_OSPF (nssa, NSSA)) - zlog_debug ("ospf_abr_nssa_check_status: " "not elected"); - } - break; - } - } - /* RFC3101, 3.1: - * All NSSA border routers must set the E-bit in the Type-1 router-LSAs - * of their directly attached non-stub areas, even when they are not - * translating. - */ - if (old_state != area->NSSATranslatorState) - { - if (old_state == OSPF_NSSA_TRANSLATE_DISABLED) - ospf_asbr_status_update (ospf, ++ospf->redistribute); - else if (area->NSSATranslatorState == OSPF_NSSA_TRANSLATE_DISABLED) - ospf_asbr_status_update (ospf, --ospf->redistribute); + struct ospf_area *area; + struct listnode *lnode, *nnode; + + for (ALL_LIST_ELEMENTS(ospf->areas, lnode, nnode, area)) { + u_char old_state = area->NSSATranslatorState; + + if (area->external_routing != OSPF_AREA_NSSA) + continue; + + if (IS_DEBUG_OSPF(nssa, NSSA)) + zlog_debug( + "ospf_abr_nssa_check_status: " + "checking area %s", + inet_ntoa(area->area_id)); + + if (!IS_OSPF_ABR(area->ospf)) { + if (IS_DEBUG_OSPF(nssa, NSSA)) + zlog_debug( + "ospf_abr_nssa_check_status: " + "not ABR"); + area->NSSATranslatorState = + OSPF_NSSA_TRANSLATE_DISABLED; + } else { + switch (area->NSSATranslatorRole) { + case OSPF_NSSA_ROLE_NEVER: + /* We never Translate Type-7 LSA. */ + /* TODO: check previous state and flush? */ + if (IS_DEBUG_OSPF(nssa, NSSA)) + zlog_debug( + "ospf_abr_nssa_check_status: " + "never translate"); + area->NSSATranslatorState = + OSPF_NSSA_TRANSLATE_DISABLED; + break; + + case OSPF_NSSA_ROLE_ALWAYS: + /* We always translate if we are an ABR + * TODO: originate new LSAs if state change? + * or let the nssa abr task take care of it? + */ + if (IS_DEBUG_OSPF(nssa, NSSA)) + zlog_debug( + "ospf_abr_nssa_check_status: " + "translate always"); + area->NSSATranslatorState = + OSPF_NSSA_TRANSLATE_ENABLED; + break; + + case OSPF_NSSA_ROLE_CANDIDATE: + /* We are a candidate for Translation */ + if (ospf_abr_nssa_am_elected(area) > 0) { + area->NSSATranslatorState = + OSPF_NSSA_TRANSLATE_ENABLED; + if (IS_DEBUG_OSPF(nssa, NSSA)) + zlog_debug( + "ospf_abr_nssa_check_status: " + "elected translator"); + } else { + area->NSSATranslatorState = + OSPF_NSSA_TRANSLATE_DISABLED; + if (IS_DEBUG_OSPF(nssa, NSSA)) + zlog_debug( + "ospf_abr_nssa_check_status: " + "not elected"); + } + break; + } + } + /* RFC3101, 3.1: + * All NSSA border routers must set the E-bit in the Type-1 + * router-LSAs + * of their directly attached non-stub areas, even when they are + * not + * translating. + */ + if (old_state != area->NSSATranslatorState) { + if (old_state == OSPF_NSSA_TRANSLATE_DISABLED) + ospf_asbr_status_update(ospf, + ++ospf->redistribute); + else if (area->NSSATranslatorState + == OSPF_NSSA_TRANSLATE_DISABLED) + ospf_asbr_status_update(ospf, + --ospf->redistribute); + } } - } } /* Check area border router status. */ -void -ospf_check_abr_status (struct ospf *ospf) +void ospf_check_abr_status(struct ospf *ospf) { - struct ospf_area *area; - struct listnode *node, *nnode; - int bb_configured = 0; - int bb_act_attached = 0; - int areas_configured = 0; - int areas_act_attached = 0; - u_char new_flags = ospf->flags; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_check_abr_status(): Start"); - - for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area)) - { - if (listcount (area->oiflist)) - { - areas_configured++; - - if (OSPF_IS_AREA_BACKBONE (area)) - bb_configured = 1; + struct ospf_area *area; + struct listnode *node, *nnode; + int bb_configured = 0; + int bb_act_attached = 0; + int areas_configured = 0; + int areas_act_attached = 0; + u_char new_flags = ospf->flags; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_check_abr_status(): Start"); + + for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) { + if (listcount(area->oiflist)) { + areas_configured++; + + if (OSPF_IS_AREA_BACKBONE(area)) + bb_configured = 1; + } + + if (ospf_area_actively_attached(area)) { + areas_act_attached++; + + if (OSPF_IS_AREA_BACKBONE(area)) + bb_act_attached = 1; + } } - if (ospf_area_actively_attached (area)) - { - areas_act_attached++; - - if (OSPF_IS_AREA_BACKBONE (area)) - bb_act_attached = 1; + if (IS_DEBUG_OSPF_EVENT) { + zlog_debug("ospf_check_abr_status(): looked through areas"); + zlog_debug("ospf_check_abr_status(): bb_configured: %d", + bb_configured); + zlog_debug("ospf_check_abr_status(): bb_act_attached: %d", + bb_act_attached); + zlog_debug("ospf_check_abr_status(): areas_configured: %d", + areas_configured); + zlog_debug("ospf_check_abr_status(): areas_act_attached: %d", + areas_act_attached); + } + + switch (ospf->abr_type) { + case OSPF_ABR_SHORTCUT: + case OSPF_ABR_STAND: + if (areas_act_attached > 1) + SET_FLAG(new_flags, OSPF_FLAG_ABR); + else + UNSET_FLAG(new_flags, OSPF_FLAG_ABR); + break; + + case OSPF_ABR_IBM: + if ((areas_act_attached > 1) && bb_configured) + SET_FLAG(new_flags, OSPF_FLAG_ABR); + else + UNSET_FLAG(new_flags, OSPF_FLAG_ABR); + break; + + case OSPF_ABR_CISCO: + if ((areas_configured > 1) && bb_act_attached) + SET_FLAG(new_flags, OSPF_FLAG_ABR); + else + UNSET_FLAG(new_flags, OSPF_FLAG_ABR); + break; + default: + break; + } + + if (new_flags != ospf->flags) { + ospf_spf_calculate_schedule(ospf, SPF_FLAG_ABR_STATUS_CHANGE); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_check_abr_status(): new router flags: %x", + new_flags); + ospf->flags = new_flags; + ospf_router_lsa_update(ospf); } - } - - if (IS_DEBUG_OSPF_EVENT) - { - zlog_debug ("ospf_check_abr_status(): looked through areas"); - zlog_debug ("ospf_check_abr_status(): bb_configured: %d", bb_configured); - zlog_debug ("ospf_check_abr_status(): bb_act_attached: %d", - bb_act_attached); - zlog_debug ("ospf_check_abr_status(): areas_configured: %d", - areas_configured); - zlog_debug ("ospf_check_abr_status(): areas_act_attached: %d", - areas_act_attached); - } - - switch (ospf->abr_type) - { - case OSPF_ABR_SHORTCUT: - case OSPF_ABR_STAND: - if (areas_act_attached > 1) - SET_FLAG (new_flags, OSPF_FLAG_ABR); - else - UNSET_FLAG (new_flags, OSPF_FLAG_ABR); - break; - - case OSPF_ABR_IBM: - if ((areas_act_attached > 1) && bb_configured) - SET_FLAG (new_flags, OSPF_FLAG_ABR); - else - UNSET_FLAG (new_flags, OSPF_FLAG_ABR); - break; - - case OSPF_ABR_CISCO: - if ((areas_configured > 1) && bb_act_attached) - SET_FLAG (new_flags, OSPF_FLAG_ABR); - else - UNSET_FLAG (new_flags, OSPF_FLAG_ABR); - break; - default: - break; - } - - if (new_flags != ospf->flags) - { - ospf_spf_calculate_schedule (ospf, SPF_FLAG_ABR_STATUS_CHANGE); - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_check_abr_status(): new router flags: %x",new_flags); - ospf->flags = new_flags; - ospf_router_lsa_update (ospf); - } } -static void -ospf_abr_update_aggregate (struct ospf_area_range *range, - struct ospf_route *or, struct ospf_area *area) +static void ospf_abr_update_aggregate(struct ospf_area_range *range, + struct ospf_route * or, + struct ospf_area *area) { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_update_aggregate(): Start"); - - if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED) && - (range->cost != OSPF_STUB_MAX_METRIC_SUMMARY_COST)) - { - range->cost = OSPF_STUB_MAX_METRIC_SUMMARY_COST; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_update_aggregate(): use summary max-metric 0x%08x", - range->cost); - } - else if (range->cost_config != OSPF_AREA_RANGE_COST_UNSPEC) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_update_aggregate(): use configured cost %d", - range->cost_config); - - range->cost = range->cost_config; - } - else - { - if (range->specifics == 0) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_update_aggregate(): use or->cost %d", - or->cost); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_update_aggregate(): Start"); - range->cost = or->cost; /* 1st time get 1st cost */ - } + if (CHECK_FLAG(area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED) + && (range->cost != OSPF_STUB_MAX_METRIC_SUMMARY_COST)) { + range->cost = OSPF_STUB_MAX_METRIC_SUMMARY_COST; + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_update_aggregate(): use summary max-metric 0x%08x", + range->cost); + } else if (range->cost_config != OSPF_AREA_RANGE_COST_UNSPEC) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_update_aggregate(): use configured cost %d", + range->cost_config); - if (or->cost > range->cost) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_update_aggregate(): update to %d", or->cost); + range->cost = range->cost_config; + } else { + if (range->specifics == 0) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_update_aggregate(): use or->cost %d", + or->cost); + + range->cost = or->cost; /* 1st time get 1st cost */ + } - range->cost = or->cost; - } - } + if (or->cost > range->cost) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_update_aggregate(): update to %d", + or->cost); - range->specifics++; + range->cost = or->cost; + } + } + + range->specifics++; } -static void -set_metric (struct ospf_lsa *lsa, u_int32_t metric) +static void set_metric(struct ospf_lsa *lsa, u_int32_t metric) { - struct summary_lsa *header; - u_char *mp; - metric = htonl (metric); - mp = (u_char *) &metric; - mp++; - header = (struct summary_lsa *) lsa->data; - memcpy(header->metric, mp, 3); + struct summary_lsa *header; + u_char *mp; + metric = htonl(metric); + mp = (u_char *)&metric; + mp++; + header = (struct summary_lsa *)lsa->data; + memcpy(header->metric, mp, 3); } /* ospf_abr_translate_nssa */ -static int -ospf_abr_translate_nssa (struct ospf_area *area, struct ospf_lsa *lsa) +static int ospf_abr_translate_nssa(struct ospf_area *area, struct ospf_lsa *lsa) { - /* Incoming Type-7 or later aggregated Type-7 - * - * LSA is skipped if P-bit is off. - * LSA is aggregated if within range. - * - * The Type-7 is translated, Installed/Approved as a Type-5 into - * global LSDB, then Flooded through AS - * - * Later, any Unapproved Translated Type-5's are flushed/discarded - */ - - struct ospf_lsa *old = NULL, - *new = NULL; - struct as_external_lsa *ext7; - struct prefix_ipv4 p; - - if (! CHECK_FLAG (lsa->data->options, OSPF_OPTION_NP)) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_translate_nssa(): LSA Id %s, P-bit off, NO Translation", - inet_ntoa (lsa->data->id)); - return 1; - } - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_translate_nssa(): LSA Id %s, TRANSLATING 7 to 5", - inet_ntoa (lsa->data->id)); - - ext7 = (struct as_external_lsa *)(lsa->data); - p.prefix = lsa->data->id; - p.prefixlen = ip_masklen (ext7->mask); - - if (ext7->e[0].fwd_addr.s_addr == OSPF_DEFAULT_DESTINATION) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_translate_nssa(): LSA Id %s, " - "Forward address is 0, NO Translation", - inet_ntoa (lsa->data->id)); - return 1; - } - - /* try find existing AS-External LSA for this prefix */ - - old = ospf_external_info_find_lsa (area->ospf, &p); - - if (old) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_translate_nssa(): " - "found old translated LSA Id %s, refreshing", - inet_ntoa (old->data->id)); - - /* refresh */ - new = ospf_translated_nssa_refresh (area->ospf, lsa, old); - if (!new) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_translate_nssa(): " - "could not refresh translated LSA Id %s", - inet_ntoa (old->data->id)); - } - } - else - { - /* no existing external route for this LSA Id - * originate translated LSA - */ - - if ((new = ospf_translated_nssa_originate (area->ospf, lsa)) - == NULL) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_translate_nssa(): Could not translate " - "Type-7 for %s to Type-5", - inet_ntoa (lsa->data->id)); - return 1; - } - } - - /* Area where Aggregate testing will be inserted, just like summary - advertisements */ - /* ospf_abr_check_nssa_range (p_arg, lsa-> cost, lsa -> area); */ - - return 0; + /* Incoming Type-7 or later aggregated Type-7 + * + * LSA is skipped if P-bit is off. + * LSA is aggregated if within range. + * + * The Type-7 is translated, Installed/Approved as a Type-5 into + * global LSDB, then Flooded through AS + * + * Later, any Unapproved Translated Type-5's are flushed/discarded + */ + + struct ospf_lsa *old = NULL, *new = NULL; + struct as_external_lsa *ext7; + struct prefix_ipv4 p; + + if (!CHECK_FLAG(lsa->data->options, OSPF_OPTION_NP)) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_translate_nssa(): LSA Id %s, P-bit off, NO Translation", + inet_ntoa(lsa->data->id)); + return 1; + } + + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_translate_nssa(): LSA Id %s, TRANSLATING 7 to 5", + inet_ntoa(lsa->data->id)); + + ext7 = (struct as_external_lsa *)(lsa->data); + p.prefix = lsa->data->id; + p.prefixlen = ip_masklen(ext7->mask); + + if (ext7->e[0].fwd_addr.s_addr == OSPF_DEFAULT_DESTINATION) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_translate_nssa(): LSA Id %s, " + "Forward address is 0, NO Translation", + inet_ntoa(lsa->data->id)); + return 1; + } + + /* try find existing AS-External LSA for this prefix */ + + old = ospf_external_info_find_lsa(area->ospf, &p); + + if (old) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_translate_nssa(): " + "found old translated LSA Id %s, refreshing", + inet_ntoa(old->data->id)); + + /* refresh */ + new = ospf_translated_nssa_refresh(area->ospf, lsa, old); + if (!new) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_translate_nssa(): " + "could not refresh translated LSA Id %s", + inet_ntoa(old->data->id)); + } + } else { + /* no existing external route for this LSA Id + * originate translated LSA + */ + + if ((new = ospf_translated_nssa_originate(area->ospf, lsa)) + == NULL) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_translate_nssa(): Could not translate " + "Type-7 for %s to Type-5", + inet_ntoa(lsa->data->id)); + return 1; + } + } + + /* Area where Aggregate testing will be inserted, just like summary + advertisements */ + /* ospf_abr_check_nssa_range (p_arg, lsa-> cost, lsa -> area); */ + + return 0; } -static void -ospf_abr_translate_nssa_range (struct prefix_ipv4 *p, u_int32_t cost) +static void ospf_abr_translate_nssa_range(struct prefix_ipv4 *p, u_int32_t cost) { - /* The Type-7 is created from the aggregated prefix and forwarded - for lsa installation and flooding... to be added... */ + /* The Type-7 is created from the aggregated prefix and forwarded + for lsa installation and flooding... to be added... */ } -void -ospf_abr_announce_network_to_area (struct prefix_ipv4 *p, u_int32_t cost, - struct ospf_area *area) +void ospf_abr_announce_network_to_area(struct prefix_ipv4 *p, u_int32_t cost, + struct ospf_area *area) { - struct ospf_lsa *lsa, *old = NULL; - struct summary_lsa *sl = NULL; - u_int32_t full_cost; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network_to_area(): Start"); - - if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED)) - full_cost = OSPF_STUB_MAX_METRIC_SUMMARY_COST; - else - full_cost = cost; - - old = ospf_lsa_lookup_by_prefix (area->lsdb, OSPF_SUMMARY_LSA, - (struct prefix_ipv4 *) p, - area->ospf->router_id); - if (old) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network_to_area(): old summary found"); - - sl = (struct summary_lsa *) old->data; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network_to_area(): " - "old metric: %d, new metric: %d", - GET_METRIC (sl->metric), cost); - - if ((GET_METRIC (sl->metric) == full_cost) && - ((old->flags & OSPF_LSA_IN_MAXAGE) == 0)) - { - /* unchanged. simply reapprove it */ - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network_to_area(): " - "old summary approved"); - SET_FLAG (old->flags, OSPF_LSA_APPROVED); - } - else - { - /* LSA is changed, refresh it */ - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network_to_area(): " - "refreshing summary"); - set_metric (old, full_cost); - lsa = ospf_lsa_refresh (area->ospf, old); - - if (!lsa) - { - char buf[PREFIX2STR_BUFFER]; - - prefix2str ((struct prefix *) p, buf, sizeof(buf)); - zlog_warn ("%s: Could not refresh %s to %s", - __func__, - buf, - inet_ntoa (area->area_id)); - return; - } - - SET_FLAG (lsa->flags, OSPF_LSA_APPROVED); - /* This will flood through area. */ - } - } - else - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network_to_area(): " - "creating new summary"); - lsa = ospf_summary_lsa_originate ( (struct prefix_ipv4 *)p, full_cost, area); - /* This will flood through area. */ - - if (!lsa) - { - char buf[PREFIX2STR_BUFFER]; - - prefix2str ((struct prefix *)p, buf, sizeof(buf)); - zlog_warn ("%s: Could not originate %s to %s", - __func__, - buf, - inet_ntoa (area->area_id)); - return; + struct ospf_lsa *lsa, *old = NULL; + struct summary_lsa *sl = NULL; + u_int32_t full_cost; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_announce_network_to_area(): Start"); + + if (CHECK_FLAG(area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED)) + full_cost = OSPF_STUB_MAX_METRIC_SUMMARY_COST; + else + full_cost = cost; + + old = ospf_lsa_lookup_by_prefix(area->lsdb, OSPF_SUMMARY_LSA, + (struct prefix_ipv4 *)p, + area->ospf->router_id); + if (old) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_network_to_area(): old summary found"); + + sl = (struct summary_lsa *)old->data; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_network_to_area(): " + "old metric: %d, new metric: %d", + GET_METRIC(sl->metric), cost); + + if ((GET_METRIC(sl->metric) == full_cost) + && ((old->flags & OSPF_LSA_IN_MAXAGE) == 0)) { + /* unchanged. simply reapprove it */ + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_network_to_area(): " + "old summary approved"); + SET_FLAG(old->flags, OSPF_LSA_APPROVED); + } else { + /* LSA is changed, refresh it */ + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_network_to_area(): " + "refreshing summary"); + set_metric(old, full_cost); + lsa = ospf_lsa_refresh(area->ospf, old); + + if (!lsa) { + char buf[PREFIX2STR_BUFFER]; + + prefix2str((struct prefix *)p, buf, + sizeof(buf)); + zlog_warn("%s: Could not refresh %s to %s", + __func__, buf, + inet_ntoa(area->area_id)); + return; + } + + SET_FLAG(lsa->flags, OSPF_LSA_APPROVED); + /* This will flood through area. */ + } + } else { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_network_to_area(): " + "creating new summary"); + lsa = ospf_summary_lsa_originate((struct prefix_ipv4 *)p, + full_cost, area); + /* This will flood through area. */ + + if (!lsa) { + char buf[PREFIX2STR_BUFFER]; + + prefix2str((struct prefix *)p, buf, sizeof(buf)); + zlog_warn("%s: Could not originate %s to %s", __func__, + buf, inet_ntoa(area->area_id)); + return; + } + + SET_FLAG(lsa->flags, OSPF_LSA_APPROVED); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_network_to_area(): " + "flooding new version of summary"); } - - SET_FLAG (lsa->flags, OSPF_LSA_APPROVED); - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network_to_area(): " - "flooding new version of summary"); - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network_to_area(): Stop"); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_announce_network_to_area(): Stop"); } -static int -ospf_abr_nexthops_belong_to_area (struct ospf_route *or, - struct ospf_area *area) +static int ospf_abr_nexthops_belong_to_area(struct ospf_route * or, + struct ospf_area *area) { - struct listnode *node, *nnode; - struct ospf_path *path; - struct ospf_interface *oi; + struct listnode *node, *nnode; + struct ospf_path *path; + struct ospf_interface *oi; - for (ALL_LIST_ELEMENTS_RO (or->paths, node, path)) - for (ALL_LIST_ELEMENTS_RO (area->oiflist, nnode, oi)) - if (oi->ifp && oi->ifp->ifindex == path->ifindex) - return 1; + for (ALL_LIST_ELEMENTS_RO(or->paths, node, path)) + for (ALL_LIST_ELEMENTS_RO(area->oiflist, nnode, oi)) + if (oi->ifp && oi->ifp->ifindex == path->ifindex) + return 1; - return 0; + return 0; } -static int -ospf_abr_should_accept (struct prefix_ipv4 *p, struct ospf_area *area) +static int ospf_abr_should_accept(struct prefix_ipv4 *p, struct ospf_area *area) { - if (IMPORT_NAME (area)) - { - if (IMPORT_LIST (area) == NULL) - IMPORT_LIST (area) = access_list_lookup (AFI_IP, IMPORT_NAME (area)); - - if (IMPORT_LIST (area)) - if (access_list_apply (IMPORT_LIST (area), p) == FILTER_DENY) - return 0; - } + if (IMPORT_NAME(area)) { + if (IMPORT_LIST(area) == NULL) + IMPORT_LIST(area) = + access_list_lookup(AFI_IP, IMPORT_NAME(area)); + + if (IMPORT_LIST(area)) + if (access_list_apply(IMPORT_LIST(area), p) + == FILTER_DENY) + return 0; + } - return 1; + return 1; } -static int -ospf_abr_plist_in_check (struct ospf_area *area, struct ospf_route *or, - struct prefix_ipv4 *p) +static int ospf_abr_plist_in_check(struct ospf_area *area, + struct ospf_route * or, + struct prefix_ipv4 *p) { - if (PREFIX_NAME_IN (area)) - { - if (PREFIX_LIST_IN (area) == NULL) - PREFIX_LIST_IN (area) = prefix_list_lookup (AFI_IP, - PREFIX_NAME_IN (area)); - if (PREFIX_LIST_IN (area)) - if (prefix_list_apply (PREFIX_LIST_IN (area), p) != PREFIX_PERMIT) - return 0; - } - return 1; + if (PREFIX_NAME_IN(area)) { + if (PREFIX_LIST_IN(area) == NULL) + PREFIX_LIST_IN(area) = prefix_list_lookup( + AFI_IP, PREFIX_NAME_IN(area)); + if (PREFIX_LIST_IN(area)) + if (prefix_list_apply(PREFIX_LIST_IN(area), p) + != PREFIX_PERMIT) + return 0; + } + return 1; } -static int -ospf_abr_plist_out_check (struct ospf_area *area, struct ospf_route *or, - struct prefix_ipv4 *p) +static int ospf_abr_plist_out_check(struct ospf_area *area, + struct ospf_route * or, + struct prefix_ipv4 *p) { - if (PREFIX_NAME_OUT (area)) - { - if (PREFIX_LIST_OUT (area) == NULL) - PREFIX_LIST_OUT (area) = prefix_list_lookup (AFI_IP, - PREFIX_NAME_OUT (area)); - if (PREFIX_LIST_OUT (area)) - if (prefix_list_apply (PREFIX_LIST_OUT (area), p) != PREFIX_PERMIT) - return 0; - } - return 1; + if (PREFIX_NAME_OUT(area)) { + if (PREFIX_LIST_OUT(area) == NULL) + PREFIX_LIST_OUT(area) = prefix_list_lookup( + AFI_IP, PREFIX_NAME_OUT(area)); + if (PREFIX_LIST_OUT(area)) + if (prefix_list_apply(PREFIX_LIST_OUT(area), p) + != PREFIX_PERMIT) + return 0; + } + return 1; } -static void -ospf_abr_announce_network (struct ospf *ospf, - struct prefix_ipv4 *p, struct ospf_route *or) +static void ospf_abr_announce_network(struct ospf *ospf, struct prefix_ipv4 *p, + struct ospf_route * or) { - struct ospf_area_range *range; - struct ospf_area *area, *or_area; - struct listnode *node; + struct ospf_area_range *range; + struct ospf_area *area, *or_area; + struct listnode *node; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network(): Start"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_announce_network(): Start"); - or_area = ospf_area_lookup_by_area_id (ospf, or->u.std.area_id); - assert (or_area); + or_area = ospf_area_lookup_by_area_id(ospf, or->u.std.area_id); + assert(or_area); - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network(): looking at area %s", - inet_ntoa (area->area_id)); + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_network(): looking at area %s", + inet_ntoa(area->area_id)); - if (IPV4_ADDR_SAME (&or->u.std.area_id, &area->area_id)) - continue; + if (IPV4_ADDR_SAME(& or->u.std.area_id, &area->area_id)) + continue; - if (ospf_abr_nexthops_belong_to_area (or, area)) - continue; + if (ospf_abr_nexthops_belong_to_area(or, area)) + continue; - if (!ospf_abr_should_accept (p, area)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network(): " - "prefix %s/%d was denied by import-list", - inet_ntoa (p->prefix), p->prefixlen); - continue; - } + if (!ospf_abr_should_accept(p, area)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_network(): " + "prefix %s/%d was denied by import-list", + inet_ntoa(p->prefix), p->prefixlen); + continue; + } + + if (!ospf_abr_plist_in_check(area, or, p)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_network(): " + "prefix %s/%d was denied by prefix-list", + inet_ntoa(p->prefix), p->prefixlen); + continue; + } + + if (area->external_routing != OSPF_AREA_DEFAULT + && area->no_summary) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_network(): " + "area %s is stub and no_summary", + inet_ntoa(area->area_id)); + continue; + } + + if (or->path_type == OSPF_PATH_INTER_AREA) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_network(): this is " + "inter-area route to %s/%d", + inet_ntoa(p->prefix), p->prefixlen); - if (!ospf_abr_plist_in_check (area, or, p)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network(): " - "prefix %s/%d was denied by prefix-list", - inet_ntoa (p->prefix), p->prefixlen); - continue; + if (!OSPF_IS_AREA_BACKBONE(area)) + ospf_abr_announce_network_to_area(p, or->cost, + area); + } + + if (or->path_type == OSPF_PATH_INTRA_AREA) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_network(): " + "this is intra-area route to %s/%d", + inet_ntoa(p->prefix), p->prefixlen); + if ((range = ospf_area_range_match(or_area, p)) + && !ospf_area_is_transit(area)) + ospf_abr_update_aggregate(range, or, area); + else + ospf_abr_announce_network_to_area(p, or->cost, + area); + } } +} - if (area->external_routing != OSPF_AREA_DEFAULT && area->no_summary) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network(): " - "area %s is stub and no_summary", - inet_ntoa (area->area_id)); - continue; +static int ospf_abr_should_announce(struct ospf *ospf, struct prefix_ipv4 *p, + struct ospf_route * or) +{ + struct ospf_area *area; + + area = ospf_area_lookup_by_area_id(ospf, or->u.std.area_id); + + assert(area); + + if (EXPORT_NAME(area)) { + if (EXPORT_LIST(area) == NULL) + EXPORT_LIST(area) = + access_list_lookup(AFI_IP, EXPORT_NAME(area)); + + if (EXPORT_LIST(area)) + if (access_list_apply(EXPORT_LIST(area), p) + == FILTER_DENY) + return 0; } - if (or->path_type == OSPF_PATH_INTER_AREA) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network(): this is " - "inter-area route to %s/%d", - inet_ntoa (p->prefix), p->prefixlen); + return 1; +} - if (!OSPF_IS_AREA_BACKBONE (area)) - ospf_abr_announce_network_to_area (p, or->cost, area); +static void ospf_abr_process_nssa_translates(struct ospf *ospf) +{ + /* Scan through all NSSA_LSDB records for all areas; + + If P-bit is on, translate all Type-7's to 5's and aggregate or + flood install as approved in Type-5 LSDB with XLATE Flag on + later, do same for all aggregates... At end, DISCARD all + remaining UNAPPROVED Type-5's (Aggregate is for future ) */ + struct listnode *node; + struct ospf_area *area; + struct route_node *rn; + struct ospf_lsa *lsa; + + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_process_nssa_translates(): Start"); + + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + if (!area->NSSATranslatorState) + continue; /* skip if not translator */ + + if (area->external_routing != OSPF_AREA_NSSA) + continue; /* skip if not Nssa Area */ + + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_process_nssa_translates(): " + "looking at area %s", + inet_ntoa(area->area_id)); + + LSDB_LOOP(NSSA_LSDB(area), rn, lsa) + ospf_abr_translate_nssa(area, lsa); } - if (or->path_type == OSPF_PATH_INTRA_AREA) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network(): " - "this is intra-area route to %s/%d", - inet_ntoa (p->prefix), p->prefixlen); - if ((range = ospf_area_range_match (or_area, p)) - && !ospf_area_is_transit (area)) - ospf_abr_update_aggregate (range, or, area); - else - ospf_abr_announce_network_to_area (p, or->cost, area); - } - } + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_process_nssa_translates(): Stop"); } -static int -ospf_abr_should_announce (struct ospf *ospf, - struct prefix_ipv4 *p, struct ospf_route *or) +static void ospf_abr_process_network_rt(struct ospf *ospf, + struct route_table *rt) { - struct ospf_area *area; + struct ospf_area *area; + struct ospf_route * or ; + struct route_node *rn; - area = ospf_area_lookup_by_area_id (ospf, or->u.std.area_id); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_process_network_rt(): Start"); - assert (area); - - if (EXPORT_NAME (area)) - { - if (EXPORT_LIST (area) == NULL) - EXPORT_LIST (area) = access_list_lookup (AFI_IP, EXPORT_NAME (area)); + for (rn = route_top(rt); rn; rn = route_next(rn)) { + if ((or = rn->info) == NULL) + continue; - if (EXPORT_LIST (area)) - if (access_list_apply (EXPORT_LIST (area), p) == FILTER_DENY) - return 0; - } + if (!(area = ospf_area_lookup_by_area_id(ospf, + or->u.std.area_id))) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_network_rt(): area %s no longer exists", + inet_ntoa(or->u.std.area_id)); + continue; + } - return 1; -} + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_network_rt(): this is a route to %s/%d", + inet_ntoa(rn->p.u.prefix4), rn->p.prefixlen); + if (or->path_type >= OSPF_PATH_TYPE1_EXTERNAL) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_network_rt(): " + "this is an External router, skipping"); + continue; + } -static void -ospf_abr_process_nssa_translates (struct ospf *ospf) -{ - /* Scan through all NSSA_LSDB records for all areas; - - If P-bit is on, translate all Type-7's to 5's and aggregate or - flood install as approved in Type-5 LSDB with XLATE Flag on - later, do same for all aggregates... At end, DISCARD all - remaining UNAPPROVED Type-5's (Aggregate is for future ) */ - struct listnode *node; - struct ospf_area *area; - struct route_node *rn; - struct ospf_lsa *lsa; - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_process_nssa_translates(): Start"); - - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - if (! area->NSSATranslatorState) - continue; /* skip if not translator */ - - if (area->external_routing != OSPF_AREA_NSSA) - continue; /* skip if not Nssa Area */ - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_process_nssa_translates(): " - "looking at area %s", inet_ntoa (area->area_id)); - - LSDB_LOOP (NSSA_LSDB (area), rn, lsa) - ospf_abr_translate_nssa (area, lsa); - } - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_process_nssa_translates(): Stop"); + if (or->cost >= OSPF_LS_INFINITY) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_network_rt():" + " this route's cost is infinity, skipping"); + continue; + } -} + if (or->type == OSPF_DESTINATION_DISCARD) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_network_rt():" + " this is a discard entry, skipping"); + continue; + } + + if ( + or->path_type == OSPF_PATH_INTRA_AREA + && !ospf_abr_should_announce( + ospf, (struct prefix_ipv4 *)&rn->p, + or)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_network_rt(): denied by export-list"); + continue; + } + + if ( + or->path_type == OSPF_PATH_INTRA_AREA + && !ospf_abr_plist_out_check( + area, or, + (struct prefix_ipv4 *)&rn->p)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_network_rt(): denied by prefix-list"); + continue; + } -static void -ospf_abr_process_network_rt (struct ospf *ospf, - struct route_table *rt) -{ - struct ospf_area *area; - struct ospf_route *or; - struct route_node *rn; + if ((or->path_type == OSPF_PATH_INTER_AREA) + && !OSPF_IS_AREA_ID_BACKBONE(or->u.std.area_id)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_network_rt():" + " this is route is not backbone one, skipping"); + continue; + } - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_network_rt(): Start"); - for (rn = route_top (rt); rn; rn = route_next (rn)) - { - if ((or = rn->info) == NULL) - continue; + if ((ospf->abr_type == OSPF_ABR_CISCO) + || (ospf->abr_type == OSPF_ABR_IBM)) - if (!(area = ospf_area_lookup_by_area_id (ospf, or->u.std.area_id))) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_network_rt(): area %s no longer exists", - inet_ntoa (or->u.std.area_id)); - continue; - } + if (!ospf_act_bb_connection(ospf) && + or->path_type != OSPF_PATH_INTRA_AREA) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_network_rt(): ALT ABR: " + "No BB connection, skip not intra-area routes"); + continue; + } - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_network_rt(): this is a route to %s/%d", - inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen); - if (or->path_type >= OSPF_PATH_TYPE1_EXTERNAL) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_network_rt(): " - "this is an External router, skipping"); - continue; + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_process_network_rt(): announcing"); + ospf_abr_announce_network(ospf, (struct prefix_ipv4 *)&rn->p, + or); } - if (or->cost >= OSPF_LS_INFINITY) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_network_rt():" - " this route's cost is infinity, skipping"); - continue; - } + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_process_network_rt(): Stop"); +} - if (or->type == OSPF_DESTINATION_DISCARD) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_network_rt():" - " this is a discard entry, skipping"); - continue; - } +static void ospf_abr_announce_rtr_to_area(struct prefix_ipv4 *p, u_int32_t cost, + struct ospf_area *area) +{ + struct ospf_lsa *lsa, *old = NULL; + struct summary_lsa *slsa = NULL; - if (or->path_type == OSPF_PATH_INTRA_AREA && - !ospf_abr_should_announce (ospf, (struct prefix_ipv4 *) &rn->p, or)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug("ospf_abr_process_network_rt(): denied by export-list"); - continue; - } + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_announce_rtr_to_area(): Start"); - if (or->path_type == OSPF_PATH_INTRA_AREA && - !ospf_abr_plist_out_check (area, or, (struct prefix_ipv4 *) &rn->p)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug("ospf_abr_process_network_rt(): denied by prefix-list"); - continue; - } + old = ospf_lsa_lookup_by_prefix(area->lsdb, OSPF_ASBR_SUMMARY_LSA, p, + area->ospf->router_id); + if (old) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_rtr_to_area(): old summary found"); + slsa = (struct summary_lsa *)old->data; - if ((or->path_type == OSPF_PATH_INTER_AREA) && - !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_network_rt():" - " this is route is not backbone one, skipping"); - continue; + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_network_to_area(): " + "old metric: %d, new metric: %d", + GET_METRIC(slsa->metric), cost); } + if (old && (GET_METRIC(slsa->metric) == cost) + && ((old->flags & OSPF_LSA_IN_MAXAGE) == 0)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_rtr_to_area(): old summary approved"); + SET_FLAG(old->flags, OSPF_LSA_APPROVED); + } else { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_announce_rtr_to_area(): 2.2"); + + if (old) { + set_metric(old, cost); + lsa = ospf_lsa_refresh(area->ospf, old); + } else + lsa = ospf_summary_asbr_lsa_originate(p, cost, area); + if (!lsa) { + char buf[PREFIX2STR_BUFFER]; + + prefix2str((struct prefix *)p, buf, sizeof(buf)); + zlog_warn("%s: Could not refresh/originate %s to %s", + __func__, buf, inet_ntoa(area->area_id)); + return; + } - if ((ospf->abr_type == OSPF_ABR_CISCO) || - (ospf->abr_type == OSPF_ABR_IBM)) + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_rtr_to_area(): " + "flooding new version of summary"); - if (!ospf_act_bb_connection (ospf) && - or->path_type != OSPF_PATH_INTRA_AREA) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_network_rt(): ALT ABR: " - "No BB connection, skip not intra-area routes"); - continue; - } + /* + zlog_info ("ospf_abr_announce_rtr_to_area(): creating new + summary"); + lsa = ospf_summary_asbr_lsa (p, cost, area, old); */ - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_network_rt(): announcing"); - ospf_abr_announce_network (ospf, (struct prefix_ipv4 *)&rn->p, or); - } + SET_FLAG(lsa->flags, OSPF_LSA_APPROVED); + /* ospf_flood_through_area (area, NULL, lsa);*/ + } - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_network_rt(): Stop"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_announce_rtr_to_area(): Stop"); } -static void -ospf_abr_announce_rtr_to_area (struct prefix_ipv4 *p, u_int32_t cost, - struct ospf_area *area) + +static void ospf_abr_announce_rtr(struct ospf *ospf, struct prefix_ipv4 *p, + struct ospf_route * or) { - struct ospf_lsa *lsa, *old = NULL; - struct summary_lsa *slsa = NULL; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_rtr_to_area(): Start"); - - old = ospf_lsa_lookup_by_prefix (area->lsdb, OSPF_ASBR_SUMMARY_LSA, - p, area->ospf->router_id); - if (old) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_rtr_to_area(): old summary found"); - slsa = (struct summary_lsa *) old->data; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_network_to_area(): " - "old metric: %d, new metric: %d", - GET_METRIC (slsa->metric), cost); - } - - if (old && (GET_METRIC (slsa->metric) == cost) && - ((old->flags & OSPF_LSA_IN_MAXAGE) == 0)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_rtr_to_area(): old summary approved"); - SET_FLAG (old->flags, OSPF_LSA_APPROVED); - } - else - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_rtr_to_area(): 2.2"); - - if (old) - { - set_metric (old, cost); - lsa = ospf_lsa_refresh (area->ospf, old); + struct listnode *node; + struct ospf_area *area; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_announce_rtr(): Start"); + + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_rtr(): looking at area %s", + inet_ntoa(area->area_id)); + + if (IPV4_ADDR_SAME(& or->u.std.area_id, &area->area_id)) + continue; + + if (ospf_abr_nexthops_belong_to_area(or, area)) + continue; + + if (area->external_routing != OSPF_AREA_DEFAULT) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_rtr(): " + "area %s doesn't support external routing", + inet_ntoa(area->area_id)); + continue; + } + + if (or->path_type == OSPF_PATH_INTER_AREA) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_rtr(): " + "this is inter-area route to %s", + inet_ntoa(p->prefix)); + if (!OSPF_IS_AREA_BACKBONE(area)) + ospf_abr_announce_rtr_to_area(p, or->cost, + area); + } + + if (or->path_type == OSPF_PATH_INTRA_AREA) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_rtr(): " + "this is intra-area route to %s", + inet_ntoa(p->prefix)); + ospf_abr_announce_rtr_to_area(p, or->cost, area); + } } - else - lsa = ospf_summary_asbr_lsa_originate (p, cost, area); - if (!lsa) - { - char buf[PREFIX2STR_BUFFER]; - - prefix2str ((struct prefix *)p, buf, sizeof(buf)); - zlog_warn ("%s: Could not refresh/originate %s to %s", - __func__, - buf, - inet_ntoa (area->area_id)); - return; - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_rtr_to_area(): " - "flooding new version of summary"); - - /* - zlog_info ("ospf_abr_announce_rtr_to_area(): creating new summary"); - lsa = ospf_summary_asbr_lsa (p, cost, area, old); */ - - SET_FLAG (lsa->flags, OSPF_LSA_APPROVED); - /* ospf_flood_through_area (area, NULL, lsa);*/ - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_rtr_to_area(): Stop"); -} + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_announce_rtr(): Stop"); +} -static void -ospf_abr_announce_rtr (struct ospf *ospf, - struct prefix_ipv4 *p, struct ospf_route *or) +static void ospf_abr_process_router_rt(struct ospf *ospf, + struct route_table *rt) { - struct listnode *node; - struct ospf_area *area; + struct ospf_route * or ; + struct route_node *rn; + struct list *l; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_rtr(): Start"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_process_router_rt(): Start"); - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_rtr(): looking at area %s", - inet_ntoa (area->area_id)); + for (rn = route_top(rt); rn; rn = route_next(rn)) { + struct listnode *node, *nnode; + char flag = 0; + struct ospf_route *best = NULL; - if (IPV4_ADDR_SAME (&or->u.std.area_id, &area->area_id)) - continue; + if (rn->info == NULL) + continue; - if (ospf_abr_nexthops_belong_to_area (or, area)) - continue; + l = rn->info; - if (area->external_routing != OSPF_AREA_DEFAULT) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_rtr(): " - "area %s doesn't support external routing", - inet_ntoa(area->area_id)); - continue; + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_router_rt(): this is a route to %s", + inet_ntoa(rn->p.u.prefix4)); + + for (ALL_LIST_ELEMENTS(l, node, nnode, or)) { + if (!ospf_area_lookup_by_area_id(ospf, + or->u.std.area_id)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_router_rt(): area %s no longer exists", + inet_ntoa(or->u.std.area_id)); + continue; + } + + + if (!CHECK_FLAG(or->u.std.flags, ROUTER_LSA_EXTERNAL)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_router_rt(): " + "This is not an ASBR, skipping"); + continue; + } + + if (!flag) { + best = ospf_find_asbr_route( + ospf, rt, (struct prefix_ipv4 *)&rn->p); + flag = 1; + } + + if (best == NULL) + continue; + + if (or != best) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_router_rt(): " + "This route is not the best among possible, skipping"); + continue; + } + + if ( + or->path_type == OSPF_PATH_INTER_AREA + && !OSPF_IS_AREA_ID_BACKBONE( + or->u.std.area_id)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_router_rt(): " + "This route is not a backbone one, skipping"); + continue; + } + + if (or->cost >= OSPF_LS_INFINITY) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_router_rt(): " + "This route has LS_INFINITY metric, skipping"); + continue; + } + + if (ospf->abr_type == OSPF_ABR_CISCO + || ospf->abr_type == OSPF_ABR_IBM) + if (!ospf_act_bb_connection(ospf) && + or->path_type != OSPF_PATH_INTRA_AREA) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_process_network_rt(): ALT ABR: " + "No BB connection, skip not intra-area routes"); + continue; + } + + ospf_abr_announce_rtr(ospf, + (struct prefix_ipv4 *)&rn->p, or); + } } - if (or->path_type == OSPF_PATH_INTER_AREA) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_rtr(): " - "this is inter-area route to %s", inet_ntoa (p->prefix)); - if (!OSPF_IS_AREA_BACKBONE (area)) - ospf_abr_announce_rtr_to_area (p, or->cost, area); - } + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_process_router_rt(): Stop"); +} - if (or->path_type == OSPF_PATH_INTRA_AREA) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_rtr(): " - "this is intra-area route to %s", inet_ntoa (p->prefix)); - ospf_abr_announce_rtr_to_area (p, or->cost, area); +static void +ospf_abr_unapprove_translates(struct ospf *ospf) /* For NSSA Translations */ +{ + struct ospf_lsa *lsa; + struct route_node *rn; + + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_unapprove_translates(): Start"); + + /* NSSA Translator is not checked, because it may have gone away, + and we would want to flush any residuals anyway */ + + LSDB_LOOP(EXTERNAL_LSDB(ospf), rn, lsa) + if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT)) { + UNSET_FLAG(lsa->flags, OSPF_LSA_APPROVED); + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_unapprove_translates(): " + "approved unset on link id %s", + inet_ntoa(lsa->data->id)); } - } - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_rtr(): Stop"); + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_unapprove_translates(): Stop"); } -static void -ospf_abr_process_router_rt (struct ospf *ospf, struct route_table *rt) +static void ospf_abr_unapprove_summaries(struct ospf *ospf) { - struct ospf_route *or; - struct route_node *rn; - struct list *l; + struct listnode *node; + struct ospf_area *area; + struct route_node *rn; + struct ospf_lsa *lsa; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_router_rt(): Start"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_unapprove_summaries(): Start"); - for (rn = route_top (rt); rn; rn = route_next (rn)) - { - struct listnode *node, *nnode; - char flag = 0; - struct ospf_route *best = NULL; + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_unapprove_summaries(): " + "considering area %s", + inet_ntoa(area->area_id)); + LSDB_LOOP(SUMMARY_LSDB(area), rn, lsa) + if (ospf_lsa_is_self_originated(ospf, lsa)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_unapprove_summaries(): " + "approved unset on summary link id %s", + inet_ntoa(lsa->data->id)); + UNSET_FLAG(lsa->flags, OSPF_LSA_APPROVED); + } + + LSDB_LOOP(ASBR_SUMMARY_LSDB(area), rn, lsa) + if (ospf_lsa_is_self_originated(ospf, lsa)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_unapprove_summaries(): " + "approved unset on asbr-summary link id %s", + inet_ntoa(lsa->data->id)); + UNSET_FLAG(lsa->flags, OSPF_LSA_APPROVED); + } + } - if (rn->info == NULL) - continue; + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_unapprove_summaries(): Stop"); +} - l = rn->info; +static void ospf_abr_prepare_aggregates(struct ospf *ospf) +{ + struct listnode *node; + struct route_node *rn; + struct ospf_area_range *range; + struct ospf_area *area; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_prepare_aggregates(): Start"); + + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + for (rn = route_top(area->ranges); rn; rn = route_next(rn)) + if ((range = rn->info) != NULL) { + range->cost = 0; + range->specifics = 0; + } + } - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_router_rt(): this is a route to %s", - inet_ntoa (rn->p.u.prefix4)); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_prepare_aggregates(): Stop"); +} - for (ALL_LIST_ELEMENTS (l, node, nnode, or)) - { - if (!ospf_area_lookup_by_area_id (ospf, or->u.std.area_id)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_router_rt(): area %s no longer exists", - inet_ntoa (or->u.std.area_id)); - continue; - } - - - if (!CHECK_FLAG (or->u.std.flags, ROUTER_LSA_EXTERNAL)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_router_rt(): " - "This is not an ASBR, skipping"); - continue; - } - - if (!flag) - { - best = ospf_find_asbr_route (ospf, rt, - (struct prefix_ipv4 *) &rn->p); - flag = 1; - } - - if (best == NULL) - continue; - - if (or != best) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_router_rt(): " - "This route is not the best among possible, skipping"); - continue; - } - - if (or->path_type == OSPF_PATH_INTER_AREA && - !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_router_rt(): " - "This route is not a backbone one, skipping"); - continue; - } - - if (or->cost >= OSPF_LS_INFINITY) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_router_rt(): " - "This route has LS_INFINITY metric, skipping"); - continue; - } - - if (ospf->abr_type == OSPF_ABR_CISCO - || ospf->abr_type == OSPF_ABR_IBM) - if (!ospf_act_bb_connection (ospf) - && or->path_type != OSPF_PATH_INTRA_AREA) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug("ospf_abr_process_network_rt(): ALT ABR: " - "No BB connection, skip not intra-area routes"); - continue; - } - - ospf_abr_announce_rtr (ospf, (struct prefix_ipv4 *) &rn->p, or); +static void ospf_abr_announce_aggregates(struct ospf *ospf) +{ + struct ospf_area *area, *ar; + struct ospf_area_range *range; + struct route_node *rn; + struct prefix p; + struct listnode *node, *n; - } + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_announce_aggregates(): Start"); - } + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_aggregates(): looking at area %s", + inet_ntoa(area->area_id)); + + for (rn = route_top(area->ranges); rn; rn = route_next(rn)) + if ((range = rn->info)) { + if (!CHECK_FLAG(range->flags, + OSPF_AREA_RANGE_ADVERTISE)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_aggregates():" + " discarding suppress-ranges"); + continue; + } + + p.family = AF_INET; + p.u.prefix4 = range->addr; + p.prefixlen = range->masklen; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_aggregates():" + " this is range: %s/%d", + inet_ntoa(p.u.prefix4), + p.prefixlen); + + if (CHECK_FLAG(range->flags, + OSPF_AREA_RANGE_SUBSTITUTE)) { + p.family = AF_INET; + p.u.prefix4 = range->subst_addr; + p.prefixlen = range->subst_masklen; + } + + if (range->specifics) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_aggregates(): active range"); + + for (ALL_LIST_ELEMENTS_RO(ospf->areas, + n, ar)) { + if (ar == area) + continue; + + /* We do not check nexthops + here, because + intra-area routes can be + associated with + one area only */ + + /* backbone routes are not + summarized + when announced into transit + areas */ + + if (ospf_area_is_transit(ar) + && OSPF_IS_AREA_BACKBONE( + area)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_aggregates(): Skipping " + "announcement of BB aggregate into" + " a transit area"); + continue; + } + ospf_abr_announce_network_to_area( + (struct prefix_ipv4 + *)&p, + range->cost, ar); + } + } + } + } - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_process_router_rt(): Stop"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_announce_aggregates(): Stop"); } static void -ospf_abr_unapprove_translates (struct ospf *ospf) /* For NSSA Translations */ +ospf_abr_send_nssa_aggregates(struct ospf *ospf) /* temporarily turned off */ { - struct ospf_lsa *lsa; - struct route_node *rn; - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_unapprove_translates(): Start"); - - /* NSSA Translator is not checked, because it may have gone away, - and we would want to flush any residuals anyway */ - - LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa) - if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)) - { - UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED); - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_unapprove_translates(): " - "approved unset on link id %s", - inet_ntoa (lsa->data->id)); - } - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_unapprove_translates(): Stop"); + struct listnode *node; /*, n; */ + struct ospf_area *area; /*, *ar; */ + struct route_node *rn; + struct ospf_area_range *range; + struct prefix_ipv4 p; + + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_send_nssa_aggregates(): Start"); + + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + if (!area->NSSATranslatorState) + continue; + + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_send_nssa_aggregates(): looking at area %s", + inet_ntoa(area->area_id)); + + for (rn = route_top(area->ranges); rn; rn = route_next(rn)) { + if (rn->info == NULL) + continue; + + range = rn->info; + + if (!CHECK_FLAG(range->flags, + OSPF_AREA_RANGE_ADVERTISE)) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_send_nssa_aggregates():" + " discarding suppress-ranges"); + continue; + } + + p.family = AF_INET; + p.prefix = range->addr; + p.prefixlen = range->masklen; + + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_send_nssa_aggregates():" + " this is range: %s/%d", + inet_ntoa(p.prefix), p.prefixlen); + + if (CHECK_FLAG(range->flags, + OSPF_AREA_RANGE_SUBSTITUTE)) { + p.family = AF_INET; + p.prefix = range->subst_addr; + p.prefixlen = range->subst_masklen; + } + + if (range->specifics) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_send_nssa_aggregates(): active range"); + + /* Fetch LSA-Type-7 from aggregate prefix, and + * then + * translate, Install (as Type-5), Approve, and + * Flood + */ + ospf_abr_translate_nssa_range(&p, range->cost); + } + } /* all area ranges*/ + } /* all areas */ + + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_send_nssa_aggregates(): Stop"); } -static void -ospf_abr_unapprove_summaries (struct ospf *ospf) +static void ospf_abr_announce_stub_defaults(struct ospf *ospf) { - struct listnode *node; - struct ospf_area *area; - struct route_node *rn; - struct ospf_lsa *lsa; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_unapprove_summaries(): Start"); - - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_unapprove_summaries(): " - "considering area %s", - inet_ntoa (area->area_id)); - LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa) - if (ospf_lsa_is_self_originated (ospf, lsa)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_unapprove_summaries(): " - "approved unset on summary link id %s", - inet_ntoa (lsa->data->id)); - UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED); - } - - LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa) - if (ospf_lsa_is_self_originated (ospf, lsa)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_unapprove_summaries(): " - "approved unset on asbr-summary link id %s", - inet_ntoa (lsa->data->id)); - UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED); - } - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_unapprove_summaries(): Stop"); -} + struct listnode *node; + struct ospf_area *area; + struct prefix_ipv4 p; -static void -ospf_abr_prepare_aggregates (struct ospf *ospf) -{ - struct listnode *node; - struct route_node *rn; - struct ospf_area_range *range; - struct ospf_area *area; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_prepare_aggregates(): Start"); - - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - for (rn = route_top (area->ranges); rn; rn = route_next (rn)) - if ((range = rn->info) != NULL) - { - range->cost = 0; - range->specifics = 0; - } - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_prepare_aggregates(): Stop"); -} + if (!IS_OSPF_ABR(ospf)) + return; -static void -ospf_abr_announce_aggregates (struct ospf *ospf) -{ - struct ospf_area *area, *ar; - struct ospf_area_range *range; - struct route_node *rn; - struct prefix p; - struct listnode *node, *n; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_aggregates(): Start"); - - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_aggregates(): looking at area %s", - inet_ntoa (area->area_id)); - - for (rn = route_top (area->ranges); rn; rn = route_next (rn)) - if ((range = rn->info)) - { - if (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_aggregates():" - " discarding suppress-ranges"); - continue; - } - - p.family = AF_INET; - p.u.prefix4 = range->addr; - p.prefixlen = range->masklen; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_aggregates():" - " this is range: %s/%d", - inet_ntoa (p.u.prefix4), p.prefixlen); - - if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE)) - { - p.family = AF_INET; - p.u.prefix4 = range->subst_addr; - p.prefixlen = range->subst_masklen; - } - - if (range->specifics) - { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_announce_stub_defaults(): Start"); + + p.family = AF_INET; + p.prefix.s_addr = OSPF_DEFAULT_DESTINATION; + p.prefixlen = 0; + + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_aggregates(): active range"); + zlog_debug( + "ospf_abr_announce_stub_defaults(): looking at area %s", + inet_ntoa(area->area_id)); - for (ALL_LIST_ELEMENTS_RO (ospf->areas, n, ar)) - { - if (ar == area) - continue; + if ((area->external_routing != OSPF_AREA_STUB) + && (area->external_routing != OSPF_AREA_NSSA)) + continue; - /* We do not check nexthops here, because - intra-area routes can be associated with - one area only */ + if (OSPF_IS_AREA_BACKBONE(area)) + continue; /* Sanity Check */ - /* backbone routes are not summarized - when announced into transit areas */ + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_stub_defaults(): " + "announcing 0.0.0.0/0 to area %s", + inet_ntoa(area->area_id)); + ospf_abr_announce_network_to_area(&p, area->default_cost, area); + } - if (ospf_area_is_transit (ar) && - OSPF_IS_AREA_BACKBONE (area)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_aggregates(): Skipping " - "announcement of BB aggregate into" - " a transit area"); - continue; - } - ospf_abr_announce_network_to_area ((struct prefix_ipv4 *)&p, range->cost, ar); - } - } - } - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_aggregates(): Stop"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_announce_stub_defaults(): Stop"); } -static void -ospf_abr_send_nssa_aggregates (struct ospf *ospf) /* temporarily turned off */ +static int ospf_abr_remove_unapproved_translates_apply(struct ospf *ospf, + struct ospf_lsa *lsa) { - struct listnode *node; /*, n; */ - struct ospf_area *area; /*, *ar; */ - struct route_node *rn; - struct ospf_area_range *range; - struct prefix_ipv4 p; + if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT) + && !CHECK_FLAG(lsa->flags, OSPF_LSA_APPROVED)) { + zlog_info( + "ospf_abr_remove_unapproved_translates(): " + "removing unapproved translates, ID: %s", + inet_ntoa(lsa->data->id)); - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_send_nssa_aggregates(): Start"); + /* FLUSH THROUGHOUT AS */ + ospf_lsa_flush_as(ospf, lsa); - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - if (! area->NSSATranslatorState) - continue; - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_send_nssa_aggregates(): looking at area %s", - inet_ntoa (area->area_id)); - - for (rn = route_top (area->ranges); rn; rn = route_next (rn)) - { - if (rn->info == NULL) - continue; - - range = rn->info; - - if (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE)) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_send_nssa_aggregates():" - " discarding suppress-ranges"); - continue; - } - - p.family = AF_INET; - p.prefix = range->addr; - p.prefixlen = range->masklen; - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_send_nssa_aggregates():" - " this is range: %s/%d", - inet_ntoa (p.prefix), p.prefixlen); - - if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE)) - { - p.family = AF_INET; - p.prefix = range->subst_addr; - p.prefixlen = range->subst_masklen; - } - - if (range->specifics) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_send_nssa_aggregates(): active range"); - - /* Fetch LSA-Type-7 from aggregate prefix, and then - * translate, Install (as Type-5), Approve, and Flood - */ - ospf_abr_translate_nssa_range (&p, range->cost); - } - } /* all area ranges*/ - } /* all areas */ - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_send_nssa_aggregates(): Stop"); + /* DISCARD from LSDB */ + } + return 0; } -static void -ospf_abr_announce_stub_defaults (struct ospf *ospf) +static void ospf_abr_remove_unapproved_translates(struct ospf *ospf) { - struct listnode *node; - struct ospf_area *area; - struct prefix_ipv4 p; - - if (! IS_OSPF_ABR (ospf)) - return; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_stub_defaults(): Start"); - - p.family = AF_INET; - p.prefix.s_addr = OSPF_DEFAULT_DESTINATION; - p.prefixlen = 0; - - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_stub_defaults(): looking at area %s", - inet_ntoa (area->area_id)); - - if ( (area->external_routing != OSPF_AREA_STUB) - && (area->external_routing != OSPF_AREA_NSSA) - ) - continue; - - if (OSPF_IS_AREA_BACKBONE (area)) - continue; /* Sanity Check */ - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_stub_defaults(): " - "announcing 0.0.0.0/0 to area %s", - inet_ntoa (area->area_id)); - ospf_abr_announce_network_to_area (&p, area->default_cost, area); - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_stub_defaults(): Stop"); -} + struct route_node *rn; + struct ospf_lsa *lsa; -static int -ospf_abr_remove_unapproved_translates_apply (struct ospf *ospf, - struct ospf_lsa *lsa) -{ - if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT) - && ! CHECK_FLAG (lsa->flags, OSPF_LSA_APPROVED)) - { - zlog_info ("ospf_abr_remove_unapproved_translates(): " - "removing unapproved translates, ID: %s", - inet_ntoa (lsa->data->id)); - - /* FLUSH THROUGHOUT AS */ - ospf_lsa_flush_as (ospf, lsa); - - /* DISCARD from LSDB */ - } - return 0; -} + /* All AREA PROCESS should have APPROVED necessary LSAs */ + /* Remove any left over and not APPROVED */ + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_remove_unapproved_translates(): Start"); -static void -ospf_abr_remove_unapproved_translates (struct ospf *ospf) -{ - struct route_node *rn; - struct ospf_lsa *lsa; - - /* All AREA PROCESS should have APPROVED necessary LSAs */ - /* Remove any left over and not APPROVED */ - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_remove_unapproved_translates(): Start"); - - LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa) - ospf_abr_remove_unapproved_translates_apply (ospf, lsa); - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_remove_unapproved_translates(): Stop"); + LSDB_LOOP(EXTERNAL_LSDB(ospf), rn, lsa) + ospf_abr_remove_unapproved_translates_apply(ospf, lsa); + + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_remove_unapproved_translates(): Stop"); } -static void -ospf_abr_remove_unapproved_summaries (struct ospf *ospf) +static void ospf_abr_remove_unapproved_summaries(struct ospf *ospf) { - struct listnode *node; - struct ospf_area *area; - struct route_node *rn; - struct ospf_lsa *lsa; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_remove_unapproved_summaries(): Start"); - - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_remove_unapproved_summaries(): " - "looking at area %s", inet_ntoa (area->area_id)); - - LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa) - if (ospf_lsa_is_self_originated (ospf, lsa)) - if (!CHECK_FLAG (lsa->flags, OSPF_LSA_APPROVED)) - ospf_lsa_flush_area (lsa, area); - - LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa) - if (ospf_lsa_is_self_originated (ospf, lsa)) - if (!CHECK_FLAG (lsa->flags, OSPF_LSA_APPROVED)) - ospf_lsa_flush_area (lsa, area); - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_remove_unapproved_summaries(): Stop"); + struct listnode *node; + struct ospf_area *area; + struct route_node *rn; + struct ospf_lsa *lsa; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_remove_unapproved_summaries(): Start"); + + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_remove_unapproved_summaries(): " + "looking at area %s", + inet_ntoa(area->area_id)); + + LSDB_LOOP(SUMMARY_LSDB(area), rn, lsa) + if (ospf_lsa_is_self_originated(ospf, lsa)) + if (!CHECK_FLAG(lsa->flags, OSPF_LSA_APPROVED)) + ospf_lsa_flush_area(lsa, area); + + LSDB_LOOP(ASBR_SUMMARY_LSDB(area), rn, lsa) + if (ospf_lsa_is_self_originated(ospf, lsa)) + if (!CHECK_FLAG(lsa->flags, OSPF_LSA_APPROVED)) + ospf_lsa_flush_area(lsa, area); + } + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_remove_unapproved_summaries(): Stop"); } -static void -ospf_abr_manage_discard_routes (struct ospf *ospf) +static void ospf_abr_manage_discard_routes(struct ospf *ospf) { - struct listnode *node, *nnode; - struct route_node *rn; - struct ospf_area *area; - struct ospf_area_range *range; - - for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area)) - for (rn = route_top (area->ranges); rn; rn = route_next (rn)) - if ((range = rn->info) != NULL) - if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE)) - { - if (range->specifics) - ospf_add_discard_route (ospf->new_table, area, - (struct prefix_ipv4 *) &rn->p); - else - ospf_delete_discard_route (ospf->new_table, - (struct prefix_ipv4 *) &rn->p); - } + struct listnode *node, *nnode; + struct route_node *rn; + struct ospf_area *area; + struct ospf_area_range *range; + + for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) + for (rn = route_top(area->ranges); rn; rn = route_next(rn)) + if ((range = rn->info) != NULL) + if (CHECK_FLAG(range->flags, + OSPF_AREA_RANGE_ADVERTISE)) { + if (range->specifics) + ospf_add_discard_route( + ospf->new_table, area, + (struct prefix_ipv4 + *)&rn->p); + else + ospf_delete_discard_route( + ospf->new_table, + (struct prefix_ipv4 + *)&rn->p); + } } /* This is the function taking care about ABR NSSA, i.e. NSSA @@ -1738,145 +1719,141 @@ ospf_abr_manage_discard_routes (struct ospf *ospf) For External Calculations, any NSSA areas use the Type-7 AREA-LSDB, any ABR-non-NSSA areas use the Type-5 GLOBAL-LSDB. */ -static void -ospf_abr_nssa_task (struct ospf *ospf) /* called only if any_nssa */ +static void ospf_abr_nssa_task(struct ospf *ospf) /* called only if any_nssa */ { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("Check for NSSA-ABR Tasks():"); - - if (! IS_OSPF_ABR (ospf)) - return; - - if (! ospf->anyNSSA) - return; - - /* Each area must confirm TranslatorRole */ - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_nssa_task(): Start"); - - /* For all Global Entries flagged "local-translate", unset APPROVED */ - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_nssa_task(): unapprove translates"); - - ospf_abr_unapprove_translates (ospf); - - /* RESET all Ranges in every Area, same as summaries */ - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_nssa_task(): NSSA initialize aggregates"); - ospf_abr_prepare_aggregates (ospf); /*TURNED OFF just for now */ - - /* For all NSSAs, Type-7s, translate to 5's, INSTALL/FLOOD, or - * Aggregate as Type-7 - * Install or Approve in Type-5 Global LSDB - */ - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_nssa_task(): process translates"); - ospf_abr_process_nssa_translates (ospf); - - /* Translate/Send any "ranged" aggregates, and also 5-Install and - * Approve - * Scan Type-7's for aggregates, translate to Type-5's, - * Install/Flood/Approve - */ - if (IS_DEBUG_OSPF_NSSA) - zlog_debug("ospf_abr_nssa_task(): send NSSA aggregates"); - ospf_abr_send_nssa_aggregates (ospf); /*TURNED OFF FOR NOW */ - - /* Send any NSSA defaults as Type-5 - *if (IS_DEBUG_OSPF_NSSA) - * zlog_debug ("ospf_abr_nssa_task(): announce nssa defaults"); - *ospf_abr_announce_nssa_defaults (ospf); - * havnt a clue what above is supposed to do. - */ - - /* Flush any unapproved previous translates from Global Data Base */ - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_nssa_task(): remove unapproved translates"); - ospf_abr_remove_unapproved_translates (ospf); - - ospf_abr_manage_discard_routes (ospf); /* same as normal...discard */ - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_nssa_task(): Stop"); + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("Check for NSSA-ABR Tasks():"); + + if (!IS_OSPF_ABR(ospf)) + return; + + if (!ospf->anyNSSA) + return; + + /* Each area must confirm TranslatorRole */ + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_nssa_task(): Start"); + + /* For all Global Entries flagged "local-translate", unset APPROVED */ + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_nssa_task(): unapprove translates"); + + ospf_abr_unapprove_translates(ospf); + + /* RESET all Ranges in every Area, same as summaries */ + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_nssa_task(): NSSA initialize aggregates"); + ospf_abr_prepare_aggregates(ospf); /*TURNED OFF just for now */ + + /* For all NSSAs, Type-7s, translate to 5's, INSTALL/FLOOD, or + * Aggregate as Type-7 + * Install or Approve in Type-5 Global LSDB + */ + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_nssa_task(): process translates"); + ospf_abr_process_nssa_translates(ospf); + + /* Translate/Send any "ranged" aggregates, and also 5-Install and + * Approve + * Scan Type-7's for aggregates, translate to Type-5's, + * Install/Flood/Approve + */ + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_nssa_task(): send NSSA aggregates"); + ospf_abr_send_nssa_aggregates(ospf); /*TURNED OFF FOR NOW */ + + /* Send any NSSA defaults as Type-5 + *if (IS_DEBUG_OSPF_NSSA) + * zlog_debug ("ospf_abr_nssa_task(): announce nssa defaults"); + *ospf_abr_announce_nssa_defaults (ospf); + * havnt a clue what above is supposed to do. + */ + + /* Flush any unapproved previous translates from Global Data Base */ + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_abr_nssa_task(): remove unapproved translates"); + ospf_abr_remove_unapproved_translates(ospf); + + ospf_abr_manage_discard_routes(ospf); /* same as normal...discard */ + + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_abr_nssa_task(): Stop"); } /* This is the function taking care about ABR stuff, i.e. summary-LSA origination and flooding. */ -void -ospf_abr_task (struct ospf *ospf) +void ospf_abr_task(struct ospf *ospf) { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_task(): Start"); - - if (ospf->new_table == NULL || ospf->new_rtrs == NULL) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_task(): Routing tables are not yet ready"); - return; - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_task(): unapprove summaries"); - ospf_abr_unapprove_summaries (ospf); - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_task(): prepare aggregates"); - ospf_abr_prepare_aggregates (ospf); - - if (IS_OSPF_ABR (ospf)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_task(): process network RT"); - ospf_abr_process_network_rt (ospf, ospf->new_table); - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_task(): process router RT"); - ospf_abr_process_router_rt (ospf, ospf->new_rtrs); - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_task(): announce aggregates"); - ospf_abr_announce_aggregates (ospf); - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_task(): announce stub defaults"); - ospf_abr_announce_stub_defaults (ospf); - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_task(): remove unapproved summaries"); - ospf_abr_remove_unapproved_summaries (ospf); - - ospf_abr_manage_discard_routes (ospf); - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_task(): Stop"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_task(): Start"); + + if (ospf->new_table == NULL || ospf->new_rtrs == NULL) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_task(): Routing tables are not yet ready"); + return; + } + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_task(): unapprove summaries"); + ospf_abr_unapprove_summaries(ospf); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_task(): prepare aggregates"); + ospf_abr_prepare_aggregates(ospf); + + if (IS_OSPF_ABR(ospf)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_task(): process network RT"); + ospf_abr_process_network_rt(ospf, ospf->new_table); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_task(): process router RT"); + ospf_abr_process_router_rt(ospf, ospf->new_rtrs); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_task(): announce aggregates"); + ospf_abr_announce_aggregates(ospf); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_task(): announce stub defaults"); + ospf_abr_announce_stub_defaults(ospf); + } + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_task(): remove unapproved summaries"); + ospf_abr_remove_unapproved_summaries(ospf); + + ospf_abr_manage_discard_routes(ospf); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_abr_task(): Stop"); } -static int -ospf_abr_task_timer (struct thread *thread) +static int ospf_abr_task_timer(struct thread *thread) { - struct ospf *ospf = THREAD_ARG (thread); + struct ospf *ospf = THREAD_ARG(thread); - ospf->t_abr_task = 0; + ospf->t_abr_task = 0; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Running ABR task on timer"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Running ABR task on timer"); - ospf_check_abr_status (ospf); - ospf_abr_nssa_check_status (ospf); + ospf_check_abr_status(ospf); + ospf_abr_nssa_check_status(ospf); - ospf_abr_task (ospf); - ospf_abr_nssa_task (ospf); /* if nssa-abr, then scan Type-7 LSDB */ + ospf_abr_task(ospf); + ospf_abr_nssa_task(ospf); /* if nssa-abr, then scan Type-7 LSDB */ - return 0; + return 0; } -void -ospf_schedule_abr_task (struct ospf *ospf) +void ospf_schedule_abr_task(struct ospf *ospf) { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Scheduling ABR task"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Scheduling ABR task"); - thread_add_timer(master, ospf_abr_task_timer, ospf, OSPF_ABR_TASK_DELAY, - &ospf->t_abr_task); + thread_add_timer(master, ospf_abr_task_timer, ospf, OSPF_ABR_TASK_DELAY, + &ospf->t_abr_task); } diff --git a/ospfd/ospf_abr.h b/ospfd/ospf_abr.h index 71eb71bdc..379273213 100644 --- a/ospfd/ospf_abr.h +++ b/ospfd/ospf_abr.h @@ -28,65 +28,59 @@ #define OSPF_AREA_RANGE_SUBSTITUTE (1 << 1) /* Area range. */ -struct ospf_area_range -{ - /* Area range address. */ - struct in_addr addr; +struct ospf_area_range { + /* Area range address. */ + struct in_addr addr; - /* Area range masklen. */ - u_char masklen; + /* Area range masklen. */ + u_char masklen; - /* Flags. */ - u_char flags; + /* Flags. */ + u_char flags; - /* Number of more specific prefixes. */ - int specifics; + /* Number of more specific prefixes. */ + int specifics; - /* Addr and masklen to substitute. */ - struct in_addr subst_addr; - u_char subst_masklen; + /* Addr and masklen to substitute. */ + struct in_addr subst_addr; + u_char subst_masklen; - /* Range cost. */ - u_int32_t cost; + /* Range cost. */ + u_int32_t cost; - /* Configured range cost. */ - u_int32_t cost_config; + /* Configured range cost. */ + u_int32_t cost_config; }; /* Prototypes. */ -extern struct ospf_area_range *ospf_area_range_lookup (struct ospf_area *, - struct prefix_ipv4 *); - -extern struct ospf_area_range *ospf_some_area_range_match (struct prefix_ipv4 - *); - -extern struct ospf_area_range *ospf_area_range_lookup_next (struct ospf_area - *, - struct in_addr *, - int); - -extern int ospf_area_range_set (struct ospf *, struct in_addr, - struct prefix_ipv4 *, int); -extern int ospf_area_range_cost_set (struct ospf *, struct in_addr, - struct prefix_ipv4 *, u_int32_t); -extern int ospf_area_range_unset (struct ospf *, struct in_addr, - struct prefix_ipv4 *); -extern int ospf_area_range_substitute_set (struct ospf *, struct in_addr, - struct prefix_ipv4 *, - struct prefix_ipv4 *); -extern int ospf_area_range_substitute_unset (struct ospf *, struct in_addr, - struct prefix_ipv4 *); -extern struct ospf_area_range *ospf_area_range_match_any (struct ospf *, - struct prefix_ipv4 - *); -extern int ospf_area_range_active (struct ospf_area_range *); -extern int ospf_act_bb_connection (struct ospf *); - -extern void ospf_check_abr_status (struct ospf *); -extern void ospf_abr_task (struct ospf *); -extern void ospf_schedule_abr_task (struct ospf *); - -extern void ospf_abr_announce_network_to_area (struct prefix_ipv4 *, - u_int32_t, - struct ospf_area *); +extern struct ospf_area_range *ospf_area_range_lookup(struct ospf_area *, + struct prefix_ipv4 *); + +extern struct ospf_area_range *ospf_some_area_range_match(struct prefix_ipv4 *); + +extern struct ospf_area_range * +ospf_area_range_lookup_next(struct ospf_area *, struct in_addr *, int); + +extern int ospf_area_range_set(struct ospf *, struct in_addr, + struct prefix_ipv4 *, int); +extern int ospf_area_range_cost_set(struct ospf *, struct in_addr, + struct prefix_ipv4 *, u_int32_t); +extern int ospf_area_range_unset(struct ospf *, struct in_addr, + struct prefix_ipv4 *); +extern int ospf_area_range_substitute_set(struct ospf *, struct in_addr, + struct prefix_ipv4 *, + struct prefix_ipv4 *); +extern int ospf_area_range_substitute_unset(struct ospf *, struct in_addr, + struct prefix_ipv4 *); +extern struct ospf_area_range *ospf_area_range_match_any(struct ospf *, + struct prefix_ipv4 *); +extern int ospf_area_range_active(struct ospf_area_range *); +extern int ospf_act_bb_connection(struct ospf *); + +extern void ospf_check_abr_status(struct ospf *); +extern void ospf_abr_task(struct ospf *); +extern void ospf_schedule_abr_task(struct ospf *); + +extern void ospf_abr_announce_network_to_area(struct prefix_ipv4 *, u_int32_t, + struct ospf_area *); #endif /* _ZEBRA_OSPF_ABR_H */ diff --git a/ospfd/ospf_api.c b/ospfd/ospf_api.c index 69d61b12e..f1a743376 100644 --- a/ospfd/ospf_api.c +++ b/ospfd/ospf_api.c @@ -34,7 +34,7 @@ #include "log.h" #include "thread.h" #include "hash.h" -#include "sockunion.h" /* for inet_aton() */ +#include "sockunion.h" /* for inet_aton() */ #include "buffer.h" #include "network.h" @@ -58,31 +58,28 @@ /* For debugging only, will be removed */ -void -api_opaque_lsa_print (struct lsa_header *data) +void api_opaque_lsa_print(struct lsa_header *data) { - struct opaque_lsa - { - struct lsa_header header; - u_char mydata[]; - }; + struct opaque_lsa { + struct lsa_header header; + u_char mydata[]; + }; - struct opaque_lsa *olsa; - int opaquelen; - int i; + struct opaque_lsa *olsa; + int opaquelen; + int i; - ospf_lsa_header_dump (data); + ospf_lsa_header_dump(data); - olsa = (struct opaque_lsa *) data; + olsa = (struct opaque_lsa *)data; - opaquelen = ntohs (data->length) - OSPF_LSA_HEADER_SIZE; - zlog_debug ("apiserver_lsa_print: opaquelen=%d\n", opaquelen); + opaquelen = ntohs(data->length) - OSPF_LSA_HEADER_SIZE; + zlog_debug("apiserver_lsa_print: opaquelen=%d\n", opaquelen); - for (i = 0; i < opaquelen; i++) - { - zlog_debug ("0x%x ", olsa->mydata[i]); - } - zlog_debug ("\n"); + for (i = 0; i < opaquelen; i++) { + zlog_debug("0x%x ", olsa->mydata[i]); + } + zlog_debug("\n"); } /* ----------------------------------------------------------- @@ -90,172 +87,212 @@ api_opaque_lsa_print (struct lsa_header *data) * ----------------------------------------------------------- */ -struct msg * -msg_new (u_char msgtype, void *msgbody, u_int32_t seqnum, u_int16_t msglen) +struct msg *msg_new(u_char msgtype, void *msgbody, u_int32_t seqnum, + u_int16_t msglen) { - struct msg *new; + struct msg *new; - new = XCALLOC (MTYPE_OSPF_API_MSG, sizeof (struct msg)); + new = XCALLOC(MTYPE_OSPF_API_MSG, sizeof(struct msg)); - new->hdr.version = OSPF_API_VERSION; - new->hdr.msgtype = msgtype; - new->hdr.msglen = htons (msglen); - new->hdr.msgseq = htonl (seqnum); + new->hdr.version = OSPF_API_VERSION; + new->hdr.msgtype = msgtype; + new->hdr.msglen = htons(msglen); + new->hdr.msgseq = htonl(seqnum); - new->s = stream_new (msglen); - assert (new->s); - stream_put (new->s, msgbody, msglen); + new->s = stream_new(msglen); + assert(new->s); + stream_put(new->s, msgbody, msglen); - return new; + return new; } /* Duplicate a message by copying content. */ -struct msg * -msg_dup (struct msg *msg) +struct msg *msg_dup(struct msg *msg) { - struct msg *new; + struct msg *new; - assert (msg); + assert(msg); - new = msg_new (msg->hdr.msgtype, STREAM_DATA (msg->s), - ntohl (msg->hdr.msgseq), ntohs (msg->hdr.msglen)); - return new; + new = msg_new(msg->hdr.msgtype, STREAM_DATA(msg->s), + ntohl(msg->hdr.msgseq), ntohs(msg->hdr.msglen)); + return new; } /* XXX only for testing, will be removed */ struct nametab { - int value; - const char *name; + int value; + const char *name; }; -const char * -ospf_api_typename (int msgtype) +const char *ospf_api_typename(int msgtype) { - struct nametab NameTab[] = { - { MSG_REGISTER_OPAQUETYPE, "Register opaque-type", }, - { MSG_UNREGISTER_OPAQUETYPE, "Unregister opaque-type", }, - { MSG_REGISTER_EVENT, "Register event", }, - { MSG_SYNC_LSDB, "Sync LSDB", }, - { MSG_ORIGINATE_REQUEST, "Originate request", }, - { MSG_DELETE_REQUEST, "Delete request", }, - { MSG_REPLY, "Reply", }, - { MSG_READY_NOTIFY, "Ready notify", }, - { MSG_LSA_UPDATE_NOTIFY, "LSA update notify", }, - { MSG_LSA_DELETE_NOTIFY, "LSA delete notify", }, - { MSG_NEW_IF, "New interface", }, - { MSG_DEL_IF, "Del interface", }, - { MSG_ISM_CHANGE, "ISM change", }, - { MSG_NSM_CHANGE, "NSM change", }, - }; - - int i, n = array_size(NameTab); - const char *name = NULL; - - for (i = 0; i < n; i++) - { - if (NameTab[i].value == msgtype) - { - name = NameTab[i].name; - break; - } - } - - return name ? name : "?"; + struct nametab NameTab[] = { + { + MSG_REGISTER_OPAQUETYPE, "Register opaque-type", + }, + { + MSG_UNREGISTER_OPAQUETYPE, "Unregister opaque-type", + }, + { + MSG_REGISTER_EVENT, "Register event", + }, + { + MSG_SYNC_LSDB, "Sync LSDB", + }, + { + MSG_ORIGINATE_REQUEST, "Originate request", + }, + { + MSG_DELETE_REQUEST, "Delete request", + }, + { + MSG_REPLY, "Reply", + }, + { + MSG_READY_NOTIFY, "Ready notify", + }, + { + MSG_LSA_UPDATE_NOTIFY, "LSA update notify", + }, + { + MSG_LSA_DELETE_NOTIFY, "LSA delete notify", + }, + { + MSG_NEW_IF, "New interface", + }, + { + MSG_DEL_IF, "Del interface", + }, + { + MSG_ISM_CHANGE, "ISM change", + }, + { + MSG_NSM_CHANGE, "NSM change", + }, + }; + + int i, n = array_size(NameTab); + const char *name = NULL; + + for (i = 0; i < n; i++) { + if (NameTab[i].value == msgtype) { + name = NameTab[i].name; + break; + } + } + + return name ? name : "?"; } -const char * -ospf_api_errname (int errcode) +const char *ospf_api_errname(int errcode) { - struct nametab NameTab[] = { - { OSPF_API_OK, "OK", }, - { OSPF_API_NOSUCHINTERFACE, "No such interface", }, - { OSPF_API_NOSUCHAREA, "No such area", }, - { OSPF_API_NOSUCHLSA, "No such LSA", }, - { OSPF_API_ILLEGALLSATYPE, "Illegal LSA type", }, - { OSPF_API_OPAQUETYPEINUSE, "Opaque type in use", }, - { OSPF_API_OPAQUETYPENOTREGISTERED, "Opaque type not registered", }, - { OSPF_API_NOTREADY, "Not ready", }, - { OSPF_API_NOMEMORY, "No memory", }, - { OSPF_API_ERROR, "Other error", }, - { OSPF_API_UNDEF, "Undefined", }, - }; - - int i, n = array_size(NameTab); - const char *name = NULL; - - for (i = 0; i < n; i++) - { - if (NameTab[i].value == errcode) - { - name = NameTab[i].name; - break; - } - } - - return name ? name : "?"; + struct nametab NameTab[] = { + { + OSPF_API_OK, "OK", + }, + { + OSPF_API_NOSUCHINTERFACE, "No such interface", + }, + { + OSPF_API_NOSUCHAREA, "No such area", + }, + { + OSPF_API_NOSUCHLSA, "No such LSA", + }, + { + OSPF_API_ILLEGALLSATYPE, "Illegal LSA type", + }, + { + OSPF_API_OPAQUETYPEINUSE, "Opaque type in use", + }, + { + OSPF_API_OPAQUETYPENOTREGISTERED, + "Opaque type not registered", + }, + { + OSPF_API_NOTREADY, "Not ready", + }, + { + OSPF_API_NOMEMORY, "No memory", + }, + { + OSPF_API_ERROR, "Other error", + }, + { + OSPF_API_UNDEF, "Undefined", + }, + }; + + int i, n = array_size(NameTab); + const char *name = NULL; + + for (i = 0; i < n; i++) { + if (NameTab[i].value == errcode) { + name = NameTab[i].name; + break; + } + } + + return name ? name : "?"; } -void -msg_print (struct msg *msg) +void msg_print(struct msg *msg) { - if (!msg) - { - zlog_debug ("msg_print msg=NULL!\n"); - return; - } + if (!msg) { + zlog_debug("msg_print msg=NULL!\n"); + return; + } #ifdef ORIGINAL_CODING - zlog_debug - ("msg=%p msgtype=%d msglen=%d msgseq=%d streamdata=%p streamsize=%lu\n", - msg, msg->hdr.msgtype, ntohs (msg->hdr.msglen), ntohl (msg->hdr.msgseq), - STREAM_DATA (msg->s), STREAM_SIZE (msg->s)); + zlog_debug( + "msg=%p msgtype=%d msglen=%d msgseq=%d streamdata=%p streamsize=%lu\n", + msg, msg->hdr.msgtype, ntohs(msg->hdr.msglen), + ntohl(msg->hdr.msgseq), STREAM_DATA(msg->s), + STREAM_SIZE(msg->s)); #else /* ORIGINAL_CODING */ - /* API message common header part. */ - zlog_debug - ("API-msg [%s]: type(%d),len(%d),seq(%lu),data(%p),size(%zd)", - ospf_api_typename (msg->hdr.msgtype), msg->hdr.msgtype, - ntohs (msg->hdr.msglen), (unsigned long) ntohl (msg->hdr.msgseq), - STREAM_DATA (msg->s), STREAM_SIZE (msg->s)); - - /* API message body part. */ + /* API message common header part. */ + zlog_debug("API-msg [%s]: type(%d),len(%d),seq(%lu),data(%p),size(%zd)", + ospf_api_typename(msg->hdr.msgtype), msg->hdr.msgtype, + ntohs(msg->hdr.msglen), + (unsigned long)ntohl(msg->hdr.msgseq), STREAM_DATA(msg->s), + STREAM_SIZE(msg->s)); + +/* API message body part. */ #ifdef ndef - /* Generic Hex/Ascii dump */ - DumpBuf (STREAM_DATA (msg->s), STREAM_SIZE (msg->s)); /* Sorry, deleted! */ -#else /* ndef */ - /* Message-type dependent dump function. */ + /* Generic Hex/Ascii dump */ + DumpBuf(STREAM_DATA(msg->s), STREAM_SIZE(msg->s)); /* Sorry, deleted! */ +#else /* ndef */ +/* Message-type dependent dump function. */ #endif /* ndef */ - return; + return; #endif /* ORIGINAL_CODING */ } -void -msg_free (struct msg *msg) +void msg_free(struct msg *msg) { - if (msg->s) - stream_free (msg->s); + if (msg->s) + stream_free(msg->s); - XFREE (MTYPE_OSPF_API_MSG, msg); + XFREE(MTYPE_OSPF_API_MSG, msg); } /* Set sequence number of message */ -void -msg_set_seq (struct msg *msg, u_int32_t seqnr) +void msg_set_seq(struct msg *msg, u_int32_t seqnr) { - assert (msg); - msg->hdr.msgseq = htonl (seqnr); + assert(msg); + msg->hdr.msgseq = htonl(seqnr); } /* Get sequence number of message */ -u_int32_t -msg_get_seq (struct msg *msg) +u_int32_t msg_get_seq(struct msg *msg) { - assert (msg); - return ntohl (msg->hdr.msgseq); + assert(msg); + return ntohl(msg->hdr.msgseq); } /* ----------------------------------------------------------- @@ -263,178 +300,151 @@ msg_get_seq (struct msg *msg) * ----------------------------------------------------------- */ -struct msg_fifo * -msg_fifo_new () +struct msg_fifo *msg_fifo_new() { - return XCALLOC (MTYPE_OSPF_API_FIFO, sizeof (struct msg_fifo)); + return XCALLOC(MTYPE_OSPF_API_FIFO, sizeof(struct msg_fifo)); } /* Add new message to fifo. */ -void -msg_fifo_push (struct msg_fifo *fifo, struct msg *msg) +void msg_fifo_push(struct msg_fifo *fifo, struct msg *msg) { - if (fifo->tail) - fifo->tail->next = msg; - else - fifo->head = msg; + if (fifo->tail) + fifo->tail->next = msg; + else + fifo->head = msg; - fifo->tail = msg; - fifo->count++; + fifo->tail = msg; + fifo->count++; } /* Remove first message from fifo. */ -struct msg * -msg_fifo_pop (struct msg_fifo *fifo) +struct msg *msg_fifo_pop(struct msg_fifo *fifo) { - struct msg *msg; + struct msg *msg; - msg = fifo->head; - if (msg) - { - fifo->head = msg->next; + msg = fifo->head; + if (msg) { + fifo->head = msg->next; - if (fifo->head == NULL) - fifo->tail = NULL; + if (fifo->head == NULL) + fifo->tail = NULL; - fifo->count--; - } - return msg; + fifo->count--; + } + return msg; } /* Return first fifo entry but do not remove it. */ -struct msg * -msg_fifo_head (struct msg_fifo *fifo) +struct msg *msg_fifo_head(struct msg_fifo *fifo) { - return fifo->head; + return fifo->head; } /* Flush message fifo. */ -void -msg_fifo_flush (struct msg_fifo *fifo) +void msg_fifo_flush(struct msg_fifo *fifo) { - struct msg *op; - struct msg *next; + struct msg *op; + struct msg *next; - for (op = fifo->head; op; op = next) - { - next = op->next; - msg_free (op); - } + for (op = fifo->head; op; op = next) { + next = op->next; + msg_free(op); + } - fifo->head = fifo->tail = NULL; - fifo->count = 0; + fifo->head = fifo->tail = NULL; + fifo->count = 0; } /* Free API message fifo. */ -void -msg_fifo_free (struct msg_fifo *fifo) +void msg_fifo_free(struct msg_fifo *fifo) { - msg_fifo_flush (fifo); + msg_fifo_flush(fifo); - XFREE (MTYPE_OSPF_API_FIFO, fifo); + XFREE(MTYPE_OSPF_API_FIFO, fifo); } -struct msg * -msg_read (int fd) +struct msg *msg_read(int fd) { - struct msg *msg; - struct apimsghdr hdr; - u_char buf[OSPF_API_MAX_MSG_SIZE]; - int bodylen; - int rlen; - - /* Read message header */ - rlen = readn (fd, (u_char *) &hdr, sizeof (struct apimsghdr)); - - if (rlen < 0) - { - zlog_warn ("msg_read: readn %s", safe_strerror (errno)); - return NULL; - } - else if (rlen == 0) - { - zlog_warn ("msg_read: Connection closed by peer"); - return NULL; - } - else if (rlen != sizeof (struct apimsghdr)) - { - zlog_warn ("msg_read: Cannot read message header!"); - return NULL; - } - - /* Check version of API protocol */ - if (hdr.version != OSPF_API_VERSION) - { - zlog_warn ("msg_read: OSPF API protocol version mismatch"); - return NULL; - } - - /* Determine body length. */ - bodylen = ntohs (hdr.msglen); - if (bodylen > 0) - { - - /* Read message body */ - rlen = readn (fd, buf, bodylen); - if (rlen < 0) - { - zlog_warn ("msg_read: readn %s", safe_strerror (errno)); - return NULL; + struct msg *msg; + struct apimsghdr hdr; + u_char buf[OSPF_API_MAX_MSG_SIZE]; + int bodylen; + int rlen; + + /* Read message header */ + rlen = readn(fd, (u_char *)&hdr, sizeof(struct apimsghdr)); + + if (rlen < 0) { + zlog_warn("msg_read: readn %s", safe_strerror(errno)); + return NULL; + } else if (rlen == 0) { + zlog_warn("msg_read: Connection closed by peer"); + return NULL; + } else if (rlen != sizeof(struct apimsghdr)) { + zlog_warn("msg_read: Cannot read message header!"); + return NULL; } - else if (rlen == 0) - { - zlog_warn ("msg_read: Connection closed by peer"); - return NULL; + + /* Check version of API protocol */ + if (hdr.version != OSPF_API_VERSION) { + zlog_warn("msg_read: OSPF API protocol version mismatch"); + return NULL; } - else if (rlen != bodylen) - { - zlog_warn ("msg_read: Cannot read message body!"); - return NULL; + + /* Determine body length. */ + bodylen = ntohs(hdr.msglen); + if (bodylen > 0) { + + /* Read message body */ + rlen = readn(fd, buf, bodylen); + if (rlen < 0) { + zlog_warn("msg_read: readn %s", safe_strerror(errno)); + return NULL; + } else if (rlen == 0) { + zlog_warn("msg_read: Connection closed by peer"); + return NULL; + } else if (rlen != bodylen) { + zlog_warn("msg_read: Cannot read message body!"); + return NULL; + } } - } - /* Allocate new message */ - msg = msg_new (hdr.msgtype, buf, ntohl (hdr.msgseq), ntohs (hdr.msglen)); + /* Allocate new message */ + msg = msg_new(hdr.msgtype, buf, ntohl(hdr.msgseq), ntohs(hdr.msglen)); - return msg; + return msg; } -int -msg_write (int fd, struct msg *msg) +int msg_write(int fd, struct msg *msg) { - u_char buf[OSPF_API_MAX_MSG_SIZE]; - int l; - int wlen; - - assert (msg); - assert (msg->s); - - /* Length of message including header */ - l = sizeof (struct apimsghdr) + ntohs (msg->hdr.msglen); - - /* Make contiguous memory buffer for message */ - memcpy (buf, &msg->hdr, sizeof (struct apimsghdr)); - memcpy (buf + sizeof (struct apimsghdr), STREAM_DATA (msg->s), - ntohs (msg->hdr.msglen)); - - wlen = writen (fd, buf, l); - if (wlen < 0) - { - zlog_warn ("msg_write: writen %s", safe_strerror (errno)); - return -1; - } - else if (wlen == 0) - { - zlog_warn ("msg_write: Connection closed by peer"); - return -1; - } - else if (wlen != l) - { - zlog_warn ("msg_write: Cannot write API message"); - return -1; - } - return 0; + u_char buf[OSPF_API_MAX_MSG_SIZE]; + int l; + int wlen; + + assert(msg); + assert(msg->s); + + /* Length of message including header */ + l = sizeof(struct apimsghdr) + ntohs(msg->hdr.msglen); + + /* Make contiguous memory buffer for message */ + memcpy(buf, &msg->hdr, sizeof(struct apimsghdr)); + memcpy(buf + sizeof(struct apimsghdr), STREAM_DATA(msg->s), + ntohs(msg->hdr.msglen)); + + wlen = writen(fd, buf, l); + if (wlen < 0) { + zlog_warn("msg_write: writen %s", safe_strerror(errno)); + return -1; + } else if (wlen == 0) { + zlog_warn("msg_write: Connection closed by peer"); + return -1; + } else if (wlen != l) { + zlog_warn("msg_write: Cannot write API message"); + return -1; + } + return 0; } /* ----------------------------------------------------------- @@ -442,207 +452,201 @@ msg_write (int fd, struct msg *msg) * ----------------------------------------------------------- */ -struct msg * -new_msg_register_opaque_type (u_int32_t seqnum, u_char ltype, u_char otype) +struct msg *new_msg_register_opaque_type(u_int32_t seqnum, u_char ltype, + u_char otype) { - struct msg_register_opaque_type rmsg; + struct msg_register_opaque_type rmsg; - rmsg.lsatype = ltype; - rmsg.opaquetype = otype; - memset (&rmsg.pad, 0, sizeof (rmsg.pad)); + rmsg.lsatype = ltype; + rmsg.opaquetype = otype; + memset(&rmsg.pad, 0, sizeof(rmsg.pad)); - return msg_new (MSG_REGISTER_OPAQUETYPE, &rmsg, seqnum, - sizeof (struct msg_register_opaque_type)); + return msg_new(MSG_REGISTER_OPAQUETYPE, &rmsg, seqnum, + sizeof(struct msg_register_opaque_type)); } -struct msg * -new_msg_register_event (u_int32_t seqnum, struct lsa_filter_type *filter) +struct msg *new_msg_register_event(u_int32_t seqnum, + struct lsa_filter_type *filter) { - u_char buf[OSPF_API_MAX_MSG_SIZE]; - struct msg_register_event *emsg; - unsigned int len; - - emsg = (struct msg_register_event *) buf; - len = sizeof (struct msg_register_event) + - filter->num_areas * sizeof (struct in_addr); - emsg->filter.typemask = htons (filter->typemask); - emsg->filter.origin = filter->origin; - emsg->filter.num_areas = filter->num_areas; - if (len > sizeof (buf)) - len = sizeof(buf); - /* API broken - missing memcpy to fill data */ - return msg_new (MSG_REGISTER_EVENT, emsg, seqnum, len); + u_char buf[OSPF_API_MAX_MSG_SIZE]; + struct msg_register_event *emsg; + unsigned int len; + + emsg = (struct msg_register_event *)buf; + len = sizeof(struct msg_register_event) + + filter->num_areas * sizeof(struct in_addr); + emsg->filter.typemask = htons(filter->typemask); + emsg->filter.origin = filter->origin; + emsg->filter.num_areas = filter->num_areas; + if (len > sizeof(buf)) + len = sizeof(buf); + /* API broken - missing memcpy to fill data */ + return msg_new(MSG_REGISTER_EVENT, emsg, seqnum, len); } -struct msg * -new_msg_sync_lsdb (u_int32_t seqnum, struct lsa_filter_type *filter) +struct msg *new_msg_sync_lsdb(u_int32_t seqnum, struct lsa_filter_type *filter) { - u_char buf[OSPF_API_MAX_MSG_SIZE]; - struct msg_sync_lsdb *smsg; - unsigned int len; - - smsg = (struct msg_sync_lsdb *) buf; - len = sizeof (struct msg_sync_lsdb) + - filter->num_areas * sizeof (struct in_addr); - smsg->filter.typemask = htons (filter->typemask); - smsg->filter.origin = filter->origin; - smsg->filter.num_areas = filter->num_areas; - if (len > sizeof (buf)) - len = sizeof(buf); - /* API broken - missing memcpy to fill data */ - return msg_new (MSG_SYNC_LSDB, smsg, seqnum, len); + u_char buf[OSPF_API_MAX_MSG_SIZE]; + struct msg_sync_lsdb *smsg; + unsigned int len; + + smsg = (struct msg_sync_lsdb *)buf; + len = sizeof(struct msg_sync_lsdb) + + filter->num_areas * sizeof(struct in_addr); + smsg->filter.typemask = htons(filter->typemask); + smsg->filter.origin = filter->origin; + smsg->filter.num_areas = filter->num_areas; + if (len > sizeof(buf)) + len = sizeof(buf); + /* API broken - missing memcpy to fill data */ + return msg_new(MSG_SYNC_LSDB, smsg, seqnum, len); } -struct msg * -new_msg_originate_request (u_int32_t seqnum, - struct in_addr ifaddr, - struct in_addr area_id, struct lsa_header *data) +struct msg *new_msg_originate_request(u_int32_t seqnum, struct in_addr ifaddr, + struct in_addr area_id, + struct lsa_header *data) { - struct msg_originate_request *omsg; - unsigned int omsglen; - char buf[OSPF_API_MAX_MSG_SIZE]; - - omsg = (struct msg_originate_request *) buf; - omsg->ifaddr = ifaddr; - omsg->area_id = area_id; - - omsglen = ntohs (data->length); - if (omsglen > sizeof (buf) - offsetof (struct msg_originate_request, data)) - omsglen = sizeof (buf) - offsetof (struct msg_originate_request, data); - memcpy (&omsg->data, data, omsglen); - omsglen += sizeof (struct msg_originate_request) - sizeof (struct lsa_header); - - return msg_new (MSG_ORIGINATE_REQUEST, omsg, seqnum, omsglen); + struct msg_originate_request *omsg; + unsigned int omsglen; + char buf[OSPF_API_MAX_MSG_SIZE]; + + omsg = (struct msg_originate_request *)buf; + omsg->ifaddr = ifaddr; + omsg->area_id = area_id; + + omsglen = ntohs(data->length); + if (omsglen + > sizeof(buf) - offsetof(struct msg_originate_request, data)) + omsglen = sizeof(buf) + - offsetof(struct msg_originate_request, data); + memcpy(&omsg->data, data, omsglen); + omsglen += sizeof(struct msg_originate_request) + - sizeof(struct lsa_header); + + return msg_new(MSG_ORIGINATE_REQUEST, omsg, seqnum, omsglen); } -struct msg * -new_msg_delete_request (u_int32_t seqnum, - struct in_addr area_id, u_char lsa_type, - u_char opaque_type, u_int32_t opaque_id) +struct msg *new_msg_delete_request(u_int32_t seqnum, struct in_addr area_id, + u_char lsa_type, u_char opaque_type, + u_int32_t opaque_id) { - struct msg_delete_request dmsg; - dmsg.area_id = area_id; - dmsg.lsa_type = lsa_type; - dmsg.opaque_type = opaque_type; - dmsg.opaque_id = htonl (opaque_id); - memset (&dmsg.pad, 0, sizeof (dmsg.pad)); - - return msg_new (MSG_DELETE_REQUEST, &dmsg, seqnum, - sizeof (struct msg_delete_request)); + struct msg_delete_request dmsg; + dmsg.area_id = area_id; + dmsg.lsa_type = lsa_type; + dmsg.opaque_type = opaque_type; + dmsg.opaque_id = htonl(opaque_id); + memset(&dmsg.pad, 0, sizeof(dmsg.pad)); + + return msg_new(MSG_DELETE_REQUEST, &dmsg, seqnum, + sizeof(struct msg_delete_request)); } -struct msg * -new_msg_reply (u_int32_t seqnr, u_char rc) +struct msg *new_msg_reply(u_int32_t seqnr, u_char rc) { - struct msg *msg; - struct msg_reply rmsg; + struct msg *msg; + struct msg_reply rmsg; - /* Set return code */ - rmsg.errcode = rc; - memset (&rmsg.pad, 0, sizeof (rmsg.pad)); + /* Set return code */ + rmsg.errcode = rc; + memset(&rmsg.pad, 0, sizeof(rmsg.pad)); - msg = msg_new (MSG_REPLY, &rmsg, seqnr, sizeof (struct msg_reply)); + msg = msg_new(MSG_REPLY, &rmsg, seqnr, sizeof(struct msg_reply)); - return msg; + return msg; } -struct msg * -new_msg_ready_notify (u_int32_t seqnr, u_char lsa_type, - u_char opaque_type, struct in_addr addr) +struct msg *new_msg_ready_notify(u_int32_t seqnr, u_char lsa_type, + u_char opaque_type, struct in_addr addr) { - struct msg_ready_notify rmsg; + struct msg_ready_notify rmsg; - rmsg.lsa_type = lsa_type; - rmsg.opaque_type = opaque_type; - memset (&rmsg.pad, 0, sizeof (rmsg.pad)); - rmsg.addr = addr; + rmsg.lsa_type = lsa_type; + rmsg.opaque_type = opaque_type; + memset(&rmsg.pad, 0, sizeof(rmsg.pad)); + rmsg.addr = addr; - return msg_new (MSG_READY_NOTIFY, &rmsg, seqnr, - sizeof (struct msg_ready_notify)); + return msg_new(MSG_READY_NOTIFY, &rmsg, seqnr, + sizeof(struct msg_ready_notify)); } -struct msg * -new_msg_new_if (u_int32_t seqnr, - struct in_addr ifaddr, struct in_addr area_id) +struct msg *new_msg_new_if(u_int32_t seqnr, struct in_addr ifaddr, + struct in_addr area_id) { - struct msg_new_if nmsg; + struct msg_new_if nmsg; - nmsg.ifaddr = ifaddr; - nmsg.area_id = area_id; + nmsg.ifaddr = ifaddr; + nmsg.area_id = area_id; - return msg_new (MSG_NEW_IF, &nmsg, seqnr, sizeof (struct msg_new_if)); + return msg_new(MSG_NEW_IF, &nmsg, seqnr, sizeof(struct msg_new_if)); } -struct msg * -new_msg_del_if (u_int32_t seqnr, struct in_addr ifaddr) +struct msg *new_msg_del_if(u_int32_t seqnr, struct in_addr ifaddr) { - struct msg_del_if dmsg; + struct msg_del_if dmsg; - dmsg.ifaddr = ifaddr; + dmsg.ifaddr = ifaddr; - return msg_new (MSG_DEL_IF, &dmsg, seqnr, sizeof (struct msg_del_if)); + return msg_new(MSG_DEL_IF, &dmsg, seqnr, sizeof(struct msg_del_if)); } -struct msg * -new_msg_ism_change (u_int32_t seqnr, struct in_addr ifaddr, - struct in_addr area_id, u_char status) +struct msg *new_msg_ism_change(u_int32_t seqnr, struct in_addr ifaddr, + struct in_addr area_id, u_char status) { - struct msg_ism_change imsg; + struct msg_ism_change imsg; - imsg.ifaddr = ifaddr; - imsg.area_id = area_id; - imsg.status = status; - memset (&imsg.pad, 0, sizeof (imsg.pad)); + imsg.ifaddr = ifaddr; + imsg.area_id = area_id; + imsg.status = status; + memset(&imsg.pad, 0, sizeof(imsg.pad)); - return msg_new (MSG_ISM_CHANGE, &imsg, seqnr, - sizeof (struct msg_ism_change)); + return msg_new(MSG_ISM_CHANGE, &imsg, seqnr, + sizeof(struct msg_ism_change)); } -struct msg * -new_msg_nsm_change (u_int32_t seqnr, struct in_addr ifaddr, - struct in_addr nbraddr, - struct in_addr router_id, u_char status) +struct msg *new_msg_nsm_change(u_int32_t seqnr, struct in_addr ifaddr, + struct in_addr nbraddr, struct in_addr router_id, + u_char status) { - struct msg_nsm_change nmsg; + struct msg_nsm_change nmsg; - nmsg.ifaddr = ifaddr; - nmsg.nbraddr = nbraddr; - nmsg.router_id = router_id; - nmsg.status = status; - memset (&nmsg.pad, 0, sizeof (nmsg.pad)); + nmsg.ifaddr = ifaddr; + nmsg.nbraddr = nbraddr; + nmsg.router_id = router_id; + nmsg.status = status; + memset(&nmsg.pad, 0, sizeof(nmsg.pad)); - return msg_new (MSG_NSM_CHANGE, &nmsg, seqnr, - sizeof (struct msg_nsm_change)); + return msg_new(MSG_NSM_CHANGE, &nmsg, seqnr, + sizeof(struct msg_nsm_change)); } -struct msg * -new_msg_lsa_change_notify (u_char msgtype, - u_int32_t seqnum, - struct in_addr ifaddr, - struct in_addr area_id, - u_char is_self_originated, struct lsa_header *data) +struct msg *new_msg_lsa_change_notify(u_char msgtype, u_int32_t seqnum, + struct in_addr ifaddr, + struct in_addr area_id, + u_char is_self_originated, + struct lsa_header *data) { - u_char buf[OSPF_API_MAX_MSG_SIZE]; - struct msg_lsa_change_notify *nmsg; - unsigned int len; - - assert (data); - - nmsg = (struct msg_lsa_change_notify *) buf; - nmsg->ifaddr = ifaddr; - nmsg->area_id = area_id; - nmsg->is_self_originated = is_self_originated; - memset (&nmsg->pad, 0, sizeof (nmsg->pad)); - - len = ntohs (data->length); - if (len > sizeof (buf) - offsetof (struct msg_lsa_change_notify, data)) - len = sizeof (buf) - offsetof (struct msg_lsa_change_notify, data); - memcpy (&nmsg->data, data, len); - len += sizeof (struct msg_lsa_change_notify) - sizeof (struct lsa_header); - - return msg_new (msgtype, nmsg, seqnum, len); + u_char buf[OSPF_API_MAX_MSG_SIZE]; + struct msg_lsa_change_notify *nmsg; + unsigned int len; + + assert(data); + + nmsg = (struct msg_lsa_change_notify *)buf; + nmsg->ifaddr = ifaddr; + nmsg->area_id = area_id; + nmsg->is_self_originated = is_self_originated; + memset(&nmsg->pad, 0, sizeof(nmsg->pad)); + + len = ntohs(data->length); + if (len > sizeof(buf) - offsetof(struct msg_lsa_change_notify, data)) + len = sizeof(buf) + - offsetof(struct msg_lsa_change_notify, data); + memcpy(&nmsg->data, data, len); + len += sizeof(struct msg_lsa_change_notify) - sizeof(struct lsa_header); + + return msg_new(msgtype, nmsg, seqnum, len); } #endif /* SUPPORT_OSPF_API */ diff --git a/ospfd/ospf_api.h b/ospfd/ospf_api.h index ee18c8934..526e8228f 100644 --- a/ospfd/ospf_api.h +++ b/ospfd/ospf_api.h @@ -37,40 +37,38 @@ #define OSPF_API_SYNC_PORT 2607 /* ----------------------------------------------------------- - * Generic messages + * Generic messages * ----------------------------------------------------------- */ /* Message header structure, fields are in network byte order and aligned to four octets. */ -struct apimsghdr -{ - u_char version; /* OSPF API protocol version */ - u_char msgtype; /* Type of message */ - u_int16_t msglen; /* Length of message w/o header */ - u_int32_t msgseq; /* Sequence number */ +struct apimsghdr { + u_char version; /* OSPF API protocol version */ + u_char msgtype; /* Type of message */ + u_int16_t msglen; /* Length of message w/o header */ + u_int32_t msgseq; /* Sequence number */ }; /* Message representation with header and body */ -struct msg -{ - struct msg *next; /* to link into fifo */ +struct msg { + struct msg *next; /* to link into fifo */ - /* Message header */ - struct apimsghdr hdr; + /* Message header */ + struct apimsghdr hdr; - /* Message body */ - struct stream *s; + /* Message body */ + struct stream *s; }; /* Prototypes for generic messages. */ -extern struct msg *msg_new (u_char msgtype, void *msgbody, - u_int32_t seqnum, u_int16_t msglen); -extern struct msg *msg_dup (struct msg *msg); -extern void msg_print (struct msg *msg); /* XXX debug only */ -extern void msg_free (struct msg *msg); -struct msg *msg_read (int fd); -extern int msg_write (int fd, struct msg *msg); +extern struct msg *msg_new(u_char msgtype, void *msgbody, u_int32_t seqnum, + u_int16_t msglen); +extern struct msg *msg_dup(struct msg *msg); +extern void msg_print(struct msg *msg); /* XXX debug only */ +extern void msg_free(struct msg *msg); +struct msg *msg_read(int fd); +extern int msg_write(int fd, struct msg *msg); /* For requests, the message sequence number is between MIN_SEQ and MAX_SEQ. For notifications, the sequence number is 0. */ @@ -78,8 +76,8 @@ extern int msg_write (int fd, struct msg *msg); #define MIN_SEQ 1 #define MAX_SEQ 2147483647 -extern void msg_set_seq (struct msg *msg, u_int32_t seqnr); -extern u_int32_t msg_get_seq (struct msg *msg); +extern void msg_set_seq(struct msg *msg, u_int32_t seqnr); +extern u_int32_t msg_get_seq(struct msg *msg); /* ----------------------------------------------------------- * Message fifo queues @@ -87,21 +85,20 @@ extern u_int32_t msg_get_seq (struct msg *msg); */ /* Message queue structure. */ -struct msg_fifo -{ - unsigned long count; +struct msg_fifo { + unsigned long count; - struct msg *head; - struct msg *tail; + struct msg *head; + struct msg *tail; }; /* Prototype for message fifo queues. */ -extern struct msg_fifo *msg_fifo_new (void); -extern void msg_fifo_push (struct msg_fifo *, struct msg *msg); -extern struct msg *msg_fifo_pop (struct msg_fifo *fifo); -extern struct msg *msg_fifo_head (struct msg_fifo *fifo); -extern void msg_fifo_flush (struct msg_fifo *fifo); -extern void msg_fifo_free (struct msg_fifo *fifo); +extern struct msg_fifo *msg_fifo_new(void); +extern void msg_fifo_push(struct msg_fifo *, struct msg *msg); +extern struct msg *msg_fifo_pop(struct msg_fifo *fifo); +extern struct msg *msg_fifo_head(struct msg_fifo *fifo); +extern void msg_fifo_flush(struct msg_fifo *fifo); +extern void msg_fifo_free(struct msg_fifo *fifo); /* ----------------------------------------------------------- * Specific message type and format definitions @@ -126,18 +123,16 @@ extern void msg_fifo_free (struct msg_fifo *fifo); #define MSG_ISM_CHANGE 16 #define MSG_NSM_CHANGE 17 -struct msg_register_opaque_type -{ - u_char lsatype; - u_char opaquetype; - u_char pad[2]; /* padding */ +struct msg_register_opaque_type { + u_char lsatype; + u_char opaquetype; + u_char pad[2]; /* padding */ }; -struct msg_unregister_opaque_type -{ - u_char lsatype; - u_char opaquetype; - u_char pad[2]; /* padding */ +struct msg_unregister_opaque_type { + u_char lsatype; + u_char opaquetype; + u_char pad[2]; /* padding */ }; /* Power2 is needed to convert LSA types into bit positions, @@ -146,65 +141,58 @@ struct msg_unregister_opaque_type #ifdef ORIGINAL_CODING -static const u_int16_t - Power2[] = { 0x0, 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, - 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000 -}; +static const u_int16_t Power2[] = {0x0, 0x1, 0x2, 0x4, 0x8, 0x10, + 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, + 0x800, 0x1000, 0x2000, 0x4000, 0x8000}; #else -static const u_int16_t - Power2[] = { 0, (1 << 0), (1 << 1), (1 << 2), (1 << 3), (1 << 4), - (1 << 5), (1 << 6), (1 << 7), (1 << 8), (1 << 9), - (1 << 10), (1 << 11), (1 << 12), (1 << 13), (1 << 14), - (1 << 15) -}; +static const u_int16_t Power2[] = { + 0, (1 << 0), (1 << 1), (1 << 2), (1 << 3), (1 << 4), + (1 << 5), (1 << 6), (1 << 7), (1 << 8), (1 << 9), (1 << 10), + (1 << 11), (1 << 12), (1 << 13), (1 << 14), (1 << 15)}; #endif /* ORIGINAL_CODING */ -struct lsa_filter_type -{ - u_int16_t typemask; /* bitmask for selecting LSA types (1..16) */ - u_char origin; /* selects according to origin. */ +struct lsa_filter_type { + u_int16_t typemask; /* bitmask for selecting LSA types (1..16) */ + u_char origin; /* selects according to origin. */ + /* $FRR indent$ */ + /* clang-format off */ #define NON_SELF_ORIGINATED 0 #define SELF_ORIGINATED (OSPF_LSA_SELF) #define ANY_ORIGIN 2 - u_char num_areas; /* number of areas in the filter. */ - /* areas, if any, go here. */ + u_char num_areas; /* number of areas in the filter. */ + /* areas, if any, go here. */ }; -struct msg_register_event -{ - struct lsa_filter_type filter; +struct msg_register_event { + struct lsa_filter_type filter; }; -struct msg_sync_lsdb -{ - struct lsa_filter_type filter; +struct msg_sync_lsdb { + struct lsa_filter_type filter; }; -struct msg_originate_request -{ - /* Used for LSA type 9 otherwise ignored */ - struct in_addr ifaddr; +struct msg_originate_request { + /* Used for LSA type 9 otherwise ignored */ + struct in_addr ifaddr; - /* Used for LSA type 10 otherwise ignored */ - struct in_addr area_id; + /* Used for LSA type 10 otherwise ignored */ + struct in_addr area_id; - /* LSA header and LSA-specific part */ - struct lsa_header data; + /* LSA header and LSA-specific part */ + struct lsa_header data; }; -struct msg_delete_request -{ - struct in_addr area_id; /* "0.0.0.0" for AS-external opaque LSAs */ - u_char lsa_type; - u_char opaque_type; - u_char pad[2]; /* padding */ - u_int32_t opaque_id; +struct msg_delete_request { + struct in_addr area_id; /* "0.0.0.0" for AS-external opaque LSAs */ + u_char lsa_type; + u_char opaque_type; + u_char pad[2]; /* padding */ + u_int32_t opaque_id; }; -struct msg_reply -{ - signed char errcode; +struct msg_reply { + signed char errcode; #define OSPF_API_OK 0 #define OSPF_API_NOSUCHINTERFACE (-1) #define OSPF_API_NOSUCHAREA (-2) @@ -216,85 +204,76 @@ struct msg_reply #define OSPF_API_NOMEMORY (-8) #define OSPF_API_ERROR (-9) #define OSPF_API_UNDEF (-10) - u_char pad[3]; /* padding to four byte alignment */ + u_char pad[3]; /* padding to four byte alignment */ }; -/* Message to tell client application that it ospf daemon is +/* Message to tell client application that it ospf daemon is * ready to accept opaque LSAs for a given interface or area. */ -struct msg_ready_notify -{ - u_char lsa_type; - u_char opaque_type; - u_char pad[2]; /* padding */ - struct in_addr addr; /* interface address or area address */ +struct msg_ready_notify { + u_char lsa_type; + u_char opaque_type; + u_char pad[2]; /* padding */ + struct in_addr addr; /* interface address or area address */ }; /* These messages have a dynamic length depending on the embodied LSA. They are aligned to four octets. msg_lsa_change_notify is used for both LSA update and LSAs delete. */ -struct msg_lsa_change_notify -{ - /* Used for LSA type 9 otherwise ignored */ - struct in_addr ifaddr; - /* Area ID. Not valid for AS-External and Opaque11 LSAs. */ - struct in_addr area_id; - u_char is_self_originated; /* 1 if self originated. */ - u_char pad[3]; - struct lsa_header data; +struct msg_lsa_change_notify { + /* Used for LSA type 9 otherwise ignored */ + struct in_addr ifaddr; + /* Area ID. Not valid for AS-External and Opaque11 LSAs. */ + struct in_addr area_id; + u_char is_self_originated; /* 1 if self originated. */ + u_char pad[3]; + struct lsa_header data; }; -struct msg_new_if -{ - struct in_addr ifaddr; /* interface IP address */ - struct in_addr area_id; /* area this interface belongs to */ +struct msg_new_if { + struct in_addr ifaddr; /* interface IP address */ + struct in_addr area_id; /* area this interface belongs to */ }; -struct msg_del_if -{ - struct in_addr ifaddr; /* interface IP address */ +struct msg_del_if { + struct in_addr ifaddr; /* interface IP address */ }; -struct msg_ism_change -{ - struct in_addr ifaddr; /* interface IP address */ - struct in_addr area_id; /* area this interface belongs to */ - u_char status; /* interface status (up/down) */ - u_char pad[3]; /* not used */ +struct msg_ism_change { + struct in_addr ifaddr; /* interface IP address */ + struct in_addr area_id; /* area this interface belongs to */ + u_char status; /* interface status (up/down) */ + u_char pad[3]; /* not used */ }; -struct msg_nsm_change -{ - struct in_addr ifaddr; /* attached interface */ - struct in_addr nbraddr; /* Neighbor interface address */ - struct in_addr router_id; /* Router ID of neighbor */ - u_char status; /* NSM status */ - u_char pad[3]; +struct msg_nsm_change { + struct in_addr ifaddr; /* attached interface */ + struct in_addr nbraddr; /* Neighbor interface address */ + struct in_addr router_id; /* Router ID of neighbor */ + u_char status; /* NSM status */ + u_char pad[3]; }; /* We make use of a union to define a structure that covers all possible API messages. This allows us to find out how much memory needs to be reserved for the largest API message. */ -struct apimsg -{ - struct apimsghdr hdr; - union - { - struct msg_register_opaque_type register_opaque_type; - struct msg_register_event register_event; - struct msg_sync_lsdb sync_lsdb; - struct msg_originate_request originate_request; - struct msg_delete_request delete_request; - struct msg_reply reply; - struct msg_ready_notify ready_notify; - struct msg_new_if new_if; - struct msg_del_if del_if; - struct msg_ism_change ism_change; - struct msg_nsm_change nsm_change; - struct msg_lsa_change_notify lsa_change_notify; - } - u; +struct apimsg { + struct apimsghdr hdr; + union { + struct msg_register_opaque_type register_opaque_type; + struct msg_register_event register_event; + struct msg_sync_lsdb sync_lsdb; + struct msg_originate_request originate_request; + struct msg_delete_request delete_request; + struct msg_reply reply; + struct msg_ready_notify ready_notify; + struct msg_new_if new_if; + struct msg_del_if del_if; + struct msg_ism_change ism_change; + struct msg_nsm_change nsm_change; + struct msg_lsa_change_notify lsa_change_notify; + } u; }; #define OSPF_API_MAX_MSG_SIZE (sizeof(struct apimsg) + OSPF_MAX_LSA_SIZE) @@ -305,56 +284,52 @@ struct apimsg */ /* For debugging only. */ -extern void api_opaque_lsa_print (struct lsa_header *data); +extern void api_opaque_lsa_print(struct lsa_header *data); /* Messages sent by client */ -extern struct msg *new_msg_register_opaque_type (u_int32_t seqnum, - u_char ltype, u_char otype); -extern struct msg *new_msg_register_event (u_int32_t seqnum, - struct lsa_filter_type *filter); -extern struct msg *new_msg_sync_lsdb (u_int32_t seqnum, - struct lsa_filter_type *filter); -extern struct msg *new_msg_originate_request (u_int32_t seqnum, - struct in_addr ifaddr, - struct in_addr area_id, - struct lsa_header *data); -extern struct msg *new_msg_delete_request (u_int32_t seqnum, - struct in_addr area_id, - u_char lsa_type, - u_char opaque_type, - u_int32_t opaque_id); +extern struct msg *new_msg_register_opaque_type(u_int32_t seqnum, u_char ltype, + u_char otype); +extern struct msg *new_msg_register_event(u_int32_t seqnum, + struct lsa_filter_type *filter); +extern struct msg *new_msg_sync_lsdb(u_int32_t seqnum, + struct lsa_filter_type *filter); +extern struct msg *new_msg_originate_request(u_int32_t seqnum, + struct in_addr ifaddr, + struct in_addr area_id, + struct lsa_header *data); +extern struct msg *new_msg_delete_request(u_int32_t seqnum, + struct in_addr area_id, + u_char lsa_type, u_char opaque_type, + u_int32_t opaque_id); /* Messages sent by OSPF daemon */ -extern struct msg *new_msg_reply (u_int32_t seqnum, u_char rc); +extern struct msg *new_msg_reply(u_int32_t seqnum, u_char rc); -extern struct msg *new_msg_ready_notify (u_int32_t seqnr, u_char lsa_type, - u_char opaque_type, - struct in_addr addr); +extern struct msg *new_msg_ready_notify(u_int32_t seqnr, u_char lsa_type, + u_char opaque_type, + struct in_addr addr); -extern struct msg *new_msg_new_if (u_int32_t seqnr, - struct in_addr ifaddr, - struct in_addr area); +extern struct msg *new_msg_new_if(u_int32_t seqnr, struct in_addr ifaddr, + struct in_addr area); -extern struct msg *new_msg_del_if (u_int32_t seqnr, struct in_addr ifaddr); +extern struct msg *new_msg_del_if(u_int32_t seqnr, struct in_addr ifaddr); -extern struct msg *new_msg_ism_change (u_int32_t seqnr, struct in_addr ifaddr, - struct in_addr area, u_char status); +extern struct msg *new_msg_ism_change(u_int32_t seqnr, struct in_addr ifaddr, + struct in_addr area, u_char status); -extern struct msg *new_msg_nsm_change (u_int32_t seqnr, struct in_addr ifaddr, - struct in_addr nbraddr, - struct in_addr router_id, - u_char status); +extern struct msg *new_msg_nsm_change(u_int32_t seqnr, struct in_addr ifaddr, + struct in_addr nbraddr, + struct in_addr router_id, u_char status); /* msgtype is MSG_LSA_UPDATE_NOTIFY or MSG_LSA_DELETE_NOTIFY */ -extern struct msg *new_msg_lsa_change_notify (u_char msgtype, - u_int32_t seqnum, - struct in_addr ifaddr, - struct in_addr area_id, - u_char is_self_originated, - struct lsa_header *data); +extern struct msg *new_msg_lsa_change_notify(u_char msgtype, u_int32_t seqnum, + struct in_addr ifaddr, + struct in_addr area_id, + u_char is_self_originated, + struct lsa_header *data); /* string printing functions */ -extern const char *ospf_api_errname (int errcode); -extern const char *ospf_api_typename (int msgtype); +extern const char *ospf_api_errname(int errcode); +extern const char *ospf_api_typename(int msgtype); #endif /* _OSPF_API_H */ diff --git a/ospfd/ospf_apiserver.c b/ospfd/ospf_apiserver.c index 2b72abcd7..a5f5971ac 100644 --- a/ospfd/ospf_apiserver.c +++ b/ospfd/ospf_apiserver.c @@ -34,12 +34,12 @@ #include "log.h" #include "thread.h" #include "hash.h" -#include "sockunion.h" /* for inet_aton() */ +#include "sockunion.h" /* for inet_aton() */ #include "buffer.h" #include <sys/types.h> -#include "ospfd/ospfd.h" /* for "struct thread_master" */ +#include "ospfd/ospfd.h" /* for "struct thread_master" */ #include "ospfd/ospf_interface.h" #include "ospfd/ospf_ism.h" #include "ospfd/ospf_asbr.h" @@ -76,39 +76,37 @@ struct list *apiserver_list; * ----------------------------------------------------------- */ -struct ospf_interface * -ospf_apiserver_if_lookup_by_addr (struct in_addr address) +struct ospf_interface *ospf_apiserver_if_lookup_by_addr(struct in_addr address) { - struct listnode *node, *nnode; - struct ospf_interface *oi; - struct ospf *ospf; + struct listnode *node, *nnode; + struct ospf_interface *oi; + struct ospf *ospf; - if (!(ospf = ospf_lookup ())) - return NULL; + if (!(ospf = ospf_lookup())) + return NULL; - for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) - if (oi->type != OSPF_IFTYPE_VIRTUALLINK) - if (IPV4_ADDR_SAME (&address, &oi->address->u.prefix4)) - return oi; + for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) + if (oi->type != OSPF_IFTYPE_VIRTUALLINK) + if (IPV4_ADDR_SAME(&address, &oi->address->u.prefix4)) + return oi; - return NULL; + return NULL; } -struct ospf_interface * -ospf_apiserver_if_lookup_by_ifp (struct interface *ifp) +struct ospf_interface *ospf_apiserver_if_lookup_by_ifp(struct interface *ifp) { - struct listnode *node, *nnode; - struct ospf_interface *oi; - struct ospf *ospf; + struct listnode *node, *nnode; + struct ospf_interface *oi; + struct ospf *ospf; - if (!(ospf = ospf_lookup ())) - return NULL; + if (!(ospf = ospf_lookup())) + return NULL; - for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) - if (oi->ifp == ifp) - return oi; + for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) + if (oi->ifp == ifp) + return oi; - return NULL; + return NULL; } /* ----------------------------------------------------------- @@ -116,644 +114,604 @@ ospf_apiserver_if_lookup_by_ifp (struct interface *ifp) * ----------------------------------------------------------- */ -unsigned short -ospf_apiserver_getport (void) +unsigned short ospf_apiserver_getport(void) { - struct servent *sp = getservbyname ("ospfapi", "tcp"); + struct servent *sp = getservbyname("ospfapi", "tcp"); - return sp ? ntohs (sp->s_port) : OSPF_API_SYNC_PORT; + return sp ? ntohs(sp->s_port) : OSPF_API_SYNC_PORT; } /* Initialize OSPF API module. Invoked from ospf_opaque_init() */ -int -ospf_apiserver_init (void) +int ospf_apiserver_init(void) { - int fd; - int rc = -1; - - /* Create new socket for synchronous messages. */ - fd = ospf_apiserver_serv_sock_family (ospf_apiserver_getport (), AF_INET); - - if (fd < 0) - goto out; - - /* Schedule new thread that handles accepted connections. */ - ospf_apiserver_event (OSPF_APISERVER_ACCEPT, fd, NULL); - - /* Initialize list that keeps track of all connections. */ - apiserver_list = list_new (); - - /* Register opaque-independent call back functions. These functions - are invoked on ISM, NSM changes and LSA update and LSA deletes */ - rc = - ospf_register_opaque_functab (0 /* all LSAs */, - 0 /* all opaque types */, - ospf_apiserver_new_if, - ospf_apiserver_del_if, - ospf_apiserver_ism_change, - ospf_apiserver_nsm_change, - NULL, - NULL, - NULL, - NULL, /* ospf_apiserver_show_info */ - NULL, /* originator_func */ - NULL, /* ospf_apiserver_lsa_refresher */ - ospf_apiserver_lsa_update, - ospf_apiserver_lsa_delete); - if (rc != 0) - { - zlog_warn ("ospf_apiserver_init: Failed to register opaque type [0/0]"); - } - - rc = 0; + int fd; + int rc = -1; + + /* Create new socket for synchronous messages. */ + fd = ospf_apiserver_serv_sock_family(ospf_apiserver_getport(), AF_INET); + + if (fd < 0) + goto out; + + /* Schedule new thread that handles accepted connections. */ + ospf_apiserver_event(OSPF_APISERVER_ACCEPT, fd, NULL); + + /* Initialize list that keeps track of all connections. */ + apiserver_list = list_new(); + + /* Register opaque-independent call back functions. These functions + are invoked on ISM, NSM changes and LSA update and LSA deletes */ + rc = ospf_register_opaque_functab( + 0 /* all LSAs */, 0 /* all opaque types */, + ospf_apiserver_new_if, ospf_apiserver_del_if, + ospf_apiserver_ism_change, ospf_apiserver_nsm_change, NULL, + NULL, NULL, NULL, /* ospf_apiserver_show_info */ + NULL, /* originator_func */ + NULL, /* ospf_apiserver_lsa_refresher */ + ospf_apiserver_lsa_update, ospf_apiserver_lsa_delete); + if (rc != 0) { + zlog_warn( + "ospf_apiserver_init: Failed to register opaque type [0/0]"); + } + + rc = 0; out: - return rc; + return rc; } /* Terminate OSPF API module. */ -void -ospf_apiserver_term (void) +void ospf_apiserver_term(void) { - struct ospf_apiserver *apiserv; - - /* Unregister wildcard [0/0] type */ - ospf_delete_opaque_functab (0 /* all LSAs */, - 0 /* all opaque types */); - - /* - * Free all client instances. ospf_apiserver_free removes the node - * from the list, so we examine the head of the list anew each time. - */ - while ( apiserver_list && - (apiserv = listgetdata (listhead (apiserver_list))) != NULL) - ospf_apiserver_free (apiserv); - - /* Free client list itself */ - if (apiserver_list) - list_delete (apiserver_list); - - /* Free wildcard list */ - /* XXX */ + struct ospf_apiserver *apiserv; + + /* Unregister wildcard [0/0] type */ + ospf_delete_opaque_functab(0 /* all LSAs */, 0 /* all opaque types */); + + /* + * Free all client instances. ospf_apiserver_free removes the node + * from the list, so we examine the head of the list anew each time. + */ + while (apiserver_list + && (apiserv = listgetdata(listhead(apiserver_list))) != NULL) + ospf_apiserver_free(apiserv); + + /* Free client list itself */ + if (apiserver_list) + list_delete(apiserver_list); + + /* Free wildcard list */ + /* XXX */ } -static struct ospf_apiserver * -lookup_apiserver (u_char lsa_type, u_char opaque_type) +static struct ospf_apiserver *lookup_apiserver(u_char lsa_type, + u_char opaque_type) { - struct listnode *n1, *n2; - struct registered_opaque_type *r; - struct ospf_apiserver *apiserv, *found = NULL; - - /* XXX: this approaches O(n**2) */ - for (ALL_LIST_ELEMENTS_RO (apiserver_list, n1, apiserv)) - { - for (ALL_LIST_ELEMENTS_RO (apiserv->opaque_types, n2, r)) - if (r->lsa_type == lsa_type && r->opaque_type == opaque_type) - { - found = apiserv; - goto out; - } - } + struct listnode *n1, *n2; + struct registered_opaque_type *r; + struct ospf_apiserver *apiserv, *found = NULL; + + /* XXX: this approaches O(n**2) */ + for (ALL_LIST_ELEMENTS_RO(apiserver_list, n1, apiserv)) { + for (ALL_LIST_ELEMENTS_RO(apiserv->opaque_types, n2, r)) + if (r->lsa_type == lsa_type + && r->opaque_type == opaque_type) { + found = apiserv; + goto out; + } + } out: - return found; + return found; } -static struct ospf_apiserver * -lookup_apiserver_by_lsa (struct ospf_lsa *lsa) +static struct ospf_apiserver *lookup_apiserver_by_lsa(struct ospf_lsa *lsa) { - struct lsa_header *lsah = lsa->data; - struct ospf_apiserver *found = NULL; - - if (IS_OPAQUE_LSA (lsah->type)) - { - found = lookup_apiserver (lsah->type, - GET_OPAQUE_TYPE (ntohl (lsah->id.s_addr))); - } - return found; + struct lsa_header *lsah = lsa->data; + struct ospf_apiserver *found = NULL; + + if (IS_OPAQUE_LSA(lsah->type)) { + found = lookup_apiserver( + lsah->type, GET_OPAQUE_TYPE(ntohl(lsah->id.s_addr))); + } + return found; } /* ----------------------------------------------------------- * Followings are functions to manage client connections. * ----------------------------------------------------------- */ -static int -ospf_apiserver_new_lsa_hook (struct ospf_lsa *lsa) +static int ospf_apiserver_new_lsa_hook(struct ospf_lsa *lsa) { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("API: Put LSA(%p)[%s] into reserve, total=%ld", (void *)lsa, - dump_lsa_key (lsa), lsa->lsdb->total); - return 0; + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("API: Put LSA(%p)[%s] into reserve, total=%ld", + (void *)lsa, dump_lsa_key(lsa), lsa->lsdb->total); + return 0; } -static int -ospf_apiserver_del_lsa_hook (struct ospf_lsa *lsa) +static int ospf_apiserver_del_lsa_hook(struct ospf_lsa *lsa) { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("API: Get LSA(%p)[%s] from reserve, total=%ld", (void *)lsa, - dump_lsa_key (lsa), lsa->lsdb->total); - return 0; + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("API: Get LSA(%p)[%s] from reserve, total=%ld", + (void *)lsa, dump_lsa_key(lsa), lsa->lsdb->total); + return 0; } /* Allocate new connection structure. */ -struct ospf_apiserver * -ospf_apiserver_new (int fd_sync, int fd_async) +struct ospf_apiserver *ospf_apiserver_new(int fd_sync, int fd_async) { - struct ospf_apiserver *new = - XMALLOC (MTYPE_OSPF_APISERVER, sizeof (struct ospf_apiserver)); + struct ospf_apiserver *new = + XMALLOC(MTYPE_OSPF_APISERVER, sizeof(struct ospf_apiserver)); - new->filter = - XMALLOC (MTYPE_OSPF_APISERVER_MSGFILTER, sizeof (struct lsa_filter_type)); + new->filter = XMALLOC(MTYPE_OSPF_APISERVER_MSGFILTER, + sizeof(struct lsa_filter_type)); - new->fd_sync = fd_sync; - new->fd_async = fd_async; + new->fd_sync = fd_sync; + new->fd_async = fd_async; - /* list of registered opaque types that application uses */ - new->opaque_types = list_new (); + /* list of registered opaque types that application uses */ + new->opaque_types = list_new(); - /* Initialize temporary strage for LSA instances to be refreshed. */ - memset (&new->reserve, 0, sizeof (struct ospf_lsdb)); - ospf_lsdb_init (&new->reserve); + /* Initialize temporary strage for LSA instances to be refreshed. */ + memset(&new->reserve, 0, sizeof(struct ospf_lsdb)); + ospf_lsdb_init(&new->reserve); - new->reserve.new_lsa_hook = ospf_apiserver_new_lsa_hook; /* debug */ - new->reserve.del_lsa_hook = ospf_apiserver_del_lsa_hook; /* debug */ + new->reserve.new_lsa_hook = ospf_apiserver_new_lsa_hook; /* debug */ + new->reserve.del_lsa_hook = ospf_apiserver_del_lsa_hook; /* debug */ - new->out_sync_fifo = msg_fifo_new (); - new->out_async_fifo = msg_fifo_new (); - new->t_sync_read = NULL; + new->out_sync_fifo = msg_fifo_new(); + new->out_async_fifo = msg_fifo_new(); + new->t_sync_read = NULL; #ifdef USE_ASYNC_READ - new->t_async_read = NULL; + new->t_async_read = NULL; #endif /* USE_ASYNC_READ */ - new->t_sync_write = NULL; - new->t_async_write = NULL; + new->t_sync_write = NULL; + new->t_async_write = NULL; - new->filter->typemask = 0; /* filter all LSAs */ - new->filter->origin = ANY_ORIGIN; - new->filter->num_areas = 0; + new->filter->typemask = 0; /* filter all LSAs */ + new->filter->origin = ANY_ORIGIN; + new->filter->num_areas = 0; - return new; + return new; } -void -ospf_apiserver_event (enum event event, int fd, - struct ospf_apiserver *apiserv) +void ospf_apiserver_event(enum event event, int fd, + struct ospf_apiserver *apiserv) { - switch (event) - { - case OSPF_APISERVER_ACCEPT: - (void) thread_add_read(master, ospf_apiserver_accept, apiserv, fd, NULL); - break; - case OSPF_APISERVER_SYNC_READ: - apiserv->t_sync_read = NULL; - thread_add_read(master, ospf_apiserver_read, apiserv, fd, - &apiserv->t_sync_read); - break; + switch (event) { + case OSPF_APISERVER_ACCEPT: + (void)thread_add_read(master, ospf_apiserver_accept, apiserv, + fd, NULL); + break; + case OSPF_APISERVER_SYNC_READ: + apiserv->t_sync_read = NULL; + thread_add_read(master, ospf_apiserver_read, apiserv, fd, + &apiserv->t_sync_read); + break; #ifdef USE_ASYNC_READ - case OSPF_APISERVER_ASYNC_READ: - apiserv->t_async_read = NULL; - thread_add_read(master, ospf_apiserver_read, apiserv, fd, - &apiserv->t_async_read); - break; + case OSPF_APISERVER_ASYNC_READ: + apiserv->t_async_read = NULL; + thread_add_read(master, ospf_apiserver_read, apiserv, fd, + &apiserv->t_async_read); + break; #endif /* USE_ASYNC_READ */ - case OSPF_APISERVER_SYNC_WRITE: - thread_add_write(master, ospf_apiserver_sync_write, apiserv, fd, - &apiserv->t_sync_write); - break; - case OSPF_APISERVER_ASYNC_WRITE: - thread_add_write(master, ospf_apiserver_async_write, apiserv, fd, - &apiserv->t_async_write); - break; - } + case OSPF_APISERVER_SYNC_WRITE: + thread_add_write(master, ospf_apiserver_sync_write, apiserv, fd, + &apiserv->t_sync_write); + break; + case OSPF_APISERVER_ASYNC_WRITE: + thread_add_write(master, ospf_apiserver_async_write, apiserv, + fd, &apiserv->t_async_write); + break; + } } /* Free instance. First unregister all opaque types used by - application, flush opaque LSAs injected by application + application, flush opaque LSAs injected by application from network and close connection. */ -void -ospf_apiserver_free (struct ospf_apiserver *apiserv) +void ospf_apiserver_free(struct ospf_apiserver *apiserv) { - struct listnode *node; + struct listnode *node; - /* Cancel read and write threads. */ - if (apiserv->t_sync_read) - { - thread_cancel (apiserv->t_sync_read); - } + /* Cancel read and write threads. */ + if (apiserv->t_sync_read) { + thread_cancel(apiserv->t_sync_read); + } #ifdef USE_ASYNC_READ - if (apiserv->t_async_read) - { - thread_cancel (apiserv->t_async_read); - } + if (apiserv->t_async_read) { + thread_cancel(apiserv->t_async_read); + } #endif /* USE_ASYNC_READ */ - if (apiserv->t_sync_write) - { - thread_cancel (apiserv->t_sync_write); - } - - if (apiserv->t_async_write) - { - thread_cancel (apiserv->t_async_write); - } + if (apiserv->t_sync_write) { + thread_cancel(apiserv->t_sync_write); + } - /* Unregister all opaque types that application registered - and flush opaque LSAs if still in LSDB. */ + if (apiserv->t_async_write) { + thread_cancel(apiserv->t_async_write); + } - while ((node = listhead (apiserv->opaque_types)) != NULL) - { - struct registered_opaque_type *regtype = listgetdata(node); + /* Unregister all opaque types that application registered + and flush opaque LSAs if still in LSDB. */ - ospf_apiserver_unregister_opaque_type (apiserv, regtype->lsa_type, - regtype->opaque_type); + while ((node = listhead(apiserv->opaque_types)) != NULL) { + struct registered_opaque_type *regtype = listgetdata(node); - } + ospf_apiserver_unregister_opaque_type( + apiserv, regtype->lsa_type, regtype->opaque_type); + } - /* Close connections to OSPFd. */ - if (apiserv->fd_sync > 0) - { - close (apiserv->fd_sync); - } + /* Close connections to OSPFd. */ + if (apiserv->fd_sync > 0) { + close(apiserv->fd_sync); + } - if (apiserv->fd_async > 0) - { - close (apiserv->fd_async); - } + if (apiserv->fd_async > 0) { + close(apiserv->fd_async); + } - /* Free fifos */ - msg_fifo_free (apiserv->out_sync_fifo); - msg_fifo_free (apiserv->out_async_fifo); + /* Free fifos */ + msg_fifo_free(apiserv->out_sync_fifo); + msg_fifo_free(apiserv->out_async_fifo); - /* Clear temporary strage for LSA instances to be refreshed. */ - ospf_lsdb_delete_all (&apiserv->reserve); - ospf_lsdb_cleanup (&apiserv->reserve); + /* Clear temporary strage for LSA instances to be refreshed. */ + ospf_lsdb_delete_all(&apiserv->reserve); + ospf_lsdb_cleanup(&apiserv->reserve); - /* Remove from the list of active clients. */ - listnode_delete (apiserver_list, apiserv); + /* Remove from the list of active clients. */ + listnode_delete(apiserver_list, apiserv); - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("API: Delete apiserv(%p), total#(%d)", - (void *)apiserv, apiserver_list->count); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("API: Delete apiserv(%p), total#(%d)", + (void *)apiserv, apiserver_list->count); - /* And free instance. */ - XFREE (MTYPE_OSPF_APISERVER, apiserv); + /* And free instance. */ + XFREE(MTYPE_OSPF_APISERVER, apiserv); } -int -ospf_apiserver_read (struct thread *thread) +int ospf_apiserver_read(struct thread *thread) { - struct ospf_apiserver *apiserv; - struct msg *msg; - int fd; - int rc = -1; - enum event event; - - apiserv = THREAD_ARG (thread); - fd = THREAD_FD (thread); - - if (fd == apiserv->fd_sync) - { - event = OSPF_APISERVER_SYNC_READ; - apiserv->t_sync_read = NULL; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("API: ospf_apiserver_read: Peer: %s/%u", - inet_ntoa (apiserv->peer_sync.sin_addr), - ntohs (apiserv->peer_sync.sin_port)); - } + struct ospf_apiserver *apiserv; + struct msg *msg; + int fd; + int rc = -1; + enum event event; + + apiserv = THREAD_ARG(thread); + fd = THREAD_FD(thread); + + if (fd == apiserv->fd_sync) { + event = OSPF_APISERVER_SYNC_READ; + apiserv->t_sync_read = NULL; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("API: ospf_apiserver_read: Peer: %s/%u", + inet_ntoa(apiserv->peer_sync.sin_addr), + ntohs(apiserv->peer_sync.sin_port)); + } #ifdef USE_ASYNC_READ - else if (fd == apiserv->fd_async) - { - event = OSPF_APISERVER_ASYNC_READ; - apiserv->t_async_read = NULL; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("API: ospf_apiserver_read: Peer: %s/%u", - inet_ntoa (apiserv->peer_async.sin_addr), - ntohs (apiserv->peer_async.sin_port)); - } + else if (fd == apiserv->fd_async) { + event = OSPF_APISERVER_ASYNC_READ; + apiserv->t_async_read = NULL; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("API: ospf_apiserver_read: Peer: %s/%u", + inet_ntoa(apiserv->peer_async.sin_addr), + ntohs(apiserv->peer_async.sin_port)); + } #endif /* USE_ASYNC_READ */ - else - { - zlog_warn ("ospf_apiserver_read: Unknown fd(%d)", fd); - ospf_apiserver_free (apiserv); - goto out; - } + else { + zlog_warn("ospf_apiserver_read: Unknown fd(%d)", fd); + ospf_apiserver_free(apiserv); + goto out; + } - /* Read message from fd. */ - msg = msg_read (fd); - if (msg == NULL) - { - zlog_warn - ("ospf_apiserver_read: read failed on fd=%d, closing connection", fd); + /* Read message from fd. */ + msg = msg_read(fd); + if (msg == NULL) { + zlog_warn( + "ospf_apiserver_read: read failed on fd=%d, closing connection", + fd); - /* Perform cleanup. */ - ospf_apiserver_free (apiserv); - goto out; - } + /* Perform cleanup. */ + ospf_apiserver_free(apiserv); + goto out; + } - if (IS_DEBUG_OSPF_EVENT) - msg_print (msg); + if (IS_DEBUG_OSPF_EVENT) + msg_print(msg); - /* Dispatch to corresponding message handler. */ - rc = ospf_apiserver_handle_msg (apiserv, msg); + /* Dispatch to corresponding message handler. */ + rc = ospf_apiserver_handle_msg(apiserv, msg); - /* Prepare for next message, add read thread. */ - ospf_apiserver_event (event, fd, apiserv); + /* Prepare for next message, add read thread. */ + ospf_apiserver_event(event, fd, apiserv); - msg_free (msg); + msg_free(msg); out: - return rc; + return rc; } -int -ospf_apiserver_sync_write (struct thread *thread) +int ospf_apiserver_sync_write(struct thread *thread) { - struct ospf_apiserver *apiserv; - struct msg *msg; - int fd; - int rc = -1; - - apiserv = THREAD_ARG (thread); - assert (apiserv); - fd = THREAD_FD (thread); - - apiserv->t_sync_write = NULL; - - /* Sanity check */ - if (fd != apiserv->fd_sync) - { - zlog_warn ("ospf_apiserver_sync_write: Unknown fd=%d", fd); - goto out; - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("API: ospf_apiserver_sync_write: Peer: %s/%u", - inet_ntoa (apiserv->peer_sync.sin_addr), - ntohs (apiserv->peer_sync.sin_port)); - - /* Check whether there is really a message in the fifo. */ - msg = msg_fifo_pop (apiserv->out_sync_fifo); - if (!msg) - { - zlog_warn ("API: ospf_apiserver_sync_write: No message in Sync-FIFO?"); - return 0; - } - - if (IS_DEBUG_OSPF_EVENT) - msg_print (msg); - - rc = msg_write (fd, msg); - - /* Once a message is dequeued, it should be freed anyway. */ - msg_free (msg); - - if (rc < 0) - { - zlog_warn - ("ospf_apiserver_sync_write: write failed on fd=%d", fd); - goto out; - } - - - /* If more messages are in sync message fifo, schedule write thread. */ - if (msg_fifo_head (apiserv->out_sync_fifo)) - { - ospf_apiserver_event (OSPF_APISERVER_SYNC_WRITE, apiserv->fd_sync, - apiserv); - } - - out: - - if (rc < 0) - { - /* Perform cleanup and disconnect with peer */ - ospf_apiserver_free (apiserv); - } - - return rc; + struct ospf_apiserver *apiserv; + struct msg *msg; + int fd; + int rc = -1; + + apiserv = THREAD_ARG(thread); + assert(apiserv); + fd = THREAD_FD(thread); + + apiserv->t_sync_write = NULL; + + /* Sanity check */ + if (fd != apiserv->fd_sync) { + zlog_warn("ospf_apiserver_sync_write: Unknown fd=%d", fd); + goto out; + } + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("API: ospf_apiserver_sync_write: Peer: %s/%u", + inet_ntoa(apiserv->peer_sync.sin_addr), + ntohs(apiserv->peer_sync.sin_port)); + + /* Check whether there is really a message in the fifo. */ + msg = msg_fifo_pop(apiserv->out_sync_fifo); + if (!msg) { + zlog_warn( + "API: ospf_apiserver_sync_write: No message in Sync-FIFO?"); + return 0; + } + + if (IS_DEBUG_OSPF_EVENT) + msg_print(msg); + + rc = msg_write(fd, msg); + + /* Once a message is dequeued, it should be freed anyway. */ + msg_free(msg); + + if (rc < 0) { + zlog_warn("ospf_apiserver_sync_write: write failed on fd=%d", + fd); + goto out; + } + + + /* If more messages are in sync message fifo, schedule write thread. */ + if (msg_fifo_head(apiserv->out_sync_fifo)) { + ospf_apiserver_event(OSPF_APISERVER_SYNC_WRITE, + apiserv->fd_sync, apiserv); + } + +out: + + if (rc < 0) { + /* Perform cleanup and disconnect with peer */ + ospf_apiserver_free(apiserv); + } + + return rc; } -int -ospf_apiserver_async_write (struct thread *thread) +int ospf_apiserver_async_write(struct thread *thread) { - struct ospf_apiserver *apiserv; - struct msg *msg; - int fd; - int rc = -1; - - apiserv = THREAD_ARG (thread); - assert (apiserv); - fd = THREAD_FD (thread); - - apiserv->t_async_write = NULL; - - /* Sanity check */ - if (fd != apiserv->fd_async) - { - zlog_warn ("ospf_apiserver_async_write: Unknown fd=%d", fd); - goto out; - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("API: ospf_apiserver_async_write: Peer: %s/%u", - inet_ntoa (apiserv->peer_async.sin_addr), - ntohs (apiserv->peer_async.sin_port)); - - /* Check whether there is really a message in the fifo. */ - msg = msg_fifo_pop (apiserv->out_async_fifo); - if (!msg) - { - zlog_warn ("API: ospf_apiserver_async_write: No message in Async-FIFO?"); - return 0; - } - - if (IS_DEBUG_OSPF_EVENT) - msg_print (msg); - - rc = msg_write (fd, msg); - - /* Once a message is dequeued, it should be freed anyway. */ - msg_free (msg); - - if (rc < 0) - { - zlog_warn - ("ospf_apiserver_async_write: write failed on fd=%d", fd); - goto out; - } - - - /* If more messages are in async message fifo, schedule write thread. */ - if (msg_fifo_head (apiserv->out_async_fifo)) - { - ospf_apiserver_event (OSPF_APISERVER_ASYNC_WRITE, apiserv->fd_async, - apiserv); - } - - out: - - if (rc < 0) - { - /* Perform cleanup and disconnect with peer */ - ospf_apiserver_free (apiserv); - } - - return rc; + struct ospf_apiserver *apiserv; + struct msg *msg; + int fd; + int rc = -1; + + apiserv = THREAD_ARG(thread); + assert(apiserv); + fd = THREAD_FD(thread); + + apiserv->t_async_write = NULL; + + /* Sanity check */ + if (fd != apiserv->fd_async) { + zlog_warn("ospf_apiserver_async_write: Unknown fd=%d", fd); + goto out; + } + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("API: ospf_apiserver_async_write: Peer: %s/%u", + inet_ntoa(apiserv->peer_async.sin_addr), + ntohs(apiserv->peer_async.sin_port)); + + /* Check whether there is really a message in the fifo. */ + msg = msg_fifo_pop(apiserv->out_async_fifo); + if (!msg) { + zlog_warn( + "API: ospf_apiserver_async_write: No message in Async-FIFO?"); + return 0; + } + + if (IS_DEBUG_OSPF_EVENT) + msg_print(msg); + + rc = msg_write(fd, msg); + + /* Once a message is dequeued, it should be freed anyway. */ + msg_free(msg); + + if (rc < 0) { + zlog_warn("ospf_apiserver_async_write: write failed on fd=%d", + fd); + goto out; + } + + + /* If more messages are in async message fifo, schedule write thread. */ + if (msg_fifo_head(apiserv->out_async_fifo)) { + ospf_apiserver_event(OSPF_APISERVER_ASYNC_WRITE, + apiserv->fd_async, apiserv); + } + +out: + + if (rc < 0) { + /* Perform cleanup and disconnect with peer */ + ospf_apiserver_free(apiserv); + } + + return rc; } -int -ospf_apiserver_serv_sock_family (unsigned short port, int family) +int ospf_apiserver_serv_sock_family(unsigned short port, int family) { - union sockunion su; - int accept_sock; - int rc; - - memset (&su, 0, sizeof (union sockunion)); - su.sa.sa_family = family; - - /* Make new socket */ - accept_sock = sockunion_stream_socket (&su); - if (accept_sock < 0) - return accept_sock; - - /* This is a server, so reuse address and port */ - sockopt_reuseaddr (accept_sock); - sockopt_reuseport (accept_sock); - - /* Bind socket to address and given port. */ - rc = sockunion_bind (accept_sock, &su, port, NULL); - if (rc < 0) - { - close (accept_sock); /* Close socket */ - return rc; - } - - /* Listen socket under queue length 3. */ - rc = listen (accept_sock, 3); - if (rc < 0) - { - zlog_warn ("ospf_apiserver_serv_sock_family: listen: %s", - safe_strerror (errno)); - close (accept_sock); /* Close socket */ - return rc; - } - return accept_sock; + union sockunion su; + int accept_sock; + int rc; + + memset(&su, 0, sizeof(union sockunion)); + su.sa.sa_family = family; + + /* Make new socket */ + accept_sock = sockunion_stream_socket(&su); + if (accept_sock < 0) + return accept_sock; + + /* This is a server, so reuse address and port */ + sockopt_reuseaddr(accept_sock); + sockopt_reuseport(accept_sock); + + /* Bind socket to address and given port. */ + rc = sockunion_bind(accept_sock, &su, port, NULL); + if (rc < 0) { + close(accept_sock); /* Close socket */ + return rc; + } + + /* Listen socket under queue length 3. */ + rc = listen(accept_sock, 3); + if (rc < 0) { + zlog_warn("ospf_apiserver_serv_sock_family: listen: %s", + safe_strerror(errno)); + close(accept_sock); /* Close socket */ + return rc; + } + return accept_sock; } /* Accept connection request from external applications. For each accepted connection allocate own connection instance. */ -int -ospf_apiserver_accept (struct thread *thread) +int ospf_apiserver_accept(struct thread *thread) { - int accept_sock; - int new_sync_sock; - int new_async_sock; - union sockunion su; - struct ospf_apiserver *apiserv; - struct sockaddr_in peer_async; - struct sockaddr_in peer_sync; - unsigned int peerlen; - int ret; - - /* THREAD_ARG (thread) is NULL */ - accept_sock = THREAD_FD (thread); - - /* Keep hearing on socket for further connections. */ - ospf_apiserver_event (OSPF_APISERVER_ACCEPT, accept_sock, NULL); - - memset (&su, 0, sizeof (union sockunion)); - /* Accept connection for synchronous messages */ - new_sync_sock = sockunion_accept (accept_sock, &su); - if (new_sync_sock < 0) - { - zlog_warn ("ospf_apiserver_accept: accept: %s", safe_strerror (errno)); - return -1; - } - - /* Get port address and port number of peer to make reverse connection. - The reverse channel uses the port number of the peer port+1. */ - - memset(&peer_sync, 0, sizeof(struct sockaddr_in)); - peerlen = sizeof (struct sockaddr_in); - - ret = getpeername (new_sync_sock, (struct sockaddr *)&peer_sync, &peerlen); - if (ret < 0) - { - zlog_warn ("ospf_apiserver_accept: getpeername: %s", safe_strerror (errno)); - close (new_sync_sock); - return -1; - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("API: ospf_apiserver_accept: New peer: %s/%u", - inet_ntoa (peer_sync.sin_addr), ntohs (peer_sync.sin_port)); - - /* Create new socket for asynchronous messages. */ - peer_async = peer_sync; - peer_async.sin_port = htons(ntohs(peer_sync.sin_port) + 1); - - /* Check if remote port number to make reverse connection is valid one. */ - if (ntohs (peer_async.sin_port) == ospf_apiserver_getport ()) - { - zlog_warn ("API: ospf_apiserver_accept: Peer(%s/%u): Invalid async port number?", - inet_ntoa (peer_async.sin_addr), ntohs (peer_async.sin_port)); - close (new_sync_sock); - return -1; - } - - new_async_sock = socket (AF_INET, SOCK_STREAM, 0); - if (new_async_sock < 0) - { - zlog_warn ("ospf_apiserver_accept: socket: %s", safe_strerror (errno)); - close (new_sync_sock); - return -1; - } - - ret = connect (new_async_sock, (struct sockaddr *) &peer_async, - sizeof (struct sockaddr_in)); - - if (ret < 0) - { - zlog_warn ("ospf_apiserver_accept: connect: %s", safe_strerror (errno)); - close (new_sync_sock); - close (new_async_sock); - return -1; - } + int accept_sock; + int new_sync_sock; + int new_async_sock; + union sockunion su; + struct ospf_apiserver *apiserv; + struct sockaddr_in peer_async; + struct sockaddr_in peer_sync; + unsigned int peerlen; + int ret; + + /* THREAD_ARG (thread) is NULL */ + accept_sock = THREAD_FD(thread); + + /* Keep hearing on socket for further connections. */ + ospf_apiserver_event(OSPF_APISERVER_ACCEPT, accept_sock, NULL); + + memset(&su, 0, sizeof(union sockunion)); + /* Accept connection for synchronous messages */ + new_sync_sock = sockunion_accept(accept_sock, &su); + if (new_sync_sock < 0) { + zlog_warn("ospf_apiserver_accept: accept: %s", + safe_strerror(errno)); + return -1; + } + + /* Get port address and port number of peer to make reverse connection. + The reverse channel uses the port number of the peer port+1. */ + + memset(&peer_sync, 0, sizeof(struct sockaddr_in)); + peerlen = sizeof(struct sockaddr_in); + + ret = getpeername(new_sync_sock, (struct sockaddr *)&peer_sync, + &peerlen); + if (ret < 0) { + zlog_warn("ospf_apiserver_accept: getpeername: %s", + safe_strerror(errno)); + close(new_sync_sock); + return -1; + } + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("API: ospf_apiserver_accept: New peer: %s/%u", + inet_ntoa(peer_sync.sin_addr), + ntohs(peer_sync.sin_port)); + + /* Create new socket for asynchronous messages. */ + peer_async = peer_sync; + peer_async.sin_port = htons(ntohs(peer_sync.sin_port) + 1); + + /* Check if remote port number to make reverse connection is valid one. + */ + if (ntohs(peer_async.sin_port) == ospf_apiserver_getport()) { + zlog_warn( + "API: ospf_apiserver_accept: Peer(%s/%u): Invalid async port number?", + inet_ntoa(peer_async.sin_addr), + ntohs(peer_async.sin_port)); + close(new_sync_sock); + return -1; + } + + new_async_sock = socket(AF_INET, SOCK_STREAM, 0); + if (new_async_sock < 0) { + zlog_warn("ospf_apiserver_accept: socket: %s", + safe_strerror(errno)); + close(new_sync_sock); + return -1; + } + + ret = connect(new_async_sock, (struct sockaddr *)&peer_async, + sizeof(struct sockaddr_in)); + + if (ret < 0) { + zlog_warn("ospf_apiserver_accept: connect: %s", + safe_strerror(errno)); + close(new_sync_sock); + close(new_async_sock); + return -1; + } #ifdef USE_ASYNC_READ -#else /* USE_ASYNC_READ */ - /* Make the asynchronous channel write-only. */ - ret = shutdown (new_async_sock, SHUT_RD); - if (ret < 0) - { - zlog_warn ("ospf_apiserver_accept: shutdown: %s", safe_strerror (errno)); - close (new_sync_sock); - close (new_async_sock); - return -1; - } +#else /* USE_ASYNC_READ */ + /* Make the asynchronous channel write-only. */ + ret = shutdown(new_async_sock, SHUT_RD); + if (ret < 0) { + zlog_warn("ospf_apiserver_accept: shutdown: %s", + safe_strerror(errno)); + close(new_sync_sock); + close(new_async_sock); + return -1; + } #endif /* USE_ASYNC_READ */ - /* Allocate new server-side connection structure */ - apiserv = ospf_apiserver_new (new_sync_sock, new_async_sock); + /* Allocate new server-side connection structure */ + apiserv = ospf_apiserver_new(new_sync_sock, new_async_sock); - /* Add to active connection list */ - listnode_add (apiserver_list, apiserv); - apiserv->peer_sync = peer_sync; - apiserv->peer_async = peer_async; + /* Add to active connection list */ + listnode_add(apiserver_list, apiserv); + apiserv->peer_sync = peer_sync; + apiserv->peer_async = peer_async; - /* And add read threads for new connection */ - ospf_apiserver_event (OSPF_APISERVER_SYNC_READ, new_sync_sock, apiserv); + /* And add read threads for new connection */ + ospf_apiserver_event(OSPF_APISERVER_SYNC_READ, new_sync_sock, apiserv); #ifdef USE_ASYNC_READ - ospf_apiserver_event (OSPF_APISERVER_ASYNC_READ, new_async_sock, apiserv); + ospf_apiserver_event(OSPF_APISERVER_ASYNC_READ, new_async_sock, + apiserv); #endif /* USE_ASYNC_READ */ - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("API: New apiserv(%p), total#(%d)", - (void *)apiserv, apiserver_list->count); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("API: New apiserv(%p), total#(%d)", (void *)apiserv, + apiserver_list->count); - return 0; + return 0; } @@ -762,71 +720,68 @@ ospf_apiserver_accept (struct thread *thread) * ----------------------------------------------------------- */ -static int -ospf_apiserver_send_msg (struct ospf_apiserver *apiserv, struct msg *msg) +static int ospf_apiserver_send_msg(struct ospf_apiserver *apiserv, + struct msg *msg) { - struct msg_fifo *fifo; - struct msg *msg2; - enum event event; - int fd; - - switch (msg->hdr.msgtype) - { - case MSG_REPLY: - fifo = apiserv->out_sync_fifo; - fd = apiserv->fd_sync; - event = OSPF_APISERVER_SYNC_WRITE; - break; - case MSG_READY_NOTIFY: - case MSG_LSA_UPDATE_NOTIFY: - case MSG_LSA_DELETE_NOTIFY: - case MSG_NEW_IF: - case MSG_DEL_IF: - case MSG_ISM_CHANGE: - case MSG_NSM_CHANGE: - fifo = apiserv->out_async_fifo; - fd = apiserv->fd_async; - event = OSPF_APISERVER_ASYNC_WRITE; - break; - default: - zlog_warn ("ospf_apiserver_send_msg: Unknown message type %d", - msg->hdr.msgtype); - return -1; - } - - /* Make a copy of the message and put in the fifo. Once the fifo - gets drained by the write thread, the message will be freed. */ - /* NB: Given "msg" is untouched in this function. */ - msg2 = msg_dup (msg); - - /* Enqueue message into corresponding fifo queue */ - msg_fifo_push (fifo, msg2); - - /* Schedule write thread */ - ospf_apiserver_event (event, fd, apiserv); - return 0; + struct msg_fifo *fifo; + struct msg *msg2; + enum event event; + int fd; + + switch (msg->hdr.msgtype) { + case MSG_REPLY: + fifo = apiserv->out_sync_fifo; + fd = apiserv->fd_sync; + event = OSPF_APISERVER_SYNC_WRITE; + break; + case MSG_READY_NOTIFY: + case MSG_LSA_UPDATE_NOTIFY: + case MSG_LSA_DELETE_NOTIFY: + case MSG_NEW_IF: + case MSG_DEL_IF: + case MSG_ISM_CHANGE: + case MSG_NSM_CHANGE: + fifo = apiserv->out_async_fifo; + fd = apiserv->fd_async; + event = OSPF_APISERVER_ASYNC_WRITE; + break; + default: + zlog_warn("ospf_apiserver_send_msg: Unknown message type %d", + msg->hdr.msgtype); + return -1; + } + + /* Make a copy of the message and put in the fifo. Once the fifo + gets drained by the write thread, the message will be freed. */ + /* NB: Given "msg" is untouched in this function. */ + msg2 = msg_dup(msg); + + /* Enqueue message into corresponding fifo queue */ + msg_fifo_push(fifo, msg2); + + /* Schedule write thread */ + ospf_apiserver_event(event, fd, apiserv); + return 0; } -int -ospf_apiserver_send_reply (struct ospf_apiserver *apiserv, u_int32_t seqnr, - u_char rc) +int ospf_apiserver_send_reply(struct ospf_apiserver *apiserv, u_int32_t seqnr, + u_char rc) { - struct msg *msg = new_msg_reply (seqnr, rc); - int ret; + struct msg *msg = new_msg_reply(seqnr, rc); + int ret; - if (!msg) - { - zlog_warn ("ospf_apiserver_send_reply: msg_new failed"); + if (!msg) { + zlog_warn("ospf_apiserver_send_reply: msg_new failed"); #ifdef NOTYET - /* Cannot allocate new message. What should we do? */ - ospf_apiserver_free (apiserv); + /* Cannot allocate new message. What should we do? */ + ospf_apiserver_free(apiserv); #endif - return -1; - } + return -1; + } - ret = ospf_apiserver_send_msg (apiserv, msg); - msg_free (msg); - return ret; + ret = ospf_apiserver_send_msg(apiserv, msg); + msg_free(msg); + return ret; } @@ -835,38 +790,36 @@ ospf_apiserver_send_reply (struct ospf_apiserver *apiserv, u_int32_t seqnr, * ----------------------------------------------------------- */ -int -ospf_apiserver_handle_msg (struct ospf_apiserver *apiserv, struct msg *msg) +int ospf_apiserver_handle_msg(struct ospf_apiserver *apiserv, struct msg *msg) { - int rc; - - /* Call corresponding message handler function. */ - switch (msg->hdr.msgtype) - { - case MSG_REGISTER_OPAQUETYPE: - rc = ospf_apiserver_handle_register_opaque_type (apiserv, msg); - break; - case MSG_UNREGISTER_OPAQUETYPE: - rc = ospf_apiserver_handle_unregister_opaque_type (apiserv, msg); - break; - case MSG_REGISTER_EVENT: - rc = ospf_apiserver_handle_register_event (apiserv, msg); - break; - case MSG_SYNC_LSDB: - rc = ospf_apiserver_handle_sync_lsdb (apiserv, msg); - break; - case MSG_ORIGINATE_REQUEST: - rc = ospf_apiserver_handle_originate_request (apiserv, msg); - break; - case MSG_DELETE_REQUEST: - rc = ospf_apiserver_handle_delete_request (apiserv, msg); - break; - default: - zlog_warn ("ospf_apiserver_handle_msg: Unknown message type: %d", - msg->hdr.msgtype); - rc = -1; - } - return rc; + int rc; + + /* Call corresponding message handler function. */ + switch (msg->hdr.msgtype) { + case MSG_REGISTER_OPAQUETYPE: + rc = ospf_apiserver_handle_register_opaque_type(apiserv, msg); + break; + case MSG_UNREGISTER_OPAQUETYPE: + rc = ospf_apiserver_handle_unregister_opaque_type(apiserv, msg); + break; + case MSG_REGISTER_EVENT: + rc = ospf_apiserver_handle_register_event(apiserv, msg); + break; + case MSG_SYNC_LSDB: + rc = ospf_apiserver_handle_sync_lsdb(apiserv, msg); + break; + case MSG_ORIGINATE_REQUEST: + rc = ospf_apiserver_handle_originate_request(apiserv, msg); + break; + case MSG_DELETE_REQUEST: + rc = ospf_apiserver_handle_delete_request(apiserv, msg); + break; + default: + zlog_warn("ospf_apiserver_handle_msg: Unknown message type: %d", + msg->hdr.msgtype); + rc = -1; + } + return rc; } @@ -875,346 +828,327 @@ ospf_apiserver_handle_msg (struct ospf_apiserver *apiserv, struct msg *msg) * ----------------------------------------------------------- */ -int -ospf_apiserver_register_opaque_type (struct ospf_apiserver *apiserv, - u_char lsa_type, u_char opaque_type) +int ospf_apiserver_register_opaque_type(struct ospf_apiserver *apiserv, + u_char lsa_type, u_char opaque_type) { - struct registered_opaque_type *regtype; - int (*originator_func) (void *arg); - int rc; - - switch (lsa_type) - { - case OSPF_OPAQUE_LINK_LSA: - originator_func = ospf_apiserver_lsa9_originator; - break; - case OSPF_OPAQUE_AREA_LSA: - originator_func = ospf_apiserver_lsa10_originator; - break; - case OSPF_OPAQUE_AS_LSA: - originator_func = ospf_apiserver_lsa11_originator; - break; - default: - zlog_warn ("ospf_apiserver_register_opaque_type: lsa_type(%d)", - lsa_type); - return OSPF_API_ILLEGALLSATYPE; - } - - - /* Register opaque function table */ - /* NB: Duplicated registration will be detected inside the function. */ - rc = - ospf_register_opaque_functab (lsa_type, opaque_type, - NULL, /* ospf_apiserver_new_if */ - NULL, /* ospf_apiserver_del_if */ - NULL, /* ospf_apiserver_ism_change */ - NULL, /* ospf_apiserver_nsm_change */ - NULL, - NULL, - NULL, - ospf_apiserver_show_info, - originator_func, - ospf_apiserver_lsa_refresher, - NULL, /* ospf_apiserver_lsa_update */ - NULL /* ospf_apiserver_lsa_delete */); - - if (rc != 0) - { - zlog_warn ("Failed to register opaque type [%d/%d]", - lsa_type, opaque_type); - return OSPF_API_OPAQUETYPEINUSE; - } - - /* Remember the opaque type that application registers so when - connection shuts down, we can flush all LSAs of this opaque - type. */ - - regtype = - XCALLOC (MTYPE_OSPF_APISERVER, sizeof (struct registered_opaque_type)); - regtype->lsa_type = lsa_type; - regtype->opaque_type = opaque_type; - - /* Add to list of registered opaque types */ - listnode_add (apiserv->opaque_types, regtype); - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("API: Add LSA-type(%d)/Opaque-type(%d) into" - " apiserv(%p), total#(%d)", - lsa_type, opaque_type, (void *)apiserv, - listcount (apiserv->opaque_types)); - - return 0; + struct registered_opaque_type *regtype; + int (*originator_func)(void *arg); + int rc; + + switch (lsa_type) { + case OSPF_OPAQUE_LINK_LSA: + originator_func = ospf_apiserver_lsa9_originator; + break; + case OSPF_OPAQUE_AREA_LSA: + originator_func = ospf_apiserver_lsa10_originator; + break; + case OSPF_OPAQUE_AS_LSA: + originator_func = ospf_apiserver_lsa11_originator; + break; + default: + zlog_warn("ospf_apiserver_register_opaque_type: lsa_type(%d)", + lsa_type); + return OSPF_API_ILLEGALLSATYPE; + } + + + /* Register opaque function table */ + /* NB: Duplicated registration will be detected inside the function. */ + rc = ospf_register_opaque_functab( + lsa_type, opaque_type, NULL, /* ospf_apiserver_new_if */ + NULL, /* ospf_apiserver_del_if */ + NULL, /* ospf_apiserver_ism_change */ + NULL, /* ospf_apiserver_nsm_change */ + NULL, NULL, NULL, ospf_apiserver_show_info, originator_func, + ospf_apiserver_lsa_refresher, + NULL, /* ospf_apiserver_lsa_update */ + NULL /* ospf_apiserver_lsa_delete */); + + if (rc != 0) { + zlog_warn("Failed to register opaque type [%d/%d]", lsa_type, + opaque_type); + return OSPF_API_OPAQUETYPEINUSE; + } + + /* Remember the opaque type that application registers so when + connection shuts down, we can flush all LSAs of this opaque + type. */ + + regtype = XCALLOC(MTYPE_OSPF_APISERVER, + sizeof(struct registered_opaque_type)); + regtype->lsa_type = lsa_type; + regtype->opaque_type = opaque_type; + + /* Add to list of registered opaque types */ + listnode_add(apiserv->opaque_types, regtype); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "API: Add LSA-type(%d)/Opaque-type(%d) into" + " apiserv(%p), total#(%d)", + lsa_type, opaque_type, (void *)apiserv, + listcount(apiserv->opaque_types)); + + return 0; } -int -ospf_apiserver_unregister_opaque_type (struct ospf_apiserver *apiserv, - u_char lsa_type, u_char opaque_type) +int ospf_apiserver_unregister_opaque_type(struct ospf_apiserver *apiserv, + u_char lsa_type, u_char opaque_type) { - struct listnode *node, *nnode; - struct registered_opaque_type *regtype; + struct listnode *node, *nnode; + struct registered_opaque_type *regtype; - for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node, nnode, regtype)) - { - /* Check if we really registered this opaque type */ - if (regtype->lsa_type == lsa_type && - regtype->opaque_type == opaque_type) - { + for (ALL_LIST_ELEMENTS(apiserv->opaque_types, node, nnode, regtype)) { + /* Check if we really registered this opaque type */ + if (regtype->lsa_type == lsa_type + && regtype->opaque_type == opaque_type) { - /* Yes, we registered this opaque type. Flush - all existing opaque LSAs of this type */ + /* Yes, we registered this opaque type. Flush + all existing opaque LSAs of this type */ - ospf_apiserver_flush_opaque_lsa (apiserv, lsa_type, opaque_type); - ospf_delete_opaque_functab (lsa_type, opaque_type); + ospf_apiserver_flush_opaque_lsa(apiserv, lsa_type, + opaque_type); + ospf_delete_opaque_functab(lsa_type, opaque_type); - /* Remove from list of registered opaque types */ - listnode_delete (apiserv->opaque_types, regtype); + /* Remove from list of registered opaque types */ + listnode_delete(apiserv->opaque_types, regtype); - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("API: Del LSA-type(%d)/Opaque-type(%d)" - " from apiserv(%p), total#(%d)", - lsa_type, opaque_type, (void *)apiserv, - listcount (apiserv->opaque_types)); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "API: Del LSA-type(%d)/Opaque-type(%d)" + " from apiserv(%p), total#(%d)", + lsa_type, opaque_type, (void *)apiserv, + listcount(apiserv->opaque_types)); - return 0; + return 0; + } } - } - /* Opaque type is not registered */ - zlog_warn ("Failed to unregister opaque type [%d/%d]", - lsa_type, opaque_type); - return OSPF_API_OPAQUETYPENOTREGISTERED; + /* Opaque type is not registered */ + zlog_warn("Failed to unregister opaque type [%d/%d]", lsa_type, + opaque_type); + return OSPF_API_OPAQUETYPENOTREGISTERED; } -static int -apiserver_is_opaque_type_registered (struct ospf_apiserver *apiserv, - u_char lsa_type, u_char opaque_type) +static int apiserver_is_opaque_type_registered(struct ospf_apiserver *apiserv, + u_char lsa_type, + u_char opaque_type) { - struct listnode *node, *nnode; - struct registered_opaque_type *regtype; - - /* XXX: how many types are there? if few, why not just a bitmap? */ - for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node, nnode, regtype)) - { - /* Check if we really registered this opaque type */ - if (regtype->lsa_type == lsa_type && - regtype->opaque_type == opaque_type) - { - /* Yes registered */ - return 1; - } - } - /* Not registered */ - return 0; + struct listnode *node, *nnode; + struct registered_opaque_type *regtype; + + /* XXX: how many types are there? if few, why not just a bitmap? */ + for (ALL_LIST_ELEMENTS(apiserv->opaque_types, node, nnode, regtype)) { + /* Check if we really registered this opaque type */ + if (regtype->lsa_type == lsa_type + && regtype->opaque_type == opaque_type) { + /* Yes registered */ + return 1; + } + } + /* Not registered */ + return 0; } -int -ospf_apiserver_handle_register_opaque_type (struct ospf_apiserver *apiserv, - struct msg *msg) +int ospf_apiserver_handle_register_opaque_type(struct ospf_apiserver *apiserv, + struct msg *msg) { - struct msg_register_opaque_type *rmsg; - u_char lsa_type; - u_char opaque_type; - int rc = 0; - - /* Extract parameters from register opaque type message */ - rmsg = (struct msg_register_opaque_type *) STREAM_DATA (msg->s); - - lsa_type = rmsg->lsatype; - opaque_type = rmsg->opaquetype; - - rc = ospf_apiserver_register_opaque_type (apiserv, lsa_type, opaque_type); - - /* Send a reply back to client including return code */ - rc = ospf_apiserver_send_reply (apiserv, ntohl (msg->hdr.msgseq), rc); - if (rc < 0) - goto out; - - /* Now inform application about opaque types that are ready */ - switch (lsa_type) - { - case OSPF_OPAQUE_LINK_LSA: - ospf_apiserver_notify_ready_type9 (apiserv); - break; - case OSPF_OPAQUE_AREA_LSA: - ospf_apiserver_notify_ready_type10 (apiserv); - break; - case OSPF_OPAQUE_AS_LSA: - ospf_apiserver_notify_ready_type11 (apiserv); - break; - } + struct msg_register_opaque_type *rmsg; + u_char lsa_type; + u_char opaque_type; + int rc = 0; + + /* Extract parameters from register opaque type message */ + rmsg = (struct msg_register_opaque_type *)STREAM_DATA(msg->s); + + lsa_type = rmsg->lsatype; + opaque_type = rmsg->opaquetype; + + rc = ospf_apiserver_register_opaque_type(apiserv, lsa_type, + opaque_type); + + /* Send a reply back to client including return code */ + rc = ospf_apiserver_send_reply(apiserv, ntohl(msg->hdr.msgseq), rc); + if (rc < 0) + goto out; + + /* Now inform application about opaque types that are ready */ + switch (lsa_type) { + case OSPF_OPAQUE_LINK_LSA: + ospf_apiserver_notify_ready_type9(apiserv); + break; + case OSPF_OPAQUE_AREA_LSA: + ospf_apiserver_notify_ready_type10(apiserv); + break; + case OSPF_OPAQUE_AS_LSA: + ospf_apiserver_notify_ready_type11(apiserv); + break; + } out: - return rc; + return rc; } /* Notify specific client about all opaque types 9 that are ready. */ -void -ospf_apiserver_notify_ready_type9 (struct ospf_apiserver *apiserv) +void ospf_apiserver_notify_ready_type9(struct ospf_apiserver *apiserv) { - struct listnode *node, *nnode; - struct listnode *node2, *nnode2; - struct ospf *ospf; - struct ospf_interface *oi; - struct registered_opaque_type *r; - - ospf = ospf_lookup (); - - for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) - { - /* Check if this interface is indeed ready for type 9 */ - if (!ospf_apiserver_is_ready_type9 (oi)) - continue; - - /* Check for registered opaque type 9 types */ - /* XXX: loop-de-loop - optimise me */ - for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node2, nnode2, r)) - { - struct msg *msg; - - if (r->lsa_type == OSPF_OPAQUE_LINK_LSA) - { - - /* Yes, this opaque type is ready */ - msg = new_msg_ready_notify (0, OSPF_OPAQUE_LINK_LSA, - r->opaque_type, - oi->address->u.prefix4); - if (!msg) - { - zlog_warn ("apiserver_notify_ready_type9: msg_new failed"); + struct listnode *node, *nnode; + struct listnode *node2, *nnode2; + struct ospf *ospf; + struct ospf_interface *oi; + struct registered_opaque_type *r; + + ospf = ospf_lookup(); + + for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) { + /* Check if this interface is indeed ready for type 9 */ + if (!ospf_apiserver_is_ready_type9(oi)) + continue; + + /* Check for registered opaque type 9 types */ + /* XXX: loop-de-loop - optimise me */ + for (ALL_LIST_ELEMENTS(apiserv->opaque_types, node2, nnode2, + r)) { + struct msg *msg; + + if (r->lsa_type == OSPF_OPAQUE_LINK_LSA) { + + /* Yes, this opaque type is ready */ + msg = new_msg_ready_notify( + 0, OSPF_OPAQUE_LINK_LSA, r->opaque_type, + oi->address->u.prefix4); + if (!msg) { + zlog_warn( + "apiserver_notify_ready_type9: msg_new failed"); #ifdef NOTYET - /* Cannot allocate new message. What should we do? */ - ospf_apiserver_free (apiserv); + /* Cannot allocate new message. What + * should we do? */ + ospf_apiserver_free(apiserv); #endif - goto out; + goto out; + } + ospf_apiserver_send_msg(apiserv, msg); + msg_free(msg); + } } - ospf_apiserver_send_msg (apiserv, msg); - msg_free (msg); - } } - } out: - return; + return; } /* Notify specific client about all opaque types 10 that are ready. */ -void -ospf_apiserver_notify_ready_type10 (struct ospf_apiserver *apiserv) +void ospf_apiserver_notify_ready_type10(struct ospf_apiserver *apiserv) { - struct listnode *node, *nnode; - struct listnode *node2, *nnode2; - struct ospf *ospf; - struct ospf_area *area; - - ospf = ospf_lookup (); - - for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area)) - { - struct registered_opaque_type *r; - - if (!ospf_apiserver_is_ready_type10 (area)) - { - continue; - } - - /* Check for registered opaque type 10 types */ - /* XXX: loop in loop - optimise me */ - for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node2, nnode2, r)) - { - struct msg *msg; - - if (r->lsa_type == OSPF_OPAQUE_AREA_LSA) - { - /* Yes, this opaque type is ready */ - msg = - new_msg_ready_notify (0, OSPF_OPAQUE_AREA_LSA, - r->opaque_type, area->area_id); - if (!msg) - { - zlog_warn ("apiserver_notify_ready_type10: msg_new failed"); + struct listnode *node, *nnode; + struct listnode *node2, *nnode2; + struct ospf *ospf; + struct ospf_area *area; + + ospf = ospf_lookup(); + + for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) { + struct registered_opaque_type *r; + + if (!ospf_apiserver_is_ready_type10(area)) { + continue; + } + + /* Check for registered opaque type 10 types */ + /* XXX: loop in loop - optimise me */ + for (ALL_LIST_ELEMENTS(apiserv->opaque_types, node2, nnode2, + r)) { + struct msg *msg; + + if (r->lsa_type == OSPF_OPAQUE_AREA_LSA) { + /* Yes, this opaque type is ready */ + msg = new_msg_ready_notify( + 0, OSPF_OPAQUE_AREA_LSA, r->opaque_type, + area->area_id); + if (!msg) { + zlog_warn( + "apiserver_notify_ready_type10: msg_new failed"); #ifdef NOTYET - /* Cannot allocate new message. What should we do? */ - ospf_apiserver_free (apiserv); + /* Cannot allocate new message. What + * should we do? */ + ospf_apiserver_free(apiserv); #endif - goto out; + goto out; + } + ospf_apiserver_send_msg(apiserv, msg); + msg_free(msg); + } } - ospf_apiserver_send_msg (apiserv, msg); - msg_free (msg); - } } - } out: - return; + return; } /* Notify specific client about all opaque types 11 that are ready */ -void -ospf_apiserver_notify_ready_type11 (struct ospf_apiserver *apiserv) +void ospf_apiserver_notify_ready_type11(struct ospf_apiserver *apiserv) { - struct listnode *node, *nnode; - struct ospf *ospf; - struct registered_opaque_type *r; - - ospf = ospf_lookup (); - - /* Can type 11 be originated? */ - if (!ospf_apiserver_is_ready_type11 (ospf)) - goto out; - - /* Check for registered opaque type 11 types */ - for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node, nnode, r)) - { - struct msg *msg; - struct in_addr noarea_id = { .s_addr = 0L }; - - if (r->lsa_type == OSPF_OPAQUE_AS_LSA) - { - /* Yes, this opaque type is ready */ - msg = new_msg_ready_notify (0, OSPF_OPAQUE_AS_LSA, - r->opaque_type, noarea_id); - - if (!msg) - { - zlog_warn ("apiserver_notify_ready_type11: msg_new failed"); + struct listnode *node, *nnode; + struct ospf *ospf; + struct registered_opaque_type *r; + + ospf = ospf_lookup(); + + /* Can type 11 be originated? */ + if (!ospf_apiserver_is_ready_type11(ospf)) + goto out; + + /* Check for registered opaque type 11 types */ + for (ALL_LIST_ELEMENTS(apiserv->opaque_types, node, nnode, r)) { + struct msg *msg; + struct in_addr noarea_id = {.s_addr = 0L}; + + if (r->lsa_type == OSPF_OPAQUE_AS_LSA) { + /* Yes, this opaque type is ready */ + msg = new_msg_ready_notify(0, OSPF_OPAQUE_AS_LSA, + r->opaque_type, noarea_id); + + if (!msg) { + zlog_warn( + "apiserver_notify_ready_type11: msg_new failed"); #ifdef NOTYET - /* Cannot allocate new message. What should we do? */ - ospf_apiserver_free (apiserv); + /* Cannot allocate new message. What should we + * do? */ + ospf_apiserver_free(apiserv); #endif - goto out; - } - ospf_apiserver_send_msg (apiserv, msg); - msg_free (msg); + goto out; + } + ospf_apiserver_send_msg(apiserv, msg); + msg_free(msg); + } } - } out: - return; + return; } -int -ospf_apiserver_handle_unregister_opaque_type (struct ospf_apiserver *apiserv, - struct msg *msg) +int ospf_apiserver_handle_unregister_opaque_type(struct ospf_apiserver *apiserv, + struct msg *msg) { - struct msg_unregister_opaque_type *umsg; - u_char ltype; - u_char otype; - int rc = 0; + struct msg_unregister_opaque_type *umsg; + u_char ltype; + u_char otype; + int rc = 0; - /* Extract parameters from unregister opaque type message */ - umsg = (struct msg_unregister_opaque_type *) STREAM_DATA (msg->s); + /* Extract parameters from unregister opaque type message */ + umsg = (struct msg_unregister_opaque_type *)STREAM_DATA(msg->s); - ltype = umsg->lsatype; - otype = umsg->opaquetype; + ltype = umsg->lsatype; + otype = umsg->opaquetype; - rc = ospf_apiserver_unregister_opaque_type (apiserv, ltype, otype); + rc = ospf_apiserver_unregister_opaque_type(apiserv, ltype, otype); - /* Send a reply back to client including return code */ - rc = ospf_apiserver_send_reply (apiserv, ntohl (msg->hdr.msgseq), rc); + /* Send a reply back to client including return code */ + rc = ospf_apiserver_send_reply(apiserv, ntohl(msg->hdr.msgseq), rc); - return rc; + return rc; } @@ -1222,38 +1156,34 @@ ospf_apiserver_handle_unregister_opaque_type (struct ospf_apiserver *apiserv, * Following are functions for event (filter) registration. * ----------------------------------------------------------- */ -int -ospf_apiserver_handle_register_event (struct ospf_apiserver *apiserv, - struct msg *msg) +int ospf_apiserver_handle_register_event(struct ospf_apiserver *apiserv, + struct msg *msg) { - struct msg_register_event *rmsg; - int rc; - u_int32_t seqnum; - - rmsg = (struct msg_register_event *) STREAM_DATA (msg->s); - - /* Get request sequence number */ - seqnum = msg_get_seq (msg); - - /* Free existing filter in apiserv. */ - XFREE (MTYPE_OSPF_APISERVER_MSGFILTER, apiserv->filter); - /* Alloc new space for filter. */ - - apiserv->filter = XMALLOC (MTYPE_OSPF_APISERVER_MSGFILTER, - ntohs (msg->hdr.msglen)); - if (apiserv->filter) - { - /* copy it over. */ - memcpy (apiserv->filter, &rmsg->filter, ntohs (msg->hdr.msglen)); - rc = OSPF_API_OK; - } - else - { - rc = OSPF_API_NOMEMORY; - } - /* Send a reply back to client with return code */ - rc = ospf_apiserver_send_reply (apiserv, seqnum, rc); - return rc; + struct msg_register_event *rmsg; + int rc; + u_int32_t seqnum; + + rmsg = (struct msg_register_event *)STREAM_DATA(msg->s); + + /* Get request sequence number */ + seqnum = msg_get_seq(msg); + + /* Free existing filter in apiserv. */ + XFREE(MTYPE_OSPF_APISERVER_MSGFILTER, apiserv->filter); + /* Alloc new space for filter. */ + + apiserv->filter = + XMALLOC(MTYPE_OSPF_APISERVER_MSGFILTER, ntohs(msg->hdr.msglen)); + if (apiserv->filter) { + /* copy it over. */ + memcpy(apiserv->filter, &rmsg->filter, ntohs(msg->hdr.msglen)); + rc = OSPF_API_OK; + } else { + rc = OSPF_API_NOMEMORY; + } + /* Send a reply back to client with return code */ + rc = ospf_apiserver_send_reply(apiserv, seqnum, rc); + return rc; } @@ -1262,176 +1192,161 @@ ospf_apiserver_handle_register_event (struct ospf_apiserver *apiserv, * ----------------------------------------------------------- */ -static int -apiserver_sync_callback (struct ospf_lsa *lsa, void *p_arg, int int_arg) +static int apiserver_sync_callback(struct ospf_lsa *lsa, void *p_arg, + int int_arg) { - struct ospf_apiserver *apiserv; - int seqnum; - struct msg *msg; - struct param_t - { - struct ospf_apiserver *apiserv; - struct lsa_filter_type *filter; - } - *param; - int rc = -1; - - /* Sanity check */ - assert (lsa->data); - assert (p_arg); - - param = (struct param_t *) p_arg; - apiserv = param->apiserv; - seqnum = (u_int32_t) int_arg; - - /* Check origin in filter. */ - if ((param->filter->origin == ANY_ORIGIN) || - (param->filter->origin == (lsa->flags & OSPF_LSA_SELF))) - { - - /* Default area for AS-External and Opaque11 LSAs */ - struct in_addr area_id = { .s_addr = 0L }; - - /* Default interface for non Opaque9 LSAs */ - struct in_addr ifaddr = { .s_addr = 0L }; - - if (lsa->area) - { - area_id = lsa->area->area_id; - } - if (lsa->data->type == OSPF_OPAQUE_LINK_LSA) - { - ifaddr = lsa->oi->address->u.prefix4; - } - - msg = new_msg_lsa_change_notify (MSG_LSA_UPDATE_NOTIFY, - seqnum, - ifaddr, area_id, - lsa->flags & OSPF_LSA_SELF, lsa->data); - if (!msg) - { - zlog_warn ("apiserver_sync_callback: new_msg_update failed"); + struct ospf_apiserver *apiserv; + int seqnum; + struct msg *msg; + struct param_t { + struct ospf_apiserver *apiserv; + struct lsa_filter_type *filter; + } * param; + int rc = -1; + + /* Sanity check */ + assert(lsa->data); + assert(p_arg); + + param = (struct param_t *)p_arg; + apiserv = param->apiserv; + seqnum = (u_int32_t)int_arg; + + /* Check origin in filter. */ + if ((param->filter->origin == ANY_ORIGIN) + || (param->filter->origin == (lsa->flags & OSPF_LSA_SELF))) { + + /* Default area for AS-External and Opaque11 LSAs */ + struct in_addr area_id = {.s_addr = 0L}; + + /* Default interface for non Opaque9 LSAs */ + struct in_addr ifaddr = {.s_addr = 0L}; + + if (lsa->area) { + area_id = lsa->area->area_id; + } + if (lsa->data->type == OSPF_OPAQUE_LINK_LSA) { + ifaddr = lsa->oi->address->u.prefix4; + } + + msg = new_msg_lsa_change_notify( + MSG_LSA_UPDATE_NOTIFY, seqnum, ifaddr, area_id, + lsa->flags & OSPF_LSA_SELF, lsa->data); + if (!msg) { + zlog_warn( + "apiserver_sync_callback: new_msg_update failed"); #ifdef NOTYET - /* Cannot allocate new message. What should we do? */ -/* ospf_apiserver_free (apiserv);*//* Do nothing here XXX */ + /* Cannot allocate new message. What should we do? */ + /* ospf_apiserver_free (apiserv);*/ /* Do nothing + here XXX + */ #endif - goto out; - } + goto out; + } - /* Send LSA */ - ospf_apiserver_send_msg (apiserv, msg); - msg_free (msg); - } - rc = 0; + /* Send LSA */ + ospf_apiserver_send_msg(apiserv, msg); + msg_free(msg); + } + rc = 0; out: - return rc; + return rc; } -int -ospf_apiserver_handle_sync_lsdb (struct ospf_apiserver *apiserv, - struct msg *msg) +int ospf_apiserver_handle_sync_lsdb(struct ospf_apiserver *apiserv, + struct msg *msg) { - struct listnode *node, *nnode; - u_int32_t seqnum; - int rc = 0; - struct msg_sync_lsdb *smsg; - struct ospf_apiserver_param_t - { - struct ospf_apiserver *apiserv; - struct lsa_filter_type *filter; - } param; - u_int16_t mask; - struct route_node *rn; - struct ospf_lsa *lsa; - struct ospf *ospf; - struct ospf_area *area; - - ospf = ospf_lookup (); - - /* Get request sequence number */ - seqnum = msg_get_seq (msg); - /* Set sync msg. */ - smsg = (struct msg_sync_lsdb *) STREAM_DATA (msg->s); - - /* Set parameter struct. */ - param.apiserv = apiserv; - param.filter = &smsg->filter; - - /* Remember mask. */ - mask = ntohs (smsg->filter.typemask); - - /* Iterate over all areas. */ - for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area)) - { - int i; - u_int32_t *area_id = NULL; - - /* Compare area_id with area_ids in sync request. */ - if ((i = smsg->filter.num_areas) > 0) - { - /* Let area_id point to the list of area IDs, - * which is at the end of smsg->filter. */ - area_id = (u_int32_t *) (&smsg->filter + 1); - while (i) - { - if (*area_id == area->area_id.s_addr) - { - break; + struct listnode *node, *nnode; + u_int32_t seqnum; + int rc = 0; + struct msg_sync_lsdb *smsg; + struct ospf_apiserver_param_t { + struct ospf_apiserver *apiserv; + struct lsa_filter_type *filter; + } param; + u_int16_t mask; + struct route_node *rn; + struct ospf_lsa *lsa; + struct ospf *ospf; + struct ospf_area *area; + + ospf = ospf_lookup(); + + /* Get request sequence number */ + seqnum = msg_get_seq(msg); + /* Set sync msg. */ + smsg = (struct msg_sync_lsdb *)STREAM_DATA(msg->s); + + /* Set parameter struct. */ + param.apiserv = apiserv; + param.filter = &smsg->filter; + + /* Remember mask. */ + mask = ntohs(smsg->filter.typemask); + + /* Iterate over all areas. */ + for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) { + int i; + u_int32_t *area_id = NULL; + + /* Compare area_id with area_ids in sync request. */ + if ((i = smsg->filter.num_areas) > 0) { + /* Let area_id point to the list of area IDs, + * which is at the end of smsg->filter. */ + area_id = (u_int32_t *)(&smsg->filter + 1); + while (i) { + if (*area_id == area->area_id.s_addr) { + break; + } + i--; + area_id++; + } + } else { + i = 1; + } + + /* If area was found, then i>0 here. */ + if (i) { + /* Check msg type. */ + if (mask & Power2[OSPF_ROUTER_LSA]) + LSDB_LOOP(ROUTER_LSDB(area), rn, lsa) + apiserver_sync_callback(lsa, (void *)¶m, seqnum); + if (mask & Power2[OSPF_NETWORK_LSA]) + LSDB_LOOP(NETWORK_LSDB(area), rn, lsa) + apiserver_sync_callback(lsa, (void *)¶m, seqnum); + if (mask & Power2[OSPF_SUMMARY_LSA]) + LSDB_LOOP(SUMMARY_LSDB(area), rn, lsa) + apiserver_sync_callback(lsa, (void *)¶m, seqnum); + if (mask & Power2[OSPF_ASBR_SUMMARY_LSA]) + LSDB_LOOP(ASBR_SUMMARY_LSDB(area), rn, lsa) + apiserver_sync_callback(lsa, (void *)¶m, seqnum); + if (mask & Power2[OSPF_OPAQUE_LINK_LSA]) + LSDB_LOOP(OPAQUE_LINK_LSDB(area), rn, lsa) + apiserver_sync_callback(lsa, (void *)¶m, seqnum); + if (mask & Power2[OSPF_OPAQUE_AREA_LSA]) + LSDB_LOOP(OPAQUE_AREA_LSDB(area), rn, lsa) + apiserver_sync_callback(lsa, (void *)¶m, seqnum); } - i--; - area_id++; - } - } - else - { - i = 1; - } - - /* If area was found, then i>0 here. */ - if (i) - { - /* Check msg type. */ - if (mask & Power2[OSPF_ROUTER_LSA]) - LSDB_LOOP (ROUTER_LSDB (area), rn, lsa) - apiserver_sync_callback(lsa, (void *) ¶m, seqnum); - if (mask & Power2[OSPF_NETWORK_LSA]) - LSDB_LOOP (NETWORK_LSDB (area), rn, lsa) - apiserver_sync_callback(lsa, (void *) ¶m, seqnum); - if (mask & Power2[OSPF_SUMMARY_LSA]) - LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa) - apiserver_sync_callback(lsa, (void *) ¶m, seqnum); - if (mask & Power2[OSPF_ASBR_SUMMARY_LSA]) - LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa) - apiserver_sync_callback(lsa, (void *) ¶m, seqnum); - if (mask & Power2[OSPF_OPAQUE_LINK_LSA]) - LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa) - apiserver_sync_callback(lsa, (void *) ¶m, seqnum); - if (mask & Power2[OSPF_OPAQUE_AREA_LSA]) - LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa) - apiserver_sync_callback(lsa, (void *) ¶m, seqnum); - } - } - - /* For AS-external LSAs */ - if (ospf->lsdb) - { - if (mask & Power2[OSPF_AS_EXTERNAL_LSA]) - LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa) - apiserver_sync_callback(lsa, (void *) ¶m, seqnum); - } - - /* For AS-external opaque LSAs */ - if (ospf->lsdb) - { - if (mask & Power2[OSPF_OPAQUE_AS_LSA]) - LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa) - apiserver_sync_callback(lsa, (void *) ¶m, seqnum); - } - - /* Send a reply back to client with return code */ - rc = ospf_apiserver_send_reply (apiserv, seqnum, rc); - return rc; + } + + /* For AS-external LSAs */ + if (ospf->lsdb) { + if (mask & Power2[OSPF_AS_EXTERNAL_LSA]) + LSDB_LOOP(EXTERNAL_LSDB(ospf), rn, lsa) + apiserver_sync_callback(lsa, (void *)¶m, seqnum); + } + + /* For AS-external opaque LSAs */ + if (ospf->lsdb) { + if (mask & Power2[OSPF_OPAQUE_AS_LSA]) + LSDB_LOOP(OPAQUE_AS_LSDB(ospf), rn, lsa) + apiserver_sync_callback(lsa, (void *)¶m, seqnum); + } + + /* Send a reply back to client with return code */ + rc = ospf_apiserver_send_reply(apiserv, seqnum, rc); + return rc; } @@ -1447,457 +1362,435 @@ ospf_apiserver_handle_sync_lsdb (struct ospf_apiserver *apiserv, LSAs, area parameter for type 10. Type 11 LSAs do neither need area nor interface. */ -struct ospf_lsa * -ospf_apiserver_opaque_lsa_new (struct ospf_area *area, - struct ospf_interface *oi, - struct lsa_header *protolsa) +struct ospf_lsa *ospf_apiserver_opaque_lsa_new(struct ospf_area *area, + struct ospf_interface *oi, + struct lsa_header *protolsa) { - struct stream *s; - struct lsa_header *newlsa; - struct ospf_lsa *new = NULL; - u_char options = 0x0; - u_int16_t length; - - struct ospf *ospf; - - ospf = ospf_lookup(); - assert(ospf); - - /* Create a stream for internal opaque LSA */ - if ((s = stream_new (OSPF_MAX_LSA_SIZE)) == NULL) - { - zlog_warn ("ospf_apiserver_opaque_lsa_new: stream_new failed"); - return NULL; - } - - newlsa = (struct lsa_header *) STREAM_DATA (s); - - /* XXX If this is a link-local LSA or an AS-external LSA, how do we - have to set options? */ - - if (area) - { - options = LSA_OPTIONS_GET (area); - options |= LSA_OPTIONS_NSSA_GET (area); - } - - options |= OSPF_OPTION_O; /* Don't forget to set option bit */ - - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - { - zlog_debug ("LSA[Type%d:%s]: Creating an Opaque-LSA instance", - protolsa->type, inet_ntoa (protolsa->id)); - } - - /* Set opaque-LSA header fields. */ - lsa_header_set (s, options, protolsa->type, protolsa->id, - ospf->router_id); - - /* Set opaque-LSA body fields. */ - stream_put (s, ((u_char *) protolsa) + sizeof (struct lsa_header), - ntohs (protolsa->length) - sizeof (struct lsa_header)); - - /* Determine length of LSA. */ - length = stream_get_endp (s); - newlsa->length = htons (length); - - /* Create OSPF LSA. */ - if ((new = ospf_lsa_new ()) == NULL) - { - zlog_warn ("ospf_apiserver_opaque_lsa_new: ospf_lsa_new() ?"); - stream_free (s); - return NULL; - } - - if ((new->data = ospf_lsa_data_new (length)) == NULL) - { - zlog_warn ("ospf_apiserver_opaque_lsa_new: ospf_lsa_data_new() ?"); - ospf_lsa_unlock (&new); - stream_free (s); - return NULL; - } - - new->area = area; - new->oi = oi; - - SET_FLAG (new->flags, OSPF_LSA_SELF); - memcpy (new->data, newlsa, length); - stream_free (s); - - return new; + struct stream *s; + struct lsa_header *newlsa; + struct ospf_lsa *new = NULL; + u_char options = 0x0; + u_int16_t length; + + struct ospf *ospf; + + ospf = ospf_lookup(); + assert(ospf); + + /* Create a stream for internal opaque LSA */ + if ((s = stream_new(OSPF_MAX_LSA_SIZE)) == NULL) { + zlog_warn("ospf_apiserver_opaque_lsa_new: stream_new failed"); + return NULL; + } + + newlsa = (struct lsa_header *)STREAM_DATA(s); + + /* XXX If this is a link-local LSA or an AS-external LSA, how do we + have to set options? */ + + if (area) { + options = LSA_OPTIONS_GET(area); + options |= LSA_OPTIONS_NSSA_GET(area); + } + + options |= OSPF_OPTION_O; /* Don't forget to set option bit */ + + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { + zlog_debug("LSA[Type%d:%s]: Creating an Opaque-LSA instance", + protolsa->type, inet_ntoa(protolsa->id)); + } + + /* Set opaque-LSA header fields. */ + lsa_header_set(s, options, protolsa->type, protolsa->id, + ospf->router_id); + + /* Set opaque-LSA body fields. */ + stream_put(s, ((u_char *)protolsa) + sizeof(struct lsa_header), + ntohs(protolsa->length) - sizeof(struct lsa_header)); + + /* Determine length of LSA. */ + length = stream_get_endp(s); + newlsa->length = htons(length); + + /* Create OSPF LSA. */ + if ((new = ospf_lsa_new()) == NULL) { + zlog_warn("ospf_apiserver_opaque_lsa_new: ospf_lsa_new() ?"); + stream_free(s); + return NULL; + } + + if ((new->data = ospf_lsa_data_new(length)) == NULL) { + zlog_warn( + "ospf_apiserver_opaque_lsa_new: ospf_lsa_data_new() ?"); + ospf_lsa_unlock(&new); + stream_free(s); + return NULL; + } + + new->area = area; + new->oi = oi; + + SET_FLAG(new->flags, OSPF_LSA_SELF); + memcpy(new->data, newlsa, length); + stream_free(s); + + return new; } -int -ospf_apiserver_is_ready_type9 (struct ospf_interface *oi) +int ospf_apiserver_is_ready_type9(struct ospf_interface *oi) { - /* Type 9 opaque LSA can be originated if there is at least one - active opaque-capable neighbor attached to the outgoing - interface. */ + /* Type 9 opaque LSA can be originated if there is at least one + active opaque-capable neighbor attached to the outgoing + interface. */ - return (ospf_nbr_count_opaque_capable (oi) > 0); + return (ospf_nbr_count_opaque_capable(oi) > 0); } -int -ospf_apiserver_is_ready_type10 (struct ospf_area *area) +int ospf_apiserver_is_ready_type10(struct ospf_area *area) { - /* Type 10 opaque LSA can be originated if there is at least one - interface belonging to the area that has an active opaque-capable - neighbor. */ - struct listnode *node, *nnode; - struct ospf_interface *oi; - - for (ALL_LIST_ELEMENTS (area->oiflist, node, nnode, oi)) - /* Is there an active neighbor attached to this interface? */ - if (ospf_apiserver_is_ready_type9 (oi)) - return 1; - - /* No active neighbor in area */ - return 0; + /* Type 10 opaque LSA can be originated if there is at least one + interface belonging to the area that has an active opaque-capable + neighbor. */ + struct listnode *node, *nnode; + struct ospf_interface *oi; + + for (ALL_LIST_ELEMENTS(area->oiflist, node, nnode, oi)) + /* Is there an active neighbor attached to this interface? */ + if (ospf_apiserver_is_ready_type9(oi)) + return 1; + + /* No active neighbor in area */ + return 0; } -int -ospf_apiserver_is_ready_type11 (struct ospf *ospf) +int ospf_apiserver_is_ready_type11(struct ospf *ospf) { - /* Type 11 opaque LSA can be originated if there is at least one interface - that has an active opaque-capable neighbor. */ - struct listnode *node, *nnode; - struct ospf_interface *oi; - - for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) - /* Is there an active neighbor attached to this interface? */ - if (ospf_apiserver_is_ready_type9 (oi)) - return 1; - - /* No active neighbor at all */ - return 0; + /* Type 11 opaque LSA can be originated if there is at least one + interface + that has an active opaque-capable neighbor. */ + struct listnode *node, *nnode; + struct ospf_interface *oi; + + for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) + /* Is there an active neighbor attached to this interface? */ + if (ospf_apiserver_is_ready_type9(oi)) + return 1; + + /* No active neighbor at all */ + return 0; } -int -ospf_apiserver_handle_originate_request (struct ospf_apiserver *apiserv, - struct msg *msg) +int ospf_apiserver_handle_originate_request(struct ospf_apiserver *apiserv, + struct msg *msg) { - struct msg_originate_request *omsg; - struct lsa_header *data; - struct ospf_lsa *new; - struct ospf_lsa *old; - struct ospf_area *area = NULL; - struct ospf_interface *oi = NULL; - struct ospf_lsdb *lsdb = NULL; - struct ospf *ospf; - int lsa_type, opaque_type; - int ready = 0; - int rc = 0; - - ospf = ospf_lookup(); - - /* Extract opaque LSA data from message */ - omsg = (struct msg_originate_request *) STREAM_DATA (msg->s); - data = &omsg->data; - - /* Determine interface for type9 or area for type10 LSAs. */ - switch (data->type) - { - case OSPF_OPAQUE_LINK_LSA: - oi = ospf_apiserver_if_lookup_by_addr (omsg->ifaddr); - if (!oi) - { - zlog_warn ("apiserver_originate: unknown interface %s", - inet_ntoa (omsg->ifaddr)); - rc = OSPF_API_NOSUCHINTERFACE; - goto out; - } - area = oi->area; - lsdb = area->lsdb; - break; - case OSPF_OPAQUE_AREA_LSA: - area = ospf_area_lookup_by_area_id (ospf, omsg->area_id); - if (!area) - { - zlog_warn ("apiserver_originate: unknown area %s", - inet_ntoa (omsg->area_id)); - rc = OSPF_API_NOSUCHAREA; - goto out; - } - lsdb = area->lsdb; - break; - case OSPF_OPAQUE_AS_LSA: - lsdb = ospf->lsdb; - break; - default: - /* We can only handle opaque types here */ - zlog_warn ("apiserver_originate: Cannot originate non-opaque LSA type %d", - data->type); - rc = OSPF_API_ILLEGALLSATYPE; - goto out; - } - - /* Check if we registered this opaque type */ - lsa_type = data->type; - opaque_type = GET_OPAQUE_TYPE (ntohl (data->id.s_addr)); - - if (!apiserver_is_opaque_type_registered (apiserv, lsa_type, opaque_type)) - { - zlog_warn ("apiserver_originate: LSA-type(%d)/Opaque-type(%d): Not registered", lsa_type, opaque_type); - rc = OSPF_API_OPAQUETYPENOTREGISTERED; - goto out; - } - - /* Make sure that the neighbors are ready before we can originate */ - switch (data->type) - { - case OSPF_OPAQUE_LINK_LSA: - ready = ospf_apiserver_is_ready_type9 (oi); - break; - case OSPF_OPAQUE_AREA_LSA: - ready = ospf_apiserver_is_ready_type10 (area); - break; - case OSPF_OPAQUE_AS_LSA: - ready = ospf_apiserver_is_ready_type11 (ospf); - break; - default: - break; - } - - if (!ready) - { - zlog_warn ("Neighbors not ready to originate type %d", data->type); - rc = OSPF_API_NOTREADY; - goto out; - } - - /* Create OSPF's internal opaque LSA representation */ - new = ospf_apiserver_opaque_lsa_new (area, oi, data); - if (!new) - { - rc = OSPF_API_NOMEMORY; /* XXX */ - goto out; - } - - /* Determine if LSA is new or an update for an existing one. */ - old = ospf_lsdb_lookup (lsdb, new); - - if (!old) - { - /* New LSA install in LSDB. */ - rc = ospf_apiserver_originate1 (new); - } - else - { - /* - * Keep the new LSA instance in the "waiting place" until the next - * refresh timing. If several LSA update requests for the same LSID - * have issued by peer, the last one takes effect. - */ - new->lsdb = &apiserv->reserve; - ospf_lsdb_add (&apiserv->reserve, new); - - /* Kick the scheduler function. */ - ospf_opaque_lsa_refresh_schedule (old); - } + struct msg_originate_request *omsg; + struct lsa_header *data; + struct ospf_lsa *new; + struct ospf_lsa *old; + struct ospf_area *area = NULL; + struct ospf_interface *oi = NULL; + struct ospf_lsdb *lsdb = NULL; + struct ospf *ospf; + int lsa_type, opaque_type; + int ready = 0; + int rc = 0; + + ospf = ospf_lookup(); + + /* Extract opaque LSA data from message */ + omsg = (struct msg_originate_request *)STREAM_DATA(msg->s); + data = &omsg->data; + + /* Determine interface for type9 or area for type10 LSAs. */ + switch (data->type) { + case OSPF_OPAQUE_LINK_LSA: + oi = ospf_apiserver_if_lookup_by_addr(omsg->ifaddr); + if (!oi) { + zlog_warn("apiserver_originate: unknown interface %s", + inet_ntoa(omsg->ifaddr)); + rc = OSPF_API_NOSUCHINTERFACE; + goto out; + } + area = oi->area; + lsdb = area->lsdb; + break; + case OSPF_OPAQUE_AREA_LSA: + area = ospf_area_lookup_by_area_id(ospf, omsg->area_id); + if (!area) { + zlog_warn("apiserver_originate: unknown area %s", + inet_ntoa(omsg->area_id)); + rc = OSPF_API_NOSUCHAREA; + goto out; + } + lsdb = area->lsdb; + break; + case OSPF_OPAQUE_AS_LSA: + lsdb = ospf->lsdb; + break; + default: + /* We can only handle opaque types here */ + zlog_warn( + "apiserver_originate: Cannot originate non-opaque LSA type %d", + data->type); + rc = OSPF_API_ILLEGALLSATYPE; + goto out; + } + + /* Check if we registered this opaque type */ + lsa_type = data->type; + opaque_type = GET_OPAQUE_TYPE(ntohl(data->id.s_addr)); + + if (!apiserver_is_opaque_type_registered(apiserv, lsa_type, + opaque_type)) { + zlog_warn( + "apiserver_originate: LSA-type(%d)/Opaque-type(%d): Not registered", + lsa_type, opaque_type); + rc = OSPF_API_OPAQUETYPENOTREGISTERED; + goto out; + } + + /* Make sure that the neighbors are ready before we can originate */ + switch (data->type) { + case OSPF_OPAQUE_LINK_LSA: + ready = ospf_apiserver_is_ready_type9(oi); + break; + case OSPF_OPAQUE_AREA_LSA: + ready = ospf_apiserver_is_ready_type10(area); + break; + case OSPF_OPAQUE_AS_LSA: + ready = ospf_apiserver_is_ready_type11(ospf); + break; + default: + break; + } + + if (!ready) { + zlog_warn("Neighbors not ready to originate type %d", + data->type); + rc = OSPF_API_NOTREADY; + goto out; + } + + /* Create OSPF's internal opaque LSA representation */ + new = ospf_apiserver_opaque_lsa_new(area, oi, data); + if (!new) { + rc = OSPF_API_NOMEMORY; /* XXX */ + goto out; + } + + /* Determine if LSA is new or an update for an existing one. */ + old = ospf_lsdb_lookup(lsdb, new); + + if (!old) { + /* New LSA install in LSDB. */ + rc = ospf_apiserver_originate1(new); + } else { + /* + * Keep the new LSA instance in the "waiting place" until the + * next + * refresh timing. If several LSA update requests for the same + * LSID + * have issued by peer, the last one takes effect. + */ + new->lsdb = &apiserv->reserve; + ospf_lsdb_add(&apiserv->reserve, new); + + /* Kick the scheduler function. */ + ospf_opaque_lsa_refresh_schedule(old); + } out: - /* Send a reply back to client with return code */ - rc = ospf_apiserver_send_reply (apiserv, ntohl (msg->hdr.msgseq), rc); - return rc; + /* Send a reply back to client with return code */ + rc = ospf_apiserver_send_reply(apiserv, ntohl(msg->hdr.msgseq), rc); + return rc; } /* ----------------------------------------------------------- - * Flood an LSA within its flooding scope. + * Flood an LSA within its flooding scope. * ----------------------------------------------------------- */ /* XXX We can probably use ospf_flood_through instead of this function - but then we need the neighbor parameter. If we set nbr to + but then we need the neighbor parameter. If we set nbr to NULL then ospf_flood_through crashes due to dereferencing NULL. */ -void -ospf_apiserver_flood_opaque_lsa (struct ospf_lsa *lsa) +void ospf_apiserver_flood_opaque_lsa(struct ospf_lsa *lsa) { - assert (lsa); - - switch (lsa->data->type) - { - case OSPF_OPAQUE_LINK_LSA: - /* Increment counters? XXX */ - - /* Flood LSA through local network. */ - ospf_flood_through_area (lsa->area, NULL /*nbr */ , lsa); - break; - case OSPF_OPAQUE_AREA_LSA: - /* Update LSA origination count. */ - assert (lsa->area); - lsa->area->ospf->lsa_originate_count++; - - /* Flood LSA through area. */ - ospf_flood_through_area (lsa->area, NULL /*nbr */ , lsa); - break; - case OSPF_OPAQUE_AS_LSA: - { - struct ospf *ospf; - - ospf = ospf_lookup(); - assert(ospf); - - /* Increment counters? XXX */ - - /* Flood LSA through AS. */ - ospf_flood_through_as (ospf, NULL /*nbr */ , lsa); - break; - } - } + assert(lsa); + + switch (lsa->data->type) { + case OSPF_OPAQUE_LINK_LSA: + /* Increment counters? XXX */ + + /* Flood LSA through local network. */ + ospf_flood_through_area(lsa->area, NULL /*nbr */, lsa); + break; + case OSPF_OPAQUE_AREA_LSA: + /* Update LSA origination count. */ + assert(lsa->area); + lsa->area->ospf->lsa_originate_count++; + + /* Flood LSA through area. */ + ospf_flood_through_area(lsa->area, NULL /*nbr */, lsa); + break; + case OSPF_OPAQUE_AS_LSA: { + struct ospf *ospf; + + ospf = ospf_lookup(); + assert(ospf); + + /* Increment counters? XXX */ + + /* Flood LSA through AS. */ + ospf_flood_through_as(ospf, NULL /*nbr */, lsa); + break; + } + } } -int -ospf_apiserver_originate1 (struct ospf_lsa *lsa) +int ospf_apiserver_originate1(struct ospf_lsa *lsa) { - struct ospf *ospf; + struct ospf *ospf; - ospf = ospf_lookup(); - assert(ospf); + ospf = ospf_lookup(); + assert(ospf); - /* Install this LSA into LSDB. */ - if (ospf_lsa_install (ospf, lsa->oi, lsa) == NULL) - { - zlog_warn ("ospf_apiserver_originate1: ospf_lsa_install failed"); - return -1; - } + /* Install this LSA into LSDB. */ + if (ospf_lsa_install(ospf, lsa->oi, lsa) == NULL) { + zlog_warn("ospf_apiserver_originate1: ospf_lsa_install failed"); + return -1; + } - /* Flood LSA within scope */ +/* Flood LSA within scope */ #ifdef NOTYET - /* - * NB: Modified version of "ospf_flood_though ()" accepts NULL "inbr" - * parameter, and thus it does not cause SIGSEGV error. - */ - ospf_flood_through (NULL /*nbr */ , lsa); -#else /* NOTYET */ - - ospf_apiserver_flood_opaque_lsa (lsa); + /* + * NB: Modified version of "ospf_flood_though ()" accepts NULL "inbr" + * parameter, and thus it does not cause SIGSEGV error. + */ + ospf_flood_through(NULL /*nbr */, lsa); +#else /* NOTYET */ + + ospf_apiserver_flood_opaque_lsa(lsa); #endif /* NOTYET */ - return 0; + return 0; } /* Opaque LSAs of type 9 on a specific interface can now be originated. Tell clients that registered type 9. */ -int -ospf_apiserver_lsa9_originator (void *arg) +int ospf_apiserver_lsa9_originator(void *arg) { - struct ospf_interface *oi; + struct ospf_interface *oi; - oi = (struct ospf_interface *) arg; - if (listcount (apiserver_list) > 0) { - ospf_apiserver_clients_notify_ready_type9 (oi); - } - return 0; + oi = (struct ospf_interface *)arg; + if (listcount(apiserver_list) > 0) { + ospf_apiserver_clients_notify_ready_type9(oi); + } + return 0; } -int -ospf_apiserver_lsa10_originator (void *arg) +int ospf_apiserver_lsa10_originator(void *arg) { - struct ospf_area *area; + struct ospf_area *area; - area = (struct ospf_area *) arg; - if (listcount (apiserver_list) > 0) { - ospf_apiserver_clients_notify_ready_type10 (area); - } - return 0; + area = (struct ospf_area *)arg; + if (listcount(apiserver_list) > 0) { + ospf_apiserver_clients_notify_ready_type10(area); + } + return 0; } -int -ospf_apiserver_lsa11_originator (void *arg) +int ospf_apiserver_lsa11_originator(void *arg) { - struct ospf *ospf; + struct ospf *ospf; - ospf = (struct ospf *) arg; - if (listcount (apiserver_list) > 0) { - ospf_apiserver_clients_notify_ready_type11 (ospf); - } - return 0; + ospf = (struct ospf *)arg; + if (listcount(apiserver_list) > 0) { + ospf_apiserver_clients_notify_ready_type11(ospf); + } + return 0; } /* Periodically refresh opaque LSAs so that they do not expire in other routers. */ -struct ospf_lsa * -ospf_apiserver_lsa_refresher (struct ospf_lsa *lsa) +struct ospf_lsa *ospf_apiserver_lsa_refresher(struct ospf_lsa *lsa) { - struct ospf_apiserver *apiserv; - struct ospf_lsa *new = NULL; - struct ospf * ospf; - - ospf = ospf_lookup(); - assert(ospf); - - apiserv = lookup_apiserver_by_lsa (lsa); - if (!apiserv) - { - zlog_warn ("ospf_apiserver_lsa_refresher: LSA[%s]: No apiserver?", dump_lsa_key (lsa)); - lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); /* Flush it anyway. */ - } - - if (IS_LSA_MAXAGE (lsa)) - { - ospf_opaque_lsa_flush_schedule (lsa); - goto out; - } - - /* Check if updated version of LSA instance has already prepared. */ - new = ospf_lsdb_lookup (&apiserv->reserve, lsa); - if (!new) - { - /* This is a periodic refresh, driven by core OSPF mechanism. */ - new = ospf_apiserver_opaque_lsa_new (lsa->area, lsa->oi, lsa->data); - if (!new) - { - zlog_warn ("ospf_apiserver_lsa_refresher: Cannot create a new LSA?"); - goto out; - } - } - else - { - /* This is a forcible refresh, requested by OSPF-API client. */ - ospf_lsdb_delete (&apiserv->reserve, new); - new->lsdb = NULL; - } - - /* Increment sequence number */ - new->data->ls_seqnum = lsa_seqnum_increment (lsa); - - /* New LSA is in same area. */ - new->area = lsa->area; - SET_FLAG (new->flags, OSPF_LSA_SELF); - - /* Install LSA into LSDB. */ - if (ospf_lsa_install (ospf, new->oi, new) == NULL) - { - zlog_warn ("ospf_apiserver_lsa_refresher: ospf_lsa_install failed"); - ospf_lsa_unlock (&new); - goto out; - } - - /* Flood updated LSA through interface, area or AS */ + struct ospf_apiserver *apiserv; + struct ospf_lsa *new = NULL; + struct ospf *ospf; + + ospf = ospf_lookup(); + assert(ospf); + + apiserv = lookup_apiserver_by_lsa(lsa); + if (!apiserv) { + zlog_warn( + "ospf_apiserver_lsa_refresher: LSA[%s]: No apiserver?", + dump_lsa_key(lsa)); + lsa->data->ls_age = + htons(OSPF_LSA_MAXAGE); /* Flush it anyway. */ + } + + if (IS_LSA_MAXAGE(lsa)) { + ospf_opaque_lsa_flush_schedule(lsa); + goto out; + } + + /* Check if updated version of LSA instance has already prepared. */ + new = ospf_lsdb_lookup(&apiserv->reserve, lsa); + if (!new) { + /* This is a periodic refresh, driven by core OSPF mechanism. */ + new = ospf_apiserver_opaque_lsa_new(lsa->area, lsa->oi, + lsa->data); + if (!new) { + zlog_warn( + "ospf_apiserver_lsa_refresher: Cannot create a new LSA?"); + goto out; + } + } else { + /* This is a forcible refresh, requested by OSPF-API client. */ + ospf_lsdb_delete(&apiserv->reserve, new); + new->lsdb = NULL; + } + + /* Increment sequence number */ + new->data->ls_seqnum = lsa_seqnum_increment(lsa); + + /* New LSA is in same area. */ + new->area = lsa->area; + SET_FLAG(new->flags, OSPF_LSA_SELF); + + /* Install LSA into LSDB. */ + if (ospf_lsa_install(ospf, new->oi, new) == NULL) { + zlog_warn( + "ospf_apiserver_lsa_refresher: ospf_lsa_install failed"); + ospf_lsa_unlock(&new); + goto out; + } + +/* Flood updated LSA through interface, area or AS */ #ifdef NOTYET - ospf_flood_through (NULL /*nbr */ , new); + ospf_flood_through(NULL /*nbr */, new); #endif /* NOTYET */ - ospf_apiserver_flood_opaque_lsa (new); + ospf_apiserver_flood_opaque_lsa(new); - /* Debug logging. */ - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - { - zlog_debug ("LSA[Type%d:%s]: Refresh Opaque LSA", - new->data->type, inet_ntoa (new->data->id)); - ospf_lsa_header_dump (new->data); - } + /* Debug logging. */ + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { + zlog_debug("LSA[Type%d:%s]: Refresh Opaque LSA", + new->data->type, inet_ntoa(new->data->id)); + ospf_lsa_header_dump(new->data); + } out: - return new; + return new; } @@ -1906,319 +1799,308 @@ out: * ----------------------------------------------------------- */ -int -ospf_apiserver_handle_delete_request (struct ospf_apiserver *apiserv, - struct msg *msg) +int ospf_apiserver_handle_delete_request(struct ospf_apiserver *apiserv, + struct msg *msg) { - struct msg_delete_request *dmsg; - struct ospf_lsa *old; - struct ospf_area *area = NULL; - struct in_addr id; - int lsa_type, opaque_type; - int rc = 0; - struct ospf * ospf; - - ospf = ospf_lookup(); - assert(ospf); - - /* Extract opaque LSA from message */ - dmsg = (struct msg_delete_request *) STREAM_DATA (msg->s); - - /* Lookup area for link-local and area-local opaque LSAs */ - switch (dmsg->lsa_type) - { - case OSPF_OPAQUE_LINK_LSA: - case OSPF_OPAQUE_AREA_LSA: - area = ospf_area_lookup_by_area_id (ospf, dmsg->area_id); - if (!area) - { - zlog_warn ("ospf_apiserver_lsa_delete: unknown area %s", - inet_ntoa (dmsg->area_id)); - rc = OSPF_API_NOSUCHAREA; - goto out; - } - break; - case OSPF_OPAQUE_AS_LSA: - /* AS-external opaque LSAs have no designated area */ - area = NULL; - break; - default: - zlog_warn - ("ospf_apiserver_lsa_delete: Cannot delete non-opaque LSA type %d", - dmsg->lsa_type); - rc = OSPF_API_ILLEGALLSATYPE; - goto out; - } - - /* Check if we registered this opaque type */ - lsa_type = dmsg->lsa_type; - opaque_type = dmsg->opaque_type; - - if (!apiserver_is_opaque_type_registered (apiserv, lsa_type, opaque_type)) - { - zlog_warn ("ospf_apiserver_lsa_delete: LSA-type(%d)/Opaque-type(%d): Not registered", lsa_type, opaque_type); - rc = OSPF_API_OPAQUETYPENOTREGISTERED; - goto out; - } - - /* opaque_id is in network byte order */ - id.s_addr = htonl (SET_OPAQUE_LSID (dmsg->opaque_type, - ntohl (dmsg->opaque_id))); - - /* - * Even if the target LSA has once scheduled to flush, it remains in - * the LSDB until it is finally handled by the maxage remover thread. - * Therefore, the lookup function below may return non-NULL result. - */ - old = ospf_lsa_lookup (area, dmsg->lsa_type, id, ospf->router_id); - if (!old) - { - zlog_warn ("ospf_apiserver_lsa_delete: LSA[Type%d:%s] not in LSDB", - dmsg->lsa_type, inet_ntoa (id)); - rc = OSPF_API_NOSUCHLSA; - goto out; - } - - /* Schedule flushing of LSA from LSDB */ - /* NB: Multiple scheduling will produce a warning message, but harmless. */ - ospf_opaque_lsa_flush_schedule (old); + struct msg_delete_request *dmsg; + struct ospf_lsa *old; + struct ospf_area *area = NULL; + struct in_addr id; + int lsa_type, opaque_type; + int rc = 0; + struct ospf *ospf; + + ospf = ospf_lookup(); + assert(ospf); + + /* Extract opaque LSA from message */ + dmsg = (struct msg_delete_request *)STREAM_DATA(msg->s); + + /* Lookup area for link-local and area-local opaque LSAs */ + switch (dmsg->lsa_type) { + case OSPF_OPAQUE_LINK_LSA: + case OSPF_OPAQUE_AREA_LSA: + area = ospf_area_lookup_by_area_id(ospf, dmsg->area_id); + if (!area) { + zlog_warn("ospf_apiserver_lsa_delete: unknown area %s", + inet_ntoa(dmsg->area_id)); + rc = OSPF_API_NOSUCHAREA; + goto out; + } + break; + case OSPF_OPAQUE_AS_LSA: + /* AS-external opaque LSAs have no designated area */ + area = NULL; + break; + default: + zlog_warn( + "ospf_apiserver_lsa_delete: Cannot delete non-opaque LSA type %d", + dmsg->lsa_type); + rc = OSPF_API_ILLEGALLSATYPE; + goto out; + } + + /* Check if we registered this opaque type */ + lsa_type = dmsg->lsa_type; + opaque_type = dmsg->opaque_type; + + if (!apiserver_is_opaque_type_registered(apiserv, lsa_type, + opaque_type)) { + zlog_warn( + "ospf_apiserver_lsa_delete: LSA-type(%d)/Opaque-type(%d): Not registered", + lsa_type, opaque_type); + rc = OSPF_API_OPAQUETYPENOTREGISTERED; + goto out; + } + + /* opaque_id is in network byte order */ + id.s_addr = htonl( + SET_OPAQUE_LSID(dmsg->opaque_type, ntohl(dmsg->opaque_id))); + + /* + * Even if the target LSA has once scheduled to flush, it remains in + * the LSDB until it is finally handled by the maxage remover thread. + * Therefore, the lookup function below may return non-NULL result. + */ + old = ospf_lsa_lookup(area, dmsg->lsa_type, id, ospf->router_id); + if (!old) { + zlog_warn( + "ospf_apiserver_lsa_delete: LSA[Type%d:%s] not in LSDB", + dmsg->lsa_type, inet_ntoa(id)); + rc = OSPF_API_NOSUCHLSA; + goto out; + } + + /* Schedule flushing of LSA from LSDB */ + /* NB: Multiple scheduling will produce a warning message, but harmless. + */ + ospf_opaque_lsa_flush_schedule(old); out: - /* Send reply back to client including return code */ - rc = ospf_apiserver_send_reply (apiserv, ntohl (msg->hdr.msgseq), rc); - return rc; + /* Send reply back to client including return code */ + rc = ospf_apiserver_send_reply(apiserv, ntohl(msg->hdr.msgseq), rc); + return rc; } /* Flush self-originated opaque LSA */ -static int -apiserver_flush_opaque_type_callback (struct ospf_lsa *lsa, - void *p_arg, int int_arg) +static int apiserver_flush_opaque_type_callback(struct ospf_lsa *lsa, + void *p_arg, int int_arg) { - struct param_t - { - struct ospf_apiserver *apiserv; - u_char lsa_type; - u_char opaque_type; - } - *param; - - /* Sanity check */ - assert (lsa->data); - assert (p_arg); - param = (struct param_t *) p_arg; - - /* If LSA matches type and opaque type then delete it */ - if (IS_LSA_SELF (lsa) && lsa->data->type == param->lsa_type - && GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)) == param->opaque_type) - { - ospf_opaque_lsa_flush_schedule (lsa); - } - return 0; + struct param_t { + struct ospf_apiserver *apiserv; + u_char lsa_type; + u_char opaque_type; + } * param; + + /* Sanity check */ + assert(lsa->data); + assert(p_arg); + param = (struct param_t *)p_arg; + + /* If LSA matches type and opaque type then delete it */ + if (IS_LSA_SELF(lsa) && lsa->data->type == param->lsa_type + && GET_OPAQUE_TYPE(ntohl(lsa->data->id.s_addr)) + == param->opaque_type) { + ospf_opaque_lsa_flush_schedule(lsa); + } + return 0; } /* Delete self-originated opaque LSAs of a given opaque type. This function is called when an application unregisters a given opaque type or a connection to an application closes and all those opaque LSAs need to be flushed the LSDB. */ -void -ospf_apiserver_flush_opaque_lsa (struct ospf_apiserver *apiserv, - u_char lsa_type, u_char opaque_type) +void ospf_apiserver_flush_opaque_lsa(struct ospf_apiserver *apiserv, + u_char lsa_type, u_char opaque_type) { - struct param_t - { - struct ospf_apiserver *apiserv; - u_char lsa_type; - u_char opaque_type; - } param; - struct listnode *node, *nnode; - struct ospf * ospf; - struct ospf_area *area; - - ospf = ospf_lookup(); - assert(ospf); - - /* Set parameter struct. */ - param.apiserv = apiserv; - param.lsa_type = lsa_type; - param.opaque_type = opaque_type; - - switch (lsa_type) - { - struct route_node *rn; - struct ospf_lsa *lsa; - - case OSPF_OPAQUE_LINK_LSA: - for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area)) - LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa) - apiserver_flush_opaque_type_callback(lsa, (void *) ¶m, 0); - break; - case OSPF_OPAQUE_AREA_LSA: - for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area)) - LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa) - apiserver_flush_opaque_type_callback(lsa, (void *) ¶m, 0); - break; - case OSPF_OPAQUE_AS_LSA: - LSDB_LOOP (OPAQUE_LINK_LSDB (ospf), rn, lsa) - apiserver_flush_opaque_type_callback(lsa, (void *) ¶m, 0); - break; - default: - break; - } - return; + struct param_t { + struct ospf_apiserver *apiserv; + u_char lsa_type; + u_char opaque_type; + } param; + struct listnode *node, *nnode; + struct ospf *ospf; + struct ospf_area *area; + + ospf = ospf_lookup(); + assert(ospf); + + /* Set parameter struct. */ + param.apiserv = apiserv; + param.lsa_type = lsa_type; + param.opaque_type = opaque_type; + + switch (lsa_type) { + struct route_node *rn; + struct ospf_lsa *lsa; + + case OSPF_OPAQUE_LINK_LSA: + for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) + LSDB_LOOP(OPAQUE_LINK_LSDB(area), rn, lsa) + apiserver_flush_opaque_type_callback(lsa, (void *)¶m, 0); + break; + case OSPF_OPAQUE_AREA_LSA: + for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) + LSDB_LOOP(OPAQUE_AREA_LSDB(area), rn, lsa) + apiserver_flush_opaque_type_callback(lsa, (void *)¶m, 0); + break; + case OSPF_OPAQUE_AS_LSA: + LSDB_LOOP(OPAQUE_LINK_LSDB(ospf), rn, lsa) + apiserver_flush_opaque_type_callback(lsa, (void *)¶m, 0); + break; + default: + break; + } + return; } /* ----------------------------------------------------------- - * Followings are callback functions to handle opaque types + * Followings are callback functions to handle opaque types * ----------------------------------------------------------- */ -int -ospf_apiserver_new_if (struct interface *ifp) +int ospf_apiserver_new_if(struct interface *ifp) { - struct ospf_interface *oi; - - /* For some strange reason it seems possible that we are invoked - with an interface that has no name. This seems to happen during - initialization. Return if this happens */ - - if (ifp->name[0] == '\0') { - /* interface has empty name */ - zlog_warn ("ospf_apiserver_new_if: interface has no name?"); - return 0; - } - - /* zlog_warn for debugging */ - zlog_warn ("ospf_apiserver_new_if"); - zlog_warn ("ifp name=%s status=%d index=%d", ifp->name, ifp->status, - ifp->ifindex); - - if (ifp->name[0] == '\0') { - /* interface has empty name */ - zlog_warn ("ospf_apiserver_new_if: interface has no name?"); - return 0; - } - - oi = ospf_apiserver_if_lookup_by_ifp (ifp); - - if (!oi) { - /* This interface is known to Zebra but not to OSPF daemon yet. */ - zlog_warn ("ospf_apiserver_new_if: interface %s not known to OSPFd?", - ifp->name); - return 0; - } - - assert (oi); - - /* New interface added to OSPF, tell clients about it */ - if (listcount (apiserver_list) > 0) { - ospf_apiserver_clients_notify_new_if (oi); - } - return 0; + struct ospf_interface *oi; + + /* For some strange reason it seems possible that we are invoked + with an interface that has no name. This seems to happen during + initialization. Return if this happens */ + + if (ifp->name[0] == '\0') { + /* interface has empty name */ + zlog_warn("ospf_apiserver_new_if: interface has no name?"); + return 0; + } + + /* zlog_warn for debugging */ + zlog_warn("ospf_apiserver_new_if"); + zlog_warn("ifp name=%s status=%d index=%d", ifp->name, ifp->status, + ifp->ifindex); + + if (ifp->name[0] == '\0') { + /* interface has empty name */ + zlog_warn("ospf_apiserver_new_if: interface has no name?"); + return 0; + } + + oi = ospf_apiserver_if_lookup_by_ifp(ifp); + + if (!oi) { + /* This interface is known to Zebra but not to OSPF daemon yet. + */ + zlog_warn( + "ospf_apiserver_new_if: interface %s not known to OSPFd?", + ifp->name); + return 0; + } + + assert(oi); + + /* New interface added to OSPF, tell clients about it */ + if (listcount(apiserver_list) > 0) { + ospf_apiserver_clients_notify_new_if(oi); + } + return 0; } -int -ospf_apiserver_del_if (struct interface *ifp) +int ospf_apiserver_del_if(struct interface *ifp) { - struct ospf_interface *oi; - - /* zlog_warn for debugging */ - zlog_warn ("ospf_apiserver_del_if"); - zlog_warn ("ifp name=%s status=%d index=%d\n", ifp->name, ifp->status, - ifp->ifindex); - - oi = ospf_apiserver_if_lookup_by_ifp (ifp); - - if (!oi) { - /* This interface is known to Zebra but not to OSPF daemon - anymore. No need to tell clients about it */ - return 0; - } - - /* Interface deleted, tell clients about it */ - if (listcount (apiserver_list) > 0) { - ospf_apiserver_clients_notify_del_if (oi); - } - return 0; + struct ospf_interface *oi; + + /* zlog_warn for debugging */ + zlog_warn("ospf_apiserver_del_if"); + zlog_warn("ifp name=%s status=%d index=%d\n", ifp->name, ifp->status, + ifp->ifindex); + + oi = ospf_apiserver_if_lookup_by_ifp(ifp); + + if (!oi) { + /* This interface is known to Zebra but not to OSPF daemon + anymore. No need to tell clients about it */ + return 0; + } + + /* Interface deleted, tell clients about it */ + if (listcount(apiserver_list) > 0) { + ospf_apiserver_clients_notify_del_if(oi); + } + return 0; } -void -ospf_apiserver_ism_change (struct ospf_interface *oi, int old_state) +void ospf_apiserver_ism_change(struct ospf_interface *oi, int old_state) { - /* Tell clients about interface change */ + /* Tell clients about interface change */ - /* zlog_warn for debugging */ - zlog_warn ("ospf_apiserver_ism_change"); - if (listcount (apiserver_list) > 0) { - ospf_apiserver_clients_notify_ism_change (oi); - } + /* zlog_warn for debugging */ + zlog_warn("ospf_apiserver_ism_change"); + if (listcount(apiserver_list) > 0) { + ospf_apiserver_clients_notify_ism_change(oi); + } - zlog_warn ("oi->ifp->name=%s", oi->ifp->name); - zlog_warn ("old_state=%d", old_state); - zlog_warn ("oi->state=%d", oi->state); + zlog_warn("oi->ifp->name=%s", oi->ifp->name); + zlog_warn("old_state=%d", old_state); + zlog_warn("oi->state=%d", oi->state); } -void -ospf_apiserver_nsm_change (struct ospf_neighbor *nbr, int old_status) +void ospf_apiserver_nsm_change(struct ospf_neighbor *nbr, int old_status) { - /* Neighbor status changed, tell clients about it */ - zlog_warn ("ospf_apiserver_nsm_change"); - if (listcount (apiserver_list) > 0) { - ospf_apiserver_clients_notify_nsm_change (nbr); - } + /* Neighbor status changed, tell clients about it */ + zlog_warn("ospf_apiserver_nsm_change"); + if (listcount(apiserver_list) > 0) { + ospf_apiserver_clients_notify_nsm_change(nbr); + } } -void -ospf_apiserver_show_info (struct vty *vty, struct ospf_lsa *lsa) +void ospf_apiserver_show_info(struct vty *vty, struct ospf_lsa *lsa) { - struct opaque_lsa - { - struct lsa_header header; - u_char data[1]; /* opaque data have variable length. This is start - address */ - }; - struct opaque_lsa *olsa; - int opaquelen; - - olsa = (struct opaque_lsa *) lsa->data; - - if (VALID_OPAQUE_INFO_LEN (lsa->data)) - opaquelen = ntohs (lsa->data->length) - OSPF_LSA_HEADER_SIZE; - else - opaquelen = 0; - - /* Output information about opaque LSAs */ - if (vty != NULL) - { - int i; - vty_out (vty, " Added using OSPF API: %u octets of opaque data %s\n", - opaquelen, - VALID_OPAQUE_INFO_LEN(lsa->data) ? "" : "(Invalid length?)"); - vty_out (vty, " Opaque data: "); - - for (i = 0; i < opaquelen; i++) - { - vty_out (vty, "0x%x ", olsa->data[i]); - } - vty_out (vty, "\n"); - } - else - { - int i; - zlog_debug (" Added using OSPF API: %u octets of opaque data %s", - opaquelen, - VALID_OPAQUE_INFO_LEN (lsa-> - data) ? "" : "(Invalid length?)"); - zlog_debug (" Opaque data: "); - - for (i = 0; i < opaquelen; i++) - { - zlog_debug ("0x%x ", olsa->data[i]); - } - zlog_debug ("\n"); - } - return; + struct opaque_lsa { + struct lsa_header header; + u_char data[1]; /* opaque data have variable length. This is + start + address */ + }; + struct opaque_lsa *olsa; + int opaquelen; + + olsa = (struct opaque_lsa *)lsa->data; + + if (VALID_OPAQUE_INFO_LEN(lsa->data)) + opaquelen = ntohs(lsa->data->length) - OSPF_LSA_HEADER_SIZE; + else + opaquelen = 0; + + /* Output information about opaque LSAs */ + if (vty != NULL) { + int i; + vty_out(vty, + " Added using OSPF API: %u octets of opaque data %s\n", + opaquelen, + VALID_OPAQUE_INFO_LEN(lsa->data) ? "" + : "(Invalid length?)"); + vty_out(vty, " Opaque data: "); + + for (i = 0; i < opaquelen; i++) { + vty_out(vty, "0x%x ", olsa->data[i]); + } + vty_out(vty, "\n"); + } else { + int i; + zlog_debug( + " Added using OSPF API: %u octets of opaque data %s", + opaquelen, + VALID_OPAQUE_INFO_LEN(lsa->data) ? "" + : "(Invalid length?)"); + zlog_debug(" Opaque data: "); + + for (i = 0; i < opaquelen; i++) { + zlog_debug("0x%x ", olsa->data[i]); + } + zlog_debug("\n"); + } + return; } /* ----------------------------------------------------------- @@ -2230,343 +2112,311 @@ ospf_apiserver_show_info (struct vty *vty, struct ospf_lsa *lsa) that need to be notified to all clients (such as interface changes) */ -void -ospf_apiserver_clients_notify_all (struct msg *msg) +void ospf_apiserver_clients_notify_all(struct msg *msg) { - struct listnode *node, *nnode; - struct ospf_apiserver *apiserv; + struct listnode *node, *nnode; + struct ospf_apiserver *apiserv; - /* Send message to all clients */ - for (ALL_LIST_ELEMENTS (apiserver_list, node, nnode, apiserv)) - ospf_apiserver_send_msg (apiserv, msg); + /* Send message to all clients */ + for (ALL_LIST_ELEMENTS(apiserver_list, node, nnode, apiserv)) + ospf_apiserver_send_msg(apiserv, msg); } /* An interface is now ready to accept opaque LSAs. Notify all clients that registered to use this opaque type */ -void -ospf_apiserver_clients_notify_ready_type9 (struct ospf_interface *oi) +void ospf_apiserver_clients_notify_ready_type9(struct ospf_interface *oi) { - struct listnode *node, *nnode; - struct msg *msg; - struct ospf_apiserver *apiserv; - - assert (oi); - if (!oi->address) - { - zlog_warn ("Interface has no address?"); - return; - } - - if (!ospf_apiserver_is_ready_type9 (oi)) - { - zlog_warn ("Interface not ready for type 9?"); - return; - } - - for (ALL_LIST_ELEMENTS (apiserver_list, node, nnode, apiserv)) - { - struct listnode *node2, *nnode2; - struct registered_opaque_type *r; - - for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node2, nnode2, r)) - { - if (r->lsa_type == OSPF_OPAQUE_LINK_LSA) - { - msg = new_msg_ready_notify (0, OSPF_OPAQUE_LINK_LSA, - r->opaque_type, - oi->address->u.prefix4); - if (!msg) - { - zlog_warn - ("ospf_apiserver_clients_notify_ready_type9: new_msg_ready_notify failed"); + struct listnode *node, *nnode; + struct msg *msg; + struct ospf_apiserver *apiserv; + + assert(oi); + if (!oi->address) { + zlog_warn("Interface has no address?"); + return; + } + + if (!ospf_apiserver_is_ready_type9(oi)) { + zlog_warn("Interface not ready for type 9?"); + return; + } + + for (ALL_LIST_ELEMENTS(apiserver_list, node, nnode, apiserv)) { + struct listnode *node2, *nnode2; + struct registered_opaque_type *r; + + for (ALL_LIST_ELEMENTS(apiserv->opaque_types, node2, nnode2, + r)) { + if (r->lsa_type == OSPF_OPAQUE_LINK_LSA) { + msg = new_msg_ready_notify( + 0, OSPF_OPAQUE_LINK_LSA, r->opaque_type, + oi->address->u.prefix4); + if (!msg) { + zlog_warn( + "ospf_apiserver_clients_notify_ready_type9: new_msg_ready_notify failed"); #ifdef NOTYET - /* Cannot allocate new message. What should we do? */ - ospf_apiserver_free (apiserv); + /* Cannot allocate new message. What + * should we do? */ + ospf_apiserver_free(apiserv); #endif - goto out; - } + goto out; + } - ospf_apiserver_send_msg (apiserv, msg); - msg_free (msg); - } + ospf_apiserver_send_msg(apiserv, msg); + msg_free(msg); + } + } } - } out: - return; + return; } -void -ospf_apiserver_clients_notify_ready_type10 (struct ospf_area *area) +void ospf_apiserver_clients_notify_ready_type10(struct ospf_area *area) { - struct listnode *node, *nnode; - struct msg *msg; - struct ospf_apiserver *apiserv; - - assert (area); - - if (!ospf_apiserver_is_ready_type10 (area)) - { - zlog_warn ("Area not ready for type 10?"); - return; - } - - for (ALL_LIST_ELEMENTS (apiserver_list, node, nnode, apiserv)) - { - struct listnode *node2, *nnode2; - struct registered_opaque_type *r; - - for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node2, nnode2, r)) - { - if (r->lsa_type == OSPF_OPAQUE_AREA_LSA) - { - msg = new_msg_ready_notify (0, OSPF_OPAQUE_AREA_LSA, - r->opaque_type, area->area_id); - if (!msg) - { - zlog_warn - ("ospf_apiserver_clients_notify_ready_type10: new_msg_ready_nofity failed"); + struct listnode *node, *nnode; + struct msg *msg; + struct ospf_apiserver *apiserv; + + assert(area); + + if (!ospf_apiserver_is_ready_type10(area)) { + zlog_warn("Area not ready for type 10?"); + return; + } + + for (ALL_LIST_ELEMENTS(apiserver_list, node, nnode, apiserv)) { + struct listnode *node2, *nnode2; + struct registered_opaque_type *r; + + for (ALL_LIST_ELEMENTS(apiserv->opaque_types, node2, nnode2, + r)) { + if (r->lsa_type == OSPF_OPAQUE_AREA_LSA) { + msg = new_msg_ready_notify( + 0, OSPF_OPAQUE_AREA_LSA, r->opaque_type, + area->area_id); + if (!msg) { + zlog_warn( + "ospf_apiserver_clients_notify_ready_type10: new_msg_ready_nofity failed"); #ifdef NOTYET - /* Cannot allocate new message. What should we do? */ - ospf_apiserver_free (apiserv); + /* Cannot allocate new message. What + * should we do? */ + ospf_apiserver_free(apiserv); #endif - goto out; - } + goto out; + } - ospf_apiserver_send_msg (apiserv, msg); - msg_free (msg); - } + ospf_apiserver_send_msg(apiserv, msg); + msg_free(msg); + } + } } - } out: - return; + return; } -void -ospf_apiserver_clients_notify_ready_type11 (struct ospf *top) +void ospf_apiserver_clients_notify_ready_type11(struct ospf *top) { - struct listnode *node, *nnode; - struct msg *msg; - struct in_addr id_null = { .s_addr = 0L }; - struct ospf_apiserver *apiserv; - - assert (top); - - if (!ospf_apiserver_is_ready_type11 (top)) - { - zlog_warn ("AS not ready for type 11?"); - return; - } - - for (ALL_LIST_ELEMENTS (apiserver_list, node, nnode, apiserv)) - { - struct listnode *node2, *nnode2; - struct registered_opaque_type *r; - - for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node2, nnode2, r)) - { - if (r->lsa_type == OSPF_OPAQUE_AS_LSA) - { - msg = new_msg_ready_notify (0, OSPF_OPAQUE_AS_LSA, - r->opaque_type, id_null); - if (!msg) - { - zlog_warn - ("ospf_apiserver_clients_notify_ready_type11: new_msg_ready_notify failed"); + struct listnode *node, *nnode; + struct msg *msg; + struct in_addr id_null = {.s_addr = 0L}; + struct ospf_apiserver *apiserv; + + assert(top); + + if (!ospf_apiserver_is_ready_type11(top)) { + zlog_warn("AS not ready for type 11?"); + return; + } + + for (ALL_LIST_ELEMENTS(apiserver_list, node, nnode, apiserv)) { + struct listnode *node2, *nnode2; + struct registered_opaque_type *r; + + for (ALL_LIST_ELEMENTS(apiserv->opaque_types, node2, nnode2, + r)) { + if (r->lsa_type == OSPF_OPAQUE_AS_LSA) { + msg = new_msg_ready_notify( + 0, OSPF_OPAQUE_AS_LSA, r->opaque_type, + id_null); + if (!msg) { + zlog_warn( + "ospf_apiserver_clients_notify_ready_type11: new_msg_ready_notify failed"); #ifdef NOTYET - /* Cannot allocate new message. What should we do? */ - ospf_apiserver_free (apiserv); + /* Cannot allocate new message. What + * should we do? */ + ospf_apiserver_free(apiserv); #endif - goto out; - } + goto out; + } - ospf_apiserver_send_msg (apiserv, msg); - msg_free (msg); - } + ospf_apiserver_send_msg(apiserv, msg); + msg_free(msg); + } + } } - } out: - return; + return; } -void -ospf_apiserver_clients_notify_new_if (struct ospf_interface *oi) +void ospf_apiserver_clients_notify_new_if(struct ospf_interface *oi) { - struct msg *msg; - - msg = new_msg_new_if (0, oi->address->u.prefix4, oi->area->area_id); - if (msg != NULL) - { - ospf_apiserver_clients_notify_all (msg); - msg_free (msg); - } + struct msg *msg; + + msg = new_msg_new_if(0, oi->address->u.prefix4, oi->area->area_id); + if (msg != NULL) { + ospf_apiserver_clients_notify_all(msg); + msg_free(msg); + } } -void -ospf_apiserver_clients_notify_del_if (struct ospf_interface *oi) +void ospf_apiserver_clients_notify_del_if(struct ospf_interface *oi) { - struct msg *msg; - - msg = new_msg_del_if (0, oi->address->u.prefix4); - if (msg != NULL) - { - ospf_apiserver_clients_notify_all (msg); - msg_free (msg); - } + struct msg *msg; + + msg = new_msg_del_if(0, oi->address->u.prefix4); + if (msg != NULL) { + ospf_apiserver_clients_notify_all(msg); + msg_free(msg); + } } -void -ospf_apiserver_clients_notify_ism_change (struct ospf_interface *oi) +void ospf_apiserver_clients_notify_ism_change(struct ospf_interface *oi) { - struct msg *msg; - struct in_addr ifaddr = { .s_addr = 0L }; - struct in_addr area_id = { .s_addr = 0L }; - - assert (oi); - assert (oi->ifp); - - if (oi->address) - { - ifaddr = oi->address->u.prefix4; - } - if (oi->area) - { - area_id = oi->area->area_id; - } - - msg = new_msg_ism_change (0, ifaddr, area_id, oi->state); - if (!msg) - { - zlog_warn ("apiserver_clients_notify_ism_change: msg_new failed"); - return; - } - - ospf_apiserver_clients_notify_all (msg); - msg_free (msg); + struct msg *msg; + struct in_addr ifaddr = {.s_addr = 0L}; + struct in_addr area_id = {.s_addr = 0L}; + + assert(oi); + assert(oi->ifp); + + if (oi->address) { + ifaddr = oi->address->u.prefix4; + } + if (oi->area) { + area_id = oi->area->area_id; + } + + msg = new_msg_ism_change(0, ifaddr, area_id, oi->state); + if (!msg) { + zlog_warn( + "apiserver_clients_notify_ism_change: msg_new failed"); + return; + } + + ospf_apiserver_clients_notify_all(msg); + msg_free(msg); } -void -ospf_apiserver_clients_notify_nsm_change (struct ospf_neighbor *nbr) +void ospf_apiserver_clients_notify_nsm_change(struct ospf_neighbor *nbr) { - struct msg *msg; - struct in_addr ifaddr = { .s_addr = 0L }; - struct in_addr nbraddr = { .s_addr = 0L }; + struct msg *msg; + struct in_addr ifaddr = {.s_addr = 0L}; + struct in_addr nbraddr = {.s_addr = 0L}; - assert (nbr); + assert(nbr); - if (nbr->oi) - { - ifaddr = nbr->oi->address->u.prefix4; - } + if (nbr->oi) { + ifaddr = nbr->oi->address->u.prefix4; + } - nbraddr = nbr->address.u.prefix4; + nbraddr = nbr->address.u.prefix4; - msg = new_msg_nsm_change (0, ifaddr, nbraddr, nbr->router_id, nbr->state); - if (!msg) - { - zlog_warn ("apiserver_clients_notify_nsm_change: msg_new failed"); - return; - } + msg = new_msg_nsm_change(0, ifaddr, nbraddr, nbr->router_id, + nbr->state); + if (!msg) { + zlog_warn( + "apiserver_clients_notify_nsm_change: msg_new failed"); + return; + } - ospf_apiserver_clients_notify_all (msg); - msg_free (msg); + ospf_apiserver_clients_notify_all(msg); + msg_free(msg); } -static void -apiserver_clients_lsa_change_notify (u_char msgtype, struct ospf_lsa *lsa) +static void apiserver_clients_lsa_change_notify(u_char msgtype, + struct ospf_lsa *lsa) { - struct msg *msg; - struct listnode *node, *nnode; - struct ospf_apiserver *apiserv; - - /* Default area for AS-External and Opaque11 LSAs */ - struct in_addr area_id = { .s_addr = 0L }; - - /* Default interface for non Opaque9 LSAs */ - struct in_addr ifaddr = { .s_addr = 0L }; - - if (lsa->area) - { - area_id = lsa->area->area_id; - } - if (lsa->data->type == OSPF_OPAQUE_LINK_LSA) - { - assert (lsa->oi); - ifaddr = lsa->oi->address->u.prefix4; - } - - /* Prepare message that can be sent to clients that have a matching - filter */ - msg = new_msg_lsa_change_notify (msgtype, 0L, /* no sequence number */ - ifaddr, area_id, - lsa->flags & OSPF_LSA_SELF, lsa->data); - if (!msg) - { - zlog_warn ("apiserver_clients_lsa_change_notify: msg_new failed"); - return; - } - - /* Now send message to all clients with a matching filter */ - for (ALL_LIST_ELEMENTS (apiserver_list, node, nnode, apiserv)) - { - struct lsa_filter_type *filter; - u_int16_t mask; - u_int32_t *area; - int i; - - /* Check filter for this client. */ - filter = apiserv->filter; - - /* Check area IDs in case of non AS-E LSAs. - * If filter has areas (num_areas > 0), - * then one of the areas must match the area ID of this LSA. */ - - i = filter->num_areas; - if ((lsa->data->type == OSPF_AS_EXTERNAL_LSA) || - (lsa->data->type == OSPF_OPAQUE_AS_LSA)) - { - i = 0; - } - - if (i > 0) - { - area = (u_int32_t *) (filter + 1); - while (i) - { - if (*area == area_id.s_addr) - { - break; + struct msg *msg; + struct listnode *node, *nnode; + struct ospf_apiserver *apiserv; + + /* Default area for AS-External and Opaque11 LSAs */ + struct in_addr area_id = {.s_addr = 0L}; + + /* Default interface for non Opaque9 LSAs */ + struct in_addr ifaddr = {.s_addr = 0L}; + + if (lsa->area) { + area_id = lsa->area->area_id; + } + if (lsa->data->type == OSPF_OPAQUE_LINK_LSA) { + assert(lsa->oi); + ifaddr = lsa->oi->address->u.prefix4; + } + + /* Prepare message that can be sent to clients that have a matching + filter */ + msg = new_msg_lsa_change_notify(msgtype, 0L, /* no sequence number */ + ifaddr, area_id, + lsa->flags & OSPF_LSA_SELF, lsa->data); + if (!msg) { + zlog_warn( + "apiserver_clients_lsa_change_notify: msg_new failed"); + return; + } + + /* Now send message to all clients with a matching filter */ + for (ALL_LIST_ELEMENTS(apiserver_list, node, nnode, apiserv)) { + struct lsa_filter_type *filter; + u_int16_t mask; + u_int32_t *area; + int i; + + /* Check filter for this client. */ + filter = apiserv->filter; + + /* Check area IDs in case of non AS-E LSAs. + * If filter has areas (num_areas > 0), + * then one of the areas must match the area ID of this LSA. */ + + i = filter->num_areas; + if ((lsa->data->type == OSPF_AS_EXTERNAL_LSA) + || (lsa->data->type == OSPF_OPAQUE_AS_LSA)) { + i = 0; } - i--; - area++; - } - } - else - { - i = 1; - } - - if (i > 0) - { - /* Area match. Check LSA type. */ - mask = ntohs (filter->typemask); - - if (mask & Power2[lsa->data->type]) - { - /* Type also matches. Check origin. */ - if ((filter->origin == ANY_ORIGIN) || - (filter->origin == IS_LSA_SELF (lsa))) - { - ospf_apiserver_send_msg (apiserv, msg); + + if (i > 0) { + area = (u_int32_t *)(filter + 1); + while (i) { + if (*area == area_id.s_addr) { + break; + } + i--; + area++; + } + } else { + i = 1; + } + + if (i > 0) { + /* Area match. Check LSA type. */ + mask = ntohs(filter->typemask); + + if (mask & Power2[lsa->data->type]) { + /* Type also matches. Check origin. */ + if ((filter->origin == ANY_ORIGIN) + || (filter->origin == IS_LSA_SELF(lsa))) { + ospf_apiserver_send_msg(apiserv, msg); + } + } } - } } - } - /* Free message since it is not used anymore */ - msg_free (msg); + /* Free message since it is not used anymore */ + msg_free(msg); } @@ -2576,60 +2426,53 @@ apiserver_clients_lsa_change_notify (u_char msgtype, struct ospf_lsa *lsa) */ -static int -apiserver_notify_clients_lsa (u_char msgtype, struct ospf_lsa *lsa) +static int apiserver_notify_clients_lsa(u_char msgtype, struct ospf_lsa *lsa) { - struct msg *msg; - /* default area for AS-External and Opaque11 LSAs */ - struct in_addr area_id = { .s_addr = 0L }; - - /* default interface for non Opaque9 LSAs */ - struct in_addr ifaddr = { .s_addr = 0L }; - - /* Only notify this update if the LSA's age is smaller than - MAXAGE. Otherwise clients would see LSA updates with max age just - before they are deleted from the LSDB. LSA delete messages have - MAXAGE too but should not be filtered. */ - if (IS_LSA_MAXAGE(lsa) && (msgtype == MSG_LSA_UPDATE_NOTIFY)) { - return 0; - } - - if (lsa->area) - { - area_id = lsa->area->area_id; - } - if (lsa->data->type == OSPF_OPAQUE_LINK_LSA) - { - ifaddr = lsa->oi->address->u.prefix4; - } - msg = new_msg_lsa_change_notify (msgtype, 0L, /* no sequence number */ - ifaddr, area_id, - lsa->flags & OSPF_LSA_SELF, lsa->data); - if (!msg) - { - zlog_warn ("notify_clients_lsa: msg_new failed"); - return -1; - } - /* Notify all clients that new LSA is added/updated */ - apiserver_clients_lsa_change_notify (msgtype, lsa); - - /* Clients made their own copies of msg so we can free msg here */ - msg_free (msg); - - return 0; + struct msg *msg; + /* default area for AS-External and Opaque11 LSAs */ + struct in_addr area_id = {.s_addr = 0L}; + + /* default interface for non Opaque9 LSAs */ + struct in_addr ifaddr = {.s_addr = 0L}; + + /* Only notify this update if the LSA's age is smaller than + MAXAGE. Otherwise clients would see LSA updates with max age just + before they are deleted from the LSDB. LSA delete messages have + MAXAGE too but should not be filtered. */ + if (IS_LSA_MAXAGE(lsa) && (msgtype == MSG_LSA_UPDATE_NOTIFY)) { + return 0; + } + + if (lsa->area) { + area_id = lsa->area->area_id; + } + if (lsa->data->type == OSPF_OPAQUE_LINK_LSA) { + ifaddr = lsa->oi->address->u.prefix4; + } + msg = new_msg_lsa_change_notify(msgtype, 0L, /* no sequence number */ + ifaddr, area_id, + lsa->flags & OSPF_LSA_SELF, lsa->data); + if (!msg) { + zlog_warn("notify_clients_lsa: msg_new failed"); + return -1; + } + /* Notify all clients that new LSA is added/updated */ + apiserver_clients_lsa_change_notify(msgtype, lsa); + + /* Clients made their own copies of msg so we can free msg here */ + msg_free(msg); + + return 0; } -int -ospf_apiserver_lsa_update (struct ospf_lsa *lsa) +int ospf_apiserver_lsa_update(struct ospf_lsa *lsa) { - return apiserver_notify_clients_lsa (MSG_LSA_UPDATE_NOTIFY, lsa); + return apiserver_notify_clients_lsa(MSG_LSA_UPDATE_NOTIFY, lsa); } -int -ospf_apiserver_lsa_delete (struct ospf_lsa *lsa) +int ospf_apiserver_lsa_delete(struct ospf_lsa *lsa) { - return apiserver_notify_clients_lsa (MSG_LSA_DELETE_NOTIFY, lsa); + return apiserver_notify_clients_lsa(MSG_LSA_DELETE_NOTIFY, lsa); } #endif /* SUPPORT_OSPF_API */ - diff --git a/ospfd/ospf_apiserver.h b/ospfd/ospf_apiserver.h index 2fd8e7a37..59d18bfd6 100644 --- a/ospfd/ospf_apiserver.h +++ b/ospfd/ospf_apiserver.h @@ -27,58 +27,55 @@ #define MTYPE_OSPF_APISERVER_MSGFILTER MTYPE_TMP /* List of opaque types that application registered */ -struct registered_opaque_type -{ - u_char lsa_type; - u_char opaque_type; +struct registered_opaque_type { + u_char lsa_type; + u_char opaque_type; }; /* Server instance for each accepted client connection. */ -struct ospf_apiserver -{ - /* Socket connections for synchronous commands and asynchronous - notifications */ - int fd_sync; /* synchronous requests */ - struct sockaddr_in peer_sync; - - int fd_async; /* asynchronous notifications */ - struct sockaddr_in peer_async; - - /* List of all opaque types that application registers to use. Using - a single connection with the OSPF daemon, multiple - <lsa,opaque_type> pairs can be registered. However, each - combination can only be registered once by all applications. */ - struct list *opaque_types; /* of type registered_opaque_type */ - - /* Temporary storage for LSA instances to be refreshed. */ - struct ospf_lsdb reserve; - - /* filter for LSA update/delete notifies */ - struct lsa_filter_type *filter; - - /* Fifo buffers for outgoing messages */ - struct msg_fifo *out_sync_fifo; - struct msg_fifo *out_async_fifo; - - /* Read and write threads */ - struct thread *t_sync_read; +struct ospf_apiserver { + /* Socket connections for synchronous commands and asynchronous + notifications */ + int fd_sync; /* synchronous requests */ + struct sockaddr_in peer_sync; + + int fd_async; /* asynchronous notifications */ + struct sockaddr_in peer_async; + + /* List of all opaque types that application registers to use. Using + a single connection with the OSPF daemon, multiple + <lsa,opaque_type> pairs can be registered. However, each + combination can only be registered once by all applications. */ + struct list *opaque_types; /* of type registered_opaque_type */ + + /* Temporary storage for LSA instances to be refreshed. */ + struct ospf_lsdb reserve; + + /* filter for LSA update/delete notifies */ + struct lsa_filter_type *filter; + + /* Fifo buffers for outgoing messages */ + struct msg_fifo *out_sync_fifo; + struct msg_fifo *out_async_fifo; + + /* Read and write threads */ + struct thread *t_sync_read; #ifdef USE_ASYNC_READ - struct thread *t_async_read; + struct thread *t_async_read; #endif /* USE_ASYNC_READ */ - struct thread *t_sync_write; - struct thread *t_async_write; + struct thread *t_sync_write; + struct thread *t_async_write; }; -enum event -{ - OSPF_APISERVER_ACCEPT, - OSPF_APISERVER_SYNC_READ, +enum event { + OSPF_APISERVER_ACCEPT, + OSPF_APISERVER_SYNC_READ, #ifdef USE_ASYNC_READ - OSPF_APISERVER_ASYNC_READ, + OSPF_APISERVER_ASYNC_READ, #endif /* USE_ASYNC_READ */ - OSPF_APISERVER_SYNC_WRITE, - OSPF_APISERVER_ASYNC_WRITE + OSPF_APISERVER_SYNC_WRITE, + OSPF_APISERVER_ASYNC_WRITE }; /* ----------------------------------------------------------- @@ -86,63 +83,67 @@ enum event * ----------------------------------------------------------- */ -extern unsigned short ospf_apiserver_getport (void); -extern int ospf_apiserver_init (void); -extern void ospf_apiserver_term (void); -extern struct ospf_apiserver *ospf_apiserver_new (int fd_sync, int fd_async); -extern void ospf_apiserver_free (struct ospf_apiserver *apiserv); -extern void ospf_apiserver_event (enum event event, int fd, - struct ospf_apiserver *apiserv); -extern int ospf_apiserver_serv_sock_family (unsigned short port, int family); -extern int ospf_apiserver_accept (struct thread *thread); -extern int ospf_apiserver_read (struct thread *thread); -extern int ospf_apiserver_sync_write (struct thread *thread); -extern int ospf_apiserver_async_write (struct thread *thread); -extern int ospf_apiserver_send_reply (struct ospf_apiserver *apiserv, - u_int32_t seqnr, u_char rc); +extern unsigned short ospf_apiserver_getport(void); +extern int ospf_apiserver_init(void); +extern void ospf_apiserver_term(void); +extern struct ospf_apiserver *ospf_apiserver_new(int fd_sync, int fd_async); +extern void ospf_apiserver_free(struct ospf_apiserver *apiserv); +extern void ospf_apiserver_event(enum event event, int fd, + struct ospf_apiserver *apiserv); +extern int ospf_apiserver_serv_sock_family(unsigned short port, int family); +extern int ospf_apiserver_accept(struct thread *thread); +extern int ospf_apiserver_read(struct thread *thread); +extern int ospf_apiserver_sync_write(struct thread *thread); +extern int ospf_apiserver_async_write(struct thread *thread); +extern int ospf_apiserver_send_reply(struct ospf_apiserver *apiserv, + u_int32_t seqnr, u_char rc); /* ----------------------------------------------------------- * Followings are message handler functions * ----------------------------------------------------------- */ -extern int ospf_apiserver_lsa9_originator (void *arg); -extern int ospf_apiserver_lsa10_originator (void *arg); -extern int ospf_apiserver_lsa11_originator (void *arg); - -extern void ospf_apiserver_clients_notify_all (struct msg *msg); - -extern void ospf_apiserver_clients_notify_ready_type9 (struct ospf_interface *oi); -extern void ospf_apiserver_clients_notify_ready_type10 (struct ospf_area *area); -extern void ospf_apiserver_clients_notify_ready_type11 (struct ospf *top); - -extern void ospf_apiserver_clients_notify_new_if (struct ospf_interface *oi); -extern void ospf_apiserver_clients_notify_del_if (struct ospf_interface *oi); -extern void ospf_apiserver_clients_notify_ism_change (struct ospf_interface *oi); -extern void ospf_apiserver_clients_notify_nsm_change (struct ospf_neighbor *nbr); - -extern int ospf_apiserver_is_ready_type9 (struct ospf_interface *oi); -extern int ospf_apiserver_is_ready_type10 (struct ospf_area *area); -extern int ospf_apiserver_is_ready_type11 (struct ospf *ospf); - -extern void ospf_apiserver_notify_ready_type9 (struct ospf_apiserver *apiserv); -extern void ospf_apiserver_notify_ready_type10 (struct ospf_apiserver *apiserv); -extern void ospf_apiserver_notify_ready_type11 (struct ospf_apiserver *apiserv); - -extern int ospf_apiserver_handle_msg (struct ospf_apiserver *apiserv, - struct msg *msg); -extern int ospf_apiserver_handle_register_opaque_type (struct ospf_apiserver - *apiserv, struct msg *msg); -extern int ospf_apiserver_handle_unregister_opaque_type (struct ospf_apiserver - *apiserv, struct msg *msg); -extern int ospf_apiserver_handle_register_event (struct ospf_apiserver *apiserv, - struct msg *msg); -extern int ospf_apiserver_handle_originate_request (struct ospf_apiserver *apiserv, - struct msg *msg); -extern int ospf_apiserver_handle_delete_request (struct ospf_apiserver *apiserv, - struct msg *msg); -extern int ospf_apiserver_handle_sync_lsdb (struct ospf_apiserver *apiserv, +extern int ospf_apiserver_lsa9_originator(void *arg); +extern int ospf_apiserver_lsa10_originator(void *arg); +extern int ospf_apiserver_lsa11_originator(void *arg); + +extern void ospf_apiserver_clients_notify_all(struct msg *msg); + +extern void +ospf_apiserver_clients_notify_ready_type9(struct ospf_interface *oi); +extern void ospf_apiserver_clients_notify_ready_type10(struct ospf_area *area); +extern void ospf_apiserver_clients_notify_ready_type11(struct ospf *top); + +extern void ospf_apiserver_clients_notify_new_if(struct ospf_interface *oi); +extern void ospf_apiserver_clients_notify_del_if(struct ospf_interface *oi); +extern void ospf_apiserver_clients_notify_ism_change(struct ospf_interface *oi); +extern void ospf_apiserver_clients_notify_nsm_change(struct ospf_neighbor *nbr); + +extern int ospf_apiserver_is_ready_type9(struct ospf_interface *oi); +extern int ospf_apiserver_is_ready_type10(struct ospf_area *area); +extern int ospf_apiserver_is_ready_type11(struct ospf *ospf); + +extern void ospf_apiserver_notify_ready_type9(struct ospf_apiserver *apiserv); +extern void ospf_apiserver_notify_ready_type10(struct ospf_apiserver *apiserv); +extern void ospf_apiserver_notify_ready_type11(struct ospf_apiserver *apiserv); + +extern int ospf_apiserver_handle_msg(struct ospf_apiserver *apiserv, struct msg *msg); +extern int +ospf_apiserver_handle_register_opaque_type(struct ospf_apiserver *apiserv, + struct msg *msg); +extern int +ospf_apiserver_handle_unregister_opaque_type(struct ospf_apiserver *apiserv, + struct msg *msg); +extern int ospf_apiserver_handle_register_event(struct ospf_apiserver *apiserv, + struct msg *msg); +extern int +ospf_apiserver_handle_originate_request(struct ospf_apiserver *apiserv, + struct msg *msg); +extern int ospf_apiserver_handle_delete_request(struct ospf_apiserver *apiserv, + struct msg *msg); +extern int ospf_apiserver_handle_sync_lsdb(struct ospf_apiserver *apiserv, + struct msg *msg); /* ----------------------------------------------------------- @@ -150,38 +151,43 @@ extern int ospf_apiserver_handle_sync_lsdb (struct ospf_apiserver *apiserv, * ----------------------------------------------------------- */ -extern int ospf_apiserver_register_opaque_type (struct ospf_apiserver *apiserver, - u_char lsa_type, u_char opaque_type); -extern int ospf_apiserver_unregister_opaque_type (struct ospf_apiserver *apiserver, - u_char lsa_type, - u_char opaque_type); -extern struct ospf_lsa *ospf_apiserver_opaque_lsa_new (struct ospf_area *area, - struct ospf_interface *oi, - struct lsa_header *protolsa); -extern struct ospf_interface *ospf_apiserver_if_lookup_by_addr (struct in_addr - address); -extern struct ospf_interface *ospf_apiserver_if_lookup_by_ifp (struct interface - *ifp); -extern int ospf_apiserver_originate1 (struct ospf_lsa *lsa); -extern void ospf_apiserver_flood_opaque_lsa (struct ospf_lsa *lsa); +extern int ospf_apiserver_register_opaque_type(struct ospf_apiserver *apiserver, + u_char lsa_type, + u_char opaque_type); +extern int +ospf_apiserver_unregister_opaque_type(struct ospf_apiserver *apiserver, + u_char lsa_type, u_char opaque_type); +extern struct ospf_lsa * +ospf_apiserver_opaque_lsa_new(struct ospf_area *area, struct ospf_interface *oi, + struct lsa_header *protolsa); +extern struct ospf_interface * +ospf_apiserver_if_lookup_by_addr(struct in_addr address); +extern struct ospf_interface * +ospf_apiserver_if_lookup_by_ifp(struct interface *ifp); +extern int ospf_apiserver_originate1(struct ospf_lsa *lsa); +extern void ospf_apiserver_flood_opaque_lsa(struct ospf_lsa *lsa); /* ----------------------------------------------------------- - * Followings are callback functions to handle opaque types + * Followings are callback functions to handle opaque types * ----------------------------------------------------------- */ -extern int ospf_apiserver_new_if (struct interface *ifp); -extern int ospf_apiserver_del_if (struct interface *ifp); -extern void ospf_apiserver_ism_change (struct ospf_interface *oi, int old_status); -extern void ospf_apiserver_nsm_change (struct ospf_neighbor *nbr, int old_status); -extern void ospf_apiserver_config_write_router (struct vty *vty); -extern void ospf_apiserver_config_write_if (struct vty *vty, struct interface *ifp); -extern void ospf_apiserver_show_info (struct vty *vty, struct ospf_lsa *lsa); -extern int ospf_ospf_apiserver_lsa_originator (void *arg); -extern struct ospf_lsa *ospf_apiserver_lsa_refresher (struct ospf_lsa *lsa); -extern void ospf_apiserver_flush_opaque_lsa (struct ospf_apiserver *apiserv, - u_char lsa_type, u_char opaque_type); +extern int ospf_apiserver_new_if(struct interface *ifp); +extern int ospf_apiserver_del_if(struct interface *ifp); +extern void ospf_apiserver_ism_change(struct ospf_interface *oi, + int old_status); +extern void ospf_apiserver_nsm_change(struct ospf_neighbor *nbr, + int old_status); +extern void ospf_apiserver_config_write_router(struct vty *vty); +extern void ospf_apiserver_config_write_if(struct vty *vty, + struct interface *ifp); +extern void ospf_apiserver_show_info(struct vty *vty, struct ospf_lsa *lsa); +extern int ospf_ospf_apiserver_lsa_originator(void *arg); +extern struct ospf_lsa *ospf_apiserver_lsa_refresher(struct ospf_lsa *lsa); +extern void ospf_apiserver_flush_opaque_lsa(struct ospf_apiserver *apiserv, + u_char lsa_type, + u_char opaque_type); /* ----------------------------------------------------------- * Followings are hooks when LSAs are updated or deleted @@ -191,10 +197,10 @@ extern void ospf_apiserver_flush_opaque_lsa (struct ospf_apiserver *apiserv, /* Hooks that are invoked from ospf opaque module */ -extern int ospf_apiserver_lsa_update (struct ospf_lsa *lsa); -extern int ospf_apiserver_lsa_delete (struct ospf_lsa *lsa); +extern int ospf_apiserver_lsa_update(struct ospf_lsa *lsa); +extern int ospf_apiserver_lsa_delete(struct ospf_lsa *lsa); -extern void ospf_apiserver_clients_lsa_change_notify (u_char msgtype, - struct ospf_lsa *lsa); +extern void ospf_apiserver_clients_lsa_change_notify(u_char msgtype, + struct ospf_lsa *lsa); #endif /* _OSPF_APISERVER_H */ diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c index 2ba3b5533..e3b66d597 100644 --- a/ospfd/ospf_asbr.c +++ b/ospfd/ospf_asbr.c @@ -45,280 +45,268 @@ /* Remove external route. */ -void -ospf_external_route_remove (struct ospf *ospf, struct prefix_ipv4 *p) +void ospf_external_route_remove(struct ospf *ospf, struct prefix_ipv4 *p) { - struct route_node *rn; - struct ospf_route *or; - - rn = route_node_lookup (ospf->old_external_route, (struct prefix *) p); - if (rn) - if ((or = rn->info)) - { - zlog_info ("Route[%s/%d]: external path deleted", - inet_ntoa (p->prefix), p->prefixlen); - - /* Remove route from zebra. */ - if (or->type == OSPF_DESTINATION_NETWORK) - ospf_zebra_delete ((struct prefix_ipv4 *) &rn->p, or); - - ospf_route_free (or); - rn->info = NULL; - - route_unlock_node (rn); - route_unlock_node (rn); - return; - } - - zlog_info ("Route[%s/%d]: no such external path", - inet_ntoa (p->prefix), p->prefixlen); + struct route_node *rn; + struct ospf_route * or ; + + rn = route_node_lookup(ospf->old_external_route, (struct prefix *)p); + if (rn) + if ((or = rn->info)) { + zlog_info("Route[%s/%d]: external path deleted", + inet_ntoa(p->prefix), p->prefixlen); + + /* Remove route from zebra. */ + if (or->type == OSPF_DESTINATION_NETWORK) + ospf_zebra_delete((struct prefix_ipv4 *)&rn->p, + or); + + ospf_route_free(or); + rn->info = NULL; + + route_unlock_node(rn); + route_unlock_node(rn); + return; + } + + zlog_info("Route[%s/%d]: no such external path", inet_ntoa(p->prefix), + p->prefixlen); } /* Lookup external route. */ -struct ospf_route * -ospf_external_route_lookup (struct ospf *ospf, - struct prefix_ipv4 *p) +struct ospf_route *ospf_external_route_lookup(struct ospf *ospf, + struct prefix_ipv4 *p) { - struct route_node *rn; + struct route_node *rn; - rn = route_node_lookup (ospf->old_external_route, (struct prefix *) p); - if (rn) - { - route_unlock_node (rn); - if (rn->info) - return rn->info; - } + rn = route_node_lookup(ospf->old_external_route, (struct prefix *)p); + if (rn) { + route_unlock_node(rn); + if (rn->info) + return rn->info; + } - zlog_warn ("Route[%s/%d]: lookup, no such prefix", - inet_ntoa (p->prefix), p->prefixlen); + zlog_warn("Route[%s/%d]: lookup, no such prefix", inet_ntoa(p->prefix), + p->prefixlen); - return NULL; + return NULL; } /* Add an External info for AS-external-LSA. */ -struct external_info * -ospf_external_info_new (u_char type, u_short instance) +struct external_info *ospf_external_info_new(u_char type, u_short instance) { - struct external_info *new; + struct external_info *new; - new = (struct external_info *) - XCALLOC (MTYPE_OSPF_EXTERNAL_INFO, sizeof (struct external_info)); - new->type = type; - new->instance = instance; + new = (struct external_info *)XCALLOC(MTYPE_OSPF_EXTERNAL_INFO, + sizeof(struct external_info)); + new->type = type; + new->instance = instance; - ospf_reset_route_map_set_values (&new->route_map_set); - return new; + ospf_reset_route_map_set_values(&new->route_map_set); + return new; } -static void -ospf_external_info_free (struct external_info *ei) +static void ospf_external_info_free(struct external_info *ei) { - XFREE (MTYPE_OSPF_EXTERNAL_INFO, ei); + XFREE(MTYPE_OSPF_EXTERNAL_INFO, ei); } -void -ospf_reset_route_map_set_values (struct route_map_set_values *values) +void ospf_reset_route_map_set_values(struct route_map_set_values *values) { - values->metric = -1; - values->metric_type = -1; + values->metric = -1; + values->metric_type = -1; } -int -ospf_route_map_set_compare (struct route_map_set_values *values1, - struct route_map_set_values *values2) +int ospf_route_map_set_compare(struct route_map_set_values *values1, + struct route_map_set_values *values2) { - return values1->metric == values2->metric && - values1->metric_type == values2->metric_type; + return values1->metric == values2->metric + && values1->metric_type == values2->metric_type; } /* Add an External info for AS-external-LSA. */ -struct external_info * -ospf_external_info_add (u_char type, u_short instance, struct prefix_ipv4 p, - ifindex_t ifindex, struct in_addr nexthop, - route_tag_t tag) +struct external_info *ospf_external_info_add(u_char type, u_short instance, + struct prefix_ipv4 p, + ifindex_t ifindex, + struct in_addr nexthop, + route_tag_t tag) { - struct external_info *new; - struct route_node *rn; - struct ospf_external *ext; - char inetbuf[INET6_BUFSIZ]; - - ext = ospf_external_lookup(type, instance); - if (!ext) - ext = ospf_external_add(type, instance); - - rn = route_node_get (EXTERNAL_INFO (ext), (struct prefix *) &p); - /* If old info exists, -- discard new one or overwrite with new one? */ - if (rn) - if (rn->info) - { - new = rn->info; - if ((new->ifindex == ifindex) && - (new->nexthop.s_addr == nexthop.s_addr) && (new->tag == tag)) - { - route_unlock_node(rn); - return NULL; /* NULL => no LSA to refresh */ - } - - inet_ntop(AF_INET, (void *)&nexthop.s_addr, inetbuf, INET6_BUFSIZ); - zlog_warn ("Redistribute[%s][%d]: %s/%d discarding old info with NH %s.", - ospf_redist_string(type), instance, - inet_ntoa (p.prefix), p.prefixlen, inetbuf); - XFREE (MTYPE_OSPF_EXTERNAL_INFO, rn->info); - rn->info = NULL; - } - - /* Create new External info instance. */ - new = ospf_external_info_new (type, instance); - new->p = p; - new->ifindex = ifindex; - new->nexthop = nexthop; - new->tag = tag; - - /* we don't unlock rn from the get() because we're attaching the info */ - if (rn) - rn->info = new; - - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - { - inet_ntop(AF_INET, (void *)&nexthop.s_addr, inetbuf, INET6_BUFSIZ); - zlog_debug ("Redistribute[%s]: %s/%d external info created, with NH %s", - ospf_redist_string(type), - inet_ntoa (p.prefix), p.prefixlen, inetbuf); - } - return new; + struct external_info *new; + struct route_node *rn; + struct ospf_external *ext; + char inetbuf[INET6_BUFSIZ]; + + ext = ospf_external_lookup(type, instance); + if (!ext) + ext = ospf_external_add(type, instance); + + rn = route_node_get(EXTERNAL_INFO(ext), (struct prefix *)&p); + /* If old info exists, -- discard new one or overwrite with new one? */ + if (rn) + if (rn->info) { + new = rn->info; + if ((new->ifindex == ifindex) + && (new->nexthop.s_addr == nexthop.s_addr) + && (new->tag == tag)) { + route_unlock_node(rn); + return NULL; /* NULL => no LSA to refresh */ + } + + inet_ntop(AF_INET, (void *)&nexthop.s_addr, inetbuf, + INET6_BUFSIZ); + zlog_warn( + "Redistribute[%s][%d]: %s/%d discarding old info with NH %s.", + ospf_redist_string(type), instance, + inet_ntoa(p.prefix), p.prefixlen, inetbuf); + XFREE(MTYPE_OSPF_EXTERNAL_INFO, rn->info); + rn->info = NULL; + } + + /* Create new External info instance. */ + new = ospf_external_info_new(type, instance); + new->p = p; + new->ifindex = ifindex; + new->nexthop = nexthop; + new->tag = tag; + + /* we don't unlock rn from the get() because we're attaching the info */ + if (rn) + rn->info = new; + + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { + inet_ntop(AF_INET, (void *)&nexthop.s_addr, inetbuf, + INET6_BUFSIZ); + zlog_debug( + "Redistribute[%s]: %s/%d external info created, with NH %s", + ospf_redist_string(type), inet_ntoa(p.prefix), + p.prefixlen, inetbuf); + } + return new; } -void -ospf_external_info_delete (u_char type, u_short instance, struct prefix_ipv4 p) +void ospf_external_info_delete(u_char type, u_short instance, + struct prefix_ipv4 p) { - struct route_node *rn; - struct ospf_external *ext; - - ext = ospf_external_lookup(type, instance); - if (!ext) - return; - - rn = route_node_lookup (EXTERNAL_INFO (ext), (struct prefix *) &p); - if (rn) - { - ospf_external_info_free (rn->info); - rn->info = NULL; - route_unlock_node (rn); - route_unlock_node (rn); - } + struct route_node *rn; + struct ospf_external *ext; + + ext = ospf_external_lookup(type, instance); + if (!ext) + return; + + rn = route_node_lookup(EXTERNAL_INFO(ext), (struct prefix *)&p); + if (rn) { + ospf_external_info_free(rn->info); + rn->info = NULL; + route_unlock_node(rn); + route_unlock_node(rn); + } } -struct external_info * -ospf_external_info_lookup (u_char type, u_short instance, struct prefix_ipv4 *p) +struct external_info *ospf_external_info_lookup(u_char type, u_short instance, + struct prefix_ipv4 *p) { - struct route_node *rn; - struct ospf_external *ext; - - ext = ospf_external_lookup(type, instance); - if (!ext) - return NULL; - - rn = route_node_lookup (EXTERNAL_INFO (ext), (struct prefix *) p); - if (rn) - { - route_unlock_node (rn); - if (rn->info) - return rn->info; - } - - return NULL; + struct route_node *rn; + struct ospf_external *ext; + + ext = ospf_external_lookup(type, instance); + if (!ext) + return NULL; + + rn = route_node_lookup(EXTERNAL_INFO(ext), (struct prefix *)p); + if (rn) { + route_unlock_node(rn); + if (rn->info) + return rn->info; + } + + return NULL; } -struct ospf_lsa * -ospf_external_info_find_lsa (struct ospf *ospf, - struct prefix_ipv4 *p) +struct ospf_lsa *ospf_external_info_find_lsa(struct ospf *ospf, + struct prefix_ipv4 *p) { - struct ospf_lsa *lsa; - struct as_external_lsa *al; - struct in_addr mask, id; + struct ospf_lsa *lsa; + struct as_external_lsa *al; + struct in_addr mask, id; - lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, OSPF_AS_EXTERNAL_LSA, - p->prefix, ospf->router_id); + lsa = ospf_lsdb_lookup_by_id(ospf->lsdb, OSPF_AS_EXTERNAL_LSA, + p->prefix, ospf->router_id); - if (!lsa) - return NULL; + if (!lsa) + return NULL; - al = (struct as_external_lsa *) lsa->data; + al = (struct as_external_lsa *)lsa->data; - masklen2ip (p->prefixlen, &mask); + masklen2ip(p->prefixlen, &mask); - if (mask.s_addr != al->mask.s_addr) - { - id.s_addr = p->prefix.s_addr | (~mask.s_addr); - lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, OSPF_AS_EXTERNAL_LSA, - id, ospf->router_id); - if (!lsa) - return NULL; - } + if (mask.s_addr != al->mask.s_addr) { + id.s_addr = p->prefix.s_addr | (~mask.s_addr); + lsa = ospf_lsdb_lookup_by_id(ospf->lsdb, OSPF_AS_EXTERNAL_LSA, + id, ospf->router_id); + if (!lsa) + return NULL; + } - return lsa; + return lsa; } /* Update ASBR status. */ -void -ospf_asbr_status_update (struct ospf *ospf, u_char status) +void ospf_asbr_status_update(struct ospf *ospf, u_char status) { - zlog_info ("ASBR[Status:%d]: Update", status); - - /* ASBR on. */ - if (status) - { - /* Already ASBR. */ - if (IS_OSPF_ASBR (ospf)) - { - zlog_info ("ASBR[Status:%d]: Already ASBR", status); - return; - } - SET_FLAG (ospf->flags, OSPF_FLAG_ASBR); - } - else - { - /* Already non ASBR. */ - if (! IS_OSPF_ASBR (ospf)) - { - zlog_info ("ASBR[Status:%d]: Already non ASBR", status); - return; + zlog_info("ASBR[Status:%d]: Update", status); + + /* ASBR on. */ + if (status) { + /* Already ASBR. */ + if (IS_OSPF_ASBR(ospf)) { + zlog_info("ASBR[Status:%d]: Already ASBR", status); + return; + } + SET_FLAG(ospf->flags, OSPF_FLAG_ASBR); + } else { + /* Already non ASBR. */ + if (!IS_OSPF_ASBR(ospf)) { + zlog_info("ASBR[Status:%d]: Already non ASBR", status); + return; + } + UNSET_FLAG(ospf->flags, OSPF_FLAG_ASBR); } - UNSET_FLAG (ospf->flags, OSPF_FLAG_ASBR); - } - /* Transition from/to status ASBR, schedule timer. */ - ospf_spf_calculate_schedule (ospf, SPF_FLAG_ASBR_STATUS_CHANGE); - ospf_router_lsa_update (ospf); + /* Transition from/to status ASBR, schedule timer. */ + ospf_spf_calculate_schedule(ospf, SPF_FLAG_ASBR_STATUS_CHANGE); + ospf_router_lsa_update(ospf); } -void -ospf_redistribute_withdraw (struct ospf *ospf, u_char type, u_short instance) +void ospf_redistribute_withdraw(struct ospf *ospf, u_char type, + u_short instance) { - struct route_node *rn; - struct external_info *ei; - struct ospf_external *ext; - - ext = ospf_external_lookup(type, instance); - if (!ext) - return; - - /* Delete external info for specified type. */ - if (EXTERNAL_INFO (ext)) - for (rn = route_top (EXTERNAL_INFO (ext)); rn; rn = route_next (rn)) - if ((ei = rn->info)) - if (ospf_external_info_find_lsa (ospf, &ei->p)) - { - if (is_prefix_default (&ei->p) && - ospf->default_originate != DEFAULT_ORIGINATE_NONE) - continue; - ospf_external_lsa_flush (ospf, type, &ei->p, - ei->ifindex /*, ei->nexthop */); - - ospf_external_info_free (ei); - route_unlock_node (rn); - rn->info = NULL; - } + struct route_node *rn; + struct external_info *ei; + struct ospf_external *ext; + + ext = ospf_external_lookup(type, instance); + if (!ext) + return; + + /* Delete external info for specified type. */ + if (EXTERNAL_INFO(ext)) + for (rn = route_top(EXTERNAL_INFO(ext)); rn; + rn = route_next(rn)) + if ((ei = rn->info)) + if (ospf_external_info_find_lsa(ospf, &ei->p)) { + if (is_prefix_default(&ei->p) + && ospf->default_originate + != DEFAULT_ORIGINATE_NONE) + continue; + ospf_external_lsa_flush( + ospf, type, &ei->p, + ei->ifindex /*, ei->nexthop */); + + ospf_external_info_free(ei); + route_unlock_node(rn); + rn->info = NULL; + } } diff --git a/ospfd/ospf_asbr.h b/ospfd/ospf_asbr.h index 2fd570d1b..3d7f14e7f 100644 --- a/ospfd/ospf_asbr.h +++ b/ospfd/ospf_asbr.h @@ -22,61 +22,58 @@ #ifndef _ZEBRA_OSPF_ASBR_H #define _ZEBRA_OSPF_ASBR_H -struct route_map_set_values -{ - int32_t metric; - int32_t metric_type; +struct route_map_set_values { + int32_t metric; + int32_t metric_type; }; /* Redistributed external information. */ -struct external_info -{ - /* Type of source protocol. */ - u_char type; +struct external_info { + /* Type of source protocol. */ + u_char type; - u_short instance; + u_short instance; - /* Prefix. */ - struct prefix_ipv4 p; + /* Prefix. */ + struct prefix_ipv4 p; - /* Interface index. */ - ifindex_t ifindex; + /* Interface index. */ + ifindex_t ifindex; - /* Nexthop address. */ - struct in_addr nexthop; + /* Nexthop address. */ + struct in_addr nexthop; - /* Additional Route tag. */ - route_tag_t tag; + /* Additional Route tag. */ + route_tag_t tag; - struct route_map_set_values route_map_set; + struct route_map_set_values route_map_set; #define ROUTEMAP_METRIC(E) (E)->route_map_set.metric #define ROUTEMAP_METRIC_TYPE(E) (E)->route_map_set.metric_type }; #define OSPF_ASBR_CHECK_DELAY 30 -extern void ospf_external_route_remove (struct ospf *, struct prefix_ipv4 *); -extern struct external_info *ospf_external_info_new (u_char, u_short); -extern void ospf_reset_route_map_set_values (struct route_map_set_values *); -extern int ospf_route_map_set_compare (struct route_map_set_values *, - struct route_map_set_values *); -extern struct external_info *ospf_external_info_add (u_char, u_short, - struct prefix_ipv4, - ifindex_t, - struct in_addr, - route_tag_t); -extern void ospf_external_info_delete (u_char, u_short, struct prefix_ipv4); -extern struct external_info *ospf_external_info_lookup (u_char, u_short, - struct prefix_ipv4 *); -extern struct ospf_route *ospf_external_route_lookup (struct ospf *, - struct prefix_ipv4 *); -extern void ospf_asbr_status_update (struct ospf *, u_char); +extern void ospf_external_route_remove(struct ospf *, struct prefix_ipv4 *); +extern struct external_info *ospf_external_info_new(u_char, u_short); +extern void ospf_reset_route_map_set_values(struct route_map_set_values *); +extern int ospf_route_map_set_compare(struct route_map_set_values *, + struct route_map_set_values *); +extern struct external_info *ospf_external_info_add(u_char, u_short, + struct prefix_ipv4, + ifindex_t, struct in_addr, + route_tag_t); +extern void ospf_external_info_delete(u_char, u_short, struct prefix_ipv4); +extern struct external_info *ospf_external_info_lookup(u_char, u_short, + struct prefix_ipv4 *); +extern struct ospf_route *ospf_external_route_lookup(struct ospf *, + struct prefix_ipv4 *); +extern void ospf_asbr_status_update(struct ospf *, u_char); -extern void ospf_redistribute_withdraw (struct ospf *, u_char, u_short); -extern void ospf_asbr_check (void); -extern void ospf_schedule_asbr_check (void); -extern void ospf_asbr_route_install_lsa (struct ospf_lsa *); -extern struct ospf_lsa *ospf_external_info_find_lsa (struct ospf *, - struct prefix_ipv4 *p); +extern void ospf_redistribute_withdraw(struct ospf *, u_char, u_short); +extern void ospf_asbr_check(void); +extern void ospf_schedule_asbr_check(void); +extern void ospf_asbr_route_install_lsa(struct ospf_lsa *); +extern struct ospf_lsa *ospf_external_info_find_lsa(struct ospf *, + struct prefix_ipv4 *p); #endif /* _ZEBRA_OSPF_ASBR_H */ diff --git a/ospfd/ospf_ase.c b/ospfd/ospf_ase.c index b7cba7fd7..bf2b809dd 100644 --- a/ospfd/ospf_ase.c +++ b/ospfd/ospf_ase.c @@ -45,114 +45,115 @@ #include "ospfd/ospf_zebra.h" #include "ospfd/ospf_dump.h" -struct ospf_route * -ospf_find_asbr_route (struct ospf *ospf, - struct route_table *rtrs, struct prefix_ipv4 *asbr) +struct ospf_route *ospf_find_asbr_route(struct ospf *ospf, + struct route_table *rtrs, + struct prefix_ipv4 *asbr) { - struct route_node *rn; - struct ospf_route *or, *best = NULL; - struct listnode *node; - struct list *chosen; - - /* Sanity check. */ - if (rtrs == NULL) - return NULL; - - rn = route_node_lookup (rtrs, (struct prefix *) asbr); - if (! rn) - return NULL; - - route_unlock_node (rn); - - chosen = list_new (); - - /* First try to find intra-area non-bb paths. */ - if (!CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE)) - for (ALL_LIST_ELEMENTS_RO ((struct list *) rn->info, node, or)) - if (or->cost < OSPF_LS_INFINITY) - if (!OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id) && - or->path_type == OSPF_PATH_INTRA_AREA) - listnode_add (chosen, or); - - /* If none is found -- look through all. */ - if (listcount (chosen) == 0) - { - list_free (chosen); - chosen = rn->info; - } + struct route_node *rn; + struct ospf_route * or, *best = NULL; + struct listnode *node; + struct list *chosen; + + /* Sanity check. */ + if (rtrs == NULL) + return NULL; + + rn = route_node_lookup(rtrs, (struct prefix *)asbr); + if (!rn) + return NULL; + + route_unlock_node(rn); + + chosen = list_new(); + + /* First try to find intra-area non-bb paths. */ + if (!CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE)) + for (ALL_LIST_ELEMENTS_RO((struct list *)rn->info, node, or)) + if (or->cost < OSPF_LS_INFINITY) + if (!OSPF_IS_AREA_ID_BACKBONE(or->u.std.area_id) + && + or->path_type == OSPF_PATH_INTRA_AREA) + listnode_add(chosen, or); + + /* If none is found -- look through all. */ + if (listcount(chosen) == 0) { + list_free(chosen); + chosen = rn->info; + } - /* Now find the route with least cost. */ - for (ALL_LIST_ELEMENTS_RO (chosen, node, or)) - if (or->cost < OSPF_LS_INFINITY) - { - if (best == NULL) - best = or; - else if (best->cost > or->cost) - best = or; - else if (best->cost == or->cost && - IPV4_ADDR_CMP (&best->u.std.area_id, - &or->u.std.area_id) < 0) - best = or; - } - - if (chosen != rn->info) - list_delete (chosen); - - return best; + /* Now find the route with least cost. */ + for (ALL_LIST_ELEMENTS_RO(chosen, node, or)) + if (or->cost < OSPF_LS_INFINITY) { + if (best == NULL) + best = or ; + else if (best->cost > or->cost) + best = or ; + else if (best->cost == + or->cost + && IPV4_ADDR_CMP( + &best->u.std.area_id, + & or->u.std.area_id) + < 0) + best = or ; + } + + if (chosen != rn->info) + list_delete(chosen); + + return best; } -struct ospf_route * -ospf_find_asbr_route_through_area (struct route_table *rtrs, - struct prefix_ipv4 *asbr, - struct ospf_area *area) +struct ospf_route *ospf_find_asbr_route_through_area(struct route_table *rtrs, + struct prefix_ipv4 *asbr, + struct ospf_area *area) { - struct route_node *rn; + struct route_node *rn; - /* Sanity check. */ - if (rtrs == NULL) - return NULL; + /* Sanity check. */ + if (rtrs == NULL) + return NULL; - rn = route_node_lookup (rtrs, (struct prefix *) asbr); - - if (rn) - { - struct listnode *node; - struct ospf_route *or; + rn = route_node_lookup(rtrs, (struct prefix *)asbr); - route_unlock_node (rn); + if (rn) { + struct listnode *node; + struct ospf_route * or ; - for (ALL_LIST_ELEMENTS_RO ((struct list *) rn->info, node, or)) - if (IPV4_ADDR_SAME (&or->u.std.area_id, &area->area_id)) - return or; - } + route_unlock_node(rn); + + for (ALL_LIST_ELEMENTS_RO((struct list *)rn->info, node, or)) + if (IPV4_ADDR_SAME(& or->u.std.area_id, &area->area_id)) + return or ; + } - return NULL; + return NULL; } -static void -ospf_ase_complete_direct_routes (struct ospf_route *ro, struct in_addr nexthop) +static void ospf_ase_complete_direct_routes(struct ospf_route *ro, + struct in_addr nexthop) { - struct listnode *node; - struct ospf_path *op; + struct listnode *node; + struct ospf_path *op; - for (ALL_LIST_ELEMENTS_RO (ro->paths, node, op)) - if (op->nexthop.s_addr == 0) - op->nexthop.s_addr = nexthop.s_addr; + for (ALL_LIST_ELEMENTS_RO(ro->paths, node, op)) + if (op->nexthop.s_addr == 0) + op->nexthop.s_addr = nexthop.s_addr; } -static int -ospf_ase_forward_address_check (struct ospf *ospf, struct in_addr fwd_addr) +static int ospf_ase_forward_address_check(struct ospf *ospf, + struct in_addr fwd_addr) { - struct listnode *ifn; - struct ospf_interface *oi; - - for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, ifn, oi)) - if (if_is_operative (oi->ifp)) - if (oi->type != OSPF_IFTYPE_VIRTUALLINK) - if (IPV4_ADDR_SAME (&oi->address->u.prefix4, &fwd_addr)) - return 0; - - return 1; + struct listnode *ifn; + struct ospf_interface *oi; + + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, ifn, oi)) + if (if_is_operative(oi->ifp)) + if (oi->type != OSPF_IFTYPE_VIRTUALLINK) + if (IPV4_ADDR_SAME(&oi->address->u.prefix4, + &fwd_addr)) + return 0; + + return 1; } #if 0 @@ -239,627 +240,608 @@ ospf_ase_calculate_asbr_route (struct ospf *ospf, #endif static struct ospf_route * -ospf_ase_calculate_new_route (struct ospf_lsa *lsa, - struct ospf_route *asbr_route, u_int32_t metric) +ospf_ase_calculate_new_route(struct ospf_lsa *lsa, + struct ospf_route *asbr_route, u_int32_t metric) { - struct as_external_lsa *al; - struct ospf_route *new; - - al = (struct as_external_lsa *) lsa->data; - - new = ospf_route_new (); - - /* Set redistributed type -- does make sense? */ - /* new->type = type; */ - new->id = al->header.id; - new->mask = al->mask; - - if (!IS_EXTERNAL_METRIC (al->e[0].tos)) - { - if (IS_DEBUG_OSPF (lsa, LSA)) - zlog_debug ("Route[External]: type-1 created."); - new->path_type = OSPF_PATH_TYPE1_EXTERNAL; - new->cost = asbr_route->cost + metric; /* X + Y */ - } - else - { - if (IS_DEBUG_OSPF (lsa, LSA)) - zlog_debug ("Route[External]: type-2 created."); - new->path_type = OSPF_PATH_TYPE2_EXTERNAL; - new->cost = asbr_route->cost; /* X */ - new->u.ext.type2_cost = metric; /* Y */ - } + struct as_external_lsa *al; + struct ospf_route *new; + + al = (struct as_external_lsa *)lsa->data; + + new = ospf_route_new(); + + /* Set redistributed type -- does make sense? */ + /* new->type = type; */ + new->id = al->header.id; + new->mask = al->mask; + + if (!IS_EXTERNAL_METRIC(al->e[0].tos)) { + if (IS_DEBUG_OSPF(lsa, LSA)) + zlog_debug("Route[External]: type-1 created."); + new->path_type = OSPF_PATH_TYPE1_EXTERNAL; + new->cost = asbr_route->cost + metric; /* X + Y */ + } else { + if (IS_DEBUG_OSPF(lsa, LSA)) + zlog_debug("Route[External]: type-2 created."); + new->path_type = OSPF_PATH_TYPE2_EXTERNAL; + new->cost = asbr_route->cost; /* X */ + new->u.ext.type2_cost = metric; /* Y */ + } - new->type = OSPF_DESTINATION_NETWORK; - new->u.ext.origin = lsa; - new->u.ext.tag = ntohl (al->e[0].route_tag); - new->u.ext.asbr = asbr_route; + new->type = OSPF_DESTINATION_NETWORK; + new->u.ext.origin = lsa; + new->u.ext.tag = ntohl(al->e[0].route_tag); + new->u.ext.asbr = asbr_route; - assert (new != asbr_route); + assert(new != asbr_route); - return new; + return new; } #define OSPF_ASE_CALC_INTERVAL 1 -int -ospf_ase_calculate_route (struct ospf *ospf, struct ospf_lsa * lsa) +int ospf_ase_calculate_route(struct ospf *ospf, struct ospf_lsa *lsa) { - u_int32_t metric; - struct as_external_lsa *al; - struct ospf_route *asbr_route; - struct prefix_ipv4 asbr, p; - struct route_node *rn; - struct ospf_route *new, *or; - int ret; - - assert (lsa); - al = (struct as_external_lsa *) lsa->data; - - if (lsa->data->type == OSPF_AS_NSSA_LSA) - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_ase_calc(): Processing Type-7"); - - /* Stay away from any Local Translated Type-7 LSAs */ - if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_ase_calc(): Rejecting Local Xlt'd"); - return 0; - } - - if (IS_DEBUG_OSPF (lsa, LSA)) - zlog_debug ("Route[External]: Calculate AS-external-LSA to %s/%d", - inet_ntoa (al->header.id), ip_masklen (al->mask)); - /* (1) If the cost specified by the LSA is LSInfinity, or if the - LSA's LS age is equal to MaxAge, then examine the next LSA. */ - if ((metric = GET_METRIC (al->e[0].metric)) >= OSPF_LS_INFINITY) - { - if (IS_DEBUG_OSPF (lsa, LSA)) - zlog_debug ("Route[External]: Metric is OSPF_LS_INFINITY"); - return 0; - } - if (IS_LSA_MAXAGE (lsa)) - { - if (IS_DEBUG_OSPF (lsa, LSA)) - zlog_debug ("Route[External]: AS-external-LSA is MAXAGE"); - return 0; - } - - /* (2) If the LSA was originated by the calculating router itself, - examine the next LSA. */ - if (IS_LSA_SELF (lsa)) - { - if (IS_DEBUG_OSPF (lsa, LSA)) - zlog_debug ("Route[External]: AS-external-LSA is self originated"); - return 0; - } - - /* (3) Call the destination described by the LSA N. N's address is - obtained by masking the LSA's Link State ID with the - network/subnet mask contained in the body of the LSA. Look - up the routing table entries (potentially one per attached - area) for the AS boundary router (ASBR) that originated the - LSA. If no entries exist for router ASBR (i.e., ASBR is - unreachable), do nothing with this LSA and consider the next - in the list. */ - - asbr.family = AF_INET; - asbr.prefix = al->header.adv_router; - asbr.prefixlen = IPV4_MAX_BITLEN; - apply_mask_ipv4 (&asbr); - - asbr_route = ospf_find_asbr_route (ospf, ospf->new_rtrs, &asbr); - if (asbr_route == NULL) - { - if (IS_DEBUG_OSPF (lsa, LSA)) - zlog_debug ("Route[External]: Can't find originating ASBR route"); - return 0; - } - if (!(asbr_route->u.std.flags & ROUTER_LSA_EXTERNAL)) - { - if (IS_DEBUG_OSPF (lsa, LSA)) - zlog_debug ("Route[External]: Originating router is not an ASBR"); - return 0; - } - - /* Else, this LSA describes an AS external path to destination - N. Examine the forwarding address specified in the AS- - external-LSA. This indicates the IP address to which - packets for the destination should be forwarded. */ - - if (al->e[0].fwd_addr.s_addr == 0) - { - /* If the forwarding address is set to 0.0.0.0, packets should - be sent to the ASBR itself. Among the multiple routing table - entries for the ASBR, select the preferred entry as follows. - If RFC1583Compatibility is set to "disabled", prune the set - of routing table entries for the ASBR as described in - Section 16.4.1. In any case, among the remaining routing - table entries, select the routing table entry with the least - cost; when there are multiple least cost routing table - entries the entry whose associated area has the largest OSPF - Area ID (when considered as an unsigned 32-bit integer) is - chosen. */ - - /* asbr_route already contains the requested route */ - } - else - { - /* If the forwarding address is non-zero, look up the - forwarding address in the routing table.[24] The matching - routing table entry must specify an intra-area or inter-area - path; if no such path exists, do nothing with the LSA and - consider the next in the list. */ - if (! ospf_ase_forward_address_check (ospf, al->e[0].fwd_addr)) - { - if (IS_DEBUG_OSPF (lsa, LSA)) - zlog_debug ("Route[External]: Forwarding address is our router " - "address"); - return 0; + u_int32_t metric; + struct as_external_lsa *al; + struct ospf_route *asbr_route; + struct prefix_ipv4 asbr, p; + struct route_node *rn; + struct ospf_route *new, * or ; + int ret; + + assert(lsa); + al = (struct as_external_lsa *)lsa->data; + + if (lsa->data->type == OSPF_AS_NSSA_LSA) + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_ase_calc(): Processing Type-7"); + + /* Stay away from any Local Translated Type-7 LSAs */ + if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT)) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("ospf_ase_calc(): Rejecting Local Xlt'd"); + return 0; } - - asbr.family = AF_INET; - asbr.prefix = al->e[0].fwd_addr; - asbr.prefixlen = IPV4_MAX_BITLEN; - rn = route_node_match (ospf->new_table, (struct prefix *) &asbr); - - if (rn == NULL || (asbr_route = rn->info) == NULL) - { - if (IS_DEBUG_OSPF (lsa, LSA)) - zlog_debug ("Route[External]: Can't find route to forwarding " - "address"); - if (rn) - route_unlock_node (rn); - return 0; + if (IS_DEBUG_OSPF(lsa, LSA)) + zlog_debug( + "Route[External]: Calculate AS-external-LSA to %s/%d", + inet_ntoa(al->header.id), ip_masklen(al->mask)); + /* (1) If the cost specified by the LSA is LSInfinity, or if the + LSA's LS age is equal to MaxAge, then examine the next LSA. */ + if ((metric = GET_METRIC(al->e[0].metric)) >= OSPF_LS_INFINITY) { + if (IS_DEBUG_OSPF(lsa, LSA)) + zlog_debug( + "Route[External]: Metric is OSPF_LS_INFINITY"); + return 0; + } + if (IS_LSA_MAXAGE(lsa)) { + if (IS_DEBUG_OSPF(lsa, LSA)) + zlog_debug( + "Route[External]: AS-external-LSA is MAXAGE"); + return 0; } - route_unlock_node (rn); - } - - /* (4) Let X be the cost specified by the preferred routing table - entry for the ASBR/forwarding address, and Y the cost - specified in the LSA. X is in terms of the link state - metric, and Y is a type 1 or 2 external metric. */ - - - /* (5) Look up the routing table entry for the destination N. If - no entry exists for N, install the AS external path to N, - with next hop equal to the list of next hops to the - forwarding address, and advertising router equal to ASBR. - If the external metric type is 1, then the path-type is set - to type 1 external and the cost is equal to X+Y. If the - external metric type is 2, the path-type is set to type 2 - external, the link state component of the route's cost is X, - and the type 2 cost is Y. */ - new = ospf_ase_calculate_new_route (lsa, asbr_route, metric); - - /* (6) Compare the AS external path described by the LSA with the - existing paths in N's routing table entry, as follows. If - the new path is preferred, it replaces the present paths in - N's routing table entry. If the new path is of equal - preference, it is added to N's routing table entry's list of - paths. */ - - /* Set prefix. */ - p.family = AF_INET; - p.prefix = al->header.id; - p.prefixlen = ip_masklen (al->mask); - - /* if there is a Intra/Inter area route to the N - do not install external route */ - if ((rn = route_node_lookup (ospf->new_table, - (struct prefix *) &p))) - { - route_unlock_node(rn); - if (rn->info == NULL) - zlog_info ("Route[External]: rn->info NULL"); - if (new) - ospf_route_free (new); - return 0; - } - /* Find a route to the same dest */ - /* If there is no route, create new one. */ - if ((rn = route_node_lookup (ospf->new_external_route, - (struct prefix *) &p))) - route_unlock_node(rn); - - if (!rn || (or = rn->info) == NULL) - { - if (IS_DEBUG_OSPF (lsa, LSA)) - zlog_debug ("Route[External]: Adding a new route %s/%d", - inet_ntoa (p.prefix), p.prefixlen); + /* (2) If the LSA was originated by the calculating router itself, + examine the next LSA. */ + if (IS_LSA_SELF(lsa)) { + if (IS_DEBUG_OSPF(lsa, LSA)) + zlog_debug( + "Route[External]: AS-external-LSA is self originated"); + return 0; + } - ospf_route_add (ospf->new_external_route, &p, new, asbr_route); + /* (3) Call the destination described by the LSA N. N's address is + obtained by masking the LSA's Link State ID with the + network/subnet mask contained in the body of the LSA. Look + up the routing table entries (potentially one per attached + area) for the AS boundary router (ASBR) that originated the + LSA. If no entries exist for router ASBR (i.e., ASBR is + unreachable), do nothing with this LSA and consider the next + in the list. */ + + asbr.family = AF_INET; + asbr.prefix = al->header.adv_router; + asbr.prefixlen = IPV4_MAX_BITLEN; + apply_mask_ipv4(&asbr); + + asbr_route = ospf_find_asbr_route(ospf, ospf->new_rtrs, &asbr); + if (asbr_route == NULL) { + if (IS_DEBUG_OSPF(lsa, LSA)) + zlog_debug( + "Route[External]: Can't find originating ASBR route"); + return 0; + } + if (!(asbr_route->u.std.flags & ROUTER_LSA_EXTERNAL)) { + if (IS_DEBUG_OSPF(lsa, LSA)) + zlog_debug( + "Route[External]: Originating router is not an ASBR"); + return 0; + } - if (al->e[0].fwd_addr.s_addr) - ospf_ase_complete_direct_routes (new, al->e[0].fwd_addr); - return 0; - } - else - { - /* (a) Intra-area and inter-area paths are always preferred - over AS external paths. - - (b) Type 1 external paths are always preferred over type 2 - external paths. When all paths are type 2 external - paths, the paths with the smallest advertised type 2 - metric are always preferred. */ - ret = ospf_route_cmp (ospf, new, or); - - /* (c) If the new AS external path is still indistinguishable - from the current paths in the N's routing table entry, - and RFC1583Compatibility is set to "disabled", select - the preferred paths based on the intra-AS paths to the - ASBR/forwarding addresses, as specified in Section - 16.4.1. - - (d) If the new AS external path is still indistinguishable - from the current paths in the N's routing table entry, - select the preferred path based on a least cost - comparison. Type 1 external paths are compared by - looking at the sum of the distance to the forwarding - address and the advertised type 1 metric (X+Y). Type 2 - external paths advertising equal type 2 metrics are - compared by looking at the distance to the forwarding - addresses. - */ - /* New route is better */ - if (ret < 0) - { - if (IS_DEBUG_OSPF (lsa, LSA)) - zlog_debug ("Route[External]: New route is better"); - ospf_route_subst (rn, new, asbr_route); - if (al->e[0].fwd_addr.s_addr) - ospf_ase_complete_direct_routes (new, al->e[0].fwd_addr); - or = new; - new = NULL; + /* Else, this LSA describes an AS external path to destination + N. Examine the forwarding address specified in the AS- + external-LSA. This indicates the IP address to which + packets for the destination should be forwarded. */ + + if (al->e[0].fwd_addr.s_addr == 0) { + /* If the forwarding address is set to 0.0.0.0, packets should + be sent to the ASBR itself. Among the multiple routing table + entries for the ASBR, select the preferred entry as follows. + If RFC1583Compatibility is set to "disabled", prune the set + of routing table entries for the ASBR as described in + Section 16.4.1. In any case, among the remaining routing + table entries, select the routing table entry with the least + cost; when there are multiple least cost routing table + entries the entry whose associated area has the largest OSPF + Area ID (when considered as an unsigned 32-bit integer) is + chosen. */ + + /* asbr_route already contains the requested route */ + } else { + /* If the forwarding address is non-zero, look up the + forwarding address in the routing table.[24] The matching + routing table entry must specify an intra-area or inter-area + path; if no such path exists, do nothing with the LSA and + consider the next in the list. */ + if (!ospf_ase_forward_address_check(ospf, al->e[0].fwd_addr)) { + if (IS_DEBUG_OSPF(lsa, LSA)) + zlog_debug( + "Route[External]: Forwarding address is our router " + "address"); + return 0; + } + + asbr.family = AF_INET; + asbr.prefix = al->e[0].fwd_addr; + asbr.prefixlen = IPV4_MAX_BITLEN; + + rn = route_node_match(ospf->new_table, (struct prefix *)&asbr); + + if (rn == NULL || (asbr_route = rn->info) == NULL) { + if (IS_DEBUG_OSPF(lsa, LSA)) + zlog_debug( + "Route[External]: Can't find route to forwarding " + "address"); + if (rn) + route_unlock_node(rn); + return 0; + } + + route_unlock_node(rn); } - /* Old route is better */ - else if (ret > 0) - { - if (IS_DEBUG_OSPF (lsa, LSA)) - zlog_debug ("Route[External]: Old route is better"); - /* do nothing */ + + /* (4) Let X be the cost specified by the preferred routing table + entry for the ASBR/forwarding address, and Y the cost + specified in the LSA. X is in terms of the link state + metric, and Y is a type 1 or 2 external metric. */ + + + /* (5) Look up the routing table entry for the destination N. If + no entry exists for N, install the AS external path to N, + with next hop equal to the list of next hops to the + forwarding address, and advertising router equal to ASBR. + If the external metric type is 1, then the path-type is set + to type 1 external and the cost is equal to X+Y. If the + external metric type is 2, the path-type is set to type 2 + external, the link state component of the route's cost is X, + and the type 2 cost is Y. */ + new = ospf_ase_calculate_new_route(lsa, asbr_route, metric); + + /* (6) Compare the AS external path described by the LSA with the + existing paths in N's routing table entry, as follows. If + the new path is preferred, it replaces the present paths in + N's routing table entry. If the new path is of equal + preference, it is added to N's routing table entry's list of + paths. */ + + /* Set prefix. */ + p.family = AF_INET; + p.prefix = al->header.id; + p.prefixlen = ip_masklen(al->mask); + + /* if there is a Intra/Inter area route to the N + do not install external route */ + if ((rn = route_node_lookup(ospf->new_table, (struct prefix *)&p))) { + route_unlock_node(rn); + if (rn->info == NULL) + zlog_info("Route[External]: rn->info NULL"); + if (new) + ospf_route_free(new); + return 0; } - /* Routes are equal */ - else - { - if (IS_DEBUG_OSPF (lsa, LSA)) - zlog_debug ("Route[External]: Routes are equal"); - ospf_route_copy_nexthops (or, asbr_route->paths); - if (al->e[0].fwd_addr.s_addr) - ospf_ase_complete_direct_routes (or, al->e[0].fwd_addr); + /* Find a route to the same dest */ + /* If there is no route, create new one. */ + if ((rn = route_node_lookup(ospf->new_external_route, + (struct prefix *)&p))) + route_unlock_node(rn); + + if (!rn || (or = rn->info) == NULL) { + if (IS_DEBUG_OSPF(lsa, LSA)) + zlog_debug("Route[External]: Adding a new route %s/%d", + inet_ntoa(p.prefix), p.prefixlen); + + ospf_route_add(ospf->new_external_route, &p, new, asbr_route); + + if (al->e[0].fwd_addr.s_addr) + ospf_ase_complete_direct_routes(new, al->e[0].fwd_addr); + return 0; + } else { + /* (a) Intra-area and inter-area paths are always preferred + over AS external paths. + + (b) Type 1 external paths are always preferred over type 2 + external paths. When all paths are type 2 external + paths, the paths with the smallest advertised type 2 + metric are always preferred. */ + ret = ospf_route_cmp(ospf, new, or); + + /* (c) If the new AS external path is still + indistinguishable + from the current paths in the N's routing table + entry, + and RFC1583Compatibility is set to "disabled", select + the preferred paths based on the intra-AS paths to + the + ASBR/forwarding addresses, as specified in Section + 16.4.1. + + (d) If the new AS external path is still + indistinguishable + from the current paths in the N's routing table + entry, + select the preferred path based on a least cost + comparison. Type 1 external paths are compared by + looking at the sum of the distance to the forwarding + address and the advertised type 1 metric (X+Y). Type + 2 + external paths advertising equal type 2 metrics are + compared by looking at the distance to the forwarding + addresses. + */ + /* New route is better */ + if (ret < 0) { + if (IS_DEBUG_OSPF(lsa, LSA)) + zlog_debug( + "Route[External]: New route is better"); + ospf_route_subst(rn, new, asbr_route); + if (al->e[0].fwd_addr.s_addr) + ospf_ase_complete_direct_routes( + new, al->e[0].fwd_addr); + or = new; + new = NULL; + } + /* Old route is better */ + else if (ret > 0) { + if (IS_DEBUG_OSPF(lsa, LSA)) + zlog_debug( + "Route[External]: Old route is better"); + /* do nothing */ + } + /* Routes are equal */ + else { + if (IS_DEBUG_OSPF(lsa, LSA)) + zlog_debug("Route[External]: Routes are equal"); + ospf_route_copy_nexthops(or, asbr_route->paths); + if (al->e[0].fwd_addr.s_addr) + ospf_ase_complete_direct_routes( + or, al->e[0].fwd_addr); + } } - } - /* Make sure setting newly calculated ASBR route.*/ - or->u.ext.asbr = asbr_route; - if (new) - ospf_route_free (new); + /* Make sure setting newly calculated ASBR route.*/ + or->u.ext.asbr = asbr_route; + if (new) + ospf_route_free(new); - lsa->route = or; - return 0; + lsa->route = or ; + return 0; } -static int -ospf_ase_route_match_same (struct route_table *rt, struct prefix *prefix, - struct ospf_route *newor) +static int ospf_ase_route_match_same(struct route_table *rt, + struct prefix *prefix, + struct ospf_route *newor) { - struct route_node *rn; - struct ospf_route *or; - struct ospf_path *op; - struct ospf_path *newop; - struct listnode *n1; - struct listnode *n2; - - if (! rt || ! prefix) - return 0; - - rn = route_node_lookup (rt, prefix); - if (! rn) - return 0; - - route_unlock_node (rn); - - or = rn->info; - if (or->path_type != newor->path_type) - return 0; - - switch (or->path_type) - { - case OSPF_PATH_TYPE1_EXTERNAL: - if (or->cost != newor->cost) - return 0; - break; - case OSPF_PATH_TYPE2_EXTERNAL: - if ((or->cost != newor->cost) || - (or->u.ext.type2_cost != newor->u.ext.type2_cost)) - return 0; - break; - default: - assert (0); - return 0; - } - - if (or->paths->count != newor->paths->count) - return 0; - - /* Check each path. */ - for (n1 = listhead (or->paths), n2 = listhead (newor->paths); - n1 && n2; n1 = listnextnode (n1), n2 = listnextnode (n2)) - { - op = listgetdata (n1); - newop = listgetdata (n2); - - if (! IPV4_ADDR_SAME (&op->nexthop, &newop->nexthop)) - return 0; - if (op->ifindex != newop->ifindex) - return 0; - } - - if (or->u.ext.tag != newor->u.ext.tag) - return 0; - - return 1; + struct route_node *rn; + struct ospf_route * or ; + struct ospf_path *op; + struct ospf_path *newop; + struct listnode *n1; + struct listnode *n2; + + if (!rt || !prefix) + return 0; + + rn = route_node_lookup(rt, prefix); + if (!rn) + return 0; + + route_unlock_node(rn); + + or = rn->info; + if (or->path_type != newor->path_type) + return 0; + + switch (or->path_type) { + case OSPF_PATH_TYPE1_EXTERNAL: + if (or->cost != newor->cost) + return 0; + break; + case OSPF_PATH_TYPE2_EXTERNAL: + if ((or->cost != newor->cost) + || (or->u.ext.type2_cost != newor->u.ext.type2_cost)) + return 0; + break; + default: + assert(0); + return 0; + } + + if (or->paths->count != newor->paths->count) + return 0; + + /* Check each path. */ + for (n1 = listhead(or->paths), n2 = listhead(newor->paths); n1 && n2; + n1 = listnextnode(n1), n2 = listnextnode(n2)) { + op = listgetdata(n1); + newop = listgetdata(n2); + + if (!IPV4_ADDR_SAME(&op->nexthop, &newop->nexthop)) + return 0; + if (op->ifindex != newop->ifindex) + return 0; + } + + if (or->u.ext.tag != newor->u.ext.tag) + return 0; + + return 1; } -static int -ospf_ase_compare_tables (struct route_table *new_external_route, - struct route_table *old_external_route) +static int ospf_ase_compare_tables(struct route_table *new_external_route, + struct route_table *old_external_route) { - struct route_node *rn, *new_rn; - struct ospf_route *or; - - /* Remove deleted routes */ - for (rn = route_top (old_external_route); rn; rn = route_next (rn)) - if ((or = rn->info)) - { - if (! (new_rn = route_node_lookup (new_external_route, &rn->p))) - ospf_zebra_delete ((struct prefix_ipv4 *) &rn->p, or); - else - route_unlock_node (new_rn); - } - - - /* Install new routes */ - for (rn = route_top (new_external_route); rn; rn = route_next (rn)) - if ((or = rn->info) != NULL) - if (! ospf_ase_route_match_same (old_external_route, &rn->p, or)) - ospf_zebra_add ((struct prefix_ipv4 *) &rn->p, or); - - return 0; + struct route_node *rn, *new_rn; + struct ospf_route * or ; + + /* Remove deleted routes */ + for (rn = route_top(old_external_route); rn; rn = route_next(rn)) + if ((or = rn->info)) { + if (!(new_rn = route_node_lookup(new_external_route, + &rn->p))) + ospf_zebra_delete((struct prefix_ipv4 *)&rn->p, + or); + else + route_unlock_node(new_rn); + } + + + /* Install new routes */ + for (rn = route_top(new_external_route); rn; rn = route_next(rn)) + if ((or = rn->info) != NULL) + if (!ospf_ase_route_match_same(old_external_route, + &rn->p, or)) + ospf_zebra_add((struct prefix_ipv4 *)&rn->p, + or); + + return 0; } -static int -ospf_ase_calculate_timer (struct thread *t) +static int ospf_ase_calculate_timer(struct thread *t) { - struct ospf *ospf; - struct ospf_lsa *lsa; - struct route_node *rn; - struct listnode *node; - struct ospf_area *area; - struct timeval start_time, stop_time; - - ospf = THREAD_ARG (t); - ospf->t_ase_calc = NULL; - - if (ospf->ase_calc) - { - ospf->ase_calc = 0; - - monotime(&start_time); - - /* Calculate external route for each AS-external-LSA */ - LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa) - ospf_ase_calculate_route (ospf, lsa); - - /* This version simple adds to the table all NSSA areas */ - if (ospf->anyNSSA) - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_ase_calculate_timer(): looking at area %s", - inet_ntoa (area->area_id)); - - if (area->external_routing == OSPF_AREA_NSSA) - LSDB_LOOP (NSSA_LSDB (area), rn, lsa) - ospf_ase_calculate_route (ospf, lsa); - } - /* kevinm: And add the NSSA routes in ospf_top */ - LSDB_LOOP (NSSA_LSDB (ospf),rn,lsa) - ospf_ase_calculate_route(ospf,lsa); - - /* Compare old and new external routing table and install the - difference info zebra/kernel */ - ospf_ase_compare_tables (ospf->new_external_route, - ospf->old_external_route); - - /* Delete old external routing table */ - ospf_route_table_free (ospf->old_external_route); - ospf->old_external_route = ospf->new_external_route; - ospf->new_external_route = route_table_init (); - - monotime(&stop_time); - - zlog_info ("SPF Processing Time(usecs): External Routes: %lld\n", - (stop_time.tv_sec - start_time.tv_sec)*1000000LL+ - (stop_time.tv_usec - start_time.tv_usec)); - } - return 0; + struct ospf *ospf; + struct ospf_lsa *lsa; + struct route_node *rn; + struct listnode *node; + struct ospf_area *area; + struct timeval start_time, stop_time; + + ospf = THREAD_ARG(t); + ospf->t_ase_calc = NULL; + + if (ospf->ase_calc) { + ospf->ase_calc = 0; + + monotime(&start_time); + + /* Calculate external route for each AS-external-LSA */ + LSDB_LOOP(EXTERNAL_LSDB(ospf), rn, lsa) + ospf_ase_calculate_route(ospf, lsa); + + /* This version simple adds to the table all NSSA areas */ + if (ospf->anyNSSA) + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_ase_calculate_timer(): looking at area %s", + inet_ntoa(area->area_id)); + + if (area->external_routing == OSPF_AREA_NSSA) + LSDB_LOOP(NSSA_LSDB(area), rn, lsa) + ospf_ase_calculate_route(ospf, lsa); + } + /* kevinm: And add the NSSA routes in ospf_top */ + LSDB_LOOP(NSSA_LSDB(ospf), rn, lsa) + ospf_ase_calculate_route(ospf, lsa); + + /* Compare old and new external routing table and install the + difference info zebra/kernel */ + ospf_ase_compare_tables(ospf->new_external_route, + ospf->old_external_route); + + /* Delete old external routing table */ + ospf_route_table_free(ospf->old_external_route); + ospf->old_external_route = ospf->new_external_route; + ospf->new_external_route = route_table_init(); + + monotime(&stop_time); + + zlog_info("SPF Processing Time(usecs): External Routes: %lld\n", + (stop_time.tv_sec - start_time.tv_sec) * 1000000LL + + (stop_time.tv_usec - start_time.tv_usec)); + } + return 0; } -void -ospf_ase_calculate_schedule (struct ospf *ospf) +void ospf_ase_calculate_schedule(struct ospf *ospf) { - if (ospf == NULL) - return; + if (ospf == NULL) + return; - ospf->ase_calc = 1; + ospf->ase_calc = 1; } -void -ospf_ase_calculate_timer_add (struct ospf *ospf) +void ospf_ase_calculate_timer_add(struct ospf *ospf) { - if (ospf == NULL) - return; + if (ospf == NULL) + return; - thread_add_timer(master, ospf_ase_calculate_timer, ospf, - OSPF_ASE_CALC_INTERVAL, &ospf->t_ase_calc); + thread_add_timer(master, ospf_ase_calculate_timer, ospf, + OSPF_ASE_CALC_INTERVAL, &ospf->t_ase_calc); } -void -ospf_ase_register_external_lsa (struct ospf_lsa *lsa, struct ospf *top) +void ospf_ase_register_external_lsa(struct ospf_lsa *lsa, struct ospf *top) { - struct route_node *rn; - struct prefix_ipv4 p; - struct list *lst; - struct as_external_lsa *al; - - al = (struct as_external_lsa *) lsa->data; - p.family = AF_INET; - p.prefix = lsa->data->id; - p.prefixlen = ip_masklen (al->mask); - apply_mask_ipv4 (&p); - - rn = route_node_get (top->external_lsas, (struct prefix *) &p); - if ((lst = rn->info) == NULL) - rn->info = lst = list_new(); - else - route_unlock_node (rn); - - /* We assume that if LSA is deleted from DB - is is also deleted from this RT */ - listnode_add (lst, ospf_lsa_lock (lsa)); /* external_lsas lst */ + struct route_node *rn; + struct prefix_ipv4 p; + struct list *lst; + struct as_external_lsa *al; + + al = (struct as_external_lsa *)lsa->data; + p.family = AF_INET; + p.prefix = lsa->data->id; + p.prefixlen = ip_masklen(al->mask); + apply_mask_ipv4(&p); + + rn = route_node_get(top->external_lsas, (struct prefix *)&p); + if ((lst = rn->info) == NULL) + rn->info = lst = list_new(); + else + route_unlock_node(rn); + + /* We assume that if LSA is deleted from DB + is is also deleted from this RT */ + listnode_add(lst, ospf_lsa_lock(lsa)); /* external_lsas lst */ } -void -ospf_ase_unregister_external_lsa (struct ospf_lsa *lsa, struct ospf *top) +void ospf_ase_unregister_external_lsa(struct ospf_lsa *lsa, struct ospf *top) { - struct route_node *rn; - struct prefix_ipv4 p; - struct list *lst; - struct as_external_lsa *al; - - al = (struct as_external_lsa *) lsa->data; - p.family = AF_INET; - p.prefix = lsa->data->id; - p.prefixlen = ip_masklen (al->mask); - apply_mask_ipv4 (&p); - - rn = route_node_lookup (top->external_lsas, (struct prefix *) &p); - - if (rn) { - lst = rn->info; - listnode_delete (lst, lsa); - ospf_lsa_unlock (&lsa); /* external_lsas list */ - route_unlock_node (rn); - } + struct route_node *rn; + struct prefix_ipv4 p; + struct list *lst; + struct as_external_lsa *al; + + al = (struct as_external_lsa *)lsa->data; + p.family = AF_INET; + p.prefix = lsa->data->id; + p.prefixlen = ip_masklen(al->mask); + apply_mask_ipv4(&p); + + rn = route_node_lookup(top->external_lsas, (struct prefix *)&p); + + if (rn) { + lst = rn->info; + listnode_delete(lst, lsa); + ospf_lsa_unlock(&lsa); /* external_lsas list */ + route_unlock_node(rn); + } } -void -ospf_ase_external_lsas_finish (struct route_table *rt) +void ospf_ase_external_lsas_finish(struct route_table *rt) { - struct route_node *rn; - struct ospf_lsa *lsa; - struct list *lst; - struct listnode *node, *nnode; - - for (rn = route_top (rt); rn; rn = route_next (rn)) - if ((lst = rn->info) != NULL) - { - for (ALL_LIST_ELEMENTS (lst, node, nnode, lsa)) - ospf_lsa_unlock (&lsa); /* external_lsas lst */ - list_delete (lst); - } - - route_table_finish (rt); + struct route_node *rn; + struct ospf_lsa *lsa; + struct list *lst; + struct listnode *node, *nnode; + + for (rn = route_top(rt); rn; rn = route_next(rn)) + if ((lst = rn->info) != NULL) { + for (ALL_LIST_ELEMENTS(lst, node, nnode, lsa)) + ospf_lsa_unlock(&lsa); /* external_lsas lst */ + list_delete(lst); + } + + route_table_finish(rt); } -void -ospf_ase_incremental_update (struct ospf *ospf, struct ospf_lsa *lsa) +void ospf_ase_incremental_update(struct ospf *ospf, struct ospf_lsa *lsa) { - struct list *lsas; - struct listnode *node; - struct route_node *rn, *rn2; - struct prefix_ipv4 p; - struct route_table *tmp_old; - struct as_external_lsa *al; - - al = (struct as_external_lsa *) lsa->data; - p.family = AF_INET; - p.prefix = lsa->data->id; - p.prefixlen = ip_masklen (al->mask); - apply_mask_ipv4 (&p); - - /* if new_table is NULL, there was no spf calculation, thus - incremental update is unneeded */ - if (!ospf->new_table) - return; - - /* If there is already an intra-area or inter-area route - to the destination, no recalculation is necessary - (internal routes take precedence). */ - - rn = route_node_lookup (ospf->new_table, (struct prefix *) &p); - if (rn) - { - route_unlock_node (rn); - if (rn->info) - return; - } - - rn = route_node_lookup (ospf->external_lsas, (struct prefix *) &p); - assert (rn); - assert (rn->info); - lsas = rn->info; - route_unlock_node (rn); - - for (ALL_LIST_ELEMENTS_RO (lsas, node, lsa)) - ospf_ase_calculate_route (ospf, lsa); - - /* prepare temporary old routing table for compare */ - tmp_old = route_table_init (); - rn = route_node_lookup (ospf->old_external_route, (struct prefix *) &p); - if (rn && rn->info) - { - rn2 = route_node_get (tmp_old, (struct prefix *) &p); - rn2->info = rn->info; - route_unlock_node (rn); - } - - /* install changes to zebra */ - ospf_ase_compare_tables (ospf->new_external_route, tmp_old); + struct list *lsas; + struct listnode *node; + struct route_node *rn, *rn2; + struct prefix_ipv4 p; + struct route_table *tmp_old; + struct as_external_lsa *al; + + al = (struct as_external_lsa *)lsa->data; + p.family = AF_INET; + p.prefix = lsa->data->id; + p.prefixlen = ip_masklen(al->mask); + apply_mask_ipv4(&p); + + /* if new_table is NULL, there was no spf calculation, thus + incremental update is unneeded */ + if (!ospf->new_table) + return; + + /* If there is already an intra-area or inter-area route + to the destination, no recalculation is necessary + (internal routes take precedence). */ + + rn = route_node_lookup(ospf->new_table, (struct prefix *)&p); + if (rn) { + route_unlock_node(rn); + if (rn->info) + return; + } - /* update ospf->old_external_route table */ - if (rn && rn->info) - ospf_route_free ((struct ospf_route *) rn->info); + rn = route_node_lookup(ospf->external_lsas, (struct prefix *)&p); + assert(rn); + assert(rn->info); + lsas = rn->info; + route_unlock_node(rn); + + for (ALL_LIST_ELEMENTS_RO(lsas, node, lsa)) + ospf_ase_calculate_route(ospf, lsa); + + /* prepare temporary old routing table for compare */ + tmp_old = route_table_init(); + rn = route_node_lookup(ospf->old_external_route, (struct prefix *)&p); + if (rn && rn->info) { + rn2 = route_node_get(tmp_old, (struct prefix *)&p); + rn2->info = rn->info; + route_unlock_node(rn); + } - rn2 = route_node_lookup (ospf->new_external_route, (struct prefix *) &p); - /* if new route exists, install it to ospf->old_external_route */ - if (rn2 && rn2->info) - { - if (!rn) - rn = route_node_get (ospf->old_external_route, (struct prefix *) &p); - rn->info = rn2->info; - } - else - { - /* remove route node from ospf->old_external_route */ - if (rn) - { - rn->info = NULL; - route_unlock_node (rn); + /* install changes to zebra */ + ospf_ase_compare_tables(ospf->new_external_route, tmp_old); + + /* update ospf->old_external_route table */ + if (rn && rn->info) + ospf_route_free((struct ospf_route *)rn->info); + + rn2 = route_node_lookup(ospf->new_external_route, (struct prefix *)&p); + /* if new route exists, install it to ospf->old_external_route */ + if (rn2 && rn2->info) { + if (!rn) + rn = route_node_get(ospf->old_external_route, + (struct prefix *)&p); + rn->info = rn2->info; + } else { + /* remove route node from ospf->old_external_route */ + if (rn) { + rn->info = NULL; + route_unlock_node(rn); + } } - } - if (rn2) - { - /* rn2->info is stored in route node of ospf->old_external_route */ - rn2->info = NULL; - route_unlock_node (rn2); - route_unlock_node (rn2); - } + if (rn2) { + /* rn2->info is stored in route node of ospf->old_external_route + */ + rn2->info = NULL; + route_unlock_node(rn2); + route_unlock_node(rn2); + } - route_table_finish (tmp_old); + route_table_finish(tmp_old); } diff --git a/ospfd/ospf_ase.h b/ospfd/ospf_ase.h index d73322fca..195d658c0 100644 --- a/ospfd/ospf_ase.h +++ b/ospfd/ospf_ase.h @@ -22,25 +22,19 @@ #ifndef _ZEBRA_OSPF_ASE_H #define _ZEBRA_OSPF_ASE_H +extern struct ospf_route * +ospf_find_asbr_route(struct ospf *, struct route_table *, struct prefix_ipv4 *); +extern struct ospf_route * +ospf_find_asbr_route_through_area(struct route_table *, struct prefix_ipv4 *, + struct ospf_area *); -extern struct ospf_route *ospf_find_asbr_route (struct ospf *, - struct route_table *, - struct prefix_ipv4 *); -extern struct ospf_route *ospf_find_asbr_route_through_area (struct - route_table *, - struct - prefix_ipv4 *, - struct ospf_area - *); +extern int ospf_ase_calculate_route(struct ospf *, struct ospf_lsa *); +extern void ospf_ase_calculate_schedule(struct ospf *); +extern void ospf_ase_calculate_timer_add(struct ospf *); -extern int ospf_ase_calculate_route (struct ospf *, struct ospf_lsa *); -extern void ospf_ase_calculate_schedule (struct ospf *); -extern void ospf_ase_calculate_timer_add (struct ospf *); - -extern void ospf_ase_external_lsas_finish (struct route_table *); -extern void ospf_ase_incremental_update (struct ospf *, struct ospf_lsa *); -extern void ospf_ase_register_external_lsa (struct ospf_lsa *, struct ospf *); -extern void ospf_ase_unregister_external_lsa (struct ospf_lsa *, - struct ospf *); +extern void ospf_ase_external_lsas_finish(struct route_table *); +extern void ospf_ase_incremental_update(struct ospf *, struct ospf_lsa *); +extern void ospf_ase_register_external_lsa(struct ospf_lsa *, struct ospf *); +extern void ospf_ase_unregister_external_lsa(struct ospf_lsa *, struct ospf *); #endif /* _ZEBRA_OSPF_ASE_H */ diff --git a/ospfd/ospf_bfd.c b/ospfd/ospf_bfd.c index 1bcffea6f..6d07b4436 100644 --- a/ospfd/ospf_bfd.c +++ b/ospfd/ospf_bfd.c @@ -49,10 +49,9 @@ extern struct zclient *zclient; /* * ospf_bfd_info_free - Free BFD info structure */ -void -ospf_bfd_info_free(void **bfd_info) +void ospf_bfd_info_free(void **bfd_info) { - bfd_info_free((struct bfd_info **) bfd_info); + bfd_info_free((struct bfd_info **)bfd_info); } /* @@ -60,42 +59,40 @@ ospf_bfd_info_free(void **bfd_info) * zebra for starting/stopping the monitoring of * the neighbor rechahability. */ -static void -ospf_bfd_reg_dereg_nbr (struct ospf_neighbor *nbr, int command) +static void ospf_bfd_reg_dereg_nbr(struct ospf_neighbor *nbr, int command) { - struct ospf_interface *oi = nbr->oi; - struct interface *ifp = oi->ifp; - struct ospf_if_params *params; - struct bfd_info *bfd_info; - - /* Check if BFD is enabled */ - params = IF_DEF_PARAMS (ifp); - - /* Check if BFD is enabled */ - if (!params->bfd_info) - return; - bfd_info = (struct bfd_info *)params->bfd_info; - - if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) - zlog_debug ("%s nbr (%s) with BFD", - bfd_get_command_dbg_str(command), - inet_ntoa (nbr->src)); - - bfd_peer_sendmsg (zclient, bfd_info, AF_INET, - &nbr->src, NULL, ifp->name, 0, 0, command, 0, VRF_DEFAULT); + struct ospf_interface *oi = nbr->oi; + struct interface *ifp = oi->ifp; + struct ospf_if_params *params; + struct bfd_info *bfd_info; + + /* Check if BFD is enabled */ + params = IF_DEF_PARAMS(ifp); + + /* Check if BFD is enabled */ + if (!params->bfd_info) + return; + bfd_info = (struct bfd_info *)params->bfd_info; + + if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) + zlog_debug("%s nbr (%s) with BFD", + bfd_get_command_dbg_str(command), + inet_ntoa(nbr->src)); + + bfd_peer_sendmsg(zclient, bfd_info, AF_INET, &nbr->src, NULL, ifp->name, + 0, 0, command, 0, VRF_DEFAULT); } /* * ospf_bfd_trigger_event - Neighbor is registered/deregistered with BFD when * neighbor state is changed to/from 2way. */ -void -ospf_bfd_trigger_event(struct ospf_neighbor *nbr, int old_state, int state) +void ospf_bfd_trigger_event(struct ospf_neighbor *nbr, int old_state, int state) { - if ((old_state < NSM_TwoWay) && (state >= NSM_TwoWay)) - ospf_bfd_reg_dereg_nbr(nbr, ZEBRA_BFD_DEST_REGISTER); - else if ((old_state >= NSM_TwoWay) && (state < NSM_TwoWay)) - ospf_bfd_reg_dereg_nbr(nbr, ZEBRA_BFD_DEST_DEREGISTER); + if ((old_state < NSM_TwoWay) && (state >= NSM_TwoWay)) + ospf_bfd_reg_dereg_nbr(nbr, ZEBRA_BFD_DEST_REGISTER); + else if ((old_state >= NSM_TwoWay) && (state < NSM_TwoWay)) + ospf_bfd_reg_dereg_nbr(nbr, ZEBRA_BFD_DEST_DEREGISTER); } /* @@ -104,95 +101,91 @@ ospf_bfd_trigger_event(struct ospf_neighbor *nbr, int old_state, int state) * zebra for starting/stopping the monitoring of * the neighbor rechahability. */ -static int -ospf_bfd_reg_dereg_all_nbr (struct interface *ifp, int command) +static int ospf_bfd_reg_dereg_all_nbr(struct interface *ifp, int command) { - struct ospf_interface *oi; - struct route_table *nbrs; - struct ospf_neighbor *nbr; - struct route_node *irn; - struct route_node *nrn; - - for (irn = route_top (IF_OIFS (ifp)); irn; irn = route_next (irn)) - { - if ((oi = irn->info) == NULL) - continue; - - if ((nbrs = oi->nbrs) == NULL) - continue; - - for (nrn = route_top (nbrs); nrn; nrn = route_next (nrn)) - { - if ((nbr = nrn->info) == NULL || nbr == oi->nbr_self) - continue; - - if (command != ZEBRA_BFD_DEST_DEREGISTER) - ospf_bfd_info_nbr_create(oi, nbr); - else - bfd_info_free((struct bfd_info **)&nbr->bfd_info); - - if (nbr->state < NSM_TwoWay) - continue; - - ospf_bfd_reg_dereg_nbr(nbr, command); - } - } - - return 0; + struct ospf_interface *oi; + struct route_table *nbrs; + struct ospf_neighbor *nbr; + struct route_node *irn; + struct route_node *nrn; + + for (irn = route_top(IF_OIFS(ifp)); irn; irn = route_next(irn)) { + if ((oi = irn->info) == NULL) + continue; + + if ((nbrs = oi->nbrs) == NULL) + continue; + + for (nrn = route_top(nbrs); nrn; nrn = route_next(nrn)) { + if ((nbr = nrn->info) == NULL || nbr == oi->nbr_self) + continue; + + if (command != ZEBRA_BFD_DEST_DEREGISTER) + ospf_bfd_info_nbr_create(oi, nbr); + else + bfd_info_free( + (struct bfd_info **)&nbr->bfd_info); + + if (nbr->state < NSM_TwoWay) + continue; + + ospf_bfd_reg_dereg_nbr(nbr, command); + } + } + + return 0; } /* * ospf_bfd_nbr_replay - Replay all the neighbors that have BFD enabled * to zebra */ -static int -ospf_bfd_nbr_replay (int command, struct zclient *zclient, zebra_size_t length, - vrf_id_t vrf_id) +static int ospf_bfd_nbr_replay(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct listnode *inode, *node, *onode; - struct ospf *ospf; - struct ospf_interface *oi; - struct route_table *nbrs; - struct route_node *rn; - struct ospf_neighbor *nbr; - struct ospf_if_params *params; - - if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) - { - 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 in BGP */ - for (ALL_LIST_ELEMENTS (om->ospf, node, onode, ospf)) - { - for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, inode, oi)) - { - if ((nbrs = oi->nbrs) == NULL) - continue; - - params = IF_DEF_PARAMS (oi->ifp); - if (!params->bfd_info) - continue; - - for (rn = route_top (nbrs); rn; rn = route_next (rn)) - { - if ((nbr = rn->info) == NULL || nbr == oi->nbr_self) - continue; - - if (nbr->state < NSM_TwoWay) - continue; - - if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) - zlog_debug ("Replaying nbr (%s) to BFD", inet_ntoa (nbr->src)); - - ospf_bfd_reg_dereg_nbr(nbr, ZEBRA_BFD_DEST_UPDATE); - } - } - } - return 0; + struct listnode *inode, *node, *onode; + struct ospf *ospf; + struct ospf_interface *oi; + struct route_table *nbrs; + struct route_node *rn; + struct ospf_neighbor *nbr; + struct ospf_if_params *params; + + if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) { + 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 in BGP */ + for (ALL_LIST_ELEMENTS(om->ospf, node, onode, ospf)) { + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, inode, oi)) { + if ((nbrs = oi->nbrs) == NULL) + continue; + + params = IF_DEF_PARAMS(oi->ifp); + if (!params->bfd_info) + continue; + + for (rn = route_top(nbrs); rn; rn = route_next(rn)) { + if ((nbr = rn->info) == NULL + || nbr == oi->nbr_self) + continue; + + if (nbr->state < NSM_TwoWay) + continue; + + if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) + zlog_debug("Replaying nbr (%s) to BFD", + inet_ntoa(nbr->src)); + + ospf_bfd_reg_dereg_nbr(nbr, + ZEBRA_BFD_DEST_UPDATE); + } + } + } + return 0; } /* @@ -201,163 +194,160 @@ ospf_bfd_nbr_replay (int command, struct zclient *zclient, zebra_size_t length, * connectivity if the BFD status changed to * down. */ -static int -ospf_bfd_interface_dest_update (int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int ospf_bfd_interface_dest_update(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct interface *ifp; - struct ospf_interface *oi; - struct ospf_if_params *params; - struct ospf_neighbor *nbr; - struct route_node *node; - struct prefix p; - int status; - int old_status; - struct bfd_info *bfd_info; - struct timeval tv; - - ifp = bfd_get_peer_info (zclient->ibuf, &p, NULL, &status, vrf_id); - - if ((ifp == NULL) || (p.family != AF_INET)) - return 0; - - if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE)) - { - char buf[PREFIX2STR_BUFFER]; - prefix2str(&p, buf, sizeof(buf)); - zlog_debug("Zebra: interface %s bfd destination %s %s", ifp->name, buf, - bfd_get_status_str(status)); - } - - params = IF_DEF_PARAMS (ifp); - if (!params->bfd_info) - return 0; - - for (node = route_top (IF_OIFS (ifp)); node; node = route_next (node)) - { - if ((oi = node->info) == NULL) - continue; - - nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &p.u.prefix4); - if (!nbr || !nbr->bfd_info) - continue; - - bfd_info = (struct bfd_info *)nbr->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)) - { - if (IS_DEBUG_OSPF (nsm, NSM_EVENTS)) - zlog_debug ("NSM[%s:%s]: BFD Down", - IF_NAME (nbr->oi), inet_ntoa (nbr->address.u.prefix4)); - - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_InactivityTimer); - } - } - - return 0; + struct interface *ifp; + struct ospf_interface *oi; + struct ospf_if_params *params; + struct ospf_neighbor *nbr; + struct route_node *node; + struct prefix p; + int status; + int old_status; + struct bfd_info *bfd_info; + struct timeval tv; + + ifp = bfd_get_peer_info(zclient->ibuf, &p, NULL, &status, vrf_id); + + if ((ifp == NULL) || (p.family != AF_INET)) + return 0; + + if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) { + char buf[PREFIX2STR_BUFFER]; + prefix2str(&p, buf, sizeof(buf)); + zlog_debug("Zebra: interface %s bfd destination %s %s", + ifp->name, buf, bfd_get_status_str(status)); + } + + params = IF_DEF_PARAMS(ifp); + if (!params->bfd_info) + return 0; + + for (node = route_top(IF_OIFS(ifp)); node; node = route_next(node)) { + if ((oi = node->info) == NULL) + continue; + + nbr = ospf_nbr_lookup_by_addr(oi->nbrs, &p.u.prefix4); + if (!nbr || !nbr->bfd_info) + continue; + + bfd_info = (struct bfd_info *)nbr->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)) { + if (IS_DEBUG_OSPF(nsm, NSM_EVENTS)) + zlog_debug("NSM[%s:%s]: BFD Down", + IF_NAME(nbr->oi), + inet_ntoa(nbr->address.u.prefix4)); + + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_InactivityTimer); + } + } + + return 0; } /* * ospf_bfd_info_nbr_create - Create/update BFD information for a neighbor. */ -void -ospf_bfd_info_nbr_create (struct ospf_interface *oi, struct ospf_neighbor *nbr) +void ospf_bfd_info_nbr_create(struct ospf_interface *oi, + struct ospf_neighbor *nbr) { - struct bfd_info *oi_bfd_info; - struct bfd_info *nbr_bfd_info; - struct interface *ifp = oi->ifp; - struct ospf_if_params *params; - - /* Check if BFD is enabled */ - params = IF_DEF_PARAMS (ifp); - - /* Check if BFD is enabled */ - if (!params->bfd_info) - return; - - oi_bfd_info = (struct bfd_info *)params->bfd_info; - if (!nbr->bfd_info) - nbr->bfd_info = bfd_info_create(); - - nbr_bfd_info = (struct bfd_info *)nbr->bfd_info; - nbr_bfd_info->detect_mult = oi_bfd_info->detect_mult; - nbr_bfd_info->desired_min_tx = oi_bfd_info->desired_min_tx; - nbr_bfd_info->required_min_rx = oi_bfd_info->required_min_rx; + struct bfd_info *oi_bfd_info; + struct bfd_info *nbr_bfd_info; + struct interface *ifp = oi->ifp; + struct ospf_if_params *params; + + /* Check if BFD is enabled */ + params = IF_DEF_PARAMS(ifp); + + /* Check if BFD is enabled */ + if (!params->bfd_info) + return; + + oi_bfd_info = (struct bfd_info *)params->bfd_info; + if (!nbr->bfd_info) + nbr->bfd_info = bfd_info_create(); + + nbr_bfd_info = (struct bfd_info *)nbr->bfd_info; + nbr_bfd_info->detect_mult = oi_bfd_info->detect_mult; + nbr_bfd_info->desired_min_tx = oi_bfd_info->desired_min_tx; + nbr_bfd_info->required_min_rx = oi_bfd_info->required_min_rx; } /* * ospf_bfd_write_config - Write the interface BFD configuration. */ -void -ospf_bfd_write_config(struct vty *vty, struct ospf_if_params *params) +void ospf_bfd_write_config(struct vty *vty, struct ospf_if_params *params) { - struct bfd_info *bfd_info; + struct bfd_info *bfd_info; - if (!params->bfd_info) - return; + if (!params->bfd_info) + return; - bfd_info = (struct bfd_info *)params->bfd_info; + bfd_info = (struct bfd_info *)params->bfd_info; - if (CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG)) - vty_out (vty, " ip ospf bfd %d %d %d\n", - bfd_info->detect_mult, bfd_info->required_min_rx, - bfd_info->desired_min_tx); - else - vty_out (vty, " ip ospf bfd\n"); + if (CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG)) + vty_out(vty, " ip ospf bfd %d %d %d\n", bfd_info->detect_mult, + bfd_info->required_min_rx, bfd_info->desired_min_tx); + else + vty_out(vty, " ip ospf bfd\n"); } /* * ospf_bfd_show_info - Show BFD info structure */ -void -ospf_bfd_show_info(struct vty *vty, void *bfd_info, json_object *json_obj, - u_char use_json, int param_only) +void ospf_bfd_show_info(struct vty *vty, void *bfd_info, json_object *json_obj, + u_char use_json, int param_only) { - if (param_only) - bfd_show_param(vty, (struct bfd_info *)bfd_info, 1, 0, use_json, json_obj); - else - bfd_show_info(vty, (struct bfd_info *)bfd_info, 0, 1, use_json, json_obj); + if (param_only) + bfd_show_param(vty, (struct bfd_info *)bfd_info, 1, 0, use_json, + json_obj); + else + bfd_show_info(vty, (struct bfd_info *)bfd_info, 0, 1, use_json, + json_obj); } /* * ospf_bfd_interface_show - Show the interface BFD configuration. */ -void -ospf_bfd_interface_show(struct vty *vty, struct interface *ifp, - json_object *json_interface_sub, u_char use_json) +void ospf_bfd_interface_show(struct vty *vty, struct interface *ifp, + json_object *json_interface_sub, u_char use_json) { - struct ospf_if_params *params; + struct ospf_if_params *params; - params = IF_DEF_PARAMS (ifp); + params = IF_DEF_PARAMS(ifp); - ospf_bfd_show_info(vty, params->bfd_info, json_interface_sub, use_json, 1); + ospf_bfd_show_info(vty, params->bfd_info, json_interface_sub, use_json, + 1); } /* * ospf_bfd_if_param_set - Set the configured BFD paramter values for * interface. */ -static void -ospf_bfd_if_param_set (struct interface *ifp, u_int32_t min_rx, - u_int32_t min_tx, u_int8_t detect_mult, int defaults) +static void ospf_bfd_if_param_set(struct interface *ifp, u_int32_t min_rx, + u_int32_t min_tx, u_int8_t detect_mult, + int defaults) { - struct ospf_if_params *params; - int command = 0; + struct ospf_if_params *params; + int command = 0; - params = IF_DEF_PARAMS (ifp); + params = IF_DEF_PARAMS(ifp); - bfd_set_param((struct bfd_info **)&(params->bfd_info), min_rx, min_tx, - detect_mult, defaults, &command); - if (command) - ospf_bfd_reg_dereg_all_nbr(ifp, command); + bfd_set_param((struct bfd_info **)&(params->bfd_info), min_rx, min_tx, + detect_mult, defaults, &command); + if (command) + ospf_bfd_reg_dereg_all_nbr(ifp, command); } DEFUN (ip_ospf_bfd, @@ -367,19 +357,19 @@ DEFUN (ip_ospf_bfd, "OSPF interface commands\n" "Enables BFD support\n") { - VTY_DECLVAR_CONTEXT(interface, ifp); - struct ospf_if_params *params; - struct bfd_info *bfd_info; + VTY_DECLVAR_CONTEXT(interface, ifp); + struct ospf_if_params *params; + struct bfd_info *bfd_info; - assert (ifp); - params = IF_DEF_PARAMS (ifp); - bfd_info = params->bfd_info; + assert(ifp); + params = IF_DEF_PARAMS(ifp); + bfd_info = params->bfd_info; - if (!bfd_info || ! CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG)) - ospf_bfd_if_param_set (ifp, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX, - BFD_DEF_DETECT_MULT, 1); + if (!bfd_info || !CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG)) + ospf_bfd_if_param_set(ifp, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX, + BFD_DEF_DETECT_MULT, 1); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (ip_ospf_bfd_param, @@ -392,24 +382,26 @@ DEFUN (ip_ospf_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; - u_int32_t rx_val; - u_int32_t tx_val; - u_int8_t dm_val; - int ret; - - assert (ifp); - - 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; - - ospf_bfd_if_param_set (ifp, 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; + u_int32_t rx_val; + u_int32_t tx_val; + u_int8_t dm_val; + int ret; + + assert(ifp); + + 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; + + ospf_bfd_if_param_set(ifp, rx_val, tx_val, dm_val, 0); + + return CMD_SUCCESS; } DEFUN (no_ip_ospf_bfd, @@ -423,32 +415,30 @@ DEFUN (no_ip_ospf_bfd, "Required min receive interval\n" "Desired min transmit interval\n") { - VTY_DECLVAR_CONTEXT(interface, ifp); - struct ospf_if_params *params; + VTY_DECLVAR_CONTEXT(interface, ifp); + struct ospf_if_params *params; - assert (ifp); + assert(ifp); - params = IF_DEF_PARAMS (ifp); - if (params->bfd_info) - { - ospf_bfd_reg_dereg_all_nbr(ifp, ZEBRA_BFD_DEST_DEREGISTER); - bfd_info_free(&(params->bfd_info)); - } + params = IF_DEF_PARAMS(ifp); + if (params->bfd_info) { + ospf_bfd_reg_dereg_all_nbr(ifp, ZEBRA_BFD_DEST_DEREGISTER); + bfd_info_free(&(params->bfd_info)); + } - return CMD_SUCCESS; + return CMD_SUCCESS; } -void -ospf_bfd_init(void) +void ospf_bfd_init(void) { - bfd_gbl_init(); + bfd_gbl_init(); - /* Initialize BFD client functions */ - zclient->interface_bfd_dest_update = ospf_bfd_interface_dest_update; - zclient->bfd_dest_replay = ospf_bfd_nbr_replay; + /* Initialize BFD client functions */ + zclient->interface_bfd_dest_update = ospf_bfd_interface_dest_update; + zclient->bfd_dest_replay = ospf_bfd_nbr_replay; - /* Install BFD command */ - install_element (INTERFACE_NODE, &ip_ospf_bfd_cmd); - install_element (INTERFACE_NODE, &ip_ospf_bfd_param_cmd); - install_element (INTERFACE_NODE, &no_ip_ospf_bfd_cmd); + /* Install BFD command */ + install_element(INTERFACE_NODE, &ip_ospf_bfd_cmd); + install_element(INTERFACE_NODE, &ip_ospf_bfd_param_cmd); + install_element(INTERFACE_NODE, &no_ip_ospf_bfd_cmd); } diff --git a/ospfd/ospf_bfd.h b/ospfd/ospf_bfd.h index 75b8e11f4..c940f31eb 100644 --- a/ospfd/ospf_bfd.h +++ b/ospfd/ospf_bfd.h @@ -25,27 +25,25 @@ #include "json.h" -extern void -ospf_bfd_init(void); +extern void ospf_bfd_init(void); -extern void -ospf_bfd_write_config(struct vty *vty, struct ospf_if_params *params); +extern void ospf_bfd_write_config(struct vty *vty, + struct ospf_if_params *params); -extern void -ospf_bfd_trigger_event(struct ospf_neighbor *nbr, int old_state, int state); +extern void ospf_bfd_trigger_event(struct ospf_neighbor *nbr, int old_state, + int state); -extern void -ospf_bfd_interface_show(struct vty *vty, struct interface *ifp, - json_object *json_interface_sub, u_char use_json); +extern void ospf_bfd_interface_show(struct vty *vty, struct interface *ifp, + json_object *json_interface_sub, + u_char use_json); -extern void -ospf_bfd_info_nbr_create (struct ospf_interface *oi, struct ospf_neighbor *nbr); +extern void ospf_bfd_info_nbr_create(struct ospf_interface *oi, + struct ospf_neighbor *nbr); -extern void -ospf_bfd_show_info(struct vty *vty, void *bfd_info, json_object *json_obj, - u_char use_json, int param_only); +extern void ospf_bfd_show_info(struct vty *vty, void *bfd_info, + json_object *json_obj, u_char use_json, + int param_only); -extern void -ospf_bfd_info_free(void **bfd_info); +extern void ospf_bfd_info_free(void **bfd_info); #endif /* _ZEBRA_OSPF_BFD_H */ diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c index f233f79c0..c0670012b 100644 --- a/ospfd/ospf_dump.c +++ b/ospfd/ospf_dump.c @@ -63,574 +63,539 @@ unsigned long term_debug_ospf_nssa = 0; unsigned long term_debug_ospf_te = 0; -const char * -ospf_redist_string(u_int route_type) +const char *ospf_redist_string(u_int route_type) { - return (route_type == ZEBRA_ROUTE_MAX) ? - "Default" : zebra_route_string(route_type); + return (route_type == ZEBRA_ROUTE_MAX) ? "Default" + : zebra_route_string(route_type); } #define OSPF_AREA_STRING_MAXLEN 16 -const char * -ospf_area_name_string (struct ospf_area *area) +const char *ospf_area_name_string(struct ospf_area *area) { - static char buf[OSPF_AREA_STRING_MAXLEN] = ""; - u_int32_t area_id; + static char buf[OSPF_AREA_STRING_MAXLEN] = ""; + u_int32_t area_id; - if (!area) - return "-"; + if (!area) + return "-"; - area_id = ntohl (area->area_id.s_addr); - snprintf (buf, OSPF_AREA_STRING_MAXLEN, "%d.%d.%d.%d", - (area_id >> 24) & 0xff, (area_id >> 16) & 0xff, - (area_id >> 8) & 0xff, area_id & 0xff); - return buf; + area_id = ntohl(area->area_id.s_addr); + snprintf(buf, OSPF_AREA_STRING_MAXLEN, "%d.%d.%d.%d", + (area_id >> 24) & 0xff, (area_id >> 16) & 0xff, + (area_id >> 8) & 0xff, area_id & 0xff); + return buf; } #define OSPF_AREA_DESC_STRING_MAXLEN 23 -const char * -ospf_area_desc_string (struct ospf_area *area) +const char *ospf_area_desc_string(struct ospf_area *area) { - static char buf[OSPF_AREA_DESC_STRING_MAXLEN] = ""; - u_char type; - - if (!area) - return "(incomplete)"; - - type = area->external_routing; - switch (type) - { - case OSPF_AREA_NSSA: - snprintf (buf, OSPF_AREA_DESC_STRING_MAXLEN, "%s [NSSA]", - ospf_area_name_string (area)); - break; - case OSPF_AREA_STUB: - snprintf (buf, OSPF_AREA_DESC_STRING_MAXLEN, "%s [Stub]", - ospf_area_name_string (area)); - break; - default: - return ospf_area_name_string (area); - } - - return buf; + static char buf[OSPF_AREA_DESC_STRING_MAXLEN] = ""; + u_char type; + + if (!area) + return "(incomplete)"; + + type = area->external_routing; + switch (type) { + case OSPF_AREA_NSSA: + snprintf(buf, OSPF_AREA_DESC_STRING_MAXLEN, "%s [NSSA]", + ospf_area_name_string(area)); + break; + case OSPF_AREA_STUB: + snprintf(buf, OSPF_AREA_DESC_STRING_MAXLEN, "%s [Stub]", + ospf_area_name_string(area)); + break; + default: + return ospf_area_name_string(area); + } + + return buf; } #define OSPF_IF_STRING_MAXLEN 40 -const char * -ospf_if_name_string (struct ospf_interface *oi) +const char *ospf_if_name_string(struct ospf_interface *oi) { - static char buf[OSPF_IF_STRING_MAXLEN] = ""; - u_int32_t ifaddr; + static char buf[OSPF_IF_STRING_MAXLEN] = ""; + u_int32_t ifaddr; - if (!oi || !oi->address) - return "inactive"; + if (!oi || !oi->address) + return "inactive"; - if (oi->type == OSPF_IFTYPE_VIRTUALLINK) - return oi->ifp->name; + if (oi->type == OSPF_IFTYPE_VIRTUALLINK) + return oi->ifp->name; - ifaddr = ntohl (oi->address->u.prefix4.s_addr); - snprintf (buf, OSPF_IF_STRING_MAXLEN, - "%s:%d.%d.%d.%d", oi->ifp->name, - (ifaddr >> 24) & 0xff, (ifaddr >> 16) & 0xff, - (ifaddr >> 8) & 0xff, ifaddr & 0xff); - return buf; + ifaddr = ntohl(oi->address->u.prefix4.s_addr); + snprintf(buf, OSPF_IF_STRING_MAXLEN, "%s:%d.%d.%d.%d", oi->ifp->name, + (ifaddr >> 24) & 0xff, (ifaddr >> 16) & 0xff, + (ifaddr >> 8) & 0xff, ifaddr & 0xff); + return buf; } -void -ospf_nbr_state_message (struct ospf_neighbor *nbr, char *buf, size_t size) +void ospf_nbr_state_message(struct ospf_neighbor *nbr, char *buf, size_t size) { - int state; - struct ospf_interface *oi = nbr->oi; + int state; + struct ospf_interface *oi = nbr->oi; - if (IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4)) - state = ISM_DR; - else if (IPV4_ADDR_SAME (&BDR (oi), &nbr->address.u.prefix4)) - state = ISM_Backup; - else - state = ISM_DROther; + if (IPV4_ADDR_SAME(&DR(oi), &nbr->address.u.prefix4)) + state = ISM_DR; + else if (IPV4_ADDR_SAME(&BDR(oi), &nbr->address.u.prefix4)) + state = ISM_Backup; + else + state = ISM_DROther; - memset (buf, 0, size); + memset(buf, 0, size); - snprintf (buf, size, "%s/%s", - lookup_msg(ospf_nsm_state_msg, nbr->state, NULL), - lookup_msg(ospf_ism_state_msg, state, NULL)); + snprintf(buf, size, "%s/%s", + lookup_msg(ospf_nsm_state_msg, nbr->state, NULL), + lookup_msg(ospf_ism_state_msg, state, NULL)); } -const char * -ospf_timeval_dump (struct timeval *t, char *buf, size_t size) +const char *ospf_timeval_dump(struct timeval *t, char *buf, size_t size) { - /* Making formatted timer strings. */ +/* Making formatted timer strings. */ #define MINUTE_IN_SECONDS 60 #define HOUR_IN_SECONDS (60*MINUTE_IN_SECONDS) #define DAY_IN_SECONDS (24*HOUR_IN_SECONDS) #define WEEK_IN_SECONDS (7*DAY_IN_SECONDS) - unsigned long w, d, h, m, s, ms, us; - - if (!t) - return "inactive"; - - w = d = h = m = s = ms = us = 0; - memset (buf, 0, size); - - us = t->tv_usec; - if (us >= 1000) - { - ms = us / 1000; - us %= 1000; - } - - if (ms >= 1000) - { - t->tv_sec += ms / 1000; - ms %= 1000; - } - - if (t->tv_sec > WEEK_IN_SECONDS) - { - w = t->tv_sec / WEEK_IN_SECONDS; - t->tv_sec -= w * WEEK_IN_SECONDS; - } - - if (t->tv_sec > DAY_IN_SECONDS) - { - d = t->tv_sec / DAY_IN_SECONDS; - t->tv_sec -= d * DAY_IN_SECONDS; - } - - if (t->tv_sec >= HOUR_IN_SECONDS) - { - h = t->tv_sec / HOUR_IN_SECONDS; - t->tv_sec -= h * HOUR_IN_SECONDS; - } - - if (t->tv_sec >= MINUTE_IN_SECONDS) - { - m = t->tv_sec / MINUTE_IN_SECONDS; - t->tv_sec -= m * MINUTE_IN_SECONDS; - } - - if (w > 99) - snprintf (buf, size, "%ldw%1ldd", w, d); - else if (w) - snprintf (buf, size, "%ldw%1ldd%02ldh", w, d, h); - else if (d) - snprintf (buf, size, "%1ldd%02ldh%02ldm", d, h, m); - else if (h) - snprintf (buf, size, "%ldh%02ldm%02lds", h, m, (long)t->tv_sec); - else if (m) - snprintf (buf, size, "%ldm%02lds", m, (long)t->tv_sec); - else if (ms) - snprintf (buf, size, "%ld.%03lds", (long)t->tv_sec, ms); - else - snprintf (buf, size, "%ld usecs", (long)t->tv_usec); - - return buf; + unsigned long w, d, h, m, s, ms, us; + + if (!t) + return "inactive"; + + w = d = h = m = s = ms = us = 0; + memset(buf, 0, size); + + us = t->tv_usec; + if (us >= 1000) { + ms = us / 1000; + us %= 1000; + } + + if (ms >= 1000) { + t->tv_sec += ms / 1000; + ms %= 1000; + } + + if (t->tv_sec > WEEK_IN_SECONDS) { + w = t->tv_sec / WEEK_IN_SECONDS; + t->tv_sec -= w * WEEK_IN_SECONDS; + } + + if (t->tv_sec > DAY_IN_SECONDS) { + d = t->tv_sec / DAY_IN_SECONDS; + t->tv_sec -= d * DAY_IN_SECONDS; + } + + if (t->tv_sec >= HOUR_IN_SECONDS) { + h = t->tv_sec / HOUR_IN_SECONDS; + t->tv_sec -= h * HOUR_IN_SECONDS; + } + + if (t->tv_sec >= MINUTE_IN_SECONDS) { + m = t->tv_sec / MINUTE_IN_SECONDS; + t->tv_sec -= m * MINUTE_IN_SECONDS; + } + + if (w > 99) + snprintf(buf, size, "%ldw%1ldd", w, d); + else if (w) + snprintf(buf, size, "%ldw%1ldd%02ldh", w, d, h); + else if (d) + snprintf(buf, size, "%1ldd%02ldh%02ldm", d, h, m); + else if (h) + snprintf(buf, size, "%ldh%02ldm%02lds", h, m, (long)t->tv_sec); + else if (m) + snprintf(buf, size, "%ldm%02lds", m, (long)t->tv_sec); + else if (ms) + snprintf(buf, size, "%ld.%03lds", (long)t->tv_sec, ms); + else + snprintf(buf, size, "%ld usecs", (long)t->tv_usec); + + return buf; } -const char * -ospf_timer_dump (struct thread *t, char *buf, size_t size) +const char *ospf_timer_dump(struct thread *t, char *buf, size_t size) { - struct timeval result; - if (!t) - return "inactive"; + struct timeval result; + if (!t) + return "inactive"; - monotime_until (&t->u.sands, &result); - return ospf_timeval_dump (&result, buf, size); + monotime_until(&t->u.sands, &result); + return ospf_timeval_dump(&result, buf, size); } -static void -ospf_packet_hello_dump (struct stream *s, u_int16_t length) +static void ospf_packet_hello_dump(struct stream *s, u_int16_t length) { - struct ospf_hello *hello; - int i; - - hello = (struct ospf_hello *) STREAM_PNT (s); - - zlog_debug ("Hello"); - zlog_debug (" NetworkMask %s", inet_ntoa (hello->network_mask)); - zlog_debug (" HelloInterval %d", ntohs (hello->hello_interval)); - zlog_debug (" Options %d (%s)", hello->options, - ospf_options_dump (hello->options)); - zlog_debug (" RtrPriority %d", hello->priority); - zlog_debug (" RtrDeadInterval %ld", (u_long)ntohl (hello->dead_interval)); - zlog_debug (" DRouter %s", inet_ntoa (hello->d_router)); - zlog_debug (" BDRouter %s", inet_ntoa (hello->bd_router)); - - length -= OSPF_HEADER_SIZE + OSPF_HELLO_MIN_SIZE; - zlog_debug (" # Neighbors %d", length / 4); - for (i = 0; length > 0; i++, length -= sizeof (struct in_addr)) - zlog_debug (" Neighbor %s", inet_ntoa (hello->neighbors[i])); + struct ospf_hello *hello; + int i; + + hello = (struct ospf_hello *)STREAM_PNT(s); + + zlog_debug("Hello"); + zlog_debug(" NetworkMask %s", inet_ntoa(hello->network_mask)); + zlog_debug(" HelloInterval %d", ntohs(hello->hello_interval)); + zlog_debug(" Options %d (%s)", hello->options, + ospf_options_dump(hello->options)); + zlog_debug(" RtrPriority %d", hello->priority); + zlog_debug(" RtrDeadInterval %ld", + (u_long)ntohl(hello->dead_interval)); + zlog_debug(" DRouter %s", inet_ntoa(hello->d_router)); + zlog_debug(" BDRouter %s", inet_ntoa(hello->bd_router)); + + length -= OSPF_HEADER_SIZE + OSPF_HELLO_MIN_SIZE; + zlog_debug(" # Neighbors %d", length / 4); + for (i = 0; length > 0; i++, length -= sizeof(struct in_addr)) + zlog_debug(" Neighbor %s", inet_ntoa(hello->neighbors[i])); } -static char * -ospf_dd_flags_dump (u_char flags, char *buf, size_t size) +static char *ospf_dd_flags_dump(u_char flags, char *buf, size_t size) { - memset (buf, 0, size); + memset(buf, 0, size); - snprintf (buf, size, "%s|%s|%s", - (flags & OSPF_DD_FLAG_I) ? "I" : "-", - (flags & OSPF_DD_FLAG_M) ? "M" : "-", - (flags & OSPF_DD_FLAG_MS) ? "MS" : "-"); + snprintf(buf, size, "%s|%s|%s", (flags & OSPF_DD_FLAG_I) ? "I" : "-", + (flags & OSPF_DD_FLAG_M) ? "M" : "-", + (flags & OSPF_DD_FLAG_MS) ? "MS" : "-"); - return buf; + return buf; } -static char * -ospf_router_lsa_flags_dump (u_char flags, char *buf, size_t size) +static char *ospf_router_lsa_flags_dump(u_char flags, char *buf, size_t size) { - memset (buf, 0, size); + memset(buf, 0, size); - snprintf (buf, size, "%s|%s|%s", - (flags & ROUTER_LSA_VIRTUAL) ? "V" : "-", - (flags & ROUTER_LSA_EXTERNAL) ? "E" : "-", - (flags & ROUTER_LSA_BORDER) ? "B" : "-"); + snprintf(buf, size, "%s|%s|%s", + (flags & ROUTER_LSA_VIRTUAL) ? "V" : "-", + (flags & ROUTER_LSA_EXTERNAL) ? "E" : "-", + (flags & ROUTER_LSA_BORDER) ? "B" : "-"); - return buf; + return buf; } -static void -ospf_router_lsa_dump (struct stream *s, u_int16_t length) +static void ospf_router_lsa_dump(struct stream *s, u_int16_t length) { - char buf[BUFSIZ]; - struct router_lsa *rl; - int i, len; - - rl = (struct router_lsa *) STREAM_PNT (s); - - zlog_debug (" Router-LSA"); - zlog_debug (" flags %s", - ospf_router_lsa_flags_dump (rl->flags, buf, BUFSIZ)); - zlog_debug (" # links %d", ntohs (rl->links)); - - len = ntohs (rl->header.length) - OSPF_LSA_HEADER_SIZE - 4; - for (i = 0; len > 0; i++) - { - zlog_debug (" Link ID %s", inet_ntoa (rl->link[i].link_id)); - zlog_debug (" Link Data %s", inet_ntoa (rl->link[i].link_data)); - zlog_debug (" Type %d", (u_char) rl->link[i].type); - zlog_debug (" TOS %d", (u_char) rl->link[i].tos); - zlog_debug (" metric %d", ntohs (rl->link[i].metric)); - - len -= 12; - } + char buf[BUFSIZ]; + struct router_lsa *rl; + int i, len; + + rl = (struct router_lsa *)STREAM_PNT(s); + + zlog_debug(" Router-LSA"); + zlog_debug(" flags %s", + ospf_router_lsa_flags_dump(rl->flags, buf, BUFSIZ)); + zlog_debug(" # links %d", ntohs(rl->links)); + + len = ntohs(rl->header.length) - OSPF_LSA_HEADER_SIZE - 4; + for (i = 0; len > 0; i++) { + zlog_debug(" Link ID %s", inet_ntoa(rl->link[i].link_id)); + zlog_debug(" Link Data %s", + inet_ntoa(rl->link[i].link_data)); + zlog_debug(" Type %d", (u_char)rl->link[i].type); + zlog_debug(" TOS %d", (u_char)rl->link[i].tos); + zlog_debug(" metric %d", ntohs(rl->link[i].metric)); + + len -= 12; + } } -static void -ospf_network_lsa_dump (struct stream *s, u_int16_t length) +static void ospf_network_lsa_dump(struct stream *s, u_int16_t length) { - struct network_lsa *nl; - int i, cnt; - - nl = (struct network_lsa *) STREAM_PNT (s); - cnt = (ntohs (nl->header.length) - (OSPF_LSA_HEADER_SIZE + 4)) / 4; - - zlog_debug (" Network-LSA"); - /* - zlog_debug ("LSA total size %d", ntohs (nl->header.length)); - zlog_debug ("Network-LSA size %d", - ntohs (nl->header.length) - OSPF_LSA_HEADER_SIZE); - */ - zlog_debug (" Network Mask %s", inet_ntoa (nl->mask)); - zlog_debug (" # Attached Routers %d", cnt); - for (i = 0; i < cnt; i++) - zlog_debug (" Attached Router %s", inet_ntoa (nl->routers[i])); + struct network_lsa *nl; + int i, cnt; + + nl = (struct network_lsa *)STREAM_PNT(s); + cnt = (ntohs(nl->header.length) - (OSPF_LSA_HEADER_SIZE + 4)) / 4; + + zlog_debug(" Network-LSA"); + /* + zlog_debug ("LSA total size %d", ntohs (nl->header.length)); + zlog_debug ("Network-LSA size %d", + ntohs (nl->header.length) - OSPF_LSA_HEADER_SIZE); + */ + zlog_debug(" Network Mask %s", inet_ntoa(nl->mask)); + zlog_debug(" # Attached Routers %d", cnt); + for (i = 0; i < cnt; i++) + zlog_debug(" Attached Router %s", + inet_ntoa(nl->routers[i])); } -static void -ospf_summary_lsa_dump (struct stream *s, u_int16_t length) +static void ospf_summary_lsa_dump(struct stream *s, u_int16_t length) { - struct summary_lsa *sl; - int size; - int i; + struct summary_lsa *sl; + int size; + int i; - sl = (struct summary_lsa *) STREAM_PNT (s); + sl = (struct summary_lsa *)STREAM_PNT(s); - zlog_debug (" Summary-LSA"); - zlog_debug (" Network Mask %s", inet_ntoa (sl->mask)); + zlog_debug(" Summary-LSA"); + zlog_debug(" Network Mask %s", inet_ntoa(sl->mask)); - size = ntohs (sl->header.length) - OSPF_LSA_HEADER_SIZE - 4; - for (i = 0; size > 0; size -= 4, i++) - zlog_debug (" TOS=%d metric %d", sl->tos, - GET_METRIC (sl->metric)); + size = ntohs(sl->header.length) - OSPF_LSA_HEADER_SIZE - 4; + for (i = 0; size > 0; size -= 4, i++) + zlog_debug(" TOS=%d metric %d", sl->tos, + GET_METRIC(sl->metric)); } -static void -ospf_as_external_lsa_dump (struct stream *s, u_int16_t length) +static void ospf_as_external_lsa_dump(struct stream *s, u_int16_t length) { - struct as_external_lsa *al; - int size; - int i; - - al = (struct as_external_lsa *) STREAM_PNT (s); - zlog_debug (" %s", ospf_lsa_type_msg[al->header.type].str); - zlog_debug (" Network Mask %s", inet_ntoa (al->mask)); - - size = ntohs (al->header.length) - OSPF_LSA_HEADER_SIZE -4; - for (i = 0; size > 0; size -= 12, i++) - { - zlog_debug (" bit %s TOS=%d metric %d", - IS_EXTERNAL_METRIC (al->e[i].tos) ? "E" : "-", - al->e[i].tos & 0x7f, GET_METRIC (al->e[i].metric)); - zlog_debug (" Forwarding address %s", inet_ntoa (al->e[i].fwd_addr)); - zlog_debug (" External Route Tag %"ROUTE_TAG_PRI, al->e[i].route_tag); - } + struct as_external_lsa *al; + int size; + int i; + + al = (struct as_external_lsa *)STREAM_PNT(s); + zlog_debug(" %s", ospf_lsa_type_msg[al->header.type].str); + zlog_debug(" Network Mask %s", inet_ntoa(al->mask)); + + size = ntohs(al->header.length) - OSPF_LSA_HEADER_SIZE - 4; + for (i = 0; size > 0; size -= 12, i++) { + zlog_debug(" bit %s TOS=%d metric %d", + IS_EXTERNAL_METRIC(al->e[i].tos) ? "E" : "-", + al->e[i].tos & 0x7f, GET_METRIC(al->e[i].metric)); + zlog_debug(" Forwarding address %s", + inet_ntoa(al->e[i].fwd_addr)); + zlog_debug(" External Route Tag %" ROUTE_TAG_PRI, + al->e[i].route_tag); + } } -static void -ospf_lsa_header_list_dump (struct stream *s, u_int16_t length) +static void ospf_lsa_header_list_dump(struct stream *s, u_int16_t length) { - struct lsa_header *lsa; + struct lsa_header *lsa; - zlog_debug (" # LSA Headers %d", length / OSPF_LSA_HEADER_SIZE); + zlog_debug(" # LSA Headers %d", length / OSPF_LSA_HEADER_SIZE); - /* LSA Headers. */ - while (length > 0) - { - lsa = (struct lsa_header *) STREAM_PNT (s); - ospf_lsa_header_dump (lsa); + /* LSA Headers. */ + while (length > 0) { + lsa = (struct lsa_header *)STREAM_PNT(s); + ospf_lsa_header_dump(lsa); - stream_forward_getp (s, OSPF_LSA_HEADER_SIZE); - length -= OSPF_LSA_HEADER_SIZE; - } + stream_forward_getp(s, OSPF_LSA_HEADER_SIZE); + length -= OSPF_LSA_HEADER_SIZE; + } } -static void -ospf_packet_db_desc_dump (struct stream *s, u_int16_t length) +static void ospf_packet_db_desc_dump(struct stream *s, u_int16_t length) { - struct ospf_db_desc *dd; - char dd_flags[8]; + struct ospf_db_desc *dd; + char dd_flags[8]; - u_int32_t gp; + u_int32_t gp; - gp = stream_get_getp (s); - dd = (struct ospf_db_desc *) STREAM_PNT (s); + gp = stream_get_getp(s); + dd = (struct ospf_db_desc *)STREAM_PNT(s); - zlog_debug ("Database Description"); - zlog_debug (" Interface MTU %d", ntohs (dd->mtu)); - zlog_debug (" Options %d (%s)", dd->options, - ospf_options_dump (dd->options)); - zlog_debug (" Flags %d (%s)", dd->flags, - ospf_dd_flags_dump (dd->flags, dd_flags, sizeof dd_flags)); - zlog_debug (" Sequence Number 0x%08lx", (u_long)ntohl (dd->dd_seqnum)); + zlog_debug("Database Description"); + zlog_debug(" Interface MTU %d", ntohs(dd->mtu)); + zlog_debug(" Options %d (%s)", dd->options, + ospf_options_dump(dd->options)); + zlog_debug(" Flags %d (%s)", dd->flags, + ospf_dd_flags_dump(dd->flags, dd_flags, sizeof dd_flags)); + zlog_debug(" Sequence Number 0x%08lx", (u_long)ntohl(dd->dd_seqnum)); - length -= OSPF_HEADER_SIZE + OSPF_DB_DESC_MIN_SIZE; + length -= OSPF_HEADER_SIZE + OSPF_DB_DESC_MIN_SIZE; - stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE); + stream_forward_getp(s, OSPF_DB_DESC_MIN_SIZE); - ospf_lsa_header_list_dump (s, length); + ospf_lsa_header_list_dump(s, length); - stream_set_getp (s, gp); + stream_set_getp(s, gp); } -static void -ospf_packet_ls_req_dump (struct stream *s, u_int16_t length) +static void ospf_packet_ls_req_dump(struct stream *s, u_int16_t length) { - u_int32_t sp; - u_int32_t ls_type; - struct in_addr ls_id; - struct in_addr adv_router; + u_int32_t sp; + u_int32_t ls_type; + struct in_addr ls_id; + struct in_addr adv_router; - sp = stream_get_getp (s); + sp = stream_get_getp(s); - length -= OSPF_HEADER_SIZE; + length -= OSPF_HEADER_SIZE; - zlog_debug ("Link State Request"); - zlog_debug (" # Requests %d", length / 12); + zlog_debug("Link State Request"); + zlog_debug(" # Requests %d", length / 12); - for (; length > 0; length -= 12) - { - ls_type = stream_getl (s); - ls_id.s_addr = stream_get_ipv4 (s); - adv_router.s_addr = stream_get_ipv4 (s); + for (; length > 0; length -= 12) { + ls_type = stream_getl(s); + ls_id.s_addr = stream_get_ipv4(s); + adv_router.s_addr = stream_get_ipv4(s); - zlog_debug (" LS type %d", ls_type); - zlog_debug (" Link State ID %s", inet_ntoa (ls_id)); - zlog_debug (" Advertising Router %s", - inet_ntoa (adv_router)); - } + zlog_debug(" LS type %d", ls_type); + zlog_debug(" Link State ID %s", inet_ntoa(ls_id)); + zlog_debug(" Advertising Router %s", inet_ntoa(adv_router)); + } - stream_set_getp (s, sp); + stream_set_getp(s, sp); } -static void -ospf_packet_ls_upd_dump (struct stream *s, u_int16_t length) +static void ospf_packet_ls_upd_dump(struct stream *s, u_int16_t length) { - u_int32_t sp; - struct lsa_header *lsa; - int lsa_len; - u_int32_t count; - - length -= OSPF_HEADER_SIZE; - - sp = stream_get_getp (s); - - count = stream_getl (s); - length -= 4; - - zlog_debug ("Link State Update"); - zlog_debug (" # LSAs %d", count); - - while (length > 0 && count > 0) - { - if (length < OSPF_HEADER_SIZE || length % 4 != 0) - { - zlog_debug (" Remaining %d bytes; Incorrect length.", length); - break; + u_int32_t sp; + struct lsa_header *lsa; + int lsa_len; + u_int32_t count; + + length -= OSPF_HEADER_SIZE; + + sp = stream_get_getp(s); + + count = stream_getl(s); + length -= 4; + + zlog_debug("Link State Update"); + zlog_debug(" # LSAs %d", count); + + while (length > 0 && count > 0) { + if (length < OSPF_HEADER_SIZE || length % 4 != 0) { + zlog_debug(" Remaining %d bytes; Incorrect length.", + length); + break; + } + + lsa = (struct lsa_header *)STREAM_PNT(s); + lsa_len = ntohs(lsa->length); + ospf_lsa_header_dump(lsa); + + switch (lsa->type) { + case OSPF_ROUTER_LSA: + ospf_router_lsa_dump(s, length); + break; + case OSPF_NETWORK_LSA: + ospf_network_lsa_dump(s, length); + break; + case OSPF_SUMMARY_LSA: + case OSPF_ASBR_SUMMARY_LSA: + ospf_summary_lsa_dump(s, length); + break; + case OSPF_AS_EXTERNAL_LSA: + ospf_as_external_lsa_dump(s, length); + break; + case OSPF_AS_NSSA_LSA: + ospf_as_external_lsa_dump(s, length); + break; + case OSPF_OPAQUE_LINK_LSA: + case OSPF_OPAQUE_AREA_LSA: + case OSPF_OPAQUE_AS_LSA: + ospf_opaque_lsa_dump(s, length); + break; + default: + break; + } + + stream_forward_getp(s, lsa_len); + length -= lsa_len; + count--; } - lsa = (struct lsa_header *) STREAM_PNT (s); - lsa_len = ntohs (lsa->length); - ospf_lsa_header_dump (lsa); - - switch (lsa->type) - { - case OSPF_ROUTER_LSA: - ospf_router_lsa_dump (s, length); - break; - case OSPF_NETWORK_LSA: - ospf_network_lsa_dump (s, length); - break; - case OSPF_SUMMARY_LSA: - case OSPF_ASBR_SUMMARY_LSA: - ospf_summary_lsa_dump (s, length); - break; - case OSPF_AS_EXTERNAL_LSA: - ospf_as_external_lsa_dump (s, length); - break; - case OSPF_AS_NSSA_LSA: - ospf_as_external_lsa_dump (s, length); - break; - case OSPF_OPAQUE_LINK_LSA: - case OSPF_OPAQUE_AREA_LSA: - case OSPF_OPAQUE_AS_LSA: - ospf_opaque_lsa_dump (s, length); - break; - default: - break; - } - - stream_forward_getp (s, lsa_len); - length -= lsa_len; - count--; - } - - stream_set_getp (s, sp); + stream_set_getp(s, sp); } -static void -ospf_packet_ls_ack_dump (struct stream *s, u_int16_t length) +static void ospf_packet_ls_ack_dump(struct stream *s, u_int16_t length) { - u_int32_t sp; + u_int32_t sp; - length -= OSPF_HEADER_SIZE; - sp = stream_get_getp (s); + length -= OSPF_HEADER_SIZE; + sp = stream_get_getp(s); - zlog_debug ("Link State Acknowledgment"); - ospf_lsa_header_list_dump (s, length); + zlog_debug("Link State Acknowledgment"); + ospf_lsa_header_list_dump(s, length); - stream_set_getp (s, sp); + stream_set_getp(s, sp); } /* Expects header to be in host order */ -void -ospf_ip_header_dump (struct ip *iph) +void ospf_ip_header_dump(struct ip *iph) { - /* IP Header dump. */ - zlog_debug ("ip_v %d", iph->ip_v); - zlog_debug ("ip_hl %d", iph->ip_hl); - zlog_debug ("ip_tos %d", iph->ip_tos); - zlog_debug ("ip_len %d", iph->ip_len); - zlog_debug ("ip_id %u", (u_int32_t) iph->ip_id); - zlog_debug ("ip_off %u", (u_int32_t) iph->ip_off); - zlog_debug ("ip_ttl %d", iph->ip_ttl); - zlog_debug ("ip_p %d", iph->ip_p); - zlog_debug ("ip_sum 0x%x", (u_int32_t) iph->ip_sum); - zlog_debug ("ip_src %s", inet_ntoa (iph->ip_src)); - zlog_debug ("ip_dst %s", inet_ntoa (iph->ip_dst)); + /* IP Header dump. */ + zlog_debug("ip_v %d", iph->ip_v); + zlog_debug("ip_hl %d", iph->ip_hl); + zlog_debug("ip_tos %d", iph->ip_tos); + zlog_debug("ip_len %d", iph->ip_len); + zlog_debug("ip_id %u", (u_int32_t)iph->ip_id); + zlog_debug("ip_off %u", (u_int32_t)iph->ip_off); + zlog_debug("ip_ttl %d", iph->ip_ttl); + zlog_debug("ip_p %d", iph->ip_p); + zlog_debug("ip_sum 0x%x", (u_int32_t)iph->ip_sum); + zlog_debug("ip_src %s", inet_ntoa(iph->ip_src)); + zlog_debug("ip_dst %s", inet_ntoa(iph->ip_dst)); } -static void -ospf_header_dump (struct ospf_header *ospfh) +static void ospf_header_dump(struct ospf_header *ospfh) { - char buf[9]; - u_int16_t auth_type = ntohs (ospfh->auth_type); - - zlog_debug ("Header"); - zlog_debug (" Version %d", ospfh->version); - zlog_debug (" Type %d (%s)", ospfh->type, - lookup_msg(ospf_packet_type_str, ospfh->type, NULL)); - zlog_debug (" Packet Len %d", ntohs (ospfh->length)); - zlog_debug (" Router ID %s", inet_ntoa (ospfh->router_id)); - zlog_debug (" Area ID %s", inet_ntoa (ospfh->area_id)); - zlog_debug (" Checksum 0x%x", ntohs (ospfh->checksum)); - zlog_debug (" AuType %s", lookup_msg(ospf_auth_type_str, auth_type, NULL)); - - switch (auth_type) - { - case OSPF_AUTH_NULL: - break; - case OSPF_AUTH_SIMPLE: - memset (buf, 0, 9); - strncpy (buf, (char *) ospfh->u.auth_data, 8); - zlog_debug (" Simple Password %s", buf); - break; - case OSPF_AUTH_CRYPTOGRAPHIC: - zlog_debug (" Cryptographic Authentication"); - zlog_debug (" Key ID %d", ospfh->u.crypt.key_id); - zlog_debug (" Auth Data Len %d", ospfh->u.crypt.auth_data_len); - zlog_debug (" Sequence number %ld", - (u_long)ntohl (ospfh->u.crypt.crypt_seqnum)); - break; - default: - zlog_debug ("* This is not supported authentication type"); - break; - } - + char buf[9]; + u_int16_t auth_type = ntohs(ospfh->auth_type); + + zlog_debug("Header"); + zlog_debug(" Version %d", ospfh->version); + zlog_debug(" Type %d (%s)", ospfh->type, + lookup_msg(ospf_packet_type_str, ospfh->type, NULL)); + zlog_debug(" Packet Len %d", ntohs(ospfh->length)); + zlog_debug(" Router ID %s", inet_ntoa(ospfh->router_id)); + zlog_debug(" Area ID %s", inet_ntoa(ospfh->area_id)); + zlog_debug(" Checksum 0x%x", ntohs(ospfh->checksum)); + zlog_debug(" AuType %s", + lookup_msg(ospf_auth_type_str, auth_type, NULL)); + + switch (auth_type) { + case OSPF_AUTH_NULL: + break; + case OSPF_AUTH_SIMPLE: + memset(buf, 0, 9); + strncpy(buf, (char *)ospfh->u.auth_data, 8); + zlog_debug(" Simple Password %s", buf); + break; + case OSPF_AUTH_CRYPTOGRAPHIC: + zlog_debug(" Cryptographic Authentication"); + zlog_debug(" Key ID %d", ospfh->u.crypt.key_id); + zlog_debug(" Auth Data Len %d", ospfh->u.crypt.auth_data_len); + zlog_debug(" Sequence number %ld", + (u_long)ntohl(ospfh->u.crypt.crypt_seqnum)); + break; + default: + zlog_debug("* This is not supported authentication type"); + break; + } } -void -ospf_packet_dump (struct stream *s) +void ospf_packet_dump(struct stream *s) { - struct ospf_header *ospfh; - unsigned long gp; - - /* Preserve pointer. */ - gp = stream_get_getp (s); - - /* OSPF Header dump. */ - ospfh = (struct ospf_header *) STREAM_PNT (s); - - /* Until detail flag is set, return. */ - if (!(term_debug_ospf_packet[ospfh->type - 1] & OSPF_DEBUG_DETAIL)) - return; - - /* Show OSPF header detail. */ - ospf_header_dump (ospfh); - stream_forward_getp (s, OSPF_HEADER_SIZE); - - switch (ospfh->type) - { - case OSPF_MSG_HELLO: - ospf_packet_hello_dump (s, ntohs (ospfh->length)); - break; - case OSPF_MSG_DB_DESC: - ospf_packet_db_desc_dump (s, ntohs (ospfh->length)); - break; - case OSPF_MSG_LS_REQ: - ospf_packet_ls_req_dump (s, ntohs (ospfh->length)); - break; - case OSPF_MSG_LS_UPD: - ospf_packet_ls_upd_dump (s, ntohs (ospfh->length)); - break; - case OSPF_MSG_LS_ACK: - ospf_packet_ls_ack_dump (s, ntohs (ospfh->length)); - break; - default: - break; - } - - stream_set_getp (s, gp); + struct ospf_header *ospfh; + unsigned long gp; + + /* Preserve pointer. */ + gp = stream_get_getp(s); + + /* OSPF Header dump. */ + ospfh = (struct ospf_header *)STREAM_PNT(s); + + /* Until detail flag is set, return. */ + if (!(term_debug_ospf_packet[ospfh->type - 1] & OSPF_DEBUG_DETAIL)) + return; + + /* Show OSPF header detail. */ + ospf_header_dump(ospfh); + stream_forward_getp(s, OSPF_HEADER_SIZE); + + switch (ospfh->type) { + case OSPF_MSG_HELLO: + ospf_packet_hello_dump(s, ntohs(ospfh->length)); + break; + case OSPF_MSG_DB_DESC: + ospf_packet_db_desc_dump(s, ntohs(ospfh->length)); + break; + case OSPF_MSG_LS_REQ: + ospf_packet_ls_req_dump(s, ntohs(ospfh->length)); + break; + case OSPF_MSG_LS_UPD: + ospf_packet_ls_upd_dump(s, ntohs(ospfh->length)); + break; + case OSPF_MSG_LS_ACK: + ospf_packet_ls_ack_dump(s, ntohs(ospfh->length)); + break; + default: + break; + } + + stream_set_getp(s, gp); } DEFUN (debug_ospf_packet, @@ -652,61 +617,60 @@ DEFUN (debug_ospf_packet, "Detail Information\n" "Detail Information\n") { - int inst = (argv[2]->type == RANGE_TKN) ? 1 : 0; - int detail = strmatch (argv[argc - 1]->text, "detail"); - int send = strmatch (argv[argc - (1+detail)]->text, "send"); - int recv = strmatch (argv[argc - (1+detail)]->text, "recv"); - char *packet = argv[3 + inst]->text; - - if (inst) // user passed instance ID - { - if (!ospf_lookup_instance (strtoul (argv[2]->arg, NULL, 10))) - return CMD_SUCCESS; - } - - int type = 0; - int flag = 0; - int i; - - /* Check packet type. */ - if (strmatch (packet, "hello")) - type = OSPF_DEBUG_HELLO; - else if (strmatch (packet, "dd")) - type = OSPF_DEBUG_DB_DESC; - else if (strmatch (packet, "ls-request")) - type = OSPF_DEBUG_LS_REQ; - else if (strmatch (packet, "ls-update")) - type = OSPF_DEBUG_LS_UPD; - else if (strmatch (packet, "ls-ack")) - type = OSPF_DEBUG_LS_ACK; - else if (strmatch (packet, "all")) - type = OSPF_DEBUG_ALL; - - /* Cases: - * (none) = send + recv - * detail = send + recv + detail - * recv = recv - * send = send - * recv detail = recv + detail - * send detail = send + detail - */ - if (!send && !recv) - send = recv = 1; - - flag |= (send) ? OSPF_DEBUG_SEND : 0; - flag |= (recv) ? OSPF_DEBUG_RECV : 0; - flag |= (detail) ? OSPF_DEBUG_DETAIL : 0; - - for (i = 0; i < 5; i++) - if (type & (0x01 << i)) - { - if (vty->node == CONFIG_NODE) - DEBUG_PACKET_ON (i, flag); - else - TERM_DEBUG_PACKET_ON (i, flag); - } + int inst = (argv[2]->type == RANGE_TKN) ? 1 : 0; + int detail = strmatch(argv[argc - 1]->text, "detail"); + int send = strmatch(argv[argc - (1 + detail)]->text, "send"); + int recv = strmatch(argv[argc - (1 + detail)]->text, "recv"); + char *packet = argv[3 + inst]->text; - return CMD_SUCCESS; + if (inst) // user passed instance ID + { + if (!ospf_lookup_instance(strtoul(argv[2]->arg, NULL, 10))) + return CMD_SUCCESS; + } + + int type = 0; + int flag = 0; + int i; + + /* Check packet type. */ + if (strmatch(packet, "hello")) + type = OSPF_DEBUG_HELLO; + else if (strmatch(packet, "dd")) + type = OSPF_DEBUG_DB_DESC; + else if (strmatch(packet, "ls-request")) + type = OSPF_DEBUG_LS_REQ; + else if (strmatch(packet, "ls-update")) + type = OSPF_DEBUG_LS_UPD; + else if (strmatch(packet, "ls-ack")) + type = OSPF_DEBUG_LS_ACK; + else if (strmatch(packet, "all")) + type = OSPF_DEBUG_ALL; + + /* Cases: + * (none) = send + recv + * detail = send + recv + detail + * recv = recv + * send = send + * recv detail = recv + detail + * send detail = send + detail + */ + if (!send && !recv) + send = recv = 1; + + flag |= (send) ? OSPF_DEBUG_SEND : 0; + flag |= (recv) ? OSPF_DEBUG_RECV : 0; + flag |= (detail) ? OSPF_DEBUG_DETAIL : 0; + + for (i = 0; i < 5; i++) + if (type & (0x01 << i)) { + if (vty->node == CONFIG_NODE) + DEBUG_PACKET_ON(i, flag); + else + TERM_DEBUG_PACKET_ON(i, flag); + } + + return CMD_SUCCESS; } DEFUN (no_debug_ospf_packet, @@ -729,68 +693,67 @@ DEFUN (no_debug_ospf_packet, "Detail Information\n" "Detail Information\n") { - int inst = (argv[3]->type == RANGE_TKN) ? 1 : 0; - int detail = strmatch (argv[argc - 1]->text, "detail"); - int send = strmatch (argv[argc - (1+detail)]->text, "send"); - int recv = strmatch (argv[argc - (1+detail)]->text, "recv"); - char *packet = argv[4 + inst]->text; - - if (inst) // user passed instance ID - { - if (!ospf_lookup_instance (strtoul (argv[3]->arg, NULL, 10))) - return CMD_SUCCESS; - } - - int type = 0; - int flag = 0; - int i; - - /* Check packet type. */ - if (strmatch (packet, "hello")) - type = OSPF_DEBUG_HELLO; - else if (strmatch (packet, "dd")) - type = OSPF_DEBUG_DB_DESC; - else if (strmatch (packet, "ls-request")) - type = OSPF_DEBUG_LS_REQ; - else if (strmatch (packet, "ls-update")) - type = OSPF_DEBUG_LS_UPD; - else if (strmatch (packet, "ls-ack")) - type = OSPF_DEBUG_LS_ACK; - else if (strmatch (packet, "all")) - type = OSPF_DEBUG_ALL; - - /* Cases: - * (none) = send + recv - * detail = send + recv + detail - * recv = recv - * send = send - * recv detail = recv + detail - * send detail = send + detail - */ - if (!send && !recv) - send = recv = 1; - - flag |= (send) ? OSPF_DEBUG_SEND : 0; - flag |= (recv) ? OSPF_DEBUG_RECV : 0; - flag |= (detail) ? OSPF_DEBUG_DETAIL : 0; - - for (i = 0; i < 5; i++) - if (type & (0x01 << i)) - { - if (vty->node == CONFIG_NODE) - DEBUG_PACKET_OFF (i, flag); - else - TERM_DEBUG_PACKET_OFF (i, flag); - } + int inst = (argv[3]->type == RANGE_TKN) ? 1 : 0; + int detail = strmatch(argv[argc - 1]->text, "detail"); + int send = strmatch(argv[argc - (1 + detail)]->text, "send"); + int recv = strmatch(argv[argc - (1 + detail)]->text, "recv"); + char *packet = argv[4 + inst]->text; + + if (inst) // user passed instance ID + { + if (!ospf_lookup_instance(strtoul(argv[3]->arg, NULL, 10))) + return CMD_SUCCESS; + } + + int type = 0; + int flag = 0; + int i; + + /* Check packet type. */ + if (strmatch(packet, "hello")) + type = OSPF_DEBUG_HELLO; + else if (strmatch(packet, "dd")) + type = OSPF_DEBUG_DB_DESC; + else if (strmatch(packet, "ls-request")) + type = OSPF_DEBUG_LS_REQ; + else if (strmatch(packet, "ls-update")) + type = OSPF_DEBUG_LS_UPD; + else if (strmatch(packet, "ls-ack")) + type = OSPF_DEBUG_LS_ACK; + else if (strmatch(packet, "all")) + type = OSPF_DEBUG_ALL; + + /* Cases: + * (none) = send + recv + * detail = send + recv + detail + * recv = recv + * send = send + * recv detail = recv + detail + * send detail = send + detail + */ + if (!send && !recv) + send = recv = 1; + + flag |= (send) ? OSPF_DEBUG_SEND : 0; + flag |= (recv) ? OSPF_DEBUG_RECV : 0; + flag |= (detail) ? OSPF_DEBUG_DETAIL : 0; + + for (i = 0; i < 5; i++) + if (type & (0x01 << i)) { + if (vty->node == CONFIG_NODE) + DEBUG_PACKET_OFF(i, flag); + else + TERM_DEBUG_PACKET_OFF(i, flag); + } #ifdef DEBUG - /* - for (i = 0; i < 5; i++) - zlog_debug ("flag[%d] = %d", i, ospf_debug_packet[i]); - */ +/* +for (i = 0; i < 5; i++) + zlog_debug ("flag[%d] = %d", i, ospf_debug_packet[i]); +*/ #endif /* DEBUG */ - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (debug_ospf_ism, @@ -804,46 +767,43 @@ DEFUN (debug_ospf_ism, "ISM Event Information\n" "ISM TImer Information\n") { - int inst = (argv[2]->type == RANGE_TKN); - char *dbgparam = (argc == 4 + inst) ? argv[argc - 1]->text : NULL; - - if (inst) // user passed instance ID - { - if (!ospf_lookup_instance (strtoul (argv[2]->arg, NULL, 10))) - return CMD_SUCCESS; - } - - if (vty->node == CONFIG_NODE) - { - if (!dbgparam) - DEBUG_ON (ism, ISM); - else + int inst = (argv[2]->type == RANGE_TKN); + char *dbgparam = (argc == 4 + inst) ? argv[argc - 1]->text : NULL; + + if (inst) // user passed instance ID { - if (strmatch (dbgparam, "status")) - DEBUG_ON (ism, ISM_STATUS); - else if (strmatch (dbgparam, "events")) - DEBUG_ON (ism, ISM_EVENTS); - else if (strmatch (dbgparam, "timers")) - DEBUG_ON (ism, ISM_TIMERS); + if (!ospf_lookup_instance(strtoul(argv[2]->arg, NULL, 10))) + return CMD_SUCCESS; } - return CMD_SUCCESS; - } - - /* ENABLE_NODE. */ - if (!dbgparam) - TERM_DEBUG_ON (ism, ISM); - else - { - if (strmatch (dbgparam, "status")) - TERM_DEBUG_ON (ism, ISM_STATUS); - else if (strmatch (dbgparam, "events")) - TERM_DEBUG_ON (ism, ISM_EVENTS); - else if (strmatch (dbgparam, "timers")) - TERM_DEBUG_ON (ism, ISM_TIMERS); - } - - return CMD_SUCCESS; + if (vty->node == CONFIG_NODE) { + if (!dbgparam) + DEBUG_ON(ism, ISM); + else { + if (strmatch(dbgparam, "status")) + DEBUG_ON(ism, ISM_STATUS); + else if (strmatch(dbgparam, "events")) + DEBUG_ON(ism, ISM_EVENTS); + else if (strmatch(dbgparam, "timers")) + DEBUG_ON(ism, ISM_TIMERS); + } + + return CMD_SUCCESS; + } + + /* ENABLE_NODE. */ + if (!dbgparam) + TERM_DEBUG_ON(ism, ISM); + else { + if (strmatch(dbgparam, "status")) + TERM_DEBUG_ON(ism, ISM_STATUS); + else if (strmatch(dbgparam, "events")) + TERM_DEBUG_ON(ism, ISM_EVENTS); + else if (strmatch(dbgparam, "timers")) + TERM_DEBUG_ON(ism, ISM_TIMERS); + } + + return CMD_SUCCESS; } DEFUN (no_debug_ospf_ism, @@ -858,82 +818,76 @@ DEFUN (no_debug_ospf_ism, "ISM Event Information\n" "ISM TImer Information\n") { - int inst = (argv[3]->type == RANGE_TKN); - char *dbgparam = (argc == 5 + inst) ? argv[argc - 1]->text : NULL; - - if (inst) // user passed instance ID - { - if (!ospf_lookup_instance (strtoul (argv[3]->arg, NULL, 10))) - return CMD_SUCCESS; - } - - if (vty->node == CONFIG_NODE) - { - if (!dbgparam) - DEBUG_OFF (ism, ISM); - else + int inst = (argv[3]->type == RANGE_TKN); + char *dbgparam = (argc == 5 + inst) ? argv[argc - 1]->text : NULL; + + if (inst) // user passed instance ID { - if (strmatch (dbgparam, "status")) - DEBUG_OFF (ism, ISM_STATUS); - else if (strmatch (dbgparam, "events")) - DEBUG_OFF (ism, ISM_EVENTS); - else if (strmatch (dbgparam, "timers")) - DEBUG_OFF (ism, ISM_TIMERS); + if (!ospf_lookup_instance(strtoul(argv[3]->arg, NULL, 10))) + return CMD_SUCCESS; + } + + if (vty->node == CONFIG_NODE) { + if (!dbgparam) + DEBUG_OFF(ism, ISM); + else { + if (strmatch(dbgparam, "status")) + DEBUG_OFF(ism, ISM_STATUS); + else if (strmatch(dbgparam, "events")) + DEBUG_OFF(ism, ISM_EVENTS); + else if (strmatch(dbgparam, "timers")) + DEBUG_OFF(ism, ISM_TIMERS); + } + + return CMD_SUCCESS; + } + + /* ENABLE_NODE. */ + if (!dbgparam) + TERM_DEBUG_OFF(ism, ISM); + else { + if (strmatch(dbgparam, "status")) + TERM_DEBUG_OFF(ism, ISM_STATUS); + else if (strmatch(dbgparam, "events")) + TERM_DEBUG_OFF(ism, ISM_EVENTS); + else if (strmatch(dbgparam, "timers")) + TERM_DEBUG_OFF(ism, ISM_TIMERS); } - return CMD_SUCCESS; - } - - /* ENABLE_NODE. */ - if (!dbgparam) - TERM_DEBUG_OFF (ism, ISM); - else - { - if (strmatch (dbgparam, "status")) - TERM_DEBUG_OFF (ism, ISM_STATUS); - else if (strmatch (dbgparam, "events")) - TERM_DEBUG_OFF (ism, ISM_EVENTS); - else if (strmatch (dbgparam, "timers")) - TERM_DEBUG_OFF (ism, ISM_TIMERS); - } - - return CMD_SUCCESS; + return CMD_SUCCESS; } -static int -debug_ospf_nsm_common (struct vty *vty, int arg_base, int argc, struct cmd_token **argv) +static int debug_ospf_nsm_common(struct vty *vty, int arg_base, int argc, + struct cmd_token **argv) { - if (vty->node == CONFIG_NODE) - { - if (argc == arg_base + 0) - DEBUG_ON (nsm, NSM); - else if (argc == arg_base + 1) - { - if (strmatch(argv[arg_base]->text, "status")) - DEBUG_ON (nsm, NSM_STATUS); - else if (strmatch(argv[arg_base]->text, "events")) - DEBUG_ON (nsm, NSM_EVENTS); - else if (strmatch(argv[arg_base]->text, "timers")) - DEBUG_ON (nsm, NSM_TIMERS); + if (vty->node == CONFIG_NODE) { + if (argc == arg_base + 0) + DEBUG_ON(nsm, NSM); + else if (argc == arg_base + 1) { + if (strmatch(argv[arg_base]->text, "status")) + DEBUG_ON(nsm, NSM_STATUS); + else if (strmatch(argv[arg_base]->text, "events")) + DEBUG_ON(nsm, NSM_EVENTS); + else if (strmatch(argv[arg_base]->text, "timers")) + DEBUG_ON(nsm, NSM_TIMERS); + } + + return CMD_SUCCESS; + } + + /* ENABLE_NODE. */ + if (argc == arg_base + 0) + TERM_DEBUG_ON(nsm, NSM); + else if (argc == arg_base + 1) { + if (strmatch(argv[arg_base]->text, "status")) + TERM_DEBUG_ON(nsm, NSM_STATUS); + else if (strmatch(argv[arg_base]->text, "events")) + TERM_DEBUG_ON(nsm, NSM_EVENTS); + else if (strmatch(argv[arg_base]->text, "timers")) + TERM_DEBUG_ON(nsm, NSM_TIMERS); } - return CMD_SUCCESS; - } - - /* ENABLE_NODE. */ - if (argc == arg_base + 0) - TERM_DEBUG_ON (nsm, NSM); - else if (argc == arg_base + 1) - { - if (strmatch(argv[arg_base]->text, "status")) - TERM_DEBUG_ON (nsm, NSM_STATUS); - else if (strmatch(argv[arg_base]->text, "events")) - TERM_DEBUG_ON (nsm, NSM_EVENTS); - else if (strmatch(argv[arg_base]->text, "timers")) - TERM_DEBUG_ON (nsm, NSM_TIMERS); - } - - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (debug_ospf_nsm, @@ -946,7 +900,7 @@ DEFUN (debug_ospf_nsm, "NSM Event Information\n" "NSM Timer Information\n") { - return debug_ospf_nsm_common (vty, 3, argc, argv); + return debug_ospf_nsm_common(vty, 3, argc, argv); } DEFUN (debug_ospf_instance_nsm, @@ -960,52 +914,49 @@ DEFUN (debug_ospf_instance_nsm, "NSM Event Information\n" "NSM Timer Information\n") { - int idx_number = 2; - u_short instance = 0; + int idx_number = 2; + u_short instance = 0; - instance = strtoul(argv[idx_number]->arg, NULL, 10); - if (!ospf_lookup_instance (instance)) - return CMD_SUCCESS; + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if (!ospf_lookup_instance(instance)) + return CMD_SUCCESS; - return debug_ospf_nsm_common (vty, 4, argc, argv); + return debug_ospf_nsm_common(vty, 4, argc, argv); } -static int -no_debug_ospf_nsm_common (struct vty *vty, int arg_base, int argc, struct cmd_token **argv) +static int no_debug_ospf_nsm_common(struct vty *vty, int arg_base, int argc, + struct cmd_token **argv) { - /* XXX qlyoung */ - if (vty->node == CONFIG_NODE) - { - if (argc == arg_base + 0) - DEBUG_OFF (nsm, NSM); - else if (argc == arg_base + 1) - { - if (strmatch(argv[arg_base]->text, "status")) - DEBUG_OFF (nsm, NSM_STATUS); - else if (strmatch(argv[arg_base]->text, "events")) - DEBUG_OFF (nsm, NSM_EVENTS); - else if (strmatch(argv[arg_base]->text, "timers")) - DEBUG_OFF (nsm, NSM_TIMERS); + /* XXX qlyoung */ + if (vty->node == CONFIG_NODE) { + if (argc == arg_base + 0) + DEBUG_OFF(nsm, NSM); + else if (argc == arg_base + 1) { + if (strmatch(argv[arg_base]->text, "status")) + DEBUG_OFF(nsm, NSM_STATUS); + else if (strmatch(argv[arg_base]->text, "events")) + DEBUG_OFF(nsm, NSM_EVENTS); + else if (strmatch(argv[arg_base]->text, "timers")) + DEBUG_OFF(nsm, NSM_TIMERS); + } + + return CMD_SUCCESS; + } + + /* ENABLE_NODE. */ + if (argc == arg_base + 0) + TERM_DEBUG_OFF(nsm, NSM); + else if (argc == arg_base + 1) { + if (strmatch(argv[arg_base]->text, "status")) + TERM_DEBUG_OFF(nsm, NSM_STATUS); + else if (strmatch(argv[arg_base]->text, "events")) + TERM_DEBUG_OFF(nsm, NSM_EVENTS); + else if (strmatch(argv[arg_base]->text, "timers")) + TERM_DEBUG_OFF(nsm, NSM_TIMERS); } - return CMD_SUCCESS; - } - - /* ENABLE_NODE. */ - if (argc == arg_base + 0) - TERM_DEBUG_OFF (nsm, NSM); - else if (argc == arg_base + 1) - { - if (strmatch(argv[arg_base]->text, "status")) - TERM_DEBUG_OFF (nsm, NSM_STATUS); - else if (strmatch(argv[arg_base]->text, "events")) - TERM_DEBUG_OFF (nsm, NSM_EVENTS); - else if (strmatch(argv[arg_base]->text, "timers")) - TERM_DEBUG_OFF (nsm, NSM_TIMERS); - } - - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_debug_ospf_nsm, @@ -1019,7 +970,7 @@ DEFUN (no_debug_ospf_nsm, "NSM Event Information\n" "NSM Timer Information\n") { - return no_debug_ospf_nsm_common(vty, 4, argc, argv); + return no_debug_ospf_nsm_common(vty, 4, argc, argv); } @@ -1035,55 +986,52 @@ DEFUN (no_debug_ospf_instance_nsm, "NSM Event Information\n" "NSM Timer Information\n") { - int idx_number = 3; - u_short instance = 0; + int idx_number = 3; + u_short instance = 0; - instance = strtoul(argv[idx_number]->arg, NULL, 10); - if (!ospf_lookup_instance (instance)) - return CMD_SUCCESS; + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if (!ospf_lookup_instance(instance)) + return CMD_SUCCESS; - return no_debug_ospf_nsm_common(vty, 5, argc, argv); + return no_debug_ospf_nsm_common(vty, 5, argc, argv); } -static int -debug_ospf_lsa_common (struct vty *vty, int arg_base, int argc, struct cmd_token **argv) +static int debug_ospf_lsa_common(struct vty *vty, int arg_base, int argc, + struct cmd_token **argv) { - if (vty->node == CONFIG_NODE) - { - if (argc == arg_base + 0) - DEBUG_ON (lsa, LSA); - else if (argc == arg_base + 1) - { - if (strmatch(argv[arg_base]->text, "generate")) - DEBUG_ON (lsa, LSA_GENERATE); - else if (strmatch(argv[arg_base]->text, "flooding")) - DEBUG_ON (lsa, LSA_FLOODING); - else if (strmatch(argv[arg_base]->text, "install")) - DEBUG_ON (lsa, LSA_INSTALL); - else if (strmatch(argv[arg_base]->text, "refresh")) - DEBUG_ON (lsa, LSA_REFRESH); + if (vty->node == CONFIG_NODE) { + if (argc == arg_base + 0) + DEBUG_ON(lsa, LSA); + else if (argc == arg_base + 1) { + if (strmatch(argv[arg_base]->text, "generate")) + DEBUG_ON(lsa, LSA_GENERATE); + else if (strmatch(argv[arg_base]->text, "flooding")) + DEBUG_ON(lsa, LSA_FLOODING); + else if (strmatch(argv[arg_base]->text, "install")) + DEBUG_ON(lsa, LSA_INSTALL); + else if (strmatch(argv[arg_base]->text, "refresh")) + DEBUG_ON(lsa, LSA_REFRESH); + } + + return CMD_SUCCESS; } - return CMD_SUCCESS; - } - - /* ENABLE_NODE. */ - if (argc == arg_base + 0) - TERM_DEBUG_ON (lsa, LSA); - else if (argc == arg_base + 1) - { - if (strmatch(argv[arg_base]->text, "generate")) - TERM_DEBUG_ON (lsa, LSA_GENERATE); - else if (strmatch(argv[arg_base]->text, "flooding")) - TERM_DEBUG_ON (lsa, LSA_FLOODING); - else if (strmatch(argv[arg_base]->text, "install")) - TERM_DEBUG_ON (lsa, LSA_INSTALL); - else if (strmatch(argv[arg_base]->text, "refresh")) - TERM_DEBUG_ON (lsa, LSA_REFRESH); - } - - return CMD_SUCCESS; + /* ENABLE_NODE. */ + if (argc == arg_base + 0) + TERM_DEBUG_ON(lsa, LSA); + else if (argc == arg_base + 1) { + if (strmatch(argv[arg_base]->text, "generate")) + TERM_DEBUG_ON(lsa, LSA_GENERATE); + else if (strmatch(argv[arg_base]->text, "flooding")) + TERM_DEBUG_ON(lsa, LSA_FLOODING); + else if (strmatch(argv[arg_base]->text, "install")) + TERM_DEBUG_ON(lsa, LSA_INSTALL); + else if (strmatch(argv[arg_base]->text, "refresh")) + TERM_DEBUG_ON(lsa, LSA_REFRESH); + } + + return CMD_SUCCESS; } DEFUN (debug_ospf_lsa, @@ -1097,7 +1045,7 @@ DEFUN (debug_ospf_lsa, "LSA Install/Delete\n" "LSA Refresh\n") { - return debug_ospf_lsa_common(vty, 3, argc, argv); + return debug_ospf_lsa_common(vty, 3, argc, argv); } DEFUN (debug_ospf_instance_lsa, @@ -1112,55 +1060,52 @@ DEFUN (debug_ospf_instance_lsa, "LSA Install/Delete\n" "LSA Refresh\n") { - int idx_number = 2; - u_short instance = 0; + int idx_number = 2; + u_short instance = 0; - instance = strtoul(argv[idx_number]->arg, NULL, 10); - if (!ospf_lookup_instance (instance)) - return CMD_SUCCESS; + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if (!ospf_lookup_instance(instance)) + return CMD_SUCCESS; - return debug_ospf_lsa_common(vty, 4, argc, argv); + return debug_ospf_lsa_common(vty, 4, argc, argv); } -static int -no_debug_ospf_lsa_common (struct vty *vty, int arg_base, int argc, struct cmd_token **argv) +static int no_debug_ospf_lsa_common(struct vty *vty, int arg_base, int argc, + struct cmd_token **argv) { - if (vty->node == CONFIG_NODE) - { - if (argc == arg_base + 0) - DEBUG_OFF (lsa, LSA); - else if (argc == arg_base + 1) - { - if (strmatch(argv[arg_base]->text, "generate")) - DEBUG_OFF (lsa, LSA_GENERATE); - else if (strmatch(argv[arg_base]->text, "flooding")) - DEBUG_OFF (lsa, LSA_FLOODING); - else if (strmatch(argv[arg_base]->text, "install")) - DEBUG_OFF (lsa, LSA_INSTALL); - else if (strmatch(argv[arg_base]->text, "refresh")) - DEBUG_OFF (lsa, LSA_REFRESH); + if (vty->node == CONFIG_NODE) { + if (argc == arg_base + 0) + DEBUG_OFF(lsa, LSA); + else if (argc == arg_base + 1) { + if (strmatch(argv[arg_base]->text, "generate")) + DEBUG_OFF(lsa, LSA_GENERATE); + else if (strmatch(argv[arg_base]->text, "flooding")) + DEBUG_OFF(lsa, LSA_FLOODING); + else if (strmatch(argv[arg_base]->text, "install")) + DEBUG_OFF(lsa, LSA_INSTALL); + else if (strmatch(argv[arg_base]->text, "refresh")) + DEBUG_OFF(lsa, LSA_REFRESH); + } + + return CMD_SUCCESS; + } + + /* ENABLE_NODE. */ + if (argc == arg_base + 0) + TERM_DEBUG_OFF(lsa, LSA); + else if (argc == arg_base + 1) { + if (strmatch(argv[arg_base]->text, "generate")) + TERM_DEBUG_OFF(lsa, LSA_GENERATE); + else if (strmatch(argv[arg_base]->text, "flooding")) + TERM_DEBUG_OFF(lsa, LSA_FLOODING); + else if (strmatch(argv[arg_base]->text, "install")) + TERM_DEBUG_OFF(lsa, LSA_INSTALL); + else if (strmatch(argv[arg_base]->text, "refresh")) + TERM_DEBUG_OFF(lsa, LSA_REFRESH); } - return CMD_SUCCESS; - } - - /* ENABLE_NODE. */ - if (argc == arg_base + 0) - TERM_DEBUG_OFF (lsa, LSA); - else if (argc == arg_base + 1) - { - if (strmatch(argv[arg_base]->text, "generate")) - TERM_DEBUG_OFF (lsa, LSA_GENERATE); - else if (strmatch(argv[arg_base]->text, "flooding")) - TERM_DEBUG_OFF (lsa, LSA_FLOODING); - else if (strmatch(argv[arg_base]->text, "install")) - TERM_DEBUG_OFF (lsa, LSA_INSTALL); - else if (strmatch(argv[arg_base]->text, "refresh")) - TERM_DEBUG_OFF (lsa, LSA_REFRESH); - } - - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_debug_ospf_lsa, @@ -1175,7 +1120,7 @@ DEFUN (no_debug_ospf_lsa, "LSA Install/Delete\n" "LSA Refres\n") { - return no_debug_ospf_lsa_common (vty, 4, argc, argv); + return no_debug_ospf_lsa_common(vty, 4, argc, argv); } DEFUN (no_debug_ospf_instance_lsa, @@ -1191,47 +1136,44 @@ DEFUN (no_debug_ospf_instance_lsa, "LSA Install/Delete\n" "LSA Refres\n") { - int idx_number = 3; - u_short instance = 0; + int idx_number = 3; + u_short instance = 0; - instance = strtoul(argv[idx_number]->arg, NULL, 10); - if (!ospf_lookup_instance (instance)) - return CMD_SUCCESS; + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if (!ospf_lookup_instance(instance)) + return CMD_SUCCESS; - return no_debug_ospf_lsa_common (vty, 5, argc, argv); + return no_debug_ospf_lsa_common(vty, 5, argc, argv); } -static int -debug_ospf_zebra_common (struct vty *vty, int arg_base, int argc, struct cmd_token **argv) +static int debug_ospf_zebra_common(struct vty *vty, int arg_base, int argc, + struct cmd_token **argv) { - if (vty->node == CONFIG_NODE) - { - if (argc == arg_base + 0) - DEBUG_ON (zebra, ZEBRA); - else if (argc == arg_base + 1) - { - if (strmatch(argv[arg_base]->text, "interface")) - DEBUG_ON (zebra, ZEBRA_INTERFACE); - else if (strmatch(argv[arg_base]->text, "redistribute")) - DEBUG_ON (zebra, ZEBRA_REDISTRIBUTE); + if (vty->node == CONFIG_NODE) { + if (argc == arg_base + 0) + DEBUG_ON(zebra, ZEBRA); + else if (argc == arg_base + 1) { + if (strmatch(argv[arg_base]->text, "interface")) + DEBUG_ON(zebra, ZEBRA_INTERFACE); + else if (strmatch(argv[arg_base]->text, "redistribute")) + DEBUG_ON(zebra, ZEBRA_REDISTRIBUTE); + } + + return CMD_SUCCESS; + } + + /* ENABLE_NODE. */ + if (argc == arg_base + 0) + TERM_DEBUG_ON(zebra, ZEBRA); + else if (argc == arg_base + 1) { + if (strmatch(argv[arg_base]->text, "interface")) + TERM_DEBUG_ON(zebra, ZEBRA_INTERFACE); + else if (strmatch(argv[arg_base]->text, "redistribute")) + TERM_DEBUG_ON(zebra, ZEBRA_REDISTRIBUTE); } - return CMD_SUCCESS; - } - - /* ENABLE_NODE. */ - if (argc == arg_base + 0) - TERM_DEBUG_ON (zebra, ZEBRA); - else if (argc == arg_base + 1) - { - if (strmatch(argv[arg_base]->text, "interface")) - TERM_DEBUG_ON (zebra, ZEBRA_INTERFACE); - else if (strmatch(argv[arg_base]->text, "redistribute")) - TERM_DEBUG_ON (zebra, ZEBRA_REDISTRIBUTE); - } - - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (debug_ospf_zebra, @@ -1243,7 +1185,7 @@ DEFUN (debug_ospf_zebra, "Zebra interface\n" "Zebra redistribute\n") { - return debug_ospf_zebra_common(vty, 3, argc, argv); + return debug_ospf_zebra_common(vty, 3, argc, argv); } DEFUN (debug_ospf_instance_zebra, @@ -1256,48 +1198,44 @@ DEFUN (debug_ospf_instance_zebra, "Zebra interface\n" "Zebra redistribute\n") { - int idx_number = 2; - u_short instance = 0; + int idx_number = 2; + u_short instance = 0; - instance = strtoul(argv[idx_number]->arg, NULL, 10); - if (!ospf_lookup_instance (instance)) - return CMD_SUCCESS; + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if (!ospf_lookup_instance(instance)) + return CMD_SUCCESS; - return debug_ospf_zebra_common(vty, 4, argc, argv); + return debug_ospf_zebra_common(vty, 4, argc, argv); } -static int -no_debug_ospf_zebra_common(struct vty *vty, int arg_base, int argc, - struct cmd_token **argv) +static int no_debug_ospf_zebra_common(struct vty *vty, int arg_base, int argc, + struct cmd_token **argv) { - if (vty->node == CONFIG_NODE) - { - if (argc == arg_base + 0) - DEBUG_OFF (zebra, ZEBRA); - else if (argc == arg_base + 1) - { - if (strmatch(argv[arg_base]->text, "interface")) - DEBUG_OFF (zebra, ZEBRA_INTERFACE); - else if (strmatch(argv[arg_base]->text, "redistribute")) - DEBUG_OFF (zebra, ZEBRA_REDISTRIBUTE); + if (vty->node == CONFIG_NODE) { + if (argc == arg_base + 0) + DEBUG_OFF(zebra, ZEBRA); + else if (argc == arg_base + 1) { + if (strmatch(argv[arg_base]->text, "interface")) + DEBUG_OFF(zebra, ZEBRA_INTERFACE); + else if (strmatch(argv[arg_base]->text, "redistribute")) + DEBUG_OFF(zebra, ZEBRA_REDISTRIBUTE); + } + + return CMD_SUCCESS; + } + + /* ENABLE_NODE. */ + if (argc == arg_base + 0) + TERM_DEBUG_OFF(zebra, ZEBRA); + else if (argc == arg_base + 1) { + if (strmatch(argv[arg_base]->text, "interface")) + TERM_DEBUG_OFF(zebra, ZEBRA_INTERFACE); + else if (strmatch(argv[arg_base]->text, "redistribute")) + TERM_DEBUG_OFF(zebra, ZEBRA_REDISTRIBUTE); } - return CMD_SUCCESS; - } - - /* ENABLE_NODE. */ - if (argc == arg_base + 0) - TERM_DEBUG_OFF (zebra, ZEBRA); - else if (argc == arg_base + 1) - { - if (strmatch(argv[arg_base]->text, "interface")) - TERM_DEBUG_OFF (zebra, ZEBRA_INTERFACE); - else if (strmatch(argv[arg_base]->text, "redistribute")) - TERM_DEBUG_OFF (zebra, ZEBRA_REDISTRIBUTE); - } - - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_debug_ospf_zebra, @@ -1310,7 +1248,7 @@ DEFUN (no_debug_ospf_zebra, "Zebra interface\n" "Zebra redistribute\n") { - return no_debug_ospf_zebra_common(vty, 4, argc, argv); + return no_debug_ospf_zebra_common(vty, 4, argc, argv); } DEFUN (no_debug_ospf_instance_zebra, @@ -1324,18 +1262,17 @@ DEFUN (no_debug_ospf_instance_zebra, "Zebra interface\n" "Zebra redistribute\n") { - int idx_number = 3; - u_short instance = 0; + int idx_number = 3; + u_short instance = 0; - instance = strtoul(argv[idx_number]->arg, NULL, 10); - if (!ospf_lookup_instance (instance)) - return CMD_SUCCESS; + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if (!ospf_lookup_instance(instance)) + return CMD_SUCCESS; - return no_debug_ospf_zebra_common(vty, 5, argc, argv); + return no_debug_ospf_zebra_common(vty, 5, argc, argv); } - DEFUN (debug_ospf_event, debug_ospf_event_cmd, "debug ospf event", @@ -1343,10 +1280,10 @@ DEFUN (debug_ospf_event, OSPF_STR "OSPF event information\n") { - if (vty->node == CONFIG_NODE) - CONF_DEBUG_ON (event, EVENT); - TERM_DEBUG_ON (event, EVENT); - return CMD_SUCCESS; + if (vty->node == CONFIG_NODE) + CONF_DEBUG_ON(event, EVENT); + TERM_DEBUG_ON(event, EVENT); + return CMD_SUCCESS; } DEFUN (no_debug_ospf_event, @@ -1357,10 +1294,10 @@ DEFUN (no_debug_ospf_event, OSPF_STR "OSPF event information\n") { - if (vty->node == CONFIG_NODE) - CONF_DEBUG_OFF (event, EVENT); - TERM_DEBUG_OFF (event, EVENT); - return CMD_SUCCESS; + if (vty->node == CONFIG_NODE) + CONF_DEBUG_OFF(event, EVENT); + TERM_DEBUG_OFF(event, EVENT); + return CMD_SUCCESS; } DEFUN (debug_ospf_instance_event, @@ -1371,17 +1308,17 @@ DEFUN (debug_ospf_instance_event, "Instance ID\n" "OSPF event information\n") { - int idx_number = 2; - u_short instance = 0; + int idx_number = 2; + u_short instance = 0; - instance = strtoul(argv[idx_number]->arg, NULL, 10); - if (!ospf_lookup_instance (instance)) - return CMD_SUCCESS; + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if (!ospf_lookup_instance(instance)) + return CMD_SUCCESS; - if (vty->node == CONFIG_NODE) - CONF_DEBUG_ON (event, EVENT); - TERM_DEBUG_ON (event, EVENT); - return CMD_SUCCESS; + if (vty->node == CONFIG_NODE) + CONF_DEBUG_ON(event, EVENT); + TERM_DEBUG_ON(event, EVENT); + return CMD_SUCCESS; } DEFUN (no_debug_ospf_instance_event, @@ -1393,17 +1330,17 @@ DEFUN (no_debug_ospf_instance_event, "Instance ID\n" "OSPF event information\n") { - int idx_number = 3; - u_short instance = 0; + int idx_number = 3; + u_short instance = 0; - instance = strtoul(argv[idx_number]->arg, NULL, 10); - if (!ospf_lookup_instance (instance)) - return CMD_SUCCESS; + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if (!ospf_lookup_instance(instance)) + return CMD_SUCCESS; - if (vty->node == CONFIG_NODE) - CONF_DEBUG_OFF (event, EVENT); - TERM_DEBUG_OFF (event, EVENT); - return CMD_SUCCESS; + if (vty->node == CONFIG_NODE) + CONF_DEBUG_OFF(event, EVENT); + TERM_DEBUG_OFF(event, EVENT); + return CMD_SUCCESS; } DEFUN (debug_ospf_nssa, @@ -1413,10 +1350,10 @@ DEFUN (debug_ospf_nssa, OSPF_STR "OSPF nssa information\n") { - if (vty->node == CONFIG_NODE) - CONF_DEBUG_ON (nssa, NSSA); - TERM_DEBUG_ON (nssa, NSSA); - return CMD_SUCCESS; + if (vty->node == CONFIG_NODE) + CONF_DEBUG_ON(nssa, NSSA); + TERM_DEBUG_ON(nssa, NSSA); + return CMD_SUCCESS; } DEFUN (no_debug_ospf_nssa, @@ -1427,10 +1364,10 @@ DEFUN (no_debug_ospf_nssa, OSPF_STR "OSPF nssa information\n") { - if (vty->node == CONFIG_NODE) - CONF_DEBUG_OFF (nssa, NSSA); - TERM_DEBUG_OFF (nssa, NSSA); - return CMD_SUCCESS; + if (vty->node == CONFIG_NODE) + CONF_DEBUG_OFF(nssa, NSSA); + TERM_DEBUG_OFF(nssa, NSSA); + return CMD_SUCCESS; } DEFUN (debug_ospf_instance_nssa, @@ -1441,17 +1378,17 @@ DEFUN (debug_ospf_instance_nssa, "Instance ID\n" "OSPF nssa information\n") { - int idx_number = 2; - u_short instance = 0; + int idx_number = 2; + u_short instance = 0; - instance = strtoul(argv[idx_number]->arg, NULL, 10); - if (!ospf_lookup_instance (instance)) - return CMD_SUCCESS; + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if (!ospf_lookup_instance(instance)) + return CMD_SUCCESS; - if (vty->node == CONFIG_NODE) - CONF_DEBUG_ON (nssa, NSSA); - TERM_DEBUG_ON (nssa, NSSA); - return CMD_SUCCESS; + if (vty->node == CONFIG_NODE) + CONF_DEBUG_ON(nssa, NSSA); + TERM_DEBUG_ON(nssa, NSSA); + return CMD_SUCCESS; } DEFUN (no_debug_ospf_instance_nssa, @@ -1463,17 +1400,17 @@ DEFUN (no_debug_ospf_instance_nssa, "Instance ID\n" "OSPF nssa information\n") { - int idx_number = 3; - u_short instance = 0; + int idx_number = 3; + u_short instance = 0; - instance = strtoul(argv[idx_number]->arg, NULL, 10); - if (!ospf_lookup_instance (instance)) - return CMD_SUCCESS; + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if (!ospf_lookup_instance(instance)) + return CMD_SUCCESS; - if (vty->node == CONFIG_NODE) - CONF_DEBUG_OFF (nssa, NSSA); - TERM_DEBUG_OFF (nssa, NSSA); - return CMD_SUCCESS; + if (vty->node == CONFIG_NODE) + CONF_DEBUG_OFF(nssa, NSSA); + TERM_DEBUG_OFF(nssa, NSSA); + return CMD_SUCCESS; } DEFUN (debug_ospf_te, @@ -1483,10 +1420,10 @@ DEFUN (debug_ospf_te, OSPF_STR "OSPF-TE information\n") { - if (vty->node == CONFIG_NODE) - CONF_DEBUG_ON (te, TE); - TERM_DEBUG_ON (te, TE); - return CMD_SUCCESS; + if (vty->node == CONFIG_NODE) + CONF_DEBUG_ON(te, TE); + TERM_DEBUG_ON(te, TE); + return CMD_SUCCESS; } DEFUN (no_debug_ospf_te, @@ -1497,10 +1434,10 @@ DEFUN (no_debug_ospf_te, OSPF_STR "OSPF-TE information\n") { - if (vty->node == CONFIG_NODE) - CONF_DEBUG_OFF (te, TE); - TERM_DEBUG_OFF (te, TE); - return CMD_SUCCESS; + if (vty->node == CONFIG_NODE) + CONF_DEBUG_OFF(te, TE); + TERM_DEBUG_OFF(te, TE); + return CMD_SUCCESS; } DEFUN (no_debug_ospf, @@ -1510,151 +1447,154 @@ DEFUN (no_debug_ospf, DEBUG_STR OSPF_STR) { - int flag = OSPF_DEBUG_SEND | OSPF_DEBUG_RECV | OSPF_DEBUG_DETAIL; - int i; - - if (vty->node == CONFIG_NODE) - { - CONF_DEBUG_OFF (event, EVENT); - CONF_DEBUG_OFF (nssa, NSSA); - DEBUG_OFF (ism, ISM_EVENTS); - DEBUG_OFF (ism, ISM_STATUS); - DEBUG_OFF (ism, ISM_TIMERS); - DEBUG_OFF (lsa, LSA); - DEBUG_OFF (lsa, LSA_FLOODING); - DEBUG_OFF (lsa, LSA_GENERATE); - DEBUG_OFF (lsa, LSA_INSTALL); - DEBUG_OFF (lsa, LSA_REFRESH); - DEBUG_OFF (nsm, NSM); - DEBUG_OFF (nsm, NSM_EVENTS); - DEBUG_OFF (nsm, NSM_STATUS); - DEBUG_OFF (nsm, NSM_TIMERS); - DEBUG_OFF (zebra, ZEBRA); - DEBUG_OFF (zebra, ZEBRA_INTERFACE); - DEBUG_OFF (zebra, ZEBRA_REDISTRIBUTE); - - for (i = 0; i < 5; i++) - DEBUG_PACKET_OFF (i, flag); - } - - for (i = 0; i < 5; i++) - TERM_DEBUG_PACKET_OFF (i, flag); - - TERM_DEBUG_OFF (event, EVENT); - TERM_DEBUG_OFF (ism, ISM); - TERM_DEBUG_OFF (ism, ISM_EVENTS); - TERM_DEBUG_OFF (ism, ISM_STATUS); - TERM_DEBUG_OFF (ism, ISM_TIMERS); - TERM_DEBUG_OFF (lsa, LSA); - TERM_DEBUG_OFF (lsa, LSA_FLOODING); - TERM_DEBUG_OFF (lsa, LSA_GENERATE); - TERM_DEBUG_OFF (lsa, LSA_INSTALL); - TERM_DEBUG_OFF (lsa, LSA_REFRESH); - TERM_DEBUG_OFF (nsm, NSM); - TERM_DEBUG_OFF (nsm, NSM_EVENTS); - TERM_DEBUG_OFF (nsm, NSM_STATUS); - TERM_DEBUG_OFF (nsm, NSM_TIMERS); - TERM_DEBUG_OFF (nssa, NSSA); - TERM_DEBUG_OFF (zebra, ZEBRA); - TERM_DEBUG_OFF (zebra, ZEBRA_INTERFACE); - TERM_DEBUG_OFF (zebra, ZEBRA_REDISTRIBUTE); - - return CMD_SUCCESS; + int flag = OSPF_DEBUG_SEND | OSPF_DEBUG_RECV | OSPF_DEBUG_DETAIL; + int i; + + if (vty->node == CONFIG_NODE) { + CONF_DEBUG_OFF(event, EVENT); + CONF_DEBUG_OFF(nssa, NSSA); + DEBUG_OFF(ism, ISM_EVENTS); + DEBUG_OFF(ism, ISM_STATUS); + DEBUG_OFF(ism, ISM_TIMERS); + DEBUG_OFF(lsa, LSA); + DEBUG_OFF(lsa, LSA_FLOODING); + DEBUG_OFF(lsa, LSA_GENERATE); + DEBUG_OFF(lsa, LSA_INSTALL); + DEBUG_OFF(lsa, LSA_REFRESH); + DEBUG_OFF(nsm, NSM); + DEBUG_OFF(nsm, NSM_EVENTS); + DEBUG_OFF(nsm, NSM_STATUS); + DEBUG_OFF(nsm, NSM_TIMERS); + DEBUG_OFF(zebra, ZEBRA); + DEBUG_OFF(zebra, ZEBRA_INTERFACE); + DEBUG_OFF(zebra, ZEBRA_REDISTRIBUTE); + + for (i = 0; i < 5; i++) + DEBUG_PACKET_OFF(i, flag); + } + + for (i = 0; i < 5; i++) + TERM_DEBUG_PACKET_OFF(i, flag); + + TERM_DEBUG_OFF(event, EVENT); + TERM_DEBUG_OFF(ism, ISM); + TERM_DEBUG_OFF(ism, ISM_EVENTS); + TERM_DEBUG_OFF(ism, ISM_STATUS); + TERM_DEBUG_OFF(ism, ISM_TIMERS); + TERM_DEBUG_OFF(lsa, LSA); + TERM_DEBUG_OFF(lsa, LSA_FLOODING); + TERM_DEBUG_OFF(lsa, LSA_GENERATE); + TERM_DEBUG_OFF(lsa, LSA_INSTALL); + TERM_DEBUG_OFF(lsa, LSA_REFRESH); + TERM_DEBUG_OFF(nsm, NSM); + TERM_DEBUG_OFF(nsm, NSM_EVENTS); + TERM_DEBUG_OFF(nsm, NSM_STATUS); + TERM_DEBUG_OFF(nsm, NSM_TIMERS); + TERM_DEBUG_OFF(nssa, NSSA); + TERM_DEBUG_OFF(zebra, ZEBRA); + TERM_DEBUG_OFF(zebra, ZEBRA_INTERFACE); + TERM_DEBUG_OFF(zebra, ZEBRA_REDISTRIBUTE); + + return CMD_SUCCESS; } -static int -show_debugging_ospf_common (struct vty *vty, struct ospf *ospf) +static int show_debugging_ospf_common(struct vty *vty, struct ospf *ospf) { - int i; - - if (ospf->instance) - vty_out (vty, "\nOSPF Instance: %d\n\n", ospf->instance); - - vty_out (vty, "OSPF debugging status:\n"); - - /* Show debug status for events. */ - if (IS_DEBUG_OSPF(event,EVENT)) - vty_out (vty, " OSPF event debugging is on\n"); - - /* Show debug status for ISM. */ - if (IS_DEBUG_OSPF (ism, ISM) == OSPF_DEBUG_ISM) - vty_out (vty, " OSPF ISM debugging is on\n"); - else - { - if (IS_DEBUG_OSPF (ism, ISM_STATUS)) - vty_out (vty, " OSPF ISM status debugging is on\n"); - if (IS_DEBUG_OSPF (ism, ISM_EVENTS)) - vty_out (vty, " OSPF ISM event debugging is on\n"); - if (IS_DEBUG_OSPF (ism, ISM_TIMERS)) - vty_out (vty, " OSPF ISM timer debugging is on\n"); - } - - /* Show debug status for NSM. */ - if (IS_DEBUG_OSPF (nsm, NSM) == OSPF_DEBUG_NSM) - vty_out (vty, " OSPF NSM debugging is on\n"); - else - { - if (IS_DEBUG_OSPF (nsm, NSM_STATUS)) - vty_out (vty, " OSPF NSM status debugging is on\n"); - if (IS_DEBUG_OSPF (nsm, NSM_EVENTS)) - vty_out (vty, " OSPF NSM event debugging is on\n"); - if (IS_DEBUG_OSPF (nsm, NSM_TIMERS)) - vty_out (vty, " OSPF NSM timer debugging is on\n"); - } - - /* Show debug status for OSPF Packets. */ - for (i = 0; i < 5; i++) - if (IS_DEBUG_OSPF_PACKET (i, SEND) && IS_DEBUG_OSPF_PACKET (i, RECV)) - { - vty_out (vty, " OSPF packet %s%s debugging is on\n", - lookup_msg(ospf_packet_type_str, i + 1, NULL), - IS_DEBUG_OSPF_PACKET (i, DETAIL) ? " detail" : ""); - } - else - { - if (IS_DEBUG_OSPF_PACKET (i, SEND)) - vty_out (vty, " OSPF packet %s send%s debugging is on\n", - lookup_msg(ospf_packet_type_str, i + 1, NULL), - IS_DEBUG_OSPF_PACKET (i, DETAIL) ? " detail" : ""); - if (IS_DEBUG_OSPF_PACKET (i, RECV)) - vty_out (vty, " OSPF packet %s receive%s debugging is on\n", - lookup_msg(ospf_packet_type_str, i + 1, NULL), - IS_DEBUG_OSPF_PACKET (i, DETAIL) ? " detail" : ""); - } - - /* Show debug status for OSPF LSAs. */ - if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA) - vty_out (vty, " OSPF LSA debugging is on\n"); - else - { - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - vty_out (vty, " OSPF LSA generation debugging is on\n"); - if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) - vty_out (vty, " OSPF LSA flooding debugging is on\n"); - if (IS_DEBUG_OSPF (lsa, LSA_INSTALL)) - vty_out (vty, " OSPF LSA install debugging is on\n"); - if (IS_DEBUG_OSPF (lsa, LSA_REFRESH)) - vty_out (vty, " OSPF LSA refresh debugging is on\n"); - } - - /* Show debug status for Zebra. */ - if (IS_DEBUG_OSPF (zebra, ZEBRA) == OSPF_DEBUG_ZEBRA) - vty_out (vty, " OSPF Zebra debugging is on\n"); - else - { - if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE)) - vty_out (vty, " OSPF Zebra interface debugging is on\n"); - if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE)) - vty_out (vty, " OSPF Zebra redistribute debugging is on\n"); - } - - /* Show debug status for NSSA. */ - if (IS_DEBUG_OSPF (nssa, NSSA) == OSPF_DEBUG_NSSA) - vty_out (vty, " OSPF NSSA debugging is on\n"); - - vty_out (vty, "\n"); - - return CMD_SUCCESS; + int i; + + if (ospf->instance) + vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); + + vty_out(vty, "OSPF debugging status:\n"); + + /* Show debug status for events. */ + if (IS_DEBUG_OSPF(event, EVENT)) + vty_out(vty, " OSPF event debugging is on\n"); + + /* Show debug status for ISM. */ + if (IS_DEBUG_OSPF(ism, ISM) == OSPF_DEBUG_ISM) + vty_out(vty, " OSPF ISM debugging is on\n"); + else { + if (IS_DEBUG_OSPF(ism, ISM_STATUS)) + vty_out(vty, " OSPF ISM status debugging is on\n"); + if (IS_DEBUG_OSPF(ism, ISM_EVENTS)) + vty_out(vty, " OSPF ISM event debugging is on\n"); + if (IS_DEBUG_OSPF(ism, ISM_TIMERS)) + vty_out(vty, " OSPF ISM timer debugging is on\n"); + } + + /* Show debug status for NSM. */ + if (IS_DEBUG_OSPF(nsm, NSM) == OSPF_DEBUG_NSM) + vty_out(vty, " OSPF NSM debugging is on\n"); + else { + if (IS_DEBUG_OSPF(nsm, NSM_STATUS)) + vty_out(vty, " OSPF NSM status debugging is on\n"); + if (IS_DEBUG_OSPF(nsm, NSM_EVENTS)) + vty_out(vty, " OSPF NSM event debugging is on\n"); + if (IS_DEBUG_OSPF(nsm, NSM_TIMERS)) + vty_out(vty, " OSPF NSM timer debugging is on\n"); + } + + /* Show debug status for OSPF Packets. */ + for (i = 0; i < 5; i++) + if (IS_DEBUG_OSPF_PACKET(i, SEND) + && IS_DEBUG_OSPF_PACKET(i, RECV)) { + vty_out(vty, " OSPF packet %s%s debugging is on\n", + lookup_msg(ospf_packet_type_str, i + 1, NULL), + IS_DEBUG_OSPF_PACKET(i, DETAIL) ? " detail" + : ""); + } else { + if (IS_DEBUG_OSPF_PACKET(i, SEND)) + vty_out(vty, + " OSPF packet %s send%s debugging is on\n", + lookup_msg(ospf_packet_type_str, i + 1, + NULL), + IS_DEBUG_OSPF_PACKET(i, DETAIL) + ? " detail" + : ""); + if (IS_DEBUG_OSPF_PACKET(i, RECV)) + vty_out(vty, + " OSPF packet %s receive%s debugging is on\n", + lookup_msg(ospf_packet_type_str, i + 1, + NULL), + IS_DEBUG_OSPF_PACKET(i, DETAIL) + ? " detail" + : ""); + } + + /* Show debug status for OSPF LSAs. */ + if (IS_DEBUG_OSPF(lsa, LSA) == OSPF_DEBUG_LSA) + vty_out(vty, " OSPF LSA debugging is on\n"); + else { + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + vty_out(vty, " OSPF LSA generation debugging is on\n"); + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) + vty_out(vty, " OSPF LSA flooding debugging is on\n"); + if (IS_DEBUG_OSPF(lsa, LSA_INSTALL)) + vty_out(vty, " OSPF LSA install debugging is on\n"); + if (IS_DEBUG_OSPF(lsa, LSA_REFRESH)) + vty_out(vty, " OSPF LSA refresh debugging is on\n"); + } + + /* Show debug status for Zebra. */ + if (IS_DEBUG_OSPF(zebra, ZEBRA) == OSPF_DEBUG_ZEBRA) + vty_out(vty, " OSPF Zebra debugging is on\n"); + else { + if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) + vty_out(vty, + " OSPF Zebra interface debugging is on\n"); + if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) + vty_out(vty, + " OSPF Zebra redistribute debugging is on\n"); + } + + /* Show debug status for NSSA. */ + if (IS_DEBUG_OSPF(nssa, NSSA) == OSPF_DEBUG_NSSA) + vty_out(vty, " OSPF NSSA debugging is on\n"); + + vty_out(vty, "\n"); + + return CMD_SUCCESS; } DEFUN (show_debugging_ospf, @@ -1664,12 +1604,12 @@ DEFUN (show_debugging_ospf, DEBUG_STR OSPF_STR) { - struct ospf *ospf; + struct ospf *ospf; - if ((ospf = ospf_lookup()) == NULL) - return CMD_SUCCESS; + if ((ospf = ospf_lookup()) == NULL) + return CMD_SUCCESS; - return show_debugging_ospf_common(vty, ospf); + return show_debugging_ospf_common(vty, ospf); } DEFUN (show_debugging_ospf_instance, @@ -1680,219 +1620,208 @@ DEFUN (show_debugging_ospf_instance, OSPF_STR "Instance ID\n") { - int idx_number = 3; - struct ospf *ospf; - u_short instance = 0; + int idx_number = 3; + struct ospf *ospf; + u_short instance = 0; - instance = strtoul(argv[idx_number]->arg, NULL, 10); - if ((ospf = ospf_lookup_instance (instance)) == NULL ) - return CMD_SUCCESS; + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if ((ospf = ospf_lookup_instance(instance)) == NULL) + return CMD_SUCCESS; - return show_debugging_ospf_common(vty, ospf); + return show_debugging_ospf_common(vty, ospf); } /* Debug node. */ -static struct cmd_node debug_node = -{ - DEBUG_NODE, - "", - 1 /* VTYSH */ +static struct cmd_node debug_node = { + DEBUG_NODE, "", 1 /* VTYSH */ }; -static int -config_write_debug (struct vty *vty) +static int config_write_debug(struct vty *vty) { - int write = 0; - int i, r; - - const char *type_str[] = {"hello", "dd", "ls-request", "ls-update", "ls-ack"}; - const char *detail_str[] = {"", " send", " recv", "", " detail", - " send detail", " recv detail", " detail"}; - - struct ospf *ospf; - char str[16]; - memset (str, 0, 16); - - if ((ospf = ospf_lookup()) == NULL) - return CMD_SUCCESS; - - if (ospf->instance) - sprintf(str, " %d", ospf->instance); - - /* debug ospf ism (status|events|timers). */ - if (IS_CONF_DEBUG_OSPF (ism, ISM) == OSPF_DEBUG_ISM) - vty_out (vty, "debug ospf%s ism\n", str); - else - { - if (IS_CONF_DEBUG_OSPF (ism, ISM_STATUS)) - vty_out (vty, "debug ospf%s ism status\n", str); - if (IS_CONF_DEBUG_OSPF (ism, ISM_EVENTS)) - vty_out (vty, "debug ospf%s ism event\n", str); - if (IS_CONF_DEBUG_OSPF (ism, ISM_TIMERS)) - vty_out (vty, "debug ospf%s ism timer\n", str); - } - - /* debug ospf nsm (status|events|timers). */ - if (IS_CONF_DEBUG_OSPF (nsm, NSM) == OSPF_DEBUG_NSM) - vty_out (vty, "debug ospf%s nsm\n", str); - else - { - if (IS_CONF_DEBUG_OSPF (nsm, NSM_STATUS)) - vty_out (vty, "debug ospf%s nsm status\n", str); - if (IS_CONF_DEBUG_OSPF (nsm, NSM_EVENTS)) - vty_out (vty, "debug ospf%s nsm event\n", str); - if (IS_CONF_DEBUG_OSPF (nsm, NSM_TIMERS)) - vty_out (vty, "debug ospf%s nsm timer\n", str); - } - - /* debug ospf lsa (generate|flooding|install|refresh). */ - if (IS_CONF_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA) - vty_out (vty, "debug ospf%s lsa\n", str); - else - { - if (IS_CONF_DEBUG_OSPF (lsa, LSA_GENERATE)) - vty_out (vty, "debug ospf%s lsa generate\n", str); - if (IS_CONF_DEBUG_OSPF (lsa, LSA_FLOODING)) - vty_out (vty, "debug ospf%s lsa flooding\n", str); - if (IS_CONF_DEBUG_OSPF (lsa, LSA_INSTALL)) - vty_out (vty, "debug ospf%s lsa install\n", str); - if (IS_CONF_DEBUG_OSPF (lsa, LSA_REFRESH)) - vty_out (vty, "debug ospf%s lsa refresh\n", str); - - write = 1; - } - - /* debug ospf zebra (interface|redistribute). */ - if (IS_CONF_DEBUG_OSPF (zebra, ZEBRA) == OSPF_DEBUG_ZEBRA) - vty_out (vty, "debug ospf%s zebra\n", str); - else - { - if (IS_CONF_DEBUG_OSPF (zebra, ZEBRA_INTERFACE)) - vty_out (vty, "debug ospf%s zebra interface\n", str); - if (IS_CONF_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE)) - vty_out (vty, "debug ospf%s zebra redistribute\n", str); - - write = 1; - } - - /* debug ospf event. */ - if (IS_CONF_DEBUG_OSPF (event, EVENT) == OSPF_DEBUG_EVENT) - { - vty_out (vty, "debug ospf%s event\n", str); - write = 1; - } - - /* debug ospf nssa. */ - if (IS_CONF_DEBUG_OSPF (nssa, NSSA) == OSPF_DEBUG_NSSA) - { - vty_out (vty, "debug ospf%s nssa\n", str); - write = 1; - } - - /* debug ospf packet all detail. */ - r = OSPF_DEBUG_SEND_RECV|OSPF_DEBUG_DETAIL; - for (i = 0; i < 5; i++) - r &= conf_debug_ospf_packet[i] & (OSPF_DEBUG_SEND_RECV|OSPF_DEBUG_DETAIL); - if (r == (OSPF_DEBUG_SEND_RECV|OSPF_DEBUG_DETAIL)) - { - vty_out (vty, "debug ospf%s packet all detail\n", str); - return 1; - } - - /* debug ospf packet all. */ - r = OSPF_DEBUG_SEND_RECV; - for (i = 0; i < 5; i++) - r &= conf_debug_ospf_packet[i] & OSPF_DEBUG_SEND_RECV; - if (r == OSPF_DEBUG_SEND_RECV) - { - vty_out (vty, "debug ospf%s packet all\n", str); - for (i = 0; i < 5; i++) - if (conf_debug_ospf_packet[i] & OSPF_DEBUG_DETAIL) - vty_out (vty, "debug ospf%s packet %s detail\n", str, - type_str[i]); - return 1; - } - - /* debug ospf packet (hello|dd|ls-request|ls-update|ls-ack) - (send|recv) (detail). */ - for (i = 0; i < 5; i++) - { - if (conf_debug_ospf_packet[i] == 0) - continue; - - vty_out (vty, "debug ospf%s packet %s%s\n", str, - type_str[i],detail_str[conf_debug_ospf_packet[i]]); - write = 1; - } - - return write; + int write = 0; + int i, r; + + const char *type_str[] = {"hello", "dd", "ls-request", "ls-update", + "ls-ack"}; + const char *detail_str[] = { + "", " send", " recv", "", + " detail", " send detail", " recv detail", " detail"}; + + struct ospf *ospf; + char str[16]; + memset(str, 0, 16); + + if ((ospf = ospf_lookup()) == NULL) + return CMD_SUCCESS; + + if (ospf->instance) + sprintf(str, " %d", ospf->instance); + + /* debug ospf ism (status|events|timers). */ + if (IS_CONF_DEBUG_OSPF(ism, ISM) == OSPF_DEBUG_ISM) + vty_out(vty, "debug ospf%s ism\n", str); + else { + if (IS_CONF_DEBUG_OSPF(ism, ISM_STATUS)) + vty_out(vty, "debug ospf%s ism status\n", str); + if (IS_CONF_DEBUG_OSPF(ism, ISM_EVENTS)) + vty_out(vty, "debug ospf%s ism event\n", str); + if (IS_CONF_DEBUG_OSPF(ism, ISM_TIMERS)) + vty_out(vty, "debug ospf%s ism timer\n", str); + } + + /* debug ospf nsm (status|events|timers). */ + if (IS_CONF_DEBUG_OSPF(nsm, NSM) == OSPF_DEBUG_NSM) + vty_out(vty, "debug ospf%s nsm\n", str); + else { + if (IS_CONF_DEBUG_OSPF(nsm, NSM_STATUS)) + vty_out(vty, "debug ospf%s nsm status\n", str); + if (IS_CONF_DEBUG_OSPF(nsm, NSM_EVENTS)) + vty_out(vty, "debug ospf%s nsm event\n", str); + if (IS_CONF_DEBUG_OSPF(nsm, NSM_TIMERS)) + vty_out(vty, "debug ospf%s nsm timer\n", str); + } + + /* debug ospf lsa (generate|flooding|install|refresh). */ + if (IS_CONF_DEBUG_OSPF(lsa, LSA) == OSPF_DEBUG_LSA) + vty_out(vty, "debug ospf%s lsa\n", str); + else { + if (IS_CONF_DEBUG_OSPF(lsa, LSA_GENERATE)) + vty_out(vty, "debug ospf%s lsa generate\n", str); + if (IS_CONF_DEBUG_OSPF(lsa, LSA_FLOODING)) + vty_out(vty, "debug ospf%s lsa flooding\n", str); + if (IS_CONF_DEBUG_OSPF(lsa, LSA_INSTALL)) + vty_out(vty, "debug ospf%s lsa install\n", str); + if (IS_CONF_DEBUG_OSPF(lsa, LSA_REFRESH)) + vty_out(vty, "debug ospf%s lsa refresh\n", str); + + write = 1; + } + + /* debug ospf zebra (interface|redistribute). */ + if (IS_CONF_DEBUG_OSPF(zebra, ZEBRA) == OSPF_DEBUG_ZEBRA) + vty_out(vty, "debug ospf%s zebra\n", str); + else { + if (IS_CONF_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) + vty_out(vty, "debug ospf%s zebra interface\n", str); + if (IS_CONF_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) + vty_out(vty, "debug ospf%s zebra redistribute\n", str); + + write = 1; + } + + /* debug ospf event. */ + if (IS_CONF_DEBUG_OSPF(event, EVENT) == OSPF_DEBUG_EVENT) { + vty_out(vty, "debug ospf%s event\n", str); + write = 1; + } + + /* debug ospf nssa. */ + if (IS_CONF_DEBUG_OSPF(nssa, NSSA) == OSPF_DEBUG_NSSA) { + vty_out(vty, "debug ospf%s nssa\n", str); + write = 1; + } + + /* debug ospf packet all detail. */ + r = OSPF_DEBUG_SEND_RECV | OSPF_DEBUG_DETAIL; + for (i = 0; i < 5; i++) + r &= conf_debug_ospf_packet[i] + & (OSPF_DEBUG_SEND_RECV | OSPF_DEBUG_DETAIL); + if (r == (OSPF_DEBUG_SEND_RECV | OSPF_DEBUG_DETAIL)) { + vty_out(vty, "debug ospf%s packet all detail\n", str); + return 1; + } + + /* debug ospf packet all. */ + r = OSPF_DEBUG_SEND_RECV; + for (i = 0; i < 5; i++) + r &= conf_debug_ospf_packet[i] & OSPF_DEBUG_SEND_RECV; + if (r == OSPF_DEBUG_SEND_RECV) { + vty_out(vty, "debug ospf%s packet all\n", str); + for (i = 0; i < 5; i++) + if (conf_debug_ospf_packet[i] & OSPF_DEBUG_DETAIL) + vty_out(vty, "debug ospf%s packet %s detail\n", + str, type_str[i]); + return 1; + } + + /* debug ospf packet (hello|dd|ls-request|ls-update|ls-ack) + (send|recv) (detail). */ + for (i = 0; i < 5; i++) { + if (conf_debug_ospf_packet[i] == 0) + continue; + + vty_out(vty, "debug ospf%s packet %s%s\n", str, type_str[i], + detail_str[conf_debug_ospf_packet[i]]); + write = 1; + } + + return write; } /* Initialize debug commands. */ -void -debug_init () +void debug_init() { - install_node (&debug_node, config_write_debug); - - install_element (ENABLE_NODE, &show_debugging_ospf_cmd); - install_element (ENABLE_NODE, &debug_ospf_ism_cmd); - install_element (ENABLE_NODE, &debug_ospf_nsm_cmd); - install_element (ENABLE_NODE, &debug_ospf_lsa_cmd); - install_element (ENABLE_NODE, &debug_ospf_zebra_cmd); - install_element (ENABLE_NODE, &debug_ospf_event_cmd); - install_element (ENABLE_NODE, &debug_ospf_nssa_cmd); - install_element (ENABLE_NODE, &debug_ospf_te_cmd); - install_element (ENABLE_NODE, &no_debug_ospf_ism_cmd); - install_element (ENABLE_NODE, &no_debug_ospf_nsm_cmd); - install_element (ENABLE_NODE, &no_debug_ospf_lsa_cmd); - install_element (ENABLE_NODE, &no_debug_ospf_zebra_cmd); - install_element (ENABLE_NODE, &no_debug_ospf_event_cmd); - install_element (ENABLE_NODE, &no_debug_ospf_nssa_cmd); - install_element (ENABLE_NODE, &no_debug_ospf_te_cmd); - - install_element (ENABLE_NODE, &show_debugging_ospf_instance_cmd); - install_element (ENABLE_NODE, &debug_ospf_packet_cmd); - install_element (ENABLE_NODE, &no_debug_ospf_packet_cmd); - - install_element (ENABLE_NODE, &debug_ospf_instance_nsm_cmd); - install_element (ENABLE_NODE, &debug_ospf_instance_lsa_cmd); - install_element (ENABLE_NODE, &debug_ospf_instance_zebra_cmd); - install_element (ENABLE_NODE, &debug_ospf_instance_event_cmd); - install_element (ENABLE_NODE, &debug_ospf_instance_nssa_cmd); - install_element (ENABLE_NODE, &no_debug_ospf_instance_nsm_cmd); - install_element (ENABLE_NODE, &no_debug_ospf_instance_lsa_cmd); - install_element (ENABLE_NODE, &no_debug_ospf_instance_zebra_cmd); - install_element (ENABLE_NODE, &no_debug_ospf_instance_event_cmd); - install_element (ENABLE_NODE, &no_debug_ospf_instance_nssa_cmd); - install_element (ENABLE_NODE, &no_debug_ospf_cmd); - - install_element (CONFIG_NODE, &debug_ospf_packet_cmd); - install_element (CONFIG_NODE, &no_debug_ospf_packet_cmd); - install_element (CONFIG_NODE, &debug_ospf_ism_cmd); - install_element (CONFIG_NODE, &no_debug_ospf_ism_cmd); - - install_element (CONFIG_NODE, &debug_ospf_nsm_cmd); - install_element (CONFIG_NODE, &debug_ospf_lsa_cmd); - install_element (CONFIG_NODE, &debug_ospf_zebra_cmd); - install_element (CONFIG_NODE, &debug_ospf_event_cmd); - install_element (CONFIG_NODE, &debug_ospf_nssa_cmd); - install_element (CONFIG_NODE, &debug_ospf_te_cmd); - install_element (CONFIG_NODE, &no_debug_ospf_nsm_cmd); - install_element (CONFIG_NODE, &no_debug_ospf_lsa_cmd); - install_element (CONFIG_NODE, &no_debug_ospf_zebra_cmd); - install_element (CONFIG_NODE, &no_debug_ospf_event_cmd); - install_element (CONFIG_NODE, &no_debug_ospf_nssa_cmd); - install_element (CONFIG_NODE, &no_debug_ospf_te_cmd); - - install_element (CONFIG_NODE, &debug_ospf_instance_nsm_cmd); - install_element (CONFIG_NODE, &debug_ospf_instance_lsa_cmd); - install_element (CONFIG_NODE, &debug_ospf_instance_zebra_cmd); - install_element (CONFIG_NODE, &debug_ospf_instance_event_cmd); - install_element (CONFIG_NODE, &debug_ospf_instance_nssa_cmd); - install_element (CONFIG_NODE, &no_debug_ospf_instance_nsm_cmd); - install_element (CONFIG_NODE, &no_debug_ospf_instance_lsa_cmd); - install_element (CONFIG_NODE, &no_debug_ospf_instance_zebra_cmd); - install_element (CONFIG_NODE, &no_debug_ospf_instance_event_cmd); - install_element (CONFIG_NODE, &no_debug_ospf_instance_nssa_cmd); - install_element (CONFIG_NODE, &no_debug_ospf_cmd); + install_node(&debug_node, config_write_debug); + + install_element(ENABLE_NODE, &show_debugging_ospf_cmd); + install_element(ENABLE_NODE, &debug_ospf_ism_cmd); + install_element(ENABLE_NODE, &debug_ospf_nsm_cmd); + install_element(ENABLE_NODE, &debug_ospf_lsa_cmd); + install_element(ENABLE_NODE, &debug_ospf_zebra_cmd); + install_element(ENABLE_NODE, &debug_ospf_event_cmd); + install_element(ENABLE_NODE, &debug_ospf_nssa_cmd); + install_element(ENABLE_NODE, &debug_ospf_te_cmd); + install_element(ENABLE_NODE, &no_debug_ospf_ism_cmd); + install_element(ENABLE_NODE, &no_debug_ospf_nsm_cmd); + install_element(ENABLE_NODE, &no_debug_ospf_lsa_cmd); + install_element(ENABLE_NODE, &no_debug_ospf_zebra_cmd); + install_element(ENABLE_NODE, &no_debug_ospf_event_cmd); + install_element(ENABLE_NODE, &no_debug_ospf_nssa_cmd); + install_element(ENABLE_NODE, &no_debug_ospf_te_cmd); + + install_element(ENABLE_NODE, &show_debugging_ospf_instance_cmd); + install_element(ENABLE_NODE, &debug_ospf_packet_cmd); + install_element(ENABLE_NODE, &no_debug_ospf_packet_cmd); + + install_element(ENABLE_NODE, &debug_ospf_instance_nsm_cmd); + install_element(ENABLE_NODE, &debug_ospf_instance_lsa_cmd); + install_element(ENABLE_NODE, &debug_ospf_instance_zebra_cmd); + install_element(ENABLE_NODE, &debug_ospf_instance_event_cmd); + install_element(ENABLE_NODE, &debug_ospf_instance_nssa_cmd); + install_element(ENABLE_NODE, &no_debug_ospf_instance_nsm_cmd); + install_element(ENABLE_NODE, &no_debug_ospf_instance_lsa_cmd); + install_element(ENABLE_NODE, &no_debug_ospf_instance_zebra_cmd); + install_element(ENABLE_NODE, &no_debug_ospf_instance_event_cmd); + install_element(ENABLE_NODE, &no_debug_ospf_instance_nssa_cmd); + install_element(ENABLE_NODE, &no_debug_ospf_cmd); + + install_element(CONFIG_NODE, &debug_ospf_packet_cmd); + install_element(CONFIG_NODE, &no_debug_ospf_packet_cmd); + install_element(CONFIG_NODE, &debug_ospf_ism_cmd); + install_element(CONFIG_NODE, &no_debug_ospf_ism_cmd); + + install_element(CONFIG_NODE, &debug_ospf_nsm_cmd); + install_element(CONFIG_NODE, &debug_ospf_lsa_cmd); + install_element(CONFIG_NODE, &debug_ospf_zebra_cmd); + install_element(CONFIG_NODE, &debug_ospf_event_cmd); + install_element(CONFIG_NODE, &debug_ospf_nssa_cmd); + install_element(CONFIG_NODE, &debug_ospf_te_cmd); + install_element(CONFIG_NODE, &no_debug_ospf_nsm_cmd); + install_element(CONFIG_NODE, &no_debug_ospf_lsa_cmd); + install_element(CONFIG_NODE, &no_debug_ospf_zebra_cmd); + install_element(CONFIG_NODE, &no_debug_ospf_event_cmd); + install_element(CONFIG_NODE, &no_debug_ospf_nssa_cmd); + install_element(CONFIG_NODE, &no_debug_ospf_te_cmd); + + install_element(CONFIG_NODE, &debug_ospf_instance_nsm_cmd); + install_element(CONFIG_NODE, &debug_ospf_instance_lsa_cmd); + install_element(CONFIG_NODE, &debug_ospf_instance_zebra_cmd); + install_element(CONFIG_NODE, &debug_ospf_instance_event_cmd); + install_element(CONFIG_NODE, &debug_ospf_instance_nssa_cmd); + install_element(CONFIG_NODE, &no_debug_ospf_instance_nsm_cmd); + install_element(CONFIG_NODE, &no_debug_ospf_instance_lsa_cmd); + install_element(CONFIG_NODE, &no_debug_ospf_instance_zebra_cmd); + install_element(CONFIG_NODE, &no_debug_ospf_instance_event_cmd); + install_element(CONFIG_NODE, &no_debug_ospf_instance_nssa_cmd); + install_element(CONFIG_NODE, &no_debug_ospf_cmd); } diff --git a/ospfd/ospf_dump.h b/ospfd/ospf_dump.h index 94918c265..ead2f526b 100644 --- a/ospfd/ospf_dump.h +++ b/ospfd/ospf_dump.h @@ -63,50 +63,47 @@ #define CONF_DEBUG_PACKET_OFF(a, b) conf_debug_ospf_packet[a] &= ~(b) #define TERM_DEBUG_PACKET_ON(a, b) term_debug_ospf_packet[a] |= (b) #define TERM_DEBUG_PACKET_OFF(a, b) term_debug_ospf_packet[a] &= ~(b) -#define DEBUG_PACKET_ON(a, b) \ - do { \ - CONF_DEBUG_PACKET_ON(a, b); \ - TERM_DEBUG_PACKET_ON(a, b); \ - } while (0) -#define DEBUG_PACKET_OFF(a, b) \ - do { \ - CONF_DEBUG_PACKET_OFF(a, b); \ - TERM_DEBUG_PACKET_OFF(a, b); \ - } while (0) +#define DEBUG_PACKET_ON(a, b) \ + do { \ + CONF_DEBUG_PACKET_ON(a, b); \ + TERM_DEBUG_PACKET_ON(a, b); \ + } while (0) +#define DEBUG_PACKET_OFF(a, b) \ + do { \ + CONF_DEBUG_PACKET_OFF(a, b); \ + TERM_DEBUG_PACKET_OFF(a, b); \ + } while (0) #define CONF_DEBUG_ON(a, b) conf_debug_ospf_ ## a |= (OSPF_DEBUG_ ## b) #define CONF_DEBUG_OFF(a, b) conf_debug_ospf_ ## a &= ~(OSPF_DEBUG_ ## b) #define TERM_DEBUG_ON(a, b) term_debug_ospf_ ## a |= (OSPF_DEBUG_ ## b) #define TERM_DEBUG_OFF(a, b) term_debug_ospf_ ## a &= ~(OSPF_DEBUG_ ## b) -#define DEBUG_ON(a, b) \ - do { \ - CONF_DEBUG_ON(a, b); \ - TERM_DEBUG_ON(a, b); \ - } while (0) -#define DEBUG_OFF(a, b) \ - do { \ - CONF_DEBUG_OFF(a, b); \ - TERM_DEBUG_OFF(a, b); \ - } while (0) +#define DEBUG_ON(a, b) \ + do { \ + CONF_DEBUG_ON(a, b); \ + TERM_DEBUG_ON(a, b); \ + } while (0) +#define DEBUG_OFF(a, b) \ + do { \ + CONF_DEBUG_OFF(a, b); \ + TERM_DEBUG_OFF(a, b); \ + } while (0) /* Macro for checking debug option. */ -#define IS_DEBUG_OSPF_PACKET(a, b) \ - (term_debug_ospf_packet[a] & OSPF_DEBUG_ ## b) -#define IS_DEBUG_OSPF(a, b) \ - (term_debug_ospf_ ## a & OSPF_DEBUG_ ## b) +#define IS_DEBUG_OSPF_PACKET(a, b) (term_debug_ospf_packet[a] & OSPF_DEBUG_##b) +#define IS_DEBUG_OSPF(a, b) (term_debug_ospf_##a & OSPF_DEBUG_##b) #define IS_DEBUG_OSPF_EVENT IS_DEBUG_OSPF(event,EVENT) #define IS_DEBUG_OSPF_NSSA IS_DEBUG_OSPF(nssa,NSSA) #define IS_DEBUG_OSPF_TE IS_DEBUG_OSPF(te,TE) -#define IS_CONF_DEBUG_OSPF_PACKET(a, b) \ - (conf_debug_ospf_packet[a] & OSPF_DEBUG_ ## b) -#define IS_CONF_DEBUG_OSPF(a, b) \ - (conf_debug_ospf_ ## a & OSPF_DEBUG_ ## b) +#define IS_CONF_DEBUG_OSPF_PACKET(a, b) \ + (conf_debug_ospf_packet[a] & OSPF_DEBUG_##b) +#define IS_CONF_DEBUG_OSPF(a, b) (conf_debug_ospf_##a & OSPF_DEBUG_##b) #ifdef ORIGINAL_CODING -#else /* ORIGINAL_CODING */ +#else /* ORIGINAL_CODING */ struct stream; #endif /* ORIGINAL_CODING */ @@ -127,15 +124,15 @@ extern unsigned long term_debug_ospf_te; extern char *ospf_lsa_type_str[]; /* Prototypes. */ -extern const char *ospf_area_name_string (struct ospf_area *); -extern const char *ospf_area_desc_string (struct ospf_area *); -extern const char *ospf_if_name_string (struct ospf_interface *); -extern void ospf_nbr_state_message (struct ospf_neighbor *, char *, size_t); -extern const char *ospf_timer_dump (struct thread *, char *, size_t); -extern const char *ospf_timeval_dump (struct timeval *, char *, size_t); -extern void ospf_ip_header_dump (struct ip *); -extern void ospf_packet_dump (struct stream *); -extern void debug_init (void); +extern const char *ospf_area_name_string(struct ospf_area *); +extern const char *ospf_area_desc_string(struct ospf_area *); +extern const char *ospf_if_name_string(struct ospf_interface *); +extern void ospf_nbr_state_message(struct ospf_neighbor *, char *, size_t); +extern const char *ospf_timer_dump(struct thread *, char *, size_t); +extern const char *ospf_timeval_dump(struct timeval *, char *, size_t); +extern void ospf_ip_header_dump(struct ip *); +extern void ospf_packet_dump(struct stream *); +extern void debug_init(void); /* Appropriate buffer size to use with ospf_timer_dump and ospf_timeval_dump: */ #define OSPF_TIME_DUMP_SIZE 16 diff --git a/ospfd/ospf_dump_api.c b/ospfd/ospf_dump_api.c index 09f5422ef..3cfe3453a 100644 --- a/ospfd/ospf_dump_api.c +++ b/ospfd/ospf_dump_api.c @@ -30,121 +30,107 @@ #include "ospf_nsm.h" #include "ospf_ism.h" -const struct message ospf_ism_state_msg[] = -{ - { ISM_DependUpon, "DependUpon" }, - { ISM_Down, "Down" }, - { ISM_Loopback, "Loopback" }, - { ISM_Waiting, "Waiting" }, - { ISM_PointToPoint, "Point-To-Point" }, - { ISM_DROther, "DROther" }, - { ISM_Backup, "Backup" }, - { ISM_DR, "DR" }, - { 0 } -}; +const struct message ospf_ism_state_msg[] = { + {ISM_DependUpon, "DependUpon"}, + {ISM_Down, "Down"}, + {ISM_Loopback, "Loopback"}, + {ISM_Waiting, "Waiting"}, + {ISM_PointToPoint, "Point-To-Point"}, + {ISM_DROther, "DROther"}, + {ISM_Backup, "Backup"}, + {ISM_DR, "DR"}, + {0}}; -const struct message ospf_nsm_state_msg[] = -{ - { NSM_DependUpon, "DependUpon" }, - { NSM_Deleted, "Deleted" }, - { NSM_Down, "Down" }, - { NSM_Attempt, "Attempt" }, - { NSM_Init, "Init" }, - { NSM_TwoWay, "2-Way" }, - { NSM_ExStart, "ExStart" }, - { NSM_Exchange, "Exchange" }, - { NSM_Loading, "Loading" }, - { NSM_Full, "Full" }, - { 0 } -}; +const struct message ospf_nsm_state_msg[] = {{NSM_DependUpon, "DependUpon"}, + {NSM_Deleted, "Deleted"}, + {NSM_Down, "Down"}, + {NSM_Attempt, "Attempt"}, + {NSM_Init, "Init"}, + {NSM_TwoWay, "2-Way"}, + {NSM_ExStart, "ExStart"}, + {NSM_Exchange, "Exchange"}, + {NSM_Loading, "Loading"}, + {NSM_Full, "Full"}, + {0}}; -const struct message ospf_lsa_type_msg[] = -{ - { OSPF_UNKNOWN_LSA, "unknown" }, - { OSPF_ROUTER_LSA, "router-LSA" }, - { OSPF_NETWORK_LSA, "network-LSA" }, - { OSPF_SUMMARY_LSA, "summary-LSA" }, - { OSPF_ASBR_SUMMARY_LSA, "summary-LSA" }, - { OSPF_AS_EXTERNAL_LSA, "AS-external-LSA" }, - { OSPF_GROUP_MEMBER_LSA, "GROUP MEMBER LSA" }, - { OSPF_AS_NSSA_LSA, "NSSA-LSA" }, - { 8, "Type-8 LSA" }, - { OSPF_OPAQUE_LINK_LSA, "Link-Local Opaque-LSA" }, - { OSPF_OPAQUE_AREA_LSA, "Area-Local Opaque-LSA" }, - { OSPF_OPAQUE_AS_LSA, "AS-external Opaque-LSA" }, - { 0 } -}; +const struct message ospf_lsa_type_msg[] = { + {OSPF_UNKNOWN_LSA, "unknown"}, + {OSPF_ROUTER_LSA, "router-LSA"}, + {OSPF_NETWORK_LSA, "network-LSA"}, + {OSPF_SUMMARY_LSA, "summary-LSA"}, + {OSPF_ASBR_SUMMARY_LSA, "summary-LSA"}, + {OSPF_AS_EXTERNAL_LSA, "AS-external-LSA"}, + {OSPF_GROUP_MEMBER_LSA, "GROUP MEMBER LSA"}, + {OSPF_AS_NSSA_LSA, "NSSA-LSA"}, + {8, "Type-8 LSA"}, + {OSPF_OPAQUE_LINK_LSA, "Link-Local Opaque-LSA"}, + {OSPF_OPAQUE_AREA_LSA, "Area-Local Opaque-LSA"}, + {OSPF_OPAQUE_AS_LSA, "AS-external Opaque-LSA"}, + {0}}; -const struct message ospf_link_state_id_type_msg[] = -{ - { OSPF_UNKNOWN_LSA, "(unknown)" }, - { OSPF_ROUTER_LSA, "" }, - { OSPF_NETWORK_LSA, "(address of Designated Router)" }, - { OSPF_SUMMARY_LSA, "(summary Network Number)" }, - { OSPF_ASBR_SUMMARY_LSA, "(AS Boundary Router address)" }, - { OSPF_AS_EXTERNAL_LSA, "(External Network Number)" }, - { OSPF_GROUP_MEMBER_LSA, "(Group membership information)" }, - { OSPF_AS_NSSA_LSA, "(External Network Number for NSSA)" }, - { 8, "(Type-8 LSID)" }, - { OSPF_OPAQUE_LINK_LSA, "(Link-Local Opaque-Type/ID)" }, - { OSPF_OPAQUE_AREA_LSA, "(Area-Local Opaque-Type/ID)" }, - { OSPF_OPAQUE_AS_LSA, "(AS-external Opaque-Type/ID)" }, - { 0 } -}; +const struct message ospf_link_state_id_type_msg[] = { + {OSPF_UNKNOWN_LSA, "(unknown)"}, + {OSPF_ROUTER_LSA, ""}, + {OSPF_NETWORK_LSA, "(address of Designated Router)"}, + {OSPF_SUMMARY_LSA, "(summary Network Number)"}, + {OSPF_ASBR_SUMMARY_LSA, "(AS Boundary Router address)"}, + {OSPF_AS_EXTERNAL_LSA, "(External Network Number)"}, + {OSPF_GROUP_MEMBER_LSA, "(Group membership information)"}, + {OSPF_AS_NSSA_LSA, "(External Network Number for NSSA)"}, + {8, "(Type-8 LSID)"}, + {OSPF_OPAQUE_LINK_LSA, "(Link-Local Opaque-Type/ID)"}, + {OSPF_OPAQUE_AREA_LSA, "(Area-Local Opaque-Type/ID)"}, + {OSPF_OPAQUE_AS_LSA, "(AS-external Opaque-Type/ID)"}, + {0}}; -const struct message ospf_network_type_msg[] = -{ - { OSPF_IFTYPE_NONE, "NONE" }, - { OSPF_IFTYPE_POINTOPOINT, "Point-to-Point" }, - { OSPF_IFTYPE_BROADCAST, "Broadcast" }, - { OSPF_IFTYPE_NBMA, "NBMA" }, - { OSPF_IFTYPE_POINTOMULTIPOINT, "Point-to-MultiPoint" }, - { OSPF_IFTYPE_VIRTUALLINK, "Virtual-Link" }, - { 0 } -}; +const struct message ospf_network_type_msg[] = { + {OSPF_IFTYPE_NONE, "NONE"}, + {OSPF_IFTYPE_POINTOPOINT, "Point-to-Point"}, + {OSPF_IFTYPE_BROADCAST, "Broadcast"}, + {OSPF_IFTYPE_NBMA, "NBMA"}, + {OSPF_IFTYPE_POINTOMULTIPOINT, "Point-to-MultiPoint"}, + {OSPF_IFTYPE_VIRTUALLINK, "Virtual-Link"}, + {0}}; /* AuType */ -const struct message ospf_auth_type_str[] = -{ - { OSPF_AUTH_NULL, "Null" }, - { OSPF_AUTH_SIMPLE, "Simple" }, - { OSPF_AUTH_CRYPTOGRAPHIC, "Cryptographic" }, - { 0 } -}; +const struct message ospf_auth_type_str[] = { + {OSPF_AUTH_NULL, "Null"}, + {OSPF_AUTH_SIMPLE, "Simple"}, + {OSPF_AUTH_CRYPTOGRAPHIC, "Cryptographic"}, + {0}}; #define OSPF_OPTION_STR_MAXLEN 24 -char * -ospf_options_dump (u_char options) +char *ospf_options_dump(u_char options) { - static char buf[OSPF_OPTION_STR_MAXLEN]; + static char buf[OSPF_OPTION_STR_MAXLEN]; - snprintf (buf, OSPF_OPTION_STR_MAXLEN, "*|%s|%s|%s|%s|%s|%s|%s", - (options & OSPF_OPTION_O) ? "O" : "-", - (options & OSPF_OPTION_DC) ? "DC" : "-", - (options & OSPF_OPTION_EA) ? "EA" : "-", - (options & OSPF_OPTION_NP) ? "N/P" : "-", - (options & OSPF_OPTION_MC) ? "MC" : "-", - (options & OSPF_OPTION_E) ? "E" : "-", - (options & OSPF_OPTION_MT) ? "M/T" : "-"); + snprintf(buf, OSPF_OPTION_STR_MAXLEN, "*|%s|%s|%s|%s|%s|%s|%s", + (options & OSPF_OPTION_O) ? "O" : "-", + (options & OSPF_OPTION_DC) ? "DC" : "-", + (options & OSPF_OPTION_EA) ? "EA" : "-", + (options & OSPF_OPTION_NP) ? "N/P" : "-", + (options & OSPF_OPTION_MC) ? "MC" : "-", + (options & OSPF_OPTION_E) ? "E" : "-", + (options & OSPF_OPTION_MT) ? "M/T" : "-"); - return buf; + return buf; } -void -ospf_lsa_header_dump (struct lsa_header *lsah) +void ospf_lsa_header_dump(struct lsa_header *lsah) { - const char *lsah_type = lookup_msg(ospf_lsa_type_msg, lsah->type, NULL); + const char *lsah_type = lookup_msg(ospf_lsa_type_msg, lsah->type, NULL); - zlog_debug (" LSA Header"); - zlog_debug (" LS age %d", ntohs (lsah->ls_age)); - zlog_debug (" Options %d (%s)", lsah->options, - ospf_options_dump (lsah->options)); - zlog_debug (" LS type %d (%s)", lsah->type, - (lsah->type ? lsah_type : "unknown type")); - zlog_debug (" Link State ID %s", inet_ntoa (lsah->id)); - zlog_debug (" Advertising Router %s", inet_ntoa (lsah->adv_router)); - zlog_debug (" LS sequence number 0x%lx", (u_long)ntohl (lsah->ls_seqnum)); - zlog_debug (" LS checksum 0x%x", ntohs (lsah->checksum)); - zlog_debug (" length %d", ntohs (lsah->length)); + zlog_debug(" LSA Header"); + zlog_debug(" LS age %d", ntohs(lsah->ls_age)); + zlog_debug(" Options %d (%s)", lsah->options, + ospf_options_dump(lsah->options)); + zlog_debug(" LS type %d (%s)", lsah->type, + (lsah->type ? lsah_type : "unknown type")); + zlog_debug(" Link State ID %s", inet_ntoa(lsah->id)); + zlog_debug(" Advertising Router %s", inet_ntoa(lsah->adv_router)); + zlog_debug(" LS sequence number 0x%lx", + (u_long)ntohl(lsah->ls_seqnum)); + zlog_debug(" LS checksum 0x%x", ntohs(lsah->checksum)); + zlog_debug(" length %d", ntohs(lsah->length)); } diff --git a/ospfd/ospf_dump_api.h b/ospfd/ospf_dump_api.h index 836d23455..359522061 100644 --- a/ospfd/ospf_dump_api.h +++ b/ospfd/ospf_dump_api.h @@ -37,7 +37,7 @@ extern const int ospf_link_state_id_type_msg_max; extern const int ospf_network_type_msg_max; extern const size_t ospf_auth_type_str_max; -extern char *ospf_options_dump (u_char); -extern void ospf_lsa_header_dump (struct lsa_header *); +extern char *ospf_options_dump(u_char); +extern void ospf_lsa_header_dump(struct lsa_header *); #endif /* _ZEBRA_OSPF_DUMP_API_H */ diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index ba3d9e324..c775f2ea2 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -51,171 +51,177 @@ extern struct zclient *zclient; /* Do the LSA acking specified in table 19, Section 13.5, row 2 - * This get called from ospf_flood_out_interface. Declared inline + * This get called from ospf_flood_out_interface. Declared inline * for speed. */ -static void -ospf_flood_delayed_lsa_ack (struct ospf_neighbor *inbr, struct ospf_lsa *lsa) +static void ospf_flood_delayed_lsa_ack(struct ospf_neighbor *inbr, + struct ospf_lsa *lsa) { - /* LSA is more recent than database copy, but was not - flooded back out receiving interface. Delayed - acknowledgment sent. If interface is in Backup state - delayed acknowledgment sent only if advertisement - received from Designated Router, otherwise do nothing See - RFC 2328 Section 13.5 */ - - /* Whether LSA is more recent or not, and whether this is in - response to the LSA being sent out recieving interface has been - worked out previously */ - - /* Deal with router as BDR */ - if (inbr->oi->state == ISM_Backup && ! NBR_IS_DR (inbr)) - return; - - /* Schedule a delayed LSA Ack to be sent */ - listnode_add (inbr->oi->ls_ack, ospf_lsa_lock (lsa)); /* delayed LSA Ack */ + /* LSA is more recent than database copy, but was not + flooded back out receiving interface. Delayed + acknowledgment sent. If interface is in Backup state + delayed acknowledgment sent only if advertisement + received from Designated Router, otherwise do nothing See + RFC 2328 Section 13.5 */ + + /* Whether LSA is more recent or not, and whether this is in + response to the LSA being sent out recieving interface has been + worked out previously */ + + /* Deal with router as BDR */ + if (inbr->oi->state == ISM_Backup && !NBR_IS_DR(inbr)) + return; + + /* Schedule a delayed LSA Ack to be sent */ + listnode_add(inbr->oi->ls_ack, + ospf_lsa_lock(lsa)); /* delayed LSA Ack */ } /* Check LSA is related to external info. */ -struct external_info * -ospf_external_info_check (struct ospf_lsa *lsa) +struct external_info *ospf_external_info_check(struct ospf_lsa *lsa) { - struct as_external_lsa *al; - struct prefix_ipv4 p; - struct route_node *rn; - int type; - - al = (struct as_external_lsa *) lsa->data; - - p.family = AF_INET; - p.prefix = lsa->data->id; - p.prefixlen = ip_masklen (al->mask); - - for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) - { - int redist_on = 0; - - redist_on = is_prefix_default (&p) ? - vrf_bitmap_check (zclient->default_information, VRF_DEFAULT) : - (zclient->mi_redist[AFI_IP][type].enabled || - vrf_bitmap_check (zclient->redist[AFI_IP][type], VRF_DEFAULT)); - //Pending: check for MI above. - if (redist_on) - { - struct list *ext_list; - struct listnode *node; - struct ospf_external *ext; - - ext_list = om->external[type]; - if (!ext_list) - continue; - - for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) - { - rn = NULL; - if (ext->external_info) - rn = route_node_lookup (ext->external_info, - (struct prefix *) &p); - if (rn) - { - route_unlock_node (rn); - if (rn->info != NULL) - return (struct external_info *) rn->info; - } - } - } - } - - return NULL; + struct as_external_lsa *al; + struct prefix_ipv4 p; + struct route_node *rn; + int type; + + al = (struct as_external_lsa *)lsa->data; + + p.family = AF_INET; + p.prefix = lsa->data->id; + p.prefixlen = ip_masklen(al->mask); + + for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) { + int redist_on = 0; + + redist_on = + is_prefix_default(&p) + ? vrf_bitmap_check(zclient->default_information, + VRF_DEFAULT) + : (zclient->mi_redist[AFI_IP][type].enabled + || vrf_bitmap_check( + zclient->redist[AFI_IP][type], + VRF_DEFAULT)); + // Pending: check for MI above. + if (redist_on) { + struct list *ext_list; + struct listnode *node; + struct ospf_external *ext; + + ext_list = om->external[type]; + if (!ext_list) + continue; + + for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) { + rn = NULL; + if (ext->external_info) + rn = route_node_lookup( + ext->external_info, + (struct prefix *)&p); + if (rn) { + route_unlock_node(rn); + if (rn->info != NULL) + return (struct external_info *) + rn->info; + } + } + } + } + + return NULL; } -static void -ospf_process_self_originated_lsa (struct ospf *ospf, - struct ospf_lsa *new, struct ospf_area *area) +static void ospf_process_self_originated_lsa(struct ospf *ospf, + struct ospf_lsa *new, + struct ospf_area *area) { - struct ospf_interface *oi; - struct external_info *ei; - struct listnode *node; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("LSA[Type%d:%s]: Process self-originated LSA seq 0x%x", - new->data->type, inet_ntoa (new->data->id), - ntohl(new->data->ls_seqnum)); - - /* If we're here, we installed a self-originated LSA that we received - from a neighbor, i.e. it's more recent. We must see whether we want - to originate it. - If yes, we should use this LSA's sequence number and reoriginate - a new instance. - if not --- we must flush this LSA from the domain. */ - switch (new->data->type) - { - case OSPF_ROUTER_LSA: - /* Originate a new instance and schedule flooding */ - if (area->router_lsa_self) - area->router_lsa_self->data->ls_seqnum = new->data->ls_seqnum; - ospf_router_lsa_update_area (area); - return; - case OSPF_NETWORK_LSA: - case OSPF_OPAQUE_LINK_LSA: - /* We must find the interface the LSA could belong to. - If the interface is no more a broadcast type or we are no more - the DR, we flush the LSA otherwise -- create the new instance and - schedule flooding. */ - - /* Look through all interfaces, not just area, since interface - could be moved from one area to another. */ - for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) - /* These are sanity check. */ - if (IPV4_ADDR_SAME (&oi->address->u.prefix4, &new->data->id)) - { - if (oi->area != area || - oi->type != OSPF_IFTYPE_BROADCAST || - !IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) - { - ospf_schedule_lsa_flush_area (area, new); - return; - } - - if (new->data->type == OSPF_OPAQUE_LINK_LSA) - { - ospf_opaque_lsa_refresh (new); - return; - } - - if (oi->network_lsa_self) - oi->network_lsa_self->data->ls_seqnum = new->data->ls_seqnum; - /* Schedule network-LSA origination. */ - ospf_network_lsa_update (oi); - return; - } - break; - case OSPF_SUMMARY_LSA: - case OSPF_ASBR_SUMMARY_LSA: - ospf_schedule_abr_task (ospf); - break; - case OSPF_AS_EXTERNAL_LSA : - case OSPF_AS_NSSA_LSA: - if ( (new->data->type == OSPF_AS_EXTERNAL_LSA) - && CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)) - { - ospf_translated_nssa_refresh (ospf, NULL, new); - return; - } - ei = ospf_external_info_check (new); - if (ei) - ospf_external_lsa_refresh (ospf, new, ei, LSA_REFRESH_FORCE); - else - ospf_lsa_flush_as (ospf, new); - break; - case OSPF_OPAQUE_AREA_LSA: - ospf_opaque_lsa_refresh (new); - break; - case OSPF_OPAQUE_AS_LSA: - ospf_opaque_lsa_refresh (new); /* Reconsideration may needed. *//* XXX */ - break; - default: - break; - } + struct ospf_interface *oi; + struct external_info *ei; + struct listnode *node; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "LSA[Type%d:%s]: Process self-originated LSA seq 0x%x", + new->data->type, inet_ntoa(new->data->id), + ntohl(new->data->ls_seqnum)); + + /* If we're here, we installed a self-originated LSA that we received + from a neighbor, i.e. it's more recent. We must see whether we want + to originate it. + If yes, we should use this LSA's sequence number and reoriginate + a new instance. + if not --- we must flush this LSA from the domain. */ + switch (new->data->type) { + case OSPF_ROUTER_LSA: + /* Originate a new instance and schedule flooding */ + if (area->router_lsa_self) + area->router_lsa_self->data->ls_seqnum = + new->data->ls_seqnum; + ospf_router_lsa_update_area(area); + return; + case OSPF_NETWORK_LSA: + case OSPF_OPAQUE_LINK_LSA: + /* We must find the interface the LSA could belong to. + If the interface is no more a broadcast type or we are no + more + the DR, we flush the LSA otherwise -- create the new instance + and + schedule flooding. */ + + /* Look through all interfaces, not just area, since interface + could be moved from one area to another. */ + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) + /* These are sanity check. */ + if (IPV4_ADDR_SAME(&oi->address->u.prefix4, + &new->data->id)) { + if (oi->area != area + || oi->type != OSPF_IFTYPE_BROADCAST + || !IPV4_ADDR_SAME(&oi->address->u.prefix4, + &DR(oi))) { + ospf_schedule_lsa_flush_area(area, new); + return; + } + + if (new->data->type == OSPF_OPAQUE_LINK_LSA) { + ospf_opaque_lsa_refresh(new); + return; + } + + if (oi->network_lsa_self) + oi->network_lsa_self->data->ls_seqnum = + new->data->ls_seqnum; + /* Schedule network-LSA origination. */ + ospf_network_lsa_update(oi); + return; + } + break; + case OSPF_SUMMARY_LSA: + case OSPF_ASBR_SUMMARY_LSA: + ospf_schedule_abr_task(ospf); + break; + case OSPF_AS_EXTERNAL_LSA: + case OSPF_AS_NSSA_LSA: + if ((new->data->type == OSPF_AS_EXTERNAL_LSA) + && CHECK_FLAG(new->flags, OSPF_LSA_LOCAL_XLT)) { + ospf_translated_nssa_refresh(ospf, NULL, new); + return; + } + ei = ospf_external_info_check(new); + if (ei) + ospf_external_lsa_refresh(ospf, new, ei, + LSA_REFRESH_FORCE); + else + ospf_lsa_flush_as(ospf, new); + break; + case OSPF_OPAQUE_AREA_LSA: + ospf_opaque_lsa_refresh(new); + break; + case OSPF_OPAQUE_AS_LSA: + ospf_opaque_lsa_refresh(new); + /* Reconsideration may needed. */ /* XXX */ + break; + default: + break; + } } /* OSPF LSA flooding -- RFC2328 Section 13.(5). */ @@ -228,7 +234,7 @@ ospf_process_self_originated_lsa (struct ospf *ospf, Type-7's can be received, and if a DR they will also flood the local NSSA Area as Type-7's - If a Self-Originated LSA (now an ASBR), + If a Self-Originated LSA (now an ASBR), The LSDB will be updated as Type-5's, (for continual re-fresh) If an NSSA-IR it is installed/flooded as Type-7, P-bit on. @@ -238,777 +244,757 @@ ospf_process_self_originated_lsa (struct ospf *ospf, translator, then All Type-7s (with P-bit ON) are Translated to Type-5's and flooded to all non-NSSA/STUB areas. - During ASE Calculations, + During ASE Calculations, non-ABRs calculate external routes from Type-7's ABRs calculate external routes from Type-5's and non-self Type-7s */ -int -ospf_flood (struct ospf *ospf, struct ospf_neighbor *nbr, - struct ospf_lsa *current, struct ospf_lsa *new) +int ospf_flood(struct ospf *ospf, struct ospf_neighbor *nbr, + struct ospf_lsa *current, struct ospf_lsa *new) { - struct ospf_interface *oi; - int lsa_ack_flag; - - /* Type-7 LSA's will be flooded throughout their native NSSA area, - but will also be flooded as Type-5's into ABR capable links. */ - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("LSA[Flooding]: start, NBR %s (%s), cur(%p), New-LSA[%s]", - inet_ntoa (nbr->router_id), - lookup_msg(ospf_nsm_state_msg, nbr->state, NULL), - (void *)current, - dump_lsa_key (new)); - - oi = nbr->oi; - - /* If there is already a database copy, and if the - database copy was received via flooding and installed less - than MinLSArrival seconds ago, discard the new LSA - (without acknowledging it). */ - if (current != NULL) /* -- endo. */ - { - if (IS_LSA_SELF (current) - && (ntohs (current->data->ls_age) == 0 - && ntohl (current->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("LSA[Flooding]: Got a self-originated LSA, " - "while local one is initial instance."); - ; /* Accept this LSA for quick LSDB resynchronization. */ - } - else if (monotime_since (¤t->tv_recv, NULL) - < ospf->min_ls_arrival * 1000LL) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("LSA[Flooding]: LSA is received recently."); - return -1; - } - } - - /* Flood the new LSA out some subset of the router's interfaces. - In some cases (e.g., the state of the receiving interface is - DR and the LSA was received from a router other than the - Backup DR) the LSA will be flooded back out the receiving - interface. */ - lsa_ack_flag = ospf_flood_through (ospf, nbr, new); - - /* Remove the current database copy from all neighbors' Link state - retransmission lists. AS_EXTERNAL and AS_EXTERNAL_OPAQUE does - ^^^^^^^^^^^^^^^^^^^^^^^ - not have area ID. - All other (even NSSA's) do have area ID. */ - if (current) - { - switch (current->data->type) - { - case OSPF_AS_EXTERNAL_LSA: - case OSPF_OPAQUE_AS_LSA: - ospf_ls_retransmit_delete_nbr_as (ospf, current); - break; - default: - ospf_ls_retransmit_delete_nbr_area (nbr->oi->area, current); - break; - } - } - - /* Do some internal house keeping that is needed here */ - SET_FLAG (new->flags, OSPF_LSA_RECEIVED); - ospf_lsa_is_self_originated (ospf, new); /* Let it set the flag */ - - /* Install the new LSA in the link state database - (replacing the current database copy). This may cause the - routing table calculation to be scheduled. In addition, - timestamp the new LSA with the current time. The flooding - procedure cannot overwrite the newly installed LSA until - MinLSArrival seconds have elapsed. */ - - if (! (new = ospf_lsa_install (ospf, nbr->oi, new))) - return -1; /* unknown LSA type or any other error condition */ - - /* Acknowledge the receipt of the LSA by sending a Link State - Acknowledgment packet back out the receiving interface. */ - if (lsa_ack_flag) - ospf_flood_delayed_lsa_ack (nbr, new); - - /* If this new LSA indicates that it was originated by the - receiving router itself, the router must take special action, - either updating the LSA or in some cases flushing it from - the routing domain. */ - if (ospf_lsa_is_self_originated (ospf, new)) - ospf_process_self_originated_lsa (ospf, new, oi->area); - else - /* Update statistics value for OSPF-MIB. */ - ospf->rx_lsa_count++; - - return 0; + struct ospf_interface *oi; + int lsa_ack_flag; + + /* Type-7 LSA's will be flooded throughout their native NSSA area, + but will also be flooded as Type-5's into ABR capable links. */ + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "LSA[Flooding]: start, NBR %s (%s), cur(%p), New-LSA[%s]", + inet_ntoa(nbr->router_id), + lookup_msg(ospf_nsm_state_msg, nbr->state, NULL), + (void *)current, dump_lsa_key(new)); + + oi = nbr->oi; + + /* If there is already a database copy, and if the + database copy was received via flooding and installed less + than MinLSArrival seconds ago, discard the new LSA + (without acknowledging it). */ + if (current != NULL) /* -- endo. */ + { + if (IS_LSA_SELF(current) + && (ntohs(current->data->ls_age) == 0 + && ntohl(current->data->ls_seqnum) + == OSPF_INITIAL_SEQUENCE_NUMBER)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "LSA[Flooding]: Got a self-originated LSA, " + "while local one is initial instance."); + ; /* Accept this LSA for quick LSDB resynchronization. + */ + } else if (monotime_since(¤t->tv_recv, NULL) + < ospf->min_ls_arrival * 1000LL) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "LSA[Flooding]: LSA is received recently."); + return -1; + } + } + + /* Flood the new LSA out some subset of the router's interfaces. + In some cases (e.g., the state of the receiving interface is + DR and the LSA was received from a router other than the + Backup DR) the LSA will be flooded back out the receiving + interface. */ + lsa_ack_flag = ospf_flood_through(ospf, nbr, new); + + /* Remove the current database copy from all neighbors' Link state + retransmission lists. AS_EXTERNAL and AS_EXTERNAL_OPAQUE does + ^^^^^^^^^^^^^^^^^^^^^^^ + not have area ID. + All other (even NSSA's) do have area ID. */ + if (current) { + switch (current->data->type) { + case OSPF_AS_EXTERNAL_LSA: + case OSPF_OPAQUE_AS_LSA: + ospf_ls_retransmit_delete_nbr_as(ospf, current); + break; + default: + ospf_ls_retransmit_delete_nbr_area(nbr->oi->area, + current); + break; + } + } + + /* Do some internal house keeping that is needed here */ + SET_FLAG(new->flags, OSPF_LSA_RECEIVED); + ospf_lsa_is_self_originated(ospf, new); /* Let it set the flag */ + + /* Install the new LSA in the link state database + (replacing the current database copy). This may cause the + routing table calculation to be scheduled. In addition, + timestamp the new LSA with the current time. The flooding + procedure cannot overwrite the newly installed LSA until + MinLSArrival seconds have elapsed. */ + + if (!(new = ospf_lsa_install(ospf, nbr->oi, new))) + return -1; /* unknown LSA type or any other error condition */ + + /* Acknowledge the receipt of the LSA by sending a Link State + Acknowledgment packet back out the receiving interface. */ + if (lsa_ack_flag) + ospf_flood_delayed_lsa_ack(nbr, new); + + /* If this new LSA indicates that it was originated by the + receiving router itself, the router must take special action, + either updating the LSA or in some cases flushing it from + the routing domain. */ + if (ospf_lsa_is_self_originated(ospf, new)) + ospf_process_self_originated_lsa(ospf, new, oi->area); + else + /* Update statistics value for OSPF-MIB. */ + ospf->rx_lsa_count++; + + return 0; } /* OSPF LSA flooding -- RFC2328 Section 13.3. */ -static int -ospf_flood_through_interface (struct ospf_interface *oi, - struct ospf_neighbor *inbr, - struct ospf_lsa *lsa) +static int ospf_flood_through_interface(struct ospf_interface *oi, + struct ospf_neighbor *inbr, + struct ospf_lsa *lsa) { - struct ospf_neighbor *onbr; - struct route_node *rn; - int retx_flag; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_flood_through_interface(): " - "considering int %s, INBR(%s), LSA[%s]", - IF_NAME (oi), inbr ? inet_ntoa (inbr->router_id) : "NULL", - dump_lsa_key (lsa)); - - if (!ospf_if_is_enable (oi)) - return 0; - - /* Remember if new LSA is aded to a retransmit list. */ - retx_flag = 0; - - /* Each of the neighbors attached to this interface are examined, - to determine whether they must receive the new LSA. The following - steps are executed for each neighbor: */ - for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) - { - struct ospf_lsa *ls_req; - - if (rn->info == NULL) - continue; - - onbr = rn->info; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_flood_through_interface(): considering nbr %s (%s)", - inet_ntoa (onbr->router_id), - lookup_msg(ospf_nsm_state_msg, onbr->state, NULL)); - - /* If the neighbor is in a lesser state than Exchange, it - does not participate in flooding, and the next neighbor - should be examined. */ - if (onbr->state < NSM_Exchange) - continue; - - /* If the adjacency is not yet full (neighbor state is - Exchange or Loading), examine the Link state request - list associated with this adjacency. If there is an - instance of the new LSA on the list, it indicates that - the neighboring router has an instance of the LSA - already. Compare the new LSA to the neighbor's copy: */ - if (onbr->state < NSM_Full) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_flood_through_interface(): nbr adj is not Full"); - ls_req = ospf_ls_request_lookup (onbr, lsa); - if (ls_req != NULL) - { - int ret; - - ret = ospf_lsa_more_recent (ls_req, lsa); - /* The new LSA is less recent. */ - if (ret > 0) - continue; - /* The two copies are the same instance, then delete - the LSA from the Link state request list. */ - else if (ret == 0) - { - ospf_ls_request_delete (onbr, ls_req); - ospf_check_nbr_loading (onbr); - continue; + struct ospf_neighbor *onbr; + struct route_node *rn; + int retx_flag; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_flood_through_interface(): " + "considering int %s, INBR(%s), LSA[%s]", + IF_NAME(oi), inbr ? inet_ntoa(inbr->router_id) : "NULL", + dump_lsa_key(lsa)); + + if (!ospf_if_is_enable(oi)) + return 0; + + /* Remember if new LSA is aded to a retransmit list. */ + retx_flag = 0; + + /* Each of the neighbors attached to this interface are examined, + to determine whether they must receive the new LSA. The following + steps are executed for each neighbor: */ + for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) { + struct ospf_lsa *ls_req; + + if (rn->info == NULL) + continue; + + onbr = rn->info; + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_flood_through_interface(): considering nbr %s (%s)", + inet_ntoa(onbr->router_id), + lookup_msg(ospf_nsm_state_msg, onbr->state, + NULL)); + + /* If the neighbor is in a lesser state than Exchange, it + does not participate in flooding, and the next neighbor + should be examined. */ + if (onbr->state < NSM_Exchange) + continue; + + /* If the adjacency is not yet full (neighbor state is + Exchange or Loading), examine the Link state request + list associated with this adjacency. If there is an + instance of the new LSA on the list, it indicates that + the neighboring router has an instance of the LSA + already. Compare the new LSA to the neighbor's copy: */ + if (onbr->state < NSM_Full) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_flood_through_interface(): nbr adj is not Full"); + ls_req = ospf_ls_request_lookup(onbr, lsa); + if (ls_req != NULL) { + int ret; + + ret = ospf_lsa_more_recent(ls_req, lsa); + /* The new LSA is less recent. */ + if (ret > 0) + continue; + /* The two copies are the same instance, then + delete + the LSA from the Link state request list. */ + else if (ret == 0) { + ospf_ls_request_delete(onbr, ls_req); + ospf_check_nbr_loading(onbr); + continue; + } + /* The new LSA is more recent. Delete the LSA + from the Link state request list. */ + else { + ospf_ls_request_delete(onbr, ls_req); + ospf_check_nbr_loading(onbr); + } + } } - /* The new LSA is more recent. Delete the LSA - from the Link state request list. */ - else - { - ospf_ls_request_delete (onbr, ls_req); - ospf_check_nbr_loading (onbr); + + if (IS_OPAQUE_LSA(lsa->data->type)) { + if (!CHECK_FLAG(onbr->options, OSPF_OPTION_O)) { + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) + zlog_debug( + "Skip this neighbor: Not Opaque-capable."); + continue; + } } - } - } - if (IS_OPAQUE_LSA (lsa->data->type)) - { - if (! CHECK_FLAG (onbr->options, OSPF_OPTION_O)) - { - if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) - zlog_debug ("Skip this neighbor: Not Opaque-capable."); - continue; - } - } - - /* If the new LSA was received from this neighbor, - examine the next neighbor. */ +/* If the new LSA was received from this neighbor, + examine the next neighbor. */ #ifdef ORIGINAL_CODING - if (inbr) - if (IPV4_ADDR_SAME (&inbr->router_id, &onbr->router_id)) - continue; -#else /* ORIGINAL_CODING */ - if (inbr) - { - /* - * Triggered by LSUpd message parser "ospf_ls_upd ()". - * E.g., all LSAs handling here is received via network. - */ - if (IPV4_ADDR_SAME (&inbr->router_id, &onbr->router_id)) - { - if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) - zlog_debug ("Skip this neighbor: inbr == onbr"); - continue; - } - } - else - { - /* - * Triggered by MaxAge remover, so far. - * NULL "inbr" means flooding starts from this node. - */ - if (IPV4_ADDR_SAME (&lsa->data->adv_router, &onbr->router_id)) - { - if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) - zlog_debug ("Skip this neighbor: lsah->adv_router == onbr"); - continue; - } - } + if (inbr) + if (IPV4_ADDR_SAME(&inbr->router_id, &onbr->router_id)) + continue; +#else /* ORIGINAL_CODING */ + if (inbr) { + /* + * Triggered by LSUpd message parser "ospf_ls_upd ()". + * E.g., all LSAs handling here is received via network. + */ + if (IPV4_ADDR_SAME(&inbr->router_id, + &onbr->router_id)) { + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) + zlog_debug( + "Skip this neighbor: inbr == onbr"); + continue; + } + } else { + /* + * Triggered by MaxAge remover, so far. + * NULL "inbr" means flooding starts from this node. + */ + if (IPV4_ADDR_SAME(&lsa->data->adv_router, + &onbr->router_id)) { + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) + zlog_debug( + "Skip this neighbor: lsah->adv_router == onbr"); + continue; + } + } #endif /* ORIGINAL_CODING */ - /* Add the new LSA to the Link state retransmission list - for the adjacency. The LSA will be retransmitted - at intervals until an acknowledgment is seen from - the neighbor. */ - ospf_ls_retransmit_add (onbr, lsa); - retx_flag = 1; - } - - /* If in the previous step, the LSA was NOT added to any of - the Link state retransmission lists, there is no need to - flood the LSA out the interface. */ - if (retx_flag == 0) - { - return (inbr && inbr->oi == oi); - } - - /* if we've received the lsa on this interface we need to perform - additional checking */ - if (inbr && (inbr->oi == oi)) - { - /* If the new LSA was received on this interface, and it was - received from either the Designated Router or the Backup - Designated Router, chances are that all the neighbors have - received the LSA already. */ - if (NBR_IS_DR (inbr) || NBR_IS_BDR (inbr)) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_flood_through_interface(): " - "DR/BDR NOT SEND to int %s", IF_NAME (oi)); - return 1; + /* Add the new LSA to the Link state retransmission list + for the adjacency. The LSA will be retransmitted + at intervals until an acknowledgment is seen from + the neighbor. */ + ospf_ls_retransmit_add(onbr, lsa); + retx_flag = 1; } - - /* If the new LSA was received on this interface, and the - interface state is Backup, examine the next interface. The - Designated Router will do the flooding on this interface. - However, if the Designated Router fails the router will - end up retransmitting the updates. */ - - if (oi->state == ISM_Backup) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_flood_through_interface(): " - "ISM_Backup NOT SEND to int %s", IF_NAME (oi)); - return 1; + + /* If in the previous step, the LSA was NOT added to any of + the Link state retransmission lists, there is no need to + flood the LSA out the interface. */ + if (retx_flag == 0) { + return (inbr && inbr->oi == oi); + } + + /* if we've received the lsa on this interface we need to perform + additional checking */ + if (inbr && (inbr->oi == oi)) { + /* If the new LSA was received on this interface, and it was + received from either the Designated Router or the Backup + Designated Router, chances are that all the neighbors have + received the LSA already. */ + if (NBR_IS_DR(inbr) || NBR_IS_BDR(inbr)) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_flood_through_interface(): " + "DR/BDR NOT SEND to int %s", + IF_NAME(oi)); + return 1; + } + + /* If the new LSA was received on this interface, and the + interface state is Backup, examine the next interface. The + Designated Router will do the flooding on this interface. + However, if the Designated Router fails the router will + end up retransmitting the updates. */ + + if (oi->state == ISM_Backup) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_flood_through_interface(): " + "ISM_Backup NOT SEND to int %s", + IF_NAME(oi)); + return 1; + } } - } - - /* The LSA must be flooded out the interface. Send a Link State - Update packet (including the new LSA as contents) out the - interface. The LSA's LS age must be incremented by InfTransDelay - (which must be > 0) when it is copied into the outgoing Link - State Update packet (until the LS age field reaches the maximum - value of MaxAge). */ - /* XXX HASSO: Is this IS_DEBUG_OSPF_NSSA really correct? */ - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_flood_through_interface(): " - "DR/BDR sending upd to int %s", IF_NAME (oi)); - - /* RFC2328 Section 13.3 - On non-broadcast networks, separate Link State Update - packets must be sent, as unicasts, to each adjacent neighbor - (i.e., those in state Exchange or greater). The destination - IP addresses for these packets are the neighbors' IP - addresses. */ - if (oi->type == OSPF_IFTYPE_NBMA) - { - struct route_node *rn; - struct ospf_neighbor *nbr; - - for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) - if ((nbr = rn->info) != NULL) - if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange) - ospf_ls_upd_send_lsa (nbr, lsa, OSPF_SEND_PACKET_DIRECT); - } - else - ospf_ls_upd_send_lsa (oi->nbr_self, lsa, OSPF_SEND_PACKET_INDIRECT); - - return 0; + + /* The LSA must be flooded out the interface. Send a Link State + Update packet (including the new LSA as contents) out the + interface. The LSA's LS age must be incremented by InfTransDelay + (which must be > 0) when it is copied into the outgoing Link + State Update packet (until the LS age field reaches the maximum + value of MaxAge). */ + /* XXX HASSO: Is this IS_DEBUG_OSPF_NSSA really correct? */ + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_flood_through_interface(): " + "DR/BDR sending upd to int %s", + IF_NAME(oi)); + + /* RFC2328 Section 13.3 + On non-broadcast networks, separate Link State Update + packets must be sent, as unicasts, to each adjacent neighbor + (i.e., those in state Exchange or greater). The destination + IP addresses for these packets are the neighbors' IP + addresses. */ + if (oi->type == OSPF_IFTYPE_NBMA) { + struct route_node *rn; + struct ospf_neighbor *nbr; + + for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) + if ((nbr = rn->info) != NULL) + if (nbr != oi->nbr_self + && nbr->state >= NSM_Exchange) + ospf_ls_upd_send_lsa( + nbr, lsa, + OSPF_SEND_PACKET_DIRECT); + } else + ospf_ls_upd_send_lsa(oi->nbr_self, lsa, + OSPF_SEND_PACKET_INDIRECT); + + return 0; } -int -ospf_flood_through_area (struct ospf_area *area, - struct ospf_neighbor *inbr, struct ospf_lsa *lsa) +int ospf_flood_through_area(struct ospf_area *area, struct ospf_neighbor *inbr, + struct ospf_lsa *lsa) { - struct listnode *node, *nnode; - struct ospf_interface *oi; - int lsa_ack_flag = 0; - - /* All other types are specific to a single area (Area A). The - eligible interfaces are all those interfaces attaching to the - Area A. If Area A is the backbone, this includes all the virtual - links. */ - for (ALL_LIST_ELEMENTS (area->oiflist, node, nnode, oi)) - { - if (area->area_id.s_addr != OSPF_AREA_BACKBONE && - oi->type == OSPF_IFTYPE_VIRTUALLINK) - continue; - - if ((lsa->data->type == OSPF_OPAQUE_LINK_LSA) && (lsa->oi != oi)) - { - /* - * Link local scoped Opaque-LSA should only be flooded - * for the link on which the LSA has received. - */ - if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) - zlog_debug ("Type-9 Opaque-LSA: lsa->oi(%p) != oi(%p)", - (void *)lsa->oi, (void *)oi); - continue; - } - - if (ospf_flood_through_interface (oi, inbr, lsa)) - lsa_ack_flag = 1; - } - - return (lsa_ack_flag); + struct listnode *node, *nnode; + struct ospf_interface *oi; + int lsa_ack_flag = 0; + + /* All other types are specific to a single area (Area A). The + eligible interfaces are all those interfaces attaching to the + Area A. If Area A is the backbone, this includes all the virtual + links. */ + for (ALL_LIST_ELEMENTS(area->oiflist, node, nnode, oi)) { + if (area->area_id.s_addr != OSPF_AREA_BACKBONE + && oi->type == OSPF_IFTYPE_VIRTUALLINK) + continue; + + if ((lsa->data->type == OSPF_OPAQUE_LINK_LSA) + && (lsa->oi != oi)) { + /* + * Link local scoped Opaque-LSA should only be flooded + * for the link on which the LSA has received. + */ + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) + zlog_debug( + "Type-9 Opaque-LSA: lsa->oi(%p) != oi(%p)", + (void *)lsa->oi, (void *)oi); + continue; + } + + if (ospf_flood_through_interface(oi, inbr, lsa)) + lsa_ack_flag = 1; + } + + return (lsa_ack_flag); } -int -ospf_flood_through_as (struct ospf *ospf, struct ospf_neighbor *inbr, - struct ospf_lsa *lsa) +int ospf_flood_through_as(struct ospf *ospf, struct ospf_neighbor *inbr, + struct ospf_lsa *lsa) { - struct listnode *node; - struct ospf_area *area; - int lsa_ack_flag; - - lsa_ack_flag = 0; + struct listnode *node; + struct ospf_area *area; + int lsa_ack_flag; + + lsa_ack_flag = 0; + + /* The incoming LSA is type 5 or type 7 (AS-EXTERNAL or AS-NSSA ) + + Divert the Type-5 LSA's to all non-NSSA/STUB areas + + Divert the Type-7 LSA's to all NSSA areas + + AS-external-LSAs are flooded throughout the entire AS, with the + exception of stub areas (see Section 3.6). The eligible + interfaces are all the router's interfaces, excluding virtual + links and those interfaces attaching to stub areas. */ + + if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT)) /* Translated from 7 */ + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("Flood/AS: NSSA TRANSLATED LSA"); + + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + int continue_flag = 0; + struct listnode *if_node; + struct ospf_interface *oi; + + switch (area->external_routing) { + /* Don't send AS externals into stub areas. Various types + of support for partial stub areas can be implemented + here. NSSA's will receive Type-7's that have areas + matching the originl LSA. */ + case OSPF_AREA_NSSA: /* Sending Type 5 or 7 into NSSA area */ + /* Type-7, flood NSSA area */ + if (lsa->data->type == OSPF_AS_NSSA_LSA + && area == lsa->area) + /* We will send it. */ + continue_flag = 0; + else + continue_flag = 1; /* Skip this NSSA area for + Type-5's et al */ + break; + + case OSPF_AREA_TYPE_MAX: + case OSPF_AREA_STUB: + continue_flag = 1; /* Skip this area. */ + break; + + case OSPF_AREA_DEFAULT: + default: + /* No Type-7 into normal area */ + if (lsa->data->type == OSPF_AS_NSSA_LSA) + continue_flag = 1; /* skip Type-7 */ + else + continue_flag = 0; /* Do this area. */ + break; + } - /* The incoming LSA is type 5 or type 7 (AS-EXTERNAL or AS-NSSA ) + /* Do continue for above switch. Saves a big if then mess */ + if (continue_flag) + continue; /* main for-loop */ - Divert the Type-5 LSA's to all non-NSSA/STUB areas + /* send to every interface in this area */ - Divert the Type-7 LSA's to all NSSA areas + for (ALL_LIST_ELEMENTS_RO(area->oiflist, if_node, oi)) { + /* Skip virtual links */ + if (oi->type != OSPF_IFTYPE_VIRTUALLINK) + if (ospf_flood_through_interface(oi, inbr, + lsa)) /* lsa */ + lsa_ack_flag = 1; + } + } /* main area for-loop */ - AS-external-LSAs are flooded throughout the entire AS, with the - exception of stub areas (see Section 3.6). The eligible - interfaces are all the router's interfaces, excluding virtual - links and those interfaces attaching to stub areas. */ + return (lsa_ack_flag); +} - if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)) /* Translated from 7 */ - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("Flood/AS: NSSA TRANSLATED LSA"); +int ospf_flood_through(struct ospf *ospf, struct ospf_neighbor *inbr, + struct ospf_lsa *lsa) +{ + int lsa_ack_flag = 0; - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - int continue_flag = 0; - struct listnode *if_node; - struct ospf_interface *oi; +/* Type-7 LSA's for NSSA are flooded throughout the AS here, and + upon return are updated in the LSDB for Type-7's. Later, + re-fresh will re-send them (and also, if ABR, packet code will + translate to Type-5's) - switch (area->external_routing) - { - /* Don't send AS externals into stub areas. Various types - of support for partial stub areas can be implemented - here. NSSA's will receive Type-7's that have areas - matching the originl LSA. */ - case OSPF_AREA_NSSA: /* Sending Type 5 or 7 into NSSA area */ - /* Type-7, flood NSSA area */ - if (lsa->data->type == OSPF_AS_NSSA_LSA - && area == lsa->area) - /* We will send it. */ - continue_flag = 0; - else - continue_flag = 1; /* Skip this NSSA area for Type-5's et al */ - break; - - case OSPF_AREA_TYPE_MAX: - case OSPF_AREA_STUB: - continue_flag = 1; /* Skip this area. */ - break; - - case OSPF_AREA_DEFAULT: + As usual, Type-5 LSA's (if not DISCARDED because we are STUB or + NSSA) are flooded throughout the AS, and are updated in the + global table. */ +#ifdef ORIGINAL_CODING + switch (lsa->data->type) { + case OSPF_ROUTER_LSA: + case OSPF_NETWORK_LSA: + case OSPF_SUMMARY_LSA: + case OSPF_ASBR_SUMMARY_LSA: + case OSPF_OPAQUE_LINK_LSA: /* ospf_flood_through_interface ? */ + case OSPF_OPAQUE_AREA_LSA: + lsa_ack_flag = + ospf_flood_through_area(inbr->oi->area, inbr, lsa); + break; + case OSPF_AS_EXTERNAL_LSA: /* Type-5 */ + case OSPF_OPAQUE_AS_LSA: + lsa_ack_flag = ospf_flood_through_as(ospf, inbr, lsa); + break; + /* Type-7 Only received within NSSA, then flooded */ + case OSPF_AS_NSSA_LSA: + /* Any P-bit was installed with the Type-7. */ + lsa_ack_flag = + ospf_flood_through_area(inbr->oi->area, inbr, lsa); + + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_flood_through: LOCAL NSSA FLOOD of Type-7."); + break; default: - /* No Type-7 into normal area */ - if (lsa->data->type == OSPF_AS_NSSA_LSA) - continue_flag = 1; /* skip Type-7 */ - else - continue_flag = 0; /* Do this area. */ - break; + break; } - - /* Do continue for above switch. Saves a big if then mess */ - if (continue_flag) - continue; /* main for-loop */ - - /* send to every interface in this area */ - - for (ALL_LIST_ELEMENTS_RO (area->oiflist, if_node, oi)) - { - /* Skip virtual links */ - if (oi->type != OSPF_IFTYPE_VIRTUALLINK) - if (ospf_flood_through_interface (oi, inbr, lsa)) /* lsa */ - lsa_ack_flag = 1; +#else /* ORIGINAL_CODING */ + /* + * At the common sub-sub-function "ospf_flood_through_interface()", + * a parameter "inbr" will be used to distinguish the called context + * whether the given LSA was received from the neighbor, or the + * flooding for the LSA starts from this node (e.g. the LSA was self- + * originated, or the LSA is going to be flushed from routing domain). + * + * So, for consistency reasons, this function "ospf_flood_through()" + * should also allow the usage that the given "inbr" parameter to be + * NULL. If we do so, corresponding AREA parameter should be referred + * by "lsa->area", instead of "inbr->oi->area". + */ + switch (lsa->data->type) { + case OSPF_AS_EXTERNAL_LSA: /* Type-5 */ + case OSPF_OPAQUE_AS_LSA: + lsa_ack_flag = ospf_flood_through_as(ospf, inbr, lsa); + break; + /* Type-7 Only received within NSSA, then flooded */ + case OSPF_AS_NSSA_LSA: + /* Any P-bit was installed with the Type-7. */ + + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_flood_through: LOCAL NSSA FLOOD of Type-7."); + /* Fallthrough */ + default: + lsa_ack_flag = ospf_flood_through_area(lsa->area, inbr, lsa); + break; } - } /* main area for-loop */ - - return (lsa_ack_flag); -} - -int -ospf_flood_through (struct ospf *ospf, - struct ospf_neighbor *inbr, struct ospf_lsa *lsa) -{ - int lsa_ack_flag = 0; - - /* Type-7 LSA's for NSSA are flooded throughout the AS here, and - upon return are updated in the LSDB for Type-7's. Later, - re-fresh will re-send them (and also, if ABR, packet code will - translate to Type-5's) - - As usual, Type-5 LSA's (if not DISCARDED because we are STUB or - NSSA) are flooded throughout the AS, and are updated in the - global table. */ -#ifdef ORIGINAL_CODING - switch (lsa->data->type) - { - case OSPF_ROUTER_LSA: - case OSPF_NETWORK_LSA: - case OSPF_SUMMARY_LSA: - case OSPF_ASBR_SUMMARY_LSA: - case OSPF_OPAQUE_LINK_LSA: /* ospf_flood_through_interface ? */ - case OSPF_OPAQUE_AREA_LSA: - lsa_ack_flag = ospf_flood_through_area (inbr->oi->area, inbr, lsa); - break; - case OSPF_AS_EXTERNAL_LSA: /* Type-5 */ - case OSPF_OPAQUE_AS_LSA: - lsa_ack_flag = ospf_flood_through_as (ospf, inbr, lsa); - break; - /* Type-7 Only received within NSSA, then flooded */ - case OSPF_AS_NSSA_LSA: - /* Any P-bit was installed with the Type-7. */ - lsa_ack_flag = ospf_flood_through_area (inbr->oi->area, inbr, lsa); - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_flood_through: LOCAL NSSA FLOOD of Type-7."); - break; - default: - break; - } -#else /* ORIGINAL_CODING */ - /* - * At the common sub-sub-function "ospf_flood_through_interface()", - * a parameter "inbr" will be used to distinguish the called context - * whether the given LSA was received from the neighbor, or the - * flooding for the LSA starts from this node (e.g. the LSA was self- - * originated, or the LSA is going to be flushed from routing domain). - * - * So, for consistency reasons, this function "ospf_flood_through()" - * should also allow the usage that the given "inbr" parameter to be - * NULL. If we do so, corresponding AREA parameter should be referred - * by "lsa->area", instead of "inbr->oi->area". - */ - switch (lsa->data->type) - { - case OSPF_AS_EXTERNAL_LSA: /* Type-5 */ - case OSPF_OPAQUE_AS_LSA: - lsa_ack_flag = ospf_flood_through_as (ospf, inbr, lsa); - break; - /* Type-7 Only received within NSSA, then flooded */ - case OSPF_AS_NSSA_LSA: - /* Any P-bit was installed with the Type-7. */ - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_flood_through: LOCAL NSSA FLOOD of Type-7."); - /* Fallthrough */ - default: - lsa_ack_flag = ospf_flood_through_area (lsa->area, inbr, lsa); - break; - } #endif /* ORIGINAL_CODING */ - - return (lsa_ack_flag); -} + return (lsa_ack_flag); +} /* Management functions for neighbor's Link State Request list. */ -void -ospf_ls_request_add (struct ospf_neighbor *nbr, struct ospf_lsa *lsa) +void ospf_ls_request_add(struct ospf_neighbor *nbr, struct ospf_lsa *lsa) { - /* - * We cannot make use of the newly introduced callback function - * "lsdb->new_lsa_hook" to replace debug output below, just because - * it seems no simple and smart way to pass neighbor information to - * the common function "ospf_lsdb_add()" -- endo. - */ - if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) - zlog_debug ("RqstL(%lu)++, NBR(%s), LSA[%s]", - ospf_ls_request_count (nbr), - inet_ntoa (nbr->router_id), dump_lsa_key (lsa)); - - ospf_lsdb_add (&nbr->ls_req, lsa); + /* + * We cannot make use of the newly introduced callback function + * "lsdb->new_lsa_hook" to replace debug output below, just because + * it seems no simple and smart way to pass neighbor information to + * the common function "ospf_lsdb_add()" -- endo. + */ + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) + zlog_debug("RqstL(%lu)++, NBR(%s), LSA[%s]", + ospf_ls_request_count(nbr), + inet_ntoa(nbr->router_id), dump_lsa_key(lsa)); + + ospf_lsdb_add(&nbr->ls_req, lsa); } -unsigned long -ospf_ls_request_count (struct ospf_neighbor *nbr) +unsigned long ospf_ls_request_count(struct ospf_neighbor *nbr) { - return ospf_lsdb_count_all (&nbr->ls_req); + return ospf_lsdb_count_all(&nbr->ls_req); } -int -ospf_ls_request_isempty (struct ospf_neighbor *nbr) +int ospf_ls_request_isempty(struct ospf_neighbor *nbr) { - return ospf_lsdb_isempty (&nbr->ls_req); + return ospf_lsdb_isempty(&nbr->ls_req); } /* Remove LSA from neighbor's ls-request list. */ -void -ospf_ls_request_delete (struct ospf_neighbor *nbr, struct ospf_lsa *lsa) +void ospf_ls_request_delete(struct ospf_neighbor *nbr, struct ospf_lsa *lsa) { - if (nbr->ls_req_last == lsa) - { - ospf_lsa_unlock (&nbr->ls_req_last); - nbr->ls_req_last = NULL; - } - - if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) /* -- endo. */ - zlog_debug ("RqstL(%lu)--, NBR(%s), LSA[%s]", - ospf_ls_request_count (nbr), - inet_ntoa (nbr->router_id), dump_lsa_key (lsa)); - - ospf_lsdb_delete (&nbr->ls_req, lsa); + if (nbr->ls_req_last == lsa) { + ospf_lsa_unlock(&nbr->ls_req_last); + nbr->ls_req_last = NULL; + } + + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) /* -- endo. */ + zlog_debug("RqstL(%lu)--, NBR(%s), LSA[%s]", + ospf_ls_request_count(nbr), + inet_ntoa(nbr->router_id), dump_lsa_key(lsa)); + + ospf_lsdb_delete(&nbr->ls_req, lsa); } /* Remove all LSA from neighbor's ls-requenst list. */ -void -ospf_ls_request_delete_all (struct ospf_neighbor *nbr) +void ospf_ls_request_delete_all(struct ospf_neighbor *nbr) { - ospf_lsa_unlock (&nbr->ls_req_last); - nbr->ls_req_last = NULL; - ospf_lsdb_delete_all (&nbr->ls_req); + ospf_lsa_unlock(&nbr->ls_req_last); + nbr->ls_req_last = NULL; + ospf_lsdb_delete_all(&nbr->ls_req); } /* Lookup LSA from neighbor's ls-request list. */ -struct ospf_lsa * -ospf_ls_request_lookup (struct ospf_neighbor *nbr, struct ospf_lsa *lsa) +struct ospf_lsa *ospf_ls_request_lookup(struct ospf_neighbor *nbr, + struct ospf_lsa *lsa) { - return ospf_lsdb_lookup (&nbr->ls_req, lsa); + return ospf_lsdb_lookup(&nbr->ls_req, lsa); } -struct ospf_lsa * -ospf_ls_request_new (struct lsa_header *lsah) +struct ospf_lsa *ospf_ls_request_new(struct lsa_header *lsah) { - struct ospf_lsa *new; + struct ospf_lsa *new; - new = ospf_lsa_new (); - new->data = ospf_lsa_data_new (OSPF_LSA_HEADER_SIZE); - memcpy (new->data, lsah, OSPF_LSA_HEADER_SIZE); + new = ospf_lsa_new(); + new->data = ospf_lsa_data_new(OSPF_LSA_HEADER_SIZE); + memcpy(new->data, lsah, OSPF_LSA_HEADER_SIZE); - return new; + return new; } /* Management functions for neighbor's ls-retransmit list. */ -unsigned long -ospf_ls_retransmit_count (struct ospf_neighbor *nbr) +unsigned long ospf_ls_retransmit_count(struct ospf_neighbor *nbr) { - return ospf_lsdb_count_all (&nbr->ls_rxmt); + return ospf_lsdb_count_all(&nbr->ls_rxmt); } -unsigned long -ospf_ls_retransmit_count_self (struct ospf_neighbor *nbr, int lsa_type) +unsigned long ospf_ls_retransmit_count_self(struct ospf_neighbor *nbr, + int lsa_type) { - return ospf_lsdb_count_self (&nbr->ls_rxmt, lsa_type); + return ospf_lsdb_count_self(&nbr->ls_rxmt, lsa_type); } -int -ospf_ls_retransmit_isempty (struct ospf_neighbor *nbr) +int ospf_ls_retransmit_isempty(struct ospf_neighbor *nbr) { - return ospf_lsdb_isempty (&nbr->ls_rxmt); + return ospf_lsdb_isempty(&nbr->ls_rxmt); } /* Add LSA to be retransmitted to neighbor's ls-retransmit list. */ -void -ospf_ls_retransmit_add (struct ospf_neighbor *nbr, struct ospf_lsa *lsa) +void ospf_ls_retransmit_add(struct ospf_neighbor *nbr, struct ospf_lsa *lsa) { - struct ospf_lsa *old; + struct ospf_lsa *old; - old = ospf_ls_retransmit_lookup (nbr, lsa); + old = ospf_ls_retransmit_lookup(nbr, lsa); - if (ospf_lsa_more_recent (old, lsa) < 0) - { - if (old) - { - old->retransmit_counter--; - ospf_lsdb_delete (&nbr->ls_rxmt, old); + if (ospf_lsa_more_recent(old, lsa) < 0) { + if (old) { + old->retransmit_counter--; + ospf_lsdb_delete(&nbr->ls_rxmt, old); + } + lsa->retransmit_counter++; + /* + * We cannot make use of the newly introduced callback function + * "lsdb->new_lsa_hook" to replace debug output below, just + * because + * it seems no simple and smart way to pass neighbor information + * to + * the common function "ospf_lsdb_add()" -- endo. + */ + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) + zlog_debug("RXmtL(%lu)++, NBR(%s), LSA[%s]", + ospf_ls_retransmit_count(nbr), + inet_ntoa(nbr->router_id), + dump_lsa_key(lsa)); + ospf_lsdb_add(&nbr->ls_rxmt, lsa); } - lsa->retransmit_counter++; - /* - * We cannot make use of the newly introduced callback function - * "lsdb->new_lsa_hook" to replace debug output below, just because - * it seems no simple and smart way to pass neighbor information to - * the common function "ospf_lsdb_add()" -- endo. - */ - if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) - zlog_debug ("RXmtL(%lu)++, NBR(%s), LSA[%s]", - ospf_ls_retransmit_count (nbr), - inet_ntoa (nbr->router_id), dump_lsa_key (lsa)); - ospf_lsdb_add (&nbr->ls_rxmt, lsa); - } } /* Remove LSA from neibghbor's ls-retransmit list. */ -void -ospf_ls_retransmit_delete (struct ospf_neighbor *nbr, struct ospf_lsa *lsa) +void ospf_ls_retransmit_delete(struct ospf_neighbor *nbr, struct ospf_lsa *lsa) { - if (ospf_ls_retransmit_lookup (nbr, lsa)) - { - lsa->retransmit_counter--; - if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) /* -- endo. */ - zlog_debug ("RXmtL(%lu)--, NBR(%s), LSA[%s]", - ospf_ls_retransmit_count (nbr), - inet_ntoa (nbr->router_id), dump_lsa_key (lsa)); - ospf_lsdb_delete (&nbr->ls_rxmt, lsa); - } + if (ospf_ls_retransmit_lookup(nbr, lsa)) { + lsa->retransmit_counter--; + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) /* -- endo. */ + zlog_debug("RXmtL(%lu)--, NBR(%s), LSA[%s]", + ospf_ls_retransmit_count(nbr), + inet_ntoa(nbr->router_id), + dump_lsa_key(lsa)); + ospf_lsdb_delete(&nbr->ls_rxmt, lsa); + } } /* Clear neighbor's ls-retransmit list. */ -void -ospf_ls_retransmit_clear (struct ospf_neighbor *nbr) +void ospf_ls_retransmit_clear(struct ospf_neighbor *nbr) { - struct ospf_lsdb *lsdb; - int i; + struct ospf_lsdb *lsdb; + int i; - lsdb = &nbr->ls_rxmt; + lsdb = &nbr->ls_rxmt; - for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++) - { - struct route_table *table = lsdb->type[i].db; - struct route_node *rn; - struct ospf_lsa *lsa; + for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++) { + struct route_table *table = lsdb->type[i].db; + struct route_node *rn; + struct ospf_lsa *lsa; - for (rn = route_top (table); rn; rn = route_next (rn)) - if ((lsa = rn->info) != NULL) - ospf_ls_retransmit_delete (nbr, lsa); - } + for (rn = route_top(table); rn; rn = route_next(rn)) + if ((lsa = rn->info) != NULL) + ospf_ls_retransmit_delete(nbr, lsa); + } - ospf_lsa_unlock (&nbr->ls_req_last); - nbr->ls_req_last = NULL; + ospf_lsa_unlock(&nbr->ls_req_last); + nbr->ls_req_last = NULL; } /* Lookup LSA from neighbor's ls-retransmit list. */ -struct ospf_lsa * -ospf_ls_retransmit_lookup (struct ospf_neighbor *nbr, struct ospf_lsa *lsa) +struct ospf_lsa *ospf_ls_retransmit_lookup(struct ospf_neighbor *nbr, + struct ospf_lsa *lsa) { - return ospf_lsdb_lookup (&nbr->ls_rxmt, lsa); + return ospf_lsdb_lookup(&nbr->ls_rxmt, lsa); } -static void -ospf_ls_retransmit_delete_nbr_if (struct ospf_interface *oi, - struct ospf_lsa *lsa) +static void ospf_ls_retransmit_delete_nbr_if(struct ospf_interface *oi, + struct ospf_lsa *lsa) { - struct route_node *rn; - struct ospf_neighbor *nbr; - struct ospf_lsa *lsr; - - if (ospf_if_is_enable (oi)) - for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) - /* If LSA find in LS-retransmit list, then remove it. */ - if ((nbr = rn->info) != NULL) - { - lsr = ospf_ls_retransmit_lookup (nbr, lsa); - - /* If LSA find in ls-retransmit list, remove it. */ - if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum) - ospf_ls_retransmit_delete (nbr, lsr); - } + struct route_node *rn; + struct ospf_neighbor *nbr; + struct ospf_lsa *lsr; + + if (ospf_if_is_enable(oi)) + for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) + /* If LSA find in LS-retransmit list, then remove it. */ + if ((nbr = rn->info) != NULL) { + lsr = ospf_ls_retransmit_lookup(nbr, lsa); + + /* If LSA find in ls-retransmit list, remove it. + */ + if (lsr != NULL + && lsr->data->ls_seqnum + == lsa->data->ls_seqnum) + ospf_ls_retransmit_delete(nbr, lsr); + } } -void -ospf_ls_retransmit_delete_nbr_area (struct ospf_area *area, - struct ospf_lsa *lsa) +void ospf_ls_retransmit_delete_nbr_area(struct ospf_area *area, + struct ospf_lsa *lsa) { - struct listnode *node, *nnode; - struct ospf_interface *oi; + struct listnode *node, *nnode; + struct ospf_interface *oi; - for (ALL_LIST_ELEMENTS (area->oiflist, node, nnode, oi)) - ospf_ls_retransmit_delete_nbr_if (oi, lsa); + for (ALL_LIST_ELEMENTS(area->oiflist, node, nnode, oi)) + ospf_ls_retransmit_delete_nbr_if(oi, lsa); } -void -ospf_ls_retransmit_delete_nbr_as (struct ospf *ospf, struct ospf_lsa *lsa) +void ospf_ls_retransmit_delete_nbr_as(struct ospf *ospf, struct ospf_lsa *lsa) { - struct listnode *node, *nnode; - struct ospf_interface *oi; + struct listnode *node, *nnode; + struct ospf_interface *oi; - for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) - ospf_ls_retransmit_delete_nbr_if (oi, lsa); + for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) + ospf_ls_retransmit_delete_nbr_if(oi, lsa); } -/* Sets ls_age to MaxAge and floods throu the area. +/* Sets ls_age to MaxAge and floods throu the area. When we implement ASE routing, there will be anothe function flushing an LSA from the whole domain. */ -void -ospf_lsa_flush_area (struct ospf_lsa *lsa, struct ospf_area *area) +void ospf_lsa_flush_area(struct ospf_lsa *lsa, struct ospf_area *area) { - /* Reset the lsa origination time such that it gives - more time for the ACK to be received and avoid - retransmissions */ - lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); - monotime(&lsa->tv_recv); - lsa->tv_orig = lsa->tv_recv; - ospf_flood_through_area (area, NULL, lsa); - ospf_lsa_maxage (area->ospf, lsa); + /* Reset the lsa origination time such that it gives + more time for the ACK to be received and avoid + retransmissions */ + lsa->data->ls_age = htons(OSPF_LSA_MAXAGE); + monotime(&lsa->tv_recv); + lsa->tv_orig = lsa->tv_recv; + ospf_flood_through_area(area, NULL, lsa); + ospf_lsa_maxage(area->ospf, lsa); } -void -ospf_lsa_flush_as (struct ospf *ospf, struct ospf_lsa *lsa) +void ospf_lsa_flush_as(struct ospf *ospf, struct ospf_lsa *lsa) { - /* Reset the lsa origination time such that it gives - more time for the ACK to be received and avoid - retransmissions */ - lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); - monotime(&lsa->tv_recv); - lsa->tv_orig = lsa->tv_recv; - ospf_flood_through_as (ospf, NULL, lsa); - ospf_lsa_maxage (ospf, lsa); + /* Reset the lsa origination time such that it gives + more time for the ACK to be received and avoid + retransmissions */ + lsa->data->ls_age = htons(OSPF_LSA_MAXAGE); + monotime(&lsa->tv_recv); + lsa->tv_orig = lsa->tv_recv; + ospf_flood_through_as(ospf, NULL, lsa); + ospf_lsa_maxage(ospf, lsa); } -void -ospf_lsa_flush (struct ospf *ospf, struct ospf_lsa *lsa) +void ospf_lsa_flush(struct ospf *ospf, struct ospf_lsa *lsa) { - lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); - - switch (lsa->data->type) - { - case OSPF_ROUTER_LSA: - case OSPF_NETWORK_LSA: - case OSPF_SUMMARY_LSA: - case OSPF_ASBR_SUMMARY_LSA: - case OSPF_AS_NSSA_LSA: - case OSPF_OPAQUE_LINK_LSA: - case OSPF_OPAQUE_AREA_LSA: - ospf_lsa_flush_area (lsa, lsa->area); - break; - case OSPF_AS_EXTERNAL_LSA: - case OSPF_OPAQUE_AS_LSA: - ospf_lsa_flush_as (ospf, lsa); - break; - default: - zlog_info ("%s: Unknown LSA type %u", __func__, lsa->data->type); - break; - } + lsa->data->ls_age = htons(OSPF_LSA_MAXAGE); + + switch (lsa->data->type) { + case OSPF_ROUTER_LSA: + case OSPF_NETWORK_LSA: + case OSPF_SUMMARY_LSA: + case OSPF_ASBR_SUMMARY_LSA: + case OSPF_AS_NSSA_LSA: + case OSPF_OPAQUE_LINK_LSA: + case OSPF_OPAQUE_AREA_LSA: + ospf_lsa_flush_area(lsa, lsa->area); + break; + case OSPF_AS_EXTERNAL_LSA: + case OSPF_OPAQUE_AS_LSA: + ospf_lsa_flush_as(ospf, lsa); + break; + default: + zlog_info("%s: Unknown LSA type %u", __func__, lsa->data->type); + break; + } } diff --git a/ospfd/ospf_flood.h b/ospfd/ospf_flood.h index b08385754..b74894567 100644 --- a/ospfd/ospf_flood.h +++ b/ospfd/ospf_flood.h @@ -22,52 +22,47 @@ #ifndef _ZEBRA_OSPF_FLOOD_H #define _ZEBRA_OSPF_FLOOD_H -extern int ospf_flood (struct ospf *, struct ospf_neighbor *, - struct ospf_lsa *, struct ospf_lsa *); -extern int ospf_flood_through (struct ospf *, struct ospf_neighbor *, - struct ospf_lsa *); -extern int ospf_flood_through_area (struct ospf_area *, - struct ospf_neighbor *, - struct ospf_lsa *); -extern int ospf_flood_through_as (struct ospf *, struct ospf_neighbor *, - struct ospf_lsa *); +extern int ospf_flood(struct ospf *, struct ospf_neighbor *, struct ospf_lsa *, + struct ospf_lsa *); +extern int ospf_flood_through(struct ospf *, struct ospf_neighbor *, + struct ospf_lsa *); +extern int ospf_flood_through_area(struct ospf_area *, struct ospf_neighbor *, + struct ospf_lsa *); +extern int ospf_flood_through_as(struct ospf *, struct ospf_neighbor *, + struct ospf_lsa *); -extern unsigned long ospf_ls_request_count (struct ospf_neighbor *); -extern int ospf_ls_request_isempty (struct ospf_neighbor *); -extern struct ospf_lsa *ospf_ls_request_new (struct lsa_header *); -extern void ospf_ls_request_free (struct ospf_lsa *); -extern void ospf_ls_request_add (struct ospf_neighbor *, struct ospf_lsa *); -extern void ospf_ls_request_delete (struct ospf_neighbor *, - struct ospf_lsa *); -extern void ospf_ls_request_delete_all (struct ospf_neighbor *); -extern struct ospf_lsa *ospf_ls_request_lookup (struct ospf_neighbor *, - struct ospf_lsa *); +extern unsigned long ospf_ls_request_count(struct ospf_neighbor *); +extern int ospf_ls_request_isempty(struct ospf_neighbor *); +extern struct ospf_lsa *ospf_ls_request_new(struct lsa_header *); +extern void ospf_ls_request_free(struct ospf_lsa *); +extern void ospf_ls_request_add(struct ospf_neighbor *, struct ospf_lsa *); +extern void ospf_ls_request_delete(struct ospf_neighbor *, struct ospf_lsa *); +extern void ospf_ls_request_delete_all(struct ospf_neighbor *); +extern struct ospf_lsa *ospf_ls_request_lookup(struct ospf_neighbor *, + struct ospf_lsa *); -extern unsigned long ospf_ls_retransmit_count (struct ospf_neighbor *); -extern unsigned long ospf_ls_retransmit_count_self (struct ospf_neighbor *, - int); -extern int ospf_ls_retransmit_isempty (struct ospf_neighbor *); -extern void ospf_ls_retransmit_add (struct ospf_neighbor *, - struct ospf_lsa *); -extern void ospf_ls_retransmit_delete (struct ospf_neighbor *, - struct ospf_lsa *); -extern void ospf_ls_retransmit_clear (struct ospf_neighbor *); -extern struct ospf_lsa *ospf_ls_retransmit_lookup (struct ospf_neighbor *, - struct ospf_lsa *); -extern void ospf_ls_retransmit_delete_nbr_area (struct ospf_area *, - struct ospf_lsa *); -extern void ospf_ls_retransmit_delete_nbr_as (struct ospf *, - struct ospf_lsa *); -extern void ospf_ls_retransmit_add_nbr_all (struct ospf_interface *, - struct ospf_lsa *); +extern unsigned long ospf_ls_retransmit_count(struct ospf_neighbor *); +extern unsigned long ospf_ls_retransmit_count_self(struct ospf_neighbor *, int); +extern int ospf_ls_retransmit_isempty(struct ospf_neighbor *); +extern void ospf_ls_retransmit_add(struct ospf_neighbor *, struct ospf_lsa *); +extern void ospf_ls_retransmit_delete(struct ospf_neighbor *, + struct ospf_lsa *); +extern void ospf_ls_retransmit_clear(struct ospf_neighbor *); +extern struct ospf_lsa *ospf_ls_retransmit_lookup(struct ospf_neighbor *, + struct ospf_lsa *); +extern void ospf_ls_retransmit_delete_nbr_area(struct ospf_area *, + struct ospf_lsa *); +extern void ospf_ls_retransmit_delete_nbr_as(struct ospf *, struct ospf_lsa *); +extern void ospf_ls_retransmit_add_nbr_all(struct ospf_interface *, + struct ospf_lsa *); -extern void ospf_flood_lsa_area (struct ospf_lsa *, struct ospf_area *); -extern void ospf_flood_lsa_as (struct ospf_lsa *); -extern void ospf_lsa_flush_area (struct ospf_lsa *, struct ospf_area *); -extern void ospf_lsa_flush_as (struct ospf *, struct ospf_lsa *); -extern void ospf_lsa_flush (struct ospf *, struct ospf_lsa *); -extern struct external_info *ospf_external_info_check (struct ospf_lsa *); +extern void ospf_flood_lsa_area(struct ospf_lsa *, struct ospf_area *); +extern void ospf_flood_lsa_as(struct ospf_lsa *); +extern void ospf_lsa_flush_area(struct ospf_lsa *, struct ospf_area *); +extern void ospf_lsa_flush_as(struct ospf *, struct ospf_lsa *); +extern void ospf_lsa_flush(struct ospf *, struct ospf_lsa *); +extern struct external_info *ospf_external_info_check(struct ospf_lsa *); -extern void ospf_lsdb_init (struct ospf_lsdb *); +extern void ospf_lsdb_init(struct ospf_lsdb *); #endif /* _ZEBRA_OSPF_FLOOD_H */ diff --git a/ospfd/ospf_ia.c b/ospfd/ospf_ia.c index ebd267ded..c65d8b874 100644 --- a/ospfd/ospf_ia.c +++ b/ospfd/ospf_ia.c @@ -45,670 +45,662 @@ #include "ospfd/ospf_ia.h" #include "ospfd/ospf_dump.h" -static struct ospf_route * -ospf_find_abr_route (struct route_table *rtrs, - struct prefix_ipv4 *abr, - struct ospf_area *area) +static struct ospf_route *ospf_find_abr_route(struct route_table *rtrs, + struct prefix_ipv4 *abr, + struct ospf_area *area) { - struct route_node *rn; - struct ospf_route *or; - struct listnode *node; + struct route_node *rn; + struct ospf_route * or ; + struct listnode *node; - if ((rn = route_node_lookup (rtrs, (struct prefix *) abr)) == NULL) - return NULL; + if ((rn = route_node_lookup(rtrs, (struct prefix *)abr)) == NULL) + return NULL; - route_unlock_node (rn); + route_unlock_node(rn); - for (ALL_LIST_ELEMENTS_RO ((struct list *) rn->info, node, or)) - if (IPV4_ADDR_SAME (&or->u.std.area_id, &area->area_id) - && (or->u.std.flags & ROUTER_LSA_BORDER)) - return or; + for (ALL_LIST_ELEMENTS_RO((struct list *)rn->info, node, or)) + if (IPV4_ADDR_SAME(& or->u.std.area_id, &area->area_id) + && (or->u.std.flags & ROUTER_LSA_BORDER)) + return or ; - return NULL; + return NULL; } -static void -ospf_ia_network_route (struct ospf *ospf, struct route_table *rt, - struct prefix_ipv4 *p, struct ospf_route *new_or, - struct ospf_route *abr_or) +static void ospf_ia_network_route(struct ospf *ospf, struct route_table *rt, + struct prefix_ipv4 *p, + struct ospf_route *new_or, + struct ospf_route *abr_or) { - struct route_node *rn1; - struct ospf_route *or; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_ia_network_route(): processing summary route to %s/%d", - inet_ntoa (p->prefix), p->prefixlen); - - /* Find a route to the same dest */ - if ((rn1 = route_node_lookup (rt, (struct prefix *) p))) - { - int res; - - route_unlock_node (rn1); - - if ((or = rn1->info)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_ia_network_route(): " - "Found a route to the same network"); - /* Check the existing route. */ - if ((res = ospf_route_cmp (ospf, new_or, or)) < 0) - { - /* New route is better, so replace old one. */ - ospf_route_subst (rn1, new_or, abr_or); - } - else if (res == 0) - { - /* New and old route are equal, so next hops can be added. */ - route_lock_node (rn1); - ospf_route_copy_nexthops (or, abr_or->paths); - route_unlock_node (rn1); - - /* new route can be deleted, because existing route has been updated. */ - ospf_route_free (new_or); - } - else - { - /* New route is worse, so free it. */ - ospf_route_free (new_or); - return; - } - } /* if (or)*/ - } /*if (rn1)*/ - else - { /* no route */ - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_ia_network_route(): add new route to %s/%d", - inet_ntoa (p->prefix), p->prefixlen); - ospf_route_add (rt, p, new_or, abr_or); - } + struct route_node *rn1; + struct ospf_route * or ; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_ia_network_route(): processing summary route to %s/%d", + inet_ntoa(p->prefix), p->prefixlen); + + /* Find a route to the same dest */ + if ((rn1 = route_node_lookup(rt, (struct prefix *)p))) { + int res; + + route_unlock_node(rn1); + + if ((or = rn1->info)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_ia_network_route(): " + "Found a route to the same network"); + /* Check the existing route. */ + if ((res = ospf_route_cmp(ospf, new_or, or)) < 0) { + /* New route is better, so replace old one. */ + ospf_route_subst(rn1, new_or, abr_or); + } else if (res == 0) { + /* New and old route are equal, so next hops can + * be added. */ + route_lock_node(rn1); + ospf_route_copy_nexthops(or, abr_or->paths); + route_unlock_node(rn1); + + /* new route can be deleted, because existing + * route has been updated. */ + ospf_route_free(new_or); + } else { + /* New route is worse, so free it. */ + ospf_route_free(new_or); + return; + } + } /* if (or)*/ + } /*if (rn1)*/ + else { /* no route */ + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_ia_network_route(): add new route to %s/%d", + inet_ntoa(p->prefix), p->prefixlen); + ospf_route_add(rt, p, new_or, abr_or); + } } -static void -ospf_ia_router_route (struct ospf *ospf, struct route_table *rtrs, - struct prefix_ipv4 *p, - struct ospf_route *new_or, struct ospf_route *abr_or) +static void ospf_ia_router_route(struct ospf *ospf, struct route_table *rtrs, + struct prefix_ipv4 *p, + struct ospf_route *new_or, + struct ospf_route *abr_or) { - struct ospf_route *or = NULL; - struct route_node *rn; - int ret; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_ia_router_route(): considering %s/%d", - inet_ntoa (p->prefix), p->prefixlen); - /* Find a route to the same dest */ - rn = route_node_get (rtrs, (struct prefix *) p); - - if (rn->info == NULL) - /* This is a new route */ - rn->info = list_new (); - else - { - struct ospf_area *or_area; - or_area = ospf_area_lookup_by_area_id (ospf, new_or->u.std.area_id); - assert (or_area); - /* This is an additional route */ - route_unlock_node (rn); - or = ospf_find_asbr_route_through_area (rtrs, p, or_area); - } - - if (or) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_ia_router_route(): " - "a route to the same ABR through the same area exists"); - /* New route is better */ - if ((ret = ospf_route_cmp (ospf, new_or, or)) < 0) - { - listnode_delete (rn->info, or); - ospf_route_free (or); - /* proceed down */ + struct ospf_route * or = NULL; + struct route_node *rn; + int ret; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_ia_router_route(): considering %s/%d", + inet_ntoa(p->prefix), p->prefixlen); + /* Find a route to the same dest */ + rn = route_node_get(rtrs, (struct prefix *)p); + + if (rn->info == NULL) + /* This is a new route */ + rn->info = list_new(); + else { + struct ospf_area *or_area; + or_area = ospf_area_lookup_by_area_id(ospf, + new_or->u.std.area_id); + assert(or_area); + /* This is an additional route */ + route_unlock_node(rn); + or = ospf_find_asbr_route_through_area(rtrs, p, or_area); } - /* Routes are the same */ - else if (ret == 0) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_ia_router_route(): merging the new route"); - ospf_route_copy_nexthops (or, abr_or->paths); - ospf_route_free (new_or); - return; - } - /* New route is worse */ - else - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_ia_router_route(): skipping the new route"); - ospf_route_free (new_or); - return; + if (or) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_ia_router_route(): " + "a route to the same ABR through the same area exists"); + /* New route is better */ + if ((ret = ospf_route_cmp(ospf, new_or, or)) < 0) { + listnode_delete(rn->info, or); + ospf_route_free(or); + /* proceed down */ + } + /* Routes are the same */ + else if (ret == 0) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_ia_router_route(): merging the new route"); + + ospf_route_copy_nexthops(or, abr_or->paths); + ospf_route_free(new_or); + return; + } + /* New route is worse */ + else { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_ia_router_route(): skipping the new route"); + ospf_route_free(new_or); + return; + } } - } - ospf_route_copy_nexthops (new_or, abr_or->paths); + ospf_route_copy_nexthops(new_or, abr_or->paths); - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_ia_router_route(): adding the new route"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_ia_router_route(): adding the new route"); - listnode_add (rn->info, new_or); + listnode_add(rn->info, new_or); } -static int -process_summary_lsa (struct ospf_area *area, struct route_table *rt, - struct route_table *rtrs, struct ospf_lsa *lsa) +static int process_summary_lsa(struct ospf_area *area, struct route_table *rt, + struct route_table *rtrs, struct ospf_lsa *lsa) { - struct ospf *ospf = area->ospf; - struct ospf_area_range *range; - struct ospf_route *abr_or, *new_or; - struct summary_lsa *sl; - struct prefix_ipv4 p, abr; - u_int32_t metric; - - if (lsa == NULL) - return 0; - - sl = (struct summary_lsa *) lsa->data; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("process_summary_lsa(): LS ID: %s", inet_ntoa (sl->header.id)); - - metric = GET_METRIC (sl->metric); - - if (metric == OSPF_LS_INFINITY) - return 0; - - if (IS_LSA_MAXAGE (lsa)) - return 0; - - if (ospf_lsa_is_self_originated (area->ospf, lsa)) - return 0; - - p.family = AF_INET; - p.prefix = sl->header.id; - - if (sl->header.type == OSPF_SUMMARY_LSA) - p.prefixlen = ip_masklen (sl->mask); - else - p.prefixlen = IPV4_MAX_BITLEN; - - apply_mask_ipv4 (&p); - - if (sl->header.type == OSPF_SUMMARY_LSA && - (range = ospf_area_range_match_any (ospf, &p)) && - ospf_area_range_active (range)) - return 0; - - /* XXX: This check seems dubious to me. If an ABR has already decided - * to consider summaries received in this area, then why would one wish - * to exclude default? - */ - if (IS_OSPF_ABR(ospf) && - ospf->abr_type != OSPF_ABR_STAND && - area->external_routing != OSPF_AREA_DEFAULT && - p.prefix.s_addr == OSPF_DEFAULT_DESTINATION && - p.prefixlen == 0) - return 0; /* Ignore summary default from a stub area */ - - abr.family = AF_INET; - abr.prefix = sl->header.adv_router; - abr.prefixlen = IPV4_MAX_BITLEN; - apply_mask_ipv4 (&abr); - - abr_or = ospf_find_abr_route (rtrs, &abr, area); - - if (abr_or == NULL) - return 0; - - new_or = ospf_route_new (); - new_or->type = OSPF_DESTINATION_NETWORK; - new_or->id = sl->header.id; - new_or->mask = sl->mask; - new_or->u.std.options = sl->header.options; - new_or->u.std.origin = (struct lsa_header *) sl; - new_or->cost = abr_or->cost + metric; - new_or->u.std.area_id = area->area_id; - new_or->u.std.external_routing = area->external_routing; - new_or->path_type = OSPF_PATH_INTER_AREA; - - if (sl->header.type == OSPF_SUMMARY_LSA) - ospf_ia_network_route (ospf, rt, &p, new_or, abr_or); - else - { - new_or->type = OSPF_DESTINATION_ROUTER; - new_or->u.std.flags = ROUTER_LSA_EXTERNAL; - ospf_ia_router_route (ospf, rtrs, &p, new_or, abr_or); - } - - return 0; + struct ospf *ospf = area->ospf; + struct ospf_area_range *range; + struct ospf_route *abr_or, *new_or; + struct summary_lsa *sl; + struct prefix_ipv4 p, abr; + u_int32_t metric; + + if (lsa == NULL) + return 0; + + sl = (struct summary_lsa *)lsa->data; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("process_summary_lsa(): LS ID: %s", + inet_ntoa(sl->header.id)); + + metric = GET_METRIC(sl->metric); + + if (metric == OSPF_LS_INFINITY) + return 0; + + if (IS_LSA_MAXAGE(lsa)) + return 0; + + if (ospf_lsa_is_self_originated(area->ospf, lsa)) + return 0; + + p.family = AF_INET; + p.prefix = sl->header.id; + + if (sl->header.type == OSPF_SUMMARY_LSA) + p.prefixlen = ip_masklen(sl->mask); + else + p.prefixlen = IPV4_MAX_BITLEN; + + apply_mask_ipv4(&p); + + if (sl->header.type == OSPF_SUMMARY_LSA + && (range = ospf_area_range_match_any(ospf, &p)) + && ospf_area_range_active(range)) + return 0; + + /* XXX: This check seems dubious to me. If an ABR has already decided + * to consider summaries received in this area, then why would one wish + * to exclude default? + */ + if (IS_OSPF_ABR(ospf) && ospf->abr_type != OSPF_ABR_STAND + && area->external_routing != OSPF_AREA_DEFAULT + && p.prefix.s_addr == OSPF_DEFAULT_DESTINATION && p.prefixlen == 0) + return 0; /* Ignore summary default from a stub area */ + + abr.family = AF_INET; + abr.prefix = sl->header.adv_router; + abr.prefixlen = IPV4_MAX_BITLEN; + apply_mask_ipv4(&abr); + + abr_or = ospf_find_abr_route(rtrs, &abr, area); + + if (abr_or == NULL) + return 0; + + new_or = ospf_route_new(); + new_or->type = OSPF_DESTINATION_NETWORK; + new_or->id = sl->header.id; + new_or->mask = sl->mask; + new_or->u.std.options = sl->header.options; + new_or->u.std.origin = (struct lsa_header *)sl; + new_or->cost = abr_or->cost + metric; + new_or->u.std.area_id = area->area_id; + new_or->u.std.external_routing = area->external_routing; + new_or->path_type = OSPF_PATH_INTER_AREA; + + if (sl->header.type == OSPF_SUMMARY_LSA) + ospf_ia_network_route(ospf, rt, &p, new_or, abr_or); + else { + new_or->type = OSPF_DESTINATION_ROUTER; + new_or->u.std.flags = ROUTER_LSA_EXTERNAL; + ospf_ia_router_route(ospf, rtrs, &p, new_or, abr_or); + } + + return 0; } -static void -ospf_examine_summaries (struct ospf_area *area, - struct route_table *lsdb_rt, - struct route_table *rt, - struct route_table *rtrs) +static void ospf_examine_summaries(struct ospf_area *area, + struct route_table *lsdb_rt, + struct route_table *rt, + struct route_table *rtrs) { - struct ospf_lsa *lsa; - struct route_node *rn; + struct ospf_lsa *lsa; + struct route_node *rn; - LSDB_LOOP (lsdb_rt, rn, lsa) - process_summary_lsa (area, rt, rtrs, lsa); + LSDB_LOOP(lsdb_rt, rn, lsa) + process_summary_lsa(area, rt, rtrs, lsa); } -int -ospf_area_is_transit (struct ospf_area *area) +int ospf_area_is_transit(struct ospf_area *area) { - return (area->transit == OSPF_TRANSIT_TRUE) || - ospf_full_virtual_nbrs(area); /* Cisco forgets to set the V-bit :( */ + return (area->transit == OSPF_TRANSIT_TRUE) + || ospf_full_virtual_nbrs( + area); /* Cisco forgets to set the V-bit :( */ } -static void -ospf_update_network_route (struct ospf *ospf, - struct route_table *rt, - struct route_table *rtrs, - struct summary_lsa *lsa, - struct prefix_ipv4 *p, - struct ospf_area *area) +static void ospf_update_network_route(struct ospf *ospf, struct route_table *rt, + struct route_table *rtrs, + struct summary_lsa *lsa, + struct prefix_ipv4 *p, + struct ospf_area *area) { - struct route_node *rn; - struct ospf_route *or, *abr_or, *new_or; - struct prefix_ipv4 abr; - u_int32_t cost; - - abr.family = AF_INET; - abr.prefix =lsa->header.adv_router; - abr.prefixlen = IPV4_MAX_BITLEN; - apply_mask_ipv4 (&abr); - - abr_or = ospf_find_abr_route (rtrs, &abr, area); - - if (abr_or == NULL) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_update_network_route(): can't find a route to the ABR"); - return; - } - - cost = abr_or->cost + GET_METRIC (lsa->metric); - - rn = route_node_lookup (rt, (struct prefix *) p); - - if (! rn) - { - if (ospf->abr_type != OSPF_ABR_SHORTCUT) - return; /* Standard ABR can update only already installed - backbone paths */ - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_update_network_route(): " - "Allowing Shortcut ABR to add new route"); - new_or = ospf_route_new (); - new_or->type = OSPF_DESTINATION_NETWORK; - new_or->id = lsa->header.id; - new_or->mask = lsa->mask; - new_or->u.std.options = lsa->header.options; - new_or->u.std.origin = (struct lsa_header *) lsa; - new_or->cost = cost; - new_or->u.std.area_id = area->area_id; - new_or->u.std.external_routing = area->external_routing; - new_or->path_type = OSPF_PATH_INTER_AREA; - ospf_route_add (rt, p, new_or, abr_or); - - return; - } - else - { - route_unlock_node (rn); - if (rn->info == NULL) - return; - } - - or = rn->info; - - if (or->path_type != OSPF_PATH_INTRA_AREA && - or->path_type != OSPF_PATH_INTER_AREA) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_update_network_route(): ERR: path type is wrong"); - return; - } - - if (ospf->abr_type == OSPF_ABR_SHORTCUT) - { - if (or->path_type == OSPF_PATH_INTRA_AREA && - !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_update_network_route(): Shortcut: " - "this intra-area path is not backbone"); - return; + struct route_node *rn; + struct ospf_route * or, *abr_or, *new_or; + struct prefix_ipv4 abr; + u_int32_t cost; + + abr.family = AF_INET; + abr.prefix = lsa->header.adv_router; + abr.prefixlen = IPV4_MAX_BITLEN; + apply_mask_ipv4(&abr); + + abr_or = ospf_find_abr_route(rtrs, &abr, area); + + if (abr_or == NULL) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_update_network_route(): can't find a route to the ABR"); + return; } - } - else /* Not Shortcut ABR */ - { - if (!OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_update_network_route(): " - "route is not BB-associated"); - return; /* We can update only BB routes */ + + cost = abr_or->cost + GET_METRIC(lsa->metric); + + rn = route_node_lookup(rt, (struct prefix *)p); + + if (!rn) { + if (ospf->abr_type != OSPF_ABR_SHORTCUT) + return; /* Standard ABR can update only already + installed + backbone paths */ + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_update_network_route(): " + "Allowing Shortcut ABR to add new route"); + new_or = ospf_route_new(); + new_or->type = OSPF_DESTINATION_NETWORK; + new_or->id = lsa->header.id; + new_or->mask = lsa->mask; + new_or->u.std.options = lsa->header.options; + new_or->u.std.origin = (struct lsa_header *)lsa; + new_or->cost = cost; + new_or->u.std.area_id = area->area_id; + new_or->u.std.external_routing = area->external_routing; + new_or->path_type = OSPF_PATH_INTER_AREA; + ospf_route_add(rt, p, new_or, abr_or); + + return; + } else { + route_unlock_node(rn); + if (rn->info == NULL) + return; } - } - - if (or->cost < cost) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_update_network_route(): new route is worse"); - return; - } - - if (or->cost == cost) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_update_network_route(): " - "new route is same distance, adding nexthops"); - ospf_route_copy_nexthops (or, abr_or->paths); - } - - if (or->cost > cost) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_update_network_route(): " - "new route is better, overriding nexthops"); - ospf_route_subst_nexthops (or, abr_or->paths); - or->cost = cost; - - if ((ospf->abr_type == OSPF_ABR_SHORTCUT) && - !OSPF_IS_AREA_ID_BACKBONE (or->u.std.area_id)) - { - or->path_type = OSPF_PATH_INTER_AREA; - or->u.std.area_id = area->area_id; - or->u.std.external_routing = area->external_routing; - /* Note that we can do this only in Shortcut ABR mode, - because standard ABR must leave the route type and area - unchanged - */ - } - } -} -static void -ospf_update_router_route (struct ospf *ospf, - struct route_table *rtrs, - struct summary_lsa *lsa, - struct prefix_ipv4 *p, - struct ospf_area *area) -{ - struct ospf_route *or, *abr_or, *new_or; - struct prefix_ipv4 abr; - u_int32_t cost; - - abr.family = AF_INET; - abr.prefix = lsa->header.adv_router; - abr.prefixlen = IPV4_MAX_BITLEN; - apply_mask_ipv4 (&abr); - - abr_or = ospf_find_abr_route (rtrs, &abr, area); - - if (abr_or == NULL) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_update_router_route(): can't find a route to the ABR"); - return; - } - - cost = abr_or->cost + GET_METRIC (lsa->metric); - - /* First try to find a backbone path, - because standard ABR can update only BB-associated paths */ - - if ((ospf->backbone == NULL) && - (ospf->abr_type != OSPF_ABR_SHORTCUT)) - return; /* no BB area, not Shortcut ABR, exiting */ - - /* find the backbone route, if possible */ - if ((ospf->backbone == NULL) - || !(or = ospf_find_asbr_route_through_area (rtrs, p, ospf->backbone))) - { - if (ospf->abr_type != OSPF_ABR_SHORTCUT) - - /* route to ASBR through the BB not found - the router is not Shortcut ABR, exiting */ - - return; - else - /* We're a Shortcut ABR*/ + or = rn->info; + + if (or->path_type != OSPF_PATH_INTRA_AREA && + or->path_type != OSPF_PATH_INTER_AREA) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_update_network_route(): ERR: path type is wrong"); + return; + } + + if (ospf->abr_type == OSPF_ABR_SHORTCUT) { + if ( + or->path_type == OSPF_PATH_INTRA_AREA + && !OSPF_IS_AREA_ID_BACKBONE( + or->u.std.area_id)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_update_network_route(): Shortcut: " + "this intra-area path is not backbone"); + return; + } + } else /* Not Shortcut ABR */ { - /* Let it either add a new router or update the route - through the same (non-BB) area. */ - - new_or = ospf_route_new (); - new_or->type = OSPF_DESTINATION_ROUTER; - new_or->id = lsa->header.id; - new_or->mask = lsa->mask; - new_or->u.std.options = lsa->header.options; - new_or->u.std.origin = (struct lsa_header *)lsa; - new_or->cost = cost; - new_or->u.std.area_id = area->area_id; - new_or->u.std.external_routing = area->external_routing; - new_or->path_type = OSPF_PATH_INTER_AREA; - new_or->u.std.flags = ROUTER_LSA_EXTERNAL; - ospf_ia_router_route (ospf, rtrs, p, new_or, abr_or); - - return; - } - } - - /* At this point the "or" is always bb-associated */ - - if (!(or->u.std.flags & ROUTER_LSA_EXTERNAL)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_upd_router_route(): the remote router is not an ASBR"); - return; - } - - if (or->path_type != OSPF_PATH_INTRA_AREA && - or->path_type != OSPF_PATH_INTER_AREA) - return; - - if (or->cost < cost) - return; - - else if (or->cost == cost) - ospf_route_copy_nexthops (or, abr_or->paths); - - else if (or->cost > cost) - { - ospf_route_subst_nexthops (or, abr_or->paths); - or->cost = cost; - - /* Even if the ABR runs in Shortcut mode, we can't change - the path type and area, because the "or" is always bb-associated - at this point and even Shortcut ABR can't change these attributes */ - } -} + if (!OSPF_IS_AREA_ID_BACKBONE(or->u.std.area_id)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_update_network_route(): " + "route is not BB-associated"); + return; /* We can update only BB routes */ + } + } -static int -process_transit_summary_lsa (struct ospf_area *area, struct route_table *rt, - struct route_table *rtrs, struct ospf_lsa *lsa) -{ - struct ospf *ospf = area->ospf; - struct summary_lsa *sl; - struct prefix_ipv4 p; - u_int32_t metric; - - if (lsa == NULL) - return 0; - - sl = (struct summary_lsa *) lsa->data; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("process_transit_summaries(): LS ID: %s", - inet_ntoa (lsa->data->id)); - metric = GET_METRIC (sl->metric); - - if (metric == OSPF_LS_INFINITY) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("process_transit_summaries(): metric is infinity, skip"); - return 0; - } - - if (IS_LSA_MAXAGE (lsa)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("process_transit_summaries(): This LSA is too old"); - return 0; - } - - if (ospf_lsa_is_self_originated (area->ospf, lsa)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("process_transit_summaries(): This LSA is mine, skip"); - return 0; - } - - p.family = AF_INET; - p.prefix = sl->header.id; - - if (sl->header.type == OSPF_SUMMARY_LSA) - p.prefixlen = ip_masklen (sl->mask); - else - p.prefixlen = IPV4_MAX_BITLEN; - - apply_mask_ipv4 (&p); - - if (sl->header.type == OSPF_SUMMARY_LSA) - ospf_update_network_route (ospf, rt, rtrs, sl, &p, area); - else - ospf_update_router_route (ospf, rtrs, sl, &p, area); - - return 0; -} + if (or->cost < cost) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_update_network_route(): new route is worse"); + return; + } -static void -ospf_examine_transit_summaries (struct ospf_area *area, - struct route_table *lsdb_rt, - struct route_table *rt, - struct route_table *rtrs) -{ - struct ospf_lsa *lsa; - struct route_node *rn; + if (or->cost == cost) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_update_network_route(): " + "new route is same distance, adding nexthops"); + ospf_route_copy_nexthops(or, abr_or->paths); + } - LSDB_LOOP (lsdb_rt, rn, lsa) - process_transit_summary_lsa (area, rt, rtrs, lsa); + if (or->cost > cost) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_update_network_route(): " + "new route is better, overriding nexthops"); + ospf_route_subst_nexthops(or, abr_or->paths); + or->cost = cost; + + if ((ospf->abr_type == OSPF_ABR_SHORTCUT) + && !OSPF_IS_AREA_ID_BACKBONE(or->u.std.area_id)) { + or->path_type = OSPF_PATH_INTER_AREA; + or->u.std.area_id = area->area_id; + or->u.std.external_routing = area->external_routing; + /* Note that we can do this only in Shortcut ABR mode, + because standard ABR must leave the route type and + area + unchanged + */ + } + } } -void -ospf_ia_routing (struct ospf *ospf, - struct route_table *rt, - struct route_table *rtrs) +static void ospf_update_router_route(struct ospf *ospf, + struct route_table *rtrs, + struct summary_lsa *lsa, + struct prefix_ipv4 *p, + struct ospf_area *area) { - struct ospf_area * area; + struct ospf_route * or, *abr_or, *new_or; + struct prefix_ipv4 abr; + u_int32_t cost; + + abr.family = AF_INET; + abr.prefix = lsa->header.adv_router; + abr.prefixlen = IPV4_MAX_BITLEN; + apply_mask_ipv4(&abr); + + abr_or = ospf_find_abr_route(rtrs, &abr, area); + + if (abr_or == NULL) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_update_router_route(): can't find a route to the ABR"); + return; + } - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_ia_routing():start"); + cost = abr_or->cost + GET_METRIC(lsa->metric); - if (IS_OSPF_ABR (ospf)) - { - struct listnode *node; - struct ospf_area *area; + /* First try to find a backbone path, + because standard ABR can update only BB-associated paths */ - switch (ospf->abr_type) - { - case OSPF_ABR_STAND: - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_ia_routing():Standard ABR"); + if ((ospf->backbone == NULL) && (ospf->abr_type != OSPF_ABR_SHORTCUT)) + return; /* no BB area, not Shortcut ABR, exiting */ - if ((area = ospf->backbone)) - { - struct listnode *node; + /* find the backbone route, if possible */ + if ((ospf->backbone == NULL) + || !(or = ospf_find_asbr_route_through_area(rtrs, p, + ospf->backbone))) { + if (ospf->abr_type != OSPF_ABR_SHORTCUT) - if (IS_DEBUG_OSPF_EVENT) - { - zlog_debug ("ospf_ia_routing():backbone area found"); - zlog_debug ("ospf_ia_routing():examining summaries"); - } + /* route to ASBR through the BB not found + the router is not Shortcut ABR, exiting */ - OSPF_EXAMINE_SUMMARIES_ALL (area, rt, rtrs); - - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - if (area != ospf->backbone) - if (ospf_area_is_transit (area)) - OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL (area, rt, rtrs); - } - else - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_ia_routing():backbone area NOT found"); - break; - case OSPF_ABR_IBM: - case OSPF_ABR_CISCO: - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_ia_routing():Alternative Cisco/IBM ABR"); - area = ospf->backbone; /* Find the BB */ - - /* If we have an active BB connection */ - if (area && ospf_act_bb_connection (ospf)) - { - if (IS_DEBUG_OSPF_EVENT) + return; + else + /* We're a Shortcut ABR*/ { - zlog_debug ("ospf_ia_routing(): backbone area found"); - zlog_debug ("ospf_ia_routing(): examining BB summaries"); + /* Let it either add a new router or update the route + through the same (non-BB) area. */ + + new_or = ospf_route_new(); + new_or->type = OSPF_DESTINATION_ROUTER; + new_or->id = lsa->header.id; + new_or->mask = lsa->mask; + new_or->u.std.options = lsa->header.options; + new_or->u.std.origin = (struct lsa_header *)lsa; + new_or->cost = cost; + new_or->u.std.area_id = area->area_id; + new_or->u.std.external_routing = area->external_routing; + new_or->path_type = OSPF_PATH_INTER_AREA; + new_or->u.std.flags = ROUTER_LSA_EXTERNAL; + ospf_ia_router_route(ospf, rtrs, p, new_or, abr_or); + + return; } + } - OSPF_EXAMINE_SUMMARIES_ALL (area, rt, rtrs); - - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - if (area != ospf->backbone) - if (ospf_area_is_transit (area)) - OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL (area, rt, rtrs); - } - else - { /* No active BB connection--consider all areas */ - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_ia_routing(): " - "Active BB connection not found"); - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - OSPF_EXAMINE_SUMMARIES_ALL (area, rt, rtrs); - } - break; - case OSPF_ABR_SHORTCUT: - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_ia_routing():Alternative Shortcut"); - area = ospf->backbone; /* Find the BB */ - - /* If we have an active BB connection */ - if (area && ospf_act_bb_connection (ospf)) - { - if (IS_DEBUG_OSPF_EVENT) - { - zlog_debug ("ospf_ia_routing(): backbone area found"); - zlog_debug ("ospf_ia_routing(): examining BB summaries"); + /* At this point the "or" is always bb-associated */ + + if (!(or->u.std.flags & ROUTER_LSA_EXTERNAL)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_upd_router_route(): the remote router is not an ASBR"); + return; + } + + if (or->path_type != OSPF_PATH_INTRA_AREA && + or->path_type != OSPF_PATH_INTER_AREA) + return; + + if (or->cost < cost) + return; + + else if (or->cost == cost) + ospf_route_copy_nexthops(or, abr_or->paths); + + else if (or->cost > cost) { + ospf_route_subst_nexthops(or, abr_or->paths); + or->cost = cost; + + /* Even if the ABR runs in Shortcut mode, we can't change + the path type and area, because the "or" is always + bb-associated + at this point and even Shortcut ABR can't change these + attributes */ + } +} + +static int process_transit_summary_lsa(struct ospf_area *area, + struct route_table *rt, + struct route_table *rtrs, + struct ospf_lsa *lsa) +{ + struct ospf *ospf = area->ospf; + struct summary_lsa *sl; + struct prefix_ipv4 p; + u_int32_t metric; + + if (lsa == NULL) + return 0; + + sl = (struct summary_lsa *)lsa->data; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("process_transit_summaries(): LS ID: %s", + inet_ntoa(lsa->data->id)); + metric = GET_METRIC(sl->metric); + + if (metric == OSPF_LS_INFINITY) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "process_transit_summaries(): metric is infinity, skip"); + return 0; + } + + if (IS_LSA_MAXAGE(lsa)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "process_transit_summaries(): This LSA is too old"); + return 0; + } + + if (ospf_lsa_is_self_originated(area->ospf, lsa)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "process_transit_summaries(): This LSA is mine, skip"); + return 0; + } + + p.family = AF_INET; + p.prefix = sl->header.id; + + if (sl->header.type == OSPF_SUMMARY_LSA) + p.prefixlen = ip_masklen(sl->mask); + else + p.prefixlen = IPV4_MAX_BITLEN; + + apply_mask_ipv4(&p); + + if (sl->header.type == OSPF_SUMMARY_LSA) + ospf_update_network_route(ospf, rt, rtrs, sl, &p, area); + else + ospf_update_router_route(ospf, rtrs, sl, &p, area); + + return 0; +} + +static void ospf_examine_transit_summaries(struct ospf_area *area, + struct route_table *lsdb_rt, + struct route_table *rt, + struct route_table *rtrs) +{ + struct ospf_lsa *lsa; + struct route_node *rn; + + LSDB_LOOP(lsdb_rt, rn, lsa) + process_transit_summary_lsa(area, rt, rtrs, lsa); +} + +void ospf_ia_routing(struct ospf *ospf, struct route_table *rt, + struct route_table *rtrs) +{ + struct ospf_area *area; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_ia_routing():start"); + + if (IS_OSPF_ABR(ospf)) { + struct listnode *node; + struct ospf_area *area; + + switch (ospf->abr_type) { + case OSPF_ABR_STAND: + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_ia_routing():Standard ABR"); + + if ((area = ospf->backbone)) { + struct listnode *node; + + if (IS_DEBUG_OSPF_EVENT) { + zlog_debug( + "ospf_ia_routing():backbone area found"); + zlog_debug( + "ospf_ia_routing():examining summaries"); + } + + OSPF_EXAMINE_SUMMARIES_ALL(area, rt, rtrs); + + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, + area)) + if (area != ospf->backbone) + if (ospf_area_is_transit(area)) + OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL( + area, rt, rtrs); + } else if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_ia_routing():backbone area NOT found"); + break; + case OSPF_ABR_IBM: + case OSPF_ABR_CISCO: + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_ia_routing():Alternative Cisco/IBM ABR"); + area = ospf->backbone; /* Find the BB */ + + /* If we have an active BB connection */ + if (area && ospf_act_bb_connection(ospf)) { + if (IS_DEBUG_OSPF_EVENT) { + zlog_debug( + "ospf_ia_routing(): backbone area found"); + zlog_debug( + "ospf_ia_routing(): examining BB summaries"); + } + + OSPF_EXAMINE_SUMMARIES_ALL(area, rt, rtrs); + + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, + area)) + if (area != ospf->backbone) + if (ospf_area_is_transit(area)) + OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL( + area, rt, rtrs); + } else { /* No active BB connection--consider all areas + */ + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_ia_routing(): " + "Active BB connection not found"); + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, + area)) + OSPF_EXAMINE_SUMMARIES_ALL(area, rt, + rtrs); + } + break; + case OSPF_ABR_SHORTCUT: + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_ia_routing():Alternative Shortcut"); + area = ospf->backbone; /* Find the BB */ + + /* If we have an active BB connection */ + if (area && ospf_act_bb_connection(ospf)) { + if (IS_DEBUG_OSPF_EVENT) { + zlog_debug( + "ospf_ia_routing(): backbone area found"); + zlog_debug( + "ospf_ia_routing(): examining BB summaries"); + } + OSPF_EXAMINE_SUMMARIES_ALL(area, rt, rtrs); + } + + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) + if (area != ospf->backbone) + if (ospf_area_is_transit(area) + || ((area->shortcut_configured + != OSPF_SHORTCUT_DISABLE) + && ((ospf->backbone == NULL) + || ((area->shortcut_configured + == OSPF_SHORTCUT_ENABLE) + && area->shortcut_capability)))) + OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL( + area, rt, rtrs); + break; + default: + break; } - OSPF_EXAMINE_SUMMARIES_ALL (area, rt, rtrs); - } - - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - if (area != ospf->backbone) - if (ospf_area_is_transit (area) || - ((area->shortcut_configured != OSPF_SHORTCUT_DISABLE) && - ((ospf->backbone == NULL) || - ((area->shortcut_configured == OSPF_SHORTCUT_ENABLE) && - area->shortcut_capability)))) - OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL (area, rt, rtrs); - break; - default: - break; - } - } - else - { - struct listnode *node; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_ia_routing():not ABR, considering all areas"); - - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - OSPF_EXAMINE_SUMMARIES_ALL (area, rt, rtrs); - } + } else { + struct listnode *node; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_ia_routing():not ABR, considering all areas"); + + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) + OSPF_EXAMINE_SUMMARIES_ALL(area, rt, rtrs); + } } diff --git a/ospfd/ospf_ia.h b/ospfd/ospf_ia.h index f102545f8..05ad13c06 100644 --- a/ospfd/ospf_ia.h +++ b/ospfd/ospf_ia.h @@ -23,20 +23,22 @@ #define _ZEBRA_OSPF_IA_H /* Macros. */ -#define OSPF_EXAMINE_SUMMARIES_ALL(A,N,R) \ - { \ - ospf_examine_summaries ((A), SUMMARY_LSDB ((A)), (N), (R)); \ - ospf_examine_summaries ((A), ASBR_SUMMARY_LSDB ((A)), (N), (R)); \ +#define OSPF_EXAMINE_SUMMARIES_ALL(A, N, R) \ + { \ + ospf_examine_summaries((A), SUMMARY_LSDB((A)), (N), (R)); \ + ospf_examine_summaries((A), ASBR_SUMMARY_LSDB((A)), (N), (R)); \ } -#define OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL(A,N,R) \ - { \ - ospf_examine_transit_summaries ((A), SUMMARY_LSDB ((A)), (N), (R)); \ - ospf_examine_transit_summaries ((A), ASBR_SUMMARY_LSDB ((A)), (N), (R)); \ +#define OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL(A, N, R) \ + { \ + ospf_examine_transit_summaries((A), SUMMARY_LSDB((A)), (N), \ + (R)); \ + ospf_examine_transit_summaries((A), ASBR_SUMMARY_LSDB((A)), \ + (N), (R)); \ } -extern void ospf_ia_routing (struct ospf *, struct route_table *, - struct route_table *); -extern int ospf_area_is_transit (struct ospf_area *); +extern void ospf_ia_routing(struct ospf *, struct route_table *, + struct route_table *); +extern int ospf_area_is_transit(struct ospf_area *); #endif /* _ZEBRA_OSPF_IA_H */ diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index 1e95e4312..4ea8ec26f 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -48,1180 +48,1121 @@ #include "ospfd/ospf_dump.h" DEFINE_QOBJ_TYPE(ospf_interface) -DEFINE_HOOK(ospf_vl_add, (struct ospf_vl_data *vd), (vd)) -DEFINE_HOOK(ospf_vl_delete, (struct ospf_vl_data *vd), (vd)) +DEFINE_HOOK(ospf_vl_add, (struct ospf_vl_data * vd), (vd)) +DEFINE_HOOK(ospf_vl_delete, (struct ospf_vl_data * vd), (vd)) -int -ospf_if_get_output_cost (struct ospf_interface *oi) +int ospf_if_get_output_cost(struct ospf_interface *oi) { - /* If all else fails, use default OSPF cost */ - u_int32_t cost; - u_int32_t bw, refbw; - - /* ifp speed and bw can be 0 in some platforms, use ospf default bw - if bw is configured under interface it would be used. - */ - if (!oi->ifp->bandwidth && oi->ifp->speed) - bw = oi->ifp->speed; - else - bw = oi->ifp->bandwidth ? oi->ifp->bandwidth : OSPF_DEFAULT_BANDWIDTH; - refbw = oi->ospf->ref_bandwidth; - - /* A specifed ip ospf cost overrides a calculated one. */ - if (OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (oi->ifp), output_cost_cmd) || - OSPF_IF_PARAM_CONFIGURED (oi->params, output_cost_cmd)) - cost = OSPF_IF_PARAM (oi, output_cost_cmd); - /* See if a cost can be calculated from the zebra processes - interface bandwidth field. */ - else - { - cost = (u_int32_t) ((double)refbw / (double)bw + (double)0.5); - if (cost < 1) - cost = 1; - else if (cost > 65535) - cost = 65535; - } - - return cost; + /* If all else fails, use default OSPF cost */ + u_int32_t cost; + u_int32_t bw, refbw; + + /* ifp speed and bw can be 0 in some platforms, use ospf default bw + if bw is configured under interface it would be used. + */ + if (!oi->ifp->bandwidth && oi->ifp->speed) + bw = oi->ifp->speed; + else + bw = oi->ifp->bandwidth ? oi->ifp->bandwidth + : OSPF_DEFAULT_BANDWIDTH; + refbw = oi->ospf->ref_bandwidth; + + /* A specifed ip ospf cost overrides a calculated one. */ + if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(oi->ifp), output_cost_cmd) + || OSPF_IF_PARAM_CONFIGURED(oi->params, output_cost_cmd)) + cost = OSPF_IF_PARAM(oi, output_cost_cmd); + /* See if a cost can be calculated from the zebra processes + interface bandwidth field. */ + else { + cost = (u_int32_t)((double)refbw / (double)bw + (double)0.5); + if (cost < 1) + cost = 1; + else if (cost > 65535) + cost = 65535; + } + + return cost; } -void -ospf_if_recalculate_output_cost (struct interface *ifp) +void ospf_if_recalculate_output_cost(struct interface *ifp) { - u_int32_t newcost; - struct route_node *rn; - - for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn)) - { - struct ospf_interface *oi; - - if ( (oi = rn->info) == NULL) - continue; - - newcost = ospf_if_get_output_cost (oi); - - /* Is actual output cost changed? */ - if (oi->output_cost != newcost) - { - oi->output_cost = newcost; - ospf_router_lsa_update_area (oi->area); + u_int32_t newcost; + struct route_node *rn; + + for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) { + struct ospf_interface *oi; + + if ((oi = rn->info) == NULL) + continue; + + newcost = ospf_if_get_output_cost(oi); + + /* Is actual output cost changed? */ + if (oi->output_cost != newcost) { + oi->output_cost = newcost; + ospf_router_lsa_update_area(oi->area); + } } - } } -/* Simulate down/up on the interface. This is needed, for example, when +/* Simulate down/up on the interface. This is needed, for example, when the MTU changes. */ -void -ospf_if_reset(struct interface *ifp) +void ospf_if_reset(struct interface *ifp) { - struct route_node *rn; - - for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn)) - { - struct ospf_interface *oi; - - if ( (oi = rn->info) == NULL) - continue; - - ospf_if_down(oi); - ospf_if_up(oi); - } + struct route_node *rn; + + for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) { + struct ospf_interface *oi; + + if ((oi = rn->info) == NULL) + continue; + + ospf_if_down(oi); + ospf_if_up(oi); + } } -void -ospf_if_reset_variables (struct ospf_interface *oi) +void ospf_if_reset_variables(struct ospf_interface *oi) { - /* Set default values. */ - /* don't clear this flag. oi->flag = OSPF_IF_DISABLE; */ + /* Set default values. */ + /* don't clear this flag. oi->flag = OSPF_IF_DISABLE; */ - if (oi->vl_data) - oi->type = OSPF_IFTYPE_VIRTUALLINK; - else - /* preserve network-type */ - if (oi->type != OSPF_IFTYPE_NBMA) - oi->type = OSPF_IFTYPE_BROADCAST; + if (oi->vl_data) + oi->type = OSPF_IFTYPE_VIRTUALLINK; + else + /* preserve network-type */ + if (oi->type != OSPF_IFTYPE_NBMA) + oi->type = OSPF_IFTYPE_BROADCAST; - oi->state = ISM_Down; + oi->state = ISM_Down; - oi->crypt_seqnum = 0; + oi->crypt_seqnum = 0; - /* This must be short, (less than RxmtInterval) - - RFC 2328 Section 13.5 para 3. Set to 1 second to avoid Acks being - held back for too long - MAG */ - oi->v_ls_ack = 1; + /* This must be short, (less than RxmtInterval) + - RFC 2328 Section 13.5 para 3. Set to 1 second to avoid Acks being + held back for too long - MAG */ + oi->v_ls_ack = 1; } /* lookup oi for specified prefix/ifp */ -struct ospf_interface * -ospf_if_table_lookup (struct interface *ifp, struct prefix *prefix) +struct ospf_interface *ospf_if_table_lookup(struct interface *ifp, + struct prefix *prefix) { - struct prefix p; - struct route_node *rn; - struct ospf_interface *rninfo = NULL; - - p = *prefix; - p.prefixlen = IPV4_MAX_PREFIXLEN; - - /* route_node_get implicitely locks */ - if ((rn = route_node_lookup (IF_OIFS (ifp), &p))) - { - rninfo = (struct ospf_interface *) rn->info; - route_unlock_node (rn); - } - - return rninfo; + struct prefix p; + struct route_node *rn; + struct ospf_interface *rninfo = NULL; + + p = *prefix; + p.prefixlen = IPV4_MAX_PREFIXLEN; + + /* route_node_get implicitely locks */ + if ((rn = route_node_lookup(IF_OIFS(ifp), &p))) { + rninfo = (struct ospf_interface *)rn->info; + route_unlock_node(rn); + } + + return rninfo; } -static void -ospf_add_to_if (struct interface *ifp, struct ospf_interface *oi) +static void ospf_add_to_if(struct interface *ifp, struct ospf_interface *oi) { - struct route_node *rn; - struct prefix p; - - p = *oi->address; - p.prefixlen = IPV4_MAX_PREFIXLEN; - - rn = route_node_get (IF_OIFS (ifp), &p); - /* rn->info should either be NULL or equal to this oi - * as route_node_get may return an existing node - */ - assert (!rn->info || rn->info == oi); - rn->info = oi; + struct route_node *rn; + struct prefix p; + + p = *oi->address; + p.prefixlen = IPV4_MAX_PREFIXLEN; + + rn = route_node_get(IF_OIFS(ifp), &p); + /* rn->info should either be NULL or equal to this oi + * as route_node_get may return an existing node + */ + assert(!rn->info || rn->info == oi); + rn->info = oi; } -static void -ospf_delete_from_if (struct interface *ifp, struct ospf_interface *oi) +static void ospf_delete_from_if(struct interface *ifp, + struct ospf_interface *oi) { - struct route_node *rn; - struct prefix p; - - p = *oi->address; - p.prefixlen = IPV4_MAX_PREFIXLEN; - - rn = route_node_lookup (IF_OIFS (oi->ifp), &p); - assert (rn); - assert (rn->info); - rn->info = NULL; - route_unlock_node (rn); - route_unlock_node (rn); + struct route_node *rn; + struct prefix p; + + p = *oi->address; + p.prefixlen = IPV4_MAX_PREFIXLEN; + + rn = route_node_lookup(IF_OIFS(oi->ifp), &p); + assert(rn); + assert(rn->info); + rn->info = NULL; + route_unlock_node(rn); + route_unlock_node(rn); } -struct ospf_interface * -ospf_if_new (struct ospf *ospf, struct interface *ifp, struct prefix *p) +struct ospf_interface *ospf_if_new(struct ospf *ospf, struct interface *ifp, + struct prefix *p) { - struct ospf_interface *oi; - - if ((oi = ospf_if_table_lookup (ifp, p)) == NULL) - { - oi = XCALLOC (MTYPE_OSPF_IF, sizeof (struct ospf_interface)); - memset (oi, 0, sizeof (struct ospf_interface)); - } - else - return oi; - - /* Set zebra interface pointer. */ - oi->ifp = ifp; - oi->address = p; - - ospf_add_to_if (ifp, oi); - listnode_add (ospf->oiflist, oi); - - /* Initialize neighbor list. */ - oi->nbrs = route_table_init (); - - /* Initialize static neighbor list. */ - oi->nbr_nbma = list_new (); - - /* Initialize Link State Acknowledgment list. */ - oi->ls_ack = list_new (); - oi->ls_ack_direct.ls_ack = list_new (); - - /* Set default values. */ - ospf_if_reset_variables (oi); - - /* Set pseudo neighbor to Null */ - oi->nbr_self = NULL; - - oi->ls_upd_queue = route_table_init (); - oi->t_ls_upd_event = NULL; - oi->t_ls_ack_direct = NULL; - - oi->crypt_seqnum = time (NULL); - - ospf_opaque_type9_lsa_init (oi); - - oi->ospf = ospf; - QOBJ_REG (oi, ospf_interface); - - return oi; + struct ospf_interface *oi; + + if ((oi = ospf_if_table_lookup(ifp, p)) == NULL) { + oi = XCALLOC(MTYPE_OSPF_IF, sizeof(struct ospf_interface)); + memset(oi, 0, sizeof(struct ospf_interface)); + } else + return oi; + + /* Set zebra interface pointer. */ + oi->ifp = ifp; + oi->address = p; + + ospf_add_to_if(ifp, oi); + listnode_add(ospf->oiflist, oi); + + /* Initialize neighbor list. */ + oi->nbrs = route_table_init(); + + /* Initialize static neighbor list. */ + oi->nbr_nbma = list_new(); + + /* Initialize Link State Acknowledgment list. */ + oi->ls_ack = list_new(); + oi->ls_ack_direct.ls_ack = list_new(); + + /* Set default values. */ + ospf_if_reset_variables(oi); + + /* Set pseudo neighbor to Null */ + oi->nbr_self = NULL; + + oi->ls_upd_queue = route_table_init(); + oi->t_ls_upd_event = NULL; + oi->t_ls_ack_direct = NULL; + + oi->crypt_seqnum = time(NULL); + + ospf_opaque_type9_lsa_init(oi); + + oi->ospf = ospf; + QOBJ_REG(oi, ospf_interface); + + return oi; } /* Restore an interface to its pre UP state Used from ism_interface_down only */ -void -ospf_if_cleanup (struct ospf_interface *oi) +void ospf_if_cleanup(struct ospf_interface *oi) { - struct route_node *rn; - struct listnode *node, *nnode; - struct ospf_neighbor *nbr; - struct ospf_nbr_nbma *nbr_nbma; - struct ospf_lsa *lsa; - - /* oi->nbrs and oi->nbr_nbma should be deleted on InterfaceDown event */ - /* delete all static neighbors attached to this interface */ - for (ALL_LIST_ELEMENTS (oi->nbr_nbma, node, nnode, nbr_nbma)) - { - OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll); - - if (nbr_nbma->nbr) - { - nbr_nbma->nbr->nbr_nbma = NULL; - nbr_nbma->nbr = NULL; + struct route_node *rn; + struct listnode *node, *nnode; + struct ospf_neighbor *nbr; + struct ospf_nbr_nbma *nbr_nbma; + struct ospf_lsa *lsa; + + /* oi->nbrs and oi->nbr_nbma should be deleted on InterfaceDown event */ + /* delete all static neighbors attached to this interface */ + for (ALL_LIST_ELEMENTS(oi->nbr_nbma, node, nnode, nbr_nbma)) { + OSPF_POLL_TIMER_OFF(nbr_nbma->t_poll); + + if (nbr_nbma->nbr) { + nbr_nbma->nbr->nbr_nbma = NULL; + nbr_nbma->nbr = NULL; + } + + nbr_nbma->oi = NULL; + + listnode_delete(oi->nbr_nbma, nbr_nbma); } - nbr_nbma->oi = NULL; - - listnode_delete (oi->nbr_nbma, nbr_nbma); - } - - /* send Neighbor event KillNbr to all associated neighbors. */ - for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) - if ((nbr = rn->info) != NULL) - if (nbr != oi->nbr_self) - OSPF_NSM_EVENT_EXECUTE (nbr, NSM_KillNbr); - - /* Cleanup Link State Acknowlegdment list. */ - for (ALL_LIST_ELEMENTS (oi->ls_ack, node, nnode, lsa)) - ospf_lsa_unlock (&lsa); /* oi->ls_ack */ - list_delete_all_node (oi->ls_ack); - - oi->crypt_seqnum = 0; - - /* Empty link state update queue */ - ospf_ls_upd_queue_empty (oi); - - /* Reset pseudo neighbor. */ - ospf_nbr_self_reset (oi, oi->ospf->router_id); + /* send Neighbor event KillNbr to all associated neighbors. */ + for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) + if ((nbr = rn->info) != NULL) + if (nbr != oi->nbr_self) + OSPF_NSM_EVENT_EXECUTE(nbr, NSM_KillNbr); + + /* Cleanup Link State Acknowlegdment list. */ + for (ALL_LIST_ELEMENTS(oi->ls_ack, node, nnode, lsa)) + ospf_lsa_unlock(&lsa); /* oi->ls_ack */ + list_delete_all_node(oi->ls_ack); + + oi->crypt_seqnum = 0; + + /* Empty link state update queue */ + ospf_ls_upd_queue_empty(oi); + + /* Reset pseudo neighbor. */ + ospf_nbr_self_reset(oi, oi->ospf->router_id); } -void -ospf_if_free (struct ospf_interface *oi) +void ospf_if_free(struct ospf_interface *oi) { - ospf_if_down (oi); + ospf_if_down(oi); + + assert(oi->state == ISM_Down); + + ospf_opaque_type9_lsa_term(oi); + + QOBJ_UNREG(oi); + + /* Free Pseudo Neighbour */ + ospf_nbr_delete(oi->nbr_self); - assert (oi->state == ISM_Down); + route_table_finish(oi->nbrs); + route_table_finish(oi->ls_upd_queue); - ospf_opaque_type9_lsa_term (oi); + /* Free any lists that should be freed */ + list_free(oi->nbr_nbma); - QOBJ_UNREG (oi); + list_free(oi->ls_ack); + list_free(oi->ls_ack_direct.ls_ack); - /* Free Pseudo Neighbour */ - ospf_nbr_delete (oi->nbr_self); - - route_table_finish (oi->nbrs); - route_table_finish (oi->ls_upd_queue); - - /* Free any lists that should be freed */ - list_free (oi->nbr_nbma); - - list_free (oi->ls_ack); - list_free (oi->ls_ack_direct.ls_ack); - - ospf_delete_from_if (oi->ifp, oi); + ospf_delete_from_if(oi->ifp, oi); - listnode_delete (oi->ospf->oiflist, oi); - listnode_delete (oi->area->oiflist, oi); + listnode_delete(oi->ospf->oiflist, oi); + listnode_delete(oi->area->oiflist, oi); - thread_cancel_event (master, oi); + thread_cancel_event(master, oi); - memset (oi, 0, sizeof (*oi)); - XFREE (MTYPE_OSPF_IF, oi); + memset(oi, 0, sizeof(*oi)); + XFREE(MTYPE_OSPF_IF, oi); } -int -ospf_if_is_up (struct ospf_interface *oi) +int ospf_if_is_up(struct ospf_interface *oi) { - return if_is_up (oi->ifp); + return if_is_up(oi->ifp); } -struct ospf_interface * -ospf_if_exists (struct ospf_interface *oic) -{ - struct listnode *node; - struct ospf *ospf; - struct ospf_interface *oi; +struct ospf_interface *ospf_if_exists(struct ospf_interface *oic) +{ + struct listnode *node; + struct ospf *ospf; + struct ospf_interface *oi; - if ((ospf = ospf_lookup ()) == NULL) - return NULL; + if ((ospf = ospf_lookup()) == NULL) + return NULL; - for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) - if (oi == oic) - return oi; + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) + if (oi == oic) + return oi; - return NULL; + return NULL; } /* Lookup OSPF interface by router LSA posistion */ -struct ospf_interface * -ospf_if_lookup_by_lsa_pos (struct ospf_area *area, int lsa_pos) +struct ospf_interface *ospf_if_lookup_by_lsa_pos(struct ospf_area *area, + int lsa_pos) { - struct listnode *node; - struct ospf_interface *oi; + struct listnode *node; + struct ospf_interface *oi; - for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi)) - { - if (lsa_pos >= oi->lsa_pos_beg && lsa_pos < oi->lsa_pos_end) - return oi; - } - return NULL; + for (ALL_LIST_ELEMENTS_RO(area->oiflist, node, oi)) { + if (lsa_pos >= oi->lsa_pos_beg && lsa_pos < oi->lsa_pos_end) + return oi; + } + return NULL; } -struct ospf_interface * -ospf_if_lookup_by_local_addr (struct ospf *ospf, - struct interface *ifp, struct in_addr address) +struct ospf_interface *ospf_if_lookup_by_local_addr(struct ospf *ospf, + struct interface *ifp, + struct in_addr address) { - struct listnode *node; - struct ospf_interface *oi; - - for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) - if (oi->type != OSPF_IFTYPE_VIRTUALLINK) - { - if (ifp && oi->ifp != ifp) - continue; - - if (IPV4_ADDR_SAME (&address, &oi->address->u.prefix4)) - return oi; - } - - return NULL; + struct listnode *node; + struct ospf_interface *oi; + + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) + if (oi->type != OSPF_IFTYPE_VIRTUALLINK) { + if (ifp && oi->ifp != ifp) + continue; + + if (IPV4_ADDR_SAME(&address, &oi->address->u.prefix4)) + return oi; + } + + return NULL; } -struct ospf_interface * -ospf_if_lookup_by_prefix (struct ospf *ospf, struct prefix_ipv4 *p) +struct ospf_interface *ospf_if_lookup_by_prefix(struct ospf *ospf, + struct prefix_ipv4 *p) { - struct listnode *node; - struct ospf_interface *oi; - - /* Check each Interface. */ - for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) - { - if (oi->type != OSPF_IFTYPE_VIRTUALLINK) - { - struct prefix ptmp; - - prefix_copy (&ptmp, CONNECTED_PREFIX(oi->connected)); - apply_mask (&ptmp); - if (prefix_same (&ptmp, (struct prefix *) p)) - return oi; + struct listnode *node; + struct ospf_interface *oi; + + /* Check each Interface. */ + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) { + if (oi->type != OSPF_IFTYPE_VIRTUALLINK) { + struct prefix ptmp; + + prefix_copy(&ptmp, CONNECTED_PREFIX(oi->connected)); + apply_mask(&ptmp); + if (prefix_same(&ptmp, (struct prefix *)p)) + return oi; + } } - } - return NULL; + return NULL; } /* determine receiving interface by ifp and source address */ -struct ospf_interface * -ospf_if_lookup_recv_if (struct ospf *ospf, struct in_addr src, - struct interface *ifp) +struct ospf_interface *ospf_if_lookup_recv_if(struct ospf *ospf, + struct in_addr src, + struct interface *ifp) { - struct route_node *rn; - struct prefix_ipv4 addr; - struct ospf_interface *oi, *match; - - addr.family = AF_INET; - addr.prefix = src; - addr.prefixlen = IPV4_MAX_BITLEN; - - match = NULL; - - for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn)) - { - oi = rn->info; - - if (!oi) /* oi can be NULL for PtP aliases */ - continue; - - if (oi->type == OSPF_IFTYPE_VIRTUALLINK) - continue; - - if (if_is_loopback (oi->ifp)) - continue; - - if (CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED)) - match = oi; - else if (prefix_match (CONNECTED_PREFIX(oi->connected), - (struct prefix *) &addr)) - { - if ( (match == NULL) || - (match->address->prefixlen < oi->address->prefixlen) - ) - match = oi; + struct route_node *rn; + struct prefix_ipv4 addr; + struct ospf_interface *oi, *match; + + addr.family = AF_INET; + addr.prefix = src; + addr.prefixlen = IPV4_MAX_BITLEN; + + match = NULL; + + for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) { + oi = rn->info; + + if (!oi) /* oi can be NULL for PtP aliases */ + continue; + + if (oi->type == OSPF_IFTYPE_VIRTUALLINK) + continue; + + if (if_is_loopback(oi->ifp)) + continue; + + if (CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED)) + match = oi; + else if (prefix_match(CONNECTED_PREFIX(oi->connected), + (struct prefix *)&addr)) { + if ((match == NULL) || (match->address->prefixlen + < oi->address->prefixlen)) + match = oi; + } } - } - return match; + return match; } -void -ospf_if_stream_set (struct ospf_interface *oi) +void ospf_if_stream_set(struct ospf_interface *oi) { - /* set output fifo queue. */ - if (oi->obuf == NULL) - oi->obuf = ospf_fifo_new (); + /* set output fifo queue. */ + if (oi->obuf == NULL) + oi->obuf = ospf_fifo_new(); } -void -ospf_if_stream_unset (struct ospf_interface *oi) +void ospf_if_stream_unset(struct ospf_interface *oi) { - struct ospf *ospf = oi->ospf; - - if (oi->obuf) - { - ospf_fifo_free (oi->obuf); - oi->obuf = NULL; - - if (oi->on_write_q) - { - listnode_delete (ospf->oi_write_q, oi); - if (list_isempty(ospf->oi_write_q)) - OSPF_TIMER_OFF (ospf->t_write); - oi->on_write_q = 0; - } - } + struct ospf *ospf = oi->ospf; + + if (oi->obuf) { + ospf_fifo_free(oi->obuf); + oi->obuf = NULL; + + if (oi->on_write_q) { + listnode_delete(ospf->oi_write_q, oi); + if (list_isempty(ospf->oi_write_q)) + OSPF_TIMER_OFF(ospf->t_write); + oi->on_write_q = 0; + } + } } -static struct ospf_if_params * -ospf_new_if_params (void) +static struct ospf_if_params *ospf_new_if_params(void) { - struct ospf_if_params *oip; - - oip = XCALLOC (MTYPE_OSPF_IF_PARAMS, sizeof (struct ospf_if_params)); - - if (!oip) - return NULL; - - UNSET_IF_PARAM (oip, output_cost_cmd); - UNSET_IF_PARAM (oip, transmit_delay); - UNSET_IF_PARAM (oip, retransmit_interval); - UNSET_IF_PARAM (oip, passive_interface); - UNSET_IF_PARAM (oip, v_hello); - UNSET_IF_PARAM (oip, fast_hello); - UNSET_IF_PARAM (oip, v_wait); - UNSET_IF_PARAM (oip, priority); - UNSET_IF_PARAM (oip, type); - UNSET_IF_PARAM (oip, auth_simple); - UNSET_IF_PARAM (oip, auth_crypt); - UNSET_IF_PARAM (oip, auth_type); - - oip->auth_crypt = list_new (); - - oip->network_lsa_seqnum = htonl(OSPF_INITIAL_SEQUENCE_NUMBER); - - return oip; + struct ospf_if_params *oip; + + oip = XCALLOC(MTYPE_OSPF_IF_PARAMS, sizeof(struct ospf_if_params)); + + if (!oip) + return NULL; + + UNSET_IF_PARAM(oip, output_cost_cmd); + UNSET_IF_PARAM(oip, transmit_delay); + UNSET_IF_PARAM(oip, retransmit_interval); + UNSET_IF_PARAM(oip, passive_interface); + UNSET_IF_PARAM(oip, v_hello); + UNSET_IF_PARAM(oip, fast_hello); + UNSET_IF_PARAM(oip, v_wait); + UNSET_IF_PARAM(oip, priority); + UNSET_IF_PARAM(oip, type); + UNSET_IF_PARAM(oip, auth_simple); + UNSET_IF_PARAM(oip, auth_crypt); + UNSET_IF_PARAM(oip, auth_type); + + oip->auth_crypt = list_new(); + + oip->network_lsa_seqnum = htonl(OSPF_INITIAL_SEQUENCE_NUMBER); + + return oip; } -void -ospf_del_if_params (struct ospf_if_params *oip) +void ospf_del_if_params(struct ospf_if_params *oip) { - list_delete (oip->auth_crypt); - bfd_info_free(&(oip->bfd_info)); - XFREE (MTYPE_OSPF_IF_PARAMS, oip); + list_delete(oip->auth_crypt); + bfd_info_free(&(oip->bfd_info)); + XFREE(MTYPE_OSPF_IF_PARAMS, oip); } -void -ospf_free_if_params (struct interface *ifp, struct in_addr addr) +void ospf_free_if_params(struct interface *ifp, struct in_addr addr) { - struct ospf_if_params *oip; - struct prefix_ipv4 p; - struct route_node *rn; - - p.family = AF_INET; - p.prefixlen = IPV4_MAX_PREFIXLEN; - p.prefix = addr; - rn = route_node_lookup (IF_OIFS_PARAMS (ifp), (struct prefix*)&p); - if (!rn || !rn->info) - return; - - oip = rn->info; - route_unlock_node (rn); - - if (!OSPF_IF_PARAM_CONFIGURED (oip, output_cost_cmd) && - !OSPF_IF_PARAM_CONFIGURED (oip, transmit_delay) && - !OSPF_IF_PARAM_CONFIGURED (oip, retransmit_interval) && - !OSPF_IF_PARAM_CONFIGURED (oip, passive_interface) && - !OSPF_IF_PARAM_CONFIGURED (oip, v_hello) && - !OSPF_IF_PARAM_CONFIGURED (oip, fast_hello) && - !OSPF_IF_PARAM_CONFIGURED (oip, v_wait) && - !OSPF_IF_PARAM_CONFIGURED (oip, priority) && - !OSPF_IF_PARAM_CONFIGURED (oip, type) && - !OSPF_IF_PARAM_CONFIGURED (oip, auth_simple) && - !OSPF_IF_PARAM_CONFIGURED (oip, auth_type) && - listcount (oip->auth_crypt) == 0 && - ntohl (oip->network_lsa_seqnum) != OSPF_INITIAL_SEQUENCE_NUMBER) - { - ospf_del_if_params (oip); - rn->info = NULL; - route_unlock_node (rn); - } + struct ospf_if_params *oip; + struct prefix_ipv4 p; + struct route_node *rn; + + p.family = AF_INET; + p.prefixlen = IPV4_MAX_PREFIXLEN; + p.prefix = addr; + rn = route_node_lookup(IF_OIFS_PARAMS(ifp), (struct prefix *)&p); + if (!rn || !rn->info) + return; + + oip = rn->info; + route_unlock_node(rn); + + if (!OSPF_IF_PARAM_CONFIGURED(oip, output_cost_cmd) + && !OSPF_IF_PARAM_CONFIGURED(oip, transmit_delay) + && !OSPF_IF_PARAM_CONFIGURED(oip, retransmit_interval) + && !OSPF_IF_PARAM_CONFIGURED(oip, passive_interface) + && !OSPF_IF_PARAM_CONFIGURED(oip, v_hello) + && !OSPF_IF_PARAM_CONFIGURED(oip, fast_hello) + && !OSPF_IF_PARAM_CONFIGURED(oip, v_wait) + && !OSPF_IF_PARAM_CONFIGURED(oip, priority) + && !OSPF_IF_PARAM_CONFIGURED(oip, type) + && !OSPF_IF_PARAM_CONFIGURED(oip, auth_simple) + && !OSPF_IF_PARAM_CONFIGURED(oip, auth_type) + && listcount(oip->auth_crypt) == 0 + && ntohl(oip->network_lsa_seqnum) != OSPF_INITIAL_SEQUENCE_NUMBER) { + ospf_del_if_params(oip); + rn->info = NULL; + route_unlock_node(rn); + } } -struct ospf_if_params * -ospf_lookup_if_params (struct interface *ifp, struct in_addr addr) +struct ospf_if_params *ospf_lookup_if_params(struct interface *ifp, + struct in_addr addr) { - struct prefix_ipv4 p; - struct route_node *rn; - - p.family = AF_INET; - p.prefixlen = IPV4_MAX_PREFIXLEN; - p.prefix = addr; - - rn = route_node_lookup (IF_OIFS_PARAMS (ifp), (struct prefix*)&p); - - if (rn) - { - route_unlock_node (rn); - return rn->info; - } - - return NULL; + struct prefix_ipv4 p; + struct route_node *rn; + + p.family = AF_INET; + p.prefixlen = IPV4_MAX_PREFIXLEN; + p.prefix = addr; + + rn = route_node_lookup(IF_OIFS_PARAMS(ifp), (struct prefix *)&p); + + if (rn) { + route_unlock_node(rn); + return rn->info; + } + + return NULL; } -struct ospf_if_params * -ospf_get_if_params (struct interface *ifp, struct in_addr addr) +struct ospf_if_params *ospf_get_if_params(struct interface *ifp, + struct in_addr addr) { - struct prefix_ipv4 p; - struct route_node *rn; - - p.family = AF_INET; - p.prefixlen = IPV4_MAX_PREFIXLEN; - p.prefix = addr; - - rn = route_node_get (IF_OIFS_PARAMS (ifp), (struct prefix*)&p); - - if (rn->info == NULL) - rn->info = ospf_new_if_params (); - else - route_unlock_node (rn); - - return rn->info; + struct prefix_ipv4 p; + struct route_node *rn; + + p.family = AF_INET; + p.prefixlen = IPV4_MAX_PREFIXLEN; + p.prefix = addr; + + rn = route_node_get(IF_OIFS_PARAMS(ifp), (struct prefix *)&p); + + if (rn->info == NULL) + rn->info = ospf_new_if_params(); + else + route_unlock_node(rn); + + return rn->info; } -void -ospf_if_update_params (struct interface *ifp, struct in_addr addr) +void ospf_if_update_params(struct interface *ifp, struct in_addr addr) { - struct route_node *rn; - struct ospf_interface *oi; - - for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn)) - { - if ((oi = rn->info) == NULL) - continue; - - if (IPV4_ADDR_SAME (&oi->address->u.prefix4, &addr)) - oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4); - } + struct route_node *rn; + struct ospf_interface *oi; + + for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) { + if ((oi = rn->info) == NULL) + continue; + + if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &addr)) + oi->params = ospf_lookup_if_params( + ifp, oi->address->u.prefix4); + } } -int -ospf_if_new_hook (struct interface *ifp) +int ospf_if_new_hook(struct interface *ifp) { - int rc = 0; - - ifp->info = XCALLOC (MTYPE_OSPF_IF_INFO, sizeof (struct ospf_if_info)); - - IF_OIFS (ifp) = route_table_init (); - IF_OIFS_PARAMS (ifp) = route_table_init (); - - IF_DEF_PARAMS (ifp) = ospf_new_if_params (); - - SET_IF_PARAM (IF_DEF_PARAMS (ifp), transmit_delay); - IF_DEF_PARAMS (ifp)->transmit_delay = OSPF_TRANSMIT_DELAY_DEFAULT; - - SET_IF_PARAM (IF_DEF_PARAMS (ifp), retransmit_interval); - IF_DEF_PARAMS (ifp)->retransmit_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT; - - SET_IF_PARAM (IF_DEF_PARAMS (ifp), priority); - IF_DEF_PARAMS (ifp)->priority = OSPF_ROUTER_PRIORITY_DEFAULT; - - IF_DEF_PARAMS (ifp)->mtu_ignore = OSPF_MTU_IGNORE_DEFAULT; - - SET_IF_PARAM (IF_DEF_PARAMS (ifp), v_hello); - IF_DEF_PARAMS (ifp)->v_hello = OSPF_HELLO_INTERVAL_DEFAULT; - - SET_IF_PARAM (IF_DEF_PARAMS (ifp), fast_hello); - IF_DEF_PARAMS (ifp)->fast_hello = OSPF_FAST_HELLO_DEFAULT; - - SET_IF_PARAM (IF_DEF_PARAMS (ifp), v_wait); - IF_DEF_PARAMS (ifp)->v_wait = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT; - - SET_IF_PARAM (IF_DEF_PARAMS (ifp), auth_simple); - memset (IF_DEF_PARAMS (ifp)->auth_simple, 0, OSPF_AUTH_SIMPLE_SIZE); - - SET_IF_PARAM (IF_DEF_PARAMS (ifp), auth_type); - IF_DEF_PARAMS (ifp)->auth_type = OSPF_AUTH_NOTSET; - - rc = ospf_opaque_new_if (ifp); - return rc; + int rc = 0; + + ifp->info = XCALLOC(MTYPE_OSPF_IF_INFO, sizeof(struct ospf_if_info)); + + IF_OIFS(ifp) = route_table_init(); + IF_OIFS_PARAMS(ifp) = route_table_init(); + + IF_DEF_PARAMS(ifp) = ospf_new_if_params(); + + SET_IF_PARAM(IF_DEF_PARAMS(ifp), transmit_delay); + IF_DEF_PARAMS(ifp)->transmit_delay = OSPF_TRANSMIT_DELAY_DEFAULT; + + SET_IF_PARAM(IF_DEF_PARAMS(ifp), retransmit_interval); + IF_DEF_PARAMS(ifp)->retransmit_interval = + OSPF_RETRANSMIT_INTERVAL_DEFAULT; + + SET_IF_PARAM(IF_DEF_PARAMS(ifp), priority); + IF_DEF_PARAMS(ifp)->priority = OSPF_ROUTER_PRIORITY_DEFAULT; + + IF_DEF_PARAMS(ifp)->mtu_ignore = OSPF_MTU_IGNORE_DEFAULT; + + SET_IF_PARAM(IF_DEF_PARAMS(ifp), v_hello); + IF_DEF_PARAMS(ifp)->v_hello = OSPF_HELLO_INTERVAL_DEFAULT; + + SET_IF_PARAM(IF_DEF_PARAMS(ifp), fast_hello); + IF_DEF_PARAMS(ifp)->fast_hello = OSPF_FAST_HELLO_DEFAULT; + + SET_IF_PARAM(IF_DEF_PARAMS(ifp), v_wait); + IF_DEF_PARAMS(ifp)->v_wait = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT; + + SET_IF_PARAM(IF_DEF_PARAMS(ifp), auth_simple); + memset(IF_DEF_PARAMS(ifp)->auth_simple, 0, OSPF_AUTH_SIMPLE_SIZE); + + SET_IF_PARAM(IF_DEF_PARAMS(ifp), auth_type); + IF_DEF_PARAMS(ifp)->auth_type = OSPF_AUTH_NOTSET; + + rc = ospf_opaque_new_if(ifp); + return rc; } -static int -ospf_if_delete_hook (struct interface *ifp) +static int ospf_if_delete_hook(struct interface *ifp) { - int rc = 0; - struct route_node *rn; - rc = ospf_opaque_del_if (ifp); + int rc = 0; + struct route_node *rn; + rc = ospf_opaque_del_if(ifp); - route_table_finish (IF_OIFS (ifp)); + route_table_finish(IF_OIFS(ifp)); - for (rn = route_top (IF_OIFS_PARAMS (ifp)); rn; rn = route_next (rn)) - if (rn->info) - ospf_del_if_params (rn->info); - route_table_finish (IF_OIFS_PARAMS (ifp)); + for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn)) + if (rn->info) + ospf_del_if_params(rn->info); + route_table_finish(IF_OIFS_PARAMS(ifp)); - ospf_del_if_params ((struct ospf_if_params *) IF_DEF_PARAMS (ifp)); - XFREE (MTYPE_OSPF_IF_INFO, ifp->info); - ifp->info = NULL; + ospf_del_if_params((struct ospf_if_params *)IF_DEF_PARAMS(ifp)); + XFREE(MTYPE_OSPF_IF_INFO, ifp->info); + ifp->info = NULL; - return rc; + return rc; } -int -ospf_if_is_enable (struct ospf_interface *oi) +int ospf_if_is_enable(struct ospf_interface *oi) { - if (!if_is_loopback (oi->ifp)) - if (if_is_up (oi->ifp)) - return 1; + if (!if_is_loopback(oi->ifp)) + if (if_is_up(oi->ifp)) + return 1; - return 0; + return 0; } -void -ospf_if_set_multicast(struct ospf_interface *oi) +void ospf_if_set_multicast(struct ospf_interface *oi) { - if ((oi->state > ISM_Loopback) && - (oi->type != OSPF_IFTYPE_LOOPBACK) && - (oi->type != OSPF_IFTYPE_VIRTUALLINK) && - (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_ACTIVE)) - { - /* The interface should belong to the OSPF-all-routers group. */ - if (!OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS) && - (ospf_if_add_allspfrouters(oi->ospf, oi->address, - oi->ifp->ifindex) >= 0)) - /* Set the flag only if the system call to join succeeded. */ - OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS); - } - else - { - /* The interface should NOT belong to the OSPF-all-routers group. */ - if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS)) - { - /* Only actually drop if this is the last reference */ - if (OI_MEMBER_COUNT(oi, MEMBER_ALLROUTERS) == 1) - ospf_if_drop_allspfrouters (oi->ospf, oi->address, - oi->ifp->ifindex); - /* Unset the flag regardless of whether the system call to leave - the group succeeded, since it's much safer to assume that - we are not a member. */ - OI_MEMBER_LEFT(oi,MEMBER_ALLROUTERS); - } - } - - if (((oi->type == OSPF_IFTYPE_BROADCAST) || - (oi->type == OSPF_IFTYPE_POINTOPOINT)) && - ((oi->state == ISM_DR) || (oi->state == ISM_Backup)) && - (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_ACTIVE)) - { - /* The interface should belong to the OSPF-designated-routers group. */ - if (!OI_MEMBER_CHECK(oi, MEMBER_DROUTERS) && - (ospf_if_add_alldrouters(oi->ospf, oi->address, - oi->ifp->ifindex) >= 0)) - /* Set the flag only if the system call to join succeeded. */ - OI_MEMBER_JOINED(oi, MEMBER_DROUTERS); - } - else - { - /* The interface should NOT belong to the OSPF-designated-routers group */ - if (OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) - { - /* drop only if last reference */ - if (OI_MEMBER_COUNT(oi, MEMBER_DROUTERS) == 1) - ospf_if_drop_alldrouters(oi->ospf, oi->address, oi->ifp->ifindex); - - /* Unset the flag regardless of whether the system call to leave - the group succeeded, since it's much safer to assume that - we are not a member. */ - OI_MEMBER_LEFT(oi, MEMBER_DROUTERS); - } - } + if ((oi->state > ISM_Loopback) && (oi->type != OSPF_IFTYPE_LOOPBACK) + && (oi->type != OSPF_IFTYPE_VIRTUALLINK) + && (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_ACTIVE)) { + /* The interface should belong to the OSPF-all-routers group. */ + if (!OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS) + && (ospf_if_add_allspfrouters(oi->ospf, oi->address, + oi->ifp->ifindex) + >= 0)) + /* Set the flag only if the system call to join + * succeeded. */ + OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS); + } else { + /* The interface should NOT belong to the OSPF-all-routers + * group. */ + if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS)) { + /* Only actually drop if this is the last reference */ + if (OI_MEMBER_COUNT(oi, MEMBER_ALLROUTERS) == 1) + ospf_if_drop_allspfrouters(oi->ospf, + oi->address, + oi->ifp->ifindex); + /* Unset the flag regardless of whether the system call + to leave + the group succeeded, since it's much safer to assume + that + we are not a member. */ + OI_MEMBER_LEFT(oi, MEMBER_ALLROUTERS); + } + } + + if (((oi->type == OSPF_IFTYPE_BROADCAST) + || (oi->type == OSPF_IFTYPE_POINTOPOINT)) + && ((oi->state == ISM_DR) || (oi->state == ISM_Backup)) + && (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_ACTIVE)) { + /* The interface should belong to the OSPF-designated-routers + * group. */ + if (!OI_MEMBER_CHECK(oi, MEMBER_DROUTERS) + && (ospf_if_add_alldrouters(oi->ospf, oi->address, + oi->ifp->ifindex) + >= 0)) + /* Set the flag only if the system call to join + * succeeded. */ + OI_MEMBER_JOINED(oi, MEMBER_DROUTERS); + } else { + /* The interface should NOT belong to the + * OSPF-designated-routers group */ + if (OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) { + /* drop only if last reference */ + if (OI_MEMBER_COUNT(oi, MEMBER_DROUTERS) == 1) + ospf_if_drop_alldrouters(oi->ospf, oi->address, + oi->ifp->ifindex); + + /* Unset the flag regardless of whether the system call + to leave + the group succeeded, since it's much safer to assume + that + we are not a member. */ + OI_MEMBER_LEFT(oi, MEMBER_DROUTERS); + } + } } -int -ospf_if_up (struct ospf_interface *oi) +int ospf_if_up(struct ospf_interface *oi) { - if (oi == NULL) - return 0; - - if (oi->type == OSPF_IFTYPE_LOOPBACK) - OSPF_ISM_EVENT_SCHEDULE (oi, ISM_LoopInd); - else - { - ospf_if_stream_set (oi); - OSPF_ISM_EVENT_SCHEDULE (oi, ISM_InterfaceUp); - } - - return 1; + if (oi == NULL) + return 0; + + if (oi->type == OSPF_IFTYPE_LOOPBACK) + OSPF_ISM_EVENT_SCHEDULE(oi, ISM_LoopInd); + else { + ospf_if_stream_set(oi); + OSPF_ISM_EVENT_SCHEDULE(oi, ISM_InterfaceUp); + } + + return 1; } -int -ospf_if_down (struct ospf_interface *oi) +int ospf_if_down(struct ospf_interface *oi) { - if (oi == NULL) - return 0; + if (oi == NULL) + return 0; - OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceDown); - /* delete position in router LSA */ - oi->lsa_pos_beg = 0; - oi->lsa_pos_end = 0; - /* Shutdown packet reception and sending */ - ospf_if_stream_unset (oi); + OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceDown); + /* delete position in router LSA */ + oi->lsa_pos_beg = 0; + oi->lsa_pos_end = 0; + /* Shutdown packet reception and sending */ + ospf_if_stream_unset(oi); - return 1; + return 1; } /* Virtual Link related functions. */ -struct ospf_vl_data * -ospf_vl_data_new (struct ospf_area *area, struct in_addr vl_peer) +struct ospf_vl_data *ospf_vl_data_new(struct ospf_area *area, + struct in_addr vl_peer) { - struct ospf_vl_data *vl_data; + struct ospf_vl_data *vl_data; - vl_data = XCALLOC (MTYPE_OSPF_VL_DATA, sizeof (struct ospf_vl_data)); + vl_data = XCALLOC(MTYPE_OSPF_VL_DATA, sizeof(struct ospf_vl_data)); - vl_data->vl_peer.s_addr = vl_peer.s_addr; - vl_data->vl_area_id = area->area_id; - vl_data->vl_area_id_fmt = area->area_id_fmt; + vl_data->vl_peer.s_addr = vl_peer.s_addr; + vl_data->vl_area_id = area->area_id; + vl_data->vl_area_id_fmt = area->area_id_fmt; - return vl_data; + return vl_data; } -void -ospf_vl_data_free (struct ospf_vl_data *vl_data) +void ospf_vl_data_free(struct ospf_vl_data *vl_data) { - XFREE (MTYPE_OSPF_VL_DATA, vl_data); + XFREE(MTYPE_OSPF_VL_DATA, vl_data); } u_int vlink_count = 0; -struct ospf_interface * -ospf_vl_new (struct ospf *ospf, struct ospf_vl_data *vl_data) +struct ospf_interface *ospf_vl_new(struct ospf *ospf, + struct ospf_vl_data *vl_data) { - struct ospf_interface * voi; - struct interface * vi; - char ifname[INTERFACE_NAMSIZ + 1]; - struct ospf_area *area; - struct in_addr area_id; - struct connected *co; - struct prefix_ipv4 *p; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_vl_new(): Start"); - if (vlink_count == OSPF_VL_MAX_COUNT) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_vl_new(): Alarm: " - "cannot create more than OSPF_MAX_VL_COUNT virtual links"); - return NULL; - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_vl_new(): creating pseudo zebra interface"); - - snprintf (ifname, sizeof(ifname), "VLINK%d", vlink_count); - vi = if_create (ifname, strnlen(ifname, sizeof(ifname)), VRF_DEFAULT); - /* - * if_create sets ZEBRA_INTERFACE_LINKDETECTION - * virtual links don't need this. - */ - UNSET_FLAG (vi->status, ZEBRA_INTERFACE_LINKDETECTION); - co = connected_new (); - co->ifp = vi; - listnode_add (vi->connected, co); - - p = prefix_ipv4_new (); - p->family = AF_INET; - p->prefix.s_addr = 0; - p->prefixlen = 0; - - co->address = (struct prefix *)p; - - voi = ospf_if_new (ospf, vi, co->address); - if (voi == NULL) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_vl_new(): Alarm: OSPF int structure is not created"); - return NULL; - } - voi->connected = co; - voi->vl_data = vl_data; - voi->ifp->mtu = OSPF_VL_MTU; - voi->type = OSPF_IFTYPE_VIRTUALLINK; - - vlink_count++; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_vl_new(): Created name: %s", ifname); - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_vl_new(): set if->name to %s", vi->name); - - area_id.s_addr = 0; - area = ospf_area_get (ospf, area_id); - voi->area = area; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_vl_new(): set associated area to the backbone"); - - /* Add pseudo neighbor. */ - ospf_nbr_self_reset (voi, voi->ospf->router_id); - - ospf_area_add_if (voi->area, voi); - - ospf_if_stream_set (voi); - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_vl_new(): Stop"); - return voi; + struct ospf_interface *voi; + struct interface *vi; + char ifname[INTERFACE_NAMSIZ + 1]; + struct ospf_area *area; + struct in_addr area_id; + struct connected *co; + struct prefix_ipv4 *p; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_vl_new(): Start"); + if (vlink_count == OSPF_VL_MAX_COUNT) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_vl_new(): Alarm: " + "cannot create more than OSPF_MAX_VL_COUNT virtual links"); + return NULL; + } + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_vl_new(): creating pseudo zebra interface"); + + snprintf(ifname, sizeof(ifname), "VLINK%d", vlink_count); + vi = if_create(ifname, strnlen(ifname, sizeof(ifname)), VRF_DEFAULT); + /* + * if_create sets ZEBRA_INTERFACE_LINKDETECTION + * virtual links don't need this. + */ + UNSET_FLAG(vi->status, ZEBRA_INTERFACE_LINKDETECTION); + co = connected_new(); + co->ifp = vi; + listnode_add(vi->connected, co); + + p = prefix_ipv4_new(); + p->family = AF_INET; + p->prefix.s_addr = 0; + p->prefixlen = 0; + + co->address = (struct prefix *)p; + + voi = ospf_if_new(ospf, vi, co->address); + if (voi == NULL) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_vl_new(): Alarm: OSPF int structure is not created"); + return NULL; + } + voi->connected = co; + voi->vl_data = vl_data; + voi->ifp->mtu = OSPF_VL_MTU; + voi->type = OSPF_IFTYPE_VIRTUALLINK; + + vlink_count++; + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_vl_new(): Created name: %s", ifname); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_vl_new(): set if->name to %s", vi->name); + + area_id.s_addr = 0; + area = ospf_area_get(ospf, area_id); + voi->area = area; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_vl_new(): set associated area to the backbone"); + + /* Add pseudo neighbor. */ + ospf_nbr_self_reset(voi, voi->ospf->router_id); + + ospf_area_add_if(voi->area, voi); + + ospf_if_stream_set(voi); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_vl_new(): Stop"); + return voi; } -static void -ospf_vl_if_delete (struct ospf_vl_data *vl_data) +static void ospf_vl_if_delete(struct ospf_vl_data *vl_data) { - struct interface *ifp = vl_data->vl_oi->ifp; - vl_data->vl_oi->address->u.prefix4.s_addr = 0; - vl_data->vl_oi->address->prefixlen = 0; - ospf_if_free (vl_data->vl_oi); - if_delete (ifp); - vlink_count--; + struct interface *ifp = vl_data->vl_oi->ifp; + vl_data->vl_oi->address->u.prefix4.s_addr = 0; + vl_data->vl_oi->address->prefixlen = 0; + ospf_if_free(vl_data->vl_oi); + if_delete(ifp); + vlink_count--; } /* Look up vl_data for given peer, optionally qualified to be in the * specified area. NULL area returns first found.. */ -struct ospf_vl_data * -ospf_vl_lookup (struct ospf *ospf, struct ospf_area *area, - struct in_addr vl_peer) +struct ospf_vl_data *ospf_vl_lookup(struct ospf *ospf, struct ospf_area *area, + struct in_addr vl_peer) { - struct ospf_vl_data *vl_data; - struct listnode *node; - - if (IS_DEBUG_OSPF_EVENT) - { - zlog_debug ("%s: Looking for %s", __func__, inet_ntoa (vl_peer)); - if (area) - zlog_debug ("%s: in area %s", __func__, inet_ntoa (area->area_id)); - } - - for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("%s: VL %s, peer %s", __func__, - vl_data->vl_oi->ifp->name, - inet_ntoa (vl_data->vl_peer)); - - if (area && !IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id)) - continue; - - if (IPV4_ADDR_SAME (&vl_data->vl_peer, &vl_peer)) - return vl_data; - } - - return NULL; + struct ospf_vl_data *vl_data; + struct listnode *node; + + if (IS_DEBUG_OSPF_EVENT) { + zlog_debug("%s: Looking for %s", __func__, inet_ntoa(vl_peer)); + if (area) + zlog_debug("%s: in area %s", __func__, + inet_ntoa(area->area_id)); + } + + for (ALL_LIST_ELEMENTS_RO(ospf->vlinks, node, vl_data)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("%s: VL %s, peer %s", __func__, + vl_data->vl_oi->ifp->name, + inet_ntoa(vl_data->vl_peer)); + + if (area + && !IPV4_ADDR_SAME(&vl_data->vl_area_id, &area->area_id)) + continue; + + if (IPV4_ADDR_SAME(&vl_data->vl_peer, &vl_peer)) + return vl_data; + } + + return NULL; } -static void -ospf_vl_shutdown (struct ospf_vl_data *vl_data) +static void ospf_vl_shutdown(struct ospf_vl_data *vl_data) { - struct ospf_interface *oi; + struct ospf_interface *oi; - if ((oi = vl_data->vl_oi) == NULL) - return; + if ((oi = vl_data->vl_oi) == NULL) + return; - oi->address->u.prefix4.s_addr = 0; - oi->address->prefixlen = 0; + oi->address->u.prefix4.s_addr = 0; + oi->address->prefixlen = 0; - UNSET_FLAG (oi->ifp->flags, IFF_UP); - /* OSPF_ISM_EVENT_SCHEDULE (oi, ISM_InterfaceDown); */ - OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceDown); + UNSET_FLAG(oi->ifp->flags, IFF_UP); + /* OSPF_ISM_EVENT_SCHEDULE (oi, ISM_InterfaceDown); */ + OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceDown); } -void -ospf_vl_add (struct ospf *ospf, struct ospf_vl_data *vl_data) +void ospf_vl_add(struct ospf *ospf, struct ospf_vl_data *vl_data) { - listnode_add (ospf->vlinks, vl_data); - hook_call(ospf_vl_add, vl_data); + listnode_add(ospf->vlinks, vl_data); + hook_call(ospf_vl_add, vl_data); } -void -ospf_vl_delete (struct ospf *ospf, struct ospf_vl_data *vl_data) +void ospf_vl_delete(struct ospf *ospf, struct ospf_vl_data *vl_data) { - ospf_vl_shutdown (vl_data); - ospf_vl_if_delete (vl_data); + ospf_vl_shutdown(vl_data); + ospf_vl_if_delete(vl_data); - hook_call(ospf_vl_delete, vl_data); - listnode_delete (ospf->vlinks, vl_data); + hook_call(ospf_vl_delete, vl_data); + listnode_delete(ospf->vlinks, vl_data); - ospf_vl_data_free (vl_data); + ospf_vl_data_free(vl_data); } -static int -ospf_vl_set_params (struct ospf_vl_data *vl_data, struct vertex *v) +static int ospf_vl_set_params(struct ospf_vl_data *vl_data, struct vertex *v) { - int changed = 0; - struct ospf_interface *voi; - struct listnode *node; - struct vertex_parent *vp = NULL; - unsigned int i; - struct router_lsa *rl; - - voi = vl_data->vl_oi; - - if (voi->output_cost != v->distance) - { - - voi->output_cost = v->distance; - changed = 1; - } - - for (ALL_LIST_ELEMENTS_RO (v->parents, node, vp)) - { - vl_data->nexthop.oi = vp->nexthop->oi; - vl_data->nexthop.router = vp->nexthop->router; - - if (!IPV4_ADDR_SAME(&voi->address->u.prefix4, - &vl_data->nexthop.oi->address->u.prefix4)) - changed = 1; - - voi->address->u.prefix4 = vl_data->nexthop.oi->address->u.prefix4; - voi->address->prefixlen = vl_data->nexthop.oi->address->prefixlen; - - break; /* We take the first interface. */ - } - - rl = (struct router_lsa *)v->lsa; - - /* use SPF determined backlink index in struct vertex - * for virtual link destination address - */ - if (vp && vp->backlink >= 0) - { - if (!IPV4_ADDR_SAME (&vl_data->peer_addr, - &rl->link[vp->backlink].link_data)) - changed = 1; - vl_data->peer_addr = rl->link[vp->backlink].link_data; - } - else - { - /* This is highly odd, there is no backlink index - * there should be due to the ospf_spf_has_link() check - * in SPF. Lets warn and try pick a link anyway. - */ - zlog_warn ("ospf_vl_set_params: No backlink for %s!", - vl_data->vl_oi->ifp->name); - for (i = 0; i < ntohs (rl->links); i++) - { - switch (rl->link[i].type) - { - case LSA_LINK_TYPE_VIRTUALLINK: - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("found back link through VL"); - /* fallthru */ - case LSA_LINK_TYPE_TRANSIT: - case LSA_LINK_TYPE_POINTOPOINT: - if (!IPV4_ADDR_SAME (&vl_data->peer_addr, - &rl->link[i].link_data)) - changed = 1; - vl_data->peer_addr = rl->link[i].link_data; - } - } - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("%s: %s peer address: %s, cost: %d,%schanged", __func__, - vl_data->vl_oi->ifp->name, - inet_ntoa(vl_data->peer_addr), - voi->output_cost, - (changed ? " " : " un")); - - return changed; + int changed = 0; + struct ospf_interface *voi; + struct listnode *node; + struct vertex_parent *vp = NULL; + unsigned int i; + struct router_lsa *rl; + + voi = vl_data->vl_oi; + + if (voi->output_cost != v->distance) { + + voi->output_cost = v->distance; + changed = 1; + } + + for (ALL_LIST_ELEMENTS_RO(v->parents, node, vp)) { + vl_data->nexthop.oi = vp->nexthop->oi; + vl_data->nexthop.router = vp->nexthop->router; + + if (!IPV4_ADDR_SAME(&voi->address->u.prefix4, + &vl_data->nexthop.oi->address->u.prefix4)) + changed = 1; + + voi->address->u.prefix4 = + vl_data->nexthop.oi->address->u.prefix4; + voi->address->prefixlen = + vl_data->nexthop.oi->address->prefixlen; + + break; /* We take the first interface. */ + } + + rl = (struct router_lsa *)v->lsa; + + /* use SPF determined backlink index in struct vertex + * for virtual link destination address + */ + if (vp && vp->backlink >= 0) { + if (!IPV4_ADDR_SAME(&vl_data->peer_addr, + &rl->link[vp->backlink].link_data)) + changed = 1; + vl_data->peer_addr = rl->link[vp->backlink].link_data; + } else { + /* This is highly odd, there is no backlink index + * there should be due to the ospf_spf_has_link() check + * in SPF. Lets warn and try pick a link anyway. + */ + zlog_warn("ospf_vl_set_params: No backlink for %s!", + vl_data->vl_oi->ifp->name); + for (i = 0; i < ntohs(rl->links); i++) { + switch (rl->link[i].type) { + case LSA_LINK_TYPE_VIRTUALLINK: + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "found back link through VL"); + /* fallthru */ + case LSA_LINK_TYPE_TRANSIT: + case LSA_LINK_TYPE_POINTOPOINT: + if (!IPV4_ADDR_SAME(&vl_data->peer_addr, + &rl->link[i].link_data)) + changed = 1; + vl_data->peer_addr = rl->link[i].link_data; + } + } + } + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("%s: %s peer address: %s, cost: %d,%schanged", + __func__, vl_data->vl_oi->ifp->name, + inet_ntoa(vl_data->peer_addr), voi->output_cost, + (changed ? " " : " un")); + + return changed; } -void -ospf_vl_up_check (struct ospf_area *area, struct in_addr rid, - struct vertex *v) +void ospf_vl_up_check(struct ospf_area *area, struct in_addr rid, + struct vertex *v) { - struct ospf *ospf = area->ospf; - struct listnode *node; - struct ospf_vl_data *vl_data; - struct ospf_interface *oi; - - if (IS_DEBUG_OSPF_EVENT) - { - zlog_debug ("ospf_vl_up_check(): Start"); - zlog_debug ("ospf_vl_up_check(): Router ID is %s", inet_ntoa (rid)); - zlog_debug ("ospf_vl_up_check(): Area is %s", inet_ntoa (area->area_id)); - } - - for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data)) - { - if (IS_DEBUG_OSPF_EVENT) - { - zlog_debug ("%s: considering VL, %s in area %s", __func__, - vl_data->vl_oi->ifp->name, - inet_ntoa (vl_data->vl_area_id)); - zlog_debug ("%s: peer ID: %s", __func__, - inet_ntoa (vl_data->vl_peer)); + struct ospf *ospf = area->ospf; + struct listnode *node; + struct ospf_vl_data *vl_data; + struct ospf_interface *oi; + + if (IS_DEBUG_OSPF_EVENT) { + zlog_debug("ospf_vl_up_check(): Start"); + zlog_debug("ospf_vl_up_check(): Router ID is %s", + inet_ntoa(rid)); + zlog_debug("ospf_vl_up_check(): Area is %s", + inet_ntoa(area->area_id)); } - if (IPV4_ADDR_SAME (&vl_data->vl_peer, &rid) && - IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id)) - { - oi = vl_data->vl_oi; - SET_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED); - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_vl_up_check(): this VL matched"); - - if (oi->state == ISM_Down) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_vl_up_check(): VL is down, waking it up"); - SET_FLAG (oi->ifp->flags, IFF_UP); - OSPF_ISM_EVENT_EXECUTE(oi,ISM_InterfaceUp); - } - - if (ospf_vl_set_params (vl_data, v)) - { - if (IS_DEBUG_OSPF (ism, ISM_EVENTS)) - zlog_debug ("ospf_vl_up_check: VL cost change," - " scheduling router lsa refresh"); - if (ospf->backbone) - ospf_router_lsa_update_area (ospf->backbone); - else if (IS_DEBUG_OSPF (ism, ISM_EVENTS)) - zlog_debug ("ospf_vl_up_check: VL cost change, no backbone!"); - } - } - } + for (ALL_LIST_ELEMENTS_RO(ospf->vlinks, node, vl_data)) { + if (IS_DEBUG_OSPF_EVENT) { + zlog_debug("%s: considering VL, %s in area %s", + __func__, vl_data->vl_oi->ifp->name, + inet_ntoa(vl_data->vl_area_id)); + zlog_debug("%s: peer ID: %s", __func__, + inet_ntoa(vl_data->vl_peer)); + } + + if (IPV4_ADDR_SAME(&vl_data->vl_peer, &rid) + && IPV4_ADDR_SAME(&vl_data->vl_area_id, &area->area_id)) { + oi = vl_data->vl_oi; + SET_FLAG(vl_data->flags, OSPF_VL_FLAG_APPROVED); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_vl_up_check(): this VL matched"); + + if (oi->state == ISM_Down) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_vl_up_check(): VL is down, waking it up"); + SET_FLAG(oi->ifp->flags, IFF_UP); + OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceUp); + } + + if (ospf_vl_set_params(vl_data, v)) { + if (IS_DEBUG_OSPF(ism, ISM_EVENTS)) + zlog_debug( + "ospf_vl_up_check: VL cost change," + " scheduling router lsa refresh"); + if (ospf->backbone) + ospf_router_lsa_update_area( + ospf->backbone); + else if (IS_DEBUG_OSPF(ism, ISM_EVENTS)) + zlog_debug( + "ospf_vl_up_check: VL cost change, no backbone!"); + } + } + } } -void -ospf_vl_unapprove (struct ospf *ospf) +void ospf_vl_unapprove(struct ospf *ospf) { - struct listnode *node; - struct ospf_vl_data *vl_data; + struct listnode *node; + struct ospf_vl_data *vl_data; - for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data)) - UNSET_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED); + for (ALL_LIST_ELEMENTS_RO(ospf->vlinks, node, vl_data)) + UNSET_FLAG(vl_data->flags, OSPF_VL_FLAG_APPROVED); } -void -ospf_vl_shut_unapproved (struct ospf *ospf) +void ospf_vl_shut_unapproved(struct ospf *ospf) { - struct listnode *node, *nnode; - struct ospf_vl_data *vl_data; + struct listnode *node, *nnode; + struct ospf_vl_data *vl_data; - for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data)) - if (!CHECK_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED)) - ospf_vl_shutdown (vl_data); + for (ALL_LIST_ELEMENTS(ospf->vlinks, node, nnode, vl_data)) + if (!CHECK_FLAG(vl_data->flags, OSPF_VL_FLAG_APPROVED)) + ospf_vl_shutdown(vl_data); } -int -ospf_full_virtual_nbrs (struct ospf_area *area) +int ospf_full_virtual_nbrs(struct ospf_area *area) { - if (IS_DEBUG_OSPF_EVENT) - { - zlog_debug ("counting fully adjacent virtual neighbors in area %s", - inet_ntoa (area->area_id)); - zlog_debug ("there are %d of them", area->full_vls); - } - - return area->full_vls; + if (IS_DEBUG_OSPF_EVENT) { + zlog_debug( + "counting fully adjacent virtual neighbors in area %s", + inet_ntoa(area->area_id)); + zlog_debug("there are %d of them", area->full_vls); + } + + return area->full_vls; } -int -ospf_vls_in_area (struct ospf_area *area) +int ospf_vls_in_area(struct ospf_area *area) { - struct listnode *node; - struct ospf_vl_data *vl_data; - int c = 0; + struct listnode *node; + struct ospf_vl_data *vl_data; + int c = 0; - for (ALL_LIST_ELEMENTS_RO (area->ospf->vlinks, node, vl_data)) - if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id)) - c++; + for (ALL_LIST_ELEMENTS_RO(area->ospf->vlinks, node, vl_data)) + if (IPV4_ADDR_SAME(&vl_data->vl_area_id, &area->area_id)) + c++; - return c; + return c; } -struct crypt_key * -ospf_crypt_key_new () +struct crypt_key *ospf_crypt_key_new() { - return XCALLOC (MTYPE_OSPF_CRYPT_KEY, sizeof (struct crypt_key)); + return XCALLOC(MTYPE_OSPF_CRYPT_KEY, sizeof(struct crypt_key)); } -void -ospf_crypt_key_add (struct list *crypt, struct crypt_key *ck) +void ospf_crypt_key_add(struct list *crypt, struct crypt_key *ck) { - listnode_add (crypt, ck); + listnode_add(crypt, ck); } -struct crypt_key * -ospf_crypt_key_lookup (struct list *auth_crypt, u_char key_id) +struct crypt_key *ospf_crypt_key_lookup(struct list *auth_crypt, u_char key_id) { - struct listnode *node; - struct crypt_key *ck; + struct listnode *node; + struct crypt_key *ck; - for (ALL_LIST_ELEMENTS_RO (auth_crypt, node, ck)) - if (ck->key_id == key_id) - return ck; + for (ALL_LIST_ELEMENTS_RO(auth_crypt, node, ck)) + if (ck->key_id == key_id) + return ck; - return NULL; + return NULL; } -int -ospf_crypt_key_delete (struct list *auth_crypt, u_char key_id) +int ospf_crypt_key_delete(struct list *auth_crypt, u_char key_id) { - struct listnode *node, *nnode; - struct crypt_key *ck; - - for (ALL_LIST_ELEMENTS (auth_crypt, node, nnode, ck)) - { - if (ck->key_id == key_id) - { - listnode_delete (auth_crypt, ck); - XFREE (MTYPE_OSPF_CRYPT_KEY, ck); - return 1; - } - } - - return 0; + struct listnode *node, *nnode; + struct crypt_key *ck; + + for (ALL_LIST_ELEMENTS(auth_crypt, node, nnode, ck)) { + if (ck->key_id == key_id) { + listnode_delete(auth_crypt, ck); + XFREE(MTYPE_OSPF_CRYPT_KEY, ck); + return 1; + } + } + + return 0; } -u_char -ospf_default_iftype(struct interface *ifp) +u_char ospf_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; } -void -ospf_if_init () +void ospf_if_init() { - /* Initialize Zebra interface data structure. */ - om->iflist = vrf_iflist (VRF_DEFAULT); - if_add_hook (IF_NEW_HOOK, ospf_if_new_hook); - if_add_hook (IF_DELETE_HOOK, ospf_if_delete_hook); + /* Initialize Zebra interface data structure. */ + om->iflist = vrf_iflist(VRF_DEFAULT); + if_add_hook(IF_NEW_HOOK, ospf_if_new_hook); + if_add_hook(IF_DELETE_HOOK, ospf_if_delete_hook); } diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h index afb282010..d4b495b20 100644 --- a/ospfd/ospf_interface.h +++ b/ospfd/ospf_interface.h @@ -38,87 +38,93 @@ /* Test whether an OSPF interface parameter is set, generally, given some * existing ospf interface */ -#define OSPF_IF_PARAM_IS_SET(O,P) \ - (OSPF_IF_PARAM_CONFIGURED ((O)->params, P) || \ - OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS((O)->ifp)->P)) +#define OSPF_IF_PARAM_IS_SET(O, P) \ + (OSPF_IF_PARAM_CONFIGURED((O)->params, P) \ + || OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS((O)->ifp)->P)) -#define OSPF_IF_PARAM(O, P) \ - (OSPF_IF_PARAM_CONFIGURED ((O)->params, P)?\ - (O)->params->P:IF_DEF_PARAMS((O)->ifp)->P) +#define OSPF_IF_PARAM(O, P) \ + (OSPF_IF_PARAM_CONFIGURED((O)->params, P) \ + ? (O)->params->P \ + : IF_DEF_PARAMS((O)->ifp)->P) #define DECLARE_IF_PARAM(T, P) T P; u_char P##__config:1 #define UNSET_IF_PARAM(S, P) ((S)->P##__config) = 0 #define SET_IF_PARAM(S, P) ((S)->P##__config) = 1 -struct ospf_if_params -{ - DECLARE_IF_PARAM (u_int32_t, transmit_delay); /* Interface Transmisson Delay */ - DECLARE_IF_PARAM (u_int32_t, output_cost_cmd);/* Command Interface Output Cost */ - DECLARE_IF_PARAM (u_int32_t, retransmit_interval); /* Retransmission Interval */ - DECLARE_IF_PARAM (u_char, passive_interface); /* OSPF Interface is passive: no sending or receiving (no need to join multicast groups) */ - DECLARE_IF_PARAM (u_char, priority); /* OSPF Interface priority */ - /* Enable OSPF on this interface with area if_area */ - DECLARE_IF_PARAM (struct in_addr, if_area); - DECLARE_IF_PARAM (u_char, type); /* type of interface */ +struct ospf_if_params { + DECLARE_IF_PARAM(u_int32_t, + transmit_delay); /* Interface Transmisson Delay */ + DECLARE_IF_PARAM(u_int32_t, + output_cost_cmd); /* Command Interface Output Cost */ + DECLARE_IF_PARAM(u_int32_t, + retransmit_interval); /* Retransmission Interval */ + DECLARE_IF_PARAM(u_char, passive_interface); /* OSPF Interface is + passive: no sending or + receiving (no need to + join multicast groups) + */ + DECLARE_IF_PARAM(u_char, priority); /* OSPF Interface priority */ + /* Enable OSPF on this interface with area if_area */ + DECLARE_IF_PARAM(struct in_addr, if_area); + DECLARE_IF_PARAM(u_char, type); /* type of interface */ #define OSPF_IF_ACTIVE 0 #define OSPF_IF_PASSIVE 1 -#define OSPF_IF_PASSIVE_STATUS(O) \ - (OSPF_IF_PARAM_CONFIGURED((O)->params, passive_interface) ? \ - (O)->params->passive_interface : \ - (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS((O)->ifp), passive_interface) ? \ - IF_DEF_PARAMS((O)->ifp)->passive_interface : \ - (O)->ospf->passive_interface_default)) - - DECLARE_IF_PARAM (u_int32_t, v_hello); /* Hello Interval */ - DECLARE_IF_PARAM (u_int32_t, v_wait); /* Router Dead Interval */ - - /* MTU mismatch check (see RFC2328, chap 10.6) */ - DECLARE_IF_PARAM (u_char, mtu_ignore); - - /* Fast-Hellos */ - DECLARE_IF_PARAM (u_char, fast_hello); - - /* Authentication data. */ - u_char auth_simple[OSPF_AUTH_SIMPLE_SIZE + 1]; /* Simple password. */ - u_char auth_simple__config:1; - - DECLARE_IF_PARAM (struct list *, auth_crypt); /* List of Auth cryptographic data. */ - DECLARE_IF_PARAM (int, auth_type); /* OSPF authentication type */ - - /* Other, non-configuration state */ - u_int32_t network_lsa_seqnum; /* Network LSA seqnum */ - - /* BFD configuration */ - struct bfd_info *bfd_info; +#define OSPF_IF_PASSIVE_STATUS(O) \ + (OSPF_IF_PARAM_CONFIGURED((O)->params, passive_interface) \ + ? (O)->params->passive_interface \ + : (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS((O)->ifp), \ + passive_interface) \ + ? IF_DEF_PARAMS((O)->ifp)->passive_interface \ + : (O)->ospf->passive_interface_default)) + + DECLARE_IF_PARAM(u_int32_t, v_hello); /* Hello Interval */ + DECLARE_IF_PARAM(u_int32_t, v_wait); /* Router Dead Interval */ + + /* MTU mismatch check (see RFC2328, chap 10.6) */ + DECLARE_IF_PARAM(u_char, mtu_ignore); + + /* Fast-Hellos */ + DECLARE_IF_PARAM(u_char, fast_hello); + + /* Authentication data. */ + u_char auth_simple[OSPF_AUTH_SIMPLE_SIZE + 1]; /* Simple password. */ + u_char auth_simple__config : 1; + + DECLARE_IF_PARAM(struct list *, + auth_crypt); /* List of Auth cryptographic data. */ + DECLARE_IF_PARAM(int, auth_type); /* OSPF authentication type */ + + /* Other, non-configuration state */ + u_int32_t network_lsa_seqnum; /* Network LSA seqnum */ + + /* BFD configuration */ + struct bfd_info *bfd_info; }; -enum -{ - MEMBER_ALLROUTERS = 0, - MEMBER_DROUTERS, - MEMBER_MAX, +enum { MEMBER_ALLROUTERS = 0, + MEMBER_DROUTERS, + MEMBER_MAX, }; -struct ospf_if_info -{ - struct ospf_if_params *def_params; - struct route_table *params; - struct route_table *oifs; - unsigned int membership_counts[MEMBER_MAX]; /* multicast group refcnts */ +struct ospf_if_info { + struct ospf_if_params *def_params; + struct route_table *params; + struct route_table *oifs; + unsigned int + membership_counts[MEMBER_MAX]; /* multicast group refcnts */ }; struct ospf_interface; -struct ospf_vl_data -{ - struct in_addr vl_peer; /* Router-ID of the peer */ - struct in_addr vl_area_id; /* Transit area */ - int vl_area_id_fmt; /* Area ID format */ - struct ospf_interface *vl_oi; /* Interface data structure */ - struct vertex_nexthop nexthop; /* Nexthop router and oi to use */ - struct in_addr peer_addr; /* Address used to reach the peer */ - u_char flags; +struct ospf_vl_data { + struct in_addr vl_peer; /* Router-ID of the peer */ + struct in_addr vl_area_id; /* Transit area */ + int vl_area_id_fmt; /* Area ID format */ + struct ospf_interface *vl_oi; /* Interface data structure */ + struct vertex_nexthop nexthop; /* Nexthop router and oi to use */ + struct in_addr peer_addr; /* Address used to reach the peer */ + u_char flags; }; @@ -127,198 +133,193 @@ struct ospf_vl_data #define OSPF_VL_FLAG_APPROVED 0x01 -struct crypt_key -{ - u_char key_id; - u_char auth_key[OSPF_AUTH_MD5_SIZE + 1]; +struct crypt_key { + u_char key_id; + u_char auth_key[OSPF_AUTH_MD5_SIZE + 1]; }; /* OSPF interface structure. */ -struct ospf_interface -{ - /* This interface's parent ospf instance. */ - struct ospf *ospf; +struct ospf_interface { + /* This interface's parent ospf instance. */ + struct ospf *ospf; - /* OSPF Area. */ - struct ospf_area *area; + /* OSPF Area. */ + struct ospf_area *area; - /* Position range in Router LSA */ - uint16_t lsa_pos_beg; /* inclusive, >= */ - uint16_t lsa_pos_end; /* exclusive, < */ + /* Position range in Router LSA */ + uint16_t lsa_pos_beg; /* inclusive, >= */ + uint16_t lsa_pos_end; /* exclusive, < */ - /* Interface data from zebra. */ - struct interface *ifp; - struct ospf_vl_data *vl_data; /* Data for Virtual Link */ - - /* Packet send buffer. */ - struct ospf_fifo *obuf; /* Output queue */ + /* Interface data from zebra. */ + struct interface *ifp; + struct ospf_vl_data *vl_data; /* Data for Virtual Link */ - /* OSPF Network Type. */ - u_char type; + /* Packet send buffer. */ + struct ospf_fifo *obuf; /* Output queue */ - /* State of Interface State Machine. */ - u_char state; + /* OSPF Network Type. */ + u_char type; - /* To which multicast groups do we currently belong? */ - u_char multicast_memberships; + /* State of Interface State Machine. */ + u_char state; + + /* To which multicast groups do we currently belong? */ + u_char multicast_memberships; #define OI_MEMBER_FLAG(M) (1 << (M)) #define OI_MEMBER_COUNT(O,M) (IF_OSPF_IF_INFO(oi->ifp)->membership_counts[(M)]) -#define OI_MEMBER_CHECK(O,M) \ - (CHECK_FLAG((O)->multicast_memberships, OI_MEMBER_FLAG(M))) -#define OI_MEMBER_JOINED(O,M) \ - do { \ - SET_FLAG ((O)->multicast_memberships, OI_MEMBER_FLAG(M)); \ - IF_OSPF_IF_INFO((O)->ifp)->membership_counts[(M)]++; \ - } while (0) -#define OI_MEMBER_LEFT(O,M) \ - do { \ - UNSET_FLAG ((O)->multicast_memberships, OI_MEMBER_FLAG(M)); \ - IF_OSPF_IF_INFO((O)->ifp)->membership_counts[(M)]--; \ - } while (0) - - struct prefix *address; /* Interface prefix */ - struct connected *connected; /* Pointer to connected */ - - /* Configured varables. */ - struct ospf_if_params *params; - - u_int32_t crypt_seqnum; /* Cryptographic Sequence Number */ - u_int32_t output_cost; /* Acutual Interface Output Cost */ - - /* Neighbor information. */ - struct route_table *nbrs; /* OSPF Neighbor List */ - struct ospf_neighbor *nbr_self; /* Neighbor Self */ +#define OI_MEMBER_CHECK(O, M) \ + (CHECK_FLAG((O)->multicast_memberships, OI_MEMBER_FLAG(M))) +#define OI_MEMBER_JOINED(O, M) \ + do { \ + SET_FLAG((O)->multicast_memberships, OI_MEMBER_FLAG(M)); \ + IF_OSPF_IF_INFO((O)->ifp)->membership_counts[(M)]++; \ + } while (0) +#define OI_MEMBER_LEFT(O, M) \ + do { \ + UNSET_FLAG((O)->multicast_memberships, OI_MEMBER_FLAG(M)); \ + IF_OSPF_IF_INFO((O)->ifp)->membership_counts[(M)]--; \ + } while (0) + + struct prefix *address; /* Interface prefix */ + struct connected *connected; /* Pointer to connected */ + + /* Configured varables. */ + struct ospf_if_params *params; + + u_int32_t crypt_seqnum; /* Cryptographic Sequence Number */ + u_int32_t output_cost; /* Acutual Interface Output Cost */ + + /* Neighbor information. */ + struct route_table *nbrs; /* OSPF Neighbor List */ + struct ospf_neighbor *nbr_self; /* Neighbor Self */ + /* $FRR indent$ */ + /* clang-format off */ #define DR(I) ((I)->nbr_self->d_router) #define BDR(I) ((I)->nbr_self->bd_router) #define OPTIONS(I) ((I)->nbr_self->options) #define PRIORITY(I) ((I)->nbr_self->priority) - /* List of configured NBMA neighbor. */ - struct list *nbr_nbma; - - /* self-originated LSAs. */ - struct ospf_lsa *network_lsa_self; /* network-LSA. */ - struct list *opaque_lsa_self; /* Type-9 Opaque-LSAs */ - - struct route_table *ls_upd_queue; - - struct list *ls_ack; /* Link State Acknowledgment list. */ - - struct - { - struct list *ls_ack; - struct in_addr dst; - } ls_ack_direct; - - /* Timer values. */ - u_int32_t v_ls_ack; /* Delayed Link State Acknowledgment */ - - /* Threads. */ - struct thread *t_hello; /* timer */ - struct thread *t_wait; /* timer */ - struct thread *t_ls_ack; /* timer */ - struct thread *t_ls_ack_direct; /* event */ - struct thread *t_ls_upd_event; /* event */ - struct thread *t_opaque_lsa_self; /* Type-9 Opaque-LSAs */ - - int on_write_q; - - /* Statistics fields. */ - u_int32_t hello_in; /* Hello message input count. */ - u_int32_t hello_out; /* Hello message output count. */ - u_int32_t db_desc_in; /* database desc. message input count. */ - u_int32_t db_desc_out; /* database desc. message output count. */ - u_int32_t ls_req_in; /* LS request message input count. */ - u_int32_t ls_req_out; /* LS request message output count. */ - u_int32_t ls_upd_in; /* LS update message input count. */ - u_int32_t ls_upd_out; /* LS update message output count. */ - u_int32_t ls_ack_in; /* LS Ack message input count. */ - u_int32_t ls_ack_out; /* LS Ack message output count. */ - u_int32_t discarded; /* discarded input count by error. */ - u_int32_t state_change; /* Number of status change. */ - - u_int32_t full_nbrs; - - QOBJ_FIELDS + /* List of configured NBMA neighbor. */ + struct list *nbr_nbma; + + /* self-originated LSAs. */ + struct ospf_lsa *network_lsa_self; /* network-LSA. */ + struct list *opaque_lsa_self; /* Type-9 Opaque-LSAs */ + + struct route_table *ls_upd_queue; + + struct list *ls_ack; /* Link State Acknowledgment list. */ + + struct { + struct list *ls_ack; + struct in_addr dst; + } ls_ack_direct; + + /* Timer values. */ + u_int32_t v_ls_ack; /* Delayed Link State Acknowledgment */ + + /* Threads. */ + struct thread *t_hello; /* timer */ + struct thread *t_wait; /* timer */ + struct thread *t_ls_ack; /* timer */ + struct thread *t_ls_ack_direct; /* event */ + struct thread *t_ls_upd_event; /* event */ + struct thread *t_opaque_lsa_self; /* Type-9 Opaque-LSAs */ + + int on_write_q; + + /* Statistics fields. */ + u_int32_t hello_in; /* Hello message input count. */ + u_int32_t hello_out; /* Hello message output count. */ + u_int32_t db_desc_in; /* database desc. message input count. */ + u_int32_t db_desc_out; /* database desc. message output count. */ + u_int32_t ls_req_in; /* LS request message input count. */ + u_int32_t ls_req_out; /* LS request message output count. */ + u_int32_t ls_upd_in; /* LS update message input count. */ + u_int32_t ls_upd_out; /* LS update message output count. */ + u_int32_t ls_ack_in; /* LS Ack message input count. */ + u_int32_t ls_ack_out; /* LS Ack message output count. */ + u_int32_t discarded; /* discarded input count by error. */ + u_int32_t state_change; /* Number of status change. */ + + u_int32_t full_nbrs; + + QOBJ_FIELDS }; DECLARE_QOBJ_TYPE(ospf_interface) /* Prototypes. */ -extern char *ospf_if_name (struct ospf_interface *); -extern struct ospf_interface *ospf_if_new (struct ospf *, struct interface *, - struct prefix *); -extern void ospf_if_cleanup (struct ospf_interface *); -extern void ospf_if_free (struct ospf_interface *); -extern int ospf_if_up (struct ospf_interface *); -extern int ospf_if_down (struct ospf_interface *); - -extern int ospf_if_is_up (struct ospf_interface *); -extern struct ospf_interface *ospf_if_exists (struct ospf_interface *); -extern struct ospf_interface *ospf_if_lookup_by_lsa_pos (struct ospf_area *, - int); -extern struct ospf_interface *ospf_if_lookup_by_local_addr (struct ospf *, - struct interface - *, - struct in_addr); -extern struct ospf_interface *ospf_if_lookup_by_prefix (struct ospf *, - struct prefix_ipv4 *); -extern struct ospf_interface *ospf_if_table_lookup (struct interface *, - struct prefix *); -extern struct ospf_interface *ospf_if_addr_local (struct in_addr); -extern struct ospf_interface *ospf_if_lookup_recv_if (struct ospf *, - struct in_addr, - struct interface *); -extern struct ospf_interface *ospf_if_is_configured (struct ospf *, - struct in_addr *); - -extern struct ospf_if_params *ospf_lookup_if_params (struct interface *, - struct in_addr); -extern struct ospf_if_params *ospf_get_if_params (struct interface *, - struct in_addr); -extern void ospf_del_if_params (struct ospf_if_params *); -extern void ospf_free_if_params (struct interface *, struct in_addr); -extern void ospf_if_update_params (struct interface *, struct in_addr); - -extern int ospf_if_new_hook (struct interface *); -extern void ospf_if_init (void); -extern void ospf_if_stream_set (struct ospf_interface *); -extern void ospf_if_stream_unset (struct ospf_interface *); -extern void ospf_if_reset_variables (struct ospf_interface *); -extern int ospf_if_is_enable (struct ospf_interface *); -extern int ospf_if_get_output_cost (struct ospf_interface *); -extern void ospf_if_recalculate_output_cost (struct interface *); +extern char *ospf_if_name(struct ospf_interface *); +extern struct ospf_interface *ospf_if_new(struct ospf *, struct interface *, + struct prefix *); +extern void ospf_if_cleanup(struct ospf_interface *); +extern void ospf_if_free(struct ospf_interface *); +extern int ospf_if_up(struct ospf_interface *); +extern int ospf_if_down(struct ospf_interface *); + +extern int ospf_if_is_up(struct ospf_interface *); +extern struct ospf_interface *ospf_if_exists(struct ospf_interface *); +extern struct ospf_interface *ospf_if_lookup_by_lsa_pos(struct ospf_area *, + int); +extern struct ospf_interface * +ospf_if_lookup_by_local_addr(struct ospf *, struct interface *, struct in_addr); +extern struct ospf_interface *ospf_if_lookup_by_prefix(struct ospf *, + struct prefix_ipv4 *); +extern struct ospf_interface *ospf_if_table_lookup(struct interface *, + struct prefix *); +extern struct ospf_interface *ospf_if_addr_local(struct in_addr); +extern struct ospf_interface * +ospf_if_lookup_recv_if(struct ospf *, struct in_addr, struct interface *); +extern struct ospf_interface *ospf_if_is_configured(struct ospf *, + struct in_addr *); + +extern struct ospf_if_params *ospf_lookup_if_params(struct interface *, + struct in_addr); +extern struct ospf_if_params *ospf_get_if_params(struct interface *, + struct in_addr); +extern void ospf_del_if_params(struct ospf_if_params *); +extern void ospf_free_if_params(struct interface *, struct in_addr); +extern void ospf_if_update_params(struct interface *, struct in_addr); + +extern int ospf_if_new_hook(struct interface *); +extern void ospf_if_init(void); +extern void ospf_if_stream_set(struct ospf_interface *); +extern void ospf_if_stream_unset(struct ospf_interface *); +extern void ospf_if_reset_variables(struct ospf_interface *); +extern int ospf_if_is_enable(struct ospf_interface *); +extern int ospf_if_get_output_cost(struct ospf_interface *); +extern void ospf_if_recalculate_output_cost(struct interface *); /* Simulate down/up on the interface. */ -extern void ospf_if_reset (struct interface *); - -extern struct ospf_interface *ospf_vl_new (struct ospf *, - struct ospf_vl_data *); -extern struct ospf_vl_data *ospf_vl_data_new (struct ospf_area *, - struct in_addr); -extern struct ospf_vl_data *ospf_vl_lookup (struct ospf *, struct ospf_area *, - struct in_addr); -extern void ospf_vl_data_free (struct ospf_vl_data *); -extern void ospf_vl_add (struct ospf *, struct ospf_vl_data *); -extern void ospf_vl_delete (struct ospf *, struct ospf_vl_data *); -extern void ospf_vl_up_check (struct ospf_area *, struct in_addr, - struct vertex *); -extern void ospf_vl_unapprove (struct ospf *); -extern void ospf_vl_shut_unapproved (struct ospf *); -extern int ospf_full_virtual_nbrs (struct ospf_area *); -extern int ospf_vls_in_area (struct ospf_area *); - -extern struct crypt_key *ospf_crypt_key_lookup (struct list *, u_char); -extern struct crypt_key *ospf_crypt_key_new (void); -extern void ospf_crypt_key_add (struct list *, struct crypt_key *); -extern int ospf_crypt_key_delete (struct list *, u_char); - -extern u_char ospf_default_iftype (struct interface *ifp); +extern void ospf_if_reset(struct interface *); + +extern struct ospf_interface *ospf_vl_new(struct ospf *, struct ospf_vl_data *); +extern struct ospf_vl_data *ospf_vl_data_new(struct ospf_area *, + struct in_addr); +extern struct ospf_vl_data *ospf_vl_lookup(struct ospf *, struct ospf_area *, + struct in_addr); +extern void ospf_vl_data_free(struct ospf_vl_data *); +extern void ospf_vl_add(struct ospf *, struct ospf_vl_data *); +extern void ospf_vl_delete(struct ospf *, struct ospf_vl_data *); +extern void ospf_vl_up_check(struct ospf_area *, struct in_addr, + struct vertex *); +extern void ospf_vl_unapprove(struct ospf *); +extern void ospf_vl_shut_unapproved(struct ospf *); +extern int ospf_full_virtual_nbrs(struct ospf_area *); +extern int ospf_vls_in_area(struct ospf_area *); + +extern struct crypt_key *ospf_crypt_key_lookup(struct list *, u_char); +extern struct crypt_key *ospf_crypt_key_new(void); +extern void ospf_crypt_key_add(struct list *, struct crypt_key *); +extern int ospf_crypt_key_delete(struct list *, u_char); + +extern u_char ospf_default_iftype(struct interface *ifp); /* Set all multicast memberships appropriately based on the type and state of the interface. */ -extern void ospf_if_set_multicast (struct ospf_interface *); +extern void ospf_if_set_multicast(struct ospf_interface *); -DECLARE_HOOK(ospf_vl_add, (struct ospf_vl_data *vd), (vd)) -DECLARE_HOOK(ospf_vl_delete, (struct ospf_vl_data *vd), (vd)) +DECLARE_HOOK(ospf_vl_add, (struct ospf_vl_data * vd), (vd)) +DECLARE_HOOK(ospf_vl_delete, (struct ospf_vl_data * vd), (vd)) #endif /* _ZEBRA_OSPF_INTERFACE_H */ diff --git a/ospfd/ospf_ism.c b/ospfd/ospf_ism.c index b536491d8..f223a870d 100644 --- a/ospfd/ospf_ism.c +++ b/ospfd/ospf_ism.c @@ -1,6 +1,6 @@ /* * OSPF version 2 Interface State Machine - * From RFC2328 [OSPF Version 2] + * From RFC2328 [OSPF Version 2] * Copyright (C) 1999, 2000 Toshiaki Takada * * This file is part of GNU Zebra. @@ -44,578 +44,560 @@ #include "ospfd/ospf_abr.h" DEFINE_HOOK(ospf_ism_change, - (struct ospf_interface *oi, int state, int oldstate), - (oi, state, oldstate)) + (struct ospf_interface * oi, int state, int oldstate), + (oi, state, oldstate)) /* elect DR and BDR. Refer to RFC2319 section 9.4 */ -static struct ospf_neighbor * -ospf_dr_election_sub (struct list *routers) +static struct ospf_neighbor *ospf_dr_election_sub(struct list *routers) { - struct listnode *node; - struct ospf_neighbor *nbr, *max = NULL; - - /* Choose highest router priority. - In case of tie, choose highest Router ID. */ - for (ALL_LIST_ELEMENTS_RO (routers, node, nbr)) - { - if (max == NULL) - max = nbr; - else - { - if (max->priority < nbr->priority) - max = nbr; - else if (max->priority == nbr->priority) - if (IPV4_ADDR_CMP (&max->router_id, &nbr->router_id) < 0) - max = nbr; + struct listnode *node; + struct ospf_neighbor *nbr, *max = NULL; + + /* Choose highest router priority. + In case of tie, choose highest Router ID. */ + for (ALL_LIST_ELEMENTS_RO(routers, node, nbr)) { + if (max == NULL) + max = nbr; + else { + if (max->priority < nbr->priority) + max = nbr; + else if (max->priority == nbr->priority) + if (IPV4_ADDR_CMP(&max->router_id, + &nbr->router_id) + < 0) + max = nbr; + } } - } - return max; + return max; } -static struct ospf_neighbor * -ospf_elect_dr (struct ospf_interface *oi, struct list *el_list) +static struct ospf_neighbor *ospf_elect_dr(struct ospf_interface *oi, + struct list *el_list) { - struct list *dr_list; - struct listnode *node; - struct ospf_neighbor *nbr, *dr = NULL, *bdr = NULL; - - dr_list = list_new (); - - /* Add neighbors to the list. */ - for (ALL_LIST_ELEMENTS_RO (el_list, node, nbr)) - { - /* neighbor declared to be DR. */ - if (NBR_IS_DR (nbr)) - listnode_add (dr_list, nbr); - - /* Preserve neighbor BDR. */ - if (IPV4_ADDR_SAME (&BDR (oi), &nbr->address.u.prefix4)) - bdr = nbr; - } - - /* Elect Designated Router. */ - if (listcount (dr_list) > 0) - dr = ospf_dr_election_sub (dr_list); - else - dr = bdr; - - /* Set DR to interface. */ - if (dr) - DR (oi) = dr->address.u.prefix4; - else - DR (oi).s_addr = 0; - - list_delete (dr_list); - - return dr; + struct list *dr_list; + struct listnode *node; + struct ospf_neighbor *nbr, *dr = NULL, *bdr = NULL; + + dr_list = list_new(); + + /* Add neighbors to the list. */ + for (ALL_LIST_ELEMENTS_RO(el_list, node, nbr)) { + /* neighbor declared to be DR. */ + if (NBR_IS_DR(nbr)) + listnode_add(dr_list, nbr); + + /* Preserve neighbor BDR. */ + if (IPV4_ADDR_SAME(&BDR(oi), &nbr->address.u.prefix4)) + bdr = nbr; + } + + /* Elect Designated Router. */ + if (listcount(dr_list) > 0) + dr = ospf_dr_election_sub(dr_list); + else + dr = bdr; + + /* Set DR to interface. */ + if (dr) + DR(oi) = dr->address.u.prefix4; + else + DR(oi).s_addr = 0; + + list_delete(dr_list); + + return dr; } -static struct ospf_neighbor * -ospf_elect_bdr (struct ospf_interface *oi, struct list *el_list) +static struct ospf_neighbor *ospf_elect_bdr(struct ospf_interface *oi, + struct list *el_list) { - struct list *bdr_list, *no_dr_list; - struct listnode *node; - struct ospf_neighbor *nbr, *bdr = NULL; - - bdr_list = list_new (); - no_dr_list = list_new (); - - /* Add neighbors to the list. */ - for (ALL_LIST_ELEMENTS_RO (el_list, node, nbr)) - { - /* neighbor declared to be DR. */ - if (NBR_IS_DR (nbr)) - continue; - - /* neighbor declared to be BDR. */ - if (NBR_IS_BDR (nbr)) - listnode_add (bdr_list, nbr); - - listnode_add (no_dr_list, nbr); - } - - /* Elect Backup Designated Router. */ - if (listcount (bdr_list) > 0) - bdr = ospf_dr_election_sub (bdr_list); - else - bdr = ospf_dr_election_sub (no_dr_list); - - /* Set BDR to interface. */ - if (bdr) - BDR (oi) = bdr->address.u.prefix4; - else - BDR (oi).s_addr = 0; - - list_delete (bdr_list); - list_delete (no_dr_list); - - return bdr; + struct list *bdr_list, *no_dr_list; + struct listnode *node; + struct ospf_neighbor *nbr, *bdr = NULL; + + bdr_list = list_new(); + no_dr_list = list_new(); + + /* Add neighbors to the list. */ + for (ALL_LIST_ELEMENTS_RO(el_list, node, nbr)) { + /* neighbor declared to be DR. */ + if (NBR_IS_DR(nbr)) + continue; + + /* neighbor declared to be BDR. */ + if (NBR_IS_BDR(nbr)) + listnode_add(bdr_list, nbr); + + listnode_add(no_dr_list, nbr); + } + + /* Elect Backup Designated Router. */ + if (listcount(bdr_list) > 0) + bdr = ospf_dr_election_sub(bdr_list); + else + bdr = ospf_dr_election_sub(no_dr_list); + + /* Set BDR to interface. */ + if (bdr) + BDR(oi) = bdr->address.u.prefix4; + else + BDR(oi).s_addr = 0; + + list_delete(bdr_list); + list_delete(no_dr_list); + + return bdr; } -static int -ospf_ism_state (struct ospf_interface *oi) +static int ospf_ism_state(struct ospf_interface *oi) { - if (IPV4_ADDR_SAME (&DR (oi), &oi->address->u.prefix4)) - return ISM_DR; - else if (IPV4_ADDR_SAME (&BDR (oi), &oi->address->u.prefix4)) - return ISM_Backup; - else - return ISM_DROther; + if (IPV4_ADDR_SAME(&DR(oi), &oi->address->u.prefix4)) + return ISM_DR; + else if (IPV4_ADDR_SAME(&BDR(oi), &oi->address->u.prefix4)) + return ISM_Backup; + else + return ISM_DROther; } -static void -ospf_dr_eligible_routers (struct route_table *nbrs, struct list *el_list) +static void ospf_dr_eligible_routers(struct route_table *nbrs, + struct list *el_list) { - struct route_node *rn; - struct ospf_neighbor *nbr; - - for (rn = route_top (nbrs); rn; rn = route_next (rn)) - if ((nbr = rn->info) != NULL) - /* Ignore 0.0.0.0 node*/ - if (nbr->router_id.s_addr != 0) - /* Is neighbor eligible? */ - if (nbr->priority > 0) - /* Is neighbor upper 2-Way? */ - if (nbr->state >= NSM_TwoWay) - listnode_add (el_list, nbr); + struct route_node *rn; + struct ospf_neighbor *nbr; + + for (rn = route_top(nbrs); rn; rn = route_next(rn)) + if ((nbr = rn->info) != NULL) + /* Ignore 0.0.0.0 node*/ + if (nbr->router_id.s_addr != 0) + /* Is neighbor eligible? */ + if (nbr->priority > 0) + /* Is neighbor upper 2-Way? */ + if (nbr->state >= NSM_TwoWay) + listnode_add(el_list, nbr); } /* Generate AdjOK? NSM event. */ -static void -ospf_dr_change (struct ospf *ospf, struct route_table *nbrs) +static void ospf_dr_change(struct ospf *ospf, struct route_table *nbrs) { - struct route_node *rn; - struct ospf_neighbor *nbr; - - for (rn = route_top (nbrs); rn; rn = route_next (rn)) - if ((nbr = rn->info) != NULL) - /* Ignore 0.0.0.0 node*/ - if (nbr->router_id.s_addr != 0) - /* Is neighbor upper 2-Way? */ - if (nbr->state >= NSM_TwoWay) - /* Ignore myself. */ - if (!IPV4_ADDR_SAME (&nbr->router_id, &ospf->router_id)) - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_AdjOK); + struct route_node *rn; + struct ospf_neighbor *nbr; + + for (rn = route_top(nbrs); rn; rn = route_next(rn)) + if ((nbr = rn->info) != NULL) + /* Ignore 0.0.0.0 node*/ + if (nbr->router_id.s_addr != 0) + /* Is neighbor upper 2-Way? */ + if (nbr->state >= NSM_TwoWay) + /* Ignore myself. */ + if (!IPV4_ADDR_SAME(&nbr->router_id, + &ospf->router_id)) + OSPF_NSM_EVENT_SCHEDULE( + nbr, NSM_AdjOK); } -static int -ospf_dr_election (struct ospf_interface *oi) +static int ospf_dr_election(struct ospf_interface *oi) { - struct in_addr old_dr, old_bdr; - int old_state, new_state; - struct list *el_list; + struct in_addr old_dr, old_bdr; + int old_state, new_state; + struct list *el_list; - /* backup current values. */ - old_dr = DR (oi); - old_bdr = BDR (oi); - old_state = oi->state; + /* backup current values. */ + old_dr = DR(oi); + old_bdr = BDR(oi); + old_state = oi->state; - el_list = list_new (); + el_list = list_new(); - /* List eligible routers. */ - ospf_dr_eligible_routers (oi->nbrs, el_list); + /* List eligible routers. */ + ospf_dr_eligible_routers(oi->nbrs, el_list); - /* First election of DR and BDR. */ - ospf_elect_bdr (oi, el_list); - ospf_elect_dr (oi, el_list); + /* First election of DR and BDR. */ + ospf_elect_bdr(oi, el_list); + ospf_elect_dr(oi, el_list); - new_state = ospf_ism_state (oi); + new_state = ospf_ism_state(oi); - zlog_debug ("DR-Election[1st]: Backup %s", inet_ntoa (BDR (oi))); - zlog_debug ("DR-Election[1st]: DR %s", inet_ntoa (DR (oi))); + zlog_debug("DR-Election[1st]: Backup %s", inet_ntoa(BDR(oi))); + zlog_debug("DR-Election[1st]: DR %s", inet_ntoa(DR(oi))); - if (new_state != old_state && - !(new_state == ISM_DROther && old_state < ISM_DROther)) - { - ospf_elect_bdr (oi, el_list); - ospf_elect_dr (oi, el_list); + if (new_state != old_state + && !(new_state == ISM_DROther && old_state < ISM_DROther)) { + ospf_elect_bdr(oi, el_list); + ospf_elect_dr(oi, el_list); - new_state = ospf_ism_state (oi); + new_state = ospf_ism_state(oi); - zlog_debug ("DR-Election[2nd]: Backup %s", inet_ntoa (BDR (oi))); - zlog_debug ("DR-Election[2nd]: DR %s", inet_ntoa (DR (oi))); - } + zlog_debug("DR-Election[2nd]: Backup %s", inet_ntoa(BDR(oi))); + zlog_debug("DR-Election[2nd]: DR %s", inet_ntoa(DR(oi))); + } - list_delete (el_list); + list_delete(el_list); - /* if DR or BDR changes, cause AdjOK? neighbor event. */ - if (!IPV4_ADDR_SAME (&old_dr, &DR (oi)) || - !IPV4_ADDR_SAME (&old_bdr, &BDR (oi))) - ospf_dr_change (oi->ospf, oi->nbrs); + /* if DR or BDR changes, cause AdjOK? neighbor event. */ + if (!IPV4_ADDR_SAME(&old_dr, &DR(oi)) + || !IPV4_ADDR_SAME(&old_bdr, &BDR(oi))) + ospf_dr_change(oi->ospf, oi->nbrs); - return new_state; + return new_state; } -int -ospf_hello_timer (struct thread *thread) +int ospf_hello_timer(struct thread *thread) { - struct ospf_interface *oi; + struct ospf_interface *oi; - oi = THREAD_ARG (thread); - oi->t_hello = NULL; + oi = THREAD_ARG(thread); + oi->t_hello = NULL; - if (IS_DEBUG_OSPF (ism, ISM_TIMERS)) - zlog_debug("ISM[%s]: Timer (Hello timer expire)", IF_NAME(oi)); + if (IS_DEBUG_OSPF(ism, ISM_TIMERS)) + zlog_debug("ISM[%s]: Timer (Hello timer expire)", IF_NAME(oi)); - /* Sending hello packet. */ - ospf_hello_send (oi); + /* Sending hello packet. */ + ospf_hello_send(oi); - /* Hello timer set. */ - OSPF_HELLO_TIMER_ON (oi); - - return 0; + /* Hello timer set. */ + OSPF_HELLO_TIMER_ON(oi); + + return 0; } -static int -ospf_wait_timer (struct thread *thread) +static int ospf_wait_timer(struct thread *thread) { - struct ospf_interface *oi; + struct ospf_interface *oi; - oi = THREAD_ARG (thread); - oi->t_wait = NULL; + oi = THREAD_ARG(thread); + oi->t_wait = NULL; - if (IS_DEBUG_OSPF (ism, ISM_TIMERS)) - zlog_debug("ISM[%s]: Timer (Wait timer expire)", IF_NAME(oi)); + if (IS_DEBUG_OSPF(ism, ISM_TIMERS)) + zlog_debug("ISM[%s]: Timer (Wait timer expire)", IF_NAME(oi)); - OSPF_ISM_EVENT_SCHEDULE (oi, ISM_WaitTimer); + OSPF_ISM_EVENT_SCHEDULE(oi, ISM_WaitTimer); - return 0; + return 0; } /* Hook function called after ospf ISM event is occured. And vty's network command invoke this function after making interface structure. */ -static void -ism_timer_set (struct ospf_interface *oi) +static void ism_timer_set(struct ospf_interface *oi) { - switch (oi->state) - { - case ISM_Down: - /* First entry point of ospf interface state machine. In this state - interface parameters must be set to initial values, and timers are - reset also. */ - OSPF_ISM_TIMER_OFF (oi->t_hello); - OSPF_ISM_TIMER_OFF (oi->t_wait); - OSPF_ISM_TIMER_OFF (oi->t_ls_ack); - break; - case ISM_Loopback: - /* In this state, the interface may be looped back and will be - unavailable for regular data traffic. */ - OSPF_ISM_TIMER_OFF (oi->t_hello); - OSPF_ISM_TIMER_OFF (oi->t_wait); - OSPF_ISM_TIMER_OFF (oi->t_ls_ack); - break; - case ISM_Waiting: - /* The router is trying to determine the identity of DRouter and - BDRouter. The router begin to receive and send Hello Packets. */ - /* send first hello immediately */ - OSPF_ISM_TIMER_MSEC_ON (oi->t_hello, ospf_hello_timer, 1); - OSPF_ISM_TIMER_ON (oi->t_wait, ospf_wait_timer, - OSPF_IF_PARAM (oi, v_wait)); - OSPF_ISM_TIMER_OFF (oi->t_ls_ack); - break; - case ISM_PointToPoint: - /* The interface connects to a physical Point-to-point network or - virtual link. The router attempts to form an adjacency with - neighboring router. Hello packets are also sent. */ - /* send first hello immediately */ - OSPF_ISM_TIMER_MSEC_ON (oi->t_hello, ospf_hello_timer, 1); - OSPF_ISM_TIMER_OFF (oi->t_wait); - OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack); - break; - case ISM_DROther: - /* The network type of the interface is broadcast or NBMA network, - and the router itself is neither Designated Router nor - Backup Designated Router. */ - OSPF_HELLO_TIMER_ON (oi); - OSPF_ISM_TIMER_OFF (oi->t_wait); - OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack); - break; - case ISM_Backup: - /* The network type of the interface is broadcast os NBMA network, - and the router is Backup Designated Router. */ - OSPF_HELLO_TIMER_ON (oi); - OSPF_ISM_TIMER_OFF (oi->t_wait); - OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack); - break; - case ISM_DR: - /* The network type of the interface is broadcast or NBMA network, - and the router is Designated Router. */ - OSPF_HELLO_TIMER_ON (oi); - OSPF_ISM_TIMER_OFF (oi->t_wait); - OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack); - break; - } + switch (oi->state) { + case ISM_Down: + /* First entry point of ospf interface state machine. In this + state + interface parameters must be set to initial values, and + timers are + reset also. */ + OSPF_ISM_TIMER_OFF(oi->t_hello); + OSPF_ISM_TIMER_OFF(oi->t_wait); + OSPF_ISM_TIMER_OFF(oi->t_ls_ack); + break; + case ISM_Loopback: + /* In this state, the interface may be looped back and will be + unavailable for regular data traffic. */ + OSPF_ISM_TIMER_OFF(oi->t_hello); + OSPF_ISM_TIMER_OFF(oi->t_wait); + OSPF_ISM_TIMER_OFF(oi->t_ls_ack); + break; + case ISM_Waiting: + /* The router is trying to determine the identity of DRouter and + BDRouter. The router begin to receive and send Hello Packets. + */ + /* send first hello immediately */ + OSPF_ISM_TIMER_MSEC_ON(oi->t_hello, ospf_hello_timer, 1); + OSPF_ISM_TIMER_ON(oi->t_wait, ospf_wait_timer, + OSPF_IF_PARAM(oi, v_wait)); + OSPF_ISM_TIMER_OFF(oi->t_ls_ack); + break; + case ISM_PointToPoint: + /* The interface connects to a physical Point-to-point network + or + virtual link. The router attempts to form an adjacency with + neighboring router. Hello packets are also sent. */ + /* send first hello immediately */ + OSPF_ISM_TIMER_MSEC_ON(oi->t_hello, ospf_hello_timer, 1); + OSPF_ISM_TIMER_OFF(oi->t_wait); + OSPF_ISM_TIMER_ON(oi->t_ls_ack, ospf_ls_ack_timer, + oi->v_ls_ack); + break; + case ISM_DROther: + /* The network type of the interface is broadcast or NBMA + network, + and the router itself is neither Designated Router nor + Backup Designated Router. */ + OSPF_HELLO_TIMER_ON(oi); + OSPF_ISM_TIMER_OFF(oi->t_wait); + OSPF_ISM_TIMER_ON(oi->t_ls_ack, ospf_ls_ack_timer, + oi->v_ls_ack); + break; + case ISM_Backup: + /* The network type of the interface is broadcast os NBMA + network, + and the router is Backup Designated Router. */ + OSPF_HELLO_TIMER_ON(oi); + OSPF_ISM_TIMER_OFF(oi->t_wait); + OSPF_ISM_TIMER_ON(oi->t_ls_ack, ospf_ls_ack_timer, + oi->v_ls_ack); + break; + case ISM_DR: + /* The network type of the interface is broadcast or NBMA + network, + and the router is Designated Router. */ + OSPF_HELLO_TIMER_ON(oi); + OSPF_ISM_TIMER_OFF(oi->t_wait); + OSPF_ISM_TIMER_ON(oi->t_ls_ack, ospf_ls_ack_timer, + oi->v_ls_ack); + break; + } } -static int -ism_interface_up (struct ospf_interface *oi) +static int ism_interface_up(struct ospf_interface *oi) { - int next_state = 0; - - /* if network type is point-to-point, Point-to-MultiPoint or virtual link, - the state transitions to Point-to-Point. */ - if (oi->type == OSPF_IFTYPE_POINTOPOINT || - oi->type == OSPF_IFTYPE_POINTOMULTIPOINT || - oi->type == OSPF_IFTYPE_VIRTUALLINK) - next_state = ISM_PointToPoint; - /* Else if the router is not eligible to DR, the state transitions to - DROther. */ - else if (PRIORITY (oi) == 0) /* router is eligible? */ - next_state = ISM_DROther; - else - /* Otherwise, the state transitions to Waiting. */ - next_state = ISM_Waiting; - - if (oi->type == OSPF_IFTYPE_NBMA) - ospf_nbr_nbma_if_update (oi->ospf, oi); - - /* ospf_ism_event (t); */ - return next_state; + int next_state = 0; + + /* if network type is point-to-point, Point-to-MultiPoint or virtual + link, + the state transitions to Point-to-Point. */ + if (oi->type == OSPF_IFTYPE_POINTOPOINT + || oi->type == OSPF_IFTYPE_POINTOMULTIPOINT + || oi->type == OSPF_IFTYPE_VIRTUALLINK) + next_state = ISM_PointToPoint; + /* Else if the router is not eligible to DR, the state transitions to + DROther. */ + else if (PRIORITY(oi) == 0) /* router is eligible? */ + next_state = ISM_DROther; + else + /* Otherwise, the state transitions to Waiting. */ + next_state = ISM_Waiting; + + if (oi->type == OSPF_IFTYPE_NBMA) + ospf_nbr_nbma_if_update(oi->ospf, oi); + + /* ospf_ism_event (t); */ + return next_state; } -static int -ism_loop_ind (struct ospf_interface *oi) +static int ism_loop_ind(struct ospf_interface *oi) { - int ret = 0; + int ret = 0; - /* call ism_interface_down. */ - /* ret = ism_interface_down (oi); */ + /* call ism_interface_down. */ + /* ret = ism_interface_down (oi); */ - return ret; + return ret; } /* Interface down event handler. */ -static int -ism_interface_down (struct ospf_interface *oi) +static int ism_interface_down(struct ospf_interface *oi) { - ospf_if_cleanup (oi); - return 0; + ospf_if_cleanup(oi); + return 0; } -static int -ism_backup_seen (struct ospf_interface *oi) +static int ism_backup_seen(struct ospf_interface *oi) { - return ospf_dr_election (oi); + return ospf_dr_election(oi); } -static int -ism_wait_timer (struct ospf_interface *oi) +static int ism_wait_timer(struct ospf_interface *oi) { - return ospf_dr_election (oi); + return ospf_dr_election(oi); } -static int -ism_neighbor_change (struct ospf_interface *oi) +static int ism_neighbor_change(struct ospf_interface *oi) { - return ospf_dr_election (oi); + return ospf_dr_election(oi); } -static int -ism_ignore (struct ospf_interface *oi) +static int ism_ignore(struct ospf_interface *oi) { - if (IS_DEBUG_OSPF (ism, ISM_EVENTS)) - zlog_debug("ISM[%s]: ism_ignore called", IF_NAME(oi)); + if (IS_DEBUG_OSPF(ism, ISM_EVENTS)) + zlog_debug("ISM[%s]: ism_ignore called", IF_NAME(oi)); - return 0; + return 0; } /* Interface State Machine */ struct { - int (*func) (struct ospf_interface *); - int next_state; -} ISM [OSPF_ISM_STATE_MAX][OSPF_ISM_EVENT_MAX] = -{ - { - /* DependUpon: dummy state. */ - { ism_ignore, ISM_DependUpon }, /* NoEvent */ - { ism_ignore, ISM_DependUpon }, /* InterfaceUp */ - { ism_ignore, ISM_DependUpon }, /* WaitTimer */ - { ism_ignore, ISM_DependUpon }, /* BackupSeen */ - { ism_ignore, ISM_DependUpon }, /* NeighborChange */ - { ism_ignore, ISM_DependUpon }, /* LoopInd */ - { ism_ignore, ISM_DependUpon }, /* UnloopInd */ - { ism_ignore, ISM_DependUpon }, /* InterfaceDown */ - }, - { - /* Down:*/ - { ism_ignore, ISM_DependUpon }, /* NoEvent */ - { ism_interface_up, ISM_DependUpon }, /* InterfaceUp */ - { ism_ignore, ISM_Down }, /* WaitTimer */ - { ism_ignore, ISM_Down }, /* BackupSeen */ - { ism_ignore, ISM_Down }, /* NeighborChange */ - { ism_loop_ind, ISM_Loopback }, /* LoopInd */ - { ism_ignore, ISM_Down }, /* UnloopInd */ - { ism_interface_down, ISM_Down }, /* InterfaceDown */ - }, - { - /* Loopback: */ - { ism_ignore, ISM_DependUpon }, /* NoEvent */ - { ism_ignore, ISM_Loopback }, /* InterfaceUp */ - { ism_ignore, ISM_Loopback }, /* WaitTimer */ - { ism_ignore, ISM_Loopback }, /* BackupSeen */ - { ism_ignore, ISM_Loopback }, /* NeighborChange */ - { ism_ignore, ISM_Loopback }, /* LoopInd */ - { ism_ignore, ISM_Down }, /* UnloopInd */ - { ism_interface_down, ISM_Down }, /* InterfaceDown */ - }, - { - /* Waiting: */ - { ism_ignore, ISM_DependUpon }, /* NoEvent */ - { ism_ignore, ISM_Waiting }, /* InterfaceUp */ - { ism_wait_timer, ISM_DependUpon }, /* WaitTimer */ - { ism_backup_seen, ISM_DependUpon }, /* BackupSeen */ - { ism_ignore, ISM_Waiting }, /* NeighborChange */ - { ism_loop_ind, ISM_Loopback }, /* LoopInd */ - { ism_ignore, ISM_Waiting }, /* UnloopInd */ - { ism_interface_down, ISM_Down }, /* InterfaceDown */ - }, - { - /* Point-to-Point: */ - { ism_ignore, ISM_DependUpon }, /* NoEvent */ - { ism_ignore, ISM_PointToPoint }, /* InterfaceUp */ - { ism_ignore, ISM_PointToPoint }, /* WaitTimer */ - { ism_ignore, ISM_PointToPoint }, /* BackupSeen */ - { ism_ignore, ISM_PointToPoint }, /* NeighborChange */ - { ism_loop_ind, ISM_Loopback }, /* LoopInd */ - { ism_ignore, ISM_PointToPoint }, /* UnloopInd */ - { ism_interface_down, ISM_Down }, /* InterfaceDown */ - }, - { - /* DROther: */ - { ism_ignore, ISM_DependUpon }, /* NoEvent */ - { ism_ignore, ISM_DROther }, /* InterfaceUp */ - { ism_ignore, ISM_DROther }, /* WaitTimer */ - { ism_ignore, ISM_DROther }, /* BackupSeen */ - { ism_neighbor_change, ISM_DependUpon }, /* NeighborChange */ - { ism_loop_ind, ISM_Loopback }, /* LoopInd */ - { ism_ignore, ISM_DROther }, /* UnloopInd */ - { ism_interface_down, ISM_Down }, /* InterfaceDown */ - }, - { - /* Backup: */ - { ism_ignore, ISM_DependUpon }, /* NoEvent */ - { ism_ignore, ISM_Backup }, /* InterfaceUp */ - { ism_ignore, ISM_Backup }, /* WaitTimer */ - { ism_ignore, ISM_Backup }, /* BackupSeen */ - { ism_neighbor_change, ISM_DependUpon }, /* NeighborChange */ - { ism_loop_ind, ISM_Loopback }, /* LoopInd */ - { ism_ignore, ISM_Backup }, /* UnloopInd */ - { ism_interface_down, ISM_Down }, /* InterfaceDown */ - }, - { - /* DR: */ - { ism_ignore, ISM_DependUpon }, /* NoEvent */ - { ism_ignore, ISM_DR }, /* InterfaceUp */ - { ism_ignore, ISM_DR }, /* WaitTimer */ - { ism_ignore, ISM_DR }, /* BackupSeen */ - { ism_neighbor_change, ISM_DependUpon }, /* NeighborChange */ - { ism_loop_ind, ISM_Loopback }, /* LoopInd */ - { ism_ignore, ISM_DR }, /* UnloopInd */ - { ism_interface_down, ISM_Down }, /* InterfaceDown */ - }, -}; - -static const char *ospf_ism_event_str[] = -{ - "NoEvent", - "InterfaceUp", - "WaitTimer", - "BackupSeen", - "NeighborChange", - "LoopInd", - "UnLoopInd", - "InterfaceDown", + int (*func)(struct ospf_interface *); + int next_state; +} ISM[OSPF_ISM_STATE_MAX][OSPF_ISM_EVENT_MAX] = { + { + /* DependUpon: dummy state. */ + {ism_ignore, ISM_DependUpon}, /* NoEvent */ + {ism_ignore, ISM_DependUpon}, /* InterfaceUp */ + {ism_ignore, ISM_DependUpon}, /* WaitTimer */ + {ism_ignore, ISM_DependUpon}, /* BackupSeen */ + {ism_ignore, ISM_DependUpon}, /* NeighborChange */ + {ism_ignore, ISM_DependUpon}, /* LoopInd */ + {ism_ignore, ISM_DependUpon}, /* UnloopInd */ + {ism_ignore, ISM_DependUpon}, /* InterfaceDown */ + }, + { + /* Down:*/ + {ism_ignore, ISM_DependUpon}, /* NoEvent */ + {ism_interface_up, ISM_DependUpon}, /* InterfaceUp */ + {ism_ignore, ISM_Down}, /* WaitTimer */ + {ism_ignore, ISM_Down}, /* BackupSeen */ + {ism_ignore, ISM_Down}, /* NeighborChange */ + {ism_loop_ind, ISM_Loopback}, /* LoopInd */ + {ism_ignore, ISM_Down}, /* UnloopInd */ + {ism_interface_down, ISM_Down}, /* InterfaceDown */ + }, + { + /* Loopback: */ + {ism_ignore, ISM_DependUpon}, /* NoEvent */ + {ism_ignore, ISM_Loopback}, /* InterfaceUp */ + {ism_ignore, ISM_Loopback}, /* WaitTimer */ + {ism_ignore, ISM_Loopback}, /* BackupSeen */ + {ism_ignore, ISM_Loopback}, /* NeighborChange */ + {ism_ignore, ISM_Loopback}, /* LoopInd */ + {ism_ignore, ISM_Down}, /* UnloopInd */ + {ism_interface_down, ISM_Down}, /* InterfaceDown */ + }, + { + /* Waiting: */ + {ism_ignore, ISM_DependUpon}, /* NoEvent */ + {ism_ignore, ISM_Waiting}, /* InterfaceUp */ + {ism_wait_timer, ISM_DependUpon}, /* WaitTimer */ + {ism_backup_seen, ISM_DependUpon}, /* BackupSeen */ + {ism_ignore, ISM_Waiting}, /* NeighborChange */ + {ism_loop_ind, ISM_Loopback}, /* LoopInd */ + {ism_ignore, ISM_Waiting}, /* UnloopInd */ + {ism_interface_down, ISM_Down}, /* InterfaceDown */ + }, + { + /* Point-to-Point: */ + {ism_ignore, ISM_DependUpon}, /* NoEvent */ + {ism_ignore, ISM_PointToPoint}, /* InterfaceUp */ + {ism_ignore, ISM_PointToPoint}, /* WaitTimer */ + {ism_ignore, ISM_PointToPoint}, /* BackupSeen */ + {ism_ignore, ISM_PointToPoint}, /* NeighborChange */ + {ism_loop_ind, ISM_Loopback}, /* LoopInd */ + {ism_ignore, ISM_PointToPoint}, /* UnloopInd */ + {ism_interface_down, ISM_Down}, /* InterfaceDown */ + }, + { + /* DROther: */ + {ism_ignore, ISM_DependUpon}, /* NoEvent */ + {ism_ignore, ISM_DROther}, /* InterfaceUp */ + {ism_ignore, ISM_DROther}, /* WaitTimer */ + {ism_ignore, ISM_DROther}, /* BackupSeen */ + {ism_neighbor_change, ISM_DependUpon}, /* NeighborChange */ + {ism_loop_ind, ISM_Loopback}, /* LoopInd */ + {ism_ignore, ISM_DROther}, /* UnloopInd */ + {ism_interface_down, ISM_Down}, /* InterfaceDown */ + }, + { + /* Backup: */ + {ism_ignore, ISM_DependUpon}, /* NoEvent */ + {ism_ignore, ISM_Backup}, /* InterfaceUp */ + {ism_ignore, ISM_Backup}, /* WaitTimer */ + {ism_ignore, ISM_Backup}, /* BackupSeen */ + {ism_neighbor_change, ISM_DependUpon}, /* NeighborChange */ + {ism_loop_ind, ISM_Loopback}, /* LoopInd */ + {ism_ignore, ISM_Backup}, /* UnloopInd */ + {ism_interface_down, ISM_Down}, /* InterfaceDown */ + }, + { + /* DR: */ + {ism_ignore, ISM_DependUpon}, /* NoEvent */ + {ism_ignore, ISM_DR}, /* InterfaceUp */ + {ism_ignore, ISM_DR}, /* WaitTimer */ + {ism_ignore, ISM_DR}, /* BackupSeen */ + {ism_neighbor_change, ISM_DependUpon}, /* NeighborChange */ + {ism_loop_ind, ISM_Loopback}, /* LoopInd */ + {ism_ignore, ISM_DR}, /* UnloopInd */ + {ism_interface_down, ISM_Down}, /* InterfaceDown */ + }, +}; + +static const char *ospf_ism_event_str[] = { + "NoEvent", "InterfaceUp", "WaitTimer", "BackupSeen", + "NeighborChange", "LoopInd", "UnLoopInd", "InterfaceDown", }; -static void -ism_change_state (struct ospf_interface *oi, int state) +static void ism_change_state(struct ospf_interface *oi, int state) { - int old_state; - struct ospf_lsa *lsa; - - /* Logging change of state. */ - if (IS_DEBUG_OSPF (ism, ISM_STATUS)) - zlog_debug("ISM[%s]: State change %s -> %s", IF_NAME(oi), - lookup_msg(ospf_ism_state_msg, oi->state, NULL), - lookup_msg(ospf_ism_state_msg, state, NULL)); - - old_state = oi->state; - oi->state = state; - oi->state_change++; - - hook_call(ospf_ism_change, oi, state, old_state); - - /* Set multicast memberships appropriately for new state. */ - ospf_if_set_multicast(oi); - - if (old_state == ISM_Down || state == ISM_Down) - ospf_check_abr_status (oi->ospf); - - /* Originate router-LSA. */ - if (state == ISM_Down) - { - if (oi->area->act_ints > 0) - oi->area->act_ints--; - } - else if (old_state == ISM_Down) - oi->area->act_ints++; - - /* schedule router-LSA originate. */ - ospf_router_lsa_update_area (oi->area); - - /* Originate network-LSA. */ - if (old_state != ISM_DR && state == ISM_DR) - ospf_network_lsa_update (oi); - else if (old_state == ISM_DR && state != ISM_DR) - { - /* Free self originated network LSA. */ - lsa = oi->network_lsa_self; - if (lsa) - ospf_lsa_flush_area (lsa, oi->area); - - ospf_lsa_unlock (&oi->network_lsa_self); - oi->network_lsa_self = NULL; - } - - ospf_opaque_ism_change (oi, old_state); - - /* Check area border status. */ - ospf_check_abr_status (oi->ospf); + int old_state; + struct ospf_lsa *lsa; + + /* Logging change of state. */ + if (IS_DEBUG_OSPF(ism, ISM_STATUS)) + zlog_debug("ISM[%s]: State change %s -> %s", IF_NAME(oi), + lookup_msg(ospf_ism_state_msg, oi->state, NULL), + lookup_msg(ospf_ism_state_msg, state, NULL)); + + old_state = oi->state; + oi->state = state; + oi->state_change++; + + hook_call(ospf_ism_change, oi, state, old_state); + + /* Set multicast memberships appropriately for new state. */ + ospf_if_set_multicast(oi); + + if (old_state == ISM_Down || state == ISM_Down) + ospf_check_abr_status(oi->ospf); + + /* Originate router-LSA. */ + if (state == ISM_Down) { + if (oi->area->act_ints > 0) + oi->area->act_ints--; + } else if (old_state == ISM_Down) + oi->area->act_ints++; + + /* schedule router-LSA originate. */ + ospf_router_lsa_update_area(oi->area); + + /* Originate network-LSA. */ + if (old_state != ISM_DR && state == ISM_DR) + ospf_network_lsa_update(oi); + else if (old_state == ISM_DR && state != ISM_DR) { + /* Free self originated network LSA. */ + lsa = oi->network_lsa_self; + if (lsa) + ospf_lsa_flush_area(lsa, oi->area); + + ospf_lsa_unlock(&oi->network_lsa_self); + oi->network_lsa_self = NULL; + } + + ospf_opaque_ism_change(oi, old_state); + + /* Check area border status. */ + ospf_check_abr_status(oi->ospf); } /* Execute ISM event process. */ -int -ospf_ism_event (struct thread *thread) +int ospf_ism_event(struct thread *thread) { - int event; - int next_state; - struct ospf_interface *oi; + int event; + int next_state; + struct ospf_interface *oi; - oi = THREAD_ARG (thread); - event = THREAD_VAL (thread); + oi = THREAD_ARG(thread); + event = THREAD_VAL(thread); - /* Call function. */ - next_state = (*(ISM [oi->state][event].func))(oi); + /* Call function. */ + next_state = (*(ISM[oi->state][event].func))(oi); - if (! next_state) - next_state = ISM [oi->state][event].next_state; + if (!next_state) + next_state = ISM[oi->state][event].next_state; - if (IS_DEBUG_OSPF (ism, ISM_EVENTS)) - zlog_debug("ISM[%s]: %s (%s)", IF_NAME(oi), - lookup_msg(ospf_ism_state_msg, oi->state, NULL), - ospf_ism_event_str[event]); + if (IS_DEBUG_OSPF(ism, ISM_EVENTS)) + zlog_debug("ISM[%s]: %s (%s)", IF_NAME(oi), + lookup_msg(ospf_ism_state_msg, oi->state, NULL), + ospf_ism_event_str[event]); - /* If state is changed. */ - if (next_state != oi->state) - ism_change_state (oi, next_state); + /* If state is changed. */ + if (next_state != oi->state) + ism_change_state(oi, next_state); - /* Make sure timer is set. */ - ism_timer_set (oi); + /* Make sure timer is set. */ + ism_timer_set(oi); - return 0; + return 0; } - diff --git a/ospfd/ospf_ism.h b/ospfd/ospf_ism.h index f099fe875..5ae99ab32 100644 --- a/ospfd/ospf_ism.h +++ b/ospfd/ospf_ism.h @@ -47,62 +47,60 @@ #define ISM_InterfaceDown 7 #define OSPF_ISM_EVENT_MAX 8 -#define OSPF_ISM_WRITE_ON(O) \ - do \ - { \ - if (oi->on_write_q == 0) \ - { \ - listnode_add ((O)->oi_write_q, oi); \ - oi->on_write_q = 1; \ - } \ - thread_add_write (master, ospf_write, (O), (O)->fd, &(O)->t_write); \ - } while (0) - +#define OSPF_ISM_WRITE_ON(O) \ + do { \ + if (oi->on_write_q == 0) { \ + listnode_add((O)->oi_write_q, oi); \ + oi->on_write_q = 1; \ + } \ + thread_add_write(master, ospf_write, (O), (O)->fd, \ + &(O)->t_write); \ + } while (0) + /* Macro for OSPF ISM timer turn on. */ -#define OSPF_ISM_TIMER_ON(T,F,V) \ - thread_add_timer (master, (F), oi, (V), &(T)) +#define OSPF_ISM_TIMER_ON(T, F, V) thread_add_timer(master, (F), oi, (V), &(T)) -#define OSPF_ISM_TIMER_MSEC_ON(T,F,V) \ - thread_add_timer_msec (master, (F), oi, (V), &(T)) +#define OSPF_ISM_TIMER_MSEC_ON(T, F, V) \ + thread_add_timer_msec(master, (F), oi, (V), &(T)) /* convenience macro to set hello timer correctly, according to * whether fast-hello is set or not */ -#define OSPF_HELLO_TIMER_ON(O) \ - do { \ - if (OSPF_IF_PARAM ((O), fast_hello)) \ - OSPF_ISM_TIMER_MSEC_ON ((O)->t_hello, ospf_hello_timer, \ - 1000 / OSPF_IF_PARAM ((O), fast_hello)); \ - else \ - OSPF_ISM_TIMER_ON ((O)->t_hello, ospf_hello_timer, \ - OSPF_IF_PARAM ((O), v_hello)); \ - } while (0) +#define OSPF_HELLO_TIMER_ON(O) \ + do { \ + if (OSPF_IF_PARAM((O), fast_hello)) \ + OSPF_ISM_TIMER_MSEC_ON( \ + (O)->t_hello, ospf_hello_timer, \ + 1000 / OSPF_IF_PARAM((O), fast_hello)); \ + else \ + OSPF_ISM_TIMER_ON((O)->t_hello, ospf_hello_timer, \ + OSPF_IF_PARAM((O), v_hello)); \ + } while (0) /* Macro for OSPF ISM timer turn off. */ -#define OSPF_ISM_TIMER_OFF(X) \ - do { \ - if (X) \ - { \ - thread_cancel (X); \ - (X) = NULL; \ - } \ - } while (0) +#define OSPF_ISM_TIMER_OFF(X) \ + do { \ + if (X) { \ + thread_cancel(X); \ + (X) = NULL; \ + } \ + } while (0) /* Macro for OSPF schedule event. */ -#define OSPF_ISM_EVENT_SCHEDULE(I,E) \ - thread_add_event (master, ospf_ism_event, (I), (E), NULL) +#define OSPF_ISM_EVENT_SCHEDULE(I, E) \ + thread_add_event(master, ospf_ism_event, (I), (E), NULL) /* Macro for OSPF execute event. */ -#define OSPF_ISM_EVENT_EXECUTE(I,E) \ - thread_execute (master, ospf_ism_event, (I), (E)) +#define OSPF_ISM_EVENT_EXECUTE(I, E) \ + thread_execute(master, ospf_ism_event, (I), (E)) /* Prototypes. */ -extern int ospf_ism_event (struct thread *); -extern void ism_change_status (struct ospf_interface *, int); -extern int ospf_hello_timer (struct thread *thread); +extern int ospf_ism_event(struct thread *); +extern void ism_change_status(struct ospf_interface *, int); +extern int ospf_hello_timer(struct thread *thread); DECLARE_HOOK(ospf_ism_change, - (struct ospf_interface *oi, int state, int oldstate), - (oi, state, oldstate)) + (struct ospf_interface * oi, int state, int oldstate), + (oi, state, oldstate)) #endif /* _ZEBRA_OSPF_ISM_H */ diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 835d321bb..68adf2e10 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -31,7 +31,7 @@ #include "log.h" #include "thread.h" #include "hash.h" -#include "sockunion.h" /* for inet_aton() */ +#include "sockunion.h" /* for inet_aton() */ #include "checksum.h" #include "ospfd/ospfd.h" @@ -51,1483 +51,1442 @@ #include "ospfd/ospf_zebra.h" -u_int32_t -get_metric (u_char *metric) +u_int32_t get_metric(u_char *metric) { - u_int32_t m; - m = metric[0]; - m = (m << 8) + metric[1]; - m = (m << 8) + metric[2]; - return m; + u_int32_t m; + m = metric[0]; + m = (m << 8) + metric[1]; + m = (m << 8) + metric[2]; + return m; } -struct timeval -int2tv (int a) +struct timeval int2tv(int a) { - struct timeval ret; + struct timeval ret; - ret.tv_sec = a; - ret.tv_usec = 0; + ret.tv_sec = a; + ret.tv_usec = 0; - return ret; + return ret; } -struct timeval -msec2tv (int a) +struct timeval msec2tv(int a) { - struct timeval ret; + struct timeval ret; - ret.tv_sec = a/1000; - ret.tv_usec = (a%1000) * 1000; + ret.tv_sec = a / 1000; + ret.tv_usec = (a % 1000) * 1000; - return ret; + return ret; } -int -ospf_lsa_refresh_delay (struct ospf_lsa *lsa) +int ospf_lsa_refresh_delay(struct ospf_lsa *lsa) { - struct timeval delta; - int delay = 0; + struct timeval delta; + int delay = 0; - if (monotime_since (&lsa->tv_orig, &delta) < OSPF_MIN_LS_INTERVAL * 1000LL) - { - struct timeval minv = msec2tv (OSPF_MIN_LS_INTERVAL); - timersub (&minv, &delta, &minv); + if (monotime_since(&lsa->tv_orig, &delta) + < OSPF_MIN_LS_INTERVAL * 1000LL) { + struct timeval minv = msec2tv(OSPF_MIN_LS_INTERVAL); + timersub(&minv, &delta, &minv); - /* TBD: remove padding to full sec, return timeval instead */ - delay = minv.tv_sec + !!minv.tv_usec; + /* TBD: remove padding to full sec, return timeval instead */ + delay = minv.tv_sec + !!minv.tv_usec; - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("LSA[Type%d:%s]: Refresh timer delay %d seconds", - lsa->data->type, inet_ntoa (lsa->data->id), delay); + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug( + "LSA[Type%d:%s]: Refresh timer delay %d seconds", + lsa->data->type, inet_ntoa(lsa->data->id), + delay); - assert (delay > 0); - } + assert(delay > 0); + } - return delay; + return delay; } -int -get_age (struct ospf_lsa *lsa) +int get_age(struct ospf_lsa *lsa) { - struct timeval rel; + struct timeval rel; - monotime_since (&lsa->tv_recv, &rel); - return ntohs (lsa->data->ls_age) + rel.tv_sec; + monotime_since(&lsa->tv_recv, &rel); + return ntohs(lsa->data->ls_age) + rel.tv_sec; } /* Fletcher Checksum -- Refer to RFC1008. */ -/* All the offsets are zero-based. The offsets in the RFC1008 are +/* All the offsets are zero-based. The offsets in the RFC1008 are one-based. */ -u_int16_t -ospf_lsa_checksum (struct lsa_header *lsa) +u_int16_t ospf_lsa_checksum(struct lsa_header *lsa) { - u_char *buffer = (u_char *) &lsa->options; - int options_offset = buffer - (u_char *) &lsa->ls_age; /* should be 2 */ + u_char *buffer = (u_char *)&lsa->options; + int options_offset = buffer - (u_char *)&lsa->ls_age; /* should be 2 */ - /* Skip the AGE field */ - u_int16_t len = ntohs(lsa->length) - options_offset; + /* Skip the AGE field */ + u_int16_t len = ntohs(lsa->length) - options_offset; - /* Checksum offset starts from "options" field, not the beginning of the - lsa_header struct. The offset is 14, rather than 16. */ - int checksum_offset = (u_char *) &lsa->checksum - buffer; + /* Checksum offset starts from "options" field, not the beginning of the + lsa_header struct. The offset is 14, rather than 16. */ + int checksum_offset = (u_char *)&lsa->checksum - buffer; - return fletcher_checksum(buffer, len, checksum_offset); + return fletcher_checksum(buffer, len, checksum_offset); } -int -ospf_lsa_checksum_valid (struct lsa_header *lsa) +int ospf_lsa_checksum_valid(struct lsa_header *lsa) { - u_char *buffer = (u_char *) &lsa->options; - int options_offset = buffer - (u_char *) &lsa->ls_age; /* should be 2 */ + u_char *buffer = (u_char *)&lsa->options; + int options_offset = buffer - (u_char *)&lsa->ls_age; /* should be 2 */ - /* Skip the AGE field */ - u_int16_t len = ntohs(lsa->length) - options_offset; + /* Skip the AGE field */ + u_int16_t len = ntohs(lsa->length) - options_offset; - return(fletcher_checksum(buffer, len, FLETCHER_CHECKSUM_VALIDATE) == 0); + return (fletcher_checksum(buffer, len, FLETCHER_CHECKSUM_VALIDATE) + == 0); } - /* Create OSPF LSA. */ -struct ospf_lsa * -ospf_lsa_new () +struct ospf_lsa *ospf_lsa_new() { - struct ospf_lsa *new; + struct ospf_lsa *new; - new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa)); + new = XCALLOC(MTYPE_OSPF_LSA, sizeof(struct ospf_lsa)); - new->flags = 0; - new->lock = 1; - new->retransmit_counter = 0; - monotime(&new->tv_recv); - new->tv_orig = new->tv_recv; - new->refresh_list = -1; - - return new; + new->flags = 0; + new->lock = 1; + new->retransmit_counter = 0; + monotime(&new->tv_recv); + new->tv_orig = new->tv_recv; + new->refresh_list = -1; + + return new; } /* Duplicate OSPF LSA. */ -struct ospf_lsa * -ospf_lsa_dup (struct ospf_lsa *lsa) +struct ospf_lsa *ospf_lsa_dup(struct ospf_lsa *lsa) { - struct ospf_lsa *new; + struct ospf_lsa *new; - if (lsa == NULL) - return NULL; + if (lsa == NULL) + return NULL; - new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa)); + new = XCALLOC(MTYPE_OSPF_LSA, sizeof(struct ospf_lsa)); - memcpy (new, lsa, sizeof (struct ospf_lsa)); - UNSET_FLAG (new->flags, OSPF_LSA_DISCARD); - new->lock = 1; - new->retransmit_counter = 0; - new->data = ospf_lsa_data_dup (lsa->data); + memcpy(new, lsa, sizeof(struct ospf_lsa)); + UNSET_FLAG(new->flags, OSPF_LSA_DISCARD); + new->lock = 1; + new->retransmit_counter = 0; + new->data = ospf_lsa_data_dup(lsa->data); - /* kevinm: Clear the refresh_list, otherwise there are going - to be problems when we try to remove the LSA from the - queue (which it's not a member of.) - XXX: Should we add the LSA to the refresh_list queue? */ - new->refresh_list = -1; + /* kevinm: Clear the refresh_list, otherwise there are going + to be problems when we try to remove the LSA from the + queue (which it's not a member of.) + XXX: Should we add the LSA to the refresh_list queue? */ + new->refresh_list = -1; - if (IS_DEBUG_OSPF (lsa, LSA)) - zlog_debug ("LSA: duplicated %p (new: %p)", (void *)lsa, (void *)new); + if (IS_DEBUG_OSPF(lsa, LSA)) + zlog_debug("LSA: duplicated %p (new: %p)", (void *)lsa, + (void *)new); - return new; + return new; } /* Free OSPF LSA. */ -void -ospf_lsa_free (struct ospf_lsa *lsa) +void ospf_lsa_free(struct ospf_lsa *lsa) { - assert (lsa->lock == 0); - - if (IS_DEBUG_OSPF (lsa, LSA)) - zlog_debug ("LSA: freed %p", (void *)lsa); + assert(lsa->lock == 0); + + if (IS_DEBUG_OSPF(lsa, LSA)) + zlog_debug("LSA: freed %p", (void *)lsa); - /* Delete LSA data. */ - if (lsa->data != NULL) - ospf_lsa_data_free (lsa->data); + /* Delete LSA data. */ + if (lsa->data != NULL) + ospf_lsa_data_free(lsa->data); - assert (lsa->refresh_list < 0); + assert(lsa->refresh_list < 0); - memset (lsa, 0, sizeof (struct ospf_lsa)); - XFREE (MTYPE_OSPF_LSA, lsa); + memset(lsa, 0, sizeof(struct ospf_lsa)); + XFREE(MTYPE_OSPF_LSA, lsa); } /* Lock LSA. */ -struct ospf_lsa * -ospf_lsa_lock (struct ospf_lsa *lsa) +struct ospf_lsa *ospf_lsa_lock(struct ospf_lsa *lsa) { - lsa->lock++; - return lsa; + lsa->lock++; + return lsa; } /* Unlock LSA. */ -void -ospf_lsa_unlock (struct ospf_lsa **lsa) +void ospf_lsa_unlock(struct ospf_lsa **lsa) { - /* This is sanity check. */ - if (!lsa || !*lsa) - return; - - (*lsa)->lock--; + /* This is sanity check. */ + if (!lsa || !*lsa) + return; - assert ((*lsa)->lock >= 0); + (*lsa)->lock--; - if ((*lsa)->lock == 0) - { - assert (CHECK_FLAG ((*lsa)->flags, OSPF_LSA_DISCARD)); - ospf_lsa_free (*lsa); - *lsa = NULL; - } + assert((*lsa)->lock >= 0); + + if ((*lsa)->lock == 0) { + assert(CHECK_FLAG((*lsa)->flags, OSPF_LSA_DISCARD)); + ospf_lsa_free(*lsa); + *lsa = NULL; + } } /* Check discard flag. */ -void -ospf_lsa_discard (struct ospf_lsa *lsa) +void ospf_lsa_discard(struct ospf_lsa *lsa) { - if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD)) - { - SET_FLAG (lsa->flags, OSPF_LSA_DISCARD); - ospf_lsa_unlock (&lsa); - } + if (!CHECK_FLAG(lsa->flags, OSPF_LSA_DISCARD)) { + SET_FLAG(lsa->flags, OSPF_LSA_DISCARD); + ospf_lsa_unlock(&lsa); + } } /* Create LSA data. */ -struct lsa_header * -ospf_lsa_data_new (size_t size) +struct lsa_header *ospf_lsa_data_new(size_t size) { - return XCALLOC (MTYPE_OSPF_LSA_DATA, size); + return XCALLOC(MTYPE_OSPF_LSA_DATA, size); } /* Duplicate LSA data. */ -struct lsa_header * -ospf_lsa_data_dup (struct lsa_header *lsah) +struct lsa_header *ospf_lsa_data_dup(struct lsa_header *lsah) { - struct lsa_header *new; + struct lsa_header *new; - new = ospf_lsa_data_new (ntohs (lsah->length)); - memcpy (new, lsah, ntohs (lsah->length)); + new = ospf_lsa_data_new(ntohs(lsah->length)); + memcpy(new, lsah, ntohs(lsah->length)); - return new; + return new; } /* Free LSA data. */ -void -ospf_lsa_data_free (struct lsa_header *lsah) +void ospf_lsa_data_free(struct lsa_header *lsah) { - if (IS_DEBUG_OSPF (lsa, LSA)) - zlog_debug ("LSA[Type%d:%s]: data freed %p", - lsah->type, inet_ntoa (lsah->id), (void *)lsah); + if (IS_DEBUG_OSPF(lsa, LSA)) + zlog_debug("LSA[Type%d:%s]: data freed %p", lsah->type, + inet_ntoa(lsah->id), (void *)lsah); - XFREE (MTYPE_OSPF_LSA_DATA, lsah); + XFREE(MTYPE_OSPF_LSA_DATA, lsah); } /* LSA general functions. */ -const char * -dump_lsa_key (struct ospf_lsa *lsa) +const char *dump_lsa_key(struct ospf_lsa *lsa) { - static char buf[] = { - "Type255,id(255.255.255.255),ar(255.255.255.255)" - }; - struct lsa_header *lsah; + static char buf[] = {"Type255,id(255.255.255.255),ar(255.255.255.255)"}; + struct lsa_header *lsah; - if (lsa != NULL && (lsah = lsa->data) != NULL) - { - char id[INET_ADDRSTRLEN], ar[INET_ADDRSTRLEN]; - strcpy (id, inet_ntoa (lsah->id)); - strcpy (ar, inet_ntoa (lsah->adv_router)); + if (lsa != NULL && (lsah = lsa->data) != NULL) { + char id[INET_ADDRSTRLEN], ar[INET_ADDRSTRLEN]; + strcpy(id, inet_ntoa(lsah->id)); + strcpy(ar, inet_ntoa(lsah->adv_router)); - sprintf (buf, "Type%d,id(%s),ar(%s)", lsah->type, id, ar); - } - else - strcpy (buf, "NULL"); + sprintf(buf, "Type%d,id(%s),ar(%s)", lsah->type, id, ar); + } else + strcpy(buf, "NULL"); - return buf; + return buf; } -u_int32_t -lsa_seqnum_increment (struct ospf_lsa *lsa) +u_int32_t lsa_seqnum_increment(struct ospf_lsa *lsa) { - u_int32_t seqnum; + u_int32_t seqnum; - seqnum = ntohl (lsa->data->ls_seqnum) + 1; + seqnum = ntohl(lsa->data->ls_seqnum) + 1; - return htonl (seqnum); + return htonl(seqnum); } -void -lsa_header_set (struct stream *s, u_char options, - u_char type, struct in_addr id, struct in_addr router_id) +void lsa_header_set(struct stream *s, u_char options, u_char type, + struct in_addr id, struct in_addr router_id) { - struct lsa_header *lsah; + struct lsa_header *lsah; - lsah = (struct lsa_header *) STREAM_DATA (s); + lsah = (struct lsa_header *)STREAM_DATA(s); - lsah->ls_age = htons (OSPF_LSA_INITIAL_AGE); - lsah->options = options; - lsah->type = type; - lsah->id = id; - lsah->adv_router = router_id; - lsah->ls_seqnum = htonl (OSPF_INITIAL_SEQUENCE_NUMBER); + lsah->ls_age = htons(OSPF_LSA_INITIAL_AGE); + lsah->options = options; + lsah->type = type; + lsah->id = id; + lsah->adv_router = router_id; + lsah->ls_seqnum = htonl(OSPF_INITIAL_SEQUENCE_NUMBER); - stream_forward_endp (s, OSPF_LSA_HEADER_SIZE); + stream_forward_endp(s, OSPF_LSA_HEADER_SIZE); } /* router-LSA related functions. */ /* Get router-LSA flags. */ -static u_char -router_lsa_flags (struct ospf_area *area) -{ - u_char flags; - - flags = area->ospf->flags; - - /* Set virtual link flag. */ - if (ospf_full_virtual_nbrs (area)) - SET_FLAG (flags, ROUTER_LSA_VIRTUAL); - else - /* Just sanity check */ - UNSET_FLAG (flags, ROUTER_LSA_VIRTUAL); - - /* Set Shortcut ABR behabiour flag. */ - UNSET_FLAG (flags, ROUTER_LSA_SHORTCUT); - if (area->ospf->abr_type == OSPF_ABR_SHORTCUT) - if (!OSPF_IS_AREA_BACKBONE (area)) - if ((area->shortcut_configured == OSPF_SHORTCUT_DEFAULT && - area->ospf->backbone == NULL) || - area->shortcut_configured == OSPF_SHORTCUT_ENABLE) - SET_FLAG (flags, ROUTER_LSA_SHORTCUT); - - /* ASBR can't exit in stub area. */ - if (area->external_routing == OSPF_AREA_STUB) - UNSET_FLAG (flags, ROUTER_LSA_EXTERNAL); - /* If ASBR set External flag */ - else if (IS_OSPF_ASBR (area->ospf)) - SET_FLAG (flags, ROUTER_LSA_EXTERNAL); - - /* Set ABR dependent flags */ - if (IS_OSPF_ABR (area->ospf)) - { - SET_FLAG (flags, ROUTER_LSA_BORDER); - /* If Area is NSSA and we are both ABR and unconditional translator, - * set Nt bit to inform other routers. - */ - if ( (area->external_routing == OSPF_AREA_NSSA) - && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS)) - SET_FLAG (flags, ROUTER_LSA_NT); - } - return flags; +static u_char router_lsa_flags(struct ospf_area *area) +{ + u_char flags; + + flags = area->ospf->flags; + + /* Set virtual link flag. */ + if (ospf_full_virtual_nbrs(area)) + SET_FLAG(flags, ROUTER_LSA_VIRTUAL); + else + /* Just sanity check */ + UNSET_FLAG(flags, ROUTER_LSA_VIRTUAL); + + /* Set Shortcut ABR behabiour flag. */ + UNSET_FLAG(flags, ROUTER_LSA_SHORTCUT); + if (area->ospf->abr_type == OSPF_ABR_SHORTCUT) + if (!OSPF_IS_AREA_BACKBONE(area)) + if ((area->shortcut_configured == OSPF_SHORTCUT_DEFAULT + && area->ospf->backbone == NULL) + || area->shortcut_configured + == OSPF_SHORTCUT_ENABLE) + SET_FLAG(flags, ROUTER_LSA_SHORTCUT); + + /* ASBR can't exit in stub area. */ + if (area->external_routing == OSPF_AREA_STUB) + UNSET_FLAG(flags, ROUTER_LSA_EXTERNAL); + /* If ASBR set External flag */ + else if (IS_OSPF_ASBR(area->ospf)) + SET_FLAG(flags, ROUTER_LSA_EXTERNAL); + + /* Set ABR dependent flags */ + if (IS_OSPF_ABR(area->ospf)) { + SET_FLAG(flags, ROUTER_LSA_BORDER); + /* If Area is NSSA and we are both ABR and unconditional + * translator, + * set Nt bit to inform other routers. + */ + if ((area->external_routing == OSPF_AREA_NSSA) + && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS)) + SET_FLAG(flags, ROUTER_LSA_NT); + } + return flags; } /* Lookup neighbor other than myself. And check neighbor count, Point-to-Point link must have only 1 neighbor. */ -struct ospf_neighbor * -ospf_nbr_lookup_ptop (struct ospf_interface *oi) +struct ospf_neighbor *ospf_nbr_lookup_ptop(struct ospf_interface *oi) { - struct ospf_neighbor *nbr = NULL; - struct route_node *rn; + struct ospf_neighbor *nbr = NULL; + struct route_node *rn; - /* Search neighbor, there must be one of two nbrs. */ - for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) - if ((nbr = rn->info)) - if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id)) - if (nbr->state == NSM_Full) - { - route_unlock_node (rn); - break; - } + /* Search neighbor, there must be one of two nbrs. */ + for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) + if ((nbr = rn->info)) + if (!IPV4_ADDR_SAME(&nbr->router_id, + &oi->ospf->router_id)) + if (nbr->state == NSM_Full) { + route_unlock_node(rn); + break; + } - /* PtoP link must have only 1 neighbor. */ - if (ospf_nbr_count (oi, 0) > 1) - zlog_warn ("Point-to-Point link has more than 1 neighobrs."); + /* PtoP link must have only 1 neighbor. */ + if (ospf_nbr_count(oi, 0) > 1) + zlog_warn("Point-to-Point link has more than 1 neighobrs."); - return nbr; + return nbr; } /* Determine cost of link, taking RFC3137 stub-router support into * consideration */ -static u_int16_t -ospf_link_cost (struct ospf_interface *oi) +static u_int16_t ospf_link_cost(struct ospf_interface *oi) { - /* RFC3137 stub router support */ - if (!CHECK_FLAG (oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED)) - return oi->output_cost; - else - return OSPF_OUTPUT_COST_INFINITE; + /* RFC3137 stub router support */ + if (!CHECK_FLAG(oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED)) + return oi->output_cost; + else + return OSPF_OUTPUT_COST_INFINITE; } /* Set a link information. */ -static char -link_info_set (struct stream *s, struct in_addr id, - struct in_addr data, u_char type, u_char tos, u_int16_t cost) -{ - /* LSA stream is initially allocated to OSPF_MAX_LSA_SIZE, suits - * vast majority of cases. Some rare routers with lots of links need more. - * we try accomodate those here. - */ - if (STREAM_WRITEABLE(s) < OSPF_ROUTER_LSA_LINK_SIZE) - { - size_t ret = OSPF_MAX_LSA_SIZE; - - /* Can we enlarge the stream still? */ - if (STREAM_SIZE(s) == OSPF_MAX_LSA_SIZE) - { - /* we futz the size here for simplicity, really we need to account - * for just: - * IP Header - (sizeof (struct ip)) - * OSPF Header - OSPF_HEADER_SIZE - * LSA Header - OSPF_LSA_HEADER_SIZE - * MD5 auth data, if MD5 is configured - OSPF_AUTH_MD5_SIZE. - * - * Simpler just to subtract OSPF_MAX_LSA_SIZE though. - */ - ret = stream_resize (s, OSPF_MAX_PACKET_SIZE - OSPF_MAX_LSA_SIZE); - } - - if (ret == OSPF_MAX_LSA_SIZE) - { - zlog_warn ("%s: Out of space in LSA stream, left %zd, size %zd", - __func__, STREAM_REMAIN (s), STREAM_SIZE (s)); - return 0; - } - } - - /* TOS based routing is not supported. */ - stream_put_ipv4 (s, id.s_addr); /* Link ID. */ - stream_put_ipv4 (s, data.s_addr); /* Link Data. */ - stream_putc (s, type); /* Link Type. */ - stream_putc (s, tos); /* TOS = 0. */ - stream_putw (s, cost); /* Link Cost. */ - - return 1; +static char link_info_set(struct stream *s, struct in_addr id, + struct in_addr data, u_char type, u_char tos, + u_int16_t cost) +{ + /* LSA stream is initially allocated to OSPF_MAX_LSA_SIZE, suits + * vast majority of cases. Some rare routers with lots of links need + * more. + * we try accomodate those here. + */ + if (STREAM_WRITEABLE(s) < OSPF_ROUTER_LSA_LINK_SIZE) { + size_t ret = OSPF_MAX_LSA_SIZE; + + /* Can we enlarge the stream still? */ + if (STREAM_SIZE(s) == OSPF_MAX_LSA_SIZE) { + /* we futz the size here for simplicity, really we need + * to account + * for just: + * IP Header - (sizeof (struct ip)) + * OSPF Header - OSPF_HEADER_SIZE + * LSA Header - OSPF_LSA_HEADER_SIZE + * MD5 auth data, if MD5 is configured - + * OSPF_AUTH_MD5_SIZE. + * + * Simpler just to subtract OSPF_MAX_LSA_SIZE though. + */ + ret = stream_resize( + s, OSPF_MAX_PACKET_SIZE - OSPF_MAX_LSA_SIZE); + } + + if (ret == OSPF_MAX_LSA_SIZE) { + zlog_warn( + "%s: Out of space in LSA stream, left %zd, size %zd", + __func__, STREAM_REMAIN(s), STREAM_SIZE(s)); + return 0; + } + } + + /* TOS based routing is not supported. */ + stream_put_ipv4(s, id.s_addr); /* Link ID. */ + stream_put_ipv4(s, data.s_addr); /* Link Data. */ + stream_putc(s, type); /* Link Type. */ + stream_putc(s, tos); /* TOS = 0. */ + stream_putw(s, cost); /* Link Cost. */ + + return 1; } /* Describe Point-to-Point link (Section 12.4.1.1). */ -static int -lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi) -{ - int links = 0; - struct ospf_neighbor *nbr; - struct in_addr id, mask, data; - u_int16_t cost = ospf_link_cost (oi); - - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("LSA[Type1]: Set link Point-to-Point"); - - if ((nbr = ospf_nbr_lookup_ptop (oi))) - if (nbr->state == NSM_Full) - { - if (CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED)) - { - /* For unnumbered point-to-point networks, the Link Data field - should specify the interface's MIB-II ifIndex value. */ - data.s_addr = htonl(oi->ifp->ifindex); - links += link_info_set (s, nbr->router_id, data, - LSA_LINK_TYPE_POINTOPOINT, 0, cost); - } - else - { - links += link_info_set (s, nbr->router_id, - oi->address->u.prefix4, - LSA_LINK_TYPE_POINTOPOINT, 0, cost); - } - } - - /* no need for a stub link for unnumbered interfaces */ - if (!CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED)) - { - /* Regardless of the state of the neighboring router, we must - add a Type 3 link (stub network). - N.B. Options 1 & 2 share basically the same logic. */ - masklen2ip (oi->address->prefixlen, &mask); - id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr & mask.s_addr; - links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, - oi->output_cost); - } - - return links; +static int lsa_link_ptop_set(struct stream *s, struct ospf_interface *oi) +{ + int links = 0; + struct ospf_neighbor *nbr; + struct in_addr id, mask, data; + u_int16_t cost = ospf_link_cost(oi); + + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug("LSA[Type1]: Set link Point-to-Point"); + + if ((nbr = ospf_nbr_lookup_ptop(oi))) + if (nbr->state == NSM_Full) { + if (CHECK_FLAG(oi->connected->flags, + ZEBRA_IFA_UNNUMBERED)) { + /* For unnumbered point-to-point networks, the + Link Data field + should specify the interface's MIB-II ifIndex + value. */ + data.s_addr = htonl(oi->ifp->ifindex); + links += link_info_set( + s, nbr->router_id, data, + LSA_LINK_TYPE_POINTOPOINT, 0, cost); + } else { + links += link_info_set( + s, nbr->router_id, + oi->address->u.prefix4, + LSA_LINK_TYPE_POINTOPOINT, 0, cost); + } + } + + /* no need for a stub link for unnumbered interfaces */ + if (!CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED)) { + /* Regardless of the state of the neighboring router, we must + add a Type 3 link (stub network). + N.B. Options 1 & 2 share basically the same logic. */ + masklen2ip(oi->address->prefixlen, &mask); + id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr + & mask.s_addr; + links += link_info_set(s, id, mask, LSA_LINK_TYPE_STUB, 0, + oi->output_cost); + } + + return links; } /* Describe Broadcast Link. */ -static int -lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi) -{ - struct ospf_neighbor *dr; - struct in_addr id, mask; - u_int16_t cost = ospf_link_cost (oi); - - /* Describe Type 3 Link. */ - if (oi->state == ISM_Waiting) - { - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("LSA[Type1]: Interface %s is in state Waiting. " - "Adding stub interface", oi->ifp->name); - masklen2ip (oi->address->prefixlen, &mask); - id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr; - return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, - oi->output_cost); - } - - dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi)); - /* Describe Type 2 link. */ - if (dr && (dr->state == NSM_Full || - IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) && - ospf_nbr_count (oi, NSM_Full) > 0) - { - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("LSA[Type1]: Interface %s has a DR. " - "Adding transit interface", oi->ifp->name); - return link_info_set (s, DR (oi), oi->address->u.prefix4, - LSA_LINK_TYPE_TRANSIT, 0, cost); - } - /* Describe type 3 link. */ - else - { - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("LSA[Type1]: Interface %s has no DR. " - "Adding stub interface", oi->ifp->name); - masklen2ip (oi->address->prefixlen, &mask); - id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr; - return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, - oi->output_cost); - } -} - -static int -lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi) -{ - struct in_addr id, mask; - - /* Describe Type 3 Link. */ - if (oi->state != ISM_Loopback) - return 0; - - mask.s_addr = 0xffffffff; - id.s_addr = oi->address->u.prefix4.s_addr; - return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0); +static int lsa_link_broadcast_set(struct stream *s, struct ospf_interface *oi) +{ + struct ospf_neighbor *dr; + struct in_addr id, mask; + u_int16_t cost = ospf_link_cost(oi); + + /* Describe Type 3 Link. */ + if (oi->state == ISM_Waiting) { + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug( + "LSA[Type1]: Interface %s is in state Waiting. " + "Adding stub interface", + oi->ifp->name); + masklen2ip(oi->address->prefixlen, &mask); + id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr; + return link_info_set(s, id, mask, LSA_LINK_TYPE_STUB, 0, + oi->output_cost); + } + + dr = ospf_nbr_lookup_by_addr(oi->nbrs, &DR(oi)); + /* Describe Type 2 link. */ + if (dr && (dr->state == NSM_Full + || IPV4_ADDR_SAME(&oi->address->u.prefix4, &DR(oi))) + && ospf_nbr_count(oi, NSM_Full) > 0) { + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug( + "LSA[Type1]: Interface %s has a DR. " + "Adding transit interface", + oi->ifp->name); + return link_info_set(s, DR(oi), oi->address->u.prefix4, + LSA_LINK_TYPE_TRANSIT, 0, cost); + } + /* Describe type 3 link. */ + else { + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug( + "LSA[Type1]: Interface %s has no DR. " + "Adding stub interface", + oi->ifp->name); + masklen2ip(oi->address->prefixlen, &mask); + id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr; + return link_info_set(s, id, mask, LSA_LINK_TYPE_STUB, 0, + oi->output_cost); + } +} + +static int lsa_link_loopback_set(struct stream *s, struct ospf_interface *oi) +{ + struct in_addr id, mask; + + /* Describe Type 3 Link. */ + if (oi->state != ISM_Loopback) + return 0; + + mask.s_addr = 0xffffffff; + id.s_addr = oi->address->u.prefix4.s_addr; + return link_info_set(s, id, mask, LSA_LINK_TYPE_STUB, 0, 0); } /* Describe Virtual Link. */ -static int -lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi) +static int lsa_link_virtuallink_set(struct stream *s, struct ospf_interface *oi) { - struct ospf_neighbor *nbr; - u_int16_t cost = ospf_link_cost (oi); + struct ospf_neighbor *nbr; + u_int16_t cost = ospf_link_cost(oi); - if (oi->state == ISM_PointToPoint) - if ((nbr = ospf_nbr_lookup_ptop (oi))) - if (nbr->state == NSM_Full) - { - return link_info_set (s, nbr->router_id, oi->address->u.prefix4, - LSA_LINK_TYPE_VIRTUALLINK, 0, cost); - } + if (oi->state == ISM_PointToPoint) + if ((nbr = ospf_nbr_lookup_ptop(oi))) + if (nbr->state == NSM_Full) { + return link_info_set(s, nbr->router_id, + oi->address->u.prefix4, + LSA_LINK_TYPE_VIRTUALLINK, + 0, cost); + } - return 0; + return 0; } #define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O) -/* this function add for support point-to-multipoint ,see rfc2328 +/* this function add for support point-to-multipoint ,see rfc2328 12.4.1.4.*/ /* from "edward rrr" <edward_rrr@hotmail.com> http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */ -static int -lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi) -{ - int links = 0; - struct route_node *rn; - struct ospf_neighbor *nbr = NULL; - struct in_addr id, mask; - u_int16_t cost = ospf_link_cost (oi); - - mask.s_addr = 0xffffffff; - id.s_addr = oi->address->u.prefix4.s_addr; - links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0); - - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("PointToMultipoint: running ptomultip_set"); - - /* Search neighbor, */ - for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) - if ((nbr = rn->info) != NULL) - /* Ignore myself. */ - if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id)) - if (nbr->state == NSM_Full) - - { - links += link_info_set (s, nbr->router_id, oi->address->u.prefix4, - LSA_LINK_TYPE_POINTOPOINT, 0, cost); - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("PointToMultipoint: set link to %s", - inet_ntoa(oi->address->u.prefix4)); - } - - return links; +static int lsa_link_ptomp_set(struct stream *s, struct ospf_interface *oi) +{ + int links = 0; + struct route_node *rn; + struct ospf_neighbor *nbr = NULL; + struct in_addr id, mask; + u_int16_t cost = ospf_link_cost(oi); + + mask.s_addr = 0xffffffff; + id.s_addr = oi->address->u.prefix4.s_addr; + links += link_info_set(s, id, mask, LSA_LINK_TYPE_STUB, 0, 0); + + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug("PointToMultipoint: running ptomultip_set"); + + /* Search neighbor, */ + for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) + if ((nbr = rn->info) != NULL) + /* Ignore myself. */ + if (!IPV4_ADDR_SAME(&nbr->router_id, + &oi->ospf->router_id)) + if (nbr->state == NSM_Full) + + { + links += link_info_set( + s, nbr->router_id, + oi->address->u.prefix4, + LSA_LINK_TYPE_POINTOPOINT, 0, + cost); + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug( + "PointToMultipoint: set link to %s", + inet_ntoa( + oi->address->u + .prefix4)); + } + + return links; } /* Set router-LSA link information. */ -static int -router_lsa_link_set (struct stream *s, struct ospf_area *area) -{ - struct listnode *node; - struct ospf_interface *oi; - int links = 0; - - for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi)) - { - struct interface *ifp = oi->ifp; - - /* Check interface is up, OSPF is enable. */ - if (if_is_operative (ifp)) - { - if (oi->state != ISM_Down) - { - oi->lsa_pos_beg = links; - /* Describe each link. */ - switch (oi->type) - { - case OSPF_IFTYPE_POINTOPOINT: - links += lsa_link_ptop_set (s, oi); - break; - case OSPF_IFTYPE_BROADCAST: - links += lsa_link_broadcast_set (s, oi); - break; - case OSPF_IFTYPE_NBMA: - links += lsa_link_nbma_set (s, oi); - break; - case OSPF_IFTYPE_POINTOMULTIPOINT: - links += lsa_link_ptomp_set (s, oi); - break; - case OSPF_IFTYPE_VIRTUALLINK: - links += lsa_link_virtuallink_set (s, oi); - break; - case OSPF_IFTYPE_LOOPBACK: - links += lsa_link_loopback_set (s, oi); +static int router_lsa_link_set(struct stream *s, struct ospf_area *area) +{ + struct listnode *node; + struct ospf_interface *oi; + int links = 0; + + for (ALL_LIST_ELEMENTS_RO(area->oiflist, node, oi)) { + struct interface *ifp = oi->ifp; + + /* Check interface is up, OSPF is enable. */ + if (if_is_operative(ifp)) { + if (oi->state != ISM_Down) { + oi->lsa_pos_beg = links; + /* Describe each link. */ + switch (oi->type) { + case OSPF_IFTYPE_POINTOPOINT: + links += lsa_link_ptop_set(s, oi); + break; + case OSPF_IFTYPE_BROADCAST: + links += lsa_link_broadcast_set(s, oi); + break; + case OSPF_IFTYPE_NBMA: + links += lsa_link_nbma_set(s, oi); + break; + case OSPF_IFTYPE_POINTOMULTIPOINT: + links += lsa_link_ptomp_set(s, oi); + break; + case OSPF_IFTYPE_VIRTUALLINK: + links += + lsa_link_virtuallink_set(s, oi); + break; + case OSPF_IFTYPE_LOOPBACK: + links += lsa_link_loopback_set(s, oi); + } + oi->lsa_pos_end = links; + } } - oi->lsa_pos_end = links; - } } - } - return links; + return links; } /* Set router-LSA body. */ -static void -ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area) -{ - unsigned long putp; - u_int16_t cnt; - - /* Set flags. */ - stream_putc (s, router_lsa_flags (area)); - - /* Set Zero fields. */ - stream_putc (s, 0); - - /* Keep pointer to # links. */ - putp = stream_get_endp(s); - - /* Forward word */ - stream_putw(s, 0); - - /* Set all link information. */ - cnt = router_lsa_link_set (s, area); - - /* Set # of links here. */ - stream_putw_at (s, putp, cnt); -} - -static int -ospf_stub_router_timer (struct thread *t) -{ - struct ospf_area *area = THREAD_ARG (t); - - area->t_stub_router = NULL; - - SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED); - - /* clear stub route state and generate router-lsa refresh, don't - * clobber an administratively set stub-router state though. - */ - if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED)) - return 0; - - UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED); - - ospf_router_lsa_update_area (area); - - return 0; -} - -static void -ospf_stub_router_check (struct ospf_area *area) -{ - /* area must either be administratively configured to be stub - * or startup-time stub-router must be configured and we must in a pre-stub - * state. - */ - if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED)) - { - SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED); - return; - } - - /* not admin-stubbed, check whether startup stubbing is configured and - * whether it's not been done yet - */ - if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED)) - return; - - if (area->ospf->stub_router_startup_time == OSPF_STUB_ROUTER_UNCONFIGURED) - { - /* stub-router is hence done forever for this area, even if someone - * tries configure it (take effect next restart). - */ - SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED); - return; - } - - /* startup stub-router configured and not yet done */ - SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED); - - OSPF_AREA_TIMER_ON (area->t_stub_router, ospf_stub_router_timer, - area->ospf->stub_router_startup_time); -} - +static void ospf_router_lsa_body_set(struct stream *s, struct ospf_area *area) +{ + unsigned long putp; + u_int16_t cnt; + + /* Set flags. */ + stream_putc(s, router_lsa_flags(area)); + + /* Set Zero fields. */ + stream_putc(s, 0); + + /* Keep pointer to # links. */ + putp = stream_get_endp(s); + + /* Forward word */ + stream_putw(s, 0); + + /* Set all link information. */ + cnt = router_lsa_link_set(s, area); + + /* Set # of links here. */ + stream_putw_at(s, putp, cnt); +} + +static int ospf_stub_router_timer(struct thread *t) +{ + struct ospf_area *area = THREAD_ARG(t); + + area->t_stub_router = NULL; + + SET_FLAG(area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED); + + /* clear stub route state and generate router-lsa refresh, don't + * clobber an administratively set stub-router state though. + */ + if (CHECK_FLAG(area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED)) + return 0; + + UNSET_FLAG(area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED); + + ospf_router_lsa_update_area(area); + + return 0; +} + +static void ospf_stub_router_check(struct ospf_area *area) +{ + /* area must either be administratively configured to be stub + * or startup-time stub-router must be configured and we must in a + * pre-stub + * state. + */ + if (CHECK_FLAG(area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED)) { + SET_FLAG(area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED); + return; + } + + /* not admin-stubbed, check whether startup stubbing is configured and + * whether it's not been done yet + */ + if (CHECK_FLAG(area->stub_router_state, + OSPF_AREA_WAS_START_STUB_ROUTED)) + return; + + if (area->ospf->stub_router_startup_time + == OSPF_STUB_ROUTER_UNCONFIGURED) { + /* stub-router is hence done forever for this area, even if + * someone + * tries configure it (take effect next restart). + */ + SET_FLAG(area->stub_router_state, + OSPF_AREA_WAS_START_STUB_ROUTED); + return; + } + + /* startup stub-router configured and not yet done */ + SET_FLAG(area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED); + + OSPF_AREA_TIMER_ON(area->t_stub_router, ospf_stub_router_timer, + area->ospf->stub_router_startup_time); +} + /* Create new router-LSA. */ -static struct ospf_lsa * -ospf_router_lsa_new (struct ospf_area *area) -{ - struct ospf *ospf = area->ospf; - struct stream *s; - struct lsa_header *lsah; - struct ospf_lsa *new; - int length; - - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("LSA[Type1]: Create router-LSA instance"); - - /* check whether stub-router is desired, and if this is the first - * router LSA. - */ - ospf_stub_router_check (area); - - /* Create a stream for LSA. */ - s = stream_new (OSPF_MAX_LSA_SIZE); - /* Set LSA common header fields. */ - lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area), - OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id); - - /* Set router-LSA body fields. */ - ospf_router_lsa_body_set (s, area); - - /* Set length. */ - length = stream_get_endp (s); - lsah = (struct lsa_header *) STREAM_DATA (s); - lsah->length = htons (length); - - /* Now, create OSPF LSA instance. */ - if ( (new = ospf_lsa_new ()) == NULL) - { - zlog_err ("%s: Unable to create new lsa", __func__); - return NULL; - } - - new->area = area; - SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED); - - /* Copy LSA data to store, discard stream. */ - new->data = ospf_lsa_data_new (length); - memcpy (new->data, lsah, length); - stream_free (s); - - return new; +static struct ospf_lsa *ospf_router_lsa_new(struct ospf_area *area) +{ + struct ospf *ospf = area->ospf; + struct stream *s; + struct lsa_header *lsah; + struct ospf_lsa *new; + int length; + + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug("LSA[Type1]: Create router-LSA instance"); + + /* check whether stub-router is desired, and if this is the first + * router LSA. + */ + ospf_stub_router_check(area); + + /* Create a stream for LSA. */ + s = stream_new(OSPF_MAX_LSA_SIZE); + /* Set LSA common header fields. */ + lsa_header_set(s, LSA_OPTIONS_GET(area) | LSA_OPTIONS_NSSA_GET(area), + OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id); + + /* Set router-LSA body fields. */ + ospf_router_lsa_body_set(s, area); + + /* Set length. */ + length = stream_get_endp(s); + lsah = (struct lsa_header *)STREAM_DATA(s); + lsah->length = htons(length); + + /* Now, create OSPF LSA instance. */ + if ((new = ospf_lsa_new()) == NULL) { + zlog_err("%s: Unable to create new lsa", __func__); + return NULL; + } + + new->area = area; + SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED); + + /* Copy LSA data to store, discard stream. */ + new->data = ospf_lsa_data_new(length); + memcpy(new->data, lsah, length); + stream_free(s); + + return new; } /* Originate Router-LSA. */ -static struct ospf_lsa * -ospf_router_lsa_originate (struct ospf_area *area) +static struct ospf_lsa *ospf_router_lsa_originate(struct ospf_area *area) { - struct ospf_lsa *new; - - /* Create new router-LSA instance. */ - if ( (new = ospf_router_lsa_new (area)) == NULL) - { - zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__); - return NULL; - } + struct ospf_lsa *new; - /* Sanity check. */ - if (new->data->adv_router.s_addr == 0) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("LSA[Type1]: AdvRouter is 0, discard"); - ospf_lsa_discard (new); - return NULL; - } + /* Create new router-LSA instance. */ + if ((new = ospf_router_lsa_new(area)) == NULL) { + zlog_err("%s: ospf_router_lsa_new returned NULL", __func__); + return NULL; + } + + /* Sanity check. */ + if (new->data->adv_router.s_addr == 0) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("LSA[Type1]: AdvRouter is 0, discard"); + ospf_lsa_discard(new); + return NULL; + } - /* Install LSA to LSDB. */ - new = ospf_lsa_install (area->ospf, NULL, new); + /* Install LSA to LSDB. */ + new = ospf_lsa_install(area->ospf, NULL, new); - /* Update LSA origination count. */ - area->ospf->lsa_originate_count++; + /* Update LSA origination count. */ + area->ospf->lsa_originate_count++; - /* Flooding new LSA through area. */ - ospf_flood_through_area (area, NULL, new); + /* Flooding new LSA through area. */ + ospf_flood_through_area(area, NULL, new); - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - { - zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p", - new->data->type, inet_ntoa (new->data->id), (void *)new); - ospf_lsa_header_dump (new->data); - } + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { + zlog_debug("LSA[Type%d:%s]: Originate router-LSA %p", + new->data->type, inet_ntoa(new->data->id), + (void *)new); + ospf_lsa_header_dump(new->data); + } - return new; + return new; } /* Refresh router-LSA. */ -static struct ospf_lsa * -ospf_router_lsa_refresh (struct ospf_lsa *lsa) -{ - struct ospf_area *area = lsa->area; - struct ospf_lsa *new; - - /* Sanity check. */ - assert (lsa->data); +static struct ospf_lsa *ospf_router_lsa_refresh(struct ospf_lsa *lsa) +{ + struct ospf_area *area = lsa->area; + struct ospf_lsa *new; + + /* Sanity check. */ + assert(lsa->data); - /* Delete LSA from neighbor retransmit-list. */ - ospf_ls_retransmit_delete_nbr_area (area, lsa); + /* Delete LSA from neighbor retransmit-list. */ + ospf_ls_retransmit_delete_nbr_area(area, lsa); - /* Unregister LSA from refresh-list */ - ospf_refresher_unregister_lsa (area->ospf, lsa); - - /* Create new router-LSA instance. */ - if ( (new = ospf_router_lsa_new (area)) == NULL) - { - zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__); - return NULL; - } - - new->data->ls_seqnum = lsa_seqnum_increment (lsa); + /* Unregister LSA from refresh-list */ + ospf_refresher_unregister_lsa(area->ospf, lsa); - ospf_lsa_install (area->ospf, NULL, new); + /* Create new router-LSA instance. */ + if ((new = ospf_router_lsa_new(area)) == NULL) { + zlog_err("%s: ospf_router_lsa_new returned NULL", __func__); + return NULL; + } + + new->data->ls_seqnum = lsa_seqnum_increment(lsa); - /* Flood LSA through area. */ - ospf_flood_through_area (area, NULL, new); + ospf_lsa_install(area->ospf, NULL, new); - /* Debug logging. */ - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - { - zlog_debug ("LSA[Type%d:%s]: router-LSA refresh", - new->data->type, inet_ntoa (new->data->id)); - ospf_lsa_header_dump (new->data); - } + /* Flood LSA through area. */ + ospf_flood_through_area(area, NULL, new); + + /* Debug logging. */ + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { + zlog_debug("LSA[Type%d:%s]: router-LSA refresh", + new->data->type, inet_ntoa(new->data->id)); + ospf_lsa_header_dump(new->data); + } - return NULL; + return NULL; } -int -ospf_router_lsa_update_area (struct ospf_area *area) +int ospf_router_lsa_update_area(struct ospf_area *area) { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("[router-LSA]: (router-LSA area update)"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("[router-LSA]: (router-LSA area update)"); - /* Now refresh router-LSA. */ - if (area->router_lsa_self) - ospf_lsa_refresh (area->ospf, area->router_lsa_self); - /* Newly originate router-LSA. */ - else - ospf_router_lsa_originate (area); + /* Now refresh router-LSA. */ + if (area->router_lsa_self) + ospf_lsa_refresh(area->ospf, area->router_lsa_self); + /* Newly originate router-LSA. */ + else + ospf_router_lsa_originate(area); - return 0; + return 0; } -int -ospf_router_lsa_update (struct ospf *ospf) +int ospf_router_lsa_update(struct ospf *ospf) { - struct listnode *node, *nnode; - struct ospf_area *area; + struct listnode *node, *nnode; + struct ospf_area *area; - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("Timer[router-LSA Update]: (timer expire)"); + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug("Timer[router-LSA Update]: (timer expire)"); - for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area)) - { - struct ospf_lsa *lsa = area->router_lsa_self; - struct router_lsa *rl; - const char *area_str; + for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) { + struct ospf_lsa *lsa = area->router_lsa_self; + struct router_lsa *rl; + const char *area_str; - /* Keep Area ID string. */ - area_str = AREA_NAME (area); + /* Keep Area ID string. */ + area_str = AREA_NAME(area); - /* If LSA not exist in this Area, originate new. */ - if (lsa == NULL) - { - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str); + /* If LSA not exist in this Area, originate new. */ + if (lsa == NULL) { + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug( + "LSA[Type1]: Create router-LSA for Area %s", + area_str); - ospf_router_lsa_originate (area); - } - /* If router-ID is changed, Link ID must change. - First flush old LSA, then originate new. */ - else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id)) - { - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s", - lsa->data->type, inet_ntoa (lsa->data->id), area_str); - ospf_refresher_unregister_lsa (ospf, lsa); - ospf_lsa_flush_area (lsa, area); - ospf_lsa_unlock (&area->router_lsa_self); - area->router_lsa_self = NULL; - - /* Refresh router-LSA, (not install) and flood through area. */ - ospf_router_lsa_update_area (area); - } - else - { - rl = (struct router_lsa *) lsa->data; - /* Refresh router-LSA, (not install) and flood through area. */ - if (rl->flags != ospf->flags) - ospf_router_lsa_update_area (area); + ospf_router_lsa_originate(area); + } + /* If router-ID is changed, Link ID must change. + First flush old LSA, then originate new. */ + else if (!IPV4_ADDR_SAME(&lsa->data->id, &ospf->router_id)) { + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug( + "LSA[Type%d:%s]: Refresh router-LSA for Area %s", + lsa->data->type, + inet_ntoa(lsa->data->id), area_str); + ospf_refresher_unregister_lsa(ospf, lsa); + ospf_lsa_flush_area(lsa, area); + ospf_lsa_unlock(&area->router_lsa_self); + area->router_lsa_self = NULL; + + /* Refresh router-LSA, (not install) and flood through + * area. */ + ospf_router_lsa_update_area(area); + } else { + rl = (struct router_lsa *)lsa->data; + /* Refresh router-LSA, (not install) and flood through + * area. */ + if (rl->flags != ospf->flags) + ospf_router_lsa_update_area(area); + } } - } - return 0; + return 0; } /* network-LSA related functions. */ /* Originate Network-LSA. */ -static void -ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi) +static void ospf_network_lsa_body_set(struct stream *s, + struct ospf_interface *oi) { - struct in_addr mask; - struct route_node *rn; - struct ospf_neighbor *nbr; + struct in_addr mask; + struct route_node *rn; + struct ospf_neighbor *nbr; - masklen2ip (oi->address->prefixlen, &mask); - stream_put_ipv4 (s, mask.s_addr); + masklen2ip(oi->address->prefixlen, &mask); + stream_put_ipv4(s, mask.s_addr); - /* The network-LSA lists those routers that are fully adjacent to - the Designated Router; each fully adjacent router is identified by - its OSPF Router ID. The Designated Router includes itself in this - list. RFC2328, Section 12.4.2 */ + /* The network-LSA lists those routers that are fully adjacent to + the Designated Router; each fully adjacent router is identified by + its OSPF Router ID. The Designated Router includes itself in this + list. RFC2328, Section 12.4.2 */ - for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) - if ((nbr = rn->info) != NULL) - if (nbr->state == NSM_Full || nbr == oi->nbr_self) - stream_put_ipv4 (s, nbr->router_id.s_addr); + for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) + if ((nbr = rn->info) != NULL) + if (nbr->state == NSM_Full || nbr == oi->nbr_self) + stream_put_ipv4(s, nbr->router_id.s_addr); } -static struct ospf_lsa * -ospf_network_lsa_new (struct ospf_interface *oi) -{ - struct stream *s; - struct ospf_lsa *new; - struct lsa_header *lsah; - struct ospf_if_params *oip; - int length; - - /* If there are no neighbours on this network (the net is stub), - the router does not originate network-LSA (see RFC 12.4.2) */ - if (oi->full_nbrs == 0) - return NULL; - - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("LSA[Type2]: Create network-LSA instance"); - - /* Create new stream for LSA. */ - s = stream_new (OSPF_MAX_LSA_SIZE); - lsah = (struct lsa_header *) STREAM_DATA (s); - - lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)), - OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id); - - /* Set network-LSA body fields. */ - ospf_network_lsa_body_set (s, oi); - - /* Set length. */ - length = stream_get_endp (s); - lsah->length = htons (length); - - /* Create OSPF LSA instance. */ - if ( (new = ospf_lsa_new ()) == NULL) - { - zlog_err ("%s: ospf_lsa_new returned NULL", __func__); - return NULL; - } - - new->area = oi->area; - SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED); - - /* Copy LSA to store. */ - new->data = ospf_lsa_data_new (length); - memcpy (new->data, lsah, length); - stream_free (s); - - /* Remember prior network LSA sequence numbers, even if we stop - * originating one for this oi, to try avoid re-originating LSAs with a - * prior sequence number, and thus speed up adjency forming & convergence. - */ - if ((oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4))) - { - new->data->ls_seqnum = oip->network_lsa_seqnum; - new->data->ls_seqnum = lsa_seqnum_increment (new); - } - else - { - oip = ospf_get_if_params (oi->ifp, oi->address->u.prefix4); - ospf_if_update_params (oi->ifp, oi->address->u.prefix4); - } - oip->network_lsa_seqnum = new->data->ls_seqnum; - - return new; +static struct ospf_lsa *ospf_network_lsa_new(struct ospf_interface *oi) +{ + struct stream *s; + struct ospf_lsa *new; + struct lsa_header *lsah; + struct ospf_if_params *oip; + int length; + + /* If there are no neighbours on this network (the net is stub), + the router does not originate network-LSA (see RFC 12.4.2) */ + if (oi->full_nbrs == 0) + return NULL; + + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug("LSA[Type2]: Create network-LSA instance"); + + /* Create new stream for LSA. */ + s = stream_new(OSPF_MAX_LSA_SIZE); + lsah = (struct lsa_header *)STREAM_DATA(s); + + lsa_header_set(s, (OPTIONS(oi) | LSA_OPTIONS_GET(oi->area)), + OSPF_NETWORK_LSA, DR(oi), oi->ospf->router_id); + + /* Set network-LSA body fields. */ + ospf_network_lsa_body_set(s, oi); + + /* Set length. */ + length = stream_get_endp(s); + lsah->length = htons(length); + + /* Create OSPF LSA instance. */ + if ((new = ospf_lsa_new()) == NULL) { + zlog_err("%s: ospf_lsa_new returned NULL", __func__); + return NULL; + } + + new->area = oi->area; + SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED); + + /* Copy LSA to store. */ + new->data = ospf_lsa_data_new(length); + memcpy(new->data, lsah, length); + stream_free(s); + + /* Remember prior network LSA sequence numbers, even if we stop + * originating one for this oi, to try avoid re-originating LSAs with a + * prior sequence number, and thus speed up adjency forming & + * convergence. + */ + if ((oip = ospf_lookup_if_params(oi->ifp, oi->address->u.prefix4))) { + new->data->ls_seqnum = oip->network_lsa_seqnum; + new->data->ls_seqnum = lsa_seqnum_increment(new); + } else { + oip = ospf_get_if_params(oi->ifp, oi->address->u.prefix4); + ospf_if_update_params(oi->ifp, oi->address->u.prefix4); + } + oip->network_lsa_seqnum = new->data->ls_seqnum; + + return new; } /* Originate network-LSA. */ -void -ospf_network_lsa_update (struct ospf_interface *oi) +void ospf_network_lsa_update(struct ospf_interface *oi) { - struct ospf_lsa *new; - - if (oi->network_lsa_self != NULL) - { - ospf_lsa_refresh (oi->ospf, oi->network_lsa_self); - return; - } - - /* Create new network-LSA instance. */ - new = ospf_network_lsa_new (oi); - if (new == NULL) - return; + struct ospf_lsa *new; - /* Install LSA to LSDB. */ - new = ospf_lsa_install (oi->ospf, oi, new); + if (oi->network_lsa_self != NULL) { + ospf_lsa_refresh(oi->ospf, oi->network_lsa_self); + return; + } + + /* Create new network-LSA instance. */ + new = ospf_network_lsa_new(oi); + if (new == NULL) + return; - /* Update LSA origination count. */ - oi->ospf->lsa_originate_count++; + /* Install LSA to LSDB. */ + new = ospf_lsa_install(oi->ospf, oi, new); - /* Flooding new LSA through area. */ - ospf_flood_through_area (oi->area, NULL, new); + /* Update LSA origination count. */ + oi->ospf->lsa_originate_count++; - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - { - zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p", - new->data->type, inet_ntoa (new->data->id), (void *)new); - ospf_lsa_header_dump (new->data); - } + /* Flooding new LSA through area. */ + ospf_flood_through_area(oi->area, NULL, new); + + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { + zlog_debug("LSA[Type%d:%s]: Originate network-LSA %p", + new->data->type, inet_ntoa(new->data->id), + (void *)new); + ospf_lsa_header_dump(new->data); + } - return; + return; } -static struct ospf_lsa * -ospf_network_lsa_refresh (struct ospf_lsa *lsa) -{ - struct ospf_area *area = lsa->area; - struct ospf_lsa *new, *new2; - struct ospf_if_params *oip; - struct ospf_interface *oi; - - assert (lsa->data); - - /* Retrieve the oi for the network LSA */ - oi = ospf_if_lookup_by_local_addr (area->ospf, NULL, lsa->data->id); - if (oi == NULL) - { - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - { - zlog_debug ("LSA[Type%d:%s]: network-LSA refresh: " - "no oi found, ick, ignoring.", - lsa->data->type, inet_ntoa (lsa->data->id)); - ospf_lsa_header_dump (lsa->data); - } - return NULL; - } - /* Delete LSA from neighbor retransmit-list. */ - ospf_ls_retransmit_delete_nbr_area (area, lsa); - - /* Unregister LSA from refresh-list */ - ospf_refresher_unregister_lsa (area->ospf, lsa); - - /* Create new network-LSA instance. */ - new = ospf_network_lsa_new (oi); - if (new == NULL) - return NULL; - - oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4); - assert (oip != NULL); - oip->network_lsa_seqnum = new->data->ls_seqnum = lsa_seqnum_increment (lsa); - - new2 = ospf_lsa_install (area->ospf, oi, new); - - assert (new2 == new); - - /* Flood LSA through aera. */ - ospf_flood_through_area (area, NULL, new); - - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - { - zlog_debug ("LSA[Type%d:%s]: network-LSA refresh", - new->data->type, inet_ntoa (new->data->id)); - ospf_lsa_header_dump (new->data); - } - - return new; -} - -static void -stream_put_ospf_metric (struct stream *s, u_int32_t metric_value) -{ - u_int32_t metric; - char *mp; - - /* Put 0 metric. TOS metric is not supported. */ - metric = htonl (metric_value); - mp = (char *) &metric; - mp++; - stream_put (s, mp, 3); +static struct ospf_lsa *ospf_network_lsa_refresh(struct ospf_lsa *lsa) +{ + struct ospf_area *area = lsa->area; + struct ospf_lsa *new, *new2; + struct ospf_if_params *oip; + struct ospf_interface *oi; + + assert(lsa->data); + + /* Retrieve the oi for the network LSA */ + oi = ospf_if_lookup_by_local_addr(area->ospf, NULL, lsa->data->id); + if (oi == NULL) { + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { + zlog_debug( + "LSA[Type%d:%s]: network-LSA refresh: " + "no oi found, ick, ignoring.", + lsa->data->type, inet_ntoa(lsa->data->id)); + ospf_lsa_header_dump(lsa->data); + } + return NULL; + } + /* Delete LSA from neighbor retransmit-list. */ + ospf_ls_retransmit_delete_nbr_area(area, lsa); + + /* Unregister LSA from refresh-list */ + ospf_refresher_unregister_lsa(area->ospf, lsa); + + /* Create new network-LSA instance. */ + new = ospf_network_lsa_new(oi); + if (new == NULL) + return NULL; + + oip = ospf_lookup_if_params(oi->ifp, oi->address->u.prefix4); + assert(oip != NULL); + oip->network_lsa_seqnum = new->data->ls_seqnum = + lsa_seqnum_increment(lsa); + + new2 = ospf_lsa_install(area->ospf, oi, new); + + assert(new2 == new); + + /* Flood LSA through aera. */ + ospf_flood_through_area(area, NULL, new); + + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { + zlog_debug("LSA[Type%d:%s]: network-LSA refresh", + new->data->type, inet_ntoa(new->data->id)); + ospf_lsa_header_dump(new->data); + } + + return new; +} + +static void stream_put_ospf_metric(struct stream *s, u_int32_t metric_value) +{ + u_int32_t metric; + char *mp; + + /* Put 0 metric. TOS metric is not supported. */ + metric = htonl(metric_value); + mp = (char *)&metric; + mp++; + stream_put(s, mp, 3); } /* summary-LSA related functions. */ -static void -ospf_summary_lsa_body_set (struct stream *s, struct prefix *p, - u_int32_t metric) +static void ospf_summary_lsa_body_set(struct stream *s, struct prefix *p, + u_int32_t metric) { - struct in_addr mask; + struct in_addr mask; - masklen2ip (p->prefixlen, &mask); + masklen2ip(p->prefixlen, &mask); - /* Put Network Mask. */ - stream_put_ipv4 (s, mask.s_addr); + /* Put Network Mask. */ + stream_put_ipv4(s, mask.s_addr); - /* Set # TOS. */ - stream_putc (s, (u_char) 0); + /* Set # TOS. */ + stream_putc(s, (u_char)0); - /* Set metric. */ - stream_put_ospf_metric (s, metric); + /* Set metric. */ + stream_put_ospf_metric(s, metric); } -static struct ospf_lsa * -ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p, - u_int32_t metric, struct in_addr id) +static struct ospf_lsa *ospf_summary_lsa_new(struct ospf_area *area, + struct prefix *p, u_int32_t metric, + struct in_addr id) { - struct stream *s; - struct ospf_lsa *new; - struct lsa_header *lsah; - int length; + struct stream *s; + struct ospf_lsa *new; + struct lsa_header *lsah; + int length; - if (id.s_addr == 0xffffffff) - { - /* Maybe Link State ID not available. */ - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("LSA[Type%d]: Link ID not available, can't originate", - OSPF_SUMMARY_LSA); - return NULL; - } + if (id.s_addr == 0xffffffff) { + /* Maybe Link State ID not available. */ + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug( + "LSA[Type%d]: Link ID not available, can't originate", + OSPF_SUMMARY_LSA); + return NULL; + } - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("LSA[Type3]: Create summary-LSA instance"); + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug("LSA[Type3]: Create summary-LSA instance"); - /* Create new stream for LSA. */ - s = stream_new (OSPF_MAX_LSA_SIZE); - lsah = (struct lsa_header *) STREAM_DATA (s); + /* Create new stream for LSA. */ + s = stream_new(OSPF_MAX_LSA_SIZE); + lsah = (struct lsa_header *)STREAM_DATA(s); - lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA, - id, area->ospf->router_id); + lsa_header_set(s, LSA_OPTIONS_GET(area), OSPF_SUMMARY_LSA, id, + area->ospf->router_id); - /* Set summary-LSA body fields. */ - ospf_summary_lsa_body_set (s, p, metric); + /* Set summary-LSA body fields. */ + ospf_summary_lsa_body_set(s, p, metric); - /* Set length. */ - length = stream_get_endp (s); - lsah->length = htons (length); + /* Set length. */ + length = stream_get_endp(s); + lsah->length = htons(length); - /* Create OSPF LSA instance. */ - new = ospf_lsa_new (); - new->area = area; - SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED); + /* Create OSPF LSA instance. */ + new = ospf_lsa_new(); + new->area = area; + SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED); - /* Copy LSA to store. */ - new->data = ospf_lsa_data_new (length); - memcpy (new->data, lsah, length); - stream_free (s); + /* Copy LSA to store. */ + new->data = ospf_lsa_data_new(length); + memcpy(new->data, lsah, length); + stream_free(s); - return new; + return new; } /* Originate Summary-LSA. */ -struct ospf_lsa * -ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric, - struct ospf_area *area) -{ - struct ospf_lsa *new; - struct in_addr id; - - id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p); - - if (id.s_addr == 0xffffffff) - { - /* Maybe Link State ID not available. */ - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("LSA[Type%d]: Link ID not available, can't originate", - OSPF_SUMMARY_LSA); - return NULL; - } - - /* Create new summary-LSA instance. */ - if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id))) - return NULL; - - /* Instlal LSA to LSDB. */ - new = ospf_lsa_install (area->ospf, NULL, new); - - /* Update LSA origination count. */ - area->ospf->lsa_originate_count++; - - /* Flooding new LSA through area. */ - ospf_flood_through_area (area, NULL, new); - - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - { - zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p", - new->data->type, inet_ntoa (new->data->id), (void *)new); - ospf_lsa_header_dump (new->data); - } - - return new; -} - -static struct ospf_lsa* -ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa) -{ - struct ospf_lsa *new; - struct summary_lsa *sl; - struct prefix p; - - /* Sanity check. */ - assert (lsa->data); - - sl = (struct summary_lsa *)lsa->data; - p.prefixlen = ip_masklen (sl->mask); - new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric), - sl->header.id); - - if (!new) - return NULL; - - new->data->ls_seqnum = lsa_seqnum_increment (lsa); - - ospf_lsa_install (ospf, NULL, new); - - /* Flood LSA through AS. */ - ospf_flood_through_area (new->area, NULL, new); - - /* Debug logging. */ - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - { - zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh", - new->data->type, inet_ntoa (new->data->id)); - ospf_lsa_header_dump (new->data); - } - - return new; +struct ospf_lsa *ospf_summary_lsa_originate(struct prefix_ipv4 *p, + u_int32_t metric, + struct ospf_area *area) +{ + struct ospf_lsa *new; + struct in_addr id; + + id = ospf_lsa_unique_id(area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p); + + if (id.s_addr == 0xffffffff) { + /* Maybe Link State ID not available. */ + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug( + "LSA[Type%d]: Link ID not available, can't originate", + OSPF_SUMMARY_LSA); + return NULL; + } + + /* Create new summary-LSA instance. */ + if (!(new = ospf_summary_lsa_new(area, (struct prefix *)p, metric, id))) + return NULL; + + /* Instlal LSA to LSDB. */ + new = ospf_lsa_install(area->ospf, NULL, new); + + /* Update LSA origination count. */ + area->ospf->lsa_originate_count++; + + /* Flooding new LSA through area. */ + ospf_flood_through_area(area, NULL, new); + + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { + zlog_debug("LSA[Type%d:%s]: Originate summary-LSA %p", + new->data->type, inet_ntoa(new->data->id), + (void *)new); + ospf_lsa_header_dump(new->data); + } + + return new; +} + +static struct ospf_lsa *ospf_summary_lsa_refresh(struct ospf *ospf, + struct ospf_lsa *lsa) +{ + struct ospf_lsa *new; + struct summary_lsa *sl; + struct prefix p; + + /* Sanity check. */ + assert(lsa->data); + + sl = (struct summary_lsa *)lsa->data; + p.prefixlen = ip_masklen(sl->mask); + new = ospf_summary_lsa_new(lsa->area, &p, GET_METRIC(sl->metric), + sl->header.id); + + if (!new) + return NULL; + + new->data->ls_seqnum = lsa_seqnum_increment(lsa); + + ospf_lsa_install(ospf, NULL, new); + + /* Flood LSA through AS. */ + ospf_flood_through_area(new->area, NULL, new); + + /* Debug logging. */ + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { + zlog_debug("LSA[Type%d:%s]: summary-LSA refresh", + new->data->type, inet_ntoa(new->data->id)); + ospf_lsa_header_dump(new->data); + } + + return new; } /* summary-ASBR-LSA related functions. */ -static void -ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p, - u_int32_t metric) +static void ospf_summary_asbr_lsa_body_set(struct stream *s, struct prefix *p, + u_int32_t metric) { - /* Put Network Mask. */ - stream_put_ipv4 (s, (u_int32_t) 0); + /* Put Network Mask. */ + stream_put_ipv4(s, (u_int32_t)0); - /* Set # TOS. */ - stream_putc (s, (u_char) 0); + /* Set # TOS. */ + stream_putc(s, (u_char)0); - /* Set metric. */ - stream_put_ospf_metric (s, metric); + /* Set metric. */ + stream_put_ospf_metric(s, metric); } -static struct ospf_lsa * -ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p, - u_int32_t metric, struct in_addr id) +static struct ospf_lsa *ospf_summary_asbr_lsa_new(struct ospf_area *area, + struct prefix *p, + u_int32_t metric, + struct in_addr id) { - struct stream *s; - struct ospf_lsa *new; - struct lsa_header *lsah; - int length; + struct stream *s; + struct ospf_lsa *new; + struct lsa_header *lsah; + int length; - if (id.s_addr == 0xffffffff) - { - /* Maybe Link State ID not available. */ - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("LSA[Type%d]: Link ID not available, can't originate", - OSPF_ASBR_SUMMARY_LSA); - return NULL; - } + if (id.s_addr == 0xffffffff) { + /* Maybe Link State ID not available. */ + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug( + "LSA[Type%d]: Link ID not available, can't originate", + OSPF_ASBR_SUMMARY_LSA); + return NULL; + } - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("LSA[Type3]: Create summary-LSA instance"); + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug("LSA[Type3]: Create summary-LSA instance"); - /* Create new stream for LSA. */ - s = stream_new (OSPF_MAX_LSA_SIZE); - lsah = (struct lsa_header *) STREAM_DATA (s); + /* Create new stream for LSA. */ + s = stream_new(OSPF_MAX_LSA_SIZE); + lsah = (struct lsa_header *)STREAM_DATA(s); - lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA, - id, area->ospf->router_id); + lsa_header_set(s, LSA_OPTIONS_GET(area), OSPF_ASBR_SUMMARY_LSA, id, + area->ospf->router_id); - /* Set summary-LSA body fields. */ - ospf_summary_asbr_lsa_body_set (s, p, metric); + /* Set summary-LSA body fields. */ + ospf_summary_asbr_lsa_body_set(s, p, metric); - /* Set length. */ - length = stream_get_endp (s); - lsah->length = htons (length); + /* Set length. */ + length = stream_get_endp(s); + lsah->length = htons(length); - /* Create OSPF LSA instance. */ - new = ospf_lsa_new (); - new->area = area; - SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED); + /* Create OSPF LSA instance. */ + new = ospf_lsa_new(); + new->area = area; + SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED); - /* Copy LSA to store. */ - new->data = ospf_lsa_data_new (length); - memcpy (new->data, lsah, length); - stream_free (s); + /* Copy LSA to store. */ + new->data = ospf_lsa_data_new(length); + memcpy(new->data, lsah, length); + stream_free(s); - return new; + return new; } /* Originate summary-ASBR-LSA. */ -struct ospf_lsa * -ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric, - struct ospf_area *area) -{ - struct ospf_lsa *new; - struct in_addr id; - - id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p); - - if (id.s_addr == 0xffffffff) - { - /* Maybe Link State ID not available. */ - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("LSA[Type%d]: Link ID not available, can't originate", - OSPF_ASBR_SUMMARY_LSA); - return NULL; - } - - /* Create new summary-LSA instance. */ - new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id); - if (!new) - return NULL; - - /* Install LSA to LSDB. */ - new = ospf_lsa_install (area->ospf, NULL, new); - - /* Update LSA origination count. */ - area->ospf->lsa_originate_count++; - - /* Flooding new LSA through area. */ - ospf_flood_through_area (area, NULL, new); - - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - { - zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p", - new->data->type, inet_ntoa (new->data->id), (void *)new); - ospf_lsa_header_dump (new->data); - } - - return new; -} - -static struct ospf_lsa* -ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa) -{ - struct ospf_lsa *new; - struct summary_lsa *sl; - struct prefix p; - - /* Sanity check. */ - assert (lsa->data); - - sl = (struct summary_lsa *)lsa->data; - p.prefixlen = ip_masklen (sl->mask); - new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric), - sl->header.id); - if (!new) - return NULL; - - new->data->ls_seqnum = lsa_seqnum_increment (lsa); +struct ospf_lsa *ospf_summary_asbr_lsa_originate(struct prefix_ipv4 *p, + u_int32_t metric, + struct ospf_area *area) +{ + struct ospf_lsa *new; + struct in_addr id; + + id = ospf_lsa_unique_id(area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, + p); + + if (id.s_addr == 0xffffffff) { + /* Maybe Link State ID not available. */ + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug( + "LSA[Type%d]: Link ID not available, can't originate", + OSPF_ASBR_SUMMARY_LSA); + return NULL; + } + + /* Create new summary-LSA instance. */ + new = ospf_summary_asbr_lsa_new(area, (struct prefix *)p, metric, id); + if (!new) + return NULL; + + /* Install LSA to LSDB. */ + new = ospf_lsa_install(area->ospf, NULL, new); - ospf_lsa_install (ospf, NULL, new); - - /* Flood LSA through area. */ - ospf_flood_through_area (new->area, NULL, new); + /* Update LSA origination count. */ + area->ospf->lsa_originate_count++; - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - { - zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh", - new->data->type, inet_ntoa (new->data->id)); - ospf_lsa_header_dump (new->data); - } + /* Flooding new LSA through area. */ + ospf_flood_through_area(area, NULL, new); - return new; + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { + zlog_debug("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p", + new->data->type, inet_ntoa(new->data->id), + (void *)new); + ospf_lsa_header_dump(new->data); + } + + return new; +} + +static struct ospf_lsa *ospf_summary_asbr_lsa_refresh(struct ospf *ospf, + struct ospf_lsa *lsa) +{ + struct ospf_lsa *new; + struct summary_lsa *sl; + struct prefix p; + + /* Sanity check. */ + assert(lsa->data); + + sl = (struct summary_lsa *)lsa->data; + p.prefixlen = ip_masklen(sl->mask); + new = ospf_summary_asbr_lsa_new(lsa->area, &p, GET_METRIC(sl->metric), + sl->header.id); + if (!new) + return NULL; + + new->data->ls_seqnum = lsa_seqnum_increment(lsa); + + ospf_lsa_install(ospf, NULL, new); + + /* Flood LSA through area. */ + ospf_flood_through_area(new->area, NULL, new); + + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { + zlog_debug("LSA[Type%d:%s]: summary-ASBR-LSA refresh", + new->data->type, inet_ntoa(new->data->id)); + ospf_lsa_header_dump(new->data); + } + + return new; } /* AS-external-LSA related functions. */ /* Get nexthop for AS-external-LSAs. Return nexthop if its interface is connected, else 0*/ -static struct in_addr -ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop) +static struct in_addr ospf_external_lsa_nexthop_get(struct ospf *ospf, + struct in_addr nexthop) { - struct in_addr fwd; - struct prefix nh; - struct listnode *node; - struct ospf_interface *oi; + struct in_addr fwd; + struct prefix nh; + struct listnode *node; + struct ospf_interface *oi; + + fwd.s_addr = 0; - fwd.s_addr = 0; + if (!nexthop.s_addr) + return fwd; - if (!nexthop.s_addr) - return fwd; + /* Check whether nexthop is covered by OSPF network. */ + nh.family = AF_INET; + nh.u.prefix4 = nexthop; + nh.prefixlen = IPV4_MAX_BITLEN; - /* Check whether nexthop is covered by OSPF network. */ - nh.family = AF_INET; - nh.u.prefix4 = nexthop; - nh.prefixlen = IPV4_MAX_BITLEN; - - /* XXX/SCALE: If there were a lot of oi's on an ifp, then it'd be - * better to make use of the per-ifp table of ois. - */ - for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) - if (if_is_operative (oi->ifp)) - if (oi->address->family == AF_INET) - if (prefix_match (oi->address, &nh)) - return nexthop; + /* XXX/SCALE: If there were a lot of oi's on an ifp, then it'd be + * better to make use of the per-ifp table of ois. + */ + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) + if (if_is_operative(oi->ifp)) + if (oi->address->family == AF_INET) + if (prefix_match(oi->address, &nh)) + return nexthop; - return fwd; + return fwd; } /* NSSA-external-LSA related functions. */ /* Get 1st IP connection for Forward Addr */ -struct in_addr -ospf_get_ip_from_ifp (struct ospf_interface *oi) +struct in_addr ospf_get_ip_from_ifp(struct ospf_interface *oi) { - struct in_addr fwd; + struct in_addr fwd; - fwd.s_addr = 0; + fwd.s_addr = 0; - if (if_is_operative (oi->ifp)) - return oi->address->u.prefix4; - - return fwd; + if (if_is_operative(oi->ifp)) + return oi->address->u.prefix4; + + return fwd; } /* Get 1st IP connection for Forward Addr */ -struct in_addr -ospf_get_nssa_ip (struct ospf_area *area) -{ - struct in_addr fwd; - struct in_addr best_default; - struct listnode *node; - struct ospf_interface *oi; - - fwd.s_addr = 0; - best_default.s_addr = 0; - - for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi)) - { - if (if_is_operative (oi->ifp)) - if (oi->area->external_routing == OSPF_AREA_NSSA) - if (oi->address && oi->address->family == AF_INET) - { - if (best_default.s_addr == 0) - best_default = oi->address->u.prefix4; - if (oi->area == area) - return oi->address->u.prefix4; - } - } - if (best_default.s_addr != 0) - return best_default; +struct in_addr ospf_get_nssa_ip(struct ospf_area *area) +{ + struct in_addr fwd; + struct in_addr best_default; + struct listnode *node; + struct ospf_interface *oi; + + fwd.s_addr = 0; + best_default.s_addr = 0; + + for (ALL_LIST_ELEMENTS_RO(area->ospf->oiflist, node, oi)) { + if (if_is_operative(oi->ifp)) + if (oi->area->external_routing == OSPF_AREA_NSSA) + if (oi->address + && oi->address->family == AF_INET) { + if (best_default.s_addr == 0) + best_default = + oi->address->u.prefix4; + if (oi->area == area) + return oi->address->u.prefix4; + } + } + if (best_default.s_addr != 0) + return best_default; - if (best_default.s_addr != 0) - return best_default; + if (best_default.s_addr != 0) + return best_default; - return fwd; + return fwd; } #define DEFAULT_DEFAULT_METRIC 20 @@ -1536,841 +1495,840 @@ ospf_get_nssa_ip (struct ospf_area *area) #define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2 -int -metric_type (struct ospf *ospf, u_char src, u_short instance) +int metric_type(struct ospf *ospf, u_char src, u_short instance) { - struct ospf_redist *red; + struct ospf_redist *red; - red = ospf_redist_lookup(ospf, src, instance); + red = ospf_redist_lookup(ospf, src, instance); - return ((!red || red->dmetric.type < 0) ? - DEFAULT_METRIC_TYPE : red->dmetric.type); + return ((!red || red->dmetric.type < 0) ? DEFAULT_METRIC_TYPE + : red->dmetric.type); } -int -metric_value (struct ospf *ospf, u_char src, u_short instance) +int metric_value(struct ospf *ospf, u_char src, u_short instance) { - struct ospf_redist *red; + struct ospf_redist *red; - red = ospf_redist_lookup(ospf, src, instance); - if (!red || red->dmetric.value < 0) - { - if (src == DEFAULT_ROUTE) - { - if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA) - return DEFAULT_DEFAULT_ORIGINATE_METRIC; - else - return DEFAULT_DEFAULT_ALWAYS_METRIC; + red = ospf_redist_lookup(ospf, src, instance); + if (!red || red->dmetric.value < 0) { + if (src == DEFAULT_ROUTE) { + if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA) + return DEFAULT_DEFAULT_ORIGINATE_METRIC; + else + return DEFAULT_DEFAULT_ALWAYS_METRIC; + } else if (ospf->default_metric < 0) + return DEFAULT_DEFAULT_METRIC; + else + return ospf->default_metric; } - else if (ospf->default_metric < 0) - return DEFAULT_DEFAULT_METRIC; - else - return ospf->default_metric; - } - return red->dmetric.value; + return red->dmetric.value; } /* Set AS-external-LSA body. */ -static void -ospf_external_lsa_body_set (struct stream *s, struct external_info *ei, - struct ospf *ospf) -{ - struct prefix_ipv4 *p = &ei->p; - struct in_addr mask, fwd_addr; - u_int32_t mvalue; - int mtype; - int type; - u_short instance; - - /* Put Network Mask. */ - masklen2ip (p->prefixlen, &mask); - stream_put_ipv4 (s, mask.s_addr); - - /* If prefix is default, specify DEFAULT_ROUTE. */ - type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type; - instance = is_prefix_default (&ei->p) ? 0 : ei->instance; - - mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ? - ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type, instance); - - mvalue = (ROUTEMAP_METRIC (ei) != -1) ? - ROUTEMAP_METRIC (ei) : metric_value (ospf, type, instance); - - /* Put type of external metric. */ - stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0)); - - /* Put 0 metric. TOS metric is not supported. */ - stream_put_ospf_metric (s, mvalue); - - /* Get forwarding address to nexthop if on the Connection List, else 0. */ - fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop); - - /* Put forwarding address. */ - stream_put_ipv4 (s, fwd_addr.s_addr); - - /* Put route tag */ - stream_putl (s, ei->tag); +static void ospf_external_lsa_body_set(struct stream *s, + struct external_info *ei, + struct ospf *ospf) +{ + struct prefix_ipv4 *p = &ei->p; + struct in_addr mask, fwd_addr; + u_int32_t mvalue; + int mtype; + int type; + u_short instance; + + /* Put Network Mask. */ + masklen2ip(p->prefixlen, &mask); + stream_put_ipv4(s, mask.s_addr); + + /* If prefix is default, specify DEFAULT_ROUTE. */ + type = is_prefix_default(&ei->p) ? DEFAULT_ROUTE : ei->type; + instance = is_prefix_default(&ei->p) ? 0 : ei->instance; + + mtype = (ROUTEMAP_METRIC_TYPE(ei) != -1) + ? ROUTEMAP_METRIC_TYPE(ei) + : metric_type(ospf, type, instance); + + mvalue = (ROUTEMAP_METRIC(ei) != -1) + ? ROUTEMAP_METRIC(ei) + : metric_value(ospf, type, instance); + + /* Put type of external metric. */ + stream_putc(s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0)); + + /* Put 0 metric. TOS metric is not supported. */ + stream_put_ospf_metric(s, mvalue); + + /* Get forwarding address to nexthop if on the Connection List, else 0. + */ + fwd_addr = ospf_external_lsa_nexthop_get(ospf, ei->nexthop); + + /* Put forwarding address. */ + stream_put_ipv4(s, fwd_addr.s_addr); + + /* Put route tag */ + stream_putl(s, ei->tag); } /* Create new external-LSA. */ -static struct ospf_lsa * -ospf_external_lsa_new (struct ospf *ospf, - struct external_info *ei, struct in_addr *old_id) -{ - struct stream *s; - struct lsa_header *lsah; - struct ospf_lsa *new; - struct in_addr id; - int length; - - if (ei == NULL) - { - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("LSA[Type5]: External info is NULL, can't originate"); - return NULL; - } - - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance"); - - /* If old Link State ID is specified, refresh LSA with same ID. */ - if (old_id) - id = *old_id; - /* Get Link State with unique ID. */ - else - { - id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p); - if (id.s_addr == 0xffffffff) - { - /* Maybe Link State ID not available. */ - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("LSA[Type5]: Link ID not available, can't originate"); - return NULL; - } - } - - /* Create new stream for LSA. */ - s = stream_new (OSPF_MAX_LSA_SIZE); - lsah = (struct lsa_header *) STREAM_DATA (s); - - /* Set LSA common header fields. */ - lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA, - id, ospf->router_id); - - /* Set AS-external-LSA body fields. */ - ospf_external_lsa_body_set (s, ei, ospf); - - /* Set length. */ - length = stream_get_endp (s); - lsah->length = htons (length); - - /* Now, create OSPF LSA instance. */ - new = ospf_lsa_new (); - new->area = NULL; - SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED); - - /* Copy LSA data to store, discard stream. */ - new->data = ospf_lsa_data_new (length); - memcpy (new->data, lsah, length); - stream_free (s); - - return new; +static struct ospf_lsa *ospf_external_lsa_new(struct ospf *ospf, + struct external_info *ei, + struct in_addr *old_id) +{ + struct stream *s; + struct lsa_header *lsah; + struct ospf_lsa *new; + struct in_addr id; + int length; + + if (ei == NULL) { + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug( + "LSA[Type5]: External info is NULL, can't originate"); + return NULL; + } + + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug("LSA[Type5]: Originate AS-external-LSA instance"); + + /* If old Link State ID is specified, refresh LSA with same ID. */ + if (old_id) + id = *old_id; + /* Get Link State with unique ID. */ + else { + id = ospf_lsa_unique_id(ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, + &ei->p); + if (id.s_addr == 0xffffffff) { + /* Maybe Link State ID not available. */ + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug( + "LSA[Type5]: Link ID not available, can't originate"); + return NULL; + } + } + + /* Create new stream for LSA. */ + s = stream_new(OSPF_MAX_LSA_SIZE); + lsah = (struct lsa_header *)STREAM_DATA(s); + + /* Set LSA common header fields. */ + lsa_header_set(s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA, id, + ospf->router_id); + + /* Set AS-external-LSA body fields. */ + ospf_external_lsa_body_set(s, ei, ospf); + + /* Set length. */ + length = stream_get_endp(s); + lsah->length = htons(length); + + /* Now, create OSPF LSA instance. */ + new = ospf_lsa_new(); + new->area = NULL; + SET_FLAG(new->flags, + OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED); + + /* Copy LSA data to store, discard stream. */ + new->data = ospf_lsa_data_new(length); + memcpy(new->data, lsah, length); + stream_free(s); + + return new; } /* As Type-7 */ -static void -ospf_install_flood_nssa (struct ospf *ospf, - struct ospf_lsa *lsa, struct external_info *ei) -{ - struct ospf_lsa *new; - struct as_external_lsa *extlsa; - struct ospf_area *area; - struct listnode *node, *nnode; - - /* LSA may be a Type-5 originated via translation of a Type-7 LSA - * which originated from an NSSA area. In which case it should not be - * flooded back to NSSA areas. - */ - if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)) - return; - - /* NSSA Originate or Refresh (If anyNSSA) - - LSA is self-originated. And just installed as Type-5. - Additionally, install as Type-7 LSDB for every attached NSSA. - - P-Bit controls which ABR performs translation to outside world; If - we are an ABR....do not set the P-bit, because we send the Type-5, - not as the ABR Translator, but as the ASBR owner within the AS! - - If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The - elected ABR Translator will see the P-bit, Translate, and re-flood. - - Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to - Type-5's to non-NSSA Areas. (it will also attempt a re-install) */ - - for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area)) - { - /* Don't install Type-7 LSA's into nonNSSA area */ - if (area->external_routing != OSPF_AREA_NSSA) - continue; - - /* make lsa duplicate, lock=1 */ - new = ospf_lsa_dup (lsa); - new->area = area; - new->data->type = OSPF_AS_NSSA_LSA; - - /* set P-bit if not ABR */ - if (! IS_OSPF_ABR (ospf)) - { - SET_FLAG(new->data->options, OSPF_OPTION_NP); - - /* set non-zero FWD ADDR - - draft-ietf-ospf-nssa-update-09.txt - - if the network between the NSSA AS boundary router and the - adjacent AS is advertised into OSPF as an internal OSPF route, - the forwarding address should be the next op address as is cu - currently done with type-5 LSAs. If the intervening network is - not adversited into OSPF as an internal OSPF route and the - type-7 LSA's P-bit is set a forwarding address should be - selected from one of the router's active OSPF inteface addresses - which belong to the NSSA. If no such addresses exist, then - no type-7 LSA's with the P-bit set should originate from this - router. */ - - /* kevinm: not updating lsa anymore, just new */ - extlsa = (struct as_external_lsa *)(new->data); - - if (extlsa->e[0].fwd_addr.s_addr == 0) - extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */ - - if (extlsa->e[0].fwd_addr.s_addr == 0) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR"); - ospf_lsa_discard (new); - return; - } - } - - /* install also as Type-7 */ - ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */ - - /* will send each copy, lock=2+n */ - ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */ - } +static void ospf_install_flood_nssa(struct ospf *ospf, struct ospf_lsa *lsa, + struct external_info *ei) +{ + struct ospf_lsa *new; + struct as_external_lsa *extlsa; + struct ospf_area *area; + struct listnode *node, *nnode; + + /* LSA may be a Type-5 originated via translation of a Type-7 LSA + * which originated from an NSSA area. In which case it should not be + * flooded back to NSSA areas. + */ + if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT)) + return; + + /* NSSA Originate or Refresh (If anyNSSA) + + LSA is self-originated. And just installed as Type-5. + Additionally, install as Type-7 LSDB for every attached NSSA. + + P-Bit controls which ABR performs translation to outside world; If + we are an ABR....do not set the P-bit, because we send the Type-5, + not as the ABR Translator, but as the ASBR owner within the AS! + + If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The + elected ABR Translator will see the P-bit, Translate, and re-flood. + + Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to + Type-5's to non-NSSA Areas. (it will also attempt a re-install) */ + + for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) { + /* Don't install Type-7 LSA's into nonNSSA area */ + if (area->external_routing != OSPF_AREA_NSSA) + continue; + + /* make lsa duplicate, lock=1 */ + new = ospf_lsa_dup(lsa); + new->area = area; + new->data->type = OSPF_AS_NSSA_LSA; + + /* set P-bit if not ABR */ + if (!IS_OSPF_ABR(ospf)) { + SET_FLAG(new->data->options, OSPF_OPTION_NP); + + /* set non-zero FWD ADDR + + draft-ietf-ospf-nssa-update-09.txt + + if the network between the NSSA AS boundary router and + the + adjacent AS is advertised into OSPF as an internal OSPF + route, + the forwarding address should be the next op address as + is cu + currently done with type-5 LSAs. If the intervening + network is + not adversited into OSPF as an internal OSPF route and + the + type-7 LSA's P-bit is set a forwarding address should be + selected from one of the router's active OSPF inteface + addresses + which belong to the NSSA. If no such addresses exist, + then + no type-7 LSA's with the P-bit set should originate from + this + router. */ + + /* kevinm: not updating lsa anymore, just new */ + extlsa = (struct as_external_lsa *)(new->data); + + if (extlsa->e[0].fwd_addr.s_addr == 0) + extlsa->e[0].fwd_addr = ospf_get_nssa_ip( + area); /* this NSSA area in ifp */ + + if (extlsa->e[0].fwd_addr.s_addr == 0) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "LSA[Type-7]: Could not build FWD-ADDR"); + ospf_lsa_discard(new); + return; + } + } + + /* install also as Type-7 */ + ospf_lsa_install(ospf, NULL, + new); /* Remove Old, Lock New = 2 */ + + /* will send each copy, lock=2+n */ + ospf_flood_through_as( + ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */ + } } -static struct ospf_lsa * -ospf_lsa_translated_nssa_new (struct ospf *ospf, - struct ospf_lsa *type7) -{ - - struct ospf_lsa *new; - struct as_external_lsa *ext, *extnew; - struct external_info ei; - - ext = (struct as_external_lsa *)(type7->data); - - /* need external_info struct, fill in bare minimum */ - ei.p.family = AF_INET; - ei.p.prefix = type7->data->id; - ei.p.prefixlen = ip_masklen (ext->mask); - ei.type = ZEBRA_ROUTE_OSPF; - ei.nexthop = ext->header.adv_router; - ei.route_map_set.metric = -1; - ei.route_map_set.metric_type = -1; - ei.tag = 0; - - if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_nssa_translate_originate(): Could not originate " - "Translated Type-5 for %s", - inet_ntoa (ei.p.prefix)); - return NULL; - } - - extnew = (struct as_external_lsa *)(new->data); - - /* copy over Type-7 data to new */ - extnew->e[0].tos = ext->e[0].tos; - extnew->e[0].route_tag = ext->e[0].route_tag; - extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr; - new->data->ls_seqnum = type7->data->ls_seqnum; - - /* add translated flag, checksum and lock new lsa */ - SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */ - new = ospf_lsa_lock (new); - - return new; +static struct ospf_lsa *ospf_lsa_translated_nssa_new(struct ospf *ospf, + struct ospf_lsa *type7) +{ + + struct ospf_lsa *new; + struct as_external_lsa *ext, *extnew; + struct external_info ei; + + ext = (struct as_external_lsa *)(type7->data); + + /* need external_info struct, fill in bare minimum */ + ei.p.family = AF_INET; + ei.p.prefix = type7->data->id; + ei.p.prefixlen = ip_masklen(ext->mask); + ei.type = ZEBRA_ROUTE_OSPF; + ei.nexthop = ext->header.adv_router; + ei.route_map_set.metric = -1; + ei.route_map_set.metric_type = -1; + ei.tag = 0; + + if ((new = ospf_external_lsa_new(ospf, &ei, &type7->data->id)) + == NULL) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_nssa_translate_originate(): Could not originate " + "Translated Type-5 for %s", + inet_ntoa(ei.p.prefix)); + return NULL; + } + + extnew = (struct as_external_lsa *)(new->data); + + /* copy over Type-7 data to new */ + extnew->e[0].tos = ext->e[0].tos; + extnew->e[0].route_tag = ext->e[0].route_tag; + extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr; + new->data->ls_seqnum = type7->data->ls_seqnum; + + /* add translated flag, checksum and lock new lsa */ + SET_FLAG(new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */ + new = ospf_lsa_lock(new); + + return new; } /* Originate Translated Type-5 for supplied Type-7 NSSA LSA */ -struct ospf_lsa * -ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7) -{ - struct ospf_lsa *new; - struct as_external_lsa *extnew; - - /* we cant use ospf_external_lsa_originate() as we need to set - * the OSPF_LSA_LOCAL_XLT flag, must originate by hand - */ - - if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_translated_nssa_originate(): Could not translate " - "Type-7, Id %s, to Type-5", - inet_ntoa (type7->data->id)); - return NULL; - } - - extnew = (struct as_external_lsa *)new; - - if (IS_DEBUG_OSPF_NSSA) - { - zlog_debug ("ospf_translated_nssa_originate(): " - "translated Type 7, installed:"); - ospf_lsa_header_dump (new->data); - zlog_debug (" Network mask: %d",ip_masklen (extnew->mask)); - zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr)); - } - - if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_lsa_translated_nssa_originate(): " - "Could not install LSA " - "id %s", inet_ntoa (type7->data->id)); - return NULL; - } - - ospf->lsa_originate_count++; - ospf_flood_through_as (ospf, NULL, new); - - return new; +struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *ospf, + struct ospf_lsa *type7) +{ + struct ospf_lsa *new; + struct as_external_lsa *extnew; + + /* we cant use ospf_external_lsa_originate() as we need to set + * the OSPF_LSA_LOCAL_XLT flag, must originate by hand + */ + + if ((new = ospf_lsa_translated_nssa_new(ospf, type7)) == NULL) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_translated_nssa_originate(): Could not translate " + "Type-7, Id %s, to Type-5", + inet_ntoa(type7->data->id)); + return NULL; + } + + extnew = (struct as_external_lsa *)new; + + if (IS_DEBUG_OSPF_NSSA) { + zlog_debug( + "ospf_translated_nssa_originate(): " + "translated Type 7, installed:"); + ospf_lsa_header_dump(new->data); + zlog_debug(" Network mask: %d", ip_masklen(extnew->mask)); + zlog_debug(" Forward addr: %s", + inet_ntoa(extnew->e[0].fwd_addr)); + } + + if ((new = ospf_lsa_install(ospf, NULL, new)) == NULL) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_lsa_translated_nssa_originate(): " + "Could not install LSA " + "id %s", + inet_ntoa(type7->data->id)); + return NULL; + } + + ospf->lsa_originate_count++; + ospf_flood_through_as(ospf, NULL, new); + + return new; } /* Refresh Translated from NSSA AS-external-LSA. */ -struct ospf_lsa * -ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7, - struct ospf_lsa *type5) -{ - struct ospf_lsa *new = NULL; - - /* Sanity checks. */ - assert (type7 || type5); - if (!(type7 || type5)) - return NULL; - if (type7) - assert (type7->data); - if (type5) - assert (type5->data); - assert (ospf->anyNSSA); - - /* get required data according to what has been given */ - if (type7 && type5 == NULL) - { - /* find the translated Type-5 for this Type-7 */ - struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data); - struct prefix_ipv4 p = - { - .prefix = type7->data->id, - .prefixlen = ip_masklen (ext->mask), - .family = AF_INET, - }; - - type5 = ospf_external_info_find_lsa (ospf, &p); - } - else if (type5 && type7 == NULL) - { - /* find the type-7 from which supplied type-5 was translated, - * ie find first type-7 with same LSA Id. - */ - struct listnode *ln, *lnn; - struct route_node *rn; - struct ospf_lsa *lsa; - struct ospf_area *area; - - for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area)) - { - if (area->external_routing != OSPF_AREA_NSSA - && !type7) - continue; - - LSDB_LOOP (NSSA_LSDB(area), rn, lsa) - { - if (lsa->data->id.s_addr == type5->data->id.s_addr) - { - type7 = lsa; - break; - } - } - } - } - - /* do we have type7? */ - if (!type7) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for " - "Type-5 LSA Id %s", - inet_ntoa (type5->data->id)); - return NULL; - } - - /* do we have valid translated type5? */ - if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) ) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 " - "found for Type-7 with Id %s", - inet_ntoa (type7->data->id)); - return NULL; - } - - /* Delete LSA from neighbor retransmit-list. */ - ospf_ls_retransmit_delete_nbr_as (ospf, type5); - - /* create new translated LSA */ - if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_translated_nssa_refresh(): Could not translate " - "Type-7 for %s to Type-5", - inet_ntoa (type7->data->id)); - return NULL; - } - - if ( !(new = ospf_lsa_install (ospf, NULL, new)) ) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_translated_nssa_refresh(): Could not install " - "translated LSA, Id %s", - inet_ntoa (type7->data->id)); - return NULL; - } - - /* Flood LSA through area. */ - ospf_flood_through_as (ospf, NULL, new); - - return new; -} - -int -is_prefix_default (struct prefix_ipv4 *p) -{ - struct prefix_ipv4 q; - - q.family = AF_INET; - q.prefix.s_addr = 0; - q.prefixlen = 0; - - return prefix_same ((struct prefix *) p, (struct prefix *) &q); +struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf, + struct ospf_lsa *type7, + struct ospf_lsa *type5) +{ + struct ospf_lsa *new = NULL; + + /* Sanity checks. */ + assert(type7 || type5); + if (!(type7 || type5)) + return NULL; + if (type7) + assert(type7->data); + if (type5) + assert(type5->data); + assert(ospf->anyNSSA); + + /* get required data according to what has been given */ + if (type7 && type5 == NULL) { + /* find the translated Type-5 for this Type-7 */ + struct as_external_lsa *ext = + (struct as_external_lsa *)(type7->data); + struct prefix_ipv4 p = { + .prefix = type7->data->id, + .prefixlen = ip_masklen(ext->mask), + .family = AF_INET, + }; + + type5 = ospf_external_info_find_lsa(ospf, &p); + } else if (type5 && type7 == NULL) { + /* find the type-7 from which supplied type-5 was translated, + * ie find first type-7 with same LSA Id. + */ + struct listnode *ln, *lnn; + struct route_node *rn; + struct ospf_lsa *lsa; + struct ospf_area *area; + + for (ALL_LIST_ELEMENTS(ospf->areas, ln, lnn, area)) { + if (area->external_routing != OSPF_AREA_NSSA && !type7) + continue; + + LSDB_LOOP(NSSA_LSDB(area), rn, lsa) + { + if (lsa->data->id.s_addr + == type5->data->id.s_addr) { + type7 = lsa; + break; + } + } + } + } + + /* do we have type7? */ + if (!type7) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_translated_nssa_refresh(): no Type-7 found for " + "Type-5 LSA Id %s", + inet_ntoa(type5->data->id)); + return NULL; + } + + /* do we have valid translated type5? */ + if (type5 == NULL || !CHECK_FLAG(type5->flags, OSPF_LSA_LOCAL_XLT)) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_translated_nssa_refresh(): No translated Type-5 " + "found for Type-7 with Id %s", + inet_ntoa(type7->data->id)); + return NULL; + } + + /* Delete LSA from neighbor retransmit-list. */ + ospf_ls_retransmit_delete_nbr_as(ospf, type5); + + /* create new translated LSA */ + if ((new = ospf_lsa_translated_nssa_new(ospf, type7)) == NULL) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_translated_nssa_refresh(): Could not translate " + "Type-7 for %s to Type-5", + inet_ntoa(type7->data->id)); + return NULL; + } + + if (!(new = ospf_lsa_install(ospf, NULL, new))) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "ospf_translated_nssa_refresh(): Could not install " + "translated LSA, Id %s", + inet_ntoa(type7->data->id)); + return NULL; + } + + /* Flood LSA through area. */ + ospf_flood_through_as(ospf, NULL, new); + + return new; +} + +int is_prefix_default(struct prefix_ipv4 *p) +{ + struct prefix_ipv4 q; + + q.family = AF_INET; + q.prefix.s_addr = 0; + q.prefixlen = 0; + + return prefix_same((struct prefix *)p, (struct prefix *)&q); } /* Originate an AS-external-LSA, install and flood. */ -struct ospf_lsa * -ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei) -{ - struct ospf_lsa *new; - - /* Added for NSSA project.... - - External LSAs are originated in ASBRs as usual, but for NSSA systems. - there is the global Type-5 LSDB and a Type-7 LSDB installed for - every area. The Type-7's are flooded to every IR and every ABR; We - install the Type-5 LSDB so that the normal "refresh" code operates - as usual, and flag them as not used during ASE calculations. The - Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding - Address of non-zero. - - If an ABR is the elected NSSA translator, following SPF and during - the ABR task it will translate all the scanned Type-7's, with P-bit - ON and not-self generated, and translate to Type-5's throughout the - non-NSSA/STUB AS. - - A difference in operation depends whether this ASBR is an ABR - or not. If not an ABR, the P-bit is ON, to indicate that any - elected NSSA-ABR can perform its translation. - - If an ABR, the P-bit is OFF; No ABR will perform translation and - this ASBR will flood the Type-5 LSA as usual. - - For the case where this ASBR is not an ABR, the ASE calculations - are based on the Type-5 LSDB; The Type-7 LSDB exists just to - demonstrate to the user that there are LSA's that belong to any - attached NSSA. - - Finally, it just so happens that when the ABR is translating every - Type-7 into Type-5, it installs it into the Type-5 LSDB as an - approved Type-5 (translated from Type-7); at the end of translation - if any Translated Type-5's remain unapproved, then they must be - flushed from the AS. - - */ - - /* Check the AS-external-LSA should be originated. */ - if (!ospf_redistribute_check (ospf, ei, NULL)) - return NULL; - - /* Create new AS-external-LSA instance. */ - if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA", - inet_ntoa (ei->p.prefix)); - return NULL; - } - - /* Install newly created LSA into Type-5 LSDB, lock = 1. */ - ospf_lsa_install (ospf, NULL, new); - - /* Update LSA origination count. */ - ospf->lsa_originate_count++; - - /* Flooding new LSA. only to AS (non-NSSA/STUB) */ - ospf_flood_through_as (ospf, NULL, new); - - /* If there is any attached NSSA, do special handling */ - if (ospf->anyNSSA && - /* stay away from translated LSAs! */ - !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT))) - ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */ - - /* Debug logging. */ - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - { - zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p", - new->data->type, inet_ntoa (new->data->id), (void *)new); - ospf_lsa_header_dump (new->data); - } - - return new; +struct ospf_lsa *ospf_external_lsa_originate(struct ospf *ospf, + struct external_info *ei) +{ + struct ospf_lsa *new; + + /* Added for NSSA project.... + + External LSAs are originated in ASBRs as usual, but for NSSA + systems. + there is the global Type-5 LSDB and a Type-7 LSDB installed for + every area. The Type-7's are flooded to every IR and every ABR; We + install the Type-5 LSDB so that the normal "refresh" code operates + as usual, and flag them as not used during ASE calculations. The + Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding + Address of non-zero. + + If an ABR is the elected NSSA translator, following SPF and during + the ABR task it will translate all the scanned Type-7's, with P-bit + ON and not-self generated, and translate to Type-5's throughout the + non-NSSA/STUB AS. + + A difference in operation depends whether this ASBR is an ABR + or not. If not an ABR, the P-bit is ON, to indicate that any + elected NSSA-ABR can perform its translation. + + If an ABR, the P-bit is OFF; No ABR will perform translation and + this ASBR will flood the Type-5 LSA as usual. + + For the case where this ASBR is not an ABR, the ASE calculations + are based on the Type-5 LSDB; The Type-7 LSDB exists just to + demonstrate to the user that there are LSA's that belong to any + attached NSSA. + + Finally, it just so happens that when the ABR is translating every + Type-7 into Type-5, it installs it into the Type-5 LSDB as an + approved Type-5 (translated from Type-7); at the end of translation + if any Translated Type-5's remain unapproved, then they must be + flushed from the AS. + + */ + + /* Check the AS-external-LSA should be originated. */ + if (!ospf_redistribute_check(ospf, ei, NULL)) + return NULL; + + /* Create new AS-external-LSA instance. */ + if ((new = ospf_external_lsa_new(ospf, ei, NULL)) == NULL) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "LSA[Type5:%s]: Could not originate AS-external-LSA", + inet_ntoa(ei->p.prefix)); + return NULL; + } + + /* Install newly created LSA into Type-5 LSDB, lock = 1. */ + ospf_lsa_install(ospf, NULL, new); + + /* Update LSA origination count. */ + ospf->lsa_originate_count++; + + /* Flooding new LSA. only to AS (non-NSSA/STUB) */ + ospf_flood_through_as(ospf, NULL, new); + + /* If there is any attached NSSA, do special handling */ + if (ospf->anyNSSA && + /* stay away from translated LSAs! */ + !(CHECK_FLAG(new->flags, OSPF_LSA_LOCAL_XLT))) + ospf_install_flood_nssa( + ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */ + + /* Debug logging. */ + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { + zlog_debug("LSA[Type%d:%s]: Originate AS-external-LSA %p", + new->data->type, inet_ntoa(new->data->id), + (void *)new); + ospf_lsa_header_dump(new->data); + } + + return new; } /* Originate AS-external-LSA from external info with initial flag. */ -int -ospf_external_lsa_originate_timer (struct thread *thread) -{ - struct ospf *ospf = THREAD_ARG (thread); - struct route_node *rn; - struct external_info *ei; - struct route_table *rt; - int type = THREAD_VAL (thread); - struct list *ext_list; - struct listnode *node; - struct ospf_external *ext; - - ospf->t_external_lsa = NULL; - - ext_list = om->external[type]; - if (!ext_list) - return 0; - - for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) - /* Originate As-external-LSA from all type of distribute source. */ - if ((rt = ext->external_info)) - for (rn = route_top (rt); rn; rn = route_next (rn)) - if ((ei = rn->info) != NULL) - if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p)) - if (!ospf_external_lsa_originate (ospf, ei)) - zlog_warn ("LSA: AS-external-LSA was not originated."); - - return 0; -} - -static struct external_info * -ospf_default_external_info (struct ospf *ospf) -{ - int type; - struct route_node *rn; - struct prefix_ipv4 p; - - p.family = AF_INET; - p.prefix.s_addr = 0; - p.prefixlen = 0; - - /* First, lookup redistributed default route. */ - for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) - { - struct list *ext_list; - struct listnode *node; - struct ospf_external *ext; - - if (type == ZEBRA_ROUTE_OSPF) - continue; - - ext_list = om->external[type]; - if (!ext_list) - continue; - - for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) - { - rn = route_node_lookup (ext->external_info, (struct prefix *) &p); - if (rn != NULL) - { - route_unlock_node (rn); - assert (rn->info); - if (ospf_redistribute_check (ospf, rn->info, NULL)) - return rn->info; - } - } - } - - return NULL; -} - -int -ospf_default_originate_timer (struct thread *thread) -{ - struct prefix_ipv4 p; - struct in_addr nexthop; - struct external_info *ei; - struct ospf *ospf; - - ospf = THREAD_ARG (thread); - - p.family = AF_INET; - p.prefix.s_addr = 0; - p.prefixlen = 0; - - if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS) - { - /* If there is no default route via redistribute, - then originate AS-external-LSA with nexthop 0 (self). */ - nexthop.s_addr = 0; - ospf_external_info_add (DEFAULT_ROUTE, 0, p, 0, nexthop, 0); - } - - if ((ei = ospf_default_external_info (ospf))) - ospf_external_lsa_originate (ospf, ei); - - return 0; +int ospf_external_lsa_originate_timer(struct thread *thread) +{ + struct ospf *ospf = THREAD_ARG(thread); + struct route_node *rn; + struct external_info *ei; + struct route_table *rt; + int type = THREAD_VAL(thread); + struct list *ext_list; + struct listnode *node; + struct ospf_external *ext; + + ospf->t_external_lsa = NULL; + + ext_list = om->external[type]; + if (!ext_list) + return 0; + + for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) + /* Originate As-external-LSA from all type of distribute source. + */ + if ((rt = ext->external_info)) + for (rn = route_top(rt); rn; rn = route_next(rn)) + if ((ei = rn->info) != NULL) + if (!is_prefix_default( + (struct prefix_ipv4 *)&ei + ->p)) + if (!ospf_external_lsa_originate( + ospf, ei)) + zlog_warn( + "LSA: AS-external-LSA was not originated."); + + return 0; +} + +static struct external_info *ospf_default_external_info(struct ospf *ospf) +{ + int type; + struct route_node *rn; + struct prefix_ipv4 p; + + p.family = AF_INET; + p.prefix.s_addr = 0; + p.prefixlen = 0; + + /* First, lookup redistributed default route. */ + for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) { + struct list *ext_list; + struct listnode *node; + struct ospf_external *ext; + + if (type == ZEBRA_ROUTE_OSPF) + continue; + + ext_list = om->external[type]; + if (!ext_list) + continue; + + for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) { + rn = route_node_lookup(ext->external_info, + (struct prefix *)&p); + if (rn != NULL) { + route_unlock_node(rn); + assert(rn->info); + if (ospf_redistribute_check(ospf, rn->info, + NULL)) + return rn->info; + } + } + } + + return NULL; +} + +int ospf_default_originate_timer(struct thread *thread) +{ + struct prefix_ipv4 p; + struct in_addr nexthop; + struct external_info *ei; + struct ospf *ospf; + + ospf = THREAD_ARG(thread); + + p.family = AF_INET; + p.prefix.s_addr = 0; + p.prefixlen = 0; + + if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS) { + /* If there is no default route via redistribute, + then originate AS-external-LSA with nexthop 0 (self). */ + nexthop.s_addr = 0; + ospf_external_info_add(DEFAULT_ROUTE, 0, p, 0, nexthop, 0); + } + + if ((ei = ospf_default_external_info(ospf))) + ospf_external_lsa_originate(ospf, ei); + + return 0; } /* Flush any NSSA LSAs for given prefix */ -void -ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p) -{ - struct listnode *node, *nnode; - struct ospf_lsa *lsa; - struct ospf_area *area; - - for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area)) - { - if (area->external_routing == OSPF_AREA_NSSA) - { - if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix, - ospf->router_id))) - { - if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) - zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB", - inet_ntoa (p->prefix), p->prefixlen); - continue; - } - ospf_ls_retransmit_delete_nbr_area (area, lsa); - if (!IS_LSA_MAXAGE (lsa)) - { - ospf_refresher_unregister_lsa (ospf, lsa); - ospf_lsa_flush_area (lsa, area); - } - } - } +void ospf_nssa_lsa_flush(struct ospf *ospf, struct prefix_ipv4 *p) +{ + struct listnode *node, *nnode; + struct ospf_lsa *lsa; + struct ospf_area *area; + + for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) { + if (area->external_routing == OSPF_AREA_NSSA) { + if (!(lsa = ospf_lsa_lookup(area, OSPF_AS_NSSA_LSA, + p->prefix, + ospf->router_id))) { + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) + zlog_debug( + "LSA: There is no such AS-NSSA-LSA %s/%d in LSDB", + inet_ntoa(p->prefix), + p->prefixlen); + continue; + } + ospf_ls_retransmit_delete_nbr_area(area, lsa); + if (!IS_LSA_MAXAGE(lsa)) { + ospf_refresher_unregister_lsa(ospf, lsa); + ospf_lsa_flush_area(lsa, area); + } + } + } } /* Flush an AS-external-LSA from LSDB and routing domain. */ -void -ospf_external_lsa_flush (struct ospf *ospf, - u_char type, struct prefix_ipv4 *p, - ifindex_t ifindex /*, struct in_addr nexthop */) -{ - struct ospf_lsa *lsa; - - if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) - zlog_debug ("LSA: Flushing AS-external-LSA %s/%d", - inet_ntoa (p->prefix), p->prefixlen); - - /* First lookup LSA from LSDB. */ - if (!(lsa = ospf_external_info_find_lsa (ospf, p))) - { - if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) - zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB", - inet_ntoa (p->prefix), p->prefixlen); - return; - } - - /* If LSA is selforiginated, not a translated LSA, and there is - * NSSA area, flush Type-7 LSA's at first. - */ - if (IS_LSA_SELF(lsa) && (ospf->anyNSSA) - && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))) - ospf_nssa_lsa_flush (ospf, p); - - /* Sweep LSA from Link State Retransmit List. */ - ospf_ls_retransmit_delete_nbr_as (ospf, lsa); - - /* There must be no self-originated LSA in rtrs_external. */ +void ospf_external_lsa_flush(struct ospf *ospf, u_char type, + struct prefix_ipv4 *p, + ifindex_t ifindex /*, struct in_addr nexthop */) +{ + struct ospf_lsa *lsa; + + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) + zlog_debug("LSA: Flushing AS-external-LSA %s/%d", + inet_ntoa(p->prefix), p->prefixlen); + + /* First lookup LSA from LSDB. */ + if (!(lsa = ospf_external_info_find_lsa(ospf, p))) { + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) + zlog_debug( + "LSA: There is no such AS-external-LSA %s/%d in LSDB", + inet_ntoa(p->prefix), p->prefixlen); + return; + } + + /* If LSA is selforiginated, not a translated LSA, and there is + * NSSA area, flush Type-7 LSA's at first. + */ + if (IS_LSA_SELF(lsa) && (ospf->anyNSSA) + && !(CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT))) + ospf_nssa_lsa_flush(ospf, p); + + /* Sweep LSA from Link State Retransmit List. */ + ospf_ls_retransmit_delete_nbr_as(ospf, lsa); + +/* There must be no self-originated LSA in rtrs_external. */ #if 0 /* Remove External route from Zebra. */ ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop); #endif - if (!IS_LSA_MAXAGE (lsa)) - { - /* Unregister LSA from Refresh queue. */ - ospf_refresher_unregister_lsa (ospf, lsa); - - /* Flush AS-external-LSA through AS. */ - ospf_lsa_flush_as (ospf, lsa); - } - - if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) - zlog_debug ("ospf_external_lsa_flush(): stop"); -} - -void -ospf_external_lsa_refresh_default (struct ospf *ospf) -{ - struct prefix_ipv4 p; - struct external_info *ei; - struct ospf_lsa *lsa; - - p.family = AF_INET; - p.prefixlen = 0; - p.prefix.s_addr = 0; - - ei = ospf_default_external_info (ospf); - lsa = ospf_external_info_find_lsa (ospf, &p); - - if (ei) - { - if (lsa) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", - (void *)lsa); - ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE); - } - else - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA"); - ospf_external_lsa_originate (ospf, ei); - } - } - else - { - if (lsa) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA"); - ospf_refresher_unregister_lsa (ospf, lsa); - ospf_lsa_flush_as (ospf, lsa); - } - } -} - -void -ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, u_short instance, - int force) -{ - struct route_node *rn; - struct external_info *ei; - struct ospf_external *ext; - - if (type != DEFAULT_ROUTE) - if ((ext = ospf_external_lookup(type, instance)) && - EXTERNAL_INFO (ext)) - /* Refresh each redistributed AS-external-LSAs. */ - for (rn = route_top (EXTERNAL_INFO (ext)); rn; rn = route_next (rn)) - if ((ei = rn->info)) - if (!is_prefix_default (&ei->p)) - { - struct ospf_lsa *lsa; - - if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p))) - ospf_external_lsa_refresh (ospf, lsa, ei, force); - else - ospf_external_lsa_originate (ospf, ei); - } + if (!IS_LSA_MAXAGE(lsa)) { + /* Unregister LSA from Refresh queue. */ + ospf_refresher_unregister_lsa(ospf, lsa); + + /* Flush AS-external-LSA through AS. */ + ospf_lsa_flush_as(ospf, lsa); + } + + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) + zlog_debug("ospf_external_lsa_flush(): stop"); +} + +void ospf_external_lsa_refresh_default(struct ospf *ospf) +{ + struct prefix_ipv4 p; + struct external_info *ei; + struct ospf_lsa *lsa; + + p.family = AF_INET; + p.prefixlen = 0; + p.prefix.s_addr = 0; + + ei = ospf_default_external_info(ospf); + lsa = ospf_external_info_find_lsa(ospf, &p); + + if (ei) { + if (lsa) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", + (void *)lsa); + ospf_external_lsa_refresh(ospf, lsa, ei, + LSA_REFRESH_FORCE); + } else { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "LSA[Type5:0.0.0.0]: Originate AS-external-LSA"); + ospf_external_lsa_originate(ospf, ei); + } + } else { + if (lsa) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "LSA[Type5:0.0.0.0]: Flush AS-external-LSA"); + ospf_refresher_unregister_lsa(ospf, lsa); + ospf_lsa_flush_as(ospf, lsa); + } + } +} + +void ospf_external_lsa_refresh_type(struct ospf *ospf, u_char type, + u_short instance, int force) +{ + struct route_node *rn; + struct external_info *ei; + struct ospf_external *ext; + + if (type != DEFAULT_ROUTE) + if ((ext = ospf_external_lookup(type, instance)) + && EXTERNAL_INFO(ext)) + /* Refresh each redistributed AS-external-LSAs. */ + for (rn = route_top(EXTERNAL_INFO(ext)); rn; + rn = route_next(rn)) + if ((ei = rn->info)) + if (!is_prefix_default(&ei->p)) { + struct ospf_lsa *lsa; + + if ((lsa = ospf_external_info_find_lsa( + ospf, &ei->p))) + ospf_external_lsa_refresh( + ospf, lsa, ei, + force); + else + ospf_external_lsa_originate( + ospf, ei); + } } /* Refresh AS-external-LSA. */ -struct ospf_lsa * -ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa, - struct external_info *ei, int force) -{ - struct ospf_lsa *new; - int changed; - - /* Check the AS-external-LSA should be originated. */ - if (!ospf_redistribute_check (ospf, ei, &changed)) - { - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, " - "redist check fail", - lsa->data->type, inet_ntoa (lsa->data->id)); - ospf_external_lsa_flush (ospf, ei->type, &ei->p, - ei->ifindex /*, ei->nexthop */); - return NULL; - } - - if (!changed && !force) - { - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced", - lsa->data->type, inet_ntoa (lsa->data->id)); - return NULL; - } - - /* Delete LSA from neighbor retransmit-list. */ - ospf_ls_retransmit_delete_nbr_as (ospf, lsa); - - /* Unregister AS-external-LSA from refresh-list. */ - ospf_refresher_unregister_lsa (ospf, lsa); - - new = ospf_external_lsa_new (ospf, ei, &lsa->data->id); - - if (new == NULL) - { - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type, - inet_ntoa (lsa->data->id)); - return NULL; - } - - new->data->ls_seqnum = lsa_seqnum_increment (lsa); - - ospf_lsa_install (ospf, NULL, new); /* As type-5. */ - - /* Flood LSA through AS. */ - ospf_flood_through_as (ospf, NULL, new); - - /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */ - if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT))) - ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */ - - /* Register self-originated LSA to refresh queue. - * Translated LSAs should not be registered, but refreshed upon - * refresh of the Type-7 - */ - if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) ) - ospf_refresher_register_lsa (ospf, new); - - /* Debug logging. */ - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - { - zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh", - new->data->type, inet_ntoa (new->data->id)); - ospf_lsa_header_dump (new->data); - } - - return new; +struct ospf_lsa *ospf_external_lsa_refresh(struct ospf *ospf, + struct ospf_lsa *lsa, + struct external_info *ei, int force) +{ + struct ospf_lsa *new; + int changed; + + /* Check the AS-external-LSA should be originated. */ + if (!ospf_redistribute_check(ospf, ei, &changed)) { + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug( + "LSA[Type%d:%s]: Could not be refreshed, " + "redist check fail", + lsa->data->type, inet_ntoa(lsa->data->id)); + ospf_external_lsa_flush(ospf, ei->type, &ei->p, + ei->ifindex /*, ei->nexthop */); + return NULL; + } + + if (!changed && !force) { + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug( + "LSA[Type%d:%s]: Not refreshed, not changed/forced", + lsa->data->type, inet_ntoa(lsa->data->id)); + return NULL; + } + + /* Delete LSA from neighbor retransmit-list. */ + ospf_ls_retransmit_delete_nbr_as(ospf, lsa); + + /* Unregister AS-external-LSA from refresh-list. */ + ospf_refresher_unregister_lsa(ospf, lsa); + + new = ospf_external_lsa_new(ospf, ei, &lsa->data->id); + + if (new == NULL) { + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug("LSA[Type%d:%s]: Could not be refreshed", + lsa->data->type, inet_ntoa(lsa->data->id)); + return NULL; + } + + new->data->ls_seqnum = lsa_seqnum_increment(lsa); + + ospf_lsa_install(ospf, NULL, new); /* As type-5. */ + + /* Flood LSA through AS. */ + ospf_flood_through_as(ospf, NULL, new); + + /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */ + if (ospf->anyNSSA && !(CHECK_FLAG(new->flags, OSPF_LSA_LOCAL_XLT))) + ospf_install_flood_nssa(ospf, new, + ei); /* Install/Flood per new rules */ + + /* Register self-originated LSA to refresh queue. + * Translated LSAs should not be registered, but refreshed upon + * refresh of the Type-7 + */ + if (!CHECK_FLAG(new->flags, OSPF_LSA_LOCAL_XLT)) + ospf_refresher_register_lsa(ospf, new); + + /* Debug logging. */ + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { + zlog_debug("LSA[Type%d:%s]: AS-external-LSA refresh", + new->data->type, inet_ntoa(new->data->id)); + ospf_lsa_header_dump(new->data); + } + + return new; } @@ -2378,114 +2336,109 @@ ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa, /* Install router-LSA to an area. */ static struct ospf_lsa * -ospf_router_lsa_install (struct ospf *ospf, struct ospf_lsa *new, - int rt_recalc) +ospf_router_lsa_install(struct ospf *ospf, struct ospf_lsa *new, int rt_recalc) { - struct ospf_area *area = new->area; + struct ospf_area *area = new->area; - /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs - The entire routing table must be recalculated, starting with - the shortest path calculations for each area (not just the - area whose link-state database has changed). - */ + /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs + The entire routing table must be recalculated, starting with + the shortest path calculations for each area (not just the + area whose link-state database has changed). + */ - if (IS_LSA_SELF (new)) - { + if (IS_LSA_SELF(new)) { - /* Only install LSA if it is originated/refreshed by us. - * If LSA was received by flooding, the RECEIVED flag is set so do - * not link the LSA */ - if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED)) - return new; /* ignore stale LSA */ + /* Only install LSA if it is originated/refreshed by us. + * If LSA was received by flooding, the RECEIVED flag is set so + * do + * not link the LSA */ + if (CHECK_FLAG(new->flags, OSPF_LSA_RECEIVED)) + return new; /* ignore stale LSA */ - /* Set self-originated router-LSA. */ - ospf_lsa_unlock (&area->router_lsa_self); - area->router_lsa_self = ospf_lsa_lock (new); + /* Set self-originated router-LSA. */ + ospf_lsa_unlock(&area->router_lsa_self); + area->router_lsa_self = ospf_lsa_lock(new); - ospf_refresher_register_lsa (ospf, new); - } - if (rt_recalc) - ospf_spf_calculate_schedule (ospf, SPF_FLAG_ROUTER_LSA_INSTALL); - return new; + ospf_refresher_register_lsa(ospf, new); + } + if (rt_recalc) + ospf_spf_calculate_schedule(ospf, SPF_FLAG_ROUTER_LSA_INSTALL); + return new; } -#define OSPF_INTERFACE_TIMER_ON(T,F,V) \ - if (!(T)) \ - (T) = thread_add_timer (master, (F), oi, (V)) +#define OSPF_INTERFACE_TIMER_ON(T, F, V) \ + if (!(T)) \ + (T) = thread_add_timer(master, (F), oi, (V)) /* Install network-LSA to an area. */ -static struct ospf_lsa * -ospf_network_lsa_install (struct ospf *ospf, - struct ospf_interface *oi, - struct ospf_lsa *new, - int rt_recalc) -{ - - /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs - The entire routing table must be recalculated, starting with - the shortest path calculations for each area (not just the - area whose link-state database has changed). - */ - if (IS_LSA_SELF (new)) - { - /* We supposed that when LSA is originated by us, we pass the int - for which it was originated. If LSA was received by flooding, - the RECEIVED flag is set, so we do not link the LSA to the int. */ - if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED)) - return new; /* ignore stale LSA */ - - ospf_lsa_unlock (&oi->network_lsa_self); - oi->network_lsa_self = ospf_lsa_lock (new); - ospf_refresher_register_lsa (ospf, new); - } - if (rt_recalc) - ospf_spf_calculate_schedule (ospf, SPF_FLAG_NETWORK_LSA_INSTALL); - - return new; +static struct ospf_lsa *ospf_network_lsa_install(struct ospf *ospf, + struct ospf_interface *oi, + struct ospf_lsa *new, + int rt_recalc) +{ + + /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs + The entire routing table must be recalculated, starting with + the shortest path calculations for each area (not just the + area whose link-state database has changed). + */ + if (IS_LSA_SELF(new)) { + /* We supposed that when LSA is originated by us, we pass the + int + for which it was originated. If LSA was received by flooding, + the RECEIVED flag is set, so we do not link the LSA to the + int. */ + if (CHECK_FLAG(new->flags, OSPF_LSA_RECEIVED)) + return new; /* ignore stale LSA */ + + ospf_lsa_unlock(&oi->network_lsa_self); + oi->network_lsa_self = ospf_lsa_lock(new); + ospf_refresher_register_lsa(ospf, new); + } + if (rt_recalc) + ospf_spf_calculate_schedule(ospf, SPF_FLAG_NETWORK_LSA_INSTALL); + + return new; } /* Install summary-LSA to an area. */ static struct ospf_lsa * -ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new, - int rt_recalc) -{ - if (rt_recalc && !IS_LSA_SELF (new)) - { - /* RFC 2328 Section 13.2 Summary-LSAs - The best route to the destination described by the summary- - LSA must be recalculated (see Section 16.5). If this - destination is an AS boundary router, it may also be - necessary to re-examine all the AS-external-LSAs. - */ +ospf_summary_lsa_install(struct ospf *ospf, struct ospf_lsa *new, int rt_recalc) +{ + if (rt_recalc && !IS_LSA_SELF(new)) { +/* RFC 2328 Section 13.2 Summary-LSAs + The best route to the destination described by the summary- + LSA must be recalculated (see Section 16.5). If this + destination is an AS boundary router, it may also be + necessary to re-examine all the AS-external-LSAs. +*/ #if 0 /* This doesn't exist yet... */ ospf_summary_incremental_update(new); */ -#else /* #if 0 */ - ospf_spf_calculate_schedule (ospf, SPF_FLAG_SUMMARY_LSA_INSTALL); +#else /* #if 0 */ + ospf_spf_calculate_schedule(ospf, SPF_FLAG_SUMMARY_LSA_INSTALL); #endif /* #if 0 */ - - } + } - if (IS_LSA_SELF (new)) - ospf_refresher_register_lsa (ospf, new); + if (IS_LSA_SELF(new)) + ospf_refresher_register_lsa(ospf, new); - return new; + return new; } /* Install ASBR-summary-LSA to an area. */ -static struct ospf_lsa * -ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new, - int rt_recalc) -{ - if (rt_recalc && !IS_LSA_SELF (new)) - { - /* RFC 2328 Section 13.2 Summary-LSAs - The best route to the destination described by the summary- - LSA must be recalculated (see Section 16.5). If this - destination is an AS boundary router, it may also be - necessary to re-examine all the AS-external-LSAs. - */ +static struct ospf_lsa *ospf_summary_asbr_lsa_install(struct ospf *ospf, + struct ospf_lsa *new, + int rt_recalc) +{ + if (rt_recalc && !IS_LSA_SELF(new)) { +/* RFC 2328 Section 13.2 Summary-LSAs + The best route to the destination described by the summary- + LSA must be recalculated (see Section 16.5). If this + destination is an AS boundary router, it may also be + necessary to re-examine all the AS-external-LSAs. +*/ #if 0 /* These don't exist yet... */ ospf_summary_incremental_update(new); @@ -2493,428 +2446,421 @@ ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new, - RFC 2328 Section 16.5 implies it should be */ /* ospf_ase_calculate_schedule(); */ #else /* #if 0 */ - ospf_spf_calculate_schedule (ospf, SPF_FLAG_ASBR_SUMMARY_LSA_INSTALL); + ospf_spf_calculate_schedule(ospf, + SPF_FLAG_ASBR_SUMMARY_LSA_INSTALL); #endif /* #if 0 */ - } + } - /* register LSA to refresh-list. */ - if (IS_LSA_SELF (new)) - ospf_refresher_register_lsa (ospf, new); + /* register LSA to refresh-list. */ + if (IS_LSA_SELF(new)) + ospf_refresher_register_lsa(ospf, new); - return new; + return new; } /* Install AS-external-LSA. */ -static struct ospf_lsa * -ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new, - int rt_recalc) -{ - ospf_ase_register_external_lsa (new, ospf); - /* If LSA is not self-originated, calculate an external route. */ - if (rt_recalc) - { - /* RFC 2328 Section 13.2 AS-external-LSAs - The best route to the destination described by the AS- - external-LSA must be recalculated (see Section 16.6). - */ - - if (!IS_LSA_SELF (new)) - ospf_ase_incremental_update (ospf, new); - } - - if (new->data->type == OSPF_AS_NSSA_LSA) - { - /* There is no point to register selforiginate Type-7 LSA for - * refreshing. We rely on refreshing Type-5 LSA's - */ - if (IS_LSA_SELF (new)) - return new; - else - { - /* Try refresh type-5 translated LSA for this LSA, if one exists. - * New translations will be taken care of by the abr_task. - */ - ospf_translated_nssa_refresh (ospf, new, NULL); - } - } - - /* Register self-originated LSA to refresh queue. - * Leave Translated LSAs alone if NSSA is enabled - */ - if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) ) - ospf_refresher_register_lsa (ospf, new); - - return new; -} - -void -ospf_discard_from_db (struct ospf *ospf, - struct ospf_lsdb *lsdb, struct ospf_lsa *lsa) -{ - struct ospf_lsa *old; - - if (!lsdb) - { - zlog_warn ("%s: Called with NULL lsdb!", __func__); - if (!lsa) - zlog_warn ("%s: and NULL LSA!", __func__); - else - zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!", - lsa->data->type, inet_ntoa (lsa->data->id)); - return; - } - - old = ospf_lsdb_lookup (lsdb, lsa); - - if (!old) - return; - - if (old->refresh_list >= 0) - ospf_refresher_unregister_lsa (ospf, old); - - switch (old->data->type) - { - case OSPF_AS_EXTERNAL_LSA: - ospf_ase_unregister_external_lsa (old, ospf); - ospf_ls_retransmit_delete_nbr_as (ospf, old); - break; - case OSPF_OPAQUE_AS_LSA: - ospf_ls_retransmit_delete_nbr_as (ospf, old); - break; - case OSPF_AS_NSSA_LSA: - ospf_ls_retransmit_delete_nbr_area (old->area, old); - ospf_ase_unregister_external_lsa (old, ospf); - break; - default: - ospf_ls_retransmit_delete_nbr_area (old->area, old); - break; - } - - ospf_lsa_maxage_delete (ospf, old); - ospf_lsa_discard (old); -} - -struct ospf_lsa * -ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi, - struct ospf_lsa *lsa) -{ - struct ospf_lsa *new = NULL; - struct ospf_lsa *old = NULL; - struct ospf_lsdb *lsdb = NULL; - int rt_recalc; - - /* Set LSDB. */ - switch (lsa->data->type) - { - /* kevinm */ - case OSPF_AS_NSSA_LSA: - if (lsa->area) - lsdb = lsa->area->lsdb; - else - lsdb = ospf->lsdb; - break; - case OSPF_AS_EXTERNAL_LSA: - case OSPF_OPAQUE_AS_LSA: - lsdb = ospf->lsdb; - break; - default: - lsdb = lsa->area->lsdb; - break; - } - - assert (lsdb); - - /* RFC 2328 13.2. Installing LSAs in the database - - Installing a new LSA in the database, either as the result of - flooding or a newly self-originated LSA, may cause the OSPF - routing table structure to be recalculated. The contents of the - new LSA should be compared to the old instance, if present. If - there is no difference, there is no need to recalculate the - routing table. When comparing an LSA to its previous instance, - the following are all considered to be differences in contents: - - o The LSA's Options field has changed. - - o One of the LSA instances has LS age set to MaxAge, and - the other does not. - - o The length field in the LSA header has changed. - - o The body of the LSA (i.e., anything outside the 20-byte - LSA header) has changed. Note that this excludes changes - in LS Sequence Number and LS Checksum. - - */ - /* Look up old LSA and determine if any SPF calculation or incremental - update is needed */ - old = ospf_lsdb_lookup (lsdb, lsa); - - /* Do comparision and record if recalc needed. */ - rt_recalc = 0; - if ( old == NULL || ospf_lsa_different(old, lsa)) - rt_recalc = 1; - - /* - Sequence number check (Section 14.1 of rfc 2328) - "Premature aging is used when it is time for a self-originated - LSA's sequence number field to wrap. At this point, the current - LSA instance (having LS sequence number MaxSequenceNumber) must - be prematurely aged and flushed from the routing domain before a - new instance with sequence number equal to InitialSequenceNumber - can be originated. " - */ - - if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER) - { - if (ospf_lsa_is_self_originated(ospf, lsa)) - { - lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER); - - if (!IS_LSA_MAXAGE(lsa)) - lsa->flags |= OSPF_LSA_PREMATURE_AGE; - lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); - - if (IS_DEBUG_OSPF (lsa, LSA_REFRESH)) - { - zlog_debug ("ospf_lsa_install() Premature Aging " - "lsa 0x%p, seqnum 0x%x", - (void *)lsa, ntohl(lsa->data->ls_seqnum)); - ospf_lsa_header_dump (lsa->data); - } - } - else - { - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - { - zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 " - "that was not self originated. Ignoring\n"); - ospf_lsa_header_dump (lsa->data); - } - return old; - } - } - - /* discard old LSA from LSDB */ - if (old != NULL) - ospf_discard_from_db (ospf, lsdb, lsa); - - /* Calculate Checksum if self-originated?. */ - if (IS_LSA_SELF (lsa)) - ospf_lsa_checksum (lsa->data); - - /* Insert LSA to LSDB. */ - ospf_lsdb_add (lsdb, lsa); - lsa->lsdb = lsdb; - - /* Do LSA specific installation process. */ - switch (lsa->data->type) - { - case OSPF_ROUTER_LSA: - new = ospf_router_lsa_install (ospf, lsa, rt_recalc); - break; - case OSPF_NETWORK_LSA: - assert (oi); - new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc); - break; - case OSPF_SUMMARY_LSA: - new = ospf_summary_lsa_install (ospf, lsa, rt_recalc); - break; - case OSPF_ASBR_SUMMARY_LSA: - new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc); - break; - case OSPF_AS_EXTERNAL_LSA: - new = ospf_external_lsa_install (ospf, lsa, rt_recalc); - break; - case OSPF_OPAQUE_LINK_LSA: - if (IS_LSA_SELF (lsa)) - lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */ - else - { - /* Incoming "oi" for this LSA has set at LSUpd reception. */ - } - /* Fallthrough */ - case OSPF_OPAQUE_AREA_LSA: - case OSPF_OPAQUE_AS_LSA: - new = ospf_opaque_lsa_install (lsa, rt_recalc); - break; - case OSPF_AS_NSSA_LSA: - new = ospf_external_lsa_install (ospf, lsa, rt_recalc); - default: /* type-6,8,9....nothing special */ - break; - } - - if (new == NULL) - return new; /* Installation failed, cannot proceed further -- endo. */ - - /* Debug logs. */ - if (IS_DEBUG_OSPF (lsa, LSA_INSTALL)) - { - char area_str[INET_ADDRSTRLEN]; - - switch (lsa->data->type) - { - case OSPF_AS_EXTERNAL_LSA: - case OSPF_OPAQUE_AS_LSA: - case OSPF_AS_NSSA_LSA: - zlog_debug ("LSA[%s]: Install %s", - dump_lsa_key (new), - lookup_msg(ospf_lsa_type_msg, new->data->type, NULL)); - break; - default: - strcpy (area_str, inet_ntoa (new->area->area_id)); - zlog_debug ("LSA[%s]: Install %s to Area %s", - dump_lsa_key (new), - lookup_msg(ospf_lsa_type_msg, new->data->type, NULL), area_str); - break; - } - } - - /* - If received LSA' ls_age is MaxAge, or lsa is being prematurely aged - (it's getting flushed out of the area), set LSA on MaxAge LSA list. - */ - if (IS_LSA_MAXAGE (new)) - { - if (IS_DEBUG_OSPF (lsa, LSA_INSTALL)) - zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge", - new->data->type, - inet_ntoa (new->data->id), - (void *)lsa); - ospf_lsa_maxage (ospf, lsa); - } - - return new; -} - - -int -ospf_check_nbr_status (struct ospf *ospf) -{ - struct listnode *node, *nnode; - struct ospf_interface *oi; - - for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) - { - struct route_node *rn; - struct ospf_neighbor *nbr; - - if (ospf_if_is_enable (oi)) - for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) - if ((nbr = rn->info) != NULL) - if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading) - { - route_unlock_node (rn); - return 0; - } - } - - return 1; -} - - - -static int -ospf_maxage_lsa_remover (struct thread *thread) -{ - struct ospf *ospf = THREAD_ARG (thread); - struct ospf_lsa *lsa; - struct route_node *rn; - int reschedule = 0; - - ospf->t_maxage = NULL; - - if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) - zlog_debug ("LSA[MaxAge]: remover Start"); - - reschedule = !ospf_check_nbr_status (ospf); - - if (!reschedule) - for (rn = route_top(ospf->maxage_lsa); rn; rn = route_next(rn)) - { - if ((lsa = rn->info) == NULL) - { - continue; - } - - /* There is at least one neighbor from which we still await an ack - * for that LSA, so we are not allowed to remove it from our lsdb yet - * as per RFC 2328 section 14 para 4 a) */ - if (lsa->retransmit_counter > 0) - { - reschedule = 1; - continue; - } - - /* TODO: maybe convert this function to a work-queue */ - if (thread_should_yield (thread)) - { - OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 0); - route_unlock_node(rn); /* route_top/route_next */ - return 0; - } - - /* Remove LSA from the LSDB */ - if (IS_LSA_SELF (lsa)) - if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) - zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-originated: ", - lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa); - - if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) - zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list", - lsa->data->type, inet_ntoa (lsa->data->id)); - - if (CHECK_FLAG (lsa->flags, OSPF_LSA_PREMATURE_AGE)) - { - if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) - zlog_debug ("originating new lsa for lsa 0x%p\n", (void *)lsa); - ospf_lsa_refresh (ospf, lsa); - } - - /* Remove from lsdb. */ - if (lsa->lsdb) - { - ospf_discard_from_db (ospf, lsa->lsdb, lsa); - ospf_lsdb_delete (lsa->lsdb, lsa); - } - else - zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__, - lsa->data->type, inet_ntoa (lsa->data->id)); - } - - /* A MaxAge LSA must be removed immediately from the router's link - state database as soon as both a) it is no longer contained on any - neighbor Link state retransmission lists and b) none of the router's - neighbors are in states Exchange or Loading. */ - if (reschedule) - OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, - ospf->maxage_delay); - - return 0; -} - -void -ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa) -{ - struct route_node *rn; - struct prefix_ptr lsa_prefix; - - lsa_prefix.family = 0; - lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT; - lsa_prefix.prefix = (uintptr_t) lsa; - - if ((rn = route_node_lookup(ospf->maxage_lsa, - (struct prefix *)&lsa_prefix))) - { - if (rn->info == lsa) - { - UNSET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE); - ospf_lsa_unlock (&lsa); /* maxage_lsa */ - rn->info = NULL; - route_unlock_node (rn); /* unlock node because lsa is deleted */ - } - route_unlock_node (rn); /* route_node_lookup */ - } +static struct ospf_lsa *ospf_external_lsa_install(struct ospf *ospf, + struct ospf_lsa *new, + int rt_recalc) +{ + ospf_ase_register_external_lsa(new, ospf); + /* If LSA is not self-originated, calculate an external route. */ + if (rt_recalc) { + /* RFC 2328 Section 13.2 AS-external-LSAs + The best route to the destination described by the AS- + external-LSA must be recalculated (see Section 16.6). + */ + + if (!IS_LSA_SELF(new)) + ospf_ase_incremental_update(ospf, new); + } + + if (new->data->type == OSPF_AS_NSSA_LSA) { + /* There is no point to register selforiginate Type-7 LSA for + * refreshing. We rely on refreshing Type-5 LSA's + */ + if (IS_LSA_SELF(new)) + return new; + else { + /* Try refresh type-5 translated LSA for this LSA, if + * one exists. + * New translations will be taken care of by the + * abr_task. + */ + ospf_translated_nssa_refresh(ospf, new, NULL); + } + } + + /* Register self-originated LSA to refresh queue. + * Leave Translated LSAs alone if NSSA is enabled + */ + if (IS_LSA_SELF(new) && !CHECK_FLAG(new->flags, OSPF_LSA_LOCAL_XLT)) + ospf_refresher_register_lsa(ospf, new); + + return new; +} + +void ospf_discard_from_db(struct ospf *ospf, struct ospf_lsdb *lsdb, + struct ospf_lsa *lsa) +{ + struct ospf_lsa *old; + + if (!lsdb) { + zlog_warn("%s: Called with NULL lsdb!", __func__); + if (!lsa) + zlog_warn("%s: and NULL LSA!", __func__); + else + zlog_warn("LSA[Type%d:%s]: not associated with LSDB!", + lsa->data->type, inet_ntoa(lsa->data->id)); + return; + } + + old = ospf_lsdb_lookup(lsdb, lsa); + + if (!old) + return; + + if (old->refresh_list >= 0) + ospf_refresher_unregister_lsa(ospf, old); + + switch (old->data->type) { + case OSPF_AS_EXTERNAL_LSA: + ospf_ase_unregister_external_lsa(old, ospf); + ospf_ls_retransmit_delete_nbr_as(ospf, old); + break; + case OSPF_OPAQUE_AS_LSA: + ospf_ls_retransmit_delete_nbr_as(ospf, old); + break; + case OSPF_AS_NSSA_LSA: + ospf_ls_retransmit_delete_nbr_area(old->area, old); + ospf_ase_unregister_external_lsa(old, ospf); + break; + default: + ospf_ls_retransmit_delete_nbr_area(old->area, old); + break; + } + + ospf_lsa_maxage_delete(ospf, old); + ospf_lsa_discard(old); +} + +struct ospf_lsa *ospf_lsa_install(struct ospf *ospf, struct ospf_interface *oi, + struct ospf_lsa *lsa) +{ + struct ospf_lsa *new = NULL; + struct ospf_lsa *old = NULL; + struct ospf_lsdb *lsdb = NULL; + int rt_recalc; + + /* Set LSDB. */ + switch (lsa->data->type) { + /* kevinm */ + case OSPF_AS_NSSA_LSA: + if (lsa->area) + lsdb = lsa->area->lsdb; + else + lsdb = ospf->lsdb; + break; + case OSPF_AS_EXTERNAL_LSA: + case OSPF_OPAQUE_AS_LSA: + lsdb = ospf->lsdb; + break; + default: + lsdb = lsa->area->lsdb; + break; + } + + assert(lsdb); + + /* RFC 2328 13.2. Installing LSAs in the database + + Installing a new LSA in the database, either as the result of + flooding or a newly self-originated LSA, may cause the OSPF + routing table structure to be recalculated. The contents of the + new LSA should be compared to the old instance, if present. If + there is no difference, there is no need to recalculate the + routing table. When comparing an LSA to its previous instance, + the following are all considered to be differences in contents: + + o The LSA's Options field has changed. + + o One of the LSA instances has LS age set to MaxAge, and + the other does not. + + o The length field in the LSA header has changed. + + o The body of the LSA (i.e., anything outside the 20-byte + LSA header) has changed. Note that this excludes changes + in LS Sequence Number and LS Checksum. + + */ + /* Look up old LSA and determine if any SPF calculation or incremental + update is needed */ + old = ospf_lsdb_lookup(lsdb, lsa); + + /* Do comparision and record if recalc needed. */ + rt_recalc = 0; + if (old == NULL || ospf_lsa_different(old, lsa)) + rt_recalc = 1; + + /* + Sequence number check (Section 14.1 of rfc 2328) + "Premature aging is used when it is time for a self-originated + LSA's sequence number field to wrap. At this point, the current + LSA instance (having LS sequence number MaxSequenceNumber) must + be prematurely aged and flushed from the routing domain before a + new instance with sequence number equal to InitialSequenceNumber + can be originated. " + */ + + if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER) { + if (ospf_lsa_is_self_originated(ospf, lsa)) { + lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER); + + if (!IS_LSA_MAXAGE(lsa)) + lsa->flags |= OSPF_LSA_PREMATURE_AGE; + lsa->data->ls_age = htons(OSPF_LSA_MAXAGE); + + if (IS_DEBUG_OSPF(lsa, LSA_REFRESH)) { + zlog_debug( + "ospf_lsa_install() Premature Aging " + "lsa 0x%p, seqnum 0x%x", + (void *)lsa, + ntohl(lsa->data->ls_seqnum)); + ospf_lsa_header_dump(lsa->data); + } + } else { + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { + zlog_debug( + "ospf_lsa_install() got an lsa with seq 0x80000000 " + "that was not self originated. Ignoring\n"); + ospf_lsa_header_dump(lsa->data); + } + return old; + } + } + + /* discard old LSA from LSDB */ + if (old != NULL) + ospf_discard_from_db(ospf, lsdb, lsa); + + /* Calculate Checksum if self-originated?. */ + if (IS_LSA_SELF(lsa)) + ospf_lsa_checksum(lsa->data); + + /* Insert LSA to LSDB. */ + ospf_lsdb_add(lsdb, lsa); + lsa->lsdb = lsdb; + + /* Do LSA specific installation process. */ + switch (lsa->data->type) { + case OSPF_ROUTER_LSA: + new = ospf_router_lsa_install(ospf, lsa, rt_recalc); + break; + case OSPF_NETWORK_LSA: + assert(oi); + new = ospf_network_lsa_install(ospf, oi, lsa, rt_recalc); + break; + case OSPF_SUMMARY_LSA: + new = ospf_summary_lsa_install(ospf, lsa, rt_recalc); + break; + case OSPF_ASBR_SUMMARY_LSA: + new = ospf_summary_asbr_lsa_install(ospf, lsa, rt_recalc); + break; + case OSPF_AS_EXTERNAL_LSA: + new = ospf_external_lsa_install(ospf, lsa, rt_recalc); + break; + case OSPF_OPAQUE_LINK_LSA: + if (IS_LSA_SELF(lsa)) + lsa->oi = oi; /* Specify outgoing ospf-interface for + this LSA. */ + else { + /* Incoming "oi" for this LSA has set at LSUpd + * reception. */ + } + /* Fallthrough */ + case OSPF_OPAQUE_AREA_LSA: + case OSPF_OPAQUE_AS_LSA: + new = ospf_opaque_lsa_install(lsa, rt_recalc); + break; + case OSPF_AS_NSSA_LSA: + new = ospf_external_lsa_install(ospf, lsa, rt_recalc); + default: /* type-6,8,9....nothing special */ + break; + } + + if (new == NULL) + return new; /* Installation failed, cannot proceed further -- + endo. */ + + /* Debug logs. */ + if (IS_DEBUG_OSPF(lsa, LSA_INSTALL)) { + char area_str[INET_ADDRSTRLEN]; + + switch (lsa->data->type) { + case OSPF_AS_EXTERNAL_LSA: + case OSPF_OPAQUE_AS_LSA: + case OSPF_AS_NSSA_LSA: + zlog_debug("LSA[%s]: Install %s", dump_lsa_key(new), + lookup_msg(ospf_lsa_type_msg, + new->data->type, NULL)); + break; + default: + strcpy(area_str, inet_ntoa(new->area->area_id)); + zlog_debug("LSA[%s]: Install %s to Area %s", + dump_lsa_key(new), + lookup_msg(ospf_lsa_type_msg, + new->data->type, NULL), + area_str); + break; + } + } + + /* + If received LSA' ls_age is MaxAge, or lsa is being prematurely aged + (it's getting flushed out of the area), set LSA on MaxAge LSA list. + */ + if (IS_LSA_MAXAGE(new)) { + if (IS_DEBUG_OSPF(lsa, LSA_INSTALL)) + zlog_debug("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge", + new->data->type, inet_ntoa(new->data->id), + (void *)lsa); + ospf_lsa_maxage(ospf, lsa); + } + + return new; +} + + +int ospf_check_nbr_status(struct ospf *ospf) +{ + struct listnode *node, *nnode; + struct ospf_interface *oi; + + for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) { + struct route_node *rn; + struct ospf_neighbor *nbr; + + if (ospf_if_is_enable(oi)) + for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) + if ((nbr = rn->info) != NULL) + if (nbr->state == NSM_Exchange + || nbr->state == NSM_Loading) { + route_unlock_node(rn); + return 0; + } + } + + return 1; +} + + +static int ospf_maxage_lsa_remover(struct thread *thread) +{ + struct ospf *ospf = THREAD_ARG(thread); + struct ospf_lsa *lsa; + struct route_node *rn; + int reschedule = 0; + + ospf->t_maxage = NULL; + + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) + zlog_debug("LSA[MaxAge]: remover Start"); + + reschedule = !ospf_check_nbr_status(ospf); + + if (!reschedule) + for (rn = route_top(ospf->maxage_lsa); rn; + rn = route_next(rn)) { + if ((lsa = rn->info) == NULL) { + continue; + } + + /* There is at least one neighbor from which we still + * await an ack + * for that LSA, so we are not allowed to remove it from + * our lsdb yet + * as per RFC 2328 section 14 para 4 a) */ + if (lsa->retransmit_counter > 0) { + reschedule = 1; + continue; + } + + /* TODO: maybe convert this function to a work-queue */ + if (thread_should_yield(thread)) { + OSPF_TIMER_ON(ospf->t_maxage, + ospf_maxage_lsa_remover, 0); + route_unlock_node( + rn); /* route_top/route_next */ + return 0; + } + + /* Remove LSA from the LSDB */ + if (IS_LSA_SELF(lsa)) + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) + zlog_debug( + "LSA[Type%d:%s]: LSA 0x%lx is self-originated: ", + lsa->data->type, + inet_ntoa(lsa->data->id), + (u_long)lsa); + + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) + zlog_debug( + "LSA[Type%d:%s]: MaxAge LSA removed from list", + lsa->data->type, + inet_ntoa(lsa->data->id)); + + if (CHECK_FLAG(lsa->flags, OSPF_LSA_PREMATURE_AGE)) { + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) + zlog_debug( + "originating new lsa for lsa 0x%p\n", + (void *)lsa); + ospf_lsa_refresh(ospf, lsa); + } + + /* Remove from lsdb. */ + if (lsa->lsdb) { + ospf_discard_from_db(ospf, lsa->lsdb, lsa); + ospf_lsdb_delete(lsa->lsdb, lsa); + } else + zlog_warn( + "%s: LSA[Type%d:%s]: No associated LSDB!", + __func__, lsa->data->type, + inet_ntoa(lsa->data->id)); + } + + /* A MaxAge LSA must be removed immediately from the router's link + state database as soon as both a) it is no longer contained on any + neighbor Link state retransmission lists and b) none of the + router's + neighbors are in states Exchange or Loading. */ + if (reschedule) + OSPF_TIMER_ON(ospf->t_maxage, ospf_maxage_lsa_remover, + ospf->maxage_delay); + + return 0; +} + +void ospf_lsa_maxage_delete(struct ospf *ospf, struct ospf_lsa *lsa) +{ + struct route_node *rn; + struct prefix_ptr lsa_prefix; + + lsa_prefix.family = 0; + lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT; + lsa_prefix.prefix = (uintptr_t)lsa; + + if ((rn = route_node_lookup(ospf->maxage_lsa, + (struct prefix *)&lsa_prefix))) { + if (rn->info == lsa) { + UNSET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE); + ospf_lsa_unlock(&lsa); /* maxage_lsa */ + rn->info = NULL; + route_unlock_node( + rn); /* unlock node because lsa is deleted */ + } + route_unlock_node(rn); /* route_node_lookup */ + } } /* Add LSA onto the MaxAge list, and schedule for removal. @@ -2922,841 +2868,833 @@ ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa) * care of elsewhere, see, e.g., ospf_lsa_flush* (which are callers of this * function). */ -void -ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa) -{ - struct prefix_ptr lsa_prefix; - struct route_node *rn; - - /* When we saw a MaxAge LSA flooded to us, we put it on the list - and schedule the MaxAge LSA remover. */ - if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE)) - { - if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) - zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list", - lsa->data->type, inet_ntoa (lsa->data->id), (void *)lsa); - return; - } - - lsa_prefix.family = 0; - lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT; - lsa_prefix.prefix = (uintptr_t) lsa; - - if ((rn = route_node_get (ospf->maxage_lsa, - (struct prefix *)&lsa_prefix)) != NULL) - { - if (rn->info != NULL) - { - if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) - zlog_debug ("LSA[%s]: found LSA (%p) in table for LSA %p %d", - dump_lsa_key (lsa), rn->info, (void *)lsa, - lsa_prefix.prefixlen); - route_unlock_node (rn); - } - else - { - rn->info = ospf_lsa_lock(lsa); - SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE); - } - } - else - { - zlog_err("Unable to allocate memory for maxage lsa\n"); - assert(0); - } - - if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) - zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa)); - - OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, - ospf->maxage_delay); -} - -static int -ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa) -{ - /* Stay away from any Local Translated Type-7 LSAs */ - if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)) - return 0; - - if (IS_LSA_MAXAGE (lsa)) - /* Self-originated LSAs should NOT time-out instead, - they're flushed and submitted to the max_age list explicitly. */ - if (!ospf_lsa_is_self_originated (ospf, lsa)) - { - if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) - zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa)); - - switch (lsa->data->type) - { - case OSPF_OPAQUE_LINK_LSA: - case OSPF_OPAQUE_AREA_LSA: - case OSPF_OPAQUE_AS_LSA: - /* - * As a general rule, whenever network topology has changed - * (due to an LSA removal in this case), routing recalculation - * should be triggered. However, this is not true for opaque - * LSAs. Even if an opaque LSA instance is going to be removed - * from the routing domain, it does not mean a change in network - * topology, and thus, routing recalculation is not needed here. - */ - break; - case OSPF_AS_EXTERNAL_LSA: - case OSPF_AS_NSSA_LSA: - ospf_ase_incremental_update (ospf, lsa); - break; - default: - ospf_spf_calculate_schedule (ospf, SPF_FLAG_MAXAGE); - break; - } - ospf_lsa_maxage (ospf, lsa); - } - - if (IS_LSA_MAXAGE (lsa) && !ospf_lsa_is_self_originated (ospf, lsa)) - if (LS_AGE (lsa) > OSPF_LSA_MAXAGE + 30) - printf ("Eek! Shouldn't happen!\n"); - - return 0; +void ospf_lsa_maxage(struct ospf *ospf, struct ospf_lsa *lsa) +{ + struct prefix_ptr lsa_prefix; + struct route_node *rn; + + /* When we saw a MaxAge LSA flooded to us, we put it on the list + and schedule the MaxAge LSA remover. */ + if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE)) { + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) + zlog_debug( + "LSA[Type%d:%s]: %p already exists on MaxAge LSA list", + lsa->data->type, inet_ntoa(lsa->data->id), + (void *)lsa); + return; + } + + lsa_prefix.family = 0; + lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT; + lsa_prefix.prefix = (uintptr_t)lsa; + + if ((rn = route_node_get(ospf->maxage_lsa, + (struct prefix *)&lsa_prefix)) + != NULL) { + if (rn->info != NULL) { + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) + zlog_debug( + "LSA[%s]: found LSA (%p) in table for LSA %p %d", + dump_lsa_key(lsa), rn->info, + (void *)lsa, lsa_prefix.prefixlen); + route_unlock_node(rn); + } else { + rn->info = ospf_lsa_lock(lsa); + SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE); + } + } else { + zlog_err("Unable to allocate memory for maxage lsa\n"); + assert(0); + } + + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) + zlog_debug("LSA[%s]: MaxAge LSA remover scheduled.", + dump_lsa_key(lsa)); + + OSPF_TIMER_ON(ospf->t_maxage, ospf_maxage_lsa_remover, + ospf->maxage_delay); +} + +static int ospf_lsa_maxage_walker_remover(struct ospf *ospf, + struct ospf_lsa *lsa) +{ + /* Stay away from any Local Translated Type-7 LSAs */ + if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT)) + return 0; + + if (IS_LSA_MAXAGE(lsa)) + /* Self-originated LSAs should NOT time-out instead, + they're flushed and submitted to the max_age list explicitly. + */ + if (!ospf_lsa_is_self_originated(ospf, lsa)) { + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) + zlog_debug("LSA[%s]: is MaxAge", + dump_lsa_key(lsa)); + + switch (lsa->data->type) { + case OSPF_OPAQUE_LINK_LSA: + case OSPF_OPAQUE_AREA_LSA: + case OSPF_OPAQUE_AS_LSA: + /* + * As a general rule, whenever network topology + * has changed + * (due to an LSA removal in this case), routing + * recalculation + * should be triggered. However, this is not + * true for opaque + * LSAs. Even if an opaque LSA instance is going + * to be removed + * from the routing domain, it does not mean a + * change in network + * topology, and thus, routing recalculation is + * not needed here. + */ + break; + case OSPF_AS_EXTERNAL_LSA: + case OSPF_AS_NSSA_LSA: + ospf_ase_incremental_update(ospf, lsa); + break; + default: + ospf_spf_calculate_schedule(ospf, + SPF_FLAG_MAXAGE); + break; + } + ospf_lsa_maxage(ospf, lsa); + } + + if (IS_LSA_MAXAGE(lsa) && !ospf_lsa_is_self_originated(ospf, lsa)) + if (LS_AGE(lsa) > OSPF_LSA_MAXAGE + 30) + printf("Eek! Shouldn't happen!\n"); + + return 0; } /* Periodical check of MaxAge LSA. */ -int -ospf_lsa_maxage_walker (struct thread *thread) -{ - struct ospf *ospf = THREAD_ARG (thread); - struct route_node *rn; - struct ospf_lsa *lsa; - struct ospf_area *area; - struct listnode *node, *nnode; - - ospf->t_maxage_walker = NULL; - - for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area)) - { - LSDB_LOOP (ROUTER_LSDB (area), rn, lsa) - ospf_lsa_maxage_walker_remover (ospf, lsa); - LSDB_LOOP (NETWORK_LSDB (area), rn, lsa) - ospf_lsa_maxage_walker_remover (ospf, lsa); - LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa) - ospf_lsa_maxage_walker_remover (ospf, lsa); - LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa) - ospf_lsa_maxage_walker_remover (ospf, lsa); - LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa) - ospf_lsa_maxage_walker_remover (ospf, lsa); - LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa) - ospf_lsa_maxage_walker_remover (ospf, lsa); - LSDB_LOOP (NSSA_LSDB (area), rn, lsa) - ospf_lsa_maxage_walker_remover (ospf, lsa); - } - - /* for AS-external-LSAs. */ - if (ospf->lsdb) - { - LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa) - ospf_lsa_maxage_walker_remover (ospf, lsa); - LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa) - ospf_lsa_maxage_walker_remover (ospf, lsa); - } - - OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker, - OSPF_LSA_MAXAGE_CHECK_INTERVAL); - return 0; -} - -struct ospf_lsa * -ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type, - struct prefix_ipv4 *p, struct in_addr router_id) -{ - struct ospf_lsa *lsa; - struct in_addr mask, id; - struct lsa_header_mask - { - struct lsa_header header; - struct in_addr mask; - } *hmask; - - lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id); - if (lsa == NULL) - return NULL; - - masklen2ip (p->prefixlen, &mask); - - hmask = (struct lsa_header_mask *) lsa->data; - - if (mask.s_addr != hmask->mask.s_addr) - { - id.s_addr = p->prefix.s_addr | (~mask.s_addr); - lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id); - if (!lsa) - return NULL; - } - - return lsa; -} - -struct ospf_lsa * -ospf_lsa_lookup (struct ospf_area *area, u_int32_t type, - struct in_addr id, struct in_addr adv_router) -{ - struct ospf *ospf = ospf_lookup(); - assert(ospf); - - switch (type) - { - case OSPF_ROUTER_LSA: - case OSPF_NETWORK_LSA: - case OSPF_SUMMARY_LSA: - case OSPF_ASBR_SUMMARY_LSA: - case OSPF_AS_NSSA_LSA: - case OSPF_OPAQUE_LINK_LSA: - case OSPF_OPAQUE_AREA_LSA: - return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router); - case OSPF_AS_EXTERNAL_LSA: - case OSPF_OPAQUE_AS_LSA: - return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router); - default: - break; - } - - return NULL; -} - -struct ospf_lsa * -ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type, - struct in_addr id) -{ - struct ospf_lsa *lsa; - struct route_node *rn; - - switch (type) - { - case OSPF_ROUTER_LSA: - return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id); - case OSPF_NETWORK_LSA: - for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn)) - if ((lsa = rn->info)) - if (IPV4_ADDR_SAME (&lsa->data->id, &id)) - { - route_unlock_node (rn); - return lsa; - } - break; - case OSPF_SUMMARY_LSA: - case OSPF_ASBR_SUMMARY_LSA: - /* Currently not used. */ - assert (1); - return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id); - case OSPF_AS_EXTERNAL_LSA: - case OSPF_AS_NSSA_LSA: - case OSPF_OPAQUE_LINK_LSA: - case OSPF_OPAQUE_AREA_LSA: - case OSPF_OPAQUE_AS_LSA: - /* Currently not used. */ - break; - default: - break; - } - - return NULL; -} - -struct ospf_lsa * -ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah) -{ - struct ospf_lsa *match; - - /* - * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11) - * is redefined to have two subfields; opaque-type and opaque-id. - * However, it is harmless to treat the two sub fields together, as if - * they two were forming a unique LSA-ID. - */ - - match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router); - - if (match == NULL) - if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA) - zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH", - lsah->type, inet_ntoa (lsah->id)); - - return match; +int ospf_lsa_maxage_walker(struct thread *thread) +{ + struct ospf *ospf = THREAD_ARG(thread); + struct route_node *rn; + struct ospf_lsa *lsa; + struct ospf_area *area; + struct listnode *node, *nnode; + + ospf->t_maxage_walker = NULL; + + for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) { + LSDB_LOOP(ROUTER_LSDB(area), rn, lsa) + ospf_lsa_maxage_walker_remover(ospf, lsa); + LSDB_LOOP(NETWORK_LSDB(area), rn, lsa) + ospf_lsa_maxage_walker_remover(ospf, lsa); + LSDB_LOOP(SUMMARY_LSDB(area), rn, lsa) + ospf_lsa_maxage_walker_remover(ospf, lsa); + LSDB_LOOP(ASBR_SUMMARY_LSDB(area), rn, lsa) + ospf_lsa_maxage_walker_remover(ospf, lsa); + LSDB_LOOP(OPAQUE_AREA_LSDB(area), rn, lsa) + ospf_lsa_maxage_walker_remover(ospf, lsa); + LSDB_LOOP(OPAQUE_LINK_LSDB(area), rn, lsa) + ospf_lsa_maxage_walker_remover(ospf, lsa); + LSDB_LOOP(NSSA_LSDB(area), rn, lsa) + ospf_lsa_maxage_walker_remover(ospf, lsa); + } + + /* for AS-external-LSAs. */ + if (ospf->lsdb) { + LSDB_LOOP(EXTERNAL_LSDB(ospf), rn, lsa) + ospf_lsa_maxage_walker_remover(ospf, lsa); + LSDB_LOOP(OPAQUE_AS_LSDB(ospf), rn, lsa) + ospf_lsa_maxage_walker_remover(ospf, lsa); + } + + OSPF_TIMER_ON(ospf->t_maxage_walker, ospf_lsa_maxage_walker, + OSPF_LSA_MAXAGE_CHECK_INTERVAL); + return 0; +} + +struct ospf_lsa *ospf_lsa_lookup_by_prefix(struct ospf_lsdb *lsdb, u_char type, + struct prefix_ipv4 *p, + struct in_addr router_id) +{ + struct ospf_lsa *lsa; + struct in_addr mask, id; + struct lsa_header_mask { + struct lsa_header header; + struct in_addr mask; + } * hmask; + + lsa = ospf_lsdb_lookup_by_id(lsdb, type, p->prefix, router_id); + if (lsa == NULL) + return NULL; + + masklen2ip(p->prefixlen, &mask); + + hmask = (struct lsa_header_mask *)lsa->data; + + if (mask.s_addr != hmask->mask.s_addr) { + id.s_addr = p->prefix.s_addr | (~mask.s_addr); + lsa = ospf_lsdb_lookup_by_id(lsdb, type, id, router_id); + if (!lsa) + return NULL; + } + + return lsa; +} + +struct ospf_lsa *ospf_lsa_lookup(struct ospf_area *area, u_int32_t type, + struct in_addr id, struct in_addr adv_router) +{ + struct ospf *ospf = ospf_lookup(); + assert(ospf); + + switch (type) { + case OSPF_ROUTER_LSA: + case OSPF_NETWORK_LSA: + case OSPF_SUMMARY_LSA: + case OSPF_ASBR_SUMMARY_LSA: + case OSPF_AS_NSSA_LSA: + case OSPF_OPAQUE_LINK_LSA: + case OSPF_OPAQUE_AREA_LSA: + return ospf_lsdb_lookup_by_id(area->lsdb, type, id, adv_router); + case OSPF_AS_EXTERNAL_LSA: + case OSPF_OPAQUE_AS_LSA: + return ospf_lsdb_lookup_by_id(ospf->lsdb, type, id, adv_router); + default: + break; + } + + return NULL; +} + +struct ospf_lsa *ospf_lsa_lookup_by_id(struct ospf_area *area, u_int32_t type, + struct in_addr id) +{ + struct ospf_lsa *lsa; + struct route_node *rn; + + switch (type) { + case OSPF_ROUTER_LSA: + return ospf_lsdb_lookup_by_id(area->lsdb, type, id, id); + case OSPF_NETWORK_LSA: + for (rn = route_top(NETWORK_LSDB(area)); rn; + rn = route_next(rn)) + if ((lsa = rn->info)) + if (IPV4_ADDR_SAME(&lsa->data->id, &id)) { + route_unlock_node(rn); + return lsa; + } + break; + case OSPF_SUMMARY_LSA: + case OSPF_ASBR_SUMMARY_LSA: + /* Currently not used. */ + assert(1); + return ospf_lsdb_lookup_by_id(area->lsdb, type, id, id); + case OSPF_AS_EXTERNAL_LSA: + case OSPF_AS_NSSA_LSA: + case OSPF_OPAQUE_LINK_LSA: + case OSPF_OPAQUE_AREA_LSA: + case OSPF_OPAQUE_AS_LSA: + /* Currently not used. */ + break; + default: + break; + } + + return NULL; +} + +struct ospf_lsa *ospf_lsa_lookup_by_header(struct ospf_area *area, + struct lsa_header *lsah) +{ + struct ospf_lsa *match; + + /* + * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11) + * is redefined to have two subfields; opaque-type and opaque-id. + * However, it is harmless to treat the two sub fields together, as if + * they two were forming a unique LSA-ID. + */ + + match = ospf_lsa_lookup(area, lsah->type, lsah->id, lsah->adv_router); + + if (match == NULL) + if (IS_DEBUG_OSPF(lsa, LSA) == OSPF_DEBUG_LSA) + zlog_debug("LSA[Type%d:%s]: Lookup by header, NO MATCH", + lsah->type, inet_ntoa(lsah->id)); + + return match; } /* return +n, l1 is more recent. return -n, l2 is more recent. return 0, l1 and l2 is identical. */ -int -ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2) -{ - int r; - int x, y; - - if (l1 == NULL && l2 == NULL) - return 0; - if (l1 == NULL) - return -1; - if (l2 == NULL) - return 1; - - /* compare LS sequence number. */ - x = (int) ntohl (l1->data->ls_seqnum); - y = (int) ntohl (l2->data->ls_seqnum); - if (x > y) - return 1; - if (x < y) - return -1; - - /* compare LS checksum. */ - r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum); - if (r) - return r; - - /* compare LS age. */ - if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2)) - return 1; - else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2)) - return -1; - - /* compare LS age with MaxAgeDiff. */ - if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF) - return -1; - else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF) - return 1; - - /* LSAs are identical. */ - return 0; +int ospf_lsa_more_recent(struct ospf_lsa *l1, struct ospf_lsa *l2) +{ + int r; + int x, y; + + if (l1 == NULL && l2 == NULL) + return 0; + if (l1 == NULL) + return -1; + if (l2 == NULL) + return 1; + + /* compare LS sequence number. */ + x = (int)ntohl(l1->data->ls_seqnum); + y = (int)ntohl(l2->data->ls_seqnum); + if (x > y) + return 1; + if (x < y) + return -1; + + /* compare LS checksum. */ + r = ntohs(l1->data->checksum) - ntohs(l2->data->checksum); + if (r) + return r; + + /* compare LS age. */ + if (IS_LSA_MAXAGE(l1) && !IS_LSA_MAXAGE(l2)) + return 1; + else if (!IS_LSA_MAXAGE(l1) && IS_LSA_MAXAGE(l2)) + return -1; + + /* compare LS age with MaxAgeDiff. */ + if (LS_AGE(l1) - LS_AGE(l2) > OSPF_LSA_MAXAGE_DIFF) + return -1; + else if (LS_AGE(l2) - LS_AGE(l1) > OSPF_LSA_MAXAGE_DIFF) + return 1; + + /* LSAs are identical. */ + return 0; } /* If two LSAs are different, return 1, otherwise return 0. */ -int -ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2) +int ospf_lsa_different(struct ospf_lsa *l1, struct ospf_lsa *l2) { - char *p1, *p2; - assert (l1); - assert (l2); - assert (l1->data); - assert (l2->data); + char *p1, *p2; + assert(l1); + assert(l2); + assert(l1->data); + assert(l2->data); - if (l1->data->options != l2->data->options) - return 1; + if (l1->data->options != l2->data->options) + return 1; - if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2)) - return 1; + if (IS_LSA_MAXAGE(l1) && !IS_LSA_MAXAGE(l2)) + return 1; - if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1)) - return 1; + if (IS_LSA_MAXAGE(l2) && !IS_LSA_MAXAGE(l1)) + return 1; - if (l1->data->length != l2->data->length) - return 1; + if (l1->data->length != l2->data->length) + return 1; - if (l1->data->length == 0) - return 1; + if (l1->data->length == 0) + return 1; - if (CHECK_FLAG ((l1->flags ^ l2->flags), OSPF_LSA_RECEIVED)) - return 1; /* May be a stale LSA in the LSBD */ + if (CHECK_FLAG((l1->flags ^ l2->flags), OSPF_LSA_RECEIVED)) + return 1; /* May be a stale LSA in the LSBD */ - assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE); + assert(ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE); - p1 = (char *) l1->data; - p2 = (char *) l2->data; + p1 = (char *)l1->data; + p2 = (char *)l2->data; - if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE, - ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0) - return 1; + if (memcmp(p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE, + ntohs(l1->data->length) - OSPF_LSA_HEADER_SIZE) + != 0) + return 1; - return 0; + return 0; } #ifdef ORIGINAL_CODING -void -ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr, - struct ospf_lsa *self, - struct ospf_lsa *new) -{ - u_int32_t seqnum; - - /* Adjust LS Sequence Number. */ - seqnum = ntohl (new->data->ls_seqnum) + 1; - self->data->ls_seqnum = htonl (seqnum); - - /* Recalculate LSA checksum. */ - ospf_lsa_checksum (self->data); - - /* Reflooding LSA. */ - /* RFC2328 Section 13.3 - On non-broadcast networks, separate Link State Update - packets must be sent, as unicasts, to each adjacent neighbor - (i.e., those in state Exchange or greater). The destination - IP addresses for these packets are the neighbors' IP - addresses. */ - if (nbr->oi->type == OSPF_IFTYPE_NBMA) - { - struct route_node *rn; - struct ospf_neighbor *onbr; - - for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn)) - if ((onbr = rn->info) != NULL) - if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange) - ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT); - } - else - ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT); - - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA", - self->data->type, inet_ntoa (self->data->id)); -} -#else /* ORIGINAL_CODING */ -int -ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa) -{ - if (lsa == NULL || !IS_LSA_SELF (lsa)) - return 0; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id)); - - /* Force given lsa's age to MaxAge. */ - lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); - - switch (lsa->data->type) - { - /* Opaque wants to be notified of flushes */ - case OSPF_OPAQUE_LINK_LSA: - case OSPF_OPAQUE_AREA_LSA: - case OSPF_OPAQUE_AS_LSA: - ospf_opaque_lsa_refresh (lsa); - break; - default: - ospf_refresher_unregister_lsa (ospf, lsa); - ospf_lsa_flush (ospf, lsa); - break; - } - - return 0; -} - -void -ospf_flush_self_originated_lsas_now (struct ospf *ospf) -{ - struct listnode *node, *nnode; - struct listnode *node2, *nnode2; - struct ospf_area *area; - struct ospf_interface *oi; - struct ospf_lsa *lsa; - struct route_node *rn; - int need_to_flush_ase = 0; - - for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area)) - { - if ((lsa = area->router_lsa_self) != NULL) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", - lsa->data->type, inet_ntoa (lsa->data->id)); - - ospf_refresher_unregister_lsa (ospf, lsa); - ospf_lsa_flush_area (lsa, area); - ospf_lsa_unlock (&area->router_lsa_self); - area->router_lsa_self = NULL; - } - - for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi)) - { - if ((lsa = oi->network_lsa_self) != NULL - && oi->state == ISM_DR - && oi->full_nbrs > 0) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", - lsa->data->type, inet_ntoa (lsa->data->id)); - - ospf_refresher_unregister_lsa (ospf, oi->network_lsa_self); - ospf_lsa_flush_area (oi->network_lsa_self, area); - ospf_lsa_unlock (&oi->network_lsa_self); - oi->network_lsa_self = NULL; - } - - if (oi->type != OSPF_IFTYPE_VIRTUALLINK - && area->external_routing == OSPF_AREA_DEFAULT) - need_to_flush_ase = 1; - } - - LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa) - ospf_lsa_flush_schedule (ospf, lsa); - LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa) - ospf_lsa_flush_schedule (ospf, lsa); - LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa) - ospf_lsa_flush_schedule (ospf, lsa); - LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa) - ospf_lsa_flush_schedule (ospf, lsa); - } - - if (need_to_flush_ase) - { - LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa) - ospf_lsa_flush_schedule (ospf, lsa); - LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa) - ospf_lsa_flush_schedule (ospf, lsa); - } - - /* - * Make sure that the MaxAge LSA remover is executed immediately, - * without conflicting to other threads. - */ - if (ospf->t_maxage != NULL) - { - OSPF_TIMER_OFF (ospf->t_maxage); - thread_execute (master, ospf_maxage_lsa_remover, ospf, 0); - } - - return; +void ospf_lsa_flush_self_originated(struct ospf_neighbor *nbr, + struct ospf_lsa *self, struct ospf_lsa *new) +{ + u_int32_t seqnum; + + /* Adjust LS Sequence Number. */ + seqnum = ntohl(new->data->ls_seqnum) + 1; + self->data->ls_seqnum = htonl(seqnum); + + /* Recalculate LSA checksum. */ + ospf_lsa_checksum(self->data); + + /* Reflooding LSA. */ + /* RFC2328 Section 13.3 + On non-broadcast networks, separate Link State Update + packets must be sent, as unicasts, to each adjacent neighbor + (i.e., those in state Exchange or greater). The destination + IP addresses for these packets are the neighbors' IP + addresses. */ + if (nbr->oi->type == OSPF_IFTYPE_NBMA) { + struct route_node *rn; + struct ospf_neighbor *onbr; + + for (rn = route_top(nbr->oi->nbrs); rn; rn = route_next(rn)) + if ((onbr = rn->info) != NULL) + if (onbr != nbr->oi->nbr_self + && onbr->status >= NSM_Exchange) + ospf_ls_upd_send_lsa( + onbr, self, + OSPF_SEND_PACKET_DIRECT); + } else + ospf_ls_upd_send_lsa(nbr, self, OSPF_SEND_PACKET_INDIRECT); + + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug("LSA[Type%d:%s]: Flush self-originated LSA", + self->data->type, inet_ntoa(self->data->id)); +} +#else /* ORIGINAL_CODING */ +int ospf_lsa_flush_schedule(struct ospf *ospf, struct ospf_lsa *lsa) +{ + if (lsa == NULL || !IS_LSA_SELF(lsa)) + return 0; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", + lsa->data->type, inet_ntoa(lsa->data->id)); + + /* Force given lsa's age to MaxAge. */ + lsa->data->ls_age = htons(OSPF_LSA_MAXAGE); + + switch (lsa->data->type) { + /* Opaque wants to be notified of flushes */ + case OSPF_OPAQUE_LINK_LSA: + case OSPF_OPAQUE_AREA_LSA: + case OSPF_OPAQUE_AS_LSA: + ospf_opaque_lsa_refresh(lsa); + break; + default: + ospf_refresher_unregister_lsa(ospf, lsa); + ospf_lsa_flush(ospf, lsa); + break; + } + + return 0; +} + +void ospf_flush_self_originated_lsas_now(struct ospf *ospf) +{ + struct listnode *node, *nnode; + struct listnode *node2, *nnode2; + struct ospf_area *area; + struct ospf_interface *oi; + struct ospf_lsa *lsa; + struct route_node *rn; + int need_to_flush_ase = 0; + + for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) { + if ((lsa = area->router_lsa_self) != NULL) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", + lsa->data->type, + inet_ntoa(lsa->data->id)); + + ospf_refresher_unregister_lsa(ospf, lsa); + ospf_lsa_flush_area(lsa, area); + ospf_lsa_unlock(&area->router_lsa_self); + area->router_lsa_self = NULL; + } + + for (ALL_LIST_ELEMENTS(area->oiflist, node2, nnode2, oi)) { + if ((lsa = oi->network_lsa_self) != NULL + && oi->state == ISM_DR && oi->full_nbrs > 0) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", + lsa->data->type, + inet_ntoa(lsa->data->id)); + + ospf_refresher_unregister_lsa( + ospf, oi->network_lsa_self); + ospf_lsa_flush_area(oi->network_lsa_self, area); + ospf_lsa_unlock(&oi->network_lsa_self); + oi->network_lsa_self = NULL; + } + + if (oi->type != OSPF_IFTYPE_VIRTUALLINK + && area->external_routing == OSPF_AREA_DEFAULT) + need_to_flush_ase = 1; + } + + LSDB_LOOP(SUMMARY_LSDB(area), rn, lsa) + ospf_lsa_flush_schedule(ospf, lsa); + LSDB_LOOP(ASBR_SUMMARY_LSDB(area), rn, lsa) + ospf_lsa_flush_schedule(ospf, lsa); + LSDB_LOOP(OPAQUE_LINK_LSDB(area), rn, lsa) + ospf_lsa_flush_schedule(ospf, lsa); + LSDB_LOOP(OPAQUE_AREA_LSDB(area), rn, lsa) + ospf_lsa_flush_schedule(ospf, lsa); + } + + if (need_to_flush_ase) { + LSDB_LOOP(EXTERNAL_LSDB(ospf), rn, lsa) + ospf_lsa_flush_schedule(ospf, lsa); + LSDB_LOOP(OPAQUE_AS_LSDB(ospf), rn, lsa) + ospf_lsa_flush_schedule(ospf, lsa); + } + + /* + * Make sure that the MaxAge LSA remover is executed immediately, + * without conflicting to other threads. + */ + if (ospf->t_maxage != NULL) { + OSPF_TIMER_OFF(ospf->t_maxage); + thread_execute(master, ospf_maxage_lsa_remover, ospf, 0); + } + + return; } #endif /* ORIGINAL_CODING */ /* If there is self-originated LSA, then return 1, otherwise return 0. */ /* An interface-independent version of ospf_lsa_is_self_originated */ -int -ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa) -{ - struct listnode *node; - struct ospf_interface *oi; - - /* This LSA is already checked. */ - if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED)) - return IS_LSA_SELF (lsa); - - /* Make sure LSA is self-checked. */ - SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED); - - /* AdvRouter and Router ID is the same. */ - if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id)) - SET_FLAG (lsa->flags, OSPF_LSA_SELF); - - /* LSA is router-LSA. */ - else if (lsa->data->type == OSPF_ROUTER_LSA && - IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id)) - SET_FLAG (lsa->flags, OSPF_LSA_SELF); - - /* LSA is network-LSA. Compare Link ID with all interfaces. */ - else if (lsa->data->type == OSPF_NETWORK_LSA) - for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) - { - /* Ignore virtual link. */ - if (oi->type != OSPF_IFTYPE_VIRTUALLINK) - if (oi->address->family == AF_INET) - if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4)) - { - /* to make it easier later */ - SET_FLAG (lsa->flags, OSPF_LSA_SELF); - return IS_LSA_SELF (lsa); - } - } - - return IS_LSA_SELF (lsa); +int ospf_lsa_is_self_originated(struct ospf *ospf, struct ospf_lsa *lsa) +{ + struct listnode *node; + struct ospf_interface *oi; + + /* This LSA is already checked. */ + if (CHECK_FLAG(lsa->flags, OSPF_LSA_SELF_CHECKED)) + return IS_LSA_SELF(lsa); + + /* Make sure LSA is self-checked. */ + SET_FLAG(lsa->flags, OSPF_LSA_SELF_CHECKED); + + /* AdvRouter and Router ID is the same. */ + if (IPV4_ADDR_SAME(&lsa->data->adv_router, &ospf->router_id)) + SET_FLAG(lsa->flags, OSPF_LSA_SELF); + + /* LSA is router-LSA. */ + else if (lsa->data->type == OSPF_ROUTER_LSA + && IPV4_ADDR_SAME(&lsa->data->id, &ospf->router_id)) + SET_FLAG(lsa->flags, OSPF_LSA_SELF); + + /* LSA is network-LSA. Compare Link ID with all interfaces. */ + else if (lsa->data->type == OSPF_NETWORK_LSA) + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) { + /* Ignore virtual link. */ + if (oi->type != OSPF_IFTYPE_VIRTUALLINK) + if (oi->address->family == AF_INET) + if (IPV4_ADDR_SAME( + &lsa->data->id, + &oi->address->u.prefix4)) { + /* to make it easier later */ + SET_FLAG(lsa->flags, + OSPF_LSA_SELF); + return IS_LSA_SELF(lsa); + } + } + + return IS_LSA_SELF(lsa); } /* Get unique Link State ID. */ -struct in_addr -ospf_lsa_unique_id (struct ospf *ospf, - struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p) -{ - struct ospf_lsa *lsa; - struct in_addr mask, id; - - id = p->prefix; - - /* Check existence of LSA instance. */ - lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id); - if (lsa) - { - struct as_external_lsa *al = (struct as_external_lsa *) lsa->data; - if (ip_masklen (al->mask) == p->prefixlen) - { - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("ospf_lsa_unique_id(): " - "Can't get Link State ID for %s/%d", - inet_ntoa (p->prefix), p->prefixlen); - /* id.s_addr = 0; */ - id.s_addr = 0xffffffff; - return id; - } - /* Masklen differs, then apply wildcard mask to Link State ID. */ - else - { - masklen2ip (p->prefixlen, &mask); - - id.s_addr = p->prefix.s_addr | (~mask.s_addr); - lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type, - id, ospf->router_id); - if (lsa) - { - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("ospf_lsa_unique_id(): " - "Can't get Link State ID for %s/%d", - inet_ntoa (p->prefix), p->prefixlen); - /* id.s_addr = 0; */ - id.s_addr = 0xffffffff; - return id; - } - } - } - - return id; +struct in_addr ospf_lsa_unique_id(struct ospf *ospf, struct ospf_lsdb *lsdb, + u_char type, struct prefix_ipv4 *p) +{ + struct ospf_lsa *lsa; + struct in_addr mask, id; + + id = p->prefix; + + /* Check existence of LSA instance. */ + lsa = ospf_lsdb_lookup_by_id(lsdb, type, id, ospf->router_id); + if (lsa) { + struct as_external_lsa *al = + (struct as_external_lsa *)lsa->data; + if (ip_masklen(al->mask) == p->prefixlen) { + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug( + "ospf_lsa_unique_id(): " + "Can't get Link State ID for %s/%d", + inet_ntoa(p->prefix), p->prefixlen); + /* id.s_addr = 0; */ + id.s_addr = 0xffffffff; + return id; + } + /* Masklen differs, then apply wildcard mask to Link State ID. + */ + else { + masklen2ip(p->prefixlen, &mask); + + id.s_addr = p->prefix.s_addr | (~mask.s_addr); + lsa = ospf_lsdb_lookup_by_id(ospf->lsdb, type, id, + ospf->router_id); + if (lsa) { + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug( + "ospf_lsa_unique_id(): " + "Can't get Link State ID for %s/%d", + inet_ntoa(p->prefix), + p->prefixlen); + /* id.s_addr = 0; */ + id.s_addr = 0xffffffff; + return id; + } + } + } + + return id; } #define LSA_ACTION_FLOOD_AREA 1 #define LSA_ACTION_FLUSH_AREA 2 -struct lsa_action -{ - u_char action; - struct ospf_area *area; - struct ospf_lsa *lsa; +struct lsa_action { + u_char action; + struct ospf_area *area; + struct ospf_lsa *lsa; }; -static int -ospf_lsa_action (struct thread *t) +static int ospf_lsa_action(struct thread *t) { - struct lsa_action *data; + struct lsa_action *data; - data = THREAD_ARG (t); + data = THREAD_ARG(t); - if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA) - zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d", - data->action); + if (IS_DEBUG_OSPF(lsa, LSA) == OSPF_DEBUG_LSA) + zlog_debug("LSA[Action]: Performing scheduled LSA action: %d", + data->action); - switch (data->action) - { - case LSA_ACTION_FLOOD_AREA: - ospf_flood_through_area (data->area, NULL, data->lsa); - break; - case LSA_ACTION_FLUSH_AREA: - ospf_lsa_flush_area (data->lsa, data->area); - break; - } + switch (data->action) { + case LSA_ACTION_FLOOD_AREA: + ospf_flood_through_area(data->area, NULL, data->lsa); + break; + case LSA_ACTION_FLUSH_AREA: + ospf_lsa_flush_area(data->lsa, data->area); + break; + } - ospf_lsa_unlock (&data->lsa); /* Message */ - XFREE (MTYPE_OSPF_MESSAGE, data); - return 0; + ospf_lsa_unlock(&data->lsa); /* Message */ + XFREE(MTYPE_OSPF_MESSAGE, data); + return 0; } -void -ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa) +void ospf_schedule_lsa_flood_area(struct ospf_area *area, struct ospf_lsa *lsa) { - struct lsa_action *data; + struct lsa_action *data; - data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action)); - data->action = LSA_ACTION_FLOOD_AREA; - data->area = area; - data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */ + data = XCALLOC(MTYPE_OSPF_MESSAGE, sizeof(struct lsa_action)); + data->action = LSA_ACTION_FLOOD_AREA; + data->area = area; + data->lsa = ospf_lsa_lock(lsa); /* Message / Flood area */ - thread_add_event(master, ospf_lsa_action, data, 0, NULL); + thread_add_event(master, ospf_lsa_action, data, 0, NULL); } -void -ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa) +void ospf_schedule_lsa_flush_area(struct ospf_area *area, struct ospf_lsa *lsa) { - struct lsa_action *data; + struct lsa_action *data; - data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action)); - data->action = LSA_ACTION_FLUSH_AREA; - data->area = area; - data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */ + data = XCALLOC(MTYPE_OSPF_MESSAGE, sizeof(struct lsa_action)); + data->action = LSA_ACTION_FLUSH_AREA; + data->area = area; + data->lsa = ospf_lsa_lock(lsa); /* Message / Flush area */ - thread_add_event(master, ospf_lsa_action, data, 0, NULL); + thread_add_event(master, ospf_lsa_action, data, 0, NULL); } /* LSA Refreshment functions. */ -struct ospf_lsa * -ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa) -{ - struct external_info *ei; - struct ospf_lsa *new = NULL; - assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF)); - assert (IS_LSA_SELF (lsa)); - assert (lsa->lock > 0); - - switch (lsa->data->type) - { - /* Router and Network LSAs are processed differently. */ - case OSPF_ROUTER_LSA: - new = ospf_router_lsa_refresh (lsa); - break; - case OSPF_NETWORK_LSA: - new = ospf_network_lsa_refresh (lsa); - break; - case OSPF_SUMMARY_LSA: - new = ospf_summary_lsa_refresh (ospf, lsa); - break; - case OSPF_ASBR_SUMMARY_LSA: - new = ospf_summary_asbr_lsa_refresh (ospf, lsa); - break; - case OSPF_AS_EXTERNAL_LSA: - /* Translated from NSSA Type-5s are refreshed when - * from refresh of Type-7 - do not refresh these directly. - */ - if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)) - break; - ei = ospf_external_info_check (lsa); - if (ei) - new = ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE); - else - ospf_lsa_flush_as (ospf, lsa); - break; - case OSPF_OPAQUE_LINK_LSA: - case OSPF_OPAQUE_AREA_LSA: - case OSPF_OPAQUE_AS_LSA: - new = ospf_opaque_lsa_refresh (lsa); - break; - default: - break; - } - return new; -} - -void -ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa) -{ - u_int16_t index, current_index; - - assert (lsa->lock > 0); - assert (IS_LSA_SELF (lsa)); - - if (lsa->refresh_list < 0) - { - int delay; - int min_delay = OSPF_LS_REFRESH_TIME - (2 * OSPF_LS_REFRESH_JITTER); - int max_delay = OSPF_LS_REFRESH_TIME - OSPF_LS_REFRESH_JITTER; - - /* We want to refresh the LSA within OSPF_LS_REFRESH_TIME which is - * 1800s. Use jitter so that we send the LSA sometime between 1680s - * and 1740s. - */ - delay = (random() % (max_delay - min_delay)) + min_delay; - - current_index = ospf->lsa_refresh_queue.index + (monotime(NULL) - - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY; - - index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY) - % (OSPF_LSA_REFRESHER_SLOTS); - - if (IS_DEBUG_OSPF (lsa, LSA_REFRESH)) - zlog_debug ("LSA[Refresh:Type%d:%s]: age %d, added to index %d", - lsa->data->type, inet_ntoa (lsa->data->id), LS_AGE (lsa), index); - - if (!ospf->lsa_refresh_queue.qs[index]) - ospf->lsa_refresh_queue.qs[index] = list_new (); - - listnode_add (ospf->lsa_refresh_queue.qs[index], - ospf_lsa_lock (lsa)); /* lsa_refresh_queue */ - lsa->refresh_list = index; - - if (IS_DEBUG_OSPF (lsa, LSA_REFRESH)) - zlog_debug ("LSA[Refresh:Type%d:%s]: ospf_refresher_register_lsa(): " - "setting refresh_list on lsa %p (slod %d)", - lsa->data->type, inet_ntoa (lsa->data->id), (void *)lsa, index); - } -} - -void -ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa) -{ - assert (lsa->lock > 0); - assert (IS_LSA_SELF (lsa)); - if (lsa->refresh_list >= 0) - { - struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list]; - listnode_delete (refresh_list, lsa); - if (!listcount (refresh_list)) - { - list_free (refresh_list); - ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL; - } - ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */ - lsa->refresh_list = -1; - } -} - -int -ospf_lsa_refresh_walker (struct thread *t) -{ - struct list *refresh_list; - struct listnode *node, *nnode; - struct ospf *ospf = THREAD_ARG (t); - struct ospf_lsa *lsa; - int i; - struct list *lsa_to_refresh = list_new (); - - if (IS_DEBUG_OSPF (lsa, LSA_REFRESH)) - zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): start"); - - - i = ospf->lsa_refresh_queue.index; - - /* Note: if clock has jumped backwards, then time change could be negative, - so we are careful to cast the expression to unsigned before taking - modulus. */ - ospf->lsa_refresh_queue.index = - ((unsigned long)(ospf->lsa_refresh_queue.index + - (monotime(NULL) - ospf->lsa_refresher_started) - / OSPF_LSA_REFRESHER_GRANULARITY)) - % OSPF_LSA_REFRESHER_SLOTS; - - if (IS_DEBUG_OSPF (lsa, LSA_REFRESH)) - zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d", - ospf->lsa_refresh_queue.index); - - for (;i != ospf->lsa_refresh_queue.index; - i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS) - { - if (IS_DEBUG_OSPF (lsa, LSA_REFRESH)) - zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): " - "refresh index %d", i); - - refresh_list = ospf->lsa_refresh_queue.qs [i]; - - assert (i >= 0); - - ospf->lsa_refresh_queue.qs [i] = NULL; - - if (refresh_list) - { - for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa)) - { - if (IS_DEBUG_OSPF (lsa, LSA_REFRESH)) - zlog_debug ("LSA[Refresh:Type%d:%s]: ospf_lsa_refresh_walker(): " - "refresh lsa %p (slot %d)", - lsa->data->type, inet_ntoa (lsa->data->id), (void *)lsa, i); - - assert (lsa->lock > 0); - list_delete_node (refresh_list, node); - lsa->refresh_list = -1; - listnode_add (lsa_to_refresh, lsa); - } - list_free (refresh_list); - } - } - - ospf->t_lsa_refresher = NULL; - thread_add_timer(master, ospf_lsa_refresh_walker, ospf, ospf->lsa_refresh_interval, - &ospf->t_lsa_refresher); - ospf->lsa_refresher_started = monotime(NULL); - - for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa)) - { - ospf_lsa_refresh (ospf, lsa); - assert (lsa->lock > 0); - ospf_lsa_unlock (&lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/ - } - - list_delete (lsa_to_refresh); - - if (IS_DEBUG_OSPF (lsa, LSA_REFRESH)) - zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end"); - - return 0; +struct ospf_lsa *ospf_lsa_refresh(struct ospf *ospf, struct ospf_lsa *lsa) +{ + struct external_info *ei; + struct ospf_lsa *new = NULL; + assert(CHECK_FLAG(lsa->flags, OSPF_LSA_SELF)); + assert(IS_LSA_SELF(lsa)); + assert(lsa->lock > 0); + + switch (lsa->data->type) { + /* Router and Network LSAs are processed differently. */ + case OSPF_ROUTER_LSA: + new = ospf_router_lsa_refresh(lsa); + break; + case OSPF_NETWORK_LSA: + new = ospf_network_lsa_refresh(lsa); + break; + case OSPF_SUMMARY_LSA: + new = ospf_summary_lsa_refresh(ospf, lsa); + break; + case OSPF_ASBR_SUMMARY_LSA: + new = ospf_summary_asbr_lsa_refresh(ospf, lsa); + break; + case OSPF_AS_EXTERNAL_LSA: + /* Translated from NSSA Type-5s are refreshed when + * from refresh of Type-7 - do not refresh these directly. + */ + if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT)) + break; + ei = ospf_external_info_check(lsa); + if (ei) + new = ospf_external_lsa_refresh(ospf, lsa, ei, + LSA_REFRESH_FORCE); + else + ospf_lsa_flush_as(ospf, lsa); + break; + case OSPF_OPAQUE_LINK_LSA: + case OSPF_OPAQUE_AREA_LSA: + case OSPF_OPAQUE_AS_LSA: + new = ospf_opaque_lsa_refresh(lsa); + break; + default: + break; + } + return new; } +void ospf_refresher_register_lsa(struct ospf *ospf, struct ospf_lsa *lsa) +{ + u_int16_t index, current_index; + + assert(lsa->lock > 0); + assert(IS_LSA_SELF(lsa)); + + if (lsa->refresh_list < 0) { + int delay; + int min_delay = + OSPF_LS_REFRESH_TIME - (2 * OSPF_LS_REFRESH_JITTER); + int max_delay = OSPF_LS_REFRESH_TIME - OSPF_LS_REFRESH_JITTER; + + /* We want to refresh the LSA within OSPF_LS_REFRESH_TIME which + * is + * 1800s. Use jitter so that we send the LSA sometime between + * 1680s + * and 1740s. + */ + delay = (random() % (max_delay - min_delay)) + min_delay; + + current_index = ospf->lsa_refresh_queue.index + + (monotime(NULL) - ospf->lsa_refresher_started) + / OSPF_LSA_REFRESHER_GRANULARITY; + + index = (current_index + delay / OSPF_LSA_REFRESHER_GRANULARITY) + % (OSPF_LSA_REFRESHER_SLOTS); + + if (IS_DEBUG_OSPF(lsa, LSA_REFRESH)) + zlog_debug( + "LSA[Refresh:Type%d:%s]: age %d, added to index %d", + lsa->data->type, inet_ntoa(lsa->data->id), + LS_AGE(lsa), index); + + if (!ospf->lsa_refresh_queue.qs[index]) + ospf->lsa_refresh_queue.qs[index] = list_new(); + + listnode_add(ospf->lsa_refresh_queue.qs[index], + ospf_lsa_lock(lsa)); /* lsa_refresh_queue */ + lsa->refresh_list = index; + + if (IS_DEBUG_OSPF(lsa, LSA_REFRESH)) + zlog_debug( + "LSA[Refresh:Type%d:%s]: ospf_refresher_register_lsa(): " + "setting refresh_list on lsa %p (slod %d)", + lsa->data->type, inet_ntoa(lsa->data->id), + (void *)lsa, index); + } +} + +void ospf_refresher_unregister_lsa(struct ospf *ospf, struct ospf_lsa *lsa) +{ + assert(lsa->lock > 0); + assert(IS_LSA_SELF(lsa)); + if (lsa->refresh_list >= 0) { + struct list *refresh_list = + ospf->lsa_refresh_queue.qs[lsa->refresh_list]; + listnode_delete(refresh_list, lsa); + if (!listcount(refresh_list)) { + list_free(refresh_list); + ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL; + } + ospf_lsa_unlock(&lsa); /* lsa_refresh_queue */ + lsa->refresh_list = -1; + } +} + +int ospf_lsa_refresh_walker(struct thread *t) +{ + struct list *refresh_list; + struct listnode *node, *nnode; + struct ospf *ospf = THREAD_ARG(t); + struct ospf_lsa *lsa; + int i; + struct list *lsa_to_refresh = list_new(); + + if (IS_DEBUG_OSPF(lsa, LSA_REFRESH)) + zlog_debug("LSA[Refresh]: ospf_lsa_refresh_walker(): start"); + + + i = ospf->lsa_refresh_queue.index; + + /* Note: if clock has jumped backwards, then time change could be + negative, + so we are careful to cast the expression to unsigned before taking + modulus. */ + ospf->lsa_refresh_queue.index = + ((unsigned long)(ospf->lsa_refresh_queue.index + + (monotime(NULL) + - ospf->lsa_refresher_started) + / OSPF_LSA_REFRESHER_GRANULARITY)) + % OSPF_LSA_REFRESHER_SLOTS; + + if (IS_DEBUG_OSPF(lsa, LSA_REFRESH)) + zlog_debug( + "LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d", + ospf->lsa_refresh_queue.index); + + for (; i != ospf->lsa_refresh_queue.index; + i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS) { + if (IS_DEBUG_OSPF(lsa, LSA_REFRESH)) + zlog_debug( + "LSA[Refresh]: ospf_lsa_refresh_walker(): " + "refresh index %d", + i); + + refresh_list = ospf->lsa_refresh_queue.qs[i]; + + assert(i >= 0); + + ospf->lsa_refresh_queue.qs[i] = NULL; + + if (refresh_list) { + for (ALL_LIST_ELEMENTS(refresh_list, node, nnode, + lsa)) { + if (IS_DEBUG_OSPF(lsa, LSA_REFRESH)) + zlog_debug( + "LSA[Refresh:Type%d:%s]: ospf_lsa_refresh_walker(): " + "refresh lsa %p (slot %d)", + lsa->data->type, + inet_ntoa(lsa->data->id), + (void *)lsa, i); + + assert(lsa->lock > 0); + list_delete_node(refresh_list, node); + lsa->refresh_list = -1; + listnode_add(lsa_to_refresh, lsa); + } + list_free(refresh_list); + } + } + + ospf->t_lsa_refresher = NULL; + thread_add_timer(master, ospf_lsa_refresh_walker, ospf, + ospf->lsa_refresh_interval, &ospf->t_lsa_refresher); + ospf->lsa_refresher_started = monotime(NULL); + + for (ALL_LIST_ELEMENTS(lsa_to_refresh, node, nnode, lsa)) { + ospf_lsa_refresh(ospf, lsa); + assert(lsa->lock > 0); + ospf_lsa_unlock( + &lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/ + } + + list_delete(lsa_to_refresh); + + if (IS_DEBUG_OSPF(lsa, LSA_REFRESH)) + zlog_debug("LSA[Refresh]: ospf_lsa_refresh_walker(): end"); + + return 0; +} diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h index b6f2526c9..ab8e62b6e 100644 --- a/ospfd/ospf_lsa.h +++ b/ospfd/ospf_lsa.h @@ -52,23 +52,21 @@ #define LSA_REFRESH_FORCE 1 /* OSPF LSA header. */ -struct lsa_header -{ - u_int16_t ls_age; - u_char options; - u_char type; - struct in_addr id; - struct in_addr adv_router; - u_int32_t ls_seqnum; - u_int16_t checksum; - u_int16_t length; +struct lsa_header { + u_int16_t ls_age; + u_char options; + u_char type; + struct in_addr id; + struct in_addr adv_router; + u_int32_t ls_seqnum; + u_int16_t checksum; + u_int16_t length; }; /* OSPF LSA. */ -struct ospf_lsa -{ - /* LSA origination flag. */ - u_char flags; +struct ospf_lsa { + /* LSA origination flag. */ + u_char flags; #define OSPF_LSA_SELF 0x01 #define OSPF_LSA_SELF_CHECKED 0x02 #define OSPF_LSA_RECEIVED 0x04 @@ -78,41 +76,41 @@ struct ospf_lsa #define OSPF_LSA_PREMATURE_AGE 0x40 #define OSPF_LSA_IN_MAXAGE 0x80 - /* LSA data. */ - struct lsa_header *data; + /* LSA data. */ + struct lsa_header *data; - /* Received time stamp. */ - struct timeval tv_recv; + /* Received time stamp. */ + struct timeval tv_recv; - /* Last time it was originated */ - struct timeval tv_orig; + /* Last time it was originated */ + struct timeval tv_orig; - /* All of reference count, also lock to remove. */ - int lock; + /* All of reference count, also lock to remove. */ + int lock; - /* Flags for the SPF calculation. */ - int stat; - #define LSA_SPF_NOT_EXPLORED -1 - #define LSA_SPF_IN_SPFTREE -2 - /* If stat >= 0, stat is LSA position in candidates heap. */ - - /* References to this LSA in neighbor retransmission lists*/ - int retransmit_counter; + /* Flags for the SPF calculation. */ + int stat; +#define LSA_SPF_NOT_EXPLORED -1 +#define LSA_SPF_IN_SPFTREE -2 + /* If stat >= 0, stat is LSA position in candidates heap. */ - /* Area the LSA belongs to, may be NULL if AS-external-LSA. */ - struct ospf_area *area; + /* References to this LSA in neighbor retransmission lists*/ + int retransmit_counter; - /* Parent LSDB. */ - struct ospf_lsdb *lsdb; + /* Area the LSA belongs to, may be NULL if AS-external-LSA. */ + struct ospf_area *area; - /* Related Route. */ - void *route; + /* Parent LSDB. */ + struct ospf_lsdb *lsdb; - /* Refreshement List or Queue */ - int refresh_list; - - /* For Type-9 Opaque-LSAs */ - struct ospf_interface *oi; + /* Related Route. */ + void *route; + + /* Refreshement List or Queue */ + int refresh_list; + + /* For Type-9 Opaque-LSAs */ + struct ospf_interface *oi; }; /* OSPF LSA Link Type. */ @@ -135,16 +133,14 @@ struct ospf_lsa #define IS_ROUTER_LSA_NT(x) ((x)->flags & ROUTER_LSA_NT) /* OSPF Router-LSA Link information. */ -struct router_lsa_link -{ - struct in_addr link_id; - struct in_addr link_data; - struct - { - u_char type; - u_char tos_count; - u_int16_t metric; - } m[1]; +struct router_lsa_link { + struct in_addr link_id; + struct in_addr link_data; + struct { + u_char type; + u_char tos_count; + u_int16_t metric; + } m[1]; }; /* OSPF Router-LSAs structure. */ @@ -156,54 +152,48 @@ struct router_lsa_link reached (RFC2328 12.4.1.3). In this case the Router-LSA initially received by the other end of the VL will have 0 link descriptor blocks, but soon will be replaced with the next revision having 1 descriptor block. */ -struct router_lsa -{ - struct lsa_header header; - u_char flags; - u_char zero; - u_int16_t links; - struct - { - struct in_addr link_id; - struct in_addr link_data; - u_char type; - u_char tos; - u_int16_t metric; - } link[1]; +struct router_lsa { + struct lsa_header header; + u_char flags; + u_char zero; + u_int16_t links; + struct { + struct in_addr link_id; + struct in_addr link_data; + u_char type; + u_char tos; + u_int16_t metric; + } link[1]; }; /* OSPF Network-LSAs structure. */ #define OSPF_NETWORK_LSA_MIN_SIZE 8U /* w/1 router-ID */ -struct network_lsa -{ - struct lsa_header header; - struct in_addr mask; - struct in_addr routers[1]; +struct network_lsa { + struct lsa_header header; + struct in_addr mask; + struct in_addr routers[1]; }; /* OSPF Summary-LSAs structure. */ #define OSPF_SUMMARY_LSA_MIN_SIZE 8U /* w/1 TOS metric block */ -struct summary_lsa -{ - struct lsa_header header; - struct in_addr mask; - u_char tos; - u_char metric[3]; +struct summary_lsa { + struct lsa_header header; + struct in_addr mask; + u_char tos; + u_char metric[3]; }; /* OSPF AS-external-LSAs structure. */ #define OSPF_AS_EXTERNAL_LSA_MIN_SIZE 16U /* w/1 TOS forwarding block */ -struct as_external_lsa -{ - struct lsa_header header; - struct in_addr mask; - struct - { - u_char tos; - u_char metric[3]; - struct in_addr fwd_addr; - u_int32_t route_tag; - } e[1]; +struct as_external_lsa { + struct lsa_header header; + struct in_addr mask; + struct { + u_char tos; + u_char metric[3]; + struct in_addr fwd_addr; + u_int32_t route_tag; + } e[1]; }; #include "ospfd/ospf_opaque.h" @@ -213,121 +203,122 @@ struct as_external_lsa #define IS_EXTERNAL_METRIC(x) ((x) & 0x80) #define GET_AGE(x) (ntohs ((x)->data->ls_age) + time (NULL) - (x)->tv_recv) -#define LS_AGE(x) (OSPF_LSA_MAXAGE < get_age(x) ? \ - OSPF_LSA_MAXAGE : get_age(x)) +#define LS_AGE(x) (OSPF_LSA_MAXAGE < get_age(x) ? OSPF_LSA_MAXAGE : get_age(x)) #define IS_LSA_SELF(L) (CHECK_FLAG ((L)->flags, OSPF_LSA_SELF)) #define IS_LSA_MAXAGE(L) (LS_AGE ((L)) == OSPF_LSA_MAXAGE) #define OSPF_LSA_UPDATE_DELAY 2 -#define OSPF_LSA_UPDATE_TIMER_ON(T,F) \ - if (!(T)) \ - (T) = thread_add_timer (master, (F), 0, 2) +#define OSPF_LSA_UPDATE_TIMER_ON(T, F) \ + if (!(T)) \ + (T) = thread_add_timer(master, (F), 0, 2) /* Prototypes. */ /* XXX: Eek, time functions, similar are in lib/thread.c */ -extern struct timeval int2tv (int); -extern struct timeval msec2tv (int); +extern struct timeval int2tv(int); +extern struct timeval msec2tv(int); -extern int get_age (struct ospf_lsa *); -extern u_int16_t ospf_lsa_checksum (struct lsa_header *); -extern int ospf_lsa_checksum_valid (struct lsa_header *); -extern int ospf_lsa_refresh_delay (struct ospf_lsa *); +extern int get_age(struct ospf_lsa *); +extern u_int16_t ospf_lsa_checksum(struct lsa_header *); +extern int ospf_lsa_checksum_valid(struct lsa_header *); +extern int ospf_lsa_refresh_delay(struct ospf_lsa *); -extern const char *dump_lsa_key (struct ospf_lsa *); -extern u_int32_t lsa_seqnum_increment (struct ospf_lsa *); -extern void lsa_header_set (struct stream *, u_char, u_char, struct in_addr, - struct in_addr); -extern struct ospf_neighbor *ospf_nbr_lookup_ptop (struct ospf_interface *); -extern int ospf_check_nbr_status (struct ospf *); +extern const char *dump_lsa_key(struct ospf_lsa *); +extern u_int32_t lsa_seqnum_increment(struct ospf_lsa *); +extern void lsa_header_set(struct stream *, u_char, u_char, struct in_addr, + struct in_addr); +extern struct ospf_neighbor *ospf_nbr_lookup_ptop(struct ospf_interface *); +extern int ospf_check_nbr_status(struct ospf *); /* Prototype for LSA primitive. */ -extern struct ospf_lsa *ospf_lsa_new (void); -extern struct ospf_lsa *ospf_lsa_dup (struct ospf_lsa *); -extern void ospf_lsa_free (struct ospf_lsa *); -extern struct ospf_lsa *ospf_lsa_lock (struct ospf_lsa *); -extern void ospf_lsa_unlock (struct ospf_lsa **); -extern void ospf_lsa_discard (struct ospf_lsa *); -extern int ospf_lsa_flush_schedule (struct ospf *, struct ospf_lsa *); -extern struct lsa_header *ospf_lsa_data_new (size_t); -extern struct lsa_header *ospf_lsa_data_dup (struct lsa_header *); -extern void ospf_lsa_data_free (struct lsa_header *); +extern struct ospf_lsa *ospf_lsa_new(void); +extern struct ospf_lsa *ospf_lsa_dup(struct ospf_lsa *); +extern void ospf_lsa_free(struct ospf_lsa *); +extern struct ospf_lsa *ospf_lsa_lock(struct ospf_lsa *); +extern void ospf_lsa_unlock(struct ospf_lsa **); +extern void ospf_lsa_discard(struct ospf_lsa *); +extern int ospf_lsa_flush_schedule(struct ospf *, struct ospf_lsa *); +extern struct lsa_header *ospf_lsa_data_new(size_t); +extern struct lsa_header *ospf_lsa_data_dup(struct lsa_header *); +extern void ospf_lsa_data_free(struct lsa_header *); /* Prototype for various LSAs */ -extern int ospf_router_lsa_update (struct ospf *); -extern int ospf_router_lsa_update_area (struct ospf_area *); - -extern void ospf_network_lsa_update (struct ospf_interface *); - -extern struct ospf_lsa *ospf_summary_lsa_originate (struct prefix_ipv4 *, u_int32_t, - struct ospf_area *); -extern struct ospf_lsa *ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *, - u_int32_t, - struct ospf_area *); - -extern struct ospf_lsa *ospf_lsa_install (struct ospf *, - struct ospf_interface *, struct ospf_lsa *); - -extern void ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p); -extern void ospf_external_lsa_flush (struct ospf *, u_char, struct prefix_ipv4 *, - ifindex_t /* , struct in_addr nexthop */); - -extern struct in_addr ospf_get_ip_from_ifp (struct ospf_interface *); - -extern struct ospf_lsa *ospf_external_lsa_originate (struct ospf *, struct external_info *); -extern int ospf_external_lsa_originate_timer (struct thread *); -extern int ospf_default_originate_timer (struct thread *); -extern struct ospf_lsa *ospf_lsa_lookup (struct ospf_area *, u_int32_t, - struct in_addr, struct in_addr); -extern struct ospf_lsa *ospf_lsa_lookup_by_id (struct ospf_area *, - u_int32_t, - struct in_addr); -extern struct ospf_lsa *ospf_lsa_lookup_by_header (struct ospf_area *, - struct lsa_header *); -extern int ospf_lsa_more_recent (struct ospf_lsa *, struct ospf_lsa *); -extern int ospf_lsa_different (struct ospf_lsa *, struct ospf_lsa *); -extern void ospf_flush_self_originated_lsas_now (struct ospf *); - -extern int ospf_lsa_is_self_originated (struct ospf *, struct ospf_lsa *); - -extern struct ospf_lsa *ospf_lsa_lookup_by_prefix (struct ospf_lsdb *, u_char, - struct prefix_ipv4 *, - struct in_addr); - -extern void ospf_lsa_maxage (struct ospf *, struct ospf_lsa *); -extern u_int32_t get_metric (u_char *); - -extern int ospf_lsa_maxage_walker (struct thread *); -extern struct ospf_lsa *ospf_lsa_refresh (struct ospf *, struct ospf_lsa *); - -extern void ospf_external_lsa_refresh_default (struct ospf *); - -extern void ospf_external_lsa_refresh_type (struct ospf *, u_char, u_short, int); -extern struct ospf_lsa *ospf_external_lsa_refresh (struct ospf *, - struct ospf_lsa *, - struct external_info *, - int); -extern struct in_addr ospf_lsa_unique_id (struct ospf *, struct ospf_lsdb *, u_char, - struct prefix_ipv4 *); -extern void ospf_schedule_lsa_flood_area (struct ospf_area *, struct ospf_lsa *); -extern void ospf_schedule_lsa_flush_area (struct ospf_area *, struct ospf_lsa *); - -extern void ospf_refresher_register_lsa (struct ospf *, struct ospf_lsa *); -extern void ospf_refresher_unregister_lsa (struct ospf *, struct ospf_lsa *); -extern int ospf_lsa_refresh_walker (struct thread *); - -extern void ospf_lsa_maxage_delete (struct ospf *, struct ospf_lsa *); - -extern void ospf_discard_from_db (struct ospf *, struct ospf_lsdb *, struct ospf_lsa*); -extern int is_prefix_default (struct prefix_ipv4 *); - -extern int metric_type (struct ospf *, u_char, u_short); -extern int metric_value (struct ospf *, u_char, u_short); - -extern struct in_addr ospf_get_nssa_ip (struct ospf_area *); -extern int ospf_translated_nssa_compare (struct ospf_lsa *, struct ospf_lsa *); -extern struct ospf_lsa *ospf_translated_nssa_refresh (struct ospf *, struct ospf_lsa *, - struct ospf_lsa *); -extern struct ospf_lsa *ospf_translated_nssa_originate (struct ospf *, struct ospf_lsa *); +extern int ospf_router_lsa_update(struct ospf *); +extern int ospf_router_lsa_update_area(struct ospf_area *); + +extern void ospf_network_lsa_update(struct ospf_interface *); + +extern struct ospf_lsa * +ospf_summary_lsa_originate(struct prefix_ipv4 *, u_int32_t, struct ospf_area *); +extern struct ospf_lsa *ospf_summary_asbr_lsa_originate(struct prefix_ipv4 *, + u_int32_t, + struct ospf_area *); + +extern struct ospf_lsa *ospf_lsa_install(struct ospf *, struct ospf_interface *, + struct ospf_lsa *); + +extern void ospf_nssa_lsa_flush(struct ospf *ospf, struct prefix_ipv4 *p); +extern void ospf_external_lsa_flush(struct ospf *, u_char, struct prefix_ipv4 *, + ifindex_t /* , struct in_addr nexthop */); + +extern struct in_addr ospf_get_ip_from_ifp(struct ospf_interface *); + +extern struct ospf_lsa *ospf_external_lsa_originate(struct ospf *, + struct external_info *); +extern int ospf_external_lsa_originate_timer(struct thread *); +extern int ospf_default_originate_timer(struct thread *); +extern struct ospf_lsa *ospf_lsa_lookup(struct ospf_area *, u_int32_t, + struct in_addr, struct in_addr); +extern struct ospf_lsa *ospf_lsa_lookup_by_id(struct ospf_area *, u_int32_t, + struct in_addr); +extern struct ospf_lsa *ospf_lsa_lookup_by_header(struct ospf_area *, + struct lsa_header *); +extern int ospf_lsa_more_recent(struct ospf_lsa *, struct ospf_lsa *); +extern int ospf_lsa_different(struct ospf_lsa *, struct ospf_lsa *); +extern void ospf_flush_self_originated_lsas_now(struct ospf *); + +extern int ospf_lsa_is_self_originated(struct ospf *, struct ospf_lsa *); + +extern struct ospf_lsa *ospf_lsa_lookup_by_prefix(struct ospf_lsdb *, u_char, + struct prefix_ipv4 *, + struct in_addr); + +extern void ospf_lsa_maxage(struct ospf *, struct ospf_lsa *); +extern u_int32_t get_metric(u_char *); + +extern int ospf_lsa_maxage_walker(struct thread *); +extern struct ospf_lsa *ospf_lsa_refresh(struct ospf *, struct ospf_lsa *); + +extern void ospf_external_lsa_refresh_default(struct ospf *); + +extern void ospf_external_lsa_refresh_type(struct ospf *, u_char, u_short, int); +extern struct ospf_lsa *ospf_external_lsa_refresh(struct ospf *, + struct ospf_lsa *, + struct external_info *, int); +extern struct in_addr ospf_lsa_unique_id(struct ospf *, struct ospf_lsdb *, + u_char, struct prefix_ipv4 *); +extern void ospf_schedule_lsa_flood_area(struct ospf_area *, struct ospf_lsa *); +extern void ospf_schedule_lsa_flush_area(struct ospf_area *, struct ospf_lsa *); + +extern void ospf_refresher_register_lsa(struct ospf *, struct ospf_lsa *); +extern void ospf_refresher_unregister_lsa(struct ospf *, struct ospf_lsa *); +extern int ospf_lsa_refresh_walker(struct thread *); + +extern void ospf_lsa_maxage_delete(struct ospf *, struct ospf_lsa *); + +extern void ospf_discard_from_db(struct ospf *, struct ospf_lsdb *, + struct ospf_lsa *); +extern int is_prefix_default(struct prefix_ipv4 *); + +extern int metric_type(struct ospf *, u_char, u_short); +extern int metric_value(struct ospf *, u_char, u_short); + +extern struct in_addr ospf_get_nssa_ip(struct ospf_area *); +extern int ospf_translated_nssa_compare(struct ospf_lsa *, struct ospf_lsa *); +extern struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *, + struct ospf_lsa *, + struct ospf_lsa *); +extern struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *, + struct ospf_lsa *); #endif /* _ZEBRA_OSPF_LSA_H */ diff --git a/ospfd/ospf_lsdb.c b/ospfd/ospf_lsdb.c index ac22f5bbe..a596d3286 100644 --- a/ospfd/ospf_lsdb.c +++ b/ospfd/ospf_lsdb.c @@ -31,299 +31,274 @@ #include "ospfd/ospf_lsa.h" #include "ospfd/ospf_lsdb.h" -struct ospf_lsdb * -ospf_lsdb_new () +struct ospf_lsdb *ospf_lsdb_new() { - struct ospf_lsdb *new; + struct ospf_lsdb *new; - new = XCALLOC (MTYPE_OSPF_LSDB, sizeof (struct ospf_lsdb)); - ospf_lsdb_init (new); + new = XCALLOC(MTYPE_OSPF_LSDB, sizeof(struct ospf_lsdb)); + ospf_lsdb_init(new); - return new; + return new; } -void -ospf_lsdb_init (struct ospf_lsdb *lsdb) +void ospf_lsdb_init(struct ospf_lsdb *lsdb) { - int i; - - for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++) - lsdb->type[i].db = route_table_init (); + int i; + + for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++) + lsdb->type[i].db = route_table_init(); } -void -ospf_lsdb_free (struct ospf_lsdb *lsdb) +void ospf_lsdb_free(struct ospf_lsdb *lsdb) { - ospf_lsdb_cleanup (lsdb); - XFREE (MTYPE_OSPF_LSDB, lsdb); + ospf_lsdb_cleanup(lsdb); + XFREE(MTYPE_OSPF_LSDB, lsdb); } -void -ospf_lsdb_cleanup (struct ospf_lsdb *lsdb) +void ospf_lsdb_cleanup(struct ospf_lsdb *lsdb) { - int i; - assert (lsdb); - assert (lsdb->total == 0); - - ospf_lsdb_delete_all (lsdb); - - for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++) - route_table_finish (lsdb->type[i].db); + int i; + assert(lsdb); + assert(lsdb->total == 0); + + ospf_lsdb_delete_all(lsdb); + + for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++) + route_table_finish(lsdb->type[i].db); } -void -ls_prefix_set (struct prefix_ls *lp, struct ospf_lsa *lsa) +void ls_prefix_set(struct prefix_ls *lp, struct ospf_lsa *lsa) { - if (lp && lsa && lsa->data) - { - lp->family = 0; - lp->prefixlen = 64; - lp->id = lsa->data->id; - lp->adv_router = lsa->data->adv_router; - } + if (lp && lsa && lsa->data) { + lp->family = 0; + lp->prefixlen = 64; + lp->id = lsa->data->id; + lp->adv_router = lsa->data->adv_router; + } } -static void -ospf_lsdb_delete_entry (struct ospf_lsdb *lsdb, struct route_node *rn) +static void ospf_lsdb_delete_entry(struct ospf_lsdb *lsdb, + struct route_node *rn) { - struct ospf_lsa *lsa = rn->info; - - if (!lsa) - return; - - assert (rn->table == lsdb->type[lsa->data->type].db); - - if (IS_LSA_SELF (lsa)) - lsdb->type[lsa->data->type].count_self--; - lsdb->type[lsa->data->type].count--; - lsdb->type[lsa->data->type].checksum -= ntohs(lsa->data->checksum); - lsdb->total--; - rn->info = NULL; - route_unlock_node (rn); + struct ospf_lsa *lsa = rn->info; + + if (!lsa) + return; + + assert(rn->table == lsdb->type[lsa->data->type].db); + + if (IS_LSA_SELF(lsa)) + lsdb->type[lsa->data->type].count_self--; + lsdb->type[lsa->data->type].count--; + lsdb->type[lsa->data->type].checksum -= ntohs(lsa->data->checksum); + lsdb->total--; + rn->info = NULL; + route_unlock_node(rn); #ifdef MONITOR_LSDB_CHANGE - if (lsdb->del_lsa_hook != NULL) - (* lsdb->del_lsa_hook)(lsa); -#endif /* MONITOR_LSDB_CHANGE */ - ospf_lsa_unlock (&lsa); /* lsdb */ - return; + if (lsdb->del_lsa_hook != NULL) + (*lsdb->del_lsa_hook)(lsa); +#endif /* MONITOR_LSDB_CHANGE */ + ospf_lsa_unlock(&lsa); /* lsdb */ + return; } /* Add new LSA to lsdb. */ -void -ospf_lsdb_add (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa) +void ospf_lsdb_add(struct ospf_lsdb *lsdb, struct ospf_lsa *lsa) { - struct route_table *table; - struct prefix_ls lp; - struct route_node *rn; - - table = lsdb->type[lsa->data->type].db; - ls_prefix_set (&lp, lsa); - rn = route_node_get (table, (struct prefix *)&lp); - - /* nothing to do? */ - if (rn->info && rn->info == lsa) - { - route_unlock_node (rn); - return; - } - - /* purge old entry? */ - if (rn->info) - ospf_lsdb_delete_entry (lsdb, rn); - - if (IS_LSA_SELF (lsa)) - lsdb->type[lsa->data->type].count_self++; - lsdb->type[lsa->data->type].count++; - lsdb->total++; + struct route_table *table; + struct prefix_ls lp; + struct route_node *rn; + + table = lsdb->type[lsa->data->type].db; + ls_prefix_set(&lp, lsa); + rn = route_node_get(table, (struct prefix *)&lp); + + /* nothing to do? */ + if (rn->info && rn->info == lsa) { + route_unlock_node(rn); + return; + } + + /* purge old entry? */ + if (rn->info) + ospf_lsdb_delete_entry(lsdb, rn); + + if (IS_LSA_SELF(lsa)) + lsdb->type[lsa->data->type].count_self++; + lsdb->type[lsa->data->type].count++; + lsdb->total++; #ifdef MONITOR_LSDB_CHANGE - if (lsdb->new_lsa_hook != NULL) - (* lsdb->new_lsa_hook)(lsa); + if (lsdb->new_lsa_hook != NULL) + (*lsdb->new_lsa_hook)(lsa); #endif /* MONITOR_LSDB_CHANGE */ - lsdb->type[lsa->data->type].checksum += ntohs(lsa->data->checksum); - rn->info = ospf_lsa_lock (lsa); /* lsdb */ + lsdb->type[lsa->data->type].checksum += ntohs(lsa->data->checksum); + rn->info = ospf_lsa_lock(lsa); /* lsdb */ } -void -ospf_lsdb_delete (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa) +void ospf_lsdb_delete(struct ospf_lsdb *lsdb, struct ospf_lsa *lsa) { - struct route_table *table; - struct prefix_ls lp; - struct route_node *rn; - - if (!lsdb) - { - zlog_warn ("%s: Called with NULL LSDB", __func__); - if (lsa) - zlog_warn ("LSA[Type%d:%s]: LSA %p, lsa->lsdb %p", - lsa->data->type, inet_ntoa (lsa->data->id), - (void *)lsa, (void *)lsa->lsdb); - return; - } - - if (!lsa) - { - zlog_warn ("%s: Called with NULL LSA", __func__); - return; - } - - assert (lsa->data->type < OSPF_MAX_LSA); - table = lsdb->type[lsa->data->type].db; - ls_prefix_set (&lp, lsa); - if ((rn = route_node_lookup (table, (struct prefix *) &lp))) - { - if (rn->info == lsa) - ospf_lsdb_delete_entry (lsdb, rn); - route_unlock_node (rn); /* route_node_lookup */ - } + struct route_table *table; + struct prefix_ls lp; + struct route_node *rn; + + if (!lsdb) { + zlog_warn("%s: Called with NULL LSDB", __func__); + if (lsa) + zlog_warn("LSA[Type%d:%s]: LSA %p, lsa->lsdb %p", + lsa->data->type, inet_ntoa(lsa->data->id), + (void *)lsa, (void *)lsa->lsdb); + return; + } + + if (!lsa) { + zlog_warn("%s: Called with NULL LSA", __func__); + return; + } + + assert(lsa->data->type < OSPF_MAX_LSA); + table = lsdb->type[lsa->data->type].db; + ls_prefix_set(&lp, lsa); + if ((rn = route_node_lookup(table, (struct prefix *)&lp))) { + if (rn->info == lsa) + ospf_lsdb_delete_entry(lsdb, rn); + route_unlock_node(rn); /* route_node_lookup */ + } } -void -ospf_lsdb_delete_all (struct ospf_lsdb *lsdb) +void ospf_lsdb_delete_all(struct ospf_lsdb *lsdb) { - struct route_table *table; - struct route_node *rn; - int i; - - for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++) - { - table = lsdb->type[i].db; - for (rn = route_top (table); rn; rn = route_next (rn)) - if (rn->info != NULL) - ospf_lsdb_delete_entry (lsdb, rn); - } + struct route_table *table; + struct route_node *rn; + int i; + + for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++) { + table = lsdb->type[i].db; + for (rn = route_top(table); rn; rn = route_next(rn)) + if (rn->info != NULL) + ospf_lsdb_delete_entry(lsdb, rn); + } } -void -ospf_lsdb_clean_stat (struct ospf_lsdb *lsdb) +void ospf_lsdb_clean_stat(struct ospf_lsdb *lsdb) { - struct route_table *table; - struct route_node *rn; - struct ospf_lsa *lsa; - int i; - - for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++) - { - table = lsdb->type[i].db; - for (rn = route_top (table); rn; rn = route_next (rn)) - if ((lsa = (rn->info)) != NULL) - lsa->stat = LSA_SPF_NOT_EXPLORED; - } + struct route_table *table; + struct route_node *rn; + struct ospf_lsa *lsa; + int i; + + for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++) { + table = lsdb->type[i].db; + for (rn = route_top(table); rn; rn = route_next(rn)) + if ((lsa = (rn->info)) != NULL) + lsa->stat = LSA_SPF_NOT_EXPLORED; + } } -struct ospf_lsa * -ospf_lsdb_lookup (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa) +struct ospf_lsa *ospf_lsdb_lookup(struct ospf_lsdb *lsdb, struct ospf_lsa *lsa) { - struct route_table *table; - struct prefix_ls lp; - struct route_node *rn; - struct ospf_lsa *find; - - table = lsdb->type[lsa->data->type].db; - ls_prefix_set (&lp, lsa); - rn = route_node_lookup (table, (struct prefix *) &lp); - if (rn) - { - find = rn->info; - route_unlock_node (rn); - return find; - } - return NULL; + struct route_table *table; + struct prefix_ls lp; + struct route_node *rn; + struct ospf_lsa *find; + + table = lsdb->type[lsa->data->type].db; + ls_prefix_set(&lp, lsa); + rn = route_node_lookup(table, (struct prefix *)&lp); + if (rn) { + find = rn->info; + route_unlock_node(rn); + return find; + } + return NULL; } -struct ospf_lsa * -ospf_lsdb_lookup_by_id (struct ospf_lsdb *lsdb, u_char type, - struct in_addr id, struct in_addr adv_router) +struct ospf_lsa *ospf_lsdb_lookup_by_id(struct ospf_lsdb *lsdb, u_char type, + struct in_addr id, + struct in_addr adv_router) { - struct route_table *table; - struct prefix_ls lp; - struct route_node *rn; - struct ospf_lsa *find; - - table = lsdb->type[type].db; - - memset (&lp, 0, sizeof (struct prefix_ls)); - lp.family = 0; - lp.prefixlen = 64; - lp.id = id; - lp.adv_router = adv_router; - - rn = route_node_lookup (table, (struct prefix *) &lp); - if (rn) - { - find = rn->info; - route_unlock_node (rn); - return find; - } - return NULL; + struct route_table *table; + struct prefix_ls lp; + struct route_node *rn; + struct ospf_lsa *find; + + table = lsdb->type[type].db; + + memset(&lp, 0, sizeof(struct prefix_ls)); + lp.family = 0; + lp.prefixlen = 64; + lp.id = id; + lp.adv_router = adv_router; + + rn = route_node_lookup(table, (struct prefix *)&lp); + if (rn) { + find = rn->info; + route_unlock_node(rn); + return find; + } + return NULL; } -struct ospf_lsa * -ospf_lsdb_lookup_by_id_next (struct ospf_lsdb *lsdb, u_char type, - struct in_addr id, struct in_addr adv_router, - int first) +struct ospf_lsa *ospf_lsdb_lookup_by_id_next(struct ospf_lsdb *lsdb, + u_char type, struct in_addr id, + struct in_addr adv_router, + int first) { - struct route_table *table; - struct prefix_ls lp; - struct route_node *rn; - struct ospf_lsa *find; - - table = lsdb->type[type].db; - - memset (&lp, 0, sizeof (struct prefix_ls)); - lp.family = 0; - lp.prefixlen = 64; - lp.id = id; - lp.adv_router = adv_router; - - if (first) - rn = route_top (table); - else - { - if ((rn = route_node_lookup (table, (struct prefix *) &lp)) == NULL) - return NULL; - rn = route_next (rn); - } - - for (; rn; rn = route_next (rn)) - if (rn->info) - break; - - if (rn && rn->info) - { - find = rn->info; - route_unlock_node (rn); - return find; - } - return NULL; + struct route_table *table; + struct prefix_ls lp; + struct route_node *rn; + struct ospf_lsa *find; + + table = lsdb->type[type].db; + + memset(&lp, 0, sizeof(struct prefix_ls)); + lp.family = 0; + lp.prefixlen = 64; + lp.id = id; + lp.adv_router = adv_router; + + if (first) + rn = route_top(table); + else { + if ((rn = route_node_lookup(table, (struct prefix *)&lp)) + == NULL) + return NULL; + rn = route_next(rn); + } + + for (; rn; rn = route_next(rn)) + if (rn->info) + break; + + if (rn && rn->info) { + find = rn->info; + route_unlock_node(rn); + return find; + } + return NULL; } -unsigned long -ospf_lsdb_count_all (struct ospf_lsdb *lsdb) +unsigned long ospf_lsdb_count_all(struct ospf_lsdb *lsdb) { - return lsdb->total; + return lsdb->total; } -unsigned long -ospf_lsdb_count (struct ospf_lsdb *lsdb, int type) +unsigned long ospf_lsdb_count(struct ospf_lsdb *lsdb, int type) { - return lsdb->type[type].count; + return lsdb->type[type].count; } -unsigned long -ospf_lsdb_count_self (struct ospf_lsdb *lsdb, int type) +unsigned long ospf_lsdb_count_self(struct ospf_lsdb *lsdb, int type) { - return lsdb->type[type].count_self; + return lsdb->type[type].count_self; } -unsigned int -ospf_lsdb_checksum (struct ospf_lsdb *lsdb, int type) +unsigned int ospf_lsdb_checksum(struct ospf_lsdb *lsdb, int type) { - return lsdb->type[type].checksum; + return lsdb->type[type].checksum; } -unsigned long -ospf_lsdb_isempty (struct ospf_lsdb *lsdb) +unsigned long ospf_lsdb_isempty(struct ospf_lsdb *lsdb) { - return (lsdb->total == 0); + return (lsdb->total == 0); } diff --git a/ospfd/ospf_lsdb.h b/ospfd/ospf_lsdb.h index ee31cda65..483107112 100644 --- a/ospfd/ospf_lsdb.h +++ b/ospfd/ospf_lsdb.h @@ -23,29 +23,27 @@ #define _ZEBRA_OSPF_LSDB_H /* OSPF LSDB structure. */ -struct ospf_lsdb -{ - struct - { - unsigned long count; - unsigned long count_self; - unsigned int checksum; - struct route_table *db; - } type[OSPF_MAX_LSA]; - unsigned long total; +struct ospf_lsdb { + struct { + unsigned long count; + unsigned long count_self; + unsigned int checksum; + struct route_table *db; + } type[OSPF_MAX_LSA]; + unsigned long total; #define MONITOR_LSDB_CHANGE 1 /* XXX */ #ifdef MONITOR_LSDB_CHANGE - /* Hooks for callback functions to catch every add/del event. */ - int (* new_lsa_hook)(struct ospf_lsa *); - int (* del_lsa_hook)(struct ospf_lsa *); + /* Hooks for callback functions to catch every add/del event. */ + int (*new_lsa_hook)(struct ospf_lsa *); + int (*del_lsa_hook)(struct ospf_lsa *); #endif /* MONITOR_LSDB_CHANGE */ }; /* Macros. */ -#define LSDB_LOOP(T,N,L) \ - if ((T) != NULL) \ - for ((N) = route_top ((T)); ((N)); ((N)) = route_next ((N))) \ - if (((L) = (N)->info)) +#define LSDB_LOOP(T, N, L) \ + if ((T) != NULL) \ + for ((N) = route_top((T)); ((N)); ((N)) = route_next((N))) \ + if (((L) = (N)->info)) #define ROUTER_LSDB(A) ((A)->lsdb->type[OSPF_ROUTER_LSA].db) #define NETWORK_LSDB(A) ((A)->lsdb->type[OSPF_NETWORK_LSA].db) @@ -61,26 +59,26 @@ struct ospf_lsdb #define AS_LSDB(O,T) ((O)->lsdb->type[(T)].db) /* OSPF LSDB related functions. */ -extern struct ospf_lsdb *ospf_lsdb_new (void); -extern void ospf_lsdb_init (struct ospf_lsdb *); -extern void ospf_lsdb_free (struct ospf_lsdb *); -extern void ospf_lsdb_cleanup (struct ospf_lsdb *); -extern void ls_prefix_set (struct prefix_ls *lp, struct ospf_lsa *lsa); -extern void ospf_lsdb_add (struct ospf_lsdb *, struct ospf_lsa *); -extern void ospf_lsdb_delete (struct ospf_lsdb *, struct ospf_lsa *); -extern void ospf_lsdb_delete_all (struct ospf_lsdb *); +extern struct ospf_lsdb *ospf_lsdb_new(void); +extern void ospf_lsdb_init(struct ospf_lsdb *); +extern void ospf_lsdb_free(struct ospf_lsdb *); +extern void ospf_lsdb_cleanup(struct ospf_lsdb *); +extern void ls_prefix_set(struct prefix_ls *lp, struct ospf_lsa *lsa); +extern void ospf_lsdb_add(struct ospf_lsdb *, struct ospf_lsa *); +extern void ospf_lsdb_delete(struct ospf_lsdb *, struct ospf_lsa *); +extern void ospf_lsdb_delete_all(struct ospf_lsdb *); /* Set all stats to -1 (LSA_SPF_NOT_EXPLORED). */ -extern void ospf_lsdb_clean_stat (struct ospf_lsdb *lsdb); -extern struct ospf_lsa *ospf_lsdb_lookup (struct ospf_lsdb *, struct ospf_lsa *); -extern struct ospf_lsa *ospf_lsdb_lookup_by_id (struct ospf_lsdb *, u_char, - struct in_addr, struct in_addr); -extern struct ospf_lsa *ospf_lsdb_lookup_by_id_next (struct ospf_lsdb *, u_char, - struct in_addr, struct in_addr, - int); -extern unsigned long ospf_lsdb_count_all (struct ospf_lsdb *); -extern unsigned long ospf_lsdb_count (struct ospf_lsdb *, int); -extern unsigned long ospf_lsdb_count_self (struct ospf_lsdb *, int); -extern unsigned int ospf_lsdb_checksum (struct ospf_lsdb *, int); -extern unsigned long ospf_lsdb_isempty (struct ospf_lsdb *); +extern void ospf_lsdb_clean_stat(struct ospf_lsdb *lsdb); +extern struct ospf_lsa *ospf_lsdb_lookup(struct ospf_lsdb *, struct ospf_lsa *); +extern struct ospf_lsa *ospf_lsdb_lookup_by_id(struct ospf_lsdb *, u_char, + struct in_addr, struct in_addr); +extern struct ospf_lsa *ospf_lsdb_lookup_by_id_next(struct ospf_lsdb *, u_char, + struct in_addr, + struct in_addr, int); +extern unsigned long ospf_lsdb_count_all(struct ospf_lsdb *); +extern unsigned long ospf_lsdb_count(struct ospf_lsdb *, int); +extern unsigned long ospf_lsdb_count_self(struct ospf_lsdb *, int); +extern unsigned int ospf_lsdb_checksum(struct ospf_lsdb *, int); +extern unsigned long ospf_lsdb_isempty(struct ospf_lsdb *); #endif /* _ZEBRA_OSPF_LSDB_H */ diff --git a/ospfd/ospf_main.c b/ospfd/ospf_main.c index 6cd6d0272..f284a04cb 100644 --- a/ospfd/ospf_main.c +++ b/ospfd/ospf_main.c @@ -54,34 +54,26 @@ #include "ospfd/ospf_bfd.h" /* ospfd privileges */ -zebra_capabilities_t _caps_p [] = -{ - ZCAP_NET_RAW, - ZCAP_BIND, - ZCAP_NET_ADMIN, +zebra_capabilities_t _caps_p[] = { + ZCAP_NET_RAW, ZCAP_BIND, ZCAP_NET_ADMIN, }; -struct zebra_privs_t ospfd_privs = -{ +struct zebra_privs_t ospfd_privs = { #if defined(FRR_USER) && defined(FRR_GROUP) - .user = FRR_USER, - .group = FRR_GROUP, + .user = FRR_USER, + .group = FRR_GROUP, #endif #if defined(VTY_GROUP) - .vty_group = VTY_GROUP, + .vty_group = VTY_GROUP, #endif - .caps_p = _caps_p, - .cap_num_p = array_size(_caps_p), - .cap_num_i = 0 -}; + .caps_p = _caps_p, + .cap_num_p = array_size(_caps_p), + .cap_num_i = 0}; /* OSPFd options. */ -struct option longopts[] = -{ - { "instance", required_argument, NULL, 'n'}, - { "apiserver", no_argument, NULL, 'a'}, - { 0 } -}; +struct option longopts[] = {{"instance", required_argument, NULL, 'n'}, + {"apiserver", no_argument, NULL, 'a'}, + {0}}; /* OSPFd program name */ @@ -93,152 +85,140 @@ extern int ospf_apiserver_enable; #endif /* SUPPORT_OSPF_API */ /* SIGHUP handler. */ -static void -sighup (void) +static void sighup(void) { - zlog_info("SIGHUP received"); + zlog_info("SIGHUP received"); } /* SIGINT / SIGTERM handler. */ -static void -sigint (void) +static void sigint(void) { - zlog_notice ("Terminating on signal"); - ospf_terminate (); + zlog_notice("Terminating on signal"); + ospf_terminate(); } /* SIGUSR1 handler. */ -static void -sigusr1 (void) +static void sigusr1(void) { - zlog_rotate(); + zlog_rotate(); } -struct quagga_signal_t ospf_signals[] = -{ - { - .signal = SIGHUP, - .handler = &sighup, - }, - { - .signal = SIGUSR1, - .handler = &sigusr1, - }, - { - .signal = SIGINT, - .handler = &sigint, - }, - { - .signal = SIGTERM, - .handler = &sigint, - }, +struct quagga_signal_t ospf_signals[] = { + { + .signal = SIGHUP, + .handler = &sighup, + }, + { + .signal = SIGUSR1, + .handler = &sigusr1, + }, + { + .signal = SIGINT, + .handler = &sigint, + }, + { + .signal = SIGTERM, + .handler = &sigint, + }, }; -FRR_DAEMON_INFO(ospfd, OSPF, - .vty_port = OSPF_VTY_PORT, +FRR_DAEMON_INFO(ospfd, OSPF, .vty_port = OSPF_VTY_PORT, - .proghelp = "Implementation of the OSPFv2 routing protocol.", + .proghelp = "Implementation of the OSPFv2 routing protocol.", - .signals = ospf_signals, - .n_signals = array_size(ospf_signals), + .signals = ospf_signals, .n_signals = array_size(ospf_signals), - .privs = &ospfd_privs, -) + .privs = &ospfd_privs, ) /* OSPFd main routine. */ -int -main (int argc, char **argv) +int main(int argc, char **argv) { - u_short instance = 0; + u_short instance = 0; #ifdef SUPPORT_OSPF_API - /* OSPF apiserver is disabled by default. */ - ospf_apiserver_enable = 0; + /* OSPF apiserver is disabled by default. */ + ospf_apiserver_enable = 0; #endif /* SUPPORT_OSPF_API */ - frr_preinit (&ospfd_di, argc, argv); - frr_opt_add ("n:a", longopts, - " -n, --instance Set the instance id\n" - " -a, --apiserver Enable OSPF apiserver\n"); + frr_preinit(&ospfd_di, argc, argv); + frr_opt_add("n:a", longopts, + " -n, --instance Set the instance id\n" + " -a, --apiserver Enable OSPF apiserver\n"); - while (1) - { - int opt; + while (1) { + int opt; - opt = frr_getopt (argc, argv, NULL); - - if (opt == EOF) - break; + opt = frr_getopt(argc, argv, NULL); - switch (opt) - { - case 'n': - ospfd_di.instance = instance = atoi(optarg); - if (instance < 1) - exit(0); - break; - case 0: - break; + if (opt == EOF) + break; + + switch (opt) { + case 'n': + ospfd_di.instance = instance = atoi(optarg); + if (instance < 1) + exit(0); + break; + case 0: + break; #ifdef SUPPORT_OSPF_API - case 'a': - ospf_apiserver_enable = 1; - break; + case 'a': + ospf_apiserver_enable = 1; + break; #endif /* SUPPORT_OSPF_API */ - default: - frr_help_exit (1); - break; + default: + frr_help_exit(1); + break; + } } - } - - /* Invoked by a priviledged user? -- endo. */ - if (geteuid () != 0) - { - errno = EPERM; - perror (ospfd_di.progname); - exit (1); - } - - /* OSPF master init. */ - ospf_master_init (frr_init ()); - - /* Initializations. */ - master = om->master; - - /* Library inits. */ - debug_init (); - vrf_init (NULL, NULL, NULL, NULL); - - access_list_init (); - prefix_list_init (); - - /* OSPFd inits. */ - ospf_if_init (); - ospf_zebra_init(master, instance); - - /* OSPF vty inits. */ - ospf_vty_init (); - ospf_vty_show_init (); - ospf_vty_clear_init (); - - /* OSPF BFD init */ - ospf_bfd_init(); - - ospf_route_map_init (); - ospf_opaque_init (); - - /* Need to initialize the default ospf structure, so the interface mode - commands can be duly processed if they are received before 'router ospf', - when quagga(ospfd) is restarted */ - if (!ospf_get_instance(instance)) - { - zlog_err("OSPF instance init failed: %s", strerror(errno)); - exit (1); - } - - frr_config_fork(); - frr_run (master); - - /* Not reached. */ - return (0); -} + /* Invoked by a priviledged user? -- endo. */ + if (geteuid() != 0) { + errno = EPERM; + perror(ospfd_di.progname); + exit(1); + } + + /* OSPF master init. */ + ospf_master_init(frr_init()); + + /* Initializations. */ + master = om->master; + + /* Library inits. */ + debug_init(); + vrf_init(NULL, NULL, NULL, NULL); + + access_list_init(); + prefix_list_init(); + + /* OSPFd inits. */ + ospf_if_init(); + ospf_zebra_init(master, instance); + + /* OSPF vty inits. */ + ospf_vty_init(); + ospf_vty_show_init(); + ospf_vty_clear_init(); + + /* OSPF BFD init */ + ospf_bfd_init(); + + ospf_route_map_init(); + ospf_opaque_init(); + + /* Need to initialize the default ospf structure, so the interface mode + commands can be duly processed if they are received before 'router + ospf', + when quagga(ospfd) is restarted */ + if (!ospf_get_instance(instance)) { + zlog_err("OSPF instance init failed: %s", strerror(errno)); + exit(1); + } + + frr_config_fork(); + frr_run(master); + + /* Not reached. */ + return (0); +} diff --git a/ospfd/ospf_memory.c b/ospfd/ospf_memory.c index 5639c0f60..cdc9b929f 100644 --- a/ospfd/ospf_memory.c +++ b/ospfd/ospf_memory.c @@ -26,30 +26,30 @@ #include "ospf_memory.h" DEFINE_MGROUP(OSPFD, "ospfd") -DEFINE_MTYPE(OSPFD, OSPF_TOP, "OSPF top") -DEFINE_MTYPE(OSPFD, OSPF_AREA, "OSPF area") -DEFINE_MTYPE(OSPFD, OSPF_AREA_RANGE, "OSPF area range") -DEFINE_MTYPE(OSPFD, OSPF_NETWORK, "OSPF network") +DEFINE_MTYPE(OSPFD, OSPF_TOP, "OSPF top") +DEFINE_MTYPE(OSPFD, OSPF_AREA, "OSPF area") +DEFINE_MTYPE(OSPFD, OSPF_AREA_RANGE, "OSPF area range") +DEFINE_MTYPE(OSPFD, OSPF_NETWORK, "OSPF network") DEFINE_MTYPE(OSPFD, OSPF_NEIGHBOR_STATIC, "OSPF static nbr") -DEFINE_MTYPE(OSPFD, OSPF_IF, "OSPF interface") -DEFINE_MTYPE(OSPFD, OSPF_NEIGHBOR, "OSPF neighbor") -DEFINE_MTYPE(OSPFD, OSPF_ROUTE, "OSPF route") -DEFINE_MTYPE(OSPFD, OSPF_TMP, "OSPF tmp mem") -DEFINE_MTYPE(OSPFD, OSPF_LSA, "OSPF LSA") -DEFINE_MTYPE(OSPFD, OSPF_LSA_DATA, "OSPF LSA data") -DEFINE_MTYPE(OSPFD, OSPF_LSDB, "OSPF LSDB") -DEFINE_MTYPE(OSPFD, OSPF_PACKET, "OSPF packet") -DEFINE_MTYPE(OSPFD, OSPF_FIFO, "OSPF FIFO queue") -DEFINE_MTYPE(OSPFD, OSPF_VERTEX, "OSPF vertex") -DEFINE_MTYPE(OSPFD, OSPF_VERTEX_PARENT, "OSPF vertex parent") -DEFINE_MTYPE(OSPFD, OSPF_NEXTHOP, "OSPF nexthop") -DEFINE_MTYPE(OSPFD, OSPF_PATH, "OSPF path") -DEFINE_MTYPE(OSPFD, OSPF_VL_DATA, "OSPF VL data") -DEFINE_MTYPE(OSPFD, OSPF_CRYPT_KEY, "OSPF crypt key") -DEFINE_MTYPE(OSPFD, OSPF_EXTERNAL_INFO, "OSPF ext. info") -DEFINE_MTYPE(OSPFD, OSPF_DISTANCE, "OSPF distance") -DEFINE_MTYPE(OSPFD, OSPF_IF_INFO, "OSPF if info") -DEFINE_MTYPE(OSPFD, OSPF_IF_PARAMS, "OSPF if params") -DEFINE_MTYPE(OSPFD, OSPF_MESSAGE, "OSPF message") -DEFINE_MTYPE(OSPFD, OSPF_MPLS_TE, "OSPF MPLS parameters") -DEFINE_MTYPE(OSPFD, OSPF_PCE_PARAMS, "OSPF PCE parameters") +DEFINE_MTYPE(OSPFD, OSPF_IF, "OSPF interface") +DEFINE_MTYPE(OSPFD, OSPF_NEIGHBOR, "OSPF neighbor") +DEFINE_MTYPE(OSPFD, OSPF_ROUTE, "OSPF route") +DEFINE_MTYPE(OSPFD, OSPF_TMP, "OSPF tmp mem") +DEFINE_MTYPE(OSPFD, OSPF_LSA, "OSPF LSA") +DEFINE_MTYPE(OSPFD, OSPF_LSA_DATA, "OSPF LSA data") +DEFINE_MTYPE(OSPFD, OSPF_LSDB, "OSPF LSDB") +DEFINE_MTYPE(OSPFD, OSPF_PACKET, "OSPF packet") +DEFINE_MTYPE(OSPFD, OSPF_FIFO, "OSPF FIFO queue") +DEFINE_MTYPE(OSPFD, OSPF_VERTEX, "OSPF vertex") +DEFINE_MTYPE(OSPFD, OSPF_VERTEX_PARENT, "OSPF vertex parent") +DEFINE_MTYPE(OSPFD, OSPF_NEXTHOP, "OSPF nexthop") +DEFINE_MTYPE(OSPFD, OSPF_PATH, "OSPF path") +DEFINE_MTYPE(OSPFD, OSPF_VL_DATA, "OSPF VL data") +DEFINE_MTYPE(OSPFD, OSPF_CRYPT_KEY, "OSPF crypt key") +DEFINE_MTYPE(OSPFD, OSPF_EXTERNAL_INFO, "OSPF ext. info") +DEFINE_MTYPE(OSPFD, OSPF_DISTANCE, "OSPF distance") +DEFINE_MTYPE(OSPFD, OSPF_IF_INFO, "OSPF if info") +DEFINE_MTYPE(OSPFD, OSPF_IF_PARAMS, "OSPF if params") +DEFINE_MTYPE(OSPFD, OSPF_MESSAGE, "OSPF message") +DEFINE_MTYPE(OSPFD, OSPF_MPLS_TE, "OSPF MPLS parameters") +DEFINE_MTYPE(OSPFD, OSPF_PCE_PARAMS, "OSPF PCE parameters") diff --git a/ospfd/ospf_neighbor.c b/ospfd/ospf_neighbor.c index fc86cd09f..33492cf7c 100644 --- a/ospfd/ospf_neighbor.c +++ b/ospfd/ospf_neighbor.c @@ -49,462 +49,437 @@ * for all cases except Virtual-link and PointToPoint interfaces, where * neighbours are indexed by router-ID instead. */ -static void -ospf_nbr_key (struct ospf_interface *oi, struct ospf_neighbor *nbr, - struct prefix *key) +static void ospf_nbr_key(struct ospf_interface *oi, struct ospf_neighbor *nbr, + struct prefix *key) { - key->family = AF_INET; - key->prefixlen = IPV4_MAX_BITLEN; - - /* vlinks are indexed by router-id */ - if (oi->type == OSPF_IFTYPE_VIRTUALLINK || - oi->type == OSPF_IFTYPE_POINTOPOINT) - key->u.prefix4 = nbr->router_id; - else - key->u.prefix4 = nbr->src; - return; + key->family = AF_INET; + key->prefixlen = IPV4_MAX_BITLEN; + + /* vlinks are indexed by router-id */ + if (oi->type == OSPF_IFTYPE_VIRTUALLINK + || oi->type == OSPF_IFTYPE_POINTOPOINT) + key->u.prefix4 = nbr->router_id; + else + key->u.prefix4 = nbr->src; + return; } -struct ospf_neighbor * -ospf_nbr_new (struct ospf_interface *oi) +struct ospf_neighbor *ospf_nbr_new(struct ospf_interface *oi) { - struct ospf_neighbor *nbr; + struct ospf_neighbor *nbr; - /* Allcate new neighbor. */ - nbr = XCALLOC (MTYPE_OSPF_NEIGHBOR, sizeof (struct ospf_neighbor)); + /* Allcate new neighbor. */ + nbr = XCALLOC(MTYPE_OSPF_NEIGHBOR, sizeof(struct ospf_neighbor)); - /* Relate neighbor to the interface. */ - nbr->oi = oi; + /* Relate neighbor to the interface. */ + nbr->oi = oi; - /* Set default values. */ - nbr->state = NSM_Down; + /* Set default values. */ + nbr->state = NSM_Down; - /* Set inheritance values. */ - nbr->v_inactivity = OSPF_IF_PARAM (oi, v_wait); - nbr->v_db_desc = OSPF_IF_PARAM (oi, retransmit_interval); - nbr->v_ls_req = OSPF_IF_PARAM (oi, retransmit_interval); - nbr->v_ls_upd = OSPF_IF_PARAM (oi, retransmit_interval); - nbr->priority = -1; + /* Set inheritance values. */ + nbr->v_inactivity = OSPF_IF_PARAM(oi, v_wait); + nbr->v_db_desc = OSPF_IF_PARAM(oi, retransmit_interval); + nbr->v_ls_req = OSPF_IF_PARAM(oi, retransmit_interval); + nbr->v_ls_upd = OSPF_IF_PARAM(oi, retransmit_interval); + nbr->priority = -1; - /* DD flags. */ - nbr->dd_flags = OSPF_DD_FLAG_MS|OSPF_DD_FLAG_M|OSPF_DD_FLAG_I; + /* DD flags. */ + nbr->dd_flags = OSPF_DD_FLAG_MS | OSPF_DD_FLAG_M | OSPF_DD_FLAG_I; - /* Last received and sent DD. */ - nbr->last_send = NULL; + /* Last received and sent DD. */ + nbr->last_send = NULL; - nbr->nbr_nbma = NULL; + nbr->nbr_nbma = NULL; - ospf_lsdb_init (&nbr->db_sum); - ospf_lsdb_init (&nbr->ls_rxmt); - ospf_lsdb_init (&nbr->ls_req); + ospf_lsdb_init(&nbr->db_sum); + ospf_lsdb_init(&nbr->ls_rxmt); + ospf_lsdb_init(&nbr->ls_req); - nbr->crypt_seqnum = 0; + nbr->crypt_seqnum = 0; - ospf_bfd_info_nbr_create(oi, nbr); - return nbr; + ospf_bfd_info_nbr_create(oi, nbr); + return nbr; } -void -ospf_nbr_free (struct ospf_neighbor *nbr) +void ospf_nbr_free(struct ospf_neighbor *nbr) { - /* Free DB summary list. */ - if (ospf_db_summary_count (nbr)) - ospf_db_summary_clear (nbr); - /* ospf_db_summary_delete_all (nbr); */ - - /* Free ls request list. */ - if (ospf_ls_request_count (nbr)) - ospf_ls_request_delete_all (nbr); - - /* Free retransmit list. */ - if (ospf_ls_retransmit_count (nbr)) - ospf_ls_retransmit_clear (nbr); - - /* Cleanup LSDBs. */ - ospf_lsdb_cleanup (&nbr->db_sum); - ospf_lsdb_cleanup (&nbr->ls_req); - ospf_lsdb_cleanup (&nbr->ls_rxmt); - - /* Clear last send packet. */ - if (nbr->last_send) - ospf_packet_free (nbr->last_send); - - if (nbr->nbr_nbma) - { - nbr->nbr_nbma->nbr = NULL; - nbr->nbr_nbma = NULL; - } - - /* Cancel all timers. */ - OSPF_NSM_TIMER_OFF (nbr->t_inactivity); - OSPF_NSM_TIMER_OFF (nbr->t_db_desc); - OSPF_NSM_TIMER_OFF (nbr->t_ls_req); - OSPF_NSM_TIMER_OFF (nbr->t_ls_upd); - - /* Cancel all events. *//* Thread lookup cost would be negligible. */ - thread_cancel_event (master, nbr); - - ospf_bfd_info_free(&nbr->bfd_info); - XFREE (MTYPE_OSPF_NEIGHBOR, nbr); + /* Free DB summary list. */ + if (ospf_db_summary_count(nbr)) + ospf_db_summary_clear(nbr); + /* ospf_db_summary_delete_all (nbr); */ + + /* Free ls request list. */ + if (ospf_ls_request_count(nbr)) + ospf_ls_request_delete_all(nbr); + + /* Free retransmit list. */ + if (ospf_ls_retransmit_count(nbr)) + ospf_ls_retransmit_clear(nbr); + + /* Cleanup LSDBs. */ + ospf_lsdb_cleanup(&nbr->db_sum); + ospf_lsdb_cleanup(&nbr->ls_req); + ospf_lsdb_cleanup(&nbr->ls_rxmt); + + /* Clear last send packet. */ + if (nbr->last_send) + ospf_packet_free(nbr->last_send); + + if (nbr->nbr_nbma) { + nbr->nbr_nbma->nbr = NULL; + nbr->nbr_nbma = NULL; + } + + /* Cancel all timers. */ + OSPF_NSM_TIMER_OFF(nbr->t_inactivity); + OSPF_NSM_TIMER_OFF(nbr->t_db_desc); + OSPF_NSM_TIMER_OFF(nbr->t_ls_req); + OSPF_NSM_TIMER_OFF(nbr->t_ls_upd); + + /* Cancel all events. */ /* Thread lookup cost would be negligible. */ + thread_cancel_event(master, nbr); + + ospf_bfd_info_free(&nbr->bfd_info); + XFREE(MTYPE_OSPF_NEIGHBOR, nbr); } /* Delete specified OSPF neighbor from interface. */ -void -ospf_nbr_delete (struct ospf_neighbor *nbr) +void ospf_nbr_delete(struct ospf_neighbor *nbr) { - struct ospf_interface *oi; - struct route_node *rn; - struct prefix p; - - oi = nbr->oi; - - /* get appropriate prefix 'key' */ - ospf_nbr_key (oi, nbr, &p); - - rn = route_node_lookup (oi->nbrs, &p); - if (rn) - { - /* If lookup for a NBR succeeds, the leaf route_node could - * only exist because there is (or was) a nbr there. - * If the nbr was deleted, the leaf route_node should have - * lost its last refcount too, and be deleted. - * Therefore a looked-up leaf route_node in nbrs table - * should never have NULL info. - */ - assert (rn->info); - - if (rn->info) - { - rn->info = NULL; - route_unlock_node (rn); + struct ospf_interface *oi; + struct route_node *rn; + struct prefix p; + + oi = nbr->oi; + + /* get appropriate prefix 'key' */ + ospf_nbr_key(oi, nbr, &p); + + rn = route_node_lookup(oi->nbrs, &p); + if (rn) { + /* If lookup for a NBR succeeds, the leaf route_node could + * only exist because there is (or was) a nbr there. + * If the nbr was deleted, the leaf route_node should have + * lost its last refcount too, and be deleted. + * Therefore a looked-up leaf route_node in nbrs table + * should never have NULL info. + */ + assert(rn->info); + + if (rn->info) { + rn->info = NULL; + route_unlock_node(rn); + } else + zlog_info("Can't find neighbor %s in the interface %s", + inet_ntoa(nbr->src), IF_NAME(oi)); + + route_unlock_node(rn); + } else { + /* + * This neighbor was not found, but before we move on and + * free the neighbor structre, make sure that it was not + * indexed incorrectly and ended up in the "worng" place + */ + + /* Reverse the lookup rules */ + if (oi->type == OSPF_IFTYPE_VIRTUALLINK + || oi->type == OSPF_IFTYPE_POINTOPOINT) + p.u.prefix4 = nbr->src; + else + p.u.prefix4 = nbr->router_id; + + rn = route_node_lookup(oi->nbrs, &p); + if (rn) { + /* We found the neighbor! + * Now make sure it is not the exact same neighbor + * structure that we are about to free + */ + if (nbr == rn->info) { + /* Same neighbor, drop the reference to it */ + rn->info = NULL; + route_unlock_node(rn); + } + route_unlock_node(rn); + } } - else - zlog_info ("Can't find neighbor %s in the interface %s", - inet_ntoa (nbr->src), IF_NAME (oi)); - - route_unlock_node (rn); - } - else - { - /* - * This neighbor was not found, but before we move on and - * free the neighbor structre, make sure that it was not - * indexed incorrectly and ended up in the "worng" place - */ - - /* Reverse the lookup rules */ - if (oi->type == OSPF_IFTYPE_VIRTUALLINK || - oi->type == OSPF_IFTYPE_POINTOPOINT) - p.u.prefix4 = nbr->src; - else - p.u.prefix4 = nbr->router_id; - - rn = route_node_lookup (oi->nbrs, &p); - if (rn){ - /* We found the neighbor! - * Now make sure it is not the exact same neighbor - * structure that we are about to free - */ - if (nbr == rn->info){ - /* Same neighbor, drop the reference to it */ - rn->info = NULL; - route_unlock_node (rn); - } - route_unlock_node (rn); - } - } - /* Free ospf_neighbor structure. */ - ospf_nbr_free (nbr); + /* Free ospf_neighbor structure. */ + ospf_nbr_free(nbr); } /* Check myself is in the neighbor list. */ -int -ospf_nbr_bidirectional (struct in_addr *router_id, - struct in_addr *neighbors, int size) +int ospf_nbr_bidirectional(struct in_addr *router_id, struct in_addr *neighbors, + int size) { - int i; - int max; + int i; + int max; - max = size / sizeof (struct in_addr); + max = size / sizeof(struct in_addr); - for (i = 0; i < max; i ++) - if (IPV4_ADDR_SAME (router_id, &neighbors[i])) - return 1; + for (i = 0; i < max; i++) + if (IPV4_ADDR_SAME(router_id, &neighbors[i])) + return 1; - return 0; + return 0; } /* reset nbr_self */ -void -ospf_nbr_self_reset (struct ospf_interface *oi, struct in_addr router_id) +void ospf_nbr_self_reset(struct ospf_interface *oi, struct in_addr router_id) { - if (oi->nbr_self) - ospf_nbr_delete (oi->nbr_self); + if (oi->nbr_self) + ospf_nbr_delete(oi->nbr_self); - oi->nbr_self = ospf_nbr_new (oi); - ospf_nbr_add_self (oi, router_id); + oi->nbr_self = ospf_nbr_new(oi); + ospf_nbr_add_self(oi, router_id); } /* Add self to nbr list. */ -void -ospf_nbr_add_self (struct ospf_interface *oi, struct in_addr router_id) +void ospf_nbr_add_self(struct ospf_interface *oi, struct in_addr router_id) { - struct prefix p; - struct route_node *rn; - - if (!oi->nbr_self) - oi->nbr_self = ospf_nbr_new (oi); - - /* Initial state */ - oi->nbr_self->address = *oi->address; - oi->nbr_self->priority = OSPF_IF_PARAM (oi, priority); - oi->nbr_self->router_id = router_id; - oi->nbr_self->src = oi->address->u.prefix4; - oi->nbr_self->state = NSM_TwoWay; - - switch (oi->area->external_routing) - { - case OSPF_AREA_DEFAULT: - SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E); - break; - case OSPF_AREA_STUB: - UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E); - break; - case OSPF_AREA_NSSA: - UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E); - SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP); - break; - } - - /* Add nbr_self to nbrs table */ - ospf_nbr_key (oi, oi->nbr_self, &p); - - rn = route_node_get (oi->nbrs, &p); - if (rn->info) - { - /* There is already pseudo neighbor. */ - assert (oi->nbr_self == rn->info); - route_unlock_node (rn); - } - else - rn->info = oi->nbr_self; + struct prefix p; + struct route_node *rn; + + if (!oi->nbr_self) + oi->nbr_self = ospf_nbr_new(oi); + + /* Initial state */ + oi->nbr_self->address = *oi->address; + oi->nbr_self->priority = OSPF_IF_PARAM(oi, priority); + oi->nbr_self->router_id = router_id; + oi->nbr_self->src = oi->address->u.prefix4; + oi->nbr_self->state = NSM_TwoWay; + + switch (oi->area->external_routing) { + case OSPF_AREA_DEFAULT: + SET_FLAG(oi->nbr_self->options, OSPF_OPTION_E); + break; + case OSPF_AREA_STUB: + UNSET_FLAG(oi->nbr_self->options, OSPF_OPTION_E); + break; + case OSPF_AREA_NSSA: + UNSET_FLAG(oi->nbr_self->options, OSPF_OPTION_E); + SET_FLAG(oi->nbr_self->options, OSPF_OPTION_NP); + break; + } + + /* Add nbr_self to nbrs table */ + ospf_nbr_key(oi, oi->nbr_self, &p); + + rn = route_node_get(oi->nbrs, &p); + if (rn->info) { + /* There is already pseudo neighbor. */ + assert(oi->nbr_self == rn->info); + route_unlock_node(rn); + } else + rn->info = oi->nbr_self; } /* Get neighbor count by status. Specify status = 0, get all neighbor other than myself. */ -int -ospf_nbr_count (struct ospf_interface *oi, int state) +int ospf_nbr_count(struct ospf_interface *oi, int state) { - struct ospf_neighbor *nbr; - struct route_node *rn; - int count = 0; - - for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) - if ((nbr = rn->info)) - if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id)) - if (state == 0 || nbr->state == state) - count++; - - return count; + struct ospf_neighbor *nbr; + struct route_node *rn; + int count = 0; + + for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) + if ((nbr = rn->info)) + if (!IPV4_ADDR_SAME(&nbr->router_id, + &oi->ospf->router_id)) + if (state == 0 || nbr->state == state) + count++; + + return count; } -int -ospf_nbr_count_opaque_capable (struct ospf_interface *oi) +int ospf_nbr_count_opaque_capable(struct ospf_interface *oi) { - struct ospf_neighbor *nbr; - struct route_node *rn; - int count = 0; - - for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) - if ((nbr = rn->info)) - if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id)) - if (nbr->state == NSM_Full) - if (CHECK_FLAG (nbr->options, OSPF_OPTION_O)) - count++; - - return count; + struct ospf_neighbor *nbr; + struct route_node *rn; + int count = 0; + + for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) + if ((nbr = rn->info)) + if (!IPV4_ADDR_SAME(&nbr->router_id, + &oi->ospf->router_id)) + if (nbr->state == NSM_Full) + if (CHECK_FLAG(nbr->options, + OSPF_OPTION_O)) + count++; + + return count; } /* lookup nbr by address - use this only if you know you must * otherwise use the ospf_nbr_lookup() wrapper, which deals * with virtual link and PointToPoint neighbours */ -struct ospf_neighbor * -ospf_nbr_lookup_by_addr (struct route_table *nbrs, - struct in_addr *addr) +struct ospf_neighbor *ospf_nbr_lookup_by_addr(struct route_table *nbrs, + struct in_addr *addr) +{ + struct prefix p; + struct route_node *rn; + struct ospf_neighbor *nbr; + + p.family = AF_INET; + p.prefixlen = IPV4_MAX_BITLEN; + p.u.prefix4 = *addr; + + rn = route_node_lookup(nbrs, &p); + if (!rn) + return NULL; + + /* See comment in ospf_nbr_delete */ + assert(rn->info); + + if (rn->info == NULL) { + route_unlock_node(rn); + return NULL; + } + + nbr = (struct ospf_neighbor *)rn->info; + route_unlock_node(rn); + + return nbr; +} + +struct ospf_neighbor *ospf_nbr_lookup_by_routerid(struct route_table *nbrs, + struct in_addr *id) { - struct prefix p; - struct route_node *rn; - struct ospf_neighbor *nbr; - - p.family = AF_INET; - p.prefixlen = IPV4_MAX_BITLEN; - p.u.prefix4 = *addr; - - rn = route_node_lookup (nbrs, &p); - if (! rn) - return NULL; - - /* See comment in ospf_nbr_delete */ - assert (rn->info); - - if (rn->info == NULL) - { - route_unlock_node (rn); - return NULL; - } - - nbr = (struct ospf_neighbor *) rn->info; - route_unlock_node (rn); - - return nbr; + struct route_node *rn; + struct ospf_neighbor *nbr; + + for (rn = route_top(nbrs); rn; rn = route_next(rn)) + if ((nbr = rn->info) != NULL) + if (IPV4_ADDR_SAME(&nbr->router_id, id)) { + route_unlock_node(rn); + return nbr; + } + + return NULL; } -struct ospf_neighbor * -ospf_nbr_lookup_by_routerid (struct route_table *nbrs, - struct in_addr *id) +void ospf_renegotiate_optional_capabilities(struct ospf *top) { - struct route_node *rn; - struct ospf_neighbor *nbr; - - for (rn = route_top (nbrs); rn; rn = route_next (rn)) - if ((nbr = rn->info) != NULL) - if (IPV4_ADDR_SAME (&nbr->router_id, id)) - { - route_unlock_node(rn); - return nbr; + struct listnode *node; + struct ospf_interface *oi; + struct route_table *nbrs; + struct route_node *rn; + struct ospf_neighbor *nbr; + + /* At first, flush self-originated LSAs from routing domain. */ + ospf_flush_self_originated_lsas_now(top); + + /* Revert all neighbor status to ExStart. */ + for (ALL_LIST_ELEMENTS_RO(top->oiflist, node, oi)) { + if ((nbrs = oi->nbrs) == NULL) + continue; + + for (rn = route_top(nbrs); rn; rn = route_next(rn)) { + if ((nbr = rn->info) == NULL || nbr == oi->nbr_self) + continue; + + if (nbr->state < NSM_ExStart) + continue; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "Renegotiate optional capabilities with neighbor(%s)", + inet_ntoa(nbr->router_id)); + + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch); + } } - return NULL; + return; } -void -ospf_renegotiate_optional_capabilities (struct ospf *top) + +struct ospf_neighbor *ospf_nbr_lookup(struct ospf_interface *oi, struct ip *iph, + struct ospf_header *ospfh) { - struct listnode *node; - struct ospf_interface *oi; - struct route_table *nbrs; - struct route_node *rn; - struct ospf_neighbor *nbr; + if (oi->type == OSPF_IFTYPE_VIRTUALLINK + || oi->type == OSPF_IFTYPE_POINTOPOINT) + return (ospf_nbr_lookup_by_routerid(oi->nbrs, + &ospfh->router_id)); + else + return (ospf_nbr_lookup_by_addr(oi->nbrs, &iph->ip_src)); +} - /* At first, flush self-originated LSAs from routing domain. */ - ospf_flush_self_originated_lsas_now (top); +static struct ospf_neighbor *ospf_nbr_add(struct ospf_interface *oi, + struct ospf_header *ospfh, + struct prefix *p) +{ + struct ospf_neighbor *nbr; - /* Revert all neighbor status to ExStart. */ - for (ALL_LIST_ELEMENTS_RO (top->oiflist, node, oi)) - { - if ((nbrs = oi->nbrs) == NULL) - continue; + nbr = ospf_nbr_new(oi); + nbr->state = NSM_Down; + nbr->src = p->u.prefix4; + memcpy(&nbr->address, p, sizeof(struct prefix)); - for (rn = route_top (nbrs); rn; rn = route_next (rn)) - { - if ((nbr = rn->info) == NULL || nbr == oi->nbr_self) - continue; + nbr->nbr_nbma = NULL; + if (oi->type == OSPF_IFTYPE_NBMA) { + struct ospf_nbr_nbma *nbr_nbma; + struct listnode *node; - if (nbr->state < NSM_ExStart) - continue; + for (ALL_LIST_ELEMENTS_RO(oi->nbr_nbma, node, nbr_nbma)) { + if (IPV4_ADDR_SAME(&nbr_nbma->addr, &nbr->src)) { + nbr_nbma->nbr = nbr; + nbr->nbr_nbma = nbr_nbma; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Renegotiate optional capabilities with neighbor(%s)", inet_ntoa (nbr->router_id)); + if (nbr_nbma->t_poll) + OSPF_POLL_TIMER_OFF(nbr_nbma->t_poll); - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch); - } - } + nbr->state_change = nbr_nbma->state_change + 1; + } + } + } - return; -} + /* New nbr, save the crypto sequence number if necessary */ + if (ntohs(ospfh->auth_type) == OSPF_AUTH_CRYPTOGRAPHIC) + nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum; + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("NSM[%s:%s]: start", IF_NAME(nbr->oi), + inet_ntoa(nbr->router_id)); -struct ospf_neighbor * -ospf_nbr_lookup (struct ospf_interface *oi, struct ip *iph, - struct ospf_header *ospfh) -{ - if (oi->type == OSPF_IFTYPE_VIRTUALLINK || - oi->type == OSPF_IFTYPE_POINTOPOINT) - return (ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id)); - else - return (ospf_nbr_lookup_by_addr (oi->nbrs, &iph->ip_src)); + return nbr; } -static struct ospf_neighbor * -ospf_nbr_add (struct ospf_interface *oi, struct ospf_header *ospfh, - struct prefix *p) +struct ospf_neighbor *ospf_nbr_get(struct ospf_interface *oi, + struct ospf_header *ospfh, struct ip *iph, + struct prefix *p) { - struct ospf_neighbor *nbr; - - nbr = ospf_nbr_new (oi); - nbr->state = NSM_Down; - nbr->src = p->u.prefix4; - memcpy (&nbr->address, p, sizeof (struct prefix)); - - nbr->nbr_nbma = NULL; - if (oi->type == OSPF_IFTYPE_NBMA) - { - struct ospf_nbr_nbma *nbr_nbma; - struct listnode *node; - - for (ALL_LIST_ELEMENTS_RO (oi->nbr_nbma, node, nbr_nbma)) - { - if (IPV4_ADDR_SAME(&nbr_nbma->addr, &nbr->src)) - { - nbr_nbma->nbr = nbr; - nbr->nbr_nbma = nbr_nbma; - - if (nbr_nbma->t_poll) - OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll); - - nbr->state_change = nbr_nbma->state_change + 1; - } - } - } - - /* New nbr, save the crypto sequence number if necessary */ - if (ntohs (ospfh->auth_type) == OSPF_AUTH_CRYPTOGRAPHIC) - nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("NSM[%s:%s]: start", IF_NAME (nbr->oi), - inet_ntoa (nbr->router_id)); - - return nbr; -} + struct route_node *rn; + struct prefix key; + struct ospf_neighbor *nbr; + + key.family = AF_INET; + key.prefixlen = IPV4_MAX_BITLEN; + + if (oi->type == OSPF_IFTYPE_VIRTUALLINK + || oi->type == OSPF_IFTYPE_POINTOPOINT) + key.u.prefix4 = + ospfh->router_id; /* index vlink and ptp nbrs by + router-id */ + else + key.u.prefix4 = iph->ip_src; + + rn = route_node_get(oi->nbrs, &key); + if (rn->info) { + route_unlock_node(rn); + nbr = rn->info; + + if (oi->type == OSPF_IFTYPE_NBMA && nbr->state == NSM_Attempt) { + nbr->src = iph->ip_src; + memcpy(&nbr->address, p, sizeof(struct prefix)); + } + } else { + rn->info = nbr = ospf_nbr_add(oi, ospfh, p); + } -struct ospf_neighbor * -ospf_nbr_get (struct ospf_interface *oi, struct ospf_header *ospfh, - struct ip *iph, struct prefix *p) -{ - struct route_node *rn; - struct prefix key; - struct ospf_neighbor *nbr; - - key.family = AF_INET; - key.prefixlen = IPV4_MAX_BITLEN; - - if (oi->type == OSPF_IFTYPE_VIRTUALLINK || - oi->type == OSPF_IFTYPE_POINTOPOINT) - key.u.prefix4 = ospfh->router_id;/* index vlink and ptp nbrs by router-id */ - else - key.u.prefix4 = iph->ip_src; - - rn = route_node_get (oi->nbrs, &key); - if (rn->info) - { - route_unlock_node (rn); - nbr = rn->info; - - if (oi->type == OSPF_IFTYPE_NBMA && nbr->state == NSM_Attempt) - { - nbr->src = iph->ip_src; - memcpy (&nbr->address, p, sizeof (struct prefix)); - } - } - else - { - rn->info = nbr = ospf_nbr_add (oi, ospfh, p); - } - - nbr->router_id = ospfh->router_id; - - return nbr; + nbr->router_id = ospfh->router_id; + + return nbr; } diff --git a/ospfd/ospf_neighbor.h b/ospfd/ospf_neighbor.h index 70e3832d9..b19cf5b3e 100644 --- a/ospfd/ospf_neighbor.h +++ b/ospfd/ospf_neighbor.h @@ -25,71 +25,69 @@ #include <ospfd/ospf_packet.h> /* Neighbor Data Structure */ -struct ospf_neighbor -{ - /* This neighbor's parent ospf interface. */ - struct ospf_interface *oi; - - /* OSPF neighbor Information */ - u_char state; /* NSM status. */ - u_char dd_flags; /* DD bit flags. */ - u_int32_t dd_seqnum; /* DD Sequence Number. */ - - /* Neighbor Information from Hello. */ - struct prefix address; /* Neighbor Interface Address. */ - - struct in_addr src; /* Src address. */ - struct in_addr router_id; /* Router ID. */ - u_char options; /* Options. */ - int priority; /* Router Priority. */ - struct in_addr d_router; /* Designated Router. */ - struct in_addr bd_router; /* Backup Designated Router. */ - - /* Last sent Database Description packet. */ - struct ospf_packet *last_send; - /* Timestemp when last Database Description packet was sent */ - struct timeval last_send_ts; - - /* Last received Databse Description packet. */ - struct - { - u_char options; - u_char flags; - u_int32_t dd_seqnum; - } last_recv; - - /* LSA data. */ - struct ospf_lsdb ls_rxmt; - struct ospf_lsdb db_sum; - struct ospf_lsdb ls_req; - struct ospf_lsa *ls_req_last; - - u_int32_t crypt_seqnum; /* Cryptographic Sequence Number. */ - - /* Timer values. */ - u_int32_t v_inactivity; - u_int32_t v_db_desc; - u_int32_t v_ls_req; - u_int32_t v_ls_upd; - - /* Threads. */ - struct thread *t_inactivity; - struct thread *t_db_desc; - struct thread *t_ls_req; - struct thread *t_ls_upd; - struct thread *t_hello_reply; - - /* NBMA configured neighbour */ - struct ospf_nbr_nbma *nbr_nbma; - - /* Statistics */ - struct timeval ts_last_progress; /* last advance of NSM */ - struct timeval ts_last_regress; /* last regressive NSM change */ - const char *last_regress_str; /* Event which last regressed NSM */ - u_int32_t state_change; /* NSM state change counter */ - - /* BFD information */ - void *bfd_info; +struct ospf_neighbor { + /* This neighbor's parent ospf interface. */ + struct ospf_interface *oi; + + /* OSPF neighbor Information */ + u_char state; /* NSM status. */ + u_char dd_flags; /* DD bit flags. */ + u_int32_t dd_seqnum; /* DD Sequence Number. */ + + /* Neighbor Information from Hello. */ + struct prefix address; /* Neighbor Interface Address. */ + + struct in_addr src; /* Src address. */ + struct in_addr router_id; /* Router ID. */ + u_char options; /* Options. */ + int priority; /* Router Priority. */ + struct in_addr d_router; /* Designated Router. */ + struct in_addr bd_router; /* Backup Designated Router. */ + + /* Last sent Database Description packet. */ + struct ospf_packet *last_send; + /* Timestemp when last Database Description packet was sent */ + struct timeval last_send_ts; + + /* Last received Databse Description packet. */ + struct { + u_char options; + u_char flags; + u_int32_t dd_seqnum; + } last_recv; + + /* LSA data. */ + struct ospf_lsdb ls_rxmt; + struct ospf_lsdb db_sum; + struct ospf_lsdb ls_req; + struct ospf_lsa *ls_req_last; + + u_int32_t crypt_seqnum; /* Cryptographic Sequence Number. */ + + /* Timer values. */ + u_int32_t v_inactivity; + u_int32_t v_db_desc; + u_int32_t v_ls_req; + u_int32_t v_ls_upd; + + /* Threads. */ + struct thread *t_inactivity; + struct thread *t_db_desc; + struct thread *t_ls_req; + struct thread *t_ls_upd; + struct thread *t_hello_reply; + + /* NBMA configured neighbour */ + struct ospf_nbr_nbma *nbr_nbma; + + /* Statistics */ + struct timeval ts_last_progress; /* last advance of NSM */ + struct timeval ts_last_regress; /* last regressive NSM change */ + const char *last_regress_str; /* Event which last regressed NSM */ + u_int32_t state_change; /* NSM state change counter */ + + /* BFD information */ + void *bfd_info; }; /* Macros. */ @@ -97,25 +95,23 @@ struct ospf_neighbor #define NBR_IS_BDR(n) IPV4_ADDR_SAME (&n->address.u.prefix4, &n->bd_router) /* Prototypes. */ -extern struct ospf_neighbor *ospf_nbr_new (struct ospf_interface *); -extern void ospf_nbr_free (struct ospf_neighbor *); -extern void ospf_nbr_delete (struct ospf_neighbor *); -extern int ospf_nbr_bidirectional (struct in_addr *, struct in_addr *, int); -extern void ospf_nbr_self_reset (struct ospf_interface *, struct in_addr); -extern void ospf_nbr_add_self (struct ospf_interface *, struct in_addr); -extern int ospf_nbr_count (struct ospf_interface *, int); -extern int ospf_nbr_count_opaque_capable (struct ospf_interface *); -extern struct ospf_neighbor *ospf_nbr_get (struct ospf_interface *, - struct ospf_header *, - struct ip *, struct prefix *); -extern struct ospf_neighbor *ospf_nbr_lookup (struct ospf_interface *, - struct ip *, - struct ospf_header *); -extern struct ospf_neighbor *ospf_nbr_lookup_by_addr (struct route_table *, - struct in_addr *); -extern struct ospf_neighbor *ospf_nbr_lookup_by_routerid (struct route_table - *, - struct in_addr *); -extern void ospf_renegotiate_optional_capabilities (struct ospf *top); +extern struct ospf_neighbor *ospf_nbr_new(struct ospf_interface *); +extern void ospf_nbr_free(struct ospf_neighbor *); +extern void ospf_nbr_delete(struct ospf_neighbor *); +extern int ospf_nbr_bidirectional(struct in_addr *, struct in_addr *, int); +extern void ospf_nbr_self_reset(struct ospf_interface *, struct in_addr); +extern void ospf_nbr_add_self(struct ospf_interface *, struct in_addr); +extern int ospf_nbr_count(struct ospf_interface *, int); +extern int ospf_nbr_count_opaque_capable(struct ospf_interface *); +extern struct ospf_neighbor *ospf_nbr_get(struct ospf_interface *, + struct ospf_header *, struct ip *, + struct prefix *); +extern struct ospf_neighbor *ospf_nbr_lookup(struct ospf_interface *, + struct ip *, struct ospf_header *); +extern struct ospf_neighbor *ospf_nbr_lookup_by_addr(struct route_table *, + struct in_addr *); +extern struct ospf_neighbor *ospf_nbr_lookup_by_routerid(struct route_table *, + struct in_addr *); +extern void ospf_renegotiate_optional_capabilities(struct ospf *top); #endif /* _ZEBRA_OSPF_NEIGHBOR_H */ diff --git a/ospfd/ospf_network.c b/ospfd/ospf_network.c index 0f5785966..c72c69856 100644 --- a/ospfd/ospf_network.c +++ b/ospfd/ospf_network.c @@ -42,185 +42,193 @@ extern struct zebra_privs_t ospfd_privs; #include "ospfd/ospf_packet.h" - /* Join to the OSPF ALL SPF ROUTERS multicast group. */ -int -ospf_if_add_allspfrouters (struct ospf *top, struct prefix *p, - ifindex_t ifindex) +int ospf_if_add_allspfrouters(struct ospf *top, struct prefix *p, + ifindex_t ifindex) { - int ret; - - ret = setsockopt_ipv4_multicast (top->fd, IP_ADD_MEMBERSHIP, - p->u.prefix4, htonl (OSPF_ALLSPFROUTERS), - ifindex); - if (ret < 0) - zlog_warn ("can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, " - "ifindex %u, AllSPFRouters): %s; perhaps a kernel limit " - "on # of multicast group memberships has been exceeded?", - top->fd, inet_ntoa(p->u.prefix4), ifindex, safe_strerror(errno)); - else - zlog_debug ("interface %s [%u] join AllSPFRouters Multicast group.", - inet_ntoa (p->u.prefix4), ifindex); - - return ret; + int ret; + + ret = setsockopt_ipv4_multicast(top->fd, IP_ADD_MEMBERSHIP, + p->u.prefix4, htonl(OSPF_ALLSPFROUTERS), + ifindex); + if (ret < 0) + zlog_warn( + "can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, " + "ifindex %u, AllSPFRouters): %s; perhaps a kernel limit " + "on # of multicast group memberships has been exceeded?", + top->fd, inet_ntoa(p->u.prefix4), ifindex, + safe_strerror(errno)); + else + zlog_debug( + "interface %s [%u] join AllSPFRouters Multicast group.", + inet_ntoa(p->u.prefix4), ifindex); + + return ret; } -int -ospf_if_drop_allspfrouters (struct ospf *top, struct prefix *p, - ifindex_t ifindex) +int ospf_if_drop_allspfrouters(struct ospf *top, struct prefix *p, + ifindex_t ifindex) { - int ret; - - ret = setsockopt_ipv4_multicast (top->fd, IP_DROP_MEMBERSHIP, - p->u.prefix4, htonl (OSPF_ALLSPFROUTERS), - ifindex); - if (ret < 0) - zlog_warn ("can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, " - "ifindex %u, AllSPFRouters): %s", - top->fd, inet_ntoa(p->u.prefix4), ifindex, safe_strerror(errno)); - else - zlog_debug ("interface %s [%u] leave AllSPFRouters Multicast group.", - inet_ntoa (p->u.prefix4), ifindex); - - return ret; + int ret; + + ret = setsockopt_ipv4_multicast(top->fd, IP_DROP_MEMBERSHIP, + p->u.prefix4, htonl(OSPF_ALLSPFROUTERS), + ifindex); + if (ret < 0) + zlog_warn( + "can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, " + "ifindex %u, AllSPFRouters): %s", + top->fd, inet_ntoa(p->u.prefix4), ifindex, + safe_strerror(errno)); + else + zlog_debug( + "interface %s [%u] leave AllSPFRouters Multicast group.", + inet_ntoa(p->u.prefix4), ifindex); + + return ret; } /* Join to the OSPF ALL Designated ROUTERS multicast group. */ -int -ospf_if_add_alldrouters (struct ospf *top, struct prefix *p, ifindex_t ifindex) +int ospf_if_add_alldrouters(struct ospf *top, struct prefix *p, + ifindex_t ifindex) { - int ret; - - ret = setsockopt_ipv4_multicast (top->fd, IP_ADD_MEMBERSHIP, - p->u.prefix4, htonl (OSPF_ALLDROUTERS), - ifindex); - if (ret < 0) - zlog_warn ("can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, " - "ifindex %u, AllDRouters): %s; perhaps a kernel limit " - "on # of multicast group memberships has been exceeded?", - top->fd, inet_ntoa(p->u.prefix4), ifindex, safe_strerror(errno)); - else - zlog_debug ("interface %s [%u] join AllDRouters Multicast group.", - inet_ntoa (p->u.prefix4), ifindex); - - return ret; + int ret; + + ret = setsockopt_ipv4_multicast(top->fd, IP_ADD_MEMBERSHIP, + p->u.prefix4, htonl(OSPF_ALLDROUTERS), + ifindex); + if (ret < 0) + zlog_warn( + "can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, " + "ifindex %u, AllDRouters): %s; perhaps a kernel limit " + "on # of multicast group memberships has been exceeded?", + top->fd, inet_ntoa(p->u.prefix4), ifindex, + safe_strerror(errno)); + else + zlog_debug( + "interface %s [%u] join AllDRouters Multicast group.", + inet_ntoa(p->u.prefix4), ifindex); + + return ret; } -int -ospf_if_drop_alldrouters (struct ospf *top, struct prefix *p, ifindex_t ifindex) +int ospf_if_drop_alldrouters(struct ospf *top, struct prefix *p, + ifindex_t ifindex) { - int ret; - - ret = setsockopt_ipv4_multicast (top->fd, IP_DROP_MEMBERSHIP, - p->u.prefix4, htonl (OSPF_ALLDROUTERS), - ifindex); - if (ret < 0) - zlog_warn ("can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, " - "ifindex %u, AllDRouters): %s", - top->fd, inet_ntoa(p->u.prefix4), ifindex, safe_strerror(errno)); - else - zlog_debug ("interface %s [%u] leave AllDRouters Multicast group.", - inet_ntoa (p->u.prefix4), ifindex); - - return ret; + int ret; + + ret = setsockopt_ipv4_multicast(top->fd, IP_DROP_MEMBERSHIP, + p->u.prefix4, htonl(OSPF_ALLDROUTERS), + ifindex); + if (ret < 0) + zlog_warn( + "can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, " + "ifindex %u, AllDRouters): %s", + top->fd, inet_ntoa(p->u.prefix4), ifindex, + safe_strerror(errno)); + else + zlog_debug( + "interface %s [%u] leave AllDRouters Multicast group.", + inet_ntoa(p->u.prefix4), ifindex); + + return ret; } -int -ospf_if_ipmulticast (struct ospf *top, struct prefix *p, ifindex_t ifindex) +int ospf_if_ipmulticast(struct ospf *top, struct prefix *p, ifindex_t ifindex) { - u_char val; - int ret, len; - - /* Prevent receiving self-origined multicast packets. */ - ret = setsockopt_ipv4_multicast_loop (top->fd, 0); - if (ret < 0) - zlog_warn ("can't setsockopt IP_MULTICAST_LOOP(0) for fd %d: %s", - top->fd, safe_strerror(errno)); - - /* Explicitly set multicast ttl to 1 -- endo. */ - val = 1; - len = sizeof (val); - ret = setsockopt (top->fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&val, len); - if (ret < 0) - zlog_warn ("can't setsockopt IP_MULTICAST_TTL(1) for fd %d: %s", - top->fd, safe_strerror (errno)); - - ret = setsockopt_ipv4_multicast_if (top->fd, p->u.prefix4, ifindex); - if (ret < 0) - zlog_warn("can't setsockopt IP_MULTICAST_IF(fd %d, addr %s, " - "ifindex %u): %s", - top->fd, inet_ntoa(p->u.prefix4), ifindex, safe_strerror(errno)); - - return ret; + u_char val; + int ret, len; + + /* Prevent receiving self-origined multicast packets. */ + ret = setsockopt_ipv4_multicast_loop(top->fd, 0); + if (ret < 0) + zlog_warn("can't setsockopt IP_MULTICAST_LOOP(0) for fd %d: %s", + top->fd, safe_strerror(errno)); + + /* Explicitly set multicast ttl to 1 -- endo. */ + val = 1; + len = sizeof(val); + ret = setsockopt(top->fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&val, + len); + if (ret < 0) + zlog_warn("can't setsockopt IP_MULTICAST_TTL(1) for fd %d: %s", + top->fd, safe_strerror(errno)); + + ret = setsockopt_ipv4_multicast_if(top->fd, p->u.prefix4, ifindex); + if (ret < 0) + zlog_warn( + "can't setsockopt IP_MULTICAST_IF(fd %d, addr %s, " + "ifindex %u): %s", + top->fd, inet_ntoa(p->u.prefix4), ifindex, + safe_strerror(errno)); + + return ret; } -int -ospf_sock_init (void) +int ospf_sock_init(void) { - int ospf_sock; - int ret, hincl = 1; - int bufsize = (8 * 1024 * 1024); - - if ( ospfd_privs.change (ZPRIVS_RAISE) ) - zlog_err ("ospf_sock_init: could not raise privs, %s", - safe_strerror (errno) ); - - ospf_sock = socket (AF_INET, SOCK_RAW, IPPROTO_OSPFIGP); - if (ospf_sock < 0) - { - int save_errno = errno; - if ( ospfd_privs.change (ZPRIVS_LOWER) ) - zlog_err ("ospf_sock_init: could not lower privs, %s", - safe_strerror (errno) ); - zlog_err ("ospf_read_sock_init: socket: %s", safe_strerror (save_errno)); - exit(1); - } - + int ospf_sock; + int ret, hincl = 1; + int bufsize = (8 * 1024 * 1024); + + if (ospfd_privs.change(ZPRIVS_RAISE)) + zlog_err("ospf_sock_init: could not raise privs, %s", + safe_strerror(errno)); + + ospf_sock = socket(AF_INET, SOCK_RAW, IPPROTO_OSPFIGP); + if (ospf_sock < 0) { + int save_errno = errno; + if (ospfd_privs.change(ZPRIVS_LOWER)) + zlog_err("ospf_sock_init: could not lower privs, %s", + safe_strerror(errno)); + zlog_err("ospf_read_sock_init: socket: %s", + safe_strerror(save_errno)); + exit(1); + } + #ifdef IP_HDRINCL - /* we will include IP header with packet */ - ret = setsockopt (ospf_sock, IPPROTO_IP, IP_HDRINCL, &hincl, sizeof (hincl)); - if (ret < 0) - { - int save_errno = errno; - if ( ospfd_privs.change (ZPRIVS_LOWER) ) - zlog_err ("ospf_sock_init: could not lower privs, %s", - safe_strerror (errno) ); - zlog_warn ("Can't set IP_HDRINCL option for fd %d: %s", - ospf_sock, safe_strerror(save_errno)); - } -#elif defined (IPTOS_PREC_INTERNETCONTROL) + /* we will include IP header with packet */ + ret = setsockopt(ospf_sock, IPPROTO_IP, IP_HDRINCL, &hincl, + sizeof(hincl)); + if (ret < 0) { + int save_errno = errno; + if (ospfd_privs.change(ZPRIVS_LOWER)) + zlog_err("ospf_sock_init: could not lower privs, %s", + safe_strerror(errno)); + zlog_warn("Can't set IP_HDRINCL option for fd %d: %s", + ospf_sock, safe_strerror(save_errno)); + } +#elif defined(IPTOS_PREC_INTERNETCONTROL) #warning "IP_HDRINCL not available on this system" #warning "using IPTOS_PREC_INTERNETCONTROL" - ret = setsockopt_ipv4_tos(ospf_sock, IPTOS_PREC_INTERNETCONTROL); - if (ret < 0) - { - int save_errno = errno; - if ( ospfd_privs.change (ZPRIVS_LOWER) ) - zlog_err ("ospf_sock_init: could not lower privs, %s", - safe_strerror (errno) ); - zlog_warn ("can't set sockopt IP_TOS %d to socket %d: %s", - tos, ospf_sock, safe_strerror(save_errno)); - close (ospf_sock); /* Prevent sd leak. */ - return ret; - } + ret = setsockopt_ipv4_tos(ospf_sock, IPTOS_PREC_INTERNETCONTROL); + if (ret < 0) { + int save_errno = errno; + if (ospfd_privs.change(ZPRIVS_LOWER)) + zlog_err("ospf_sock_init: could not lower privs, %s", + safe_strerror(errno)); + zlog_warn("can't set sockopt IP_TOS %d to socket %d: %s", tos, + ospf_sock, safe_strerror(save_errno)); + close(ospf_sock); /* Prevent sd leak. */ + return ret; + } #else /* !IPTOS_PREC_INTERNETCONTROL */ #warning "IP_HDRINCL not available, nor is IPTOS_PREC_INTERNETCONTROL" - zlog_warn ("IP_HDRINCL option not available"); + zlog_warn("IP_HDRINCL option not available"); #endif /* IP_HDRINCL */ - ret = setsockopt_ifindex (AF_INET, ospf_sock, 1); + ret = setsockopt_ifindex(AF_INET, ospf_sock, 1); - if (ret < 0) - zlog_warn ("Can't set pktinfo option for fd %d", ospf_sock); + if (ret < 0) + zlog_warn("Can't set pktinfo option for fd %d", ospf_sock); - if (ospfd_privs.change (ZPRIVS_LOWER)) - { - zlog_err ("ospf_sock_init: could not lower privs, %s", - safe_strerror (errno) ); - } + if (ospfd_privs.change(ZPRIVS_LOWER)) { + zlog_err("ospf_sock_init: could not lower privs, %s", + safe_strerror(errno)); + } - setsockopt_so_sendbuf (ospf_sock, bufsize); - setsockopt_so_recvbuf (ospf_sock, bufsize); + setsockopt_so_sendbuf(ospf_sock, bufsize); + setsockopt_so_recvbuf(ospf_sock, bufsize); - return ospf_sock; + return ospf_sock; } diff --git a/ospfd/ospf_network.h b/ospfd/ospf_network.h index 506a41905..ed5e00315 100644 --- a/ospfd/ospf_network.h +++ b/ospfd/ospf_network.h @@ -23,15 +23,12 @@ #define _ZEBRA_OSPF_NETWORK_H /* Prototypes. */ -extern int ospf_if_add_allspfrouters (struct ospf *, struct prefix *, +extern int ospf_if_add_allspfrouters(struct ospf *, struct prefix *, ifindex_t); +extern int ospf_if_drop_allspfrouters(struct ospf *, struct prefix *, ifindex_t); -extern int ospf_if_drop_allspfrouters (struct ospf *, struct prefix *, - ifindex_t); -extern int ospf_if_add_alldrouters (struct ospf *, struct prefix *, - ifindex_t); -extern int ospf_if_drop_alldrouters (struct ospf *, struct prefix *, - ifindex_t); -extern int ospf_if_ipmulticast (struct ospf *, struct prefix *, ifindex_t); -extern int ospf_sock_init (void); +extern int ospf_if_add_alldrouters(struct ospf *, struct prefix *, ifindex_t); +extern int ospf_if_drop_alldrouters(struct ospf *, struct prefix *, ifindex_t); +extern int ospf_if_ipmulticast(struct ospf *, struct prefix *, ifindex_t); +extern int ospf_sock_init(void); #endif /* _ZEBRA_OSPF_NETWORK_H */ diff --git a/ospfd/ospf_nsm.c b/ospfd/ospf_nsm.c index 676069d6e..a0ff2bfcc 100644 --- a/ospfd/ospf_nsm.c +++ b/ospfd/ospf_nsm.c @@ -50,49 +50,47 @@ #include "ospfd/ospf_bfd.h" DEFINE_HOOK(ospf_nsm_change, - (struct ospf_neighbor *on, int state, int oldstate), - (on, state, oldstate)) + (struct ospf_neighbor * on, int state, int oldstate), + (on, state, oldstate)) -static void nsm_clear_adj (struct ospf_neighbor *); +static void nsm_clear_adj(struct ospf_neighbor *); /* OSPF NSM Timer functions. */ -static int -ospf_inactivity_timer (struct thread *thread) +static int ospf_inactivity_timer(struct thread *thread) { - struct ospf_neighbor *nbr; + struct ospf_neighbor *nbr; - nbr = THREAD_ARG (thread); - nbr->t_inactivity = NULL; + nbr = THREAD_ARG(thread); + nbr->t_inactivity = NULL; - if (IS_DEBUG_OSPF (nsm, NSM_TIMERS)) - zlog_debug("NSM[%s:%s]: Timer (Inactivity timer expire)", - IF_NAME(nbr->oi), inet_ntoa(nbr->router_id)); + if (IS_DEBUG_OSPF(nsm, NSM_TIMERS)) + zlog_debug("NSM[%s:%s]: Timer (Inactivity timer expire)", + IF_NAME(nbr->oi), inet_ntoa(nbr->router_id)); - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_InactivityTimer); + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_InactivityTimer); - return 0; + return 0; } -static int -ospf_db_desc_timer (struct thread *thread) +static int ospf_db_desc_timer(struct thread *thread) { - struct ospf_neighbor *nbr; + struct ospf_neighbor *nbr; - nbr = THREAD_ARG (thread); - nbr->t_db_desc = NULL; + nbr = THREAD_ARG(thread); + nbr->t_db_desc = NULL; - if (IS_DEBUG_OSPF (nsm, NSM_TIMERS)) - zlog_debug("NSM[%s:%s]: Timer (DD Retransmit timer expire)", - IF_NAME(nbr->oi), inet_ntoa(nbr->src)); + if (IS_DEBUG_OSPF(nsm, NSM_TIMERS)) + zlog_debug("NSM[%s:%s]: Timer (DD Retransmit timer expire)", + IF_NAME(nbr->oi), inet_ntoa(nbr->src)); - /* resent last send DD packet. */ - assert (nbr->last_send); - ospf_db_desc_resend (nbr); + /* resent last send DD packet. */ + assert(nbr->last_send); + ospf_db_desc_resend(nbr); - /* DD Retransmit timer set. */ - OSPF_NSM_TIMER_ON (nbr->t_db_desc, ospf_db_desc_timer, nbr->v_db_desc); + /* DD Retransmit timer set. */ + OSPF_NSM_TIMER_ON(nbr->t_db_desc, ospf_db_desc_timer, nbr->v_db_desc); - return 0; + return 0; } /* Hook function called after ospf NSM event is occured. @@ -104,176 +102,166 @@ ospf_db_desc_timer (struct thread *thread) * We rely on this function to properly clear timers in lower states, * particularly before deleting a neighbour. */ -static void -nsm_timer_set (struct ospf_neighbor *nbr) +static void nsm_timer_set(struct ospf_neighbor *nbr) { - switch (nbr->state) - { - case NSM_Deleted: - case NSM_Down: - OSPF_NSM_TIMER_OFF (nbr->t_inactivity); - OSPF_NSM_TIMER_OFF (nbr->t_hello_reply); - /* fallthru */ - case NSM_Attempt: - case NSM_Init: - case NSM_TwoWay: - OSPF_NSM_TIMER_OFF (nbr->t_db_desc); - OSPF_NSM_TIMER_OFF (nbr->t_ls_upd); - OSPF_NSM_TIMER_OFF (nbr->t_ls_req); - break; - case NSM_ExStart: - OSPF_NSM_TIMER_ON (nbr->t_db_desc, ospf_db_desc_timer, nbr->v_db_desc); - OSPF_NSM_TIMER_OFF (nbr->t_ls_upd); - OSPF_NSM_TIMER_OFF (nbr->t_ls_req); - break; - case NSM_Exchange: - OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd); - if (!IS_SET_DD_MS (nbr->dd_flags)) - OSPF_NSM_TIMER_OFF (nbr->t_db_desc); - break; - case NSM_Loading: - case NSM_Full: - default: - OSPF_NSM_TIMER_OFF (nbr->t_db_desc); - break; - } + switch (nbr->state) { + case NSM_Deleted: + case NSM_Down: + OSPF_NSM_TIMER_OFF(nbr->t_inactivity); + OSPF_NSM_TIMER_OFF(nbr->t_hello_reply); + /* fallthru */ + case NSM_Attempt: + case NSM_Init: + case NSM_TwoWay: + OSPF_NSM_TIMER_OFF(nbr->t_db_desc); + OSPF_NSM_TIMER_OFF(nbr->t_ls_upd); + OSPF_NSM_TIMER_OFF(nbr->t_ls_req); + break; + case NSM_ExStart: + OSPF_NSM_TIMER_ON(nbr->t_db_desc, ospf_db_desc_timer, + nbr->v_db_desc); + OSPF_NSM_TIMER_OFF(nbr->t_ls_upd); + OSPF_NSM_TIMER_OFF(nbr->t_ls_req); + break; + case NSM_Exchange: + OSPF_NSM_TIMER_ON(nbr->t_ls_upd, ospf_ls_upd_timer, + nbr->v_ls_upd); + if (!IS_SET_DD_MS(nbr->dd_flags)) + OSPF_NSM_TIMER_OFF(nbr->t_db_desc); + break; + case NSM_Loading: + case NSM_Full: + default: + OSPF_NSM_TIMER_OFF(nbr->t_db_desc); + break; + } } /* 10.4 of RFC2328, indicate whether an adjacency is appropriate with * the given neighbour */ -static int -nsm_should_adj (struct ospf_neighbor *nbr) +static int nsm_should_adj(struct ospf_neighbor *nbr) { - struct ospf_interface *oi = nbr->oi; - - /* These network types must always form adjacencies. */ - if (oi->type == OSPF_IFTYPE_POINTOPOINT - || oi->type == OSPF_IFTYPE_POINTOMULTIPOINT - || oi->type == OSPF_IFTYPE_VIRTUALLINK - /* Router itself is the DRouter or the BDRouter. */ - || IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi)) - || IPV4_ADDR_SAME (&oi->address->u.prefix4, &BDR (oi)) - /* Neighboring Router is the DRouter or the BDRouter. */ - || IPV4_ADDR_SAME (&nbr->address.u.prefix4, &DR (oi)) - || IPV4_ADDR_SAME (&nbr->address.u.prefix4, &BDR (oi))) - return 1; - - return 0; + struct ospf_interface *oi = nbr->oi; + + /* These network types must always form adjacencies. */ + if (oi->type == OSPF_IFTYPE_POINTOPOINT + || oi->type == OSPF_IFTYPE_POINTOMULTIPOINT + || oi->type == OSPF_IFTYPE_VIRTUALLINK + /* Router itself is the DRouter or the BDRouter. */ + || IPV4_ADDR_SAME(&oi->address->u.prefix4, &DR(oi)) + || IPV4_ADDR_SAME(&oi->address->u.prefix4, &BDR(oi)) + /* Neighboring Router is the DRouter or the BDRouter. */ + || IPV4_ADDR_SAME(&nbr->address.u.prefix4, &DR(oi)) + || IPV4_ADDR_SAME(&nbr->address.u.prefix4, &BDR(oi))) + return 1; + + return 0; } /* OSPF NSM functions. */ -static int -nsm_packet_received (struct ospf_neighbor *nbr) +static int nsm_packet_received(struct ospf_neighbor *nbr) { - /* Start or Restart Inactivity Timer. */ - OSPF_NSM_TIMER_OFF (nbr->t_inactivity); - - OSPF_NSM_TIMER_ON (nbr->t_inactivity, ospf_inactivity_timer, - nbr->v_inactivity); + /* Start or Restart Inactivity Timer. */ + OSPF_NSM_TIMER_OFF(nbr->t_inactivity); + + OSPF_NSM_TIMER_ON(nbr->t_inactivity, ospf_inactivity_timer, + nbr->v_inactivity); - if (nbr->oi->type == OSPF_IFTYPE_NBMA && nbr->nbr_nbma) - OSPF_POLL_TIMER_OFF (nbr->nbr_nbma->t_poll); + if (nbr->oi->type == OSPF_IFTYPE_NBMA && nbr->nbr_nbma) + OSPF_POLL_TIMER_OFF(nbr->nbr_nbma->t_poll); - /* Send proactive ARP requests */ - if (nbr->state < NSM_Exchange) - ospf_proactively_arp (nbr); + /* Send proactive ARP requests */ + if (nbr->state < NSM_Exchange) + ospf_proactively_arp(nbr); - return 0; + return 0; } -static int -nsm_start (struct ospf_neighbor *nbr) +static int nsm_start(struct ospf_neighbor *nbr) { - if (nbr->nbr_nbma) - OSPF_POLL_TIMER_OFF (nbr->nbr_nbma->t_poll); + if (nbr->nbr_nbma) + OSPF_POLL_TIMER_OFF(nbr->nbr_nbma->t_poll); - OSPF_NSM_TIMER_OFF (nbr->t_inactivity); - - OSPF_NSM_TIMER_ON (nbr->t_inactivity, ospf_inactivity_timer, - nbr->v_inactivity); + OSPF_NSM_TIMER_OFF(nbr->t_inactivity); - /* Send proactive ARP requests */ - ospf_proactively_arp (nbr); + OSPF_NSM_TIMER_ON(nbr->t_inactivity, ospf_inactivity_timer, + nbr->v_inactivity); - return 0; + /* Send proactive ARP requests */ + ospf_proactively_arp(nbr); + + return 0; } -static int -nsm_twoway_received (struct ospf_neighbor *nbr) +static int nsm_twoway_received(struct ospf_neighbor *nbr) { - int adj = nsm_should_adj (nbr); + int adj = nsm_should_adj(nbr); - /* Send proactive ARP requests */ - if (adj) - ospf_proactively_arp (nbr); + /* Send proactive ARP requests */ + if (adj) + ospf_proactively_arp(nbr); - return (adj ? NSM_ExStart : NSM_TwoWay); + return (adj ? NSM_ExStart : NSM_TwoWay); } -int -ospf_db_summary_count (struct ospf_neighbor *nbr) +int ospf_db_summary_count(struct ospf_neighbor *nbr) { - return ospf_lsdb_count_all (&nbr->db_sum); + return ospf_lsdb_count_all(&nbr->db_sum); } -int -ospf_db_summary_isempty (struct ospf_neighbor *nbr) +int ospf_db_summary_isempty(struct ospf_neighbor *nbr) { - return ospf_lsdb_isempty (&nbr->db_sum); + return ospf_lsdb_isempty(&nbr->db_sum); } -static int -ospf_db_summary_add (struct ospf_neighbor *nbr, struct ospf_lsa *lsa) +static int ospf_db_summary_add(struct ospf_neighbor *nbr, struct ospf_lsa *lsa) { - switch (lsa->data->type) - { - case OSPF_OPAQUE_LINK_LSA: - /* Exclude type-9 LSAs that does not have the same "oi" with "nbr". */ - if (nbr->oi && ospf_if_exists (lsa->oi) != nbr->oi) - return 0; - break; - case OSPF_OPAQUE_AREA_LSA: - /* - * It is assured by the caller function "nsm_negotiation_done()" - * that every given LSA belongs to the same area with "nbr". - */ - break; - case OSPF_OPAQUE_AS_LSA: - default: - break; - } - - /* Stay away from any Local Translated Type-7 LSAs */ - if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)) - return 0; - - if (IS_LSA_MAXAGE (lsa)) - ospf_ls_retransmit_add (nbr, lsa); - else - ospf_lsdb_add (&nbr->db_sum, lsa); - - return 0; + switch (lsa->data->type) { + case OSPF_OPAQUE_LINK_LSA: + /* Exclude type-9 LSAs that does not have the same "oi" with + * "nbr". */ + if (nbr->oi && ospf_if_exists(lsa->oi) != nbr->oi) + return 0; + break; + case OSPF_OPAQUE_AREA_LSA: + /* + * It is assured by the caller function "nsm_negotiation_done()" + * that every given LSA belongs to the same area with "nbr". + */ + break; + case OSPF_OPAQUE_AS_LSA: + default: + break; + } + + /* Stay away from any Local Translated Type-7 LSAs */ + if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT)) + return 0; + + if (IS_LSA_MAXAGE(lsa)) + ospf_ls_retransmit_add(nbr, lsa); + else + ospf_lsdb_add(&nbr->db_sum, lsa); + + return 0; } -void -ospf_db_summary_clear (struct ospf_neighbor *nbr) +void ospf_db_summary_clear(struct ospf_neighbor *nbr) { - struct ospf_lsdb *lsdb; - int i; - - lsdb = &nbr->db_sum; - for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++) - { - struct route_table *table = lsdb->type[i].db; - struct route_node *rn; - - for (rn = route_top (table); rn; rn = route_next (rn)) - if (rn->info) - ospf_lsdb_delete (&nbr->db_sum, rn->info); - } -} + struct ospf_lsdb *lsdb; + int i; + lsdb = &nbr->db_sum; + for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++) { + struct route_table *table = lsdb->type[i].db; + struct route_node *rn; + + for (rn = route_top(table); rn; rn = route_next(rn)) + if (rn->info) + ospf_lsdb_delete(&nbr->db_sum, rn->info); + } +} /* The area link state database consists of the router-LSAs, @@ -282,598 +270,577 @@ ospf_db_summary_clear (struct ospf_neighbor *nbr) AS-external-LSAs are omitted from a virtual neighbor's Database summary list. AS-external-LSAs are omitted from the Database summary list if the area has been configured as a stub. */ -static int -nsm_negotiation_done (struct ospf_neighbor *nbr) +static int nsm_negotiation_done(struct ospf_neighbor *nbr) { - struct ospf_area *area = nbr->oi->area; - struct ospf_lsa *lsa; - struct route_node *rn; - - /* Send proactive ARP requests */ - ospf_proactively_arp (nbr); - - LSDB_LOOP (ROUTER_LSDB (area), rn, lsa) - ospf_db_summary_add (nbr, lsa); - LSDB_LOOP (NETWORK_LSDB (area), rn, lsa) - ospf_db_summary_add (nbr, lsa); - LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa) - ospf_db_summary_add (nbr, lsa); - LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa) - ospf_db_summary_add (nbr, lsa); - - /* Process only if the neighbor is opaque capable. */ - if (CHECK_FLAG (nbr->options, OSPF_OPTION_O)) - { - LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa) - ospf_db_summary_add (nbr, lsa); - LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa) - ospf_db_summary_add (nbr, lsa); - } - - if (CHECK_FLAG (nbr->options, OSPF_OPTION_NP)) - { - LSDB_LOOP (NSSA_LSDB (area), rn, lsa) - ospf_db_summary_add (nbr, lsa); - } - - if (nbr->oi->type != OSPF_IFTYPE_VIRTUALLINK - && area->external_routing == OSPF_AREA_DEFAULT) - LSDB_LOOP (EXTERNAL_LSDB (nbr->oi->ospf), rn, lsa) - ospf_db_summary_add (nbr, lsa); - - if (CHECK_FLAG (nbr->options, OSPF_OPTION_O) - && (nbr->oi->type != OSPF_IFTYPE_VIRTUALLINK - && area->external_routing == OSPF_AREA_DEFAULT)) - LSDB_LOOP (OPAQUE_AS_LSDB (nbr->oi->ospf), rn, lsa) - ospf_db_summary_add (nbr, lsa); - - return 0; + struct ospf_area *area = nbr->oi->area; + struct ospf_lsa *lsa; + struct route_node *rn; + + /* Send proactive ARP requests */ + ospf_proactively_arp(nbr); + + LSDB_LOOP(ROUTER_LSDB(area), rn, lsa) + ospf_db_summary_add(nbr, lsa); + LSDB_LOOP(NETWORK_LSDB(area), rn, lsa) + ospf_db_summary_add(nbr, lsa); + LSDB_LOOP(SUMMARY_LSDB(area), rn, lsa) + ospf_db_summary_add(nbr, lsa); + LSDB_LOOP(ASBR_SUMMARY_LSDB(area), rn, lsa) + ospf_db_summary_add(nbr, lsa); + + /* Process only if the neighbor is opaque capable. */ + if (CHECK_FLAG(nbr->options, OSPF_OPTION_O)) { + LSDB_LOOP(OPAQUE_LINK_LSDB(area), rn, lsa) + ospf_db_summary_add(nbr, lsa); + LSDB_LOOP(OPAQUE_AREA_LSDB(area), rn, lsa) + ospf_db_summary_add(nbr, lsa); + } + + if (CHECK_FLAG(nbr->options, OSPF_OPTION_NP)) { + LSDB_LOOP(NSSA_LSDB(area), rn, lsa) + ospf_db_summary_add(nbr, lsa); + } + + if (nbr->oi->type != OSPF_IFTYPE_VIRTUALLINK + && area->external_routing == OSPF_AREA_DEFAULT) + LSDB_LOOP(EXTERNAL_LSDB(nbr->oi->ospf), rn, lsa) + ospf_db_summary_add(nbr, lsa); + + if (CHECK_FLAG(nbr->options, OSPF_OPTION_O) + && (nbr->oi->type != OSPF_IFTYPE_VIRTUALLINK + && area->external_routing == OSPF_AREA_DEFAULT)) + LSDB_LOOP(OPAQUE_AS_LSDB(nbr->oi->ospf), rn, lsa) + ospf_db_summary_add(nbr, lsa); + + return 0; } -static int -nsm_exchange_done (struct ospf_neighbor *nbr) +static int nsm_exchange_done(struct ospf_neighbor *nbr) { - if (ospf_ls_request_isempty (nbr)) - return NSM_Full; + if (ospf_ls_request_isempty(nbr)) + return NSM_Full; - /* Send Link State Request. */ - if (nbr->t_ls_req == NULL) - ospf_ls_req_send (nbr); + /* Send Link State Request. */ + if (nbr->t_ls_req == NULL) + ospf_ls_req_send(nbr); - return NSM_Loading; + return NSM_Loading; } -static int -nsm_adj_ok (struct ospf_neighbor *nbr) +static int nsm_adj_ok(struct ospf_neighbor *nbr) { - int next_state = nbr->state; - int adj = nsm_should_adj (nbr); + int next_state = nbr->state; + int adj = nsm_should_adj(nbr); - if (nbr->state == NSM_TwoWay && adj == 1) - { - next_state = NSM_ExStart; + if (nbr->state == NSM_TwoWay && adj == 1) { + next_state = NSM_ExStart; - /* Send proactive ARP requests */ - ospf_proactively_arp (nbr); - } - else if (nbr->state >= NSM_ExStart && adj == 0) - next_state = NSM_TwoWay; + /* Send proactive ARP requests */ + ospf_proactively_arp(nbr); + } else if (nbr->state >= NSM_ExStart && adj == 0) + next_state = NSM_TwoWay; - return next_state; + return next_state; } /* Clear adjacency related state for a neighbour, intended where nbr * transitions from > ExStart (i.e. a Full or forming adjacency) * to <= ExStart. */ -static void -nsm_clear_adj (struct ospf_neighbor *nbr) +static void nsm_clear_adj(struct ospf_neighbor *nbr) { - /* Clear Database Summary list. */ - if (!ospf_db_summary_isempty (nbr)) - ospf_db_summary_clear (nbr); + /* Clear Database Summary list. */ + if (!ospf_db_summary_isempty(nbr)) + ospf_db_summary_clear(nbr); - /* Clear Link State Request list. */ - if (!ospf_ls_request_isempty (nbr)) - ospf_ls_request_delete_all (nbr); + /* Clear Link State Request list. */ + if (!ospf_ls_request_isempty(nbr)) + ospf_ls_request_delete_all(nbr); - /* Clear Link State Retransmission list. */ - if (!ospf_ls_retransmit_isempty (nbr)) - ospf_ls_retransmit_clear (nbr); + /* Clear Link State Retransmission list. */ + if (!ospf_ls_retransmit_isempty(nbr)) + ospf_ls_retransmit_clear(nbr); - if (CHECK_FLAG (nbr->options, OSPF_OPTION_O)) - UNSET_FLAG (nbr->options, OSPF_OPTION_O); + if (CHECK_FLAG(nbr->options, OSPF_OPTION_O)) + UNSET_FLAG(nbr->options, OSPF_OPTION_O); } -static int -nsm_kill_nbr (struct ospf_neighbor *nbr) +static int nsm_kill_nbr(struct ospf_neighbor *nbr) { - /* killing nbr_self is invalid */ - if (nbr == nbr->oi->nbr_self) - { - assert (nbr != nbr->oi->nbr_self); - return 0; - } - - if (nbr->oi->type == OSPF_IFTYPE_NBMA && nbr->nbr_nbma != NULL) - { - struct ospf_nbr_nbma *nbr_nbma = nbr->nbr_nbma; - - nbr_nbma->nbr = NULL; - nbr_nbma->state_change = nbr->state_change; - - nbr->nbr_nbma = NULL; - - OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer, - nbr_nbma->v_poll); - - if (IS_DEBUG_OSPF (nsm, NSM_EVENTS)) - zlog_debug ("NSM[%s:%s]: Down (PollIntervalTimer scheduled)", - IF_NAME (nbr->oi), inet_ntoa (nbr->address.u.prefix4)); - } - - return 0; + /* killing nbr_self is invalid */ + if (nbr == nbr->oi->nbr_self) { + assert(nbr != nbr->oi->nbr_self); + return 0; + } + + if (nbr->oi->type == OSPF_IFTYPE_NBMA && nbr->nbr_nbma != NULL) { + struct ospf_nbr_nbma *nbr_nbma = nbr->nbr_nbma; + + nbr_nbma->nbr = NULL; + nbr_nbma->state_change = nbr->state_change; + + nbr->nbr_nbma = NULL; + + OSPF_POLL_TIMER_ON(nbr_nbma->t_poll, ospf_poll_timer, + nbr_nbma->v_poll); + + if (IS_DEBUG_OSPF(nsm, NSM_EVENTS)) + zlog_debug( + "NSM[%s:%s]: Down (PollIntervalTimer scheduled)", + IF_NAME(nbr->oi), + inet_ntoa(nbr->address.u.prefix4)); + } + + return 0; } /* Neighbor State Machine */ struct { - int (*func) (struct ospf_neighbor *); - int next_state; -} NSM [OSPF_NSM_STATE_MAX][OSPF_NSM_EVENT_MAX] = -{ - { - /* DependUpon: dummy state. */ - { NULL, NSM_DependUpon }, /* NoEvent */ - { NULL, NSM_DependUpon }, /* PacketReceived */ - { NULL, NSM_DependUpon }, /* Start */ - { NULL, NSM_DependUpon }, /* 2-WayReceived */ - { NULL, NSM_DependUpon }, /* NegotiationDone */ - { NULL, NSM_DependUpon }, /* ExchangeDone */ - { NULL, NSM_DependUpon }, /* BadLSReq */ - { NULL, NSM_DependUpon }, /* LoadingDone */ - { NULL, NSM_DependUpon }, /* AdjOK? */ - { NULL, NSM_DependUpon }, /* SeqNumberMismatch */ - { NULL, NSM_DependUpon }, /* 1-WayReceived */ - { NULL, NSM_DependUpon }, /* KillNbr */ - { NULL, NSM_DependUpon }, /* InactivityTimer */ - { NULL, NSM_DependUpon }, /* LLDown */ - }, - { - /* Deleted: dummy state. */ - { NULL, NSM_Deleted }, /* NoEvent */ - { NULL, NSM_Deleted }, /* PacketReceived */ - { NULL, NSM_Deleted }, /* Start */ - { NULL, NSM_Deleted }, /* 2-WayReceived */ - { NULL, NSM_Deleted }, /* NegotiationDone */ - { NULL, NSM_Deleted }, /* ExchangeDone */ - { NULL, NSM_Deleted }, /* BadLSReq */ - { NULL, NSM_Deleted }, /* LoadingDone */ - { NULL, NSM_Deleted }, /* AdjOK? */ - { NULL, NSM_Deleted }, /* SeqNumberMismatch */ - { NULL, NSM_Deleted }, /* 1-WayReceived */ - { NULL, NSM_Deleted }, /* KillNbr */ - { NULL, NSM_Deleted }, /* InactivityTimer */ - { NULL, NSM_Deleted }, /* LLDown */ - }, - { - /* Down: */ - { NULL, NSM_DependUpon }, /* NoEvent */ - { nsm_packet_received, NSM_Init }, /* PacketReceived */ - { nsm_start, NSM_Attempt }, /* Start */ - { NULL, NSM_Down }, /* 2-WayReceived */ - { NULL, NSM_Down }, /* NegotiationDone */ - { NULL, NSM_Down }, /* ExchangeDone */ - { NULL, NSM_Down }, /* BadLSReq */ - { NULL, NSM_Down }, /* LoadingDone */ - { NULL, NSM_Down }, /* AdjOK? */ - { NULL, NSM_Down }, /* SeqNumberMismatch */ - { NULL, NSM_Down }, /* 1-WayReceived */ - { nsm_kill_nbr, NSM_Deleted }, /* KillNbr */ - { nsm_kill_nbr, NSM_Deleted }, /* InactivityTimer */ - { nsm_kill_nbr, NSM_Deleted }, /* LLDown */ - }, - { - /* Attempt: */ - { NULL, NSM_DependUpon }, /* NoEvent */ - { nsm_packet_received, NSM_Init }, /* PacketReceived */ - { NULL, NSM_Attempt }, /* Start */ - { NULL, NSM_Attempt }, /* 2-WayReceived */ - { NULL, NSM_Attempt }, /* NegotiationDone */ - { NULL, NSM_Attempt }, /* ExchangeDone */ - { NULL, NSM_Attempt }, /* BadLSReq */ - { NULL, NSM_Attempt }, /* LoadingDone */ - { NULL, NSM_Attempt }, /* AdjOK? */ - { NULL, NSM_Attempt }, /* SeqNumberMismatch */ - { NULL, NSM_Attempt }, /* 1-WayReceived */ - { nsm_kill_nbr, NSM_Deleted }, /* KillNbr */ - { nsm_kill_nbr, NSM_Deleted }, /* InactivityTimer */ - { nsm_kill_nbr, NSM_Deleted }, /* LLDown */ - }, - { - /* Init: */ - { NULL, NSM_DependUpon }, /* NoEvent */ - { nsm_packet_received, NSM_Init }, /* PacketReceived */ - { NULL, NSM_Init }, /* Start */ - { nsm_twoway_received, NSM_DependUpon }, /* 2-WayReceived */ - { NULL, NSM_Init }, /* NegotiationDone */ - { NULL, NSM_Init }, /* ExchangeDone */ - { NULL, NSM_Init }, /* BadLSReq */ - { NULL, NSM_Init }, /* LoadingDone */ - { NULL, NSM_Init }, /* AdjOK? */ - { NULL, NSM_Init }, /* SeqNumberMismatch */ - { NULL, NSM_Init }, /* 1-WayReceived */ - { nsm_kill_nbr, NSM_Deleted }, /* KillNbr */ - { nsm_kill_nbr, NSM_Deleted }, /* InactivityTimer */ - { nsm_kill_nbr, NSM_Deleted }, /* LLDown */ - }, - { - /* 2-Way: */ - { NULL, NSM_DependUpon }, /* NoEvent */ - { nsm_packet_received, NSM_TwoWay }, /* HelloReceived */ - { NULL, NSM_TwoWay }, /* Start */ - { NULL, NSM_TwoWay }, /* 2-WayReceived */ - { NULL, NSM_TwoWay }, /* NegotiationDone */ - { NULL, NSM_TwoWay }, /* ExchangeDone */ - { NULL, NSM_TwoWay }, /* BadLSReq */ - { NULL, NSM_TwoWay }, /* LoadingDone */ - { nsm_adj_ok, NSM_DependUpon }, /* AdjOK? */ - { NULL, NSM_TwoWay }, /* SeqNumberMismatch */ - { NULL, NSM_Init }, /* 1-WayReceived */ - { nsm_kill_nbr, NSM_Deleted }, /* KillNbr */ - { nsm_kill_nbr, NSM_Deleted }, /* InactivityTimer */ - { nsm_kill_nbr, NSM_Deleted }, /* LLDown */ - }, - { - /* ExStart: */ - { NULL, NSM_DependUpon }, /* NoEvent */ - { nsm_packet_received, NSM_ExStart }, /* PacaketReceived */ - { NULL, NSM_ExStart }, /* Start */ - { NULL, NSM_ExStart }, /* 2-WayReceived */ - { nsm_negotiation_done, NSM_Exchange }, /* NegotiationDone */ - { NULL, NSM_ExStart }, /* ExchangeDone */ - { NULL, NSM_ExStart }, /* BadLSReq */ - { NULL, NSM_ExStart }, /* LoadingDone */ - { nsm_adj_ok, NSM_DependUpon }, /* AdjOK? */ - { NULL, NSM_ExStart }, /* SeqNumberMismatch */ - { NULL, NSM_Init }, /* 1-WayReceived */ - { nsm_kill_nbr, NSM_Deleted }, /* KillNbr */ - { nsm_kill_nbr, NSM_Deleted }, /* InactivityTimer */ - { nsm_kill_nbr, NSM_Deleted }, /* LLDown */ - }, - { - /* Exchange: */ - { NULL, NSM_DependUpon }, /* NoEvent */ - { nsm_packet_received, NSM_Exchange }, /* PacketReceived */ - { NULL, NSM_Exchange }, /* Start */ - { NULL, NSM_Exchange }, /* 2-WayReceived */ - { NULL, NSM_Exchange }, /* NegotiationDone */ - { nsm_exchange_done, NSM_DependUpon }, /* ExchangeDone */ - { NULL, NSM_ExStart }, /* BadLSReq */ - { NULL, NSM_Exchange }, /* LoadingDone */ - { nsm_adj_ok, NSM_DependUpon }, /* AdjOK? */ - { NULL, NSM_ExStart }, /* SeqNumberMismatch */ - { NULL, NSM_Init }, /* 1-WayReceived */ - { nsm_kill_nbr, NSM_Deleted }, /* KillNbr */ - { nsm_kill_nbr, NSM_Deleted }, /* InactivityTimer */ - { nsm_kill_nbr, NSM_Deleted }, /* LLDown */ - }, - { - /* Loading: */ - { NULL, NSM_DependUpon }, /* NoEvent */ - { nsm_packet_received, NSM_Loading }, /* PacketReceived */ - { NULL, NSM_Loading }, /* Start */ - { NULL, NSM_Loading }, /* 2-WayReceived */ - { NULL, NSM_Loading }, /* NegotiationDone */ - { NULL, NSM_Loading }, /* ExchangeDone */ - { NULL, NSM_ExStart }, /* BadLSReq */ - { NULL, NSM_Full }, /* LoadingDone */ - { nsm_adj_ok, NSM_DependUpon }, /* AdjOK? */ - { NULL, NSM_ExStart }, /* SeqNumberMismatch */ - { NULL, NSM_Init }, /* 1-WayReceived */ - { nsm_kill_nbr, NSM_Deleted }, /* KillNbr */ - { nsm_kill_nbr, NSM_Deleted }, /* InactivityTimer */ - { nsm_kill_nbr, NSM_Deleted }, /* LLDown */ - }, - { /* Full: */ - { NULL, NSM_DependUpon }, /* NoEvent */ - { nsm_packet_received, NSM_Full }, /* PacketReceived */ - { NULL, NSM_Full }, /* Start */ - { NULL, NSM_Full }, /* 2-WayReceived */ - { NULL, NSM_Full }, /* NegotiationDone */ - { NULL, NSM_Full }, /* ExchangeDone */ - { NULL, NSM_ExStart }, /* BadLSReq */ - { NULL, NSM_Full }, /* LoadingDone */ - { nsm_adj_ok, NSM_DependUpon }, /* AdjOK? */ - { NULL, NSM_ExStart }, /* SeqNumberMismatch */ - { NULL, NSM_Init }, /* 1-WayReceived */ - { nsm_kill_nbr, NSM_Deleted }, /* KillNbr */ - { nsm_kill_nbr, NSM_Deleted }, /* InactivityTimer */ - { nsm_kill_nbr, NSM_Deleted }, /* LLDown */ - }, + int (*func)(struct ospf_neighbor *); + int next_state; +} NSM[OSPF_NSM_STATE_MAX][OSPF_NSM_EVENT_MAX] = { + { + /* DependUpon: dummy state. */ + {NULL, NSM_DependUpon}, /* NoEvent */ + {NULL, NSM_DependUpon}, /* PacketReceived */ + {NULL, NSM_DependUpon}, /* Start */ + {NULL, NSM_DependUpon}, /* 2-WayReceived */ + {NULL, NSM_DependUpon}, /* NegotiationDone */ + {NULL, NSM_DependUpon}, /* ExchangeDone */ + {NULL, NSM_DependUpon}, /* BadLSReq */ + {NULL, NSM_DependUpon}, /* LoadingDone */ + {NULL, NSM_DependUpon}, /* AdjOK? */ + {NULL, NSM_DependUpon}, /* SeqNumberMismatch */ + {NULL, NSM_DependUpon}, /* 1-WayReceived */ + {NULL, NSM_DependUpon}, /* KillNbr */ + {NULL, NSM_DependUpon}, /* InactivityTimer */ + {NULL, NSM_DependUpon}, /* LLDown */ + }, + { + /* Deleted: dummy state. */ + {NULL, NSM_Deleted}, /* NoEvent */ + {NULL, NSM_Deleted}, /* PacketReceived */ + {NULL, NSM_Deleted}, /* Start */ + {NULL, NSM_Deleted}, /* 2-WayReceived */ + {NULL, NSM_Deleted}, /* NegotiationDone */ + {NULL, NSM_Deleted}, /* ExchangeDone */ + {NULL, NSM_Deleted}, /* BadLSReq */ + {NULL, NSM_Deleted}, /* LoadingDone */ + {NULL, NSM_Deleted}, /* AdjOK? */ + {NULL, NSM_Deleted}, /* SeqNumberMismatch */ + {NULL, NSM_Deleted}, /* 1-WayReceived */ + {NULL, NSM_Deleted}, /* KillNbr */ + {NULL, NSM_Deleted}, /* InactivityTimer */ + {NULL, NSM_Deleted}, /* LLDown */ + }, + { + /* Down: */ + {NULL, NSM_DependUpon}, /* NoEvent */ + {nsm_packet_received, NSM_Init}, /* PacketReceived */ + {nsm_start, NSM_Attempt}, /* Start */ + {NULL, NSM_Down}, /* 2-WayReceived */ + {NULL, NSM_Down}, /* NegotiationDone */ + {NULL, NSM_Down}, /* ExchangeDone */ + {NULL, NSM_Down}, /* BadLSReq */ + {NULL, NSM_Down}, /* LoadingDone */ + {NULL, NSM_Down}, /* AdjOK? */ + {NULL, NSM_Down}, /* SeqNumberMismatch */ + {NULL, NSM_Down}, /* 1-WayReceived */ + {nsm_kill_nbr, NSM_Deleted}, /* KillNbr */ + {nsm_kill_nbr, NSM_Deleted}, /* InactivityTimer */ + {nsm_kill_nbr, NSM_Deleted}, /* LLDown */ + }, + { + /* Attempt: */ + {NULL, NSM_DependUpon}, /* NoEvent */ + {nsm_packet_received, NSM_Init}, /* PacketReceived */ + {NULL, NSM_Attempt}, /* Start */ + {NULL, NSM_Attempt}, /* 2-WayReceived */ + {NULL, NSM_Attempt}, /* NegotiationDone */ + {NULL, NSM_Attempt}, /* ExchangeDone */ + {NULL, NSM_Attempt}, /* BadLSReq */ + {NULL, NSM_Attempt}, /* LoadingDone */ + {NULL, NSM_Attempt}, /* AdjOK? */ + {NULL, NSM_Attempt}, /* SeqNumberMismatch */ + {NULL, NSM_Attempt}, /* 1-WayReceived */ + {nsm_kill_nbr, NSM_Deleted}, /* KillNbr */ + {nsm_kill_nbr, NSM_Deleted}, /* InactivityTimer */ + {nsm_kill_nbr, NSM_Deleted}, /* LLDown */ + }, + { + /* Init: */ + {NULL, NSM_DependUpon}, /* NoEvent */ + {nsm_packet_received, NSM_Init}, /* PacketReceived */ + {NULL, NSM_Init}, /* Start */ + {nsm_twoway_received, NSM_DependUpon}, /* 2-WayReceived */ + {NULL, NSM_Init}, /* NegotiationDone */ + {NULL, NSM_Init}, /* ExchangeDone */ + {NULL, NSM_Init}, /* BadLSReq */ + {NULL, NSM_Init}, /* LoadingDone */ + {NULL, NSM_Init}, /* AdjOK? */ + {NULL, NSM_Init}, /* SeqNumberMismatch */ + {NULL, NSM_Init}, /* 1-WayReceived */ + {nsm_kill_nbr, NSM_Deleted}, /* KillNbr */ + {nsm_kill_nbr, NSM_Deleted}, /* InactivityTimer */ + {nsm_kill_nbr, NSM_Deleted}, /* LLDown */ + }, + { + /* 2-Way: */ + {NULL, NSM_DependUpon}, /* NoEvent */ + {nsm_packet_received, NSM_TwoWay}, /* HelloReceived */ + {NULL, NSM_TwoWay}, /* Start */ + {NULL, NSM_TwoWay}, /* 2-WayReceived */ + {NULL, NSM_TwoWay}, /* NegotiationDone */ + {NULL, NSM_TwoWay}, /* ExchangeDone */ + {NULL, NSM_TwoWay}, /* BadLSReq */ + {NULL, NSM_TwoWay}, /* LoadingDone */ + {nsm_adj_ok, NSM_DependUpon}, /* AdjOK? */ + {NULL, NSM_TwoWay}, /* SeqNumberMismatch */ + {NULL, NSM_Init}, /* 1-WayReceived */ + {nsm_kill_nbr, NSM_Deleted}, /* KillNbr */ + {nsm_kill_nbr, NSM_Deleted}, /* InactivityTimer */ + {nsm_kill_nbr, NSM_Deleted}, /* LLDown */ + }, + { + /* ExStart: */ + {NULL, NSM_DependUpon}, /* NoEvent */ + {nsm_packet_received, NSM_ExStart}, /* PacaketReceived */ + {NULL, NSM_ExStart}, /* Start */ + {NULL, NSM_ExStart}, /* 2-WayReceived */ + {nsm_negotiation_done, NSM_Exchange}, /* NegotiationDone */ + {NULL, NSM_ExStart}, /* ExchangeDone */ + {NULL, NSM_ExStart}, /* BadLSReq */ + {NULL, NSM_ExStart}, /* LoadingDone */ + {nsm_adj_ok, NSM_DependUpon}, /* AdjOK? */ + {NULL, NSM_ExStart}, /* SeqNumberMismatch */ + {NULL, NSM_Init}, /* 1-WayReceived */ + {nsm_kill_nbr, NSM_Deleted}, /* KillNbr */ + {nsm_kill_nbr, NSM_Deleted}, /* InactivityTimer */ + {nsm_kill_nbr, NSM_Deleted}, /* LLDown */ + }, + { + /* Exchange: */ + {NULL, NSM_DependUpon}, /* NoEvent */ + {nsm_packet_received, NSM_Exchange}, /* PacketReceived */ + {NULL, NSM_Exchange}, /* Start */ + {NULL, NSM_Exchange}, /* 2-WayReceived */ + {NULL, NSM_Exchange}, /* NegotiationDone */ + {nsm_exchange_done, NSM_DependUpon}, /* ExchangeDone */ + {NULL, NSM_ExStart}, /* BadLSReq */ + {NULL, NSM_Exchange}, /* LoadingDone */ + {nsm_adj_ok, NSM_DependUpon}, /* AdjOK? */ + {NULL, NSM_ExStart}, /* SeqNumberMismatch */ + {NULL, NSM_Init}, /* 1-WayReceived */ + {nsm_kill_nbr, NSM_Deleted}, /* KillNbr */ + {nsm_kill_nbr, NSM_Deleted}, /* InactivityTimer */ + {nsm_kill_nbr, NSM_Deleted}, /* LLDown */ + }, + { + /* Loading: */ + {NULL, NSM_DependUpon}, /* NoEvent */ + {nsm_packet_received, NSM_Loading}, /* PacketReceived */ + {NULL, NSM_Loading}, /* Start */ + {NULL, NSM_Loading}, /* 2-WayReceived */ + {NULL, NSM_Loading}, /* NegotiationDone */ + {NULL, NSM_Loading}, /* ExchangeDone */ + {NULL, NSM_ExStart}, /* BadLSReq */ + {NULL, NSM_Full}, /* LoadingDone */ + {nsm_adj_ok, NSM_DependUpon}, /* AdjOK? */ + {NULL, NSM_ExStart}, /* SeqNumberMismatch */ + {NULL, NSM_Init}, /* 1-WayReceived */ + {nsm_kill_nbr, NSM_Deleted}, /* KillNbr */ + {nsm_kill_nbr, NSM_Deleted}, /* InactivityTimer */ + {nsm_kill_nbr, NSM_Deleted}, /* LLDown */ + }, + { + /* Full: */ + {NULL, NSM_DependUpon}, /* NoEvent */ + {nsm_packet_received, NSM_Full}, /* PacketReceived */ + {NULL, NSM_Full}, /* Start */ + {NULL, NSM_Full}, /* 2-WayReceived */ + {NULL, NSM_Full}, /* NegotiationDone */ + {NULL, NSM_Full}, /* ExchangeDone */ + {NULL, NSM_ExStart}, /* BadLSReq */ + {NULL, NSM_Full}, /* LoadingDone */ + {nsm_adj_ok, NSM_DependUpon}, /* AdjOK? */ + {NULL, NSM_ExStart}, /* SeqNumberMismatch */ + {NULL, NSM_Init}, /* 1-WayReceived */ + {nsm_kill_nbr, NSM_Deleted}, /* KillNbr */ + {nsm_kill_nbr, NSM_Deleted}, /* InactivityTimer */ + {nsm_kill_nbr, NSM_Deleted}, /* LLDown */ + }, }; -static const char *ospf_nsm_event_str[] = -{ - "NoEvent", - "PacketReceived", - "Start", - "2-WayReceived", - "NegotiationDone", - "ExchangeDone", - "BadLSReq", - "LoadingDone", - "AdjOK?", - "SeqNumberMismatch", - "1-WayReceived", - "KillNbr", - "InactivityTimer", - "LLDown", +static const char *ospf_nsm_event_str[] = { + "NoEvent", "PacketReceived", "Start", + "2-WayReceived", "NegotiationDone", "ExchangeDone", + "BadLSReq", "LoadingDone", "AdjOK?", + "SeqNumberMismatch", "1-WayReceived", "KillNbr", + "InactivityTimer", "LLDown", }; -static void -nsm_notice_state_change (struct ospf_neighbor *nbr, int next_state, int event) +static void nsm_notice_state_change(struct ospf_neighbor *nbr, int next_state, + int event) { - /* Logging change of status. */ - if (IS_DEBUG_OSPF (nsm, NSM_STATUS)) - zlog_debug ("NSM[%s:%s]: State change %s -> %s (%s)", - IF_NAME (nbr->oi), inet_ntoa (nbr->router_id), - lookup_msg(ospf_nsm_state_msg, nbr->state, NULL), - lookup_msg(ospf_nsm_state_msg, next_state, NULL), - ospf_nsm_event_str [event]); - - /* Optionally notify about adjacency changes */ - if (CHECK_FLAG(nbr->oi->ospf->config, OSPF_LOG_ADJACENCY_CHANGES) && - (CHECK_FLAG(nbr->oi->ospf->config, OSPF_LOG_ADJACENCY_DETAIL) || - (next_state == NSM_Full) || (next_state < nbr->state))) - zlog_notice("AdjChg: Nbr %s on %s: %s -> %s (%s)", - inet_ntoa (nbr->router_id), IF_NAME (nbr->oi), - lookup_msg(ospf_nsm_state_msg, nbr->state, NULL), - lookup_msg(ospf_nsm_state_msg, next_state, NULL), - ospf_nsm_event_str [event]); - - /* Advance in NSM */ - if (next_state > nbr->state) - monotime(&nbr->ts_last_progress); - else /* regression in NSM */ - { - monotime(&nbr->ts_last_regress); - nbr->last_regress_str = ospf_nsm_event_str [event]; - } - + /* Logging change of status. */ + if (IS_DEBUG_OSPF(nsm, NSM_STATUS)) + zlog_debug("NSM[%s:%s]: State change %s -> %s (%s)", + IF_NAME(nbr->oi), inet_ntoa(nbr->router_id), + lookup_msg(ospf_nsm_state_msg, nbr->state, NULL), + lookup_msg(ospf_nsm_state_msg, next_state, NULL), + ospf_nsm_event_str[event]); + + /* Optionally notify about adjacency changes */ + if (CHECK_FLAG(nbr->oi->ospf->config, OSPF_LOG_ADJACENCY_CHANGES) + && (CHECK_FLAG(nbr->oi->ospf->config, OSPF_LOG_ADJACENCY_DETAIL) + || (next_state == NSM_Full) || (next_state < nbr->state))) + zlog_notice("AdjChg: Nbr %s on %s: %s -> %s (%s)", + inet_ntoa(nbr->router_id), IF_NAME(nbr->oi), + lookup_msg(ospf_nsm_state_msg, nbr->state, NULL), + lookup_msg(ospf_nsm_state_msg, next_state, NULL), + ospf_nsm_event_str[event]); + + /* Advance in NSM */ + if (next_state > nbr->state) + monotime(&nbr->ts_last_progress); + else /* regression in NSM */ + { + monotime(&nbr->ts_last_regress); + nbr->last_regress_str = ospf_nsm_event_str[event]; + } } -static void -nsm_change_state (struct ospf_neighbor *nbr, int state) +static void nsm_change_state(struct ospf_neighbor *nbr, int state) { - struct ospf_interface *oi = nbr->oi; - struct ospf_area *vl_area = NULL; - u_char old_state; - int x; - int force = 1; - - /* Preserve old status. */ - old_state = nbr->state; - - /* Change to new status. */ - nbr->state = state; - - /* Statistics. */ - nbr->state_change++; - - if (oi->type == OSPF_IFTYPE_VIRTUALLINK) - vl_area = ospf_area_lookup_by_area_id (oi->ospf, oi->vl_data->vl_area_id); - - /* Generate NeighborChange ISM event. - * - * In response to NeighborChange, DR election is rerun. The information - * from the election process is required by the router-lsa construction. - * - * Therefore, trigger the event prior to refreshing the LSAs. */ - switch (oi->state) { - case ISM_DROther: - case ISM_Backup: - case ISM_DR: - if ((old_state < NSM_TwoWay && state >= NSM_TwoWay) || - (old_state >= NSM_TwoWay && state < NSM_TwoWay)) - OSPF_ISM_EVENT_EXECUTE (oi, ISM_NeighborChange); - break; - default: - /* ISM_PointToPoint -> ISM_Down, ISM_Loopback -> ISM_Down, etc. */ - break; - } - - /* One of the neighboring routers changes to/from the FULL state. */ - if ((old_state != NSM_Full && state == NSM_Full) || - (old_state == NSM_Full && state != NSM_Full)) - { - if (state == NSM_Full) - { - oi->full_nbrs++; - oi->area->full_nbrs++; - - ospf_check_abr_status (oi->ospf); - - if (oi->type == OSPF_IFTYPE_VIRTUALLINK && vl_area) - if (++vl_area->full_vls == 1) - ospf_schedule_abr_task (oi->ospf); - - /* kevinm: refresh any redistributions */ - for (x = ZEBRA_ROUTE_SYSTEM; x < ZEBRA_ROUTE_MAX; x++) - { - struct list *red_list; - struct listnode *node; - struct ospf_redist *red; - - if (x == ZEBRA_ROUTE_OSPF6) - continue; - - red_list = oi->ospf->redist[x]; - if (!red_list) - continue; - - for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) - ospf_external_lsa_refresh_type (oi->ospf, x, red->instance, force); - } - /* XXX: Clearly some thing is wrong with refresh of external LSAs - * this added to hack around defaults not refreshing after a timer - * jump. - */ - ospf_external_lsa_refresh_default (oi->ospf); + struct ospf_interface *oi = nbr->oi; + struct ospf_area *vl_area = NULL; + u_char old_state; + int x; + int force = 1; + + /* Preserve old status. */ + old_state = nbr->state; + + /* Change to new status. */ + nbr->state = state; + + /* Statistics. */ + nbr->state_change++; + + if (oi->type == OSPF_IFTYPE_VIRTUALLINK) + vl_area = ospf_area_lookup_by_area_id(oi->ospf, + oi->vl_data->vl_area_id); + + /* Generate NeighborChange ISM event. + * + * In response to NeighborChange, DR election is rerun. The information + * from the election process is required by the router-lsa construction. + * + * Therefore, trigger the event prior to refreshing the LSAs. */ + switch (oi->state) { + case ISM_DROther: + case ISM_Backup: + case ISM_DR: + if ((old_state < NSM_TwoWay && state >= NSM_TwoWay) + || (old_state >= NSM_TwoWay && state < NSM_TwoWay)) + OSPF_ISM_EVENT_EXECUTE(oi, ISM_NeighborChange); + break; + default: + /* ISM_PointToPoint -> ISM_Down, ISM_Loopback -> ISM_Down, etc. + */ + break; } - else - { - oi->full_nbrs--; - oi->area->full_nbrs--; - ospf_check_abr_status (oi->ospf); + /* One of the neighboring routers changes to/from the FULL state. */ + if ((old_state != NSM_Full && state == NSM_Full) + || (old_state == NSM_Full && state != NSM_Full)) { + if (state == NSM_Full) { + oi->full_nbrs++; + oi->area->full_nbrs++; + + ospf_check_abr_status(oi->ospf); + + if (oi->type == OSPF_IFTYPE_VIRTUALLINK && vl_area) + if (++vl_area->full_vls == 1) + ospf_schedule_abr_task(oi->ospf); + + /* kevinm: refresh any redistributions */ + for (x = ZEBRA_ROUTE_SYSTEM; x < ZEBRA_ROUTE_MAX; x++) { + struct list *red_list; + struct listnode *node; + struct ospf_redist *red; + + if (x == ZEBRA_ROUTE_OSPF6) + continue; + + red_list = oi->ospf->redist[x]; + if (!red_list) + continue; + + for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) + ospf_external_lsa_refresh_type( + oi->ospf, x, red->instance, + force); + } + /* XXX: Clearly some thing is wrong with refresh of + * external LSAs + * this added to hack around defaults not refreshing + * after a timer + * jump. + */ + ospf_external_lsa_refresh_default(oi->ospf); + } else { + oi->full_nbrs--; + oi->area->full_nbrs--; + + ospf_check_abr_status(oi->ospf); + + if (oi->type == OSPF_IFTYPE_VIRTUALLINK && vl_area) + if (vl_area->full_vls > 0) + if (--vl_area->full_vls == 0) + ospf_schedule_abr_task( + oi->ospf); + } + + zlog_info( + "nsm_change_state(%s, %s -> %s): " + "scheduling new router-LSA origination", + inet_ntoa(nbr->router_id), + lookup_msg(ospf_nsm_state_msg, old_state, NULL), + lookup_msg(ospf_nsm_state_msg, state, NULL)); + + ospf_router_lsa_update_area(oi->area); + + if (oi->type == OSPF_IFTYPE_VIRTUALLINK) { + struct ospf_area *vl_area = ospf_area_lookup_by_area_id( + oi->ospf, oi->vl_data->vl_area_id); + + if (vl_area) + ospf_router_lsa_update_area(vl_area); + } + + /* Originate network-LSA. */ + if (oi->state == ISM_DR) { + if (oi->network_lsa_self && oi->full_nbrs == 0) { + ospf_lsa_flush_area(oi->network_lsa_self, + oi->area); + ospf_lsa_unlock(&oi->network_lsa_self); + oi->network_lsa_self = NULL; + } else + ospf_network_lsa_update(oi); + } + } - if (oi->type == OSPF_IFTYPE_VIRTUALLINK && vl_area) - if (vl_area->full_vls > 0) - if (--vl_area->full_vls == 0) - ospf_schedule_abr_task (oi->ospf); + ospf_opaque_nsm_change(nbr, old_state); + + /* State changes from > ExStart to <= ExStart should clear any Exchange + * or Full/LSA Update related lists and state. + * Potential causal events: BadLSReq, SeqNumberMismatch, AdjOK? + */ + if ((old_state > NSM_ExStart) && (state <= NSM_ExStart)) + nsm_clear_adj(nbr); + + /* Start DD exchange protocol */ + if (state == NSM_ExStart) { + if (nbr->dd_seqnum == 0) + nbr->dd_seqnum = (uint32_t)random(); + else + nbr->dd_seqnum++; + + nbr->dd_flags = + OSPF_DD_FLAG_I | OSPF_DD_FLAG_M | OSPF_DD_FLAG_MS; + ospf_db_desc_send(nbr); } - zlog_info ("nsm_change_state(%s, %s -> %s): " - "scheduling new router-LSA origination", - inet_ntoa (nbr->router_id), - lookup_msg(ospf_nsm_state_msg, old_state, NULL), - lookup_msg(ospf_nsm_state_msg, state, NULL)); + /* clear cryptographic sequence number */ + if (state == NSM_Down) + nbr->crypt_seqnum = 0; - ospf_router_lsa_update_area (oi->area); + ospf_bfd_trigger_event(nbr, old_state, state); - if (oi->type == OSPF_IFTYPE_VIRTUALLINK) - { - struct ospf_area *vl_area = - ospf_area_lookup_by_area_id (oi->ospf, oi->vl_data->vl_area_id); - - if (vl_area) - ospf_router_lsa_update_area (vl_area); - } - - /* Originate network-LSA. */ - if (oi->state == ISM_DR) - { - if (oi->network_lsa_self && oi->full_nbrs == 0) - { - ospf_lsa_flush_area (oi->network_lsa_self, oi->area); - ospf_lsa_unlock (&oi->network_lsa_self); - oi->network_lsa_self = NULL; - } - else - ospf_network_lsa_update (oi); - } - } - - ospf_opaque_nsm_change (nbr, old_state); - - /* State changes from > ExStart to <= ExStart should clear any Exchange - * or Full/LSA Update related lists and state. - * Potential causal events: BadLSReq, SeqNumberMismatch, AdjOK? - */ - if ((old_state > NSM_ExStart) && (state <= NSM_ExStart)) - nsm_clear_adj (nbr); - - /* Start DD exchange protocol */ - if (state == NSM_ExStart) - { - if (nbr->dd_seqnum == 0) - nbr->dd_seqnum = (uint32_t)random (); - else - nbr->dd_seqnum++; - - nbr->dd_flags = OSPF_DD_FLAG_I|OSPF_DD_FLAG_M|OSPF_DD_FLAG_MS; - ospf_db_desc_send (nbr); - } - - /* clear cryptographic sequence number */ - if (state == NSM_Down) - nbr->crypt_seqnum = 0; - - ospf_bfd_trigger_event(nbr, old_state, state); - - /* Preserve old status? */ + /* Preserve old status? */ } /* Execute NSM event process. */ -int -ospf_nsm_event (struct thread *thread) +int ospf_nsm_event(struct thread *thread) { - int event; - int next_state; - struct ospf_neighbor *nbr; - - nbr = THREAD_ARG (thread); - event = THREAD_VAL (thread); - - if (IS_DEBUG_OSPF (nsm, NSM_EVENTS)) - zlog_debug ("NSM[%s:%s]: %s (%s)", IF_NAME (nbr->oi), - inet_ntoa (nbr->router_id), - lookup_msg(ospf_nsm_state_msg, nbr->state, NULL), - ospf_nsm_event_str [event]); - - next_state = NSM [nbr->state][event].next_state; - - /* Call function. */ - if (NSM [nbr->state][event].func != NULL) - { - int func_state = (*(NSM [nbr->state][event].func))(nbr); - - if (NSM [nbr->state][event].next_state == NSM_DependUpon) - next_state = func_state; - else if (func_state) - { - /* There's a mismatch between the FSM tables and what an FSM - * action/state-change function returned. State changes which - * do not have conditional/DependUpon next-states should not - * try set next_state. - */ - zlog_warn ("NSM[%s:%s]: %s (%s): " - "Warning: action tried to change next_state to %s", - IF_NAME (nbr->oi), inet_ntoa (nbr->router_id), - lookup_msg(ospf_nsm_state_msg, nbr->state, NULL), - ospf_nsm_event_str [event], - lookup_msg(ospf_nsm_state_msg, func_state, NULL)); - } - } - - assert (next_state != NSM_DependUpon); - - /* If state is changed. */ - if (next_state != nbr->state) - { - int old_state = nbr->state; - - nsm_notice_state_change (nbr, next_state, event); - nsm_change_state (nbr, next_state); - - hook_call(ospf_nsm_change, nbr, next_state, old_state); - } - - /* Make sure timer is set. */ - nsm_timer_set (nbr); - - /* When event is NSM_KillNbr, InactivityTimer or LLDown, the neighbor - * is deleted. - * - * Rather than encode knowledge here of which events lead to NBR - * delete, we take our cue from the NSM table, via the dummy - * 'Deleted' neighbour state. - */ - if (nbr->state == NSM_Deleted) - ospf_nbr_delete (nbr); - - return 0; + int event; + int next_state; + struct ospf_neighbor *nbr; + + nbr = THREAD_ARG(thread); + event = THREAD_VAL(thread); + + if (IS_DEBUG_OSPF(nsm, NSM_EVENTS)) + zlog_debug("NSM[%s:%s]: %s (%s)", IF_NAME(nbr->oi), + inet_ntoa(nbr->router_id), + lookup_msg(ospf_nsm_state_msg, nbr->state, NULL), + ospf_nsm_event_str[event]); + + next_state = NSM[nbr->state][event].next_state; + + /* Call function. */ + if (NSM[nbr->state][event].func != NULL) { + int func_state = (*(NSM[nbr->state][event].func))(nbr); + + if (NSM[nbr->state][event].next_state == NSM_DependUpon) + next_state = func_state; + else if (func_state) { + /* There's a mismatch between the FSM tables and what an + * FSM + * action/state-change function returned. State changes + * which + * do not have conditional/DependUpon next-states should + * not + * try set next_state. + */ + zlog_warn( + "NSM[%s:%s]: %s (%s): " + "Warning: action tried to change next_state to %s", + IF_NAME(nbr->oi), inet_ntoa(nbr->router_id), + lookup_msg(ospf_nsm_state_msg, nbr->state, + NULL), + ospf_nsm_event_str[event], + lookup_msg(ospf_nsm_state_msg, func_state, + NULL)); + } + } + + assert(next_state != NSM_DependUpon); + + /* If state is changed. */ + if (next_state != nbr->state) { + int old_state = nbr->state; + + nsm_notice_state_change(nbr, next_state, event); + nsm_change_state(nbr, next_state); + + hook_call(ospf_nsm_change, nbr, next_state, old_state); + } + + /* Make sure timer is set. */ + nsm_timer_set(nbr); + + /* When event is NSM_KillNbr, InactivityTimer or LLDown, the neighbor + * is deleted. + * + * Rather than encode knowledge here of which events lead to NBR + * delete, we take our cue from the NSM table, via the dummy + * 'Deleted' neighbour state. + */ + if (nbr->state == NSM_Deleted) + ospf_nbr_delete(nbr); + + return 0; } /* Check loading state. */ -void -ospf_check_nbr_loading (struct ospf_neighbor *nbr) +void ospf_check_nbr_loading(struct ospf_neighbor *nbr) { - if (nbr->state == NSM_Loading) - { - if (ospf_ls_request_isempty (nbr)) - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_LoadingDone); - else if (nbr->ls_req_last == NULL) - ospf_ls_req_event (nbr); - } + if (nbr->state == NSM_Loading) { + if (ospf_ls_request_isempty(nbr)) + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_LoadingDone); + else if (nbr->ls_req_last == NULL) + ospf_ls_req_event(nbr); + } } diff --git a/ospfd/ospf_nsm.h b/ospfd/ospf_nsm.h index 4f363b4e6..dcfba84d8 100644 --- a/ospfd/ospf_nsm.h +++ b/ospfd/ospf_nsm.h @@ -59,33 +59,31 @@ #define OSPF_NSM_TIMER_ON(T,F,V) thread_add_timer (master, (F), nbr, (V), &(T)) /* Macro for OSPF NSM timer turn off. */ -#define OSPF_NSM_TIMER_OFF(X) \ - do { \ - if (X) \ - { \ - thread_cancel (X); \ - (X) = NULL; \ - } \ - } while (0) +#define OSPF_NSM_TIMER_OFF(X) \ + do { \ + if (X) { \ + thread_cancel(X); \ + (X) = NULL; \ + } \ + } while (0) /* Macro for OSPF NSM schedule event. */ -#define OSPF_NSM_EVENT_SCHEDULE(N,E) \ - thread_add_event (master, ospf_nsm_event, (N), (E), NULL) +#define OSPF_NSM_EVENT_SCHEDULE(N, E) \ + thread_add_event(master, ospf_nsm_event, (N), (E), NULL) /* Macro for OSPF NSM execute event. */ -#define OSPF_NSM_EVENT_EXECUTE(N,E) \ - thread_execute (master, ospf_nsm_event, (N), (E)) +#define OSPF_NSM_EVENT_EXECUTE(N, E) \ + thread_execute(master, ospf_nsm_event, (N), (E)) /* Prototypes. */ -extern int ospf_nsm_event (struct thread *); -extern void ospf_check_nbr_loading (struct ospf_neighbor *); -extern int ospf_db_summary_isempty (struct ospf_neighbor *); -extern int ospf_db_summary_count (struct ospf_neighbor *); -extern void ospf_db_summary_clear (struct ospf_neighbor *); +extern int ospf_nsm_event(struct thread *); +extern void ospf_check_nbr_loading(struct ospf_neighbor *); +extern int ospf_db_summary_isempty(struct ospf_neighbor *); +extern int ospf_db_summary_count(struct ospf_neighbor *); +extern void ospf_db_summary_clear(struct ospf_neighbor *); DECLARE_HOOK(ospf_nsm_change, - (struct ospf_neighbor *on, int state, int oldstate), - (on, state, oldstate)) + (struct ospf_neighbor * on, int state, int oldstate), + (on, state, oldstate)) #endif /* _ZEBRA_OSPF_NSM_H */ - diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c index f3db6afd1..a2c40923b 100644 --- a/ospfd/ospf_opaque.c +++ b/ospfd/ospf_opaque.c @@ -33,7 +33,7 @@ #include "log.h" #include "thread.h" #include "hash.h" -#include "sockunion.h" /* for inet_aton() */ +#include "sockunion.h" /* for inet_aton() */ #include "ospfd/ospfd.h" #include "ospfd/ospf_interface.h" @@ -51,9 +51,9 @@ #include "ospfd/ospf_ase.h" #include "ospfd/ospf_zebra.h" -DEFINE_MTYPE_STATIC(OSPFD, OSPF_OPAQUE_FUNCTAB, "OSPF opaque function table") +DEFINE_MTYPE_STATIC(OSPFD, OSPF_OPAQUE_FUNCTAB, "OSPF opaque function table") DEFINE_MTYPE_STATIC(OSPFD, OPAQUE_INFO_PER_TYPE, "OSPF opaque per-type info") -DEFINE_MTYPE_STATIC(OSPFD, OPAQUE_INFO_PER_ID, "OSPF opaque per-ID info") +DEFINE_MTYPE_STATIC(OSPFD, OPAQUE_INFO_PER_ID, "OSPF opaque per-ID info") /*------------------------------------------------------------------------* * Followings are initialize/terminate functions for Opaque-LSAs handling. @@ -63,181 +63,169 @@ DEFINE_MTYPE_STATIC(OSPFD, OPAQUE_INFO_PER_ID, "OSPF opaque per-ID info") #include "ospfd/ospf_ri.h" #ifdef SUPPORT_OSPF_API -int ospf_apiserver_init (void); -void ospf_apiserver_term (void); +int ospf_apiserver_init(void); +void ospf_apiserver_term(void); /* Init apiserver? It's disabled by default. */ int ospf_apiserver_enable; #endif /* SUPPORT_OSPF_API */ -static void ospf_opaque_register_vty (void); -static void ospf_opaque_funclist_init (void); -static void ospf_opaque_funclist_term (void); -static void free_opaque_info_per_type (void *val); -static void free_opaque_info_per_id (void *val); -static int ospf_opaque_lsa_install_hook (struct ospf_lsa *lsa); -static int ospf_opaque_lsa_delete_hook (struct ospf_lsa *lsa); +static void ospf_opaque_register_vty(void); +static void ospf_opaque_funclist_init(void); +static void ospf_opaque_funclist_term(void); +static void free_opaque_info_per_type(void *val); +static void free_opaque_info_per_id(void *val); +static int ospf_opaque_lsa_install_hook(struct ospf_lsa *lsa); +static int ospf_opaque_lsa_delete_hook(struct ospf_lsa *lsa); -void -ospf_opaque_init (void) +void ospf_opaque_init(void) { - ospf_opaque_register_vty (); - ospf_opaque_funclist_init (); + ospf_opaque_register_vty(); + ospf_opaque_funclist_init(); - if (ospf_mpls_te_init () != 0) - exit (1); + if (ospf_mpls_te_init() != 0) + exit(1); - if (ospf_router_info_init () != 0) - exit (1); + if (ospf_router_info_init() != 0) + exit(1); #ifdef SUPPORT_OSPF_API - if ((ospf_apiserver_enable) && (ospf_apiserver_init () != 0)) - exit (1); + if ((ospf_apiserver_enable) && (ospf_apiserver_init() != 0)) + exit(1); #endif /* SUPPORT_OSPF_API */ - return; + return; } -void -ospf_opaque_term (void) +void ospf_opaque_term(void) { - ospf_mpls_te_term (); + ospf_mpls_te_term(); - ospf_router_info_term (); + ospf_router_info_term(); #ifdef SUPPORT_OSPF_API - ospf_apiserver_term (); + ospf_apiserver_term(); #endif /* SUPPORT_OSPF_API */ - ospf_opaque_funclist_term (); - return; + ospf_opaque_funclist_term(); + return; } -int -ospf_opaque_type9_lsa_init (struct ospf_interface *oi) +int ospf_opaque_type9_lsa_init(struct ospf_interface *oi) { - if (oi->opaque_lsa_self != NULL) - list_delete (oi->opaque_lsa_self); + if (oi->opaque_lsa_self != NULL) + list_delete(oi->opaque_lsa_self); - oi->opaque_lsa_self = list_new (); - oi->opaque_lsa_self->del = free_opaque_info_per_type; - oi->t_opaque_lsa_self = NULL; - return 0; + oi->opaque_lsa_self = list_new(); + oi->opaque_lsa_self->del = free_opaque_info_per_type; + oi->t_opaque_lsa_self = NULL; + return 0; } -void -ospf_opaque_type9_lsa_term (struct ospf_interface *oi) +void ospf_opaque_type9_lsa_term(struct ospf_interface *oi) { - OSPF_TIMER_OFF (oi->t_opaque_lsa_self); - if (oi->opaque_lsa_self != NULL) - list_delete (oi->opaque_lsa_self); - oi->opaque_lsa_self = NULL; - return; + OSPF_TIMER_OFF(oi->t_opaque_lsa_self); + if (oi->opaque_lsa_self != NULL) + list_delete(oi->opaque_lsa_self); + oi->opaque_lsa_self = NULL; + return; } -int -ospf_opaque_type10_lsa_init (struct ospf_area *area) +int ospf_opaque_type10_lsa_init(struct ospf_area *area) { - if (area->opaque_lsa_self != NULL) - list_delete (area->opaque_lsa_self); + if (area->opaque_lsa_self != NULL) + list_delete(area->opaque_lsa_self); - area->opaque_lsa_self = list_new (); - area->opaque_lsa_self->del = free_opaque_info_per_type; - area->t_opaque_lsa_self = NULL; + area->opaque_lsa_self = list_new(); + area->opaque_lsa_self->del = free_opaque_info_per_type; + area->t_opaque_lsa_self = NULL; #ifdef MONITOR_LSDB_CHANGE - area->lsdb->new_lsa_hook = ospf_opaque_lsa_install_hook; - area->lsdb->del_lsa_hook = ospf_opaque_lsa_delete_hook; + area->lsdb->new_lsa_hook = ospf_opaque_lsa_install_hook; + area->lsdb->del_lsa_hook = ospf_opaque_lsa_delete_hook; #endif /* MONITOR_LSDB_CHANGE */ - return 0; + return 0; } -void -ospf_opaque_type10_lsa_term (struct ospf_area *area) +void ospf_opaque_type10_lsa_term(struct ospf_area *area) { #ifdef MONITOR_LSDB_CHANGE - area->lsdb->new_lsa_hook = - area->lsdb->del_lsa_hook = NULL; + area->lsdb->new_lsa_hook = area->lsdb->del_lsa_hook = NULL; #endif /* MONITOR_LSDB_CHANGE */ - OSPF_TIMER_OFF (area->t_opaque_lsa_self); - if (area->opaque_lsa_self != NULL) - list_delete (area->opaque_lsa_self); - area->opaque_lsa_self = NULL; - return; + OSPF_TIMER_OFF(area->t_opaque_lsa_self); + if (area->opaque_lsa_self != NULL) + list_delete(area->opaque_lsa_self); + area->opaque_lsa_self = NULL; + return; } -int -ospf_opaque_type11_lsa_init (struct ospf *top) +int ospf_opaque_type11_lsa_init(struct ospf *top) { - if (top->opaque_lsa_self != NULL) - list_delete (top->opaque_lsa_self); + if (top->opaque_lsa_self != NULL) + list_delete(top->opaque_lsa_self); - top->opaque_lsa_self = list_new (); - top->opaque_lsa_self->del = free_opaque_info_per_type; - top->t_opaque_lsa_self = NULL; + top->opaque_lsa_self = list_new(); + top->opaque_lsa_self->del = free_opaque_info_per_type; + top->t_opaque_lsa_self = NULL; #ifdef MONITOR_LSDB_CHANGE - top->lsdb->new_lsa_hook = ospf_opaque_lsa_install_hook; - top->lsdb->del_lsa_hook = ospf_opaque_lsa_delete_hook; + top->lsdb->new_lsa_hook = ospf_opaque_lsa_install_hook; + top->lsdb->del_lsa_hook = ospf_opaque_lsa_delete_hook; #endif /* MONITOR_LSDB_CHANGE */ - return 0; + return 0; } -void -ospf_opaque_type11_lsa_term (struct ospf *top) +void ospf_opaque_type11_lsa_term(struct ospf *top) { #ifdef MONITOR_LSDB_CHANGE - top->lsdb->new_lsa_hook = - top->lsdb->del_lsa_hook = NULL; + top->lsdb->new_lsa_hook = top->lsdb->del_lsa_hook = NULL; #endif /* MONITOR_LSDB_CHANGE */ - OSPF_TIMER_OFF (top->t_opaque_lsa_self); - if (top->opaque_lsa_self != NULL) - list_delete (top->opaque_lsa_self); - top->opaque_lsa_self = NULL; - return; -} - -static const char * -ospf_opaque_type_name (u_char opaque_type) -{ - const char *name = "Unknown"; - - switch (opaque_type) - { - case OPAQUE_TYPE_WILDCARD: /* This is a special assignment! */ - name = "Wildcard"; - break; - case OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA: - name = "Traffic Engineering LSA"; - break; - case OPAQUE_TYPE_SYCAMORE_OPTICAL_TOPOLOGY_DESC: - name = "Sycamore optical topology description"; - break; - case OPAQUE_TYPE_GRACE_LSA: - name = "Grace-LSA"; - break; - case OPAQUE_TYPE_INTER_AS_LSA: - name = "Inter-AS TE-v2 LSA"; - break; - case OPAQUE_TYPE_ROUTER_INFORMATION_LSA: - name = "Router Information LSA"; - break; - default: - if (OPAQUE_TYPE_RANGE_UNASSIGNED (opaque_type)) - name = "Unassigned"; - else - { - u_int32_t bigger_range = opaque_type; - /* - * Get around type-limits warning: comparison is always true due to limited range of data type - */ - if (OPAQUE_TYPE_RANGE_RESERVED (bigger_range)) - name = "Private/Experimental"; - } - break; - } - return name; + OSPF_TIMER_OFF(top->t_opaque_lsa_self); + if (top->opaque_lsa_self != NULL) + list_delete(top->opaque_lsa_self); + top->opaque_lsa_self = NULL; + return; +} + +static const char *ospf_opaque_type_name(u_char opaque_type) +{ + const char *name = "Unknown"; + + switch (opaque_type) { + case OPAQUE_TYPE_WILDCARD: /* This is a special assignment! */ + name = "Wildcard"; + break; + case OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA: + name = "Traffic Engineering LSA"; + break; + case OPAQUE_TYPE_SYCAMORE_OPTICAL_TOPOLOGY_DESC: + name = "Sycamore optical topology description"; + break; + case OPAQUE_TYPE_GRACE_LSA: + name = "Grace-LSA"; + break; + case OPAQUE_TYPE_INTER_AS_LSA: + name = "Inter-AS TE-v2 LSA"; + break; + case OPAQUE_TYPE_ROUTER_INFORMATION_LSA: + name = "Router Information LSA"; + break; + default: + if (OPAQUE_TYPE_RANGE_UNASSIGNED(opaque_type)) + name = "Unassigned"; + else { + u_int32_t bigger_range = opaque_type; + /* + * Get around type-limits warning: comparison is always + * true due to limited range of data type + */ + if (OPAQUE_TYPE_RANGE_RESERVED(bigger_range)) + name = "Private/Experimental"; + } + break; + } + return name; } /*------------------------------------------------------------------------* @@ -246,23 +234,22 @@ ospf_opaque_type_name (u_char opaque_type) struct opaque_info_per_type; /* Forward declaration. */ -struct ospf_opaque_functab -{ - u_char opaque_type; - struct opaque_info_per_type *oipt; - - int (* new_if_hook)(struct interface *ifp); - int (* del_if_hook)(struct interface *ifp); - void (* ism_change_hook)(struct ospf_interface *oi, int old_status); - void (* nsm_change_hook)(struct ospf_neighbor *nbr, int old_status); - void (* config_write_router)(struct vty *vty); - void (* config_write_if )(struct vty *vty, struct interface *ifp); - void (* config_write_debug )(struct vty *vty); - void (* show_opaque_info )(struct vty *vty, struct ospf_lsa *lsa); - int (* lsa_originator)(void *arg); - struct ospf_lsa *(* lsa_refresher )(struct ospf_lsa *lsa); - int (* new_lsa_hook)(struct ospf_lsa *lsa); - int (* del_lsa_hook)(struct ospf_lsa *lsa); +struct ospf_opaque_functab { + u_char opaque_type; + struct opaque_info_per_type *oipt; + + int (*new_if_hook)(struct interface *ifp); + int (*del_if_hook)(struct interface *ifp); + void (*ism_change_hook)(struct ospf_interface *oi, int old_status); + void (*nsm_change_hook)(struct ospf_neighbor *nbr, int old_status); + void (*config_write_router)(struct vty *vty); + void (*config_write_if)(struct vty *vty, struct interface *ifp); + void (*config_write_debug)(struct vty *vty); + void (*show_opaque_info)(struct vty *vty, struct ospf_lsa *lsa); + int (*lsa_originator)(void *arg); + struct ospf_lsa *(*lsa_refresher)(struct ospf_lsa *lsa); + int (*new_lsa_hook)(struct ospf_lsa *lsa); + int (*del_lsa_hook)(struct ospf_lsa *lsa); }; /* Handle LSA-9/10/11 altogether. */ @@ -271,203 +258,195 @@ static struct list *ospf_opaque_type9_funclist; static struct list *ospf_opaque_type10_funclist; static struct list *ospf_opaque_type11_funclist; -static void -ospf_opaque_del_functab (void *val) +static void ospf_opaque_del_functab(void *val) { - XFREE (MTYPE_OSPF_OPAQUE_FUNCTAB, val); - return; + XFREE(MTYPE_OSPF_OPAQUE_FUNCTAB, val); + return; } -static void -ospf_opaque_funclist_init (void) +static void ospf_opaque_funclist_init(void) { - struct list *funclist; + struct list *funclist; - funclist = ospf_opaque_wildcard_funclist = list_new (); - funclist->del = ospf_opaque_del_functab; + funclist = ospf_opaque_wildcard_funclist = list_new(); + funclist->del = ospf_opaque_del_functab; - funclist = ospf_opaque_type9_funclist = list_new (); - funclist->del = ospf_opaque_del_functab; + funclist = ospf_opaque_type9_funclist = list_new(); + funclist->del = ospf_opaque_del_functab; - funclist = ospf_opaque_type10_funclist = list_new (); - funclist->del = ospf_opaque_del_functab; + funclist = ospf_opaque_type10_funclist = list_new(); + funclist->del = ospf_opaque_del_functab; - funclist = ospf_opaque_type11_funclist = list_new (); - funclist->del = ospf_opaque_del_functab; - return; + funclist = ospf_opaque_type11_funclist = list_new(); + funclist->del = ospf_opaque_del_functab; + return; } -static void -ospf_opaque_funclist_term (void) +static void ospf_opaque_funclist_term(void) { - struct list *funclist; + struct list *funclist; - funclist = ospf_opaque_wildcard_funclist; - list_delete (funclist); + funclist = ospf_opaque_wildcard_funclist; + list_delete(funclist); - funclist = ospf_opaque_type9_funclist; - list_delete (funclist); + funclist = ospf_opaque_type9_funclist; + list_delete(funclist); - funclist = ospf_opaque_type10_funclist; - list_delete (funclist); + funclist = ospf_opaque_type10_funclist; + list_delete(funclist); - funclist = ospf_opaque_type11_funclist; - list_delete (funclist); - return; + funclist = ospf_opaque_type11_funclist; + list_delete(funclist); + return; } -static struct list * -ospf_get_opaque_funclist (u_char lsa_type) +static struct list *ospf_get_opaque_funclist(u_char lsa_type) { - struct list *funclist = NULL; + struct list *funclist = NULL; - switch (lsa_type) - { - case OPAQUE_TYPE_WILDCARD: - /* XXX - * This is an ugly trick to handle type-9/10/11 LSA altogether. - * Yes, "OPAQUE_TYPE_WILDCARD (value 0)" is not an LSA-type, nor - * an officially assigned opaque-type. - * Though it is possible that the value might be officially used - * in the future, we use it internally as a special label, for now. - */ - funclist = ospf_opaque_wildcard_funclist; - break; - case OSPF_OPAQUE_LINK_LSA: - funclist = ospf_opaque_type9_funclist; - break; - case OSPF_OPAQUE_AREA_LSA: - funclist = ospf_opaque_type10_funclist; - break; - case OSPF_OPAQUE_AS_LSA: - funclist = ospf_opaque_type11_funclist; - break; - default: - zlog_warn ("ospf_get_opaque_funclist: Unexpected LSA-type(%u)", lsa_type); - break; - } - return funclist; + switch (lsa_type) { + case OPAQUE_TYPE_WILDCARD: + /* XXX + * This is an ugly trick to handle type-9/10/11 LSA altogether. + * Yes, "OPAQUE_TYPE_WILDCARD (value 0)" is not an LSA-type, nor + * an officially assigned opaque-type. + * Though it is possible that the value might be officially used + * in the future, we use it internally as a special label, for + * now. + */ + funclist = ospf_opaque_wildcard_funclist; + break; + case OSPF_OPAQUE_LINK_LSA: + funclist = ospf_opaque_type9_funclist; + break; + case OSPF_OPAQUE_AREA_LSA: + funclist = ospf_opaque_type10_funclist; + break; + case OSPF_OPAQUE_AS_LSA: + funclist = ospf_opaque_type11_funclist; + break; + default: + zlog_warn("ospf_get_opaque_funclist: Unexpected LSA-type(%u)", + lsa_type); + break; + } + return funclist; } /* XXX: such a huge argument list can /not/ be healthy... */ -int -ospf_register_opaque_functab ( - u_char lsa_type, - u_char opaque_type, - int (* new_if_hook)(struct interface *ifp), - int (* del_if_hook)(struct interface *ifp), - void (* ism_change_hook)(struct ospf_interface *oi, int old_status), - void (* nsm_change_hook)(struct ospf_neighbor *nbr, int old_status), - void (* config_write_router)(struct vty *vty), - void (* config_write_if )(struct vty *vty, struct interface *ifp), - void (* config_write_debug )(struct vty *vty), - void (* show_opaque_info )(struct vty *vty, struct ospf_lsa *lsa), - int (* lsa_originator)(void *arg), - struct ospf_lsa *(* lsa_refresher )(struct ospf_lsa *lsa), - int (* new_lsa_hook)(struct ospf_lsa *lsa), - int (* del_lsa_hook)(struct ospf_lsa *lsa)) -{ - struct list *funclist; - struct ospf_opaque_functab *new; - int rc = -1; - - if ((funclist = ospf_get_opaque_funclist (lsa_type)) == NULL) - { - zlog_warn ("ospf_register_opaque_functab: Cannot get funclist" - " for Type-%u LSAs?", - lsa_type); - goto out; - } - else - { - struct listnode *node, *nnode; - struct ospf_opaque_functab *functab; - - for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab)) - if (functab->opaque_type == opaque_type) - { - zlog_warn ("ospf_register_opaque_functab: Duplicated entry?:" - " lsa_type(%u), opaque_type(%u)", - lsa_type, opaque_type); - goto out; - } - } - - if ((new = XCALLOC (MTYPE_OSPF_OPAQUE_FUNCTAB, - sizeof (struct ospf_opaque_functab))) == NULL) - { - zlog_warn ("ospf_register_opaque_functab: XMALLOC: %s", - safe_strerror (errno)); - goto out; - } - - new->opaque_type = opaque_type; - new->oipt = NULL; - new->new_if_hook = new_if_hook; - new->del_if_hook = del_if_hook; - new->ism_change_hook = ism_change_hook; - new->nsm_change_hook = nsm_change_hook; - new->config_write_router = config_write_router; - new->config_write_if = config_write_if; - new->config_write_debug = config_write_debug; - new->show_opaque_info = show_opaque_info; - new->lsa_originator = lsa_originator; - new->lsa_refresher = lsa_refresher; - new->new_lsa_hook = new_lsa_hook; - new->del_lsa_hook = del_lsa_hook; - - listnode_add (funclist, new); - rc = 0; +int ospf_register_opaque_functab( + u_char lsa_type, u_char opaque_type, + int (*new_if_hook)(struct interface *ifp), + int (*del_if_hook)(struct interface *ifp), + void (*ism_change_hook)(struct ospf_interface *oi, int old_status), + void (*nsm_change_hook)(struct ospf_neighbor *nbr, int old_status), + void (*config_write_router)(struct vty *vty), + void (*config_write_if)(struct vty *vty, struct interface *ifp), + void (*config_write_debug)(struct vty *vty), + void (*show_opaque_info)(struct vty *vty, struct ospf_lsa *lsa), + int (*lsa_originator)(void *arg), + struct ospf_lsa *(*lsa_refresher)(struct ospf_lsa *lsa), + int (*new_lsa_hook)(struct ospf_lsa *lsa), + int (*del_lsa_hook)(struct ospf_lsa *lsa)) +{ + struct list *funclist; + struct ospf_opaque_functab *new; + int rc = -1; + + if ((funclist = ospf_get_opaque_funclist(lsa_type)) == NULL) { + zlog_warn( + "ospf_register_opaque_functab: Cannot get funclist" + " for Type-%u LSAs?", + lsa_type); + goto out; + } else { + struct listnode *node, *nnode; + struct ospf_opaque_functab *functab; + + for (ALL_LIST_ELEMENTS(funclist, node, nnode, functab)) + if (functab->opaque_type == opaque_type) { + zlog_warn( + "ospf_register_opaque_functab: Duplicated entry?:" + " lsa_type(%u), opaque_type(%u)", + lsa_type, opaque_type); + goto out; + } + } + + if ((new = XCALLOC(MTYPE_OSPF_OPAQUE_FUNCTAB, + sizeof(struct ospf_opaque_functab))) + == NULL) { + zlog_warn("ospf_register_opaque_functab: XMALLOC: %s", + safe_strerror(errno)); + goto out; + } + + new->opaque_type = opaque_type; + new->oipt = NULL; + new->new_if_hook = new_if_hook; + new->del_if_hook = del_if_hook; + new->ism_change_hook = ism_change_hook; + new->nsm_change_hook = nsm_change_hook; + new->config_write_router = config_write_router; + new->config_write_if = config_write_if; + new->config_write_debug = config_write_debug; + new->show_opaque_info = show_opaque_info; + new->lsa_originator = lsa_originator; + new->lsa_refresher = lsa_refresher; + new->new_lsa_hook = new_lsa_hook; + new->del_lsa_hook = del_lsa_hook; + + listnode_add(funclist, new); + rc = 0; out: - return rc; + return rc; } -void -ospf_delete_opaque_functab (u_char lsa_type, u_char opaque_type) +void ospf_delete_opaque_functab(u_char lsa_type, u_char opaque_type) { - struct list *funclist; - struct listnode *node, *nnode; - struct ospf_opaque_functab *functab; + struct list *funclist; + struct listnode *node, *nnode; + struct ospf_opaque_functab *functab; - if ((funclist = ospf_get_opaque_funclist (lsa_type)) != NULL) - for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab)) - { - if (functab->opaque_type == opaque_type) - { - /* Cleanup internal control information, if it still remains. */ - if (functab->oipt != NULL) - free_opaque_info_per_type (functab->oipt); + if ((funclist = ospf_get_opaque_funclist(lsa_type)) != NULL) + for (ALL_LIST_ELEMENTS(funclist, node, nnode, functab)) { + if (functab->opaque_type == opaque_type) { + /* Cleanup internal control information, if it + * still remains. */ + if (functab->oipt != NULL) + free_opaque_info_per_type( + functab->oipt); - /* Dequeue listnode entry from the list. */ - listnode_delete (funclist, functab); + /* Dequeue listnode entry from the list. */ + listnode_delete(funclist, functab); - /* Avoid misjudgement in the next lookup. */ - if (listcount (funclist) == 0) - funclist->head = funclist->tail = NULL; + /* Avoid misjudgement in the next lookup. */ + if (listcount(funclist) == 0) + funclist->head = funclist->tail = NULL; - XFREE (MTYPE_OSPF_OPAQUE_FUNCTAB, functab); - break; - } - } + XFREE(MTYPE_OSPF_OPAQUE_FUNCTAB, functab); + break; + } + } - return; + return; } static struct ospf_opaque_functab * -ospf_opaque_functab_lookup (struct ospf_lsa *lsa) +ospf_opaque_functab_lookup(struct ospf_lsa *lsa) { - struct list *funclist; - struct listnode *node; - struct ospf_opaque_functab *functab; - u_char key = GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)); + struct list *funclist; + struct listnode *node; + struct ospf_opaque_functab *functab; + u_char key = GET_OPAQUE_TYPE(ntohl(lsa->data->id.s_addr)); - if ((funclist = ospf_get_opaque_funclist (lsa->data->type)) != NULL) - for (ALL_LIST_ELEMENTS_RO (funclist, node, functab)) - if (functab->opaque_type == key) - return functab; + if ((funclist = ospf_get_opaque_funclist(lsa->data->type)) != NULL) + for (ALL_LIST_ELEMENTS_RO(funclist, node, functab)) + if (functab->opaque_type == key) + return functab; - return NULL; + return NULL; } /*------------------------------------------------------------------------* @@ -479,283 +458,286 @@ ospf_opaque_functab_lookup (struct ospf_lsa *lsa) * Single Opaque-Type may have multiple instances; each of them will be * identified by their opaque-id. */ -struct opaque_info_per_type -{ - u_char lsa_type; - u_char opaque_type; - - enum { PROC_NORMAL, PROC_SUSPEND } status; - - /* - * Thread for (re-)origination scheduling for this opaque-type. - * - * Initial origination of Opaque-LSAs is controlled by generic - * Opaque-LSA handling module so that same opaque-type entries are - * called all at once when certain conditions are met. - * However, there might be cases that some Opaque-LSA clients need - * to (re-)originate their own Opaque-LSAs out-of-sync with others. - * This thread is prepared for that specific purpose. - */ - struct thread *t_opaque_lsa_self; - - /* - * Backpointer to an "owner" which is LSA-type dependent. - * type-9: struct ospf_interface - * type-10: struct ospf_area - * type-11: struct ospf - */ - void *owner; - - /* Collection of callback functions for this opaque-type. */ - struct ospf_opaque_functab *functab; - - /* List of Opaque-LSA control informations per opaque-id. */ - struct list *id_list; +struct opaque_info_per_type { + u_char lsa_type; + u_char opaque_type; + + enum { PROC_NORMAL, PROC_SUSPEND } status; + + /* + * Thread for (re-)origination scheduling for this opaque-type. + * + * Initial origination of Opaque-LSAs is controlled by generic + * Opaque-LSA handling module so that same opaque-type entries are + * called all at once when certain conditions are met. + * However, there might be cases that some Opaque-LSA clients need + * to (re-)originate their own Opaque-LSAs out-of-sync with others. + * This thread is prepared for that specific purpose. + */ + struct thread *t_opaque_lsa_self; + + /* + * Backpointer to an "owner" which is LSA-type dependent. + * type-9: struct ospf_interface + * type-10: struct ospf_area + * type-11: struct ospf + */ + void *owner; + + /* Collection of callback functions for this opaque-type. */ + struct ospf_opaque_functab *functab; + + /* List of Opaque-LSA control informations per opaque-id. */ + struct list *id_list; }; /* Opaque-LSA control information per opaque-id. */ -struct opaque_info_per_id -{ - u_int32_t opaque_id; +struct opaque_info_per_id { + u_int32_t opaque_id; - /* Thread for refresh/flush scheduling for this opaque-type/id. */ - struct thread *t_opaque_lsa_self; + /* Thread for refresh/flush scheduling for this opaque-type/id. */ + struct thread *t_opaque_lsa_self; - /* Backpointer to Opaque-LSA control information per opaque-type. */ - struct opaque_info_per_type *opqctl_type; + /* Backpointer to Opaque-LSA control information per opaque-type. */ + struct opaque_info_per_type *opqctl_type; - /* Here comes an actual Opaque-LSA entry for this opaque-type/id. */ - struct ospf_lsa *lsa; + /* Here comes an actual Opaque-LSA entry for this opaque-type/id. */ + struct ospf_lsa *lsa; }; -static struct opaque_info_per_type *register_opaque_info_per_type (struct ospf_opaque_functab *functab, struct ospf_lsa *new); -static struct opaque_info_per_type *lookup_opaque_info_by_type (struct ospf_lsa *lsa); -static struct opaque_info_per_id *register_opaque_info_per_id (struct opaque_info_per_type *oipt, struct ospf_lsa *new); -static struct opaque_info_per_id *lookup_opaque_info_by_id (struct opaque_info_per_type *oipt, struct ospf_lsa *lsa); -static struct opaque_info_per_id *register_opaque_lsa (struct ospf_lsa *new); +static struct opaque_info_per_type * +register_opaque_info_per_type(struct ospf_opaque_functab *functab, + struct ospf_lsa *new); +static struct opaque_info_per_type * +lookup_opaque_info_by_type(struct ospf_lsa *lsa); +static struct opaque_info_per_id * +register_opaque_info_per_id(struct opaque_info_per_type *oipt, + struct ospf_lsa *new); +static struct opaque_info_per_id * +lookup_opaque_info_by_id(struct opaque_info_per_type *oipt, + struct ospf_lsa *lsa); +static struct opaque_info_per_id *register_opaque_lsa(struct ospf_lsa *new); static struct opaque_info_per_type * -register_opaque_info_per_type (struct ospf_opaque_functab *functab, - struct ospf_lsa *new) -{ - struct ospf *top; - struct opaque_info_per_type *oipt; - - if ((oipt = XCALLOC (MTYPE_OPAQUE_INFO_PER_TYPE, - sizeof (struct opaque_info_per_type))) == NULL) - { - zlog_warn ("register_opaque_info_per_type: XMALLOC: %s", safe_strerror (errno)); - goto out; - } - - switch (new->data->type) - { - case OSPF_OPAQUE_LINK_LSA: - oipt->owner = new->oi; - listnode_add (new->oi->opaque_lsa_self, oipt); - break; - case OSPF_OPAQUE_AREA_LSA: - oipt->owner = new->area; - listnode_add (new->area->opaque_lsa_self, oipt); - break; - case OSPF_OPAQUE_AS_LSA: - top = ospf_lookup (); - if (new->area != NULL && (top = new->area->ospf) == NULL) - { - free_opaque_info_per_type ((void *) oipt); - oipt = NULL; - goto out; /* This case may not exist. */ - } - oipt->owner = top; - listnode_add (top->opaque_lsa_self, oipt); - break; - default: - zlog_warn ("register_opaque_info_per_type: Unexpected LSA-type(%u)", new->data->type); - free_opaque_info_per_type ((void *) oipt); - oipt = NULL; - goto out; /* This case may not exist. */ - } - - oipt->lsa_type = new->data->type; - oipt->opaque_type = GET_OPAQUE_TYPE (ntohl (new->data->id.s_addr)); - oipt->status = PROC_NORMAL; - oipt->t_opaque_lsa_self = NULL; - oipt->functab = functab; - functab->oipt = oipt; - oipt->id_list = list_new (); - oipt->id_list->del = free_opaque_info_per_id; +register_opaque_info_per_type(struct ospf_opaque_functab *functab, + struct ospf_lsa *new) +{ + struct ospf *top; + struct opaque_info_per_type *oipt; + + if ((oipt = XCALLOC(MTYPE_OPAQUE_INFO_PER_TYPE, + sizeof(struct opaque_info_per_type))) + == NULL) { + zlog_warn("register_opaque_info_per_type: XMALLOC: %s", + safe_strerror(errno)); + goto out; + } + + switch (new->data->type) { + case OSPF_OPAQUE_LINK_LSA: + oipt->owner = new->oi; + listnode_add(new->oi->opaque_lsa_self, oipt); + break; + case OSPF_OPAQUE_AREA_LSA: + oipt->owner = new->area; + listnode_add(new->area->opaque_lsa_self, oipt); + break; + case OSPF_OPAQUE_AS_LSA: + top = ospf_lookup(); + if (new->area != NULL && (top = new->area->ospf) == NULL) { + free_opaque_info_per_type((void *)oipt); + oipt = NULL; + goto out; /* This case may not exist. */ + } + oipt->owner = top; + listnode_add(top->opaque_lsa_self, oipt); + break; + default: + zlog_warn( + "register_opaque_info_per_type: Unexpected LSA-type(%u)", + new->data->type); + free_opaque_info_per_type((void *)oipt); + oipt = NULL; + goto out; /* This case may not exist. */ + } + + oipt->lsa_type = new->data->type; + oipt->opaque_type = GET_OPAQUE_TYPE(ntohl(new->data->id.s_addr)); + oipt->status = PROC_NORMAL; + oipt->t_opaque_lsa_self = NULL; + oipt->functab = functab; + functab->oipt = oipt; + oipt->id_list = list_new(); + oipt->id_list->del = free_opaque_info_per_id; out: - return oipt; -} - -static void -free_opaque_info_per_type (void *val) -{ - struct opaque_info_per_type *oipt = (struct opaque_info_per_type *) val; - struct opaque_info_per_id *oipi; - struct ospf_lsa *lsa; - struct listnode *node, *nnode; - - /* Control information per opaque-id may still exist. */ - for (ALL_LIST_ELEMENTS (oipt->id_list, node, nnode, oipi)) - { - if ((lsa = oipi->lsa) == NULL) - continue; - if (IS_LSA_MAXAGE (lsa)) - continue; - ospf_opaque_lsa_flush_schedule (lsa); - } - - /* Remove "oipt" from its owner's self-originated LSA list. */ - switch (oipt->lsa_type) - { - case OSPF_OPAQUE_LINK_LSA: - { - struct ospf_interface *oi = (struct ospf_interface *)(oipt->owner); - listnode_delete (oi->opaque_lsa_self, oipt); - break; - } - case OSPF_OPAQUE_AREA_LSA: - { - struct ospf_area *area = (struct ospf_area *)(oipt->owner); - listnode_delete (area->opaque_lsa_self, oipt); - break; - } - case OSPF_OPAQUE_AS_LSA: - { - struct ospf *top = (struct ospf *)(oipt->owner); - listnode_delete (top->opaque_lsa_self, oipt); - break; - } - default: - zlog_warn ("free_opaque_info_per_type: Unexpected LSA-type(%u)", oipt->lsa_type); - break; /* This case may not exist. */ - } - - OSPF_TIMER_OFF (oipt->t_opaque_lsa_self); - list_delete (oipt->id_list); - XFREE (MTYPE_OPAQUE_INFO_PER_TYPE, oipt); - return; + return oipt; +} + +static void free_opaque_info_per_type(void *val) +{ + struct opaque_info_per_type *oipt = (struct opaque_info_per_type *)val; + struct opaque_info_per_id *oipi; + struct ospf_lsa *lsa; + struct listnode *node, *nnode; + + /* Control information per opaque-id may still exist. */ + for (ALL_LIST_ELEMENTS(oipt->id_list, node, nnode, oipi)) { + if ((lsa = oipi->lsa) == NULL) + continue; + if (IS_LSA_MAXAGE(lsa)) + continue; + ospf_opaque_lsa_flush_schedule(lsa); + } + + /* Remove "oipt" from its owner's self-originated LSA list. */ + switch (oipt->lsa_type) { + case OSPF_OPAQUE_LINK_LSA: { + struct ospf_interface *oi = + (struct ospf_interface *)(oipt->owner); + listnode_delete(oi->opaque_lsa_self, oipt); + break; + } + case OSPF_OPAQUE_AREA_LSA: { + struct ospf_area *area = (struct ospf_area *)(oipt->owner); + listnode_delete(area->opaque_lsa_self, oipt); + break; + } + case OSPF_OPAQUE_AS_LSA: { + struct ospf *top = (struct ospf *)(oipt->owner); + listnode_delete(top->opaque_lsa_self, oipt); + break; + } + default: + zlog_warn("free_opaque_info_per_type: Unexpected LSA-type(%u)", + oipt->lsa_type); + break; /* This case may not exist. */ + } + + OSPF_TIMER_OFF(oipt->t_opaque_lsa_self); + list_delete(oipt->id_list); + XFREE(MTYPE_OPAQUE_INFO_PER_TYPE, oipt); + return; } static struct opaque_info_per_type * -lookup_opaque_info_by_type (struct ospf_lsa *lsa) -{ - struct ospf *top; - struct ospf_area *area; - struct ospf_interface *oi; - struct list *listtop = NULL; - struct listnode *node, *nnode; - struct opaque_info_per_type *oipt = NULL; - u_char key = GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)); - - switch (lsa->data->type) - { - case OSPF_OPAQUE_LINK_LSA: - if ((oi = lsa->oi) != NULL) - listtop = oi->opaque_lsa_self; - else - zlog_warn ("Type-9 Opaque-LSA: Reference to OI is missing?"); - break; - case OSPF_OPAQUE_AREA_LSA: - if ((area = lsa->area) != NULL) - listtop = area->opaque_lsa_self; - else - zlog_warn ("Type-10 Opaque-LSA: Reference to AREA is missing?"); - break; - case OSPF_OPAQUE_AS_LSA: - top = ospf_lookup (); - if ((area = lsa->area) != NULL && (top = area->ospf) == NULL) - { - zlog_warn ("Type-11 Opaque-LSA: Reference to OSPF is missing?"); - break; /* Unlikely to happen. */ - } - listtop = top->opaque_lsa_self; - break; - default: - zlog_warn ("lookup_opaque_info_by_type: Unexpected LSA-type(%u)", lsa->data->type); - break; - } - - if (listtop != NULL) - for (ALL_LIST_ELEMENTS (listtop, node, nnode, oipt)) - if (oipt->opaque_type == key) - return oipt; - - return NULL; +lookup_opaque_info_by_type(struct ospf_lsa *lsa) +{ + struct ospf *top; + struct ospf_area *area; + struct ospf_interface *oi; + struct list *listtop = NULL; + struct listnode *node, *nnode; + struct opaque_info_per_type *oipt = NULL; + u_char key = GET_OPAQUE_TYPE(ntohl(lsa->data->id.s_addr)); + + switch (lsa->data->type) { + case OSPF_OPAQUE_LINK_LSA: + if ((oi = lsa->oi) != NULL) + listtop = oi->opaque_lsa_self; + else + zlog_warn( + "Type-9 Opaque-LSA: Reference to OI is missing?"); + break; + case OSPF_OPAQUE_AREA_LSA: + if ((area = lsa->area) != NULL) + listtop = area->opaque_lsa_self; + else + zlog_warn( + "Type-10 Opaque-LSA: Reference to AREA is missing?"); + break; + case OSPF_OPAQUE_AS_LSA: + top = ospf_lookup(); + if ((area = lsa->area) != NULL && (top = area->ospf) == NULL) { + zlog_warn( + "Type-11 Opaque-LSA: Reference to OSPF is missing?"); + break; /* Unlikely to happen. */ + } + listtop = top->opaque_lsa_self; + break; + default: + zlog_warn("lookup_opaque_info_by_type: Unexpected LSA-type(%u)", + lsa->data->type); + break; + } + + if (listtop != NULL) + for (ALL_LIST_ELEMENTS(listtop, node, nnode, oipt)) + if (oipt->opaque_type == key) + return oipt; + + return NULL; } static struct opaque_info_per_id * -register_opaque_info_per_id (struct opaque_info_per_type *oipt, - struct ospf_lsa *new) +register_opaque_info_per_id(struct opaque_info_per_type *oipt, + struct ospf_lsa *new) { - struct opaque_info_per_id *oipi; + struct opaque_info_per_id *oipi; - if ((oipi = XCALLOC (MTYPE_OPAQUE_INFO_PER_ID, - sizeof (struct opaque_info_per_id))) == NULL) - { - zlog_warn ("register_opaque_info_per_id: XMALLOC: %s", safe_strerror (errno)); - goto out; - } - oipi->opaque_id = GET_OPAQUE_ID (ntohl (new->data->id.s_addr)); - oipi->t_opaque_lsa_self = NULL; - oipi->opqctl_type = oipt; - oipi->lsa = ospf_lsa_lock (new); + if ((oipi = XCALLOC(MTYPE_OPAQUE_INFO_PER_ID, + sizeof(struct opaque_info_per_id))) + == NULL) { + zlog_warn("register_opaque_info_per_id: XMALLOC: %s", + safe_strerror(errno)); + goto out; + } + oipi->opaque_id = GET_OPAQUE_ID(ntohl(new->data->id.s_addr)); + oipi->t_opaque_lsa_self = NULL; + oipi->opqctl_type = oipt; + oipi->lsa = ospf_lsa_lock(new); - listnode_add (oipt->id_list, oipi); + listnode_add(oipt->id_list, oipi); out: - return oipi; + return oipi; } -static void -free_opaque_info_per_id (void *val) +static void free_opaque_info_per_id(void *val) { - struct opaque_info_per_id *oipi = (struct opaque_info_per_id *) val; + struct opaque_info_per_id *oipi = (struct opaque_info_per_id *)val; - OSPF_TIMER_OFF (oipi->t_opaque_lsa_self); - if (oipi->lsa != NULL) - ospf_lsa_unlock (&oipi->lsa); - XFREE (MTYPE_OPAQUE_INFO_PER_ID, oipi); - return; + OSPF_TIMER_OFF(oipi->t_opaque_lsa_self); + if (oipi->lsa != NULL) + ospf_lsa_unlock(&oipi->lsa); + XFREE(MTYPE_OPAQUE_INFO_PER_ID, oipi); + return; } static struct opaque_info_per_id * -lookup_opaque_info_by_id (struct opaque_info_per_type *oipt, - struct ospf_lsa *lsa) +lookup_opaque_info_by_id(struct opaque_info_per_type *oipt, + struct ospf_lsa *lsa) { - struct listnode *node, *nnode; - struct opaque_info_per_id *oipi; - u_int32_t key = GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr)); + struct listnode *node, *nnode; + struct opaque_info_per_id *oipi; + u_int32_t key = GET_OPAQUE_ID(ntohl(lsa->data->id.s_addr)); - for (ALL_LIST_ELEMENTS (oipt->id_list, node, nnode, oipi)) - if (oipi->opaque_id == key) - return oipi; + for (ALL_LIST_ELEMENTS(oipt->id_list, node, nnode, oipi)) + if (oipi->opaque_id == key) + return oipi; - return NULL; + return NULL; } -static struct opaque_info_per_id * -register_opaque_lsa (struct ospf_lsa *new) +static struct opaque_info_per_id *register_opaque_lsa(struct ospf_lsa *new) { - struct ospf_opaque_functab *functab; - struct opaque_info_per_type *oipt; - struct opaque_info_per_id *oipi = NULL; + struct ospf_opaque_functab *functab; + struct opaque_info_per_type *oipt; + struct opaque_info_per_id *oipi = NULL; - if ((functab = ospf_opaque_functab_lookup (new)) == NULL) - goto out; + if ((functab = ospf_opaque_functab_lookup(new)) == NULL) + goto out; - if ((oipt = lookup_opaque_info_by_type (new)) == NULL - && (oipt = register_opaque_info_per_type (functab, new)) == NULL) - goto out; + if ((oipt = lookup_opaque_info_by_type(new)) == NULL + && (oipt = register_opaque_info_per_type(functab, new)) == NULL) + goto out; - if ((oipi = register_opaque_info_per_id (oipt, new)) == NULL) - goto out; + if ((oipi = register_opaque_info_per_id(oipt, new)) == NULL) + goto out; out: - return oipi; + return oipi; } /*------------------------------------------------------------------------* @@ -768,18 +750,17 @@ DEFUN (capability_opaque, "Enable specific OSPF feature\n" "Opaque LSA\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); + VTY_DECLVAR_CONTEXT(ospf, ospf); - /* Turn on the "master switch" of opaque-lsa capability. */ - if (!CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Opaque capability: OFF -> ON"); + /* Turn on the "master switch" of opaque-lsa capability. */ + if (!CHECK_FLAG(ospf->config, OSPF_OPAQUE_CAPABLE)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Opaque capability: OFF -> ON"); - SET_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE); - ospf_renegotiate_optional_capabilities (ospf); - } - return CMD_SUCCESS; + SET_FLAG(ospf->config, OSPF_OPAQUE_CAPABLE); + ospf_renegotiate_optional_capabilities(ospf); + } + return CMD_SUCCESS; } DEFUN (ospf_opaque, @@ -788,7 +769,7 @@ DEFUN (ospf_opaque, "OSPF specific commands\n" "Enable the Opaque-LSA capability (rfc2370)\n") { - return capability_opaque (self, vty, argc, argv); + return capability_opaque(self, vty, argc, argv); } DEFUN (no_capability_opaque, @@ -798,18 +779,17 @@ DEFUN (no_capability_opaque, "Enable specific OSPF feature\n" "Opaque LSA\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); + VTY_DECLVAR_CONTEXT(ospf, ospf); - /* Turn off the "master switch" of opaque-lsa capability. */ - if (CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Opaque capability: ON -> OFF"); + /* Turn off the "master switch" of opaque-lsa capability. */ + if (CHECK_FLAG(ospf->config, OSPF_OPAQUE_CAPABLE)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Opaque capability: ON -> OFF"); - UNSET_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE); - ospf_renegotiate_optional_capabilities (ospf); - } - return CMD_SUCCESS; + UNSET_FLAG(ospf->config, OSPF_OPAQUE_CAPABLE); + ospf_renegotiate_optional_capabilities(ospf); + } + return CMD_SUCCESS; } DEFUN (no_ospf_opaque, @@ -819,833 +799,825 @@ DEFUN (no_ospf_opaque, "OSPF specific commands\n" "Enable the Opaque-LSA capability (rfc2370)\n") { - return no_capability_opaque (self, vty, argc, argv); + return no_capability_opaque(self, vty, argc, argv); } -static void -ospf_opaque_register_vty (void) +static void ospf_opaque_register_vty(void) { - install_element (OSPF_NODE, &capability_opaque_cmd); - install_element (OSPF_NODE, &no_capability_opaque_cmd); - install_element (OSPF_NODE, &ospf_opaque_cmd); - install_element (OSPF_NODE, &no_ospf_opaque_cmd); - return; + install_element(OSPF_NODE, &capability_opaque_cmd); + install_element(OSPF_NODE, &no_capability_opaque_cmd); + install_element(OSPF_NODE, &ospf_opaque_cmd); + install_element(OSPF_NODE, &no_ospf_opaque_cmd); + return; } /*------------------------------------------------------------------------* * Followings are collection of user-registered function callers. *------------------------------------------------------------------------*/ -static int -opaque_lsa_new_if_callback (struct list *funclist, struct interface *ifp) +static int opaque_lsa_new_if_callback(struct list *funclist, + struct interface *ifp) { - struct listnode *node, *nnode; - struct ospf_opaque_functab *functab; - int rc = -1; + struct listnode *node, *nnode; + struct ospf_opaque_functab *functab; + int rc = -1; - for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab)) - if (functab->new_if_hook != NULL) - if ((* functab->new_if_hook)(ifp) != 0) - goto out; - rc = 0; + for (ALL_LIST_ELEMENTS(funclist, node, nnode, functab)) + if (functab->new_if_hook != NULL) + if ((*functab->new_if_hook)(ifp) != 0) + goto out; + rc = 0; out: - return rc; + return rc; } -static int -opaque_lsa_del_if_callback (struct list *funclist, struct interface *ifp) +static int opaque_lsa_del_if_callback(struct list *funclist, + struct interface *ifp) { - struct listnode *node, *nnode; - struct ospf_opaque_functab *functab; - int rc = -1; + struct listnode *node, *nnode; + struct ospf_opaque_functab *functab; + int rc = -1; - for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab)) - if (functab->del_if_hook != NULL) - if ((* functab->del_if_hook)(ifp) != 0) - goto out; - rc = 0; + for (ALL_LIST_ELEMENTS(funclist, node, nnode, functab)) + if (functab->del_if_hook != NULL) + if ((*functab->del_if_hook)(ifp) != 0) + goto out; + rc = 0; out: - return rc; + return rc; } -static void -opaque_lsa_ism_change_callback (struct list *funclist, - struct ospf_interface *oi, int old_status) +static void opaque_lsa_ism_change_callback(struct list *funclist, + struct ospf_interface *oi, + int old_status) { - struct listnode *node, *nnode; - struct ospf_opaque_functab *functab; + struct listnode *node, *nnode; + struct ospf_opaque_functab *functab; - for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab)) - if (functab->ism_change_hook != NULL) - (* functab->ism_change_hook)(oi, old_status); + for (ALL_LIST_ELEMENTS(funclist, node, nnode, functab)) + if (functab->ism_change_hook != NULL) + (*functab->ism_change_hook)(oi, old_status); - return; + return; } -static void -opaque_lsa_nsm_change_callback (struct list *funclist, - struct ospf_neighbor *nbr, int old_status) +static void opaque_lsa_nsm_change_callback(struct list *funclist, + struct ospf_neighbor *nbr, + int old_status) { - struct listnode *node, *nnode; - struct ospf_opaque_functab *functab; + struct listnode *node, *nnode; + struct ospf_opaque_functab *functab; - for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab)) - if (functab->nsm_change_hook != NULL) - (* functab->nsm_change_hook)(nbr, old_status); - return; + for (ALL_LIST_ELEMENTS(funclist, node, nnode, functab)) + if (functab->nsm_change_hook != NULL) + (*functab->nsm_change_hook)(nbr, old_status); + return; } -static void -opaque_lsa_config_write_router_callback (struct list *funclist, - struct vty *vty) +static void opaque_lsa_config_write_router_callback(struct list *funclist, + struct vty *vty) { - struct listnode *node, *nnode; - struct ospf_opaque_functab *functab; + struct listnode *node, *nnode; + struct ospf_opaque_functab *functab; - for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab)) - if (functab->config_write_router != NULL) - (* functab->config_write_router)(vty); - return; + for (ALL_LIST_ELEMENTS(funclist, node, nnode, functab)) + if (functab->config_write_router != NULL) + (*functab->config_write_router)(vty); + return; } -static void -opaque_lsa_config_write_if_callback (struct list *funclist, - struct vty *vty, struct interface *ifp) +static void opaque_lsa_config_write_if_callback(struct list *funclist, + struct vty *vty, + struct interface *ifp) { - struct listnode *node, *nnode; - struct ospf_opaque_functab *functab; + struct listnode *node, *nnode; + struct ospf_opaque_functab *functab; - for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab)) - if (functab->config_write_if != NULL) - (* functab->config_write_if)(vty, ifp); - return; + for (ALL_LIST_ELEMENTS(funclist, node, nnode, functab)) + if (functab->config_write_if != NULL) + (*functab->config_write_if)(vty, ifp); + return; } -static void -opaque_lsa_config_write_debug_callback (struct list *funclist, struct vty *vty) +static void opaque_lsa_config_write_debug_callback(struct list *funclist, + struct vty *vty) { - struct listnode *node, *nnode; - struct ospf_opaque_functab *functab; + struct listnode *node, *nnode; + struct ospf_opaque_functab *functab; - for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab)) - if (functab->config_write_debug != NULL) - (* functab->config_write_debug)(vty); - return; + for (ALL_LIST_ELEMENTS(funclist, node, nnode, functab)) + if (functab->config_write_debug != NULL) + (*functab->config_write_debug)(vty); + return; } -static int -opaque_lsa_originate_callback (struct list *funclist, void *lsa_type_dependent) +static int opaque_lsa_originate_callback(struct list *funclist, + void *lsa_type_dependent) { - struct listnode *node, *nnode; - struct ospf_opaque_functab *functab; - int rc = -1; + struct listnode *node, *nnode; + struct ospf_opaque_functab *functab; + int rc = -1; - for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab)) - if (functab->lsa_originator != NULL) - if ((* functab->lsa_originator)(lsa_type_dependent) != 0) - goto out; - rc = 0; + for (ALL_LIST_ELEMENTS(funclist, node, nnode, functab)) + if (functab->lsa_originator != NULL) + if ((*functab->lsa_originator)(lsa_type_dependent) != 0) + goto out; + rc = 0; out: - return rc; + return rc; } -static int -new_lsa_callback (struct list *funclist, struct ospf_lsa *lsa) +static int new_lsa_callback(struct list *funclist, struct ospf_lsa *lsa) { - struct listnode *node, *nnode; - struct ospf_opaque_functab *functab; - int rc = -1; + struct listnode *node, *nnode; + struct ospf_opaque_functab *functab; + int rc = -1; - /* This function handles ALL types of LSAs, not only opaque ones. */ - for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab)) - if (functab->new_lsa_hook != NULL) - if ((* functab->new_lsa_hook)(lsa) != 0) - goto out; - rc = 0; + /* This function handles ALL types of LSAs, not only opaque ones. */ + for (ALL_LIST_ELEMENTS(funclist, node, nnode, functab)) + if (functab->new_lsa_hook != NULL) + if ((*functab->new_lsa_hook)(lsa) != 0) + goto out; + rc = 0; out: - return rc; + return rc; } -static int -del_lsa_callback (struct list *funclist, struct ospf_lsa *lsa) +static int del_lsa_callback(struct list *funclist, struct ospf_lsa *lsa) { - struct listnode *node, *nnode; - struct ospf_opaque_functab *functab; - int rc = -1; + struct listnode *node, *nnode; + struct ospf_opaque_functab *functab; + int rc = -1; - /* This function handles ALL types of LSAs, not only opaque ones. */ - for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab)) - if (functab->del_lsa_hook != NULL) - if ((* functab->del_lsa_hook)(lsa) != 0) - goto out; - rc = 0; + /* This function handles ALL types of LSAs, not only opaque ones. */ + for (ALL_LIST_ELEMENTS(funclist, node, nnode, functab)) + if (functab->del_lsa_hook != NULL) + if ((*functab->del_lsa_hook)(lsa) != 0) + goto out; + rc = 0; out: - return rc; + return rc; } /*------------------------------------------------------------------------* * Followings are glue functions to call Opaque-LSA specific processing. *------------------------------------------------------------------------*/ -int -ospf_opaque_new_if (struct interface *ifp) +int ospf_opaque_new_if(struct interface *ifp) { - struct list *funclist; - int rc = -1; + struct list *funclist; + int rc = -1; - funclist = ospf_opaque_wildcard_funclist; - if (opaque_lsa_new_if_callback (funclist, ifp) != 0) - goto out; + funclist = ospf_opaque_wildcard_funclist; + if (opaque_lsa_new_if_callback(funclist, ifp) != 0) + goto out; - funclist = ospf_opaque_type9_funclist; - if (opaque_lsa_new_if_callback (funclist, ifp) != 0) - goto out; + funclist = ospf_opaque_type9_funclist; + if (opaque_lsa_new_if_callback(funclist, ifp) != 0) + goto out; - funclist = ospf_opaque_type10_funclist; - if (opaque_lsa_new_if_callback (funclist, ifp) != 0) - goto out; + funclist = ospf_opaque_type10_funclist; + if (opaque_lsa_new_if_callback(funclist, ifp) != 0) + goto out; - funclist = ospf_opaque_type11_funclist; - if (opaque_lsa_new_if_callback (funclist, ifp) != 0) - goto out; + funclist = ospf_opaque_type11_funclist; + if (opaque_lsa_new_if_callback(funclist, ifp) != 0) + goto out; - rc = 0; + rc = 0; out: - return rc; + return rc; } -int -ospf_opaque_del_if (struct interface *ifp) +int ospf_opaque_del_if(struct interface *ifp) { - struct list *funclist; - int rc = -1; + struct list *funclist; + int rc = -1; - funclist = ospf_opaque_wildcard_funclist; - if (opaque_lsa_del_if_callback (funclist, ifp) != 0) - goto out; + funclist = ospf_opaque_wildcard_funclist; + if (opaque_lsa_del_if_callback(funclist, ifp) != 0) + goto out; - funclist = ospf_opaque_type9_funclist; - if (opaque_lsa_del_if_callback (funclist, ifp) != 0) - goto out; + funclist = ospf_opaque_type9_funclist; + if (opaque_lsa_del_if_callback(funclist, ifp) != 0) + goto out; - funclist = ospf_opaque_type10_funclist; - if (opaque_lsa_del_if_callback (funclist, ifp) != 0) - goto out; + funclist = ospf_opaque_type10_funclist; + if (opaque_lsa_del_if_callback(funclist, ifp) != 0) + goto out; - funclist = ospf_opaque_type11_funclist; - if (opaque_lsa_del_if_callback (funclist, ifp) != 0) - goto out; + funclist = ospf_opaque_type11_funclist; + if (opaque_lsa_del_if_callback(funclist, ifp) != 0) + goto out; - rc = 0; + rc = 0; out: - return rc; + return rc; } -void -ospf_opaque_ism_change (struct ospf_interface *oi, int old_status) +void ospf_opaque_ism_change(struct ospf_interface *oi, int old_status) { - struct list *funclist; + struct list *funclist; - funclist = ospf_opaque_wildcard_funclist; - opaque_lsa_ism_change_callback (funclist, oi, old_status); + funclist = ospf_opaque_wildcard_funclist; + opaque_lsa_ism_change_callback(funclist, oi, old_status); - funclist = ospf_opaque_type9_funclist; - opaque_lsa_ism_change_callback (funclist, oi, old_status); + funclist = ospf_opaque_type9_funclist; + opaque_lsa_ism_change_callback(funclist, oi, old_status); - funclist = ospf_opaque_type10_funclist; - opaque_lsa_ism_change_callback (funclist, oi, old_status); + funclist = ospf_opaque_type10_funclist; + opaque_lsa_ism_change_callback(funclist, oi, old_status); - funclist = ospf_opaque_type11_funclist; - opaque_lsa_ism_change_callback (funclist, oi, old_status); + funclist = ospf_opaque_type11_funclist; + opaque_lsa_ism_change_callback(funclist, oi, old_status); - return; + return; } -void -ospf_opaque_nsm_change (struct ospf_neighbor *nbr, int old_state) +void ospf_opaque_nsm_change(struct ospf_neighbor *nbr, int old_state) { - struct ospf *top; - struct list *funclist; + struct ospf *top; + struct list *funclist; - if ((top = oi_to_top (nbr->oi)) == NULL) - goto out; + if ((top = oi_to_top(nbr->oi)) == NULL) + goto out; - if (old_state != NSM_Full && nbr->state == NSM_Full) - { - if (CHECK_FLAG (nbr->options, OSPF_OPTION_O)) - { - if (! CHECK_FLAG (top->opaque, OPAQUE_OPERATION_READY_BIT)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Opaque-LSA: Now get operational!"); + if (old_state != NSM_Full && nbr->state == NSM_Full) { + if (CHECK_FLAG(nbr->options, OSPF_OPTION_O)) { + if (!CHECK_FLAG(top->opaque, + OPAQUE_OPERATION_READY_BIT)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "Opaque-LSA: Now get operational!"); - SET_FLAG (top->opaque, OPAQUE_OPERATION_READY_BIT); - } + SET_FLAG(top->opaque, + OPAQUE_OPERATION_READY_BIT); + } - ospf_opaque_lsa_originate_schedule (nbr->oi, NULL); - } - } - else - if (old_state == NSM_Full && nbr->state != NSM_Full) - { + ospf_opaque_lsa_originate_schedule(nbr->oi, NULL); + } + } else if (old_state == NSM_Full && nbr->state != NSM_Full) { #ifdef NOTYET - /* - * If no more opaque-capable full-state neighbor remains in the - * flooding scope which corresponds to Opaque-LSA type, periodic - * LS flooding should be stopped. - */ +/* + * If no more opaque-capable full-state neighbor remains in the + * flooding scope which corresponds to Opaque-LSA type, periodic + * LS flooding should be stopped. + */ #endif /* NOTYET */ - ; - } + ; + } - funclist = ospf_opaque_wildcard_funclist; - opaque_lsa_nsm_change_callback (funclist, nbr, old_state); + funclist = ospf_opaque_wildcard_funclist; + opaque_lsa_nsm_change_callback(funclist, nbr, old_state); - funclist = ospf_opaque_type9_funclist; - opaque_lsa_nsm_change_callback (funclist, nbr, old_state); + funclist = ospf_opaque_type9_funclist; + opaque_lsa_nsm_change_callback(funclist, nbr, old_state); - funclist = ospf_opaque_type10_funclist; - opaque_lsa_nsm_change_callback (funclist, nbr, old_state); + funclist = ospf_opaque_type10_funclist; + opaque_lsa_nsm_change_callback(funclist, nbr, old_state); - funclist = ospf_opaque_type11_funclist; - opaque_lsa_nsm_change_callback (funclist, nbr, old_state); + funclist = ospf_opaque_type11_funclist; + opaque_lsa_nsm_change_callback(funclist, nbr, old_state); out: - return; + return; } -void -ospf_opaque_config_write_router (struct vty *vty, struct ospf *ospf) +void ospf_opaque_config_write_router(struct vty *vty, struct ospf *ospf) { - struct list *funclist; + struct list *funclist; - if (CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE)) - vty_out (vty, " capability opaque\n"); + if (CHECK_FLAG(ospf->config, OSPF_OPAQUE_CAPABLE)) + vty_out(vty, " capability opaque\n"); - funclist = ospf_opaque_wildcard_funclist; - opaque_lsa_config_write_router_callback (funclist, vty); + funclist = ospf_opaque_wildcard_funclist; + opaque_lsa_config_write_router_callback(funclist, vty); - funclist = ospf_opaque_type9_funclist; - opaque_lsa_config_write_router_callback (funclist, vty); + funclist = ospf_opaque_type9_funclist; + opaque_lsa_config_write_router_callback(funclist, vty); - funclist = ospf_opaque_type10_funclist; - opaque_lsa_config_write_router_callback (funclist, vty); + funclist = ospf_opaque_type10_funclist; + opaque_lsa_config_write_router_callback(funclist, vty); - funclist = ospf_opaque_type11_funclist; - opaque_lsa_config_write_router_callback (funclist, vty); + funclist = ospf_opaque_type11_funclist; + opaque_lsa_config_write_router_callback(funclist, vty); - return; + return; } -void -ospf_opaque_config_write_if (struct vty *vty, struct interface *ifp) +void ospf_opaque_config_write_if(struct vty *vty, struct interface *ifp) { - struct list *funclist; + struct list *funclist; - funclist = ospf_opaque_wildcard_funclist; - opaque_lsa_config_write_if_callback (funclist, vty, ifp); + funclist = ospf_opaque_wildcard_funclist; + opaque_lsa_config_write_if_callback(funclist, vty, ifp); - funclist = ospf_opaque_type9_funclist; - opaque_lsa_config_write_if_callback (funclist, vty, ifp); + funclist = ospf_opaque_type9_funclist; + opaque_lsa_config_write_if_callback(funclist, vty, ifp); - funclist = ospf_opaque_type10_funclist; - opaque_lsa_config_write_if_callback (funclist, vty, ifp); + funclist = ospf_opaque_type10_funclist; + opaque_lsa_config_write_if_callback(funclist, vty, ifp); - funclist = ospf_opaque_type11_funclist; - opaque_lsa_config_write_if_callback (funclist, vty, ifp); + funclist = ospf_opaque_type11_funclist; + opaque_lsa_config_write_if_callback(funclist, vty, ifp); - return; + return; } -void -ospf_opaque_config_write_debug (struct vty *vty) +void ospf_opaque_config_write_debug(struct vty *vty) { - struct list *funclist; + struct list *funclist; - funclist = ospf_opaque_wildcard_funclist; - opaque_lsa_config_write_debug_callback (funclist, vty); + funclist = ospf_opaque_wildcard_funclist; + opaque_lsa_config_write_debug_callback(funclist, vty); - funclist = ospf_opaque_type9_funclist; - opaque_lsa_config_write_debug_callback (funclist, vty); + funclist = ospf_opaque_type9_funclist; + opaque_lsa_config_write_debug_callback(funclist, vty); - funclist = ospf_opaque_type10_funclist; - opaque_lsa_config_write_debug_callback (funclist, vty); + funclist = ospf_opaque_type10_funclist; + opaque_lsa_config_write_debug_callback(funclist, vty); - funclist = ospf_opaque_type11_funclist; - opaque_lsa_config_write_debug_callback (funclist, vty); + funclist = ospf_opaque_type11_funclist; + opaque_lsa_config_write_debug_callback(funclist, vty); - return; + return; } -void -show_opaque_info_detail (struct vty *vty, struct ospf_lsa *lsa) +void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa) { - struct lsa_header *lsah = (struct lsa_header *) lsa->data; - u_int32_t lsid = ntohl (lsah->id.s_addr); - u_char opaque_type = GET_OPAQUE_TYPE (lsid); - u_int32_t opaque_id = GET_OPAQUE_ID (lsid); - struct ospf_opaque_functab *functab; + struct lsa_header *lsah = (struct lsa_header *)lsa->data; + u_int32_t lsid = ntohl(lsah->id.s_addr); + u_char opaque_type = GET_OPAQUE_TYPE(lsid); + u_int32_t opaque_id = GET_OPAQUE_ID(lsid); + struct ospf_opaque_functab *functab; - /* Switch output functionality by vty address. */ - if (vty != NULL) - { - vty_out (vty, " Opaque-Type %u (%s)\n", opaque_type, - ospf_opaque_type_name(opaque_type)); - vty_out (vty, " Opaque-ID 0x%x\n", opaque_id); + /* Switch output functionality by vty address. */ + if (vty != NULL) { + vty_out(vty, " Opaque-Type %u (%s)\n", opaque_type, + ospf_opaque_type_name(opaque_type)); + vty_out(vty, " Opaque-ID 0x%x\n", opaque_id); - vty_out (vty, " Opaque-Info: %u octets of data%s\n", - ntohs (lsah->length) - OSPF_LSA_HEADER_SIZE, - VALID_OPAQUE_INFO_LEN(lsah) ? "" : "(Invalid length?)"); - } - else - { - zlog_debug (" Opaque-Type %u (%s)", opaque_type, - ospf_opaque_type_name (opaque_type)); - zlog_debug (" Opaque-ID 0x%x", opaque_id); + vty_out(vty, " Opaque-Info: %u octets of data%s\n", + ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE, + VALID_OPAQUE_INFO_LEN(lsah) ? "" : "(Invalid length?)"); + } else { + zlog_debug(" Opaque-Type %u (%s)", opaque_type, + ospf_opaque_type_name(opaque_type)); + zlog_debug(" Opaque-ID 0x%x", opaque_id); - zlog_debug (" Opaque-Info: %u octets of data%s", - ntohs (lsah->length) - OSPF_LSA_HEADER_SIZE, - VALID_OPAQUE_INFO_LEN(lsah) ? "" : "(Invalid length?)"); - } + zlog_debug(" Opaque-Info: %u octets of data%s", + ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE, + VALID_OPAQUE_INFO_LEN(lsah) ? "" + : "(Invalid length?)"); + } - /* Call individual output functions. */ - if ((functab = ospf_opaque_functab_lookup (lsa)) != NULL) - if (functab->show_opaque_info != NULL) - (* functab->show_opaque_info)(vty, lsa); + /* Call individual output functions. */ + if ((functab = ospf_opaque_functab_lookup(lsa)) != NULL) + if (functab->show_opaque_info != NULL) + (*functab->show_opaque_info)(vty, lsa); - return; + return; } -void -ospf_opaque_lsa_dump (struct stream *s, u_int16_t length) +void ospf_opaque_lsa_dump(struct stream *s, u_int16_t length) { - struct ospf_lsa lsa; + struct ospf_lsa lsa; - lsa.data = (struct lsa_header *) STREAM_PNT (s); - show_opaque_info_detail (NULL, &lsa); - return; + lsa.data = (struct lsa_header *)STREAM_PNT(s); + show_opaque_info_detail(NULL, &lsa); + return; } -static int -ospf_opaque_lsa_install_hook (struct ospf_lsa *lsa) +static int ospf_opaque_lsa_install_hook(struct ospf_lsa *lsa) { - struct list *funclist; - int rc = -1; + struct list *funclist; + int rc = -1; - /* - * Some Opaque-LSA user may want to monitor every LSA installation - * into the LSDB, regardless with target LSA type. - */ - funclist = ospf_opaque_wildcard_funclist; - if (new_lsa_callback (funclist, lsa) != 0) - goto out; + /* + * Some Opaque-LSA user may want to monitor every LSA installation + * into the LSDB, regardless with target LSA type. + */ + funclist = ospf_opaque_wildcard_funclist; + if (new_lsa_callback(funclist, lsa) != 0) + goto out; - funclist = ospf_opaque_type9_funclist; - if (new_lsa_callback (funclist, lsa) != 0) - goto out; + funclist = ospf_opaque_type9_funclist; + if (new_lsa_callback(funclist, lsa) != 0) + goto out; - funclist = ospf_opaque_type10_funclist; - if (new_lsa_callback (funclist, lsa) != 0) - goto out; + funclist = ospf_opaque_type10_funclist; + if (new_lsa_callback(funclist, lsa) != 0) + goto out; - funclist = ospf_opaque_type11_funclist; - if (new_lsa_callback (funclist, lsa) != 0) - goto out; + funclist = ospf_opaque_type11_funclist; + if (new_lsa_callback(funclist, lsa) != 0) + goto out; - rc = 0; + rc = 0; out: - return rc; + return rc; } -static int -ospf_opaque_lsa_delete_hook (struct ospf_lsa *lsa) +static int ospf_opaque_lsa_delete_hook(struct ospf_lsa *lsa) { - struct list *funclist; - int rc = -1; + struct list *funclist; + int rc = -1; - /* - * Some Opaque-LSA user may want to monitor every LSA deletion - * from the LSDB, regardless with target LSA type. - */ - funclist = ospf_opaque_wildcard_funclist; - if (del_lsa_callback (funclist, lsa) != 0) - goto out; + /* + * Some Opaque-LSA user may want to monitor every LSA deletion + * from the LSDB, regardless with target LSA type. + */ + funclist = ospf_opaque_wildcard_funclist; + if (del_lsa_callback(funclist, lsa) != 0) + goto out; - funclist = ospf_opaque_type9_funclist; - if (del_lsa_callback (funclist, lsa) != 0) - goto out; + funclist = ospf_opaque_type9_funclist; + if (del_lsa_callback(funclist, lsa) != 0) + goto out; - funclist = ospf_opaque_type10_funclist; - if (del_lsa_callback (funclist, lsa) != 0) - goto out; + funclist = ospf_opaque_type10_funclist; + if (del_lsa_callback(funclist, lsa) != 0) + goto out; - funclist = ospf_opaque_type11_funclist; - if (del_lsa_callback (funclist, lsa) != 0) - goto out; + funclist = ospf_opaque_type11_funclist; + if (del_lsa_callback(funclist, lsa) != 0) + goto out; - rc = 0; + rc = 0; out: - return rc; + return rc; } /*------------------------------------------------------------------------* * Followings are Opaque-LSA origination/refresh management functions. *------------------------------------------------------------------------*/ -static int ospf_opaque_type9_lsa_originate (struct thread *t); -static int ospf_opaque_type10_lsa_originate (struct thread *t); -static int ospf_opaque_type11_lsa_originate (struct thread *t); -static void ospf_opaque_lsa_reoriginate_resume (struct list *listtop, void *arg); - -void -ospf_opaque_lsa_originate_schedule (struct ospf_interface *oi, int *delay0) -{ - struct ospf *top; - struct ospf_area *area; - struct listnode *node, *nnode; - struct opaque_info_per_type *oipt; - int delay = 0; - - if ((top = oi_to_top (oi)) == NULL || (area = oi->area) == NULL) - { - zlog_warn ("ospf_opaque_lsa_originate_schedule: Invalid argument?"); - goto out; - } - - /* It may not a right time to schedule origination now. */ - if (! CHECK_FLAG (top->opaque, OPAQUE_OPERATION_READY_BIT)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_opaque_lsa_originate_schedule: Not operational."); - goto out; /* This is not an error. */ - } - - if (delay0 != NULL) - delay = *delay0; - - /* - * There might be some entries that have been waiting for triggering - * of per opaque-type re-origination get resumed. - */ - ospf_opaque_lsa_reoriginate_resume ( oi->opaque_lsa_self, (void *) oi); - ospf_opaque_lsa_reoriginate_resume (area->opaque_lsa_self, (void *) area); - ospf_opaque_lsa_reoriginate_resume ( top->opaque_lsa_self, (void *) top); - - /* - * Now, schedule origination of all Opaque-LSAs per opaque-type. - */ - if (! list_isempty (ospf_opaque_type9_funclist) - && list_isempty (oi->opaque_lsa_self) - && oi->t_opaque_lsa_self == NULL) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Schedule Type-9 Opaque-LSA origination in %d ms later.", delay); - oi->t_opaque_lsa_self = NULL; - thread_add_timer_msec(master, ospf_opaque_type9_lsa_originate, oi, delay, - &oi->t_opaque_lsa_self); - delay += top->min_ls_interval; - } - - if (! list_isempty (ospf_opaque_type10_funclist) - && list_isempty (area->opaque_lsa_self) - && area->t_opaque_lsa_self == NULL) - { - /* - * One AREA may contain multiple OIs, but above 2nd and 3rd - * conditions prevent from scheduling the originate function - * again and again. - */ - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Schedule Type-10 Opaque-LSA origination in %d ms later.", delay); - area->t_opaque_lsa_self = NULL; - thread_add_timer_msec(master, ospf_opaque_type10_lsa_originate, area, delay, - &area->t_opaque_lsa_self); - delay += top->min_ls_interval; - } - - if (! list_isempty (ospf_opaque_type11_funclist) - && list_isempty (top->opaque_lsa_self) - && top->t_opaque_lsa_self == NULL) - { - /* - * One OSPF may contain multiple AREAs, but above 2nd and 3rd - * conditions prevent from scheduling the originate function - * again and again. - */ - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Schedule Type-11 Opaque-LSA origination in %d ms later.", delay); - top->t_opaque_lsa_self = NULL; - thread_add_timer_msec(master, ospf_opaque_type11_lsa_originate, top, delay, - &top->t_opaque_lsa_self); - delay += top->min_ls_interval; - } - - /* - * Following section treats a special situation that this node's - * opaque capability has changed as "ON -> OFF -> ON". - */ - if (! list_isempty (ospf_opaque_type9_funclist) - && ! list_isempty (oi->opaque_lsa_self)) - { - for (ALL_LIST_ELEMENTS (oi->opaque_lsa_self, node, nnode, oipt)) - { - /* - * removed the test for - * (! list_isempty (oipt->id_list)) * Handler is already active. * - * because opaque cababilities ON -> OFF -> ON result in list_isempty (oipt->id_list) - * not being empty. - */ - if (oipt->t_opaque_lsa_self != NULL /* Waiting for a thread call. */ - || oipt->status == PROC_SUSPEND) /* Cannot originate now. */ - continue; - - ospf_opaque_lsa_reoriginate_schedule ((void *) oi, - OSPF_OPAQUE_LINK_LSA, oipt->opaque_type); - } - } - - if (! list_isempty (ospf_opaque_type10_funclist) - && ! list_isempty (area->opaque_lsa_self)) - { - for (ALL_LIST_ELEMENTS (area->opaque_lsa_self, node, nnode, oipt)) - { - /* - * removed the test for - * (! list_isempty (oipt->id_list)) * Handler is already active. * - * because opaque cababilities ON -> OFF -> ON result in list_isempty (oipt->id_list) - * not being empty. - */ - if (oipt->t_opaque_lsa_self != NULL /* Waiting for a thread call. */ - || oipt->status == PROC_SUSPEND) /* Cannot originate now. */ - continue; - - ospf_opaque_lsa_reoriginate_schedule ((void *) area, - OSPF_OPAQUE_AREA_LSA, oipt->opaque_type); - } - } - - if (! list_isempty (ospf_opaque_type11_funclist) - && ! list_isempty (top->opaque_lsa_self)) - { - for (ALL_LIST_ELEMENTS (top->opaque_lsa_self, node, nnode, oipt)) - { - /* - * removed the test for - * (! list_isempty (oipt->id_list)) * Handler is already active. * - * because opaque cababilities ON -> OFF -> ON result in list_isempty (oipt->id_list) - * not being empty. - */ - if (oipt->t_opaque_lsa_self != NULL /* Waiting for a thread call. */ - || oipt->status == PROC_SUSPEND) /* Cannot originate now. */ - continue; - - ospf_opaque_lsa_reoriginate_schedule ((void *) top, - OSPF_OPAQUE_AS_LSA, oipt->opaque_type); - } - } - - if (delay0 != NULL) - *delay0 = delay; +static int ospf_opaque_type9_lsa_originate(struct thread *t); +static int ospf_opaque_type10_lsa_originate(struct thread *t); +static int ospf_opaque_type11_lsa_originate(struct thread *t); +static void ospf_opaque_lsa_reoriginate_resume(struct list *listtop, void *arg); + +void ospf_opaque_lsa_originate_schedule(struct ospf_interface *oi, int *delay0) +{ + struct ospf *top; + struct ospf_area *area; + struct listnode *node, *nnode; + struct opaque_info_per_type *oipt; + int delay = 0; + + if ((top = oi_to_top(oi)) == NULL || (area = oi->area) == NULL) { + zlog_warn( + "ospf_opaque_lsa_originate_schedule: Invalid argument?"); + goto out; + } + + /* It may not a right time to schedule origination now. */ + if (!CHECK_FLAG(top->opaque, OPAQUE_OPERATION_READY_BIT)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_opaque_lsa_originate_schedule: Not operational."); + goto out; /* This is not an error. */ + } + + if (delay0 != NULL) + delay = *delay0; + + /* + * There might be some entries that have been waiting for triggering + * of per opaque-type re-origination get resumed. + */ + ospf_opaque_lsa_reoriginate_resume(oi->opaque_lsa_self, (void *)oi); + ospf_opaque_lsa_reoriginate_resume(area->opaque_lsa_self, (void *)area); + ospf_opaque_lsa_reoriginate_resume(top->opaque_lsa_self, (void *)top); + + /* + * Now, schedule origination of all Opaque-LSAs per opaque-type. + */ + if (!list_isempty(ospf_opaque_type9_funclist) + && list_isempty(oi->opaque_lsa_self) + && oi->t_opaque_lsa_self == NULL) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "Schedule Type-9 Opaque-LSA origination in %d ms later.", + delay); + oi->t_opaque_lsa_self = NULL; + thread_add_timer_msec(master, ospf_opaque_type9_lsa_originate, + oi, delay, &oi->t_opaque_lsa_self); + delay += top->min_ls_interval; + } + + if (!list_isempty(ospf_opaque_type10_funclist) + && list_isempty(area->opaque_lsa_self) + && area->t_opaque_lsa_self == NULL) { + /* + * One AREA may contain multiple OIs, but above 2nd and 3rd + * conditions prevent from scheduling the originate function + * again and again. + */ + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "Schedule Type-10 Opaque-LSA origination in %d ms later.", + delay); + area->t_opaque_lsa_self = NULL; + thread_add_timer_msec(master, ospf_opaque_type10_lsa_originate, + area, delay, &area->t_opaque_lsa_self); + delay += top->min_ls_interval; + } + + if (!list_isempty(ospf_opaque_type11_funclist) + && list_isempty(top->opaque_lsa_self) + && top->t_opaque_lsa_self == NULL) { + /* + * One OSPF may contain multiple AREAs, but above 2nd and 3rd + * conditions prevent from scheduling the originate function + * again and again. + */ + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "Schedule Type-11 Opaque-LSA origination in %d ms later.", + delay); + top->t_opaque_lsa_self = NULL; + thread_add_timer_msec(master, ospf_opaque_type11_lsa_originate, + top, delay, &top->t_opaque_lsa_self); + delay += top->min_ls_interval; + } + + /* + * Following section treats a special situation that this node's + * opaque capability has changed as "ON -> OFF -> ON". + */ + if (!list_isempty(ospf_opaque_type9_funclist) + && !list_isempty(oi->opaque_lsa_self)) { + for (ALL_LIST_ELEMENTS(oi->opaque_lsa_self, node, nnode, + oipt)) { + /* + * removed the test for + * (! list_isempty (oipt->id_list)) * Handler is + * already active. * + * because opaque cababilities ON -> OFF -> ON result in + * list_isempty (oipt->id_list) + * not being empty. + */ + if ( + oipt->t_opaque_lsa_self + != NULL /* Waiting for a thread call. */ + || oipt->status == PROC_SUSPEND) /* Cannot + originate + now. */ + continue; + + ospf_opaque_lsa_reoriginate_schedule( + (void *)oi, OSPF_OPAQUE_LINK_LSA, + oipt->opaque_type); + } + } + + if (!list_isempty(ospf_opaque_type10_funclist) + && !list_isempty(area->opaque_lsa_self)) { + for (ALL_LIST_ELEMENTS(area->opaque_lsa_self, node, nnode, + oipt)) { + /* + * removed the test for + * (! list_isempty (oipt->id_list)) * Handler is + * already active. * + * because opaque cababilities ON -> OFF -> ON result in + * list_isempty (oipt->id_list) + * not being empty. + */ + if ( + oipt->t_opaque_lsa_self + != NULL /* Waiting for a thread call. */ + || oipt->status == PROC_SUSPEND) /* Cannot + originate + now. */ + continue; + + ospf_opaque_lsa_reoriginate_schedule( + (void *)area, OSPF_OPAQUE_AREA_LSA, + oipt->opaque_type); + } + } + + if (!list_isempty(ospf_opaque_type11_funclist) + && !list_isempty(top->opaque_lsa_self)) { + for (ALL_LIST_ELEMENTS(top->opaque_lsa_self, node, nnode, + oipt)) { + /* + * removed the test for + * (! list_isempty (oipt->id_list)) * Handler is + * already active. * + * because opaque cababilities ON -> OFF -> ON result in + * list_isempty (oipt->id_list) + * not being empty. + */ + if ( + oipt->t_opaque_lsa_self + != NULL /* Waiting for a thread call. */ + || oipt->status == PROC_SUSPEND) /* Cannot + originate + now. */ + continue; + + ospf_opaque_lsa_reoriginate_schedule((void *)top, + OSPF_OPAQUE_AS_LSA, + oipt->opaque_type); + } + } + + if (delay0 != NULL) + *delay0 = delay; out: - return; + return; } -static int -ospf_opaque_type9_lsa_originate (struct thread *t) +static int ospf_opaque_type9_lsa_originate(struct thread *t) { - struct ospf_interface *oi; - int rc; + struct ospf_interface *oi; + int rc; - oi = THREAD_ARG (t); - oi->t_opaque_lsa_self = NULL; + oi = THREAD_ARG(t); + oi->t_opaque_lsa_self = NULL; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Timer[Type9-LSA]: Originate Opaque-LSAs for OI %s", - IF_NAME (oi)); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Timer[Type9-LSA]: Originate Opaque-LSAs for OI %s", + IF_NAME(oi)); - rc = opaque_lsa_originate_callback (ospf_opaque_type9_funclist, oi); + rc = opaque_lsa_originate_callback(ospf_opaque_type9_funclist, oi); - return rc; + return rc; } -static int -ospf_opaque_type10_lsa_originate (struct thread *t) +static int ospf_opaque_type10_lsa_originate(struct thread *t) { - struct ospf_area *area; - int rc; + struct ospf_area *area; + int rc; - area = THREAD_ARG (t); - area->t_opaque_lsa_self = NULL; + area = THREAD_ARG(t); + area->t_opaque_lsa_self = NULL; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Timer[Type10-LSA]: Originate Opaque-LSAs for Area %s", - inet_ntoa (area->area_id)); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "Timer[Type10-LSA]: Originate Opaque-LSAs for Area %s", + inet_ntoa(area->area_id)); - rc = opaque_lsa_originate_callback (ospf_opaque_type10_funclist, area); + rc = opaque_lsa_originate_callback(ospf_opaque_type10_funclist, area); - return rc; + return rc; } -static int -ospf_opaque_type11_lsa_originate (struct thread *t) +static int ospf_opaque_type11_lsa_originate(struct thread *t) { - struct ospf *top; - int rc; + struct ospf *top; + int rc; - top = THREAD_ARG (t); - top->t_opaque_lsa_self = NULL; + top = THREAD_ARG(t); + top->t_opaque_lsa_self = NULL; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Timer[Type11-LSA]: Originate AS-External Opaque-LSAs"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "Timer[Type11-LSA]: Originate AS-External Opaque-LSAs"); - rc = opaque_lsa_originate_callback (ospf_opaque_type11_funclist, top); + rc = opaque_lsa_originate_callback(ospf_opaque_type11_funclist, top); - return rc; + return rc; } -static void -ospf_opaque_lsa_reoriginate_resume (struct list *listtop, void *arg) +static void ospf_opaque_lsa_reoriginate_resume(struct list *listtop, void *arg) { - struct listnode *node, *nnode; - struct opaque_info_per_type *oipt; - struct ospf_opaque_functab *functab; + struct listnode *node, *nnode; + struct opaque_info_per_type *oipt; + struct ospf_opaque_functab *functab; - if (listtop == NULL) - goto out; + if (listtop == NULL) + goto out; - /* - * Pickup oipt entries those which in SUSPEND status, and give - * them a chance to start re-origination now. - */ - for (ALL_LIST_ELEMENTS (listtop, node, nnode, oipt)) - { - if (oipt->status != PROC_SUSPEND) - continue; + /* + * Pickup oipt entries those which in SUSPEND status, and give + * them a chance to start re-origination now. + */ + for (ALL_LIST_ELEMENTS(listtop, node, nnode, oipt)) { + if (oipt->status != PROC_SUSPEND) + continue; - oipt->status = PROC_NORMAL; + oipt->status = PROC_NORMAL; - if ((functab = oipt->functab) == NULL - || functab->lsa_originator == NULL) - continue; + if ((functab = oipt->functab) == NULL + || functab->lsa_originator == NULL) + continue; - if ((* functab->lsa_originator)(arg) != 0) - { - zlog_warn ("ospf_opaque_lsa_reoriginate_resume: Failed (opaque-type=%u)", oipt->opaque_type); - continue; - } - } + if ((*functab->lsa_originator)(arg) != 0) { + zlog_warn( + "ospf_opaque_lsa_reoriginate_resume: Failed (opaque-type=%u)", + oipt->opaque_type); + continue; + } + } out: - return; -} - -struct ospf_lsa * -ospf_opaque_lsa_install (struct ospf_lsa *lsa, int rt_recalc) -{ - struct ospf_lsa *new = NULL; - struct opaque_info_per_type *oipt; - struct opaque_info_per_id *oipi; - struct ospf *top; - - /* Don't take "rt_recalc" into consideration for now. *//* XXX */ - - if (! IS_LSA_SELF (lsa)) - { - new = lsa; /* Don't touch this LSA. */ - goto out; - } - - if (IS_DEBUG_OSPF (lsa, LSA_INSTALL)) - zlog_debug ("Install Type-%u Opaque-LSA: [opaque-type=%u, opaque-id=%x]", lsa->data->type, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)), GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr))); - - /* Replace the existing lsa with the new one. */ - if ((oipt = lookup_opaque_info_by_type (lsa)) != NULL - && (oipi = lookup_opaque_info_by_id (oipt, lsa)) != NULL) - { - ospf_lsa_unlock (&oipi->lsa); - oipi->lsa = ospf_lsa_lock (lsa); - } - /* Register the new lsa entry and get its control info. */ - else - if ((oipi = register_opaque_lsa (lsa)) == NULL) - { - zlog_warn ("ospf_opaque_lsa_install: register_opaque_lsa() ?"); - goto out; - } - - /* - * Make use of a common mechanism (ospf_lsa_refresh_walker) - * for periodic refresh of self-originated Opaque-LSAs. - */ - switch (lsa->data->type) - { - case OSPF_OPAQUE_LINK_LSA: - if ((top = oi_to_top (lsa->oi)) == NULL) - { - /* Above conditions must have passed. */ - zlog_warn ("ospf_opaque_lsa_install: Sonmething wrong?"); - goto out; - } - break; - case OSPF_OPAQUE_AREA_LSA: - if (lsa->area == NULL || (top = lsa->area->ospf) == NULL) - { - /* Above conditions must have passed. */ - zlog_warn ("ospf_opaque_lsa_install: Sonmething wrong?"); - goto out; - } - break; - case OSPF_OPAQUE_AS_LSA: - top = ospf_lookup (); - if (lsa->area != NULL && (top = lsa->area->ospf) == NULL) - { - /* Above conditions must have passed. */ - zlog_warn ("ospf_opaque_lsa_install: Sonmething wrong?"); - goto out; - } - break; - default: - zlog_warn ("ospf_opaque_lsa_install: Unexpected LSA-type(%u)", lsa->data->type); - goto out; - } - - ospf_refresher_register_lsa (top, lsa); - new = lsa; + return; +} + +struct ospf_lsa *ospf_opaque_lsa_install(struct ospf_lsa *lsa, int rt_recalc) +{ + struct ospf_lsa *new = NULL; + struct opaque_info_per_type *oipt; + struct opaque_info_per_id *oipi; + struct ospf *top; + + /* Don't take "rt_recalc" into consideration for now. */ /* XXX */ + + if (!IS_LSA_SELF(lsa)) { + new = lsa; /* Don't touch this LSA. */ + goto out; + } + + if (IS_DEBUG_OSPF(lsa, LSA_INSTALL)) + zlog_debug( + "Install Type-%u Opaque-LSA: [opaque-type=%u, opaque-id=%x]", + lsa->data->type, + GET_OPAQUE_TYPE(ntohl(lsa->data->id.s_addr)), + GET_OPAQUE_ID(ntohl(lsa->data->id.s_addr))); + + /* Replace the existing lsa with the new one. */ + if ((oipt = lookup_opaque_info_by_type(lsa)) != NULL + && (oipi = lookup_opaque_info_by_id(oipt, lsa)) != NULL) { + ospf_lsa_unlock(&oipi->lsa); + oipi->lsa = ospf_lsa_lock(lsa); + } + /* Register the new lsa entry and get its control info. */ + else if ((oipi = register_opaque_lsa(lsa)) == NULL) { + zlog_warn("ospf_opaque_lsa_install: register_opaque_lsa() ?"); + goto out; + } + + /* + * Make use of a common mechanism (ospf_lsa_refresh_walker) + * for periodic refresh of self-originated Opaque-LSAs. + */ + switch (lsa->data->type) { + case OSPF_OPAQUE_LINK_LSA: + if ((top = oi_to_top(lsa->oi)) == NULL) { + /* Above conditions must have passed. */ + zlog_warn("ospf_opaque_lsa_install: Sonmething wrong?"); + goto out; + } + break; + case OSPF_OPAQUE_AREA_LSA: + if (lsa->area == NULL || (top = lsa->area->ospf) == NULL) { + /* Above conditions must have passed. */ + zlog_warn("ospf_opaque_lsa_install: Sonmething wrong?"); + goto out; + } + break; + case OSPF_OPAQUE_AS_LSA: + top = ospf_lookup(); + if (lsa->area != NULL && (top = lsa->area->ospf) == NULL) { + /* Above conditions must have passed. */ + zlog_warn("ospf_opaque_lsa_install: Sonmething wrong?"); + goto out; + } + break; + default: + zlog_warn("ospf_opaque_lsa_install: Unexpected LSA-type(%u)", + lsa->data->type); + goto out; + } + + ospf_refresher_register_lsa(top, lsa); + new = lsa; out: - return new; + return new; } -struct ospf_lsa * -ospf_opaque_lsa_refresh (struct ospf_lsa *lsa) +struct ospf_lsa *ospf_opaque_lsa_refresh(struct ospf_lsa *lsa) { - struct ospf *ospf; - struct ospf_opaque_functab *functab; - struct ospf_lsa *new = NULL; - - ospf = ospf_lookup (); + struct ospf *ospf; + struct ospf_opaque_functab *functab; + struct ospf_lsa *new = NULL; + + ospf = ospf_lookup(); - if ((functab = ospf_opaque_functab_lookup (lsa)) == NULL - || functab->lsa_refresher == NULL) - { - /* - * Though this LSA seems to have originated on this node, the - * handling module for this "lsa-type and opaque-type" was - * already deleted sometime ago. - * Anyway, this node still has a responsibility to flush this - * LSA from the routing domain. - */ - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("LSA[Type%d:%s]: Flush stray Opaque-LSA", lsa->data->type, inet_ntoa (lsa->data->id)); + if ((functab = ospf_opaque_functab_lookup(lsa)) == NULL + || functab->lsa_refresher == NULL) { + /* + * Though this LSA seems to have originated on this node, the + * handling module for this "lsa-type and opaque-type" was + * already deleted sometime ago. + * Anyway, this node still has a responsibility to flush this + * LSA from the routing domain. + */ + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("LSA[Type%d:%s]: Flush stray Opaque-LSA", + lsa->data->type, inet_ntoa(lsa->data->id)); - lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); - ospf_lsa_flush (ospf, lsa); - } - else - new = (* functab->lsa_refresher)(lsa); + lsa->data->ls_age = htons(OSPF_LSA_MAXAGE); + ospf_lsa_flush(ospf, lsa); + } else + new = (*functab->lsa_refresher)(lsa); - return new; + return new; } /*------------------------------------------------------------------------* @@ -1655,521 +1627,536 @@ ospf_opaque_lsa_refresh (struct ospf_lsa *lsa) #define OSPF_OPAQUE_TIMER_ON(T,F,L,V) thread_add_timer_msec (master, (F), (L), (V), &(T)) -static struct ospf_lsa *pseudo_lsa (struct ospf_interface *oi, struct ospf_area *area, u_char lsa_type, u_char opaque_type); -static int ospf_opaque_type9_lsa_reoriginate_timer (struct thread *t); -static int ospf_opaque_type10_lsa_reoriginate_timer (struct thread *t); -static int ospf_opaque_type11_lsa_reoriginate_timer (struct thread *t); -static int ospf_opaque_lsa_refresh_timer (struct thread *t); - -void -ospf_opaque_lsa_reoriginate_schedule (void *lsa_type_dependent, - u_char lsa_type, u_char opaque_type) -{ - struct ospf *top; - struct ospf_area dummy, *area = NULL; - struct ospf_interface *oi = NULL; - - struct ospf_lsa *lsa; - struct opaque_info_per_type *oipt; - int (*func) (struct thread * t) = NULL; - int delay; - - switch (lsa_type) - { - case OSPF_OPAQUE_LINK_LSA: - if ((oi = (struct ospf_interface *) lsa_type_dependent) == NULL) - { - zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:" - " Type-9 Opaque-LSA: Invalid parameter?"); - goto out; - } - if ((top = oi_to_top (oi)) == NULL) - { - zlog_warn ("ospf_opaque_lsa_reoriginate_schedule: OI(%s) -> TOP?", - IF_NAME (oi)); - goto out; - } - if (!list_isempty (ospf_opaque_type9_funclist) - && list_isempty (oi->opaque_lsa_self) - && oi->t_opaque_lsa_self != NULL) - { - zlog_warn ("Type-9 Opaque-LSA (opaque_type=%u):" - " Common origination for OI(%s) has already started", - opaque_type, IF_NAME (oi)); - goto out; - } - func = ospf_opaque_type9_lsa_reoriginate_timer; - break; - case OSPF_OPAQUE_AREA_LSA: - if ((area = (struct ospf_area *) lsa_type_dependent) == NULL) - { - zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:" - " Type-10 Opaque-LSA: Invalid parameter?"); - goto out; - } - if ((top = area->ospf) == NULL) - { - zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:" - " AREA(%s) -> TOP?", inet_ntoa (area->area_id)); - goto out; - } - if (!list_isempty (ospf_opaque_type10_funclist) - && list_isempty (area->opaque_lsa_self) - && area->t_opaque_lsa_self != NULL) - { - zlog_warn ("Type-10 Opaque-LSA (opaque_type=%u):" - " Common origination for AREA(%s) has already started", - opaque_type, inet_ntoa (area->area_id)); - goto out; - } - func = ospf_opaque_type10_lsa_reoriginate_timer; - break; - case OSPF_OPAQUE_AS_LSA: - if ((top = (struct ospf *) lsa_type_dependent) == NULL) - { - zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:" - " Type-11 Opaque-LSA: Invalid parameter?"); - goto out; - } - if (!list_isempty (ospf_opaque_type11_funclist) - && list_isempty (top->opaque_lsa_self) - && top->t_opaque_lsa_self != NULL) - { - zlog_warn ("Type-11 Opaque-LSA (opaque_type=%u):" - " Common origination has already started", opaque_type); - goto out; - } - - /* Fake "area" to pass "ospf" to a lookup function later. */ - dummy.ospf = top; - area = &dummy; - - func = ospf_opaque_type11_lsa_reoriginate_timer; - break; - default: - zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:" - " Unexpected LSA-type(%u)", - lsa_type); - goto out; - } - - /* It may not a right time to schedule reorigination now. */ - if (!CHECK_FLAG (top->opaque, OPAQUE_OPERATION_READY_BIT)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_opaque_lsa_reoriginate_schedule: Not operational."); - goto out; /* This is not an error. */ - } - - /* Generate a dummy lsa to be passed for a lookup function. */ - lsa = pseudo_lsa (oi, area, lsa_type, opaque_type); - - if ((oipt = lookup_opaque_info_by_type (lsa)) == NULL) - { - struct ospf_opaque_functab *functab; - if ((functab = ospf_opaque_functab_lookup (lsa)) == NULL) - { - zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:" - " No associated function?: lsa_type(%u)," - " opaque_type(%u)", - lsa_type, opaque_type); - goto out; - } - if ((oipt = register_opaque_info_per_type (functab, lsa)) == NULL) - { - zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:" - " Cannot get a control info?: lsa_type(%u)," - " opaque_type(%u)", - lsa_type, opaque_type); - goto out; - } - } - - if (oipt->t_opaque_lsa_self != NULL) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Type-%u Opaque-LSA has already scheduled to" - " RE-ORIGINATE: [opaque-type=%u]", - lsa_type, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr))); - goto out; - } - - /* - * Different from initial origination time, in which various conditions - * (opaque capability, neighbor status etc) are assured by caller of - * the originating function "ospf_opaque_lsa_originate_schedule ()", - * it is highly possible that these conditions might not be satisfied - * at the time of re-origination function is to be called. - */ - delay = top->min_ls_interval; /* XXX */ - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Schedule Type-%u Opaque-LSA to RE-ORIGINATE in %d" - " ms later: [opaque-type=%u]", - lsa_type, delay, - GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr))); - - OSPF_OPAQUE_TIMER_ON (oipt->t_opaque_lsa_self, func, oipt, delay * 1000); +static struct ospf_lsa *pseudo_lsa(struct ospf_interface *oi, + struct ospf_area *area, u_char lsa_type, + u_char opaque_type); +static int ospf_opaque_type9_lsa_reoriginate_timer(struct thread *t); +static int ospf_opaque_type10_lsa_reoriginate_timer(struct thread *t); +static int ospf_opaque_type11_lsa_reoriginate_timer(struct thread *t); +static int ospf_opaque_lsa_refresh_timer(struct thread *t); + +void ospf_opaque_lsa_reoriginate_schedule(void *lsa_type_dependent, + u_char lsa_type, u_char opaque_type) +{ + struct ospf *top; + struct ospf_area dummy, *area = NULL; + struct ospf_interface *oi = NULL; + + struct ospf_lsa *lsa; + struct opaque_info_per_type *oipt; + int (*func)(struct thread * t) = NULL; + int delay; + + switch (lsa_type) { + case OSPF_OPAQUE_LINK_LSA: + if ((oi = (struct ospf_interface *)lsa_type_dependent) + == NULL) { + zlog_warn( + "ospf_opaque_lsa_reoriginate_schedule:" + " Type-9 Opaque-LSA: Invalid parameter?"); + goto out; + } + if ((top = oi_to_top(oi)) == NULL) { + zlog_warn( + "ospf_opaque_lsa_reoriginate_schedule: OI(%s) -> TOP?", + IF_NAME(oi)); + goto out; + } + if (!list_isempty(ospf_opaque_type9_funclist) + && list_isempty(oi->opaque_lsa_self) + && oi->t_opaque_lsa_self != NULL) { + zlog_warn( + "Type-9 Opaque-LSA (opaque_type=%u):" + " Common origination for OI(%s) has already started", + opaque_type, IF_NAME(oi)); + goto out; + } + func = ospf_opaque_type9_lsa_reoriginate_timer; + break; + case OSPF_OPAQUE_AREA_LSA: + if ((area = (struct ospf_area *)lsa_type_dependent) == NULL) { + zlog_warn( + "ospf_opaque_lsa_reoriginate_schedule:" + " Type-10 Opaque-LSA: Invalid parameter?"); + goto out; + } + if ((top = area->ospf) == NULL) { + zlog_warn( + "ospf_opaque_lsa_reoriginate_schedule:" + " AREA(%s) -> TOP?", + inet_ntoa(area->area_id)); + goto out; + } + if (!list_isempty(ospf_opaque_type10_funclist) + && list_isempty(area->opaque_lsa_self) + && area->t_opaque_lsa_self != NULL) { + zlog_warn( + "Type-10 Opaque-LSA (opaque_type=%u):" + " Common origination for AREA(%s) has already started", + opaque_type, inet_ntoa(area->area_id)); + goto out; + } + func = ospf_opaque_type10_lsa_reoriginate_timer; + break; + case OSPF_OPAQUE_AS_LSA: + if ((top = (struct ospf *)lsa_type_dependent) == NULL) { + zlog_warn( + "ospf_opaque_lsa_reoriginate_schedule:" + " Type-11 Opaque-LSA: Invalid parameter?"); + goto out; + } + if (!list_isempty(ospf_opaque_type11_funclist) + && list_isempty(top->opaque_lsa_self) + && top->t_opaque_lsa_self != NULL) { + zlog_warn( + "Type-11 Opaque-LSA (opaque_type=%u):" + " Common origination has already started", + opaque_type); + goto out; + } + + /* Fake "area" to pass "ospf" to a lookup function later. */ + dummy.ospf = top; + area = &dummy; + + func = ospf_opaque_type11_lsa_reoriginate_timer; + break; + default: + zlog_warn( + "ospf_opaque_lsa_reoriginate_schedule:" + " Unexpected LSA-type(%u)", + lsa_type); + goto out; + } + + /* It may not a right time to schedule reorigination now. */ + if (!CHECK_FLAG(top->opaque, OPAQUE_OPERATION_READY_BIT)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_opaque_lsa_reoriginate_schedule: Not operational."); + goto out; /* This is not an error. */ + } + + /* Generate a dummy lsa to be passed for a lookup function. */ + lsa = pseudo_lsa(oi, area, lsa_type, opaque_type); + + if ((oipt = lookup_opaque_info_by_type(lsa)) == NULL) { + struct ospf_opaque_functab *functab; + if ((functab = ospf_opaque_functab_lookup(lsa)) == NULL) { + zlog_warn( + "ospf_opaque_lsa_reoriginate_schedule:" + " No associated function?: lsa_type(%u)," + " opaque_type(%u)", + lsa_type, opaque_type); + goto out; + } + if ((oipt = register_opaque_info_per_type(functab, lsa)) + == NULL) { + zlog_warn( + "ospf_opaque_lsa_reoriginate_schedule:" + " Cannot get a control info?: lsa_type(%u)," + " opaque_type(%u)", + lsa_type, opaque_type); + goto out; + } + } + + if (oipt->t_opaque_lsa_self != NULL) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "Type-%u Opaque-LSA has already scheduled to" + " RE-ORIGINATE: [opaque-type=%u]", + lsa_type, + GET_OPAQUE_TYPE(ntohl(lsa->data->id.s_addr))); + goto out; + } + + /* + * Different from initial origination time, in which various conditions + * (opaque capability, neighbor status etc) are assured by caller of + * the originating function "ospf_opaque_lsa_originate_schedule ()", + * it is highly possible that these conditions might not be satisfied + * at the time of re-origination function is to be called. + */ + delay = top->min_ls_interval; /* XXX */ + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "Schedule Type-%u Opaque-LSA to RE-ORIGINATE in %d" + " ms later: [opaque-type=%u]", + lsa_type, delay, + GET_OPAQUE_TYPE(ntohl(lsa->data->id.s_addr))); + + OSPF_OPAQUE_TIMER_ON(oipt->t_opaque_lsa_self, func, oipt, delay * 1000); out: - return; -} - -static struct ospf_lsa * -pseudo_lsa (struct ospf_interface *oi, struct ospf_area *area, - u_char lsa_type, u_char opaque_type) -{ - static struct ospf_lsa lsa = { 0 }; - static struct lsa_header lsah = { 0 }; - u_int32_t tmp; - - lsa.oi = oi; - lsa.area = area; - lsa.data = &lsah; - - lsah.type = lsa_type; - tmp = SET_OPAQUE_LSID (opaque_type, 0); /* Opaque-ID is unused here. */ - lsah.id.s_addr = htonl (tmp); - - return &lsa; -} - -static int -ospf_opaque_type9_lsa_reoriginate_timer (struct thread *t) -{ - struct opaque_info_per_type *oipt; - struct ospf_opaque_functab *functab; - struct ospf *top; - struct ospf_interface *oi; - int rc = -1; - - oipt = THREAD_ARG (t); - oipt->t_opaque_lsa_self = NULL; - - if ((functab = oipt->functab) == NULL - || functab->lsa_originator == NULL) - { - zlog_warn ("ospf_opaque_type9_lsa_reoriginate_timer: No associated function?"); - goto out; - } - - oi = (struct ospf_interface *) oipt->owner; - if ((top = oi_to_top (oi)) == NULL) - { - zlog_warn ("ospf_opaque_type9_lsa_reoriginate_timer: Something wrong?"); - goto out; - } - - if (! CHECK_FLAG (top->config, OSPF_OPAQUE_CAPABLE) - || ! ospf_if_is_enable (oi) - || ospf_nbr_count_opaque_capable (oi) == 0) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Suspend re-origination of Type-9 Opaque-LSAs (opaque-type=%u) for a while...", oipt->opaque_type); - - oipt->status = PROC_SUSPEND; - rc = 0; - goto out; - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Timer[Type9-LSA]: Re-originate Opaque-LSAs (opaque-type=%u) for OI (%s)", oipt->opaque_type, IF_NAME (oi)); - - rc = (* functab->lsa_originator)(oi); + return; +} + +static struct ospf_lsa *pseudo_lsa(struct ospf_interface *oi, + struct ospf_area *area, u_char lsa_type, + u_char opaque_type) +{ + static struct ospf_lsa lsa = {0}; + static struct lsa_header lsah = {0}; + u_int32_t tmp; + + lsa.oi = oi; + lsa.area = area; + lsa.data = &lsah; + + lsah.type = lsa_type; + tmp = SET_OPAQUE_LSID(opaque_type, 0); /* Opaque-ID is unused here. */ + lsah.id.s_addr = htonl(tmp); + + return &lsa; +} + +static int ospf_opaque_type9_lsa_reoriginate_timer(struct thread *t) +{ + struct opaque_info_per_type *oipt; + struct ospf_opaque_functab *functab; + struct ospf *top; + struct ospf_interface *oi; + int rc = -1; + + oipt = THREAD_ARG(t); + oipt->t_opaque_lsa_self = NULL; + + if ((functab = oipt->functab) == NULL + || functab->lsa_originator == NULL) { + zlog_warn( + "ospf_opaque_type9_lsa_reoriginate_timer: No associated function?"); + goto out; + } + + oi = (struct ospf_interface *)oipt->owner; + if ((top = oi_to_top(oi)) == NULL) { + zlog_warn( + "ospf_opaque_type9_lsa_reoriginate_timer: Something wrong?"); + goto out; + } + + if (!CHECK_FLAG(top->config, OSPF_OPAQUE_CAPABLE) + || !ospf_if_is_enable(oi) + || ospf_nbr_count_opaque_capable(oi) == 0) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "Suspend re-origination of Type-9 Opaque-LSAs (opaque-type=%u) for a while...", + oipt->opaque_type); + + oipt->status = PROC_SUSPEND; + rc = 0; + goto out; + } + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "Timer[Type9-LSA]: Re-originate Opaque-LSAs (opaque-type=%u) for OI (%s)", + oipt->opaque_type, IF_NAME(oi)); + + rc = (*functab->lsa_originator)(oi); out: - return rc; -} - -static int -ospf_opaque_type10_lsa_reoriginate_timer (struct thread *t) -{ - struct opaque_info_per_type *oipt; - struct ospf_opaque_functab *functab; - struct listnode *node, *nnode; - struct ospf *top; - struct ospf_area *area; - struct ospf_interface *oi; - int n, rc = -1; - - oipt = THREAD_ARG (t); - oipt->t_opaque_lsa_self = NULL; - - if ((functab = oipt->functab) == NULL - || functab->lsa_originator == NULL) - { - zlog_warn ("ospf_opaque_type10_lsa_reoriginate_timer: No associated function?"); - goto out; - } - - area = (struct ospf_area *) oipt->owner; - if (area == NULL || (top = area->ospf) == NULL) - { - zlog_warn ("ospf_opaque_type10_lsa_reoriginate_timer: Something wrong?"); - goto out; - } - - /* There must be at least one "opaque-capable, full-state" neighbor. */ - n = 0; - for (ALL_LIST_ELEMENTS (area->oiflist, node, nnode, oi)) - { - if ((n = ospf_nbr_count_opaque_capable (oi)) > 0) - break; - } - - if (n == 0 || ! CHECK_FLAG (top->config, OSPF_OPAQUE_CAPABLE)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Suspend re-origination of Type-10 Opaque-LSAs" - " (opaque-type=%u) for a while...", - oipt->opaque_type); - - oipt->status = PROC_SUSPEND; - rc = 0; - goto out; - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Timer[Type10-LSA]: Re-originate Opaque-LSAs" - " (opaque-type=%u) for Area %s", - oipt->opaque_type, inet_ntoa (area->area_id)); - - rc = (* functab->lsa_originator)(area); + return rc; +} + +static int ospf_opaque_type10_lsa_reoriginate_timer(struct thread *t) +{ + struct opaque_info_per_type *oipt; + struct ospf_opaque_functab *functab; + struct listnode *node, *nnode; + struct ospf *top; + struct ospf_area *area; + struct ospf_interface *oi; + int n, rc = -1; + + oipt = THREAD_ARG(t); + oipt->t_opaque_lsa_self = NULL; + + if ((functab = oipt->functab) == NULL + || functab->lsa_originator == NULL) { + zlog_warn( + "ospf_opaque_type10_lsa_reoriginate_timer: No associated function?"); + goto out; + } + + area = (struct ospf_area *)oipt->owner; + if (area == NULL || (top = area->ospf) == NULL) { + zlog_warn( + "ospf_opaque_type10_lsa_reoriginate_timer: Something wrong?"); + goto out; + } + + /* There must be at least one "opaque-capable, full-state" neighbor. */ + n = 0; + for (ALL_LIST_ELEMENTS(area->oiflist, node, nnode, oi)) { + if ((n = ospf_nbr_count_opaque_capable(oi)) > 0) + break; + } + + if (n == 0 || !CHECK_FLAG(top->config, OSPF_OPAQUE_CAPABLE)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "Suspend re-origination of Type-10 Opaque-LSAs" + " (opaque-type=%u) for a while...", + oipt->opaque_type); + + oipt->status = PROC_SUSPEND; + rc = 0; + goto out; + } + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "Timer[Type10-LSA]: Re-originate Opaque-LSAs" + " (opaque-type=%u) for Area %s", + oipt->opaque_type, inet_ntoa(area->area_id)); + + rc = (*functab->lsa_originator)(area); out: - return rc; -} - -static int -ospf_opaque_type11_lsa_reoriginate_timer (struct thread *t) -{ - struct opaque_info_per_type *oipt; - struct ospf_opaque_functab *functab; - struct ospf *top; - int rc = -1; - - oipt = THREAD_ARG (t); - oipt->t_opaque_lsa_self = NULL; - - if ((functab = oipt->functab) == NULL - || functab->lsa_originator == NULL) - { - zlog_warn ("ospf_opaque_type11_lsa_reoriginate_timer:" - " No associated function?"); - goto out; - } - - if ((top = (struct ospf *) oipt->owner) == NULL) - { - zlog_warn ("ospf_opaque_type11_lsa_reoriginate_timer: Something wrong?"); - goto out; - } - - if (! CHECK_FLAG (top->config, OSPF_OPAQUE_CAPABLE)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Suspend re-origination of Type-11 Opaque-LSAs (opaque-type=%u) for a while...", oipt->opaque_type); - - oipt->status = PROC_SUSPEND; - rc = 0; - goto out; - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Timer[Type11-LSA]: Re-originate Opaque-LSAs (opaque-type=%u).", oipt->opaque_type); - - rc = (* functab->lsa_originator)(top); + return rc; +} + +static int ospf_opaque_type11_lsa_reoriginate_timer(struct thread *t) +{ + struct opaque_info_per_type *oipt; + struct ospf_opaque_functab *functab; + struct ospf *top; + int rc = -1; + + oipt = THREAD_ARG(t); + oipt->t_opaque_lsa_self = NULL; + + if ((functab = oipt->functab) == NULL + || functab->lsa_originator == NULL) { + zlog_warn( + "ospf_opaque_type11_lsa_reoriginate_timer:" + " No associated function?"); + goto out; + } + + if ((top = (struct ospf *)oipt->owner) == NULL) { + zlog_warn( + "ospf_opaque_type11_lsa_reoriginate_timer: Something wrong?"); + goto out; + } + + if (!CHECK_FLAG(top->config, OSPF_OPAQUE_CAPABLE)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "Suspend re-origination of Type-11 Opaque-LSAs (opaque-type=%u) for a while...", + oipt->opaque_type); + + oipt->status = PROC_SUSPEND; + rc = 0; + goto out; + } + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "Timer[Type11-LSA]: Re-originate Opaque-LSAs (opaque-type=%u).", + oipt->opaque_type); + + rc = (*functab->lsa_originator)(top); out: - return rc; -} - -void -ospf_opaque_lsa_refresh_schedule (struct ospf_lsa *lsa0) -{ - struct opaque_info_per_type *oipt; - struct opaque_info_per_id *oipi; - struct ospf_lsa *lsa; - struct ospf *top; - int delay; - - if ((oipt = lookup_opaque_info_by_type (lsa0)) == NULL - || (oipi = lookup_opaque_info_by_id (oipt, lsa0)) == NULL) - { - zlog_warn ("ospf_opaque_lsa_refresh_schedule: Invalid parameter?"); - goto out; - } - - /* Given "lsa0" and current "oipi->lsa" may different, but harmless. */ - if ((lsa = oipi->lsa) == NULL) - { - zlog_warn ("ospf_opaque_lsa_refresh_schedule: Something wrong?"); - goto out; - } - - if (oipi->t_opaque_lsa_self != NULL) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Type-%u Opaque-LSA has already scheduled to REFRESH: [opaque-type=%u, opaque-id=%x]", lsa->data->type, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)), GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr))); - goto out; - } - - /* Delete this lsa from neighbor retransmit-list. */ - switch (lsa->data->type) - { - case OSPF_OPAQUE_LINK_LSA: - case OSPF_OPAQUE_AREA_LSA: - ospf_ls_retransmit_delete_nbr_area (lsa->area, lsa); - break; - case OSPF_OPAQUE_AS_LSA: - top = ospf_lookup (); - if ((lsa0->area != NULL) && (lsa0->area->ospf != NULL)) - top = lsa0->area->ospf; - ospf_ls_retransmit_delete_nbr_as (top, lsa); - break; - default: - zlog_warn ("ospf_opaque_lsa_refresh_schedule: Unexpected LSA-type(%u)", lsa->data->type); - goto out; - } - - delay = ospf_lsa_refresh_delay (lsa); - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Schedule Type-%u Opaque-LSA to REFRESH in %d sec later: [opaque-type=%u, opaque-id=%x]", lsa->data->type, delay, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)), GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr))); - - OSPF_OPAQUE_TIMER_ON (oipi->t_opaque_lsa_self, - ospf_opaque_lsa_refresh_timer, oipi, delay * 1000); + return rc; +} + +void ospf_opaque_lsa_refresh_schedule(struct ospf_lsa *lsa0) +{ + struct opaque_info_per_type *oipt; + struct opaque_info_per_id *oipi; + struct ospf_lsa *lsa; + struct ospf *top; + int delay; + + if ((oipt = lookup_opaque_info_by_type(lsa0)) == NULL + || (oipi = lookup_opaque_info_by_id(oipt, lsa0)) == NULL) { + zlog_warn( + "ospf_opaque_lsa_refresh_schedule: Invalid parameter?"); + goto out; + } + + /* Given "lsa0" and current "oipi->lsa" may different, but harmless. */ + if ((lsa = oipi->lsa) == NULL) { + zlog_warn("ospf_opaque_lsa_refresh_schedule: Something wrong?"); + goto out; + } + + if (oipi->t_opaque_lsa_self != NULL) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "Type-%u Opaque-LSA has already scheduled to REFRESH: [opaque-type=%u, opaque-id=%x]", + lsa->data->type, + GET_OPAQUE_TYPE(ntohl(lsa->data->id.s_addr)), + GET_OPAQUE_ID(ntohl(lsa->data->id.s_addr))); + goto out; + } + + /* Delete this lsa from neighbor retransmit-list. */ + switch (lsa->data->type) { + case OSPF_OPAQUE_LINK_LSA: + case OSPF_OPAQUE_AREA_LSA: + ospf_ls_retransmit_delete_nbr_area(lsa->area, lsa); + break; + case OSPF_OPAQUE_AS_LSA: + top = ospf_lookup(); + if ((lsa0->area != NULL) && (lsa0->area->ospf != NULL)) + top = lsa0->area->ospf; + ospf_ls_retransmit_delete_nbr_as(top, lsa); + break; + default: + zlog_warn( + "ospf_opaque_lsa_refresh_schedule: Unexpected LSA-type(%u)", + lsa->data->type); + goto out; + } + + delay = ospf_lsa_refresh_delay(lsa); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "Schedule Type-%u Opaque-LSA to REFRESH in %d sec later: [opaque-type=%u, opaque-id=%x]", + lsa->data->type, delay, + GET_OPAQUE_TYPE(ntohl(lsa->data->id.s_addr)), + GET_OPAQUE_ID(ntohl(lsa->data->id.s_addr))); + + OSPF_OPAQUE_TIMER_ON(oipi->t_opaque_lsa_self, + ospf_opaque_lsa_refresh_timer, oipi, delay * 1000); out: - return; + return; } -static int -ospf_opaque_lsa_refresh_timer (struct thread *t) +static int ospf_opaque_lsa_refresh_timer(struct thread *t) { - struct opaque_info_per_id *oipi; - struct ospf_opaque_functab *functab; - struct ospf_lsa *lsa; + struct opaque_info_per_id *oipi; + struct ospf_opaque_functab *functab; + struct ospf_lsa *lsa; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Timer[Opaque-LSA]: (Opaque-LSA Refresh expire)"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Timer[Opaque-LSA]: (Opaque-LSA Refresh expire)"); - oipi = THREAD_ARG (t); - oipi->t_opaque_lsa_self = NULL; + oipi = THREAD_ARG(t); + oipi->t_opaque_lsa_self = NULL; - if ((lsa = oipi->lsa) != NULL) - if ((functab = oipi->opqctl_type->functab) != NULL) - if (functab->lsa_refresher != NULL) - (* functab->lsa_refresher)(lsa); + if ((lsa = oipi->lsa) != NULL) + if ((functab = oipi->opqctl_type->functab) != NULL) + if (functab->lsa_refresher != NULL) + (*functab->lsa_refresher)(lsa); - return 0; + return 0; } -void -ospf_opaque_lsa_flush_schedule (struct ospf_lsa *lsa0) +void ospf_opaque_lsa_flush_schedule(struct ospf_lsa *lsa0) { - struct opaque_info_per_type *oipt; - struct opaque_info_per_id *oipi; - struct ospf_lsa *lsa; - struct ospf *top; + struct opaque_info_per_type *oipt; + struct opaque_info_per_id *oipi; + struct ospf_lsa *lsa; + struct ospf *top; - top = ospf_lookup (); + top = ospf_lookup(); - if ((oipt = lookup_opaque_info_by_type (lsa0)) == NULL - || (oipi = lookup_opaque_info_by_id (oipt, lsa0)) == NULL) - { - zlog_warn ("ospf_opaque_lsa_flush_schedule: Invalid parameter?"); - goto out; - } + if ((oipt = lookup_opaque_info_by_type(lsa0)) == NULL + || (oipi = lookup_opaque_info_by_id(oipt, lsa0)) == NULL) { + zlog_warn("ospf_opaque_lsa_flush_schedule: Invalid parameter?"); + goto out; + } - /* Given "lsa0" and current "oipi->lsa" may different, but harmless. */ - if ((lsa = oipi->lsa) == NULL) - { - zlog_warn ("ospf_opaque_lsa_flush_schedule: Something wrong?"); - goto out; - } + /* Given "lsa0" and current "oipi->lsa" may different, but harmless. */ + if ((lsa = oipi->lsa) == NULL) { + zlog_warn("ospf_opaque_lsa_flush_schedule: Something wrong?"); + goto out; + } - /* Delete this lsa from neighbor retransmit-list. */ - switch (lsa->data->type) - { - case OSPF_OPAQUE_LINK_LSA: - case OSPF_OPAQUE_AREA_LSA: - ospf_ls_retransmit_delete_nbr_area (lsa->area, lsa); - break; - case OSPF_OPAQUE_AS_LSA: - if ((lsa0->area != NULL) && (lsa0->area->ospf != NULL)) - top = lsa0->area->ospf; - ospf_ls_retransmit_delete_nbr_as (top, lsa); - break; - default: - zlog_warn ("ospf_opaque_lsa_flush_schedule: Unexpected LSA-type(%u)", lsa->data->type); - goto out; - } + /* Delete this lsa from neighbor retransmit-list. */ + switch (lsa->data->type) { + case OSPF_OPAQUE_LINK_LSA: + case OSPF_OPAQUE_AREA_LSA: + ospf_ls_retransmit_delete_nbr_area(lsa->area, lsa); + break; + case OSPF_OPAQUE_AS_LSA: + if ((lsa0->area != NULL) && (lsa0->area->ospf != NULL)) + top = lsa0->area->ospf; + ospf_ls_retransmit_delete_nbr_as(top, lsa); + break; + default: + zlog_warn( + "ospf_opaque_lsa_flush_schedule: Unexpected LSA-type(%u)", + lsa->data->type); + goto out; + } - /* Dequeue listnode entry from the list. */ - listnode_delete (oipt->id_list, oipi); + /* Dequeue listnode entry from the list. */ + listnode_delete(oipt->id_list, oipi); - /* Avoid misjudgement in the next lookup. */ - if (listcount (oipt->id_list) == 0) - oipt->id_list->head = oipt->id_list->tail = NULL; + /* Avoid misjudgement in the next lookup. */ + if (listcount(oipt->id_list) == 0) + oipt->id_list->head = oipt->id_list->tail = NULL; - /* Disassociate internal control information with the given lsa. */ - free_opaque_info_per_id ((void *) oipi); + /* Disassociate internal control information with the given lsa. */ + free_opaque_info_per_id((void *)oipi); - /* Force given lsa's age to MaxAge. */ - lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); + /* Force given lsa's age to MaxAge. */ + lsa->data->ls_age = htons(OSPF_LSA_MAXAGE); - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Schedule Type-%u Opaque-LSA to FLUSH: [opaque-type=%u, opaque-id=%x]", lsa->data->type, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)), GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr))); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "Schedule Type-%u Opaque-LSA to FLUSH: [opaque-type=%u, opaque-id=%x]", + lsa->data->type, + GET_OPAQUE_TYPE(ntohl(lsa->data->id.s_addr)), + GET_OPAQUE_ID(ntohl(lsa->data->id.s_addr))); - /* This lsa will be flushed and removed eventually. */ - ospf_lsa_flush (top, lsa); + /* This lsa will be flushed and removed eventually. */ + ospf_lsa_flush(top, lsa); out: - return; -} - -void -ospf_opaque_self_originated_lsa_received (struct ospf_neighbor *nbr, - struct ospf_lsa *lsa) -{ - struct ospf *top; - - if ((top = oi_to_top (nbr->oi)) == NULL) - return; - - /* - * Since these LSA entries are not yet installed into corresponding - * LSDB, just flush them without calling ospf_ls_maxage() afterward. - */ - lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); - switch (lsa->data->type) - { - case OSPF_OPAQUE_LINK_LSA: - ospf_flood_through_area (nbr->oi->area, NULL/*inbr*/, lsa); - break; - case OSPF_OPAQUE_AREA_LSA: - ospf_flood_through_area (nbr->oi->area, NULL/*inbr*/, lsa); - break; - case OSPF_OPAQUE_AS_LSA: - ospf_flood_through_as (top, NULL/*inbr*/, lsa); - break; - default: - zlog_warn ("ospf_opaque_self_originated_lsa_received: Unexpected LSA-type(%u)", lsa->data->type); - return; - } - ospf_lsa_discard (lsa); /* List "lsas" will be deleted by caller. */ + return; +} + +void ospf_opaque_self_originated_lsa_received(struct ospf_neighbor *nbr, + struct ospf_lsa *lsa) +{ + struct ospf *top; + + if ((top = oi_to_top(nbr->oi)) == NULL) + return; + + /* + * Since these LSA entries are not yet installed into corresponding + * LSDB, just flush them without calling ospf_ls_maxage() afterward. + */ + lsa->data->ls_age = htons(OSPF_LSA_MAXAGE); + switch (lsa->data->type) { + case OSPF_OPAQUE_LINK_LSA: + ospf_flood_through_area(nbr->oi->area, NULL /*inbr*/, lsa); + break; + case OSPF_OPAQUE_AREA_LSA: + ospf_flood_through_area(nbr->oi->area, NULL /*inbr*/, lsa); + break; + case OSPF_OPAQUE_AS_LSA: + ospf_flood_through_as(top, NULL /*inbr*/, lsa); + break; + default: + zlog_warn( + "ospf_opaque_self_originated_lsa_received: Unexpected LSA-type(%u)", + lsa->data->type); + return; + } + ospf_lsa_discard(lsa); /* List "lsas" will be deleted by caller. */ } /*------------------------------------------------------------------------* * Followings are util functions; probably be used by Opaque-LSAs only... *------------------------------------------------------------------------*/ -struct ospf * -oi_to_top (struct ospf_interface *oi) +struct ospf *oi_to_top(struct ospf_interface *oi) { - struct ospf *top = NULL; - struct ospf_area *area; + struct ospf *top = NULL; + struct ospf_area *area; - if (oi == NULL || (area = oi->area) == NULL || (top = area->ospf) == NULL) - zlog_warn ("Broken relationship for \"OI -> AREA -> OSPF\"?"); + if (oi == NULL || (area = oi->area) == NULL + || (top = area->ospf) == NULL) + zlog_warn("Broken relationship for \"OI -> AREA -> OSPF\"?"); - return top; + return top; } - diff --git a/ospfd/ospf_opaque.h b/ospfd/ospf_opaque.h index 69cbb0766..8bad51e65 100644 --- a/ospfd/ospf_opaque.h +++ b/ospfd/ospf_opaque.h @@ -25,10 +25,9 @@ #include "vty.h" -#define IS_OPAQUE_LSA(type) \ - ((type) == OSPF_OPAQUE_LINK_LSA || \ - (type) == OSPF_OPAQUE_AREA_LSA || \ - (type) == OSPF_OPAQUE_AS_LSA) +#define IS_OPAQUE_LSA(type) \ + ((type) == OSPF_OPAQUE_LINK_LSA || (type) == OSPF_OPAQUE_AREA_LSA \ + || (type) == OSPF_OPAQUE_AS_LSA) /* * Opaque LSA's link state ID is redefined as follows. @@ -42,15 +41,12 @@ #define LSID_OPAQUE_TYPE_MASK 0xff000000 /* 8 bits */ #define LSID_OPAQUE_ID_MASK 0x00ffffff /* 24 bits */ -#define GET_OPAQUE_TYPE(lsid) \ - (((u_int32_t)(lsid) & LSID_OPAQUE_TYPE_MASK) >> 24) +#define GET_OPAQUE_TYPE(lsid) (((u_int32_t)(lsid)&LSID_OPAQUE_TYPE_MASK) >> 24) -#define GET_OPAQUE_ID(lsid) \ - ((u_int32_t)(lsid) & LSID_OPAQUE_ID_MASK) +#define GET_OPAQUE_ID(lsid) ((u_int32_t)(lsid)&LSID_OPAQUE_ID_MASK) -#define SET_OPAQUE_LSID(type, id) \ - ((((type) << 24) & LSID_OPAQUE_TYPE_MASK) \ - | ((id) & LSID_OPAQUE_ID_MASK)) +#define SET_OPAQUE_LSID(type, id) \ + ((((type) << 24) & LSID_OPAQUE_TYPE_MASK) | ((id)&LSID_OPAQUE_ID_MASK)) /* * Opaque LSA types will be assigned by IANA. @@ -72,74 +68,66 @@ /* Ugly hack to make use of an unallocated value for wildcard matching! */ #define OPAQUE_TYPE_WILDCARD 0 -#define OPAQUE_TYPE_RANGE_UNASSIGNED(type) \ - ( OPAQUE_TYPE_MAX <= (type) && (type) <= 127) +#define OPAQUE_TYPE_RANGE_UNASSIGNED(type) \ + (OPAQUE_TYPE_MAX <= (type) && (type) <= 127) -#define OPAQUE_TYPE_RANGE_RESERVED(type) \ - (127 < (type) && (type) <= 255) +#define OPAQUE_TYPE_RANGE_RESERVED(type) (127 < (type) && (type) <= 255) -#define VALID_OPAQUE_INFO_LEN(lsahdr) \ - ((ntohs((lsahdr)->length) >= sizeof (struct lsa_header)) && \ - ((ntohs((lsahdr)->length) % sizeof (u_int32_t)) == 0)) +#define VALID_OPAQUE_INFO_LEN(lsahdr) \ + ((ntohs((lsahdr)->length) >= sizeof(struct lsa_header)) \ + && ((ntohs((lsahdr)->length) % sizeof(u_int32_t)) == 0)) /* Prototypes. */ -extern void ospf_opaque_init (void); -extern void ospf_opaque_term (void); -extern int ospf_opaque_type9_lsa_init (struct ospf_interface *oi); -extern void ospf_opaque_type9_lsa_term (struct ospf_interface *oi); -extern int ospf_opaque_type10_lsa_init (struct ospf_area *area); -extern void ospf_opaque_type10_lsa_term (struct ospf_area *area); -extern int ospf_opaque_type11_lsa_init (struct ospf *ospf); -extern void ospf_opaque_type11_lsa_term (struct ospf *ospf); - -extern int -ospf_register_opaque_functab ( - u_char lsa_type, - u_char opaque_type, - int (* new_if_hook)(struct interface *ifp), - int (* del_if_hook)(struct interface *ifp), - void (* ism_change_hook)(struct ospf_interface *oi, int old_status), - void (* nsm_change_hook)(struct ospf_neighbor *nbr, int old_status), - void (* config_write_router)(struct vty *vty), - void (* config_write_if )(struct vty *vty, struct interface *ifp), - void (* config_write_debug )(struct vty *vty), - void (* show_opaque_info )(struct vty *vty, struct ospf_lsa *lsa), - int (* lsa_originator)(void *arg), - struct ospf_lsa *(* lsa_refresher )(struct ospf_lsa *lsa), - int (* new_lsa_hook)(struct ospf_lsa *lsa), - int (* del_lsa_hook)(struct ospf_lsa *lsa) -); -extern void ospf_delete_opaque_functab (u_char lsa_type, u_char opaque_type); - -extern int ospf_opaque_new_if (struct interface *ifp); -extern int ospf_opaque_del_if (struct interface *ifp); -extern void ospf_opaque_ism_change (struct ospf_interface *oi, - int old_status); -extern void ospf_opaque_nsm_change (struct ospf_neighbor *nbr, - int old_status); -extern void ospf_opaque_config_write_router (struct vty *vty, struct ospf *); -extern void ospf_opaque_config_write_if (struct vty *vty, - struct interface *ifp); -extern void ospf_opaque_config_write_debug (struct vty *vty); -extern void show_opaque_info_detail (struct vty *vty, struct ospf_lsa *lsa); -extern void ospf_opaque_lsa_dump (struct stream *s, u_int16_t length); - -extern void ospf_opaque_lsa_originate_schedule (struct ospf_interface *oi, - int *init_delay); -extern struct ospf_lsa *ospf_opaque_lsa_install (struct ospf_lsa *, - int rt_recalc); -extern struct ospf_lsa *ospf_opaque_lsa_refresh (struct ospf_lsa *lsa); - -extern void ospf_opaque_lsa_reoriginate_schedule (void *lsa_type_dependent, - u_char lsa_type, - u_char opaque_type); -extern void ospf_opaque_lsa_refresh_schedule (struct ospf_lsa *lsa); -extern void ospf_opaque_lsa_flush_schedule (struct ospf_lsa *lsa); - -extern void ospf_opaque_self_originated_lsa_received (struct ospf_neighbor - *nbr, - struct ospf_lsa *lsa); -extern struct ospf *oi_to_top (struct ospf_interface *oi); +extern void ospf_opaque_init(void); +extern void ospf_opaque_term(void); +extern int ospf_opaque_type9_lsa_init(struct ospf_interface *oi); +extern void ospf_opaque_type9_lsa_term(struct ospf_interface *oi); +extern int ospf_opaque_type10_lsa_init(struct ospf_area *area); +extern void ospf_opaque_type10_lsa_term(struct ospf_area *area); +extern int ospf_opaque_type11_lsa_init(struct ospf *ospf); +extern void ospf_opaque_type11_lsa_term(struct ospf *ospf); + +extern int ospf_register_opaque_functab( + u_char lsa_type, u_char opaque_type, + int (*new_if_hook)(struct interface *ifp), + int (*del_if_hook)(struct interface *ifp), + void (*ism_change_hook)(struct ospf_interface *oi, int old_status), + void (*nsm_change_hook)(struct ospf_neighbor *nbr, int old_status), + void (*config_write_router)(struct vty *vty), + void (*config_write_if)(struct vty *vty, struct interface *ifp), + void (*config_write_debug)(struct vty *vty), + void (*show_opaque_info)(struct vty *vty, struct ospf_lsa *lsa), + int (*lsa_originator)(void *arg), + struct ospf_lsa *(*lsa_refresher)(struct ospf_lsa *lsa), + int (*new_lsa_hook)(struct ospf_lsa *lsa), + int (*del_lsa_hook)(struct ospf_lsa *lsa)); +extern void ospf_delete_opaque_functab(u_char lsa_type, u_char opaque_type); + +extern int ospf_opaque_new_if(struct interface *ifp); +extern int ospf_opaque_del_if(struct interface *ifp); +extern void ospf_opaque_ism_change(struct ospf_interface *oi, int old_status); +extern void ospf_opaque_nsm_change(struct ospf_neighbor *nbr, int old_status); +extern void ospf_opaque_config_write_router(struct vty *vty, struct ospf *); +extern void ospf_opaque_config_write_if(struct vty *vty, struct interface *ifp); +extern void ospf_opaque_config_write_debug(struct vty *vty); +extern void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa); +extern void ospf_opaque_lsa_dump(struct stream *s, u_int16_t length); + +extern void ospf_opaque_lsa_originate_schedule(struct ospf_interface *oi, + int *init_delay); +extern struct ospf_lsa *ospf_opaque_lsa_install(struct ospf_lsa *, + int rt_recalc); +extern struct ospf_lsa *ospf_opaque_lsa_refresh(struct ospf_lsa *lsa); + +extern void ospf_opaque_lsa_reoriginate_schedule(void *lsa_type_dependent, + u_char lsa_type, + u_char opaque_type); +extern void ospf_opaque_lsa_refresh_schedule(struct ospf_lsa *lsa); +extern void ospf_opaque_lsa_flush_schedule(struct ospf_lsa *lsa); + +extern void ospf_opaque_self_originated_lsa_received(struct ospf_neighbor *nbr, + struct ospf_lsa *lsa); +extern struct ospf *oi_to_top(struct ospf_interface *oi); #endif /* _ZEBRA_OSPF_OPAQUE_H */ diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 951304c4d..ac2406ec2 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -71,3588 +71,3675 @@ #endif /* Packet Type String. */ -const struct message ospf_packet_type_str[] = -{ - { OSPF_MSG_HELLO, "Hello" }, - { OSPF_MSG_DB_DESC, "Database Description" }, - { OSPF_MSG_LS_REQ, "Link State Request" }, - { OSPF_MSG_LS_UPD, "Link State Update" }, - { OSPF_MSG_LS_ACK, "Link State Acknowledgment" }, - { 0 } -}; +const struct message ospf_packet_type_str[] = { + {OSPF_MSG_HELLO, "Hello"}, + {OSPF_MSG_DB_DESC, "Database Description"}, + {OSPF_MSG_LS_REQ, "Link State Request"}, + {OSPF_MSG_LS_UPD, "Link State Update"}, + {OSPF_MSG_LS_ACK, "Link State Acknowledgment"}, + {0}}; /* Minimum (besides OSPF_HEADER_SIZE) lengths for OSPF packets of particular types, offset is the "type" field of a packet. */ -static const u_int16_t ospf_packet_minlen[] = -{ - 0, - OSPF_HELLO_MIN_SIZE, - OSPF_DB_DESC_MIN_SIZE, - OSPF_LS_REQ_MIN_SIZE, - OSPF_LS_UPD_MIN_SIZE, - OSPF_LS_ACK_MIN_SIZE, +static const u_int16_t ospf_packet_minlen[] = { + 0, + OSPF_HELLO_MIN_SIZE, + OSPF_DB_DESC_MIN_SIZE, + OSPF_LS_REQ_MIN_SIZE, + OSPF_LS_UPD_MIN_SIZE, + OSPF_LS_ACK_MIN_SIZE, }; /* Minimum (besides OSPF_LSA_HEADER_SIZE) lengths for LSAs of particular types, offset is the "LSA type" field. */ -static const u_int16_t ospf_lsa_minlen[] = -{ - 0, - OSPF_ROUTER_LSA_MIN_SIZE, - OSPF_NETWORK_LSA_MIN_SIZE, - OSPF_SUMMARY_LSA_MIN_SIZE, - OSPF_SUMMARY_LSA_MIN_SIZE, - OSPF_AS_EXTERNAL_LSA_MIN_SIZE, - 0, - OSPF_AS_EXTERNAL_LSA_MIN_SIZE, - 0, - 0, - 0, - 0, +static const u_int16_t ospf_lsa_minlen[] = { + 0, + OSPF_ROUTER_LSA_MIN_SIZE, + OSPF_NETWORK_LSA_MIN_SIZE, + OSPF_SUMMARY_LSA_MIN_SIZE, + OSPF_SUMMARY_LSA_MIN_SIZE, + OSPF_AS_EXTERNAL_LSA_MIN_SIZE, + 0, + OSPF_AS_EXTERNAL_LSA_MIN_SIZE, + 0, + 0, + 0, + 0, }; /* for ospf_check_auth() */ -static int ospf_check_sum (struct ospf_header *); +static int ospf_check_sum(struct ospf_header *); /* OSPF authentication checking function */ -static int -ospf_auth_type (struct ospf_interface *oi) +static int ospf_auth_type(struct ospf_interface *oi) { - int auth_type; + int auth_type; - if (OSPF_IF_PARAM (oi, auth_type) == OSPF_AUTH_NOTSET) - auth_type = oi->area->auth_type; - else - auth_type = OSPF_IF_PARAM (oi, auth_type); + if (OSPF_IF_PARAM(oi, auth_type) == OSPF_AUTH_NOTSET) + auth_type = oi->area->auth_type; + else + auth_type = OSPF_IF_PARAM(oi, auth_type); - /* Handle case where MD5 key list is not configured aka Cisco */ - if (auth_type == OSPF_AUTH_CRYPTOGRAPHIC && - list_isempty (OSPF_IF_PARAM (oi, auth_crypt))) - return OSPF_AUTH_NULL; - - return auth_type; + /* Handle case where MD5 key list is not configured aka Cisco */ + if (auth_type == OSPF_AUTH_CRYPTOGRAPHIC + && list_isempty(OSPF_IF_PARAM(oi, auth_crypt))) + return OSPF_AUTH_NULL; + return auth_type; } -struct ospf_packet * -ospf_packet_new (size_t size) +struct ospf_packet *ospf_packet_new(size_t size) { - struct ospf_packet *new; + struct ospf_packet *new; - new = XCALLOC (MTYPE_OSPF_PACKET, sizeof (struct ospf_packet)); - new->s = stream_new (size); + new = XCALLOC(MTYPE_OSPF_PACKET, sizeof(struct ospf_packet)); + new->s = stream_new(size); - return new; + return new; } -void -ospf_packet_free (struct ospf_packet *op) +void ospf_packet_free(struct ospf_packet *op) { - if (op->s) - stream_free (op->s); + if (op->s) + stream_free(op->s); - XFREE (MTYPE_OSPF_PACKET, op); + XFREE(MTYPE_OSPF_PACKET, op); - op = NULL; + op = NULL; } -struct ospf_fifo * -ospf_fifo_new () +struct ospf_fifo *ospf_fifo_new() { - struct ospf_fifo *new; + struct ospf_fifo *new; - new = XCALLOC (MTYPE_OSPF_FIFO, sizeof (struct ospf_fifo)); - return new; + new = XCALLOC(MTYPE_OSPF_FIFO, sizeof(struct ospf_fifo)); + return new; } /* Add new packet to fifo. */ -void -ospf_fifo_push (struct ospf_fifo *fifo, struct ospf_packet *op) +void ospf_fifo_push(struct ospf_fifo *fifo, struct ospf_packet *op) { - if (fifo->tail) - fifo->tail->next = op; - else - fifo->head = op; + if (fifo->tail) + fifo->tail->next = op; + else + fifo->head = op; - fifo->tail = op; + fifo->tail = op; - fifo->count++; + fifo->count++; } /* Add new packet to head of fifo. */ -static void -ospf_fifo_push_head (struct ospf_fifo *fifo, struct ospf_packet *op) +static void ospf_fifo_push_head(struct ospf_fifo *fifo, struct ospf_packet *op) { - op->next = fifo->head; - - if (fifo->tail == NULL) - fifo->tail = op; - - fifo->head = op; - - fifo->count++; + op->next = fifo->head; + + if (fifo->tail == NULL) + fifo->tail = op; + + fifo->head = op; + + fifo->count++; } /* Delete first packet from fifo. */ -struct ospf_packet * -ospf_fifo_pop (struct ospf_fifo *fifo) +struct ospf_packet *ospf_fifo_pop(struct ospf_fifo *fifo) { - struct ospf_packet *op; + struct ospf_packet *op; - op = fifo->head; + op = fifo->head; - if (op) - { - fifo->head = op->next; + if (op) { + fifo->head = op->next; - if (fifo->head == NULL) - fifo->tail = NULL; + if (fifo->head == NULL) + fifo->tail = NULL; - fifo->count--; - } + fifo->count--; + } - return op; + return op; } /* Return first fifo entry. */ -struct ospf_packet * -ospf_fifo_head (struct ospf_fifo *fifo) +struct ospf_packet *ospf_fifo_head(struct ospf_fifo *fifo) { - return fifo->head; + return fifo->head; } /* Flush ospf packet fifo. */ -void -ospf_fifo_flush (struct ospf_fifo *fifo) +void ospf_fifo_flush(struct ospf_fifo *fifo) { - struct ospf_packet *op; - struct ospf_packet *next; + struct ospf_packet *op; + struct ospf_packet *next; - for (op = fifo->head; op; op = next) - { - next = op->next; - ospf_packet_free (op); - } - fifo->head = fifo->tail = NULL; - fifo->count = 0; + for (op = fifo->head; op; op = next) { + next = op->next; + ospf_packet_free(op); + } + fifo->head = fifo->tail = NULL; + fifo->count = 0; } /* Free ospf packet fifo. */ -void -ospf_fifo_free (struct ospf_fifo *fifo) +void ospf_fifo_free(struct ospf_fifo *fifo) { - ospf_fifo_flush (fifo); + ospf_fifo_flush(fifo); - XFREE (MTYPE_OSPF_FIFO, fifo); + XFREE(MTYPE_OSPF_FIFO, fifo); } -void -ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op) +void ospf_packet_add(struct ospf_interface *oi, struct ospf_packet *op) { - if (!oi->obuf) - { - zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, " - "destination %s) called with NULL obuf, ignoring " - "(please report this bug)!\n", - IF_NAME(oi), oi->state, lookup_msg(ospf_ism_state_msg, oi->state, NULL), - lookup_msg(ospf_packet_type_str, stream_getc_from(op->s, 1), NULL), - inet_ntoa (op->dst)); - return; - } + if (!oi->obuf) { + zlog_err( + "ospf_packet_add(interface %s in state %d [%s], packet type %s, " + "destination %s) called with NULL obuf, ignoring " + "(please report this bug)!\n", + IF_NAME(oi), oi->state, + lookup_msg(ospf_ism_state_msg, oi->state, NULL), + lookup_msg(ospf_packet_type_str, + stream_getc_from(op->s, 1), NULL), + inet_ntoa(op->dst)); + return; + } - /* Add packet to end of queue. */ - ospf_fifo_push (oi->obuf, op); + /* Add packet to end of queue. */ + ospf_fifo_push(oi->obuf, op); - /* Debug of packet fifo*/ - /* ospf_fifo_debug (oi->obuf); */ + /* Debug of packet fifo*/ + /* ospf_fifo_debug (oi->obuf); */ } -static void -ospf_packet_add_top (struct ospf_interface *oi, struct ospf_packet *op) +static void ospf_packet_add_top(struct ospf_interface *oi, + struct ospf_packet *op) { - if (!oi->obuf) - { - zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, " - "destination %s) called with NULL obuf, ignoring " - "(please report this bug)!\n", - IF_NAME(oi), oi->state, lookup_msg(ospf_ism_state_msg, oi->state, NULL), - lookup_msg(ospf_packet_type_str, stream_getc_from(op->s, 1), NULL), - inet_ntoa (op->dst)); - return; - } + if (!oi->obuf) { + zlog_err( + "ospf_packet_add(interface %s in state %d [%s], packet type %s, " + "destination %s) called with NULL obuf, ignoring " + "(please report this bug)!\n", + IF_NAME(oi), oi->state, + lookup_msg(ospf_ism_state_msg, oi->state, NULL), + lookup_msg(ospf_packet_type_str, + stream_getc_from(op->s, 1), NULL), + inet_ntoa(op->dst)); + return; + } - /* Add packet to head of queue. */ - ospf_fifo_push_head (oi->obuf, op); + /* Add packet to head of queue. */ + ospf_fifo_push_head(oi->obuf, op); - /* Debug of packet fifo*/ - /* ospf_fifo_debug (oi->obuf); */ + /* Debug of packet fifo*/ + /* ospf_fifo_debug (oi->obuf); */ } -void -ospf_packet_delete (struct ospf_interface *oi) +void ospf_packet_delete(struct ospf_interface *oi) { - struct ospf_packet *op; - - op = ospf_fifo_pop (oi->obuf); + struct ospf_packet *op; + + op = ospf_fifo_pop(oi->obuf); - if (op) - ospf_packet_free (op); + if (op) + ospf_packet_free(op); } -struct ospf_packet * -ospf_packet_dup (struct ospf_packet *op) +struct ospf_packet *ospf_packet_dup(struct ospf_packet *op) { - struct ospf_packet *new; + struct ospf_packet *new; - if (stream_get_endp(op->s) != op->length) - /* XXX size_t */ - zlog_warn ("ospf_packet_dup stream %lu ospf_packet %u size mismatch", - (u_long)STREAM_SIZE(op->s), op->length); + if (stream_get_endp(op->s) != op->length) + /* XXX size_t */ + zlog_warn( + "ospf_packet_dup stream %lu ospf_packet %u size mismatch", + (u_long)STREAM_SIZE(op->s), op->length); - /* Reserve space for MD5 authentication that may be added later. */ - new = ospf_packet_new (stream_get_endp(op->s) + OSPF_AUTH_MD5_SIZE); - stream_copy (new->s, op->s); + /* Reserve space for MD5 authentication that may be added later. */ + new = ospf_packet_new(stream_get_endp(op->s) + OSPF_AUTH_MD5_SIZE); + stream_copy(new->s, op->s); - new->dst = op->dst; - new->length = op->length; + new->dst = op->dst; + new->length = op->length; - return new; + return new; } /* XXX inline */ -static unsigned int -ospf_packet_authspace (struct ospf_interface *oi) +static unsigned int ospf_packet_authspace(struct ospf_interface *oi) { - int auth = 0; + int auth = 0; - if ( ospf_auth_type (oi) == OSPF_AUTH_CRYPTOGRAPHIC) - auth = OSPF_AUTH_MD5_SIZE; + if (ospf_auth_type(oi) == OSPF_AUTH_CRYPTOGRAPHIC) + auth = OSPF_AUTH_MD5_SIZE; - return auth; + return auth; } -static unsigned int -ospf_packet_max (struct ospf_interface *oi) +static unsigned int ospf_packet_max(struct ospf_interface *oi) { - int max; + int max; - max = oi->ifp->mtu - ospf_packet_authspace(oi); + max = oi->ifp->mtu - ospf_packet_authspace(oi); - max -= (OSPF_HEADER_SIZE + sizeof (struct ip)); + max -= (OSPF_HEADER_SIZE + sizeof(struct ip)); - return max; + return max; } -static int -ospf_check_md5_digest (struct ospf_interface *oi, struct ospf_header *ospfh) +static int ospf_check_md5_digest(struct ospf_interface *oi, + struct ospf_header *ospfh) { - MD5_CTX ctx; - unsigned char digest[OSPF_AUTH_MD5_SIZE]; - struct crypt_key *ck; - struct ospf_neighbor *nbr; - u_int16_t length = ntohs (ospfh->length); - - /* Get secret key. */ - ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt), - ospfh->u.crypt.key_id); - if (ck == NULL) - { - zlog_warn ("interface %s: ospf_check_md5 no key %d", - IF_NAME (oi), ospfh->u.crypt.key_id); - return 0; - } + MD5_CTX ctx; + unsigned char digest[OSPF_AUTH_MD5_SIZE]; + struct crypt_key *ck; + struct ospf_neighbor *nbr; + u_int16_t length = ntohs(ospfh->length); + + /* Get secret key. */ + ck = ospf_crypt_key_lookup(OSPF_IF_PARAM(oi, auth_crypt), + ospfh->u.crypt.key_id); + if (ck == NULL) { + zlog_warn("interface %s: ospf_check_md5 no key %d", IF_NAME(oi), + ospfh->u.crypt.key_id); + return 0; + } - /* check crypto seqnum. */ - nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id); + /* check crypto seqnum. */ + nbr = ospf_nbr_lookup_by_routerid(oi->nbrs, &ospfh->router_id); - if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum)) - { - zlog_warn ("interface %s: ospf_check_md5 bad sequence %d (expect %d)", - IF_NAME (oi), - ntohl(ospfh->u.crypt.crypt_seqnum), - ntohl(nbr->crypt_seqnum)); - return 0; - } - - /* Generate a digest for the ospf packet - their digest + our digest. */ - memset(&ctx, 0, sizeof(ctx)); - MD5Init(&ctx); - MD5Update(&ctx, ospfh, length); - MD5Update(&ctx, ck->auth_key, OSPF_AUTH_MD5_SIZE); - MD5Final(digest, &ctx); + if (nbr + && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum)) { + zlog_warn( + "interface %s: ospf_check_md5 bad sequence %d (expect %d)", + IF_NAME(oi), ntohl(ospfh->u.crypt.crypt_seqnum), + ntohl(nbr->crypt_seqnum)); + return 0; + } - /* compare the two */ - if (memcmp ((caddr_t)ospfh + length, digest, OSPF_AUTH_MD5_SIZE)) - { - zlog_warn ("interface %s: ospf_check_md5 checksum mismatch", - IF_NAME (oi)); - return 0; - } + /* Generate a digest for the ospf packet - their digest + our digest. */ + memset(&ctx, 0, sizeof(ctx)); + MD5Init(&ctx); + MD5Update(&ctx, ospfh, length); + MD5Update(&ctx, ck->auth_key, OSPF_AUTH_MD5_SIZE); + MD5Final(digest, &ctx); + + /* compare the two */ + if (memcmp((caddr_t)ospfh + length, digest, OSPF_AUTH_MD5_SIZE)) { + zlog_warn("interface %s: ospf_check_md5 checksum mismatch", + IF_NAME(oi)); + return 0; + } - /* save neighbor's crypt_seqnum */ - if (nbr) - nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum; - return 1; + /* save neighbor's crypt_seqnum */ + if (nbr) + nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum; + return 1; } /* This function is called from ospf_write(), it will detect the authentication scheme and if it is MD5, it will change the sequence and update the MD5 digest. */ -static int -ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op) -{ - struct ospf_header *ospfh; - unsigned char digest[OSPF_AUTH_MD5_SIZE] = {0}; - MD5_CTX ctx; - void *ibuf; - u_int32_t t; - struct crypt_key *ck; - const u_int8_t *auth_key; - - ibuf = STREAM_DATA (op->s); - ospfh = (struct ospf_header *) ibuf; - - if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC) - return 0; - - /* We do this here so when we dup a packet, we don't have to - waste CPU rewriting other headers. - - Note that quagga_time /deliberately/ is not used here */ - t = (time(NULL) & 0xFFFFFFFF); - if (t > oi->crypt_seqnum) - oi->crypt_seqnum = t; - else - oi->crypt_seqnum++; - - ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum); - - /* Get MD5 Authentication key from auth_key list. */ - if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt))) - auth_key = (const u_int8_t *) digest; - else - { - ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt))); - auth_key = ck->auth_key; - } +static int ospf_make_md5_digest(struct ospf_interface *oi, + struct ospf_packet *op) +{ + struct ospf_header *ospfh; + unsigned char digest[OSPF_AUTH_MD5_SIZE] = {0}; + MD5_CTX ctx; + void *ibuf; + u_int32_t t; + struct crypt_key *ck; + const u_int8_t *auth_key; + + ibuf = STREAM_DATA(op->s); + ospfh = (struct ospf_header *)ibuf; + + if (ntohs(ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC) + return 0; + + /* We do this here so when we dup a packet, we don't have to + waste CPU rewriting other headers. + + Note that quagga_time /deliberately/ is not used here */ + t = (time(NULL) & 0xFFFFFFFF); + if (t > oi->crypt_seqnum) + oi->crypt_seqnum = t; + else + oi->crypt_seqnum++; + + ospfh->u.crypt.crypt_seqnum = htonl(oi->crypt_seqnum); + + /* Get MD5 Authentication key from auth_key list. */ + if (list_isempty(OSPF_IF_PARAM(oi, auth_crypt))) + auth_key = (const u_int8_t *)digest; + else { + ck = listgetdata(listtail(OSPF_IF_PARAM(oi, auth_crypt))); + auth_key = ck->auth_key; + } - /* Generate a digest for the entire packet + our secret key. */ - memset(&ctx, 0, sizeof(ctx)); - MD5Init(&ctx); - MD5Update(&ctx, ibuf, ntohs (ospfh->length)); - MD5Update(&ctx, auth_key, OSPF_AUTH_MD5_SIZE); - MD5Final(digest, &ctx); + /* Generate a digest for the entire packet + our secret key. */ + memset(&ctx, 0, sizeof(ctx)); + MD5Init(&ctx); + MD5Update(&ctx, ibuf, ntohs(ospfh->length)); + MD5Update(&ctx, auth_key, OSPF_AUTH_MD5_SIZE); + MD5Final(digest, &ctx); - /* Append md5 digest to the end of the stream. */ - stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE); + /* Append md5 digest to the end of the stream. */ + stream_put(op->s, digest, OSPF_AUTH_MD5_SIZE); - /* We do *NOT* increment the OSPF header length. */ - op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE; + /* We do *NOT* increment the OSPF header length. */ + op->length = ntohs(ospfh->length) + OSPF_AUTH_MD5_SIZE; - if (stream_get_endp(op->s) != op->length) - /* XXX size_t */ - zlog_warn("ospf_make_md5_digest: length mismatch stream %lu ospf_packet %u", - (u_long)stream_get_endp(op->s), op->length); + if (stream_get_endp(op->s) != op->length) + /* XXX size_t */ + zlog_warn( + "ospf_make_md5_digest: length mismatch stream %lu ospf_packet %u", + (u_long)stream_get_endp(op->s), op->length); - return OSPF_AUTH_MD5_SIZE; + return OSPF_AUTH_MD5_SIZE; } -static int -ospf_ls_req_timer (struct thread *thread) +static int ospf_ls_req_timer(struct thread *thread) { - struct ospf_neighbor *nbr; + struct ospf_neighbor *nbr; - nbr = THREAD_ARG (thread); - nbr->t_ls_req = NULL; + nbr = THREAD_ARG(thread); + nbr->t_ls_req = NULL; - /* Send Link State Request. */ - if (ospf_ls_request_count (nbr)) - ospf_ls_req_send (nbr); + /* Send Link State Request. */ + if (ospf_ls_request_count(nbr)) + ospf_ls_req_send(nbr); - /* Set Link State Request retransmission timer. */ - OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req); + /* Set Link State Request retransmission timer. */ + OSPF_NSM_TIMER_ON(nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req); - return 0; + return 0; } -void -ospf_ls_req_event (struct ospf_neighbor *nbr) +void ospf_ls_req_event(struct ospf_neighbor *nbr) { - if (nbr->t_ls_req) - { - thread_cancel (nbr->t_ls_req); - nbr->t_ls_req = NULL; - } - nbr->t_ls_req = NULL; - thread_add_event(master, ospf_ls_req_timer, nbr, 0, &nbr->t_ls_req); + if (nbr->t_ls_req) { + thread_cancel(nbr->t_ls_req); + nbr->t_ls_req = NULL; + } + nbr->t_ls_req = NULL; + thread_add_event(master, ospf_ls_req_timer, nbr, 0, &nbr->t_ls_req); } /* Cyclic timer function. Fist registered in ospf_nbr_new () in ospf_neighbor.c */ -int -ospf_ls_upd_timer (struct thread *thread) -{ - struct ospf_neighbor *nbr; - - nbr = THREAD_ARG (thread); - nbr->t_ls_upd = NULL; - - /* Send Link State Update. */ - if (ospf_ls_retransmit_count (nbr) > 0) - { - struct list *update; - struct ospf_lsdb *lsdb; - int i; - int retransmit_interval; - - retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval); - - lsdb = &nbr->ls_rxmt; - update = list_new (); +int ospf_ls_upd_timer(struct thread *thread) +{ + struct ospf_neighbor *nbr; + + nbr = THREAD_ARG(thread); + nbr->t_ls_upd = NULL; + + /* Send Link State Update. */ + if (ospf_ls_retransmit_count(nbr) > 0) { + struct list *update; + struct ospf_lsdb *lsdb; + int i; + int retransmit_interval; + + retransmit_interval = + OSPF_IF_PARAM(nbr->oi, retransmit_interval); + + lsdb = &nbr->ls_rxmt; + update = list_new(); + + for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++) { + struct route_table *table = lsdb->type[i].db; + struct route_node *rn; + + for (rn = route_top(table); rn; rn = route_next(rn)) { + struct ospf_lsa *lsa; + + if ((lsa = rn->info) != NULL) { + /* Don't retransmit an LSA if we + received it within + the last RxmtInterval seconds - this + is to allow the + neighbour a chance to acknowledge the + LSA as it may + have ben just received before the + retransmit timer + fired. This is a small tweak to what + is in the RFC, + but it will cut out out a lot of + retransmit traffic + - MAG */ + if (monotime_since(&lsa->tv_recv, NULL) + >= retransmit_interval * 1000000LL) + listnode_add(update, rn->info); + } + } + } - for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++) - { - struct route_table *table = lsdb->type[i].db; - struct route_node *rn; - - for (rn = route_top (table); rn; rn = route_next (rn)) - { - struct ospf_lsa *lsa; - - if ((lsa = rn->info) != NULL) - { - /* Don't retransmit an LSA if we received it within - the last RxmtInterval seconds - this is to allow the - neighbour a chance to acknowledge the LSA as it may - have ben just received before the retransmit timer - fired. This is a small tweak to what is in the RFC, - but it will cut out out a lot of retransmit traffic - - MAG */ - if (monotime_since (&lsa->tv_recv, NULL) - >= retransmit_interval * 1000000LL) - listnode_add (update, rn->info); - } - } + if (listcount(update) > 0) + ospf_ls_upd_send(nbr, update, OSPF_SEND_PACKET_DIRECT); + list_delete(update); } - if (listcount (update) > 0) - ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT); - list_delete (update); - } + /* Set LS Update retransmission timer. */ + OSPF_NSM_TIMER_ON(nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd); - /* Set LS Update retransmission timer. */ - OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd); - - return 0; + return 0; } -int -ospf_ls_ack_timer (struct thread *thread) +int ospf_ls_ack_timer(struct thread *thread) { - struct ospf_interface *oi; + struct ospf_interface *oi; - oi = THREAD_ARG (thread); - oi->t_ls_ack = NULL; + oi = THREAD_ARG(thread); + oi->t_ls_ack = NULL; - /* Send Link State Acknowledgment. */ - if (listcount (oi->ls_ack) > 0) - ospf_ls_ack_send_delayed (oi); + /* Send Link State Acknowledgment. */ + if (listcount(oi->ls_ack) > 0) + ospf_ls_ack_send_delayed(oi); - /* Set LS Ack timer. */ - OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack); + /* Set LS Ack timer. */ + OSPF_ISM_TIMER_ON(oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack); - return 0; + return 0; } #ifdef WANT_OSPF_WRITE_FRAGMENT -static void -ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph, - struct msghdr *msg, unsigned int maxdatasize, - unsigned int mtu, int flags, u_char type) +static void ospf_write_frags(int fd, struct ospf_packet *op, struct ip *iph, + struct msghdr *msg, unsigned int maxdatasize, + unsigned int mtu, int flags, u_char type) { #define OSPF_WRITE_FRAG_SHIFT 3 - u_int16_t offset; - struct iovec *iovp; - int ret; - - assert ( op->length == stream_get_endp(op->s) ); - assert (msg->msg_iovlen == 2); - - /* we can but try. - * - * SunOS, BSD and BSD derived kernels likely will clear ip_id, as - * well as the IP_MF flag, making this all quite pointless. - * - * However, for a system on which IP_MF is left alone, and ip_id left - * alone or else which sets same ip_id for each fragment this might - * work, eg linux. - * - * XXX-TODO: It would be much nicer to have the kernel's use their - * existing fragmentation support to do this for us. Bugs/RFEs need to - * be raised against the various kernels. - */ - - /* set More Frag */ - iph->ip_off |= IP_MF; - - /* ip frag offset is expressed in units of 8byte words */ - offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT; - - iovp = &msg->msg_iov[1]; - - while ( (stream_get_endp(op->s) - stream_get_getp (op->s)) - > maxdatasize ) - { - /* data length of this frag is to next offset value */ - iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT; - iph->ip_len = iovp->iov_len + sizeof (struct ip); - assert (iph->ip_len <= mtu); - - sockopt_iphdrincl_swab_htosys (iph); - - ret = sendmsg (fd, msg, flags); - - sockopt_iphdrincl_swab_systoh (iph); - - if (ret < 0) - zlog_warn ("*** ospf_write_frags: sendmsg failed to %s," - " id %d, off %d, len %d, mtu %u failed with %s", - inet_ntoa (iph->ip_dst), - iph->ip_id, - iph->ip_off, - iph->ip_len, - mtu, - safe_strerror (errno)); - - if (IS_DEBUG_OSPF_PACKET (type - 1, SEND)) - { - zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n", - iph->ip_id, iph->ip_off, iph->ip_len, - inet_ntoa (iph->ip_dst)); - if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL)) - { - zlog_debug ("-----------------IP Header Dump----------------------"); - ospf_ip_header_dump (iph); - zlog_debug ("-----------------------------------------------------"); - } - } - - iph->ip_off += offset; - stream_forward_getp (op->s, iovp->iov_len); - iovp->iov_base = STREAM_PNT (op->s); - } - - /* setup for final fragment */ - iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s); - iph->ip_len = iovp->iov_len + sizeof (struct ip); - iph->ip_off &= (~IP_MF); + u_int16_t offset; + struct iovec *iovp; + int ret; + + assert(op->length == stream_get_endp(op->s)); + assert(msg->msg_iovlen == 2); + + /* we can but try. + * + * SunOS, BSD and BSD derived kernels likely will clear ip_id, as + * well as the IP_MF flag, making this all quite pointless. + * + * However, for a system on which IP_MF is left alone, and ip_id left + * alone or else which sets same ip_id for each fragment this might + * work, eg linux. + * + * XXX-TODO: It would be much nicer to have the kernel's use their + * existing fragmentation support to do this for us. Bugs/RFEs need to + * be raised against the various kernels. + */ + + /* set More Frag */ + iph->ip_off |= IP_MF; + + /* ip frag offset is expressed in units of 8byte words */ + offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT; + + iovp = &msg->msg_iov[1]; + + while ((stream_get_endp(op->s) - stream_get_getp(op->s)) + > maxdatasize) { + /* data length of this frag is to next offset value */ + iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT; + iph->ip_len = iovp->iov_len + sizeof(struct ip); + assert(iph->ip_len <= mtu); + + sockopt_iphdrincl_swab_htosys(iph); + + ret = sendmsg(fd, msg, flags); + + sockopt_iphdrincl_swab_systoh(iph); + + if (ret < 0) + zlog_warn( + "*** ospf_write_frags: sendmsg failed to %s," + " id %d, off %d, len %d, mtu %u failed with %s", + inet_ntoa(iph->ip_dst), iph->ip_id, iph->ip_off, + iph->ip_len, mtu, safe_strerror(errno)); + + if (IS_DEBUG_OSPF_PACKET(type - 1, SEND)) { + zlog_debug( + "ospf_write_frags: sent id %d, off %d, len %d to %s\n", + iph->ip_id, iph->ip_off, iph->ip_len, + inet_ntoa(iph->ip_dst)); + if (IS_DEBUG_OSPF_PACKET(type - 1, DETAIL)) { + zlog_debug( + "-----------------IP Header Dump----------------------"); + ospf_ip_header_dump(iph); + zlog_debug( + "-----------------------------------------------------"); + } + } + + iph->ip_off += offset; + stream_forward_getp(op->s, iovp->iov_len); + iovp->iov_base = STREAM_PNT(op->s); + } + + /* setup for final fragment */ + iovp->iov_len = stream_get_endp(op->s) - stream_get_getp(op->s); + iph->ip_len = iovp->iov_len + sizeof(struct ip); + iph->ip_off &= (~IP_MF); } #endif /* WANT_OSPF_WRITE_FRAGMENT */ -static int -ospf_write (struct thread *thread) -{ - struct ospf *ospf = THREAD_ARG (thread); - struct ospf_interface *oi; - struct ospf_interface *last_serviced_oi = NULL; - struct ospf_packet *op; - struct sockaddr_in sa_dst; - struct ip iph; - struct msghdr msg; - struct iovec iov[2]; - u_char type; - int ret; - int flags = 0; - struct listnode *node; +static int ospf_write(struct thread *thread) +{ + struct ospf *ospf = THREAD_ARG(thread); + struct ospf_interface *oi; + struct ospf_interface *last_serviced_oi = NULL; + struct ospf_packet *op; + struct sockaddr_in sa_dst; + struct ip iph; + struct msghdr msg; + struct iovec iov[2]; + u_char type; + int ret; + int flags = 0; + struct listnode *node; #ifdef WANT_OSPF_WRITE_FRAGMENT - static u_int16_t ipid = 0; - u_int16_t maxdatasize; + static u_int16_t ipid = 0; + u_int16_t maxdatasize; #endif /* WANT_OSPF_WRITE_FRAGMENT */ + /* $FRR indent$ */ + /* clang-format off */ #define OSPF_WRITE_IPHL_SHIFT 2 - int pkt_count = 0; - - ospf->t_write = NULL; + int pkt_count = 0; + + ospf->t_write = NULL; - node = listhead (ospf->oi_write_q); - assert (node); - oi = listgetdata (node); - assert (oi); + node = listhead(ospf->oi_write_q); + assert(node); + oi = listgetdata(node); + assert(oi); #ifdef WANT_OSPF_WRITE_FRAGMENT - /* seed ipid static with low order bits of time */ - if (ipid == 0) - ipid = (time(NULL) & 0xffff); + /* seed ipid static with low order bits of time */ + if (ipid == 0) + ipid = (time(NULL) & 0xffff); #endif /* WANT_OSPF_WRITE_FRAGMENT */ - while ((pkt_count < ospf->write_oi_count) && oi && (last_serviced_oi != oi)) - { - /* If there is only packet in the queue, the oi is removed from - write-q, so fix up the last interface that was serviced */ - if (last_serviced_oi == NULL) { - last_serviced_oi = oi; - } - pkt_count++; + while ((pkt_count < ospf->write_oi_count) && oi + && (last_serviced_oi != oi)) { + /* If there is only packet in the queue, the oi is removed from + write-q, so fix up the last interface that was serviced */ + if (last_serviced_oi == NULL) { + last_serviced_oi = oi; + } + pkt_count++; #ifdef WANT_OSPF_WRITE_FRAGMENT - /* convenience - max OSPF data per packet */ - maxdatasize = oi->ifp->mtu - sizeof (struct ip); + /* convenience - max OSPF data per packet */ + maxdatasize = oi->ifp->mtu - sizeof(struct ip); #endif /* WANT_OSPF_WRITE_FRAGMENT */ - /* Get one packet from queue. */ - op = ospf_fifo_head (oi->obuf); - assert (op); - assert (op->length >= OSPF_HEADER_SIZE); - - if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS) - || op->dst.s_addr == htonl (OSPF_ALLDROUTERS)) - ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex); - - /* Rewrite the md5 signature & update the seq */ - ospf_make_md5_digest (oi, op); - - /* Retrieve OSPF packet type. */ - stream_set_getp (op->s, 1); - type = stream_getc (op->s); - - /* reset get pointer */ - stream_set_getp (op->s, 0); - - memset (&iph, 0, sizeof (struct ip)); - memset (&sa_dst, 0, sizeof (sa_dst)); - - sa_dst.sin_family = AF_INET; + /* Get one packet from queue. */ + op = ospf_fifo_head(oi->obuf); + assert(op); + assert(op->length >= OSPF_HEADER_SIZE); + + if (op->dst.s_addr == htonl(OSPF_ALLSPFROUTERS) + || op->dst.s_addr == htonl(OSPF_ALLDROUTERS)) + ospf_if_ipmulticast(ospf, oi->address, + oi->ifp->ifindex); + + /* Rewrite the md5 signature & update the seq */ + ospf_make_md5_digest(oi, op); + + /* Retrieve OSPF packet type. */ + stream_set_getp(op->s, 1); + type = stream_getc(op->s); + + /* reset get pointer */ + stream_set_getp(op->s, 0); + + memset(&iph, 0, sizeof(struct ip)); + memset(&sa_dst, 0, sizeof(sa_dst)); + + sa_dst.sin_family = AF_INET; #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - sa_dst.sin_len = sizeof(sa_dst); + sa_dst.sin_len = sizeof(sa_dst); #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ - sa_dst.sin_addr = op->dst; - sa_dst.sin_port = htons (0); - - /* Set DONTROUTE flag if dst is unicast. */ - if (oi->type != OSPF_IFTYPE_VIRTUALLINK) - if (!IN_MULTICAST (htonl (op->dst.s_addr))) - flags = MSG_DONTROUTE; - - iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT; - /* it'd be very strange for header to not be 4byte-word aligned but.. */ - if ( sizeof (struct ip) - > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) ) - iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */ - - iph.ip_v = IPVERSION; - iph.ip_tos = IPTOS_PREC_INTERNETCONTROL; - iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length; + sa_dst.sin_addr = op->dst; + sa_dst.sin_port = htons(0); + + /* Set DONTROUTE flag if dst is unicast. */ + if (oi->type != OSPF_IFTYPE_VIRTUALLINK) + if (!IN_MULTICAST(htonl(op->dst.s_addr))) + flags = MSG_DONTROUTE; + + iph.ip_hl = sizeof(struct ip) >> OSPF_WRITE_IPHL_SHIFT; + /* it'd be very strange for header to not be 4byte-word aligned + * but.. */ + if (sizeof(struct ip) + > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT)) + iph.ip_hl++; /* we presume sizeof struct ip cant + overflow ip_hl.. */ + + iph.ip_v = IPVERSION; + iph.ip_tos = IPTOS_PREC_INTERNETCONTROL; + iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length; #if defined(__DragonFly__) - /* - * DragonFly's raw socket expects ip_len/ip_off in network byte order. - */ - iph.ip_len = htons(iph.ip_len); + /* + * DragonFly's raw socket expects ip_len/ip_off in network byte + * order. + */ + iph.ip_len = htons(iph.ip_len); #endif #ifdef WANT_OSPF_WRITE_FRAGMENT - /* XXX-MT: not thread-safe at all.. - * XXX: this presumes this is only programme sending OSPF packets - * otherwise, no guarantee ipid will be unique - */ - iph.ip_id = ++ipid; + /* XXX-MT: not thread-safe at all.. + * XXX: this presumes this is only programme sending OSPF + * packets + * otherwise, no guarantee ipid will be unique + */ + iph.ip_id = ++ipid; #endif /* WANT_OSPF_WRITE_FRAGMENT */ - iph.ip_off = 0; - if (oi->type == OSPF_IFTYPE_VIRTUALLINK) - iph.ip_ttl = OSPF_VL_IP_TTL; - else - iph.ip_ttl = OSPF_IP_TTL; - iph.ip_p = IPPROTO_OSPFIGP; - iph.ip_sum = 0; - iph.ip_src.s_addr = oi->address->u.prefix4.s_addr; - iph.ip_dst.s_addr = op->dst.s_addr; - - memset (&msg, 0, sizeof (msg)); - msg.msg_name = (caddr_t) &sa_dst; - msg.msg_namelen = sizeof (sa_dst); - msg.msg_iov = iov; - msg.msg_iovlen = 2; - iov[0].iov_base = (char*)&iph; - iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT; - iov[1].iov_base = STREAM_PNT (op->s); - iov[1].iov_len = op->length; - - /* Sadly we can not rely on kernels to fragment packets because of either - * IP_HDRINCL and/or multicast destination being set. - */ + iph.ip_off = 0; + if (oi->type == OSPF_IFTYPE_VIRTUALLINK) + iph.ip_ttl = OSPF_VL_IP_TTL; + else + iph.ip_ttl = OSPF_IP_TTL; + iph.ip_p = IPPROTO_OSPFIGP; + iph.ip_sum = 0; + iph.ip_src.s_addr = oi->address->u.prefix4.s_addr; + iph.ip_dst.s_addr = op->dst.s_addr; + + memset(&msg, 0, sizeof(msg)); + msg.msg_name = (caddr_t)&sa_dst; + msg.msg_namelen = sizeof(sa_dst); + msg.msg_iov = iov; + msg.msg_iovlen = 2; + iov[0].iov_base = (char *)&iph; + iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT; + iov[1].iov_base = STREAM_PNT(op->s); + iov[1].iov_len = op->length; + +/* Sadly we can not rely on kernels to fragment packets because of either + * IP_HDRINCL and/or multicast destination being set. + */ #ifdef WANT_OSPF_WRITE_FRAGMENT - if ( op->length > maxdatasize ) - ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize, - oi->ifp->mtu, flags, type); + if (op->length > maxdatasize) + ospf_write_frags(ospf->fd, op, &iph, &msg, maxdatasize, + oi->ifp->mtu, flags, type); #endif /* WANT_OSPF_WRITE_FRAGMENT */ - /* send final fragment (could be first) */ - sockopt_iphdrincl_swab_htosys (&iph); - ret = sendmsg (ospf->fd, &msg, flags); - sockopt_iphdrincl_swab_systoh (&iph); - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_write to %s, " - "id %d, off %d, len %d, interface %s, mtu %u:", - inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len, - oi->ifp->name, oi->ifp->mtu); - - if (ret < 0) - zlog_warn ("*** sendmsg in ospf_write failed to %s, " - "id %d, off %d, len %d, interface %s, mtu %u: %s", - inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len, - oi->ifp->name, oi->ifp->mtu, safe_strerror (errno)); - - /* Show debug sending packet. */ - if (IS_DEBUG_OSPF_PACKET (type - 1, SEND)) - { - if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL)) - { - zlog_debug ("-----------------------------------------------------"); - ospf_ip_header_dump (&iph); - stream_set_getp (op->s, 0); - ospf_packet_dump (op->s); - } - - zlog_debug ("%s sent to [%s] via [%s].", - lookup_msg(ospf_packet_type_str, type, NULL), - inet_ntoa (op->dst), - IF_NAME (oi)); - - if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL)) - zlog_debug ("-----------------------------------------------------"); - } - - /* Now delete packet from queue. */ - ospf_packet_delete (oi); - - /* Move this interface to the tail of write_q to - serve everyone in a round robin fashion */ - list_delete_node (ospf->oi_write_q, node); - if (ospf_fifo_head (oi->obuf) == NULL) - { - oi->on_write_q = 0; - last_serviced_oi = NULL; - oi = NULL; - } - else - { - listnode_add (ospf->oi_write_q, oi); - } - - /* Setup to service from the head of the queue again */ - if (!list_isempty (ospf->oi_write_q)) - { - node = listhead (ospf->oi_write_q); - assert (node); - oi = listgetdata (node); - assert (oi); + /* send final fragment (could be first) */ + sockopt_iphdrincl_swab_htosys(&iph); + ret = sendmsg(ospf->fd, &msg, flags); + sockopt_iphdrincl_swab_systoh(&iph); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_write to %s, " + "id %d, off %d, len %d, interface %s, mtu %u:", + inet_ntoa(iph.ip_dst), iph.ip_id, iph.ip_off, + iph.ip_len, oi->ifp->name, oi->ifp->mtu); + + if (ret < 0) + zlog_warn( + "*** sendmsg in ospf_write failed to %s, " + "id %d, off %d, len %d, interface %s, mtu %u: %s", + inet_ntoa(iph.ip_dst), iph.ip_id, iph.ip_off, + iph.ip_len, oi->ifp->name, oi->ifp->mtu, + safe_strerror(errno)); + + /* Show debug sending packet. */ + if (IS_DEBUG_OSPF_PACKET(type - 1, SEND)) { + if (IS_DEBUG_OSPF_PACKET(type - 1, DETAIL)) { + zlog_debug( + "-----------------------------------------------------"); + ospf_ip_header_dump(&iph); + stream_set_getp(op->s, 0); + ospf_packet_dump(op->s); + } + + zlog_debug("%s sent to [%s] via [%s].", + lookup_msg(ospf_packet_type_str, type, NULL), + inet_ntoa(op->dst), IF_NAME(oi)); + + if (IS_DEBUG_OSPF_PACKET(type - 1, DETAIL)) + zlog_debug( + "-----------------------------------------------------"); + } + + /* Now delete packet from queue. */ + ospf_packet_delete(oi); + + /* Move this interface to the tail of write_q to + serve everyone in a round robin fashion */ + list_delete_node(ospf->oi_write_q, node); + if (ospf_fifo_head(oi->obuf) == NULL) { + oi->on_write_q = 0; + last_serviced_oi = NULL; + oi = NULL; + } else { + listnode_add(ospf->oi_write_q, oi); } + + /* Setup to service from the head of the queue again */ + if (!list_isempty(ospf->oi_write_q)) { + node = listhead(ospf->oi_write_q); + assert(node); + oi = listgetdata(node); + assert(oi); + } + } + + /* If packets still remain in queue, call write thread. */ + if (!list_isempty(ospf->oi_write_q)) { + ospf->t_write = NULL; + thread_add_write(master, ospf_write, ospf, ospf->fd, + &ospf->t_write); } - - /* If packets still remain in queue, call write thread. */ - if (!list_isempty (ospf->oi_write_q)) { - ospf->t_write = NULL; - thread_add_write(master, ospf_write, ospf, ospf->fd, &ospf->t_write); - } - return 0; + return 0; } /* OSPF Hello message read -- RFC2328 Section 10.5. */ -static void -ospf_hello (struct ip *iph, struct ospf_header *ospfh, - struct stream * s, struct ospf_interface *oi, int size) -{ - struct ospf_hello *hello; - struct ospf_neighbor *nbr; - int old_state; - struct prefix p; - - /* increment statistics. */ - oi->hello_in++; - - hello = (struct ospf_hello *) STREAM_PNT (s); - - /* If Hello is myself, silently discard. */ - if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id)) - { - if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) - { - zlog_debug ("ospf_header[%s/%s]: selforiginated, " - "dropping.", - lookup_msg(ospf_packet_type_str, ospfh->type, NULL), - inet_ntoa (iph->ip_src)); - } - return; - } - - /* get neighbor prefix. */ - p.family = AF_INET; - p.prefixlen = ip_masklen (hello->network_mask); - p.u.prefix4 = iph->ip_src; - - /* Compare network mask. */ - /* Checking is ignored for Point-to-Point and Virtual link. */ - if (oi->type != OSPF_IFTYPE_POINTOPOINT - && oi->type != OSPF_IFTYPE_VIRTUALLINK) - if (oi->address->prefixlen != p.prefixlen) - { - zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).", - inet_ntoa(ospfh->router_id), IF_NAME(oi), - (int)oi->address->prefixlen, (int)p.prefixlen); - return; - } - - /* Compare Router Dead Interval. */ - if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval)) - { - zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch " - "(expected %u, but received %u).", - inet_ntoa(ospfh->router_id), - OSPF_IF_PARAM(oi, v_wait), ntohl(hello->dead_interval)); - return; - } - - /* Compare Hello Interval - ignored if fast-hellos are set. */ - if (OSPF_IF_PARAM (oi, fast_hello) == 0) - { - if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval)) - { - zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch " - "(expected %u, but received %u).", - inet_ntoa(ospfh->router_id), - OSPF_IF_PARAM(oi, v_hello), ntohs(hello->hello_interval)); - return; - } - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Packet %s [Hello:RECV]: Options %s", - inet_ntoa (ospfh->router_id), - ospf_options_dump (hello->options)); - - /* Compare options. */ +static void ospf_hello(struct ip *iph, struct ospf_header *ospfh, + struct stream *s, struct ospf_interface *oi, int size) +{ + struct ospf_hello *hello; + struct ospf_neighbor *nbr; + int old_state; + struct prefix p; + + /* increment statistics. */ + oi->hello_in++; + + hello = (struct ospf_hello *)STREAM_PNT(s); + + /* If Hello is myself, silently discard. */ + if (IPV4_ADDR_SAME(&ospfh->router_id, &oi->ospf->router_id)) { + if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV)) { + zlog_debug( + "ospf_header[%s/%s]: selforiginated, " + "dropping.", + lookup_msg(ospf_packet_type_str, ospfh->type, + NULL), + inet_ntoa(iph->ip_src)); + } + return; + } + + /* get neighbor prefix. */ + p.family = AF_INET; + p.prefixlen = ip_masklen(hello->network_mask); + p.u.prefix4 = iph->ip_src; + + /* Compare network mask. */ + /* Checking is ignored for Point-to-Point and Virtual link. */ + if (oi->type != OSPF_IFTYPE_POINTOPOINT + && oi->type != OSPF_IFTYPE_VIRTUALLINK) + if (oi->address->prefixlen != p.prefixlen) { + zlog_warn( + "Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).", + inet_ntoa(ospfh->router_id), IF_NAME(oi), + (int)oi->address->prefixlen, (int)p.prefixlen); + return; + } + + /* Compare Router Dead Interval. */ + if (OSPF_IF_PARAM(oi, v_wait) != ntohl(hello->dead_interval)) { + zlog_warn( + "Packet %s [Hello:RECV]: RouterDeadInterval mismatch " + "(expected %u, but received %u).", + inet_ntoa(ospfh->router_id), OSPF_IF_PARAM(oi, v_wait), + ntohl(hello->dead_interval)); + return; + } + + /* Compare Hello Interval - ignored if fast-hellos are set. */ + if (OSPF_IF_PARAM(oi, fast_hello) == 0) { + if (OSPF_IF_PARAM(oi, v_hello) + != ntohs(hello->hello_interval)) { + zlog_warn( + "Packet %s [Hello:RECV]: HelloInterval mismatch " + "(expected %u, but received %u).", + inet_ntoa(ospfh->router_id), + OSPF_IF_PARAM(oi, v_hello), + ntohs(hello->hello_interval)); + return; + } + } + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Packet %s [Hello:RECV]: Options %s", + inet_ntoa(ospfh->router_id), + ospf_options_dump(hello->options)); + +/* Compare options. */ #define REJECT_IF_TBIT_ON 1 /* XXX */ #ifdef REJECT_IF_TBIT_ON - if (CHECK_FLAG (hello->options, OSPF_OPTION_MT)) - { - /* - * This router does not support non-zero TOS. - * Drop this Hello packet not to establish neighbor relationship. - */ - zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.", - inet_ntoa (ospfh->router_id)); - return; - } + if (CHECK_FLAG(hello->options, OSPF_OPTION_MT)) { + /* + * This router does not support non-zero TOS. + * Drop this Hello packet not to establish neighbor + * relationship. + */ + zlog_warn("Packet %s [Hello:RECV]: T-bit on, drop it.", + inet_ntoa(ospfh->router_id)); + return; + } #endif /* REJECT_IF_TBIT_ON */ - if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE) - && CHECK_FLAG (hello->options, OSPF_OPTION_O)) - { - /* - * This router does know the correct usage of O-bit - * the bit should be set in DD packet only. - */ - zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?", - inet_ntoa (ospfh->router_id)); + if (CHECK_FLAG(oi->ospf->config, OSPF_OPAQUE_CAPABLE) + && CHECK_FLAG(hello->options, OSPF_OPTION_O)) { + /* + * This router does know the correct usage of O-bit + * the bit should be set in DD packet only. + */ + zlog_warn("Packet %s [Hello:RECV]: O-bit abuse?", + inet_ntoa(ospfh->router_id)); #ifdef STRICT_OBIT_USAGE_CHECK - return; /* Reject this packet. */ -#else /* STRICT_OBIT_USAGE_CHECK */ - UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */ -#endif /* STRICT_OBIT_USAGE_CHECK */ - } + return; /* Reject this packet. */ +#else /* STRICT_OBIT_USAGE_CHECK */ + UNSET_FLAG(hello->options, OSPF_OPTION_O); /* Ignore O-bit. */ +#endif /* STRICT_OBIT_USAGE_CHECK */ + } - /* new for NSSA is to ensure that NP is on and E is off */ + /* new for NSSA is to ensure that NP is on and E is off */ + + if (oi->area->external_routing == OSPF_AREA_NSSA) { + if (!(CHECK_FLAG(OPTIONS(oi), OSPF_OPTION_NP) + && CHECK_FLAG(hello->options, OSPF_OPTION_NP) + && !CHECK_FLAG(OPTIONS(oi), OSPF_OPTION_E) + && !CHECK_FLAG(hello->options, OSPF_OPTION_E))) { + zlog_warn( + "NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", + inet_ntoa(ospfh->router_id), OPTIONS(oi), + hello->options); + return; + } + if (IS_DEBUG_OSPF_NSSA) + zlog_debug("NSSA-Hello:RECV:Packet from %s:", + inet_ntoa(ospfh->router_id)); + } else + /* The setting of the E-bit found in the Hello Packet's Options + field must match this area's ExternalRoutingCapability A + mismatch causes processing to stop and the packet to be + dropped. The setting of the rest of the bits in the Hello + Packet's Options field should be ignored. */ + if (CHECK_FLAG(OPTIONS(oi), OSPF_OPTION_E) + != CHECK_FLAG(hello->options, OSPF_OPTION_E)) { + zlog_warn( + "Packet %s [Hello:RECV]: my options: %x, his options %x", + inet_ntoa(ospfh->router_id), OPTIONS(oi), + hello->options); + return; + } - if (oi->area->external_routing == OSPF_AREA_NSSA) - { - if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP) - && CHECK_FLAG (hello->options, OSPF_OPTION_NP) - && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) - && ! CHECK_FLAG (hello->options, OSPF_OPTION_E))) - { - zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options); - return; - } - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id)); - } - else - /* The setting of the E-bit found in the Hello Packet's Options - field must match this area's ExternalRoutingCapability A - mismatch causes processing to stop and the packet to be - dropped. The setting of the rest of the bits in the Hello - Packet's Options field should be ignored. */ - if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) != - CHECK_FLAG (hello->options, OSPF_OPTION_E)) - { - zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x", - inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options); - return; - } - - /* get neighbour struct */ - nbr = ospf_nbr_get (oi, ospfh, iph, &p); - - /* neighbour must be valid, ospf_nbr_get creates if none existed */ - assert (nbr); - - old_state = nbr->state; - - /* Add event to thread. */ - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived); - - /* RFC2328 Section 9.5.1 - If the router is not eligible to become Designated Router, - (snip) It must also send an Hello Packet in reply to an - Hello Packet received from any eligible neighbor (other than - the current Designated Router and Backup Designated Router). */ - if (oi->type == OSPF_IFTYPE_NBMA) - if (PRIORITY(oi) == 0 && hello->priority > 0 - && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src) - && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src)) - OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer, - OSPF_HELLO_REPLY_DELAY); - - /* on NBMA network type, it happens to receive bidirectional Hello packet - without advance 1-Way Received event. - To avoid incorrect DR-seletion, raise 1-Way Received event.*/ - if (oi->type == OSPF_IFTYPE_NBMA && - (old_state == NSM_Down || old_state == NSM_Attempt)) - { - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived); - nbr->priority = hello->priority; - nbr->d_router = hello->d_router; - nbr->bd_router = hello->bd_router; - return; - } - - if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors, - size - OSPF_HELLO_MIN_SIZE)) - { - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_TwoWayReceived); - nbr->options |= hello->options; - } - else - { - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived); - /* Set neighbor information. */ - nbr->priority = hello->priority; - nbr->d_router = hello->d_router; - nbr->bd_router = hello->bd_router; - return; - } - - /* If neighbor itself declares DR and no BDR exists, - cause event BackupSeen */ - if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router)) - if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting) - OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen); - - /* neighbor itself declares BDR. */ - if (oi->state == ISM_Waiting && - IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router)) - OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen); - - /* had not previously. */ - if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) && - IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) || - (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) && - IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router))) - OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange); - - /* had not previously. */ - if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) && - IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) || - (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) && - IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router))) - OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange); - - /* Neighbor priority check. */ - if (nbr->priority >= 0 && nbr->priority != hello->priority) - OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange); - - /* Set neighbor information. */ - nbr->priority = hello->priority; - nbr->d_router = hello->d_router; - nbr->bd_router = hello->bd_router; + /* get neighbour struct */ + nbr = ospf_nbr_get(oi, ospfh, iph, &p); + + /* neighbour must be valid, ospf_nbr_get creates if none existed */ + assert(nbr); + + old_state = nbr->state; + + /* Add event to thread. */ + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_PacketReceived); + + /* RFC2328 Section 9.5.1 + If the router is not eligible to become Designated Router, + (snip) It must also send an Hello Packet in reply to an + Hello Packet received from any eligible neighbor (other than + the current Designated Router and Backup Designated Router). */ + if (oi->type == OSPF_IFTYPE_NBMA) + if (PRIORITY(oi) == 0 && hello->priority > 0 + && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src) + && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src)) + OSPF_NSM_TIMER_ON(nbr->t_hello_reply, + ospf_hello_reply_timer, + OSPF_HELLO_REPLY_DELAY); + + /* on NBMA network type, it happens to receive bidirectional Hello + packet + without advance 1-Way Received event. + To avoid incorrect DR-seletion, raise 1-Way Received event.*/ + if (oi->type == OSPF_IFTYPE_NBMA + && (old_state == NSM_Down || old_state == NSM_Attempt)) { + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_OneWayReceived); + nbr->priority = hello->priority; + nbr->d_router = hello->d_router; + nbr->bd_router = hello->bd_router; + return; + } + + if (ospf_nbr_bidirectional(&oi->ospf->router_id, hello->neighbors, + size - OSPF_HELLO_MIN_SIZE)) { + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_TwoWayReceived); + nbr->options |= hello->options; + } else { + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_OneWayReceived); + /* Set neighbor information. */ + nbr->priority = hello->priority; + nbr->d_router = hello->d_router; + nbr->bd_router = hello->bd_router; + return; + } + + /* If neighbor itself declares DR and no BDR exists, + cause event BackupSeen */ + if (IPV4_ADDR_SAME(&nbr->address.u.prefix4, &hello->d_router)) + if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting) + OSPF_ISM_EVENT_SCHEDULE(oi, ISM_BackupSeen); + + /* neighbor itself declares BDR. */ + if (oi->state == ISM_Waiting + && IPV4_ADDR_SAME(&nbr->address.u.prefix4, &hello->bd_router)) + OSPF_ISM_EVENT_SCHEDULE(oi, ISM_BackupSeen); + + /* had not previously. */ + if ((IPV4_ADDR_SAME(&nbr->address.u.prefix4, &hello->d_router) + && IPV4_ADDR_CMP(&nbr->address.u.prefix4, &nbr->d_router)) + || (IPV4_ADDR_CMP(&nbr->address.u.prefix4, &hello->d_router) + && IPV4_ADDR_SAME(&nbr->address.u.prefix4, &nbr->d_router))) + OSPF_ISM_EVENT_SCHEDULE(oi, ISM_NeighborChange); + + /* had not previously. */ + if ((IPV4_ADDR_SAME(&nbr->address.u.prefix4, &hello->bd_router) + && IPV4_ADDR_CMP(&nbr->address.u.prefix4, &nbr->bd_router)) + || (IPV4_ADDR_CMP(&nbr->address.u.prefix4, &hello->bd_router) + && IPV4_ADDR_SAME(&nbr->address.u.prefix4, &nbr->bd_router))) + OSPF_ISM_EVENT_SCHEDULE(oi, ISM_NeighborChange); + + /* Neighbor priority check. */ + if (nbr->priority >= 0 && nbr->priority != hello->priority) + OSPF_ISM_EVENT_SCHEDULE(oi, ISM_NeighborChange); + + /* Set neighbor information. */ + nbr->priority = hello->priority; + nbr->d_router = hello->d_router; + nbr->bd_router = hello->bd_router; } /* Save DD flags/options/Seqnum received. */ -static void -ospf_db_desc_save_current (struct ospf_neighbor *nbr, - struct ospf_db_desc *dd) +static void ospf_db_desc_save_current(struct ospf_neighbor *nbr, + struct ospf_db_desc *dd) { - nbr->last_recv.flags = dd->flags; - nbr->last_recv.options = dd->options; - nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum); + nbr->last_recv.flags = dd->flags; + nbr->last_recv.options = dd->options; + nbr->last_recv.dd_seqnum = ntohl(dd->dd_seqnum); } /* Process rest of DD packet. */ -static void -ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi, - struct ospf_neighbor *nbr, struct ospf_db_desc *dd, - u_int16_t size) -{ - struct ospf_lsa *new, *find; - struct lsa_header *lsah; - - stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE); - for (size -= OSPF_DB_DESC_MIN_SIZE; - size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE) - { - lsah = (struct lsa_header *) STREAM_PNT (s); - stream_forward_getp (s, OSPF_LSA_HEADER_SIZE); - - /* Unknown LS type. */ - if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA) - { - zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type); - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch); - return; - } - - if (IS_OPAQUE_LSA (lsah->type) - && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O)) - { - zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id)); - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch); - return; - } - - switch (lsah->type) - { - case OSPF_AS_EXTERNAL_LSA: - case OSPF_OPAQUE_AS_LSA: - /* Check for stub area. Reject if AS-External from stub but - allow if from NSSA. */ - if (oi->area->external_routing == OSPF_AREA_STUB) - { - zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.", - lsah->type, inet_ntoa (lsah->id), - (oi->area->external_routing == OSPF_AREA_STUB) ?\ - "STUB" : "NSSA"); - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch); - return; - } - break; - default: - break; - } - - /* Create LS-request object. */ - new = ospf_ls_request_new (lsah); - - /* Lookup received LSA, then add LS request list. */ - find = ospf_lsa_lookup_by_header (oi->area, lsah); - - /* ospf_lsa_more_recent is fine with NULL pointers */ - switch (ospf_lsa_more_recent (find, new)) - { - case -1: - /* Neighbour has a more recent LSA, we must request it */ - ospf_ls_request_add (nbr, new); - /* fallthru */ - case 0: - /* If we have a copy of this LSA, it's either less recent - * and we're requesting it from neighbour (the case above), or - * it's as recent and we both have same copy (this case). - * - * In neither of these two cases is there any point in - * describing our copy of the LSA to the neighbour in a - * DB-Summary packet, if we're still intending to do so. - * - * See: draft-ogier-ospf-dbex-opt-00.txt, describing the - * backward compatible optimisation to OSPF DB Exchange / - * DB Description process implemented here. - */ - if (find) - ospf_lsdb_delete (&nbr->db_sum, find); - ospf_lsa_discard (new); - break; - default: - /* We have the more recent copy, nothing specific to do: - * - no need to request neighbours stale copy - * - must leave DB summary list copy alone - */ - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Packet [DD:RECV]: LSA received Type %d, " - "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id)); - ospf_lsa_discard (new); - } - } - - /* Master */ - if (IS_SET_DD_MS (nbr->dd_flags)) - { - nbr->dd_seqnum++; - - /* Both sides have no More, then we're done with Exchange */ - if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags)) - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone); - else - ospf_db_desc_send (nbr); - } - /* Slave */ - else - { - nbr->dd_seqnum = ntohl (dd->dd_seqnum); - - /* Send DD packet in reply. - * - * Must be done to acknowledge the Master's DD, regardless of - * whether we have more LSAs ourselves to describe. - * - * This function will clear the 'More' bit, if after this DD - * we have no more LSAs to describe to the master.. - */ - ospf_db_desc_send (nbr); - - /* Slave can raise ExchangeDone now, if master is also done */ - if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags)) - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone); - } - - /* Save received neighbor values from DD. */ - ospf_db_desc_save_current (nbr, dd); - - if (!nbr->t_ls_req) - ospf_ls_req_send (nbr); -} - -static int -ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr) -{ - /* Is DD duplicated? */ - if (dd->options == nbr->last_recv.options && - dd->flags == nbr->last_recv.flags && - dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum)) - return 1; - - return 0; +static void ospf_db_desc_proc(struct stream *s, struct ospf_interface *oi, + struct ospf_neighbor *nbr, + struct ospf_db_desc *dd, u_int16_t size) +{ + struct ospf_lsa *new, *find; + struct lsa_header *lsah; + + stream_forward_getp(s, OSPF_DB_DESC_MIN_SIZE); + for (size -= OSPF_DB_DESC_MIN_SIZE; size >= OSPF_LSA_HEADER_SIZE; + size -= OSPF_LSA_HEADER_SIZE) { + lsah = (struct lsa_header *)STREAM_PNT(s); + stream_forward_getp(s, OSPF_LSA_HEADER_SIZE); + + /* Unknown LS type. */ + if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA) { + zlog_warn("Packet [DD:RECV]: Unknown LS type %d.", + lsah->type); + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch); + return; + } + + if (IS_OPAQUE_LSA(lsah->type) + && !CHECK_FLAG(nbr->options, OSPF_OPTION_O)) { + zlog_warn("LSA[Type%d:%s]: Opaque capability mismatch?", + lsah->type, inet_ntoa(lsah->id)); + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch); + return; + } + + switch (lsah->type) { + case OSPF_AS_EXTERNAL_LSA: + case OSPF_OPAQUE_AS_LSA: + /* Check for stub area. Reject if AS-External from stub + but + allow if from NSSA. */ + if (oi->area->external_routing == OSPF_AREA_STUB) { + zlog_warn( + "Packet [DD:RECV]: LSA[Type%d:%s] from %s area.", + lsah->type, inet_ntoa(lsah->id), + (oi->area->external_routing + == OSPF_AREA_STUB) + ? "STUB" + : "NSSA"); + OSPF_NSM_EVENT_SCHEDULE(nbr, + NSM_SeqNumberMismatch); + return; + } + break; + default: + break; + } + + /* Create LS-request object. */ + new = ospf_ls_request_new(lsah); + + /* Lookup received LSA, then add LS request list. */ + find = ospf_lsa_lookup_by_header(oi->area, lsah); + + /* ospf_lsa_more_recent is fine with NULL pointers */ + switch (ospf_lsa_more_recent(find, new)) { + case -1: + /* Neighbour has a more recent LSA, we must request it + */ + ospf_ls_request_add(nbr, new); + /* fallthru */ + case 0: + /* If we have a copy of this LSA, it's either less + * recent + * and we're requesting it from neighbour (the case + * above), or + * it's as recent and we both have same copy (this + * case). + * + * In neither of these two cases is there any point in + * describing our copy of the LSA to the neighbour in a + * DB-Summary packet, if we're still intending to do so. + * + * See: draft-ogier-ospf-dbex-opt-00.txt, describing the + * backward compatible optimisation to OSPF DB Exchange + * / + * DB Description process implemented here. + */ + if (find) + ospf_lsdb_delete(&nbr->db_sum, find); + ospf_lsa_discard(new); + break; + default: + /* We have the more recent copy, nothing specific to do: + * - no need to request neighbours stale copy + * - must leave DB summary list copy alone + */ + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "Packet [DD:RECV]: LSA received Type %d, " + "ID %s is not recent.", + lsah->type, inet_ntoa(lsah->id)); + ospf_lsa_discard(new); + } + } + + /* Master */ + if (IS_SET_DD_MS(nbr->dd_flags)) { + nbr->dd_seqnum++; + + /* Both sides have no More, then we're done with Exchange */ + if (!IS_SET_DD_M(dd->flags) && !IS_SET_DD_M(nbr->dd_flags)) + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_ExchangeDone); + else + ospf_db_desc_send(nbr); + } + /* Slave */ + else { + nbr->dd_seqnum = ntohl(dd->dd_seqnum); + + /* Send DD packet in reply. + * + * Must be done to acknowledge the Master's DD, regardless of + * whether we have more LSAs ourselves to describe. + * + * This function will clear the 'More' bit, if after this DD + * we have no more LSAs to describe to the master.. + */ + ospf_db_desc_send(nbr); + + /* Slave can raise ExchangeDone now, if master is also done */ + if (!IS_SET_DD_M(dd->flags) && !IS_SET_DD_M(nbr->dd_flags)) + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_ExchangeDone); + } + + /* Save received neighbor values from DD. */ + ospf_db_desc_save_current(nbr, dd); + + if (!nbr->t_ls_req) + ospf_ls_req_send(nbr); +} + +static int ospf_db_desc_is_dup(struct ospf_db_desc *dd, + struct ospf_neighbor *nbr) +{ + /* Is DD duplicated? */ + if (dd->options == nbr->last_recv.options + && dd->flags == nbr->last_recv.flags + && dd->dd_seqnum == htonl(nbr->last_recv.dd_seqnum)) + return 1; + + return 0; } /* OSPF Database Description message read -- RFC2328 Section 10.6. */ -static void -ospf_db_desc (struct ip *iph, struct ospf_header *ospfh, - struct stream *s, struct ospf_interface *oi, u_int16_t size) -{ - struct ospf_db_desc *dd; - struct ospf_neighbor *nbr; - - /* Increment statistics. */ - oi->db_desc_in++; - - dd = (struct ospf_db_desc *) STREAM_PNT (s); - - nbr = ospf_nbr_lookup (oi, iph, ospfh); - if (nbr == NULL) - { - zlog_warn ("Packet[DD]: Unknown Neighbor %s", - inet_ntoa (ospfh->router_id)); - return; - } - - /* Check MTU. */ - if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) && - (ntohs (dd->mtu) > oi->ifp->mtu)) - { - zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u", - inet_ntoa (nbr->router_id), ntohs (dd->mtu), - IF_NAME (oi), oi->ifp->mtu); - return; - } - - /* - * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not - * required. In fact at least JunOS sends DD packets with P bit clear. - * Until proper solution is developped, this hack should help. - * - * Update: According to the RFCs, N bit is specified /only/ for Hello - * options, unfortunately its use in DD options is not specified. Hence some - * implementations follow E-bit semantics and set it in DD options, and some - * treat it as unspecified and hence follow the directive "default for - * options is clear", ie unset. - * - * Reset the flag, as ospfd follows E-bit semantics. - */ - if ( (oi->area->external_routing == OSPF_AREA_NSSA) - && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP)) - && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) ) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options", - inet_ntoa (nbr->router_id) ); - SET_FLAG (dd->options, OSPF_OPTION_NP); - } +static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, + struct stream *s, struct ospf_interface *oi, + u_int16_t size) +{ + struct ospf_db_desc *dd; + struct ospf_neighbor *nbr; -#ifdef REJECT_IF_TBIT_ON - if (CHECK_FLAG (dd->options, OSPF_OPTION_MT)) - { - /* - * In Hello protocol, optional capability must have checked - * to prevent this T-bit enabled router be my neighbor. - */ - zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id)); - return; - } -#endif /* REJECT_IF_TBIT_ON */ + /* Increment statistics. */ + oi->db_desc_in++; - if (CHECK_FLAG (dd->options, OSPF_OPTION_O) - && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)) - { - /* - * This node is not configured to handle O-bit, for now. - * Clear it to ignore unsupported capability proposed by neighbor. - */ - UNSET_FLAG (dd->options, OSPF_OPTION_O); - } - - /* Add event to thread. */ - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived); - - /* Process DD packet by neighbor status. */ - switch (nbr->state) - { - case NSM_Down: - case NSM_Attempt: - case NSM_TwoWay: - zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.", - inet_ntoa(nbr->router_id), - lookup_msg(ospf_nsm_state_msg, nbr->state, NULL)); - break; - case NSM_Init: - OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived); - /* If the new state is ExStart, the processing of the current - packet should then continue in this new state by falling - through to case ExStart below. */ - if (nbr->state != NSM_ExStart) - break; - /* fallthru */ - case NSM_ExStart: - /* Initial DBD */ - if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) && - (size == OSPF_DB_DESC_MIN_SIZE)) - { - if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0) - { - /* We're Slave---obey */ - zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).", - inet_ntoa(nbr->router_id)); - nbr->dd_seqnum = ntohl (dd->dd_seqnum); - - /* Reset I/MS */ - UNSET_FLAG (nbr->dd_flags, (OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I)); - } - else - { - /* We're Master, ignore the initial DBD from Slave */ - zlog_info ("Packet[DD]: Neighbor %s: Initial DBD from Slave, " - "ignoring.", inet_ntoa(nbr->router_id)); - break; - } - } - /* Ack from the Slave */ - else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) && - ntohl (dd->dd_seqnum) == nbr->dd_seqnum && - IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0) - { - zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).", - inet_ntoa(nbr->router_id)); - /* Reset I, leaving MS */ - UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_I); + dd = (struct ospf_db_desc *)STREAM_PNT(s); + + nbr = ospf_nbr_lookup(oi, iph, ospfh); + if (nbr == NULL) { + zlog_warn("Packet[DD]: Unknown Neighbor %s", + inet_ntoa(ospfh->router_id)); + return; } - else - { - zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.", - inet_ntoa(nbr->router_id)); - break; - } - - /* This is where the real Options are saved */ - nbr->options = dd->options; - - if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Neighbor[%s] is %sOpaque-capable.", - inet_ntoa (nbr->router_id), - CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT "); - - if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O) - && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4)) - { - zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; " - "Opaque-LSAs cannot be reliably advertised " - "in this network.", - inet_ntoa (nbr->router_id)); - /* This situation is undesirable, but not a real error. */ - } - } - - OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone); - - /* continue processing rest of packet. */ - ospf_db_desc_proc (s, oi, nbr, dd, size); - break; - case NSM_Exchange: - if (ospf_db_desc_is_dup (dd, nbr)) - { - if (IS_SET_DD_MS (nbr->dd_flags)) - /* Master: discard duplicated DD packet. */ - zlog_info ("Packet[DD] (Master): Neighbor %s packet duplicated.", - inet_ntoa (nbr->router_id)); - else - /* Slave: cause to retransmit the last Database Description. */ - { - zlog_info ("Packet[DD] [Slave]: Neighbor %s packet duplicated.", - inet_ntoa (nbr->router_id)); - ospf_db_desc_resend (nbr); - } - break; - } - - /* Otherwise DD packet should be checked. */ - /* Check Master/Slave bit mismatch */ - if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags)) - { - zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.", - inet_ntoa(nbr->router_id)); - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch); - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d", - dd->flags, nbr->dd_flags); - break; + + /* Check MTU. */ + if ((OSPF_IF_PARAM(oi, mtu_ignore) == 0) + && (ntohs(dd->mtu) > oi->ifp->mtu)) { + zlog_warn( + "Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u", + inet_ntoa(nbr->router_id), ntohs(dd->mtu), IF_NAME(oi), + oi->ifp->mtu); + return; } - /* Check initialize bit is set. */ - if (IS_SET_DD_I (dd->flags)) - { - zlog_info ("Packet[DD]: Neighbor %s I-bit set.", - inet_ntoa(nbr->router_id)); - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch); - break; + /* + * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is + * not + * required. In fact at least JunOS sends DD packets with P bit clear. + * Until proper solution is developped, this hack should help. + * + * Update: According to the RFCs, N bit is specified /only/ for Hello + * options, unfortunately its use in DD options is not specified. Hence + * some + * implementations follow E-bit semantics and set it in DD options, and + * some + * treat it as unspecified and hence follow the directive "default for + * options is clear", ie unset. + * + * Reset the flag, as ospfd follows E-bit semantics. + */ + if ((oi->area->external_routing == OSPF_AREA_NSSA) + && (CHECK_FLAG(nbr->options, OSPF_OPTION_NP)) + && (!CHECK_FLAG(dd->options, OSPF_OPTION_NP))) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options", + inet_ntoa(nbr->router_id)); + SET_FLAG(dd->options, OSPF_OPTION_NP); } - /* Check DD Options. */ - if (dd->options != nbr->options) - { +#ifdef REJECT_IF_TBIT_ON + if (CHECK_FLAG(dd->options, OSPF_OPTION_MT)) { + /* + * In Hello protocol, optional capability must have checked + * to prevent this T-bit enabled router be my neighbor. + */ + zlog_warn("Packet[DD]: Neighbor %s: T-bit on?", + inet_ntoa(nbr->router_id)); + return; + } +#endif /* REJECT_IF_TBIT_ON */ + + if (CHECK_FLAG(dd->options, OSPF_OPTION_O) + && !CHECK_FLAG(oi->ospf->config, OSPF_OPAQUE_CAPABLE)) { + /* + * This node is not configured to handle O-bit, for now. + * Clear it to ignore unsupported capability proposed by + * neighbor. + */ + UNSET_FLAG(dd->options, OSPF_OPTION_O); + } + + /* Add event to thread. */ + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_PacketReceived); + + /* Process DD packet by neighbor status. */ + switch (nbr->state) { + case NSM_Down: + case NSM_Attempt: + case NSM_TwoWay: + zlog_warn( + "Packet[DD]: Neighbor %s state is %s, packet discarded.", + inet_ntoa(nbr->router_id), + lookup_msg(ospf_nsm_state_msg, nbr->state, NULL)); + break; + case NSM_Init: + OSPF_NSM_EVENT_EXECUTE(nbr, NSM_TwoWayReceived); + /* If the new state is ExStart, the processing of the current + packet should then continue in this new state by falling + through to case ExStart below. */ + if (nbr->state != NSM_ExStart) + break; + /* fallthru */ + case NSM_ExStart: + /* Initial DBD */ + if ((IS_SET_DD_ALL(dd->flags) == OSPF_DD_FLAG_ALL) + && (size == OSPF_DB_DESC_MIN_SIZE)) { + if (IPV4_ADDR_CMP(&nbr->router_id, &oi->ospf->router_id) + > 0) { + /* We're Slave---obey */ + zlog_info( + "Packet[DD]: Neighbor %s Negotiation done (Slave).", + inet_ntoa(nbr->router_id)); + nbr->dd_seqnum = ntohl(dd->dd_seqnum); + + /* Reset I/MS */ + UNSET_FLAG(nbr->dd_flags, + (OSPF_DD_FLAG_MS | OSPF_DD_FLAG_I)); + } else { + /* We're Master, ignore the initial DBD from + * Slave */ + zlog_info( + "Packet[DD]: Neighbor %s: Initial DBD from Slave, " + "ignoring.", + inet_ntoa(nbr->router_id)); + break; + } + } + /* Ack from the Slave */ + else if (!IS_SET_DD_MS(dd->flags) && !IS_SET_DD_I(dd->flags) + && ntohl(dd->dd_seqnum) == nbr->dd_seqnum + && IPV4_ADDR_CMP(&nbr->router_id, &oi->ospf->router_id) + < 0) { + zlog_info( + "Packet[DD]: Neighbor %s Negotiation done (Master).", + inet_ntoa(nbr->router_id)); + /* Reset I, leaving MS */ + UNSET_FLAG(nbr->dd_flags, OSPF_DD_FLAG_I); + } else { + zlog_warn("Packet[DD]: Neighbor %s Negotiation fails.", + inet_ntoa(nbr->router_id)); + break; + } + + /* This is where the real Options are saved */ + nbr->options = dd->options; + + if (CHECK_FLAG(oi->ospf->config, OSPF_OPAQUE_CAPABLE)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "Neighbor[%s] is %sOpaque-capable.", + inet_ntoa(nbr->router_id), + CHECK_FLAG(nbr->options, OSPF_OPTION_O) + ? "" + : "NOT "); + + if (!CHECK_FLAG(nbr->options, OSPF_OPTION_O) + && IPV4_ADDR_SAME(&DR(oi), + &nbr->address.u.prefix4)) { + zlog_warn( + "DR-neighbor[%s] is NOT opaque-capable; " + "Opaque-LSAs cannot be reliably advertised " + "in this network.", + inet_ntoa(nbr->router_id)); + /* This situation is undesirable, but not a real + * error. */ + } + } + + OSPF_NSM_EVENT_EXECUTE(nbr, NSM_NegotiationDone); + + /* continue processing rest of packet. */ + ospf_db_desc_proc(s, oi, nbr, dd, size); + break; + case NSM_Exchange: + if (ospf_db_desc_is_dup(dd, nbr)) { + if (IS_SET_DD_MS(nbr->dd_flags)) + /* Master: discard duplicated DD packet. */ + zlog_info( + "Packet[DD] (Master): Neighbor %s packet duplicated.", + inet_ntoa(nbr->router_id)); + else + /* Slave: cause to retransmit the last Database + Description. */ + { + zlog_info( + "Packet[DD] [Slave]: Neighbor %s packet duplicated.", + inet_ntoa(nbr->router_id)); + ospf_db_desc_resend(nbr); + } + break; + } + + /* Otherwise DD packet should be checked. */ + /* Check Master/Slave bit mismatch */ + if (IS_SET_DD_MS(dd->flags) + != IS_SET_DD_MS(nbr->last_recv.flags)) { + zlog_warn("Packet[DD]: Neighbor %s MS-bit mismatch.", + inet_ntoa(nbr->router_id)); + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "Packet[DD]: dd->flags=%d, nbr->dd_flags=%d", + dd->flags, nbr->dd_flags); + break; + } + + /* Check initialize bit is set. */ + if (IS_SET_DD_I(dd->flags)) { + zlog_info("Packet[DD]: Neighbor %s I-bit set.", + inet_ntoa(nbr->router_id)); + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch); + break; + } + + /* Check DD Options. */ + if (dd->options != nbr->options) { #ifdef ORIGINAL_CODING - /* Save the new options for debugging */ - nbr->options = dd->options; + /* Save the new options for debugging */ + nbr->options = dd->options; #endif /* ORIGINAL_CODING */ - zlog_warn ("Packet[DD]: Neighbor %s options mismatch.", - inet_ntoa(nbr->router_id)); - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch); - break; - } + zlog_warn("Packet[DD]: Neighbor %s options mismatch.", + inet_ntoa(nbr->router_id)); + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch); + break; + } - /* Check DD sequence number. */ - if ((IS_SET_DD_MS (nbr->dd_flags) && - ntohl (dd->dd_seqnum) != nbr->dd_seqnum) || - (!IS_SET_DD_MS (nbr->dd_flags) && - ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1)) - { - zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.", - inet_ntoa(nbr->router_id)); - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch); - break; - } - - /* Continue processing rest of packet. */ - ospf_db_desc_proc (s, oi, nbr, dd, size); - break; - case NSM_Loading: - case NSM_Full: - if (ospf_db_desc_is_dup (dd, nbr)) - { - if (IS_SET_DD_MS (nbr->dd_flags)) - { - /* Master should discard duplicate DD packet. */ - zlog_info ("Packet[DD]: Neighbor %s duplicated, " - "packet discarded.", - inet_ntoa(nbr->router_id)); - break; - } - else - { - if (monotime_since (&nbr->last_send_ts, NULL) - < nbr->v_inactivity * 1000000LL) - { - /* In states Loading and Full the slave must resend - its last Database Description packet in response to - duplicate Database Description packets received - from the master. For this reason the slave must - wait RouterDeadInterval seconds before freeing the - last Database Description packet. Reception of a - Database Description packet from the master after - this interval will generate a SeqNumberMismatch - neighbor event. RFC2328 Section 10.8 */ - ospf_db_desc_resend (nbr); - break; + /* Check DD sequence number. */ + if ((IS_SET_DD_MS(nbr->dd_flags) + && ntohl(dd->dd_seqnum) != nbr->dd_seqnum) + || (!IS_SET_DD_MS(nbr->dd_flags) + && ntohl(dd->dd_seqnum) != nbr->dd_seqnum + 1)) { + zlog_warn( + "Packet[DD]: Neighbor %s sequence number mismatch.", + inet_ntoa(nbr->router_id)); + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch); + break; + } + + /* Continue processing rest of packet. */ + ospf_db_desc_proc(s, oi, nbr, dd, size); + break; + case NSM_Loading: + case NSM_Full: + if (ospf_db_desc_is_dup(dd, nbr)) { + if (IS_SET_DD_MS(nbr->dd_flags)) { + /* Master should discard duplicate DD packet. */ + zlog_info( + "Packet[DD]: Neighbor %s duplicated, " + "packet discarded.", + inet_ntoa(nbr->router_id)); + break; + } else { + if (monotime_since(&nbr->last_send_ts, NULL) + < nbr->v_inactivity * 1000000LL) { + /* In states Loading and Full the slave + must resend + its last Database Description packet + in response to + duplicate Database Description + packets received + from the master. For this reason the + slave must + wait RouterDeadInterval seconds + before freeing the + last Database Description packet. + Reception of a + Database Description packet from the + master after + this interval will generate a + SeqNumberMismatch + neighbor event. RFC2328 Section 10.8 + */ + ospf_db_desc_resend(nbr); + break; + } + } } - } - } - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch); - break; - default: - zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.", - inet_ntoa(nbr->router_id), nbr->state); - break; - } + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch); + break; + default: + zlog_warn("Packet[DD]: Neighbor %s NSM illegal status %u.", + inet_ntoa(nbr->router_id), nbr->state); + break; + } } #define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */ /* OSPF Link State Request Read -- RFC2328 Section 10.7. */ -static void -ospf_ls_req (struct ip *iph, struct ospf_header *ospfh, - struct stream *s, struct ospf_interface *oi, u_int16_t size) -{ - struct ospf_neighbor *nbr; - u_int32_t ls_type; - struct in_addr ls_id; - struct in_addr adv_router; - struct ospf_lsa *find; - struct list *ls_upd; - unsigned int length; - - /* Increment statistics. */ - oi->ls_req_in++; - - nbr = ospf_nbr_lookup (oi, iph, ospfh); - if (nbr == NULL) - { - zlog_warn ("Link State Request: Unknown Neighbor %s.", - inet_ntoa (ospfh->router_id)); - return; - } - - /* Add event to thread. */ - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived); - - /* Neighbor State should be Exchange or later. */ - if (nbr->state != NSM_Exchange && - nbr->state != NSM_Loading && - nbr->state != NSM_Full) - { - zlog_warn ("Link State Request received from %s: " - "Neighbor state is %s, packet discarded.", - inet_ntoa (ospfh->router_id), - lookup_msg(ospf_nsm_state_msg, nbr->state, NULL)); - return; - } - - /* Send Link State Update for ALL requested LSAs. */ - ls_upd = list_new (); - length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE; - - while (size >= OSPF_LSA_KEY_SIZE) - { - /* Get one slice of Link State Request. */ - ls_type = stream_getl (s); - ls_id.s_addr = stream_get_ipv4 (s); - adv_router.s_addr = stream_get_ipv4 (s); - - /* Verify LSA type. */ - if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA) - { - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq); - list_delete (ls_upd); - return; +static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh, + struct stream *s, struct ospf_interface *oi, + u_int16_t size) +{ + struct ospf_neighbor *nbr; + u_int32_t ls_type; + struct in_addr ls_id; + struct in_addr adv_router; + struct ospf_lsa *find; + struct list *ls_upd; + unsigned int length; + + /* Increment statistics. */ + oi->ls_req_in++; + + nbr = ospf_nbr_lookup(oi, iph, ospfh); + if (nbr == NULL) { + zlog_warn("Link State Request: Unknown Neighbor %s.", + inet_ntoa(ospfh->router_id)); + return; } - /* Search proper LSA in LSDB. */ - find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router); - if (find == NULL) - { - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq); - list_delete (ls_upd); - return; + /* Add event to thread. */ + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_PacketReceived); + + /* Neighbor State should be Exchange or later. */ + if (nbr->state != NSM_Exchange && nbr->state != NSM_Loading + && nbr->state != NSM_Full) { + zlog_warn( + "Link State Request received from %s: " + "Neighbor state is %s, packet discarded.", + inet_ntoa(ospfh->router_id), + lookup_msg(ospf_nsm_state_msg, nbr->state, NULL)); + return; } - /* Packet overflows MTU size, send immediately. */ - if (length + ntohs (find->data->length) > ospf_packet_max (oi)) - { - if (oi->type == OSPF_IFTYPE_NBMA) - ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT); - else - ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT); + /* Send Link State Update for ALL requested LSAs. */ + ls_upd = list_new(); + length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE; + + while (size >= OSPF_LSA_KEY_SIZE) { + /* Get one slice of Link State Request. */ + ls_type = stream_getl(s); + ls_id.s_addr = stream_get_ipv4(s); + adv_router.s_addr = stream_get_ipv4(s); + + /* Verify LSA type. */ + if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA) { + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_BadLSReq); + list_delete(ls_upd); + return; + } - /* Only remove list contents. Keep ls_upd. */ - list_delete_all_node (ls_upd); + /* Search proper LSA in LSDB. */ + find = ospf_lsa_lookup(oi->area, ls_type, ls_id, adv_router); + if (find == NULL) { + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_BadLSReq); + list_delete(ls_upd); + return; + } - length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE; - } + /* Packet overflows MTU size, send immediately. */ + if (length + ntohs(find->data->length) > ospf_packet_max(oi)) { + if (oi->type == OSPF_IFTYPE_NBMA) + ospf_ls_upd_send(nbr, ls_upd, + OSPF_SEND_PACKET_DIRECT); + else + ospf_ls_upd_send(nbr, ls_upd, + OSPF_SEND_PACKET_INDIRECT); + + /* Only remove list contents. Keep ls_upd. */ + list_delete_all_node(ls_upd); - /* Append LSA to update list. */ - listnode_add (ls_upd, find); - length += ntohs (find->data->length); + length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE; + } + + /* Append LSA to update list. */ + listnode_add(ls_upd, find); + length += ntohs(find->data->length); - size -= OSPF_LSA_KEY_SIZE; - } + size -= OSPF_LSA_KEY_SIZE; + } - /* Send rest of Link State Update. */ - if (listcount (ls_upd) > 0) - { - if (oi->type == OSPF_IFTYPE_NBMA) - ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT); - else - ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT); + /* Send rest of Link State Update. */ + if (listcount(ls_upd) > 0) { + if (oi->type == OSPF_IFTYPE_NBMA) + ospf_ls_upd_send(nbr, ls_upd, OSPF_SEND_PACKET_DIRECT); + else + ospf_ls_upd_send(nbr, ls_upd, + OSPF_SEND_PACKET_INDIRECT); - list_delete (ls_upd); - } - else - list_free (ls_upd); + list_delete(ls_upd); + } else + list_free(ls_upd); } /* Get the list of LSAs from Link State Update packet. And process some validation -- RFC2328 Section 13. (1)-(2). */ -static struct list * -ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s, - struct ospf_interface *oi, size_t size) -{ - u_int16_t count, sum; - u_int32_t length; - struct lsa_header *lsah; - struct ospf_lsa *lsa; - struct list *lsas; +static struct list *ospf_ls_upd_list_lsa(struct ospf_neighbor *nbr, + struct stream *s, + struct ospf_interface *oi, size_t size) +{ + u_int16_t count, sum; + u_int32_t length; + struct lsa_header *lsah; + struct ospf_lsa *lsa; + struct list *lsas; + + lsas = list_new(); + + count = stream_getl(s); + size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */ + + for (; size >= OSPF_LSA_HEADER_SIZE && count > 0; + size -= length, stream_forward_getp(s, length), count--) { + lsah = (struct lsa_header *)STREAM_PNT(s); + length = ntohs(lsah->length); + + if (length > size) { + zlog_warn( + "Link State Update: LSA length exceeds packet size."); + break; + } - lsas = list_new (); + /* Validate the LSA's LS checksum. */ + sum = lsah->checksum; + if (!ospf_lsa_checksum_valid(lsah)) { + /* (bug #685) more details in a one-line message make it + * possible + * to identify problem source on the one hand and to + * have a better + * chance to compress repeated messages in syslog on the + * other */ + zlog_warn( + "Link State Update: LSA checksum error %x/%x, ID=%s from: nbr %s, router ID %s, adv router %s", + sum, lsah->checksum, inet_ntoa(lsah->id), + inet_ntoa(nbr->src), inet_ntoa(nbr->router_id), + inet_ntoa(lsah->adv_router)); + continue; + } - count = stream_getl (s); - size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */ + /* Examine the LSA's LS type. */ + if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA) { + zlog_warn("Link State Update: Unknown LS type %d", + lsah->type); + continue; + } - for (; size >= OSPF_LSA_HEADER_SIZE && count > 0; - size -= length, stream_forward_getp (s, length), count--) - { - lsah = (struct lsa_header *) STREAM_PNT (s); - length = ntohs (lsah->length); + /* + * What if the received LSA's age is greater than MaxAge? + * Treat it as a MaxAge case -- endo. + */ + if (ntohs(lsah->ls_age) > OSPF_LSA_MAXAGE) + lsah->ls_age = htons(OSPF_LSA_MAXAGE); - if (length > size) - { - zlog_warn ("Link State Update: LSA length exceeds packet size."); - break; - } + if (CHECK_FLAG(nbr->options, OSPF_OPTION_O)) { +#ifdef STRICT_OBIT_USAGE_CHECK + if ((IS_OPAQUE_LSA(lsah->type) + && !CHECK_FLAG(lsah->options, OSPF_OPTION_O)) + || (!IS_OPAQUE_LSA(lsah->type) + && CHECK_FLAG(lsah->options, OSPF_OPTION_O))) { + /* + * This neighbor must know the exact usage of + * O-bit; + * the bit will be set in Type-9,10,11 LSAs + * only. + */ + zlog_warn("LSA[Type%d:%s]: O-bit abuse?", + lsah->type, inet_ntoa(lsah->id)); + continue; + } +#endif /* STRICT_OBIT_USAGE_CHECK */ - /* Validate the LSA's LS checksum. */ - sum = lsah->checksum; - if (! ospf_lsa_checksum_valid (lsah)) - { - /* (bug #685) more details in a one-line message make it possible - * to identify problem source on the one hand and to have a better - * chance to compress repeated messages in syslog on the other */ - zlog_warn ("Link State Update: LSA checksum error %x/%x, ID=%s from: nbr %s, router ID %s, adv router %s", - sum, lsah->checksum, inet_ntoa (lsah->id), - inet_ntoa (nbr->src), inet_ntoa (nbr->router_id), - inet_ntoa (lsah->adv_router)); - continue; - } - - /* Examine the LSA's LS type. */ - if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA) - { - zlog_warn ("Link State Update: Unknown LS type %d", lsah->type); - continue; - } + /* Do not take in AS External Opaque-LSAs if we are a + * stub. */ + if (lsah->type == OSPF_OPAQUE_AS_LSA + && nbr->oi->area->external_routing + != OSPF_AREA_DEFAULT) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "LSA[Type%d:%s]: We are a stub, don't take this LSA.", + lsah->type, + inet_ntoa(lsah->id)); + continue; + } + } else if (IS_OPAQUE_LSA(lsah->type)) { + zlog_warn("LSA[Type%d:%s]: Opaque capability mismatch?", + lsah->type, inet_ntoa(lsah->id)); + continue; + } - /* - * What if the received LSA's age is greater than MaxAge? - * Treat it as a MaxAge case -- endo. - */ - if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE) - lsah->ls_age = htons (OSPF_LSA_MAXAGE); + /* Create OSPF LSA instance. */ + lsa = ospf_lsa_new(); + + /* We may wish to put some error checking if type NSSA comes in + and area not in NSSA mode */ + switch (lsah->type) { + case OSPF_AS_EXTERNAL_LSA: + case OSPF_OPAQUE_AS_LSA: + lsa->area = NULL; + break; + case OSPF_OPAQUE_LINK_LSA: + lsa->oi = oi; /* Remember incoming interface for + flooding control. */ + /* Fallthrough */ + default: + lsa->area = oi->area; + break; + } - if (CHECK_FLAG (nbr->options, OSPF_OPTION_O)) - { -#ifdef STRICT_OBIT_USAGE_CHECK - if ((IS_OPAQUE_LSA(lsah->type) && - ! CHECK_FLAG (lsah->options, OSPF_OPTION_O)) - || (! IS_OPAQUE_LSA(lsah->type) && - CHECK_FLAG (lsah->options, OSPF_OPTION_O))) - { - /* - * This neighbor must know the exact usage of O-bit; - * the bit will be set in Type-9,10,11 LSAs only. - */ - zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id)); - continue; - } -#endif /* STRICT_OBIT_USAGE_CHECK */ + lsa->data = ospf_lsa_data_new(length); + memcpy(lsa->data, lsah, length); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "LSA[Type%d:%s]: %p new LSA created with Link State Update", + lsa->data->type, inet_ntoa(lsa->data->id), + (void *)lsa); + listnode_add(lsas, lsa); + } - /* Do not take in AS External Opaque-LSAs if we are a stub. */ - if (lsah->type == OSPF_OPAQUE_AS_LSA - && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("LSA[Type%d:%s]: We are a stub, don't take this LSA.", lsah->type, inet_ntoa (lsah->id)); - continue; - } - } - else if (IS_OPAQUE_LSA(lsah->type)) - { - zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id)); - continue; - } - - /* Create OSPF LSA instance. */ - lsa = ospf_lsa_new (); - - /* We may wish to put some error checking if type NSSA comes in - and area not in NSSA mode */ - switch (lsah->type) - { - case OSPF_AS_EXTERNAL_LSA: - case OSPF_OPAQUE_AS_LSA: - lsa->area = NULL; - break; - case OSPF_OPAQUE_LINK_LSA: - lsa->oi = oi; /* Remember incoming interface for flooding control. */ - /* Fallthrough */ - default: - lsa->area = oi->area; - break; - } - - lsa->data = ospf_lsa_data_new (length); - memcpy (lsa->data, lsah, length); - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update", - lsa->data->type, inet_ntoa (lsa->data->id), (void *)lsa); - listnode_add (lsas, lsa); - } - - return lsas; + return lsas; } /* Cleanup Update list. */ -static void -ospf_upd_list_clean (struct list *lsas) +static void ospf_upd_list_clean(struct list *lsas) { - struct listnode *node, *nnode; - struct ospf_lsa *lsa; + struct listnode *node, *nnode; + struct ospf_lsa *lsa; - for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa)) - ospf_lsa_discard (lsa); + for (ALL_LIST_ELEMENTS(lsas, node, nnode, lsa)) + ospf_lsa_discard(lsa); - list_delete (lsas); + list_delete(lsas); } /* OSPF Link State Update message read -- RFC2328 Section 13. */ -static void -ospf_ls_upd (struct ospf *ospf, struct ip *iph, struct ospf_header *ospfh, - struct stream *s, struct ospf_interface *oi, u_int16_t size) -{ - struct ospf_neighbor *nbr; - struct list *lsas; - struct listnode *node, *nnode; - struct ospf_lsa *lsa = NULL; - /* unsigned long ls_req_found = 0; */ - - /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */ - - /* Increment statistics. */ - oi->ls_upd_in++; - - /* Check neighbor. */ - nbr = ospf_nbr_lookup (oi, iph, ospfh); - if (nbr == NULL) - { - zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s", - inet_ntoa (ospfh->router_id), IF_NAME (oi)); - return; - } - - /* Add event to thread. */ - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived); - - /* Check neighbor state. */ - if (nbr->state < NSM_Exchange) - { - if (IS_DEBUG_OSPF (nsm, NSM_EVENTS)) - zlog_debug ("Link State Update: " - "Neighbor[%s] state %s is less than Exchange", - inet_ntoa (ospfh->router_id), - lookup_msg(ospf_nsm_state_msg, nbr->state, NULL)); - return; - } - - /* Get list of LSAs from Link State Update packet. - Also perorms Stages - * 1 (validate LSA checksum) and 2 (check for LSA consistent type) - * of section 13. - */ - lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size); - -#define DISCARD_LSA(L,N) {\ - if (IS_DEBUG_OSPF_EVENT) \ - zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point %d: lsa %p" \ - " Type-%d", N, (void *)lsa, (int) lsa->data->type); \ - ospf_lsa_discard (L); \ - continue; } - - /* Process each LSA received in the one packet. - * - * Numbers in parentheses, e.g. (1), (2), etc., and the corresponding - * text below are from the steps in RFC 2328, Section 13. - */ - for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa)) - { - struct ospf_lsa *ls_ret, *current; - int ret = 1; - - if (IS_DEBUG_OSPF_NSSA) - { - char buf1[INET_ADDRSTRLEN]; - char buf2[INET_ADDRSTRLEN]; - char buf3[INET_ADDRSTRLEN]; - - zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s", - lsa->data->type, - inet_ntop (AF_INET, &ospfh->router_id, - buf1, INET_ADDRSTRLEN), - inet_ntop (AF_INET, &lsa->data->id, - buf2, INET_ADDRSTRLEN), - inet_ntop (AF_INET, &lsa->data->adv_router, - buf3, INET_ADDRSTRLEN)); - } - - listnode_delete (lsas, lsa); /* We don't need it in list anymore */ - - /* (1) Validate Checksum - Done above by ospf_ls_upd_list_lsa() */ - - /* (2) LSA Type - Done above by ospf_ls_upd_list_lsa() */ - - /* (3) Do not take in AS External LSAs if we are a stub or NSSA. */ - - /* Do not take in AS NSSA if this neighbor and we are not NSSA */ - - /* Do take in Type-7's if we are an NSSA */ - - /* If we are also an ABR, later translate them to a Type-5 packet */ - - /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will - translate them to a separate Type-5 packet. */ - - if (lsa->data->type == OSPF_AS_EXTERNAL_LSA) - /* Reject from STUB or NSSA */ - if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area"); - DISCARD_LSA (lsa, 1); - } - - if (lsa->data->type == OSPF_AS_NSSA_LSA) - if (nbr->oi->area->external_routing != OSPF_AREA_NSSA) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area"); - DISCARD_LSA (lsa,2); - } - - /* VU229804: Router-LSA Adv-ID must be equal to LS-ID */ - if (lsa->data->type == OSPF_ROUTER_LSA) - if (!IPV4_ADDR_SAME(&lsa->data->id, &lsa->data->adv_router)) - { - char buf1[INET_ADDRSTRLEN]; - char buf2[INET_ADDRSTRLEN]; - char buf3[INET_ADDRSTRLEN]; - - zlog_err("Incoming Router-LSA from %s with " - "Adv-ID[%s] != LS-ID[%s]", - inet_ntop (AF_INET, &ospfh->router_id, - buf1, INET_ADDRSTRLEN), - inet_ntop (AF_INET, &lsa->data->id, - buf2, INET_ADDRSTRLEN), - inet_ntop (AF_INET, &lsa->data->adv_router, - buf3, INET_ADDRSTRLEN)); - zlog_err("OSPF domain compromised by attack or corruption. " - "Verify correct operation of -ALL- OSPF routers."); - DISCARD_LSA (lsa, 0); - } - - /* Find the LSA in the current database. */ - - current = ospf_lsa_lookup_by_header (oi->area, lsa->data); - - /* (4) If the LSA's LS age is equal to MaxAge, and there is currently - no instance of the LSA in the router's link state database, - and none of router's neighbors are in states Exchange or Loading, - then take the following actions: */ - - if (IS_LSA_MAXAGE (lsa) && !current && - ospf_check_nbr_status(oi->ospf)) - { - /* (4a) Response Link State Acknowledgment. */ - ospf_ls_ack_send (nbr, lsa); - - /* (4b) Discard LSA. */ - if (IS_DEBUG_OSPF (lsa, LSA)) - { - zlog_debug ("Link State Update[%s]: LS age is equal to MaxAge.", - dump_lsa_key(lsa)); - } - DISCARD_LSA (lsa, 3); - } - - if (IS_OPAQUE_LSA (lsa->data->type) - && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id)) - { - /* - * Even if initial flushing seems to be completed, there might - * be a case that self-originated LSA with MaxAge still remain - * in the routing domain. - * Just send an LSAck message to cease retransmission. - */ - if (IS_LSA_MAXAGE (lsa)) - { - zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa)); - ospf_ls_ack_send (nbr, lsa); - ospf_lsa_discard (lsa); - - if (current != NULL && ! IS_LSA_MAXAGE (current)) - ospf_opaque_lsa_refresh_schedule (current); - continue; - } - - /* - * If an instance of self-originated Opaque-LSA is not found - * in the LSDB, there are some possible cases here. - * - * 1) This node lost opaque-capability after restart. - * 2) Else, a part of opaque-type is no more supported. - * 3) Else, a part of opaque-id is no more supported. - * - * Anyway, it is still this node's responsibility to flush it. - * Otherwise, the LSA instance remains in the routing domain - * until its age reaches to MaxAge. - */ - /* XXX: We should deal with this for *ALL* LSAs, not just opaque */ - if (current == NULL) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("LSA[%s]: Previously originated Opaque-LSA," - "not found in the LSDB.", dump_lsa_key (lsa)); - - SET_FLAG (lsa->flags, OSPF_LSA_SELF); - - ospf_opaque_self_originated_lsa_received (nbr, lsa); - ospf_ls_ack_send (nbr, lsa); - - continue; - } - } - - /* It might be happen that received LSA is self-originated network LSA, but - * router ID is changed. So, we should check if LSA is a network-LSA whose - * Link State ID is one of the router's own IP interface addresses but whose - * Advertising Router is not equal to the router's own Router ID - * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed. - */ - - if(lsa->data->type == OSPF_NETWORK_LSA) - { - struct listnode *oinode, *oinnode; - struct ospf_interface *out_if; - int Flag = 0; - - for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if)) - { - if(out_if == NULL) - break; - - if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) && - (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router)))) - { - if(out_if->network_lsa_self) - { - ospf_lsa_flush_area(lsa,out_if->area); - if(IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d", - (void *)lsa, (int) lsa->data->type); - ospf_lsa_discard (lsa); - Flag = 1; - } - break; - } - } - if(Flag) - continue; - } - - /* (5) Find the instance of this LSA that is currently contained - in the router's link state database. If there is no - database copy, or the received LSA is more recent than - the database copy the following steps must be performed. - (The sub steps from RFC 2328 section 13 step (5) will be performed in - ospf_flood() ) */ - - if (current == NULL || - (ret = ospf_lsa_more_recent (current, lsa)) < 0) - { - /* Actual flooding procedure. */ - if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */ - DISCARD_LSA (lsa, 4); - continue; +static void ospf_ls_upd(struct ospf *ospf, struct ip *iph, + struct ospf_header *ospfh, struct stream *s, + struct ospf_interface *oi, u_int16_t size) +{ + struct ospf_neighbor *nbr; + struct list *lsas; + struct listnode *node, *nnode; + struct ospf_lsa *lsa = NULL; + /* unsigned long ls_req_found = 0; */ + + /* Dis-assemble the stream, update each entry, re-encapsulate for + * flooding */ + + /* Increment statistics. */ + oi->ls_upd_in++; + + /* Check neighbor. */ + nbr = ospf_nbr_lookup(oi, iph, ospfh); + if (nbr == NULL) { + zlog_warn("Link State Update: Unknown Neighbor %s on int: %s", + inet_ntoa(ospfh->router_id), IF_NAME(oi)); + return; } - /* (6) Else, If there is an instance of the LSA on the sending - neighbor's Link state request list, an error has occurred in - the Database Exchange process. In this case, restart the - Database Exchange process by generating the neighbor event - BadLSReq for the sending neighbor and stop processing the - Link State Update packet. */ - - if (ospf_ls_request_lookup (nbr, lsa)) - { - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq); - zlog_warn("LSA[%s] instance exists on Link state request list", - dump_lsa_key(lsa)); + /* Add event to thread. */ + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_PacketReceived); + + /* Check neighbor state. */ + if (nbr->state < NSM_Exchange) { + if (IS_DEBUG_OSPF(nsm, NSM_EVENTS)) + zlog_debug( + "Link State Update: " + "Neighbor[%s] state %s is less than Exchange", + inet_ntoa(ospfh->router_id), + lookup_msg(ospf_nsm_state_msg, nbr->state, + NULL)); + return; + } - /* Clean list of LSAs. */ - ospf_upd_list_clean (lsas); - /* this lsa is not on lsas list already. */ - ospf_lsa_discard (lsa); - return; + /* Get list of LSAs from Link State Update packet. - Also perorms Stages + * 1 (validate LSA checksum) and 2 (check for LSA consistent type) + * of section 13. + */ + lsas = ospf_ls_upd_list_lsa(nbr, s, oi, size); + +#define DISCARD_LSA(L, N) \ + { \ + if (IS_DEBUG_OSPF_EVENT) \ + zlog_debug( \ + "ospf_lsa_discard() in ospf_ls_upd() point %d: lsa %p" \ + " Type-%d", \ + N, (void *)lsa, (int)lsa->data->type); \ + ospf_lsa_discard(L); \ + continue; \ } - /* If the received LSA is the same instance as the database copy - (i.e., neither one is more recent) the following two steps - should be performed: */ + /* Process each LSA received in the one packet. + * + * Numbers in parentheses, e.g. (1), (2), etc., and the corresponding + * text below are from the steps in RFC 2328, Section 13. + */ + for (ALL_LIST_ELEMENTS(lsas, node, nnode, lsa)) { + struct ospf_lsa *ls_ret, *current; + int ret = 1; + + if (IS_DEBUG_OSPF_NSSA) { + char buf1[INET_ADDRSTRLEN]; + char buf2[INET_ADDRSTRLEN]; + char buf3[INET_ADDRSTRLEN]; + + zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s", + lsa->data->type, + inet_ntop(AF_INET, &ospfh->router_id, buf1, + INET_ADDRSTRLEN), + inet_ntop(AF_INET, &lsa->data->id, buf2, + INET_ADDRSTRLEN), + inet_ntop(AF_INET, &lsa->data->adv_router, + buf3, INET_ADDRSTRLEN)); + } - if (ret == 0) - { - /* If the LSA is listed in the Link state retransmission list - for the receiving adjacency, the router itself is expecting - an acknowledgment for this LSA. The router should treat the - received LSA as an acknowledgment by removing the LSA from - the Link state retransmission list. This is termed an - "implied acknowledgment". */ - - ls_ret = ospf_ls_retransmit_lookup (nbr, lsa); - - if (ls_ret != NULL) - { - ospf_ls_retransmit_delete (nbr, ls_ret); - - /* Delayed acknowledgment sent if advertisement received - from Designated Router, otherwise do nothing. */ - if (oi->state == ISM_Backup) - if (NBR_IS_DR (nbr)) - listnode_add (oi->ls_ack, ospf_lsa_lock (lsa)); - - DISCARD_LSA (lsa, 5); - } - else - /* Acknowledge the receipt of the LSA by sending a - Link State Acknowledgment packet back out the receiving - interface. */ - { - ospf_ls_ack_send (nbr, lsa); - DISCARD_LSA (lsa, 6); - } - } - - /* The database copy is more recent. If the database copy - has LS age equal to MaxAge and LS sequence number equal to - MaxSequenceNumber, simply discard the received LSA without - acknowledging it. (In this case, the LSA's LS sequence number is - wrapping, and the MaxSequenceNumber LSA must be completely - flushed before any new LSA instance can be introduced). */ - - else if (ret > 0) /* Database copy is more recent */ - { - if (IS_LSA_MAXAGE (current) && - current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER)) - { - DISCARD_LSA (lsa, 7); - } - /* Otherwise, as long as the database copy has not been sent in a - Link State Update within the last MinLSArrival seconds, send the - database copy back to the sending neighbor, encapsulated within - a Link State Update Packet. The Link State Update Packet should - be sent directly to the neighbor. In so doing, do not put the - database copy of the LSA on the neighbor's link state - retransmission list, and do not acknowledge the received (less - recent) LSA instance. */ - else - { - if (monotime_since (¤t->tv_orig, NULL) - >= ospf->min_ls_arrival * 1000LL) - /* Trap NSSA type later.*/ - ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT); - DISCARD_LSA (lsa, 8); - } - } - } + listnode_delete(lsas, + lsa); /* We don't need it in list anymore */ + + /* (1) Validate Checksum - Done above by ospf_ls_upd_list_lsa() + */ + + /* (2) LSA Type - Done above by ospf_ls_upd_list_lsa() */ + + /* (3) Do not take in AS External LSAs if we are a stub or NSSA. + */ + + /* Do not take in AS NSSA if this neighbor and we are not NSSA + */ + + /* Do take in Type-7's if we are an NSSA */ + + /* If we are also an ABR, later translate them to a Type-5 + * packet */ + + /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will + translate them to a separate Type-5 packet. */ + + if (lsa->data->type == OSPF_AS_EXTERNAL_LSA) + /* Reject from STUB or NSSA */ + if (nbr->oi->area->external_routing + != OSPF_AREA_DEFAULT) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "Incoming External LSA Discarded: We are NSSA/STUB Area"); + DISCARD_LSA(lsa, 1); + } + + if (lsa->data->type == OSPF_AS_NSSA_LSA) + if (nbr->oi->area->external_routing != OSPF_AREA_NSSA) { + if (IS_DEBUG_OSPF_NSSA) + zlog_debug( + "Incoming NSSA LSA Discarded: Not NSSA Area"); + DISCARD_LSA(lsa, 2); + } + + /* VU229804: Router-LSA Adv-ID must be equal to LS-ID */ + if (lsa->data->type == OSPF_ROUTER_LSA) + if (!IPV4_ADDR_SAME(&lsa->data->id, + &lsa->data->adv_router)) { + char buf1[INET_ADDRSTRLEN]; + char buf2[INET_ADDRSTRLEN]; + char buf3[INET_ADDRSTRLEN]; + + zlog_err( + "Incoming Router-LSA from %s with " + "Adv-ID[%s] != LS-ID[%s]", + inet_ntop(AF_INET, &ospfh->router_id, + buf1, INET_ADDRSTRLEN), + inet_ntop(AF_INET, &lsa->data->id, buf2, + INET_ADDRSTRLEN), + inet_ntop(AF_INET, + &lsa->data->adv_router, buf3, + INET_ADDRSTRLEN)); + zlog_err( + "OSPF domain compromised by attack or corruption. " + "Verify correct operation of -ALL- OSPF routers."); + DISCARD_LSA(lsa, 0); + } + + /* Find the LSA in the current database. */ + + current = ospf_lsa_lookup_by_header(oi->area, lsa->data); + + /* (4) If the LSA's LS age is equal to MaxAge, and there is + currently + no instance of the LSA in the router's link state database, + and none of router's neighbors are in states Exchange or + Loading, + then take the following actions: */ + + if (IS_LSA_MAXAGE(lsa) && !current + && ospf_check_nbr_status(oi->ospf)) { + /* (4a) Response Link State Acknowledgment. */ + ospf_ls_ack_send(nbr, lsa); + + /* (4b) Discard LSA. */ + if (IS_DEBUG_OSPF(lsa, LSA)) { + zlog_debug( + "Link State Update[%s]: LS age is equal to MaxAge.", + dump_lsa_key(lsa)); + } + DISCARD_LSA(lsa, 3); + } + + if (IS_OPAQUE_LSA(lsa->data->type) + && IPV4_ADDR_SAME(&lsa->data->adv_router, + &oi->ospf->router_id)) { + /* + * Even if initial flushing seems to be completed, there + * might + * be a case that self-originated LSA with MaxAge still + * remain + * in the routing domain. + * Just send an LSAck message to cease retransmission. + */ + if (IS_LSA_MAXAGE(lsa)) { + zlog_warn("LSA[%s]: Boomerang effect?", + dump_lsa_key(lsa)); + ospf_ls_ack_send(nbr, lsa); + ospf_lsa_discard(lsa); + + if (current != NULL && !IS_LSA_MAXAGE(current)) + ospf_opaque_lsa_refresh_schedule( + current); + continue; + } + + /* + * If an instance of self-originated Opaque-LSA is not + * found + * in the LSDB, there are some possible cases here. + * + * 1) This node lost opaque-capability after restart. + * 2) Else, a part of opaque-type is no more supported. + * 3) Else, a part of opaque-id is no more supported. + * + * Anyway, it is still this node's responsibility to + * flush it. + * Otherwise, the LSA instance remains in the routing + * domain + * until its age reaches to MaxAge. + */ + /* XXX: We should deal with this for *ALL* LSAs, not + * just opaque */ + if (current == NULL) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "LSA[%s]: Previously originated Opaque-LSA," + "not found in the LSDB.", + dump_lsa_key(lsa)); + + SET_FLAG(lsa->flags, OSPF_LSA_SELF); + + ospf_opaque_self_originated_lsa_received(nbr, + lsa); + ospf_ls_ack_send(nbr, lsa); + + continue; + } + } + + /* It might be happen that received LSA is self-originated + * network LSA, but + * router ID is changed. So, we should check if LSA is a + * network-LSA whose + * Link State ID is one of the router's own IP interface + * addresses but whose + * Advertising Router is not equal to the router's own Router ID + * According to RFC 2328 12.4.2 and 13.4 this LSA should be + * flushed. + */ + + if (lsa->data->type == OSPF_NETWORK_LSA) { + struct listnode *oinode, *oinnode; + struct ospf_interface *out_if; + int Flag = 0; + + for (ALL_LIST_ELEMENTS(oi->ospf->oiflist, oinode, + oinnode, out_if)) { + if (out_if == NULL) + break; + + if ((IPV4_ADDR_SAME(&out_if->address->u.prefix4, + &lsa->data->id)) + && (!(IPV4_ADDR_SAME( + &oi->ospf->router_id, + &lsa->data->adv_router)))) { + if (out_if->network_lsa_self) { + ospf_lsa_flush_area( + lsa, out_if->area); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d", + (void *)lsa, + (int)lsa->data + ->type); + ospf_lsa_discard(lsa); + Flag = 1; + } + break; + } + } + if (Flag) + continue; + } + + /* (5) Find the instance of this LSA that is currently contained + in the router's link state database. If there is no + database copy, or the received LSA is more recent than + the database copy the following steps must be performed. + (The sub steps from RFC 2328 section 13 step (5) will be + performed in + ospf_flood() ) */ + + if (current == NULL + || (ret = ospf_lsa_more_recent(current, lsa)) < 0) { + /* Actual flooding procedure. */ + if (ospf_flood(oi->ospf, nbr, current, lsa) + < 0) /* Trap NSSA later. */ + DISCARD_LSA(lsa, 4); + continue; + } + + /* (6) Else, If there is an instance of the LSA on the sending + neighbor's Link state request list, an error has occurred in + the Database Exchange process. In this case, restart the + Database Exchange process by generating the neighbor event + BadLSReq for the sending neighbor and stop processing the + Link State Update packet. */ + + if (ospf_ls_request_lookup(nbr, lsa)) { + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_BadLSReq); + zlog_warn( + "LSA[%s] instance exists on Link state request list", + dump_lsa_key(lsa)); + + /* Clean list of LSAs. */ + ospf_upd_list_clean(lsas); + /* this lsa is not on lsas list already. */ + ospf_lsa_discard(lsa); + return; + } + + /* If the received LSA is the same instance as the database copy + (i.e., neither one is more recent) the following two steps + should be performed: */ + + if (ret == 0) { + /* If the LSA is listed in the Link state retransmission + list + for the receiving adjacency, the router itself is + expecting + an acknowledgment for this LSA. The router should + treat the + received LSA as an acknowledgment by removing the LSA + from + the Link state retransmission list. This is termed + an + "implied acknowledgment". */ + + ls_ret = ospf_ls_retransmit_lookup(nbr, lsa); + + if (ls_ret != NULL) { + ospf_ls_retransmit_delete(nbr, ls_ret); + + /* Delayed acknowledgment sent if advertisement + received + from Designated Router, otherwise do nothing. + */ + if (oi->state == ISM_Backup) + if (NBR_IS_DR(nbr)) + listnode_add( + oi->ls_ack, + ospf_lsa_lock(lsa)); + + DISCARD_LSA(lsa, 5); + } else + /* Acknowledge the receipt of the LSA by sending a + Link State Acknowledgment packet back out the + receiving + interface. */ + { + ospf_ls_ack_send(nbr, lsa); + DISCARD_LSA(lsa, 6); + } + } + + /* The database copy is more recent. If the database copy + has LS age equal to MaxAge and LS sequence number equal to + MaxSequenceNumber, simply discard the received LSA without + acknowledging it. (In this case, the LSA's LS sequence number + is + wrapping, and the MaxSequenceNumber LSA must be completely + flushed before any new LSA instance can be introduced). */ + + else if (ret > 0) /* Database copy is more recent */ + { + if (IS_LSA_MAXAGE(current) + && current->data->ls_seqnum + == htonl(OSPF_MAX_SEQUENCE_NUMBER)) { + DISCARD_LSA(lsa, 7); + } + /* Otherwise, as long as the database copy has not been + sent in a + Link State Update within the last MinLSArrival + seconds, send the + database copy back to the sending neighbor, + encapsulated within + a Link State Update Packet. The Link State Update + Packet should + be sent directly to the neighbor. In so doing, do not + put the + database copy of the LSA on the neighbor's link state + retransmission list, and do not acknowledge the + received (less + recent) LSA instance. */ + else { + if (monotime_since(¤t->tv_orig, NULL) + >= ospf->min_ls_arrival * 1000LL) + /* Trap NSSA type later.*/ + ospf_ls_upd_send_lsa( + nbr, current, + OSPF_SEND_PACKET_DIRECT); + DISCARD_LSA(lsa, 8); + } + } + } #undef DISCARD_LSA - assert (listcount (lsas) == 0); - list_delete (lsas); + assert(listcount(lsas) == 0); + list_delete(lsas); } /* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */ -static void -ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh, - struct stream *s, struct ospf_interface *oi, u_int16_t size) -{ - struct ospf_neighbor *nbr; - - /* increment statistics. */ - oi->ls_ack_in++; - - nbr = ospf_nbr_lookup (oi, iph, ospfh); - if (nbr == NULL) - { - zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.", - inet_ntoa (ospfh->router_id)); - return; - } - - /* Add event to thread. */ - OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived); - - if (nbr->state < NSM_Exchange) - { - if (IS_DEBUG_OSPF (nsm, NSM_EVENTS)) - zlog_debug ("Link State Acknowledgment: " - "Neighbor[%s] state %s is less than Exchange", - inet_ntoa (ospfh->router_id), - lookup_msg(ospf_nsm_state_msg, nbr->state, NULL)); - return; - } - - while (size >= OSPF_LSA_HEADER_SIZE) - { - struct ospf_lsa *lsa, *lsr; - - lsa = ospf_lsa_new (); - lsa->data = (struct lsa_header *) STREAM_PNT (s); - - /* lsah = (struct lsa_header *) STREAM_PNT (s); */ - size -= OSPF_LSA_HEADER_SIZE; - stream_forward_getp (s, OSPF_LSA_HEADER_SIZE); - - if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA) +static void ospf_ls_ack(struct ip *iph, struct ospf_header *ospfh, + struct stream *s, struct ospf_interface *oi, + u_int16_t size) +{ + struct ospf_neighbor *nbr; + + /* increment statistics. */ + oi->ls_ack_in++; + + nbr = ospf_nbr_lookup(oi, iph, ospfh); + if (nbr == NULL) { + zlog_warn("Link State Acknowledgment: Unknown Neighbor %s.", + inet_ntoa(ospfh->router_id)); + return; + } + + /* Add event to thread. */ + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_PacketReceived); + + if (nbr->state < NSM_Exchange) { + if (IS_DEBUG_OSPF(nsm, NSM_EVENTS)) + zlog_debug( + "Link State Acknowledgment: " + "Neighbor[%s] state %s is less than Exchange", + inet_ntoa(ospfh->router_id), + lookup_msg(ospf_nsm_state_msg, nbr->state, + NULL)); + return; + } + + while (size >= OSPF_LSA_HEADER_SIZE) { + struct ospf_lsa *lsa, *lsr; + + lsa = ospf_lsa_new(); + lsa->data = (struct lsa_header *)STREAM_PNT(s); + + /* lsah = (struct lsa_header *) STREAM_PNT (s); */ + size -= OSPF_LSA_HEADER_SIZE; + stream_forward_getp(s, OSPF_LSA_HEADER_SIZE); + + if (lsa->data->type < OSPF_MIN_LSA + || lsa->data->type >= OSPF_MAX_LSA) { + lsa->data = NULL; + ospf_lsa_discard(lsa); + continue; + } + + lsr = ospf_ls_retransmit_lookup(nbr, lsa); + + if (lsr != NULL && ospf_lsa_more_recent(lsr, lsa) == 0) + ospf_ls_retransmit_delete(nbr, lsr); + + lsa->data = NULL; + ospf_lsa_discard(lsa); + } + + return; +} + +static struct stream *ospf_recv_packet(int fd, struct interface **ifp, + struct stream *ibuf) +{ + int ret; + struct ip *iph; + u_int16_t ip_len; + ifindex_t ifindex = 0; + struct iovec iov; + /* Header and data both require alignment. */ + char buff[CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())]; + struct msghdr msgh; + + memset(&msgh, 0, sizeof(struct msghdr)); + msgh.msg_iov = &iov; + msgh.msg_iovlen = 1; + msgh.msg_control = (caddr_t)buff; + msgh.msg_controllen = sizeof(buff); + + ret = stream_recvmsg(ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE + 1); + if (ret < 0) { + zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno)); + return NULL; + } + if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */ { - lsa->data = NULL; - ospf_lsa_discard (lsa); - continue; - } - - lsr = ospf_ls_retransmit_lookup (nbr, lsa); - - if (lsr != NULL && ospf_lsa_more_recent (lsr, lsa) == 0) - ospf_ls_retransmit_delete (nbr, lsr); - - lsa->data = NULL; - ospf_lsa_discard (lsa); - } - - return; -} - -static struct stream * -ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf) -{ - int ret; - struct ip *iph; - u_int16_t ip_len; - ifindex_t ifindex = 0; - struct iovec iov; - /* Header and data both require alignment. */ - char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())]; - struct msghdr msgh; - - memset (&msgh, 0, sizeof (struct msghdr)); - msgh.msg_iov = &iov; - msgh.msg_iovlen = 1; - msgh.msg_control = (caddr_t) buff; - msgh.msg_controllen = sizeof (buff); - - ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1); - if (ret < 0) - { - zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno)); - return NULL; - } - if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */ - { - zlog_warn("ospf_recv_packet: discarding runt packet of length %d " - "(ip header size is %u)", - ret, (u_int)sizeof(iph)); - return NULL; - } - - /* Note that there should not be alignment problems with this assignment - because this is at the beginning of the stream data buffer. */ - iph = (struct ip *) STREAM_DATA(ibuf); - sockopt_iphdrincl_swab_systoh (iph); - - ip_len = iph->ip_len; - + zlog_warn( + "ospf_recv_packet: discarding runt packet of length %d " + "(ip header size is %u)", + ret, (u_int)sizeof(iph)); + return NULL; + } + + /* Note that there should not be alignment problems with this assignment + because this is at the beginning of the stream data buffer. */ + iph = (struct ip *)STREAM_DATA(ibuf); + sockopt_iphdrincl_swab_systoh(iph); + + ip_len = iph->ip_len; + #if !defined(GNU_LINUX) && (OpenBSD < 200311) && (__FreeBSD_version < 1000000) - /* - * Kernel network code touches incoming IP header parameters, - * before protocol specific processing. - * - * 1) Convert byteorder to host representation. - * --> ip_len, ip_id, ip_off - * - * 2) Adjust ip_len to strip IP header size! - * --> If user process receives entire IP packet via RAW - * socket, it must consider adding IP header size to - * the "ip_len" field of "ip" structure. - * - * For more details, see <netinet/ip_input.c>. - */ - ip_len = ip_len + (iph->ip_hl << 2); + /* + * Kernel network code touches incoming IP header parameters, + * before protocol specific processing. + * + * 1) Convert byteorder to host representation. + * --> ip_len, ip_id, ip_off + * + * 2) Adjust ip_len to strip IP header size! + * --> If user process receives entire IP packet via RAW + * socket, it must consider adding IP header size to + * the "ip_len" field of "ip" structure. + * + * For more details, see <netinet/ip_input.c>. + */ + ip_len = ip_len + (iph->ip_hl << 2); #endif - + #if defined(__DragonFly__) - /* - * in DragonFly's raw socket, ip_len/ip_off are read - * in network byte order. - * As OpenBSD < 200311 adjust ip_len to strip IP header size! - */ - ip_len = ntohs(iph->ip_len) + (iph->ip_hl << 2); + /* + * in DragonFly's raw socket, ip_len/ip_off are read + * in network byte order. + * As OpenBSD < 200311 adjust ip_len to strip IP header size! + */ + ip_len = ntohs(iph->ip_len) + (iph->ip_hl << 2); #endif - ifindex = getsockopt_ifindex (AF_INET, &msgh); - - *ifp = if_lookup_by_index (ifindex, VRF_DEFAULT); + ifindex = getsockopt_ifindex(AF_INET, &msgh); + + *ifp = if_lookup_by_index(ifindex, VRF_DEFAULT); + + if (ret != ip_len) { + zlog_warn( + "ospf_recv_packet read length mismatch: ip_len is %d, " + "but recvmsg returned %d", + ip_len, ret); + return NULL; + } - if (ret != ip_len) - { - zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, " - "but recvmsg returned %d", ip_len, ret); - return NULL; - } - - return ibuf; + return ibuf; } static struct ospf_interface * -ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp, - struct ip *iph, struct ospf_header *ospfh) -{ - struct ospf_interface *rcv_oi; - struct ospf_vl_data *vl_data; - struct ospf_area *vl_area; - struct listnode *node; - - if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) || - !OSPF_IS_AREA_BACKBONE (ospfh)) - return NULL; - - /* look for local OSPF interface matching the destination - * to determine Area ID. We presume therefore the destination address - * is unique, or at least (for "unnumbered" links), not used in other - * areas - */ - if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL, - iph->ip_dst)) == NULL) - return NULL; - - for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data)) - { - vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id); - if (!vl_area) - continue; - - if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) && - IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("associating packet with %s", - IF_NAME (vl_data->vl_oi)); - if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("This VL is not up yet, sorry"); - return NULL; - } - - return vl_data->vl_oi; +ospf_associate_packet_vl(struct ospf *ospf, struct interface *ifp, + struct ip *iph, struct ospf_header *ospfh) +{ + struct ospf_interface *rcv_oi; + struct ospf_vl_data *vl_data; + struct ospf_area *vl_area; + struct listnode *node; + + if (IN_MULTICAST(ntohl(iph->ip_dst.s_addr)) + || !OSPF_IS_AREA_BACKBONE(ospfh)) + return NULL; + + /* look for local OSPF interface matching the destination + * to determine Area ID. We presume therefore the destination address + * is unique, or at least (for "unnumbered" links), not used in other + * areas + */ + if ((rcv_oi = ospf_if_lookup_by_local_addr(ospf, NULL, iph->ip_dst)) + == NULL) + return NULL; + + for (ALL_LIST_ELEMENTS_RO(ospf->vlinks, node, vl_data)) { + vl_area = + ospf_area_lookup_by_area_id(ospf, vl_data->vl_area_id); + if (!vl_area) + continue; + + if (OSPF_AREA_SAME(&vl_area, &rcv_oi->area) + && IPV4_ADDR_SAME(&vl_data->vl_peer, &ospfh->router_id)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("associating packet with %s", + IF_NAME(vl_data->vl_oi)); + if (!CHECK_FLAG(vl_data->vl_oi->ifp->flags, IFF_UP)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "This VL is not up yet, sorry"); + return NULL; + } + + return vl_data->vl_oi; + } } - } - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("couldn't find any VL to associate the packet with"); - - return NULL; + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("couldn't find any VL to associate the packet with"); + + return NULL; } -static int -ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh) +static int ospf_check_area_id(struct ospf_interface *oi, + struct ospf_header *ospfh) { - /* Check match the Area ID of the receiving interface. */ - if (OSPF_AREA_SAME (&oi->area, &ospfh)) - return 1; + /* Check match the Area ID of the receiving interface. */ + if (OSPF_AREA_SAME(&oi->area, &ospfh)) + return 1; - return 0; + return 0; } /* Unbound socket will accept any Raw IP packets if proto is matched. To prevent it, compare src IP address and i/f address with masking i/f network mask. */ -static int -ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src) +static int ospf_check_network_mask(struct ospf_interface *oi, + struct in_addr ip_src) { - struct in_addr mask, me, him; + struct in_addr mask, me, him; - if (oi->type == OSPF_IFTYPE_POINTOPOINT || - oi->type == OSPF_IFTYPE_VIRTUALLINK) - return 1; + if (oi->type == OSPF_IFTYPE_POINTOPOINT + || oi->type == OSPF_IFTYPE_VIRTUALLINK) + return 1; - masklen2ip (oi->address->prefixlen, &mask); + masklen2ip(oi->address->prefixlen, &mask); - me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr; - him.s_addr = ip_src.s_addr & mask.s_addr; + me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr; + him.s_addr = ip_src.s_addr & mask.s_addr; - if (IPV4_ADDR_SAME (&me, &him)) - return 1; + if (IPV4_ADDR_SAME(&me, &him)) + return 1; - return 0; + return 0; } /* Return 1, if the packet is properly authenticated and checksummed, 0 otherwise. In particular, check that AuType header field is valid and matches the locally configured AuType, and that D.5 requirements are met. */ -static int -ospf_check_auth (struct ospf_interface *oi, struct ospf_header *ospfh) -{ - struct crypt_key *ck; - u_int16_t iface_auth_type; - u_int16_t pkt_auth_type = ntohs (ospfh->auth_type); - - switch (pkt_auth_type) - { - case OSPF_AUTH_NULL: /* RFC2328 D.5.1 */ - if (OSPF_AUTH_NULL != (iface_auth_type = ospf_auth_type (oi))) - { - if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) - zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Null", - IF_NAME (oi), lookup_msg(ospf_auth_type_str, iface_auth_type, NULL)); - return 0; - } - if (! ospf_check_sum (ospfh)) - { - if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) - zlog_warn ("interface %s: Null auth OK, but checksum error, Router-ID %s", - IF_NAME (oi), inet_ntoa (ospfh->router_id)); - return 0; - } - return 1; - case OSPF_AUTH_SIMPLE: /* RFC2328 D.5.2 */ - if (OSPF_AUTH_SIMPLE != (iface_auth_type = ospf_auth_type (oi))) - { - if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) - zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Simple", - IF_NAME (oi), lookup_msg(ospf_auth_type_str, iface_auth_type, NULL)); - return 0; - } - if (memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE)) - { - if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) - zlog_warn ("interface %s: Simple auth failed", IF_NAME (oi)); - return 0; - } - if (! ospf_check_sum (ospfh)) - { - if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) - zlog_warn ("interface %s: Simple auth OK, checksum error, Router-ID %s", - IF_NAME (oi), inet_ntoa (ospfh->router_id)); - return 0; - } - return 1; - case OSPF_AUTH_CRYPTOGRAPHIC: /* RFC2328 D.5.3 */ - if (OSPF_AUTH_CRYPTOGRAPHIC != (iface_auth_type = ospf_auth_type (oi))) - { - if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) - zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Cryptographic", - IF_NAME (oi), lookup_msg(ospf_auth_type_str, iface_auth_type, NULL)); - return 0; - } - if (ospfh->checksum) - { - if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) - zlog_warn ("interface %s: OSPF header checksum is not 0", IF_NAME (oi)); - return 0; - } - /* only MD5 crypto method can pass ospf_packet_examin() */ - if - ( - NULL == (ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) || - ospfh->u.crypt.key_id != ck->key_id || - /* Condition above uses the last key ID on the list, which is - different from what ospf_crypt_key_lookup() does. A bug? */ - ! ospf_check_md5_digest (oi, ospfh) - ) - { - if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) - zlog_warn ("interface %s: MD5 auth failed", IF_NAME (oi)); - return 0; - } - return 1; - default: - if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) - zlog_warn ("interface %s: invalid packet auth-type (%02x)", - IF_NAME (oi), pkt_auth_type); - return 0; - } -} - -static int -ospf_check_sum (struct ospf_header *ospfh) -{ - u_int32_t ret; - u_int16_t sum; - - /* clear auth_data for checksum. */ - memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE); - - /* keep checksum and clear. */ - sum = ospfh->checksum; - memset (&ospfh->checksum, 0, sizeof (u_int16_t)); - - /* calculate checksum. */ - ret = in_cksum (ospfh, ntohs (ospfh->length)); - - if (ret != sum) - { - zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X", - ret, sum); - return 0; - } - - return 1; +static int ospf_check_auth(struct ospf_interface *oi, struct ospf_header *ospfh) +{ + struct crypt_key *ck; + u_int16_t iface_auth_type; + u_int16_t pkt_auth_type = ntohs(ospfh->auth_type); + + switch (pkt_auth_type) { + case OSPF_AUTH_NULL: /* RFC2328 D.5.1 */ + if (OSPF_AUTH_NULL != (iface_auth_type = ospf_auth_type(oi))) { + if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV)) + zlog_warn( + "interface %s: auth-type mismatch, local %s, rcvd Null", + IF_NAME(oi), + lookup_msg(ospf_auth_type_str, + iface_auth_type, NULL)); + return 0; + } + if (!ospf_check_sum(ospfh)) { + if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV)) + zlog_warn( + "interface %s: Null auth OK, but checksum error, Router-ID %s", + IF_NAME(oi), + inet_ntoa(ospfh->router_id)); + return 0; + } + return 1; + case OSPF_AUTH_SIMPLE: /* RFC2328 D.5.2 */ + if (OSPF_AUTH_SIMPLE + != (iface_auth_type = ospf_auth_type(oi))) { + if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV)) + zlog_warn( + "interface %s: auth-type mismatch, local %s, rcvd Simple", + IF_NAME(oi), + lookup_msg(ospf_auth_type_str, + iface_auth_type, NULL)); + return 0; + } + if (memcmp(OSPF_IF_PARAM(oi, auth_simple), ospfh->u.auth_data, + OSPF_AUTH_SIMPLE_SIZE)) { + if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV)) + zlog_warn("interface %s: Simple auth failed", + IF_NAME(oi)); + return 0; + } + if (!ospf_check_sum(ospfh)) { + if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV)) + zlog_warn( + "interface %s: Simple auth OK, checksum error, Router-ID %s", + IF_NAME(oi), + inet_ntoa(ospfh->router_id)); + return 0; + } + return 1; + case OSPF_AUTH_CRYPTOGRAPHIC: /* RFC2328 D.5.3 */ + if (OSPF_AUTH_CRYPTOGRAPHIC + != (iface_auth_type = ospf_auth_type(oi))) { + if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV)) + zlog_warn( + "interface %s: auth-type mismatch, local %s, rcvd Cryptographic", + IF_NAME(oi), + lookup_msg(ospf_auth_type_str, + iface_auth_type, NULL)); + return 0; + } + if (ospfh->checksum) { + if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV)) + zlog_warn( + "interface %s: OSPF header checksum is not 0", + IF_NAME(oi)); + return 0; + } + /* only MD5 crypto method can pass ospf_packet_examin() */ + if ( + NULL == (ck = listgetdata(listtail( + OSPF_IF_PARAM(oi, auth_crypt)))) + || ospfh->u.crypt.key_id != ck->key_id || + /* Condition above uses the last key ID on the list, + which is + different from what ospf_crypt_key_lookup() does. A + bug? */ + !ospf_check_md5_digest(oi, ospfh)) { + if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV)) + zlog_warn("interface %s: MD5 auth failed", + IF_NAME(oi)); + return 0; + } + return 1; + default: + if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV)) + zlog_warn( + "interface %s: invalid packet auth-type (%02x)", + IF_NAME(oi), pkt_auth_type); + return 0; + } +} + +static int ospf_check_sum(struct ospf_header *ospfh) +{ + u_int32_t ret; + u_int16_t sum; + + /* clear auth_data for checksum. */ + memset(ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE); + + /* keep checksum and clear. */ + sum = ospfh->checksum; + memset(&ospfh->checksum, 0, sizeof(u_int16_t)); + + /* calculate checksum. */ + ret = in_cksum(ospfh, ntohs(ospfh->length)); + + if (ret != sum) { + zlog_info("ospf_check_sum(): checksum mismatch, my %X, his %X", + ret, sum); + return 0; + } + + return 1; } /* Verify, that given link/TOS records are properly sized/aligned and match Router-LSA "# links" and "# TOS" fields as specified in RFC2328 A.4.2. */ -static unsigned -ospf_router_lsa_links_examin -( - struct router_lsa_link * link, - u_int16_t linkbytes, - const u_int16_t num_links -) -{ - unsigned counted_links = 0, thislinklen; - - while (linkbytes) - { - thislinklen = OSPF_ROUTER_LSA_LINK_SIZE + 4 * link->m[0].tos_count; - if (thislinklen > linkbytes) - { - if (IS_DEBUG_OSPF_PACKET (0, RECV)) - zlog_debug ("%s: length error in link block #%u", __func__, counted_links); - return MSG_NG; - } - link = (struct router_lsa_link *)((caddr_t) link + thislinklen); - linkbytes -= thislinklen; - counted_links++; - } - if (counted_links != num_links) - { - if (IS_DEBUG_OSPF_PACKET (0, RECV)) - zlog_debug ("%s: %u link blocks declared, %u present", - __func__, num_links, counted_links); - return MSG_NG; - } - return MSG_OK; +static unsigned ospf_router_lsa_links_examin(struct router_lsa_link *link, + u_int16_t linkbytes, + const u_int16_t num_links) +{ + unsigned counted_links = 0, thislinklen; + + while (linkbytes) { + thislinklen = + OSPF_ROUTER_LSA_LINK_SIZE + 4 * link->m[0].tos_count; + if (thislinklen > linkbytes) { + if (IS_DEBUG_OSPF_PACKET(0, RECV)) + zlog_debug("%s: length error in link block #%u", + __func__, counted_links); + return MSG_NG; + } + link = (struct router_lsa_link *)((caddr_t)link + thislinklen); + linkbytes -= thislinklen; + counted_links++; + } + if (counted_links != num_links) { + if (IS_DEBUG_OSPF_PACKET(0, RECV)) + zlog_debug("%s: %u link blocks declared, %u present", + __func__, num_links, counted_links); + return MSG_NG; + } + return MSG_OK; } /* Verify, that the given LSA is properly sized/aligned (including type-specific minimum length constraint). */ -static unsigned -ospf_lsa_examin (struct lsa_header * lsah, const u_int16_t lsalen, const u_char headeronly) -{ - unsigned ret; - struct router_lsa * rlsa; - if - ( - lsah->type < OSPF_MAX_LSA && - ospf_lsa_minlen[lsah->type] && - lsalen < OSPF_LSA_HEADER_SIZE + ospf_lsa_minlen[lsah->type] - ) - { - if (IS_DEBUG_OSPF_PACKET (0, RECV)) - zlog_debug ("%s: undersized (%u B) %s", - __func__, lsalen, lookup_msg(ospf_lsa_type_msg, lsah->type, NULL)); - return MSG_NG; - } - switch (lsah->type) - { - case OSPF_ROUTER_LSA: - /* RFC2328 A.4.2, LSA header + 4 bytes followed by N>=1 (12+)-byte link blocks */ - if (headeronly) - { - ret = (lsalen - OSPF_LSA_HEADER_SIZE - OSPF_ROUTER_LSA_MIN_SIZE) % 4 ? MSG_NG : MSG_OK; - break; - } - rlsa = (struct router_lsa *) lsah; - ret = ospf_router_lsa_links_examin - ( - (struct router_lsa_link *) rlsa->link, - lsalen - OSPF_LSA_HEADER_SIZE - 4, /* skip: basic header, "flags", 0, "# links" */ - ntohs (rlsa->links) /* 16 bits */ - ); - break; - case OSPF_AS_EXTERNAL_LSA: - /* RFC2328 A.4.5, LSA header + 4 bytes followed by N>=1 12-bytes long blocks */ - case OSPF_AS_NSSA_LSA: - /* RFC3101 C, idem */ - ret = (lsalen - OSPF_LSA_HEADER_SIZE - OSPF_AS_EXTERNAL_LSA_MIN_SIZE) % 12 ? MSG_NG : MSG_OK; - break; - /* Following LSA types are considered OK length-wise as soon as their minimum - * length constraint is met and length of the whole LSA is a multiple of 4 - * (basic LSA header size is already a multiple of 4). */ - case OSPF_NETWORK_LSA: - /* RFC2328 A.4.3, LSA header + 4 bytes followed by N>=1 router-IDs */ - case OSPF_SUMMARY_LSA: - case OSPF_ASBR_SUMMARY_LSA: - /* RFC2328 A.4.4, LSA header + 4 bytes followed by N>=1 4-bytes TOS blocks */ - case OSPF_OPAQUE_LINK_LSA: - case OSPF_OPAQUE_AREA_LSA: - case OSPF_OPAQUE_AS_LSA: - /* RFC5250 A.2, "some number of octets (of application-specific - * data) padded to 32-bit alignment." This is considered equivalent - * to 4-byte alignment of all other LSA types, see OSPF-ALIGNMENT.txt - * file for the detailed analysis of this passage. */ - ret = lsalen % 4 ? MSG_NG : MSG_OK; - break; - default: - if (IS_DEBUG_OSPF_PACKET (0, RECV)) - zlog_debug ("%s: unsupported LSA type 0x%02x", __func__, lsah->type); - return MSG_NG; - } - if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET (0, RECV)) - zlog_debug ("%s: alignment error in %s", - __func__, lookup_msg(ospf_lsa_type_msg, lsah->type, NULL)); - return ret; +static unsigned ospf_lsa_examin(struct lsa_header *lsah, const u_int16_t lsalen, + const u_char headeronly) +{ + unsigned ret; + struct router_lsa *rlsa; + if (lsah->type < OSPF_MAX_LSA && ospf_lsa_minlen[lsah->type] + && lsalen < OSPF_LSA_HEADER_SIZE + ospf_lsa_minlen[lsah->type]) { + if (IS_DEBUG_OSPF_PACKET(0, RECV)) + zlog_debug("%s: undersized (%u B) %s", __func__, lsalen, + lookup_msg(ospf_lsa_type_msg, lsah->type, + NULL)); + return MSG_NG; + } + switch (lsah->type) { + case OSPF_ROUTER_LSA: + /* RFC2328 A.4.2, LSA header + 4 bytes followed by N>=1 + * (12+)-byte link blocks */ + if (headeronly) { + ret = (lsalen - OSPF_LSA_HEADER_SIZE + - OSPF_ROUTER_LSA_MIN_SIZE) + % 4 + ? MSG_NG + : MSG_OK; + break; + } + rlsa = (struct router_lsa *)lsah; + ret = ospf_router_lsa_links_examin( + (struct router_lsa_link *)rlsa->link, + lsalen - OSPF_LSA_HEADER_SIZE - 4, /* skip: basic + header, "flags", + 0, "# links" */ + ntohs(rlsa->links) /* 16 bits */ + ); + break; + case OSPF_AS_EXTERNAL_LSA: + /* RFC2328 A.4.5, LSA header + 4 bytes followed by N>=1 12-bytes long + * blocks */ + case OSPF_AS_NSSA_LSA: + /* RFC3101 C, idem */ + ret = (lsalen - OSPF_LSA_HEADER_SIZE + - OSPF_AS_EXTERNAL_LSA_MIN_SIZE) + % 12 + ? MSG_NG + : MSG_OK; + break; + /* Following LSA types are considered OK length-wise as soon as their + * minimum + * length constraint is met and length of the whole LSA is a multiple of + * 4 + * (basic LSA header size is already a multiple of 4). */ + case OSPF_NETWORK_LSA: + /* RFC2328 A.4.3, LSA header + 4 bytes followed by N>=1 router-IDs */ + case OSPF_SUMMARY_LSA: + case OSPF_ASBR_SUMMARY_LSA: + /* RFC2328 A.4.4, LSA header + 4 bytes followed by N>=1 4-bytes TOS + * blocks */ + case OSPF_OPAQUE_LINK_LSA: + case OSPF_OPAQUE_AREA_LSA: + case OSPF_OPAQUE_AS_LSA: + /* RFC5250 A.2, "some number of octets (of application-specific + * data) padded to 32-bit alignment." This is considered + * equivalent + * to 4-byte alignment of all other LSA types, see + * OSPF-ALIGNMENT.txt + * file for the detailed analysis of this passage. */ + ret = lsalen % 4 ? MSG_NG : MSG_OK; + break; + default: + if (IS_DEBUG_OSPF_PACKET(0, RECV)) + zlog_debug("%s: unsupported LSA type 0x%02x", __func__, + lsah->type); + return MSG_NG; + } + if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET(0, RECV)) + zlog_debug("%s: alignment error in %s", __func__, + lookup_msg(ospf_lsa_type_msg, lsah->type, NULL)); + return ret; } /* 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 -ospf_lsaseq_examin -( - struct 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 < OSPF_LSA_HEADER_SIZE) - { - if (IS_DEBUG_OSPF_PACKET (0, 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 = ntohs (lsah->length); - if (lsalen < OSPF_LSA_HEADER_SIZE) - { - if (IS_DEBUG_OSPF_PACKET (0, 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 ospf_lsa_examin() */ - if (MSG_OK != ospf_lsa_examin (lsah, lsalen, 1)) - { - if (IS_DEBUG_OSPF_PACKET (0, RECV)) - zlog_debug ("%s: malformed header-only LSA #%u", __func__, counted_lsas); - return MSG_NG; - } - lsah = (struct lsa_header *) ((caddr_t) lsah + OSPF_LSA_HEADER_SIZE); - length -= OSPF_LSA_HEADER_SIZE; - } - else - { - /* make sure the input buffer is deep enough before further checks */ - if (lsalen > length) - { - if (IS_DEBUG_OSPF_PACKET (0, RECV)) - zlog_debug ("%s: anomaly in LSA #%u: declared length is %u B, buffered length is %zu B", - __func__, counted_lsas, lsalen, length); - return MSG_NG; - } - if (MSG_OK != ospf_lsa_examin (lsah, lsalen, 0)) - { - if (IS_DEBUG_OSPF_PACKET (0, RECV)) - zlog_debug ("%s: malformed LSA #%u", __func__, counted_lsas); - return MSG_NG; - } - lsah = (struct lsa_header *) ((caddr_t) lsah + lsalen); - length -= lsalen; - } - counted_lsas++; - } - - if (declared_num_lsas && counted_lsas != declared_num_lsas) - { - if (IS_DEBUG_OSPF_PACKET (0, RECV)) - zlog_debug ("%s: #LSAs declared (%u) does not match actual (%u)", - __func__, declared_num_lsas, counted_lsas); - return MSG_NG; - } - return MSG_OK; +ospf_lsaseq_examin(struct 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 < OSPF_LSA_HEADER_SIZE) { + if (IS_DEBUG_OSPF_PACKET(0, 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 = ntohs(lsah->length); + if (lsalen < OSPF_LSA_HEADER_SIZE) { + if (IS_DEBUG_OSPF_PACKET(0, 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 ospf_lsa_examin() */ + if (MSG_OK != ospf_lsa_examin(lsah, lsalen, 1)) { + if (IS_DEBUG_OSPF_PACKET(0, RECV)) + zlog_debug( + "%s: malformed header-only LSA #%u", + __func__, counted_lsas); + return MSG_NG; + } + lsah = (struct lsa_header *)((caddr_t)lsah + + OSPF_LSA_HEADER_SIZE); + length -= OSPF_LSA_HEADER_SIZE; + } else { + /* make sure the input buffer is deep enough before + * further checks */ + if (lsalen > length) { + if (IS_DEBUG_OSPF_PACKET(0, RECV)) + zlog_debug( + "%s: anomaly in LSA #%u: declared length is %u B, buffered length is %zu B", + __func__, counted_lsas, lsalen, + length); + return MSG_NG; + } + if (MSG_OK != ospf_lsa_examin(lsah, lsalen, 0)) { + if (IS_DEBUG_OSPF_PACKET(0, RECV)) + zlog_debug("%s: malformed LSA #%u", + __func__, counted_lsas); + return MSG_NG; + } + lsah = (struct lsa_header *)((caddr_t)lsah + lsalen); + length -= lsalen; + } + counted_lsas++; + } + + if (declared_num_lsas && counted_lsas != declared_num_lsas) { + if (IS_DEBUG_OSPF_PACKET(0, 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 -ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire) -{ - u_int16_t bytesdeclared, bytesauth; - unsigned ret; - struct ospf_ls_update * lsupd; - - /* Length, 1st approximation. */ - if (bytesonwire < OSPF_HEADER_SIZE) - { - if (IS_DEBUG_OSPF_PACKET (0, RECV)) - zlog_debug ("%s: undersized (%u B) packet", __func__, bytesonwire); - return MSG_NG; - } - /* Now it is safe to access header fields. Performing length check, allow - * for possible extra bytes of crypto auth/padding, which are not counted - * in the OSPF header "length" field. */ - if (oh->version != OSPF_VERSION) - { - if (IS_DEBUG_OSPF_PACKET (0, RECV)) - zlog_debug ("%s: invalid (%u) protocol version", __func__, oh->version); - return MSG_NG; - } - bytesdeclared = ntohs (oh->length); - if (ntohs (oh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC) - bytesauth = 0; - else - { - if (oh->u.crypt.auth_data_len != OSPF_AUTH_MD5_SIZE) - { - if (IS_DEBUG_OSPF_PACKET (0, RECV)) - zlog_debug ("%s: unsupported crypto auth length (%u B)", - __func__, oh->u.crypt.auth_data_len); - return MSG_NG; - } - bytesauth = OSPF_AUTH_MD5_SIZE; - } - if (bytesdeclared + bytesauth > bytesonwire) - { - if (IS_DEBUG_OSPF_PACKET (0, RECV)) - zlog_debug ("%s: packet length error (%u real, %u+%u declared)", - __func__, bytesonwire, bytesdeclared, bytesauth); - return MSG_NG; - } - /* Length, 2nd approximation. The type-specific constraint is checked - against declared length, not amount of bytes on wire. */ - if - ( - oh->type >= OSPF_MSG_HELLO && - oh->type <= OSPF_MSG_LS_ACK && - bytesdeclared < OSPF_HEADER_SIZE + ospf_packet_minlen[oh->type] - ) - { - if (IS_DEBUG_OSPF_PACKET (0, RECV)) - zlog_debug ("%s: undersized (%u B) %s packet", __func__, - bytesdeclared, lookup_msg(ospf_packet_type_str, oh->type, NULL)); - return MSG_NG; - } - switch (oh->type) - { - case OSPF_MSG_HELLO: - /* RFC2328 A.3.2, packet header + OSPF_HELLO_MIN_SIZE bytes followed - by N>=0 router-IDs. */ - ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_HELLO_MIN_SIZE) % 4 ? MSG_NG : MSG_OK; - break; - case OSPF_MSG_DB_DESC: - /* RFC2328 A.3.3, packet header + OSPF_DB_DESC_MIN_SIZE bytes followed - by N>=0 header-only LSAs. */ - ret = ospf_lsaseq_examin - ( - (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_DB_DESC_MIN_SIZE), - bytesdeclared - OSPF_HEADER_SIZE - OSPF_DB_DESC_MIN_SIZE, - 1, /* header-only LSAs */ - 0 - ); - break; - case OSPF_MSG_LS_REQ: - /* RFC2328 A.3.4, packet header followed by N>=0 12-bytes request blocks. */ - ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_REQ_MIN_SIZE) % - OSPF_LSA_KEY_SIZE ? MSG_NG : MSG_OK; - break; - case OSPF_MSG_LS_UPD: - /* RFC2328 A.3.5, packet header + OSPF_LS_UPD_MIN_SIZE bytes followed - by N>=0 full LSAs (with N declared beforehand). */ - lsupd = (struct ospf_ls_update *) ((caddr_t) oh + OSPF_HEADER_SIZE); - ret = ospf_lsaseq_examin - ( - (struct lsa_header *) ((caddr_t) lsupd + OSPF_LS_UPD_MIN_SIZE), - bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_UPD_MIN_SIZE, - 0, /* full LSAs */ - ntohl (lsupd->num_lsas) /* 32 bits */ - ); - break; - case OSPF_MSG_LS_ACK: - /* RFC2328 A.3.6, packet header followed by N>=0 header-only LSAs. */ - ret = ospf_lsaseq_examin - ( - (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_LS_ACK_MIN_SIZE), - bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_ACK_MIN_SIZE, - 1, /* header-only LSAs */ - 0 - ); - break; - default: - if (IS_DEBUG_OSPF_PACKET (0, RECV)) - zlog_debug ("%s: invalid packet type 0x%02x", __func__, oh->type); - return MSG_NG; - } - if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET (0, RECV)) - zlog_debug ("%s: malformed %s packet", __func__, lookup_msg(ospf_packet_type_str, oh->type, NULL)); - return ret; +static unsigned ospf_packet_examin(struct ospf_header *oh, + const unsigned bytesonwire) +{ + u_int16_t bytesdeclared, bytesauth; + unsigned ret; + struct ospf_ls_update *lsupd; + + /* Length, 1st approximation. */ + if (bytesonwire < OSPF_HEADER_SIZE) { + if (IS_DEBUG_OSPF_PACKET(0, RECV)) + zlog_debug("%s: undersized (%u B) packet", __func__, + bytesonwire); + return MSG_NG; + } + /* Now it is safe to access header fields. Performing length check, + * allow + * for possible extra bytes of crypto auth/padding, which are not + * counted + * in the OSPF header "length" field. */ + if (oh->version != OSPF_VERSION) { + if (IS_DEBUG_OSPF_PACKET(0, RECV)) + zlog_debug("%s: invalid (%u) protocol version", + __func__, oh->version); + return MSG_NG; + } + bytesdeclared = ntohs(oh->length); + if (ntohs(oh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC) + bytesauth = 0; + else { + if (oh->u.crypt.auth_data_len != OSPF_AUTH_MD5_SIZE) { + if (IS_DEBUG_OSPF_PACKET(0, RECV)) + zlog_debug( + "%s: unsupported crypto auth length (%u B)", + __func__, oh->u.crypt.auth_data_len); + return MSG_NG; + } + bytesauth = OSPF_AUTH_MD5_SIZE; + } + if (bytesdeclared + bytesauth > bytesonwire) { + if (IS_DEBUG_OSPF_PACKET(0, RECV)) + zlog_debug( + "%s: packet length error (%u real, %u+%u declared)", + __func__, bytesonwire, bytesdeclared, + bytesauth); + return MSG_NG; + } + /* Length, 2nd approximation. The type-specific constraint is checked + against declared length, not amount of bytes on wire. */ + if (oh->type >= OSPF_MSG_HELLO && oh->type <= OSPF_MSG_LS_ACK + && bytesdeclared + < OSPF_HEADER_SIZE + ospf_packet_minlen[oh->type]) { + if (IS_DEBUG_OSPF_PACKET(0, RECV)) + zlog_debug("%s: undersized (%u B) %s packet", __func__, + bytesdeclared, + lookup_msg(ospf_packet_type_str, oh->type, + NULL)); + return MSG_NG; + } + switch (oh->type) { + case OSPF_MSG_HELLO: + /* RFC2328 A.3.2, packet header + OSPF_HELLO_MIN_SIZE bytes + followed + by N>=0 router-IDs. */ + ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_HELLO_MIN_SIZE) + % 4 + ? MSG_NG + : MSG_OK; + break; + case OSPF_MSG_DB_DESC: + /* RFC2328 A.3.3, packet header + OSPF_DB_DESC_MIN_SIZE bytes + followed + by N>=0 header-only LSAs. */ + ret = ospf_lsaseq_examin( + (struct lsa_header *)((caddr_t)oh + OSPF_HEADER_SIZE + + OSPF_DB_DESC_MIN_SIZE), + bytesdeclared - OSPF_HEADER_SIZE + - OSPF_DB_DESC_MIN_SIZE, + 1, /* header-only LSAs */ + 0); + break; + case OSPF_MSG_LS_REQ: + /* RFC2328 A.3.4, packet header followed by N>=0 12-bytes + * request blocks. */ + ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_REQ_MIN_SIZE) + % OSPF_LSA_KEY_SIZE + ? MSG_NG + : MSG_OK; + break; + case OSPF_MSG_LS_UPD: + /* RFC2328 A.3.5, packet header + OSPF_LS_UPD_MIN_SIZE bytes + followed + by N>=0 full LSAs (with N declared beforehand). */ + lsupd = (struct ospf_ls_update *)((caddr_t)oh + + OSPF_HEADER_SIZE); + ret = ospf_lsaseq_examin( + (struct lsa_header *)((caddr_t)lsupd + + OSPF_LS_UPD_MIN_SIZE), + bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_UPD_MIN_SIZE, + 0, /* full LSAs */ + ntohl(lsupd->num_lsas) /* 32 bits */ + ); + break; + case OSPF_MSG_LS_ACK: + /* RFC2328 A.3.6, packet header followed by N>=0 header-only + * LSAs. */ + ret = ospf_lsaseq_examin( + (struct lsa_header *)((caddr_t)oh + OSPF_HEADER_SIZE + + OSPF_LS_ACK_MIN_SIZE), + bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_ACK_MIN_SIZE, + 1, /* header-only LSAs */ + 0); + break; + default: + if (IS_DEBUG_OSPF_PACKET(0, RECV)) + zlog_debug("%s: invalid packet type 0x%02x", __func__, + oh->type); + return MSG_NG; + } + if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET(0, RECV)) + zlog_debug("%s: malformed %s packet", __func__, + lookup_msg(ospf_packet_type_str, oh->type, NULL)); + return ret; } /* OSPF Header verification. */ -static int -ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi, - struct ip *iph, struct ospf_header *ospfh) -{ - /* Check Area ID. */ - if (!ospf_check_area_id (oi, ospfh)) - { - zlog_warn ("interface %s: ospf_read invalid Area ID %s.", - IF_NAME (oi), inet_ntoa (ospfh->area_id)); - return -1; - } +static int ospf_verify_header(struct stream *ibuf, struct ospf_interface *oi, + struct ip *iph, struct ospf_header *ospfh) +{ + /* Check Area ID. */ + if (!ospf_check_area_id(oi, ospfh)) { + zlog_warn("interface %s: ospf_read invalid Area ID %s.", + IF_NAME(oi), inet_ntoa(ospfh->area_id)); + return -1; + } - /* Check network mask, Silently discarded. */ - if (! ospf_check_network_mask (oi, iph->ip_src)) - { - zlog_warn ("interface %s: ospf_read network address is not same [%s]", - IF_NAME (oi), inet_ntoa (iph->ip_src)); - return -1; - } + /* Check network mask, Silently discarded. */ + if (!ospf_check_network_mask(oi, iph->ip_src)) { + zlog_warn( + "interface %s: ospf_read network address is not same [%s]", + IF_NAME(oi), inet_ntoa(iph->ip_src)); + return -1; + } - /* Check authentication. The function handles logging actions, where required. */ - if (! ospf_check_auth (oi, ospfh)) - return -1; + /* Check authentication. The function handles logging actions, where + * required. */ + if (!ospf_check_auth(oi, ospfh)) + return -1; - return 0; + return 0; } /* Starting point of packet process function. */ -int -ospf_read (struct thread *thread) -{ - int ret; - struct stream *ibuf; - struct ospf *ospf; - struct ospf_interface *oi; - struct ip *iph; - struct ospf_header *ospfh; - u_int16_t length; - struct interface *ifp; - struct connected *c; - - /* first of all get interface pointer. */ - ospf = THREAD_ARG (thread); - - /* prepare for next packet. */ - ospf->t_read = NULL; - thread_add_read(master, ospf_read, ospf, ospf->fd, &ospf->t_read); - - stream_reset(ospf->ibuf); - if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf))) - return -1; - /* This raw packet is known to be at least as big as its IP header. */ - - /* Note that there should not be alignment problems with this assignment - because this is at the beginning of the stream data buffer. */ - iph = (struct ip *) STREAM_DATA (ibuf); - /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */ - - if (ifp == NULL) - { - /* Handle cases where the platform does not support retrieving the ifindex, - and also platforms (such as Solaris 8) that claim to support ifindex - retrieval but do not. */ - c = if_lookup_address ((void *)&iph->ip_src, AF_INET, VRF_DEFAULT); - if (c) - ifp = c->ifp; - if (ifp == NULL) +int ospf_read(struct thread *thread) +{ + int ret; + struct stream *ibuf; + struct ospf *ospf; + struct ospf_interface *oi; + struct ip *iph; + struct ospf_header *ospfh; + u_int16_t length; + struct interface *ifp; + struct connected *c; + + /* first of all get interface pointer. */ + ospf = THREAD_ARG(thread); + + /* prepare for next packet. */ + ospf->t_read = NULL; + thread_add_read(master, ospf_read, ospf, ospf->fd, &ospf->t_read); + + stream_reset(ospf->ibuf); + if (!(ibuf = ospf_recv_packet(ospf->fd, &ifp, ospf->ibuf))) + return -1; + /* This raw packet is known to be at least as big as its IP header. */ + + /* Note that there should not be alignment problems with this assignment + because this is at the beginning of the stream data buffer. */ + iph = (struct ip *)STREAM_DATA(ibuf); + /* Note that sockopt_iphdrincl_swab_systoh was called in + * ospf_recv_packet. */ + + if (ifp == NULL) { + /* Handle cases where the platform does not support retrieving + the ifindex, + and also platforms (such as Solaris 8) that claim to support + ifindex + retrieval but do not. */ + c = if_lookup_address((void *)&iph->ip_src, AF_INET, + VRF_DEFAULT); + if (c) + ifp = c->ifp; + if (ifp == NULL) + return 0; + } + + /* IP Header dump. */ + if (IS_DEBUG_OSPF_PACKET(0, RECV)) + ospf_ip_header_dump(iph); + + /* Self-originated packet should be discarded silently. */ + if (ospf_if_lookup_by_local_addr(ospf, NULL, iph->ip_src)) { + if (IS_DEBUG_OSPF_PACKET(0, RECV)) { + zlog_debug( + "ospf_read[%s]: Dropping self-originated packet", + inet_ntoa(iph->ip_src)); + } + return 0; + } + + /* Advance from IP header to OSPF header (iph->ip_hl has been verified + by ospf_recv_packet() to be correct). */ + stream_forward_getp(ibuf, iph->ip_hl * 4); + + ospfh = (struct ospf_header *)STREAM_PNT(ibuf); + if (MSG_OK + != ospf_packet_examin( + ospfh, stream_get_endp(ibuf) - stream_get_getp(ibuf))) + return -1; + /* Now it is safe to access all fields of OSPF packet header. */ + + /* associate packet with ospf interface */ + oi = ospf_if_lookup_recv_if(ospf, iph->ip_src, ifp); + + /* ospf_verify_header() relies on a valid "oi" and thus can be called + only + after the passive/backbone/other checks below are passed. These + checks + in turn access the fields of unverified "ospfh" structure for their + own + purposes and must remain very accurate in doing this. */ + + /* If incoming interface is passive one, ignore it. */ + if (oi && OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_PASSIVE) { + char buf[3][INET_ADDRSTRLEN]; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ignoring packet from router %s sent to %s, " + "received on a passive interface, %s", + inet_ntop(AF_INET, &ospfh->router_id, buf[0], + sizeof(buf[0])), + inet_ntop(AF_INET, &iph->ip_dst, buf[1], + sizeof(buf[1])), + inet_ntop(AF_INET, &oi->address->u.prefix4, + buf[2], sizeof(buf[2]))); + + if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS)) { + /* Try to fix multicast membership. + * Some OS:es may have problems in this area, + * make sure it is removed. + */ + OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS); + ospf_if_set_multicast(oi); + } + return 0; + } + + + /* if no local ospf_interface, + * or header area is backbone but ospf_interface is not + * check for VLINK interface + */ + if ((oi == NULL) || (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id) + && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))) { + if ((oi = ospf_associate_packet_vl(ospf, ifp, iph, ospfh)) + == NULL) { + if (!ospf->instance && IS_DEBUG_OSPF_EVENT) + zlog_debug( + "Packet from [%s] received on link %s" + " but no ospf_interface", + inet_ntoa(iph->ip_src), ifp->name); + return 0; + } + } + + /* else it must be a local ospf interface, check it was received on + * correct link + */ + else if (oi->ifp != ifp) { + if (IS_DEBUG_OSPF_EVENT) + zlog_warn("Packet from [%s] received on wrong link %s", + inet_ntoa(iph->ip_src), ifp->name); + return 0; + } else if (oi->state == ISM_Down) { + char buf[2][INET_ADDRSTRLEN]; + zlog_warn( + "Ignoring packet from %s to %s received on interface that is " + "down [%s]; interface flags are %s", + inet_ntop(AF_INET, &iph->ip_src, buf[0], + sizeof(buf[0])), + inet_ntop(AF_INET, &iph->ip_dst, buf[1], + sizeof(buf[1])), + ifp->name, if_flag_dump(ifp->flags)); + /* Fix multicast memberships? */ + if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS)) + OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS); + else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS)) + OI_MEMBER_JOINED(oi, MEMBER_DROUTERS); + if (oi->multicast_memberships) + ospf_if_set_multicast(oi); + return 0; + } + + /* + * If the received packet is destined for AllDRouters, the packet + * should be accepted only if the received ospf interface state is + * either DR or Backup -- endo. + */ + if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS) + && (oi->state != ISM_DR && oi->state != ISM_Backup)) { + zlog_warn( + "Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)", + inet_ntoa(iph->ip_src), IF_NAME(oi), + lookup_msg(ospf_ism_state_msg, oi->state, NULL)); + /* Try to fix multicast membership. */ + SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS); + ospf_if_set_multicast(oi); + return 0; + } + + /* Verify more OSPF header fields. */ + ret = ospf_verify_header(ibuf, oi, iph, ospfh); + if (ret < 0) { + if (IS_DEBUG_OSPF_PACKET(0, RECV)) + zlog_debug( + "ospf_read[%s]: Header check failed, " + "dropping.", + inet_ntoa(iph->ip_src)); + return ret; + } + + /* Show debug receiving packet. */ + if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV)) { + if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, DETAIL)) { + zlog_debug( + "-----------------------------------------------------"); + ospf_packet_dump(ibuf); + } + + zlog_debug("%s received from [%s] via [%s]", + lookup_msg(ospf_packet_type_str, ospfh->type, NULL), + inet_ntoa(ospfh->router_id), IF_NAME(oi)); + zlog_debug(" src [%s],", inet_ntoa(iph->ip_src)); + zlog_debug(" dst [%s]", inet_ntoa(iph->ip_dst)); + + if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, DETAIL)) + zlog_debug( + "-----------------------------------------------------"); + } + + stream_forward_getp(ibuf, OSPF_HEADER_SIZE); + + /* Adjust size to message length. */ + length = ntohs(ospfh->length) - OSPF_HEADER_SIZE; + + /* Read rest of the packet and call each sort of packet routine. */ + switch (ospfh->type) { + case OSPF_MSG_HELLO: + ospf_hello(iph, ospfh, ibuf, oi, length); + break; + case OSPF_MSG_DB_DESC: + ospf_db_desc(iph, ospfh, ibuf, oi, length); + break; + case OSPF_MSG_LS_REQ: + ospf_ls_req(iph, ospfh, ibuf, oi, length); + break; + case OSPF_MSG_LS_UPD: + ospf_ls_upd(ospf, iph, ospfh, ibuf, oi, length); + break; + case OSPF_MSG_LS_ACK: + ospf_ls_ack(iph, ospfh, ibuf, oi, length); + break; + default: + zlog_warn("interface %s: OSPF packet header type %d is illegal", + IF_NAME(oi), ospfh->type); + break; + } + return 0; - } - - /* IP Header dump. */ - if (IS_DEBUG_OSPF_PACKET(0, RECV)) - ospf_ip_header_dump (iph); - - /* Self-originated packet should be discarded silently. */ - if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src)) - { - if (IS_DEBUG_OSPF_PACKET (0, RECV)) - { - zlog_debug ("ospf_read[%s]: Dropping self-originated packet", - inet_ntoa (iph->ip_src)); - } - return 0; - } - - /* Advance from IP header to OSPF header (iph->ip_hl has been verified - by ospf_recv_packet() to be correct). */ - stream_forward_getp (ibuf, iph->ip_hl * 4); - - ospfh = (struct ospf_header *) STREAM_PNT (ibuf); - if (MSG_OK != ospf_packet_examin (ospfh, stream_get_endp (ibuf) - stream_get_getp (ibuf))) - return -1; - /* Now it is safe to access all fields of OSPF packet header. */ - - /* associate packet with ospf interface */ - oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp); - - /* ospf_verify_header() relies on a valid "oi" and thus can be called only - after the passive/backbone/other checks below are passed. These checks - in turn access the fields of unverified "ospfh" structure for their own - purposes and must remain very accurate in doing this. */ - - /* If incoming interface is passive one, ignore it. */ - if (oi && OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE) - { - char buf[3][INET_ADDRSTRLEN]; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ignoring packet from router %s sent to %s, " - "received on a passive interface, %s", - inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])), - inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])), - inet_ntop(AF_INET, &oi->address->u.prefix4, - buf[2], sizeof(buf[2]))); - - if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS)) - { - /* Try to fix multicast membership. - * Some OS:es may have problems in this area, - * make sure it is removed. - */ - OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS); - ospf_if_set_multicast(oi); - } - return 0; - } - - - /* if no local ospf_interface, - * or header area is backbone but ospf_interface is not - * check for VLINK interface - */ - if ( (oi == NULL) || - (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id) - && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id)) - ) - { - if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL) - { - if (!ospf->instance && IS_DEBUG_OSPF_EVENT) - zlog_debug ("Packet from [%s] received on link %s" - " but no ospf_interface", - inet_ntoa (iph->ip_src), ifp->name); - return 0; - } - } - - /* else it must be a local ospf interface, check it was received on - * correct link - */ - else if (oi->ifp != ifp) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_warn ("Packet from [%s] received on wrong link %s", - inet_ntoa (iph->ip_src), ifp->name); - return 0; - } - else if (oi->state == ISM_Down) - { - char buf[2][INET_ADDRSTRLEN]; - zlog_warn ("Ignoring packet from %s to %s received on interface that is " - "down [%s]; interface flags are %s", - inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])), - inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])), - ifp->name, if_flag_dump(ifp->flags)); - /* Fix multicast memberships? */ - if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS)) - OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS); - else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS)) - OI_MEMBER_JOINED(oi, MEMBER_DROUTERS); - if (oi->multicast_memberships) - ospf_if_set_multicast(oi); - return 0; - } - - /* - * If the received packet is destined for AllDRouters, the packet - * should be accepted only if the received ospf interface state is - * either DR or Backup -- endo. - */ - if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS) - && (oi->state != ISM_DR && oi->state != ISM_Backup)) - { - zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)", - inet_ntoa (iph->ip_src), IF_NAME (oi), - lookup_msg(ospf_ism_state_msg, oi->state, NULL)); - /* Try to fix multicast membership. */ - SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS); - ospf_if_set_multicast(oi); - return 0; - } - - /* Verify more OSPF header fields. */ - ret = ospf_verify_header (ibuf, oi, iph, ospfh); - if (ret < 0) - { - if (IS_DEBUG_OSPF_PACKET (0, RECV)) - zlog_debug ("ospf_read[%s]: Header check failed, " - "dropping.", - inet_ntoa (iph->ip_src)); - return ret; - } - - /* Show debug receiving packet. */ - if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) - { - if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL)) - { - zlog_debug ("-----------------------------------------------------"); - ospf_packet_dump (ibuf); - } - - zlog_debug ("%s received from [%s] via [%s]", - lookup_msg(ospf_packet_type_str, ospfh->type, NULL), - inet_ntoa (ospfh->router_id), IF_NAME (oi)); - zlog_debug (" src [%s],", inet_ntoa (iph->ip_src)); - zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst)); - - if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL)) - zlog_debug ("-----------------------------------------------------"); - } - - stream_forward_getp (ibuf, OSPF_HEADER_SIZE); - - /* Adjust size to message length. */ - length = ntohs (ospfh->length) - OSPF_HEADER_SIZE; - - /* Read rest of the packet and call each sort of packet routine. */ - switch (ospfh->type) - { - case OSPF_MSG_HELLO: - ospf_hello (iph, ospfh, ibuf, oi, length); - break; - case OSPF_MSG_DB_DESC: - ospf_db_desc (iph, ospfh, ibuf, oi, length); - break; - case OSPF_MSG_LS_REQ: - ospf_ls_req (iph, ospfh, ibuf, oi, length); - break; - case OSPF_MSG_LS_UPD: - ospf_ls_upd (ospf, iph, ospfh, ibuf, oi, length); - break; - case OSPF_MSG_LS_ACK: - ospf_ls_ack (iph, ospfh, ibuf, oi, length); - break; - default: - zlog_warn("interface %s: OSPF packet header type %d is illegal", - IF_NAME(oi), ospfh->type); - break; - } - - return 0; } /* Make OSPF header. */ -static void -ospf_make_header (int type, struct ospf_interface *oi, struct stream *s) +static void ospf_make_header(int type, struct ospf_interface *oi, + struct stream *s) { - struct ospf_header *ospfh; + struct ospf_header *ospfh; - ospfh = (struct ospf_header *) STREAM_DATA (s); + ospfh = (struct ospf_header *)STREAM_DATA(s); - ospfh->version = (u_char) OSPF_VERSION; - ospfh->type = (u_char) type; + ospfh->version = (u_char)OSPF_VERSION; + ospfh->type = (u_char)type; - ospfh->router_id = oi->ospf->router_id; + ospfh->router_id = oi->ospf->router_id; - ospfh->checksum = 0; - ospfh->area_id = oi->area->area_id; - ospfh->auth_type = htons (ospf_auth_type (oi)); + ospfh->checksum = 0; + ospfh->area_id = oi->area->area_id; + ospfh->auth_type = htons(ospf_auth_type(oi)); - memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE); + memset(ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE); - stream_forward_endp (s, OSPF_HEADER_SIZE); + stream_forward_endp(s, OSPF_HEADER_SIZE); } /* Make Authentication Data. */ -static int -ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh) -{ - struct crypt_key *ck; - - switch (ospf_auth_type (oi)) - { - case OSPF_AUTH_NULL: - /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */ - break; - case OSPF_AUTH_SIMPLE: - memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple), - OSPF_AUTH_SIMPLE_SIZE); - break; - case OSPF_AUTH_CRYPTOGRAPHIC: - /* If key is not set, then set 0. */ - if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt))) - { - ospfh->u.crypt.zero = 0; - ospfh->u.crypt.key_id = 0; - ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE; - } - else - { - ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt))); - ospfh->u.crypt.zero = 0; - ospfh->u.crypt.key_id = ck->key_id; - ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE; +static int ospf_make_auth(struct ospf_interface *oi, struct ospf_header *ospfh) +{ + struct crypt_key *ck; + + switch (ospf_auth_type(oi)) { + case OSPF_AUTH_NULL: + /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); + */ + break; + case OSPF_AUTH_SIMPLE: + memcpy(ospfh->u.auth_data, OSPF_IF_PARAM(oi, auth_simple), + OSPF_AUTH_SIMPLE_SIZE); + break; + case OSPF_AUTH_CRYPTOGRAPHIC: + /* If key is not set, then set 0. */ + if (list_isempty(OSPF_IF_PARAM(oi, auth_crypt))) { + ospfh->u.crypt.zero = 0; + ospfh->u.crypt.key_id = 0; + ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE; + } else { + ck = listgetdata( + listtail(OSPF_IF_PARAM(oi, auth_crypt))); + ospfh->u.crypt.zero = 0; + ospfh->u.crypt.key_id = ck->key_id; + ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE; + } + /* note: the seq is done in ospf_make_md5_digest() */ + break; + default: + /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); + */ + break; } - /* note: the seq is done in ospf_make_md5_digest() */ - break; - default: - /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */ - break; - } - return 0; + return 0; } /* Fill rest of OSPF header. */ -static void -ospf_fill_header (struct ospf_interface *oi, - struct stream *s, u_int16_t length) -{ - struct ospf_header *ospfh; - - ospfh = (struct ospf_header *) STREAM_DATA (s); - - /* Fill length. */ - ospfh->length = htons (length); - - /* Calculate checksum. */ - if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC) - ospfh->checksum = in_cksum (ospfh, length); - else - ospfh->checksum = 0; - - /* Add Authentication Data. */ - ospf_make_auth (oi, ospfh); -} - -static int -ospf_make_hello (struct ospf_interface *oi, struct stream *s) -{ - struct ospf_neighbor *nbr; - struct route_node *rn; - u_int16_t length = OSPF_HELLO_MIN_SIZE; - struct in_addr mask; - unsigned long p; - int flag = 0; - - /* Set netmask of interface. */ - if (!(CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED) && - oi->type == OSPF_IFTYPE_POINTOPOINT) && - oi->type != OSPF_IFTYPE_VIRTUALLINK) - masklen2ip (oi->address->prefixlen, &mask); - else - memset ((char *) &mask, 0, sizeof (struct in_addr)); - stream_put_ipv4 (s, mask.s_addr); - - /* Set Hello Interval. */ - if (OSPF_IF_PARAM (oi, fast_hello) == 0) - stream_putw (s, OSPF_IF_PARAM (oi, v_hello)); - else - stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */ - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("make_hello: options: %x, int: %s", - OPTIONS(oi), IF_NAME (oi)); - - /* Set Options. */ - stream_putc (s, OPTIONS (oi)); - - /* Set Router Priority. */ - stream_putc (s, PRIORITY (oi)); - - /* Set Router Dead Interval. */ - stream_putl (s, OSPF_IF_PARAM (oi, v_wait)); - - /* Set Designated Router. */ - stream_put_ipv4 (s, DR (oi).s_addr); - - p = stream_get_endp (s); - - /* Set Backup Designated Router. */ - stream_put_ipv4 (s, BDR (oi).s_addr); - - /* Add neighbor seen. */ - for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) - if ((nbr = rn->info)) - if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */ - if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */ - if (nbr->state != NSM_Down) /* This is myself for DR election. */ - if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id)) - { - /* Check neighbor is sane? */ - if (nbr->d_router.s_addr != 0 - && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4) - && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4)) - flag = 1; - - stream_put_ipv4 (s, nbr->router_id.s_addr); - length += 4; - } - - /* Let neighbor generate BackupSeen. */ - if (flag == 1) - stream_putl_at (s, p, 0); /* ipv4 address, normally */ - - return length; -} - -static int -ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr, - struct stream *s) -{ - struct ospf_lsa *lsa; - u_int16_t length = OSPF_DB_DESC_MIN_SIZE; - u_char options; - unsigned long pp; - int i; - struct ospf_lsdb *lsdb; - - /* Set Interface MTU. */ - if (oi->type == OSPF_IFTYPE_VIRTUALLINK) - stream_putw (s, 0); - else - stream_putw (s, oi->ifp->mtu); - - /* Set Options. */ - options = OPTIONS (oi); - if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)) - SET_FLAG (options, OSPF_OPTION_O); - stream_putc (s, options); - - /* DD flags */ - pp = stream_get_endp (s); - stream_putc (s, nbr->dd_flags); - - /* Set DD Sequence Number. */ - stream_putl (s, nbr->dd_seqnum); - - /* shortcut unneeded walk of (empty) summary LSDBs */ - if (ospf_db_summary_isempty (nbr)) - goto empty; - - /* Describe LSA Header from Database Summary List. */ - lsdb = &nbr->db_sum; - - for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++) - { - struct route_table *table = lsdb->type[i].db; - struct route_node *rn; - - for (rn = route_top (table); rn; rn = route_next (rn)) - if ((lsa = rn->info) != NULL) - { - if (IS_OPAQUE_LSA (lsa->data->type) - && (! CHECK_FLAG (options, OSPF_OPTION_O))) - { - /* Suppress advertising opaque-informations. */ - /* Remove LSA from DB summary list. */ - ospf_lsdb_delete (lsdb, lsa); - continue; - } - - if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD)) - { - struct lsa_header *lsah; - u_int16_t ls_age; - - /* DD packet overflows interface MTU. */ - if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi)) - break; - - /* Keep pointer to LS age. */ - lsah = (struct lsa_header *) (STREAM_DATA (s) + - stream_get_endp (s)); - - /* Proceed stream pointer. */ - stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE); - length += OSPF_LSA_HEADER_SIZE; - - /* Set LS age. */ - ls_age = LS_AGE (lsa); - lsah->ls_age = htons (ls_age); - - } - - /* Remove LSA from DB summary list. */ - ospf_lsdb_delete (lsdb, lsa); - } - } - - /* Update 'More' bit */ - if (ospf_db_summary_isempty (nbr)) - { -empty: - if (nbr->state >= NSM_Exchange) - { - UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M); - /* Rewrite DD flags */ - stream_putc_at (s, pp, nbr->dd_flags); - } - else - { - assert (IS_SET_DD_M(nbr->dd_flags)); - } - } - return length; -} - -static int -ospf_make_ls_req_func (struct stream *s, u_int16_t *length, - unsigned long delta, struct ospf_neighbor *nbr, - struct ospf_lsa *lsa) -{ - struct ospf_interface *oi; - - oi = nbr->oi; - - /* LS Request packet overflows interface MTU. */ - if (*length + delta > ospf_packet_max(oi)) - return 0; - - stream_putl (s, lsa->data->type); - stream_put_ipv4 (s, lsa->data->id.s_addr); - stream_put_ipv4 (s, lsa->data->adv_router.s_addr); - - ospf_lsa_unlock (&nbr->ls_req_last); - nbr->ls_req_last = ospf_lsa_lock (lsa); - - *length += 12; - return 1; -} - -static int -ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s) -{ - struct ospf_lsa *lsa; - u_int16_t length = OSPF_LS_REQ_MIN_SIZE; - unsigned long delta = stream_get_endp(s)+12; - struct route_table *table; - struct route_node *rn; - int i; - struct ospf_lsdb *lsdb; - - lsdb = &nbr->ls_req; - - for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++) - { - table = lsdb->type[i].db; - for (rn = route_top (table); rn; rn = route_next (rn)) - if ((lsa = (rn->info)) != NULL) - if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0) - { - route_unlock_node (rn); - break; - } - } - return length; -} - -static int -ls_age_increment (struct ospf_lsa *lsa, int delay) -{ - int age; - - age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay; - - return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age); -} - -static int -ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s) -{ - struct ospf_lsa *lsa; - struct listnode *node; - u_int16_t length = 0; - unsigned int size_noauth; - unsigned long delta = stream_get_endp (s); - unsigned long pp; - int count = 0; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_make_ls_upd: Start"); - - pp = stream_get_endp (s); - stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE); - length += OSPF_LS_UPD_MIN_SIZE; +static void ospf_fill_header(struct ospf_interface *oi, struct stream *s, + u_int16_t length) +{ + struct ospf_header *ospfh; + + ospfh = (struct ospf_header *)STREAM_DATA(s); + + /* Fill length. */ + ospfh->length = htons(length); + + /* Calculate checksum. */ + if (ntohs(ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC) + ospfh->checksum = in_cksum(ospfh, length); + else + ospfh->checksum = 0; + + /* Add Authentication Data. */ + ospf_make_auth(oi, ospfh); +} + +static int ospf_make_hello(struct ospf_interface *oi, struct stream *s) +{ + struct ospf_neighbor *nbr; + struct route_node *rn; + u_int16_t length = OSPF_HELLO_MIN_SIZE; + struct in_addr mask; + unsigned long p; + int flag = 0; + + /* Set netmask of interface. */ + if (!(CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED) + && oi->type == OSPF_IFTYPE_POINTOPOINT) + && oi->type != OSPF_IFTYPE_VIRTUALLINK) + masklen2ip(oi->address->prefixlen, &mask); + else + memset((char *)&mask, 0, sizeof(struct in_addr)); + stream_put_ipv4(s, mask.s_addr); + + /* Set Hello Interval. */ + if (OSPF_IF_PARAM(oi, fast_hello) == 0) + stream_putw(s, OSPF_IF_PARAM(oi, v_hello)); + else + stream_putw(s, 0); /* hello-interval of 0 for fast-hellos */ + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("make_hello: options: %x, int: %s", OPTIONS(oi), + IF_NAME(oi)); + + /* Set Options. */ + stream_putc(s, OPTIONS(oi)); + + /* Set Router Priority. */ + stream_putc(s, PRIORITY(oi)); + + /* Set Router Dead Interval. */ + stream_putl(s, OSPF_IF_PARAM(oi, v_wait)); + + /* Set Designated Router. */ + stream_put_ipv4(s, DR(oi).s_addr); + + p = stream_get_endp(s); + + /* Set Backup Designated Router. */ + stream_put_ipv4(s, BDR(oi).s_addr); + + /* Add neighbor seen. */ + for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) + if ((nbr = rn->info)) + if (nbr->router_id.s_addr + != 0) /* Ignore 0.0.0.0 node. */ + if (nbr->state + != NSM_Attempt) /* Ignore Down neighbor. */ + if (nbr->state + != NSM_Down) /* This is myself for + DR election. */ + if (!IPV4_ADDR_SAME( + &nbr->router_id, + &oi->ospf->router_id)) { + /* Check neighbor is + * sane? */ + if (nbr->d_router.s_addr + != 0 + && IPV4_ADDR_SAME( + &nbr->d_router, + &oi->address + ->u + .prefix4) + && IPV4_ADDR_SAME( + &nbr->bd_router, + &oi->address + ->u + .prefix4)) + flag = 1; + + stream_put_ipv4( + s, + nbr->router_id + .s_addr); + length += 4; + } + + /* Let neighbor generate BackupSeen. */ + if (flag == 1) + stream_putl_at(s, p, 0); /* ipv4 address, normally */ + + return length; +} + +static int ospf_make_db_desc(struct ospf_interface *oi, + struct ospf_neighbor *nbr, struct stream *s) +{ + struct ospf_lsa *lsa; + u_int16_t length = OSPF_DB_DESC_MIN_SIZE; + u_char options; + unsigned long pp; + int i; + struct ospf_lsdb *lsdb; + + /* Set Interface MTU. */ + if (oi->type == OSPF_IFTYPE_VIRTUALLINK) + stream_putw(s, 0); + else + stream_putw(s, oi->ifp->mtu); + + /* Set Options. */ + options = OPTIONS(oi); + if (CHECK_FLAG(oi->ospf->config, OSPF_OPAQUE_CAPABLE)) + SET_FLAG(options, OSPF_OPTION_O); + stream_putc(s, options); + + /* DD flags */ + pp = stream_get_endp(s); + stream_putc(s, nbr->dd_flags); + + /* Set DD Sequence Number. */ + stream_putl(s, nbr->dd_seqnum); + + /* shortcut unneeded walk of (empty) summary LSDBs */ + if (ospf_db_summary_isempty(nbr)) + goto empty; + + /* Describe LSA Header from Database Summary List. */ + lsdb = &nbr->db_sum; + + for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++) { + struct route_table *table = lsdb->type[i].db; + struct route_node *rn; + + for (rn = route_top(table); rn; rn = route_next(rn)) + if ((lsa = rn->info) != NULL) { + if (IS_OPAQUE_LSA(lsa->data->type) + && (!CHECK_FLAG(options, OSPF_OPTION_O))) { + /* Suppress advertising + * opaque-informations. */ + /* Remove LSA from DB summary list. */ + ospf_lsdb_delete(lsdb, lsa); + continue; + } + + if (!CHECK_FLAG(lsa->flags, OSPF_LSA_DISCARD)) { + struct lsa_header *lsah; + u_int16_t ls_age; + + /* DD packet overflows interface MTU. */ + if (length + OSPF_LSA_HEADER_SIZE + > ospf_packet_max(oi)) + break; + + /* Keep pointer to LS age. */ + lsah = (struct lsa_header + *)(STREAM_DATA(s) + + stream_get_endp( + s)); + + /* Proceed stream pointer. */ + stream_put(s, lsa->data, + OSPF_LSA_HEADER_SIZE); + length += OSPF_LSA_HEADER_SIZE; + + /* Set LS age. */ + ls_age = LS_AGE(lsa); + lsah->ls_age = htons(ls_age); + } + + /* Remove LSA from DB summary list. */ + ospf_lsdb_delete(lsdb, lsa); + } + } - /* Calculate amount of packet usable for data. */ - size_noauth = stream_get_size(s) - ospf_packet_authspace(oi); + /* Update 'More' bit */ + if (ospf_db_summary_isempty(nbr)) { + empty: + if (nbr->state >= NSM_Exchange) { + UNSET_FLAG(nbr->dd_flags, OSPF_DD_FLAG_M); + /* Rewrite DD flags */ + stream_putc_at(s, pp, nbr->dd_flags); + } else { + assert(IS_SET_DD_M(nbr->dd_flags)); + } + } + return length; +} - while ((node = listhead (update)) != NULL) - { - struct lsa_header *lsah; - u_int16_t ls_age; +static int ospf_make_ls_req_func(struct stream *s, u_int16_t *length, + unsigned long delta, struct ospf_neighbor *nbr, + struct ospf_lsa *lsa) +{ + struct ospf_interface *oi; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_make_ls_upd: List Iteration %d", count); + oi = nbr->oi; - lsa = listgetdata (node); + /* LS Request packet overflows interface MTU. */ + if (*length + delta > ospf_packet_max(oi)) + return 0; - assert (lsa->data); + stream_putl(s, lsa->data->type); + stream_put_ipv4(s, lsa->data->id.s_addr); + stream_put_ipv4(s, lsa->data->adv_router.s_addr); - /* Will it fit? */ - if (length + delta + ntohs (lsa->data->length) > size_noauth) - break; + ospf_lsa_unlock(&nbr->ls_req_last); + nbr->ls_req_last = ospf_lsa_lock(lsa); - /* Keep pointer to LS age. */ - lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s)); + *length += 12; + return 1; +} - /* Put LSA to Link State Request. */ - stream_put (s, lsa->data, ntohs (lsa->data->length)); +static int ospf_make_ls_req(struct ospf_neighbor *nbr, struct stream *s) +{ + struct ospf_lsa *lsa; + u_int16_t length = OSPF_LS_REQ_MIN_SIZE; + unsigned long delta = stream_get_endp(s) + 12; + struct route_table *table; + struct route_node *rn; + int i; + struct ospf_lsdb *lsdb; - /* Set LS age. */ - /* each hop must increment an lsa_age by transmit_delay - of OSPF interface */ - ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay)); - lsah->ls_age = htons (ls_age); + lsdb = &nbr->ls_req; - length += ntohs (lsa->data->length); - count++; + for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++) { + table = lsdb->type[i].db; + for (rn = route_top(table); rn; rn = route_next(rn)) + if ((lsa = (rn->info)) != NULL) + if (ospf_make_ls_req_func(s, &length, delta, + nbr, lsa) + == 0) { + route_unlock_node(rn); + break; + } + } + return length; +} - list_delete_node (update, node); - ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */ - } +static int ls_age_increment(struct ospf_lsa *lsa, int delay) +{ + int age; - /* Now set #LSAs. */ - stream_putl_at (s, pp, count); + age = IS_LSA_MAXAGE(lsa) ? OSPF_LSA_MAXAGE : LS_AGE(lsa) + delay; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_make_ls_upd: Stop"); - return length; + return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age); } -static int -ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s) +static int ospf_make_ls_upd(struct ospf_interface *oi, struct list *update, + struct stream *s) { - struct listnode *node, *nnode; - u_int16_t length = OSPF_LS_ACK_MIN_SIZE; - unsigned long delta = stream_get_endp(s) + 24; - struct ospf_lsa *lsa; + struct ospf_lsa *lsa; + struct listnode *node; + u_int16_t length = 0; + unsigned int size_noauth; + unsigned long delta = stream_get_endp(s); + unsigned long pp; + int count = 0; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_make_ls_upd: Start"); + + pp = stream_get_endp(s); + stream_forward_endp(s, OSPF_LS_UPD_MIN_SIZE); + length += OSPF_LS_UPD_MIN_SIZE; + + /* Calculate amount of packet usable for data. */ + size_noauth = stream_get_size(s) - ospf_packet_authspace(oi); + + while ((node = listhead(update)) != NULL) { + struct lsa_header *lsah; + u_int16_t ls_age; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_make_ls_upd: List Iteration %d", + count); + + lsa = listgetdata(node); + + assert(lsa->data); + + /* Will it fit? */ + if (length + delta + ntohs(lsa->data->length) > size_noauth) + break; + + /* Keep pointer to LS age. */ + lsah = (struct lsa_header *)(STREAM_DATA(s) + + stream_get_endp(s)); + + /* Put LSA to Link State Request. */ + stream_put(s, lsa->data, ntohs(lsa->data->length)); - for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa)) - { - assert (lsa); - - if (length + delta > ospf_packet_max (oi)) - break; - - stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE); - length += OSPF_LSA_HEADER_SIZE; - - listnode_delete (ack, lsa); - ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */ - } - - return length; + /* Set LS age. */ + /* each hop must increment an lsa_age by transmit_delay + of OSPF interface */ + ls_age = ls_age_increment(lsa, + OSPF_IF_PARAM(oi, transmit_delay)); + lsah->ls_age = htons(ls_age); + + length += ntohs(lsa->data->length); + count++; + + list_delete_node(update, node); + ospf_lsa_unlock(&lsa); /* oi->ls_upd_queue */ + } + + /* Now set #LSAs. */ + stream_putl_at(s, pp, count); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_make_ls_upd: Stop"); + return length; } -static void -ospf_hello_send_sub (struct ospf_interface *oi, in_addr_t addr) +static int ospf_make_ls_ack(struct ospf_interface *oi, struct list *ack, + struct stream *s) { - struct ospf_packet *op; - u_int16_t length = OSPF_HEADER_SIZE; + struct listnode *node, *nnode; + u_int16_t length = OSPF_LS_ACK_MIN_SIZE; + unsigned long delta = stream_get_endp(s) + 24; + struct ospf_lsa *lsa; - op = ospf_packet_new (oi->ifp->mtu); + for (ALL_LIST_ELEMENTS(ack, node, nnode, lsa)) { + assert(lsa); - /* Prepare OSPF common header. */ - ospf_make_header (OSPF_MSG_HELLO, oi, op->s); + if (length + delta > ospf_packet_max(oi)) + break; - /* Prepare OSPF Hello body. */ - length += ospf_make_hello (oi, op->s); + stream_put(s, lsa->data, OSPF_LSA_HEADER_SIZE); + length += OSPF_LSA_HEADER_SIZE; + + listnode_delete(ack, lsa); + ospf_lsa_unlock(&lsa); /* oi->ls_ack_direct.ls_ack */ + } + + return length; +} + +static void ospf_hello_send_sub(struct ospf_interface *oi, in_addr_t addr) +{ + struct ospf_packet *op; + u_int16_t length = OSPF_HEADER_SIZE; - /* Fill OSPF header. */ - ospf_fill_header (oi, op->s, length); + op = ospf_packet_new(oi->ifp->mtu); - /* Set packet length. */ - op->length = length; + /* Prepare OSPF common header. */ + ospf_make_header(OSPF_MSG_HELLO, oi, op->s); - op->dst.s_addr = addr; + /* Prepare OSPF Hello body. */ + length += ospf_make_hello(oi, op->s); - /* Add packet to the top of the interface output queue, so that they - * can't get delayed by things like long queues of LS Update packets - */ - ospf_packet_add_top (oi, op); + /* Fill OSPF header. */ + ospf_fill_header(oi, op->s, length); - /* Hook thread to write packet. */ - OSPF_ISM_WRITE_ON (oi->ospf); + /* Set packet length. */ + op->length = length; + + op->dst.s_addr = addr; + + /* Add packet to the top of the interface output queue, so that they + * can't get delayed by things like long queues of LS Update packets + */ + ospf_packet_add_top(oi, op); + + /* Hook thread to write packet. */ + OSPF_ISM_WRITE_ON(oi->ospf); } -static void -ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma) +static void ospf_poll_send(struct ospf_nbr_nbma *nbr_nbma) { - struct ospf_interface *oi; + struct ospf_interface *oi; - oi = nbr_nbma->oi; - assert(oi); + oi = nbr_nbma->oi; + assert(oi); - /* If this is passive interface, do not send OSPF Hello. */ - if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE) - return; + /* If this is passive interface, do not send OSPF Hello. */ + if (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_PASSIVE) + return; - if (oi->type != OSPF_IFTYPE_NBMA) - return; + if (oi->type != OSPF_IFTYPE_NBMA) + return; - if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down) - return; + if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down) + return; - if (PRIORITY(oi) == 0) - return; + if (PRIORITY(oi) == 0) + return; - if (nbr_nbma->priority == 0 - && oi->state != ISM_DR && oi->state != ISM_Backup) - return; + if (nbr_nbma->priority == 0 && oi->state != ISM_DR + && oi->state != ISM_Backup) + return; - ospf_hello_send_sub (oi, nbr_nbma->addr.s_addr); + ospf_hello_send_sub(oi, nbr_nbma->addr.s_addr); } -int -ospf_poll_timer (struct thread *thread) +int ospf_poll_timer(struct thread *thread) { - struct ospf_nbr_nbma *nbr_nbma; + struct ospf_nbr_nbma *nbr_nbma; - nbr_nbma = THREAD_ARG (thread); - nbr_nbma->t_poll = NULL; + nbr_nbma = THREAD_ARG(thread); + nbr_nbma->t_poll = NULL; - if (IS_DEBUG_OSPF (nsm, NSM_TIMERS)) - zlog_debug("NSM[%s:%s]: Timer (Poll timer expire)", IF_NAME(nbr_nbma->oi), - inet_ntoa(nbr_nbma->addr)); + if (IS_DEBUG_OSPF(nsm, NSM_TIMERS)) + zlog_debug("NSM[%s:%s]: Timer (Poll timer expire)", + IF_NAME(nbr_nbma->oi), inet_ntoa(nbr_nbma->addr)); - ospf_poll_send (nbr_nbma); + ospf_poll_send(nbr_nbma); - if (nbr_nbma->v_poll > 0) - OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer, - nbr_nbma->v_poll); + if (nbr_nbma->v_poll > 0) + OSPF_POLL_TIMER_ON(nbr_nbma->t_poll, ospf_poll_timer, + nbr_nbma->v_poll); - return 0; + return 0; } -int -ospf_hello_reply_timer (struct thread *thread) +int ospf_hello_reply_timer(struct thread *thread) { - struct ospf_neighbor *nbr; + struct ospf_neighbor *nbr; - nbr = THREAD_ARG (thread); - nbr->t_hello_reply = NULL; + nbr = THREAD_ARG(thread); + nbr->t_hello_reply = NULL; - assert (nbr->oi); + assert(nbr->oi); - if (IS_DEBUG_OSPF (nsm, NSM_TIMERS)) - zlog_debug("NSM[%s:%s]: Timer (hello-reply timer expire)", - IF_NAME(nbr->oi), inet_ntoa(nbr->router_id)); + if (IS_DEBUG_OSPF(nsm, NSM_TIMERS)) + zlog_debug("NSM[%s:%s]: Timer (hello-reply timer expire)", + IF_NAME(nbr->oi), inet_ntoa(nbr->router_id)); - ospf_hello_send_sub (nbr->oi, nbr->address.u.prefix4.s_addr); + ospf_hello_send_sub(nbr->oi, nbr->address.u.prefix4.s_addr); - return 0; + return 0; } /* Send OSPF Hello. */ -void -ospf_hello_send (struct ospf_interface *oi) -{ - /* If this is passive interface, do not send OSPF Hello. */ - if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE) - return; - - if (oi->type == OSPF_IFTYPE_NBMA) - { - struct ospf_neighbor *nbr; - struct route_node *rn; - - for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) - if ((nbr = rn->info)) - if (nbr != oi->nbr_self) - if (nbr->state != NSM_Down) - { - /* RFC 2328 Section 9.5.1 - If the router is not eligible to become Designated Router, - it must periodically send Hello Packets to both the - Designated Router and the Backup Designated Router (if they - exist). */ - if (PRIORITY(oi) == 0 && - IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) && - IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4)) - continue; - - /* If the router is eligible to become Designated Router, it - must periodically send Hello Packets to all neighbors that - are also eligible. In addition, if the router is itself the - Designated Router or Backup Designated Router, it must also - send periodic Hello Packets to all other neighbors. */ - - if (nbr->priority == 0 && oi->state == ISM_DROther) - continue; - /* if oi->state == Waiting, send hello to all neighbors */ - ospf_hello_send_sub (oi, nbr->address.u.prefix4.s_addr); - } - } - else - { - /* Decide destination address. */ - if (oi->type == OSPF_IFTYPE_VIRTUALLINK) - ospf_hello_send_sub (oi, oi->vl_data->peer_addr.s_addr); - else - ospf_hello_send_sub (oi, htonl (OSPF_ALLSPFROUTERS)); - } +void ospf_hello_send(struct ospf_interface *oi) +{ + /* If this is passive interface, do not send OSPF Hello. */ + if (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_PASSIVE) + return; + + if (oi->type == OSPF_IFTYPE_NBMA) { + struct ospf_neighbor *nbr; + struct route_node *rn; + + for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) + if ((nbr = rn->info)) + if (nbr != oi->nbr_self) + if (nbr->state != NSM_Down) { + /* RFC 2328 Section 9.5.1 + If the router is not + eligible to become Designated + Router, + it must periodically send + Hello Packets to both the + Designated Router and the + Backup Designated Router (if + they + exist). */ + if (PRIORITY(oi) == 0 + && IPV4_ADDR_CMP( + &DR(oi), + &nbr->address.u + .prefix4) + && IPV4_ADDR_CMP( + &BDR(oi), + &nbr->address.u + .prefix4)) + continue; + + /* If the router is eligible to + become Designated Router, it + must periodically send Hello + Packets to all neighbors that + are also eligible. In + addition, if the router is + itself the + Designated Router or Backup + Designated Router, it must + also + send periodic Hello Packets + to all other neighbors. */ + + if (nbr->priority == 0 + && oi->state == ISM_DROther) + continue; + /* if oi->state == Waiting, send + * hello to all neighbors */ + ospf_hello_send_sub( + oi, + nbr->address.u.prefix4 + .s_addr); + } + } else { + /* Decide destination address. */ + if (oi->type == OSPF_IFTYPE_VIRTUALLINK) + ospf_hello_send_sub(oi, oi->vl_data->peer_addr.s_addr); + else + ospf_hello_send_sub(oi, htonl(OSPF_ALLSPFROUTERS)); + } } /* Send OSPF Database Description. */ -void -ospf_db_desc_send (struct ospf_neighbor *nbr) +void ospf_db_desc_send(struct ospf_neighbor *nbr) { - struct ospf_interface *oi; - struct ospf_packet *op; - u_int16_t length = OSPF_HEADER_SIZE; + struct ospf_interface *oi; + struct ospf_packet *op; + u_int16_t length = OSPF_HEADER_SIZE; - oi = nbr->oi; - op = ospf_packet_new (oi->ifp->mtu); + oi = nbr->oi; + op = ospf_packet_new(oi->ifp->mtu); - /* Prepare OSPF common header. */ - ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s); + /* Prepare OSPF common header. */ + ospf_make_header(OSPF_MSG_DB_DESC, oi, op->s); - /* Prepare OSPF Database Description body. */ - length += ospf_make_db_desc (oi, nbr, op->s); + /* Prepare OSPF Database Description body. */ + length += ospf_make_db_desc(oi, nbr, op->s); - /* Fill OSPF header. */ - ospf_fill_header (oi, op->s, length); + /* Fill OSPF header. */ + ospf_fill_header(oi, op->s, length); - /* Set packet length. */ - op->length = length; + /* Set packet length. */ + op->length = length; - /* Decide destination address. */ - if (oi->type == OSPF_IFTYPE_POINTOPOINT) - op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS); - else - op->dst = nbr->address.u.prefix4; + /* Decide destination address. */ + if (oi->type == OSPF_IFTYPE_POINTOPOINT) + op->dst.s_addr = htonl(OSPF_ALLSPFROUTERS); + else + op->dst = nbr->address.u.prefix4; - /* Add packet to the interface output queue. */ - ospf_packet_add (oi, op); + /* Add packet to the interface output queue. */ + ospf_packet_add(oi, op); - /* Hook thread to write packet. */ - OSPF_ISM_WRITE_ON (oi->ospf); + /* Hook thread to write packet. */ + OSPF_ISM_WRITE_ON(oi->ospf); - /* Remove old DD packet, then copy new one and keep in neighbor structure. */ - if (nbr->last_send) - ospf_packet_free (nbr->last_send); - nbr->last_send = ospf_packet_dup (op); - monotime(&nbr->last_send_ts); + /* Remove old DD packet, then copy new one and keep in neighbor + * structure. */ + if (nbr->last_send) + ospf_packet_free(nbr->last_send); + nbr->last_send = ospf_packet_dup(op); + monotime(&nbr->last_send_ts); } /* Re-send Database Description. */ -void -ospf_db_desc_resend (struct ospf_neighbor *nbr) +void ospf_db_desc_resend(struct ospf_neighbor *nbr) { - struct ospf_interface *oi; + struct ospf_interface *oi; - oi = nbr->oi; + oi = nbr->oi; - /* Add packet to the interface output queue. */ - ospf_packet_add (oi, ospf_packet_dup (nbr->last_send)); + /* Add packet to the interface output queue. */ + ospf_packet_add(oi, ospf_packet_dup(nbr->last_send)); - /* Hook thread to write packet. */ - OSPF_ISM_WRITE_ON (oi->ospf); + /* Hook thread to write packet. */ + OSPF_ISM_WRITE_ON(oi->ospf); } /* Send Link State Request. */ -void -ospf_ls_req_send (struct ospf_neighbor *nbr) +void ospf_ls_req_send(struct ospf_neighbor *nbr) { - struct ospf_interface *oi; - struct ospf_packet *op; - u_int16_t length = OSPF_HEADER_SIZE; + struct ospf_interface *oi; + struct ospf_packet *op; + u_int16_t length = OSPF_HEADER_SIZE; - oi = nbr->oi; - op = ospf_packet_new (oi->ifp->mtu); + oi = nbr->oi; + op = ospf_packet_new(oi->ifp->mtu); - /* Prepare OSPF common header. */ - ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s); + /* Prepare OSPF common header. */ + ospf_make_header(OSPF_MSG_LS_REQ, oi, op->s); - /* Prepare OSPF Link State Request body. */ - length += ospf_make_ls_req (nbr, op->s); - if (length == OSPF_HEADER_SIZE) - { - ospf_packet_free (op); - return; - } + /* Prepare OSPF Link State Request body. */ + length += ospf_make_ls_req(nbr, op->s); + if (length == OSPF_HEADER_SIZE) { + ospf_packet_free(op); + return; + } - /* Fill OSPF header. */ - ospf_fill_header (oi, op->s, length); + /* Fill OSPF header. */ + ospf_fill_header(oi, op->s, length); - /* Set packet length. */ - op->length = length; + /* Set packet length. */ + op->length = length; - /* Decide destination address. */ - if (oi->type == OSPF_IFTYPE_POINTOPOINT) - op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS); - else - op->dst = nbr->address.u.prefix4; + /* Decide destination address. */ + if (oi->type == OSPF_IFTYPE_POINTOPOINT) + op->dst.s_addr = htonl(OSPF_ALLSPFROUTERS); + else + op->dst = nbr->address.u.prefix4; - /* Add packet to the interface output queue. */ - ospf_packet_add (oi, op); + /* Add packet to the interface output queue. */ + ospf_packet_add(oi, op); - /* Hook thread to write packet. */ - OSPF_ISM_WRITE_ON (oi->ospf); + /* Hook thread to write packet. */ + OSPF_ISM_WRITE_ON(oi->ospf); - /* Add Link State Request Retransmission Timer. */ - OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req); + /* Add Link State Request Retransmission Timer. */ + OSPF_NSM_TIMER_ON(nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req); } /* Send Link State Update with an LSA. */ -void -ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa, - int flag) +void ospf_ls_upd_send_lsa(struct ospf_neighbor *nbr, struct ospf_lsa *lsa, + int flag) { - struct list *update; + struct list *update; - update = list_new (); + update = list_new(); - listnode_add (update, lsa); - ospf_ls_upd_send (nbr, update, flag); + listnode_add(update, lsa); + ospf_ls_upd_send(nbr, update, flag); - list_delete (update); + list_delete(update); } /* Determine size for packet. Must be at least big enough to accomodate next @@ -3662,309 +3749,310 @@ ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa, * NULL if we can not allocate, eg because LSA is bigger than imposed limit * on packet sizes (in which case offending LSA is deleted from update list) */ -static struct ospf_packet * -ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi) -{ - struct ospf_lsa *lsa; - struct listnode *ln; - size_t size; - static char warned = 0; - - lsa = listgetdata((ln = listhead (update))); - assert (lsa->data); - - if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length)) - > ospf_packet_max (oi)) - { - if (!warned) - { - zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!" - "will need to fragment. Not optimal. Try divide up" - " your network with areas. Use 'debug ospf packet send'" - " to see details, or look at 'show ip ospf database ..'"); - warned = 1; - } - - if (IS_DEBUG_OSPF_PACKET (0, SEND)) - zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s," - " %d bytes originated by %s, will be fragmented!", - inet_ntoa (lsa->data->id), - ntohs (lsa->data->length), - inet_ntoa (lsa->data->adv_router)); - - /* - * Allocate just enough to fit this LSA only, to avoid including other - * LSAs in fragmented LSA Updates. - */ - size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi)) - + OSPF_LS_UPD_MIN_SIZE; - } - else - size = oi->ifp->mtu; - - if (size > OSPF_MAX_PACKET_SIZE) - { - zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big," - " %d bytes, packet size %ld, dropping it completely." - " OSPF routing is broken!", - inet_ntoa (lsa->data->id), ntohs (lsa->data->length), - (long int) size); - list_delete_node (update, ln); - return NULL; - } - - /* IP header is built up separately by ospf_write(). This means, that we must - * reduce the "affordable" size just calculated by length of an IP header. - * This makes sure, that even if we manage to fill the payload with LSA data - * completely, the final packet (our data plus IP header) still fits into - * outgoing interface MTU. This correction isn't really meaningful for an - * oversized LSA, but for consistency the correction is done for both cases. - * - * P.S. OSPF_MAX_PACKET_SIZE above already includes IP header size - */ - return ospf_packet_new (size - sizeof (struct ip)); -} - -static void -ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update, - struct in_addr addr) -{ - struct ospf_packet *op; - u_int16_t length = OSPF_HEADER_SIZE; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("listcount = %d, [%s]dst %s", listcount (update), IF_NAME(oi), - inet_ntoa(addr)); - - op = ospf_ls_upd_packet_new (update, oi); - - /* Prepare OSPF common header. */ - ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s); - - /* Prepare OSPF Link State Update body. - * Includes Type-7 translation. - */ - length += ospf_make_ls_upd (oi, update, op->s); - - /* Fill OSPF header. */ - ospf_fill_header (oi, op->s, length); - - /* Set packet length. */ - op->length = length; - - /* Decide destination address. */ - if (oi->type == OSPF_IFTYPE_POINTOPOINT) - op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS); - else - op->dst.s_addr = addr.s_addr; - - /* Add packet to the interface output queue. */ - ospf_packet_add (oi, op); - - /* Hook thread to write packet. */ - OSPF_ISM_WRITE_ON (oi->ospf); -} - -static int -ospf_ls_upd_send_queue_event (struct thread *thread) -{ - struct ospf_interface *oi = THREAD_ARG(thread); - struct route_node *rn; - struct route_node *rnext; - struct list *update; - char again = 0; - - oi->t_ls_upd_event = NULL; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_ls_upd_send_queue start"); - - for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext) - { - rnext = route_next (rn); - - if (rn->info == NULL) - continue; - - update = (struct list *)rn->info; - - ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4); - - /* list might not be empty. */ - if (listcount(update) == 0) - { - list_delete (rn->info); - rn->info = NULL; - route_unlock_node (rn); - } - else - again = 1; - } - - if (again != 0) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared," - " %d nodes to try again, raising new event", again); - oi->t_ls_upd_event = NULL; - thread_add_event(master, ospf_ls_upd_send_queue_event, oi, 0, - &oi->t_ls_upd_event); - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_ls_upd_send_queue stop"); - - return 0; -} - -void -ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag) -{ - struct ospf_interface *oi; - struct ospf_lsa *lsa; - struct prefix_ipv4 p; - struct route_node *rn; - struct listnode *node; - - oi = nbr->oi; - - p.family = AF_INET; - p.prefixlen = IPV4_MAX_BITLEN; - - /* Decide destination address. */ - if (oi->type == OSPF_IFTYPE_VIRTUALLINK) - p.prefix = oi->vl_data->peer_addr; - else if (oi->type == OSPF_IFTYPE_POINTOPOINT) - p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS); - else if (flag == OSPF_SEND_PACKET_DIRECT) - p.prefix = nbr->address.u.prefix4; - else if (oi->state == ISM_DR || oi->state == ISM_Backup) - p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS); - else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) - p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS); - else - p.prefix.s_addr = htonl (OSPF_ALLDROUTERS); - - if (oi->type == OSPF_IFTYPE_NBMA) - { - if (flag == OSPF_SEND_PACKET_INDIRECT) - zlog_warn ("* LS-Update is directly sent on NBMA network."); - if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr)) - zlog_warn ("* LS-Update is sent to myself."); - } - - rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p); - - if (rn->info == NULL) - rn->info = list_new (); - else - route_unlock_node (rn); - - for (ALL_LIST_ELEMENTS_RO (update, node, lsa)) - listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */ - - thread_add_event(master, ospf_ls_upd_send_queue_event, oi, 0, - &oi->t_ls_upd_event); -} - -static void -ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack, - struct in_addr dst) -{ - struct ospf_packet *op; - u_int16_t length = OSPF_HEADER_SIZE; - - op = ospf_packet_new (oi->ifp->mtu); - - /* Prepare OSPF common header. */ - ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s); - - /* Prepare OSPF Link State Acknowledgment body. */ - length += ospf_make_ls_ack (oi, ack, op->s); - - /* Fill OSPF header. */ - ospf_fill_header (oi, op->s, length); - - /* Set packet length. */ - op->length = length; - - /* Decide destination address. */ - if (oi->type == OSPF_IFTYPE_POINTOPOINT) - op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS); - else - op->dst.s_addr = dst.s_addr; - - /* Add packet to the interface output queue. */ - ospf_packet_add (oi, op); +static struct ospf_packet *ospf_ls_upd_packet_new(struct list *update, + struct ospf_interface *oi) +{ + struct ospf_lsa *lsa; + struct listnode *ln; + size_t size; + static char warned = 0; + + lsa = listgetdata((ln = listhead(update))); + assert(lsa->data); + + if ((OSPF_LS_UPD_MIN_SIZE + ntohs(lsa->data->length)) + > ospf_packet_max(oi)) { + if (!warned) { + zlog_warn( + "ospf_ls_upd_packet_new: oversized LSA encountered!" + "will need to fragment. Not optimal. Try divide up" + " your network with areas. Use 'debug ospf packet send'" + " to see details, or look at 'show ip ospf database ..'"); + warned = 1; + } + + if (IS_DEBUG_OSPF_PACKET(0, SEND)) + zlog_debug( + "ospf_ls_upd_packet_new: oversized LSA id:%s," + " %d bytes originated by %s, will be fragmented!", + inet_ntoa(lsa->data->id), + ntohs(lsa->data->length), + inet_ntoa(lsa->data->adv_router)); + + /* + * Allocate just enough to fit this LSA only, to avoid including + * other + * LSAs in fragmented LSA Updates. + */ + size = ntohs(lsa->data->length) + + (oi->ifp->mtu - ospf_packet_max(oi)) + + OSPF_LS_UPD_MIN_SIZE; + } else + size = oi->ifp->mtu; + + if (size > OSPF_MAX_PACKET_SIZE) { + zlog_warn( + "ospf_ls_upd_packet_new: oversized LSA id:%s too big," + " %d bytes, packet size %ld, dropping it completely." + " OSPF routing is broken!", + inet_ntoa(lsa->data->id), ntohs(lsa->data->length), + (long int)size); + list_delete_node(update, ln); + return NULL; + } - /* Hook thread to write packet. */ - OSPF_ISM_WRITE_ON (oi->ospf); + /* IP header is built up separately by ospf_write(). This means, that we + * must + * reduce the "affordable" size just calculated by length of an IP + * header. + * This makes sure, that even if we manage to fill the payload with LSA + * data + * completely, the final packet (our data plus IP header) still fits + * into + * outgoing interface MTU. This correction isn't really meaningful for + * an + * oversized LSA, but for consistency the correction is done for both + * cases. + * + * P.S. OSPF_MAX_PACKET_SIZE above already includes IP header size + */ + return ospf_packet_new(size - sizeof(struct ip)); } -static int -ospf_ls_ack_send_event (struct thread *thread) +static void ospf_ls_upd_queue_send(struct ospf_interface *oi, + struct list *update, struct in_addr addr) { - struct ospf_interface *oi = THREAD_ARG (thread); + struct ospf_packet *op; + u_int16_t length = OSPF_HEADER_SIZE; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("listcount = %d, [%s]dst %s", listcount(update), + IF_NAME(oi), inet_ntoa(addr)); + + op = ospf_ls_upd_packet_new(update, oi); - oi->t_ls_ack_direct = NULL; - - while (listcount (oi->ls_ack_direct.ls_ack)) - ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack, - oi->ls_ack_direct.dst); + /* Prepare OSPF common header. */ + ospf_make_header(OSPF_MSG_LS_UPD, oi, op->s); - return 0; + /* Prepare OSPF Link State Update body. + * Includes Type-7 translation. + */ + length += ospf_make_ls_upd(oi, update, op->s); + + /* Fill OSPF header. */ + ospf_fill_header(oi, op->s, length); + + /* Set packet length. */ + op->length = length; + + /* Decide destination address. */ + if (oi->type == OSPF_IFTYPE_POINTOPOINT) + op->dst.s_addr = htonl(OSPF_ALLSPFROUTERS); + else + op->dst.s_addr = addr.s_addr; + + /* Add packet to the interface output queue. */ + ospf_packet_add(oi, op); + + /* Hook thread to write packet. */ + OSPF_ISM_WRITE_ON(oi->ospf); +} + +static int ospf_ls_upd_send_queue_event(struct thread *thread) +{ + struct ospf_interface *oi = THREAD_ARG(thread); + struct route_node *rn; + struct route_node *rnext; + struct list *update; + char again = 0; + + oi->t_ls_upd_event = NULL; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_ls_upd_send_queue start"); + + for (rn = route_top(oi->ls_upd_queue); rn; rn = rnext) { + rnext = route_next(rn); + + if (rn->info == NULL) + continue; + + update = (struct list *)rn->info; + + ospf_ls_upd_queue_send(oi, update, rn->p.u.prefix4); + + /* list might not be empty. */ + if (listcount(update) == 0) { + list_delete(rn->info); + rn->info = NULL; + route_unlock_node(rn); + } else + again = 1; + } + + if (again != 0) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_ls_upd_send_queue: update lists not cleared," + " %d nodes to try again, raising new event", + again); + oi->t_ls_upd_event = NULL; + thread_add_event(master, ospf_ls_upd_send_queue_event, oi, 0, + &oi->t_ls_upd_event); + } + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_ls_upd_send_queue stop"); + + return 0; +} + +void ospf_ls_upd_send(struct ospf_neighbor *nbr, struct list *update, int flag) +{ + struct ospf_interface *oi; + struct ospf_lsa *lsa; + struct prefix_ipv4 p; + struct route_node *rn; + struct listnode *node; + + oi = nbr->oi; + + p.family = AF_INET; + p.prefixlen = IPV4_MAX_BITLEN; + + /* Decide destination address. */ + if (oi->type == OSPF_IFTYPE_VIRTUALLINK) + p.prefix = oi->vl_data->peer_addr; + else if (oi->type == OSPF_IFTYPE_POINTOPOINT) + p.prefix.s_addr = htonl(OSPF_ALLSPFROUTERS); + else if (flag == OSPF_SEND_PACKET_DIRECT) + p.prefix = nbr->address.u.prefix4; + else if (oi->state == ISM_DR || oi->state == ISM_Backup) + p.prefix.s_addr = htonl(OSPF_ALLSPFROUTERS); + else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) + p.prefix.s_addr = htonl(OSPF_ALLSPFROUTERS); + else + p.prefix.s_addr = htonl(OSPF_ALLDROUTERS); + + if (oi->type == OSPF_IFTYPE_NBMA) { + if (flag == OSPF_SEND_PACKET_INDIRECT) + zlog_warn( + "* LS-Update is directly sent on NBMA network."); + if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr)) + zlog_warn("* LS-Update is sent to myself."); + } + + rn = route_node_get(oi->ls_upd_queue, (struct prefix *)&p); + + if (rn->info == NULL) + rn->info = list_new(); + else + route_unlock_node(rn); + + for (ALL_LIST_ELEMENTS_RO(update, node, lsa)) + listnode_add(rn->info, + ospf_lsa_lock(lsa)); /* oi->ls_upd_queue */ + + thread_add_event(master, ospf_ls_upd_send_queue_event, oi, 0, + &oi->t_ls_upd_event); } -void -ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa) +static void ospf_ls_ack_send_list(struct ospf_interface *oi, struct list *ack, + struct in_addr dst) { - struct ospf_interface *oi = nbr->oi; + struct ospf_packet *op; + u_int16_t length = OSPF_HEADER_SIZE; + + op = ospf_packet_new(oi->ifp->mtu); + + /* Prepare OSPF common header. */ + ospf_make_header(OSPF_MSG_LS_ACK, oi, op->s); + + /* Prepare OSPF Link State Acknowledgment body. */ + length += ospf_make_ls_ack(oi, ack, op->s); + + /* Fill OSPF header. */ + ospf_fill_header(oi, op->s, length); - if (listcount (oi->ls_ack_direct.ls_ack) == 0) - oi->ls_ack_direct.dst = nbr->address.u.prefix4; - - listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa)); - - thread_add_event(master, ospf_ls_ack_send_event, oi, 0, - &oi->t_ls_ack_direct); + /* Set packet length. */ + op->length = length; + + /* Decide destination address. */ + if (oi->type == OSPF_IFTYPE_POINTOPOINT) + op->dst.s_addr = htonl(OSPF_ALLSPFROUTERS); + else + op->dst.s_addr = dst.s_addr; + + /* Add packet to the interface output queue. */ + ospf_packet_add(oi, op); + + /* Hook thread to write packet. */ + OSPF_ISM_WRITE_ON(oi->ospf); +} + +static int ospf_ls_ack_send_event(struct thread *thread) +{ + struct ospf_interface *oi = THREAD_ARG(thread); + + oi->t_ls_ack_direct = NULL; + + while (listcount(oi->ls_ack_direct.ls_ack)) + ospf_ls_ack_send_list(oi, oi->ls_ack_direct.ls_ack, + oi->ls_ack_direct.dst); + + return 0; +} + +void ospf_ls_ack_send(struct ospf_neighbor *nbr, struct ospf_lsa *lsa) +{ + struct ospf_interface *oi = nbr->oi; + + if (listcount(oi->ls_ack_direct.ls_ack) == 0) + oi->ls_ack_direct.dst = nbr->address.u.prefix4; + + listnode_add(oi->ls_ack_direct.ls_ack, ospf_lsa_lock(lsa)); + + thread_add_event(master, ospf_ls_ack_send_event, oi, 0, + &oi->t_ls_ack_direct); } /* Send Link State Acknowledgment delayed. */ -void -ospf_ls_ack_send_delayed (struct ospf_interface *oi) -{ - struct in_addr dst; - - /* Decide destination address. */ - /* RFC2328 Section 13.5 On non-broadcast - networks, delayed Link State Acknowledgment packets must be - unicast separately over each adjacency (i.e., neighbor whose - state is >= Exchange). */ - if (oi->type == OSPF_IFTYPE_NBMA) - { - struct ospf_neighbor *nbr; - struct route_node *rn; - - for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) - if ((nbr = rn->info) != NULL) - if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange) - while (listcount (oi->ls_ack)) - ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4); - return; - } - if (oi->type == OSPF_IFTYPE_VIRTUALLINK) - dst.s_addr = oi->vl_data->peer_addr.s_addr; - else if (oi->state == ISM_DR || oi->state == ISM_Backup) - dst.s_addr = htonl (OSPF_ALLSPFROUTERS); - else if (oi->type == OSPF_IFTYPE_POINTOPOINT) - dst.s_addr = htonl (OSPF_ALLSPFROUTERS); - else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) - dst.s_addr = htonl (OSPF_ALLSPFROUTERS); - else - dst.s_addr = htonl (OSPF_ALLDROUTERS); - - while (listcount (oi->ls_ack)) - ospf_ls_ack_send_list (oi, oi->ls_ack, dst); +void ospf_ls_ack_send_delayed(struct ospf_interface *oi) +{ + struct in_addr dst; + + /* Decide destination address. */ + /* RFC2328 Section 13.5 On non-broadcast + networks, delayed Link State Acknowledgment packets must be + unicast separately over each adjacency (i.e., neighbor whose + state is >= Exchange). */ + if (oi->type == OSPF_IFTYPE_NBMA) { + struct ospf_neighbor *nbr; + struct route_node *rn; + + for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) + if ((nbr = rn->info) != NULL) + if (nbr != oi->nbr_self + && nbr->state >= NSM_Exchange) + while (listcount(oi->ls_ack)) + ospf_ls_ack_send_list( + oi, oi->ls_ack, + nbr->address.u.prefix4); + return; + } + if (oi->type == OSPF_IFTYPE_VIRTUALLINK) + dst.s_addr = oi->vl_data->peer_addr.s_addr; + else if (oi->state == ISM_DR || oi->state == ISM_Backup) + dst.s_addr = htonl(OSPF_ALLSPFROUTERS); + else if (oi->type == OSPF_IFTYPE_POINTOPOINT) + dst.s_addr = htonl(OSPF_ALLSPFROUTERS); + else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) + dst.s_addr = htonl(OSPF_ALLSPFROUTERS); + else + dst.s_addr = htonl(OSPF_ALLDROUTERS); + + while (listcount(oi->ls_ack)) + ospf_ls_ack_send_list(oi, oi->ls_ack, dst); } /* @@ -3978,23 +4066,22 @@ ospf_ls_ack_send_delayed (struct ospf_interface *oi) * can be avoided if the MAC was known apriori. */ #define OSPF_PING_NBR_STR_MAX (8 + 40 + 20) -void -ospf_proactively_arp (struct ospf_neighbor *nbr) -{ - char ping_nbr[OSPF_PING_NBR_STR_MAX]; - char *str_ptr; - int ret; - - if (!nbr || !nbr->oi || !nbr->oi->ifp) - return; - - str_ptr = strcpy (ping_nbr, "ping -c 1 -I "); - str_ptr = strcat (str_ptr, nbr->oi->ifp->name); - str_ptr = strcat (str_ptr, " "); - str_ptr = strcat (str_ptr, inet_ntoa (nbr->address.u.prefix4)); - str_ptr = strcat (str_ptr, " > /dev/null 2>&1 &"); - ret = system (ping_nbr); - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Executed %s %s", ping_nbr, - ((ret == 0) ? "successfully" : "but failed")); +void ospf_proactively_arp(struct ospf_neighbor *nbr) +{ + char ping_nbr[OSPF_PING_NBR_STR_MAX]; + char *str_ptr; + int ret; + + if (!nbr || !nbr->oi || !nbr->oi->ifp) + return; + + str_ptr = strcpy(ping_nbr, "ping -c 1 -I "); + str_ptr = strcat(str_ptr, nbr->oi->ifp->name); + str_ptr = strcat(str_ptr, " "); + str_ptr = strcat(str_ptr, inet_ntoa(nbr->address.u.prefix4)); + str_ptr = strcat(str_ptr, " > /dev/null 2>&1 &"); + ret = system(ping_nbr); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Executed %s %s", ping_nbr, + ((ret == 0) ? "successfully" : "but failed")); } diff --git a/ospfd/ospf_packet.h b/ospfd/ospf_packet.h index ebc5d892d..a3617c7bd 100644 --- a/ospfd/ospf_packet.h +++ b/ospfd/ospf_packet.h @@ -49,80 +49,73 @@ #define MSG_OK 0 #define MSG_NG 1 -struct ospf_packet -{ - struct ospf_packet *next; +struct ospf_packet { + struct ospf_packet *next; - /* Pointer to data stream. */ - struct stream *s; + /* Pointer to data stream. */ + struct stream *s; - /* IP destination address. */ - struct in_addr dst; + /* IP destination address. */ + struct in_addr dst; - /* OSPF packet length. */ - u_int16_t length; + /* OSPF packet length. */ + u_int16_t length; }; /* OSPF packet queue structure. */ -struct ospf_fifo -{ - unsigned long count; +struct ospf_fifo { + unsigned long count; - struct ospf_packet *head; - struct ospf_packet *tail; + struct ospf_packet *head; + struct ospf_packet *tail; }; /* OSPF packet header structure. */ -struct ospf_header -{ - u_char version; /* OSPF Version. */ - u_char type; /* Packet Type. */ - u_int16_t length; /* Packet Length. */ - struct in_addr router_id; /* Router ID. */ - struct in_addr area_id; /* Area ID. */ - u_int16_t checksum; /* Check Sum. */ - u_int16_t auth_type; /* Authentication Type. */ - /* Authentication Data. */ - union - { - /* Simple Authentication. */ - u_char auth_data [OSPF_AUTH_SIMPLE_SIZE]; - /* Cryptographic Authentication. */ - struct - { - u_int16_t zero; /* Should be 0. */ - u_char key_id; /* Key ID. */ - u_char auth_data_len; /* Auth Data Length. */ - u_int32_t crypt_seqnum; /* Cryptographic Sequence Number. */ - } crypt; - } u; +struct ospf_header { + u_char version; /* OSPF Version. */ + u_char type; /* Packet Type. */ + u_int16_t length; /* Packet Length. */ + struct in_addr router_id; /* Router ID. */ + struct in_addr area_id; /* Area ID. */ + u_int16_t checksum; /* Check Sum. */ + u_int16_t auth_type; /* Authentication Type. */ + /* Authentication Data. */ + union { + /* Simple Authentication. */ + u_char auth_data[OSPF_AUTH_SIMPLE_SIZE]; + /* Cryptographic Authentication. */ + struct { + u_int16_t zero; /* Should be 0. */ + u_char key_id; /* Key ID. */ + u_char auth_data_len; /* Auth Data Length. */ + u_int32_t crypt_seqnum; /* Cryptographic Sequence + Number. */ + } crypt; + } u; }; /* OSPF Hello body format. */ -struct ospf_hello -{ - struct in_addr network_mask; - u_int16_t hello_interval; - u_char options; - u_char priority; - u_int32_t dead_interval; - struct in_addr d_router; - struct in_addr bd_router; - struct in_addr neighbors[1]; +struct ospf_hello { + struct in_addr network_mask; + u_int16_t hello_interval; + u_char options; + u_char priority; + u_int32_t dead_interval; + struct in_addr d_router; + struct in_addr bd_router; + struct in_addr neighbors[1]; }; /* OSPF Database Description body format. */ -struct ospf_db_desc -{ - u_int16_t mtu; - u_char options; - u_char flags; - u_int32_t dd_seqnum; +struct ospf_db_desc { + u_int16_t mtu; + u_char options; + u_char flags; + u_int32_t dd_seqnum; }; -struct ospf_ls_update -{ - u_int32_t num_lsas; +struct ospf_ls_update { + u_int32_t num_lsas; }; /* Macros. */ @@ -138,41 +131,41 @@ struct ospf_ls_update #define IS_SET_DD_ALL(X) ((X) & OSPF_DD_FLAG_ALL) /* Prototypes. */ -extern void ospf_output_forward (struct stream *, int); -extern struct ospf_packet *ospf_packet_new (size_t); -extern void ospf_packet_free (struct ospf_packet *); -extern struct ospf_fifo *ospf_fifo_new (void); -extern void ospf_fifo_push (struct ospf_fifo *, struct ospf_packet *); -extern struct ospf_packet *ospf_fifo_pop (struct ospf_fifo *); -extern struct ospf_packet *ospf_fifo_head (struct ospf_fifo *); -extern void ospf_fifo_flush (struct ospf_fifo *); -extern void ospf_fifo_free (struct ospf_fifo *); -extern void ospf_packet_add (struct ospf_interface *, struct ospf_packet *); -extern void ospf_packet_delete (struct ospf_interface *); -extern struct stream *ospf_stream_dup (struct stream *); -extern struct ospf_packet *ospf_packet_dup (struct ospf_packet *); - -extern int ospf_read (struct thread *); -extern void ospf_hello_send (struct ospf_interface *); -extern void ospf_db_desc_send (struct ospf_neighbor *); -extern void ospf_db_desc_resend (struct ospf_neighbor *); -extern void ospf_ls_req_send (struct ospf_neighbor *); -extern void ospf_ls_upd_send_lsa (struct ospf_neighbor *, struct ospf_lsa *, - int); -extern void ospf_ls_upd_send (struct ospf_neighbor *, struct list *, int); -extern void ospf_ls_ack_send (struct ospf_neighbor *, struct ospf_lsa *); -extern void ospf_ls_ack_send_delayed (struct ospf_interface *); -extern void ospf_ls_retransmit (struct ospf_interface *, struct ospf_lsa *); -extern void ospf_ls_req_event (struct ospf_neighbor *); - -extern int ospf_ls_upd_timer (struct thread *); -extern int ospf_ls_ack_timer (struct thread *); -extern int ospf_poll_timer (struct thread *); -extern int ospf_hello_reply_timer (struct thread *); +extern void ospf_output_forward(struct stream *, int); +extern struct ospf_packet *ospf_packet_new(size_t); +extern void ospf_packet_free(struct ospf_packet *); +extern struct ospf_fifo *ospf_fifo_new(void); +extern void ospf_fifo_push(struct ospf_fifo *, struct ospf_packet *); +extern struct ospf_packet *ospf_fifo_pop(struct ospf_fifo *); +extern struct ospf_packet *ospf_fifo_head(struct ospf_fifo *); +extern void ospf_fifo_flush(struct ospf_fifo *); +extern void ospf_fifo_free(struct ospf_fifo *); +extern void ospf_packet_add(struct ospf_interface *, struct ospf_packet *); +extern void ospf_packet_delete(struct ospf_interface *); +extern struct stream *ospf_stream_dup(struct stream *); +extern struct ospf_packet *ospf_packet_dup(struct ospf_packet *); + +extern int ospf_read(struct thread *); +extern void ospf_hello_send(struct ospf_interface *); +extern void ospf_db_desc_send(struct ospf_neighbor *); +extern void ospf_db_desc_resend(struct ospf_neighbor *); +extern void ospf_ls_req_send(struct ospf_neighbor *); +extern void ospf_ls_upd_send_lsa(struct ospf_neighbor *, struct ospf_lsa *, + int); +extern void ospf_ls_upd_send(struct ospf_neighbor *, struct list *, int); +extern void ospf_ls_ack_send(struct ospf_neighbor *, struct ospf_lsa *); +extern void ospf_ls_ack_send_delayed(struct ospf_interface *); +extern void ospf_ls_retransmit(struct ospf_interface *, struct ospf_lsa *); +extern void ospf_ls_req_event(struct ospf_neighbor *); + +extern int ospf_ls_upd_timer(struct thread *); +extern int ospf_ls_ack_timer(struct thread *); +extern int ospf_poll_timer(struct thread *); +extern int ospf_hello_reply_timer(struct thread *); extern const struct message ospf_packet_type_str[]; extern const size_t ospf_packet_type_str_max; -extern void ospf_proactively_arp (struct ospf_neighbor *); +extern void ospf_proactively_arp(struct ospf_neighbor *); #endif /* _ZEBRA_OSPF_PACKET_H */ diff --git a/ospfd/ospf_ri.c b/ospfd/ospf_ri.c index 0f1ef35e4..26d2ed7d1 100644 --- a/ospfd/ospf_ri.c +++ b/ospfd/ospf_ri.c @@ -38,7 +38,7 @@ #include "log.h" #include "thread.h" #include "hash.h" -#include "sockunion.h" /* for inet_aton() */ +#include "sockunion.h" /* for inet_aton() */ #include "ospfd/ospfd.h" #include "ospfd/ospf_interface.h" @@ -58,41 +58,39 @@ #include "ospfd/ospf_ri.h" #include "ospfd/ospf_te.h" -struct ospf_pce_info -{ +struct ospf_pce_info { - /* Store Router Information PCE TLV and SubTLV in network byte order. */ - struct ri_tlv_pce pce_header; - struct ri_pce_subtlv_address pce_address; - struct ri_pce_subtlv_path_scope pce_scope; - struct list *pce_domain; - struct list *pce_neighbor; - struct ri_pce_subtlv_cap_flag pce_cap_flag; + /* Store Router Information PCE TLV and SubTLV in network byte order. */ + struct ri_tlv_pce pce_header; + struct ri_pce_subtlv_address pce_address; + struct ri_pce_subtlv_path_scope pce_scope; + struct list *pce_domain; + struct list *pce_neighbor; + struct ri_pce_subtlv_cap_flag pce_cap_flag; }; /* Following structure are internal use only. */ -struct ospf_router_info -{ - status_t status; +struct ospf_router_info { + status_t status; - u_int8_t registered; - u_int8_t scope; + u_int8_t registered; + u_int8_t scope; - /* Flags to manage this router information. */ +/* Flags to manage this router information. */ #define RIFLG_LOOKUP_DONE 0x1 #define RIFLG_LSA_ENGAGED 0x2 #define RIFLG_LSA_FORCED_REFRESH 0x4 - u_int32_t flags; + u_int32_t flags; - /* area pointer if flooding is Type 10 Null if flooding is AS scope */ - struct ospf_area *area; - struct in_addr area_id; + /* area pointer if flooding is Type 10 Null if flooding is AS scope */ + struct ospf_area *area; + struct in_addr area_id; - /* Store Router Information Capabilities LSA */ - struct ri_tlv_router_cap router_cap; + /* Store Router Information Capabilities LSA */ + struct ri_tlv_router_cap router_cap; - /* Store PCE capability LSA */ - struct ospf_pce_info pce_info; + /* Store PCE capability LSA */ + struct ospf_pce_info pce_info; }; /* @@ -102,1058 +100,1005 @@ struct ospf_router_info static struct ospf_router_info OspfRI; /*------------------------------------------------------------------------------* - * Followings are initialize/terminate functions for Router Information handling. + * Followings are initialize/terminate functions for Router Information + *handling. *------------------------------------------------------------------------------*/ -static void ospf_router_info_ism_change (struct ospf_interface *oi, - int old_status); -static void ospf_router_info_nsm_change (struct ospf_neighbor *nbr, - int old_status); -static void ospf_router_info_config_write_router (struct vty *vty); -static void ospf_router_info_show_info (struct vty *vty, - struct ospf_lsa *lsa); -static int ospf_router_info_lsa_originate (void *arg); -static struct ospf_lsa *ospf_router_info_lsa_refresh (struct ospf_lsa *lsa); -static void ospf_router_info_lsa_schedule (opcode_t opcode); -static void ospf_router_info_register_vty (void); -static void del_pce_info (void *val); - -int -ospf_router_info_init (void) +static void ospf_router_info_ism_change(struct ospf_interface *oi, + int old_status); +static void ospf_router_info_nsm_change(struct ospf_neighbor *nbr, + int old_status); +static void ospf_router_info_config_write_router(struct vty *vty); +static void ospf_router_info_show_info(struct vty *vty, struct ospf_lsa *lsa); +static int ospf_router_info_lsa_originate(void *arg); +static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa); +static void ospf_router_info_lsa_schedule(opcode_t opcode); +static void ospf_router_info_register_vty(void); +static void del_pce_info(void *val); + +int ospf_router_info_init(void) { - memset (&OspfRI, 0, sizeof (struct ospf_router_info)); - OspfRI.status = disabled; - OspfRI.registered = 0; - OspfRI.scope = OSPF_OPAQUE_AS_LSA; - OspfRI.flags = 0; + memset(&OspfRI, 0, sizeof(struct ospf_router_info)); + OspfRI.status = disabled; + OspfRI.registered = 0; + OspfRI.scope = OSPF_OPAQUE_AS_LSA; + OspfRI.flags = 0; - /* Initialize pce domain and neighbor list */ - OspfRI.pce_info.pce_domain = list_new (); - OspfRI.pce_info.pce_domain->del = del_pce_info; - OspfRI.pce_info.pce_neighbor = list_new (); - OspfRI.pce_info.pce_neighbor->del = del_pce_info; + /* Initialize pce domain and neighbor list */ + OspfRI.pce_info.pce_domain = list_new(); + OspfRI.pce_info.pce_domain->del = del_pce_info; + OspfRI.pce_info.pce_neighbor = list_new(); + OspfRI.pce_info.pce_neighbor->del = del_pce_info; - ospf_router_info_register_vty (); + ospf_router_info_register_vty(); - return 0; + return 0; } -static int -ospf_router_info_register (u_int8_t scope) +static int ospf_router_info_register(u_int8_t scope) { - int rc = 0; - - if (OspfRI.registered) - return 0; - - zlog_info ("Register Router Information with scope %s(%d)", - scope == OSPF_OPAQUE_AREA_LSA ? "Area" : "AS", scope); - rc = ospf_register_opaque_functab (scope, - OPAQUE_TYPE_ROUTER_INFORMATION_LSA, - NULL, /* new interface */ - NULL, /* del interface */ - ospf_router_info_ism_change, - ospf_router_info_nsm_change, - ospf_router_info_config_write_router, - NULL, /* Config. write interface */ - NULL, /* Config. write debug */ - ospf_router_info_show_info, - ospf_router_info_lsa_originate, - ospf_router_info_lsa_refresh, - NULL, /* new_lsa_hook */ - NULL); /* del_lsa_hook */ - - if (rc != 0) - { - zlog_warn ("ospf_router_info_init: Failed to register functions"); - return rc; - } - - OspfRI.registered = 1; - OspfRI.scope = scope; - return 0; + int rc = 0; + + if (OspfRI.registered) + return 0; + + zlog_info("Register Router Information with scope %s(%d)", + scope == OSPF_OPAQUE_AREA_LSA ? "Area" : "AS", scope); + rc = ospf_register_opaque_functab( + scope, OPAQUE_TYPE_ROUTER_INFORMATION_LSA, + NULL, /* new interface */ + NULL, /* del interface */ + ospf_router_info_ism_change, ospf_router_info_nsm_change, + ospf_router_info_config_write_router, + NULL, /* Config. write interface */ + NULL, /* Config. write debug */ + ospf_router_info_show_info, ospf_router_info_lsa_originate, + ospf_router_info_lsa_refresh, NULL, /* new_lsa_hook */ + NULL); /* del_lsa_hook */ + + if (rc != 0) { + zlog_warn( + "ospf_router_info_init: Failed to register functions"); + return rc; + } + + OspfRI.registered = 1; + OspfRI.scope = scope; + return 0; } -static int -ospf_router_info_unregister () +static int ospf_router_info_unregister() { - if ((OspfRI.scope != OSPF_OPAQUE_AS_LSA) - && (OspfRI.scope != OSPF_OPAQUE_AREA_LSA)) - { - zlog_warn ("Unable to unregister Router Info functions: Wrong scope!"); - return -1; - } - - ospf_delete_opaque_functab (OspfRI.scope, - OPAQUE_TYPE_ROUTER_INFORMATION_LSA); + if ((OspfRI.scope != OSPF_OPAQUE_AS_LSA) + && (OspfRI.scope != OSPF_OPAQUE_AREA_LSA)) { + zlog_warn( + "Unable to unregister Router Info functions: Wrong scope!"); + return -1; + } - OspfRI.registered = 0; - return 0; + ospf_delete_opaque_functab(OspfRI.scope, + OPAQUE_TYPE_ROUTER_INFORMATION_LSA); + OspfRI.registered = 0; + return 0; } -void -ospf_router_info_term (void) +void ospf_router_info_term(void) { - list_delete (OspfRI.pce_info.pce_domain); - list_delete (OspfRI.pce_info.pce_neighbor); + list_delete(OspfRI.pce_info.pce_domain); + list_delete(OspfRI.pce_info.pce_neighbor); - OspfRI.pce_info.pce_domain = NULL; - OspfRI.pce_info.pce_neighbor = NULL; - OspfRI.status = disabled; + OspfRI.pce_info.pce_domain = NULL; + OspfRI.pce_info.pce_neighbor = NULL; + OspfRI.status = disabled; - ospf_router_info_unregister (); + ospf_router_info_unregister(); - return; + return; } -static void -del_pce_info (void *val) +static void del_pce_info(void *val) { - XFREE (MTYPE_OSPF_PCE_PARAMS, val); - return; + XFREE(MTYPE_OSPF_PCE_PARAMS, val); + return; } /*------------------------------------------------------------------------* - * Followings are control functions for ROUTER INFORMATION parameters management. + * Followings are control functions for ROUTER INFORMATION parameters + *management. *------------------------------------------------------------------------*/ -static void -set_router_info_capabilities (struct ri_tlv_router_cap *ric, u_int32_t cap) +static void set_router_info_capabilities(struct ri_tlv_router_cap *ric, + u_int32_t cap) { - ric->header.type = htons (RI_TLV_CAPABILITIES); - ric->header.length = htons (RI_TLV_LENGTH); - ric->value = htonl (cap); - return; + ric->header.type = htons(RI_TLV_CAPABILITIES); + ric->header.length = htons(RI_TLV_LENGTH); + ric->value = htonl(cap); + return; } -static int -set_pce_header (struct ospf_pce_info *pce) +static int set_pce_header(struct ospf_pce_info *pce) { - u_int16_t length = 0; - struct listnode *node; - struct ri_pce_subtlv_domain *domain; - struct ri_pce_subtlv_neighbor *neighbor; - - /* PCE Address */ - if (ntohs (pce->pce_address.header.type) != 0) - length += RI_TLV_SIZE (&pce->pce_address.header); - - /* PCE Path Scope */ - if (ntohs (pce->pce_scope.header.type) != 0) - length += RI_TLV_SIZE (&pce->pce_scope.header); - - /* PCE Domain */ - for (ALL_LIST_ELEMENTS_RO (pce->pce_domain, node, domain)) - { - if (ntohs (domain->header.type) != 0) - length += RI_TLV_SIZE (&domain->header); - } - - /* PCE Neighbor */ - for (ALL_LIST_ELEMENTS_RO (pce->pce_neighbor, node, neighbor)) - { - if (ntohs (neighbor->header.type) != 0) - length += RI_TLV_SIZE (&neighbor->header); - } - - /* PCE Capabilities */ - if (ntohs (pce->pce_cap_flag.header.type) != 0) - length += RI_TLV_SIZE (&pce->pce_cap_flag.header); - - if (length != 0) - { - pce->pce_header.header.type = htons (RI_TLV_PCE); - pce->pce_header.header.length = htons (length); - } - else - { - pce->pce_header.header.type = 0; - pce->pce_header.header.length = 0; - } - - return length; + u_int16_t length = 0; + struct listnode *node; + struct ri_pce_subtlv_domain *domain; + struct ri_pce_subtlv_neighbor *neighbor; + + /* PCE Address */ + if (ntohs(pce->pce_address.header.type) != 0) + length += RI_TLV_SIZE(&pce->pce_address.header); + + /* PCE Path Scope */ + if (ntohs(pce->pce_scope.header.type) != 0) + length += RI_TLV_SIZE(&pce->pce_scope.header); + + /* PCE Domain */ + for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, domain)) { + if (ntohs(domain->header.type) != 0) + length += RI_TLV_SIZE(&domain->header); + } + + /* PCE Neighbor */ + for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, neighbor)) { + if (ntohs(neighbor->header.type) != 0) + length += RI_TLV_SIZE(&neighbor->header); + } + + /* PCE Capabilities */ + if (ntohs(pce->pce_cap_flag.header.type) != 0) + length += RI_TLV_SIZE(&pce->pce_cap_flag.header); + + if (length != 0) { + pce->pce_header.header.type = htons(RI_TLV_PCE); + pce->pce_header.header.length = htons(length); + } else { + pce->pce_header.header.type = 0; + pce->pce_header.header.length = 0; + } + + return length; } -static void -set_pce_address (struct in_addr ipv4, struct ospf_pce_info *pce) +static void set_pce_address(struct in_addr ipv4, struct ospf_pce_info *pce) { - /* Enable PCE Info */ - pce->pce_header.header.type = htons (RI_TLV_PCE); - /* Set PCE Address */ - pce->pce_address.header.type = htons (RI_PCE_SUBTLV_ADDRESS); - pce->pce_address.header.length = htons (PCE_ADDRESS_LENGTH_IPV4); - pce->pce_address.address.type = htons (PCE_ADDRESS_TYPE_IPV4); - pce->pce_address.address.value = ipv4; + /* Enable PCE Info */ + pce->pce_header.header.type = htons(RI_TLV_PCE); + /* Set PCE Address */ + pce->pce_address.header.type = htons(RI_PCE_SUBTLV_ADDRESS); + pce->pce_address.header.length = htons(PCE_ADDRESS_LENGTH_IPV4); + pce->pce_address.address.type = htons(PCE_ADDRESS_TYPE_IPV4); + pce->pce_address.address.value = ipv4; - return; + return; } -static void -set_pce_path_scope (u_int32_t scope, struct ospf_pce_info *pce) +static void set_pce_path_scope(u_int32_t scope, struct ospf_pce_info *pce) { - /* Enable PCE Info */ - pce->pce_header.header.type = htons (RI_TLV_PCE); - /* Set PCE Scope */ - pce->pce_scope.header.type = htons (RI_PCE_SUBTLV_PATH_SCOPE); - pce->pce_scope.header.length = htons (RI_TLV_LENGTH); - pce->pce_scope.value = htonl (scope); + /* Enable PCE Info */ + pce->pce_header.header.type = htons(RI_TLV_PCE); + /* Set PCE Scope */ + pce->pce_scope.header.type = htons(RI_PCE_SUBTLV_PATH_SCOPE); + pce->pce_scope.header.length = htons(RI_TLV_LENGTH); + pce->pce_scope.value = htonl(scope); - return; + return; } -static void -set_pce_domain (u_int16_t type, u_int32_t domain, struct ospf_pce_info *pce) +static void set_pce_domain(u_int16_t type, u_int32_t domain, + struct ospf_pce_info *pce) { - struct ri_pce_subtlv_domain *new; + struct ri_pce_subtlv_domain *new; - /* Enable PCE Info */ - pce->pce_header.header.type = htons (RI_TLV_PCE); + /* Enable PCE Info */ + pce->pce_header.header.type = htons(RI_TLV_PCE); - /* Create new domain info */ - new = - XCALLOC (MTYPE_OSPF_PCE_PARAMS, - sizeof (struct ri_pce_subtlv_domain)); + /* Create new domain info */ + new = XCALLOC(MTYPE_OSPF_PCE_PARAMS, + sizeof(struct ri_pce_subtlv_domain)); - new->header.type = htons (RI_PCE_SUBTLV_DOMAIN); - new->header.length = htons (PCE_ADDRESS_LENGTH_IPV4); - new->type = htons (type); - new->value = htonl (domain); + new->header.type = htons(RI_PCE_SUBTLV_DOMAIN); + new->header.length = htons(PCE_ADDRESS_LENGTH_IPV4); + new->type = htons(type); + new->value = htonl(domain); - /* Add new domain to the list */ - listnode_add (pce->pce_domain, new); + /* Add new domain to the list */ + listnode_add(pce->pce_domain, new); - return; + return; } -static void -unset_pce_domain (u_int16_t type, u_int32_t domain, struct ospf_pce_info *pce) +static void unset_pce_domain(u_int16_t type, u_int32_t domain, + struct ospf_pce_info *pce) { - struct listnode *node; - struct ri_pce_subtlv_domain *old = NULL; - int found = 0; - - /* Search the corresponding node */ - for (ALL_LIST_ELEMENTS_RO (pce->pce_domain, node, old)) - { - if ((old->type == htons (type)) && (old->value == htonl (domain))) - { - found = 1; - break; - } - } - - /* if found remove it */ - if (found) - { - listnode_delete (pce->pce_domain, old); - - /* Avoid misjudgement in the next lookup. */ - if (listcount (pce->pce_domain) == 0) - pce->pce_domain->head = pce->pce_domain->tail = NULL; - - /* Finally free the old domain */ - XFREE (MTYPE_OSPF_PCE_PARAMS, old); - } + struct listnode *node; + struct ri_pce_subtlv_domain *old = NULL; + int found = 0; + + /* Search the corresponding node */ + for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, old)) { + if ((old->type == htons(type)) + && (old->value == htonl(domain))) { + found = 1; + break; + } + } + + /* if found remove it */ + if (found) { + listnode_delete(pce->pce_domain, old); + + /* Avoid misjudgement in the next lookup. */ + if (listcount(pce->pce_domain) == 0) + pce->pce_domain->head = pce->pce_domain->tail = NULL; + + /* Finally free the old domain */ + XFREE(MTYPE_OSPF_PCE_PARAMS, old); + } } -static void -set_pce_neighbor (u_int16_t type, u_int32_t domain, struct ospf_pce_info *pce) +static void set_pce_neighbor(u_int16_t type, u_int32_t domain, + struct ospf_pce_info *pce) { - struct ri_pce_subtlv_neighbor *new; + struct ri_pce_subtlv_neighbor *new; - /* Enable PCE Info */ - pce->pce_header.header.type = htons (RI_TLV_PCE); + /* Enable PCE Info */ + pce->pce_header.header.type = htons(RI_TLV_PCE); - /* Create new neighbor info */ - new = - XCALLOC (MTYPE_OSPF_PCE_PARAMS, - sizeof (struct ri_pce_subtlv_neighbor)); + /* Create new neighbor info */ + new = XCALLOC(MTYPE_OSPF_PCE_PARAMS, + sizeof(struct ri_pce_subtlv_neighbor)); - new->header.type = htons (RI_PCE_SUBTLV_NEIGHBOR); - new->header.length = htons (PCE_ADDRESS_LENGTH_IPV4); - new->type = htons (type); - new->value = htonl (domain); + new->header.type = htons(RI_PCE_SUBTLV_NEIGHBOR); + new->header.length = htons(PCE_ADDRESS_LENGTH_IPV4); + new->type = htons(type); + new->value = htonl(domain); - /* Add new domain to the list */ - listnode_add (pce->pce_neighbor, new); + /* Add new domain to the list */ + listnode_add(pce->pce_neighbor, new); - return; + return; } -static void -unset_pce_neighbor (u_int16_t type, u_int32_t domain, - struct ospf_pce_info *pce) +static void unset_pce_neighbor(u_int16_t type, u_int32_t domain, + struct ospf_pce_info *pce) { - struct listnode *node; - struct ri_pce_subtlv_neighbor *old = NULL; - int found = 0; - - /* Search the corresponding node */ - for (ALL_LIST_ELEMENTS_RO (pce->pce_neighbor, node, old)) - { - if ((old->type == htons (type)) && (old->value == htonl (domain))) - { - found = 1; - break; - } - } - - /* if found remove it */ - if (found) - { - listnode_delete (pce->pce_neighbor, old); - - /* Avoid misjudgement in the next lookup. */ - if (listcount (pce->pce_neighbor) == 0) - pce->pce_neighbor->head = pce->pce_neighbor->tail = NULL; - - /* Finally free the old domain */ - XFREE (MTYPE_OSPF_PCE_PARAMS, old); - } + struct listnode *node; + struct ri_pce_subtlv_neighbor *old = NULL; + int found = 0; + + /* Search the corresponding node */ + for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, old)) { + if ((old->type == htons(type)) + && (old->value == htonl(domain))) { + found = 1; + break; + } + } + + /* if found remove it */ + if (found) { + listnode_delete(pce->pce_neighbor, old); + + /* Avoid misjudgement in the next lookup. */ + if (listcount(pce->pce_neighbor) == 0) + pce->pce_neighbor->head = pce->pce_neighbor->tail = + NULL; + + /* Finally free the old domain */ + XFREE(MTYPE_OSPF_PCE_PARAMS, old); + } } -static void -set_pce_cap_flag (u_int32_t cap, struct ospf_pce_info *pce) +static void set_pce_cap_flag(u_int32_t cap, struct ospf_pce_info *pce) { - /* Enable PCE Info */ - pce->pce_header.header.type = htons (RI_TLV_PCE); - /* Set PCE Capabilities flag */ - pce->pce_cap_flag.header.type = htons (RI_PCE_SUBTLV_CAP_FLAG); - pce->pce_cap_flag.header.length = htons (RI_TLV_LENGTH); - pce->pce_cap_flag.value = htonl (cap); + /* Enable PCE Info */ + pce->pce_header.header.type = htons(RI_TLV_PCE); + /* Set PCE Capabilities flag */ + pce->pce_cap_flag.header.type = htons(RI_PCE_SUBTLV_CAP_FLAG); + pce->pce_cap_flag.header.length = htons(RI_TLV_LENGTH); + pce->pce_cap_flag.value = htonl(cap); - return; + return; } -static void -unset_param (struct ri_tlv_header *tlv) +static void unset_param(struct ri_tlv_header *tlv) { - tlv->type = 0; - /* Fill the Value to 0 */ - memset ((tlv + RI_TLV_HDR_SIZE), 0, RI_TLV_BODY_SIZE (tlv)); - tlv->length = 0; + tlv->type = 0; + /* Fill the Value to 0 */ + memset((tlv + RI_TLV_HDR_SIZE), 0, RI_TLV_BODY_SIZE(tlv)); + tlv->length = 0; - return; + return; } -static void -initialize_params (struct ospf_router_info *ori) +static void initialize_params(struct ospf_router_info *ori) { - u_int32_t cap; - struct ospf *top; - - /* - * Initialize default Router Information Capabilities. - */ - cap = 0; - cap = cap | RI_TE_SUPPORT; - - set_router_info_capabilities (&ori->router_cap, cap); - - /* If Area address is not null and exist, retrieve corresponding structure */ - top = ospf_lookup (); - zlog_info ("RI-> Initialize Router Info for %s scope within area %s", - OspfRI.scope == OSPF_OPAQUE_AREA_LSA ? "Area" : "AS", - inet_ntoa (OspfRI.area_id)); - - /* Try to get the Area context at this step. Do it latter if not available */ - if ((OspfRI.scope == OSPF_OPAQUE_AREA_LSA) && (OspfRI.area == NULL)) - OspfRI.area = ospf_area_lookup_by_area_id (top, OspfRI.area_id); - - /* - * Initialize default PCE Information values - */ - /* PCE address == OSPF Router ID */ - set_pce_address (top->router_id, &ori->pce_info); - - /* PCE scope */ - cap = 7; /* Set L, R and Rd bits to one = intra & inter-area path computation */ - set_pce_path_scope (cap, &ori->pce_info); - - /* PCE Capabilities */ - cap = - PCE_CAP_BIDIRECTIONAL | PCE_CAP_DIVERSE_PATH | PCE_CAP_OBJECTIVES | - PCE_CAP_ADDITIVE | PCE_CAP_MULTIPLE_REQ; - set_pce_cap_flag (cap, &ori->pce_info); - - /* Finally compute PCE header */ - set_pce_header (&ori->pce_info); - - return; + u_int32_t cap; + struct ospf *top; + + /* + * Initialize default Router Information Capabilities. + */ + cap = 0; + cap = cap | RI_TE_SUPPORT; + + set_router_info_capabilities(&ori->router_cap, cap); + + /* If Area address is not null and exist, retrieve corresponding + * structure */ + top = ospf_lookup(); + zlog_info("RI-> Initialize Router Info for %s scope within area %s", + OspfRI.scope == OSPF_OPAQUE_AREA_LSA ? "Area" : "AS", + inet_ntoa(OspfRI.area_id)); + + /* Try to get the Area context at this step. Do it latter if not + * available */ + if ((OspfRI.scope == OSPF_OPAQUE_AREA_LSA) && (OspfRI.area == NULL)) + OspfRI.area = ospf_area_lookup_by_area_id(top, OspfRI.area_id); + + /* + * Initialize default PCE Information values + */ + /* PCE address == OSPF Router ID */ + set_pce_address(top->router_id, &ori->pce_info); + + /* PCE scope */ + cap = 7; /* Set L, R and Rd bits to one = intra & inter-area path + computation */ + set_pce_path_scope(cap, &ori->pce_info); + + /* PCE Capabilities */ + cap = PCE_CAP_BIDIRECTIONAL | PCE_CAP_DIVERSE_PATH | PCE_CAP_OBJECTIVES + | PCE_CAP_ADDITIVE | PCE_CAP_MULTIPLE_REQ; + set_pce_cap_flag(cap, &ori->pce_info); + + /* Finally compute PCE header */ + set_pce_header(&ori->pce_info); + + return; } -static int -is_mandated_params_set (struct ospf_router_info ori) +static int is_mandated_params_set(struct ospf_router_info ori) { - int rc = 0; + int rc = 0; - if (ntohs (ori.router_cap.header.type) == 0) - goto out; + if (ntohs(ori.router_cap.header.type) == 0) + goto out; - if ((ntohs (ori.pce_info.pce_header.header.type) == RI_TLV_PCE) - && (ntohs (ori.pce_info.pce_address.header.type) == 0) - && (ntohs (ori.pce_info.pce_cap_flag.header.type) == 0)) - goto out; + if ((ntohs(ori.pce_info.pce_header.header.type) == RI_TLV_PCE) + && (ntohs(ori.pce_info.pce_address.header.type) == 0) + && (ntohs(ori.pce_info.pce_cap_flag.header.type) == 0)) + goto out; - rc = 1; + rc = 1; out: - return rc; + return rc; } /*------------------------------------------------------------------------* * Followings are callback functions against generic Opaque-LSAs handling. *------------------------------------------------------------------------*/ -static void -ospf_router_info_ism_change (struct ospf_interface *oi, int old_state) +static void ospf_router_info_ism_change(struct ospf_interface *oi, + int old_state) { - /* So far, nothing to do here. */ - return; - + /* So far, nothing to do here. */ + return; } -static void -ospf_router_info_nsm_change (struct ospf_neighbor *nbr, int old_state) +static void ospf_router_info_nsm_change(struct ospf_neighbor *nbr, + int old_state) { - /* So far, nothing to do here. */ - return; + /* So far, nothing to do here. */ + return; } /*------------------------------------------------------------------------* * Followings are OSPF protocol processing functions for ROUTER INFORMATION *------------------------------------------------------------------------*/ -static void -build_tlv_header (struct stream *s, struct ri_tlv_header *tlvh) +static void build_tlv_header(struct stream *s, struct ri_tlv_header *tlvh) { - stream_put (s, tlvh, sizeof (struct ri_tlv_header)); - return; + stream_put(s, tlvh, sizeof(struct ri_tlv_header)); + return; } -static void -build_tlv (struct stream *s, struct ri_tlv_header *tlvh) +static void build_tlv(struct stream *s, struct ri_tlv_header *tlvh) { - if (ntohs (tlvh->type) != 0) - { - build_tlv_header (s, tlvh); - stream_put (s, tlvh + 1, RI_TLV_BODY_SIZE (tlvh)); - } - return; + if (ntohs(tlvh->type) != 0) { + build_tlv_header(s, tlvh); + stream_put(s, tlvh + 1, RI_TLV_BODY_SIZE(tlvh)); + } + return; } -static void -ospf_router_info_lsa_body_set (struct stream *s) +static void ospf_router_info_lsa_body_set(struct stream *s) { - struct listnode *node; - struct ri_pce_subtlv_domain *domain; - struct ri_pce_subtlv_neighbor *neighbor; + struct listnode *node; + struct ri_pce_subtlv_domain *domain; + struct ri_pce_subtlv_neighbor *neighbor; - /* Build Router Information TLV */ - build_tlv (s, &OspfRI.router_cap.header); + /* Build Router Information TLV */ + build_tlv(s, &OspfRI.router_cap.header); - /* Add RI PCE TLV if it is set */ - /* Compute PCE Info header first */ - if ((set_pce_header (&OspfRI.pce_info)) != 0) - { + /* Add RI PCE TLV if it is set */ + /* Compute PCE Info header first */ + if ((set_pce_header(&OspfRI.pce_info)) != 0) { - /* Build PCE TLV */ - build_tlv_header (s, &OspfRI.pce_info.pce_header.header); + /* Build PCE TLV */ + build_tlv_header(s, &OspfRI.pce_info.pce_header.header); - /* Build PCE address sub-tlv */ - build_tlv (s, &OspfRI.pce_info.pce_address.header); + /* Build PCE address sub-tlv */ + build_tlv(s, &OspfRI.pce_info.pce_address.header); - /* Build PCE path scope sub-tlv */ - build_tlv (s, &OspfRI.pce_info.pce_scope.header); + /* Build PCE path scope sub-tlv */ + build_tlv(s, &OspfRI.pce_info.pce_scope.header); - /* Build PCE domain sub-tlv */ - for (ALL_LIST_ELEMENTS_RO (OspfRI.pce_info.pce_domain, node, domain)) - build_tlv (s, &domain->header); + /* Build PCE domain sub-tlv */ + for (ALL_LIST_ELEMENTS_RO(OspfRI.pce_info.pce_domain, node, + domain)) + build_tlv(s, &domain->header); - /* Build PCE neighbor sub-tlv */ - for (ALL_LIST_ELEMENTS_RO - (OspfRI.pce_info.pce_neighbor, node, neighbor)) - build_tlv (s, &neighbor->header); + /* Build PCE neighbor sub-tlv */ + for (ALL_LIST_ELEMENTS_RO(OspfRI.pce_info.pce_neighbor, node, + neighbor)) + build_tlv(s, &neighbor->header); - /* Build PCE cap flag sub-tlv */ - build_tlv (s, &OspfRI.pce_info.pce_cap_flag.header); - } + /* Build PCE cap flag sub-tlv */ + build_tlv(s, &OspfRI.pce_info.pce_cap_flag.header); + } - return; + return; } /* Create new opaque-LSA. */ -static struct ospf_lsa * -ospf_router_info_lsa_new () +static struct ospf_lsa *ospf_router_info_lsa_new() { - struct ospf *top; - struct stream *s; - struct lsa_header *lsah; - struct ospf_lsa *new = NULL; - u_char options, lsa_type; - struct in_addr lsa_id; - u_int32_t tmp; - u_int16_t length; - - /* Create a stream for LSA. */ - if ((s = stream_new (OSPF_MAX_LSA_SIZE)) == NULL) - { - zlog_warn ("ospf_router_info_lsa_new: stream_new() ?"); - goto out; - } - lsah = (struct lsa_header *) STREAM_DATA (s); - - options = OSPF_OPTION_E; /* Enable AS external as we flood RI with Opaque Type 11 */ - options |= OSPF_OPTION_O; /* Don't forget this :-) */ - - lsa_type = OspfRI.scope; - /* LSA ID == 0 for Router Information see RFC 4970 */ - tmp = SET_OPAQUE_LSID (OPAQUE_TYPE_ROUTER_INFORMATION_LSA, 0); - lsa_id.s_addr = htonl (tmp); - - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug - ("LSA[Type%d:%s]: Create an Opaque-LSA/ROUTER INFORMATION instance", - lsa_type, inet_ntoa (lsa_id)); - - top = ospf_lookup (); - - /* Set opaque-LSA header fields. */ - lsa_header_set (s, options, lsa_type, lsa_id, top->router_id); - - /* Set opaque-LSA body fields. */ - ospf_router_info_lsa_body_set (s); - - /* Set length. */ - length = stream_get_endp (s); - lsah->length = htons (length); - - /* Now, create an OSPF LSA instance. */ - if ((new = ospf_lsa_new ()) == NULL) - { - zlog_warn ("ospf_router_info_lsa_new: ospf_lsa_new() ?"); - stream_free (s); - goto out; - } - if ((new->data = ospf_lsa_data_new (length)) == NULL) - { - zlog_warn ("ospf_router_info_lsa_new: ospf_lsa_data_new() ?"); - ospf_lsa_unlock (&new); - new = NULL; - stream_free (s); - goto out; - } - - new->area = OspfRI.area; /* Area must be null if the Opaque type is AS scope, fulfill otherwise */ - - SET_FLAG (new->flags, OSPF_LSA_SELF); - memcpy (new->data, lsah, length); - stream_free (s); - -out:return new; + struct ospf *top; + struct stream *s; + struct lsa_header *lsah; + struct ospf_lsa *new = NULL; + u_char options, lsa_type; + struct in_addr lsa_id; + u_int32_t tmp; + u_int16_t length; + + /* Create a stream for LSA. */ + if ((s = stream_new(OSPF_MAX_LSA_SIZE)) == NULL) { + zlog_warn("ospf_router_info_lsa_new: stream_new() ?"); + goto out; + } + lsah = (struct lsa_header *)STREAM_DATA(s); + + options = OSPF_OPTION_E; /* Enable AS external as we flood RI with + Opaque Type 11 */ + options |= OSPF_OPTION_O; /* Don't forget this :-) */ + + lsa_type = OspfRI.scope; + /* LSA ID == 0 for Router Information see RFC 4970 */ + tmp = SET_OPAQUE_LSID(OPAQUE_TYPE_ROUTER_INFORMATION_LSA, 0); + lsa_id.s_addr = htonl(tmp); + + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug( + "LSA[Type%d:%s]: Create an Opaque-LSA/ROUTER INFORMATION instance", + lsa_type, inet_ntoa(lsa_id)); + + top = ospf_lookup(); + + /* Set opaque-LSA header fields. */ + lsa_header_set(s, options, lsa_type, lsa_id, top->router_id); + + /* Set opaque-LSA body fields. */ + ospf_router_info_lsa_body_set(s); + + /* Set length. */ + length = stream_get_endp(s); + lsah->length = htons(length); + + /* Now, create an OSPF LSA instance. */ + if ((new = ospf_lsa_new()) == NULL) { + zlog_warn("ospf_router_info_lsa_new: ospf_lsa_new() ?"); + stream_free(s); + goto out; + } + if ((new->data = ospf_lsa_data_new(length)) == NULL) { + zlog_warn("ospf_router_info_lsa_new: ospf_lsa_data_new() ?"); + ospf_lsa_unlock(&new); + new = NULL; + stream_free(s); + goto out; + } + + new->area = OspfRI.area; /* Area must be null if the Opaque type is AS + scope, fulfill otherwise */ + + SET_FLAG(new->flags, OSPF_LSA_SELF); + memcpy(new->data, lsah, length); + stream_free(s); + +out: + return new; } -static int -ospf_router_info_lsa_originate1 (void *arg) +static int ospf_router_info_lsa_originate1(void *arg) { - struct ospf_lsa *new; - struct ospf *top; - struct ospf_area *area; - int rc = -1; - - /* First check if the area is known if flooding scope is Area */ - if (OspfRI.scope == OSPF_OPAQUE_AREA_LSA) - { - area = (struct ospf_area *) arg; - if (area->area_id.s_addr != OspfRI.area_id.s_addr) - { - zlog_debug - ("RI -> This is not the Router Information Area. Stop processing"); - goto out; - } - OspfRI.area = area; - } - - /* Create new Opaque-LSA/ROUTER INFORMATION instance. */ - if ((new = ospf_router_info_lsa_new ()) == NULL) - { - zlog_warn - ("ospf_router_info_lsa_originate1: ospf_router_info_lsa_new() ?"); - goto out; - } - - /* Get ospf info */ - top = ospf_lookup (); - - /* Install this LSA into LSDB. */ - if (ospf_lsa_install (top, NULL /*oi */ , new) == NULL) - { - zlog_warn ("ospf_router_info_lsa_originate1: ospf_lsa_install() ?"); - ospf_lsa_unlock (&new); - goto out; - } - - /* Now this Router Info parameter entry has associated LSA. */ - SET_FLAG (OspfRI.flags, RIFLG_LSA_ENGAGED); - - /* Update new LSA origination count. */ - top->lsa_originate_count++; - - /* Flood new LSA through AS. */ - if (OspfRI.scope == OSPF_OPAQUE_AS_LSA) - ospf_flood_through_as (top, NULL /*nbr */ , new); - else - ospf_flood_through_area (OspfRI.area, NULL /*nbr */ , new); - - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - { - zlog_debug ("LSA[Type%d:%s]: Originate Opaque-LSA/ROUTER INFORMATION", - new->data->type, inet_ntoa (new->data->id)); - ospf_lsa_header_dump (new->data); - } - - rc = 0; -out:return rc; + struct ospf_lsa *new; + struct ospf *top; + struct ospf_area *area; + int rc = -1; + + /* First check if the area is known if flooding scope is Area */ + if (OspfRI.scope == OSPF_OPAQUE_AREA_LSA) { + area = (struct ospf_area *)arg; + if (area->area_id.s_addr != OspfRI.area_id.s_addr) { + zlog_debug( + "RI -> This is not the Router Information Area. Stop processing"); + goto out; + } + OspfRI.area = area; + } + + /* Create new Opaque-LSA/ROUTER INFORMATION instance. */ + if ((new = ospf_router_info_lsa_new()) == NULL) { + zlog_warn( + "ospf_router_info_lsa_originate1: ospf_router_info_lsa_new() ?"); + goto out; + } + + /* Get ospf info */ + top = ospf_lookup(); + + /* Install this LSA into LSDB. */ + if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) { + zlog_warn( + "ospf_router_info_lsa_originate1: ospf_lsa_install() ?"); + ospf_lsa_unlock(&new); + goto out; + } + + /* Now this Router Info parameter entry has associated LSA. */ + SET_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED); + + /* Update new LSA origination count. */ + top->lsa_originate_count++; + + /* Flood new LSA through AS. */ + if (OspfRI.scope == OSPF_OPAQUE_AS_LSA) + ospf_flood_through_as(top, NULL /*nbr */, new); + else + ospf_flood_through_area(OspfRI.area, NULL /*nbr */, new); + + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { + zlog_debug( + "LSA[Type%d:%s]: Originate Opaque-LSA/ROUTER INFORMATION", + new->data->type, inet_ntoa(new->data->id)); + ospf_lsa_header_dump(new->data); + } + + rc = 0; +out: + return rc; } -static int -ospf_router_info_lsa_originate (void *arg) +static int ospf_router_info_lsa_originate(void *arg) { - int rc = -1; - - if (OspfRI.status == disabled) - { - zlog_info - ("ospf_router_info_lsa_originate: ROUTER INFORMATION is disabled now."); - rc = 0; /* This is not an error case. */ - goto out; - } - - /* Check if Router Information LSA is already engaged */ - if (OspfRI.flags & RIFLG_LSA_ENGAGED) - { - if (OspfRI.flags & RIFLG_LSA_FORCED_REFRESH) - { - OspfRI.flags &= ~RIFLG_LSA_FORCED_REFRESH; - ospf_router_info_lsa_schedule (REFRESH_THIS_LSA); - } - } - else - { - if (!is_mandated_params_set (OspfRI)) - zlog_warn - ("ospf_router_info_lsa_originate: lacks mandated ROUTER INFORMATION parameters"); - - /* Ok, let's try to originate an LSA */ - if (ospf_router_info_lsa_originate1 (arg) != 0) - goto out; - } - - rc = 0; -out:return rc; + int rc = -1; + + if (OspfRI.status == disabled) { + zlog_info( + "ospf_router_info_lsa_originate: ROUTER INFORMATION is disabled now."); + rc = 0; /* This is not an error case. */ + goto out; + } + + /* Check if Router Information LSA is already engaged */ + if (OspfRI.flags & RIFLG_LSA_ENGAGED) { + if (OspfRI.flags & RIFLG_LSA_FORCED_REFRESH) { + OspfRI.flags &= ~RIFLG_LSA_FORCED_REFRESH; + ospf_router_info_lsa_schedule(REFRESH_THIS_LSA); + } + } else { + if (!is_mandated_params_set(OspfRI)) + zlog_warn( + "ospf_router_info_lsa_originate: lacks mandated ROUTER INFORMATION parameters"); + + /* Ok, let's try to originate an LSA */ + if (ospf_router_info_lsa_originate1(arg) != 0) + goto out; + } + + rc = 0; +out: + return rc; } -static struct ospf_lsa * -ospf_router_info_lsa_refresh (struct ospf_lsa *lsa) +static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa) { - struct ospf_lsa *new = NULL; - struct ospf *top; - - if (OspfRI.status == disabled) - { - /* - * This LSA must have flushed before due to ROUTER INFORMATION status change. - * It seems a slip among routers in the routing domain. - */ - zlog_info - ("ospf_router_info_lsa_refresh: ROUTER INFORMATION is disabled now."); - lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); /* Flush it anyway. */ - } - - /* Verify that the Router Information ID is supported */ - if (GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr)) != 0) - { - zlog_warn - ("ospf_router_info_lsa_refresh: Unsupported Router Information ID"); - goto out; - } - - /* If the lsa's age reached to MaxAge, start flushing procedure. */ - if (IS_LSA_MAXAGE (lsa)) - { - OspfRI.flags &= ~RIFLG_LSA_ENGAGED; - ospf_opaque_lsa_flush_schedule (lsa); - goto out; - } - - /* Create new Opaque-LSA/ROUTER INFORMATION instance. */ - if ((new = ospf_router_info_lsa_new ()) == NULL) - { - zlog_warn - ("ospf_router_info_lsa_refresh: ospf_router_info_lsa_new() ?"); - goto out; - } - new->data->ls_seqnum = lsa_seqnum_increment (lsa); - - /* Install this LSA into LSDB. */ - /* Given "lsa" will be freed in the next function. */ - top = ospf_lookup (); - if (ospf_lsa_install (top, NULL /*oi */ , new) == NULL) - { - zlog_warn ("ospf_router_info_lsa_refresh: ospf_lsa_install() ?"); - ospf_lsa_unlock (&new); - goto out; - } - - /* Flood updated LSA through AS or AREA depending of OspfRI.scope. */ - if (OspfRI.scope == OSPF_OPAQUE_AS_LSA) - ospf_flood_through_as (top, NULL /*nbr */ , new); - else - ospf_flood_through_area (OspfRI.area, NULL /*nbr */ , new); - - /* Debug logging. */ - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - { - zlog_debug ("LSA[Type%d:%s]: Refresh Opaque-LSA/ROUTER INFORMATION", - new->data->type, inet_ntoa (new->data->id)); - ospf_lsa_header_dump (new->data); - } - -out:return new; + struct ospf_lsa *new = NULL; + struct ospf *top; + + if (OspfRI.status == disabled) { + /* + * This LSA must have flushed before due to ROUTER INFORMATION + * status change. + * It seems a slip among routers in the routing domain. + */ + zlog_info( + "ospf_router_info_lsa_refresh: ROUTER INFORMATION is disabled now."); + lsa->data->ls_age = + htons(OSPF_LSA_MAXAGE); /* Flush it anyway. */ + } + + /* Verify that the Router Information ID is supported */ + if (GET_OPAQUE_ID(ntohl(lsa->data->id.s_addr)) != 0) { + zlog_warn( + "ospf_router_info_lsa_refresh: Unsupported Router Information ID"); + goto out; + } + + /* If the lsa's age reached to MaxAge, start flushing procedure. */ + if (IS_LSA_MAXAGE(lsa)) { + OspfRI.flags &= ~RIFLG_LSA_ENGAGED; + ospf_opaque_lsa_flush_schedule(lsa); + goto out; + } + + /* Create new Opaque-LSA/ROUTER INFORMATION instance. */ + if ((new = ospf_router_info_lsa_new()) == NULL) { + zlog_warn( + "ospf_router_info_lsa_refresh: ospf_router_info_lsa_new() ?"); + goto out; + } + new->data->ls_seqnum = lsa_seqnum_increment(lsa); + + /* Install this LSA into LSDB. */ + /* Given "lsa" will be freed in the next function. */ + top = ospf_lookup(); + if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) { + zlog_warn("ospf_router_info_lsa_refresh: ospf_lsa_install() ?"); + ospf_lsa_unlock(&new); + goto out; + } + + /* Flood updated LSA through AS or AREA depending of OspfRI.scope. */ + if (OspfRI.scope == OSPF_OPAQUE_AS_LSA) + ospf_flood_through_as(top, NULL /*nbr */, new); + else + ospf_flood_through_area(OspfRI.area, NULL /*nbr */, new); + + /* Debug logging. */ + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { + zlog_debug( + "LSA[Type%d:%s]: Refresh Opaque-LSA/ROUTER INFORMATION", + new->data->type, inet_ntoa(new->data->id)); + ospf_lsa_header_dump(new->data); + } + +out: + return new; } -static void -ospf_router_info_lsa_schedule (opcode_t opcode) +static void ospf_router_info_lsa_schedule(opcode_t opcode) { - struct ospf_lsa lsa; - struct lsa_header lsah; - struct ospf *top; - u_int32_t tmp; - - memset (&lsa, 0, sizeof (lsa)); - memset (&lsah, 0, sizeof (lsah)); - - zlog_debug ("RI-> LSA schedule %s%s%s", - opcode == REORIGINATE_THIS_LSA ? "Re-Originate" : "", - opcode == REFRESH_THIS_LSA ? "Refresh" : "", - opcode == FLUSH_THIS_LSA ? "Flush" : ""); - - top = ospf_lookup (); - if ((OspfRI.scope == OSPF_OPAQUE_AREA_LSA) && (OspfRI.area == NULL)) - { - zlog_warn - ("ospf_router_info_lsa_schedule(): Router Info is Area scope flooding but area is not set"); - OspfRI.area = ospf_area_lookup_by_area_id (top, OspfRI.area_id); - } - lsa.area = OspfRI.area; - lsa.data = &lsah; - lsah.type = OspfRI.scope; - - /* LSA ID is set to 0 for the Router Information. See RFC 4970 */ - tmp = SET_OPAQUE_LSID (OPAQUE_TYPE_ROUTER_INFORMATION_LSA, 0); - lsah.id.s_addr = htonl (tmp); - - switch (opcode) - { - case REORIGINATE_THIS_LSA: - if (OspfRI.scope == OSPF_OPAQUE_AREA_LSA) - ospf_opaque_lsa_reoriginate_schedule ((void *) OspfRI.area, - OSPF_OPAQUE_AREA_LSA, - OPAQUE_TYPE_ROUTER_INFORMATION_LSA); - else - ospf_opaque_lsa_reoriginate_schedule ((void *) top, - OSPF_OPAQUE_AS_LSA, - OPAQUE_TYPE_ROUTER_INFORMATION_LSA); - break; - case REFRESH_THIS_LSA: - ospf_opaque_lsa_refresh_schedule (&lsa); - break; - case FLUSH_THIS_LSA: - OspfRI.flags &= ~RIFLG_LSA_ENGAGED; - ospf_opaque_lsa_flush_schedule (&lsa); - break; - default: - zlog_warn ("ospf_router_info_lsa_schedule: Unknown opcode (%u)", - opcode); - break; - } - - return; + struct ospf_lsa lsa; + struct lsa_header lsah; + struct ospf *top; + u_int32_t tmp; + + memset(&lsa, 0, sizeof(lsa)); + memset(&lsah, 0, sizeof(lsah)); + + zlog_debug("RI-> LSA schedule %s%s%s", + opcode == REORIGINATE_THIS_LSA ? "Re-Originate" : "", + opcode == REFRESH_THIS_LSA ? "Refresh" : "", + opcode == FLUSH_THIS_LSA ? "Flush" : ""); + + top = ospf_lookup(); + if ((OspfRI.scope == OSPF_OPAQUE_AREA_LSA) && (OspfRI.area == NULL)) { + zlog_warn( + "ospf_router_info_lsa_schedule(): Router Info is Area scope flooding but area is not set"); + OspfRI.area = ospf_area_lookup_by_area_id(top, OspfRI.area_id); + } + lsa.area = OspfRI.area; + lsa.data = &lsah; + lsah.type = OspfRI.scope; + + /* LSA ID is set to 0 for the Router Information. See RFC 4970 */ + tmp = SET_OPAQUE_LSID(OPAQUE_TYPE_ROUTER_INFORMATION_LSA, 0); + lsah.id.s_addr = htonl(tmp); + + switch (opcode) { + case REORIGINATE_THIS_LSA: + if (OspfRI.scope == OSPF_OPAQUE_AREA_LSA) + ospf_opaque_lsa_reoriginate_schedule( + (void *)OspfRI.area, OSPF_OPAQUE_AREA_LSA, + OPAQUE_TYPE_ROUTER_INFORMATION_LSA); + else + ospf_opaque_lsa_reoriginate_schedule( + (void *)top, OSPF_OPAQUE_AS_LSA, + OPAQUE_TYPE_ROUTER_INFORMATION_LSA); + break; + case REFRESH_THIS_LSA: + ospf_opaque_lsa_refresh_schedule(&lsa); + break; + case FLUSH_THIS_LSA: + OspfRI.flags &= ~RIFLG_LSA_ENGAGED; + ospf_opaque_lsa_flush_schedule(&lsa); + break; + default: + zlog_warn("ospf_router_info_lsa_schedule: Unknown opcode (%u)", + opcode); + break; + } + + return; } /*------------------------------------------------------------------------* * Followings are vty session control functions. *------------------------------------------------------------------------*/ -static u_int16_t -show_vty_router_cap (struct vty *vty, struct ri_tlv_header *tlvh) +static u_int16_t show_vty_router_cap(struct vty *vty, + struct ri_tlv_header *tlvh) { - struct ri_tlv_router_cap *top = (struct ri_tlv_router_cap *) tlvh; + struct ri_tlv_router_cap *top = (struct ri_tlv_router_cap *)tlvh; - if (vty != NULL) - vty_out (vty, " Router Capabilities: 0x%x\n",ntohl(top->value)); - else - zlog_debug (" Router Capabilities: 0x%x", ntohl (top->value)); + if (vty != NULL) + vty_out(vty, " Router Capabilities: 0x%x\n", + ntohl(top->value)); + else + zlog_debug(" Router Capabilities: 0x%x", ntohl(top->value)); - return RI_TLV_SIZE (tlvh); + return RI_TLV_SIZE(tlvh); } -static u_int16_t -show_vty_pce_subtlv_address (struct vty *vty, struct ri_tlv_header *tlvh) +static u_int16_t show_vty_pce_subtlv_address(struct vty *vty, + struct ri_tlv_header *tlvh) { - struct ri_pce_subtlv_address *top = (struct ri_pce_subtlv_address *) tlvh; - - if (ntohs (top->address.type) == PCE_ADDRESS_TYPE_IPV4) - { - if (vty != NULL) - vty_out (vty, " PCE Address: %s\n",inet_ntoa(top->address.value)); - else - zlog_debug (" PCE Address: %s", inet_ntoa (top->address.value)); - } - else - { - /* TODO: Add support to IPv6 with inet_ntop() */ - if (vty != NULL) - vty_out (vty, " PCE Address: 0x%x\n", - ntohl(top->address.value.s_addr)); - else - zlog_debug (" PCE Address: 0x%x", - ntohl (top->address.value.s_addr)); - } - - return RI_TLV_SIZE (tlvh); + struct ri_pce_subtlv_address *top = + (struct ri_pce_subtlv_address *)tlvh; + + if (ntohs(top->address.type) == PCE_ADDRESS_TYPE_IPV4) { + if (vty != NULL) + vty_out(vty, " PCE Address: %s\n", + inet_ntoa(top->address.value)); + else + zlog_debug(" PCE Address: %s", + inet_ntoa(top->address.value)); + } else { + /* TODO: Add support to IPv6 with inet_ntop() */ + if (vty != NULL) + vty_out(vty, " PCE Address: 0x%x\n", + ntohl(top->address.value.s_addr)); + else + zlog_debug(" PCE Address: 0x%x", + ntohl(top->address.value.s_addr)); + } + + return RI_TLV_SIZE(tlvh); } -static u_int16_t -show_vty_pce_subtlv_path_scope (struct vty *vty, struct ri_tlv_header *tlvh) +static u_int16_t show_vty_pce_subtlv_path_scope(struct vty *vty, + struct ri_tlv_header *tlvh) { - struct ri_pce_subtlv_path_scope *top = - (struct ri_pce_subtlv_path_scope *) tlvh; + struct ri_pce_subtlv_path_scope *top = + (struct ri_pce_subtlv_path_scope *)tlvh; - if (vty != NULL) - vty_out (vty, " PCE Path Scope: 0x%x\n",ntohl(top->value)); - else - zlog_debug (" PCE Path Scope: 0x%x", ntohl (top->value)); + if (vty != NULL) + vty_out(vty, " PCE Path Scope: 0x%x\n", ntohl(top->value)); + else + zlog_debug(" PCE Path Scope: 0x%x", ntohl(top->value)); - return RI_TLV_SIZE (tlvh); + return RI_TLV_SIZE(tlvh); } -static u_int16_t -show_vty_pce_subtlv_domain (struct vty *vty, struct ri_tlv_header *tlvh) +static u_int16_t show_vty_pce_subtlv_domain(struct vty *vty, + struct ri_tlv_header *tlvh) { - struct ri_pce_subtlv_domain *top = (struct ri_pce_subtlv_domain *) tlvh; - struct in_addr tmp; - - if (ntohs (top->type) == PCE_DOMAIN_TYPE_AREA) - { - tmp.s_addr = top->value; - if (vty != NULL) - vty_out (vty, " PCE domain Area: %s\n",inet_ntoa(tmp)); - else - zlog_debug (" PCE domain Area: %s", inet_ntoa (tmp)); - } - else - { - if (vty != NULL) - vty_out (vty, " PCE domain AS: %d\n",ntohl(top->value)); - else - zlog_debug (" PCE domain AS: %d", ntohl (top->value)); - } - return RI_TLV_SIZE (tlvh); + struct ri_pce_subtlv_domain *top = (struct ri_pce_subtlv_domain *)tlvh; + struct in_addr tmp; + + if (ntohs(top->type) == PCE_DOMAIN_TYPE_AREA) { + tmp.s_addr = top->value; + if (vty != NULL) + vty_out(vty, " PCE domain Area: %s\n", inet_ntoa(tmp)); + else + zlog_debug(" PCE domain Area: %s", inet_ntoa(tmp)); + } else { + if (vty != NULL) + vty_out(vty, " PCE domain AS: %d\n", + ntohl(top->value)); + else + zlog_debug(" PCE domain AS: %d", ntohl(top->value)); + } + return RI_TLV_SIZE(tlvh); } -static u_int16_t -show_vty_pce_subtlv_neighbor (struct vty *vty, struct ri_tlv_header *tlvh) +static u_int16_t show_vty_pce_subtlv_neighbor(struct vty *vty, + struct ri_tlv_header *tlvh) { - struct ri_pce_subtlv_neighbor *top = (struct ri_pce_subtlv_neighbor *) tlvh; - struct in_addr tmp; - - if (ntohs (top->type) == PCE_DOMAIN_TYPE_AREA) - { - tmp.s_addr = top->value; - if (vty != NULL) - vty_out (vty, " PCE neighbor Area: %s\n",inet_ntoa(tmp)); - else - zlog_debug (" PCE neighbor Area: %s", inet_ntoa (tmp)); - } - else - { - if (vty != NULL) - vty_out (vty, " PCE neighbor AS: %d\n",ntohl(top->value)); - else - zlog_debug (" PCE neighbor AS: %d", ntohl (top->value)); - } - return RI_TLV_SIZE (tlvh); + struct ri_pce_subtlv_neighbor *top = + (struct ri_pce_subtlv_neighbor *)tlvh; + struct in_addr tmp; + + if (ntohs(top->type) == PCE_DOMAIN_TYPE_AREA) { + tmp.s_addr = top->value; + if (vty != NULL) + vty_out(vty, " PCE neighbor Area: %s\n", + inet_ntoa(tmp)); + else + zlog_debug(" PCE neighbor Area: %s", inet_ntoa(tmp)); + } else { + if (vty != NULL) + vty_out(vty, " PCE neighbor AS: %d\n", + ntohl(top->value)); + else + zlog_debug(" PCE neighbor AS: %d", + ntohl(top->value)); + } + return RI_TLV_SIZE(tlvh); } -static u_int16_t -show_vty_pce_subtlv_cap_flag (struct vty *vty, struct ri_tlv_header *tlvh) +static u_int16_t show_vty_pce_subtlv_cap_flag(struct vty *vty, + struct ri_tlv_header *tlvh) { - struct ri_pce_subtlv_cap_flag *top = (struct ri_pce_subtlv_cap_flag *) tlvh; + struct ri_pce_subtlv_cap_flag *top = + (struct ri_pce_subtlv_cap_flag *)tlvh; - if (vty != NULL) - vty_out (vty, " PCE Capabilities Flag: 0x%x\n",ntohl(top->value)); - else - zlog_debug (" PCE Capabilities Flag: 0x%x", ntohl (top->value)); + if (vty != NULL) + vty_out(vty, " PCE Capabilities Flag: 0x%x\n", + ntohl(top->value)); + else + zlog_debug(" PCE Capabilities Flag: 0x%x", + ntohl(top->value)); - return RI_TLV_SIZE (tlvh); + return RI_TLV_SIZE(tlvh); } -static u_int16_t -show_vty_unknown_tlv (struct vty *vty, struct ri_tlv_header *tlvh) +static u_int16_t show_vty_unknown_tlv(struct vty *vty, + struct ri_tlv_header *tlvh) { - if (vty != NULL) - vty_out (vty, " Unknown TLV: [type(0x%x), length(0x%x)]\n", - ntohs (tlvh->type), ntohs(tlvh->length)); - else - zlog_debug (" Unknown TLV: [type(0x%x), length(0x%x)]", - ntohs (tlvh->type), ntohs (tlvh->length)); - - return RI_TLV_SIZE (tlvh); + if (vty != NULL) + vty_out(vty, " Unknown TLV: [type(0x%x), length(0x%x)]\n", + ntohs(tlvh->type), ntohs(tlvh->length)); + else + zlog_debug(" Unknown TLV: [type(0x%x), length(0x%x)]", + ntohs(tlvh->type), ntohs(tlvh->length)); + + return RI_TLV_SIZE(tlvh); } -static u_int16_t -show_vty_pce_info (struct vty *vty, struct ri_tlv_header *ri, uint32_t total) +static u_int16_t show_vty_pce_info(struct vty *vty, struct ri_tlv_header *ri, + uint32_t total) { - struct ri_tlv_header *tlvh; - u_int16_t sum = 0; - - for (tlvh = ri; sum < total; tlvh = RI_TLV_HDR_NEXT (tlvh)) - { - switch (ntohs (tlvh->type)) - { - case RI_PCE_SUBTLV_ADDRESS: - sum += show_vty_pce_subtlv_address (vty, tlvh); - break; - case RI_PCE_SUBTLV_PATH_SCOPE: - sum += show_vty_pce_subtlv_path_scope (vty, tlvh); - break; - case RI_PCE_SUBTLV_DOMAIN: - sum += show_vty_pce_subtlv_domain (vty, tlvh); - break; - case RI_PCE_SUBTLV_NEIGHBOR: - sum += show_vty_pce_subtlv_neighbor (vty, tlvh); - break; - case RI_PCE_SUBTLV_CAP_FLAG: - sum += show_vty_pce_subtlv_cap_flag (vty, tlvh); - break; - default: - sum += show_vty_unknown_tlv (vty, tlvh); - break; - } - } - return sum; + struct ri_tlv_header *tlvh; + u_int16_t sum = 0; + + for (tlvh = ri; sum < total; tlvh = RI_TLV_HDR_NEXT(tlvh)) { + switch (ntohs(tlvh->type)) { + case RI_PCE_SUBTLV_ADDRESS: + sum += show_vty_pce_subtlv_address(vty, tlvh); + break; + case RI_PCE_SUBTLV_PATH_SCOPE: + sum += show_vty_pce_subtlv_path_scope(vty, tlvh); + break; + case RI_PCE_SUBTLV_DOMAIN: + sum += show_vty_pce_subtlv_domain(vty, tlvh); + break; + case RI_PCE_SUBTLV_NEIGHBOR: + sum += show_vty_pce_subtlv_neighbor(vty, tlvh); + break; + case RI_PCE_SUBTLV_CAP_FLAG: + sum += show_vty_pce_subtlv_cap_flag(vty, tlvh); + break; + default: + sum += show_vty_unknown_tlv(vty, tlvh); + break; + } + } + return sum; } -static void -ospf_router_info_show_info (struct vty *vty, struct ospf_lsa *lsa) +static void ospf_router_info_show_info(struct vty *vty, struct ospf_lsa *lsa) { - struct lsa_header *lsah = (struct lsa_header *) lsa->data; - struct ri_tlv_header *tlvh; - u_int16_t length = 0, sum = 0; - - /* Initialize TLV browsing */ - length = ntohs (lsah->length) - OSPF_LSA_HEADER_SIZE; - - for (tlvh = RI_TLV_HDR_TOP (lsah); sum < length; - tlvh = RI_TLV_HDR_NEXT (tlvh)) - { - switch (ntohs (tlvh->type)) - { - case RI_TLV_CAPABILITIES: - sum += show_vty_router_cap (vty, tlvh); - break; - case RI_TLV_PCE: - tlvh++; - sum += RI_TLV_HDR_SIZE; - sum += show_vty_pce_info (vty, tlvh, length - sum); - break; - default: - sum += show_vty_unknown_tlv (vty, tlvh); - break; - } - } - - return; + struct lsa_header *lsah = (struct lsa_header *)lsa->data; + struct ri_tlv_header *tlvh; + u_int16_t length = 0, sum = 0; + + /* Initialize TLV browsing */ + length = ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE; + + for (tlvh = RI_TLV_HDR_TOP(lsah); sum < length; + tlvh = RI_TLV_HDR_NEXT(tlvh)) { + switch (ntohs(tlvh->type)) { + case RI_TLV_CAPABILITIES: + sum += show_vty_router_cap(vty, tlvh); + break; + case RI_TLV_PCE: + tlvh++; + sum += RI_TLV_HDR_SIZE; + sum += show_vty_pce_info(vty, tlvh, length - sum); + break; + default: + sum += show_vty_unknown_tlv(vty, tlvh); + break; + } + } + + return; } -static void -ospf_router_info_config_write_router (struct vty *vty) +static void ospf_router_info_config_write_router(struct vty *vty) { - struct ospf_pce_info *pce = &OspfRI.pce_info; - struct listnode *node; - struct ri_pce_subtlv_domain *domain; - struct ri_pce_subtlv_neighbor *neighbor; - struct in_addr tmp; - - if (OspfRI.status == enabled) - { - if (OspfRI.scope == OSPF_OPAQUE_AS_LSA) - vty_out (vty, " router-info as\n"); - else - vty_out (vty, " router-info area %s\n",inet_ntoa(OspfRI.area_id)); - - if (pce->pce_address.header.type != 0) - vty_out (vty, " pce address %s\n", - inet_ntoa(pce->pce_address.address.value)); - - if (pce->pce_cap_flag.header.type != 0) - vty_out (vty, " pce flag 0x%x\n",ntohl(pce->pce_cap_flag.value)); - - for (ALL_LIST_ELEMENTS_RO (pce->pce_domain, node, domain)) - { - if (domain->header.type != 0) - { - if (domain->type == PCE_DOMAIN_TYPE_AREA) - { - tmp.s_addr = domain->value; - vty_out (vty, " pce domain area %s\n",inet_ntoa(tmp)); - } - else - { - vty_out (vty, " pce domain as %d\n",ntohl(domain->value)); - } - } - } - - for (ALL_LIST_ELEMENTS_RO (pce->pce_neighbor, node, neighbor)) - { - if (neighbor->header.type != 0) - { - if (neighbor->type == PCE_DOMAIN_TYPE_AREA) - { - tmp.s_addr = neighbor->value; - vty_out (vty, " pce neighbor area %s\n",inet_ntoa(tmp)); - } - else - { - vty_out (vty, " pce neighbor as %d\n", - ntohl(neighbor->value)); - } - } - } - - if (pce->pce_scope.header.type != 0) - vty_out (vty, " pce scope 0x%x\n", - ntohl(OspfRI.pce_info.pce_scope.value)); - } - return; + struct ospf_pce_info *pce = &OspfRI.pce_info; + struct listnode *node; + struct ri_pce_subtlv_domain *domain; + struct ri_pce_subtlv_neighbor *neighbor; + struct in_addr tmp; + + if (OspfRI.status == enabled) { + if (OspfRI.scope == OSPF_OPAQUE_AS_LSA) + vty_out(vty, " router-info as\n"); + else + vty_out(vty, " router-info area %s\n", + inet_ntoa(OspfRI.area_id)); + + if (pce->pce_address.header.type != 0) + vty_out(vty, " pce address %s\n", + inet_ntoa(pce->pce_address.address.value)); + + if (pce->pce_cap_flag.header.type != 0) + vty_out(vty, " pce flag 0x%x\n", + ntohl(pce->pce_cap_flag.value)); + + for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, domain)) { + if (domain->header.type != 0) { + if (domain->type == PCE_DOMAIN_TYPE_AREA) { + tmp.s_addr = domain->value; + vty_out(vty, " pce domain area %s\n", + inet_ntoa(tmp)); + } else { + vty_out(vty, " pce domain as %d\n", + ntohl(domain->value)); + } + } + } + + for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, neighbor)) { + if (neighbor->header.type != 0) { + if (neighbor->type == PCE_DOMAIN_TYPE_AREA) { + tmp.s_addr = neighbor->value; + vty_out(vty, " pce neighbor area %s\n", + inet_ntoa(tmp)); + } else { + vty_out(vty, " pce neighbor as %d\n", + ntohl(neighbor->value)); + } + } + } + + if (pce->pce_scope.header.type != 0) + vty_out(vty, " pce scope 0x%x\n", + ntohl(OspfRI.pce_info.pce_scope.value)); + } + return; } /*------------------------------------------------------------------------* @@ -1168,61 +1113,58 @@ DEFUN (router_info, "Enable the Router Information functionality with Area flooding scope\n" "OSPF area ID in IP format") { - int idx_ipv4 = 2; - char *area = (argc == 3) ? argv[idx_ipv4]->arg : NULL; - - u_int8_t scope; - - if (OspfRI.status == enabled) - return CMD_SUCCESS; - - /* Check and get Area value if present */ - if (area) - { - if (!inet_aton (area, &OspfRI.area_id)) - { - vty_out (vty, "%% specified Area ID %s is invalid\n", - area); - return CMD_WARNING_CONFIG_FAILED; - } - scope = OSPF_OPAQUE_AREA_LSA; - } - else - { - OspfRI.area_id.s_addr = 0; - scope = OSPF_OPAQUE_AS_LSA; - } - - /* First start to register Router Information callbacks */ - if ((ospf_router_info_register (scope)) != 0) - { - zlog_warn ("Enable to register Router Information callbacks. Abort!"); - return CMD_WARNING_CONFIG_FAILED; - } - - OspfRI.status = enabled; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("RI-> Router Information (%s flooding): OFF -> ON", - OspfRI.scope == OSPF_OPAQUE_AREA_LSA ? "Area" : "AS"); - - /* - * Following code is intended to handle two cases; - * - * 1) Router Information was disabled at startup time, but now become enabled. - * 2) Router Information was once enabled then disabled, and now enabled again. - */ - - initialize_params (&OspfRI); - - /* Refresh RI LSA if already engaged */ - if (OspfRI.flags & RIFLG_LSA_ENGAGED) - { - zlog_debug ("RI-> Initial origination following configuration"); - ospf_router_info_lsa_schedule (REORIGINATE_THIS_LSA); - } - return CMD_SUCCESS; - + int idx_ipv4 = 2; + char *area = (argc == 3) ? argv[idx_ipv4]->arg : NULL; + + u_int8_t scope; + + if (OspfRI.status == enabled) + return CMD_SUCCESS; + + /* Check and get Area value if present */ + if (area) { + if (!inet_aton(area, &OspfRI.area_id)) { + vty_out(vty, "%% specified Area ID %s is invalid\n", + area); + return CMD_WARNING_CONFIG_FAILED; + } + scope = OSPF_OPAQUE_AREA_LSA; + } else { + OspfRI.area_id.s_addr = 0; + scope = OSPF_OPAQUE_AS_LSA; + } + + /* First start to register Router Information callbacks */ + if ((ospf_router_info_register(scope)) != 0) { + zlog_warn( + "Enable to register Router Information callbacks. Abort!"); + return CMD_WARNING_CONFIG_FAILED; + } + + OspfRI.status = enabled; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("RI-> Router Information (%s flooding): OFF -> ON", + OspfRI.scope == OSPF_OPAQUE_AREA_LSA ? "Area" + : "AS"); + + /* + * Following code is intended to handle two cases; + * + * 1) Router Information was disabled at startup time, but now become + * enabled. + * 2) Router Information was once enabled then disabled, and now enabled + * again. + */ + + initialize_params(&OspfRI); + + /* Refresh RI LSA if already engaged */ + if (OspfRI.flags & RIFLG_LSA_ENGAGED) { + zlog_debug("RI-> Initial origination following configuration"); + ospf_router_info_lsa_schedule(REORIGINATE_THIS_LSA); + } + return CMD_SUCCESS; } @@ -1233,33 +1175,32 @@ DEFUN (no_router_info, "Disable the Router Information functionality\n") { - if (OspfRI.status == disabled) - return CMD_SUCCESS; + if (OspfRI.status == disabled) + return CMD_SUCCESS; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("RI-> Router Information: ON -> OFF"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("RI-> Router Information: ON -> OFF"); - if (OspfRI.flags & RIFLG_LSA_ENGAGED) - ospf_router_info_lsa_schedule (FLUSH_THIS_LSA); + if (OspfRI.flags & RIFLG_LSA_ENGAGED) + ospf_router_info_lsa_schedule(FLUSH_THIS_LSA); - /* Unregister the callbacks */ - ospf_router_info_unregister (); + /* Unregister the callbacks */ + ospf_router_info_unregister(); - OspfRI.status = disabled; + OspfRI.status = disabled; - return CMD_SUCCESS; + return CMD_SUCCESS; } -static int -ospf_ri_enabled (struct vty *vty) +static int ospf_ri_enabled(struct vty *vty) { - if (OspfRI.status == enabled) - return 1; + if (OspfRI.status == enabled) + return 1; - if (vty) - vty_out (vty, "%% OSPF RI is not turned on\n"); + if (vty) + vty_out(vty, "%% OSPF RI is not turned on\n"); - return 0; + return 0; } DEFUN (pce_address, @@ -1269,31 +1210,30 @@ DEFUN (pce_address, "Stable IP address of the PCE\n" "PCE address in IPv4 address format\n") { - int idx_ipv4 = 2; - struct in_addr value; - struct ospf_pce_info *pi = &OspfRI.pce_info; + int idx_ipv4 = 2; + struct in_addr value; + struct ospf_pce_info *pi = &OspfRI.pce_info; - if (!ospf_ri_enabled (vty)) - return CMD_WARNING_CONFIG_FAILED; + if (!ospf_ri_enabled(vty)) + return CMD_WARNING_CONFIG_FAILED; - if (!inet_aton (argv[idx_ipv4]->arg, &value)) - { - vty_out (vty, "Please specify PCE Address by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; - } + if (!inet_aton(argv[idx_ipv4]->arg, &value)) { + vty_out(vty, "Please specify PCE Address by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } - if (ntohs (pi->pce_address.header.type) == 0 - || ntohl (pi->pce_address.address.value.s_addr) != ntohl (value.s_addr)) - { + if (ntohs(pi->pce_address.header.type) == 0 + || ntohl(pi->pce_address.address.value.s_addr) + != ntohl(value.s_addr)) { - set_pce_address (value, pi); + set_pce_address(value, pi); - /* Refresh RI LSA if already engaged */ - if (OspfRI.flags & RIFLG_LSA_ENGAGED) - ospf_router_info_lsa_schedule (REFRESH_THIS_LSA); - } + /* Refresh RI LSA if already engaged */ + if (OspfRI.flags & RIFLG_LSA_ENGAGED) + ospf_router_info_lsa_schedule(REFRESH_THIS_LSA); + } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_pce_address, @@ -1305,13 +1245,13 @@ DEFUN (no_pce_address, "PCE address in IPv4 address format\n") { - unset_param (&OspfRI.pce_info.pce_address.header); + unset_param(&OspfRI.pce_info.pce_address.header); - /* Refresh RI LSA if already engaged */ - if ((OspfRI.status == enabled) && (OspfRI.flags & RIFLG_LSA_ENGAGED)) - ospf_router_info_lsa_schedule (REFRESH_THIS_LSA); + /* Refresh RI LSA if already engaged */ + if ((OspfRI.status == enabled) && (OspfRI.flags & RIFLG_LSA_ENGAGED)) + ospf_router_info_lsa_schedule(REFRESH_THIS_LSA); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (pce_path_scope, @@ -1321,29 +1261,29 @@ DEFUN (pce_path_scope, "Path scope visibilities of the PCE for path computation\n" "32-bit Hexadecimal value\n") { - int idx_bitpattern = 2; - uint32_t scope; - struct ospf_pce_info *pi = &OspfRI.pce_info; + int idx_bitpattern = 2; + uint32_t scope; + struct ospf_pce_info *pi = &OspfRI.pce_info; - if (!ospf_ri_enabled (vty)) - return CMD_WARNING_CONFIG_FAILED; + if (!ospf_ri_enabled(vty)) + return CMD_WARNING_CONFIG_FAILED; - if (sscanf (argv[idx_bitpattern]->arg, "0x%x", &scope) != 1) - { - vty_out (vty, "pce_path_scope: fscanf: %s\n",safe_strerror(errno)); - return CMD_WARNING_CONFIG_FAILED; - } + if (sscanf(argv[idx_bitpattern]->arg, "0x%x", &scope) != 1) { + vty_out(vty, "pce_path_scope: fscanf: %s\n", + safe_strerror(errno)); + return CMD_WARNING_CONFIG_FAILED; + } - if (ntohl (pi->pce_scope.header.type) == 0 || scope != pi->pce_scope.value) - { - set_pce_path_scope (scope, pi); + if (ntohl(pi->pce_scope.header.type) == 0 + || scope != pi->pce_scope.value) { + set_pce_path_scope(scope, pi); - /* Refresh RI LSA if already engaged */ - if (OspfRI.flags & RIFLG_LSA_ENGAGED) - ospf_router_info_lsa_schedule (REFRESH_THIS_LSA); - } + /* Refresh RI LSA if already engaged */ + if (OspfRI.flags & RIFLG_LSA_ENGAGED) + ospf_router_info_lsa_schedule(REFRESH_THIS_LSA); + } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_pce_path_scope, @@ -1355,13 +1295,13 @@ DEFUN (no_pce_path_scope, "32-bit Hexadecimal value\n") { - unset_param (&OspfRI.pce_info.pce_address.header); + unset_param(&OspfRI.pce_info.pce_address.header); - /* Refresh RI LSA if already engaged */ - if ((OspfRI.status == enabled) && (OspfRI.flags & RIFLG_LSA_ENGAGED)) - ospf_router_info_lsa_schedule (REFRESH_THIS_LSA); + /* Refresh RI LSA if already engaged */ + if ((OspfRI.status == enabled) && (OspfRI.flags & RIFLG_LSA_ENGAGED)) + ospf_router_info_lsa_schedule(REFRESH_THIS_LSA); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (pce_domain, @@ -1372,37 +1312,35 @@ DEFUN (pce_domain, "AS number where the PCE as visibilities for path computation\n" "AS number in decimal <0-65535>\n") { - int idx_number = 3; + int idx_number = 3; - uint32_t as; - struct ospf_pce_info *pce = &OspfRI.pce_info; - struct listnode *node; - struct ri_pce_subtlv_domain *domain; + uint32_t as; + struct ospf_pce_info *pce = &OspfRI.pce_info; + struct listnode *node; + struct ri_pce_subtlv_domain *domain; - if (!ospf_ri_enabled (vty)) - return CMD_WARNING_CONFIG_FAILED; + if (!ospf_ri_enabled(vty)) + return CMD_WARNING_CONFIG_FAILED; - if (sscanf (argv[idx_number]->arg, "%d", &as) != 1) - { - vty_out (vty, "pce_domain: fscanf: %s\n",safe_strerror(errno)); - return CMD_WARNING_CONFIG_FAILED; - } + if (sscanf(argv[idx_number]->arg, "%d", &as) != 1) { + vty_out(vty, "pce_domain: fscanf: %s\n", safe_strerror(errno)); + return CMD_WARNING_CONFIG_FAILED; + } - /* Check if the domain is not already in the domain list */ - for (ALL_LIST_ELEMENTS_RO (pce->pce_domain, node, domain)) - { - if (ntohl (domain->header.type) == 0 && as == domain->value) - return CMD_SUCCESS; - } + /* Check if the domain is not already in the domain list */ + for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, domain)) { + if (ntohl(domain->header.type) == 0 && as == domain->value) + return CMD_SUCCESS; + } - /* Create new domain if not found */ - set_pce_domain (PCE_DOMAIN_TYPE_AS, as, pce); + /* Create new domain if not found */ + set_pce_domain(PCE_DOMAIN_TYPE_AS, as, pce); - /* Refresh RI LSA if already engaged */ - if (OspfRI.flags & RIFLG_LSA_ENGAGED) - ospf_router_info_lsa_schedule (REFRESH_THIS_LSA); + /* Refresh RI LSA if already engaged */ + if (OspfRI.flags & RIFLG_LSA_ENGAGED) + ospf_router_info_lsa_schedule(REFRESH_THIS_LSA); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_pce_domain, @@ -1414,25 +1352,25 @@ DEFUN (no_pce_domain, "AS number where the PCE as visibilities for path computation\n" "AS number in decimal <0-65535>\n") { - int idx_number = 4; + int idx_number = 4; - uint32_t as; - struct ospf_pce_info *pce = &OspfRI.pce_info; + uint32_t as; + struct ospf_pce_info *pce = &OspfRI.pce_info; - if (sscanf (argv[idx_number]->arg, "%d", &as) != 1) - { - vty_out (vty, "no_pce_domain: fscanf: %s\n",safe_strerror(errno)); - return CMD_WARNING_CONFIG_FAILED; - } + if (sscanf(argv[idx_number]->arg, "%d", &as) != 1) { + vty_out(vty, "no_pce_domain: fscanf: %s\n", + safe_strerror(errno)); + return CMD_WARNING_CONFIG_FAILED; + } - /* Unset corresponding PCE domain */ - unset_pce_domain (PCE_DOMAIN_TYPE_AS, as, pce); + /* Unset corresponding PCE domain */ + unset_pce_domain(PCE_DOMAIN_TYPE_AS, as, pce); - /* Refresh RI LSA if already engaged */ - if ((OspfRI.status == enabled) && (OspfRI.flags & RIFLG_LSA_ENGAGED)) - ospf_router_info_lsa_schedule (REFRESH_THIS_LSA); + /* Refresh RI LSA if already engaged */ + if ((OspfRI.status == enabled) && (OspfRI.flags & RIFLG_LSA_ENGAGED)) + ospf_router_info_lsa_schedule(REFRESH_THIS_LSA); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (pce_neigbhor, @@ -1443,37 +1381,36 @@ DEFUN (pce_neigbhor, "AS number of PCE neighbors\n" "AS number in decimal <0-65535>\n") { - int idx_number = 3; + int idx_number = 3; - uint32_t as; - struct ospf_pce_info *pce = &OspfRI.pce_info; - struct listnode *node; - struct ri_pce_subtlv_neighbor *neighbor; + uint32_t as; + struct ospf_pce_info *pce = &OspfRI.pce_info; + struct listnode *node; + struct ri_pce_subtlv_neighbor *neighbor; - if (!ospf_ri_enabled (vty)) - return CMD_WARNING_CONFIG_FAILED; + if (!ospf_ri_enabled(vty)) + return CMD_WARNING_CONFIG_FAILED; - if (sscanf (argv[idx_number]->arg, "%d", &as) != 1) - { - vty_out (vty, "pce_neighbor: fscanf: %s\n",safe_strerror(errno)); - return CMD_WARNING_CONFIG_FAILED; - } + if (sscanf(argv[idx_number]->arg, "%d", &as) != 1) { + vty_out(vty, "pce_neighbor: fscanf: %s\n", + safe_strerror(errno)); + return CMD_WARNING_CONFIG_FAILED; + } - /* Check if the domain is not already in the domain list */ - for (ALL_LIST_ELEMENTS_RO (pce->pce_neighbor, node, neighbor)) - { - if (ntohl (neighbor->header.type) == 0 && as == neighbor->value) - return CMD_SUCCESS; - } + /* Check if the domain is not already in the domain list */ + for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, neighbor)) { + if (ntohl(neighbor->header.type) == 0 && as == neighbor->value) + return CMD_SUCCESS; + } - /* Create new domain if not found */ - set_pce_neighbor (PCE_DOMAIN_TYPE_AS, as, pce); + /* Create new domain if not found */ + set_pce_neighbor(PCE_DOMAIN_TYPE_AS, as, pce); - /* Refresh RI LSA if already engaged */ - if (OspfRI.flags & RIFLG_LSA_ENGAGED) - ospf_router_info_lsa_schedule (REFRESH_THIS_LSA); + /* Refresh RI LSA if already engaged */ + if (OspfRI.flags & RIFLG_LSA_ENGAGED) + ospf_router_info_lsa_schedule(REFRESH_THIS_LSA); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_pce_neighbor, @@ -1485,25 +1422,25 @@ DEFUN (no_pce_neighbor, "AS number of PCE neighbor\n" "AS number in decimal <0-65535>\n") { - int idx_number = 4; + int idx_number = 4; - uint32_t as; - struct ospf_pce_info *pce = &OspfRI.pce_info; + uint32_t as; + struct ospf_pce_info *pce = &OspfRI.pce_info; - if (sscanf (argv[idx_number]->arg, "%d", &as) != 1) - { - vty_out (vty, "no_pce_neighbor: fscanf: %s\n",safe_strerror(errno)); - return CMD_WARNING_CONFIG_FAILED; - } + if (sscanf(argv[idx_number]->arg, "%d", &as) != 1) { + vty_out(vty, "no_pce_neighbor: fscanf: %s\n", + safe_strerror(errno)); + return CMD_WARNING_CONFIG_FAILED; + } - /* Unset corresponding PCE domain */ - unset_pce_neighbor (PCE_DOMAIN_TYPE_AS, as, pce); + /* Unset corresponding PCE domain */ + unset_pce_neighbor(PCE_DOMAIN_TYPE_AS, as, pce); - /* Refresh RI LSA if already engaged */ - if ((OspfRI.status == enabled) && (OspfRI.flags & RIFLG_LSA_ENGAGED)) - ospf_router_info_lsa_schedule (REFRESH_THIS_LSA); + /* Refresh RI LSA if already engaged */ + if ((OspfRI.status == enabled) && (OspfRI.flags & RIFLG_LSA_ENGAGED)) + ospf_router_info_lsa_schedule(REFRESH_THIS_LSA); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (pce_cap_flag, @@ -1513,31 +1450,30 @@ DEFUN (pce_cap_flag, "Capabilities of the PCE for path computation\n" "32-bit Hexadecimal value\n") { - int idx_bitpattern = 2; + int idx_bitpattern = 2; - uint32_t cap; - struct ospf_pce_info *pce = &OspfRI.pce_info; + uint32_t cap; + struct ospf_pce_info *pce = &OspfRI.pce_info; - if (!ospf_ri_enabled (vty)) - return CMD_WARNING_CONFIG_FAILED; + if (!ospf_ri_enabled(vty)) + return CMD_WARNING_CONFIG_FAILED; - if (sscanf (argv[idx_bitpattern]->arg, "0x%x", &cap) != 1) - { - vty_out (vty, "pce_cap_flag: fscanf: %s\n",safe_strerror(errno)); - return CMD_WARNING_CONFIG_FAILED; - } + if (sscanf(argv[idx_bitpattern]->arg, "0x%x", &cap) != 1) { + vty_out(vty, "pce_cap_flag: fscanf: %s\n", + safe_strerror(errno)); + return CMD_WARNING_CONFIG_FAILED; + } - if (ntohl (pce->pce_cap_flag.header.type) == 0 - || cap != pce->pce_cap_flag.value) - { - set_pce_cap_flag (cap, pce); + if (ntohl(pce->pce_cap_flag.header.type) == 0 + || cap != pce->pce_cap_flag.value) { + set_pce_cap_flag(cap, pce); - /* Refresh RI LSA if already engaged */ - if (OspfRI.flags & RIFLG_LSA_ENGAGED) - ospf_router_info_lsa_schedule (REFRESH_THIS_LSA); - } + /* Refresh RI LSA if already engaged */ + if (OspfRI.flags & RIFLG_LSA_ENGAGED) + ospf_router_info_lsa_schedule(REFRESH_THIS_LSA); + } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_pce_cap_flag, @@ -1548,13 +1484,13 @@ DEFUN (no_pce_cap_flag, "Disable PCE capabilities\n") { - unset_param (&OspfRI.pce_info.pce_cap_flag.header); + unset_param(&OspfRI.pce_info.pce_cap_flag.header); - /* Refresh RI LSA if already engaged */ - if ((OspfRI.status == enabled) && (OspfRI.flags & RIFLG_LSA_ENGAGED)) - ospf_router_info_lsa_schedule (REFRESH_THIS_LSA); + /* Refresh RI LSA if already engaged */ + if ((OspfRI.status == enabled) && (OspfRI.flags & RIFLG_LSA_ENGAGED)) + ospf_router_info_lsa_schedule(REFRESH_THIS_LSA); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (show_ip_ospf_router_info, @@ -1566,17 +1502,15 @@ DEFUN (show_ip_ospf_router_info, "Router Information\n") { - if (OspfRI.status == enabled) - { - vty_out (vty, "--- Router Information parameters ---\n"); - show_vty_router_cap (vty, &OspfRI.router_cap.header); - } - else - { - if (vty != NULL) - vty_out (vty, " Router Information is disabled on this router\n"); - } - return CMD_SUCCESS; + if (OspfRI.status == enabled) { + vty_out(vty, "--- Router Information parameters ---\n"); + show_vty_router_cap(vty, &OspfRI.router_cap.header); + } else { + if (vty != NULL) + vty_out(vty, + " Router Information is disabled on this router\n"); + } + return CMD_SUCCESS; } DEFUN (show_ip_opsf_router_info_pce, @@ -1589,64 +1523,64 @@ DEFUN (show_ip_opsf_router_info_pce, "PCE information\n") { - struct ospf_pce_info *pce = &OspfRI.pce_info; - struct listnode *node; - struct ri_pce_subtlv_domain *domain; - struct ri_pce_subtlv_neighbor *neighbor; + struct ospf_pce_info *pce = &OspfRI.pce_info; + struct listnode *node; + struct ri_pce_subtlv_domain *domain; + struct ri_pce_subtlv_neighbor *neighbor; - if (OspfRI.status == enabled) - { - vty_out (vty, "--- PCE parameters ---\n"); + if (OspfRI.status == enabled) { + vty_out(vty, "--- PCE parameters ---\n"); - if (pce->pce_address.header.type != 0) - show_vty_pce_subtlv_address (vty, &pce->pce_address.header); + if (pce->pce_address.header.type != 0) + show_vty_pce_subtlv_address(vty, + &pce->pce_address.header); - if (pce->pce_scope.header.type != 0) - show_vty_pce_subtlv_path_scope (vty, &pce->pce_scope.header); + if (pce->pce_scope.header.type != 0) + show_vty_pce_subtlv_path_scope(vty, + &pce->pce_scope.header); - for (ALL_LIST_ELEMENTS_RO (pce->pce_domain, node, domain)) - { - if (domain->header.type != 0) - show_vty_pce_subtlv_domain (vty, &domain->header); - } + for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, domain)) { + if (domain->header.type != 0) + show_vty_pce_subtlv_domain(vty, + &domain->header); + } - for (ALL_LIST_ELEMENTS_RO (pce->pce_neighbor, node, neighbor)) - { - if (neighbor->header.type != 0) - show_vty_pce_subtlv_neighbor (vty, &neighbor->header); - } + for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, neighbor)) { + if (neighbor->header.type != 0) + show_vty_pce_subtlv_neighbor(vty, + &neighbor->header); + } - if (pce->pce_cap_flag.header.type != 0) - show_vty_pce_subtlv_cap_flag (vty, &pce->pce_cap_flag.header); + if (pce->pce_cap_flag.header.type != 0) + show_vty_pce_subtlv_cap_flag(vty, + &pce->pce_cap_flag.header); - } - else - { - vty_out (vty," Router Information is disabled on this router\n"); - } + } else { + vty_out(vty, + " Router Information is disabled on this router\n"); + } - return CMD_SUCCESS; + return CMD_SUCCESS; } /* Install new CLI commands */ -static void -ospf_router_info_register_vty (void) +static void ospf_router_info_register_vty(void) { - install_element (VIEW_NODE, &show_ip_ospf_router_info_cmd); - install_element (VIEW_NODE, &show_ip_ospf_router_info_pce_cmd); - - install_element (OSPF_NODE, &router_info_area_cmd); - install_element (OSPF_NODE, &no_router_info_cmd); - install_element (OSPF_NODE, &pce_address_cmd); - install_element (OSPF_NODE, &no_pce_address_cmd); - install_element (OSPF_NODE, &pce_path_scope_cmd); - install_element (OSPF_NODE, &no_pce_path_scope_cmd); - install_element (OSPF_NODE, &pce_domain_cmd); - install_element (OSPF_NODE, &no_pce_domain_cmd); - install_element (OSPF_NODE, &pce_neighbor_cmd); - install_element (OSPF_NODE, &no_pce_neighbor_cmd); - install_element (OSPF_NODE, &pce_cap_flag_cmd); - install_element (OSPF_NODE, &no_pce_cap_flag_cmd); - - return; + install_element(VIEW_NODE, &show_ip_ospf_router_info_cmd); + install_element(VIEW_NODE, &show_ip_ospf_router_info_pce_cmd); + + install_element(OSPF_NODE, &router_info_area_cmd); + install_element(OSPF_NODE, &no_router_info_cmd); + install_element(OSPF_NODE, &pce_address_cmd); + install_element(OSPF_NODE, &no_pce_address_cmd); + install_element(OSPF_NODE, &pce_path_scope_cmd); + install_element(OSPF_NODE, &no_pce_path_scope_cmd); + install_element(OSPF_NODE, &pce_domain_cmd); + install_element(OSPF_NODE, &no_pce_domain_cmd); + install_element(OSPF_NODE, &pce_neighbor_cmd); + install_element(OSPF_NODE, &no_pce_neighbor_cmd); + install_element(OSPF_NODE, &pce_cap_flag_cmd); + install_element(OSPF_NODE, &no_pce_cap_flag_cmd); + + return; } diff --git a/ospfd/ospf_ri.h b/ospfd/ospf_ri.h index c9ed3c56a..50221b25c 100644 --- a/ospfd/ospf_ri.h +++ b/ospfd/ospf_ri.h @@ -58,7 +58,8 @@ * | LS checksum | Length | V * +--------+--------+--------+--------+ --- * | Type | Length | A - * +--------+--------+--------+--------+ | TLV part for Router Information; Values might be + * +--------+--------+--------+--------+ | TLV part for Router Information; + * Values might be * | Values ... | V structured as a set of sub-TLVs. * +--------+--------+--------+--------+ --- */ @@ -67,10 +68,9 @@ * Following section defines TLV (tag, length, value) structures, * used for Router Information. */ -struct ri_tlv_header -{ - u_int16_t type; /* RI_TLV_XXX (see below) */ - u_int16_t length; /* Value portion only, in byte */ +struct ri_tlv_header { + u_int16_t type; /* RI_TLV_XXX (see below) */ + u_int16_t length; /* Value portion only, in byte */ }; #define RI_TLV_HDR_SIZE (sizeof (struct ri_tlv_header)) @@ -90,10 +90,9 @@ struct ri_tlv_header /* RFC4970: Router Information Capabilities TLV */ /* Mandatory */ #define RI_TLV_CAPABILITIES 1 -struct ri_tlv_router_cap -{ - struct ri_tlv_header header; /* Value length is 4 bytes. */ - u_int32_t value; +struct ri_tlv_router_cap { + struct ri_tlv_header header; /* Value length is 4 bytes. */ + u_int32_t value; }; #define RI_GRACE_RESTART 0x01 @@ -109,35 +108,37 @@ struct ri_tlv_router_cap /* RI PCE TLV */ #define RI_TLV_PCE 6 -struct ri_tlv_pce -{ - struct ri_tlv_header header; -/* A set of PCE-sub-TLVs will follow. */ +struct ri_tlv_pce { + struct ri_tlv_header header; + /* A set of PCE-sub-TLVs will follow. */ }; /* PCE Address Sub-TLV */ /* Mandatory */ #define RI_PCE_SUBTLV_ADDRESS 1 -struct ri_pce_subtlv_address -{ - struct ri_tlv_header header; /* Type = 1; Length is 8 (IPv4) or 20 (IPv6) bytes. */ +struct ri_pce_subtlv_address { + struct ri_tlv_header + header; /* Type = 1; Length is 8 (IPv4) or 20 (IPv6) bytes. */ + /* $FRR indent$ */ + /* clang-format off */ #define PCE_ADDRESS_LENGTH_IPV4 8 #define PCE_ADDRESS_LENGTH_IPV6 20 - struct - { - u_int16_t type; /* Address type: 1 = IPv4, 2 = IPv6 */ + struct { + u_int16_t type; /* Address type: 1 = IPv4, 2 = IPv6 */ + /* $FRR indent$ */ + /* clang-format off */ #define PCE_ADDRESS_TYPE_IPV4 1 #define PCE_ADDRESS_TYPE_IPV6 2 - u_int16_t reserved; - struct in_addr value; /* PCE address */ - } address; + u_int16_t reserved; + struct in_addr value; /* PCE address */ + } address; }; /* PCE Path-Scope Sub-TLV */ /* Mandatory */ #define RI_PCE_SUBTLV_PATH_SCOPE 2 -struct ri_pce_subtlv_path_scope -{ - struct ri_tlv_header header; /* Type = 2; Length = 4 bytes. */ - u_int32_t value; /* L, R, Rd, S, Sd, Y, PrefL, PrefR, PrefS and PrefY bits see RFC5088 page 9 */ +struct ri_pce_subtlv_path_scope { + struct ri_tlv_header header; /* Type = 2; Length = 4 bytes. */ + u_int32_t value; /* L, R, Rd, S, Sd, Y, PrefL, PrefR, PrefS and PrefY + bits see RFC5088 page 9 */ }; /* PCE Domain Sub-TLV */ /* Optional */ @@ -146,22 +147,20 @@ struct ri_pce_subtlv_path_scope #define PCE_DOMAIN_TYPE_AREA 1 #define PCE_DOMAIN_TYPE_AS 2 -struct ri_pce_subtlv_domain -{ - struct ri_tlv_header header; /* Type = 3; Length = 8 bytes. */ - u_int16_t type; /* Domain type: 1 = OSPF Area ID, 2 = AS Number */ - u_int16_t reserved; - u_int32_t value; +struct ri_pce_subtlv_domain { + struct ri_tlv_header header; /* Type = 3; Length = 8 bytes. */ + u_int16_t type; /* Domain type: 1 = OSPF Area ID, 2 = AS Number */ + u_int16_t reserved; + u_int32_t value; }; /* PCE Neighbor Sub-TLV */ /* Mandatory if R or S bit is set */ #define RI_PCE_SUBTLV_NEIGHBOR 4 -struct ri_pce_subtlv_neighbor -{ - struct ri_tlv_header header; /* Type = 4; Length = 8 bytes. */ - u_int16_t type; /* Domain type: 1 = OSPF Area ID, 2 = AS Number */ - u_int16_t reserved; - u_int32_t value; +struct ri_pce_subtlv_neighbor { + struct ri_tlv_header header; /* Type = 4; Length = 8 bytes. */ + u_int16_t type; /* Domain type: 1 = OSPF Area ID, 2 = AS Number */ + u_int16_t reserved; + u_int32_t value; }; /* PCE Capabilities Flags Sub-TLV */ /* Optional */ @@ -177,14 +176,13 @@ struct ri_pce_subtlv_neighbor #define PCE_CAP_PRIORIZATION 0x0080 #define PCE_CAP_MULTIPLE_REQ 0x0100 -struct ri_pce_subtlv_cap_flag -{ - struct ri_tlv_header header; /* Type = 5; Length = n x 4 bytes. */ - u_int32_t value; +struct ri_pce_subtlv_cap_flag { + struct ri_tlv_header header; /* Type = 5; Length = n x 4 bytes. */ + u_int32_t value; }; /* Prototypes. */ -extern int ospf_router_info_init (void); -extern void ospf_router_info_term (void); +extern int ospf_router_info_init(void); +extern void ospf_router_info_term(void); #endif /* _ZEBRA_OSPF_ROUTER_INFO_H */ diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c index fcd5f18a7..9c4dca2e2 100644 --- a/ospfd/ospf_route.c +++ b/ospfd/ospf_route.c @@ -39,1012 +39,979 @@ #include "ospfd/ospf_zebra.h" #include "ospfd/ospf_dump.h" -struct ospf_route * -ospf_route_new () +struct ospf_route *ospf_route_new() { - struct ospf_route *new; + struct ospf_route *new; - new = XCALLOC (MTYPE_OSPF_ROUTE, sizeof (struct ospf_route)); + new = XCALLOC(MTYPE_OSPF_ROUTE, sizeof(struct ospf_route)); - new->paths = list_new (); - new->paths->del = (void (*) (void *))ospf_path_free; + new->paths = list_new(); + new->paths->del = (void (*)(void *))ospf_path_free; - return new; + return new; } -void -ospf_route_free (struct ospf_route *or) +void ospf_route_free(struct ospf_route * or) { - if (or->paths) - list_delete (or->paths); + if (or->paths) + list_delete(or->paths); - XFREE (MTYPE_OSPF_ROUTE, or); + XFREE(MTYPE_OSPF_ROUTE, or); } -struct ospf_path * -ospf_path_new () +struct ospf_path *ospf_path_new() { - struct ospf_path *new; + struct ospf_path *new; - new = XCALLOC (MTYPE_OSPF_PATH, sizeof (struct ospf_path)); + new = XCALLOC(MTYPE_OSPF_PATH, sizeof(struct ospf_path)); - return new; + return new; } -static struct ospf_path * -ospf_path_dup (struct ospf_path *path) +static struct ospf_path *ospf_path_dup(struct ospf_path *path) { - struct ospf_path *new; + struct ospf_path *new; - new = ospf_path_new (); - memcpy (new, path, sizeof (struct ospf_path)); + new = ospf_path_new(); + memcpy(new, path, sizeof(struct ospf_path)); - return new; + return new; } -void -ospf_path_free (struct ospf_path *op) +void ospf_path_free(struct ospf_path *op) { - XFREE (MTYPE_OSPF_PATH, op); + XFREE(MTYPE_OSPF_PATH, op); } -void -ospf_route_delete (struct route_table *rt) +void ospf_route_delete(struct route_table *rt) { - struct route_node *rn; - struct ospf_route *or; - - for (rn = route_top (rt); rn; rn = route_next (rn)) - if ((or = rn->info) != NULL) - { - if (or->type == OSPF_DESTINATION_NETWORK) - ospf_zebra_delete ((struct prefix_ipv4 *) &rn->p, - or); - else if (or->type == OSPF_DESTINATION_DISCARD) - ospf_zebra_delete_discard ((struct prefix_ipv4 *) &rn->p); - } + struct route_node *rn; + struct ospf_route * or ; + + for (rn = route_top(rt); rn; rn = route_next(rn)) + if ((or = rn->info) != NULL) { + if (or->type == OSPF_DESTINATION_NETWORK) + ospf_zebra_delete((struct prefix_ipv4 *)&rn->p, + or); + else if (or->type == OSPF_DESTINATION_DISCARD) + ospf_zebra_delete_discard( + (struct prefix_ipv4 *)&rn->p); + } } -void -ospf_route_table_free (struct route_table *rt) +void ospf_route_table_free(struct route_table *rt) { - struct route_node *rn; - struct ospf_route *or; + struct route_node *rn; + struct ospf_route * or ; - for (rn = route_top (rt); rn; rn = route_next (rn)) - if ((or = rn->info) != NULL) - { - ospf_route_free (or); + for (rn = route_top(rt); rn; rn = route_next(rn)) + if ((or = rn->info) != NULL) { + ospf_route_free(or); - rn->info = NULL; - route_unlock_node (rn); - } + rn->info = NULL; + route_unlock_node(rn); + } - route_table_finish (rt); + route_table_finish(rt); } /* If a prefix exists in the new routing table, then return 1, otherwise return 0. Since the ZEBRA-RIB does an implicit withdraw, it is not necessary to send a delete, an add later will act like an implicit delete. */ -static int -ospf_route_exist_new_table (struct route_table *rt, struct prefix_ipv4 *prefix) +static int ospf_route_exist_new_table(struct route_table *rt, + struct prefix_ipv4 *prefix) { - struct route_node *rn; + struct route_node *rn; - assert (rt); - assert (prefix); + assert(rt); + assert(prefix); - rn = route_node_lookup (rt, (struct prefix *) prefix); - if (!rn) { - return 0; - } - route_unlock_node (rn); + rn = route_node_lookup(rt, (struct prefix *)prefix); + if (!rn) { + return 0; + } + route_unlock_node(rn); - if (!rn->info) { - return 0; - } + if (!rn->info) { + return 0; + } - return 1; + return 1; } /* If a prefix and a nexthop match any route in the routing table, then return 1, otherwise return 0. */ -int -ospf_route_match_same (struct route_table *rt, struct prefix_ipv4 *prefix, - struct ospf_route *newor) +int ospf_route_match_same(struct route_table *rt, struct prefix_ipv4 *prefix, + struct ospf_route *newor) { - struct route_node *rn; - struct ospf_route *or; - struct ospf_path *op; - struct ospf_path *newop; - struct listnode *n1; - struct listnode *n2; - - if (! rt || ! prefix) - return 0; - - rn = route_node_lookup (rt, (struct prefix *) prefix); - if (! rn || ! rn->info) - return 0; - - route_unlock_node (rn); - - or = rn->info; - if (or->type == newor->type && or->cost == newor->cost) - { - if (or->type == OSPF_DESTINATION_NETWORK) - { - if (or->paths->count != newor->paths->count) - return 0; - - /* Check each path. */ - for (n1 = listhead (or->paths), n2 = listhead (newor->paths); - n1 && n2; n1 = listnextnode (n1), n2 = listnextnode (n2)) - { - op = listgetdata (n1); - newop = listgetdata (n2); - - if (! IPV4_ADDR_SAME (&op->nexthop, &newop->nexthop)) - return 0; - if (op->ifindex != newop->ifindex) - return 0; - } - return 1; - } - else if (prefix_same (&rn->p, (struct prefix *) prefix)) - return 1; - } - return 0; + struct route_node *rn; + struct ospf_route * or ; + struct ospf_path *op; + struct ospf_path *newop; + struct listnode *n1; + struct listnode *n2; + + if (!rt || !prefix) + return 0; + + rn = route_node_lookup(rt, (struct prefix *)prefix); + if (!rn || !rn->info) + return 0; + + route_unlock_node(rn); + + or = rn->info; + if (or->type == newor->type && or->cost == newor->cost) { + if (or->type == OSPF_DESTINATION_NETWORK) { + if (or->paths->count != newor->paths->count) + return 0; + + /* Check each path. */ + for (n1 = listhead(or->paths), + n2 = listhead(newor->paths); + n1 && n2; + n1 = listnextnode(n1), n2 = listnextnode(n2)) { + op = listgetdata(n1); + newop = listgetdata(n2); + + if (!IPV4_ADDR_SAME(&op->nexthop, + &newop->nexthop)) + return 0; + if (op->ifindex != newop->ifindex) + return 0; + } + return 1; + } else if (prefix_same(&rn->p, (struct prefix *)prefix)) + return 1; + } + return 0; } /* delete routes generated from AS-External routes if there is a inter/intra * area route */ -static void -ospf_route_delete_same_ext(struct route_table *external_routes, - struct route_table *routes) +static void ospf_route_delete_same_ext(struct route_table *external_routes, + struct route_table *routes) { - struct route_node *rn, - *ext_rn; - - if ( (external_routes == NULL) || (routes == NULL) ) - return; - - /* Remove deleted routes */ - for ( rn = route_top (routes); rn; rn = route_next (rn) ) - { - if (rn && rn->info) - { - struct prefix_ipv4 *p = (struct prefix_ipv4 *)(&rn->p); - if ( (ext_rn = route_node_lookup (external_routes, (struct prefix *)p)) ) - { - if (ext_rn->info) - { - ospf_zebra_delete (p, ext_rn->info); - ospf_route_free( ext_rn->info); - ext_rn->info = NULL; - } - route_unlock_node (ext_rn); - } - } - } + struct route_node *rn, *ext_rn; + + if ((external_routes == NULL) || (routes == NULL)) + return; + + /* Remove deleted routes */ + for (rn = route_top(routes); rn; rn = route_next(rn)) { + if (rn && rn->info) { + struct prefix_ipv4 *p = (struct prefix_ipv4 *)(&rn->p); + if ((ext_rn = route_node_lookup(external_routes, + (struct prefix *)p))) { + if (ext_rn->info) { + ospf_zebra_delete(p, ext_rn->info); + ospf_route_free(ext_rn->info); + ext_rn->info = NULL; + } + route_unlock_node(ext_rn); + } + } + } } /* rt: Old, cmprt: New */ -static void -ospf_route_delete_uniq (struct route_table *rt, struct route_table *cmprt) +static void ospf_route_delete_uniq(struct route_table *rt, + struct route_table *cmprt) { - struct route_node *rn; - struct ospf_route *or; - - for (rn = route_top (rt); rn; rn = route_next (rn)) - if ((or = rn->info) != NULL) - if (or->path_type == OSPF_PATH_INTRA_AREA || - or->path_type == OSPF_PATH_INTER_AREA) - { - if (or->type == OSPF_DESTINATION_NETWORK) - { - if (! ospf_route_exist_new_table (cmprt, - (struct prefix_ipv4 *) &rn->p)) - ospf_zebra_delete ((struct prefix_ipv4 *) &rn->p, or); - } - else if (or->type == OSPF_DESTINATION_DISCARD) - if (! ospf_route_exist_new_table (cmprt, - (struct prefix_ipv4 *) &rn->p)) - ospf_zebra_delete_discard ((struct prefix_ipv4 *) &rn->p); - } + struct route_node *rn; + struct ospf_route * or ; + + for (rn = route_top(rt); rn; rn = route_next(rn)) + if ((or = rn->info) != NULL) + if (or->path_type == OSPF_PATH_INTRA_AREA || + or->path_type == OSPF_PATH_INTER_AREA) { + if (or->type == OSPF_DESTINATION_NETWORK) { + if (!ospf_route_exist_new_table( + cmprt, + (struct prefix_ipv4 *)&rn + ->p)) + ospf_zebra_delete( + (struct prefix_ipv4 + *)&rn->p, + or); + } else if (or->type == OSPF_DESTINATION_DISCARD) + if (!ospf_route_exist_new_table( + cmprt, + (struct prefix_ipv4 *)&rn + ->p)) + ospf_zebra_delete_discard( + (struct prefix_ipv4 + *)&rn->p); + } } /* Install routes to table. */ -void -ospf_route_install (struct ospf *ospf, struct route_table *rt) +void ospf_route_install(struct ospf *ospf, struct route_table *rt) { - struct route_node *rn; - struct ospf_route *or; - - /* rt contains new routing table, new_table contains an old one. - updating pointers */ - if (ospf->old_table) - ospf_route_table_free (ospf->old_table); - - ospf->old_table = ospf->new_table; - ospf->new_table = rt; - - /* Delete old routes. */ - if (ospf->old_table) - ospf_route_delete_uniq (ospf->old_table, rt); - if (ospf->old_external_route) - ospf_route_delete_same_ext (ospf->old_external_route, rt); - - /* Install new routes. */ - for (rn = route_top (rt); rn; rn = route_next (rn)) - if ((or = rn->info) != NULL) - { - if (or->type == OSPF_DESTINATION_NETWORK) - { - if (! ospf_route_match_same (ospf->old_table, - (struct prefix_ipv4 *)&rn->p, or)) - ospf_zebra_add ((struct prefix_ipv4 *) &rn->p, or); - } - else if (or->type == OSPF_DESTINATION_DISCARD) - if (! ospf_route_match_same (ospf->old_table, - (struct prefix_ipv4 *) &rn->p, or)) - ospf_zebra_add_discard ((struct prefix_ipv4 *) &rn->p); - } + struct route_node *rn; + struct ospf_route * or ; + + /* rt contains new routing table, new_table contains an old one. + updating pointers */ + if (ospf->old_table) + ospf_route_table_free(ospf->old_table); + + ospf->old_table = ospf->new_table; + ospf->new_table = rt; + + /* Delete old routes. */ + if (ospf->old_table) + ospf_route_delete_uniq(ospf->old_table, rt); + if (ospf->old_external_route) + ospf_route_delete_same_ext(ospf->old_external_route, rt); + + /* Install new routes. */ + for (rn = route_top(rt); rn; rn = route_next(rn)) + if ((or = rn->info) != NULL) { + if (or->type == OSPF_DESTINATION_NETWORK) { + if (!ospf_route_match_same( + ospf->old_table, + (struct prefix_ipv4 *)&rn->p, or)) + ospf_zebra_add( + (struct prefix_ipv4 *)&rn->p, + or); + } else if (or->type == OSPF_DESTINATION_DISCARD) + if (!ospf_route_match_same( + ospf->old_table, + (struct prefix_ipv4 *)&rn->p, or)) + ospf_zebra_add_discard( + (struct prefix_ipv4 *)&rn->p); + } } /* RFC2328 16.1. (4). For "router". */ -void -ospf_intra_add_router (struct route_table *rt, struct vertex *v, - struct ospf_area *area) +void ospf_intra_add_router(struct route_table *rt, struct vertex *v, + struct ospf_area *area) { - struct route_node *rn; - struct ospf_route *or; - struct prefix_ipv4 p; - struct router_lsa *lsa; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_intra_add_router: Start"); - - lsa = (struct router_lsa *) v->lsa; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_intra_add_router: LS ID: %s", - inet_ntoa (lsa->header.id)); - - if (!OSPF_IS_AREA_BACKBONE(area)) - ospf_vl_up_check (area, lsa->header.id, v); - - if (!CHECK_FLAG (lsa->flags, ROUTER_LSA_SHORTCUT)) - area->shortcut_capability = 0; - - /* If the newly added vertex is an area border router or AS boundary - router, a routing table entry is added whose destination type is - "router". */ - if (! IS_ROUTER_LSA_BORDER (lsa) && ! IS_ROUTER_LSA_EXTERNAL (lsa)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_intra_add_router: " - "this router is neither ASBR nor ABR, skipping it"); - return; - } - - /* Update ABR and ASBR count in this area. */ - if (IS_ROUTER_LSA_BORDER (lsa)) - area->abr_count++; - if (IS_ROUTER_LSA_EXTERNAL (lsa)) - area->asbr_count++; - - /* The Options field found in the associated router-LSA is copied - into the routing table entry's Optional capabilities field. Call - the newly added vertex Router X. */ - or = ospf_route_new (); - - or->id = v->id; - or->u.std.area_id = area->area_id; - or->u.std.external_routing = area->external_routing; - or->path_type = OSPF_PATH_INTRA_AREA; - or->cost = v->distance; - or->type = OSPF_DESTINATION_ROUTER; - or->u.std.origin = (struct lsa_header *) lsa; - or->u.std.options = lsa->header.options; - or->u.std.flags = lsa->flags; - - /* If Router X is the endpoint of one of the calculating router's - virtual links, and the virtual link uses Area A as Transit area: - the virtual link is declared up, the IP address of the virtual - interface is set to the IP address of the outgoing interface - calculated above for Router X, and the virtual neighbor's IP - address is set to Router X's interface address (contained in - Router X's router-LSA) that points back to the root of the - shortest- path tree; equivalently, this is the interface that - points back to Router X's parent vertex on the shortest-path tree - (similar to the calculation in Section 16.1.1). */ - - p.family = AF_INET; - p.prefix = v->id; - p.prefixlen = IPV4_MAX_BITLEN; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_intra_add_router: talking about %s/%d", - inet_ntoa (p.prefix), p.prefixlen); - - rn = route_node_get (rt, (struct prefix *) &p); - - /* Note that we keep all routes to ABRs and ASBRs, not only the best */ - if (rn->info == NULL) - rn->info = list_new (); - else - route_unlock_node (rn); - - ospf_route_copy_nexthops_from_vertex (or, v); - - listnode_add (rn->info, or); - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_intra_add_router: Stop"); + struct route_node *rn; + struct ospf_route * or ; + struct prefix_ipv4 p; + struct router_lsa *lsa; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_intra_add_router: Start"); + + lsa = (struct router_lsa *)v->lsa; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_intra_add_router: LS ID: %s", + inet_ntoa(lsa->header.id)); + + if (!OSPF_IS_AREA_BACKBONE(area)) + ospf_vl_up_check(area, lsa->header.id, v); + + if (!CHECK_FLAG(lsa->flags, ROUTER_LSA_SHORTCUT)) + area->shortcut_capability = 0; + + /* If the newly added vertex is an area border router or AS boundary + router, a routing table entry is added whose destination type is + "router". */ + if (!IS_ROUTER_LSA_BORDER(lsa) && !IS_ROUTER_LSA_EXTERNAL(lsa)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_intra_add_router: " + "this router is neither ASBR nor ABR, skipping it"); + return; + } + + /* Update ABR and ASBR count in this area. */ + if (IS_ROUTER_LSA_BORDER(lsa)) + area->abr_count++; + if (IS_ROUTER_LSA_EXTERNAL(lsa)) + area->asbr_count++; + + /* The Options field found in the associated router-LSA is copied + into the routing table entry's Optional capabilities field. Call + the newly added vertex Router X. */ + or = ospf_route_new(); + + or->id = v->id; + or->u.std.area_id = area->area_id; + or->u.std.external_routing = area->external_routing; + or->path_type = OSPF_PATH_INTRA_AREA; + or->cost = v->distance; + or->type = OSPF_DESTINATION_ROUTER; + or->u.std.origin = (struct lsa_header *)lsa; + or->u.std.options = lsa->header.options; + or->u.std.flags = lsa->flags; + + /* If Router X is the endpoint of one of the calculating router's + virtual links, and the virtual link uses Area A as Transit area: + the virtual link is declared up, the IP address of the virtual + interface is set to the IP address of the outgoing interface + calculated above for Router X, and the virtual neighbor's IP + address is set to Router X's interface address (contained in + Router X's router-LSA) that points back to the root of the + shortest- path tree; equivalently, this is the interface that + points back to Router X's parent vertex on the shortest-path tree + (similar to the calculation in Section 16.1.1). */ + + p.family = AF_INET; + p.prefix = v->id; + p.prefixlen = IPV4_MAX_BITLEN; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_intra_add_router: talking about %s/%d", + inet_ntoa(p.prefix), p.prefixlen); + + rn = route_node_get(rt, (struct prefix *)&p); + + /* Note that we keep all routes to ABRs and ASBRs, not only the best */ + if (rn->info == NULL) + rn->info = list_new(); + else + route_unlock_node(rn); + + ospf_route_copy_nexthops_from_vertex(or, v); + + listnode_add(rn->info, or); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_intra_add_router: Stop"); } /* RFC2328 16.1. (4). For transit network. */ -void -ospf_intra_add_transit (struct route_table *rt, struct vertex *v, - struct ospf_area *area) +void ospf_intra_add_transit(struct route_table *rt, struct vertex *v, + struct ospf_area *area) { - struct route_node *rn; - struct ospf_route *or; - struct prefix_ipv4 p; - struct network_lsa *lsa; - - lsa = (struct network_lsa*) v->lsa; - - /* If the newly added vertex is a transit network, the routing table - entry for the network is located. The entry's Destination ID is - the IP network number, which can be obtained by masking the - Vertex ID (Link State ID) with its associated subnet mask (found - in the body of the associated network-LSA). */ - p.family = AF_INET; - p.prefix = v->id; - p.prefixlen = ip_masklen (lsa->mask); - apply_mask_ipv4 (&p); - - rn = route_node_get (rt, (struct prefix *) &p); - - /* If the routing table entry already exists (i.e., there is already - an intra-area route to the destination installed in the routing - table), multiple vertices have mapped to the same IP network. - For example, this can occur when a new Designated Router is being - established. In this case, the current routing table entry - should be overwritten if and only if the newly found path is just - as short and the current routing table entry's Link State Origin - has a smaller Link State ID than the newly added vertex' LSA. */ - if (rn->info) - { - struct ospf_route *cur_or; - - route_unlock_node (rn); - cur_or = rn->info; - - if (v->distance > cur_or->cost || - IPV4_ADDR_CMP (&cur_or->u.std.origin->id, &lsa->header.id) > 0) - return; - - ospf_route_free (rn->info); - } - - or = ospf_route_new (); - - or->id = v->id; - or->u.std.area_id = area->area_id; - or->u.std.external_routing = area->external_routing; - or->path_type = OSPF_PATH_INTRA_AREA; - or->cost = v->distance; - or->type = OSPF_DESTINATION_NETWORK; - or->u.std.origin = (struct lsa_header *) lsa; - - ospf_route_copy_nexthops_from_vertex (or, v); - - rn->info = or; + struct route_node *rn; + struct ospf_route * or ; + struct prefix_ipv4 p; + struct network_lsa *lsa; + + lsa = (struct network_lsa *)v->lsa; + + /* If the newly added vertex is a transit network, the routing table + entry for the network is located. The entry's Destination ID is + the IP network number, which can be obtained by masking the + Vertex ID (Link State ID) with its associated subnet mask (found + in the body of the associated network-LSA). */ + p.family = AF_INET; + p.prefix = v->id; + p.prefixlen = ip_masklen(lsa->mask); + apply_mask_ipv4(&p); + + rn = route_node_get(rt, (struct prefix *)&p); + + /* If the routing table entry already exists (i.e., there is already + an intra-area route to the destination installed in the routing + table), multiple vertices have mapped to the same IP network. + For example, this can occur when a new Designated Router is being + established. In this case, the current routing table entry + should be overwritten if and only if the newly found path is just + as short and the current routing table entry's Link State Origin + has a smaller Link State ID than the newly added vertex' LSA. */ + if (rn->info) { + struct ospf_route *cur_or; + + route_unlock_node(rn); + cur_or = rn->info; + + if (v->distance > cur_or->cost + || IPV4_ADDR_CMP(&cur_or->u.std.origin->id, &lsa->header.id) + > 0) + return; + + ospf_route_free(rn->info); + } + + or = ospf_route_new(); + + or->id = v->id; + or->u.std.area_id = area->area_id; + or->u.std.external_routing = area->external_routing; + or->path_type = OSPF_PATH_INTRA_AREA; + or->cost = v->distance; + or->type = OSPF_DESTINATION_NETWORK; + or->u.std.origin = (struct lsa_header *)lsa; + + ospf_route_copy_nexthops_from_vertex(or, v); + + rn->info = or ; } /* RFC2328 16.1. second stage. */ -void -ospf_intra_add_stub (struct route_table *rt, struct router_lsa_link *link, - struct vertex *v, struct ospf_area *area, - int parent_is_root, int lsa_pos) +void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link, + struct vertex *v, struct ospf_area *area, + int parent_is_root, int lsa_pos) { - u_int32_t cost; - struct route_node *rn; - struct ospf_route *or; - struct prefix_ipv4 p; - struct router_lsa *lsa; - struct ospf_interface *oi; - struct ospf_path *path; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_intra_add_stub(): Start"); - - lsa = (struct router_lsa *) v->lsa; - - p.family = AF_INET; - p.prefix = link->link_id; - p.prefixlen = ip_masklen (link->link_data); - apply_mask_ipv4 (&p); - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_intra_add_stub(): processing route to %s/%d", - inet_ntoa (p.prefix), p.prefixlen); - - /* (1) Calculate the distance D of stub network from the root. D is - equal to the distance from the root to the router vertex - (calculated in stage 1), plus the stub network link's advertised - cost. */ - cost = v->distance + ntohs (link->m[0].metric); - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_intra_add_stub(): calculated cost is %d + %d = %d", - v->distance, ntohs(link->m[0].metric), cost); - - /* PtP links with /32 masks adds host routes to remote, directly - * connected hosts, see RFC 2328, 12.4.1.1, Option 1. - * Such routes can just be ignored for the sake of tidyness. - */ - if (parent_is_root && link->link_data.s_addr == 0xffffffff && - ospf_if_lookup_by_local_addr (area->ospf, NULL, link->link_id)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("%s: ignoring host route %s/32 to self.", - __func__, inet_ntoa (link->link_id)); - return; - } - - rn = route_node_get (rt, (struct prefix *) &p); - - /* Lookup current routing table. */ - if (rn->info) - { - struct ospf_route *cur_or; - - route_unlock_node (rn); - - cur_or = rn->info; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_intra_add_stub(): " - "another route to the same prefix found with cost %u", - cur_or->cost); - - /* Compare this distance to the current best cost to the stub - network. This is done by looking up the stub network's - current routing table entry. If the calculated distance D is - larger, go on to examine the next stub network link in the - LSA. */ - if (cost > cur_or->cost) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_intra_add_stub(): old route is better, exit"); - return; + u_int32_t cost; + struct route_node *rn; + struct ospf_route * or ; + struct prefix_ipv4 p; + struct router_lsa *lsa; + struct ospf_interface *oi; + struct ospf_path *path; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_intra_add_stub(): Start"); + + lsa = (struct router_lsa *)v->lsa; + + p.family = AF_INET; + p.prefix = link->link_id; + p.prefixlen = ip_masklen(link->link_data); + apply_mask_ipv4(&p); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_intra_add_stub(): processing route to %s/%d", + inet_ntoa(p.prefix), p.prefixlen); + + /* (1) Calculate the distance D of stub network from the root. D is + equal to the distance from the root to the router vertex + (calculated in stage 1), plus the stub network link's advertised + cost. */ + cost = v->distance + ntohs(link->m[0].metric); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_intra_add_stub(): calculated cost is %d + %d = %d", + v->distance, ntohs(link->m[0].metric), cost); + + /* PtP links with /32 masks adds host routes to remote, directly + * connected hosts, see RFC 2328, 12.4.1.1, Option 1. + * Such routes can just be ignored for the sake of tidyness. + */ + if (parent_is_root && link->link_data.s_addr == 0xffffffff + && ospf_if_lookup_by_local_addr(area->ospf, NULL, link->link_id)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("%s: ignoring host route %s/32 to self.", + __func__, inet_ntoa(link->link_id)); + return; } - /* (2) If this step is reached, the stub network's routing table - entry must be updated. Calculate the set of next hops that - would result from using the stub network link. This - calculation is shown in Section 16.1.1; input to this - calculation is the destination (the stub network) and the - parent vertex (the router vertex). If the distance D is the - same as the current routing table cost, simply add this set - of next hops to the routing table entry's list of next hops. - In this case, the routing table already has a Link State - Origin. If this Link State Origin is a router-LSA whose Link - State ID is smaller than V's Router ID, reset the Link State - Origin to V's router-LSA. */ - - if (cost == cur_or->cost) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_intra_add_stub(): routes are equal, merge"); + rn = route_node_get(rt, (struct prefix *)&p); - ospf_route_copy_nexthops_from_vertex (cur_or, v); + /* Lookup current routing table. */ + if (rn->info) { + struct ospf_route *cur_or; - if (IPV4_ADDR_CMP (&cur_or->u.std.origin->id, &lsa->header.id) < 0) - cur_or->u.std.origin = (struct lsa_header *) lsa; - return; - } + route_unlock_node(rn); - /* Otherwise D is smaller than the routing table cost. - Overwrite the current routing table entry by setting the - routing table entry's cost to D, and by setting the entry's - list of next hops to the newly calculated set. Set the - routing table entry's Link State Origin to V's router-LSA. - Then go on to examine the next stub network link. */ + cur_or = rn->info; - if (cost < cur_or->cost) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_intra_add_stub(): new route is better, set it"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_intra_add_stub(): " + "another route to the same prefix found with cost %u", + cur_or->cost); + + /* Compare this distance to the current best cost to the stub + network. This is done by looking up the stub network's + current routing table entry. If the calculated distance D is + larger, go on to examine the next stub network link in the + LSA. */ + if (cost > cur_or->cost) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_intra_add_stub(): old route is better, exit"); + return; + } - cur_or->cost = cost; + /* (2) If this step is reached, the stub network's routing table + entry must be updated. Calculate the set of next hops that + would result from using the stub network link. This + calculation is shown in Section 16.1.1; input to this + calculation is the destination (the stub network) and the + parent vertex (the router vertex). If the distance D is the + same as the current routing table cost, simply add this set + of next hops to the routing table entry's list of next hops. + In this case, the routing table already has a Link State + Origin. If this Link State Origin is a router-LSA whose Link + State ID is smaller than V's Router ID, reset the Link State + Origin to V's router-LSA. */ + + if (cost == cur_or->cost) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_intra_add_stub(): routes are equal, merge"); + + ospf_route_copy_nexthops_from_vertex(cur_or, v); + + if (IPV4_ADDR_CMP(&cur_or->u.std.origin->id, + &lsa->header.id) + < 0) + cur_or->u.std.origin = (struct lsa_header *)lsa; + return; + } - list_delete_all_node (cur_or->paths); + /* Otherwise D is smaller than the routing table cost. + Overwrite the current routing table entry by setting the + routing table entry's cost to D, and by setting the entry's + list of next hops to the newly calculated set. Set the + routing table entry's Link State Origin to V's router-LSA. + Then go on to examine the next stub network link. */ - ospf_route_copy_nexthops_from_vertex (cur_or, v); + if (cost < cur_or->cost) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_intra_add_stub(): new route is better, set it"); - cur_or->u.std.origin = (struct lsa_header *) lsa; - return; - } - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_intra_add_stub(): installing new route"); - - or = ospf_route_new (); - - or->id = v->id; - or->u.std.area_id = area->area_id; - or->u.std.external_routing = area->external_routing; - or->path_type = OSPF_PATH_INTRA_AREA; - or->cost = cost; - or->type = OSPF_DESTINATION_NETWORK; - or->u.std.origin = (struct lsa_header *) lsa; - - /* Nexthop is depend on connection type. */ - if (v != area->spf) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_intra_add_stub(): this network is on remote router"); - ospf_route_copy_nexthops_from_vertex (or, v); - } - else - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_intra_add_stub(): this network is on this router"); - - if ((oi = ospf_if_lookup_by_lsa_pos (area, lsa_pos))) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_intra_add_stub(): the interface is %s", - IF_NAME (oi)); - - path = ospf_path_new (); - path->nexthop.s_addr = 0; - path->ifindex = oi->ifp->ifindex; - if (CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED)) - path->unnumbered = 1; - listnode_add (or->paths, path); + cur_or->cost = cost; + + list_delete_all_node(cur_or->paths); + + ospf_route_copy_nexthops_from_vertex(cur_or, v); + + cur_or->u.std.origin = (struct lsa_header *)lsa; + return; + } } - else - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_intra_add_stub(): where's the interface ?"); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_intra_add_stub(): installing new route"); + + or = ospf_route_new(); + + or->id = v->id; + or->u.std.area_id = area->area_id; + or->u.std.external_routing = area->external_routing; + or->path_type = OSPF_PATH_INTRA_AREA; + or->cost = cost; + or->type = OSPF_DESTINATION_NETWORK; + or->u.std.origin = (struct lsa_header *)lsa; + + /* Nexthop is depend on connection type. */ + if (v != area->spf) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_intra_add_stub(): this network is on remote router"); + ospf_route_copy_nexthops_from_vertex(or, v); + } else { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_intra_add_stub(): this network is on this router"); + + if ((oi = ospf_if_lookup_by_lsa_pos(area, lsa_pos))) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_intra_add_stub(): the interface is %s", + IF_NAME(oi)); + + path = ospf_path_new(); + path->nexthop.s_addr = 0; + path->ifindex = oi->ifp->ifindex; + if (CHECK_FLAG(oi->connected->flags, + ZEBRA_IFA_UNNUMBERED)) + path->unnumbered = 1; + listnode_add(or->paths, path); + } else { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_intra_add_stub(): where's the interface ?"); + } } - } - rn->info = or; + rn->info = or ; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug("ospf_intra_add_stub(): Stop"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_intra_add_stub(): Stop"); } -const char *ospf_path_type_str[] = -{ - "unknown-type", - "intra-area", - "inter-area", - "type1-external", - "type2-external" -}; - -void -ospf_route_table_dump (struct route_table *rt) +const char *ospf_path_type_str[] = {"unknown-type", "intra-area", "inter-area", + "type1-external", "type2-external"}; + +void ospf_route_table_dump(struct route_table *rt) { - struct route_node *rn; - struct ospf_route *or; - char buf1[BUFSIZ]; - char buf2[BUFSIZ]; - struct listnode *pnode; - struct ospf_path *path; + struct route_node *rn; + struct ospf_route * or ; + char buf1[BUFSIZ]; + char buf2[BUFSIZ]; + struct listnode *pnode; + struct ospf_path *path; #if 0 zlog_debug ("Type Dest Area Path Type Cost Next Adv."); zlog_debug (" Hop(s) Router(s)"); #endif /* 0 */ - zlog_debug ("========== OSPF routing table =========="); - for (rn = route_top (rt); rn; rn = route_next (rn)) - if ((or = rn->info) != NULL) - { - if (or->type == OSPF_DESTINATION_NETWORK) - { - zlog_debug ("N %s/%d\t%s\t%s\t%d", - inet_ntop (AF_INET, &rn->p.u.prefix4, buf1, BUFSIZ), - rn->p.prefixlen, - inet_ntop (AF_INET, &or->u.std.area_id, buf2, - BUFSIZ), - ospf_path_type_str[or->path_type], - or->cost); - for (ALL_LIST_ELEMENTS_RO (or->paths, pnode, path)) - zlog_debug (" -> %s", inet_ntoa (path->nexthop)); - } - else - zlog_debug ("R %s\t%s\t%s\t%d", - inet_ntop (AF_INET, &rn->p.u.prefix4, buf1, BUFSIZ), - inet_ntop (AF_INET, &or->u.std.area_id, buf2, - BUFSIZ), - ospf_path_type_str[or->path_type], - or->cost); - } - zlog_debug ("========================================"); + zlog_debug("========== OSPF routing table =========="); + for (rn = route_top(rt); rn; rn = route_next(rn)) + if ((or = rn->info) != NULL) { + if (or->type == OSPF_DESTINATION_NETWORK) { + zlog_debug("N %s/%d\t%s\t%s\t%d", + inet_ntop(AF_INET, &rn->p.u.prefix4, + buf1, BUFSIZ), + rn->p.prefixlen, + inet_ntop(AF_INET, + & or->u.std.area_id, buf2, + BUFSIZ), + ospf_path_type_str[or->path_type], + or->cost); + for (ALL_LIST_ELEMENTS_RO(or->paths, pnode, + path)) + zlog_debug(" -> %s", + inet_ntoa(path->nexthop)); + } else + zlog_debug("R %s\t%s\t%s\t%d", + inet_ntop(AF_INET, &rn->p.u.prefix4, + buf1, BUFSIZ), + inet_ntop(AF_INET, + & or->u.std.area_id, buf2, + BUFSIZ), + ospf_path_type_str[or->path_type], + or->cost); + } + zlog_debug("========================================"); } /* This is 16.4.1 implementation. o Intra-area paths using non-backbone areas are always the most preferred. o The other paths, intra-area backbone paths and inter-area paths, are of equal preference. */ -static int -ospf_asbr_route_cmp (struct ospf *ospf, struct ospf_route *r1, - struct ospf_route *r2) +static int ospf_asbr_route_cmp(struct ospf *ospf, struct ospf_route *r1, + struct ospf_route *r2) { - u_char r1_type, r2_type; + u_char r1_type, r2_type; - r1_type = r1->path_type; - r2_type = r2->path_type; + r1_type = r1->path_type; + r2_type = r2->path_type; - /* r1/r2 itself is backbone, and it's Inter-area path. */ - if (OSPF_IS_AREA_ID_BACKBONE (r1->u.std.area_id)) - r1_type = OSPF_PATH_INTER_AREA; - if (OSPF_IS_AREA_ID_BACKBONE (r2->u.std.area_id)) - r2_type = OSPF_PATH_INTER_AREA; + /* r1/r2 itself is backbone, and it's Inter-area path. */ + if (OSPF_IS_AREA_ID_BACKBONE(r1->u.std.area_id)) + r1_type = OSPF_PATH_INTER_AREA; + if (OSPF_IS_AREA_ID_BACKBONE(r2->u.std.area_id)) + r2_type = OSPF_PATH_INTER_AREA; - return (r1_type - r2_type); + return (r1_type - r2_type); } /* Compare two routes. ret < 0 -- r1 is better. ret == 0 -- r1 and r2 are the same. ret > 0 -- r2 is better. */ -int -ospf_route_cmp (struct ospf *ospf, struct ospf_route *r1, - struct ospf_route *r2) +int ospf_route_cmp(struct ospf *ospf, struct ospf_route *r1, + struct ospf_route *r2) { - int ret = 0; - - /* Path types of r1 and r2 are not the same. */ - if ((ret = (r1->path_type - r2->path_type))) - return ret; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Route[Compare]: Path types are the same."); - /* Path types are the same, compare any cost. */ - switch (r1->path_type) - { - case OSPF_PATH_INTRA_AREA: - case OSPF_PATH_INTER_AREA: - break; - case OSPF_PATH_TYPE1_EXTERNAL: - if (!CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE)) - { - ret = ospf_asbr_route_cmp (ospf, r1->u.ext.asbr, r2->u.ext.asbr); - if (ret != 0) - return ret; - } - break; - case OSPF_PATH_TYPE2_EXTERNAL: - if ((ret = (r1->u.ext.type2_cost - r2->u.ext.type2_cost))) - return ret; - - if (!CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE)) - { - ret = ospf_asbr_route_cmp (ospf, r1->u.ext.asbr, r2->u.ext.asbr); - if (ret != 0) - return ret; + int ret = 0; + + /* Path types of r1 and r2 are not the same. */ + if ((ret = (r1->path_type - r2->path_type))) + return ret; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Route[Compare]: Path types are the same."); + /* Path types are the same, compare any cost. */ + switch (r1->path_type) { + case OSPF_PATH_INTRA_AREA: + case OSPF_PATH_INTER_AREA: + break; + case OSPF_PATH_TYPE1_EXTERNAL: + if (!CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE)) { + ret = ospf_asbr_route_cmp(ospf, r1->u.ext.asbr, + r2->u.ext.asbr); + if (ret != 0) + return ret; + } + break; + case OSPF_PATH_TYPE2_EXTERNAL: + if ((ret = (r1->u.ext.type2_cost - r2->u.ext.type2_cost))) + return ret; + + if (!CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE)) { + ret = ospf_asbr_route_cmp(ospf, r1->u.ext.asbr, + r2->u.ext.asbr); + if (ret != 0) + return ret; + } + break; } - break; - } - /* Anyway, compare the costs. */ - return (r1->cost - r2->cost); + /* Anyway, compare the costs. */ + return (r1->cost - r2->cost); } -static int -ospf_path_exist (struct list *plist, struct in_addr nexthop, - struct ospf_interface *oi) +static int ospf_path_exist(struct list *plist, struct in_addr nexthop, + struct ospf_interface *oi) { - struct listnode *node, *nnode; - struct ospf_path *path; + struct listnode *node, *nnode; + struct ospf_path *path; - for (ALL_LIST_ELEMENTS (plist, node, nnode, path)) - if (IPV4_ADDR_SAME (&path->nexthop, &nexthop) && - path->ifindex == oi->ifp->ifindex) - return 1; + for (ALL_LIST_ELEMENTS(plist, node, nnode, path)) + if (IPV4_ADDR_SAME(&path->nexthop, &nexthop) + && path->ifindex == oi->ifp->ifindex) + return 1; - return 0; + return 0; } -void -ospf_route_copy_nexthops_from_vertex (struct ospf_route *to, - struct vertex *v) +void ospf_route_copy_nexthops_from_vertex(struct ospf_route *to, + struct vertex *v) { - struct listnode *node; - struct ospf_path *path; - struct vertex_nexthop *nexthop; - struct vertex_parent *vp; - - assert (to->paths); - - for (ALL_LIST_ELEMENTS_RO (v->parents, node, vp)) - { - nexthop = vp->nexthop; - - if (nexthop->oi != NULL) - { - if (! ospf_path_exist (to->paths, nexthop->router, nexthop->oi)) - { - path = ospf_path_new (); - path->nexthop = nexthop->router; - path->ifindex = nexthop->oi->ifp->ifindex; - if (CHECK_FLAG(nexthop->oi->connected->flags, ZEBRA_IFA_UNNUMBERED)) - path->unnumbered = 1; - listnode_add (to->paths, path); - } + struct listnode *node; + struct ospf_path *path; + struct vertex_nexthop *nexthop; + struct vertex_parent *vp; + + assert(to->paths); + + for (ALL_LIST_ELEMENTS_RO(v->parents, node, vp)) { + nexthop = vp->nexthop; + + if (nexthop->oi != NULL) { + if (!ospf_path_exist(to->paths, nexthop->router, + nexthop->oi)) { + path = ospf_path_new(); + path->nexthop = nexthop->router; + path->ifindex = nexthop->oi->ifp->ifindex; + if (CHECK_FLAG(nexthop->oi->connected->flags, + ZEBRA_IFA_UNNUMBERED)) + path->unnumbered = 1; + listnode_add(to->paths, path); + } + } } - } } -struct ospf_path * -ospf_path_lookup (struct list *plist, struct ospf_path *path) +struct ospf_path *ospf_path_lookup(struct list *plist, struct ospf_path *path) { - struct listnode *node; - struct ospf_path *op; - - for (ALL_LIST_ELEMENTS_RO (plist, node, op)) - { - if (!IPV4_ADDR_SAME (&op->nexthop, &path->nexthop)) - continue; - if (!IPV4_ADDR_SAME (&op->adv_router, &path->adv_router)) - continue; - if (op->ifindex != path->ifindex) - continue; - return op; - } - return NULL; + struct listnode *node; + struct ospf_path *op; + + for (ALL_LIST_ELEMENTS_RO(plist, node, op)) { + if (!IPV4_ADDR_SAME(&op->nexthop, &path->nexthop)) + continue; + if (!IPV4_ADDR_SAME(&op->adv_router, &path->adv_router)) + continue; + if (op->ifindex != path->ifindex) + continue; + return op; + } + return NULL; } -void -ospf_route_copy_nexthops (struct ospf_route *to, struct list *from) +void ospf_route_copy_nexthops(struct ospf_route *to, struct list *from) { - struct listnode *node, *nnode; - struct ospf_path *path; + struct listnode *node, *nnode; + struct ospf_path *path; - assert (to->paths); + assert(to->paths); - for (ALL_LIST_ELEMENTS (from, node, nnode, path)) - /* The same routes are just discarded. */ - if (!ospf_path_lookup (to->paths, path)) - listnode_add (to->paths, ospf_path_dup (path)); + for (ALL_LIST_ELEMENTS(from, node, nnode, path)) + /* The same routes are just discarded. */ + if (!ospf_path_lookup(to->paths, path)) + listnode_add(to->paths, ospf_path_dup(path)); } -void -ospf_route_subst_nexthops (struct ospf_route *to, struct list *from) +void ospf_route_subst_nexthops(struct ospf_route *to, struct list *from) { - list_delete_all_node (to->paths); - ospf_route_copy_nexthops (to, from); + list_delete_all_node(to->paths); + ospf_route_copy_nexthops(to, from); } -void -ospf_route_subst (struct route_node *rn, struct ospf_route *new_or, - struct ospf_route *over) +void ospf_route_subst(struct route_node *rn, struct ospf_route *new_or, + struct ospf_route *over) { - route_lock_node (rn); - ospf_route_free (rn->info); + route_lock_node(rn); + ospf_route_free(rn->info); - ospf_route_copy_nexthops (new_or, over->paths); - rn->info = new_or; - route_unlock_node (rn); + ospf_route_copy_nexthops(new_or, over->paths); + rn->info = new_or; + route_unlock_node(rn); } -void -ospf_route_add (struct route_table *rt, struct prefix_ipv4 *p, - struct ospf_route *new_or, struct ospf_route *over) +void ospf_route_add(struct route_table *rt, struct prefix_ipv4 *p, + struct ospf_route *new_or, struct ospf_route *over) { - struct route_node *rn; + struct route_node *rn; - rn = route_node_get (rt, (struct prefix *) p); + rn = route_node_get(rt, (struct prefix *)p); - ospf_route_copy_nexthops (new_or, over->paths); + ospf_route_copy_nexthops(new_or, over->paths); + + if (rn->info) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_route_add(): something's wrong !"); + route_unlock_node(rn); + return; + } - if (rn->info) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_route_add(): something's wrong !"); - route_unlock_node (rn); - return; - } + rn->info = new_or; +} - rn->info = new_or; +void ospf_prune_unreachable_networks(struct route_table *rt) +{ + struct route_node *rn, *next; + struct ospf_route * or ; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Pruning unreachable networks"); + + for (rn = route_top(rt); rn; rn = next) { + next = route_next(rn); + if (rn->info != NULL) { + or = rn->info; + if (listcount(or->paths) == 0) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Pruning route to %s/%d", + inet_ntoa(rn->p.u.prefix4), + rn->p.prefixlen); + + ospf_route_free(or); + rn->info = NULL; + route_unlock_node(rn); + } + } + } } -void -ospf_prune_unreachable_networks (struct route_table *rt) +void ospf_prune_unreachable_routers(struct route_table *rtrs) { - struct route_node *rn, *next; - struct ospf_route *or; + struct route_node *rn, *next; + struct ospf_route * or ; + struct listnode *node, *nnode; + struct list *paths; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Pruning unreachable routers"); + + for (rn = route_top(rtrs); rn; rn = next) { + next = route_next(rn); + if ((paths = rn->info) == NULL) + continue; + + for (ALL_LIST_ELEMENTS(paths, node, nnode, or)) { + if (listcount(or->paths) == 0) { + if (IS_DEBUG_OSPF_EVENT) { + zlog_debug("Pruning route to rtr %s", + inet_ntoa(rn->p.u.prefix4)); + zlog_debug( + " via area %s", + inet_ntoa(or->u.std.area_id)); + } + + listnode_delete(paths, or); + ospf_route_free(or); + } + } - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Pruning unreachable networks"); + if (listcount(paths) == 0) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Pruning router node %s", + inet_ntoa(rn->p.u.prefix4)); - for (rn = route_top (rt); rn; rn = next) - { - next = route_next (rn); - if (rn->info != NULL) - { - or = rn->info; - if (listcount (or->paths) == 0) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Pruning route to %s/%d", - inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen); - - ospf_route_free (or); - rn->info = NULL; - route_unlock_node (rn); - } + list_delete(paths); + rn->info = NULL; + route_unlock_node(rn); + } } - } } -void -ospf_prune_unreachable_routers (struct route_table *rtrs) +int ospf_add_discard_route(struct route_table *rt, struct ospf_area *area, + struct prefix_ipv4 *p) { - struct route_node *rn, *next; - struct ospf_route *or; - struct listnode *node, *nnode; - struct list *paths; + struct route_node *rn; + struct ospf_route * or, *new_or; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Pruning unreachable routers"); + rn = route_node_get(rt, (struct prefix *)p); - for (rn = route_top (rtrs); rn; rn = next) - { - next = route_next (rn); - if ((paths = rn->info) == NULL) - continue; + if (rn == NULL) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_add_discard_route(): router installation error"); + return 0; + } - for (ALL_LIST_ELEMENTS (paths, node, nnode, or)) + if (rn->info) /* If the route to the same destination is found */ { - if (listcount (or->paths) == 0) - { - if (IS_DEBUG_OSPF_EVENT) - { - zlog_debug ("Pruning route to rtr %s", - inet_ntoa (rn->p.u.prefix4)); - zlog_debug (" via area %s", - inet_ntoa (or->u.std.area_id)); - } + route_unlock_node(rn); - listnode_delete (paths, or); - ospf_route_free (or); - } - } + or = rn->info; - if (listcount (paths) == 0) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Pruning router node %s", inet_ntoa (rn->p.u.prefix4)); + if (or->path_type == OSPF_PATH_INTRA_AREA) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_add_discard_route(): " + "an intra-area route exists"); + return 0; + } - list_delete (paths); - rn->info = NULL; - route_unlock_node (rn); - } - } -} + if (or->type == OSPF_DESTINATION_DISCARD) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_add_discard_route(): " + "discard entry already installed"); + return 0; + } -int -ospf_add_discard_route (struct route_table *rt, struct ospf_area *area, - struct prefix_ipv4 *p) -{ - struct route_node *rn; - struct ospf_route *or, *new_or; + ospf_route_free(rn->info); + } - rn = route_node_get (rt, (struct prefix *) p); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_add_discard_route(): " + "adding %s/%d", + inet_ntoa(p->prefix), p->prefixlen); - if (rn == NULL) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_add_discard_route(): router installation error"); - return 0; - } + new_or = ospf_route_new(); + new_or->type = OSPF_DESTINATION_DISCARD; + new_or->id.s_addr = 0; + new_or->cost = 0; + new_or->u.std.area_id = area->area_id; + new_or->u.std.external_routing = area->external_routing; + new_or->path_type = OSPF_PATH_INTER_AREA; + rn->info = new_or; - if (rn->info) /* If the route to the same destination is found */ - { - route_unlock_node (rn); + ospf_zebra_add_discard(p); - or = rn->info; + return 1; +} - if (or->path_type == OSPF_PATH_INTRA_AREA) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_add_discard_route(): " - "an intra-area route exists"); - return 0; +void ospf_delete_discard_route(struct route_table *rt, struct prefix_ipv4 *p) +{ + struct route_node *rn; + struct ospf_route * or ; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_delete_discard_route(): " + "deleting %s/%d", + inet_ntoa(p->prefix), p->prefixlen); + + rn = route_node_lookup(rt, (struct prefix *)p); + + if (rn == NULL) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_delete_discard_route(): no route found"); + return; } - if (or->type == OSPF_DESTINATION_DISCARD) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_add_discard_route(): " - "discard entry already installed"); - return 0; + or = rn->info; + + if (or->path_type == OSPF_PATH_INTRA_AREA) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_delete_discard_route(): " + "an intra-area route exists"); + return; } - ospf_route_free (rn->info); - } + if (or->type != OSPF_DESTINATION_DISCARD) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_delete_discard_route(): " + "not a discard entry"); + return; + } - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_add_discard_route(): " - "adding %s/%d", inet_ntoa (p->prefix), p->prefixlen); + /* free the route entry and the route node */ + ospf_route_free(rn->info); - new_or = ospf_route_new (); - new_or->type = OSPF_DESTINATION_DISCARD; - new_or->id.s_addr = 0; - new_or->cost = 0; - new_or->u.std.area_id = area->area_id; - new_or->u.std.external_routing = area->external_routing; - new_or->path_type = OSPF_PATH_INTER_AREA; - rn->info = new_or; + rn->info = NULL; + route_unlock_node(rn); + route_unlock_node(rn); - ospf_zebra_add_discard (p); + /* remove the discard entry from the rib */ + ospf_zebra_delete_discard(p); - return 1; -} - -void -ospf_delete_discard_route (struct route_table *rt, struct prefix_ipv4 *p) -{ - struct route_node *rn; - struct ospf_route *or; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_delete_discard_route(): " - "deleting %s/%d", inet_ntoa (p->prefix), p->prefixlen); - - rn = route_node_lookup (rt, (struct prefix*)p); - - if (rn == NULL) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug("ospf_delete_discard_route(): no route found"); - return; - } - - or = rn->info; - - if (or->path_type == OSPF_PATH_INTRA_AREA) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_delete_discard_route(): " - "an intra-area route exists"); - return; - } - - if (or->type != OSPF_DESTINATION_DISCARD) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_delete_discard_route(): " - "not a discard entry"); - return; - } - - /* free the route entry and the route node */ - ospf_route_free (rn->info); - - rn->info = NULL; - route_unlock_node (rn); - route_unlock_node (rn); - - /* remove the discard entry from the rib */ - ospf_zebra_delete_discard(p); - - return; + return; } - diff --git a/ospfd/ospf_route.h b/ospfd/ospf_route.h index 16c6b0000..199937984 100644 --- a/ospfd/ospf_route.h +++ b/ospfd/ospf_route.h @@ -34,12 +34,11 @@ #define OSPF_PATH_MAX 5 /* OSPF Path. */ -struct ospf_path -{ - struct in_addr nexthop; - struct in_addr adv_router; - ifindex_t ifindex; - unsigned char unnumbered; +struct ospf_path { + struct in_addr nexthop; + struct in_addr adv_router; + ifindex_t ifindex; + unsigned char unnumbered; }; /* Below is the structure linked to every @@ -54,107 +53,103 @@ struct ospf_path nr->info is a (struct ospf_router_route *) for OSPF_DESTINATION_ROUTER */ -struct route_standard -{ - /* Link Sate Origin. */ - struct lsa_header *origin; +struct route_standard { + /* Link Sate Origin. */ + struct lsa_header *origin; - /* Associated Area. */ - struct in_addr area_id; /* The area the route belongs to */ + /* Associated Area. */ + struct in_addr area_id; /* The area the route belongs to */ - /* Area Type */ - int external_routing; + /* Area Type */ + int external_routing; - /* Optional Capability. */ - u_char options; /* Get from LSA header. */ + /* Optional Capability. */ + u_char options; /* Get from LSA header. */ - /* */ - u_char flags; /* From router-LSA */ + /* */ + u_char flags; /* From router-LSA */ }; -struct route_external -{ - /* Link State Origin. */ - struct ospf_lsa *origin; +struct route_external { + /* Link State Origin. */ + struct ospf_lsa *origin; - /* Link State Cost Type2. */ - u_int32_t type2_cost; + /* Link State Cost Type2. */ + u_int32_t type2_cost; - /* Tag value. */ - u_int32_t tag; + /* Tag value. */ + u_int32_t tag; - /* ASBR route. */ - struct ospf_route *asbr; + /* ASBR route. */ + struct ospf_route *asbr; }; -struct ospf_route -{ - /* Destination Type. */ - u_char type; +struct ospf_route { + /* Destination Type. */ + u_char type; - /* Destination ID. */ /* i.e. Link State ID. */ - struct in_addr id; + /* Destination ID. */ /* i.e. Link State ID. */ + struct in_addr id; - /* Address Mask. */ - struct in_addr mask; /* Only valid for networks. */ + /* Address Mask. */ + struct in_addr mask; /* Only valid for networks. */ - /* Path Type. */ - u_char path_type; + /* Path Type. */ + u_char path_type; - /* List of Paths. */ - struct list *paths; + /* List of Paths. */ + struct list *paths; - /* Link State Cost. */ - u_int32_t cost; /* i.e. metric. */ + /* Link State Cost. */ + u_int32_t cost; /* i.e. metric. */ - /* Route specific info. */ - union - { - struct route_standard std; - struct route_external ext; - } u; + /* Route specific info. */ + union { + struct route_standard std; + struct route_external ext; + } u; }; -extern struct ospf_path *ospf_path_new (void); -extern void ospf_path_free (struct ospf_path *); -extern struct ospf_path *ospf_path_lookup (struct list *, struct ospf_path *); -extern struct ospf_route *ospf_route_new (void); -extern void ospf_route_free (struct ospf_route *); -extern void ospf_route_delete (struct route_table *); -extern void ospf_route_table_free (struct route_table *); +extern struct ospf_path *ospf_path_new(void); +extern void ospf_path_free(struct ospf_path *); +extern struct ospf_path *ospf_path_lookup(struct list *, struct ospf_path *); +extern struct ospf_route *ospf_route_new(void); +extern void ospf_route_free(struct ospf_route *); +extern void ospf_route_delete(struct route_table *); +extern void ospf_route_table_free(struct route_table *); -extern void ospf_route_install (struct ospf *, struct route_table *); -extern void ospf_route_table_dump (struct route_table *); +extern void ospf_route_install(struct ospf *, struct route_table *); +extern void ospf_route_table_dump(struct route_table *); -extern void ospf_intra_add_router (struct route_table *, struct vertex *, +extern void ospf_intra_add_router(struct route_table *, struct vertex *, + struct ospf_area *); + +extern void ospf_intra_add_transit(struct route_table *, struct vertex *, struct ospf_area *); -extern void ospf_intra_add_transit (struct route_table *, struct vertex *, - struct ospf_area *); - -extern void ospf_intra_add_stub (struct route_table *, - struct router_lsa_link *, struct vertex *, - struct ospf_area *, - int parent_is_root, int); - -extern int ospf_route_cmp (struct ospf *, struct ospf_route *, - struct ospf_route *); -extern void ospf_route_copy_nexthops (struct ospf_route *, struct list *); -extern void ospf_route_copy_nexthops_from_vertex (struct ospf_route *, - struct vertex *); - -extern void ospf_route_subst (struct route_node *, struct ospf_route *, - struct ospf_route *); -extern void ospf_route_add (struct route_table *, struct prefix_ipv4 *, - struct ospf_route *, struct ospf_route *); - -extern void ospf_route_subst_nexthops (struct ospf_route *, struct list *); -extern void ospf_prune_unreachable_networks (struct route_table *); -extern void ospf_prune_unreachable_routers (struct route_table *); -extern int ospf_add_discard_route (struct route_table *, struct ospf_area *, - struct prefix_ipv4 *); -extern void ospf_delete_discard_route (struct route_table *, struct prefix_ipv4 *); -extern int ospf_route_match_same (struct route_table *, struct prefix_ipv4 *, - struct ospf_route *); +extern void ospf_intra_add_stub(struct route_table *, struct router_lsa_link *, + struct vertex *, struct ospf_area *, + int parent_is_root, int); + +extern int ospf_route_cmp(struct ospf *, struct ospf_route *, + struct ospf_route *); +extern void ospf_route_copy_nexthops(struct ospf_route *, struct list *); +extern void ospf_route_copy_nexthops_from_vertex(struct ospf_route *, + struct vertex *); + +extern void ospf_route_subst(struct route_node *, struct ospf_route *, + struct ospf_route *); +extern void ospf_route_add(struct route_table *, struct prefix_ipv4 *, + struct ospf_route *, struct ospf_route *); + +extern void ospf_route_subst_nexthops(struct ospf_route *, struct list *); +extern void ospf_prune_unreachable_networks(struct route_table *); +extern void ospf_prune_unreachable_routers(struct route_table *); +extern int ospf_add_discard_route(struct route_table *, struct ospf_area *, + struct prefix_ipv4 *); +extern void ospf_delete_discard_route(struct route_table *, + struct prefix_ipv4 *); +extern int ospf_route_match_same(struct route_table *, struct prefix_ipv4 *, + struct ospf_route *); #endif /* _ZEBRA_OSPF_ROUTE_H */ diff --git a/ospfd/ospf_routemap.c b/ospfd/ospf_routemap.c index 7032cbe1e..547e1e8f5 100644 --- a/ospfd/ospf_routemap.c +++ b/ospfd/ospf_routemap.c @@ -41,488 +41,432 @@ #include "ospfd/ospf_zebra.h" /* Hook function for updating route_map assignment. */ -static void -ospf_route_map_update (const char *name) -{ - struct ospf *ospf; - int type; - - /* If OSPF instatnce does not exist, return right now. */ - ospf = ospf_lookup (); - if (ospf == NULL) - return; - - /* Update route-map */ - for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) - { - struct list *red_list; - struct listnode *node; - struct ospf_redist *red; - - red_list = ospf->redist[type]; - if (!red_list) - continue; - - for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) - { - if (ROUTEMAP_NAME (red) - && strcmp (ROUTEMAP_NAME (red), name) == 0) - { - /* Keep old route-map. */ - struct route_map *old = ROUTEMAP (red); - - /* Update route-map. */ - ROUTEMAP (red) = - route_map_lookup_by_name (ROUTEMAP_NAME (red)); - - /* No update for this distribute type. */ - if (old == NULL && ROUTEMAP (red) == NULL) - continue; - - ospf_distribute_list_update (ospf, type, red->instance); - } - } - } +static void ospf_route_map_update(const char *name) +{ + struct ospf *ospf; + int type; + + /* If OSPF instatnce does not exist, return right now. */ + ospf = ospf_lookup(); + if (ospf == NULL) + return; + + /* Update route-map */ + for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) { + struct list *red_list; + struct listnode *node; + struct ospf_redist *red; + + red_list = ospf->redist[type]; + if (!red_list) + continue; + + for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) { + if (ROUTEMAP_NAME(red) + && strcmp(ROUTEMAP_NAME(red), name) == 0) { + /* Keep old route-map. */ + struct route_map *old = ROUTEMAP(red); + + /* Update route-map. */ + ROUTEMAP(red) = route_map_lookup_by_name( + ROUTEMAP_NAME(red)); + + /* No update for this distribute type. */ + if (old == NULL && ROUTEMAP(red) == NULL) + continue; + + ospf_distribute_list_update(ospf, type, + red->instance); + } + } + } } -static void -ospf_route_map_event (route_map_event_t event, const char *name) +static void ospf_route_map_event(route_map_event_t event, const char *name) { - struct ospf *ospf; - int type; - - /* If OSPF instatnce does not exist, return right now. */ - ospf = ospf_lookup (); - if (ospf == NULL) - return; - - for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) - { - struct list *red_list; - struct listnode *node; - struct ospf_redist *red; - - red_list = ospf->redist[type]; - if (!red_list) - continue; - - for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) - { - if (ROUTEMAP_NAME (red) && ROUTEMAP (red) - && !strcmp (ROUTEMAP_NAME (red), name)) - { - ospf_distribute_list_update (ospf, type, red->instance); - } - } - } + struct ospf *ospf; + int type; + + /* If OSPF instatnce does not exist, return right now. */ + ospf = ospf_lookup(); + if (ospf == NULL) + return; + + for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) { + struct list *red_list; + struct listnode *node; + struct ospf_redist *red; + + red_list = ospf->redist[type]; + if (!red_list) + continue; + + for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) { + if (ROUTEMAP_NAME(red) && ROUTEMAP(red) + && !strcmp(ROUTEMAP_NAME(red), name)) { + ospf_distribute_list_update(ospf, type, + red->instance); + } + } + } } /* `match ip netxthop ' */ /* Match function return 1 if match is success else return zero. */ -static route_map_result_t -route_match_ip_nexthop (void *rule, struct prefix *prefix, - route_map_object_t type, void *object) -{ - struct access_list *alist; - struct external_info *ei = object; - struct prefix_ipv4 p; - - if (type == RMAP_OSPF) - { - p.family = AF_INET; - p.prefix = ei->nexthop; - p.prefixlen = IPV4_MAX_BITLEN; - - alist = access_list_lookup (AFI_IP, (char *) rule); - if (alist == NULL) - return RMAP_NOMATCH; - - return (access_list_apply (alist, &p) == FILTER_DENY ? - RMAP_NOMATCH : RMAP_MATCH); - } - return RMAP_NOMATCH; +static route_map_result_t route_match_ip_nexthop(void *rule, + struct prefix *prefix, + route_map_object_t type, + void *object) +{ + struct access_list *alist; + struct external_info *ei = object; + struct prefix_ipv4 p; + + if (type == RMAP_OSPF) { + p.family = AF_INET; + p.prefix = ei->nexthop; + p.prefixlen = IPV4_MAX_BITLEN; + + alist = access_list_lookup(AFI_IP, (char *)rule); + if (alist == NULL) + return RMAP_NOMATCH; + + return (access_list_apply(alist, &p) == FILTER_DENY + ? RMAP_NOMATCH + : RMAP_MATCH); + } + return RMAP_NOMATCH; } /* Route map `ip next-hop' match statement. `arg' should be access-list name. */ -static void * -route_match_ip_nexthop_compile (const char *arg) +static void *route_match_ip_nexthop_compile(const char *arg) { - return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); + return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); } /* Free route map's compiled `ip address' value. */ -static void -route_match_ip_nexthop_free (void *rule) +static void route_match_ip_nexthop_free(void *rule) { - XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); } /* Route map commands for metric matching. */ -struct route_map_rule_cmd route_match_ip_nexthop_cmd = -{ - "ip next-hop", - route_match_ip_nexthop, - route_match_ip_nexthop_compile, - route_match_ip_nexthop_free -}; +struct route_map_rule_cmd route_match_ip_nexthop_cmd = { + "ip next-hop", route_match_ip_nexthop, route_match_ip_nexthop_compile, + route_match_ip_nexthop_free}; /* `match ip next-hop prefix-list PREFIX_LIST' */ static route_map_result_t -route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix, - route_map_object_t type, void *object) +route_match_ip_next_hop_prefix_list(void *rule, struct prefix *prefix, + route_map_object_t type, void *object) { - struct prefix_list *plist; - struct external_info *ei = object; - struct prefix_ipv4 p; - - if (type == RMAP_OSPF) - { - p.family = AF_INET; - p.prefix = ei->nexthop; - p.prefixlen = IPV4_MAX_BITLEN; - - plist = prefix_list_lookup (AFI_IP, (char *) rule); - if (plist == NULL) - return RMAP_NOMATCH; - - return (prefix_list_apply (plist, &p) == PREFIX_DENY ? - RMAP_NOMATCH : RMAP_MATCH); - } - return RMAP_NOMATCH; + struct prefix_list *plist; + struct external_info *ei = object; + struct prefix_ipv4 p; + + if (type == RMAP_OSPF) { + p.family = AF_INET; + p.prefix = ei->nexthop; + p.prefixlen = IPV4_MAX_BITLEN; + + plist = prefix_list_lookup(AFI_IP, (char *)rule); + if (plist == NULL) + return RMAP_NOMATCH; + + return (prefix_list_apply(plist, &p) == PREFIX_DENY + ? RMAP_NOMATCH + : RMAP_MATCH); + } + return RMAP_NOMATCH; } -static void * -route_match_ip_next_hop_prefix_list_compile (const char *arg) +static void *route_match_ip_next_hop_prefix_list_compile(const char *arg) { - return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); + return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); } -static void -route_match_ip_next_hop_prefix_list_free (void *rule) +static void route_match_ip_next_hop_prefix_list_free(void *rule) { - XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); } -struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd = -{ - "ip next-hop prefix-list", - route_match_ip_next_hop_prefix_list, - route_match_ip_next_hop_prefix_list_compile, - route_match_ip_next_hop_prefix_list_free -}; +struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd = { + "ip next-hop prefix-list", route_match_ip_next_hop_prefix_list, + route_match_ip_next_hop_prefix_list_compile, + route_match_ip_next_hop_prefix_list_free}; /* `match ip address IP_ACCESS_LIST' */ /* Match function should return 1 if match is success else return zero. */ -static route_map_result_t -route_match_ip_address (void *rule, struct prefix *prefix, - route_map_object_t type, void *object) -{ - struct access_list *alist; - /* struct prefix_ipv4 match; */ - - if (type == RMAP_OSPF) - { - alist = access_list_lookup (AFI_IP, (char *) rule); - if (alist == NULL) - return RMAP_NOMATCH; - - return (access_list_apply (alist, prefix) == FILTER_DENY ? - RMAP_NOMATCH : RMAP_MATCH); - } - return RMAP_NOMATCH; +static route_map_result_t route_match_ip_address(void *rule, + struct prefix *prefix, + route_map_object_t type, + void *object) +{ + struct access_list *alist; + /* struct prefix_ipv4 match; */ + + if (type == RMAP_OSPF) { + alist = access_list_lookup(AFI_IP, (char *)rule); + if (alist == NULL) + return RMAP_NOMATCH; + + return (access_list_apply(alist, prefix) == FILTER_DENY + ? RMAP_NOMATCH + : RMAP_MATCH); + } + return RMAP_NOMATCH; } /* Route map `ip address' match statement. `arg' should be access-list name. */ -static void * -route_match_ip_address_compile (const char *arg) +static void *route_match_ip_address_compile(const char *arg) { - return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); + return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); } /* Free route map's compiled `ip address' value. */ -static void -route_match_ip_address_free (void *rule) +static void route_match_ip_address_free(void *rule) { - XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); } /* Route map commands for ip address matching. */ -struct route_map_rule_cmd route_match_ip_address_cmd = -{ - "ip address", - route_match_ip_address, - route_match_ip_address_compile, - route_match_ip_address_free -}; +struct route_map_rule_cmd route_match_ip_address_cmd = { + "ip address", route_match_ip_address, route_match_ip_address_compile, + route_match_ip_address_free}; /* `match ip address prefix-list PREFIX_LIST' */ static route_map_result_t -route_match_ip_address_prefix_list (void *rule, struct prefix *prefix, - route_map_object_t type, void *object) +route_match_ip_address_prefix_list(void *rule, struct prefix *prefix, + route_map_object_t type, void *object) { - struct prefix_list *plist; - - if (type == RMAP_OSPF) - { - plist = prefix_list_lookup (AFI_IP, (char *) rule); - if (plist == NULL) - return RMAP_NOMATCH; - - return (prefix_list_apply (plist, prefix) == PREFIX_DENY ? - RMAP_NOMATCH : RMAP_MATCH); - } - return RMAP_NOMATCH; + struct prefix_list *plist; + + if (type == RMAP_OSPF) { + plist = prefix_list_lookup(AFI_IP, (char *)rule); + if (plist == NULL) + return RMAP_NOMATCH; + + return (prefix_list_apply(plist, prefix) == PREFIX_DENY + ? RMAP_NOMATCH + : RMAP_MATCH); + } + return RMAP_NOMATCH; } -static void * -route_match_ip_address_prefix_list_compile (const char *arg) +static void *route_match_ip_address_prefix_list_compile(const char *arg) { - return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); + return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); } -static void -route_match_ip_address_prefix_list_free (void *rule) +static void route_match_ip_address_prefix_list_free(void *rule) { - XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); } -struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = -{ - "ip address prefix-list", - route_match_ip_address_prefix_list, - route_match_ip_address_prefix_list_compile, - route_match_ip_address_prefix_list_free -}; +struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = { + "ip address prefix-list", route_match_ip_address_prefix_list, + route_match_ip_address_prefix_list_compile, + route_match_ip_address_prefix_list_free}; /* `match interface IFNAME' */ /* Match function should return 1 if match is success else return zero. */ -static route_map_result_t -route_match_interface (void *rule, struct prefix *prefix, - route_map_object_t type, void *object) +static route_map_result_t route_match_interface(void *rule, + struct prefix *prefix, + route_map_object_t type, + void *object) { - struct interface *ifp; - struct external_info *ei; + struct interface *ifp; + struct external_info *ei; - if (type == RMAP_OSPF) - { - ei = object; - ifp = if_lookup_by_name ((char *)rule, VRF_DEFAULT); + if (type == RMAP_OSPF) { + ei = object; + ifp = if_lookup_by_name((char *)rule, VRF_DEFAULT); - if (ifp == NULL || ifp->ifindex != ei->ifindex) - return RMAP_NOMATCH; + if (ifp == NULL || ifp->ifindex != ei->ifindex) + return RMAP_NOMATCH; - return RMAP_MATCH; - } - return RMAP_NOMATCH; + return RMAP_MATCH; + } + return RMAP_NOMATCH; } /* Route map `interface' match statement. `arg' should be interface name. */ -static void * -route_match_interface_compile (const char *arg) +static void *route_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 -route_match_interface_free (void *rule) +static void route_match_interface_free(void *rule) { - XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); } /* Route map commands for ip address matching. */ -struct route_map_rule_cmd route_match_interface_cmd = -{ - "interface", - route_match_interface, - route_match_interface_compile, - route_match_interface_free -}; +struct route_map_rule_cmd route_match_interface_cmd = { + "interface", route_match_interface, route_match_interface_compile, + route_match_interface_free}; /* Match function return 1 if match is success else return zero. */ -static route_map_result_t -route_match_tag (void *rule, struct prefix *prefix, - route_map_object_t type, void *object) +static route_map_result_t route_match_tag(void *rule, struct prefix *prefix, + route_map_object_t type, void *object) { - route_tag_t *tag; - struct external_info *ei; + route_tag_t *tag; + struct external_info *ei; - if (type == RMAP_OSPF) - { - tag = rule; - ei = object; + if (type == RMAP_OSPF) { + tag = rule; + ei = object; - return ((ei->tag == *tag)? RMAP_MATCH : RMAP_NOMATCH); - } + return ((ei->tag == *tag) ? RMAP_MATCH : RMAP_NOMATCH); + } - return RMAP_NOMATCH; + return RMAP_NOMATCH; } /* Route map commands for tag matching. */ -static struct route_map_rule_cmd route_match_tag_cmd = -{ - "tag", - route_match_tag, - route_map_rule_tag_compile, - route_map_rule_tag_free, +static struct route_map_rule_cmd route_match_tag_cmd = { + "tag", route_match_tag, route_map_rule_tag_compile, + route_map_rule_tag_free, }; /* `set metric METRIC' */ /* Set metric to attribute. */ -static route_map_result_t -route_set_metric (void *rule, struct prefix *prefix, - route_map_object_t type, void *object) +static route_map_result_t route_set_metric(void *rule, struct prefix *prefix, + route_map_object_t type, + void *object) { - u_int32_t *metric; - struct external_info *ei; - - if (type == RMAP_OSPF) - { - /* Fetch routemap's rule information. */ - metric = rule; - ei = object; - - /* Set metric out value. */ - ei->route_map_set.metric = *metric; - } - return RMAP_OKAY; + u_int32_t *metric; + struct external_info *ei; + + if (type == RMAP_OSPF) { + /* Fetch routemap's rule information. */ + metric = rule; + ei = object; + + /* Set metric out value. */ + ei->route_map_set.metric = *metric; + } + return RMAP_OKAY; } /* set metric compilation. */ -static void * -route_set_metric_compile (const char *arg) -{ - u_int32_t *metric; - - /* OSPF doesn't support the +/- in - set metric <+/-metric> check - Ignore the +/- component */ - if (! all_digit (arg)) - { - if ((arg[0] == '+' || arg[0] == '-') && all_digit (arg+1)) - { - zlog_warn ("OSPF does not support 'set metric +/-'"); - arg++; +static void *route_set_metric_compile(const char *arg) +{ + u_int32_t *metric; + + /* OSPF doesn't support the +/- in + set metric <+/-metric> check + Ignore the +/- component */ + if (!all_digit(arg)) { + if ((arg[0] == '+' || arg[0] == '-') && all_digit(arg + 1)) { + zlog_warn("OSPF does not support 'set metric +/-'"); + arg++; + } else { + if (strmatch(arg, "+rtt") || strmatch(arg, "-rtt")) + zlog_warn( + "OSPF does not support 'set metric +rtt / -rtt'"); + return NULL; + } } - else - { - if (strmatch (arg, "+rtt") || strmatch (arg, "-rtt")) - zlog_warn ("OSPF does not support 'set metric +rtt / -rtt'"); - return NULL; - } - } - metric = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t)); - *metric = strtoul (arg, NULL, 10); - - return metric; + metric = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(u_int32_t)); + *metric = strtoul(arg, NULL, 10); + + return metric; } /* Free route map's compiled `set metric' value. */ -static void -route_set_metric_free (void *rule) +static void route_set_metric_free(void *rule) { - XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); } /* Set metric rule structure. */ -struct route_map_rule_cmd route_set_metric_cmd = -{ - "metric", - route_set_metric, - route_set_metric_compile, - route_set_metric_free, +struct route_map_rule_cmd route_set_metric_cmd = { + "metric", route_set_metric, route_set_metric_compile, + route_set_metric_free, }; /* `set metric-type TYPE' */ /* Set metric-type to attribute. */ -static route_map_result_t -route_set_metric_type (void *rule, struct prefix *prefix, - route_map_object_t type, void *object) +static route_map_result_t route_set_metric_type(void *rule, + struct prefix *prefix, + route_map_object_t type, + void *object) { - u_int32_t *metric_type; - struct external_info *ei; - - if (type == RMAP_OSPF) - { - /* Fetch routemap's rule information. */ - metric_type = rule; - ei = object; - - /* Set metric out value. */ - ei->route_map_set.metric_type = *metric_type; - } - return RMAP_OKAY; + u_int32_t *metric_type; + struct external_info *ei; + + if (type == RMAP_OSPF) { + /* Fetch routemap's rule information. */ + metric_type = rule; + ei = object; + + /* Set metric out value. */ + ei->route_map_set.metric_type = *metric_type; + } + return RMAP_OKAY; } /* set metric-type compilation. */ -static void * -route_set_metric_type_compile (const char *arg) +static void *route_set_metric_type_compile(const char *arg) { - u_int32_t *metric_type; + u_int32_t *metric_type; - metric_type = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t)); - if (strcmp (arg, "type-1") == 0) - *metric_type = EXTERNAL_METRIC_TYPE_1; - else if (strcmp (arg, "type-2") == 0) - *metric_type = EXTERNAL_METRIC_TYPE_2; + metric_type = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(u_int32_t)); + if (strcmp(arg, "type-1") == 0) + *metric_type = EXTERNAL_METRIC_TYPE_1; + else if (strcmp(arg, "type-2") == 0) + *metric_type = EXTERNAL_METRIC_TYPE_2; - if (*metric_type == EXTERNAL_METRIC_TYPE_1 || - *metric_type == EXTERNAL_METRIC_TYPE_2) - return metric_type; + if (*metric_type == EXTERNAL_METRIC_TYPE_1 + || *metric_type == EXTERNAL_METRIC_TYPE_2) + return metric_type; - XFREE (MTYPE_ROUTE_MAP_COMPILED, metric_type); - return NULL; + XFREE(MTYPE_ROUTE_MAP_COMPILED, metric_type); + return NULL; } /* Free route map's compiled `set metric-type' value. */ -static void -route_set_metric_type_free (void *rule) +static void route_set_metric_type_free(void *rule) { - XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); } /* Set metric rule structure. */ -struct route_map_rule_cmd route_set_metric_type_cmd = -{ - "metric-type", - route_set_metric_type, - route_set_metric_type_compile, - route_set_metric_type_free, +struct route_map_rule_cmd route_set_metric_type_cmd = { + "metric-type", route_set_metric_type, route_set_metric_type_compile, + route_set_metric_type_free, }; -static route_map_result_t -route_set_tag (void *rule, struct prefix *prefix, - route_map_object_t type, void *object) +static route_map_result_t route_set_tag(void *rule, struct prefix *prefix, + route_map_object_t type, void *object) { - route_tag_t *tag; - struct external_info *ei; + route_tag_t *tag; + struct external_info *ei; - if (type == RMAP_OSPF) - { - tag = rule; - ei = object; + if (type == RMAP_OSPF) { + tag = rule; + ei = object; - /* Set tag value */ - ei->tag=*tag; - } + /* Set tag value */ + ei->tag = *tag; + } - return RMAP_OKAY; + return RMAP_OKAY; } /* Route map commands for tag set. */ -static struct route_map_rule_cmd route_set_tag_cmd = -{ - "tag", - route_set_tag, - route_map_rule_tag_compile, - route_map_rule_tag_free, +static struct route_map_rule_cmd route_set_tag_cmd = { + "tag", route_set_tag, route_map_rule_tag_compile, + route_map_rule_tag_free, }; DEFUN (set_metric_type, @@ -533,9 +477,9 @@ DEFUN (set_metric_type, "OSPF[6] external type 1 metric\n" "OSPF[6] external type 2 metric\n") { - char *ext = argv[2]->text; - return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index), - "metric-type", ext); + char *ext = argv[2]->text; + return generic_set_add(vty, VTY_GET_CONTEXT(route_map_index), + "metric-type", ext); } DEFUN (no_set_metric_type, @@ -547,59 +491,58 @@ DEFUN (no_set_metric_type, "OSPF[6] external type 1 metric\n" "OSPF[6] external type 2 metric\n") { - char *ext = (argc == 4) ? argv[3]->text : NULL; - return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index), - "metric-type", ext); + char *ext = (argc == 4) ? argv[3]->text : NULL; + return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index), + "metric-type", ext); } /* Route-map init */ -void -ospf_route_map_init (void) +void ospf_route_map_init(void) { - route_map_init (); + route_map_init(); + + route_map_add_hook(ospf_route_map_update); + route_map_delete_hook(ospf_route_map_update); + route_map_event_hook(ospf_route_map_event); - route_map_add_hook (ospf_route_map_update); - route_map_delete_hook (ospf_route_map_update); - route_map_event_hook (ospf_route_map_event); + 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_ip_next_hop_hook(generic_match_add); + route_map_no_match_ip_next_hop_hook(generic_match_delete); - route_map_match_ip_next_hop_hook (generic_match_add); - route_map_no_match_ip_next_hop_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_match_ip_address_hook(generic_match_add); + route_map_no_match_ip_address_hook(generic_match_delete); - route_map_match_ip_address_hook (generic_match_add); - route_map_no_match_ip_address_hook (generic_match_delete); + route_map_match_ip_address_prefix_list_hook(generic_match_add); + route_map_no_match_ip_address_prefix_list_hook(generic_match_delete); - route_map_match_ip_address_prefix_list_hook (generic_match_add); - route_map_no_match_ip_address_prefix_list_hook (generic_match_delete); + route_map_match_ip_next_hop_prefix_list_hook(generic_match_add); + route_map_no_match_ip_next_hop_prefix_list_hook(generic_match_delete); - route_map_match_ip_next_hop_prefix_list_hook (generic_match_add); - route_map_no_match_ip_next_hop_prefix_list_hook (generic_match_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_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_set_tag_hook(generic_set_add); + route_map_no_set_tag_hook(generic_set_delete); - route_map_set_tag_hook (generic_set_add); - route_map_no_set_tag_hook (generic_set_delete); - - route_map_install_match (&route_match_ip_nexthop_cmd); - route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd); - route_map_install_match (&route_match_ip_address_cmd); - route_map_install_match (&route_match_ip_address_prefix_list_cmd); - route_map_install_match (&route_match_interface_cmd); - route_map_install_match (&route_match_tag_cmd); + route_map_install_match(&route_match_ip_nexthop_cmd); + route_map_install_match(&route_match_ip_next_hop_prefix_list_cmd); + route_map_install_match(&route_match_ip_address_cmd); + route_map_install_match(&route_match_ip_address_prefix_list_cmd); + route_map_install_match(&route_match_interface_cmd); + route_map_install_match(&route_match_tag_cmd); - route_map_install_set (&route_set_metric_cmd); - route_map_install_set (&route_set_metric_type_cmd); - route_map_install_set (&route_set_tag_cmd); + route_map_install_set(&route_set_metric_cmd); + route_map_install_set(&route_set_metric_type_cmd); + route_map_install_set(&route_set_tag_cmd); - install_element (RMAP_NODE, &set_metric_type_cmd); - install_element (RMAP_NODE, &no_set_metric_type_cmd); + install_element(RMAP_NODE, &set_metric_type_cmd); + install_element(RMAP_NODE, &no_set_metric_type_cmd); } diff --git a/ospfd/ospf_snmp.c b/ospfd/ospf_snmp.c index b491d43ce..6a352380b 100644 --- a/ospfd/ospf_snmp.c +++ b/ospfd/ospf_snmp.c @@ -206,2418 +206,2352 @@ #define STRING ASN_OCTET_STR /* Because DR/DROther values are exhanged wrt RFC */ -#define ISM_SNMP(x) (((x) == ISM_DROther) ? ISM_DR : \ - ((x) == ISM_DR) ? ISM_DROther : (x)) +#define ISM_SNMP(x) \ + (((x) == ISM_DROther) ? ISM_DR : ((x) == ISM_DR) ? ISM_DROther : (x)) /* Declare static local variables for convenience. */ SNMP_LOCAL_VARIABLES /* OSPF-MIB instances. */ -static oid ospf_oid [] = { OSPF2MIB }; -static oid ospf_trap_oid [] = { OSPF2MIB, 16, 2 }; /* Not reverse mappable! */ +static oid ospf_oid[] = {OSPF2MIB}; +static oid ospf_trap_oid[] = {OSPF2MIB, 16, 2}; /* Not reverse mappable! */ /* IP address 0.0.0.0. */ -static struct in_addr ospf_empty_addr = { .s_addr = 0 }; +static struct in_addr ospf_empty_addr = {.s_addr = 0}; /* Hook functions. */ -static u_char *ospfGeneralGroup (struct variable *, oid *, size_t *, - int, size_t *, WriteMethod **); -static u_char *ospfAreaEntry (struct variable *, oid *, size_t *, int, - size_t *, WriteMethod **); -static u_char *ospfStubAreaEntry (struct variable *, oid *, size_t *, - int, size_t *, WriteMethod **); -static u_char *ospfLsdbEntry (struct variable *, oid *, size_t *, int, - size_t *, WriteMethod **); -static u_char *ospfAreaRangeEntry (struct variable *, oid *, size_t *, int, - size_t *, WriteMethod **); -static u_char *ospfHostEntry (struct variable *, oid *, size_t *, int, - size_t *, WriteMethod **); -static u_char *ospfIfEntry (struct variable *, oid *, size_t *, int, - size_t *, WriteMethod **); -static u_char *ospfIfMetricEntry (struct variable *, oid *, size_t *, int, - size_t *, WriteMethod **); -static u_char *ospfVirtIfEntry (struct variable *, oid *, size_t *, int, +static u_char *ospfGeneralGroup(struct variable *, oid *, size_t *, int, size_t *, WriteMethod **); -static u_char *ospfNbrEntry (struct variable *, oid *, size_t *, int, - size_t *, WriteMethod **); -static u_char *ospfVirtNbrEntry (struct variable *, oid *, size_t *, int, +static u_char *ospfAreaEntry(struct variable *, oid *, size_t *, int, size_t *, + WriteMethod **); +static u_char *ospfStubAreaEntry(struct variable *, oid *, size_t *, int, size_t *, WriteMethod **); -static u_char *ospfExtLsdbEntry (struct variable *, oid *, size_t *, int, +static u_char *ospfLsdbEntry(struct variable *, oid *, size_t *, int, size_t *, + WriteMethod **); +static u_char *ospfAreaRangeEntry(struct variable *, oid *, size_t *, int, + size_t *, WriteMethod **); +static u_char *ospfHostEntry(struct variable *, oid *, size_t *, int, size_t *, + WriteMethod **); +static u_char *ospfIfEntry(struct variable *, oid *, size_t *, int, size_t *, + WriteMethod **); +static u_char *ospfIfMetricEntry(struct variable *, oid *, size_t *, int, size_t *, WriteMethod **); -static u_char *ospfAreaAggregateEntry (struct variable *, oid *, size_t *, - int, size_t *, WriteMethod **); - -static struct variable ospf_variables[] = -{ - /* OSPF general variables */ - {OSPFROUTERID, IPADDRESS, RWRITE, ospfGeneralGroup, - 2, {1, 1}}, - {OSPFADMINSTAT, INTEGER, RWRITE, ospfGeneralGroup, - 2, {1, 2}}, - {OSPFVERSIONNUMBER, INTEGER, RONLY, ospfGeneralGroup, - 2, {1, 3}}, - {OSPFAREABDRRTRSTATUS, INTEGER, RONLY, ospfGeneralGroup, - 2, {1, 4}}, - {OSPFASBDRRTRSTATUS, INTEGER, RWRITE, ospfGeneralGroup, - 2, {1, 5}}, - {OSPFEXTERNLSACOUNT, GAUGE, RONLY, ospfGeneralGroup, - 2, {1, 6}}, - {OSPFEXTERNLSACKSUMSUM, INTEGER, RONLY, ospfGeneralGroup, - 2, {1, 7}}, - {OSPFTOSSUPPORT, INTEGER, RWRITE, ospfGeneralGroup, - 2, {1, 8}}, - {OSPFORIGINATENEWLSAS, COUNTER, RONLY, ospfGeneralGroup, - 2, {1, 9}}, - {OSPFRXNEWLSAS, COUNTER, RONLY, ospfGeneralGroup, - 2, {1, 10}}, - {OSPFEXTLSDBLIMIT, INTEGER, RWRITE, ospfGeneralGroup, - 2, {1, 11}}, - {OSPFMULTICASTEXTENSIONS, INTEGER, RWRITE, ospfGeneralGroup, - 2, {1, 12}}, - {OSPFEXITOVERFLOWINTERVAL, INTEGER, RWRITE, ospfGeneralGroup, - 2, {1, 13}}, - {OSPFDEMANDEXTENSIONS, INTEGER, RWRITE, ospfGeneralGroup, - 2, {1, 14}}, - - /* OSPF area data structure. */ - {OSPFAREAID, IPADDRESS, RONLY, ospfAreaEntry, - 3, {2, 1, 1}}, - {OSPFAUTHTYPE, INTEGER, RWRITE, ospfAreaEntry, - 3, {2, 1, 2}}, - {OSPFIMPORTASEXTERN, INTEGER, RWRITE, ospfAreaEntry, - 3, {2, 1, 3}}, - {OSPFSPFRUNS, COUNTER, RONLY, ospfAreaEntry, - 3, {2, 1, 4}}, - {OSPFAREABDRRTRCOUNT, GAUGE, RONLY, ospfAreaEntry, - 3, {2, 1, 5}}, - {OSPFASBDRRTRCOUNT, GAUGE, RONLY, ospfAreaEntry, - 3, {2, 1, 6}}, - {OSPFAREALSACOUNT, GAUGE, RONLY, ospfAreaEntry, - 3, {2, 1, 7}}, - {OSPFAREALSACKSUMSUM, INTEGER, RONLY, ospfAreaEntry, - 3, {2, 1, 8}}, - {OSPFAREASUMMARY, INTEGER, RWRITE, ospfAreaEntry, - 3, {2, 1, 9}}, - {OSPFAREASTATUS, INTEGER, RWRITE, ospfAreaEntry, - 3, {2, 1, 10}}, - - /* OSPF stub area information. */ - {OSPFSTUBAREAID, IPADDRESS, RONLY, ospfStubAreaEntry, - 3, {3, 1, 1}}, - {OSPFSTUBTOS, INTEGER, RONLY, ospfStubAreaEntry, - 3, {3, 1, 2}}, - {OSPFSTUBMETRIC, INTEGER, RWRITE, ospfStubAreaEntry, - 3, {3, 1, 3}}, - {OSPFSTUBSTATUS, INTEGER, RWRITE, ospfStubAreaEntry, - 3, {3, 1, 4}}, - {OSPFSTUBMETRICTYPE, INTEGER, RWRITE, ospfStubAreaEntry, - 3, {3, 1, 5}}, - - /* OSPF link state database. */ - {OSPFLSDBAREAID, IPADDRESS, RONLY, ospfLsdbEntry, - 3, {4, 1, 1}}, - {OSPFLSDBTYPE, INTEGER, RONLY, ospfLsdbEntry, - 3, {4, 1, 2}}, - {OSPFLSDBLSID, IPADDRESS, RONLY, ospfLsdbEntry, - 3, {4, 1, 3}}, - {OSPFLSDBROUTERID, IPADDRESS, RONLY, ospfLsdbEntry, - 3, {4, 1, 4}}, - {OSPFLSDBSEQUENCE, INTEGER, RONLY, ospfLsdbEntry, - 3, {4, 1, 5}}, - {OSPFLSDBAGE, INTEGER, RONLY, ospfLsdbEntry, - 3, {4, 1, 6}}, - {OSPFLSDBCHECKSUM, INTEGER, RONLY, ospfLsdbEntry, - 3, {4, 1, 7}}, - {OSPFLSDBADVERTISEMENT, STRING, RONLY, ospfLsdbEntry, - 3, {4, 1, 8}}, - - /* Area range table. */ - {OSPFAREARANGEAREAID, IPADDRESS, RONLY, ospfAreaRangeEntry, - 3, {5, 1, 1}}, - {OSPFAREARANGENET, IPADDRESS, RONLY, ospfAreaRangeEntry, - 3, {5, 1, 2}}, - {OSPFAREARANGEMASK, IPADDRESS, RWRITE, ospfAreaRangeEntry, - 3, {5, 1, 3}}, - {OSPFAREARANGESTATUS, INTEGER, RWRITE, ospfAreaRangeEntry, - 3, {5, 1, 4}}, - {OSPFAREARANGEEFFECT, INTEGER, RWRITE, ospfAreaRangeEntry, - 3, {5, 1, 5}}, - - /* OSPF host table. */ - {OSPFHOSTIPADDRESS, IPADDRESS, RONLY, ospfHostEntry, - 3, {6, 1, 1}}, - {OSPFHOSTTOS, INTEGER, RONLY, ospfHostEntry, - 3, {6, 1, 2}}, - {OSPFHOSTMETRIC, INTEGER, RWRITE, ospfHostEntry, - 3, {6, 1, 3}}, - {OSPFHOSTSTATUS, INTEGER, RWRITE, ospfHostEntry, - 3, {6, 1, 4}}, - {OSPFHOSTAREAID, IPADDRESS, RONLY, ospfHostEntry, - 3, {6, 1, 5}}, - - /* OSPF interface table. */ - {OSPFIFIPADDRESS, IPADDRESS, RONLY, ospfIfEntry, - 3, {7, 1, 1}}, - {OSPFADDRESSLESSIF, INTEGER, RONLY, ospfIfEntry, - 3, {7, 1, 2}}, - {OSPFIFAREAID, IPADDRESS, RWRITE, ospfIfEntry, - 3, {7, 1, 3}}, - {OSPFIFTYPE, INTEGER, RWRITE, ospfIfEntry, - 3, {7, 1, 4}}, - {OSPFIFADMINSTAT, INTEGER, RWRITE, ospfIfEntry, - 3, {7, 1, 5}}, - {OSPFIFRTRPRIORITY, INTEGER, RWRITE, ospfIfEntry, - 3, {7, 1, 6}}, - {OSPFIFTRANSITDELAY, INTEGER, RWRITE, ospfIfEntry, - 3, {7, 1, 7}}, - {OSPFIFRETRANSINTERVAL, INTEGER, RWRITE, ospfIfEntry, - 3, {7, 1, 8}}, - {OSPFIFHELLOINTERVAL, INTEGER, RWRITE, ospfIfEntry, - 3, {7, 1, 9}}, - {OSPFIFRTRDEADINTERVAL, INTEGER, RWRITE, ospfIfEntry, - 3, {7, 1, 10}}, - {OSPFIFPOLLINTERVAL, INTEGER, RWRITE, ospfIfEntry, - 3, {7, 1, 11}}, - {OSPFIFSTATE, INTEGER, RONLY, ospfIfEntry, - 3, {7, 1, 12}}, - {OSPFIFDESIGNATEDROUTER, IPADDRESS, RONLY, ospfIfEntry, - 3, {7, 1, 13}}, - {OSPFIFBACKUPDESIGNATEDROUTER, IPADDRESS, RONLY, ospfIfEntry, - 3, {7, 1, 14}}, - {OSPFIFEVENTS, COUNTER, RONLY, ospfIfEntry, - 3, {7, 1, 15}}, - {OSPFIFAUTHKEY, STRING, RWRITE, ospfIfEntry, - 3, {7, 1, 16}}, - {OSPFIFSTATUS, INTEGER, RWRITE, ospfIfEntry, - 3, {7, 1, 17}}, - {OSPFIFMULTICASTFORWARDING, INTEGER, RWRITE, ospfIfEntry, - 3, {7, 1, 18}}, - {OSPFIFDEMAND, INTEGER, RWRITE, ospfIfEntry, - 3, {7, 1, 19}}, - {OSPFIFAUTHTYPE, INTEGER, RWRITE, ospfIfEntry, - 3, {7, 1, 20}}, - - /* OSPF interface metric table. */ - {OSPFIFMETRICIPADDRESS, IPADDRESS, RONLY, ospfIfMetricEntry, - 3, {8, 1, 1}}, - {OSPFIFMETRICADDRESSLESSIF, INTEGER, RONLY, ospfIfMetricEntry, - 3, {8, 1, 2}}, - {OSPFIFMETRICTOS, INTEGER, RONLY, ospfIfMetricEntry, - 3, {8, 1, 3}}, - {OSPFIFMETRICVALUE, INTEGER, RWRITE, ospfIfMetricEntry, - 3, {8, 1, 4}}, - {OSPFIFMETRICSTATUS, INTEGER, RWRITE, ospfIfMetricEntry, - 3, {8, 1, 5}}, - - /* OSPF virtual interface table. */ - {OSPFVIRTIFAREAID, IPADDRESS, RONLY, ospfVirtIfEntry, - 3, {9, 1, 1}}, - {OSPFVIRTIFNEIGHBOR, IPADDRESS, RONLY, ospfVirtIfEntry, - 3, {9, 1, 2}}, - {OSPFVIRTIFTRANSITDELAY, INTEGER, RWRITE, ospfVirtIfEntry, - 3, {9, 1, 3}}, - {OSPFVIRTIFRETRANSINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry, - 3, {9, 1, 4}}, - {OSPFVIRTIFHELLOINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry, - 3, {9, 1, 5}}, - {OSPFVIRTIFRTRDEADINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry, - 3, {9, 1, 6}}, - {OSPFVIRTIFSTATE, INTEGER, RONLY, ospfVirtIfEntry, - 3, {9, 1, 7}}, - {OSPFVIRTIFEVENTS, COUNTER, RONLY, ospfVirtIfEntry, - 3, {9, 1, 8}}, - {OSPFVIRTIFAUTHKEY, STRING, RWRITE, ospfVirtIfEntry, - 3, {9, 1, 9}}, - {OSPFVIRTIFSTATUS, INTEGER, RWRITE, ospfVirtIfEntry, - 3, {9, 1, 10}}, - {OSPFVIRTIFAUTHTYPE, INTEGER, RWRITE, ospfVirtIfEntry, - 3, {9, 1, 11}}, - - /* OSPF neighbor table. */ - {OSPFNBRIPADDR, IPADDRESS, RONLY, ospfNbrEntry, - 3, {10, 1, 1}}, - {OSPFNBRADDRESSLESSINDEX, INTEGER, RONLY, ospfNbrEntry, - 3, {10, 1, 2}}, - {OSPFNBRRTRID, IPADDRESS, RONLY, ospfNbrEntry, - 3, {10, 1, 3}}, - {OSPFNBROPTIONS, INTEGER, RONLY, ospfNbrEntry, - 3, {10, 1, 4}}, - {OSPFNBRPRIORITY, INTEGER, RWRITE, ospfNbrEntry, - 3, {10, 1, 5}}, - {OSPFNBRSTATE, INTEGER, RONLY, ospfNbrEntry, - 3, {10, 1, 6}}, - {OSPFNBREVENTS, COUNTER, RONLY, ospfNbrEntry, - 3, {10, 1, 7}}, - {OSPFNBRLSRETRANSQLEN, GAUGE, RONLY, ospfNbrEntry, - 3, {10, 1, 8}}, - {OSPFNBMANBRSTATUS, INTEGER, RWRITE, ospfNbrEntry, - 3, {10, 1, 9}}, - {OSPFNBMANBRPERMANENCE, INTEGER, RONLY, ospfNbrEntry, - 3, {10, 1, 10}}, - {OSPFNBRHELLOSUPPRESSED, INTEGER, RONLY, ospfNbrEntry, - 3, {10, 1, 11}}, - - /* OSPF virtual neighbor table. */ - {OSPFVIRTNBRAREA, IPADDRESS, RONLY, ospfVirtNbrEntry, - 3, {11, 1, 1}}, - {OSPFVIRTNBRRTRID, IPADDRESS, RONLY, ospfVirtNbrEntry, - 3, {11, 1, 2}}, - {OSPFVIRTNBRIPADDR, IPADDRESS, RONLY, ospfVirtNbrEntry, - 3, {11, 1, 3}}, - {OSPFVIRTNBROPTIONS, INTEGER, RONLY, ospfVirtNbrEntry, - 3, {11, 1, 4}}, - {OSPFVIRTNBRSTATE, INTEGER, RONLY, ospfVirtNbrEntry, - 3, {11, 1, 5}}, - {OSPFVIRTNBREVENTS, COUNTER, RONLY, ospfVirtNbrEntry, - 3, {11, 1, 6}}, - {OSPFVIRTNBRLSRETRANSQLEN, INTEGER, RONLY, ospfVirtNbrEntry, - 3, {11, 1, 7}}, - {OSPFVIRTNBRHELLOSUPPRESSED, INTEGER, RONLY, ospfVirtNbrEntry, - 3, {11, 1, 8}}, - - /* OSPF link state database, external. */ - {OSPFEXTLSDBTYPE, INTEGER, RONLY, ospfExtLsdbEntry, - 3, {12, 1, 1}}, - {OSPFEXTLSDBLSID, IPADDRESS, RONLY, ospfExtLsdbEntry, - 3, {12, 1, 2}}, - {OSPFEXTLSDBROUTERID, IPADDRESS, RONLY, ospfExtLsdbEntry, - 3, {12, 1, 3}}, - {OSPFEXTLSDBSEQUENCE, INTEGER, RONLY, ospfExtLsdbEntry, - 3, {12, 1, 4}}, - {OSPFEXTLSDBAGE, INTEGER, RONLY, ospfExtLsdbEntry, - 3, {12, 1, 5}}, - {OSPFEXTLSDBCHECKSUM, INTEGER, RONLY, ospfExtLsdbEntry, - 3, {12, 1, 6}}, - {OSPFEXTLSDBADVERTISEMENT, STRING, RONLY, ospfExtLsdbEntry, - 3, {12, 1, 7}}, - - /* OSPF area aggregate table. */ - {OSPFAREAAGGREGATEAREAID, IPADDRESS, RONLY, ospfAreaAggregateEntry, - 3, {14, 1, 1}}, - {OSPFAREAAGGREGATELSDBTYPE, INTEGER, RONLY, ospfAreaAggregateEntry, - 3, {14, 1, 2}}, - {OSPFAREAAGGREGATENET, IPADDRESS, RONLY, ospfAreaAggregateEntry, - 3, {14, 1, 3}}, - {OSPFAREAAGGREGATEMASK, IPADDRESS, RONLY, ospfAreaAggregateEntry, - 3, {14, 1, 4}}, - {OSPFAREAAGGREGATESTATUS, INTEGER, RWRITE, ospfAreaAggregateEntry, - 3, {14, 1, 5}}, - {OSPFAREAAGGREGATEEFFECT, INTEGER, RWRITE, ospfAreaAggregateEntry, - 3, {14, 1, 6}} -}; +static u_char *ospfVirtIfEntry(struct variable *, oid *, size_t *, int, + size_t *, WriteMethod **); +static u_char *ospfNbrEntry(struct variable *, oid *, size_t *, int, size_t *, + WriteMethod **); +static u_char *ospfVirtNbrEntry(struct variable *, oid *, size_t *, int, + size_t *, WriteMethod **); +static u_char *ospfExtLsdbEntry(struct variable *, oid *, size_t *, int, + size_t *, WriteMethod **); +static u_char *ospfAreaAggregateEntry(struct variable *, oid *, size_t *, int, + size_t *, WriteMethod **); + +static struct variable ospf_variables[] = { + /* OSPF general variables */ + {OSPFROUTERID, IPADDRESS, RWRITE, ospfGeneralGroup, 2, {1, 1}}, + {OSPFADMINSTAT, INTEGER, RWRITE, ospfGeneralGroup, 2, {1, 2}}, + {OSPFVERSIONNUMBER, INTEGER, RONLY, ospfGeneralGroup, 2, {1, 3}}, + {OSPFAREABDRRTRSTATUS, INTEGER, RONLY, ospfGeneralGroup, 2, {1, 4}}, + {OSPFASBDRRTRSTATUS, INTEGER, RWRITE, ospfGeneralGroup, 2, {1, 5}}, + {OSPFEXTERNLSACOUNT, GAUGE, RONLY, ospfGeneralGroup, 2, {1, 6}}, + {OSPFEXTERNLSACKSUMSUM, INTEGER, RONLY, ospfGeneralGroup, 2, {1, 7}}, + {OSPFTOSSUPPORT, INTEGER, RWRITE, ospfGeneralGroup, 2, {1, 8}}, + {OSPFORIGINATENEWLSAS, COUNTER, RONLY, ospfGeneralGroup, 2, {1, 9}}, + {OSPFRXNEWLSAS, COUNTER, RONLY, ospfGeneralGroup, 2, {1, 10}}, + {OSPFEXTLSDBLIMIT, INTEGER, RWRITE, ospfGeneralGroup, 2, {1, 11}}, + {OSPFMULTICASTEXTENSIONS, + INTEGER, + RWRITE, + ospfGeneralGroup, + 2, + {1, 12}}, + {OSPFEXITOVERFLOWINTERVAL, + INTEGER, + RWRITE, + ospfGeneralGroup, + 2, + {1, 13}}, + {OSPFDEMANDEXTENSIONS, INTEGER, RWRITE, ospfGeneralGroup, 2, {1, 14}}, + + /* OSPF area data structure. */ + {OSPFAREAID, IPADDRESS, RONLY, ospfAreaEntry, 3, {2, 1, 1}}, + {OSPFAUTHTYPE, INTEGER, RWRITE, ospfAreaEntry, 3, {2, 1, 2}}, + {OSPFIMPORTASEXTERN, INTEGER, RWRITE, ospfAreaEntry, 3, {2, 1, 3}}, + {OSPFSPFRUNS, COUNTER, RONLY, ospfAreaEntry, 3, {2, 1, 4}}, + {OSPFAREABDRRTRCOUNT, GAUGE, RONLY, ospfAreaEntry, 3, {2, 1, 5}}, + {OSPFASBDRRTRCOUNT, GAUGE, RONLY, ospfAreaEntry, 3, {2, 1, 6}}, + {OSPFAREALSACOUNT, GAUGE, RONLY, ospfAreaEntry, 3, {2, 1, 7}}, + {OSPFAREALSACKSUMSUM, INTEGER, RONLY, ospfAreaEntry, 3, {2, 1, 8}}, + {OSPFAREASUMMARY, INTEGER, RWRITE, ospfAreaEntry, 3, {2, 1, 9}}, + {OSPFAREASTATUS, INTEGER, RWRITE, ospfAreaEntry, 3, {2, 1, 10}}, + + /* OSPF stub area information. */ + {OSPFSTUBAREAID, IPADDRESS, RONLY, ospfStubAreaEntry, 3, {3, 1, 1}}, + {OSPFSTUBTOS, INTEGER, RONLY, ospfStubAreaEntry, 3, {3, 1, 2}}, + {OSPFSTUBMETRIC, INTEGER, RWRITE, ospfStubAreaEntry, 3, {3, 1, 3}}, + {OSPFSTUBSTATUS, INTEGER, RWRITE, ospfStubAreaEntry, 3, {3, 1, 4}}, + {OSPFSTUBMETRICTYPE, INTEGER, RWRITE, ospfStubAreaEntry, 3, {3, 1, 5}}, + + /* OSPF link state database. */ + {OSPFLSDBAREAID, IPADDRESS, RONLY, ospfLsdbEntry, 3, {4, 1, 1}}, + {OSPFLSDBTYPE, INTEGER, RONLY, ospfLsdbEntry, 3, {4, 1, 2}}, + {OSPFLSDBLSID, IPADDRESS, RONLY, ospfLsdbEntry, 3, {4, 1, 3}}, + {OSPFLSDBROUTERID, IPADDRESS, RONLY, ospfLsdbEntry, 3, {4, 1, 4}}, + {OSPFLSDBSEQUENCE, INTEGER, RONLY, ospfLsdbEntry, 3, {4, 1, 5}}, + {OSPFLSDBAGE, INTEGER, RONLY, ospfLsdbEntry, 3, {4, 1, 6}}, + {OSPFLSDBCHECKSUM, INTEGER, RONLY, ospfLsdbEntry, 3, {4, 1, 7}}, + {OSPFLSDBADVERTISEMENT, STRING, RONLY, ospfLsdbEntry, 3, {4, 1, 8}}, + + /* Area range table. */ + {OSPFAREARANGEAREAID, + IPADDRESS, + RONLY, + ospfAreaRangeEntry, + 3, + {5, 1, 1}}, + {OSPFAREARANGENET, IPADDRESS, RONLY, ospfAreaRangeEntry, 3, {5, 1, 2}}, + {OSPFAREARANGEMASK, + IPADDRESS, + RWRITE, + ospfAreaRangeEntry, + 3, + {5, 1, 3}}, + {OSPFAREARANGESTATUS, + INTEGER, + RWRITE, + ospfAreaRangeEntry, + 3, + {5, 1, 4}}, + {OSPFAREARANGEEFFECT, + INTEGER, + RWRITE, + ospfAreaRangeEntry, + 3, + {5, 1, 5}}, + + /* OSPF host table. */ + {OSPFHOSTIPADDRESS, IPADDRESS, RONLY, ospfHostEntry, 3, {6, 1, 1}}, + {OSPFHOSTTOS, INTEGER, RONLY, ospfHostEntry, 3, {6, 1, 2}}, + {OSPFHOSTMETRIC, INTEGER, RWRITE, ospfHostEntry, 3, {6, 1, 3}}, + {OSPFHOSTSTATUS, INTEGER, RWRITE, ospfHostEntry, 3, {6, 1, 4}}, + {OSPFHOSTAREAID, IPADDRESS, RONLY, ospfHostEntry, 3, {6, 1, 5}}, + + /* OSPF interface table. */ + {OSPFIFIPADDRESS, IPADDRESS, RONLY, ospfIfEntry, 3, {7, 1, 1}}, + {OSPFADDRESSLESSIF, INTEGER, RONLY, ospfIfEntry, 3, {7, 1, 2}}, + {OSPFIFAREAID, IPADDRESS, RWRITE, ospfIfEntry, 3, {7, 1, 3}}, + {OSPFIFTYPE, INTEGER, RWRITE, ospfIfEntry, 3, {7, 1, 4}}, + {OSPFIFADMINSTAT, INTEGER, RWRITE, ospfIfEntry, 3, {7, 1, 5}}, + {OSPFIFRTRPRIORITY, INTEGER, RWRITE, ospfIfEntry, 3, {7, 1, 6}}, + {OSPFIFTRANSITDELAY, INTEGER, RWRITE, ospfIfEntry, 3, {7, 1, 7}}, + {OSPFIFRETRANSINTERVAL, INTEGER, RWRITE, ospfIfEntry, 3, {7, 1, 8}}, + {OSPFIFHELLOINTERVAL, INTEGER, RWRITE, ospfIfEntry, 3, {7, 1, 9}}, + {OSPFIFRTRDEADINTERVAL, INTEGER, RWRITE, ospfIfEntry, 3, {7, 1, 10}}, + {OSPFIFPOLLINTERVAL, INTEGER, RWRITE, ospfIfEntry, 3, {7, 1, 11}}, + {OSPFIFSTATE, INTEGER, RONLY, ospfIfEntry, 3, {7, 1, 12}}, + {OSPFIFDESIGNATEDROUTER, IPADDRESS, RONLY, ospfIfEntry, 3, {7, 1, 13}}, + {OSPFIFBACKUPDESIGNATEDROUTER, + IPADDRESS, + RONLY, + ospfIfEntry, + 3, + {7, 1, 14}}, + {OSPFIFEVENTS, COUNTER, RONLY, ospfIfEntry, 3, {7, 1, 15}}, + {OSPFIFAUTHKEY, STRING, RWRITE, ospfIfEntry, 3, {7, 1, 16}}, + {OSPFIFSTATUS, INTEGER, RWRITE, ospfIfEntry, 3, {7, 1, 17}}, + {OSPFIFMULTICASTFORWARDING, + INTEGER, + RWRITE, + ospfIfEntry, + 3, + {7, 1, 18}}, + {OSPFIFDEMAND, INTEGER, RWRITE, ospfIfEntry, 3, {7, 1, 19}}, + {OSPFIFAUTHTYPE, INTEGER, RWRITE, ospfIfEntry, 3, {7, 1, 20}}, + + /* OSPF interface metric table. */ + {OSPFIFMETRICIPADDRESS, + IPADDRESS, + RONLY, + ospfIfMetricEntry, + 3, + {8, 1, 1}}, + {OSPFIFMETRICADDRESSLESSIF, + INTEGER, + RONLY, + ospfIfMetricEntry, + 3, + {8, 1, 2}}, + {OSPFIFMETRICTOS, INTEGER, RONLY, ospfIfMetricEntry, 3, {8, 1, 3}}, + {OSPFIFMETRICVALUE, INTEGER, RWRITE, ospfIfMetricEntry, 3, {8, 1, 4}}, + {OSPFIFMETRICSTATUS, INTEGER, RWRITE, ospfIfMetricEntry, 3, {8, 1, 5}}, + + /* OSPF virtual interface table. */ + {OSPFVIRTIFAREAID, IPADDRESS, RONLY, ospfVirtIfEntry, 3, {9, 1, 1}}, + {OSPFVIRTIFNEIGHBOR, IPADDRESS, RONLY, ospfVirtIfEntry, 3, {9, 1, 2}}, + {OSPFVIRTIFTRANSITDELAY, + INTEGER, + RWRITE, + ospfVirtIfEntry, + 3, + {9, 1, 3}}, + {OSPFVIRTIFRETRANSINTERVAL, + INTEGER, + RWRITE, + ospfVirtIfEntry, + 3, + {9, 1, 4}}, + {OSPFVIRTIFHELLOINTERVAL, + INTEGER, + RWRITE, + ospfVirtIfEntry, + 3, + {9, 1, 5}}, + {OSPFVIRTIFRTRDEADINTERVAL, + INTEGER, + RWRITE, + ospfVirtIfEntry, + 3, + {9, 1, 6}}, + {OSPFVIRTIFSTATE, INTEGER, RONLY, ospfVirtIfEntry, 3, {9, 1, 7}}, + {OSPFVIRTIFEVENTS, COUNTER, RONLY, ospfVirtIfEntry, 3, {9, 1, 8}}, + {OSPFVIRTIFAUTHKEY, STRING, RWRITE, ospfVirtIfEntry, 3, {9, 1, 9}}, + {OSPFVIRTIFSTATUS, INTEGER, RWRITE, ospfVirtIfEntry, 3, {9, 1, 10}}, + {OSPFVIRTIFAUTHTYPE, INTEGER, RWRITE, ospfVirtIfEntry, 3, {9, 1, 11}}, + + /* OSPF neighbor table. */ + {OSPFNBRIPADDR, IPADDRESS, RONLY, ospfNbrEntry, 3, {10, 1, 1}}, + {OSPFNBRADDRESSLESSINDEX, INTEGER, RONLY, ospfNbrEntry, 3, {10, 1, 2}}, + {OSPFNBRRTRID, IPADDRESS, RONLY, ospfNbrEntry, 3, {10, 1, 3}}, + {OSPFNBROPTIONS, INTEGER, RONLY, ospfNbrEntry, 3, {10, 1, 4}}, + {OSPFNBRPRIORITY, INTEGER, RWRITE, ospfNbrEntry, 3, {10, 1, 5}}, + {OSPFNBRSTATE, INTEGER, RONLY, ospfNbrEntry, 3, {10, 1, 6}}, + {OSPFNBREVENTS, COUNTER, RONLY, ospfNbrEntry, 3, {10, 1, 7}}, + {OSPFNBRLSRETRANSQLEN, GAUGE, RONLY, ospfNbrEntry, 3, {10, 1, 8}}, + {OSPFNBMANBRSTATUS, INTEGER, RWRITE, ospfNbrEntry, 3, {10, 1, 9}}, + {OSPFNBMANBRPERMANENCE, INTEGER, RONLY, ospfNbrEntry, 3, {10, 1, 10}}, + {OSPFNBRHELLOSUPPRESSED, INTEGER, RONLY, ospfNbrEntry, 3, {10, 1, 11}}, + + /* OSPF virtual neighbor table. */ + {OSPFVIRTNBRAREA, IPADDRESS, RONLY, ospfVirtNbrEntry, 3, {11, 1, 1}}, + {OSPFVIRTNBRRTRID, IPADDRESS, RONLY, ospfVirtNbrEntry, 3, {11, 1, 2}}, + {OSPFVIRTNBRIPADDR, IPADDRESS, RONLY, ospfVirtNbrEntry, 3, {11, 1, 3}}, + {OSPFVIRTNBROPTIONS, INTEGER, RONLY, ospfVirtNbrEntry, 3, {11, 1, 4}}, + {OSPFVIRTNBRSTATE, INTEGER, RONLY, ospfVirtNbrEntry, 3, {11, 1, 5}}, + {OSPFVIRTNBREVENTS, COUNTER, RONLY, ospfVirtNbrEntry, 3, {11, 1, 6}}, + {OSPFVIRTNBRLSRETRANSQLEN, + INTEGER, + RONLY, + ospfVirtNbrEntry, + 3, + {11, 1, 7}}, + {OSPFVIRTNBRHELLOSUPPRESSED, + INTEGER, + RONLY, + ospfVirtNbrEntry, + 3, + {11, 1, 8}}, + + /* OSPF link state database, external. */ + {OSPFEXTLSDBTYPE, INTEGER, RONLY, ospfExtLsdbEntry, 3, {12, 1, 1}}, + {OSPFEXTLSDBLSID, IPADDRESS, RONLY, ospfExtLsdbEntry, 3, {12, 1, 2}}, + {OSPFEXTLSDBROUTERID, + IPADDRESS, + RONLY, + ospfExtLsdbEntry, + 3, + {12, 1, 3}}, + {OSPFEXTLSDBSEQUENCE, INTEGER, RONLY, ospfExtLsdbEntry, 3, {12, 1, 4}}, + {OSPFEXTLSDBAGE, INTEGER, RONLY, ospfExtLsdbEntry, 3, {12, 1, 5}}, + {OSPFEXTLSDBCHECKSUM, INTEGER, RONLY, ospfExtLsdbEntry, 3, {12, 1, 6}}, + {OSPFEXTLSDBADVERTISEMENT, + STRING, + RONLY, + ospfExtLsdbEntry, + 3, + {12, 1, 7}}, + + /* OSPF area aggregate table. */ + {OSPFAREAAGGREGATEAREAID, + IPADDRESS, + RONLY, + ospfAreaAggregateEntry, + 3, + {14, 1, 1}}, + {OSPFAREAAGGREGATELSDBTYPE, + INTEGER, + RONLY, + ospfAreaAggregateEntry, + 3, + {14, 1, 2}}, + {OSPFAREAAGGREGATENET, + IPADDRESS, + RONLY, + ospfAreaAggregateEntry, + 3, + {14, 1, 3}}, + {OSPFAREAAGGREGATEMASK, + IPADDRESS, + RONLY, + ospfAreaAggregateEntry, + 3, + {14, 1, 4}}, + {OSPFAREAAGGREGATESTATUS, + INTEGER, + RWRITE, + ospfAreaAggregateEntry, + 3, + {14, 1, 5}}, + {OSPFAREAAGGREGATEEFFECT, + INTEGER, + RWRITE, + ospfAreaAggregateEntry, + 3, + {14, 1, 6}}}; /* The administrative status of OSPF. When OSPF is enbled on at least one interface return 1. */ -static int -ospf_admin_stat (struct ospf *ospf) +static int ospf_admin_stat(struct ospf *ospf) { - struct listnode *node; - struct ospf_interface *oi; + struct listnode *node; + struct ospf_interface *oi; - if (ospf == NULL) - return 0; + if (ospf == NULL) + return 0; - for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) - if (oi && oi->address) - return 1; + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) + if (oi && oi->address) + return 1; - return 0; + return 0; } -static u_char * -ospfGeneralGroup (struct variable *v, oid *name, size_t *length, - int exact, size_t *var_len, WriteMethod **write_method) +static u_char *ospfGeneralGroup(struct variable *v, oid *name, size_t *length, + int exact, size_t *var_len, + WriteMethod **write_method) { - struct ospf *ospf; - - ospf = ospf_lookup (); - - /* 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 OSPFROUTERID: /* 1 */ - /* Router-ID of this OSPF instance. */ - if (ospf) - return SNMP_IPADDRESS (ospf->router_id); - else - return SNMP_IPADDRESS (ospf_empty_addr); - break; - case OSPFADMINSTAT: /* 2 */ - /* The administrative status of OSPF in the router. */ - if (ospf_admin_stat (ospf)) - return SNMP_INTEGER (OSPF_STATUS_ENABLED); - else - return SNMP_INTEGER (OSPF_STATUS_DISABLED); - break; - case OSPFVERSIONNUMBER: /* 3 */ - /* OSPF version 2. */ - return SNMP_INTEGER (OSPF_VERSION); - break; - case OSPFAREABDRRTRSTATUS: /* 4 */ - /* Area Border router status. */ - if (ospf && CHECK_FLAG (ospf->flags, OSPF_FLAG_ABR)) - return SNMP_INTEGER (SNMP_TRUE); - else - return SNMP_INTEGER (SNMP_FALSE); - break; - case OSPFASBDRRTRSTATUS: /* 5 */ - /* AS Border router status. */ - if (ospf && CHECK_FLAG (ospf->flags, OSPF_FLAG_ASBR)) - return SNMP_INTEGER (SNMP_TRUE); - else - return SNMP_INTEGER (SNMP_FALSE); - break; - case OSPFEXTERNLSACOUNT: /* 6 */ - /* External LSA counts. */ - if (ospf) - return SNMP_INTEGER (ospf_lsdb_count_all (ospf->lsdb)); - else - return SNMP_INTEGER (0); - break; - case OSPFEXTERNLSACKSUMSUM: /* 7 */ - /* External LSA checksum. */ - return SNMP_INTEGER (0); - break; - case OSPFTOSSUPPORT: /* 8 */ - /* TOS is not supported. */ - return SNMP_INTEGER (SNMP_FALSE); - break; - case OSPFORIGINATENEWLSAS: /* 9 */ - /* The number of new link-state advertisements. */ - if (ospf) - return SNMP_INTEGER (ospf->lsa_originate_count); - else - return SNMP_INTEGER (0); - break; - case OSPFRXNEWLSAS: /* 10 */ - /* The number of link-state advertisements received determined - to be new instantiations. */ - if (ospf) - return SNMP_INTEGER (ospf->rx_lsa_count); - else - return SNMP_INTEGER (0); - break; - case OSPFEXTLSDBLIMIT: /* 11 */ - /* There is no limit for the number of non-default - AS-external-LSAs. */ - return SNMP_INTEGER (-1); - break; - case OSPFMULTICASTEXTENSIONS: /* 12 */ - /* Multicast Extensions to OSPF is not supported. */ - return SNMP_INTEGER (0); - break; - case OSPFEXITOVERFLOWINTERVAL: /* 13 */ - /* Overflow is not supported. */ - return SNMP_INTEGER (0); - break; - case OSPFDEMANDEXTENSIONS: /* 14 */ - /* Demand routing is not supported. */ - return SNMP_INTEGER (SNMP_FALSE); - break; - default: - return NULL; - } - return NULL; + struct ospf *ospf; + + ospf = ospf_lookup(); + + /* 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 OSPFROUTERID: /* 1 */ + /* Router-ID of this OSPF instance. */ + if (ospf) + return SNMP_IPADDRESS(ospf->router_id); + else + return SNMP_IPADDRESS(ospf_empty_addr); + break; + case OSPFADMINSTAT: /* 2 */ + /* The administrative status of OSPF in the router. */ + if (ospf_admin_stat(ospf)) + return SNMP_INTEGER(OSPF_STATUS_ENABLED); + else + return SNMP_INTEGER(OSPF_STATUS_DISABLED); + break; + case OSPFVERSIONNUMBER: /* 3 */ + /* OSPF version 2. */ + return SNMP_INTEGER(OSPF_VERSION); + break; + case OSPFAREABDRRTRSTATUS: /* 4 */ + /* Area Border router status. */ + if (ospf && CHECK_FLAG(ospf->flags, OSPF_FLAG_ABR)) + return SNMP_INTEGER(SNMP_TRUE); + else + return SNMP_INTEGER(SNMP_FALSE); + break; + case OSPFASBDRRTRSTATUS: /* 5 */ + /* AS Border router status. */ + if (ospf && CHECK_FLAG(ospf->flags, OSPF_FLAG_ASBR)) + return SNMP_INTEGER(SNMP_TRUE); + else + return SNMP_INTEGER(SNMP_FALSE); + break; + case OSPFEXTERNLSACOUNT: /* 6 */ + /* External LSA counts. */ + if (ospf) + return SNMP_INTEGER(ospf_lsdb_count_all(ospf->lsdb)); + else + return SNMP_INTEGER(0); + break; + case OSPFEXTERNLSACKSUMSUM: /* 7 */ + /* External LSA checksum. */ + return SNMP_INTEGER(0); + break; + case OSPFTOSSUPPORT: /* 8 */ + /* TOS is not supported. */ + return SNMP_INTEGER(SNMP_FALSE); + break; + case OSPFORIGINATENEWLSAS: /* 9 */ + /* The number of new link-state advertisements. */ + if (ospf) + return SNMP_INTEGER(ospf->lsa_originate_count); + else + return SNMP_INTEGER(0); + break; + case OSPFRXNEWLSAS: /* 10 */ + /* The number of link-state advertisements received determined + to be new instantiations. */ + if (ospf) + return SNMP_INTEGER(ospf->rx_lsa_count); + else + return SNMP_INTEGER(0); + break; + case OSPFEXTLSDBLIMIT: /* 11 */ + /* There is no limit for the number of non-default + AS-external-LSAs. */ + return SNMP_INTEGER(-1); + break; + case OSPFMULTICASTEXTENSIONS: /* 12 */ + /* Multicast Extensions to OSPF is not supported. */ + return SNMP_INTEGER(0); + break; + case OSPFEXITOVERFLOWINTERVAL: /* 13 */ + /* Overflow is not supported. */ + return SNMP_INTEGER(0); + break; + case OSPFDEMANDEXTENSIONS: /* 14 */ + /* Demand routing is not supported. */ + return SNMP_INTEGER(SNMP_FALSE); + break; + default: + return NULL; + } + return NULL; } static struct ospf_area * -ospf_area_lookup_next (struct ospf *ospf, struct in_addr *area_id, int first) +ospf_area_lookup_next(struct ospf *ospf, struct in_addr *area_id, int first) { - struct ospf_area *area; - struct listnode *node; - - if (ospf == NULL) - return NULL; - - if (first) - { - node = listhead (ospf->areas); - if (node) - { - area = listgetdata (node); - *area_id = area->area_id; - return area; + struct ospf_area *area; + struct listnode *node; + + if (ospf == NULL) + return NULL; + + if (first) { + node = listhead(ospf->areas); + if (node) { + area = listgetdata(node); + *area_id = area->area_id; + return area; + } + return NULL; } - return NULL; - } - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - if (ntohl (area->area_id.s_addr) > ntohl (area_id->s_addr)) - { - *area_id = area->area_id; - return area; + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + if (ntohl(area->area_id.s_addr) > ntohl(area_id->s_addr)) { + *area_id = area->area_id; + return area; + } } - } - return NULL; + return NULL; } -static struct ospf_area * -ospfAreaLookup (struct variable *v, oid name[], size_t *length, - struct in_addr *addr, int exact) +static struct ospf_area *ospfAreaLookup(struct variable *v, oid name[], + size_t *length, struct in_addr *addr, + int exact) { - struct ospf *ospf; - struct ospf_area *area; - int len; - - ospf = ospf_lookup (); - if (ospf == NULL) - return NULL; - - if (exact) - { - /* Length is insufficient to lookup OSPF area. */ - if (*length - v->namelen != sizeof (struct in_addr)) - return NULL; + struct ospf *ospf; + struct ospf_area *area; + int len; - oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr); + ospf = ospf_lookup(); + if (ospf == NULL) + return NULL; - area = ospf_area_lookup_by_area_id (ospf, *addr); + if (exact) { + /* Length is insufficient to lookup OSPF area. */ + if (*length - v->namelen != sizeof(struct in_addr)) + return NULL; - return area; - } - else - { - len = *length - v->namelen; - if (len > 4) - len = 4; - - oid2in_addr (name + v->namelen, len, addr); + oid2in_addr(name + v->namelen, sizeof(struct in_addr), addr); - area = ospf_area_lookup_next (ospf, addr, len == 0 ? 1 : 0); + area = ospf_area_lookup_by_area_id(ospf, *addr); - if (area == NULL) - return NULL; - - oid_copy_addr (name + v->namelen, addr, sizeof (struct in_addr)); - *length = sizeof (struct in_addr) + v->namelen; + return area; + } else { + len = *length - v->namelen; + if (len > 4) + len = 4; - return area; - } - return NULL; -} + oid2in_addr(name + v->namelen, len, addr); -static u_char * -ospfAreaEntry (struct variable *v, oid *name, size_t *length, int exact, - size_t *var_len, WriteMethod **write_method) -{ - struct ospf_area *area; - struct in_addr addr; - - if (smux_header_table(v, name, length, exact, var_len, write_method) - == MATCH_FAILED) - return NULL; - - memset (&addr, 0, sizeof (struct in_addr)); - - area = ospfAreaLookup (v, name, length, &addr, exact); - if (! area) - return NULL; - - /* Return the current value of the variable */ - switch (v->magic) - { - case OSPFAREAID: /* 1 */ - return SNMP_IPADDRESS (area->area_id); - break; - case OSPFAUTHTYPE: /* 2 */ - return SNMP_INTEGER (area->auth_type); - break; - case OSPFIMPORTASEXTERN: /* 3 */ - return SNMP_INTEGER (area->external_routing + 1); - break; - case OSPFSPFRUNS: /* 4 */ - return SNMP_INTEGER (area->spf_calculation); - break; - case OSPFAREABDRRTRCOUNT: /* 5 */ - return SNMP_INTEGER (area->abr_count); - break; - case OSPFASBDRRTRCOUNT: /* 6 */ - return SNMP_INTEGER (area->asbr_count); - break; - case OSPFAREALSACOUNT: /* 7 */ - return SNMP_INTEGER (area->lsdb->total); - break; - case OSPFAREALSACKSUMSUM: /* 8 */ - return SNMP_INTEGER (0); - break; - case OSPFAREASUMMARY: /* 9 */ -#define OSPF_noAreaSummary 1 -#define OSPF_sendAreaSummary 2 - if (area->no_summary) - return SNMP_INTEGER (OSPF_noAreaSummary); - else - return SNMP_INTEGER (OSPF_sendAreaSummary); - break; - case OSPFAREASTATUS: /* 10 */ - return SNMP_INTEGER (SNMP_VALID); - break; - default: - return NULL; - break; - } - return NULL; -} + area = ospf_area_lookup_next(ospf, addr, len == 0 ? 1 : 0); -static struct ospf_area * -ospf_stub_area_lookup_next (struct in_addr *area_id, int first) -{ - struct ospf_area *area; - struct listnode *node; - struct ospf *ospf; + if (area == NULL) + return NULL; - ospf = ospf_lookup (); - if (ospf == NULL) - return NULL; + oid_copy_addr(name + v->namelen, addr, sizeof(struct in_addr)); + *length = sizeof(struct in_addr) + v->namelen; - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - if (area->external_routing == OSPF_AREA_STUB) - { - if (first) - { - *area_id = area->area_id; - return area; - } - else if (ntohl (area->area_id.s_addr) > ntohl (area_id->s_addr)) - { - *area_id = area->area_id; - return area; - } + return area; } - } - return NULL; + return NULL; } -static struct ospf_area * -ospfStubAreaLookup (struct variable *v, oid name[], size_t *length, - struct in_addr *addr, int exact) +static u_char *ospfAreaEntry(struct variable *v, oid *name, size_t *length, + int exact, size_t *var_len, + WriteMethod **write_method) { - struct ospf *ospf; - struct ospf_area *area; - int len; - - ospf = ospf_lookup (); - if (ospf == NULL) - return NULL; - - /* Exact lookup. */ - if (exact) - { - /* ospfStubAreaID + ospfStubTOS. */ - if (*length != v->namelen + sizeof (struct in_addr) + 1) - return NULL; - - /* Check ospfStubTOS is zero. */ - if (name[*length - 1] != 0) - return NULL; - - oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr); - - area = ospf_area_lookup_by_area_id (ospf, *addr); - - if (area->external_routing == OSPF_AREA_STUB) - return area; - else - return NULL; - } - else - { - len = *length - v->namelen; - if (len > 4) - len = 4; - - oid2in_addr (name + v->namelen, len, addr); - - area = ospf_stub_area_lookup_next (addr, len == 0 ? 1 : 0); - - if (area == NULL) + struct ospf_area *area; + struct in_addr addr; + + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + + memset(&addr, 0, sizeof(struct in_addr)); + + area = ospfAreaLookup(v, name, length, &addr, exact); + if (!area) + return NULL; + + /* Return the current value of the variable */ + switch (v->magic) { + case OSPFAREAID: /* 1 */ + return SNMP_IPADDRESS(area->area_id); + break; + case OSPFAUTHTYPE: /* 2 */ + return SNMP_INTEGER(area->auth_type); + break; + case OSPFIMPORTASEXTERN: /* 3 */ + return SNMP_INTEGER(area->external_routing + 1); + break; + case OSPFSPFRUNS: /* 4 */ + return SNMP_INTEGER(area->spf_calculation); + break; + case OSPFAREABDRRTRCOUNT: /* 5 */ + return SNMP_INTEGER(area->abr_count); + break; + case OSPFASBDRRTRCOUNT: /* 6 */ + return SNMP_INTEGER(area->asbr_count); + break; + case OSPFAREALSACOUNT: /* 7 */ + return SNMP_INTEGER(area->lsdb->total); + break; + case OSPFAREALSACKSUMSUM: /* 8 */ + return SNMP_INTEGER(0); + break; + case OSPFAREASUMMARY: /* 9 */ + /* $FRR indent$ */ + /* clang-format off */ +#define OSPF_noAreaSummary 1 +#define OSPF_sendAreaSummary 2 + if (area->no_summary) + return SNMP_INTEGER(OSPF_noAreaSummary); + else + return SNMP_INTEGER(OSPF_sendAreaSummary); + break; + case OSPFAREASTATUS: /* 10 */ + return SNMP_INTEGER(SNMP_VALID); + break; + default: + return NULL; + break; + } return NULL; - - oid_copy_addr (name + v->namelen, addr, sizeof (struct in_addr)); - /* Set TOS 0. */ - name[v->namelen + sizeof (struct in_addr)] = 0; - *length = v->namelen + sizeof (struct in_addr) + 1; - - return area; - } - return NULL; } -static u_char * -ospfStubAreaEntry (struct variable *v, oid *name, size_t *length, - int exact, size_t *var_len, WriteMethod **write_method) +static struct ospf_area *ospf_stub_area_lookup_next(struct in_addr *area_id, + int first) { - struct ospf_area *area; - struct in_addr addr; - - if (smux_header_table(v, name, length, exact, var_len, write_method) - == MATCH_FAILED) - return NULL; - - memset (&addr, 0, sizeof (struct in_addr)); - - area = ospfStubAreaLookup (v, name, length, &addr, exact); - if (! area) - return NULL; - - /* Return the current value of the variable */ - switch (v->magic) - { - case OSPFSTUBAREAID: /* 1 */ - /* OSPF stub area id. */ - return SNMP_IPADDRESS (area->area_id); - break; - case OSPFSTUBTOS: /* 2 */ - /* TOS value is not supported. */ - return SNMP_INTEGER (0); - break; - case OSPFSTUBMETRIC: /* 3 */ - /* Default cost to stub area. */ - return SNMP_INTEGER (area->default_cost); - break; - case OSPFSTUBSTATUS: /* 4 */ - /* Status of the stub area. */ - return SNMP_INTEGER (SNMP_VALID); - break; - case OSPFSTUBMETRICTYPE: /* 5 */ - /* OSPF Metric type. */ -#define OSPF_ospfMetric 1 -#define OSPF_comparableCost 2 -#define OSPF_nonComparable 3 - return SNMP_INTEGER (OSPF_ospfMetric); - break; - default: - return NULL; - break; - } - return NULL; + struct ospf_area *area; + struct listnode *node; + struct ospf *ospf; + + ospf = ospf_lookup(); + if (ospf == NULL) + return NULL; + + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + if (area->external_routing == OSPF_AREA_STUB) { + if (first) { + *area_id = area->area_id; + return area; + } else if (ntohl(area->area_id.s_addr) + > ntohl(area_id->s_addr)) { + *area_id = area->area_id; + return area; + } + } + } + return NULL; } -static struct ospf_lsa * -lsdb_lookup_next (struct ospf_area *area, u_char *type, int type_next, - struct in_addr *ls_id, int ls_id_next, - struct in_addr *router_id, int router_id_next) +static struct ospf_area *ospfStubAreaLookup(struct variable *v, oid name[], + size_t *length, + struct in_addr *addr, int exact) { - struct ospf_lsa *lsa; - int i; - - if (type_next) - i = OSPF_MIN_LSA; - else - i = *type; - - /* Sanity check, if LSA type unknwon - merley skip any LSA */ - if ((i < OSPF_MIN_LSA) || (i >= OSPF_MAX_LSA)) - { - zlog_debug("Strange request with LSA type %d\n", i); - return NULL; - } - - for (; i < OSPF_MAX_LSA; i++) - { - *type = i; - - lsa = ospf_lsdb_lookup_by_id_next (area->lsdb, *type, *ls_id, *router_id, - ls_id_next); - if (lsa) - return lsa; - - ls_id_next = 1; - } - return NULL; -} + struct ospf *ospf; + struct ospf_area *area; + int len; -static struct ospf_lsa * -ospfLsdbLookup (struct variable *v, oid *name, size_t *length, - struct in_addr *area_id, u_char *type, - struct in_addr *ls_id, struct in_addr *router_id, int exact) -{ - struct ospf *ospf; - struct ospf_area *area; - struct ospf_lsa *lsa; - int len; - int type_next; - int ls_id_next; - int router_id_next; - oid *offset; - int offsetlen; - - ospf = ospf_lookup (); - -#define OSPF_LSDB_ENTRY_OFFSET \ - (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE) - - if (exact) - { - /* Area ID + Type + LS ID + Router ID. */ - if (*length - v->namelen != OSPF_LSDB_ENTRY_OFFSET) - return NULL; - - /* Set OID offset for Area ID. */ - offset = name + v->namelen; - - /* Lookup area first. */ - oid2in_addr (offset, IN_ADDR_SIZE, area_id); - area = ospf_area_lookup_by_area_id (ospf, *area_id); - if (! area) - return NULL; - offset += IN_ADDR_SIZE; + ospf = ospf_lookup(); + if (ospf == NULL) + return NULL; - /* Type. */ - *type = *offset; - offset++; + /* Exact lookup. */ + if (exact) { + /* ospfStubAreaID + ospfStubTOS. */ + if (*length != v->namelen + sizeof(struct in_addr) + 1) + return NULL; - /* LS ID. */ - oid2in_addr (offset, IN_ADDR_SIZE, ls_id); - offset += IN_ADDR_SIZE; + /* Check ospfStubTOS is zero. */ + if (name[*length - 1] != 0) + return NULL; - /* Router ID. */ - oid2in_addr (offset, IN_ADDR_SIZE, router_id); + oid2in_addr(name + v->namelen, sizeof(struct in_addr), addr); - /* Lookup LSDB. */ - return ospf_lsdb_lookup_by_id (area->lsdb, *type, *ls_id, *router_id); - } - else - { - /* Get variable length. */ - offset = name + v->namelen; - offsetlen = *length - v->namelen; - len = offsetlen; + area = ospf_area_lookup_by_area_id(ospf, *addr); - if (len > (int)IN_ADDR_SIZE) - len = IN_ADDR_SIZE; + if (area->external_routing == OSPF_AREA_STUB) + return area; + else + return NULL; + } else { + len = *length - v->namelen; + if (len > 4) + len = 4; - oid2in_addr (offset, len, area_id); + oid2in_addr(name + v->namelen, len, addr); - /* First we search area. */ - if (len == IN_ADDR_SIZE) - area = ospf_area_lookup_by_area_id (ospf, *area_id); - else - area = ospf_area_lookup_next (ospf, area_id, 1); + area = ospf_stub_area_lookup_next(addr, len == 0 ? 1 : 0); - if (area == NULL) - return NULL; + if (area == NULL) + return NULL; - do - { - /* Next we lookup type. */ - offset += len; - offsetlen -= len; - len = offsetlen; - - if (len <= 0) - type_next = 1; - else - { - len = 1; - type_next = 0; - *type = *offset; - } - - /* LS ID. */ - offset++; - offsetlen--; - len = offsetlen; - - if (len <= 0) - ls_id_next = 1; - else - { - ls_id_next = 0; - if (len > (int)IN_ADDR_SIZE) - len = IN_ADDR_SIZE; - - oid2in_addr (offset, len, ls_id); - } - - /* Router ID. */ - offset += IN_ADDR_SIZE; - offsetlen -= IN_ADDR_SIZE; - len = offsetlen; - - if (len <= 0) - router_id_next = 1; - else - { - router_id_next = 0; - if (len > (int)IN_ADDR_SIZE) - len = IN_ADDR_SIZE; - - oid2in_addr (offset, len, router_id); - } - - lsa = lsdb_lookup_next (area, type, type_next, ls_id, ls_id_next, - router_id, router_id_next); - - if (lsa) - { - /* Fill in length. */ - *length = v->namelen + OSPF_LSDB_ENTRY_OFFSET; - - /* Fill in value. */ - offset = name + v->namelen; - oid_copy_addr (offset, area_id, IN_ADDR_SIZE); - offset += IN_ADDR_SIZE; - *offset = lsa->data->type; - offset++; - oid_copy_addr (offset, &lsa->data->id, IN_ADDR_SIZE); - offset += IN_ADDR_SIZE; - oid_copy_addr (offset, &lsa->data->adv_router, IN_ADDR_SIZE); - - return lsa; - } + oid_copy_addr(name + v->namelen, addr, sizeof(struct in_addr)); + /* Set TOS 0. */ + name[v->namelen + sizeof(struct in_addr)] = 0; + *length = v->namelen + sizeof(struct in_addr) + 1; + + return area; } - while ((area = ospf_area_lookup_next (ospf, area_id, 0)) != NULL); - } - return NULL; + return NULL; } -static u_char * -ospfLsdbEntry (struct variable *v, oid *name, size_t *length, int exact, - size_t *var_len, WriteMethod **write_method) +static u_char *ospfStubAreaEntry(struct variable *v, oid *name, size_t *length, + int exact, size_t *var_len, + WriteMethod **write_method) { - struct ospf_lsa *lsa; - struct lsa_header *lsah; - struct in_addr area_id; - u_char type; - struct in_addr ls_id; - struct in_addr router_id; - struct ospf *ospf; - - if (smux_header_table(v, name, length, exact, var_len, write_method) - == MATCH_FAILED) - return NULL; - - /* INDEX { ospfLsdbAreaId, ospfLsdbType, - ospfLsdbLsid, ospfLsdbRouterId } */ - - memset (&area_id, 0, sizeof (struct in_addr)); - type = 0; - memset (&ls_id, 0, sizeof (struct in_addr)); - memset (&router_id, 0, sizeof (struct in_addr)); - - /* Check OSPF instance. */ - ospf = ospf_lookup (); - if (ospf == NULL) - return NULL; - - lsa = ospfLsdbLookup (v, name, length, &area_id, &type, &ls_id, &router_id, - exact); - if (! lsa) - return NULL; - - lsah = lsa->data; - - /* Return the current value of the variable */ - switch (v->magic) - { - case OSPFLSDBAREAID: /* 1 */ - return SNMP_IPADDRESS (lsa->area->area_id); - break; - case OSPFLSDBTYPE: /* 2 */ - return SNMP_INTEGER (lsah->type); - break; - case OSPFLSDBLSID: /* 3 */ - return SNMP_IPADDRESS (lsah->id); - break; - case OSPFLSDBROUTERID: /* 4 */ - return SNMP_IPADDRESS (lsah->adv_router); - break; - case OSPFLSDBSEQUENCE: /* 5 */ - return SNMP_INTEGER (lsah->ls_seqnum); - break; - case OSPFLSDBAGE: /* 6 */ - return SNMP_INTEGER (lsah->ls_age); - break; - case OSPFLSDBCHECKSUM: /* 7 */ - return SNMP_INTEGER (lsah->checksum); - break; - case OSPFLSDBADVERTISEMENT: /* 8 */ - *var_len = ntohs (lsah->length); - return (u_char *) lsah; - break; - default: - return NULL; - break; - } - return NULL; + struct ospf_area *area; + struct in_addr addr; + + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + + memset(&addr, 0, sizeof(struct in_addr)); + + area = ospfStubAreaLookup(v, name, length, &addr, exact); + if (!area) + return NULL; + + /* Return the current value of the variable */ + switch (v->magic) { + case OSPFSTUBAREAID: /* 1 */ + /* OSPF stub area id. */ + return SNMP_IPADDRESS(area->area_id); + break; + case OSPFSTUBTOS: /* 2 */ + /* TOS value is not supported. */ + return SNMP_INTEGER(0); + break; + case OSPFSTUBMETRIC: /* 3 */ + /* Default cost to stub area. */ + return SNMP_INTEGER(area->default_cost); + break; + case OSPFSTUBSTATUS: /* 4 */ + /* Status of the stub area. */ + return SNMP_INTEGER(SNMP_VALID); + break; + case OSPFSTUBMETRICTYPE: /* 5 */ +/* OSPF Metric type. */ +#define OSPF_ospfMetric 1 +#define OSPF_comparableCost 2 +#define OSPF_nonComparable 3 + return SNMP_INTEGER(OSPF_ospfMetric); + break; + default: + return NULL; + break; + } + return NULL; } -static struct ospf_area_range * -ospfAreaRangeLookup (struct variable *v, oid *name, size_t *length, - struct in_addr *area_id, struct in_addr *range_net, - int exact) +static struct ospf_lsa *lsdb_lookup_next(struct ospf_area *area, u_char *type, + int type_next, struct in_addr *ls_id, + int ls_id_next, + struct in_addr *router_id, + int router_id_next) { - oid *offset; - int offsetlen; - int len; - struct ospf *ospf; - struct ospf_area *area; - struct ospf_area_range *range; - struct prefix_ipv4 p; - p.family = AF_INET; - p.prefixlen = IPV4_MAX_BITLEN; - - ospf = ospf_lookup (); - - if (exact) - { - /* Area ID + Range Network. */ - if (v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE != *length) - return NULL; + struct ospf_lsa *lsa; + int i; + + if (type_next) + i = OSPF_MIN_LSA; + else + i = *type; + + /* Sanity check, if LSA type unknwon + merley skip any LSA */ + if ((i < OSPF_MIN_LSA) || (i >= OSPF_MAX_LSA)) { + zlog_debug("Strange request with LSA type %d\n", i); + return NULL; + } - /* Set OID offset for Area ID. */ - offset = name + v->namelen; + for (; i < OSPF_MAX_LSA; i++) { + *type = i; - /* Lookup area first. */ - oid2in_addr (offset, IN_ADDR_SIZE, area_id); + lsa = ospf_lsdb_lookup_by_id_next(area->lsdb, *type, *ls_id, + *router_id, ls_id_next); + if (lsa) + return lsa; - area = ospf_area_lookup_by_area_id (ospf, *area_id); - if (! area) + ls_id_next = 1; + } return NULL; +} - offset += IN_ADDR_SIZE; - - /* Lookup area range. */ - oid2in_addr (offset, IN_ADDR_SIZE, range_net); - p.prefix = *range_net; - - return ospf_area_range_lookup (area, &p); - } - else - { - /* Set OID offset for Area ID. */ - offset = name + v->namelen; - offsetlen = *length - v->namelen; - - len = offsetlen; - if (len > (int)IN_ADDR_SIZE) - len = IN_ADDR_SIZE; - - oid2in_addr (offset, len, area_id); - - /* First we search area. */ - if (len == IN_ADDR_SIZE) - area = ospf_area_lookup_by_area_id (ospf,*area_id); - else - area = ospf_area_lookup_next (ospf, area_id, len == 0 ? 1 : 0); - - if (area == NULL) +static struct ospf_lsa *ospfLsdbLookup(struct variable *v, oid *name, + size_t *length, struct in_addr *area_id, + u_char *type, struct in_addr *ls_id, + struct in_addr *router_id, int exact) +{ + struct ospf *ospf; + struct ospf_area *area; + struct ospf_lsa *lsa; + int len; + int type_next; + int ls_id_next; + int router_id_next; + oid *offset; + int offsetlen; + + ospf = ospf_lookup(); + +#define OSPF_LSDB_ENTRY_OFFSET (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE) + + if (exact) { + /* Area ID + Type + LS ID + Router ID. */ + if (*length - v->namelen != OSPF_LSDB_ENTRY_OFFSET) + return NULL; + + /* Set OID offset for Area ID. */ + offset = name + v->namelen; + + /* Lookup area first. */ + oid2in_addr(offset, IN_ADDR_SIZE, area_id); + area = ospf_area_lookup_by_area_id(ospf, *area_id); + if (!area) + return NULL; + offset += IN_ADDR_SIZE; + + /* Type. */ + *type = *offset; + offset++; + + /* LS ID. */ + oid2in_addr(offset, IN_ADDR_SIZE, ls_id); + offset += IN_ADDR_SIZE; + + /* Router ID. */ + oid2in_addr(offset, IN_ADDR_SIZE, router_id); + + /* Lookup LSDB. */ + return ospf_lsdb_lookup_by_id(area->lsdb, *type, *ls_id, + *router_id); + } else { + /* Get variable length. */ + offset = name + v->namelen; + offsetlen = *length - v->namelen; + len = offsetlen; + + if (len > (int)IN_ADDR_SIZE) + len = IN_ADDR_SIZE; + + oid2in_addr(offset, len, area_id); + + /* First we search area. */ + if (len == IN_ADDR_SIZE) + area = ospf_area_lookup_by_area_id(ospf, *area_id); + else + area = ospf_area_lookup_next(ospf, area_id, 1); + + if (area == NULL) + return NULL; + + do { + /* Next we lookup type. */ + offset += len; + offsetlen -= len; + len = offsetlen; + + if (len <= 0) + type_next = 1; + else { + len = 1; + type_next = 0; + *type = *offset; + } + + /* LS ID. */ + offset++; + offsetlen--; + len = offsetlen; + + if (len <= 0) + ls_id_next = 1; + else { + ls_id_next = 0; + if (len > (int)IN_ADDR_SIZE) + len = IN_ADDR_SIZE; + + oid2in_addr(offset, len, ls_id); + } + + /* Router ID. */ + offset += IN_ADDR_SIZE; + offsetlen -= IN_ADDR_SIZE; + len = offsetlen; + + if (len <= 0) + router_id_next = 1; + else { + router_id_next = 0; + if (len > (int)IN_ADDR_SIZE) + len = IN_ADDR_SIZE; + + oid2in_addr(offset, len, router_id); + } + + lsa = lsdb_lookup_next(area, type, type_next, ls_id, + ls_id_next, router_id, + router_id_next); + + if (lsa) { + /* Fill in length. */ + *length = v->namelen + OSPF_LSDB_ENTRY_OFFSET; + + /* Fill in value. */ + offset = name + v->namelen; + oid_copy_addr(offset, area_id, IN_ADDR_SIZE); + offset += IN_ADDR_SIZE; + *offset = lsa->data->type; + offset++; + oid_copy_addr(offset, &lsa->data->id, + IN_ADDR_SIZE); + offset += IN_ADDR_SIZE; + oid_copy_addr(offset, &lsa->data->adv_router, + IN_ADDR_SIZE); + + return lsa; + } + } while ((area = ospf_area_lookup_next(ospf, area_id, 0)) + != NULL); + } return NULL; +} - do - { - offset += IN_ADDR_SIZE; - offsetlen -= IN_ADDR_SIZE; - len = offsetlen; - - if (len < 0) - len = 0; - if (len > (int)IN_ADDR_SIZE) - len = IN_ADDR_SIZE; - - oid2in_addr (offset, len, range_net); - - range = ospf_area_range_lookup_next (area, range_net, - len == 0 ? 1 : 0); - - if (range) - { - /* Fill in length. */ - *length = v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE; - - /* Fill in value. */ - offset = name + v->namelen; - oid_copy_addr (offset, area_id, IN_ADDR_SIZE); - offset += IN_ADDR_SIZE; - oid_copy_addr (offset, range_net, IN_ADDR_SIZE); +static u_char *ospfLsdbEntry(struct variable *v, oid *name, size_t *length, + int exact, size_t *var_len, + WriteMethod **write_method) +{ + struct ospf_lsa *lsa; + struct lsa_header *lsah; + struct in_addr area_id; + u_char type; + struct in_addr ls_id; + struct in_addr router_id; + struct ospf *ospf; + + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + + /* INDEX { ospfLsdbAreaId, ospfLsdbType, + ospfLsdbLsid, ospfLsdbRouterId } */ + + memset(&area_id, 0, sizeof(struct in_addr)); + type = 0; + memset(&ls_id, 0, sizeof(struct in_addr)); + memset(&router_id, 0, sizeof(struct in_addr)); + + /* Check OSPF instance. */ + ospf = ospf_lookup(); + if (ospf == NULL) + return NULL; + + lsa = ospfLsdbLookup(v, name, length, &area_id, &type, &ls_id, + &router_id, exact); + if (!lsa) + return NULL; + + lsah = lsa->data; + + /* Return the current value of the variable */ + switch (v->magic) { + case OSPFLSDBAREAID: /* 1 */ + return SNMP_IPADDRESS(lsa->area->area_id); + break; + case OSPFLSDBTYPE: /* 2 */ + return SNMP_INTEGER(lsah->type); + break; + case OSPFLSDBLSID: /* 3 */ + return SNMP_IPADDRESS(lsah->id); + break; + case OSPFLSDBROUTERID: /* 4 */ + return SNMP_IPADDRESS(lsah->adv_router); + break; + case OSPFLSDBSEQUENCE: /* 5 */ + return SNMP_INTEGER(lsah->ls_seqnum); + break; + case OSPFLSDBAGE: /* 6 */ + return SNMP_INTEGER(lsah->ls_age); + break; + case OSPFLSDBCHECKSUM: /* 7 */ + return SNMP_INTEGER(lsah->checksum); + break; + case OSPFLSDBADVERTISEMENT: /* 8 */ + *var_len = ntohs(lsah->length); + return (u_char *)lsah; + break; + default: + return NULL; + break; + } + return NULL; +} - return range; - } +static struct ospf_area_range *ospfAreaRangeLookup(struct variable *v, + oid *name, size_t *length, + struct in_addr *area_id, + struct in_addr *range_net, + int exact) +{ + oid *offset; + int offsetlen; + int len; + struct ospf *ospf; + struct ospf_area *area; + struct ospf_area_range *range; + struct prefix_ipv4 p; + p.family = AF_INET; + p.prefixlen = IPV4_MAX_BITLEN; + + ospf = ospf_lookup(); + + if (exact) { + /* Area ID + Range Network. */ + if (v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE != *length) + return NULL; + + /* Set OID offset for Area ID. */ + offset = name + v->namelen; + + /* Lookup area first. */ + oid2in_addr(offset, IN_ADDR_SIZE, area_id); + + area = ospf_area_lookup_by_area_id(ospf, *area_id); + if (!area) + return NULL; + + offset += IN_ADDR_SIZE; + + /* Lookup area range. */ + oid2in_addr(offset, IN_ADDR_SIZE, range_net); + p.prefix = *range_net; + + return ospf_area_range_lookup(area, &p); + } else { + /* Set OID offset for Area ID. */ + offset = name + v->namelen; + offsetlen = *length - v->namelen; + + len = offsetlen; + if (len > (int)IN_ADDR_SIZE) + len = IN_ADDR_SIZE; + + oid2in_addr(offset, len, area_id); + + /* First we search area. */ + if (len == IN_ADDR_SIZE) + area = ospf_area_lookup_by_area_id(ospf, *area_id); + else + area = ospf_area_lookup_next(ospf, area_id, + len == 0 ? 1 : 0); + + if (area == NULL) + return NULL; + + do { + offset += IN_ADDR_SIZE; + offsetlen -= IN_ADDR_SIZE; + len = offsetlen; + + if (len < 0) + len = 0; + if (len > (int)IN_ADDR_SIZE) + len = IN_ADDR_SIZE; + + oid2in_addr(offset, len, range_net); + + range = ospf_area_range_lookup_next(area, range_net, + len == 0 ? 1 : 0); + + if (range) { + /* Fill in length. */ + *length = v->namelen + IN_ADDR_SIZE + + IN_ADDR_SIZE; + + /* Fill in value. */ + offset = name + v->namelen; + oid_copy_addr(offset, area_id, IN_ADDR_SIZE); + offset += IN_ADDR_SIZE; + oid_copy_addr(offset, range_net, IN_ADDR_SIZE); + + return range; + } + } while ((area = ospf_area_lookup_next(ospf, area_id, 0)) + != NULL); } - while ((area = ospf_area_lookup_next (ospf, area_id, 0)) != NULL); - } - return NULL; + return NULL; } -static u_char * -ospfAreaRangeEntry (struct variable *v, oid *name, size_t *length, int exact, - size_t *var_len, WriteMethod **write_method) +static u_char *ospfAreaRangeEntry(struct variable *v, oid *name, size_t *length, + int exact, size_t *var_len, + WriteMethod **write_method) { - struct ospf_area_range *range; - struct in_addr area_id; - struct in_addr range_net; - struct in_addr mask; - struct ospf *ospf; - - if (smux_header_table(v, name, length, exact, var_len, write_method) - == MATCH_FAILED) - return NULL; - - /* Check OSPF instance. */ - ospf = ospf_lookup (); - if (ospf == NULL) - return NULL; - - memset (&area_id, 0, IN_ADDR_SIZE); - memset (&range_net, 0, IN_ADDR_SIZE); - - range = ospfAreaRangeLookup (v, name, length, &area_id, &range_net, exact); - if (! range) - return NULL; - - /* Convert prefixlen to network mask format. */ - masklen2ip (range->subst_masklen, &mask); - - /* Return the current value of the variable */ - switch (v->magic) - { - case OSPFAREARANGEAREAID: /* 1 */ - return SNMP_IPADDRESS (area_id); - break; - case OSPFAREARANGENET: /* 2 */ - return SNMP_IPADDRESS (range_net); - break; - case OSPFAREARANGEMASK: /* 3 */ - return SNMP_IPADDRESS (mask); - break; - case OSPFAREARANGESTATUS: /* 4 */ - return SNMP_INTEGER (SNMP_VALID); - break; - case OSPFAREARANGEEFFECT: /* 5 */ + struct ospf_area_range *range; + struct in_addr area_id; + struct in_addr range_net; + struct in_addr mask; + struct ospf *ospf; + + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + + /* Check OSPF instance. */ + ospf = ospf_lookup(); + if (ospf == NULL) + return NULL; + + memset(&area_id, 0, IN_ADDR_SIZE); + memset(&range_net, 0, IN_ADDR_SIZE); + + range = ospfAreaRangeLookup(v, name, length, &area_id, &range_net, + exact); + if (!range) + return NULL; + + /* Convert prefixlen to network mask format. */ + masklen2ip(range->subst_masklen, &mask); + + /* Return the current value of the variable */ + switch (v->magic) { + case OSPFAREARANGEAREAID: /* 1 */ + return SNMP_IPADDRESS(area_id); + break; + case OSPFAREARANGENET: /* 2 */ + return SNMP_IPADDRESS(range_net); + break; + case OSPFAREARANGEMASK: /* 3 */ + return SNMP_IPADDRESS(mask); + break; + case OSPFAREARANGESTATUS: /* 4 */ + return SNMP_INTEGER(SNMP_VALID); + break; + case OSPFAREARANGEEFFECT: /* 5 */ + /* $FRR indent$ */ + /* clang-format off */ #define OSPF_advertiseMatching 1 #define OSPF_doNotAdvertiseMatching 2 - return SNMP_INTEGER (OSPF_advertiseMatching); - break; - default: - return NULL; - break; - } - return NULL; + return SNMP_INTEGER(OSPF_advertiseMatching); + break; + default: + return NULL; + break; + } + return NULL; } -static struct ospf_nbr_nbma * -ospfHostLookup (struct variable *v, oid *name, size_t *length, - struct in_addr *addr, int exact) +static struct ospf_nbr_nbma *ospfHostLookup(struct variable *v, oid *name, + size_t *length, + struct in_addr *addr, int exact) { - int len; - struct ospf_nbr_nbma *nbr_nbma; - struct ospf *ospf; - - ospf = ospf_lookup (); - if (ospf == NULL) - return NULL; - - if (exact) - { - /* INDEX { ospfHostIpAddress, ospfHostTOS } */ - if (*length != v->namelen + IN_ADDR_SIZE + 1) - return NULL; + int len; + struct ospf_nbr_nbma *nbr_nbma; + struct ospf *ospf; - /* Check ospfHostTOS. */ - if (name[*length - 1] != 0) - return NULL; + ospf = ospf_lookup(); + if (ospf == NULL) + return NULL; - oid2in_addr (name + v->namelen, IN_ADDR_SIZE, addr); + if (exact) { + /* INDEX { ospfHostIpAddress, ospfHostTOS } */ + if (*length != v->namelen + IN_ADDR_SIZE + 1) + return NULL; - nbr_nbma = ospf_nbr_nbma_lookup (ospf, *addr); + /* Check ospfHostTOS. */ + if (name[*length - 1] != 0) + return NULL; - return nbr_nbma; - } - else - { - len = *length - v->namelen; - if (len > 4) - len = 4; - - oid2in_addr (name + v->namelen, len, addr); + oid2in_addr(name + v->namelen, IN_ADDR_SIZE, addr); - nbr_nbma = ospf_nbr_nbma_lookup_next (ospf, addr, len == 0 ? 1 : 0); + nbr_nbma = ospf_nbr_nbma_lookup(ospf, *addr); - if (nbr_nbma == NULL) - return NULL; + return nbr_nbma; + } else { + len = *length - v->namelen; + if (len > 4) + len = 4; + + oid2in_addr(name + v->namelen, len, addr); + + nbr_nbma = + ospf_nbr_nbma_lookup_next(ospf, addr, len == 0 ? 1 : 0); - oid_copy_addr (name + v->namelen, addr, IN_ADDR_SIZE); + if (nbr_nbma == NULL) + return NULL; - /* Set TOS 0. */ - name[v->namelen + IN_ADDR_SIZE] = 0; + oid_copy_addr(name + v->namelen, addr, IN_ADDR_SIZE); - *length = v->namelen + IN_ADDR_SIZE + 1; + /* Set TOS 0. */ + name[v->namelen + IN_ADDR_SIZE] = 0; - return nbr_nbma; - } - return NULL; + *length = v->namelen + IN_ADDR_SIZE + 1; + + return nbr_nbma; + } + return NULL; } -static u_char * -ospfHostEntry (struct variable *v, oid *name, size_t *length, int exact, - size_t *var_len, WriteMethod **write_method) +static u_char *ospfHostEntry(struct variable *v, oid *name, size_t *length, + int exact, size_t *var_len, + WriteMethod **write_method) { - struct ospf_nbr_nbma *nbr_nbma; - struct ospf_interface *oi; - struct in_addr addr; - struct ospf *ospf; - - if (smux_header_table(v, name, length, exact, var_len, write_method) - == MATCH_FAILED) - return NULL; - - /* Check OSPF instance. */ - ospf = ospf_lookup (); - if (ospf == NULL) - return NULL; - - memset (&addr, 0, sizeof (struct in_addr)); - - nbr_nbma = ospfHostLookup (v, name, length, &addr, exact); - if (nbr_nbma == NULL) - return NULL; - - oi = nbr_nbma->oi; - - /* Return the current value of the variable */ - switch (v->magic) - { - case OSPFHOSTIPADDRESS: /* 1 */ - return SNMP_IPADDRESS (nbr_nbma->addr); - break; - case OSPFHOSTTOS: /* 2 */ - return SNMP_INTEGER (0); - break; - case OSPFHOSTMETRIC: /* 3 */ - if (oi) - return SNMP_INTEGER (oi->output_cost); - else - return SNMP_INTEGER (1); - break; - case OSPFHOSTSTATUS: /* 4 */ - return SNMP_INTEGER (SNMP_VALID); - break; - case OSPFHOSTAREAID: /* 5 */ - if (oi && oi->area) - return SNMP_IPADDRESS (oi->area->area_id); - else - return SNMP_IPADDRESS (ospf_empty_addr); - break; - default: - return NULL; - break; - } - return NULL; + struct ospf_nbr_nbma *nbr_nbma; + struct ospf_interface *oi; + struct in_addr addr; + struct ospf *ospf; + + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + + /* Check OSPF instance. */ + ospf = ospf_lookup(); + if (ospf == NULL) + return NULL; + + memset(&addr, 0, sizeof(struct in_addr)); + + nbr_nbma = ospfHostLookup(v, name, length, &addr, exact); + if (nbr_nbma == NULL) + return NULL; + + oi = nbr_nbma->oi; + + /* Return the current value of the variable */ + switch (v->magic) { + case OSPFHOSTIPADDRESS: /* 1 */ + return SNMP_IPADDRESS(nbr_nbma->addr); + break; + case OSPFHOSTTOS: /* 2 */ + return SNMP_INTEGER(0); + break; + case OSPFHOSTMETRIC: /* 3 */ + if (oi) + return SNMP_INTEGER(oi->output_cost); + else + return SNMP_INTEGER(1); + break; + case OSPFHOSTSTATUS: /* 4 */ + return SNMP_INTEGER(SNMP_VALID); + break; + case OSPFHOSTAREAID: /* 5 */ + if (oi && oi->area) + return SNMP_IPADDRESS(oi->area->area_id); + else + return SNMP_IPADDRESS(ospf_empty_addr); + break; + default: + return NULL; + break; + } + return NULL; } static struct list *ospf_snmp_iflist; -struct ospf_snmp_if -{ - struct in_addr addr; - ifindex_t ifindex; - struct interface *ifp; +struct ospf_snmp_if { + struct in_addr addr; + ifindex_t ifindex; + struct interface *ifp; }; -static struct ospf_snmp_if * -ospf_snmp_if_new (void) +static struct ospf_snmp_if *ospf_snmp_if_new(void) { - return XCALLOC (MTYPE_TMP, sizeof (struct ospf_snmp_if)); + return XCALLOC(MTYPE_TMP, sizeof(struct ospf_snmp_if)); } -static void -ospf_snmp_if_free (struct ospf_snmp_if *osif) +static void ospf_snmp_if_free(struct ospf_snmp_if *osif) { - XFREE (MTYPE_TMP, osif); + XFREE(MTYPE_TMP, osif); } -static int -ospf_snmp_if_delete (struct interface *ifp) +static int ospf_snmp_if_delete(struct interface *ifp) { - struct listnode *node, *nnode; - struct ospf_snmp_if *osif; - - for (ALL_LIST_ELEMENTS (ospf_snmp_iflist, node, nnode, osif)) - { - if (osif->ifp == ifp) - { - list_delete_node (ospf_snmp_iflist, node); - ospf_snmp_if_free (osif); - break; + struct listnode *node, *nnode; + struct ospf_snmp_if *osif; + + for (ALL_LIST_ELEMENTS(ospf_snmp_iflist, node, nnode, osif)) { + if (osif->ifp == ifp) { + list_delete_node(ospf_snmp_iflist, node); + ospf_snmp_if_free(osif); + break; + } } - } - return 0; + return 0; } -static int -ospf_snmp_if_update (struct interface *ifp) +static int ospf_snmp_if_update(struct interface *ifp) { - struct listnode *node; - struct listnode *pn; - struct connected *ifc; - struct prefix *p; - struct ospf_snmp_if *osif; - struct in_addr *addr; - ifindex_t ifindex; - - ospf_snmp_if_delete (ifp); - - p = NULL; - addr = NULL; - ifindex = 0; - - /* Lookup first IPv4 address entry. */ - for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc)) - { - p = CONNECTED_ID(ifc); - - if (p->family == AF_INET) - { - addr = &p->u.prefix4; - break; + struct listnode *node; + struct listnode *pn; + struct connected *ifc; + struct prefix *p; + struct ospf_snmp_if *osif; + struct in_addr *addr; + ifindex_t ifindex; + + ospf_snmp_if_delete(ifp); + + p = NULL; + addr = NULL; + ifindex = 0; + + /* Lookup first IPv4 address entry. */ + for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) { + p = CONNECTED_ID(ifc); + + if (p->family == AF_INET) { + addr = &p->u.prefix4; + break; + } } - } - if (! addr) - ifindex = ifp->ifindex; - - /* Add interface to the list. */ - pn = NULL; - for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, node, osif)) - { - if (addr) - { - /* Usual interfaces --> Sort them based on interface IPv4 addresses */ - if (ntohl (osif->addr.s_addr) > ntohl (addr->s_addr)) - break; + if (!addr) + ifindex = ifp->ifindex; + + /* Add interface to the list. */ + pn = NULL; + for (ALL_LIST_ELEMENTS_RO(ospf_snmp_iflist, node, osif)) { + if (addr) { + /* Usual interfaces --> Sort them based on interface + * IPv4 addresses */ + if (ntohl(osif->addr.s_addr) > ntohl(addr->s_addr)) + break; + } else { + /* Unnumbered interfaces --> Sort them based on + * interface indexes */ + if (osif->addr.s_addr != 0 || osif->ifindex > ifindex) + break; + } + pn = node; } - else + + osif = ospf_snmp_if_new(); + if (addr) /* Usual interface */ { - /* Unnumbered interfaces --> Sort them based on interface indexes */ - if (osif->addr.s_addr != 0 || osif->ifindex > ifindex) - break; - } - pn = node; - } - - osif = ospf_snmp_if_new (); - if (addr) /* Usual interface */ - { - osif->addr = *addr; - - /* This field is used for storing ospfAddressLessIf OID value, - * conform to RFC1850 OSPF-MIB specification, it must be 0 for - * usual interface */ - osif->ifindex = 0; - } - else /* Unnumbered interface */ - osif->ifindex = ifindex; - osif->ifp = ifp; - - listnode_add_after (ospf_snmp_iflist, pn, osif); - return 0; + osif->addr = *addr; + + /* This field is used for storing ospfAddressLessIf OID value, + * conform to RFC1850 OSPF-MIB specification, it must be 0 for + * usual interface */ + osif->ifindex = 0; + } else /* Unnumbered interface */ + osif->ifindex = ifindex; + osif->ifp = ifp; + + listnode_add_after(ospf_snmp_iflist, pn, osif); + return 0; } -static int -ospf_snmp_is_if_have_addr (struct interface *ifp) +static int ospf_snmp_is_if_have_addr(struct interface *ifp) { - struct listnode *nn; - struct connected *ifc; - - /* Is this interface having any connected IPv4 address ? */ - for (ALL_LIST_ELEMENTS_RO (ifp->connected, nn, ifc)) - { - if (CONNECTED_PREFIX(ifc)->family == AF_INET) - return 1; - } - - return 0; + struct listnode *nn; + struct connected *ifc; + + /* Is this interface having any connected IPv4 address ? */ + for (ALL_LIST_ELEMENTS_RO(ifp->connected, nn, ifc)) { + if (CONNECTED_PREFIX(ifc)->family == AF_INET) + return 1; + } + + return 0; } -static struct ospf_interface * -ospf_snmp_if_lookup (struct in_addr *ifaddr, ifindex_t *ifindex) +static struct ospf_interface *ospf_snmp_if_lookup(struct in_addr *ifaddr, + ifindex_t *ifindex) { - struct listnode *node; - struct ospf_snmp_if *osif; - struct ospf_interface *oi = NULL; - struct ospf *ospf = ospf_lookup (); - - for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, node, osif)) - { - if (ifaddr->s_addr) - { - if (IPV4_ADDR_SAME (&osif->addr, ifaddr)) - oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr); - } - else - { - if (osif->ifindex == *ifindex) - oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr); - } - } - return oi; + struct listnode *node; + struct ospf_snmp_if *osif; + struct ospf_interface *oi = NULL; + struct ospf *ospf = ospf_lookup(); + + for (ALL_LIST_ELEMENTS_RO(ospf_snmp_iflist, node, osif)) { + if (ifaddr->s_addr) { + if (IPV4_ADDR_SAME(&osif->addr, ifaddr)) + oi = ospf_if_lookup_by_local_addr( + ospf, osif->ifp, *ifaddr); + } else { + if (osif->ifindex == *ifindex) + oi = ospf_if_lookup_by_local_addr( + ospf, osif->ifp, *ifaddr); + } + } + return oi; } -static struct ospf_interface * -ospf_snmp_if_lookup_next (struct in_addr *ifaddr, ifindex_t *ifindex, - int ifaddr_next, ifindex_t ifindex_next) +static struct ospf_interface *ospf_snmp_if_lookup_next(struct in_addr *ifaddr, + ifindex_t *ifindex, + int ifaddr_next, + ifindex_t ifindex_next) { - struct ospf_snmp_if *osif; - struct listnode *nn; - struct ospf *ospf = ospf_lookup (); - struct ospf_interface *oi = NULL; - - if (ospf == NULL) - return NULL; - - /* No instance is specified --> Return the first OSPF interface */ - if (ifaddr_next) - { - for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, nn, osif)) - { - osif = listgetdata (nn); - *ifaddr = osif->addr; - *ifindex = osif->ifindex; - /* Because no instance is specified, we don't care about the kind of - * interface (usual or unnumbered), just returning the first valid - * OSPF interface */ - oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr); - if (oi) - return (oi); + struct ospf_snmp_if *osif; + struct listnode *nn; + struct ospf *ospf = ospf_lookup(); + struct ospf_interface *oi = NULL; + + if (ospf == NULL) + return NULL; + + /* No instance is specified --> Return the first OSPF interface */ + if (ifaddr_next) { + for (ALL_LIST_ELEMENTS_RO(ospf_snmp_iflist, nn, osif)) { + osif = listgetdata(nn); + *ifaddr = osif->addr; + *ifindex = osif->ifindex; + /* Because no instance is specified, we don't care about + * the kind of + * interface (usual or unnumbered), just returning the + * first valid + * OSPF interface */ + oi = ospf_if_lookup_by_local_addr(ospf, osif->ifp, + *ifaddr); + if (oi) + return (oi); + } + return NULL; } - return NULL; - } - - /* An instance is specified --> Return the next OSPF interface */ - for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, nn, osif)) - { - /* Usual interface */ - if (ifaddr->s_addr) - { - /* The interface must have valid AF_INET connected address */ - /* it must have lager IPv4 address value than the lookup entry */ - if ((ospf_snmp_is_if_have_addr(osif->ifp)) && - (ntohl (osif->addr.s_addr) > ntohl (ifaddr->s_addr))) - { - *ifaddr = osif->addr; - *ifindex = osif->ifindex; - - /* and it must be an OSPF interface */ - oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr); - if (oi) - return oi; - } + + /* An instance is specified --> Return the next OSPF interface */ + for (ALL_LIST_ELEMENTS_RO(ospf_snmp_iflist, nn, osif)) { + /* Usual interface */ + if (ifaddr->s_addr) { + /* The interface must have valid AF_INET connected + * address */ + /* it must have lager IPv4 address value than the lookup + * entry */ + if ((ospf_snmp_is_if_have_addr(osif->ifp)) + && (ntohl(osif->addr.s_addr) + > ntohl(ifaddr->s_addr))) { + *ifaddr = osif->addr; + *ifindex = osif->ifindex; + + /* and it must be an OSPF interface */ + oi = ospf_if_lookup_by_local_addr( + ospf, osif->ifp, *ifaddr); + if (oi) + return oi; + } + } + /* Unnumbered interface */ + else + /* The interface must NOT have valid AF_INET connected + address */ + /* it must have lager interface index than the lookup + entry */ + if ((!ospf_snmp_is_if_have_addr(osif->ifp)) + && (osif->ifindex > *ifindex)) { + *ifaddr = osif->addr; + *ifindex = osif->ifindex; + + /* and it must be an OSPF interface */ + oi = ospf_if_lookup_by_local_addr(ospf, osif->ifp, + *ifaddr); + if (oi) + return oi; + } } - /* Unnumbered interface */ - else - /* The interface must NOT have valid AF_INET connected address */ - /* it must have lager interface index than the lookup entry */ - if ((!ospf_snmp_is_if_have_addr(osif->ifp)) && - (osif->ifindex > *ifindex)) - { - *ifaddr = osif->addr; - *ifindex = osif->ifindex; - - /* and it must be an OSPF interface */ - oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr); - if (oi) - return oi; - } - } - return NULL; + return NULL; } -static int -ospf_snmp_iftype (struct interface *ifp) +static int ospf_snmp_iftype(struct interface *ifp) { #define ospf_snmp_iftype_broadcast 1 #define ospf_snmp_iftype_nbma 2 #define ospf_snmp_iftype_pointToPoint 3 #define ospf_snmp_iftype_pointToMultipoint 5 - if (if_is_broadcast (ifp)) - return ospf_snmp_iftype_broadcast; - if (if_is_pointopoint (ifp)) - return ospf_snmp_iftype_pointToPoint; - return ospf_snmp_iftype_broadcast; + if (if_is_broadcast(ifp)) + return ospf_snmp_iftype_broadcast; + if (if_is_pointopoint(ifp)) + return ospf_snmp_iftype_pointToPoint; + return ospf_snmp_iftype_broadcast; } -static struct ospf_interface * -ospfIfLookup (struct variable *v, oid *name, size_t *length, - struct in_addr *ifaddr, ifindex_t *ifindex, int exact) +static struct ospf_interface *ospfIfLookup(struct variable *v, oid *name, + size_t *length, + struct in_addr *ifaddr, + ifindex_t *ifindex, int exact) { - unsigned int len; - int ifaddr_next = 0; - ifindex_t ifindex_next = 0; - struct ospf_interface *oi; - oid *offset; - - if (exact) - { - if (*length != v->namelen + IN_ADDR_SIZE + 1) - return NULL; - - oid2in_addr (name + v->namelen, IN_ADDR_SIZE, ifaddr); - *ifindex = name[v->namelen + IN_ADDR_SIZE]; - - return ospf_snmp_if_lookup (ifaddr, ifindex); - } - else - { - len = *length - v->namelen; - if (len >= IN_ADDR_SIZE) - len = IN_ADDR_SIZE; - if (len <= 0) - ifaddr_next = 1; - - oid2in_addr (name + v->namelen, len, ifaddr); - - len = *length - v->namelen - IN_ADDR_SIZE; - if (len >= 1) - len = 1; - else - ifindex_next = 1; - - if (len == 1) - *ifindex = name[v->namelen + IN_ADDR_SIZE]; - - oi = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next, - ifindex_next); - if (oi) - { - *length = v->namelen + IN_ADDR_SIZE + 1; - offset = name + v->namelen; - oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE); - offset += IN_ADDR_SIZE; - *offset = *ifindex; - return oi; + unsigned int len; + int ifaddr_next = 0; + ifindex_t ifindex_next = 0; + struct ospf_interface *oi; + oid *offset; + + if (exact) { + if (*length != v->namelen + IN_ADDR_SIZE + 1) + return NULL; + + oid2in_addr(name + v->namelen, IN_ADDR_SIZE, ifaddr); + *ifindex = name[v->namelen + IN_ADDR_SIZE]; + + return ospf_snmp_if_lookup(ifaddr, ifindex); + } else { + len = *length - v->namelen; + if (len >= IN_ADDR_SIZE) + len = IN_ADDR_SIZE; + if (len <= 0) + ifaddr_next = 1; + + oid2in_addr(name + v->namelen, len, ifaddr); + + len = *length - v->namelen - IN_ADDR_SIZE; + if (len >= 1) + len = 1; + else + ifindex_next = 1; + + if (len == 1) + *ifindex = name[v->namelen + IN_ADDR_SIZE]; + + oi = ospf_snmp_if_lookup_next(ifaddr, ifindex, ifaddr_next, + ifindex_next); + if (oi) { + *length = v->namelen + IN_ADDR_SIZE + 1; + offset = name + v->namelen; + oid_copy_addr(offset, ifaddr, IN_ADDR_SIZE); + offset += IN_ADDR_SIZE; + *offset = *ifindex; + return oi; + } } - } - return NULL; + return NULL; } -static u_char * -ospfIfEntry (struct variable *v, oid *name, size_t *length, int exact, - size_t *var_len, WriteMethod **write_method) +static u_char *ospfIfEntry(struct variable *v, oid *name, size_t *length, + int exact, size_t *var_len, + WriteMethod **write_method) { - ifindex_t ifindex; - struct in_addr ifaddr; - struct ospf_interface *oi; - struct ospf *ospf; - - if (smux_header_table(v, name, length, exact, var_len, write_method) - == MATCH_FAILED) - return NULL; - - ifindex = 0; - memset (&ifaddr, 0, sizeof (struct in_addr)); - - /* Check OSPF instance. */ - ospf = ospf_lookup (); - if (ospf == NULL) - return NULL; - - oi = ospfIfLookup (v, name, length, &ifaddr, &ifindex, exact); - if (oi == NULL) - return NULL; - - /* Return the current value of the variable */ - switch (v->magic) - { - case OSPFIFIPADDRESS: /* 1 */ - return SNMP_IPADDRESS (ifaddr); - break; - case OSPFADDRESSLESSIF: /* 2 */ - return SNMP_INTEGER (ifindex); - break; - case OSPFIFAREAID: /* 3 */ - if (oi->area) - return SNMP_IPADDRESS (oi->area->area_id); - else - return SNMP_IPADDRESS (ospf_empty_addr); - break; - case OSPFIFTYPE: /* 4 */ - return SNMP_INTEGER (ospf_snmp_iftype (oi->ifp)); - break; - case OSPFIFADMINSTAT: /* 5 */ - if (oi) - return SNMP_INTEGER (OSPF_STATUS_ENABLED); - else - return SNMP_INTEGER (OSPF_STATUS_DISABLED); - break; - case OSPFIFRTRPRIORITY: /* 6 */ - return SNMP_INTEGER (PRIORITY (oi)); - break; - case OSPFIFTRANSITDELAY: /* 7 */ - return SNMP_INTEGER (OSPF_IF_PARAM (oi, transmit_delay)); - break; - case OSPFIFRETRANSINTERVAL: /* 8 */ - return SNMP_INTEGER (OSPF_IF_PARAM (oi, retransmit_interval)); - break; - case OSPFIFHELLOINTERVAL: /* 9 */ - return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_hello)); - break; - case OSPFIFRTRDEADINTERVAL: /* 10 */ - return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_wait)); - break; - case OSPFIFPOLLINTERVAL: /* 11 */ - return SNMP_INTEGER (OSPF_POLL_INTERVAL_DEFAULT); - break; - case OSPFIFSTATE: /* 12 */ - return SNMP_INTEGER (ISM_SNMP(oi->state)); - break; - case OSPFIFDESIGNATEDROUTER: /* 13 */ - return SNMP_IPADDRESS (DR (oi)); - break; - case OSPFIFBACKUPDESIGNATEDROUTER: /* 14 */ - return SNMP_IPADDRESS (BDR (oi)); - break; - case OSPFIFEVENTS: /* 15 */ - return SNMP_INTEGER (oi->state_change); - break; - case OSPFIFAUTHKEY: /* 16 */ - *var_len = 0; - return (u_char *) OSPF_IF_PARAM (oi, auth_simple); - break; - case OSPFIFSTATUS: /* 17 */ - return SNMP_INTEGER (SNMP_VALID); - break; - case OSPFIFMULTICASTFORWARDING: /* 18 */ + ifindex_t ifindex; + struct in_addr ifaddr; + struct ospf_interface *oi; + struct ospf *ospf; + + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + + ifindex = 0; + memset(&ifaddr, 0, sizeof(struct in_addr)); + + /* Check OSPF instance. */ + ospf = ospf_lookup(); + if (ospf == NULL) + return NULL; + + oi = ospfIfLookup(v, name, length, &ifaddr, &ifindex, exact); + if (oi == NULL) + return NULL; + + /* Return the current value of the variable */ + switch (v->magic) { + case OSPFIFIPADDRESS: /* 1 */ + return SNMP_IPADDRESS(ifaddr); + break; + case OSPFADDRESSLESSIF: /* 2 */ + return SNMP_INTEGER(ifindex); + break; + case OSPFIFAREAID: /* 3 */ + if (oi->area) + return SNMP_IPADDRESS(oi->area->area_id); + else + return SNMP_IPADDRESS(ospf_empty_addr); + break; + case OSPFIFTYPE: /* 4 */ + return SNMP_INTEGER(ospf_snmp_iftype(oi->ifp)); + break; + case OSPFIFADMINSTAT: /* 5 */ + if (oi) + return SNMP_INTEGER(OSPF_STATUS_ENABLED); + else + return SNMP_INTEGER(OSPF_STATUS_DISABLED); + break; + case OSPFIFRTRPRIORITY: /* 6 */ + return SNMP_INTEGER(PRIORITY(oi)); + break; + case OSPFIFTRANSITDELAY: /* 7 */ + return SNMP_INTEGER(OSPF_IF_PARAM(oi, transmit_delay)); + break; + case OSPFIFRETRANSINTERVAL: /* 8 */ + return SNMP_INTEGER(OSPF_IF_PARAM(oi, retransmit_interval)); + break; + case OSPFIFHELLOINTERVAL: /* 9 */ + return SNMP_INTEGER(OSPF_IF_PARAM(oi, v_hello)); + break; + case OSPFIFRTRDEADINTERVAL: /* 10 */ + return SNMP_INTEGER(OSPF_IF_PARAM(oi, v_wait)); + break; + case OSPFIFPOLLINTERVAL: /* 11 */ + return SNMP_INTEGER(OSPF_POLL_INTERVAL_DEFAULT); + break; + case OSPFIFSTATE: /* 12 */ + return SNMP_INTEGER(ISM_SNMP(oi->state)); + break; + case OSPFIFDESIGNATEDROUTER: /* 13 */ + return SNMP_IPADDRESS(DR(oi)); + break; + case OSPFIFBACKUPDESIGNATEDROUTER: /* 14 */ + return SNMP_IPADDRESS(BDR(oi)); + break; + case OSPFIFEVENTS: /* 15 */ + return SNMP_INTEGER(oi->state_change); + break; + case OSPFIFAUTHKEY: /* 16 */ + *var_len = 0; + return (u_char *)OSPF_IF_PARAM(oi, auth_simple); + break; + case OSPFIFSTATUS: /* 17 */ + return SNMP_INTEGER(SNMP_VALID); + break; + case OSPFIFMULTICASTFORWARDING: /* 18 */ + /* $FRR indent$ */ + /* clang-format off */ #define ospf_snmp_multiforward_blocked 1 #define ospf_snmp_multiforward_multicast 2 #define ospf_snmp_multiforward_unicast 3 - return SNMP_INTEGER (ospf_snmp_multiforward_blocked); - break; - case OSPFIFDEMAND: /* 19 */ - return SNMP_INTEGER (SNMP_FALSE); - break; - case OSPFIFAUTHTYPE: /* 20 */ - if (oi->area) - return SNMP_INTEGER (oi->area->auth_type); - else - return SNMP_INTEGER (0); - break; - default: - return NULL; - break; - } - return NULL; + return SNMP_INTEGER(ospf_snmp_multiforward_blocked); + break; + case OSPFIFDEMAND: /* 19 */ + return SNMP_INTEGER(SNMP_FALSE); + break; + case OSPFIFAUTHTYPE: /* 20 */ + if (oi->area) + return SNMP_INTEGER(oi->area->auth_type); + else + return SNMP_INTEGER(0); + break; + default: + return NULL; + break; + } + return NULL; } #define OSPF_SNMP_METRIC_VALUE 1 -static struct ospf_interface * -ospfIfMetricLookup (struct variable *v, oid *name, size_t *length, - struct in_addr *ifaddr, ifindex_t *ifindex, int exact) +static struct ospf_interface *ospfIfMetricLookup(struct variable *v, oid *name, + size_t *length, + struct in_addr *ifaddr, + ifindex_t *ifindex, int exact) { - unsigned int len; - int ifaddr_next = 0; - ifindex_t ifindex_next = 0; - struct ospf_interface *oi; - oid *offset; - int metric; - - if (exact) - { - if (*length != v->namelen + IN_ADDR_SIZE + 1 + 1) - return NULL; - - oid2in_addr (name + v->namelen, IN_ADDR_SIZE, ifaddr); - *ifindex = name[v->namelen + IN_ADDR_SIZE]; - metric = name[v->namelen + IN_ADDR_SIZE + 1]; - - if (metric != OSPF_SNMP_METRIC_VALUE) - return NULL; - - return ospf_snmp_if_lookup (ifaddr, ifindex); - } - else - { - len = *length - v->namelen; - if (len >= IN_ADDR_SIZE) - len = IN_ADDR_SIZE; - else - ifaddr_next = 1; - - oid2in_addr (name + v->namelen, len, ifaddr); - - len = *length - v->namelen - IN_ADDR_SIZE; - if (len >= 1) - len = 1; - else - ifindex_next = 1; - - if (len == 1) - *ifindex = name[v->namelen + IN_ADDR_SIZE]; - - oi = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next, - ifindex_next); - if (oi) - { - *length = v->namelen + IN_ADDR_SIZE + 1 + 1; - offset = name + v->namelen; - oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE); - offset += IN_ADDR_SIZE; - *offset = *ifindex; - offset++; - *offset = OSPF_SNMP_METRIC_VALUE; - return oi; + unsigned int len; + int ifaddr_next = 0; + ifindex_t ifindex_next = 0; + struct ospf_interface *oi; + oid *offset; + int metric; + + if (exact) { + if (*length != v->namelen + IN_ADDR_SIZE + 1 + 1) + return NULL; + + oid2in_addr(name + v->namelen, IN_ADDR_SIZE, ifaddr); + *ifindex = name[v->namelen + IN_ADDR_SIZE]; + metric = name[v->namelen + IN_ADDR_SIZE + 1]; + + if (metric != OSPF_SNMP_METRIC_VALUE) + return NULL; + + return ospf_snmp_if_lookup(ifaddr, ifindex); + } else { + len = *length - v->namelen; + if (len >= IN_ADDR_SIZE) + len = IN_ADDR_SIZE; + else + ifaddr_next = 1; + + oid2in_addr(name + v->namelen, len, ifaddr); + + len = *length - v->namelen - IN_ADDR_SIZE; + if (len >= 1) + len = 1; + else + ifindex_next = 1; + + if (len == 1) + *ifindex = name[v->namelen + IN_ADDR_SIZE]; + + oi = ospf_snmp_if_lookup_next(ifaddr, ifindex, ifaddr_next, + ifindex_next); + if (oi) { + *length = v->namelen + IN_ADDR_SIZE + 1 + 1; + offset = name + v->namelen; + oid_copy_addr(offset, ifaddr, IN_ADDR_SIZE); + offset += IN_ADDR_SIZE; + *offset = *ifindex; + offset++; + *offset = OSPF_SNMP_METRIC_VALUE; + return oi; + } } - } - return NULL; + return NULL; } -static u_char * -ospfIfMetricEntry (struct variable *v, oid *name, size_t *length, int exact, - size_t *var_len, WriteMethod **write_method) +static u_char *ospfIfMetricEntry(struct variable *v, oid *name, size_t *length, + int exact, size_t *var_len, + WriteMethod **write_method) { - /* Currently we support metric 1 only. */ - ifindex_t ifindex; - struct in_addr ifaddr; - struct ospf_interface *oi; - struct ospf *ospf; - - if (smux_header_table(v, name, length, exact, var_len, write_method) - == MATCH_FAILED) - return NULL; - - ifindex = 0; - memset (&ifaddr, 0, sizeof (struct in_addr)); - - /* Check OSPF instance. */ - ospf = ospf_lookup (); - if (ospf == NULL) - return NULL; - - oi = ospfIfMetricLookup (v, name, length, &ifaddr, &ifindex, exact); - if (oi == NULL) - return NULL; - - /* Return the current value of the variable */ - switch (v->magic) - { - case OSPFIFMETRICIPADDRESS: - return SNMP_IPADDRESS (ifaddr); - break; - case OSPFIFMETRICADDRESSLESSIF: - return SNMP_INTEGER (ifindex); - break; - case OSPFIFMETRICTOS: - return SNMP_INTEGER (0); - break; - case OSPFIFMETRICVALUE: - return SNMP_INTEGER (OSPF_SNMP_METRIC_VALUE); - break; - case OSPFIFMETRICSTATUS: - return SNMP_INTEGER (1); - break; - default: - return NULL; - break; - } - return NULL; + /* Currently we support metric 1 only. */ + ifindex_t ifindex; + struct in_addr ifaddr; + struct ospf_interface *oi; + struct ospf *ospf; + + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + + ifindex = 0; + memset(&ifaddr, 0, sizeof(struct in_addr)); + + /* Check OSPF instance. */ + ospf = ospf_lookup(); + if (ospf == NULL) + return NULL; + + oi = ospfIfMetricLookup(v, name, length, &ifaddr, &ifindex, exact); + if (oi == NULL) + return NULL; + + /* Return the current value of the variable */ + switch (v->magic) { + case OSPFIFMETRICIPADDRESS: + return SNMP_IPADDRESS(ifaddr); + break; + case OSPFIFMETRICADDRESSLESSIF: + return SNMP_INTEGER(ifindex); + break; + case OSPFIFMETRICTOS: + return SNMP_INTEGER(0); + break; + case OSPFIFMETRICVALUE: + return SNMP_INTEGER(OSPF_SNMP_METRIC_VALUE); + break; + case OSPFIFMETRICSTATUS: + return SNMP_INTEGER(1); + break; + default: + return NULL; + break; + } + return NULL; } static struct route_table *ospf_snmp_vl_table; -static int -ospf_snmp_vl_add (struct ospf_vl_data *vl_data) +static int ospf_snmp_vl_add(struct ospf_vl_data *vl_data) { - struct prefix_ls lp; - struct route_node *rn; + struct prefix_ls lp; + struct route_node *rn; - memset (&lp, 0, sizeof (struct prefix_ls)); - lp.family = 0; - lp.prefixlen = 64; - lp.id = vl_data->vl_area_id; - lp.adv_router = vl_data->vl_peer; + memset(&lp, 0, sizeof(struct prefix_ls)); + lp.family = 0; + lp.prefixlen = 64; + lp.id = vl_data->vl_area_id; + lp.adv_router = vl_data->vl_peer; - rn = route_node_get (ospf_snmp_vl_table, (struct prefix *) &lp); - if (rn->info) - route_unlock_node (rn); + rn = route_node_get(ospf_snmp_vl_table, (struct prefix *)&lp); + if (rn->info) + route_unlock_node(rn); - rn->info = vl_data; - return 0; + rn->info = vl_data; + return 0; } -static int -ospf_snmp_vl_delete (struct ospf_vl_data *vl_data) +static int ospf_snmp_vl_delete(struct ospf_vl_data *vl_data) { - struct prefix_ls lp; - struct route_node *rn; - - memset (&lp, 0, sizeof (struct prefix_ls)); - lp.family = 0; - lp.prefixlen = 64; - lp.id = vl_data->vl_area_id; - lp.adv_router = vl_data->vl_peer; - - rn = route_node_lookup (ospf_snmp_vl_table, (struct prefix *) &lp); - if (! rn) - return 0; - rn->info = NULL; - route_unlock_node (rn); - route_unlock_node (rn); - return 0; + struct prefix_ls lp; + struct route_node *rn; + + memset(&lp, 0, sizeof(struct prefix_ls)); + lp.family = 0; + lp.prefixlen = 64; + lp.id = vl_data->vl_area_id; + lp.adv_router = vl_data->vl_peer; + + rn = route_node_lookup(ospf_snmp_vl_table, (struct prefix *)&lp); + if (!rn) + return 0; + rn->info = NULL; + route_unlock_node(rn); + route_unlock_node(rn); + return 0; } -static struct ospf_vl_data * -ospf_snmp_vl_lookup (struct in_addr *area_id, struct in_addr *neighbor) +static struct ospf_vl_data *ospf_snmp_vl_lookup(struct in_addr *area_id, + struct in_addr *neighbor) { - struct prefix_ls lp; - struct route_node *rn; - struct ospf_vl_data *vl_data; - - memset (&lp, 0, sizeof (struct prefix_ls)); - lp.family = 0; - lp.prefixlen = 64; - lp.id = *area_id; - lp.adv_router = *neighbor; - - rn = route_node_lookup (ospf_snmp_vl_table, (struct prefix *) &lp); - if (rn) - { - vl_data = rn->info; - route_unlock_node (rn); - return vl_data; - } - return NULL; + struct prefix_ls lp; + struct route_node *rn; + struct ospf_vl_data *vl_data; + + memset(&lp, 0, sizeof(struct prefix_ls)); + lp.family = 0; + lp.prefixlen = 64; + lp.id = *area_id; + lp.adv_router = *neighbor; + + rn = route_node_lookup(ospf_snmp_vl_table, (struct prefix *)&lp); + if (rn) { + vl_data = rn->info; + route_unlock_node(rn); + return vl_data; + } + return NULL; } -static struct ospf_vl_data * -ospf_snmp_vl_lookup_next (struct in_addr *area_id, struct in_addr *neighbor, - int first) +static struct ospf_vl_data *ospf_snmp_vl_lookup_next(struct in_addr *area_id, + struct in_addr *neighbor, + int first) { - struct prefix_ls lp; - struct route_node *rn; - struct ospf_vl_data *vl_data; - - memset (&lp, 0, sizeof (struct prefix_ls)); - lp.family = 0; - lp.prefixlen = 64; - lp.id = *area_id; - lp.adv_router = *neighbor; - - if (first) - rn = route_top (ospf_snmp_vl_table); - else - { - rn = route_node_get (ospf_snmp_vl_table, (struct prefix *) &lp); - rn = route_next (rn); - } - - for (; rn; rn = route_next (rn)) - if (rn->info) - break; - - if (rn && rn->info) - { - vl_data = rn->info; - *area_id = vl_data->vl_area_id; - *neighbor = vl_data->vl_peer; - route_unlock_node (rn); - return vl_data; - } - return NULL; -} + struct prefix_ls lp; + struct route_node *rn; + struct ospf_vl_data *vl_data; + + memset(&lp, 0, sizeof(struct prefix_ls)); + lp.family = 0; + lp.prefixlen = 64; + lp.id = *area_id; + lp.adv_router = *neighbor; + + if (first) + rn = route_top(ospf_snmp_vl_table); + else { + rn = route_node_get(ospf_snmp_vl_table, (struct prefix *)&lp); + rn = route_next(rn); + } -static struct ospf_vl_data * -ospfVirtIfLookup (struct variable *v, oid *name, size_t *length, - struct in_addr *area_id, struct in_addr *neighbor, int exact) -{ - int first; - unsigned int len; - struct ospf_vl_data *vl_data; + for (; rn; rn = route_next(rn)) + if (rn->info) + break; - if (exact) - { - if (*length != v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE) + if (rn && rn->info) { + vl_data = rn->info; + *area_id = vl_data->vl_area_id; + *neighbor = vl_data->vl_peer; + route_unlock_node(rn); + return vl_data; + } return NULL; +} - oid2in_addr (name + v->namelen, IN_ADDR_SIZE, area_id); - oid2in_addr (name + v->namelen + IN_ADDR_SIZE, IN_ADDR_SIZE, neighbor); - - return ospf_snmp_vl_lookup (area_id, neighbor); - } - else - { - first = 0; - - len = *length - v->namelen; - if (len <= 0) - first = 1; - if (len > IN_ADDR_SIZE) - len = IN_ADDR_SIZE; - oid2in_addr (name + v->namelen, len, area_id); - - len = *length - v->namelen - IN_ADDR_SIZE; - if (len > IN_ADDR_SIZE) - len = IN_ADDR_SIZE; - oid2in_addr (name + v->namelen + IN_ADDR_SIZE, len, neighbor); - - vl_data = ospf_snmp_vl_lookup_next (area_id, neighbor, first); - - if (vl_data) - { - *length = v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE; - oid_copy_addr (name + v->namelen, area_id, IN_ADDR_SIZE); - oid_copy_addr (name + v->namelen + IN_ADDR_SIZE, neighbor, - IN_ADDR_SIZE); - return vl_data; +static struct ospf_vl_data * +ospfVirtIfLookup(struct variable *v, oid *name, size_t *length, + struct in_addr *area_id, struct in_addr *neighbor, int exact) +{ + int first; + unsigned int len; + struct ospf_vl_data *vl_data; + + if (exact) { + if (*length != v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE) + return NULL; + + oid2in_addr(name + v->namelen, IN_ADDR_SIZE, area_id); + oid2in_addr(name + v->namelen + IN_ADDR_SIZE, IN_ADDR_SIZE, + neighbor); + + return ospf_snmp_vl_lookup(area_id, neighbor); + } else { + first = 0; + + len = *length - v->namelen; + if (len <= 0) + first = 1; + if (len > IN_ADDR_SIZE) + len = IN_ADDR_SIZE; + oid2in_addr(name + v->namelen, len, area_id); + + len = *length - v->namelen - IN_ADDR_SIZE; + if (len > IN_ADDR_SIZE) + len = IN_ADDR_SIZE; + oid2in_addr(name + v->namelen + IN_ADDR_SIZE, len, neighbor); + + vl_data = ospf_snmp_vl_lookup_next(area_id, neighbor, first); + + if (vl_data) { + *length = v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE; + oid_copy_addr(name + v->namelen, area_id, IN_ADDR_SIZE); + oid_copy_addr(name + v->namelen + IN_ADDR_SIZE, + neighbor, IN_ADDR_SIZE); + return vl_data; + } } - } - return NULL; + return NULL; } -static u_char * -ospfVirtIfEntry (struct variable *v, oid *name, size_t *length, int exact, - size_t *var_len, WriteMethod **write_method) +static u_char *ospfVirtIfEntry(struct variable *v, oid *name, size_t *length, + int exact, size_t *var_len, + WriteMethod **write_method) { - struct ospf_vl_data *vl_data; - struct ospf_interface *oi; - struct in_addr area_id; - struct in_addr neighbor; - - if (smux_header_table(v, name, length, exact, var_len, write_method) - == MATCH_FAILED) - return NULL; - - memset (&area_id, 0, sizeof (struct in_addr)); - memset (&neighbor, 0, sizeof (struct in_addr)); - - vl_data = ospfVirtIfLookup (v, name, length, &area_id, &neighbor, exact); - if (! vl_data) - return NULL; - oi = vl_data->vl_oi; - if (! oi) - return NULL; - - /* Return the current value of the variable */ - switch (v->magic) - { - case OSPFVIRTIFAREAID: - return SNMP_IPADDRESS (area_id); - break; - case OSPFVIRTIFNEIGHBOR: - return SNMP_IPADDRESS (neighbor); - break; - case OSPFVIRTIFTRANSITDELAY: - return SNMP_INTEGER (OSPF_IF_PARAM (oi, transmit_delay)); - break; - case OSPFVIRTIFRETRANSINTERVAL: - return SNMP_INTEGER (OSPF_IF_PARAM (oi, retransmit_interval)); - break; - case OSPFVIRTIFHELLOINTERVAL: - return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_hello)); - break; - case OSPFVIRTIFRTRDEADINTERVAL: - return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_wait)); - break; - case OSPFVIRTIFSTATE: - return SNMP_INTEGER (oi->state); - break; - case OSPFVIRTIFEVENTS: - return SNMP_INTEGER (oi->state_change); - break; - case OSPFVIRTIFAUTHKEY: - *var_len = 0; - return (u_char *) OSPF_IF_PARAM (oi, auth_simple); - break; - case OSPFVIRTIFSTATUS: - return SNMP_INTEGER (SNMP_VALID); - break; - case OSPFVIRTIFAUTHTYPE: - if (oi->area) - return SNMP_INTEGER (oi->area->auth_type); - else - return SNMP_INTEGER (0); - break; - default: - return NULL; - break; - } - return NULL; + struct ospf_vl_data *vl_data; + struct ospf_interface *oi; + struct in_addr area_id; + struct in_addr neighbor; + + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + + memset(&area_id, 0, sizeof(struct in_addr)); + memset(&neighbor, 0, sizeof(struct in_addr)); + + vl_data = ospfVirtIfLookup(v, name, length, &area_id, &neighbor, exact); + if (!vl_data) + return NULL; + oi = vl_data->vl_oi; + if (!oi) + return NULL; + + /* Return the current value of the variable */ + switch (v->magic) { + case OSPFVIRTIFAREAID: + return SNMP_IPADDRESS(area_id); + break; + case OSPFVIRTIFNEIGHBOR: + return SNMP_IPADDRESS(neighbor); + break; + case OSPFVIRTIFTRANSITDELAY: + return SNMP_INTEGER(OSPF_IF_PARAM(oi, transmit_delay)); + break; + case OSPFVIRTIFRETRANSINTERVAL: + return SNMP_INTEGER(OSPF_IF_PARAM(oi, retransmit_interval)); + break; + case OSPFVIRTIFHELLOINTERVAL: + return SNMP_INTEGER(OSPF_IF_PARAM(oi, v_hello)); + break; + case OSPFVIRTIFRTRDEADINTERVAL: + return SNMP_INTEGER(OSPF_IF_PARAM(oi, v_wait)); + break; + case OSPFVIRTIFSTATE: + return SNMP_INTEGER(oi->state); + break; + case OSPFVIRTIFEVENTS: + return SNMP_INTEGER(oi->state_change); + break; + case OSPFVIRTIFAUTHKEY: + *var_len = 0; + return (u_char *)OSPF_IF_PARAM(oi, auth_simple); + break; + case OSPFVIRTIFSTATUS: + return SNMP_INTEGER(SNMP_VALID); + break; + case OSPFVIRTIFAUTHTYPE: + if (oi->area) + return SNMP_INTEGER(oi->area->auth_type); + else + return SNMP_INTEGER(0); + break; + default: + return NULL; + break; + } + return NULL; } -static struct ospf_neighbor * -ospf_snmp_nbr_lookup (struct ospf *ospf, struct in_addr *nbr_addr, - ifindex_t *ifindex) +static struct ospf_neighbor *ospf_snmp_nbr_lookup(struct ospf *ospf, + struct in_addr *nbr_addr, + ifindex_t *ifindex) { - struct listnode *node, *nnode; - struct ospf_interface *oi; - struct ospf_neighbor *nbr; - struct route_node *rn; - - for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) - { - for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) - if ((nbr = rn->info) != NULL - && nbr != oi->nbr_self -/* If EXACT match is needed, provide ALL entry found - && nbr->state != NSM_Down - */ - && nbr->src.s_addr != 0) - { - if (IPV4_ADDR_SAME (&nbr->src, nbr_addr)) - { - route_unlock_node (rn); - return nbr; - } - } - } - return NULL; + struct listnode *node, *nnode; + struct ospf_interface *oi; + struct ospf_neighbor *nbr; + struct route_node *rn; + + for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) { + for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) + if ((nbr = rn->info) != NULL && nbr != oi->nbr_self + /* If EXACT match is needed, provide ALL entry found + && nbr->state != NSM_Down + */ + && nbr->src.s_addr != 0) { + if (IPV4_ADDR_SAME(&nbr->src, nbr_addr)) { + route_unlock_node(rn); + return nbr; + } + } + } + return NULL; } -static struct ospf_neighbor * -ospf_snmp_nbr_lookup_next (struct in_addr *nbr_addr, ifindex_t *ifindex, - int first) +static struct ospf_neighbor *ospf_snmp_nbr_lookup_next(struct in_addr *nbr_addr, + ifindex_t *ifindex, + int first) { - struct listnode *nn; - struct ospf_interface *oi; - struct ospf_neighbor *nbr; - struct route_node *rn; - struct ospf_neighbor *min = NULL; - struct ospf *ospf = ospf; - - ospf = ospf_lookup (); - - for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, nn, oi)) - { - for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) - if ((nbr = rn->info) != NULL - && nbr != oi->nbr_self - && nbr->state != NSM_Down - && nbr->src.s_addr != 0) - { - if (first) - { - if (! min) - min = nbr; - else if (ntohl (nbr->src.s_addr) < ntohl (min->src.s_addr)) - min = nbr; - } - else if (ntohl (nbr->src.s_addr) > ntohl (nbr_addr->s_addr)) - { - if (! min) - min = nbr; - else if (ntohl (nbr->src.s_addr) < ntohl (min->src.s_addr)) - min = nbr; - } - } - } - if (min) - { - *nbr_addr = min->src; - *ifindex = 0; - return min; - } - return NULL; + struct listnode *nn; + struct ospf_interface *oi; + struct ospf_neighbor *nbr; + struct route_node *rn; + struct ospf_neighbor *min = NULL; + struct ospf *ospf = ospf; + + ospf = ospf_lookup(); + + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, nn, oi)) { + for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) + if ((nbr = rn->info) != NULL && nbr != oi->nbr_self + && nbr->state != NSM_Down && nbr->src.s_addr != 0) { + if (first) { + if (!min) + min = nbr; + else if (ntohl(nbr->src.s_addr) + < ntohl(min->src.s_addr)) + min = nbr; + } else if (ntohl(nbr->src.s_addr) + > ntohl(nbr_addr->s_addr)) { + if (!min) + min = nbr; + else if (ntohl(nbr->src.s_addr) + < ntohl(min->src.s_addr)) + min = nbr; + } + } + } + if (min) { + *nbr_addr = min->src; + *ifindex = 0; + return min; + } + return NULL; } -static struct ospf_neighbor * -ospfNbrLookup (struct variable *v, oid *name, size_t *length, - struct in_addr *nbr_addr, ifindex_t *ifindex, int exact) +static struct ospf_neighbor *ospfNbrLookup(struct variable *v, oid *name, + size_t *length, + struct in_addr *nbr_addr, + ifindex_t *ifindex, int exact) { - unsigned int len; - int first; - struct ospf_neighbor *nbr; - struct ospf *ospf; + unsigned int len; + int first; + struct ospf_neighbor *nbr; + struct ospf *ospf; - ospf = ospf_lookup (); + ospf = ospf_lookup(); - if (! ospf) - return NULL; + if (!ospf) + return NULL; - if (exact) - { - if (*length != v->namelen + IN_ADDR_SIZE + 1) - return NULL; + if (exact) { + if (*length != v->namelen + IN_ADDR_SIZE + 1) + return NULL; - oid2in_addr (name + v->namelen, IN_ADDR_SIZE, nbr_addr); - *ifindex = name[v->namelen + IN_ADDR_SIZE]; + oid2in_addr(name + v->namelen, IN_ADDR_SIZE, nbr_addr); + *ifindex = name[v->namelen + IN_ADDR_SIZE]; - return ospf_snmp_nbr_lookup (ospf, nbr_addr, ifindex); - } - else - { - first = 0; - len = *length - v->namelen; + return ospf_snmp_nbr_lookup(ospf, nbr_addr, ifindex); + } else { + first = 0; + len = *length - v->namelen; - if (len <= 0) - first = 1; + if (len <= 0) + first = 1; - if (len > IN_ADDR_SIZE) - len = IN_ADDR_SIZE; + if (len > IN_ADDR_SIZE) + len = IN_ADDR_SIZE; - oid2in_addr (name + v->namelen, len, nbr_addr); + oid2in_addr(name + v->namelen, len, nbr_addr); - len = *length - v->namelen - IN_ADDR_SIZE; - if (len >= 1) - *ifindex = name[v->namelen + IN_ADDR_SIZE]; - - nbr = ospf_snmp_nbr_lookup_next (nbr_addr, ifindex, first); + len = *length - v->namelen - IN_ADDR_SIZE; + if (len >= 1) + *ifindex = name[v->namelen + IN_ADDR_SIZE]; - if (nbr) - { - *length = v->namelen + IN_ADDR_SIZE + 1; - oid_copy_addr (name + v->namelen, nbr_addr, IN_ADDR_SIZE); - name[v->namelen + IN_ADDR_SIZE] = *ifindex; - return nbr; + nbr = ospf_snmp_nbr_lookup_next(nbr_addr, ifindex, first); + + if (nbr) { + *length = v->namelen + IN_ADDR_SIZE + 1; + oid_copy_addr(name + v->namelen, nbr_addr, + IN_ADDR_SIZE); + name[v->namelen + IN_ADDR_SIZE] = *ifindex; + return nbr; + } } - } - return NULL; + return NULL; } /* map internal quagga neighbor states to official MIB values: ospfNbrState OBJECT-TYPE - SYNTAX INTEGER { - down (1), - attempt (2), - init (3), - twoWay (4), - exchangeStart (5), - exchange (6), - loading (7), - full (8) - } + SYNTAX INTEGER { + down (1), + attempt (2), + init (3), + twoWay (4), + exchangeStart (5), + exchange (6), + loading (7), + full (8) + } */ -static int32_t -ospf_snmp_neighbor_state(u_char nst) +static int32_t ospf_snmp_neighbor_state(u_char nst) { - switch (nst) - { - case NSM_Attempt: - return 2; - case NSM_Init: - return 3; - case NSM_TwoWay: - return 4; - case NSM_ExStart: - return 5; - case NSM_Exchange: - return 6; - case NSM_Loading: - return 7; - case NSM_Full: - return 8; - default: - return 1; /* down */ - } + switch (nst) { + case NSM_Attempt: + return 2; + case NSM_Init: + return 3; + case NSM_TwoWay: + return 4; + case NSM_ExStart: + return 5; + case NSM_Exchange: + return 6; + case NSM_Loading: + return 7; + case NSM_Full: + return 8; + default: + return 1; /* down */ + } } -static u_char * -ospfNbrEntry (struct variable *v, oid *name, size_t *length, int exact, - size_t *var_len, WriteMethod **write_method) +static u_char *ospfNbrEntry(struct variable *v, oid *name, size_t *length, + int exact, size_t *var_len, + WriteMethod **write_method) { - struct in_addr nbr_addr; - ifindex_t ifindex; - struct ospf_neighbor *nbr; - struct ospf_interface *oi; - - if (smux_header_table(v, name, length, exact, var_len, write_method) - == MATCH_FAILED) - return NULL; - - memset (&nbr_addr, 0, sizeof (struct in_addr)); - ifindex = 0; - - nbr = ospfNbrLookup (v, name, length, &nbr_addr, &ifindex, exact); - if (! nbr) - return NULL; - oi = nbr->oi; - if (! oi) - return NULL; - - /* Return the current value of the variable */ - switch (v->magic) - { - case OSPFNBRIPADDR: - return SNMP_IPADDRESS (nbr_addr); - break; - case OSPFNBRADDRESSLESSINDEX: - return SNMP_INTEGER (ifindex); - break; - case OSPFNBRRTRID: - return SNMP_IPADDRESS (nbr->router_id); - break; - case OSPFNBROPTIONS: - return SNMP_INTEGER (oi->nbr_self->options); - break; - case OSPFNBRPRIORITY: - return SNMP_INTEGER (nbr->priority); - break; - case OSPFNBRSTATE: - return SNMP_INTEGER (ospf_snmp_neighbor_state(nbr->state)); - break; - case OSPFNBREVENTS: - return SNMP_INTEGER (nbr->state_change); - break; - case OSPFNBRLSRETRANSQLEN: - return SNMP_INTEGER (ospf_ls_retransmit_count (nbr)); - break; - case OSPFNBMANBRSTATUS: - return SNMP_INTEGER (SNMP_VALID); - break; - case OSPFNBMANBRPERMANENCE: - return SNMP_INTEGER (2); - break; - case OSPFNBRHELLOSUPPRESSED: - return SNMP_INTEGER (SNMP_FALSE); - break; - default: - return NULL; - break; - } - return NULL; + struct in_addr nbr_addr; + ifindex_t ifindex; + struct ospf_neighbor *nbr; + struct ospf_interface *oi; + + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + + memset(&nbr_addr, 0, sizeof(struct in_addr)); + ifindex = 0; + + nbr = ospfNbrLookup(v, name, length, &nbr_addr, &ifindex, exact); + if (!nbr) + return NULL; + oi = nbr->oi; + if (!oi) + return NULL; + + /* Return the current value of the variable */ + switch (v->magic) { + case OSPFNBRIPADDR: + return SNMP_IPADDRESS(nbr_addr); + break; + case OSPFNBRADDRESSLESSINDEX: + return SNMP_INTEGER(ifindex); + break; + case OSPFNBRRTRID: + return SNMP_IPADDRESS(nbr->router_id); + break; + case OSPFNBROPTIONS: + return SNMP_INTEGER(oi->nbr_self->options); + break; + case OSPFNBRPRIORITY: + return SNMP_INTEGER(nbr->priority); + break; + case OSPFNBRSTATE: + return SNMP_INTEGER(ospf_snmp_neighbor_state(nbr->state)); + break; + case OSPFNBREVENTS: + return SNMP_INTEGER(nbr->state_change); + break; + case OSPFNBRLSRETRANSQLEN: + return SNMP_INTEGER(ospf_ls_retransmit_count(nbr)); + break; + case OSPFNBMANBRSTATUS: + return SNMP_INTEGER(SNMP_VALID); + break; + case OSPFNBMANBRPERMANENCE: + return SNMP_INTEGER(2); + break; + case OSPFNBRHELLOSUPPRESSED: + return SNMP_INTEGER(SNMP_FALSE); + break; + default: + return NULL; + break; + } + return NULL; } -static u_char * -ospfVirtNbrEntry (struct variable *v, oid *name, size_t *length, int exact, - size_t *var_len, WriteMethod **write_method) +static u_char *ospfVirtNbrEntry(struct variable *v, oid *name, size_t *length, + int exact, size_t *var_len, + WriteMethod **write_method) { - struct ospf_vl_data *vl_data; - struct in_addr area_id; - struct in_addr neighbor; - struct ospf *ospf; - - if (smux_header_table(v, name, length, exact, var_len, write_method) - == MATCH_FAILED) - return NULL; - - memset (&area_id, 0, sizeof (struct in_addr)); - memset (&neighbor, 0, sizeof (struct in_addr)); - - /* Check OSPF instance. */ - ospf = ospf_lookup (); - if (ospf == NULL) - return NULL; - - vl_data = ospfVirtIfLookup (v, name, length, &area_id, &neighbor, exact); - if (! vl_data) - return NULL; - - /* Return the current value of the variable */ - switch (v->magic) - { - case OSPFVIRTNBRAREA: - return (u_char *) NULL; - break; - case OSPFVIRTNBRRTRID: - return (u_char *) NULL; - break; - case OSPFVIRTNBRIPADDR: - return (u_char *) NULL; - break; - case OSPFVIRTNBROPTIONS: - return (u_char *) NULL; - break; - case OSPFVIRTNBRSTATE: - return (u_char *) NULL; - break; - case OSPFVIRTNBREVENTS: - return (u_char *) NULL; - break; - case OSPFVIRTNBRLSRETRANSQLEN: - return (u_char *) NULL; - break; - case OSPFVIRTNBRHELLOSUPPRESSED: - return (u_char *) NULL; - break; - default: - return NULL; - break; - } - return NULL; + struct ospf_vl_data *vl_data; + struct in_addr area_id; + struct in_addr neighbor; + struct ospf *ospf; + + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + + memset(&area_id, 0, sizeof(struct in_addr)); + memset(&neighbor, 0, sizeof(struct in_addr)); + + /* Check OSPF instance. */ + ospf = ospf_lookup(); + if (ospf == NULL) + return NULL; + + vl_data = ospfVirtIfLookup(v, name, length, &area_id, &neighbor, exact); + if (!vl_data) + return NULL; + + /* Return the current value of the variable */ + switch (v->magic) { + case OSPFVIRTNBRAREA: + return (u_char *)NULL; + break; + case OSPFVIRTNBRRTRID: + return (u_char *)NULL; + break; + case OSPFVIRTNBRIPADDR: + return (u_char *)NULL; + break; + case OSPFVIRTNBROPTIONS: + return (u_char *)NULL; + break; + case OSPFVIRTNBRSTATE: + return (u_char *)NULL; + break; + case OSPFVIRTNBREVENTS: + return (u_char *)NULL; + break; + case OSPFVIRTNBRLSRETRANSQLEN: + return (u_char *)NULL; + break; + case OSPFVIRTNBRHELLOSUPPRESSED: + return (u_char *)NULL; + break; + default: + return NULL; + break; + } + return NULL; } -static struct ospf_lsa * -ospfExtLsdbLookup (struct variable *v, oid *name, size_t *length, u_char *type, - struct in_addr *ls_id, struct in_addr *router_id, int exact) +static struct ospf_lsa *ospfExtLsdbLookup(struct variable *v, oid *name, + size_t *length, u_char *type, + struct in_addr *ls_id, + struct in_addr *router_id, int exact) { - int first; - oid *offset; - int offsetlen; - u_char lsa_type; - unsigned int len; - struct ospf_lsa *lsa; - struct ospf *ospf; - - ospf = ospf_lookup (); - if (exact) - { - if (*length != v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE) - return NULL; - - offset = name + v->namelen; - - /* Make it sure given value match to type. */ - lsa_type = *offset; - offset++; - - if (lsa_type != *type) - return NULL; - - /* LS ID. */ - oid2in_addr (offset, IN_ADDR_SIZE, ls_id); - offset += IN_ADDR_SIZE; - - /* Router ID. */ - oid2in_addr (offset, IN_ADDR_SIZE, router_id); - - return ospf_lsdb_lookup_by_id (ospf->lsdb, *type, *ls_id, *router_id); - } - else - { - /* Get variable length. */ - first = 0; - offset = name + v->namelen; - offsetlen = *length - v->namelen; - - /* LSA type value. */ - lsa_type = *offset; - offset++; - offsetlen--; - - if (offsetlen <= 0 || lsa_type < OSPF_AS_EXTERNAL_LSA) - first = 1; - - /* LS ID. */ - len = offsetlen; - if (len > IN_ADDR_SIZE) - len = IN_ADDR_SIZE; - - oid2in_addr (offset, len, ls_id); - - offset += IN_ADDR_SIZE; - offsetlen -= IN_ADDR_SIZE; - - /* Router ID. */ - len = offsetlen; - if (len > IN_ADDR_SIZE) - len = IN_ADDR_SIZE; - - oid2in_addr (offset, len, router_id); - - lsa = ospf_lsdb_lookup_by_id_next (ospf->lsdb, *type, *ls_id, - *router_id, first); - - if (lsa) - { - /* Fill in length. */ - *length = v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE; - - /* Fill in value. */ - offset = name + v->namelen; - - *offset = OSPF_AS_EXTERNAL_LSA; - offset++; - oid_copy_addr (offset, &lsa->data->id, IN_ADDR_SIZE); - offset += IN_ADDR_SIZE; - oid_copy_addr (offset, &lsa->data->adv_router, IN_ADDR_SIZE); - - return lsa; + int first; + oid *offset; + int offsetlen; + u_char lsa_type; + unsigned int len; + struct ospf_lsa *lsa; + struct ospf *ospf; + + ospf = ospf_lookup(); + if (exact) { + if (*length != v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE) + return NULL; + + offset = name + v->namelen; + + /* Make it sure given value match to type. */ + lsa_type = *offset; + offset++; + + if (lsa_type != *type) + return NULL; + + /* LS ID. */ + oid2in_addr(offset, IN_ADDR_SIZE, ls_id); + offset += IN_ADDR_SIZE; + + /* Router ID. */ + oid2in_addr(offset, IN_ADDR_SIZE, router_id); + + return ospf_lsdb_lookup_by_id(ospf->lsdb, *type, *ls_id, + *router_id); + } else { + /* Get variable length. */ + first = 0; + offset = name + v->namelen; + offsetlen = *length - v->namelen; + + /* LSA type value. */ + lsa_type = *offset; + offset++; + offsetlen--; + + if (offsetlen <= 0 || lsa_type < OSPF_AS_EXTERNAL_LSA) + first = 1; + + /* LS ID. */ + len = offsetlen; + if (len > IN_ADDR_SIZE) + len = IN_ADDR_SIZE; + + oid2in_addr(offset, len, ls_id); + + offset += IN_ADDR_SIZE; + offsetlen -= IN_ADDR_SIZE; + + /* Router ID. */ + len = offsetlen; + if (len > IN_ADDR_SIZE) + len = IN_ADDR_SIZE; + + oid2in_addr(offset, len, router_id); + + lsa = ospf_lsdb_lookup_by_id_next(ospf->lsdb, *type, *ls_id, + *router_id, first); + + if (lsa) { + /* Fill in length. */ + *length = v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE; + + /* Fill in value. */ + offset = name + v->namelen; + + *offset = OSPF_AS_EXTERNAL_LSA; + offset++; + oid_copy_addr(offset, &lsa->data->id, IN_ADDR_SIZE); + offset += IN_ADDR_SIZE; + oid_copy_addr(offset, &lsa->data->adv_router, + IN_ADDR_SIZE); + + return lsa; + } } - } - return NULL; + return NULL; } -static u_char * -ospfExtLsdbEntry (struct variable *v, oid *name, size_t *length, int exact, - size_t *var_len, WriteMethod **write_method) +static u_char *ospfExtLsdbEntry(struct variable *v, oid *name, size_t *length, + int exact, size_t *var_len, + WriteMethod **write_method) { - struct ospf_lsa *lsa; - struct lsa_header *lsah; - u_char type; - struct in_addr ls_id; - struct in_addr router_id; - struct ospf *ospf; - - if (smux_header_table(v, name, length, exact, var_len, write_method) - == MATCH_FAILED) - return NULL; - - type = OSPF_AS_EXTERNAL_LSA; - memset (&ls_id, 0, sizeof (struct in_addr)); - memset (&router_id, 0, sizeof (struct in_addr)); - - /* Check OSPF instance. */ - ospf = ospf_lookup (); - if (ospf == NULL) - return NULL; - - lsa = ospfExtLsdbLookup (v, name, length, &type, &ls_id, &router_id, exact); - if (! lsa) - return NULL; - - lsah = lsa->data; - - /* Return the current value of the variable */ - switch (v->magic) - { - case OSPFEXTLSDBTYPE: - return SNMP_INTEGER (OSPF_AS_EXTERNAL_LSA); - break; - case OSPFEXTLSDBLSID: - return SNMP_IPADDRESS (lsah->id); - break; - case OSPFEXTLSDBROUTERID: - return SNMP_IPADDRESS (lsah->adv_router); - break; - case OSPFEXTLSDBSEQUENCE: - return SNMP_INTEGER (lsah->ls_seqnum); - break; - case OSPFEXTLSDBAGE: - return SNMP_INTEGER (lsah->ls_age); - break; - case OSPFEXTLSDBCHECKSUM: - return SNMP_INTEGER (lsah->checksum); - break; - case OSPFEXTLSDBADVERTISEMENT: - *var_len = ntohs (lsah->length); - return (u_char *) lsah; - break; - default: - return NULL; - break; - } - return NULL; + struct ospf_lsa *lsa; + struct lsa_header *lsah; + u_char type; + struct in_addr ls_id; + struct in_addr router_id; + struct ospf *ospf; + + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + + type = OSPF_AS_EXTERNAL_LSA; + memset(&ls_id, 0, sizeof(struct in_addr)); + memset(&router_id, 0, sizeof(struct in_addr)); + + /* Check OSPF instance. */ + ospf = ospf_lookup(); + if (ospf == NULL) + return NULL; + + lsa = ospfExtLsdbLookup(v, name, length, &type, &ls_id, &router_id, + exact); + if (!lsa) + return NULL; + + lsah = lsa->data; + + /* Return the current value of the variable */ + switch (v->magic) { + case OSPFEXTLSDBTYPE: + return SNMP_INTEGER(OSPF_AS_EXTERNAL_LSA); + break; + case OSPFEXTLSDBLSID: + return SNMP_IPADDRESS(lsah->id); + break; + case OSPFEXTLSDBROUTERID: + return SNMP_IPADDRESS(lsah->adv_router); + break; + case OSPFEXTLSDBSEQUENCE: + return SNMP_INTEGER(lsah->ls_seqnum); + break; + case OSPFEXTLSDBAGE: + return SNMP_INTEGER(lsah->ls_age); + break; + case OSPFEXTLSDBCHECKSUM: + return SNMP_INTEGER(lsah->checksum); + break; + case OSPFEXTLSDBADVERTISEMENT: + *var_len = ntohs(lsah->length); + return (u_char *)lsah; + break; + default: + return NULL; + break; + } + return NULL; } -static u_char * -ospfAreaAggregateEntry (struct variable *v, oid *name, size_t *length, - int exact, size_t *var_len, WriteMethod **write_method) +static u_char *ospfAreaAggregateEntry(struct variable *v, oid *name, + size_t *length, int exact, + size_t *var_len, + WriteMethod **write_method) { - if (smux_header_table(v, name, length, exact, var_len, write_method) - == MATCH_FAILED) - return NULL; - - /* Return the current value of the variable */ - switch (v->magic) - { - case OSPFAREAAGGREGATEAREAID: - return (u_char *) NULL; - break; - case OSPFAREAAGGREGATELSDBTYPE: - return (u_char *) NULL; - break; - case OSPFAREAAGGREGATENET: - return (u_char *) NULL; - break; - case OSPFAREAAGGREGATEMASK: - return (u_char *) NULL; - break; - case OSPFAREAAGGREGATESTATUS: - return (u_char *) NULL; - break; - case OSPFAREAAGGREGATEEFFECT: - return (u_char *) NULL; - break; - default: - return NULL; - break; - } - return NULL; + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + + /* Return the current value of the variable */ + switch (v->magic) { + case OSPFAREAAGGREGATEAREAID: + return (u_char *)NULL; + break; + case OSPFAREAAGGREGATELSDBTYPE: + return (u_char *)NULL; + break; + case OSPFAREAAGGREGATENET: + return (u_char *)NULL; + break; + case OSPFAREAAGGREGATEMASK: + return (u_char *)NULL; + break; + case OSPFAREAAGGREGATESTATUS: + return (u_char *)NULL; + break; + case OSPFAREAAGGREGATEEFFECT: + return (u_char *)NULL; + break; + default: + return NULL; + break; + } + return NULL; } /* OSPF Traps. */ @@ -2626,188 +2560,165 @@ ospfAreaAggregateEntry (struct variable *v, oid *name, size_t *length, #define NBRSTATECHANGE 2 #define VIRTNBRSTATECHANGE 3 -static struct trap_object ospfNbrTrapList[] = -{ - {-2, {1, OSPFROUTERID}}, - {3, {10, 1, OSPFNBRIPADDR}}, - {3, {10, 1, OSPFNBRRTRID}}, - {3, {10, 1, OSPFNBRSTATE}} -}; +static struct trap_object ospfNbrTrapList[] = {{-2, {1, OSPFROUTERID}}, + {3, {10, 1, OSPFNBRIPADDR}}, + {3, {10, 1, OSPFNBRRTRID}}, + {3, {10, 1, OSPFNBRSTATE}}}; -static struct trap_object ospfVirtNbrTrapList[] = -{ - {-2, {1, 1}}, - {3, {11, 1, OSPFVIRTNBRAREA}}, - {3, {11, 1, OSPFVIRTNBRRTRID}}, - {3, {11, 1, OSPFVIRTNBRSTATE}} -}; +static struct trap_object ospfVirtNbrTrapList[] = { + {-2, {1, 1}}, + {3, {11, 1, OSPFVIRTNBRAREA}}, + {3, {11, 1, OSPFVIRTNBRRTRID}}, + {3, {11, 1, OSPFVIRTNBRSTATE}}}; -static struct trap_object ospfIfTrapList[] = -{ - {-2, {1, OSPFROUTERID}}, - {3, {7, 1, OSPFIFIPADDRESS}}, - {3, {7, 1, OSPFADDRESSLESSIF}}, - {3, {7, 1, OSPFIFSTATE}} -}; +static struct trap_object ospfIfTrapList[] = {{-2, {1, OSPFROUTERID}}, + {3, {7, 1, OSPFIFIPADDRESS}}, + {3, {7, 1, OSPFADDRESSLESSIF}}, + {3, {7, 1, OSPFIFSTATE}}}; -static struct trap_object ospfVirtIfTrapList[] = -{ - {-2, {1, OSPFROUTERID}}, - {3, {9, 1, OSPFVIRTIFAREAID}}, - {3, {9, 1, OSPFVIRTIFNEIGHBOR}}, - {3, {9, 1, OSPFVIRTIFSTATE}} -}; +static struct trap_object ospfVirtIfTrapList[] = { + {-2, {1, OSPFROUTERID}}, + {3, {9, 1, OSPFVIRTIFAREAID}}, + {3, {9, 1, OSPFVIRTIFNEIGHBOR}}, + {3, {9, 1, OSPFVIRTIFSTATE}}}; -static void -ospfTrapNbrStateChange (struct ospf_neighbor *on) +static void ospfTrapNbrStateChange(struct ospf_neighbor *on) { - oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)]; - char msgbuf[16]; - - ospf_nbr_state_message(on, msgbuf, sizeof(msgbuf)); - zlog_info("ospfTrapNbrStateChange trap sent: %s now %s", - inet_ntoa(on->address.u.prefix4), msgbuf); - - oid_copy_addr (index, &(on->address.u.prefix4), IN_ADDR_SIZE); - index[IN_ADDR_SIZE] = 0; - - smux_trap (ospf_variables, sizeof ospf_variables / sizeof (struct variable), - ospf_trap_oid, sizeof ospf_trap_oid / sizeof (oid), - ospf_oid, sizeof ospf_oid / sizeof (oid), - index, IN_ADDR_SIZE + 1, - ospfNbrTrapList, - sizeof ospfNbrTrapList / sizeof (struct trap_object), - NBRSTATECHANGE); + oid index[sizeof(oid) * (IN_ADDR_SIZE + 1)]; + char msgbuf[16]; + + ospf_nbr_state_message(on, msgbuf, sizeof(msgbuf)); + zlog_info("ospfTrapNbrStateChange trap sent: %s now %s", + inet_ntoa(on->address.u.prefix4), msgbuf); + + oid_copy_addr(index, &(on->address.u.prefix4), IN_ADDR_SIZE); + index[IN_ADDR_SIZE] = 0; + + smux_trap(ospf_variables, + sizeof ospf_variables / sizeof(struct variable), + ospf_trap_oid, sizeof ospf_trap_oid / sizeof(oid), ospf_oid, + sizeof ospf_oid / sizeof(oid), index, IN_ADDR_SIZE + 1, + ospfNbrTrapList, + sizeof ospfNbrTrapList / sizeof(struct trap_object), + NBRSTATECHANGE); } -static void -ospfTrapVirtNbrStateChange (struct ospf_neighbor *on) +static void ospfTrapVirtNbrStateChange(struct ospf_neighbor *on) { - oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)]; - - zlog_info("ospfTrapVirtNbrStateChange trap sent"); - - oid_copy_addr (index, &(on->address.u.prefix4), IN_ADDR_SIZE); - index[IN_ADDR_SIZE] = 0; - - smux_trap (ospf_variables, sizeof ospf_variables / sizeof (struct variable), - ospf_trap_oid, sizeof ospf_trap_oid / sizeof (oid), - ospf_oid, sizeof ospf_oid / sizeof (oid), - index, IN_ADDR_SIZE + 1, - ospfVirtNbrTrapList, - sizeof ospfVirtNbrTrapList / sizeof (struct trap_object), - VIRTNBRSTATECHANGE); + oid index[sizeof(oid) * (IN_ADDR_SIZE + 1)]; + + zlog_info("ospfTrapVirtNbrStateChange trap sent"); + + oid_copy_addr(index, &(on->address.u.prefix4), IN_ADDR_SIZE); + index[IN_ADDR_SIZE] = 0; + + smux_trap(ospf_variables, + sizeof ospf_variables / sizeof(struct variable), + ospf_trap_oid, sizeof ospf_trap_oid / sizeof(oid), ospf_oid, + sizeof ospf_oid / sizeof(oid), index, IN_ADDR_SIZE + 1, + ospfVirtNbrTrapList, + sizeof ospfVirtNbrTrapList / sizeof(struct trap_object), + VIRTNBRSTATECHANGE); } -static int -ospf_snmp_nsm_change (struct ospf_neighbor *nbr, - int next_state, int old_state) +static int ospf_snmp_nsm_change(struct ospf_neighbor *nbr, int next_state, + int old_state) { - /* Terminal state or regression */ - if ((next_state == NSM_Full) - || (next_state == NSM_TwoWay) - || (next_state < old_state)) - { - /* ospfVirtNbrStateChange */ - if (nbr->oi->type == OSPF_IFTYPE_VIRTUALLINK) - ospfTrapVirtNbrStateChange(nbr); - /* ospfNbrStateChange trap */ - else - /* To/From FULL, only managed by DR */ - if (((next_state != NSM_Full) && (nbr->state != NSM_Full)) - || (nbr->oi->state == ISM_DR)) - ospfTrapNbrStateChange(nbr); - } - return 0; + /* Terminal state or regression */ + if ((next_state == NSM_Full) || (next_state == NSM_TwoWay) + || (next_state < old_state)) { + /* ospfVirtNbrStateChange */ + if (nbr->oi->type == OSPF_IFTYPE_VIRTUALLINK) + ospfTrapVirtNbrStateChange(nbr); + /* ospfNbrStateChange trap */ + else + /* To/From FULL, only managed by DR */ + if (((next_state != NSM_Full) + && (nbr->state != NSM_Full)) + || (nbr->oi->state == ISM_DR)) + ospfTrapNbrStateChange(nbr); + } + return 0; } -static void -ospfTrapIfStateChange (struct ospf_interface *oi) +static void ospfTrapIfStateChange(struct ospf_interface *oi) { - oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)]; - - zlog_info("ospfTrapIfStateChange trap sent: %s now %s", - inet_ntoa(oi->address->u.prefix4), - lookup_msg(ospf_ism_state_msg, oi->state, NULL)); - - oid_copy_addr (index, &(oi->address->u.prefix4), IN_ADDR_SIZE); - index[IN_ADDR_SIZE] = 0; - - smux_trap (ospf_variables, sizeof ospf_variables / sizeof (struct variable), - ospf_trap_oid, sizeof ospf_trap_oid / sizeof (oid), - ospf_oid, sizeof ospf_oid / sizeof (oid), - index, IN_ADDR_SIZE + 1, - ospfIfTrapList, - sizeof ospfIfTrapList / sizeof (struct trap_object), - IFSTATECHANGE); + oid index[sizeof(oid) * (IN_ADDR_SIZE + 1)]; + + zlog_info("ospfTrapIfStateChange trap sent: %s now %s", + inet_ntoa(oi->address->u.prefix4), + lookup_msg(ospf_ism_state_msg, oi->state, NULL)); + + oid_copy_addr(index, &(oi->address->u.prefix4), IN_ADDR_SIZE); + index[IN_ADDR_SIZE] = 0; + + smux_trap(ospf_variables, + sizeof ospf_variables / sizeof(struct variable), + ospf_trap_oid, sizeof ospf_trap_oid / sizeof(oid), ospf_oid, + sizeof ospf_oid / sizeof(oid), index, IN_ADDR_SIZE + 1, + ospfIfTrapList, + sizeof ospfIfTrapList / sizeof(struct trap_object), + IFSTATECHANGE); } -static void -ospfTrapVirtIfStateChange (struct ospf_interface *oi) +static void ospfTrapVirtIfStateChange(struct ospf_interface *oi) { - oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)]; - - zlog_info("ospfTrapVirtIfStateChange trap sent"); - - oid_copy_addr (index, &(oi->address->u.prefix4), IN_ADDR_SIZE); - index[IN_ADDR_SIZE] = 0; - - smux_trap (ospf_variables, sizeof ospf_variables / sizeof (struct variable), - ospf_trap_oid, sizeof ospf_trap_oid / sizeof (oid), - ospf_oid, sizeof ospf_oid / sizeof (oid), - index, IN_ADDR_SIZE + 1, - ospfVirtIfTrapList, - sizeof ospfVirtIfTrapList / sizeof (struct trap_object), - VIRTIFSTATECHANGE); + oid index[sizeof(oid) * (IN_ADDR_SIZE + 1)]; + + zlog_info("ospfTrapVirtIfStateChange trap sent"); + + oid_copy_addr(index, &(oi->address->u.prefix4), IN_ADDR_SIZE); + index[IN_ADDR_SIZE] = 0; + + smux_trap(ospf_variables, + sizeof ospf_variables / sizeof(struct variable), + ospf_trap_oid, sizeof ospf_trap_oid / sizeof(oid), ospf_oid, + sizeof ospf_oid / sizeof(oid), index, IN_ADDR_SIZE + 1, + ospfVirtIfTrapList, + sizeof ospfVirtIfTrapList / sizeof(struct trap_object), + VIRTIFSTATECHANGE); } -static int -ospf_snmp_ism_change (struct ospf_interface *oi, - int state, int old_state) +static int ospf_snmp_ism_change(struct ospf_interface *oi, int state, + int old_state) { - /* Terminal state or regression */ - if ((state == ISM_DR) || (state == ISM_Backup) || (state == ISM_DROther) || - (state == ISM_PointToPoint) || (state < old_state)) - { - /* ospfVirtIfStateChange */ - if (oi->type == OSPF_IFTYPE_VIRTUALLINK) - ospfTrapVirtIfStateChange (oi); - /* ospfIfStateChange */ - else - ospfTrapIfStateChange (oi); - } - return 0; + /* Terminal state or regression */ + if ((state == ISM_DR) || (state == ISM_Backup) || (state == ISM_DROther) + || (state == ISM_PointToPoint) || (state < old_state)) { + /* ospfVirtIfStateChange */ + if (oi->type == OSPF_IFTYPE_VIRTUALLINK) + ospfTrapVirtIfStateChange(oi); + /* ospfIfStateChange */ + else + ospfTrapIfStateChange(oi); + } + return 0; } /* Register OSPF2-MIB. */ -static int -ospf_snmp_init (struct thread_master *tm) +static int ospf_snmp_init(struct thread_master *tm) { - ospf_snmp_iflist = list_new (); - ospf_snmp_vl_table = route_table_init (); - smux_init (tm); - REGISTER_MIB("mibII/ospf", ospf_variables, variable, ospf_oid); - return 0; + ospf_snmp_iflist = list_new(); + ospf_snmp_vl_table = route_table_init(); + smux_init(tm); + REGISTER_MIB("mibII/ospf", ospf_variables, variable, ospf_oid); + return 0; } -static int -ospf_snmp_module_init (void) +static int ospf_snmp_module_init(void) { - hook_register(ospf_if_update, ospf_snmp_if_update); - hook_register(ospf_if_delete, ospf_snmp_if_delete); - hook_register(ospf_vl_add, ospf_snmp_vl_add); - hook_register(ospf_vl_delete, ospf_snmp_vl_delete); - hook_register(ospf_ism_change, ospf_snmp_ism_change); - hook_register(ospf_nsm_change, ospf_snmp_nsm_change); - - hook_register(frr_late_init, ospf_snmp_init); - return 0; + hook_register(ospf_if_update, ospf_snmp_if_update); + hook_register(ospf_if_delete, ospf_snmp_if_delete); + hook_register(ospf_vl_add, ospf_snmp_vl_add); + hook_register(ospf_vl_delete, ospf_snmp_vl_delete); + hook_register(ospf_ism_change, ospf_snmp_ism_change); + hook_register(ospf_nsm_change, ospf_snmp_nsm_change); + + hook_register(frr_late_init, ospf_snmp_init); + return 0; } -FRR_MODULE_SETUP( - .name = "ospfd_snmp", - .version = FRR_VERSION, - .description = "ospfd AgentX SNMP module", - .init = ospf_snmp_module_init, -) +FRR_MODULE_SETUP(.name = "ospfd_snmp", .version = FRR_VERSION, + .description = "ospfd AgentX SNMP module", + .init = ospf_snmp_module_init, ) diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index 173c4e91d..c520a3126 100644 --- a/ospfd/ospf_spf.c +++ b/ospfd/ospf_spf.c @@ -29,7 +29,7 @@ #include "if.h" #include "table.h" #include "log.h" -#include "sockunion.h" /* for inet_ntop () */ +#include "sockunion.h" /* for inet_ntop () */ #include "pqueue.h" #include "ospfd/ospfd.h" @@ -51,326 +51,304 @@ static unsigned int spf_reason_flags = 0; -static void -ospf_clear_spf_reason_flags (void) +static void ospf_clear_spf_reason_flags(void) { - spf_reason_flags = 0; + spf_reason_flags = 0; } -static void -ospf_spf_set_reason (ospf_spf_reason_t reason) +static void ospf_spf_set_reason(ospf_spf_reason_t reason) { - spf_reason_flags |= 1 << reason; + spf_reason_flags |= 1 << reason; } -static void ospf_vertex_free (void *); +static void ospf_vertex_free(void *); /* List of allocated vertices, to simplify cleanup of SPF. * Not thread-safe obviously. If it ever needs to be, it'd have to be * dynamically allocated at begin of ospf_spf_calculate */ -static struct list vertex_list = { .del = ospf_vertex_free }; +static struct list vertex_list = {.del = ospf_vertex_free}; /* Heap related functions, for the managment of the candidates, to * be used with pqueue. */ -static int -cmp (void * node1 , void * node2) +static int cmp(void *node1, void *node2) { - struct vertex * v1 = (struct vertex *) node1; - struct vertex * v2 = (struct vertex *) node2; - if (v1 != NULL && v2 != NULL ) - { - /* network vertices must be chosen before router vertices of same - * cost in order to find all shortest paths - */ - if ( ((v1->distance - v2->distance) == 0) - && (v1->type != v2->type)) - { - switch (v1->type) - { - case OSPF_VERTEX_NETWORK: - return -1; - case OSPF_VERTEX_ROUTER: - return 1; - } - } - else - return (v1->distance - v2->distance); - } - return 0; + struct vertex *v1 = (struct vertex *)node1; + struct vertex *v2 = (struct vertex *)node2; + if (v1 != NULL && v2 != NULL) { + /* network vertices must be chosen before router vertices of + * same + * cost in order to find all shortest paths + */ + if (((v1->distance - v2->distance) == 0) + && (v1->type != v2->type)) { + switch (v1->type) { + case OSPF_VERTEX_NETWORK: + return -1; + case OSPF_VERTEX_ROUTER: + return 1; + } + } else + return (v1->distance - v2->distance); + } + return 0; } -static void -update_stat (void *node , int position) +static void update_stat(void *node, int position) { - struct vertex *v = node; + struct vertex *v = node; - /* Set the status of the vertex, when its position changes. */ - *(v->stat) = position; + /* Set the status of the vertex, when its position changes. */ + *(v->stat) = position; } -static struct vertex_nexthop * -vertex_nexthop_new (void) +static struct vertex_nexthop *vertex_nexthop_new(void) { - return XCALLOC (MTYPE_OSPF_NEXTHOP, sizeof (struct vertex_nexthop)); + return XCALLOC(MTYPE_OSPF_NEXTHOP, sizeof(struct vertex_nexthop)); } -static void -vertex_nexthop_free (struct vertex_nexthop *nh) +static void vertex_nexthop_free(struct vertex_nexthop *nh) { - XFREE (MTYPE_OSPF_NEXTHOP, nh); + XFREE(MTYPE_OSPF_NEXTHOP, nh); } /* Free the canonical nexthop objects for an area, ie the nexthop objects * attached to the first-hop router vertices, and any intervening network * vertices. */ -static void -ospf_canonical_nexthops_free (struct vertex *root) +static void ospf_canonical_nexthops_free(struct vertex *root) { - struct listnode *node, *nnode; - struct vertex *child; - - for (ALL_LIST_ELEMENTS (root->children, node, nnode, child)) - { - struct listnode *n2, *nn2; - struct vertex_parent *vp; - - /* router vertices through an attached network each - * have a distinct (canonical / not inherited) nexthop - * which must be freed. - * - * A network vertex can only have router vertices as its - * children, so only one level of recursion is possible. - */ - if (child->type == OSPF_VERTEX_NETWORK) - ospf_canonical_nexthops_free (child); - - /* Free child nexthops pointing back to this root vertex */ - for (ALL_LIST_ELEMENTS (child->parents, n2, nn2, vp)) - if (vp->parent == root && vp->nexthop) - vertex_nexthop_free (vp->nexthop); - } -} + struct listnode *node, *nnode; + struct vertex *child; + + for (ALL_LIST_ELEMENTS(root->children, node, nnode, child)) { + struct listnode *n2, *nn2; + struct vertex_parent *vp; + + /* router vertices through an attached network each + * have a distinct (canonical / not inherited) nexthop + * which must be freed. + * + * A network vertex can only have router vertices as its + * children, so only one level of recursion is possible. + */ + if (child->type == OSPF_VERTEX_NETWORK) + ospf_canonical_nexthops_free(child); + + /* Free child nexthops pointing back to this root vertex */ + for (ALL_LIST_ELEMENTS(child->parents, n2, nn2, vp)) + if (vp->parent == root && vp->nexthop) + vertex_nexthop_free(vp->nexthop); + } +} /* TODO: Parent list should be excised, in favour of maintaining only * vertex_nexthop, with refcounts. */ -static struct vertex_parent * -vertex_parent_new (struct vertex *v, int backlink, struct vertex_nexthop *hop) +static struct vertex_parent *vertex_parent_new(struct vertex *v, int backlink, + struct vertex_nexthop *hop) { - struct vertex_parent *new; - - new = XMALLOC (MTYPE_OSPF_VERTEX_PARENT, sizeof (struct vertex_parent)); - - if (new == NULL) - return NULL; - - new->parent = v; - new->backlink = backlink; - new->nexthop = hop; - return new; + struct vertex_parent *new; + + new = XMALLOC(MTYPE_OSPF_VERTEX_PARENT, sizeof(struct vertex_parent)); + + if (new == NULL) + return NULL; + + new->parent = v; + new->backlink = backlink; + new->nexthop = hop; + return new; } -static void -vertex_parent_free (void *p) +static void vertex_parent_free(void *p) { - XFREE (MTYPE_OSPF_VERTEX_PARENT, p); + XFREE(MTYPE_OSPF_VERTEX_PARENT, p); } -static struct vertex * -ospf_vertex_new (struct ospf_lsa *lsa) +static struct vertex *ospf_vertex_new(struct ospf_lsa *lsa) { - struct vertex *new; - - new = XCALLOC (MTYPE_OSPF_VERTEX, sizeof (struct vertex)); - - new->flags = 0; - new->stat = &(lsa->stat); - new->type = lsa->data->type; - new->id = lsa->data->id; - new->lsa = lsa->data; - new->children = list_new (); - new->parents = list_new (); - new->parents->del = vertex_parent_free; - - listnode_add (&vertex_list, new); - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("%s: Created %s vertex %s", __func__, - new->type == OSPF_VERTEX_ROUTER ? "Router" : "Network", - inet_ntoa (new->lsa->id)); - return new; + struct vertex *new; + + new = XCALLOC(MTYPE_OSPF_VERTEX, sizeof(struct vertex)); + + new->flags = 0; + new->stat = &(lsa->stat); + new->type = lsa->data->type; + new->id = lsa->data->id; + new->lsa = lsa->data; + new->children = list_new(); + new->parents = list_new(); + new->parents->del = vertex_parent_free; + + listnode_add(&vertex_list, new); + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("%s: Created %s vertex %s", __func__, + new->type == OSPF_VERTEX_ROUTER ? "Router" + : "Network", + inet_ntoa(new->lsa->id)); + return new; } -static void -ospf_vertex_free (void *data) +static void ospf_vertex_free(void *data) { - struct vertex *v = data; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("%s: Free %s vertex %s", __func__, - v->type == OSPF_VERTEX_ROUTER ? "Router" : "Network", - inet_ntoa (v->lsa->id)); - - /* There should be no parents potentially holding references to this vertex - * Children however may still be there, but presumably referenced by other - * vertices - */ - //assert (listcount (v->parents) == 0); - - if (v->children) - list_delete (v->children); - v->children = NULL; - - if (v->parents) - list_delete (v->parents); - v->parents = NULL; - - v->lsa = NULL; - - XFREE (MTYPE_OSPF_VERTEX, v); + struct vertex *v = data; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("%s: Free %s vertex %s", __func__, + v->type == OSPF_VERTEX_ROUTER ? "Router" : "Network", + inet_ntoa(v->lsa->id)); + + /* There should be no parents potentially holding references to this + * vertex + * Children however may still be there, but presumably referenced by + * other + * vertices + */ + // assert (listcount (v->parents) == 0); + + if (v->children) + list_delete(v->children); + v->children = NULL; + + if (v->parents) + list_delete(v->parents); + v->parents = NULL; + + v->lsa = NULL; + + XFREE(MTYPE_OSPF_VERTEX, v); } -static void -ospf_vertex_dump(const char *msg, struct vertex *v, - int print_parents, int print_children) +static void ospf_vertex_dump(const char *msg, struct vertex *v, + int print_parents, int print_children) { - if ( ! IS_DEBUG_OSPF_EVENT) - return; - - zlog_debug("%s %s vertex %s distance %u flags %u", - msg, - v->type == OSPF_VERTEX_ROUTER ? "Router" : "Network", - inet_ntoa(v->lsa->id), - v->distance, - (unsigned int)v->flags); - - if (print_parents) - { - struct listnode *node; - struct vertex_parent *vp; - - for (ALL_LIST_ELEMENTS_RO (v->parents, node, vp)) - { - char buf1[BUFSIZ]; - - if (vp) - { - zlog_debug ("parent %s backlink %d nexthop %s interface %s", - inet_ntoa(vp->parent->lsa->id), vp->backlink, - inet_ntop(AF_INET, &vp->nexthop->router, buf1, BUFSIZ), - vp->nexthop->oi ? IF_NAME(vp->nexthop->oi) : "NULL"); - } + if (!IS_DEBUG_OSPF_EVENT) + return; + + zlog_debug("%s %s vertex %s distance %u flags %u", msg, + v->type == OSPF_VERTEX_ROUTER ? "Router" : "Network", + inet_ntoa(v->lsa->id), v->distance, (unsigned int)v->flags); + + if (print_parents) { + struct listnode *node; + struct vertex_parent *vp; + + for (ALL_LIST_ELEMENTS_RO(v->parents, node, vp)) { + char buf1[BUFSIZ]; + + if (vp) { + zlog_debug( + "parent %s backlink %d nexthop %s interface %s", + inet_ntoa(vp->parent->lsa->id), + vp->backlink, + inet_ntop(AF_INET, &vp->nexthop->router, + buf1, BUFSIZ), + vp->nexthop->oi + ? IF_NAME(vp->nexthop->oi) + : "NULL"); + } + } + } + + if (print_children) { + struct listnode *cnode; + struct vertex *cv; + + for (ALL_LIST_ELEMENTS_RO(v->children, cnode, cv)) + ospf_vertex_dump(" child:", cv, 0, 0); } - } - - if (print_children) - { - struct listnode *cnode; - struct vertex *cv; - - for (ALL_LIST_ELEMENTS_RO (v->children, cnode, cv)) - ospf_vertex_dump(" child:", cv, 0, 0); - } } /* Add a vertex to the list of children in each of its parents. */ -static void -ospf_vertex_add_parent (struct vertex *v) +static void ospf_vertex_add_parent(struct vertex *v) { - struct vertex_parent *vp; - struct listnode *node; - - assert (v && v->parents); - - for (ALL_LIST_ELEMENTS_RO (v->parents, node, vp)) - { - assert (vp->parent && vp->parent->children); - - /* No need to add two links from the same parent. */ - if (listnode_lookup (vp->parent->children, v) == NULL) - listnode_add (vp->parent->children, v); - } + struct vertex_parent *vp; + struct listnode *node; + + assert(v && v->parents); + + for (ALL_LIST_ELEMENTS_RO(v->parents, node, vp)) { + assert(vp->parent && vp->parent->children); + + /* No need to add two links from the same parent. */ + if (listnode_lookup(vp->parent->children, v) == NULL) + listnode_add(vp->parent->children, v); + } } -static void -ospf_spf_init (struct ospf_area *area) +static void ospf_spf_init(struct ospf_area *area) { - struct vertex *v; - - /* Create root node. */ - v = ospf_vertex_new (area->router_lsa_self); - - area->spf = v; - - /* Reset ABR and ASBR router counts. */ - area->abr_count = 0; - area->asbr_count = 0; + struct vertex *v; + + /* Create root node. */ + v = ospf_vertex_new(area->router_lsa_self); + + area->spf = v; + + /* Reset ABR and ASBR router counts. */ + area->abr_count = 0; + area->asbr_count = 0; } /* return index of link back to V from W, or -1 if no link found */ -static int -ospf_lsa_has_link (struct lsa_header *w, struct lsa_header *v) +static int ospf_lsa_has_link(struct lsa_header *w, struct lsa_header *v) { - unsigned int i, length; - struct router_lsa *rl; - struct network_lsa *nl; - - /* In case of W is Network LSA. */ - if (w->type == OSPF_NETWORK_LSA) - { - if (v->type == OSPF_NETWORK_LSA) - return -1; - - nl = (struct network_lsa *) w; - length = (ntohs (w->length) - OSPF_LSA_HEADER_SIZE - 4) / 4; - - for (i = 0; i < length; i++) - if (IPV4_ADDR_SAME (&nl->routers[i], &v->id)) - return i; - return -1; - } - - /* In case of W is Router LSA. */ - if (w->type == OSPF_ROUTER_LSA) - { - rl = (struct router_lsa *) w; - - length = ntohs (w->length); - - for (i = 0; - i < ntohs (rl->links) && length >= sizeof (struct router_lsa); - i++, length -= 12) - { - switch (rl->link[i].type) - { - case LSA_LINK_TYPE_POINTOPOINT: - case LSA_LINK_TYPE_VIRTUALLINK: - /* Router LSA ID. */ - if (v->type == OSPF_ROUTER_LSA && - IPV4_ADDR_SAME (&rl->link[i].link_id, &v->id)) - { - return i; - } - break; - case LSA_LINK_TYPE_TRANSIT: - /* Network LSA ID. */ - if (v->type == OSPF_NETWORK_LSA && - IPV4_ADDR_SAME (&rl->link[i].link_id, &v->id)) - { - return i; - } - break; - case LSA_LINK_TYPE_STUB: - /* Stub can't lead anywhere, carry on */ - continue; - default: - break; - } - } - } - return -1; + unsigned int i, length; + struct router_lsa *rl; + struct network_lsa *nl; + + /* In case of W is Network LSA. */ + if (w->type == OSPF_NETWORK_LSA) { + if (v->type == OSPF_NETWORK_LSA) + return -1; + + nl = (struct network_lsa *)w; + length = (ntohs(w->length) - OSPF_LSA_HEADER_SIZE - 4) / 4; + + for (i = 0; i < length; i++) + if (IPV4_ADDR_SAME(&nl->routers[i], &v->id)) + return i; + return -1; + } + + /* In case of W is Router LSA. */ + if (w->type == OSPF_ROUTER_LSA) { + rl = (struct router_lsa *)w; + + length = ntohs(w->length); + + for (i = 0; i < ntohs(rl->links) + && length >= sizeof(struct router_lsa); + i++, length -= 12) { + switch (rl->link[i].type) { + case LSA_LINK_TYPE_POINTOPOINT: + case LSA_LINK_TYPE_VIRTUALLINK: + /* Router LSA ID. */ + if (v->type == OSPF_ROUTER_LSA + && IPV4_ADDR_SAME(&rl->link[i].link_id, + &v->id)) { + return i; + } + break; + case LSA_LINK_TYPE_TRANSIT: + /* Network LSA ID. */ + if (v->type == OSPF_NETWORK_LSA + && IPV4_ADDR_SAME(&rl->link[i].link_id, + &v->id)) { + return i; + } + break; + case LSA_LINK_TYPE_STUB: + /* Stub can't lead anywhere, carry on */ + continue; + default: + break; + } + } + } + return -1; } /* Find the next link after prev_link from v to w. If prev_link is @@ -378,119 +356,117 @@ ospf_lsa_has_link (struct lsa_header *w, struct lsa_header *v) * these link types will never be returned. */ static struct router_lsa_link * -ospf_get_next_link (struct vertex *v, struct vertex *w, - struct router_lsa_link *prev_link) +ospf_get_next_link(struct vertex *v, struct vertex *w, + struct router_lsa_link *prev_link) { - u_char *p; - u_char *lim; - u_char lsa_type = LSA_LINK_TYPE_TRANSIT; - struct router_lsa_link *l; - - if (w->type == OSPF_VERTEX_ROUTER) - lsa_type = LSA_LINK_TYPE_POINTOPOINT; - - if (prev_link == NULL) - p = ((u_char *) v->lsa) + OSPF_LSA_HEADER_SIZE + 4; - else - { - p = (u_char *) prev_link; - p += (OSPF_ROUTER_LSA_LINK_SIZE + - (prev_link->m[0].tos_count * OSPF_ROUTER_LSA_TOS_SIZE)); - } + u_char *p; + u_char *lim; + u_char lsa_type = LSA_LINK_TYPE_TRANSIT; + struct router_lsa_link *l; + + if (w->type == OSPF_VERTEX_ROUTER) + lsa_type = LSA_LINK_TYPE_POINTOPOINT; + + if (prev_link == NULL) + p = ((u_char *)v->lsa) + OSPF_LSA_HEADER_SIZE + 4; + else { + p = (u_char *)prev_link; + p += (OSPF_ROUTER_LSA_LINK_SIZE + + (prev_link->m[0].tos_count * OSPF_ROUTER_LSA_TOS_SIZE)); + } - lim = ((u_char *) v->lsa) + ntohs (v->lsa->length); + lim = ((u_char *)v->lsa) + ntohs(v->lsa->length); - while (p < lim) - { - l = (struct router_lsa_link *) p; + while (p < lim) { + l = (struct router_lsa_link *)p; - p += (OSPF_ROUTER_LSA_LINK_SIZE + (l->m[0].tos_count * OSPF_ROUTER_LSA_TOS_SIZE)); + p += (OSPF_ROUTER_LSA_LINK_SIZE + + (l->m[0].tos_count * OSPF_ROUTER_LSA_TOS_SIZE)); - if (l->m[0].type != lsa_type) - continue; + if (l->m[0].type != lsa_type) + continue; - if (IPV4_ADDR_SAME (&l->link_id, &w->id)) - return l; - } + if (IPV4_ADDR_SAME(&l->link_id, &w->id)) + return l; + } - return NULL; + return NULL; } -static void -ospf_spf_flush_parents (struct vertex *w) +static void ospf_spf_flush_parents(struct vertex *w) { - struct vertex_parent *vp; - struct listnode *ln, *nn; - - /* delete the existing nexthops */ - for (ALL_LIST_ELEMENTS (w->parents, ln, nn, vp)) - { - list_delete_node (w->parents, ln); - vertex_parent_free (vp); - } + struct vertex_parent *vp; + struct listnode *ln, *nn; + + /* delete the existing nexthops */ + for (ALL_LIST_ELEMENTS(w->parents, ln, nn, vp)) { + list_delete_node(w->parents, ln); + vertex_parent_free(vp); + } } -/* +/* * Consider supplied next-hop for inclusion to the supplied list of - * equal-cost next-hops, adjust list as neccessary. + * equal-cost next-hops, adjust list as neccessary. */ -static void -ospf_spf_add_parent (struct vertex *v, struct vertex *w, - struct vertex_nexthop *newhop, - unsigned int distance) +static void ospf_spf_add_parent(struct vertex *v, struct vertex *w, + struct vertex_nexthop *newhop, + unsigned int distance) { - struct vertex_parent *vp, *wp; - struct listnode *node; - - /* we must have a newhop, and a distance */ - assert (v && w && newhop); - assert (distance); - - /* IFF w has already been assigned a distance, then we shouldn't get here - * unless callers have determined V(l)->W is shortest / equal-shortest - * path (0 is a special case distance (no distance yet assigned)). - */ - if (w->distance) - assert (distance <= w->distance); - else - w->distance = distance; - - if (IS_DEBUG_OSPF_EVENT) - { - char buf[2][INET_ADDRSTRLEN]; - zlog_debug ("%s: Adding %s as parent of %s", - __func__, - inet_ntop(AF_INET, &v->lsa->id, buf[0], sizeof(buf[0])), - inet_ntop(AF_INET, &w->lsa->id, buf[1], sizeof(buf[1]))); - } - - /* Adding parent for a new, better path: flush existing parents from W. */ - if (distance < w->distance) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("%s: distance %d better than %d, flushing existing parents", - __func__, distance, w->distance); - ospf_spf_flush_parents (w); - w->distance = distance; - } - - /* new parent is <= existing parents, add it to parent list (if nexthop - * not on parent list) - */ - for (ALL_LIST_ELEMENTS_RO(w->parents, node, wp)) - { - if (memcmp(newhop, wp->nexthop, sizeof(*newhop)) == 0) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("%s: ... nexthop already on parent list, skipping add", __func__); - return; - } - } + struct vertex_parent *vp, *wp; + struct listnode *node; + + /* we must have a newhop, and a distance */ + assert(v && w && newhop); + assert(distance); + + /* IFF w has already been assigned a distance, then we shouldn't get + * here + * unless callers have determined V(l)->W is shortest / equal-shortest + * path (0 is a special case distance (no distance yet assigned)). + */ + if (w->distance) + assert(distance <= w->distance); + else + w->distance = distance; + + if (IS_DEBUG_OSPF_EVENT) { + char buf[2][INET_ADDRSTRLEN]; + zlog_debug( + "%s: Adding %s as parent of %s", __func__, + inet_ntop(AF_INET, &v->lsa->id, buf[0], sizeof(buf[0])), + inet_ntop(AF_INET, &w->lsa->id, buf[1], + sizeof(buf[1]))); + } + + /* Adding parent for a new, better path: flush existing parents from W. + */ + if (distance < w->distance) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "%s: distance %d better than %d, flushing existing parents", + __func__, distance, w->distance); + ospf_spf_flush_parents(w); + w->distance = distance; + } + + /* new parent is <= existing parents, add it to parent list (if nexthop + * not on parent list) + */ + for (ALL_LIST_ELEMENTS_RO(w->parents, node, wp)) { + if (memcmp(newhop, wp->nexthop, sizeof(*newhop)) == 0) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "%s: ... nexthop already on parent list, skipping add", + __func__); + return; + } + } - vp = vertex_parent_new (v, ospf_lsa_has_link (w->lsa, v->lsa), newhop); - listnode_add (w->parents, vp); + vp = vertex_parent_new(v, ospf_lsa_has_link(w->lsa, v->lsa), newhop); + listnode_add(w->parents, vp); - return; + return; } /* 16.1.1. Calculate nexthop from root through V (parent) to @@ -504,256 +480,298 @@ ospf_spf_add_parent (struct vertex *v, struct vertex *w, * this function returns. This function will update the W vertex with the * provided distance as appropriate. */ -static unsigned int -ospf_nexthop_calculation (struct ospf_area *area, struct vertex *v, - struct vertex *w, struct router_lsa_link *l, - unsigned int distance, int lsa_pos) +static unsigned int ospf_nexthop_calculation(struct ospf_area *area, + struct vertex *v, struct vertex *w, + struct router_lsa_link *l, + unsigned int distance, int lsa_pos) { - struct listnode *node, *nnode; - struct vertex_nexthop *nh; - struct vertex_parent *vp; - struct ospf_interface *oi = NULL; - unsigned int added = 0; - char buf1[BUFSIZ]; - char buf2[BUFSIZ]; - - if (IS_DEBUG_OSPF_EVENT) - { - zlog_debug ("ospf_nexthop_calculation(): Start"); - ospf_vertex_dump("V (parent):", v, 1, 1); - ospf_vertex_dump("W (dest) :", w, 1, 1); - zlog_debug ("V->W distance: %d", distance); - } - - if (v == area->spf) - { - /* 16.1.1 para 4. In the first case, the parent vertex (V) is the - root (the calculating router itself). This means that the - destination is either a directly connected network or directly - connected router. The outgoing interface in this case is simply - the OSPF interface connecting to the destination network/router. - */ - - /* we *must* be supplied with the link data */ - assert (l != NULL); - oi = ospf_if_lookup_by_lsa_pos (area, lsa_pos); - if (!oi) - { - zlog_debug("%s: OI not found in LSA: lsa_pos:%d link_id:%s link_data:%s", - __func__, lsa_pos, - inet_ntop (AF_INET, &l->link_id, buf1, BUFSIZ), - inet_ntop (AF_INET, &l->link_data, buf2, BUFSIZ)); - return 0; - } - - if (IS_DEBUG_OSPF_EVENT) - { - zlog_debug("%s: considering link:%s " - "type:%d link_id:%s link_data:%s", - __func__, oi->ifp->name, l->m[0].type, - inet_ntop (AF_INET, &l->link_id, buf1, BUFSIZ), - inet_ntop (AF_INET, &l->link_data, buf2, BUFSIZ)); + struct listnode *node, *nnode; + struct vertex_nexthop *nh; + struct vertex_parent *vp; + struct ospf_interface *oi = NULL; + unsigned int added = 0; + char buf1[BUFSIZ]; + char buf2[BUFSIZ]; + + if (IS_DEBUG_OSPF_EVENT) { + zlog_debug("ospf_nexthop_calculation(): Start"); + ospf_vertex_dump("V (parent):", v, 1, 1); + ospf_vertex_dump("W (dest) :", w, 1, 1); + zlog_debug("V->W distance: %d", distance); } - if (w->type == OSPF_VERTEX_ROUTER) - { - /* l is a link from v to w - * l2 will be link from w to v - */ - struct router_lsa_link *l2 = NULL; - - if (l->m[0].type == LSA_LINK_TYPE_POINTOPOINT) - { - struct in_addr nexthop = { .s_addr = 0 }; - - /* If the destination is a router which connects to - the calculating router via a Point-to-MultiPoint - network, the destination's next hop IP address(es) - can be determined by examining the destination's - router-LSA: each link pointing back to the - calculating router and having a Link Data field - belonging to the Point-to-MultiPoint network - provides an IP address of the next hop router. - - At this point l is a link from V to W, and V is the - root ("us"). If it is a point-to-multipoint interface, - then look through the links in the opposite direction (W to V). - If any of them have an address that lands within the - subnet declared by the PtMP link, then that link - is a constituent of the PtMP link, and its address is - a nexthop address for V. - */ - if (oi->type == OSPF_IFTYPE_POINTOPOINT) - { - /* Having nexthop = 0 is tempting, but NOT acceptable. - It breaks AS-External routes with a forwarding address, - since ospf_ase_complete_direct_routes() will mistakenly - assume we've reached the last hop and should place the - forwarding address as nexthop. - Also, users may configure multi-access links in p2p mode, - so we need the IP to ARP the nexthop. - */ - struct ospf_neighbor *nbr_w; - - nbr_w = ospf_nbr_lookup_by_routerid (oi->nbrs, &l->link_id); - if (nbr_w != NULL) - { - added = 1; - nexthop = nbr_w->src; - } + if (v == area->spf) { + /* 16.1.1 para 4. In the first case, the parent vertex (V) is + the + root (the calculating router itself). This means that the + destination is either a directly connected network or + directly + connected router. The outgoing interface in this case is + simply + the OSPF interface connecting to the destination + network/router. + */ + + /* we *must* be supplied with the link data */ + assert(l != NULL); + oi = ospf_if_lookup_by_lsa_pos(area, lsa_pos); + if (!oi) { + zlog_debug( + "%s: OI not found in LSA: lsa_pos:%d link_id:%s link_data:%s", + __func__, lsa_pos, + inet_ntop(AF_INET, &l->link_id, buf1, BUFSIZ), + inet_ntop(AF_INET, &l->link_data, buf2, + BUFSIZ)); + return 0; } - else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) - { - struct prefix_ipv4 la; - - la.family = AF_INET; - la.prefixlen = oi->address->prefixlen; - /* V links to W on PtMP interface - - find the interface address on W */ - while ((l2 = ospf_get_next_link (w, v, l2))) - { - la.prefix = l2->link_data; + if (IS_DEBUG_OSPF_EVENT) { + zlog_debug( + "%s: considering link:%s " + "type:%d link_id:%s link_data:%s", + __func__, oi->ifp->name, l->m[0].type, + inet_ntop(AF_INET, &l->link_id, buf1, BUFSIZ), + inet_ntop(AF_INET, &l->link_data, buf2, + BUFSIZ)); + } - if (prefix_cmp ((struct prefix *) &la, - oi->address) != 0) - continue; - /* link_data is on our PtMP network */ - added = 1; - nexthop = l2->link_data; - break; - } + if (w->type == OSPF_VERTEX_ROUTER) { + /* l is a link from v to w + * l2 will be link from w to v + */ + struct router_lsa_link *l2 = NULL; + + if (l->m[0].type == LSA_LINK_TYPE_POINTOPOINT) { + struct in_addr nexthop = {.s_addr = 0}; + + /* If the destination is a router which connects + to + the calculating router via a + Point-to-MultiPoint + network, the destination's next hop IP + address(es) + can be determined by examining the + destination's + router-LSA: each link pointing back to the + calculating router and having a Link Data + field + belonging to the Point-to-MultiPoint network + provides an IP address of the next hop + router. + + At this point l is a link from V to W, and V + is the + root ("us"). If it is a point-to-multipoint + interface, + then look through the links in the opposite + direction (W to V). + If any of them have an address that lands + within the + subnet declared by the PtMP link, then that + link + is a constituent of the PtMP link, and its + address is + a nexthop address for V. + */ + if (oi->type == OSPF_IFTYPE_POINTOPOINT) { + /* Having nexthop = 0 is tempting, but + NOT acceptable. + It breaks AS-External routes with a + forwarding address, + since + ospf_ase_complete_direct_routes() + will mistakenly + assume we've reached the last hop and + should place the + forwarding address as nexthop. + Also, users may configure + multi-access links in p2p mode, + so we need the IP to ARP the nexthop. + */ + struct ospf_neighbor *nbr_w; + + nbr_w = ospf_nbr_lookup_by_routerid( + oi->nbrs, &l->link_id); + if (nbr_w != NULL) { + added = 1; + nexthop = nbr_w->src; + } + } else if (oi->type + == OSPF_IFTYPE_POINTOMULTIPOINT) { + struct prefix_ipv4 la; + + la.family = AF_INET; + la.prefixlen = oi->address->prefixlen; + + /* V links to W on PtMP interface + - find the interface address on W */ + while ((l2 = ospf_get_next_link(w, v, + l2))) { + la.prefix = l2->link_data; + + if (prefix_cmp((struct prefix + *)&la, + oi->address) + != 0) + continue; + /* link_data is on our PtMP + * network */ + added = 1; + nexthop = l2->link_data; + break; + } + } + + if (added) { + /* found all necessary info to build + * nexthop */ + nh = vertex_nexthop_new(); + nh->oi = oi; + nh->router = nexthop; + ospf_spf_add_parent(v, w, nh, distance); + return 1; + } else + zlog_info( + "%s: could not determine nexthop for link %s", + __func__, oi->ifp->name); + } /* end point-to-point link from V to W */ + else if (l->m[0].type == LSA_LINK_TYPE_VIRTUALLINK) { + struct ospf_vl_data *vl_data; + + /* VLink implementation limitations: + * a) vl_data can only reference one nexthop, so + * no ECMP + * to backbone through VLinks. Though + * transit-area + * summaries may be considered, and those can + * be ECMP. + * b) We can only use /one/ VLink, even if + * multiple ones + * exist this router through multiple + * transit-areas. + */ + vl_data = ospf_vl_lookup(area->ospf, NULL, + l->link_id); + + if (vl_data + && CHECK_FLAG(vl_data->flags, + OSPF_VL_FLAG_APPROVED)) { + nh = vertex_nexthop_new(); + nh->oi = vl_data->nexthop.oi; + nh->router = vl_data->nexthop.router; + ospf_spf_add_parent(v, w, nh, distance); + return 1; + } else + zlog_info( + "ospf_nexthop_calculation(): " + "vl_data for VL link not found"); + } /* end virtual-link from V to W */ + return 0; + } /* end W is a Router vertex */ + else { + assert(w->type == OSPF_VERTEX_NETWORK); + + nh = vertex_nexthop_new(); + nh->oi = oi; + nh->router.s_addr = 0; /* Nexthop not required */ + ospf_spf_add_parent(v, w, nh, distance); + return 1; + } + } /* end V is the root */ + /* Check if W's parent is a network connected to root. */ + else if (v->type == OSPF_VERTEX_NETWORK) { + /* See if any of V's parents are the root. */ + for (ALL_LIST_ELEMENTS(v->parents, node, nnode, vp)) { + if (vp->parent == area->spf) /* connects to root? */ + { + /* 16.1.1 para 5. ...the parent vertex is a + * network that + * directly connects the calculating router to + * the destination + * router. The list of next hops is then + * determined by + * examining the destination's router-LSA... + */ + + assert(w->type == OSPF_VERTEX_ROUTER); + while ((l = ospf_get_next_link(w, v, l))) { + /* ...For each link in the router-LSA + * that points back to the + * parent network, the link's Link Data + * field provides the IP + * address of a next hop router. The + * outgoing interface to + * use can then be derived from the next + * hop IP address (or + * it can be inherited from the parent + * network). + */ + nh = vertex_nexthop_new(); + nh->oi = vp->nexthop->oi; + nh->router = l->link_data; + added = 1; + ospf_spf_add_parent(v, w, nh, distance); + } + /* Note lack of return is deliberate. See next + * comment. */ + } } + /* NB: This code is non-trivial. + * + * E.g. it is not enough to know that V connects to the root. It + * is + * also important that the while above, looping through all + * links from + * W->V found at least one link, so that we know there is + * bi-directional connectivity between V and W (which need not + * be the + * case, e.g. when OSPF has not yet converged fully). + * Otherwise, if + * we /always/ return here, without having checked that + * root->V->-W + * actually resulted in a valid nexthop being created, then we + * we will + * prevent SPF from finding/using higher cost paths. + * + * It is important, if root->V->W has not been added, that we + * continue + * through to the intervening-router nexthop code below. So as + * to + * ensure other paths to V may be used. This avoids unnecessary + * blackholes while OSPF is convergening. + * + * I.e. we may have arrived at this function, examining V -> W, + * via + * workable paths other than root -> V, and it's important to + * avoid + * getting "confused" by non-working root->V->W path - it's + * important + * to *not* lose the working non-root paths, just because of a + * non-viable root->V->W. + * + * See also bug #330 (required reading!), and: + * + * http://blogs.oracle.com/paulj/entry/the_difference_a_line_makes + */ + if (added) + return added; + } - if (added) - { - /* found all necessary info to build nexthop */ - nh = vertex_nexthop_new (); - nh->oi = oi; - nh->router = nexthop; - ospf_spf_add_parent (v, w, nh, distance); - return 1; - } - else - zlog_info("%s: could not determine nexthop for link %s", - __func__, oi->ifp->name); - } /* end point-to-point link from V to W */ - else if (l->m[0].type == LSA_LINK_TYPE_VIRTUALLINK) - { - struct ospf_vl_data *vl_data; - - /* VLink implementation limitations: - * a) vl_data can only reference one nexthop, so no ECMP - * to backbone through VLinks. Though transit-area - * summaries may be considered, and those can be ECMP. - * b) We can only use /one/ VLink, even if multiple ones - * exist this router through multiple transit-areas. - */ - vl_data = ospf_vl_lookup (area->ospf, NULL, l->link_id); - - if (vl_data - && CHECK_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED)) - { - nh = vertex_nexthop_new (); - nh->oi = vl_data->nexthop.oi; - nh->router = vl_data->nexthop.router; - ospf_spf_add_parent (v, w, nh, distance); - return 1; - } - else - zlog_info("ospf_nexthop_calculation(): " - "vl_data for VL link not found"); - } /* end virtual-link from V to W */ - return 0; - } /* end W is a Router vertex */ - else - { - assert(w->type == OSPF_VERTEX_NETWORK); + /* 16.1.1 para 4. If there is at least one intervening router in the + * current shortest path between the destination and the root, the + * destination simply inherits the set of next hops from the + * parent. + */ + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("%s: Intervening routers, adding parent(s)", + __func__); + + for (ALL_LIST_ELEMENTS(v->parents, node, nnode, vp)) { + added = 1; + ospf_spf_add_parent(v, w, vp->nexthop, distance); + } - nh = vertex_nexthop_new (); - nh->oi = oi; - nh->router.s_addr = 0; /* Nexthop not required */ - ospf_spf_add_parent (v, w, nh, distance); - return 1; - } - } /* end V is the root */ - /* Check if W's parent is a network connected to root. */ - else if (v->type == OSPF_VERTEX_NETWORK) - { - /* See if any of V's parents are the root. */ - for (ALL_LIST_ELEMENTS (v->parents, node, nnode, vp)) - { - if (vp->parent == area->spf) /* connects to root? */ - { - /* 16.1.1 para 5. ...the parent vertex is a network that - * directly connects the calculating router to the destination - * router. The list of next hops is then determined by - * examining the destination's router-LSA... - */ - - assert(w->type == OSPF_VERTEX_ROUTER); - while ((l = ospf_get_next_link (w, v, l))) - { - /* ...For each link in the router-LSA that points back to the - * parent network, the link's Link Data field provides the IP - * address of a next hop router. The outgoing interface to - * use can then be derived from the next hop IP address (or - * it can be inherited from the parent network). - */ - nh = vertex_nexthop_new (); - nh->oi = vp->nexthop->oi; - nh->router = l->link_data; - added = 1; - ospf_spf_add_parent (v, w, nh, distance); - } - /* Note lack of return is deliberate. See next comment. */ - } - } - /* NB: This code is non-trivial. - * - * E.g. it is not enough to know that V connects to the root. It is - * also important that the while above, looping through all links from - * W->V found at least one link, so that we know there is - * bi-directional connectivity between V and W (which need not be the - * case, e.g. when OSPF has not yet converged fully). Otherwise, if - * we /always/ return here, without having checked that root->V->-W - * actually resulted in a valid nexthop being created, then we we will - * prevent SPF from finding/using higher cost paths. - * - * It is important, if root->V->W has not been added, that we continue - * through to the intervening-router nexthop code below. So as to - * ensure other paths to V may be used. This avoids unnecessary - * blackholes while OSPF is convergening. - * - * I.e. we may have arrived at this function, examining V -> W, via - * workable paths other than root -> V, and it's important to avoid - * getting "confused" by non-working root->V->W path - it's important - * to *not* lose the working non-root paths, just because of a - * non-viable root->V->W. - * - * See also bug #330 (required reading!), and: - * - * http://blogs.oracle.com/paulj/entry/the_difference_a_line_makes - */ - if (added) - return added; - } - - /* 16.1.1 para 4. If there is at least one intervening router in the - * current shortest path between the destination and the root, the - * destination simply inherits the set of next hops from the - * parent. - */ - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("%s: Intervening routers, adding parent(s)", __func__); - - for (ALL_LIST_ELEMENTS (v->parents, node, nnode, vp)) - { - added = 1; - ospf_spf_add_parent (v, w, vp->nexthop, distance); - } - - return added; + return added; } /* RFC2328 Section 16.1 (2). @@ -761,329 +779,319 @@ ospf_nexthop_calculation (struct ospf_area *area, struct vertex *v, * of candidates with any vertices not already on the list. If a lower-cost * path is found to a vertex already on the candidate list, store the new cost. */ -static void -ospf_spf_next (struct vertex *v, struct ospf_area *area, - struct pqueue * candidate) +static void ospf_spf_next(struct vertex *v, struct ospf_area *area, + struct pqueue *candidate) { - struct ospf_lsa *w_lsa = NULL; - u_char *p; - u_char *lim; - struct router_lsa_link *l = NULL; - struct in_addr *r; - int type = 0, lsa_pos=-1, lsa_pos_next=0; - - /* If this is a router-LSA, and bit V of the router-LSA (see Section - A.4.2:RFC2328) is set, set Area A's TransitCapability to TRUE. */ - if (v->type == OSPF_VERTEX_ROUTER) - { - if (IS_ROUTER_LSA_VIRTUAL ((struct router_lsa *) v->lsa)) - area->transit = OSPF_TRANSIT_TRUE; - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("%s: Next vertex of %s vertex %s", - __func__, - v->type == OSPF_VERTEX_ROUTER ? "Router" : "Network", - inet_ntoa(v->lsa->id)); - - p = ((u_char *) v->lsa) + OSPF_LSA_HEADER_SIZE + 4; - lim = ((u_char *) v->lsa) + ntohs (v->lsa->length); - - while (p < lim) - { - struct vertex *w; - unsigned int distance; - - /* In case of V is Router-LSA. */ - if (v->lsa->type == OSPF_ROUTER_LSA) - { - l = (struct router_lsa_link *) p; - - lsa_pos = lsa_pos_next; /* LSA link position */ - lsa_pos_next++; - p += (OSPF_ROUTER_LSA_LINK_SIZE + - (l->m[0].tos_count * OSPF_ROUTER_LSA_TOS_SIZE)); - - /* (a) If this is a link to a stub network, examine the next - link in V's LSA. Links to stub networks will be - considered in the second stage of the shortest path - calculation. */ - if ((type = l->m[0].type) == LSA_LINK_TYPE_STUB) - continue; - - /* (b) Otherwise, W is a transit vertex (router or transit - network). Look up the vertex W's LSA (router-LSA or - network-LSA) in Area A's link state database. */ - switch (type) - { - case LSA_LINK_TYPE_POINTOPOINT: - case LSA_LINK_TYPE_VIRTUALLINK: - if (type == LSA_LINK_TYPE_VIRTUALLINK) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("looking up LSA through VL: %s", - inet_ntoa (l->link_id)); - } + struct ospf_lsa *w_lsa = NULL; + u_char *p; + u_char *lim; + struct router_lsa_link *l = NULL; + struct in_addr *r; + int type = 0, lsa_pos = -1, lsa_pos_next = 0; + + /* If this is a router-LSA, and bit V of the router-LSA (see Section + A.4.2:RFC2328) is set, set Area A's TransitCapability to TRUE. */ + if (v->type == OSPF_VERTEX_ROUTER) { + if (IS_ROUTER_LSA_VIRTUAL((struct router_lsa *)v->lsa)) + area->transit = OSPF_TRANSIT_TRUE; + } - w_lsa = ospf_lsa_lookup (area, OSPF_ROUTER_LSA, l->link_id, - l->link_id); - if (w_lsa) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("found Router LSA %s", inet_ntoa (l->link_id)); - } - break; - case LSA_LINK_TYPE_TRANSIT: - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Looking up Network LSA, ID: %s", - inet_ntoa (l->link_id)); - w_lsa = ospf_lsa_lookup_by_id (area, OSPF_NETWORK_LSA, - l->link_id); - if (w_lsa) - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("found the LSA"); - break; - default: - zlog_warn ("Invalid LSA link type %d", type); - continue; - } - } - else - { - /* In case of V is Network-LSA. */ - r = (struct in_addr *) p; - p += sizeof (struct in_addr); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("%s: Next vertex of %s vertex %s", __func__, + v->type == OSPF_VERTEX_ROUTER ? "Router" : "Network", + inet_ntoa(v->lsa->id)); + + p = ((u_char *)v->lsa) + OSPF_LSA_HEADER_SIZE + 4; + lim = ((u_char *)v->lsa) + ntohs(v->lsa->length); + + while (p < lim) { + struct vertex *w; + unsigned int distance; + + /* In case of V is Router-LSA. */ + if (v->lsa->type == OSPF_ROUTER_LSA) { + l = (struct router_lsa_link *)p; + + lsa_pos = lsa_pos_next; /* LSA link position */ + lsa_pos_next++; + p += (OSPF_ROUTER_LSA_LINK_SIZE + + (l->m[0].tos_count * OSPF_ROUTER_LSA_TOS_SIZE)); + + /* (a) If this is a link to a stub network, examine the + next + link in V's LSA. Links to stub networks will be + considered in the second stage of the shortest path + calculation. */ + if ((type = l->m[0].type) == LSA_LINK_TYPE_STUB) + continue; + + /* (b) Otherwise, W is a transit vertex (router or + transit + network). Look up the vertex W's LSA (router-LSA or + network-LSA) in Area A's link state database. */ + switch (type) { + case LSA_LINK_TYPE_POINTOPOINT: + case LSA_LINK_TYPE_VIRTUALLINK: + if (type == LSA_LINK_TYPE_VIRTUALLINK) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "looking up LSA through VL: %s", + inet_ntoa(l->link_id)); + } + + w_lsa = ospf_lsa_lookup(area, OSPF_ROUTER_LSA, + l->link_id, l->link_id); + if (w_lsa) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "found Router LSA %s", + inet_ntoa(l->link_id)); + } + break; + case LSA_LINK_TYPE_TRANSIT: + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "Looking up Network LSA, ID: %s", + inet_ntoa(l->link_id)); + w_lsa = ospf_lsa_lookup_by_id( + area, OSPF_NETWORK_LSA, l->link_id); + if (w_lsa) + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("found the LSA"); + break; + default: + zlog_warn("Invalid LSA link type %d", type); + continue; + } + } else { + /* In case of V is Network-LSA. */ + r = (struct in_addr *)p; + p += sizeof(struct in_addr); + + /* Lookup the vertex W's LSA. */ + w_lsa = ospf_lsa_lookup_by_id(area, OSPF_ROUTER_LSA, + *r); + if (w_lsa) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("found Router LSA %s", + inet_ntoa(w_lsa->data->id)); + } + } - /* Lookup the vertex W's LSA. */ - w_lsa = ospf_lsa_lookup_by_id (area, OSPF_ROUTER_LSA, *r); - if (w_lsa) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("found Router LSA %s", inet_ntoa (w_lsa->data->id)); - } - } + /* (b cont.) If the LSA does not exist, or its LS age is equal + to MaxAge, or it does not have a link back to vertex V, + examine the next link in V's LSA.[23] */ + if (w_lsa == NULL) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("No LSA found"); + continue; + } - /* (b cont.) If the LSA does not exist, or its LS age is equal - to MaxAge, or it does not have a link back to vertex V, - examine the next link in V's LSA.[23] */ - if (w_lsa == NULL) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("No LSA found"); - continue; - } + if (IS_LSA_MAXAGE(w_lsa)) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("LSA is MaxAge"); + continue; + } - if (IS_LSA_MAXAGE (w_lsa)) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("LSA is MaxAge"); - continue; - } + if (ospf_lsa_has_link(w_lsa->data, v->lsa) < 0) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("The LSA doesn't have a link back"); + continue; + } - if (ospf_lsa_has_link (w_lsa->data, v->lsa) < 0 ) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("The LSA doesn't have a link back"); - continue; - } + /* (c) If vertex W is already on the shortest-path tree, examine + the next link in the LSA. */ + if (w_lsa->stat == LSA_SPF_IN_SPFTREE) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("The LSA is already in SPF"); + continue; + } - /* (c) If vertex W is already on the shortest-path tree, examine - the next link in the LSA. */ - if (w_lsa->stat == LSA_SPF_IN_SPFTREE) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("The LSA is already in SPF"); - continue; - } + /* (d) Calculate the link state cost D of the resulting path + from the root to vertex W. D is equal to the sum of the link + state cost of the (already calculated) shortest path to + vertex V and the advertised cost of the link between vertices + V and W. If D is: */ + + /* calculate link cost D. */ + if (v->lsa->type == OSPF_ROUTER_LSA) + distance = v->distance + ntohs(l->m[0].metric); + else /* v is not a Router-LSA */ + distance = v->distance; + + /* Is there already vertex W in candidate list? */ + if (w_lsa->stat == LSA_SPF_NOT_EXPLORED) { + /* prepare vertex W. */ + w = ospf_vertex_new(w_lsa); + + /* Calculate nexthop to W. */ + if (ospf_nexthop_calculation(area, v, w, l, distance, + lsa_pos)) + pqueue_enqueue(w, candidate); + else if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Nexthop Calc failed"); + } else if (w_lsa->stat >= 0) { + /* Get the vertex from candidates. */ + w = candidate->array[w_lsa->stat]; + + /* if D is greater than. */ + if (w->distance < distance) { + continue; + } + /* equal to. */ + else if (w->distance == distance) { + /* Found an equal-cost path to W. + * Calculate nexthop of to W from V. */ + ospf_nexthop_calculation(area, v, w, l, + distance, lsa_pos); + } + /* less than. */ + else { + /* Found a lower-cost path to W. + * nexthop_calculation is conditional, if it + * finds + * valid nexthop it will call spf_add_parents, + * which + * will flush the old parents + */ + if (ospf_nexthop_calculation(area, v, w, l, + distance, lsa_pos)) + /* Decrease the key of the node in the + * heap. + * trickle-sort it up towards root, just + * in case this + * node should now be the new root due + * the cost change. + * (next pqueu_{de,en}queue will fully + * re-heap the queue). + */ + trickle_up(w_lsa->stat, candidate); + } + } /* end W is already on the candidate list */ + } /* end loop over the links in V's LSA */ +} - /* (d) Calculate the link state cost D of the resulting path - from the root to vertex W. D is equal to the sum of the link - state cost of the (already calculated) shortest path to - vertex V and the advertised cost of the link between vertices - V and W. If D is: */ - - /* calculate link cost D. */ - if (v->lsa->type == OSPF_ROUTER_LSA) - distance = v->distance + ntohs (l->m[0].metric); - else /* v is not a Router-LSA */ - distance = v->distance; - - /* Is there already vertex W in candidate list? */ - if (w_lsa->stat == LSA_SPF_NOT_EXPLORED) - { - /* prepare vertex W. */ - w = ospf_vertex_new (w_lsa); - - /* Calculate nexthop to W. */ - if (ospf_nexthop_calculation (area, v, w, l, distance, lsa_pos)) - pqueue_enqueue (w, candidate); - else if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Nexthop Calc failed"); +static void ospf_spf_dump(struct vertex *v, int i) +{ + struct listnode *cnode; + struct listnode *nnode; + struct vertex_parent *parent; + + if (v->type == OSPF_VERTEX_ROUTER) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("SPF Result: %d [R] %s", i, + inet_ntoa(v->lsa->id)); + } else { + struct network_lsa *lsa = (struct network_lsa *)v->lsa; + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("SPF Result: %d [N] %s/%d", i, + inet_ntoa(v->lsa->id), + ip_masklen(lsa->mask)); } - else if (w_lsa->stat >= 0) - { - /* Get the vertex from candidates. */ - w = candidate->array[w_lsa->stat]; - /* if D is greater than. */ - if (w->distance < distance) - { - continue; - } - /* equal to. */ - else if (w->distance == distance) - { - /* Found an equal-cost path to W. - * Calculate nexthop of to W from V. */ - ospf_nexthop_calculation (area, v, w, l, distance, lsa_pos); - } - /* less than. */ - else - { - /* Found a lower-cost path to W. - * nexthop_calculation is conditional, if it finds - * valid nexthop it will call spf_add_parents, which - * will flush the old parents - */ - if (ospf_nexthop_calculation (area, v, w, l, distance, lsa_pos)) - /* Decrease the key of the node in the heap. - * trickle-sort it up towards root, just in case this - * node should now be the new root due the cost change. - * (next pqueu_{de,en}queue will fully re-heap the queue). - */ - trickle_up (w_lsa->stat, candidate); - } - } /* end W is already on the candidate list */ - } /* end loop over the links in V's LSA */ -} + if (IS_DEBUG_OSPF_EVENT) + for (ALL_LIST_ELEMENTS_RO(v->parents, nnode, parent)) { + zlog_debug(" nexthop %p %s %s", (void *)parent->nexthop, + inet_ntoa(parent->nexthop->router), + parent->nexthop->oi + ? IF_NAME(parent->nexthop->oi) + : "NULL"); + } -static void -ospf_spf_dump (struct vertex *v, int i) -{ - struct listnode *cnode; - struct listnode *nnode; - struct vertex_parent *parent; - - if (v->type == OSPF_VERTEX_ROUTER) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("SPF Result: %d [R] %s", i, inet_ntoa (v->lsa->id)); - } - else - { - struct network_lsa *lsa = (struct network_lsa *) v->lsa; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("SPF Result: %d [N] %s/%d", i, inet_ntoa (v->lsa->id), - ip_masklen (lsa->mask)); - } + i++; - if (IS_DEBUG_OSPF_EVENT) - for (ALL_LIST_ELEMENTS_RO (v->parents, nnode, parent)) - { - zlog_debug (" nexthop %p %s %s", - (void *)parent->nexthop, - inet_ntoa (parent->nexthop->router), - parent->nexthop->oi ? IF_NAME(parent->nexthop->oi) - : "NULL"); - } - - i++; - - for (ALL_LIST_ELEMENTS_RO (v->children, cnode, v)) - ospf_spf_dump (v, i); + for (ALL_LIST_ELEMENTS_RO(v->children, cnode, v)) + ospf_spf_dump(v, i); } /* Second stage of SPF calculation. */ -static void -ospf_spf_process_stubs (struct ospf_area *area, struct vertex *v, - struct route_table *rt, - int parent_is_root) +static void ospf_spf_process_stubs(struct ospf_area *area, struct vertex *v, + struct route_table *rt, int parent_is_root) { - struct listnode *cnode, *cnnode; - struct vertex *child; + struct listnode *cnode, *cnnode; + struct vertex *child; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_process_stub():processing stubs for area %s", + inet_ntoa(area->area_id)); + if (v->type == OSPF_VERTEX_ROUTER) { + u_char *p; + u_char *lim; + struct router_lsa_link *l; + struct router_lsa *rlsa; + int lsa_pos = 0; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_process_stubs():processing router LSA, id: %s", + inet_ntoa(v->lsa->id)); + rlsa = (struct router_lsa *)v->lsa; + + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_process_stubs(): we have %d links to process", + ntohs(rlsa->links)); + p = ((u_char *)v->lsa) + OSPF_LSA_HEADER_SIZE + 4; + lim = ((u_char *)v->lsa) + ntohs(v->lsa->length); + + while (p < lim) { + l = (struct router_lsa_link *)p; + + p += (OSPF_ROUTER_LSA_LINK_SIZE + + (l->m[0].tos_count * OSPF_ROUTER_LSA_TOS_SIZE)); + + if (l->m[0].type == LSA_LINK_TYPE_STUB) + ospf_intra_add_stub(rt, l, v, area, + parent_is_root, lsa_pos); + lsa_pos++; + } + } - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_process_stub():processing stubs for area %s", - inet_ntoa (area->area_id)); - if (v->type == OSPF_VERTEX_ROUTER) - { - u_char *p; - u_char *lim; - struct router_lsa_link *l; - struct router_lsa *rlsa; - int lsa_pos = 0; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_process_stubs():processing router LSA, id: %s", - inet_ntoa (v->lsa->id)); - rlsa = (struct router_lsa *) v->lsa; - - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_process_stubs(): we have %d links to process", - ntohs (rlsa->links)); - p = ((u_char *) v->lsa) + OSPF_LSA_HEADER_SIZE + 4; - lim = ((u_char *) v->lsa) + ntohs (v->lsa->length); - - while (p < lim) - { - l = (struct router_lsa_link *) p; + ospf_vertex_dump("ospf_process_stubs(): after examining links: ", v, 1, + 1); - p += (OSPF_ROUTER_LSA_LINK_SIZE + - (l->m[0].tos_count * OSPF_ROUTER_LSA_TOS_SIZE)); + for (ALL_LIST_ELEMENTS(v->children, cnode, cnnode, child)) { + if (CHECK_FLAG(child->flags, OSPF_VERTEX_PROCESSED)) + continue; - if (l->m[0].type == LSA_LINK_TYPE_STUB) - ospf_intra_add_stub (rt, l, v, area, parent_is_root, lsa_pos); - lsa_pos++; - } - } - - ospf_vertex_dump("ospf_process_stubs(): after examining links: ", v, 1, 1); - - for (ALL_LIST_ELEMENTS (v->children, cnode, cnnode, child)) - { - if (CHECK_FLAG (child->flags, OSPF_VERTEX_PROCESSED)) - continue; - - /* the first level of routers connected to the root - * should have 'parent_is_root' set, including those - * connected via a network vertex. - */ - if (area->spf == v) - parent_is_root = 1; - else if (v->type == OSPF_VERTEX_ROUTER) - parent_is_root = 0; - - ospf_spf_process_stubs (area, child, rt, parent_is_root); - - SET_FLAG (child->flags, OSPF_VERTEX_PROCESSED); - } + /* the first level of routers connected to the root + * should have 'parent_is_root' set, including those + * connected via a network vertex. + */ + if (area->spf == v) + parent_is_root = 1; + else if (v->type == OSPF_VERTEX_ROUTER) + parent_is_root = 0; + + ospf_spf_process_stubs(area, child, rt, parent_is_root); + + SET_FLAG(child->flags, OSPF_VERTEX_PROCESSED); + } } -void -ospf_rtrs_free (struct route_table *rtrs) +void ospf_rtrs_free(struct route_table *rtrs) { - struct route_node *rn; - struct list *or_list; - struct ospf_route *or; - struct listnode *node, *nnode; + struct route_node *rn; + struct list *or_list; + struct ospf_route * or ; + struct listnode *node, *nnode; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Route: Router Routing Table free"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Route: Router Routing Table free"); - for (rn = route_top (rtrs); rn; rn = route_next (rn)) - if ((or_list = rn->info) != NULL) - { - for (ALL_LIST_ELEMENTS (or_list, node, nnode, or)) - ospf_route_free (or); + for (rn = route_top(rtrs); rn; rn = route_next(rn)) + if ((or_list = rn->info) != NULL) { + for (ALL_LIST_ELEMENTS(or_list, node, nnode, or)) + ospf_route_free(or); - list_delete (or_list); + list_delete(or_list); - /* Unlock the node. */ - rn->info = NULL; - route_unlock_node (rn); - } - route_table_finish (rtrs); + /* Unlock the node. */ + rn->info = NULL; + route_unlock_node(rn); + } + route_table_finish(rtrs); } #if 0 @@ -1149,318 +1157,309 @@ ospf_rtrs_print (struct route_table *rtrs) #endif /* Calculating the shortest-path tree for an area. */ -static void -ospf_spf_calculate (struct ospf_area *area, struct route_table *new_table, - struct route_table *new_rtrs) +static void ospf_spf_calculate(struct ospf_area *area, + struct route_table *new_table, + struct route_table *new_rtrs) { - struct pqueue *candidate; - struct vertex *v; - - if (IS_DEBUG_OSPF_EVENT) - { - zlog_debug ("ospf_spf_calculate: Start"); - zlog_debug ("ospf_spf_calculate: running Dijkstra for area %s", - inet_ntoa (area->area_id)); - } - - /* Check router-lsa-self. If self-router-lsa is not yet allocated, - return this area's calculation. */ - if (!area->router_lsa_self) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_spf_calculate: " - "Skip area %s's calculation due to empty router_lsa_self", - inet_ntoa (area->area_id)); - return; - } - - /* RFC2328 16.1. (1). */ - /* Initialize the algorithm's data structures. */ - - /* This function scans all the LSA database and set the stat field to - * LSA_SPF_NOT_EXPLORED. */ - ospf_lsdb_clean_stat (area->lsdb); - /* Create a new heap for the candidates. */ - candidate = pqueue_create(); - candidate->cmp = cmp; - candidate->update = update_stat; - - /* Initialize the shortest-path tree to only the root (which is the - router doing the calculation). */ - ospf_spf_init (area); - v = area->spf; - /* Set LSA position to LSA_SPF_IN_SPFTREE. This vertex is the root of the - * spanning tree. */ - *(v->stat) = LSA_SPF_IN_SPFTREE; - - /* Set Area A's TransitCapability to FALSE. */ - area->transit = OSPF_TRANSIT_FALSE; - area->shortcut_capability = 1; - - for (;;) - { - /* RFC2328 16.1. (2). */ - ospf_spf_next (v, area, candidate); - - /* RFC2328 16.1. (3). */ - /* If at this step the candidate list is empty, the shortest- - path tree (of transit vertices) has been completely built and - this stage of the procedure terminates. */ - if (candidate->size == 0) - break; - - /* Otherwise, choose the vertex belonging to the candidate list - that is closest to the root, and add it to the shortest-path - tree (removing it from the candidate list in the - process). */ - /* Extract from the candidates the node with the lower key. */ - v = (struct vertex *) pqueue_dequeue (candidate); - /* Update stat field in vertex. */ - *(v->stat) = LSA_SPF_IN_SPFTREE; - - ospf_vertex_add_parent (v); - - /* RFC2328 16.1. (4). */ - if (v->type == OSPF_VERTEX_ROUTER) - ospf_intra_add_router (new_rtrs, v, area); - else - ospf_intra_add_transit (new_table, v, area); - - /* RFC2328 16.1. (5). */ - /* Iterate the algorithm by returning to Step 2. */ - - } /* end loop until no more candidate vertices */ + struct pqueue *candidate; + struct vertex *v; - if (IS_DEBUG_OSPF_EVENT) - { - ospf_spf_dump (area->spf, 0); - ospf_route_table_dump (new_table); - } + if (IS_DEBUG_OSPF_EVENT) { + zlog_debug("ospf_spf_calculate: Start"); + zlog_debug("ospf_spf_calculate: running Dijkstra for area %s", + inet_ntoa(area->area_id)); + } - /* Second stage of SPF calculation procedure's */ - ospf_spf_process_stubs (area, area->spf, new_table, 0); + /* Check router-lsa-self. If self-router-lsa is not yet allocated, + return this area's calculation. */ + if (!area->router_lsa_self) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_spf_calculate: " + "Skip area %s's calculation due to empty router_lsa_self", + inet_ntoa(area->area_id)); + return; + } - /* Free candidate queue. */ - pqueue_delete (candidate); + /* RFC2328 16.1. (1). */ + /* Initialize the algorithm's data structures. */ + + /* This function scans all the LSA database and set the stat field to + * LSA_SPF_NOT_EXPLORED. */ + ospf_lsdb_clean_stat(area->lsdb); + /* Create a new heap for the candidates. */ + candidate = pqueue_create(); + candidate->cmp = cmp; + candidate->update = update_stat; + + /* Initialize the shortest-path tree to only the root (which is the + router doing the calculation). */ + ospf_spf_init(area); + v = area->spf; + /* Set LSA position to LSA_SPF_IN_SPFTREE. This vertex is the root of + * the + * spanning tree. */ + *(v->stat) = LSA_SPF_IN_SPFTREE; + + /* Set Area A's TransitCapability to FALSE. */ + area->transit = OSPF_TRANSIT_FALSE; + area->shortcut_capability = 1; + + for (;;) { + /* RFC2328 16.1. (2). */ + ospf_spf_next(v, area, candidate); + + /* RFC2328 16.1. (3). */ + /* If at this step the candidate list is empty, the shortest- + path tree (of transit vertices) has been completely built and + this stage of the procedure terminates. */ + if (candidate->size == 0) + break; + + /* Otherwise, choose the vertex belonging to the candidate list + that is closest to the root, and add it to the shortest-path + tree (removing it from the candidate list in the + process). */ + /* Extract from the candidates the node with the lower key. */ + v = (struct vertex *)pqueue_dequeue(candidate); + /* Update stat field in vertex. */ + *(v->stat) = LSA_SPF_IN_SPFTREE; + + ospf_vertex_add_parent(v); + + /* RFC2328 16.1. (4). */ + if (v->type == OSPF_VERTEX_ROUTER) + ospf_intra_add_router(new_rtrs, v, area); + else + ospf_intra_add_transit(new_table, v, area); + + /* RFC2328 16.1. (5). */ + /* Iterate the algorithm by returning to Step 2. */ + + } /* end loop until no more candidate vertices */ + + if (IS_DEBUG_OSPF_EVENT) { + ospf_spf_dump(area->spf, 0); + ospf_route_table_dump(new_table); + } - ospf_vertex_dump (__func__, area->spf, 0, 1); - /* Free nexthop information, canonical versions of which are attached - * the first level of router vertices attached to the root vertex, see - * ospf_nexthop_calculation. - */ - ospf_canonical_nexthops_free (area->spf); + /* Second stage of SPF calculation procedure's */ + ospf_spf_process_stubs(area, area->spf, new_table, 0); - /* Increment SPF Calculation Counter. */ - area->spf_calculation++; + /* Free candidate queue. */ + pqueue_delete(candidate); - monotime(&area->ospf->ts_spf); - area->ts_spf = area->ospf->ts_spf; + ospf_vertex_dump(__func__, area->spf, 0, 1); + /* Free nexthop information, canonical versions of which are attached + * the first level of router vertices attached to the root vertex, see + * ospf_nexthop_calculation. + */ + ospf_canonical_nexthops_free(area->spf); - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_spf_calculate: Stop. %zd vertices", - mtype_stats_alloc(MTYPE_OSPF_VERTEX)); + /* Increment SPF Calculation Counter. */ + area->spf_calculation++; + + monotime(&area->ospf->ts_spf); + area->ts_spf = area->ospf->ts_spf; - /* Free SPF vertices, but not the list. List has ospf_vertex_free - * as deconstructor. - */ - list_delete_all_node (&vertex_list); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_spf_calculate: Stop. %zd vertices", + mtype_stats_alloc(MTYPE_OSPF_VERTEX)); + + /* Free SPF vertices, but not the list. List has ospf_vertex_free + * as deconstructor. + */ + list_delete_all_node(&vertex_list); } /* Timer for SPF calculation. */ -static int -ospf_spf_calculate_timer (struct thread *thread) +static int ospf_spf_calculate_timer(struct thread *thread) { - struct ospf *ospf = THREAD_ARG (thread); - struct route_table *new_table, *new_rtrs; - struct ospf_area *area; - struct listnode *node, *nnode; - struct timeval start_time, spf_start_time; - int areas_processed = 0; - unsigned long ia_time, prune_time, rt_time; - unsigned long abr_time, total_spf_time, spf_time; - char rbuf[32]; /* reason_buf */ - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("SPF: Timer (SPF calculation expire)"); - - ospf->t_spf_calc = NULL; - - monotime(&spf_start_time); - /* Allocate new table tree. */ - new_table = route_table_init (); - new_rtrs = route_table_init (); - - ospf_vl_unapprove (ospf); - - /* Calculate SPF for each area. */ - for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area)) - { - /* Do backbone last, so as to first discover intra-area paths - * for any back-bone virtual-links - */ - if (ospf->backbone && ospf->backbone == area) - continue; - - ospf_spf_calculate (area, new_table, new_rtrs); - areas_processed++; - } - - /* SPF for backbone, if required */ - if (ospf->backbone) - { - ospf_spf_calculate (ospf->backbone, new_table, new_rtrs); - areas_processed++; - } - - spf_time = monotime_since(&spf_start_time, NULL); - - ospf_vl_shut_unapproved (ospf); - - monotime(&start_time); - ospf_ia_routing (ospf, new_table, new_rtrs); - ia_time = monotime_since(&start_time, NULL); - - monotime(&start_time); - ospf_prune_unreachable_networks (new_table); - ospf_prune_unreachable_routers (new_rtrs); - prune_time = monotime_since(&start_time, NULL); - - /* AS-external-LSA calculation should not be performed here. */ - - /* If new Router Route is installed, - then schedule re-calculate External routes. */ - if (1) - ospf_ase_calculate_schedule (ospf); - - ospf_ase_calculate_timer_add (ospf); - - /* Update routing table. */ - monotime(&start_time); - ospf_route_install (ospf, new_table); - rt_time = monotime_since(&start_time, NULL); - - /* Update ABR/ASBR routing table */ - if (ospf->old_rtrs) - { - /* old_rtrs's node holds linked list of ospf_route. --kunihiro. */ - /* ospf_route_delete (ospf->old_rtrs); */ - ospf_rtrs_free (ospf->old_rtrs); - } - - ospf->old_rtrs = ospf->new_rtrs; - ospf->new_rtrs = new_rtrs; - - monotime(&start_time); - if (IS_OSPF_ABR (ospf)) - ospf_abr_task (ospf); - abr_time = monotime_since(&start_time, NULL); - - total_spf_time = monotime_since(&spf_start_time, &ospf->ts_spf_duration); - - rbuf[0] = '\0'; - if (spf_reason_flags) - { - if (spf_reason_flags & SPF_FLAG_ROUTER_LSA_INSTALL) - strncat (rbuf, "R, ", sizeof(rbuf) - strlen(rbuf) - 1); - if (spf_reason_flags & SPF_FLAG_NETWORK_LSA_INSTALL) - strncat (rbuf, "N, ", sizeof(rbuf) - strlen(rbuf) - 1); - if (spf_reason_flags & SPF_FLAG_SUMMARY_LSA_INSTALL) - strncat (rbuf, "S, ", sizeof(rbuf) - strlen(rbuf) - 1); - if (spf_reason_flags & SPF_FLAG_ASBR_SUMMARY_LSA_INSTALL) - strncat (rbuf, "AS, ", sizeof(rbuf) - strlen(rbuf) - 1); - if (spf_reason_flags & SPF_FLAG_ABR_STATUS_CHANGE) - strncat (rbuf, "ABR, ", sizeof(rbuf) - strlen(rbuf) - 1); - if (spf_reason_flags & SPF_FLAG_ASBR_STATUS_CHANGE) - strncat (rbuf, "ASBR, ", sizeof(rbuf) - strlen(rbuf) - 1); - if (spf_reason_flags & SPF_FLAG_MAXAGE) - strncat (rbuf, "M, ", sizeof(rbuf) - strlen(rbuf) - 1); - - size_t rbuflen = strlen(rbuf); - if (rbuflen >= 2) - rbuf[rbuflen - 2] = '\0'; /* skip the last ", " */ - else - rbuf[0] = '\0'; - } + struct ospf *ospf = THREAD_ARG(thread); + struct route_table *new_table, *new_rtrs; + struct ospf_area *area; + struct listnode *node, *nnode; + struct timeval start_time, spf_start_time; + int areas_processed = 0; + unsigned long ia_time, prune_time, rt_time; + unsigned long abr_time, total_spf_time, spf_time; + char rbuf[32]; /* reason_buf */ + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("SPF: Timer (SPF calculation expire)"); + + ospf->t_spf_calc = NULL; + + monotime(&spf_start_time); + /* Allocate new table tree. */ + new_table = route_table_init(); + new_rtrs = route_table_init(); + + ospf_vl_unapprove(ospf); + + /* Calculate SPF for each area. */ + for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) { + /* Do backbone last, so as to first discover intra-area paths + * for any back-bone virtual-links + */ + if (ospf->backbone && ospf->backbone == area) + continue; - if (IS_DEBUG_OSPF_EVENT) - { - zlog_info ("SPF Processing Time(usecs): %ld", total_spf_time); - zlog_info ("\t SPF Time: %ld", spf_time); - zlog_info ("\t InterArea: %ld", ia_time); - zlog_info ("\t Prune: %ld", prune_time); - zlog_info ("\tRouteInstall: %ld", rt_time); - if (IS_OSPF_ABR (ospf)) - zlog_info ("\t ABR: %ld (%d areas)", - abr_time, areas_processed); - zlog_info ("Reason(s) for SPF: %s", rbuf); - } - - ospf_clear_spf_reason_flags (); - - return 0; + ospf_spf_calculate(area, new_table, new_rtrs); + areas_processed++; + } + + /* SPF for backbone, if required */ + if (ospf->backbone) { + ospf_spf_calculate(ospf->backbone, new_table, new_rtrs); + areas_processed++; + } + + spf_time = monotime_since(&spf_start_time, NULL); + + ospf_vl_shut_unapproved(ospf); + + monotime(&start_time); + ospf_ia_routing(ospf, new_table, new_rtrs); + ia_time = monotime_since(&start_time, NULL); + + monotime(&start_time); + ospf_prune_unreachable_networks(new_table); + ospf_prune_unreachable_routers(new_rtrs); + prune_time = monotime_since(&start_time, NULL); + + /* AS-external-LSA calculation should not be performed here. */ + + /* If new Router Route is installed, + then schedule re-calculate External routes. */ + if (1) + ospf_ase_calculate_schedule(ospf); + + ospf_ase_calculate_timer_add(ospf); + + /* Update routing table. */ + monotime(&start_time); + ospf_route_install(ospf, new_table); + rt_time = monotime_since(&start_time, NULL); + + /* Update ABR/ASBR routing table */ + if (ospf->old_rtrs) { + /* old_rtrs's node holds linked list of ospf_route. --kunihiro. + */ + /* ospf_route_delete (ospf->old_rtrs); */ + ospf_rtrs_free(ospf->old_rtrs); + } + + ospf->old_rtrs = ospf->new_rtrs; + ospf->new_rtrs = new_rtrs; + + monotime(&start_time); + if (IS_OSPF_ABR(ospf)) + ospf_abr_task(ospf); + abr_time = monotime_since(&start_time, NULL); + + total_spf_time = + monotime_since(&spf_start_time, &ospf->ts_spf_duration); + + rbuf[0] = '\0'; + if (spf_reason_flags) { + if (spf_reason_flags & SPF_FLAG_ROUTER_LSA_INSTALL) + strncat(rbuf, "R, ", sizeof(rbuf) - strlen(rbuf) - 1); + if (spf_reason_flags & SPF_FLAG_NETWORK_LSA_INSTALL) + strncat(rbuf, "N, ", sizeof(rbuf) - strlen(rbuf) - 1); + if (spf_reason_flags & SPF_FLAG_SUMMARY_LSA_INSTALL) + strncat(rbuf, "S, ", sizeof(rbuf) - strlen(rbuf) - 1); + if (spf_reason_flags & SPF_FLAG_ASBR_SUMMARY_LSA_INSTALL) + strncat(rbuf, "AS, ", sizeof(rbuf) - strlen(rbuf) - 1); + if (spf_reason_flags & SPF_FLAG_ABR_STATUS_CHANGE) + strncat(rbuf, "ABR, ", sizeof(rbuf) - strlen(rbuf) - 1); + if (spf_reason_flags & SPF_FLAG_ASBR_STATUS_CHANGE) + strncat(rbuf, "ASBR, ", + sizeof(rbuf) - strlen(rbuf) - 1); + if (spf_reason_flags & SPF_FLAG_MAXAGE) + strncat(rbuf, "M, ", sizeof(rbuf) - strlen(rbuf) - 1); + + size_t rbuflen = strlen(rbuf); + if (rbuflen >= 2) + rbuf[rbuflen - 2] = '\0'; /* skip the last ", " */ + else + rbuf[0] = '\0'; + } + + if (IS_DEBUG_OSPF_EVENT) { + zlog_info("SPF Processing Time(usecs): %ld", total_spf_time); + zlog_info("\t SPF Time: %ld", spf_time); + zlog_info("\t InterArea: %ld", ia_time); + zlog_info("\t Prune: %ld", prune_time); + zlog_info("\tRouteInstall: %ld", rt_time); + if (IS_OSPF_ABR(ospf)) + zlog_info("\t ABR: %ld (%d areas)", abr_time, + areas_processed); + zlog_info("Reason(s) for SPF: %s", rbuf); + } + + ospf_clear_spf_reason_flags(); + + return 0; } /* Add schedule for SPF calculation. To avoid frequenst SPF calc, we set timer for SPF calc. */ -void -ospf_spf_calculate_schedule (struct ospf *ospf, ospf_spf_reason_t reason) +void ospf_spf_calculate_schedule(struct ospf *ospf, ospf_spf_reason_t reason) { - unsigned long delay, elapsed, ht; + unsigned long delay, elapsed, ht; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("SPF: calculation timer scheduled"); - - /* OSPF instance does not exist. */ - if (ospf == NULL) - return; - - ospf_spf_set_reason (reason); - - /* SPF calculation timer is already scheduled. */ - if (ospf->t_spf_calc) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("SPF: calculation timer is already scheduled: %p", - (void *)ospf->t_spf_calc); - return; - } - - elapsed = monotime_since (&ospf->ts_spf, NULL) / 1000; - - ht = ospf->spf_holdtime * ospf->spf_hold_multiplier; - - if (ht > ospf->spf_max_holdtime) - ht = ospf->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 < ospf->spf_max_holdtime) - ospf->spf_hold_multiplier++; - - /* always honour the SPF initial delay */ - if ( (ht - elapsed) < ospf->spf_delay) - delay = ospf->spf_delay; - else - delay = ht - elapsed; - } - else - { - /* Event is past required hold-time of last SPF */ - delay = ospf->spf_delay; - ospf->spf_hold_multiplier = 1; - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("SPF: calculation timer delay = %ld", delay); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("SPF: calculation timer scheduled"); + + /* OSPF instance does not exist. */ + if (ospf == NULL) + return; + + ospf_spf_set_reason(reason); + + /* SPF calculation timer is already scheduled. */ + if (ospf->t_spf_calc) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "SPF: calculation timer is already scheduled: %p", + (void *)ospf->t_spf_calc); + return; + } + + elapsed = monotime_since(&ospf->ts_spf, NULL) / 1000; + + ht = ospf->spf_holdtime * ospf->spf_hold_multiplier; + + if (ht > ospf->spf_max_holdtime) + ht = ospf->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 < ospf->spf_max_holdtime) + ospf->spf_hold_multiplier++; + + /* always honour the SPF initial delay */ + if ((ht - elapsed) < ospf->spf_delay) + delay = ospf->spf_delay; + else + delay = ht - elapsed; + } else { + /* Event is past required hold-time of last SPF */ + delay = ospf->spf_delay; + ospf->spf_hold_multiplier = 1; + } + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("SPF: calculation timer delay = %ld", delay); - zlog_info ("SPF: Scheduled in %ld msec", delay); + zlog_info("SPF: Scheduled in %ld msec", delay); - ospf->t_spf_calc = NULL; - thread_add_timer_msec(master, ospf_spf_calculate_timer, ospf, delay, - &ospf->t_spf_calc); + ospf->t_spf_calc = NULL; + thread_add_timer_msec(master, ospf_spf_calculate_timer, ospf, delay, + &ospf->t_spf_calc); } diff --git a/ospfd/ospf_spf.h b/ospfd/ospf_spf.h index 349f461c9..e23f5941f 100644 --- a/ospfd/ospf_spf.h +++ b/ospfd/ospf_spf.h @@ -32,46 +32,44 @@ /* The "root" is the node running the SPF calculation */ /* A router or network in an area */ -struct vertex -{ - u_char flags; - u_char type; /* copied from LSA header */ - struct in_addr id; /* copied from LSA header */ - struct lsa_header *lsa; /* Router or Network LSA */ - int *stat; /* Link to LSA status. */ - u_int32_t distance; /* from root to this vertex */ - struct list *parents; /* list of parents in SPF tree */ - struct list *children; /* list of children in SPF tree*/ +struct vertex { + u_char flags; + u_char type; /* copied from LSA header */ + struct in_addr id; /* copied from LSA header */ + struct lsa_header *lsa; /* Router or Network LSA */ + int *stat; /* Link to LSA status. */ + u_int32_t distance; /* from root to this vertex */ + struct list *parents; /* list of parents in SPF tree */ + struct list *children; /* list of children in SPF tree*/ }; /* A nexthop taken on the root node to get to this (parent) vertex */ -struct vertex_nexthop -{ - struct ospf_interface *oi; /* output intf on root node */ - struct in_addr router; /* router address to send to */ +struct vertex_nexthop { + struct ospf_interface *oi; /* output intf on root node */ + struct in_addr router; /* router address to send to */ }; -struct vertex_parent -{ - struct vertex_nexthop *nexthop; /* link to nexthop info for this parent */ - struct vertex *parent; /* parent vertex */ - int backlink; /* index back to parent for router-lsa's */ +struct vertex_parent { + struct vertex_nexthop + *nexthop; /* link to nexthop info for this parent */ + struct vertex *parent; /* parent vertex */ + int backlink; /* index back to parent for router-lsa's */ }; /* What triggered the SPF ? */ typedef enum { - SPF_FLAG_ROUTER_LSA_INSTALL = 1, - SPF_FLAG_NETWORK_LSA_INSTALL, - SPF_FLAG_SUMMARY_LSA_INSTALL, - SPF_FLAG_ASBR_SUMMARY_LSA_INSTALL, - SPF_FLAG_MAXAGE, - SPF_FLAG_ABR_STATUS_CHANGE, - SPF_FLAG_ASBR_STATUS_CHANGE, - SPF_FLAG_CONFIG_CHANGE, + SPF_FLAG_ROUTER_LSA_INSTALL = 1, + SPF_FLAG_NETWORK_LSA_INSTALL, + SPF_FLAG_SUMMARY_LSA_INSTALL, + SPF_FLAG_ASBR_SUMMARY_LSA_INSTALL, + SPF_FLAG_MAXAGE, + SPF_FLAG_ABR_STATUS_CHANGE, + SPF_FLAG_ASBR_STATUS_CHANGE, + SPF_FLAG_CONFIG_CHANGE, } ospf_spf_reason_t; -extern void ospf_spf_calculate_schedule (struct ospf *, ospf_spf_reason_t); -extern void ospf_rtrs_free (struct route_table *); +extern void ospf_spf_calculate_schedule(struct ospf *, ospf_spf_reason_t); +extern void ospf_rtrs_free(struct route_table *); /* void ospf_spf_calculate_timer_add (); */ #endif /* _QUAGGA_OSPF_SPF_H */ diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c index c34d97ff2..4ca6578ea 100644 --- a/ospfd/ospf_te.c +++ b/ospfd/ospf_te.c @@ -41,7 +41,7 @@ #include "log.h" #include "thread.h" #include "hash.h" -#include "sockunion.h" /* for inet_aton() */ +#include "sockunion.h" /* for inet_aton() */ #include "network.h" #include "ospfd/ospfd.h" @@ -68,1596 +68,1566 @@ */ struct ospf_mpls_te OspfMplsTE; -const char *mode2text[] = { "Disable", "AS", "Area", "Emulate" }; +const char *mode2text[] = {"Disable", "AS", "Area", "Emulate"}; -enum oifstate -{ - OI_ANY, OI_DOWN, OI_UP -}; +enum oifstate { OI_ANY, OI_DOWN, OI_UP }; /*------------------------------------------------------------------------* * Followings are initialize/terminate functions for MPLS-TE handling. *------------------------------------------------------------------------*/ -static int ospf_mpls_te_new_if (struct interface *ifp); -static int ospf_mpls_te_del_if (struct interface *ifp); -static void ospf_mpls_te_ism_change (struct ospf_interface *oi, - int old_status); -static void ospf_mpls_te_nsm_change (struct ospf_neighbor *nbr, int old_status); -static void ospf_mpls_te_config_write_router (struct vty *vty); -static void ospf_mpls_te_show_info (struct vty *vty, struct ospf_lsa *lsa); -static int ospf_mpls_te_lsa_originate_area (void *arg); -static int ospf_mpls_te_lsa_originate_as (void *arg); -static struct ospf_lsa *ospf_mpls_te_lsa_refresh (struct ospf_lsa *lsa); - -static void del_mpls_te_link (void *val); -static void ospf_mpls_te_register_vty (void); - -int -ospf_mpls_te_init (void) -{ - int rc; - - rc = ospf_register_opaque_functab ( - OSPF_OPAQUE_AREA_LSA, - OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA, - ospf_mpls_te_new_if, - ospf_mpls_te_del_if, - ospf_mpls_te_ism_change, - ospf_mpls_te_nsm_change, +static int ospf_mpls_te_new_if(struct interface *ifp); +static int ospf_mpls_te_del_if(struct interface *ifp); +static void ospf_mpls_te_ism_change(struct ospf_interface *oi, int old_status); +static void ospf_mpls_te_nsm_change(struct ospf_neighbor *nbr, int old_status); +static void ospf_mpls_te_config_write_router(struct vty *vty); +static void ospf_mpls_te_show_info(struct vty *vty, struct ospf_lsa *lsa); +static int ospf_mpls_te_lsa_originate_area(void *arg); +static int ospf_mpls_te_lsa_originate_as(void *arg); +static struct ospf_lsa *ospf_mpls_te_lsa_refresh(struct ospf_lsa *lsa); + +static void del_mpls_te_link(void *val); +static void ospf_mpls_te_register_vty(void); + +int ospf_mpls_te_init(void) +{ + int rc; + + rc = ospf_register_opaque_functab( + OSPF_OPAQUE_AREA_LSA, OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA, + ospf_mpls_te_new_if, ospf_mpls_te_del_if, + ospf_mpls_te_ism_change, ospf_mpls_te_nsm_change, ospf_mpls_te_config_write_router, - NULL,/*ospf_mpls_te_config_write_if */ - NULL,/* ospf_mpls_te_config_write_debug */ - ospf_mpls_te_show_info, - ospf_mpls_te_lsa_originate_area, - ospf_mpls_te_lsa_refresh, - NULL,/* ospf_mpls_te_new_lsa_hook */ + NULL, /*ospf_mpls_te_config_write_if */ + NULL, /* ospf_mpls_te_config_write_debug */ + ospf_mpls_te_show_info, ospf_mpls_te_lsa_originate_area, + ospf_mpls_te_lsa_refresh, NULL, /* ospf_mpls_te_new_lsa_hook */ NULL /* ospf_mpls_te_del_lsa_hook */); - if (rc != 0) - { - zlog_warn ("ospf_mpls_te_init: Failed to register Traffic Engineering functions"); - goto out; - } + if (rc != 0) { + zlog_warn( + "ospf_mpls_te_init: Failed to register Traffic Engineering functions"); + goto out; + } - memset (&OspfMplsTE, 0, sizeof (struct ospf_mpls_te)); - OspfMplsTE.status = disabled; - OspfMplsTE.inter_as = Disable; - OspfMplsTE.iflist = list_new (); - OspfMplsTE.iflist->del = del_mpls_te_link; + memset(&OspfMplsTE, 0, sizeof(struct ospf_mpls_te)); + OspfMplsTE.status = disabled; + OspfMplsTE.inter_as = Disable; + OspfMplsTE.iflist = list_new(); + OspfMplsTE.iflist->del = del_mpls_te_link; - ospf_mpls_te_register_vty (); + ospf_mpls_te_register_vty(); out: - return rc; + return rc; } /* Additional register for RFC5392 support */ -static int -ospf_mpls_te_register (enum inter_as_mode mode) +static int ospf_mpls_te_register(enum inter_as_mode mode) { - int rc; - u_int8_t scope; + int rc; + u_int8_t scope; - if (OspfMplsTE.inter_as != Disable) - return 0; + if (OspfMplsTE.inter_as != Disable) + return 0; - if (mode == AS) - scope = OSPF_OPAQUE_AS_LSA; - else - scope = OSPF_OPAQUE_AREA_LSA; + if (mode == AS) + scope = OSPF_OPAQUE_AS_LSA; + else + scope = OSPF_OPAQUE_AREA_LSA; - rc = ospf_register_opaque_functab (scope, - OPAQUE_TYPE_INTER_AS_LSA, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - ospf_mpls_te_show_info, - ospf_mpls_te_lsa_originate_as, - ospf_mpls_te_lsa_refresh, NULL, NULL); + rc = ospf_register_opaque_functab(scope, OPAQUE_TYPE_INTER_AS_LSA, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + ospf_mpls_te_show_info, + ospf_mpls_te_lsa_originate_as, + ospf_mpls_te_lsa_refresh, NULL, NULL); - if (rc != 0) - { - zlog_warn ("ospf_router_info_init: Failed to register Inter-AS functions"); - return rc; - } + if (rc != 0) { + zlog_warn( + "ospf_router_info_init: Failed to register Inter-AS functions"); + return rc; + } - return 0; + return 0; } -static int -ospf_mpls_te_unregister () +static int ospf_mpls_te_unregister() { - u_int8_t scope; - - if (OspfMplsTE.inter_as == Disable) - return 0; + u_int8_t scope; - if (OspfMplsTE.inter_as == AS) - scope = OSPF_OPAQUE_AS_LSA; - else - scope = OSPF_OPAQUE_AREA_LSA; + if (OspfMplsTE.inter_as == Disable) + return 0; - ospf_delete_opaque_functab (scope, OPAQUE_TYPE_INTER_AS_LSA); + if (OspfMplsTE.inter_as == AS) + scope = OSPF_OPAQUE_AS_LSA; + else + scope = OSPF_OPAQUE_AREA_LSA; - return 0; + ospf_delete_opaque_functab(scope, OPAQUE_TYPE_INTER_AS_LSA); + return 0; } -void -ospf_mpls_te_term (void) +void ospf_mpls_te_term(void) { - list_delete (OspfMplsTE.iflist); - OspfMplsTE.iflist = NULL; + list_delete(OspfMplsTE.iflist); + OspfMplsTE.iflist = NULL; - ospf_delete_opaque_functab (OSPF_OPAQUE_AREA_LSA, - OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA); - OspfMplsTE.status = disabled; + ospf_delete_opaque_functab(OSPF_OPAQUE_AREA_LSA, + OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA); + OspfMplsTE.status = disabled; - ospf_mpls_te_unregister (); - OspfMplsTE.inter_as = Disable; + ospf_mpls_te_unregister(); + OspfMplsTE.inter_as = Disable; - return; + return; } /*------------------------------------------------------------------------* * Followings are control functions for MPLS-TE parameters management. *------------------------------------------------------------------------*/ -static void -del_mpls_te_link (void *val) +static void del_mpls_te_link(void *val) { - XFREE (MTYPE_OSPF_MPLS_TE, val); - return; + XFREE(MTYPE_OSPF_MPLS_TE, val); + return; } -u_int32_t -get_mpls_te_instance_value (void) +u_int32_t get_mpls_te_instance_value(void) { - static u_int32_t seqno = 0; + static u_int32_t seqno = 0; - if (seqno < MAX_LEGAL_TE_INSTANCE_NUM ) - seqno += 1; - else - seqno = 1; /* Avoid zero. */ + if (seqno < MAX_LEGAL_TE_INSTANCE_NUM) + seqno += 1; + else + seqno = 1; /* Avoid zero. */ - return seqno; + return seqno; } -static struct ospf_interface * -lookup_oi_by_ifp (struct interface *ifp, - struct ospf_area *area, enum oifstate oifstate) +static struct ospf_interface *lookup_oi_by_ifp(struct interface *ifp, + struct ospf_area *area, + enum oifstate oifstate) { - struct ospf_interface *oi = NULL; - struct route_node *rn; + struct ospf_interface *oi = NULL; + struct route_node *rn; - for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn)) - { - if ((oi = rn->info) == NULL) - continue; + for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) { + if ((oi = rn->info) == NULL) + continue; - switch (oifstate) - { - case OI_ANY: - break; - case OI_DOWN: - if (ospf_if_is_enable (oi)) - continue; - break; - case OI_UP: - if (! ospf_if_is_enable (oi)) - continue; - break; - default: - zlog_warn ("lookup_oi_by_ifp: Unknown oifstate: %x", oifstate); - goto out; - } + switch (oifstate) { + case OI_ANY: + break; + case OI_DOWN: + if (ospf_if_is_enable(oi)) + continue; + break; + case OI_UP: + if (!ospf_if_is_enable(oi)) + continue; + break; + default: + zlog_warn("lookup_oi_by_ifp: Unknown oifstate: %x", + oifstate); + goto out; + } - if (area == NULL || oi->area == area) - return oi; - } + if (area == NULL || oi->area == area) + return oi; + } out: - return NULL; + return NULL; } -static struct mpls_te_link * -lookup_linkparams_by_ifp (struct interface *ifp) +static struct mpls_te_link *lookup_linkparams_by_ifp(struct interface *ifp) { - struct listnode *node, *nnode; - struct mpls_te_link *lp; + struct listnode *node, *nnode; + struct mpls_te_link *lp; - for (ALL_LIST_ELEMENTS (OspfMplsTE.iflist, node, nnode, lp)) - if (lp->ifp == ifp) - return lp; + for (ALL_LIST_ELEMENTS(OspfMplsTE.iflist, node, nnode, lp)) + if (lp->ifp == ifp) + return lp; - return NULL; + return NULL; } -static struct mpls_te_link * -lookup_linkparams_by_instance (struct ospf_lsa *lsa) +static struct mpls_te_link *lookup_linkparams_by_instance(struct ospf_lsa *lsa) { - struct listnode *node; - struct mpls_te_link *lp; - unsigned int key = GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr)); + struct listnode *node; + struct mpls_te_link *lp; + unsigned int key = GET_OPAQUE_ID(ntohl(lsa->data->id.s_addr)); - for (ALL_LIST_ELEMENTS_RO (OspfMplsTE.iflist, node, lp)) - if (lp->instance == key) - return lp; + for (ALL_LIST_ELEMENTS_RO(OspfMplsTE.iflist, node, lp)) + if (lp->instance == key) + return lp; - zlog_warn ("lookup_linkparams_by_instance: Entry not found: key(%x)", key); - return NULL; + zlog_warn("lookup_linkparams_by_instance: Entry not found: key(%x)", + key); + return NULL; } -static void -ospf_mpls_te_foreach_area (void (*func) - (struct mpls_te_link * lp, opcode_t sched_opcode), - opcode_t sched_opcode) +static void ospf_mpls_te_foreach_area(void (*func)(struct mpls_te_link *lp, + opcode_t sched_opcode), + opcode_t sched_opcode) { - struct listnode *node, *nnode; - struct listnode *node2; - struct mpls_te_link *lp; - struct ospf_area *area; + struct listnode *node, *nnode; + struct listnode *node2; + struct mpls_te_link *lp; + struct ospf_area *area; - for (ALL_LIST_ELEMENTS (OspfMplsTE.iflist, node, nnode, lp)) - { - /* Skip Inter-AS TEv2 Links */ - if (IS_INTER_AS (lp->type)) - continue; - if ((area = lp->area) == NULL) - continue; - if CHECK_FLAG (lp->flags, LPFLG_LOOKUP_DONE) continue; + for (ALL_LIST_ELEMENTS(OspfMplsTE.iflist, node, nnode, lp)) { + /* Skip Inter-AS TEv2 Links */ + if (IS_INTER_AS(lp->type)) + continue; + if ((area = lp->area) == NULL) + continue; + if + CHECK_FLAG(lp->flags, LPFLG_LOOKUP_DONE) continue; - if (func != NULL) - (* func)(lp, sched_opcode); + if (func != NULL) + (*func)(lp, sched_opcode); - for (node2 = listnextnode (node); node2; node2 = listnextnode (node2)) - if ((lp = listgetdata (node2)) != NULL) - if (lp->area != NULL) - if (IPV4_ADDR_SAME (&lp->area->area_id, &area->area_id)) - SET_FLAG (lp->flags, LPFLG_LOOKUP_DONE); - } + for (node2 = listnextnode(node); node2; + node2 = listnextnode(node2)) + if ((lp = listgetdata(node2)) != NULL) + if (lp->area != NULL) + if (IPV4_ADDR_SAME(&lp->area->area_id, + &area->area_id)) + SET_FLAG(lp->flags, + LPFLG_LOOKUP_DONE); + } - for (ALL_LIST_ELEMENTS_RO (OspfMplsTE.iflist, node, lp)) - if (lp->area != NULL) - UNSET_FLAG (lp->flags, LPFLG_LOOKUP_DONE); + for (ALL_LIST_ELEMENTS_RO(OspfMplsTE.iflist, node, lp)) + if (lp->area != NULL) + UNSET_FLAG(lp->flags, LPFLG_LOOKUP_DONE); - return; + return; } -static void -set_mpls_te_router_addr (struct in_addr ipv4) +static void set_mpls_te_router_addr(struct in_addr ipv4) { - OspfMplsTE.router_addr.header.type = htons (TE_TLV_ROUTER_ADDR); - OspfMplsTE.router_addr.header.length = htons (TE_LINK_SUBTLV_DEF_SIZE); - OspfMplsTE.router_addr.value = ipv4; - return; + OspfMplsTE.router_addr.header.type = htons(TE_TLV_ROUTER_ADDR); + OspfMplsTE.router_addr.header.length = htons(TE_LINK_SUBTLV_DEF_SIZE); + OspfMplsTE.router_addr.value = ipv4; + return; } -static void -set_linkparams_link_header (struct mpls_te_link *lp) +static void set_linkparams_link_header(struct mpls_te_link *lp) { - u_int16_t length = 0; + u_int16_t length = 0; - /* TE_LINK_SUBTLV_LINK_TYPE */ - if (ntohs (lp->link_type.header.type) != 0) - length += TLV_SIZE (&lp->link_type.header); + /* TE_LINK_SUBTLV_LINK_TYPE */ + if (ntohs(lp->link_type.header.type) != 0) + length += TLV_SIZE(&lp->link_type.header); - /* TE_LINK_SUBTLV_LINK_ID */ - if (ntohs (lp->link_id.header.type) != 0) - length += TLV_SIZE (&lp->link_id.header); + /* TE_LINK_SUBTLV_LINK_ID */ + if (ntohs(lp->link_id.header.type) != 0) + length += TLV_SIZE(&lp->link_id.header); - /* TE_LINK_SUBTLV_LCLIF_IPADDR */ - if (lp->lclif_ipaddr.header.type != 0) - length += TLV_SIZE (&lp->lclif_ipaddr.header); + /* TE_LINK_SUBTLV_LCLIF_IPADDR */ + if (lp->lclif_ipaddr.header.type != 0) + length += TLV_SIZE(&lp->lclif_ipaddr.header); - /* TE_LINK_SUBTLV_RMTIF_IPADDR */ - if (lp->rmtif_ipaddr.header.type != 0) - length += TLV_SIZE (&lp->rmtif_ipaddr.header); + /* TE_LINK_SUBTLV_RMTIF_IPADDR */ + if (lp->rmtif_ipaddr.header.type != 0) + length += TLV_SIZE(&lp->rmtif_ipaddr.header); - /* TE_LINK_SUBTLV_TE_METRIC */ - if (ntohs (lp->te_metric.header.type) != 0) - length += TLV_SIZE (&lp->te_metric.header); + /* TE_LINK_SUBTLV_TE_METRIC */ + if (ntohs(lp->te_metric.header.type) != 0) + length += TLV_SIZE(&lp->te_metric.header); - /* TE_LINK_SUBTLV_MAX_BW */ - if (ntohs (lp->max_bw.header.type) != 0) - length += TLV_SIZE (&lp->max_bw.header); + /* TE_LINK_SUBTLV_MAX_BW */ + if (ntohs(lp->max_bw.header.type) != 0) + length += TLV_SIZE(&lp->max_bw.header); - /* TE_LINK_SUBTLV_MAX_RSV_BW */ - if (ntohs (lp->max_rsv_bw.header.type) != 0) - length += TLV_SIZE (&lp->max_rsv_bw.header); + /* TE_LINK_SUBTLV_MAX_RSV_BW */ + if (ntohs(lp->max_rsv_bw.header.type) != 0) + length += TLV_SIZE(&lp->max_rsv_bw.header); - /* TE_LINK_SUBTLV_UNRSV_BW */ - if (ntohs (lp->unrsv_bw.header.type) != 0) - length += TLV_SIZE (&lp->unrsv_bw.header); + /* TE_LINK_SUBTLV_UNRSV_BW */ + if (ntohs(lp->unrsv_bw.header.type) != 0) + length += TLV_SIZE(&lp->unrsv_bw.header); - /* TE_LINK_SUBTLV_RSC_CLSCLR */ - if (ntohs (lp->rsc_clsclr.header.type) != 0) - length += TLV_SIZE (&lp->rsc_clsclr.header); - - /* TE_LINK_SUBTLV_LLRI */ - if (ntohs (lp->llri.header.type) != 0) - length += TLV_SIZE (&lp->llri.header); - - /* TE_LINK_SUBTLV_RIP */ - if (ntohs (lp->rip.header.type) != 0) - length += TLV_SIZE (&lp->rip.header); - - /* TE_LINK_SUBTLV_RAS */ - if (ntohs (lp->ras.header.type) != 0) - length += TLV_SIZE (&lp->ras.header); - - /* TE_LINK_SUBTLV_LRRID */ - if (ntohs (lp->lrrid.header.type) != 0) - length += TLV_SIZE (&lp->lrrid.header); - - /* TE_LINK_SUBTLV_AV_DELAY */ - if (ntohs (lp->av_delay.header.type) != 0) - length += TLV_SIZE (&lp->av_delay.header); - - /* TE_LINK_SUBTLV_MM_DELAY */ - if (ntohs (lp->mm_delay.header.type) != 0) - length += TLV_SIZE (&lp->mm_delay.header); - - /* TE_LINK_SUBTLV_DELAY_VAR */ - if (ntohs (lp->delay_var.header.type) != 0) - length += TLV_SIZE (&lp->delay_var.header); - - /* TE_LINK_SUBTLV_PKT_LOSS */ - if (ntohs (lp->pkt_loss.header.type) != 0) - length += TLV_SIZE (&lp->pkt_loss.header); - - /* TE_LINK_SUBTLV_RES_BW */ - if (ntohs (lp->res_bw.header.type) != 0) - length += TLV_SIZE (&lp->res_bw.header); - - /* TE_LINK_SUBTLV_AVA_BW */ - if (ntohs (lp->ava_bw.header.type) != 0) - length += TLV_SIZE (&lp->ava_bw.header); - - /* TE_LINK_SUBTLV_USE_BW */ - if (ntohs (lp->use_bw.header.type) != 0) - length += TLV_SIZE (&lp->use_bw.header); - - lp->link_header.header.type = htons (TE_TLV_LINK); - lp->link_header.header.length = htons (length); + /* TE_LINK_SUBTLV_RSC_CLSCLR */ + if (ntohs(lp->rsc_clsclr.header.type) != 0) + length += TLV_SIZE(&lp->rsc_clsclr.header); + + /* TE_LINK_SUBTLV_LLRI */ + if (ntohs(lp->llri.header.type) != 0) + length += TLV_SIZE(&lp->llri.header); + + /* TE_LINK_SUBTLV_RIP */ + if (ntohs(lp->rip.header.type) != 0) + length += TLV_SIZE(&lp->rip.header); + + /* TE_LINK_SUBTLV_RAS */ + if (ntohs(lp->ras.header.type) != 0) + length += TLV_SIZE(&lp->ras.header); + + /* TE_LINK_SUBTLV_LRRID */ + if (ntohs(lp->lrrid.header.type) != 0) + length += TLV_SIZE(&lp->lrrid.header); + + /* TE_LINK_SUBTLV_AV_DELAY */ + if (ntohs(lp->av_delay.header.type) != 0) + length += TLV_SIZE(&lp->av_delay.header); + + /* TE_LINK_SUBTLV_MM_DELAY */ + if (ntohs(lp->mm_delay.header.type) != 0) + length += TLV_SIZE(&lp->mm_delay.header); + + /* TE_LINK_SUBTLV_DELAY_VAR */ + if (ntohs(lp->delay_var.header.type) != 0) + length += TLV_SIZE(&lp->delay_var.header); + + /* TE_LINK_SUBTLV_PKT_LOSS */ + if (ntohs(lp->pkt_loss.header.type) != 0) + length += TLV_SIZE(&lp->pkt_loss.header); + + /* TE_LINK_SUBTLV_RES_BW */ + if (ntohs(lp->res_bw.header.type) != 0) + length += TLV_SIZE(&lp->res_bw.header); + + /* TE_LINK_SUBTLV_AVA_BW */ + if (ntohs(lp->ava_bw.header.type) != 0) + length += TLV_SIZE(&lp->ava_bw.header); + + /* TE_LINK_SUBTLV_USE_BW */ + if (ntohs(lp->use_bw.header.type) != 0) + length += TLV_SIZE(&lp->use_bw.header); - return; + lp->link_header.header.type = htons(TE_TLV_LINK); + lp->link_header.header.length = htons(length); + + return; } - -static void -set_linkparams_link_type (struct ospf_interface *oi, struct mpls_te_link *lp) -{ - lp->link_type.header.type = htons (TE_LINK_SUBTLV_LINK_TYPE); - lp->link_type.header.length = htons (TE_LINK_SUBTLV_TYPE_SIZE); - - switch (oi->type) - { - case OSPF_IFTYPE_POINTOPOINT: - lp->link_type.link_type.value = LINK_TYPE_SUBTLV_VALUE_PTP; - break; - case OSPF_IFTYPE_BROADCAST: - case OSPF_IFTYPE_NBMA: - lp->link_type.link_type.value = LINK_TYPE_SUBTLV_VALUE_MA; - break; - default: - /* Not supported yet. *//* XXX */ - lp->link_type.header.type = htons (0); - break; - } - return; + +static void set_linkparams_link_type(struct ospf_interface *oi, + struct mpls_te_link *lp) +{ + lp->link_type.header.type = htons(TE_LINK_SUBTLV_LINK_TYPE); + lp->link_type.header.length = htons(TE_LINK_SUBTLV_TYPE_SIZE); + + switch (oi->type) { + case OSPF_IFTYPE_POINTOPOINT: + lp->link_type.link_type.value = LINK_TYPE_SUBTLV_VALUE_PTP; + break; + case OSPF_IFTYPE_BROADCAST: + case OSPF_IFTYPE_NBMA: + lp->link_type.link_type.value = LINK_TYPE_SUBTLV_VALUE_MA; + break; + default: + /* Not supported yet. */ /* XXX */ + lp->link_type.header.type = htons(0); + break; + } + return; } - -static void -set_linkparams_link_id (struct ospf_interface *oi, struct mpls_te_link *lp) + +static void set_linkparams_link_id(struct ospf_interface *oi, + struct mpls_te_link *lp) { - struct ospf_neighbor *nbr; - int done = 0; - - lp->link_id.header.type = htons (TE_LINK_SUBTLV_LINK_ID); - lp->link_id.header.length = htons (TE_LINK_SUBTLV_DEF_SIZE); + struct ospf_neighbor *nbr; + int done = 0; - /* - * The Link ID is identical to the contents of the Link ID field - * in the Router LSA for these link types. - */ - switch (oi->type) - { - case OSPF_IFTYPE_POINTOPOINT: - /* Take the router ID of the neighbor. */ - if ((nbr = ospf_nbr_lookup_ptop (oi)) && nbr->state == NSM_Full) - { - lp->link_id.value = nbr->router_id; - done = 1; - } - break; - case OSPF_IFTYPE_BROADCAST: - case OSPF_IFTYPE_NBMA: - /* Take the interface address of the designated router. */ - if ((nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi))) == NULL) - break; + lp->link_id.header.type = htons(TE_LINK_SUBTLV_LINK_ID); + lp->link_id.header.length = htons(TE_LINK_SUBTLV_DEF_SIZE); - if (nbr->state == NSM_Full - || (IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi)) - && ospf_nbr_count (oi, NSM_Full) > 0)) - { - lp->link_id.value = DR (oi); - done = 1; - } - break; - default: - /* Not supported yet. *//* XXX */ - lp->link_id.header.type = htons (0); - break; - } + /* + * The Link ID is identical to the contents of the Link ID field + * in the Router LSA for these link types. + */ + switch (oi->type) { + case OSPF_IFTYPE_POINTOPOINT: + /* Take the router ID of the neighbor. */ + if ((nbr = ospf_nbr_lookup_ptop(oi)) + && nbr->state == NSM_Full) { + lp->link_id.value = nbr->router_id; + done = 1; + } + break; + case OSPF_IFTYPE_BROADCAST: + case OSPF_IFTYPE_NBMA: + /* Take the interface address of the designated router. */ + if ((nbr = ospf_nbr_lookup_by_addr(oi->nbrs, &DR(oi))) == NULL) + break; - if (! done) - { - struct in_addr mask; - masklen2ip (oi->address->prefixlen, &mask); - lp->link_id.value.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr; - } - return; + if (nbr->state == NSM_Full + || (IPV4_ADDR_SAME(&oi->address->u.prefix4, &DR(oi)) + && ospf_nbr_count(oi, NSM_Full) > 0)) { + lp->link_id.value = DR(oi); + done = 1; + } + break; + default: + /* Not supported yet. */ /* XXX */ + lp->link_id.header.type = htons(0); + break; + } + + if (!done) { + struct in_addr mask; + masklen2ip(oi->address->prefixlen, &mask); + lp->link_id.value.s_addr = + oi->address->u.prefix4.s_addr & mask.s_addr; + } + return; } -static void -set_linkparams_lclif_ipaddr (struct mpls_te_link *lp, struct in_addr lclif) +static void set_linkparams_lclif_ipaddr(struct mpls_te_link *lp, + struct in_addr lclif) { - lp->lclif_ipaddr.header.type = htons (TE_LINK_SUBTLV_LCLIF_IPADDR); - lp->lclif_ipaddr.header.length = htons (TE_LINK_SUBTLV_DEF_SIZE); - lp->lclif_ipaddr.value[0] = lclif; - return; + lp->lclif_ipaddr.header.type = htons(TE_LINK_SUBTLV_LCLIF_IPADDR); + lp->lclif_ipaddr.header.length = htons(TE_LINK_SUBTLV_DEF_SIZE); + lp->lclif_ipaddr.value[0] = lclif; + return; } -static void -set_linkparams_rmtif_ipaddr (struct mpls_te_link *lp, struct in_addr rmtif) +static void set_linkparams_rmtif_ipaddr(struct mpls_te_link *lp, + struct in_addr rmtif) { - lp->rmtif_ipaddr.header.type = htons (TE_LINK_SUBTLV_RMTIF_IPADDR); - lp->rmtif_ipaddr.header.length = htons (TE_LINK_SUBTLV_DEF_SIZE); - lp->rmtif_ipaddr.value[0] = rmtif; - return; + lp->rmtif_ipaddr.header.type = htons(TE_LINK_SUBTLV_RMTIF_IPADDR); + lp->rmtif_ipaddr.header.length = htons(TE_LINK_SUBTLV_DEF_SIZE); + lp->rmtif_ipaddr.value[0] = rmtif; + return; } -static void -set_linkparams_te_metric (struct mpls_te_link *lp, u_int32_t te_metric) +static void set_linkparams_te_metric(struct mpls_te_link *lp, + u_int32_t te_metric) { - lp->te_metric.header.type = htons (TE_LINK_SUBTLV_TE_METRIC); - lp->te_metric.header.length = htons (TE_LINK_SUBTLV_DEF_SIZE); - lp->te_metric.value = htonl (te_metric); - return; + lp->te_metric.header.type = htons(TE_LINK_SUBTLV_TE_METRIC); + lp->te_metric.header.length = htons(TE_LINK_SUBTLV_DEF_SIZE); + lp->te_metric.value = htonl(te_metric); + return; } -static void -set_linkparams_max_bw (struct mpls_te_link *lp, float fp) +static void set_linkparams_max_bw(struct mpls_te_link *lp, float fp) { - lp->max_bw.header.type = htons (TE_LINK_SUBTLV_MAX_BW); - lp->max_bw.header.length = htons (TE_LINK_SUBTLV_DEF_SIZE); - lp->max_bw.value = htonf (fp); - return; + lp->max_bw.header.type = htons(TE_LINK_SUBTLV_MAX_BW); + lp->max_bw.header.length = htons(TE_LINK_SUBTLV_DEF_SIZE); + lp->max_bw.value = htonf(fp); + return; } -static void -set_linkparams_max_rsv_bw (struct mpls_te_link *lp, float fp) +static void set_linkparams_max_rsv_bw(struct mpls_te_link *lp, float fp) { - lp->max_rsv_bw.header.type = htons (TE_LINK_SUBTLV_MAX_RSV_BW); - lp->max_rsv_bw.header.length = htons (TE_LINK_SUBTLV_DEF_SIZE); - lp->max_rsv_bw.value = htonf (fp); - return; + lp->max_rsv_bw.header.type = htons(TE_LINK_SUBTLV_MAX_RSV_BW); + lp->max_rsv_bw.header.length = htons(TE_LINK_SUBTLV_DEF_SIZE); + lp->max_rsv_bw.value = htonf(fp); + return; } -static void -set_linkparams_unrsv_bw (struct mpls_te_link *lp, int priority, float fp) +static void set_linkparams_unrsv_bw(struct mpls_te_link *lp, int priority, + float fp) { - /* Note that TLV-length field is the size of array. */ - lp->unrsv_bw.header.type = htons (TE_LINK_SUBTLV_UNRSV_BW); - lp->unrsv_bw.header.length = htons (TE_LINK_SUBTLV_UNRSV_SIZE); - lp->unrsv_bw.value [priority] = htonf (fp); - return; + /* Note that TLV-length field is the size of array. */ + lp->unrsv_bw.header.type = htons(TE_LINK_SUBTLV_UNRSV_BW); + lp->unrsv_bw.header.length = htons(TE_LINK_SUBTLV_UNRSV_SIZE); + lp->unrsv_bw.value[priority] = htonf(fp); + return; } -static void -set_linkparams_rsc_clsclr (struct mpls_te_link *lp, u_int32_t classcolor) +static void set_linkparams_rsc_clsclr(struct mpls_te_link *lp, + u_int32_t classcolor) { - lp->rsc_clsclr.header.type = htons (TE_LINK_SUBTLV_RSC_CLSCLR); - lp->rsc_clsclr.header.length = htons (TE_LINK_SUBTLV_DEF_SIZE); - lp->rsc_clsclr.value = htonl (classcolor); - return; + lp->rsc_clsclr.header.type = htons(TE_LINK_SUBTLV_RSC_CLSCLR); + lp->rsc_clsclr.header.length = htons(TE_LINK_SUBTLV_DEF_SIZE); + lp->rsc_clsclr.value = htonl(classcolor); + return; } -static void -set_linkparams_inter_as (struct mpls_te_link *lp, struct in_addr addr, - u_int32_t as) +static void set_linkparams_inter_as(struct mpls_te_link *lp, + struct in_addr addr, u_int32_t as) { - /* Set the Remote ASBR IP address and then the associated AS number */ - lp->rip.header.type = htons (TE_LINK_SUBTLV_RIP); - lp->rip.header.length = htons (TE_LINK_SUBTLV_DEF_SIZE); - lp->rip.value = addr; + /* Set the Remote ASBR IP address and then the associated AS number */ + lp->rip.header.type = htons(TE_LINK_SUBTLV_RIP); + lp->rip.header.length = htons(TE_LINK_SUBTLV_DEF_SIZE); + lp->rip.value = addr; - lp->ras.header.type = htons (TE_LINK_SUBTLV_RAS); - lp->ras.header.length = htons (TE_LINK_SUBTLV_DEF_SIZE); - lp->ras.value = htonl (as); + lp->ras.header.type = htons(TE_LINK_SUBTLV_RAS); + lp->ras.header.length = htons(TE_LINK_SUBTLV_DEF_SIZE); + lp->ras.value = htonl(as); } -static void -unset_linkparams_inter_as (struct mpls_te_link *lp) +static void unset_linkparams_inter_as(struct mpls_te_link *lp) { - /* Reset the Remote ASBR IP address and then the associated AS number */ - lp->rip.header.type = htons (0); - lp->rip.header.length = htons (0); - lp->rip.value.s_addr = htonl (0); + /* Reset the Remote ASBR IP address and then the associated AS number */ + lp->rip.header.type = htons(0); + lp->rip.header.length = htons(0); + lp->rip.value.s_addr = htonl(0); - lp->ras.header.type = htons (0); - lp->ras.header.length = htons (0); - lp->ras.value = htonl (0); + lp->ras.header.type = htons(0); + lp->ras.header.length = htons(0); + lp->ras.value = htonl(0); } -void -set_linkparams_llri (struct mpls_te_link *lp, u_int32_t local, - u_int32_t remote) +void set_linkparams_llri(struct mpls_te_link *lp, u_int32_t local, + u_int32_t remote) { - lp->llri.header.type = htons (TE_LINK_SUBTLV_LLRI); - lp->llri.header.length = htons (TE_LINK_SUBTLV_LLRI_SIZE); - lp->llri.local = htonl (local); - lp->llri.remote = htonl (remote); + lp->llri.header.type = htons(TE_LINK_SUBTLV_LLRI); + lp->llri.header.length = htons(TE_LINK_SUBTLV_LLRI_SIZE); + lp->llri.local = htonl(local); + lp->llri.remote = htonl(remote); } -void -set_linkparams_lrrid (struct mpls_te_link *lp, struct in_addr local, - struct in_addr remote) +void set_linkparams_lrrid(struct mpls_te_link *lp, struct in_addr local, + struct in_addr remote) { - lp->lrrid.header.type = htons (TE_LINK_SUBTLV_LRRID); - lp->lrrid.header.length = htons (TE_LINK_SUBTLV_LRRID_SIZE); - lp->lrrid.local.s_addr = local.s_addr; - lp->lrrid.remote.s_addr = remote.s_addr; + lp->lrrid.header.type = htons(TE_LINK_SUBTLV_LRRID); + lp->lrrid.header.length = htons(TE_LINK_SUBTLV_LRRID_SIZE); + lp->lrrid.local.s_addr = local.s_addr; + lp->lrrid.remote.s_addr = remote.s_addr; } -static void -set_linkparams_av_delay (struct mpls_te_link *lp, u_int32_t delay, u_char anormal) +static void set_linkparams_av_delay(struct mpls_te_link *lp, u_int32_t delay, + u_char anormal) { - u_int32_t tmp; - /* Note that TLV-length field is the size of array. */ - lp->av_delay.header.type = htons (TE_LINK_SUBTLV_AV_DELAY); - lp->av_delay.header.length = htons (TE_LINK_SUBTLV_DEF_SIZE); - tmp = delay & TE_EXT_MASK; - if (anormal) - tmp |= TE_EXT_ANORMAL; - lp->av_delay.value = htonl (tmp); - return; + u_int32_t tmp; + /* Note that TLV-length field is the size of array. */ + lp->av_delay.header.type = htons(TE_LINK_SUBTLV_AV_DELAY); + lp->av_delay.header.length = htons(TE_LINK_SUBTLV_DEF_SIZE); + tmp = delay & TE_EXT_MASK; + if (anormal) + tmp |= TE_EXT_ANORMAL; + lp->av_delay.value = htonl(tmp); + return; } -static void -set_linkparams_mm_delay (struct mpls_te_link *lp, u_int32_t low, u_int32_t high, u_char anormal) +static void set_linkparams_mm_delay(struct mpls_te_link *lp, u_int32_t low, + u_int32_t high, u_char anormal) { - u_int32_t tmp; - /* Note that TLV-length field is the size of array. */ - lp->mm_delay.header.type = htons (TE_LINK_SUBTLV_MM_DELAY); - lp->mm_delay.header.length = htons (TE_LINK_SUBTLV_MM_DELAY_SIZE); - tmp = low & TE_EXT_MASK; - if (anormal) - tmp |= TE_EXT_ANORMAL; - lp->mm_delay.low = htonl (tmp); - lp->mm_delay.high = htonl (high); - return; + u_int32_t tmp; + /* Note that TLV-length field is the size of array. */ + lp->mm_delay.header.type = htons(TE_LINK_SUBTLV_MM_DELAY); + lp->mm_delay.header.length = htons(TE_LINK_SUBTLV_MM_DELAY_SIZE); + tmp = low & TE_EXT_MASK; + if (anormal) + tmp |= TE_EXT_ANORMAL; + lp->mm_delay.low = htonl(tmp); + lp->mm_delay.high = htonl(high); + return; } -static void -set_linkparams_delay_var (struct mpls_te_link *lp, u_int32_t jitter) +static void set_linkparams_delay_var(struct mpls_te_link *lp, u_int32_t jitter) { - /* Note that TLV-length field is the size of array. */ - lp->delay_var.header.type = htons (TE_LINK_SUBTLV_DELAY_VAR); - lp->delay_var.header.length = htons (TE_LINK_SUBTLV_DEF_SIZE); - lp->delay_var.value = htonl (jitter & TE_EXT_MASK); - return; + /* Note that TLV-length field is the size of array. */ + lp->delay_var.header.type = htons(TE_LINK_SUBTLV_DELAY_VAR); + lp->delay_var.header.length = htons(TE_LINK_SUBTLV_DEF_SIZE); + lp->delay_var.value = htonl(jitter & TE_EXT_MASK); + return; } -static void -set_linkparams_pkt_loss (struct mpls_te_link *lp, u_int32_t loss, u_char anormal) +static void set_linkparams_pkt_loss(struct mpls_te_link *lp, u_int32_t loss, + u_char anormal) { - u_int32_t tmp; - /* Note that TLV-length field is the size of array. */ - lp->pkt_loss.header.type = htons (TE_LINK_SUBTLV_PKT_LOSS); - lp->pkt_loss.header.length = htons (TE_LINK_SUBTLV_DEF_SIZE); - tmp = loss & TE_EXT_MASK; - if (anormal) - tmp |= TE_EXT_ANORMAL; - lp->pkt_loss.value = htonl (tmp); - return; + u_int32_t tmp; + /* Note that TLV-length field is the size of array. */ + lp->pkt_loss.header.type = htons(TE_LINK_SUBTLV_PKT_LOSS); + lp->pkt_loss.header.length = htons(TE_LINK_SUBTLV_DEF_SIZE); + tmp = loss & TE_EXT_MASK; + if (anormal) + tmp |= TE_EXT_ANORMAL; + lp->pkt_loss.value = htonl(tmp); + return; } -static void -set_linkparams_res_bw (struct mpls_te_link *lp, float fp) +static void set_linkparams_res_bw(struct mpls_te_link *lp, float fp) { - /* Note that TLV-length field is the size of array. */ - lp->res_bw.header.type = htons (TE_LINK_SUBTLV_RES_BW); - lp->res_bw.header.length = htons (TE_LINK_SUBTLV_DEF_SIZE); - lp->res_bw.value = htonf (fp); - return; + /* Note that TLV-length field is the size of array. */ + lp->res_bw.header.type = htons(TE_LINK_SUBTLV_RES_BW); + lp->res_bw.header.length = htons(TE_LINK_SUBTLV_DEF_SIZE); + lp->res_bw.value = htonf(fp); + return; } -static void -set_linkparams_ava_bw (struct mpls_te_link *lp, float fp) +static void set_linkparams_ava_bw(struct mpls_te_link *lp, float fp) { - /* Note that TLV-length field is the size of array. */ - lp->ava_bw.header.type = htons (TE_LINK_SUBTLV_AVA_BW); - lp->ava_bw.header.length = htons (TE_LINK_SUBTLV_DEF_SIZE); - lp->ava_bw.value = htonf (fp); - return; + /* Note that TLV-length field is the size of array. */ + lp->ava_bw.header.type = htons(TE_LINK_SUBTLV_AVA_BW); + lp->ava_bw.header.length = htons(TE_LINK_SUBTLV_DEF_SIZE); + lp->ava_bw.value = htonf(fp); + return; } -static void -set_linkparams_use_bw (struct mpls_te_link *lp, float fp) +static void set_linkparams_use_bw(struct mpls_te_link *lp, float fp) { - /* Note that TLV-length field is the size of array. */ - lp->use_bw.header.type = htons (TE_LINK_SUBTLV_USE_BW); - lp->use_bw.header.length = htons (TE_LINK_SUBTLV_DEF_SIZE); - lp->use_bw.value = htonf (fp); - return; + /* Note that TLV-length field is the size of array. */ + lp->use_bw.header.type = htons(TE_LINK_SUBTLV_USE_BW); + lp->use_bw.header.length = htons(TE_LINK_SUBTLV_DEF_SIZE); + lp->use_bw.value = htonf(fp); + return; } /* Update TE parameters from Interface */ -static void -update_linkparams(struct mpls_te_link *lp) -{ - int i; - struct interface *ifp; - - /* Get the Interface structure */ - if ((ifp = lp->ifp) == NULL) - { - if (IS_DEBUG_OSPF_TE) - zlog_debug("OSPF MPLS-TE: Abort update TE parameters: no interface associated to Link Parameters"); - return; - } - if (!HAS_LINK_PARAMS(ifp)) - { - if (IS_DEBUG_OSPF_TE) - zlog_debug("OSPF MPLS-TE: Abort update TE parameters: no Link Parameters for interface"); - return; - } - - /* RFC3630 metrics */ - if (IS_PARAM_SET(ifp->link_params, LP_ADM_GRP)) - set_linkparams_rsc_clsclr (lp, ifp->link_params->admin_grp); - else - TLV_TYPE(lp->rsc_clsclr) = 0; - - if (IS_PARAM_SET(ifp->link_params, LP_MAX_BW)) - set_linkparams_max_bw (lp, ifp->link_params->max_bw); - else - TLV_TYPE(lp->max_bw) = 0; - - if (IS_PARAM_SET(ifp->link_params, LP_MAX_RSV_BW)) - set_linkparams_max_rsv_bw (lp, ifp->link_params->max_rsv_bw); - else - TLV_TYPE(lp->max_rsv_bw) = 0; - - if (IS_PARAM_SET(ifp->link_params, LP_UNRSV_BW)) - for (i = 0; i < MAX_CLASS_TYPE; i++) - set_linkparams_unrsv_bw (lp, i, ifp->link_params->unrsv_bw[i]); - else - TLV_TYPE(lp->unrsv_bw) = 0; - - if (IS_PARAM_SET(ifp->link_params, LP_TE_METRIC)) - set_linkparams_te_metric(lp, ifp->link_params->te_metric); - else - TLV_TYPE(lp->te_metric) = 0; - - /* TE metric Extensions */ - if (IS_PARAM_SET(ifp->link_params, LP_DELAY)) - set_linkparams_av_delay(lp, ifp->link_params->av_delay, 0); - else - TLV_TYPE(lp->av_delay) = 0; - - if (IS_PARAM_SET(ifp->link_params, LP_MM_DELAY)) - set_linkparams_mm_delay(lp, ifp->link_params->min_delay, ifp->link_params->max_delay, 0); - else - TLV_TYPE(lp->mm_delay) = 0; - - if (IS_PARAM_SET(ifp->link_params, LP_DELAY_VAR)) - set_linkparams_delay_var(lp, ifp->link_params->delay_var); - else - TLV_TYPE(lp->delay_var) = 0; - - if (IS_PARAM_SET(ifp->link_params, LP_PKT_LOSS)) - set_linkparams_pkt_loss(lp, ifp->link_params->pkt_loss, 0); - else - TLV_TYPE(lp->pkt_loss) = 0; - - if (IS_PARAM_SET(ifp->link_params, LP_RES_BW)) - set_linkparams_res_bw(lp, ifp->link_params->res_bw); - else - TLV_TYPE(lp->res_bw) = 0; - - if (IS_PARAM_SET(ifp->link_params, LP_AVA_BW)) - set_linkparams_ava_bw(lp, ifp->link_params->ava_bw); - else - TLV_TYPE(lp->ava_bw) = 0; - - if (IS_PARAM_SET(ifp->link_params, LP_USE_BW)) - set_linkparams_use_bw(lp, ifp->link_params->use_bw); - else - TLV_TYPE(lp->use_bw) = 0; - - /* RFC5392 */ - if (IS_PARAM_SET(ifp->link_params, LP_RMT_AS)) - { - /* Flush LSA if it engaged and was previously a STD_TE one */ - if (IS_STD_TE(lp->type) && CHECK_FLAG (lp->flags, LPFLG_LSA_ENGAGED)) - { - if (IS_DEBUG_OSPF_TE) - zlog_debug("OSPF MPLS-TE Update IF: Switch from Standard LSA to INTER-AS for %s[%d/%d]", - ifp->name, lp->flags, lp->type); - - ospf_mpls_te_lsa_schedule (lp, FLUSH_THIS_LSA); - /* Then, switch it to INTER-AS */ - if (OspfMplsTE.inter_as == AS) - lp->flags = INTER_AS | FLOOD_AS; - else - { - lp->flags = INTER_AS | FLOOD_AREA; - lp->area = ospf_area_lookup_by_area_id (ospf_lookup(), OspfMplsTE.interas_areaid); - } - } - set_linkparams_inter_as(lp, ifp->link_params->rmt_ip, ifp->link_params->rmt_as); - } - else - { - if (IS_DEBUG_OSPF_TE) - zlog_debug("OSPF MPLS-TE Update IF: Switch from INTER-AS LSA to Standard for %s[%d/%d]", - ifp->name, lp->flags, lp->type); - - /* reset inter-as TE params */ - /* Flush LSA if it engaged and was previously an INTER_AS one */ - if (IS_INTER_AS(lp->type) && CHECK_FLAG (lp->flags, LPFLG_LSA_ENGAGED)) - { - ospf_mpls_te_lsa_schedule (lp, FLUSH_THIS_LSA); - /* Then, switch it to Standard TE */ - lp->flags = STD_TE | FLOOD_AREA; - } - unset_linkparams_inter_as (lp); - } -} - -static void -initialize_linkparams (struct mpls_te_link *lp) -{ - struct interface *ifp = lp->ifp; - struct ospf_interface *oi; - - if (IS_DEBUG_OSPF_TE) - zlog_debug("MPLS-TE(initialize_linkparams) Initialize Link Parameters for interface %s", - ifp->name); - - if ((oi = lookup_oi_by_ifp (ifp, NULL, OI_ANY)) == NULL) - { - if (IS_DEBUG_OSPF_TE) - zlog_warn("MPLS-TE(initialize_linkparams) Could not find corresponding OSPF Interface for %s", - ifp->name); - return; - } - - /* - * Try to set initial values those can be derived from - * zebra-interface information. - */ - set_linkparams_link_type (oi, lp); - - /* Set local IP addr */ - set_linkparams_lclif_ipaddr (lp, oi->address->u.prefix4); - - /* Set Remote IP addr if Point to Point Interface */ - if (oi->type == LINK_TYPE_SUBTLV_VALUE_PTP) - { - struct prefix *pref = CONNECTED_PREFIX(oi->connected); - if (pref != NULL) - set_linkparams_rmtif_ipaddr(lp, pref->u.prefix4); - } - - /* Keep Area information in combination with link parameters. */ - lp->area = oi->area; - - return; -} - -static int -is_mandated_params_set (struct mpls_te_link *lp) -{ - int rc = 0; - - if (ntohs (OspfMplsTE.router_addr.header.type) == 0) - { - zlog_warn ("MPLS-TE(is_mandated_params_set) Missing Router Address"); - goto out; - } - - if (ntohs (lp->link_type.header.type) == 0) - { - zlog_warn ("MPLS-TE(is_mandated_params_set) Missing Link Type"); - goto out; - } - - if (!IS_INTER_AS (lp->type) && (ntohs (lp->link_id.header.type) == 0)) - { - zlog_warn ("MPLS-TE(is_mandated_params_set) Missing Link ID"); - goto out; - } - - rc = 1; +static void update_linkparams(struct mpls_te_link *lp) +{ + int i; + struct interface *ifp; + + /* Get the Interface structure */ + if ((ifp = lp->ifp) == NULL) { + if (IS_DEBUG_OSPF_TE) + zlog_debug( + "OSPF MPLS-TE: Abort update TE parameters: no interface associated to Link Parameters"); + return; + } + if (!HAS_LINK_PARAMS(ifp)) { + if (IS_DEBUG_OSPF_TE) + zlog_debug( + "OSPF MPLS-TE: Abort update TE parameters: no Link Parameters for interface"); + return; + } + + /* RFC3630 metrics */ + if (IS_PARAM_SET(ifp->link_params, LP_ADM_GRP)) + set_linkparams_rsc_clsclr(lp, ifp->link_params->admin_grp); + else + TLV_TYPE(lp->rsc_clsclr) = 0; + + if (IS_PARAM_SET(ifp->link_params, LP_MAX_BW)) + set_linkparams_max_bw(lp, ifp->link_params->max_bw); + else + TLV_TYPE(lp->max_bw) = 0; + + if (IS_PARAM_SET(ifp->link_params, LP_MAX_RSV_BW)) + set_linkparams_max_rsv_bw(lp, ifp->link_params->max_rsv_bw); + else + TLV_TYPE(lp->max_rsv_bw) = 0; + + if (IS_PARAM_SET(ifp->link_params, LP_UNRSV_BW)) + for (i = 0; i < MAX_CLASS_TYPE; i++) + set_linkparams_unrsv_bw(lp, i, + ifp->link_params->unrsv_bw[i]); + else + TLV_TYPE(lp->unrsv_bw) = 0; + + if (IS_PARAM_SET(ifp->link_params, LP_TE_METRIC)) + set_linkparams_te_metric(lp, ifp->link_params->te_metric); + else + TLV_TYPE(lp->te_metric) = 0; + + /* TE metric Extensions */ + if (IS_PARAM_SET(ifp->link_params, LP_DELAY)) + set_linkparams_av_delay(lp, ifp->link_params->av_delay, 0); + else + TLV_TYPE(lp->av_delay) = 0; + + if (IS_PARAM_SET(ifp->link_params, LP_MM_DELAY)) + set_linkparams_mm_delay(lp, ifp->link_params->min_delay, + ifp->link_params->max_delay, 0); + else + TLV_TYPE(lp->mm_delay) = 0; + + if (IS_PARAM_SET(ifp->link_params, LP_DELAY_VAR)) + set_linkparams_delay_var(lp, ifp->link_params->delay_var); + else + TLV_TYPE(lp->delay_var) = 0; + + if (IS_PARAM_SET(ifp->link_params, LP_PKT_LOSS)) + set_linkparams_pkt_loss(lp, ifp->link_params->pkt_loss, 0); + else + TLV_TYPE(lp->pkt_loss) = 0; + + if (IS_PARAM_SET(ifp->link_params, LP_RES_BW)) + set_linkparams_res_bw(lp, ifp->link_params->res_bw); + else + TLV_TYPE(lp->res_bw) = 0; + + if (IS_PARAM_SET(ifp->link_params, LP_AVA_BW)) + set_linkparams_ava_bw(lp, ifp->link_params->ava_bw); + else + TLV_TYPE(lp->ava_bw) = 0; + + if (IS_PARAM_SET(ifp->link_params, LP_USE_BW)) + set_linkparams_use_bw(lp, ifp->link_params->use_bw); + else + TLV_TYPE(lp->use_bw) = 0; + + /* RFC5392 */ + if (IS_PARAM_SET(ifp->link_params, LP_RMT_AS)) { + /* Flush LSA if it engaged and was previously a STD_TE one */ + if (IS_STD_TE(lp->type) + && CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED)) { + if (IS_DEBUG_OSPF_TE) + zlog_debug( + "OSPF MPLS-TE Update IF: Switch from Standard LSA to INTER-AS for %s[%d/%d]", + ifp->name, lp->flags, lp->type); + + ospf_mpls_te_lsa_schedule(lp, FLUSH_THIS_LSA); + /* Then, switch it to INTER-AS */ + if (OspfMplsTE.inter_as == AS) + lp->flags = INTER_AS | FLOOD_AS; + else { + lp->flags = INTER_AS | FLOOD_AREA; + lp->area = ospf_area_lookup_by_area_id( + ospf_lookup(), + OspfMplsTE.interas_areaid); + } + } + set_linkparams_inter_as(lp, ifp->link_params->rmt_ip, + ifp->link_params->rmt_as); + } else { + if (IS_DEBUG_OSPF_TE) + zlog_debug( + "OSPF MPLS-TE Update IF: Switch from INTER-AS LSA to Standard for %s[%d/%d]", + ifp->name, lp->flags, lp->type); + + /* reset inter-as TE params */ + /* Flush LSA if it engaged and was previously an INTER_AS one */ + if (IS_INTER_AS(lp->type) + && CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED)) { + ospf_mpls_te_lsa_schedule(lp, FLUSH_THIS_LSA); + /* Then, switch it to Standard TE */ + lp->flags = STD_TE | FLOOD_AREA; + } + unset_linkparams_inter_as(lp); + } +} + +static void initialize_linkparams(struct mpls_te_link *lp) +{ + struct interface *ifp = lp->ifp; + struct ospf_interface *oi; + + if (IS_DEBUG_OSPF_TE) + zlog_debug( + "MPLS-TE(initialize_linkparams) Initialize Link Parameters for interface %s", + ifp->name); + + if ((oi = lookup_oi_by_ifp(ifp, NULL, OI_ANY)) == NULL) { + if (IS_DEBUG_OSPF_TE) + zlog_warn( + "MPLS-TE(initialize_linkparams) Could not find corresponding OSPF Interface for %s", + ifp->name); + return; + } + + /* + * Try to set initial values those can be derived from + * zebra-interface information. + */ + set_linkparams_link_type(oi, lp); + + /* Set local IP addr */ + set_linkparams_lclif_ipaddr(lp, oi->address->u.prefix4); + + /* Set Remote IP addr if Point to Point Interface */ + if (oi->type == LINK_TYPE_SUBTLV_VALUE_PTP) { + struct prefix *pref = CONNECTED_PREFIX(oi->connected); + if (pref != NULL) + set_linkparams_rmtif_ipaddr(lp, pref->u.prefix4); + } + + /* Keep Area information in combination with link parameters. */ + lp->area = oi->area; + + return; +} + +static int is_mandated_params_set(struct mpls_te_link *lp) +{ + int rc = 0; + + if (ntohs(OspfMplsTE.router_addr.header.type) == 0) { + zlog_warn( + "MPLS-TE(is_mandated_params_set) Missing Router Address"); + goto out; + } + + if (ntohs(lp->link_type.header.type) == 0) { + zlog_warn("MPLS-TE(is_mandated_params_set) Missing Link Type"); + goto out; + } + + if (!IS_INTER_AS(lp->type) && (ntohs(lp->link_id.header.type) == 0)) { + zlog_warn("MPLS-TE(is_mandated_params_set) Missing Link ID"); + goto out; + } + + rc = 1; out: - return rc; + return rc; } /*------------------------------------------------------------------------* * Followings are callback functions against generic Opaque-LSAs handling. *------------------------------------------------------------------------*/ -static int -ospf_mpls_te_new_if (struct interface *ifp) +static int ospf_mpls_te_new_if(struct interface *ifp) { - struct mpls_te_link *new; - int rc = -1; + struct mpls_te_link *new; + int rc = -1; - if (IS_DEBUG_OSPF_TE) - zlog_debug ("MPLS-TE(ospf_mpls_te_new_if) Add new %s interface %s to MPLS-TE list", - ifp->link_params ? "Active" : "Inactive", ifp->name); + if (IS_DEBUG_OSPF_TE) + zlog_debug( + "MPLS-TE(ospf_mpls_te_new_if) Add new %s interface %s to MPLS-TE list", + ifp->link_params ? "Active" : "Inactive", ifp->name); - if (lookup_linkparams_by_ifp (ifp) != NULL) - { - zlog_warn ("ospf_mpls_te_new_if: ifp(%p) already in use?", (void *)ifp); - rc = 0; /* Do nothing here. */ - goto out; - } + if (lookup_linkparams_by_ifp(ifp) != NULL) { + zlog_warn("ospf_mpls_te_new_if: ifp(%p) already in use?", + (void *)ifp); + rc = 0; /* Do nothing here. */ + goto out; + } - new = XCALLOC (MTYPE_OSPF_MPLS_TE, sizeof (struct mpls_te_link)); - if (new == NULL) - { - zlog_warn ("ospf_mpls_te_new_if: XMALLOC: %s", safe_strerror (errno)); - goto out; - } + new = XCALLOC(MTYPE_OSPF_MPLS_TE, sizeof(struct mpls_te_link)); + if (new == NULL) { + zlog_warn("ospf_mpls_te_new_if: XMALLOC: %s", + safe_strerror(errno)); + goto out; + } - new->instance = get_mpls_te_instance_value (); - new->ifp = ifp; - /* By default TE-Link is RFC3630 compatible flooding in Area and not active */ - /* This default behavior will be adapted with call to ospf_mpls_te_update_if() */ - new->type = STD_TE | FLOOD_AREA; - new->flags = LPFLG_LSA_INACTIVE; + new->instance = get_mpls_te_instance_value(); + new->ifp = ifp; + /* By default TE-Link is RFC3630 compatible flooding in Area and not + * active */ + /* This default behavior will be adapted with call to + * ospf_mpls_te_update_if() */ + new->type = STD_TE | FLOOD_AREA; + new->flags = LPFLG_LSA_INACTIVE; - /* Initialize Link Parameters from Interface */ - initialize_linkparams(new); + /* Initialize Link Parameters from Interface */ + initialize_linkparams(new); - /* Set TE Parameters from Interface */ - update_linkparams(new); + /* Set TE Parameters from Interface */ + update_linkparams(new); - /* Add Link Parameters structure to the list */ - listnode_add (OspfMplsTE.iflist, new); + /* Add Link Parameters structure to the list */ + listnode_add(OspfMplsTE.iflist, new); - if (IS_DEBUG_OSPF_TE) - zlog_debug("OSPF MPLS-TE New IF: Add new LP context for %s[%d/%d]", - ifp->name, new->flags, new->type); + if (IS_DEBUG_OSPF_TE) + zlog_debug( + "OSPF MPLS-TE New IF: Add new LP context for %s[%d/%d]", + ifp->name, new->flags, new->type); - /* Schedule Opaque-LSA refresh. *//* XXX */ + /* Schedule Opaque-LSA refresh. */ /* XXX */ - rc = 0; + rc = 0; out: - return rc; + return rc; } -static int -ospf_mpls_te_del_if (struct interface *ifp) +static int ospf_mpls_te_del_if(struct interface *ifp) { - struct mpls_te_link *lp; - int rc = -1; + struct mpls_te_link *lp; + int rc = -1; - if ((lp = lookup_linkparams_by_ifp (ifp)) != NULL) - { - struct list *iflist = OspfMplsTE.iflist; + if ((lp = lookup_linkparams_by_ifp(ifp)) != NULL) { + struct list *iflist = OspfMplsTE.iflist; - /* Dequeue listnode entry from the list. */ - listnode_delete (iflist, lp); + /* Dequeue listnode entry from the list. */ + listnode_delete(iflist, lp); - /* Avoid misjudgement in the next lookup. */ - if (listcount (iflist) == 0) - iflist->head = iflist->tail = NULL; + /* Avoid misjudgement in the next lookup. */ + if (listcount(iflist) == 0) + iflist->head = iflist->tail = NULL; - XFREE (MTYPE_OSPF_MPLS_TE, lp); - } + XFREE(MTYPE_OSPF_MPLS_TE, lp); + } - /* Schedule Opaque-LSA refresh. *//* XXX */ + /* Schedule Opaque-LSA refresh. */ /* XXX */ - rc = 0; -/*out:*/ - return rc; + rc = 0; + /*out:*/ + return rc; } /* Main initialization / update function of the MPLS TE Link context */ /* Call when interface TE Link parameters are modified */ -void -ospf_mpls_te_update_if (struct interface *ifp) -{ - struct mpls_te_link *lp; - - if (IS_DEBUG_OSPF_TE) - zlog_debug ("OSPF MPLS-TE: Update LSA parameters for interface %s [%s]", - ifp->name, HAS_LINK_PARAMS(ifp) ? "ON" : "OFF"); - - /* Get Link context from interface */ - if ((lp = lookup_linkparams_by_ifp(ifp)) == NULL) - { - if (IS_DEBUG_OSPF_TE) - zlog_warn ("OSPF MPLS-TE Update: Did not find Link Parameters context for interface %s", ifp->name); - return; - } - - /* Fulfill MPLS-TE Link TLV from Interface TE Link parameters */ - if (HAS_LINK_PARAMS(ifp)) - { - SET_FLAG (lp->flags, LPFLG_LSA_ACTIVE); - - /* Update TE parameters */ - update_linkparams(lp); - - /* Finally Re-Originate or Refresh Opaque LSA if MPLS_TE is enabled */ - if (OspfMplsTE.status == enabled) - if (lp->area != NULL) - { - if CHECK_FLAG (lp->flags, LPFLG_LSA_ENGAGED) - ospf_mpls_te_lsa_schedule (lp, REFRESH_THIS_LSA); - else - ospf_mpls_te_lsa_schedule (lp, REORIGINATE_THIS_LSA); - } - } - else - { - /* If MPLS TE is disable on this interface, flush LSA if it is already engaged */ - if CHECK_FLAG (lp->flags, LPFLG_LSA_ENGAGED) - ospf_mpls_te_lsa_schedule (lp, FLUSH_THIS_LSA); - else - /* Reset Activity flag */ - lp->flags = LPFLG_LSA_INACTIVE; - } - - return; -} - -static void -ospf_mpls_te_ism_change (struct ospf_interface *oi, int old_state) -{ - struct te_link_subtlv_link_type old_type; - struct te_link_subtlv_link_id old_id; - struct mpls_te_link *lp; - - if ((lp = lookup_linkparams_by_ifp (oi->ifp)) == NULL) - { - zlog_warn ("ospf_mpls_te_ism_change: Cannot get linkparams from OI(%s)?", IF_NAME (oi)); - goto out; - } - - if (oi->area == NULL || oi->area->ospf == NULL) - { - zlog_warn ("ospf_mpls_te_ism_change: Cannot refer to OSPF from OI(%s)?", IF_NAME (oi)); - goto out; - } +void ospf_mpls_te_update_if(struct interface *ifp) +{ + struct mpls_te_link *lp; + + if (IS_DEBUG_OSPF_TE) + zlog_debug( + "OSPF MPLS-TE: Update LSA parameters for interface %s [%s]", + ifp->name, HAS_LINK_PARAMS(ifp) ? "ON" : "OFF"); + + /* Get Link context from interface */ + if ((lp = lookup_linkparams_by_ifp(ifp)) == NULL) { + if (IS_DEBUG_OSPF_TE) + zlog_warn( + "OSPF MPLS-TE Update: Did not find Link Parameters context for interface %s", + ifp->name); + return; + } + + /* Fulfill MPLS-TE Link TLV from Interface TE Link parameters */ + if (HAS_LINK_PARAMS(ifp)) { + SET_FLAG(lp->flags, LPFLG_LSA_ACTIVE); + + /* Update TE parameters */ + update_linkparams(lp); + + /* Finally Re-Originate or Refresh Opaque LSA if MPLS_TE is + * enabled */ + if (OspfMplsTE.status == enabled) + if (lp->area != NULL) { + if + CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED) + ospf_mpls_te_lsa_schedule(lp, REFRESH_THIS_LSA); + else ospf_mpls_te_lsa_schedule( + lp, REORIGINATE_THIS_LSA); + } + } else { + /* If MPLS TE is disable on this interface, flush LSA if it is + * already engaged */ + if + CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED) + ospf_mpls_te_lsa_schedule(lp, FLUSH_THIS_LSA); + else + /* Reset Activity flag */ + lp->flags = LPFLG_LSA_INACTIVE; + } + + return; +} + +static void ospf_mpls_te_ism_change(struct ospf_interface *oi, int old_state) +{ + struct te_link_subtlv_link_type old_type; + struct te_link_subtlv_link_id old_id; + struct mpls_te_link *lp; + + if ((lp = lookup_linkparams_by_ifp(oi->ifp)) == NULL) { + zlog_warn( + "ospf_mpls_te_ism_change: Cannot get linkparams from OI(%s)?", + IF_NAME(oi)); + goto out; + } + + if (oi->area == NULL || oi->area->ospf == NULL) { + zlog_warn( + "ospf_mpls_te_ism_change: Cannot refer to OSPF from OI(%s)?", + IF_NAME(oi)); + goto out; + } #ifdef notyet - if ((lp->area != NULL - && ! IPV4_ADDR_SAME (&lp->area->area_id, &oi->area->area_id)) - || (lp->area != NULL && oi->area == NULL)) - { - /* How should we consider this case? */ - zlog_warn ("MPLS-TE: Area for OI(%s) has changed to [%s], flush previous LSAs", - IF_NAME (oi), oi->area ? inet_ntoa (oi->area->area_id) : "N/A"); - ospf_mpls_te_lsa_schedule (lp, FLUSH_THIS_LSA); - } + if ((lp->area != NULL + && !IPV4_ADDR_SAME(&lp->area->area_id, &oi->area->area_id)) + || (lp->area != NULL && oi->area == NULL)) { + /* How should we consider this case? */ + zlog_warn( + "MPLS-TE: Area for OI(%s) has changed to [%s], flush previous LSAs", + IF_NAME(oi), + oi->area ? inet_ntoa(oi->area->area_id) : "N/A"); + ospf_mpls_te_lsa_schedule(lp, FLUSH_THIS_LSA); + } #endif - /* Keep Area information in combination with linkparams. */ - lp->area = oi->area; - - /* Keep interface MPLS-TE status */ - lp->flags = HAS_LINK_PARAMS(oi->ifp); - - switch (oi->state) - { - case ISM_PointToPoint: - case ISM_DROther: - case ISM_Backup: - case ISM_DR: - old_type = lp->link_type; - old_id = lp->link_id; - - /* Set Link type, Link ID, Local and Remote IP addr */ - set_linkparams_link_type (oi, lp); - set_linkparams_link_id (oi, lp); - set_linkparams_lclif_ipaddr (lp, oi->address->u.prefix4); - - if (oi->type == LINK_TYPE_SUBTLV_VALUE_PTP) - { - struct prefix *pref = CONNECTED_PREFIX(oi->connected); - if (pref != NULL) - set_linkparams_rmtif_ipaddr(lp, pref->u.prefix4); - } - - /* Update TE parameters */ - update_linkparams(lp); - - /* Try to Schedule LSA */ - if ((ntohs (old_type.header.type) != ntohs (lp->link_type.header.type) - || old_type.link_type.value != lp->link_type.link_type.value) - || (ntohs (old_id.header.type) != ntohs (lp->link_id.header.type) - || ntohl (old_id.value.s_addr) != - ntohl (lp->link_id.value.s_addr))) - { - if CHECK_FLAG (lp->flags, LPFLG_LSA_ENGAGED) - ospf_mpls_te_lsa_schedule (lp, REFRESH_THIS_LSA); - else - ospf_mpls_te_lsa_schedule (lp, REORIGINATE_THIS_LSA); - - } - break; - default: - lp->link_type.header.type = htons (0); - lp->link_id.header.type = htons (0); - - if CHECK_FLAG (lp->flags, LPFLG_LSA_ENGAGED) - ospf_mpls_te_lsa_schedule (lp, FLUSH_THIS_LSA); - break; - } + /* Keep Area information in combination with linkparams. */ + lp->area = oi->area; + + /* Keep interface MPLS-TE status */ + lp->flags = HAS_LINK_PARAMS(oi->ifp); + + switch (oi->state) { + case ISM_PointToPoint: + case ISM_DROther: + case ISM_Backup: + case ISM_DR: + old_type = lp->link_type; + old_id = lp->link_id; + + /* Set Link type, Link ID, Local and Remote IP addr */ + set_linkparams_link_type(oi, lp); + set_linkparams_link_id(oi, lp); + set_linkparams_lclif_ipaddr(lp, oi->address->u.prefix4); + + if (oi->type == LINK_TYPE_SUBTLV_VALUE_PTP) { + struct prefix *pref = CONNECTED_PREFIX(oi->connected); + if (pref != NULL) + set_linkparams_rmtif_ipaddr(lp, + pref->u.prefix4); + } + + /* Update TE parameters */ + update_linkparams(lp); + + /* Try to Schedule LSA */ + if ((ntohs(old_type.header.type) + != ntohs(lp->link_type.header.type) + || old_type.link_type.value + != lp->link_type.link_type.value) + || (ntohs(old_id.header.type) + != ntohs(lp->link_id.header.type) + || ntohl(old_id.value.s_addr) + != ntohl(lp->link_id.value.s_addr))) { + if + CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED) + ospf_mpls_te_lsa_schedule(lp, REFRESH_THIS_LSA); + else ospf_mpls_te_lsa_schedule(lp, + REORIGINATE_THIS_LSA); + } + break; + default: + lp->link_type.header.type = htons(0); + lp->link_id.header.type = htons(0); + + if + CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED) + ospf_mpls_te_lsa_schedule(lp, FLUSH_THIS_LSA); + break; + } out: - return; - + return; } -static void -ospf_mpls_te_nsm_change (struct ospf_neighbor *nbr, int old_state) +static void ospf_mpls_te_nsm_change(struct ospf_neighbor *nbr, int old_state) { - /* Nothing to do here */ - return; + /* Nothing to do here */ + return; } /*------------------------------------------------------------------------* * Followings are OSPF protocol processing functions for MPLS-TE. *------------------------------------------------------------------------*/ -static void -build_tlv_header (struct stream *s, struct te_tlv_header *tlvh) -{ - stream_put (s, tlvh, sizeof (struct te_tlv_header)); - return; -} - -static void -build_router_tlv (struct stream *s) -{ - struct te_tlv_header *tlvh = &OspfMplsTE.router_addr.header; - if (ntohs (tlvh->type) != 0) - { - build_tlv_header (s, tlvh); - stream_put (s, tlvh+1, TLV_BODY_SIZE (tlvh)); - } - return; -} - -static void -build_link_subtlv (struct stream *s, struct te_tlv_header *tlvh) - { - - if ((tlvh != NULL) && (ntohs (tlvh->type) != 0)) - { - build_tlv_header (s, tlvh); - stream_put (s, tlvh+1, TLV_BODY_SIZE (tlvh)); - } - return; -} - -static void -build_link_tlv (struct stream *s, struct mpls_te_link *lp) -{ - set_linkparams_link_header (lp); - build_tlv_header (s, &lp->link_header.header); - - build_link_subtlv (s, &lp->link_type.header); - build_link_subtlv (s, &lp->link_id.header); - build_link_subtlv (s, &lp->lclif_ipaddr.header); - build_link_subtlv (s, &lp->rmtif_ipaddr.header); - build_link_subtlv (s, &lp->te_metric.header); - build_link_subtlv (s, &lp->max_bw.header); - build_link_subtlv (s, &lp->max_rsv_bw.header); - build_link_subtlv (s, &lp->unrsv_bw.header); - build_link_subtlv (s, &lp->rsc_clsclr.header); - build_link_subtlv (s, &lp->lrrid.header); - build_link_subtlv (s, &lp->llri.header); - build_link_subtlv (s, &lp->rip.header); - build_link_subtlv (s, &lp->ras.header); - build_link_subtlv (s, &lp->av_delay.header); - build_link_subtlv (s, &lp->mm_delay.header); - build_link_subtlv (s, &lp->delay_var.header); - build_link_subtlv (s, &lp->pkt_loss.header); - build_link_subtlv (s, &lp->res_bw.header); - build_link_subtlv (s, &lp->ava_bw.header); - build_link_subtlv (s, &lp->use_bw.header); - - return; -} - -static void -ospf_mpls_te_lsa_body_set (struct stream *s, struct mpls_te_link *lp) -{ - /* - * The router address TLV is type 1, and ... - * It must appear in exactly one - * Traffic Engineering LSA originated by a router. - */ - build_router_tlv (s); - - /* - * Only one Link TLV shall be carried in each LSA, allowing for fine - * granularity changes in topology. - */ - build_link_tlv (s, lp); - return; +static void build_tlv_header(struct stream *s, struct te_tlv_header *tlvh) +{ + stream_put(s, tlvh, sizeof(struct te_tlv_header)); + return; +} + +static void build_router_tlv(struct stream *s) +{ + struct te_tlv_header *tlvh = &OspfMplsTE.router_addr.header; + if (ntohs(tlvh->type) != 0) { + build_tlv_header(s, tlvh); + stream_put(s, tlvh + 1, TLV_BODY_SIZE(tlvh)); + } + return; +} + +static void build_link_subtlv(struct stream *s, struct te_tlv_header *tlvh) +{ + + if ((tlvh != NULL) && (ntohs(tlvh->type) != 0)) { + build_tlv_header(s, tlvh); + stream_put(s, tlvh + 1, TLV_BODY_SIZE(tlvh)); + } + return; +} + +static void build_link_tlv(struct stream *s, struct mpls_te_link *lp) +{ + set_linkparams_link_header(lp); + build_tlv_header(s, &lp->link_header.header); + + build_link_subtlv(s, &lp->link_type.header); + build_link_subtlv(s, &lp->link_id.header); + build_link_subtlv(s, &lp->lclif_ipaddr.header); + build_link_subtlv(s, &lp->rmtif_ipaddr.header); + build_link_subtlv(s, &lp->te_metric.header); + build_link_subtlv(s, &lp->max_bw.header); + build_link_subtlv(s, &lp->max_rsv_bw.header); + build_link_subtlv(s, &lp->unrsv_bw.header); + build_link_subtlv(s, &lp->rsc_clsclr.header); + build_link_subtlv(s, &lp->lrrid.header); + build_link_subtlv(s, &lp->llri.header); + build_link_subtlv(s, &lp->rip.header); + build_link_subtlv(s, &lp->ras.header); + build_link_subtlv(s, &lp->av_delay.header); + build_link_subtlv(s, &lp->mm_delay.header); + build_link_subtlv(s, &lp->delay_var.header); + build_link_subtlv(s, &lp->pkt_loss.header); + build_link_subtlv(s, &lp->res_bw.header); + build_link_subtlv(s, &lp->ava_bw.header); + build_link_subtlv(s, &lp->use_bw.header); + + return; +} + +static void ospf_mpls_te_lsa_body_set(struct stream *s, struct mpls_te_link *lp) +{ + /* + * The router address TLV is type 1, and ... + * It must appear in exactly one + * Traffic Engineering LSA originated by a router. + */ + build_router_tlv(s); + + /* + * Only one Link TLV shall be carried in each LSA, allowing for fine + * granularity changes in topology. + */ + build_link_tlv(s, lp); + return; } /* Create new opaque-LSA. */ -static struct ospf_lsa * -ospf_mpls_te_lsa_new (struct ospf_area *area, struct mpls_te_link *lp) -{ - struct stream *s; - struct lsa_header *lsah; - struct ospf_lsa *new = NULL; - u_char options, lsa_type = 0; - struct in_addr lsa_id; - u_int32_t tmp; - u_int16_t length; - - /* Create a stream for LSA. */ - if ((s = stream_new (OSPF_MAX_LSA_SIZE)) == NULL) - { - zlog_warn ("ospf_mpls_te_lsa_new: stream_new() ?"); - goto out; - } - lsah = (struct lsa_header *) STREAM_DATA (s); - - options = OSPF_OPTION_O; /* Don't forget this :-) */ - - /* Set opaque-LSA header fields depending of the type of RFC */ - if (IS_INTER_AS (lp->type)) - { - if IS_FLOOD_AS (lp->type) - { - options |= OSPF_OPTION_E; /* Enable AS external as we flood Inter-AS with Opaque Type 11 */ - lsa_type = OSPF_OPAQUE_AS_LSA; - } - else - { - options |= LSA_OPTIONS_GET (area); /* Get area default option */ - options |= LSA_OPTIONS_NSSA_GET (area); - lsa_type = OSPF_OPAQUE_AREA_LSA; - } - tmp = SET_OPAQUE_LSID (OPAQUE_TYPE_INTER_AS_LSA, lp->instance); - lsa_id.s_addr = htonl (tmp); - - struct ospf *top = ospf_lookup (); - - lsa_header_set (s, options, lsa_type, lsa_id, top->router_id); - } - else - { - options |= LSA_OPTIONS_GET (area); /* Get area default option */ - options |= LSA_OPTIONS_NSSA_GET (area); - lsa_type = OSPF_OPAQUE_AREA_LSA; - tmp = SET_OPAQUE_LSID (OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA, lp->instance); - lsa_id.s_addr = htonl (tmp); - lsa_header_set (s, options, lsa_type, lsa_id, area->ospf->router_id); - } - - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("LSA[Type%d:%s]: Create an Opaque-LSA/MPLS-TE instance", - lsa_type, inet_ntoa (lsa_id)); - - /* Set opaque-LSA body fields. */ - ospf_mpls_te_lsa_body_set (s, lp); - - /* Set length. */ - length = stream_get_endp (s); - lsah->length = htons (length); - - /* Now, create an OSPF LSA instance. */ - if ((new = ospf_lsa_new ()) == NULL) - { - zlog_warn ("ospf_mpls_te_lsa_new: ospf_lsa_new() ?"); - stream_free (s); - goto out; - } - if ((new->data = ospf_lsa_data_new (length)) == NULL) - { - zlog_warn ("ospf_mpls_te_lsa_new: ospf_lsa_data_new() ?"); - ospf_lsa_unlock (&new); - new = NULL; - stream_free (s); - goto out; - } - - new->area = area; - SET_FLAG (new->flags, OSPF_LSA_SELF); - memcpy (new->data, lsah, length); - stream_free (s); +static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf_area *area, + struct mpls_te_link *lp) +{ + struct stream *s; + struct lsa_header *lsah; + struct ospf_lsa *new = NULL; + u_char options, lsa_type = 0; + struct in_addr lsa_id; + u_int32_t tmp; + u_int16_t length; + + /* Create a stream for LSA. */ + if ((s = stream_new(OSPF_MAX_LSA_SIZE)) == NULL) { + zlog_warn("ospf_mpls_te_lsa_new: stream_new() ?"); + goto out; + } + lsah = (struct lsa_header *)STREAM_DATA(s); + + options = OSPF_OPTION_O; /* Don't forget this :-) */ + + /* Set opaque-LSA header fields depending of the type of RFC */ + if (IS_INTER_AS(lp->type)) { + if + IS_FLOOD_AS(lp->type) + { + options |= OSPF_OPTION_E; /* Enable AS external + as we flood + Inter-AS with + Opaque Type 11 */ + lsa_type = OSPF_OPAQUE_AS_LSA; + } + else { + options |= LSA_OPTIONS_GET( + area); /* Get area default option */ + options |= LSA_OPTIONS_NSSA_GET(area); + lsa_type = OSPF_OPAQUE_AREA_LSA; + } + tmp = SET_OPAQUE_LSID(OPAQUE_TYPE_INTER_AS_LSA, lp->instance); + lsa_id.s_addr = htonl(tmp); + + struct ospf *top = ospf_lookup(); + + lsa_header_set(s, options, lsa_type, lsa_id, top->router_id); + } else { + options |= LSA_OPTIONS_GET(area); /* Get area default option */ + options |= LSA_OPTIONS_NSSA_GET(area); + lsa_type = OSPF_OPAQUE_AREA_LSA; + tmp = SET_OPAQUE_LSID(OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA, + lp->instance); + lsa_id.s_addr = htonl(tmp); + lsa_header_set(s, options, lsa_type, lsa_id, + area->ospf->router_id); + } + + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug( + "LSA[Type%d:%s]: Create an Opaque-LSA/MPLS-TE instance", + lsa_type, inet_ntoa(lsa_id)); + + /* Set opaque-LSA body fields. */ + ospf_mpls_te_lsa_body_set(s, lp); + + /* Set length. */ + length = stream_get_endp(s); + lsah->length = htons(length); + + /* Now, create an OSPF LSA instance. */ + if ((new = ospf_lsa_new()) == NULL) { + zlog_warn("ospf_mpls_te_lsa_new: ospf_lsa_new() ?"); + stream_free(s); + goto out; + } + if ((new->data = ospf_lsa_data_new(length)) == NULL) { + zlog_warn("ospf_mpls_te_lsa_new: ospf_lsa_data_new() ?"); + ospf_lsa_unlock(&new); + new = NULL; + stream_free(s); + goto out; + } + + new->area = area; + SET_FLAG(new->flags, OSPF_LSA_SELF); + memcpy(new->data, lsah, length); + stream_free(s); out: - return new; -} - -static int -ospf_mpls_te_lsa_originate1 (struct ospf_area *area, struct mpls_te_link *lp) -{ - struct ospf_lsa *new; - int rc = -1; - - /* Create new Opaque-LSA/MPLS-TE instance. */ - if ((new = ospf_mpls_te_lsa_new (area, lp)) == NULL) - { - zlog_warn ("ospf_mpls_te_lsa_originate1: ospf_mpls_te_lsa_new() ?"); - goto out; - } - - /* Install this LSA into LSDB. */ - if (ospf_lsa_install (area->ospf, NULL/*oi*/, new) == NULL) - { - zlog_warn ("ospf_mpls_te_lsa_originate1: ospf_lsa_install() ?"); - ospf_lsa_unlock (&new); - goto out; - } - - /* Now this link-parameter entry has associated LSA. */ - SET_FLAG (lp->flags, LPFLG_LSA_ENGAGED); - /* Update new LSA origination count. */ - area->ospf->lsa_originate_count++; - - /* Flood new LSA through area. */ - ospf_flood_through_area (area, NULL/*nbr*/, new); - - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - { - char area_id[INET_ADDRSTRLEN]; - strcpy (area_id, inet_ntoa (area->area_id)); - zlog_debug ("LSA[Type%d:%s]: Originate Opaque-LSA/MPLS-TE: Area(%s), Link(%s)", - new->data->type, inet_ntoa (new->data->id), area_id, lp->ifp->name); - ospf_lsa_header_dump (new->data); - } - - rc = 0; + return new; +} + +static int ospf_mpls_te_lsa_originate1(struct ospf_area *area, + struct mpls_te_link *lp) +{ + struct ospf_lsa *new; + int rc = -1; + + /* Create new Opaque-LSA/MPLS-TE instance. */ + if ((new = ospf_mpls_te_lsa_new(area, lp)) == NULL) { + zlog_warn( + "ospf_mpls_te_lsa_originate1: ospf_mpls_te_lsa_new() ?"); + goto out; + } + + /* Install this LSA into LSDB. */ + if (ospf_lsa_install(area->ospf, NULL /*oi*/, new) == NULL) { + zlog_warn("ospf_mpls_te_lsa_originate1: ospf_lsa_install() ?"); + ospf_lsa_unlock(&new); + goto out; + } + + /* Now this link-parameter entry has associated LSA. */ + SET_FLAG(lp->flags, LPFLG_LSA_ENGAGED); + /* Update new LSA origination count. */ + area->ospf->lsa_originate_count++; + + /* Flood new LSA through area. */ + ospf_flood_through_area(area, NULL /*nbr*/, new); + + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { + char area_id[INET_ADDRSTRLEN]; + strcpy(area_id, inet_ntoa(area->area_id)); + zlog_debug( + "LSA[Type%d:%s]: Originate Opaque-LSA/MPLS-TE: Area(%s), Link(%s)", + new->data->type, inet_ntoa(new->data->id), area_id, + lp->ifp->name); + ospf_lsa_header_dump(new->data); + } + + rc = 0; out: - return rc; -} - -static int -ospf_mpls_te_lsa_originate_area (void *arg) -{ - struct ospf_area *area = (struct ospf_area *) arg; - struct listnode *node, *nnode; - struct mpls_te_link *lp; - int rc = -1; - - if (OspfMplsTE.status == disabled) - { - zlog_info ("ospf_mpls_te_lsa_originate_area: MPLS-TE is disabled now."); - rc = 0; /* This is not an error case. */ - goto out; - } - - for (ALL_LIST_ELEMENTS (OspfMplsTE.iflist, node, nnode, lp)) - { - /* Process only enabled LSA with area scope flooding */ - if (!CHECK_FLAG (lp->flags, LPFLG_LSA_ACTIVE) || IS_FLOOD_AS (lp->type)) - continue; - - if (lp->area == NULL) - continue; - - if (! IPV4_ADDR_SAME (&lp->area->area_id, &area->area_id)) - continue; - - if CHECK_FLAG (lp->flags, LPFLG_LSA_ENGAGED) - { - if CHECK_FLAG (lp->flags, LPFLG_LSA_FORCED_REFRESH) - { - UNSET_FLAG (lp->flags, LPFLG_LSA_FORCED_REFRESH); - zlog_warn ("OSPF MPLS-TE (ospf_mpls_te_lsa_originate_area): Refresh instead of Originate"); - ospf_mpls_te_lsa_schedule (lp, REFRESH_THIS_LSA); - } - continue; - } - if (! is_mandated_params_set (lp)) - { - zlog_warn ("ospf_mpls_te_lsa_originate_area: Link(%s) lacks some mandated MPLS-TE parameters.", - lp->ifp ? lp->ifp->name : "?"); - continue; - } - - /* Ok, let's try to originate an LSA for this area and Link. */ - if (IS_DEBUG_OSPF_TE) - zlog_debug ("MPLS-TE(ospf_mpls_te_lsa_originate_area) Let's finally reoriginate the LSA %d through the Area %s for Link %s", - lp->instance, inet_ntoa (area->area_id), lp->ifp ? lp->ifp->name : "?"); - if (ospf_mpls_te_lsa_originate1 (area, lp) != 0) - goto out; - } - - rc = 0; + return rc; +} + +static int ospf_mpls_te_lsa_originate_area(void *arg) +{ + struct ospf_area *area = (struct ospf_area *)arg; + struct listnode *node, *nnode; + struct mpls_te_link *lp; + int rc = -1; + + if (OspfMplsTE.status == disabled) { + zlog_info( + "ospf_mpls_te_lsa_originate_area: MPLS-TE is disabled now."); + rc = 0; /* This is not an error case. */ + goto out; + } + + for (ALL_LIST_ELEMENTS(OspfMplsTE.iflist, node, nnode, lp)) { + /* Process only enabled LSA with area scope flooding */ + if (!CHECK_FLAG(lp->flags, LPFLG_LSA_ACTIVE) + || IS_FLOOD_AS(lp->type)) + continue; + + if (lp->area == NULL) + continue; + + if (!IPV4_ADDR_SAME(&lp->area->area_id, &area->area_id)) + continue; + + if + CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED) + { + if + CHECK_FLAG(lp->flags, + LPFLG_LSA_FORCED_REFRESH) + { + UNSET_FLAG( + lp->flags, + LPFLG_LSA_FORCED_REFRESH); + zlog_warn( + "OSPF MPLS-TE (ospf_mpls_te_lsa_originate_area): Refresh instead of Originate"); + ospf_mpls_te_lsa_schedule( + lp, REFRESH_THIS_LSA); + } + continue; + } + if (!is_mandated_params_set(lp)) { + zlog_warn( + "ospf_mpls_te_lsa_originate_area: Link(%s) lacks some mandated MPLS-TE parameters.", + lp->ifp ? lp->ifp->name : "?"); + continue; + } + + /* Ok, let's try to originate an LSA for this area and Link. */ + if (IS_DEBUG_OSPF_TE) + zlog_debug( + "MPLS-TE(ospf_mpls_te_lsa_originate_area) Let's finally reoriginate the LSA %d through the Area %s for Link %s", + lp->instance, inet_ntoa(area->area_id), + lp->ifp ? lp->ifp->name : "?"); + if (ospf_mpls_te_lsa_originate1(area, lp) != 0) + goto out; + } + + rc = 0; out: - return rc; -} - -static int -ospf_mpls_te_lsa_originate2 (struct ospf *top, struct mpls_te_link *lp) -{ - struct ospf_lsa *new; - int rc = -1; - - /* Create new Opaque-LSA/Inter-AS instance. */ - if ((new = ospf_mpls_te_lsa_new (NULL, lp)) == NULL) - { - zlog_warn ("ospf_mpls_te_lsa_originate2: ospf_router_info_lsa_new() ?"); - goto out; - } - - /* Install this LSA into LSDB. */ - if (ospf_lsa_install (top, NULL /*oi */ , new) == NULL) - { - zlog_warn ("ospf_mpls_te_lsa_originate2: ospf_lsa_install() ?"); - ospf_lsa_unlock (&new); - goto out; - } - - /* Now this Router Info parameter entry has associated LSA. */ - SET_FLAG (lp->flags, LPFLG_LSA_ENGAGED); - /* Update new LSA origination count. */ - top->lsa_originate_count++; - - /* Flood new LSA through AS. */ - ospf_flood_through_as (top, NULL /*nbr */ , new); - - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - { - zlog_debug ("LSA[Type%d:%s]: Originate Opaque-LSA/MPLS-TE Inter-AS", - new->data->type, inet_ntoa (new->data->id)); - ospf_lsa_header_dump (new->data); - } - - rc = 0; -out:return rc; -} - -static int -ospf_mpls_te_lsa_originate_as (void *arg) -{ - struct ospf *top; - struct ospf_area *area; - struct listnode *node, *nnode; - struct mpls_te_link *lp; - int rc = -1; - - if ((OspfMplsTE.status == disabled) || (OspfMplsTE.inter_as == Disable)) - { - zlog_info - ("ospf_mpls_te_lsa_originate_as: MPLS-TE Inter-AS is disabled for now."); - rc = 0; /* This is not an error case. */ - goto out; - } - - for (ALL_LIST_ELEMENTS (OspfMplsTE.iflist, node, nnode, lp)) - { - /* Process only enabled INTER_AS Links or Pseudo-Links */ - if (!CHECK_FLAG (lp->flags, LPFLG_LSA_ACTIVE) || !IS_INTER_AS (lp->type)) - continue; - - if CHECK_FLAG (lp->flags, LPFLG_LSA_ENGAGED) - { - if CHECK_FLAG (lp->flags, LPFLG_LSA_FORCED_REFRESH) - { - UNSET_FLAG (lp->flags, LPFLG_LSA_FORCED_REFRESH); - ospf_mpls_te_lsa_schedule (lp, REFRESH_THIS_LSA); - } - continue; - } - if (!is_mandated_params_set (lp)) - { - zlog_warn ("ospf_mpls_te_lsa_originate_as: Link(%s) lacks some mandated MPLS-TE parameters.", - lp->ifp ? lp->ifp->name : "?"); - continue; - } - - /* Ok, let's try to originate an LSA for this AS and Link. */ - if (IS_DEBUG_OSPF_TE) - zlog_debug ("MPLS-TE(ospf_mpls_te_lsa_originate_as) Let's finally re-originate the Inter-AS LSA %d through the %s for Link %s", - lp->instance, IS_FLOOD_AS (lp->type) ? "AS" : "Area", lp->ifp ? lp->ifp->name : "Unknown"); - - if (IS_FLOOD_AS (lp->type)) - { - top = (struct ospf *) arg; - ospf_mpls_te_lsa_originate2 (top, lp); - } - else - { - area = (struct ospf_area *) arg; - ospf_mpls_te_lsa_originate1 (area, lp); - } - } - - rc = 0; -out:return rc; -} - -static struct ospf_lsa * -ospf_mpls_te_lsa_refresh (struct ospf_lsa *lsa) -{ - struct mpls_te_link *lp; - struct ospf_area *area = lsa->area; - struct ospf *top; - struct ospf_lsa *new = NULL; - - if (OspfMplsTE.status == disabled) - { - /* - * This LSA must have flushed before due to MPLS-TE status change. - * It seems a slip among routers in the routing domain. - */ - zlog_info ("ospf_mpls_te_lsa_refresh: MPLS-TE is disabled now."); - lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); /* Flush it anyway. */ - } - - /* At first, resolve lsa/lp relationship. */ - if ((lp = lookup_linkparams_by_instance (lsa)) == NULL) - { - zlog_warn ("ospf_mpls_te_lsa_refresh: Invalid parameter?"); - lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); /* Flush it anyway. */ - } - - /* Check if lp was not disable in the interval */ - if (!CHECK_FLAG (lp->flags, LPFLG_LSA_ACTIVE)) - { - zlog_warn ("ospf_mpls_te_lsa_refresh: lp was disabled: Flush it!"); - lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); /* Flush it anyway. */ - } - - /* If the lsa's age reached to MaxAge, start flushing procedure. */ - if (IS_LSA_MAXAGE (lsa)) - { - if (lp) - UNSET_FLAG (lp->flags, LPFLG_LSA_ENGAGED); - ospf_opaque_lsa_flush_schedule (lsa); - goto out; - } - - /* Create new Opaque-LSA/MPLS-TE instance. */ - if ((new = ospf_mpls_te_lsa_new (area, lp)) == NULL) - { - zlog_warn ("ospf_mpls_te_lsa_refresh: ospf_mpls_te_lsa_new() ?"); - goto out; - } - new->data->ls_seqnum = lsa_seqnum_increment (lsa); - - /* Install this LSA into LSDB. */ - /* Given "lsa" will be freed in the next function. */ - /* As area could be NULL i.e. when using OPAQUE_LSA_AS, we prefer to use ospf_lookup() to get ospf instance */ - if (area) - top = area->ospf; - else - top = ospf_lookup (); - - if (ospf_lsa_install (top, NULL /*oi */ , new) == NULL) - { - zlog_warn ("ospf_mpls_te_lsa_refresh: ospf_lsa_install() ?"); - ospf_lsa_unlock (&new); - goto out; - } - - /* Flood updated LSA through AS or Area depending of the RFC of the link */ - if (IS_FLOOD_AS (lp->type)) - ospf_flood_through_as (top, NULL, new); - else - ospf_flood_through_area (area, NULL/*nbr*/, new); - - /* Debug logging. */ - if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - { - zlog_debug ("LSA[Type%d:%s]: Refresh Opaque-LSA/MPLS-TE", - new->data->type, inet_ntoa (new->data->id)); - ospf_lsa_header_dump (new->data); - } + return rc; +} +static int ospf_mpls_te_lsa_originate2(struct ospf *top, + struct mpls_te_link *lp) +{ + struct ospf_lsa *new; + int rc = -1; + + /* Create new Opaque-LSA/Inter-AS instance. */ + if ((new = ospf_mpls_te_lsa_new(NULL, lp)) == NULL) { + zlog_warn( + "ospf_mpls_te_lsa_originate2: ospf_router_info_lsa_new() ?"); + goto out; + } + + /* Install this LSA into LSDB. */ + if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) { + zlog_warn("ospf_mpls_te_lsa_originate2: ospf_lsa_install() ?"); + ospf_lsa_unlock(&new); + goto out; + } + + /* Now this Router Info parameter entry has associated LSA. */ + SET_FLAG(lp->flags, LPFLG_LSA_ENGAGED); + /* Update new LSA origination count. */ + top->lsa_originate_count++; + + /* Flood new LSA through AS. */ + ospf_flood_through_as(top, NULL /*nbr */, new); + + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { + zlog_debug( + "LSA[Type%d:%s]: Originate Opaque-LSA/MPLS-TE Inter-AS", + new->data->type, inet_ntoa(new->data->id)); + ospf_lsa_header_dump(new->data); + } + + rc = 0; +out: + return rc; +} + +static int ospf_mpls_te_lsa_originate_as(void *arg) +{ + struct ospf *top; + struct ospf_area *area; + struct listnode *node, *nnode; + struct mpls_te_link *lp; + int rc = -1; + + if ((OspfMplsTE.status == disabled) + || (OspfMplsTE.inter_as == Disable)) { + zlog_info( + "ospf_mpls_te_lsa_originate_as: MPLS-TE Inter-AS is disabled for now."); + rc = 0; /* This is not an error case. */ + goto out; + } + + for (ALL_LIST_ELEMENTS(OspfMplsTE.iflist, node, nnode, lp)) { + /* Process only enabled INTER_AS Links or Pseudo-Links */ + if (!CHECK_FLAG(lp->flags, LPFLG_LSA_ACTIVE) + || !IS_INTER_AS(lp->type)) + continue; + + if + CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED) + { + if + CHECK_FLAG(lp->flags, + LPFLG_LSA_FORCED_REFRESH) + { + UNSET_FLAG( + lp->flags, + LPFLG_LSA_FORCED_REFRESH); + ospf_mpls_te_lsa_schedule( + lp, REFRESH_THIS_LSA); + } + continue; + } + if (!is_mandated_params_set(lp)) { + zlog_warn( + "ospf_mpls_te_lsa_originate_as: Link(%s) lacks some mandated MPLS-TE parameters.", + lp->ifp ? lp->ifp->name : "?"); + continue; + } + + /* Ok, let's try to originate an LSA for this AS and Link. */ + if (IS_DEBUG_OSPF_TE) + zlog_debug( + "MPLS-TE(ospf_mpls_te_lsa_originate_as) Let's finally re-originate the Inter-AS LSA %d through the %s for Link %s", + lp->instance, + IS_FLOOD_AS(lp->type) ? "AS" : "Area", + lp->ifp ? lp->ifp->name : "Unknown"); + + if (IS_FLOOD_AS(lp->type)) { + top = (struct ospf *)arg; + ospf_mpls_te_lsa_originate2(top, lp); + } else { + area = (struct ospf_area *)arg; + ospf_mpls_te_lsa_originate1(area, lp); + } + } + + rc = 0; out: - return new; -} - -void -ospf_mpls_te_lsa_schedule (struct mpls_te_link *lp, opcode_t opcode) -{ - struct ospf_lsa lsa; - struct lsa_header lsah; - struct ospf *top; - u_int32_t tmp; - - memset (&lsa, 0, sizeof (lsa)); - memset (&lsah, 0, sizeof (lsah)); - top = ospf_lookup (); - - /* Check if the pseudo link is ready to flood */ - if (!(CHECK_FLAG (lp->flags, LPFLG_LSA_ACTIVE)) - || !(IS_FLOOD_AREA (lp->type) || IS_FLOOD_AS (lp->type))) { - return; - } - - lsa.area = lp->area; - lsa.data = &lsah; - if (IS_FLOOD_AS (lp->type)) - { - lsah.type = OSPF_OPAQUE_AS_LSA; - tmp = SET_OPAQUE_LSID (OPAQUE_TYPE_INTER_AS_LSA, lp->instance); - lsah.id.s_addr = htonl (tmp); - } - else - { - lsah.type = OSPF_OPAQUE_AREA_LSA; - if (IS_INTER_AS (lp->type)) - { - /* Set the area context if not know */ - if (lp->area == NULL) - lp->area = ospf_area_lookup_by_area_id (top, OspfMplsTE.interas_areaid); - /* Unable to set the area context. Abort! */ - if (lp->area == NULL) - { - zlog_warn ("MPLS-TE(ospf_mpls_te_lsa_schedule) Area context is null. Abort !"); - return; - } - tmp = SET_OPAQUE_LSID (OPAQUE_TYPE_INTER_AS_LSA, lp->instance); - } - else - tmp = SET_OPAQUE_LSID (OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA, lp->instance); - lsah.id.s_addr = htonl (tmp); - } - - switch (opcode) - { - case REORIGINATE_THIS_LSA: - if (IS_FLOOD_AS (lp->type)) - { - ospf_opaque_lsa_reoriginate_schedule ((void *) top, OSPF_OPAQUE_AS_LSA, - OPAQUE_TYPE_INTER_AS_LSA); - break; - } - - if (IS_FLOOD_AREA (lp->type)) - { - if (IS_INTER_AS (lp->type)) - ospf_opaque_lsa_reoriginate_schedule ((void *) lp->area, OSPF_OPAQUE_AREA_LSA, - OPAQUE_TYPE_INTER_AS_LSA); - else - ospf_opaque_lsa_reoriginate_schedule ((void *) lp->area, OSPF_OPAQUE_AREA_LSA, - OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA); - break; - } - break; - case REFRESH_THIS_LSA: - ospf_opaque_lsa_refresh_schedule (&lsa); - break; - case FLUSH_THIS_LSA: - /* Reset Activity flag */ - lp->flags = LPFLG_LSA_INACTIVE; - ospf_opaque_lsa_flush_schedule (&lsa); - break; - default: - zlog_warn ("ospf_mpls_te_lsa_schedule: Unknown opcode (%u)", opcode); - break; - } - - return; + return rc; +} + +static struct ospf_lsa *ospf_mpls_te_lsa_refresh(struct ospf_lsa *lsa) +{ + struct mpls_te_link *lp; + struct ospf_area *area = lsa->area; + struct ospf *top; + struct ospf_lsa *new = NULL; + + if (OspfMplsTE.status == disabled) { + /* + * This LSA must have flushed before due to MPLS-TE status + * change. + * It seems a slip among routers in the routing domain. + */ + zlog_info("ospf_mpls_te_lsa_refresh: MPLS-TE is disabled now."); + lsa->data->ls_age = + htons(OSPF_LSA_MAXAGE); /* Flush it anyway. */ + } + + /* At first, resolve lsa/lp relationship. */ + if ((lp = lookup_linkparams_by_instance(lsa)) == NULL) { + zlog_warn("ospf_mpls_te_lsa_refresh: Invalid parameter?"); + lsa->data->ls_age = + htons(OSPF_LSA_MAXAGE); /* Flush it anyway. */ + } + + /* Check if lp was not disable in the interval */ + if (!CHECK_FLAG(lp->flags, LPFLG_LSA_ACTIVE)) { + zlog_warn( + "ospf_mpls_te_lsa_refresh: lp was disabled: Flush it!"); + lsa->data->ls_age = + htons(OSPF_LSA_MAXAGE); /* Flush it anyway. */ + } + + /* If the lsa's age reached to MaxAge, start flushing procedure. */ + if (IS_LSA_MAXAGE(lsa)) { + if (lp) + UNSET_FLAG(lp->flags, LPFLG_LSA_ENGAGED); + ospf_opaque_lsa_flush_schedule(lsa); + goto out; + } + + /* Create new Opaque-LSA/MPLS-TE instance. */ + if ((new = ospf_mpls_te_lsa_new(area, lp)) == NULL) { + zlog_warn("ospf_mpls_te_lsa_refresh: ospf_mpls_te_lsa_new() ?"); + goto out; + } + new->data->ls_seqnum = lsa_seqnum_increment(lsa); + + /* Install this LSA into LSDB. */ + /* Given "lsa" will be freed in the next function. */ + /* As area could be NULL i.e. when using OPAQUE_LSA_AS, we prefer to use + * ospf_lookup() to get ospf instance */ + if (area) + top = area->ospf; + else + top = ospf_lookup(); + + if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) { + zlog_warn("ospf_mpls_te_lsa_refresh: ospf_lsa_install() ?"); + ospf_lsa_unlock(&new); + goto out; + } + + /* Flood updated LSA through AS or Area depending of the RFC of the link + */ + if (IS_FLOOD_AS(lp->type)) + ospf_flood_through_as(top, NULL, new); + else + ospf_flood_through_area(area, NULL /*nbr*/, new); + + /* Debug logging. */ + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { + zlog_debug("LSA[Type%d:%s]: Refresh Opaque-LSA/MPLS-TE", + new->data->type, inet_ntoa(new->data->id)); + ospf_lsa_header_dump(new->data); + } + +out: + return new; +} + +void ospf_mpls_te_lsa_schedule(struct mpls_te_link *lp, opcode_t opcode) +{ + struct ospf_lsa lsa; + struct lsa_header lsah; + struct ospf *top; + u_int32_t tmp; + + memset(&lsa, 0, sizeof(lsa)); + memset(&lsah, 0, sizeof(lsah)); + top = ospf_lookup(); + + /* Check if the pseudo link is ready to flood */ + if (!(CHECK_FLAG(lp->flags, LPFLG_LSA_ACTIVE)) + || !(IS_FLOOD_AREA(lp->type) || IS_FLOOD_AS(lp->type))) { + return; + } + + lsa.area = lp->area; + lsa.data = &lsah; + if (IS_FLOOD_AS(lp->type)) { + lsah.type = OSPF_OPAQUE_AS_LSA; + tmp = SET_OPAQUE_LSID(OPAQUE_TYPE_INTER_AS_LSA, lp->instance); + lsah.id.s_addr = htonl(tmp); + } else { + lsah.type = OSPF_OPAQUE_AREA_LSA; + if (IS_INTER_AS(lp->type)) { + /* Set the area context if not know */ + if (lp->area == NULL) + lp->area = ospf_area_lookup_by_area_id( + top, OspfMplsTE.interas_areaid); + /* Unable to set the area context. Abort! */ + if (lp->area == NULL) { + zlog_warn( + "MPLS-TE(ospf_mpls_te_lsa_schedule) Area context is null. Abort !"); + return; + } + tmp = SET_OPAQUE_LSID(OPAQUE_TYPE_INTER_AS_LSA, + lp->instance); + } else + tmp = SET_OPAQUE_LSID( + OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA, + lp->instance); + lsah.id.s_addr = htonl(tmp); + } + + switch (opcode) { + case REORIGINATE_THIS_LSA: + if (IS_FLOOD_AS(lp->type)) { + ospf_opaque_lsa_reoriginate_schedule( + (void *)top, OSPF_OPAQUE_AS_LSA, + OPAQUE_TYPE_INTER_AS_LSA); + break; + } + + if (IS_FLOOD_AREA(lp->type)) { + if (IS_INTER_AS(lp->type)) + ospf_opaque_lsa_reoriginate_schedule( + (void *)lp->area, OSPF_OPAQUE_AREA_LSA, + OPAQUE_TYPE_INTER_AS_LSA); + else + ospf_opaque_lsa_reoriginate_schedule( + (void *)lp->area, OSPF_OPAQUE_AREA_LSA, + OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA); + break; + } + break; + case REFRESH_THIS_LSA: + ospf_opaque_lsa_refresh_schedule(&lsa); + break; + case FLUSH_THIS_LSA: + /* Reset Activity flag */ + lp->flags = LPFLG_LSA_INACTIVE; + ospf_opaque_lsa_flush_schedule(&lsa); + break; + default: + zlog_warn("ospf_mpls_te_lsa_schedule: Unknown opcode (%u)", + opcode); + break; + } + + return; } @@ -1665,583 +1635,594 @@ ospf_mpls_te_lsa_schedule (struct mpls_te_link *lp, opcode_t opcode) * Followings are vty session control functions. *------------------------------------------------------------------------*/ -static u_int16_t -show_vty_router_addr (struct vty *vty, struct te_tlv_header *tlvh) +static u_int16_t show_vty_router_addr(struct vty *vty, + struct te_tlv_header *tlvh) { - struct te_tlv_router_addr *top = (struct te_tlv_router_addr *) tlvh; + struct te_tlv_router_addr *top = (struct te_tlv_router_addr *)tlvh; - if (vty != NULL) - vty_out (vty, " Router-Address: %s\n",inet_ntoa(top->value)); - else - zlog_debug (" Router-Address: %s", inet_ntoa (top->value)); + if (vty != NULL) + vty_out(vty, " Router-Address: %s\n", inet_ntoa(top->value)); + else + zlog_debug(" Router-Address: %s", inet_ntoa(top->value)); - return TLV_SIZE (tlvh); + return TLV_SIZE(tlvh); } -static u_int16_t -show_vty_link_header (struct vty *vty, struct te_tlv_header *tlvh) +static u_int16_t show_vty_link_header(struct vty *vty, + struct te_tlv_header *tlvh) { - struct te_tlv_link *top = (struct te_tlv_link *) tlvh; + struct te_tlv_link *top = (struct te_tlv_link *)tlvh; - if (vty != NULL) - vty_out (vty, " Link: %u octets of data\n",ntohs(top->header.length)); - else - zlog_debug (" Link: %u octets of data", ntohs (top->header.length)); + if (vty != NULL) + vty_out(vty, " Link: %u octets of data\n", + ntohs(top->header.length)); + else + zlog_debug(" Link: %u octets of data", + ntohs(top->header.length)); - return TLV_HDR_SIZE; /* Here is special, not "TLV_SIZE". */ + return TLV_HDR_SIZE; /* Here is special, not "TLV_SIZE". */ } -static u_int16_t -show_vty_link_subtlv_link_type (struct vty *vty, struct te_tlv_header *tlvh) +static u_int16_t show_vty_link_subtlv_link_type(struct vty *vty, + struct te_tlv_header *tlvh) { - struct te_link_subtlv_link_type *top; - const char *cp = "Unknown"; + struct te_link_subtlv_link_type *top; + const char *cp = "Unknown"; - top = (struct te_link_subtlv_link_type *) tlvh; - switch (top->link_type.value) - { - case LINK_TYPE_SUBTLV_VALUE_PTP: - cp = "Point-to-point"; - break; - case LINK_TYPE_SUBTLV_VALUE_MA: - cp = "Multiaccess"; - break; - default: - break; - } + top = (struct te_link_subtlv_link_type *)tlvh; + switch (top->link_type.value) { + case LINK_TYPE_SUBTLV_VALUE_PTP: + cp = "Point-to-point"; + break; + case LINK_TYPE_SUBTLV_VALUE_MA: + cp = "Multiaccess"; + break; + default: + break; + } - if (vty != NULL) - vty_out (vty, " Link-Type: %s (%u)\n", cp,top->link_type.value); - else - zlog_debug (" Link-Type: %s (%u)", cp, top->link_type.value); + if (vty != NULL) + vty_out(vty, " Link-Type: %s (%u)\n", cp, + top->link_type.value); + else + zlog_debug(" Link-Type: %s (%u)", cp, top->link_type.value); - return TLV_SIZE (tlvh); + return TLV_SIZE(tlvh); } -static u_int16_t -show_vty_link_subtlv_link_id (struct vty *vty, struct te_tlv_header *tlvh) +static u_int16_t show_vty_link_subtlv_link_id(struct vty *vty, + struct te_tlv_header *tlvh) { - struct te_link_subtlv_link_id *top; + struct te_link_subtlv_link_id *top; - top = (struct te_link_subtlv_link_id *) tlvh; - if (vty != NULL) - vty_out (vty, " Link-ID: %s\n", inet_ntoa(top->value)); - else - zlog_debug (" Link-ID: %s", inet_ntoa (top->value)); + top = (struct te_link_subtlv_link_id *)tlvh; + if (vty != NULL) + vty_out(vty, " Link-ID: %s\n", inet_ntoa(top->value)); + else + zlog_debug(" Link-ID: %s", inet_ntoa(top->value)); - return TLV_SIZE (tlvh); + return TLV_SIZE(tlvh); } -static u_int16_t -show_vty_link_subtlv_lclif_ipaddr (struct vty *vty, - struct te_tlv_header *tlvh) +static u_int16_t show_vty_link_subtlv_lclif_ipaddr(struct vty *vty, + struct te_tlv_header *tlvh) { - struct te_link_subtlv_lclif_ipaddr *top; - int i, n; + struct te_link_subtlv_lclif_ipaddr *top; + int i, n; - top = (struct te_link_subtlv_lclif_ipaddr *) tlvh; - n = ntohs (tlvh->length) / sizeof (top->value[0]); + top = (struct te_link_subtlv_lclif_ipaddr *)tlvh; + n = ntohs(tlvh->length) / sizeof(top->value[0]); - if (vty != NULL) - vty_out (vty, " Local Interface IP Address(es): %d\n", n); - else - zlog_debug (" Local Interface IP Address(es): %d", n); + if (vty != NULL) + vty_out(vty, " Local Interface IP Address(es): %d\n", n); + else + zlog_debug(" Local Interface IP Address(es): %d", n); - for (i = 0; i < n; i++) - { - if (vty != NULL) - vty_out (vty, " #%d: %s\n", i,inet_ntoa(top->value[i])); - else - zlog_debug (" #%d: %s", i, inet_ntoa (top->value[i])); - } - return TLV_SIZE (tlvh); + for (i = 0; i < n; i++) { + if (vty != NULL) + vty_out(vty, " #%d: %s\n", i, + inet_ntoa(top->value[i])); + else + zlog_debug(" #%d: %s", i, + inet_ntoa(top->value[i])); + } + return TLV_SIZE(tlvh); } -static u_int16_t -show_vty_link_subtlv_rmtif_ipaddr (struct vty *vty, - struct te_tlv_header *tlvh) +static u_int16_t show_vty_link_subtlv_rmtif_ipaddr(struct vty *vty, + struct te_tlv_header *tlvh) { - struct te_link_subtlv_rmtif_ipaddr *top; - int i, n; + struct te_link_subtlv_rmtif_ipaddr *top; + int i, n; - top = (struct te_link_subtlv_rmtif_ipaddr *) tlvh; - n = ntohs (tlvh->length) / sizeof (top->value[0]); - if (vty != NULL) - vty_out (vty, " Remote Interface IP Address(es): %d\n", n); - else - zlog_debug (" Remote Interface IP Address(es): %d", n); + top = (struct te_link_subtlv_rmtif_ipaddr *)tlvh; + n = ntohs(tlvh->length) / sizeof(top->value[0]); + if (vty != NULL) + vty_out(vty, " Remote Interface IP Address(es): %d\n", n); + else + zlog_debug(" Remote Interface IP Address(es): %d", n); - for (i = 0; i < n; i++) - { - if (vty != NULL) - vty_out (vty, " #%d: %s\n", i,inet_ntoa(top->value[i])); - else - zlog_debug (" #%d: %s", i, inet_ntoa (top->value[i])); - } - return TLV_SIZE (tlvh); + for (i = 0; i < n; i++) { + if (vty != NULL) + vty_out(vty, " #%d: %s\n", i, + inet_ntoa(top->value[i])); + else + zlog_debug(" #%d: %s", i, + inet_ntoa(top->value[i])); + } + return TLV_SIZE(tlvh); } -static u_int16_t -show_vty_link_subtlv_te_metric (struct vty *vty, struct te_tlv_header *tlvh) +static u_int16_t show_vty_link_subtlv_te_metric(struct vty *vty, + struct te_tlv_header *tlvh) { - struct te_link_subtlv_te_metric *top; + struct te_link_subtlv_te_metric *top; - top = (struct te_link_subtlv_te_metric *) tlvh; - if (vty != NULL) - vty_out (vty, " Traffic Engineering Metric: %u\n", - (u_int32_t)ntohl(top->value)); - else - zlog_debug (" Traffic Engineering Metric: %u", - (u_int32_t) ntohl (top->value)); + top = (struct te_link_subtlv_te_metric *)tlvh; + if (vty != NULL) + vty_out(vty, " Traffic Engineering Metric: %u\n", + (u_int32_t)ntohl(top->value)); + else + zlog_debug(" Traffic Engineering Metric: %u", + (u_int32_t)ntohl(top->value)); - return TLV_SIZE (tlvh); + return TLV_SIZE(tlvh); } -static u_int16_t -show_vty_link_subtlv_max_bw (struct vty *vty, struct te_tlv_header *tlvh) +static u_int16_t show_vty_link_subtlv_max_bw(struct vty *vty, + struct te_tlv_header *tlvh) { - struct te_link_subtlv_max_bw *top; - float fval; + struct te_link_subtlv_max_bw *top; + float fval; - top = (struct te_link_subtlv_max_bw *) tlvh; - fval = ntohf (top->value); + top = (struct te_link_subtlv_max_bw *)tlvh; + fval = ntohf(top->value); - if (vty != NULL) - vty_out (vty, " Maximum Bandwidth: %g (Bytes/sec)\n", fval); - else - zlog_debug (" Maximum Bandwidth: %g (Bytes/sec)", fval); + if (vty != NULL) + vty_out(vty, " Maximum Bandwidth: %g (Bytes/sec)\n", fval); + else + zlog_debug(" Maximum Bandwidth: %g (Bytes/sec)", fval); - return TLV_SIZE (tlvh); + return TLV_SIZE(tlvh); } -static u_int16_t -show_vty_link_subtlv_max_rsv_bw (struct vty *vty, struct te_tlv_header *tlvh) +static u_int16_t show_vty_link_subtlv_max_rsv_bw(struct vty *vty, + struct te_tlv_header *tlvh) { - struct te_link_subtlv_max_rsv_bw *top; - float fval; + struct te_link_subtlv_max_rsv_bw *top; + float fval; - top = (struct te_link_subtlv_max_rsv_bw *) tlvh; - fval = ntohf (top->value); + top = (struct te_link_subtlv_max_rsv_bw *)tlvh; + fval = ntohf(top->value); - if (vty != NULL) - vty_out (vty, " Maximum Reservable Bandwidth: %g (Bytes/sec)\n",fval); - else - zlog_debug (" Maximum Reservable Bandwidth: %g (Bytes/sec)", fval); + if (vty != NULL) + vty_out(vty, " Maximum Reservable Bandwidth: %g (Bytes/sec)\n", + fval); + else + zlog_debug(" Maximum Reservable Bandwidth: %g (Bytes/sec)", + fval); - return TLV_SIZE (tlvh); + return TLV_SIZE(tlvh); } -static u_int16_t -show_vty_link_subtlv_unrsv_bw (struct vty *vty, struct te_tlv_header *tlvh) +static u_int16_t show_vty_link_subtlv_unrsv_bw(struct vty *vty, + struct te_tlv_header *tlvh) { - struct te_link_subtlv_unrsv_bw *top; - float fval1, fval2; - int i; + struct te_link_subtlv_unrsv_bw *top; + float fval1, fval2; + int i; - top = (struct te_link_subtlv_unrsv_bw *) tlvh; - if (vty != NULL) - vty_out (vty, " Unreserved Bandwidth per Class Type in Byte/s:\n"); - else - zlog_debug (" Unreserved Bandwidth per Class Type in Byte/s:"); - for (i = 0; i < MAX_CLASS_TYPE; i+=2) - { - fval1 = ntohf (top->value[i]); - fval2 = ntohf (top->value[i+1]); + top = (struct te_link_subtlv_unrsv_bw *)tlvh; + if (vty != NULL) + vty_out(vty, + " Unreserved Bandwidth per Class Type in Byte/s:\n"); + else + zlog_debug( + " Unreserved Bandwidth per Class Type in Byte/s:"); + for (i = 0; i < MAX_CLASS_TYPE; i += 2) { + fval1 = ntohf(top->value[i]); + fval2 = ntohf(top->value[i + 1]); - if (vty != NULL) - vty_out (vty, " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n", - i, fval1, i+1, fval2); - else - zlog_debug (" [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)", - i, fval1, i+1, fval2); - } + if (vty != NULL) + vty_out(vty, + " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n", + i, fval1, i + 1, fval2); + else + zlog_debug( + " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)", + i, fval1, i + 1, fval2); + } - return TLV_SIZE (tlvh); + return TLV_SIZE(tlvh); } -static u_int16_t -show_vty_link_subtlv_rsc_clsclr (struct vty *vty, struct te_tlv_header *tlvh) +static u_int16_t show_vty_link_subtlv_rsc_clsclr(struct vty *vty, + struct te_tlv_header *tlvh) { - struct te_link_subtlv_rsc_clsclr *top; + struct te_link_subtlv_rsc_clsclr *top; - top = (struct te_link_subtlv_rsc_clsclr *) tlvh; - if (vty != NULL) - vty_out (vty, " Resource class/color: 0x%x\n", - (u_int32_t)ntohl(top->value)); - else - zlog_debug (" Resource Class/Color: 0x%x", - (u_int32_t) ntohl (top->value)); + top = (struct te_link_subtlv_rsc_clsclr *)tlvh; + if (vty != NULL) + vty_out(vty, " Resource class/color: 0x%x\n", + (u_int32_t)ntohl(top->value)); + else + zlog_debug(" Resource Class/Color: 0x%x", + (u_int32_t)ntohl(top->value)); - return TLV_SIZE (tlvh); + return TLV_SIZE(tlvh); } -static u_int16_t -show_vty_link_subtlv_lrrid (struct vty *vty, struct te_tlv_header *tlvh) +static u_int16_t show_vty_link_subtlv_lrrid(struct vty *vty, + struct te_tlv_header *tlvh) { - struct te_link_subtlv_lrrid *top; + struct te_link_subtlv_lrrid *top; - top = (struct te_link_subtlv_lrrid *) tlvh; + top = (struct te_link_subtlv_lrrid *)tlvh; - if (vty != NULL) - { - vty_out (vty, " Local TE Router ID: %s\n",inet_ntoa(top->local)); - vty_out (vty, " Remote TE Router ID: %s\n",inet_ntoa(top->remote)); - } - else - { - zlog_debug (" Local TE Router ID: %s", inet_ntoa (top->local)); - zlog_debug (" Remote TE Router ID: %s", inet_ntoa (top->remote)); - } + if (vty != NULL) { + vty_out(vty, " Local TE Router ID: %s\n", + inet_ntoa(top->local)); + vty_out(vty, " Remote TE Router ID: %s\n", + inet_ntoa(top->remote)); + } else { + zlog_debug(" Local TE Router ID: %s", + inet_ntoa(top->local)); + zlog_debug(" Remote TE Router ID: %s", + inet_ntoa(top->remote)); + } - return TLV_SIZE (tlvh); + return TLV_SIZE(tlvh); } -static u_int16_t -show_vty_link_subtlv_llri (struct vty *vty, struct te_tlv_header *tlvh) +static u_int16_t show_vty_link_subtlv_llri(struct vty *vty, + struct te_tlv_header *tlvh) { - struct te_link_subtlv_llri *top; + struct te_link_subtlv_llri *top; - top = (struct te_link_subtlv_llri *) tlvh; + top = (struct te_link_subtlv_llri *)tlvh; - if (vty != NULL) - { - vty_out (vty, " Link Local ID: %d\n",(u_int32_t)ntohl(top->local)); - vty_out (vty, " Link Remote ID: %d\n",(u_int32_t)ntohl(top->remote)); - } - else - { - zlog_debug (" Link Local ID: %d", (u_int32_t) ntohl (top->local)); - zlog_debug (" Link Remote ID: %d", (u_int32_t) ntohl (top->remote)); - } + if (vty != NULL) { + vty_out(vty, " Link Local ID: %d\n", + (u_int32_t)ntohl(top->local)); + vty_out(vty, " Link Remote ID: %d\n", + (u_int32_t)ntohl(top->remote)); + } else { + zlog_debug(" Link Local ID: %d", + (u_int32_t)ntohl(top->local)); + zlog_debug(" Link Remote ID: %d", + (u_int32_t)ntohl(top->remote)); + } - return TLV_SIZE (tlvh); + return TLV_SIZE(tlvh); } -static u_int16_t -show_vty_link_subtlv_rip (struct vty *vty, struct te_tlv_header *tlvh) +static u_int16_t show_vty_link_subtlv_rip(struct vty *vty, + struct te_tlv_header *tlvh) { - struct te_link_subtlv_rip *top; + struct te_link_subtlv_rip *top; - top = (struct te_link_subtlv_rip *) tlvh; + top = (struct te_link_subtlv_rip *)tlvh; - if (vty != NULL) - vty_out (vty, " Inter-AS TE Remote ASBR IP address: %s\n", - inet_ntoa(top->value)); - else - zlog_debug (" Inter-AS TE Remote ASBR IP address: %s", - inet_ntoa (top->value)); + if (vty != NULL) + vty_out(vty, " Inter-AS TE Remote ASBR IP address: %s\n", + inet_ntoa(top->value)); + else + zlog_debug(" Inter-AS TE Remote ASBR IP address: %s", + inet_ntoa(top->value)); - return TLV_SIZE (tlvh); + return TLV_SIZE(tlvh); } -static u_int16_t -show_vty_link_subtlv_ras (struct vty *vty, struct te_tlv_header *tlvh) +static u_int16_t show_vty_link_subtlv_ras(struct vty *vty, + struct te_tlv_header *tlvh) { - struct te_link_subtlv_ras *top; + struct te_link_subtlv_ras *top; - top = (struct te_link_subtlv_ras *) tlvh; + top = (struct te_link_subtlv_ras *)tlvh; - if (vty != NULL) - vty_out (vty, " Inter-AS TE Remote AS number: %u\n",ntohl(top->value)); - else - zlog_debug (" Inter-AS TE Remote AS number: %u", ntohl (top->value)); + if (vty != NULL) + vty_out(vty, " Inter-AS TE Remote AS number: %u\n", + ntohl(top->value)); + else + zlog_debug(" Inter-AS TE Remote AS number: %u", + ntohl(top->value)); - return TLV_SIZE (tlvh); + return TLV_SIZE(tlvh); } -static u_int16_t -show_vty_link_subtlv_av_delay (struct vty *vty, struct te_tlv_header *tlvh) +static u_int16_t show_vty_link_subtlv_av_delay(struct vty *vty, + struct te_tlv_header *tlvh) { - struct te_link_subtlv_av_delay *top; - u_int32_t delay; - u_int32_t anomalous; + struct te_link_subtlv_av_delay *top; + u_int32_t delay; + u_int32_t anomalous; - top = (struct te_link_subtlv_av_delay *) tlvh; - delay = (u_int32_t) ntohl (top->value) & TE_EXT_MASK; - anomalous = (u_int32_t) ntohl (top->value) & TE_EXT_ANORMAL; + top = (struct te_link_subtlv_av_delay *)tlvh; + delay = (u_int32_t)ntohl(top->value) & TE_EXT_MASK; + anomalous = (u_int32_t)ntohl(top->value) & TE_EXT_ANORMAL; - if (vty != NULL) - vty_out (vty, " %s Average Link Delay: %d (micro-sec)\n", - anomalous ? "Anomalous" : "Normal", delay); - else - zlog_debug (" %s Average Link Delay: %d (micro-sec)", - anomalous ? "Anomalous" : "Normal", delay); + if (vty != NULL) + vty_out(vty, " %s Average Link Delay: %d (micro-sec)\n", + anomalous ? "Anomalous" : "Normal", delay); + else + zlog_debug(" %s Average Link Delay: %d (micro-sec)", + anomalous ? "Anomalous" : "Normal", delay); - return TLV_SIZE (tlvh); + return TLV_SIZE(tlvh); } -static u_int16_t -show_vty_link_subtlv_mm_delay (struct vty *vty, struct te_tlv_header *tlvh) +static u_int16_t show_vty_link_subtlv_mm_delay(struct vty *vty, + struct te_tlv_header *tlvh) { - struct te_link_subtlv_mm_delay *top; - u_int32_t low, high; - u_int32_t anomalous; + struct te_link_subtlv_mm_delay *top; + u_int32_t low, high; + u_int32_t anomalous; - top = (struct te_link_subtlv_mm_delay *) tlvh; - low = (u_int32_t) ntohl (top->low) & TE_EXT_MASK; - anomalous = (u_int32_t) ntohl (top->low) & TE_EXT_ANORMAL; - high = (u_int32_t) ntohl (top->high); + top = (struct te_link_subtlv_mm_delay *)tlvh; + low = (u_int32_t)ntohl(top->low) & TE_EXT_MASK; + anomalous = (u_int32_t)ntohl(top->low) & TE_EXT_ANORMAL; + high = (u_int32_t)ntohl(top->high); - if (vty != NULL) - vty_out (vty, " %s Min/Max Link Delay: %d/%d (micro-sec)\n", - anomalous ? "Anomalous" : "Normal", low, high); - else - zlog_debug (" %s Min/Max Link Delay: %d/%d (micro-sec)", - anomalous ? "Anomalous" : "Normal", low, high); + if (vty != NULL) + vty_out(vty, " %s Min/Max Link Delay: %d/%d (micro-sec)\n", + anomalous ? "Anomalous" : "Normal", low, high); + else + zlog_debug(" %s Min/Max Link Delay: %d/%d (micro-sec)", + anomalous ? "Anomalous" : "Normal", low, high); - return TLV_SIZE (tlvh); + return TLV_SIZE(tlvh); } -static u_int16_t -show_vty_link_subtlv_delay_var (struct vty *vty, struct te_tlv_header *tlvh) +static u_int16_t show_vty_link_subtlv_delay_var(struct vty *vty, + struct te_tlv_header *tlvh) { - struct te_link_subtlv_delay_var *top; - u_int32_t jitter; + struct te_link_subtlv_delay_var *top; + u_int32_t jitter; - top = (struct te_link_subtlv_delay_var *) tlvh; - jitter = (u_int32_t) ntohl (top->value) & TE_EXT_MASK; + top = (struct te_link_subtlv_delay_var *)tlvh; + jitter = (u_int32_t)ntohl(top->value) & TE_EXT_MASK; - if (vty != NULL) - vty_out (vty, " Delay Variation: %d (micro-sec)\n", jitter); - else - zlog_debug (" Delay Variation: %d (micro-sec)", jitter); + if (vty != NULL) + vty_out(vty, " Delay Variation: %d (micro-sec)\n", jitter); + else + zlog_debug(" Delay Variation: %d (micro-sec)", jitter); - return TLV_SIZE (tlvh); + return TLV_SIZE(tlvh); } -static u_int16_t -show_vty_link_subtlv_pkt_loss (struct vty *vty, struct te_tlv_header *tlvh) +static u_int16_t show_vty_link_subtlv_pkt_loss(struct vty *vty, + struct te_tlv_header *tlvh) { - struct te_link_subtlv_pkt_loss *top; - u_int32_t loss; - u_int32_t anomalous; - float fval; + struct te_link_subtlv_pkt_loss *top; + u_int32_t loss; + u_int32_t anomalous; + float fval; - top = (struct te_link_subtlv_pkt_loss *) tlvh; - loss = (u_int32_t) ntohl (top->value) & TE_EXT_MASK; - fval = (float) (loss * LOSS_PRECISION); - anomalous = (u_int32_t) ntohl (top->value) & TE_EXT_ANORMAL; + top = (struct te_link_subtlv_pkt_loss *)tlvh; + loss = (u_int32_t)ntohl(top->value) & TE_EXT_MASK; + fval = (float)(loss * LOSS_PRECISION); + anomalous = (u_int32_t)ntohl(top->value) & TE_EXT_ANORMAL; - if (vty != NULL) - vty_out (vty, " %s Link Loss: %g (%%)\n", anomalous ? "Anomalous" : "Normal", - fval); - else - zlog_debug (" %s Link Loss: %g (%%)", anomalous ? "Anomalous" : "Normal", - fval); + if (vty != NULL) + vty_out(vty, " %s Link Loss: %g (%%)\n", + anomalous ? "Anomalous" : "Normal", fval); + else + zlog_debug(" %s Link Loss: %g (%%)", + anomalous ? "Anomalous" : "Normal", fval); - return TLV_SIZE (tlvh); + return TLV_SIZE(tlvh); } -static u_int16_t -show_vty_link_subtlv_res_bw (struct vty *vty, struct te_tlv_header *tlvh) +static u_int16_t show_vty_link_subtlv_res_bw(struct vty *vty, + struct te_tlv_header *tlvh) { - struct te_link_subtlv_res_bw *top; - float fval; - - top = (struct te_link_subtlv_res_bw *) tlvh; - fval = ntohf (top->value); + struct te_link_subtlv_res_bw *top; + float fval; - if (vty != NULL) - vty_out (vty, " Unidirectional Residual Bandwidth: %g (Bytes/sec)\n", - fval); - else - zlog_debug (" Unidirectional Residual Bandwidth: %g (Bytes/sec)", - fval); + top = (struct te_link_subtlv_res_bw *)tlvh; + fval = ntohf(top->value); - return TLV_SIZE (tlvh); -} - -static u_int16_t -show_vty_link_subtlv_ava_bw (struct vty *vty, struct te_tlv_header *tlvh) -{ - struct te_link_subtlv_ava_bw *top; - float fval; - - top = (struct te_link_subtlv_ava_bw *) tlvh; - fval = ntohf (top->value); - - if (vty != NULL) - vty_out (vty, " Unidirectional Available Bandwidth: %g (Bytes/sec)\n", - fval); - else - zlog_debug (" Unidirectional Available Bandwidth: %g (Bytes/sec)", - fval); - - return TLV_SIZE (tlvh); -} - -static u_int16_t -show_vty_link_subtlv_use_bw (struct vty *vty, struct te_tlv_header *tlvh) -{ - struct te_link_subtlv_use_bw *top; - float fval; - - top = (struct te_link_subtlv_use_bw *) tlvh; - fval = ntohf (top->value); - - if (vty != NULL) - vty_out (vty, " Unidirectional Utilized Bandwidth: %g (Bytes/sec)\n", - fval); - else - zlog_debug (" Unidirectional Utilized Bandwidth: %g (Bytes/sec)", - fval); - - return TLV_SIZE (tlvh); -} - -static u_int16_t -show_vty_unknown_tlv (struct vty *vty, struct te_tlv_header *tlvh) -{ - if (vty != NULL) - vty_out (vty, " Unknown TLV: [type(0x%x), length(0x%x)]\n", - ntohs (tlvh->type), ntohs(tlvh->length)); - else - zlog_debug (" Unknown TLV: [type(0x%x), length(0x%x)]", - ntohs (tlvh->type), ntohs (tlvh->length)); - - return TLV_SIZE (tlvh); -} - -static u_int16_t -ospf_mpls_te_show_link_subtlv (struct vty *vty, struct te_tlv_header *tlvh0, - u_int16_t subtotal, u_int16_t total) -{ - struct te_tlv_header *tlvh, *next; - u_int16_t sum = subtotal; - - for (tlvh = tlvh0; sum < total; tlvh = (next ? next : TLV_HDR_NEXT (tlvh))) - { - next = NULL; - switch (ntohs (tlvh->type)) - { - case TE_LINK_SUBTLV_LINK_TYPE: - sum += show_vty_link_subtlv_link_type (vty, tlvh); - break; - case TE_LINK_SUBTLV_LINK_ID: - sum += show_vty_link_subtlv_link_id (vty, tlvh); - break; - case TE_LINK_SUBTLV_LCLIF_IPADDR: - sum += show_vty_link_subtlv_lclif_ipaddr (vty, tlvh); - break; - case TE_LINK_SUBTLV_RMTIF_IPADDR: - sum += show_vty_link_subtlv_rmtif_ipaddr (vty, tlvh); - break; - case TE_LINK_SUBTLV_TE_METRIC: - sum += show_vty_link_subtlv_te_metric (vty, tlvh); - break; - case TE_LINK_SUBTLV_MAX_BW: - sum += show_vty_link_subtlv_max_bw (vty, tlvh); - break; - case TE_LINK_SUBTLV_MAX_RSV_BW: - sum += show_vty_link_subtlv_max_rsv_bw (vty, tlvh); - break; - case TE_LINK_SUBTLV_UNRSV_BW: - sum += show_vty_link_subtlv_unrsv_bw (vty, tlvh); - break; - case TE_LINK_SUBTLV_RSC_CLSCLR: - sum += show_vty_link_subtlv_rsc_clsclr (vty, tlvh); - break; - case TE_LINK_SUBTLV_LRRID: - sum += show_vty_link_subtlv_lrrid (vty, tlvh); - break; - case TE_LINK_SUBTLV_LLRI: - sum += show_vty_link_subtlv_llri (vty, tlvh); - break; - case TE_LINK_SUBTLV_RIP: - sum += show_vty_link_subtlv_rip (vty, tlvh); - break; - case TE_LINK_SUBTLV_RAS: - sum += show_vty_link_subtlv_ras (vty, tlvh); - break; - case TE_LINK_SUBTLV_AV_DELAY: - sum += show_vty_link_subtlv_av_delay (vty, tlvh); - break; - case TE_LINK_SUBTLV_MM_DELAY: - sum += show_vty_link_subtlv_mm_delay (vty, tlvh); - break; - case TE_LINK_SUBTLV_DELAY_VAR: - sum += show_vty_link_subtlv_delay_var (vty, tlvh); - break; - case TE_LINK_SUBTLV_PKT_LOSS: - sum += show_vty_link_subtlv_pkt_loss (vty, tlvh); - break; - case TE_LINK_SUBTLV_RES_BW: - sum += show_vty_link_subtlv_res_bw (vty, tlvh); - break; - case TE_LINK_SUBTLV_AVA_BW: - sum += show_vty_link_subtlv_ava_bw (vty, tlvh); - break; - case TE_LINK_SUBTLV_USE_BW: - sum += show_vty_link_subtlv_use_bw (vty, tlvh); - break; - default: - sum += show_vty_unknown_tlv (vty, tlvh); - break; - } - } - return sum; -} - -static void -ospf_mpls_te_show_info (struct vty *vty, struct ospf_lsa *lsa) -{ - struct lsa_header *lsah = (struct lsa_header *) lsa->data; - struct te_tlv_header *tlvh, *next; - u_int16_t sum, total; - u_int16_t (* subfunc)(struct vty *vty, struct te_tlv_header *tlvh, - u_int16_t subtotal, u_int16_t total) = NULL; - - sum = 0; - total = ntohs (lsah->length) - OSPF_LSA_HEADER_SIZE; - - for (tlvh = TLV_HDR_TOP (lsah); sum < total; - tlvh = (next ? next : TLV_HDR_NEXT (tlvh))) - { - if (subfunc != NULL) - { - sum = (* subfunc)(vty, tlvh, sum, total); - next = (struct te_tlv_header *)((char *) tlvh + sum); - subfunc = NULL; - continue; - } - - next = NULL; - switch (ntohs (tlvh->type)) - { - case TE_TLV_ROUTER_ADDR: - sum += show_vty_router_addr (vty, tlvh); - break; - case TE_TLV_LINK: - sum += show_vty_link_header (vty, tlvh); - subfunc = ospf_mpls_te_show_link_subtlv; - next = tlvh + 1; - break; - default: - sum += show_vty_unknown_tlv (vty, tlvh); - break; - } - } - return; -} - -static void -ospf_mpls_te_config_write_router (struct vty *vty) -{ - - if (OspfMplsTE.status == enabled) - { - vty_out (vty, " mpls-te on\n"); - vty_out (vty, " mpls-te router-address %s\n", - inet_ntoa(OspfMplsTE.router_addr.value)); - } - - if (OspfMplsTE.inter_as == AS) - vty_out (vty, " mpls-te inter-as as\n"); - if (OspfMplsTE.inter_as == Area) - vty_out (vty, " mpls-te inter-as area %s \n", - inet_ntoa(OspfMplsTE.interas_areaid)); - - return; + if (vty != NULL) + vty_out(vty, + " Unidirectional Residual Bandwidth: %g (Bytes/sec)\n", + fval); + else + zlog_debug( + " Unidirectional Residual Bandwidth: %g (Bytes/sec)", + fval); + + return TLV_SIZE(tlvh); +} + +static u_int16_t show_vty_link_subtlv_ava_bw(struct vty *vty, + struct te_tlv_header *tlvh) +{ + struct te_link_subtlv_ava_bw *top; + float fval; + + top = (struct te_link_subtlv_ava_bw *)tlvh; + fval = ntohf(top->value); + + if (vty != NULL) + vty_out(vty, + " Unidirectional Available Bandwidth: %g (Bytes/sec)\n", + fval); + else + zlog_debug( + " Unidirectional Available Bandwidth: %g (Bytes/sec)", + fval); + + return TLV_SIZE(tlvh); +} + +static u_int16_t show_vty_link_subtlv_use_bw(struct vty *vty, + struct te_tlv_header *tlvh) +{ + struct te_link_subtlv_use_bw *top; + float fval; + + top = (struct te_link_subtlv_use_bw *)tlvh; + fval = ntohf(top->value); + + if (vty != NULL) + vty_out(vty, + " Unidirectional Utilized Bandwidth: %g (Bytes/sec)\n", + fval); + else + zlog_debug( + " Unidirectional Utilized Bandwidth: %g (Bytes/sec)", + fval); + + return TLV_SIZE(tlvh); +} + +static u_int16_t show_vty_unknown_tlv(struct vty *vty, + struct te_tlv_header *tlvh) +{ + if (vty != NULL) + vty_out(vty, " Unknown TLV: [type(0x%x), length(0x%x)]\n", + ntohs(tlvh->type), ntohs(tlvh->length)); + else + zlog_debug(" Unknown TLV: [type(0x%x), length(0x%x)]", + ntohs(tlvh->type), ntohs(tlvh->length)); + + return TLV_SIZE(tlvh); +} + +static u_int16_t ospf_mpls_te_show_link_subtlv(struct vty *vty, + struct te_tlv_header *tlvh0, + u_int16_t subtotal, + u_int16_t total) +{ + struct te_tlv_header *tlvh, *next; + u_int16_t sum = subtotal; + + for (tlvh = tlvh0; sum < total; + tlvh = (next ? next : TLV_HDR_NEXT(tlvh))) { + next = NULL; + switch (ntohs(tlvh->type)) { + case TE_LINK_SUBTLV_LINK_TYPE: + sum += show_vty_link_subtlv_link_type(vty, tlvh); + break; + case TE_LINK_SUBTLV_LINK_ID: + sum += show_vty_link_subtlv_link_id(vty, tlvh); + break; + case TE_LINK_SUBTLV_LCLIF_IPADDR: + sum += show_vty_link_subtlv_lclif_ipaddr(vty, tlvh); + break; + case TE_LINK_SUBTLV_RMTIF_IPADDR: + sum += show_vty_link_subtlv_rmtif_ipaddr(vty, tlvh); + break; + case TE_LINK_SUBTLV_TE_METRIC: + sum += show_vty_link_subtlv_te_metric(vty, tlvh); + break; + case TE_LINK_SUBTLV_MAX_BW: + sum += show_vty_link_subtlv_max_bw(vty, tlvh); + break; + case TE_LINK_SUBTLV_MAX_RSV_BW: + sum += show_vty_link_subtlv_max_rsv_bw(vty, tlvh); + break; + case TE_LINK_SUBTLV_UNRSV_BW: + sum += show_vty_link_subtlv_unrsv_bw(vty, tlvh); + break; + case TE_LINK_SUBTLV_RSC_CLSCLR: + sum += show_vty_link_subtlv_rsc_clsclr(vty, tlvh); + break; + case TE_LINK_SUBTLV_LRRID: + sum += show_vty_link_subtlv_lrrid(vty, tlvh); + break; + case TE_LINK_SUBTLV_LLRI: + sum += show_vty_link_subtlv_llri(vty, tlvh); + break; + case TE_LINK_SUBTLV_RIP: + sum += show_vty_link_subtlv_rip(vty, tlvh); + break; + case TE_LINK_SUBTLV_RAS: + sum += show_vty_link_subtlv_ras(vty, tlvh); + break; + case TE_LINK_SUBTLV_AV_DELAY: + sum += show_vty_link_subtlv_av_delay(vty, tlvh); + break; + case TE_LINK_SUBTLV_MM_DELAY: + sum += show_vty_link_subtlv_mm_delay(vty, tlvh); + break; + case TE_LINK_SUBTLV_DELAY_VAR: + sum += show_vty_link_subtlv_delay_var(vty, tlvh); + break; + case TE_LINK_SUBTLV_PKT_LOSS: + sum += show_vty_link_subtlv_pkt_loss(vty, tlvh); + break; + case TE_LINK_SUBTLV_RES_BW: + sum += show_vty_link_subtlv_res_bw(vty, tlvh); + break; + case TE_LINK_SUBTLV_AVA_BW: + sum += show_vty_link_subtlv_ava_bw(vty, tlvh); + break; + case TE_LINK_SUBTLV_USE_BW: + sum += show_vty_link_subtlv_use_bw(vty, tlvh); + break; + default: + sum += show_vty_unknown_tlv(vty, tlvh); + break; + } + } + return sum; +} + +static void ospf_mpls_te_show_info(struct vty *vty, struct ospf_lsa *lsa) +{ + struct lsa_header *lsah = (struct lsa_header *)lsa->data; + struct te_tlv_header *tlvh, *next; + u_int16_t sum, total; + u_int16_t (*subfunc)(struct vty * vty, struct te_tlv_header * tlvh, + u_int16_t subtotal, u_int16_t total) = NULL; + + sum = 0; + total = ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE; + + for (tlvh = TLV_HDR_TOP(lsah); sum < total; + tlvh = (next ? next : TLV_HDR_NEXT(tlvh))) { + if (subfunc != NULL) { + sum = (*subfunc)(vty, tlvh, sum, total); + next = (struct te_tlv_header *)((char *)tlvh + sum); + subfunc = NULL; + continue; + } + + next = NULL; + switch (ntohs(tlvh->type)) { + case TE_TLV_ROUTER_ADDR: + sum += show_vty_router_addr(vty, tlvh); + break; + case TE_TLV_LINK: + sum += show_vty_link_header(vty, tlvh); + subfunc = ospf_mpls_te_show_link_subtlv; + next = tlvh + 1; + break; + default: + sum += show_vty_unknown_tlv(vty, tlvh); + break; + } + } + return; +} + +static void ospf_mpls_te_config_write_router(struct vty *vty) +{ + + if (OspfMplsTE.status == enabled) { + vty_out(vty, " mpls-te on\n"); + vty_out(vty, " mpls-te router-address %s\n", + inet_ntoa(OspfMplsTE.router_addr.value)); + } + + if (OspfMplsTE.inter_as == AS) + vty_out(vty, " mpls-te inter-as as\n"); + if (OspfMplsTE.inter_as == Area) + vty_out(vty, " mpls-te inter-as area %s \n", + inet_ntoa(OspfMplsTE.interas_areaid)); + + return; } /*------------------------------------------------------------------------* @@ -2254,34 +2235,33 @@ DEFUN (ospf_mpls_te_on, MPLS_TE_STR "Enable the MPLS-TE functionality\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - struct listnode *node; - struct mpls_te_link *lp; + VTY_DECLVAR_CONTEXT(ospf, ospf); + struct listnode *node; + struct mpls_te_link *lp; - if (OspfMplsTE.status == enabled) - return CMD_SUCCESS; + if (OspfMplsTE.status == enabled) + return CMD_SUCCESS; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("MPLS-TE: OFF -> ON"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("MPLS-TE: OFF -> ON"); - OspfMplsTE.status = enabled; + OspfMplsTE.status = enabled; - /* Reoriginate RFC3630 & RFC6827 Links */ - ospf_mpls_te_foreach_area (ospf_mpls_te_lsa_schedule, REORIGINATE_THIS_LSA); + /* Reoriginate RFC3630 & RFC6827 Links */ + ospf_mpls_te_foreach_area(ospf_mpls_te_lsa_schedule, + REORIGINATE_THIS_LSA); - /* Reoriginate LSA if INTER-AS is always on */ - if (OspfMplsTE.inter_as != Disable) - { - for (ALL_LIST_ELEMENTS_RO (OspfMplsTE.iflist, node, lp)) - { - if (IS_INTER_AS (lp->type)) - { - ospf_mpls_te_lsa_schedule (lp, REORIGINATE_THIS_LSA); - } - } - } + /* Reoriginate LSA if INTER-AS is always on */ + if (OspfMplsTE.inter_as != Disable) { + for (ALL_LIST_ELEMENTS_RO(OspfMplsTE.iflist, node, lp)) { + if (IS_INTER_AS(lp->type)) { + ospf_mpls_te_lsa_schedule(lp, + REORIGINATE_THIS_LSA); + } + } + } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ospf_mpls_te, @@ -2291,23 +2271,24 @@ DEFUN (no_ospf_mpls_te, MPLS_TE_STR "Disable the MPLS-TE functionality\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - struct listnode *node, *nnode; - struct mpls_te_link *lp; + VTY_DECLVAR_CONTEXT(ospf, ospf); + struct listnode *node, *nnode; + struct mpls_te_link *lp; - if (OspfMplsTE.status == disabled) - return CMD_SUCCESS; + if (OspfMplsTE.status == disabled) + return CMD_SUCCESS; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("MPLS-TE: ON -> OFF"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("MPLS-TE: ON -> OFF"); - OspfMplsTE.status = disabled; + OspfMplsTE.status = disabled; - for (ALL_LIST_ELEMENTS (OspfMplsTE.iflist, node, nnode, lp)) - if CHECK_FLAG (lp->flags, LPFLG_LSA_ENGAGED) - ospf_mpls_te_lsa_schedule (lp, FLUSH_THIS_LSA); + for (ALL_LIST_ELEMENTS(OspfMplsTE.iflist, node, nnode, lp)) + if + CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED) + ospf_mpls_te_lsa_schedule(lp, FLUSH_THIS_LSA); - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -2318,127 +2299,118 @@ DEFUN (ospf_mpls_te_router_addr, "Stable IP address of the advertising router\n" "MPLS-TE router address in IPv4 address format\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4 = 2; - struct te_tlv_router_addr *ra = &OspfMplsTE.router_addr; - struct in_addr value; - - if (! inet_aton (argv[idx_ipv4]->arg, &value)) - { - vty_out (vty, "Please specify Router-Addr by A.B.C.D\n"); - return CMD_WARNING; - } - - if (ntohs (ra->header.type) == 0 - || ntohl (ra->value.s_addr) != ntohl (value.s_addr)) - { - struct listnode *node, *nnode; - struct mpls_te_link *lp; - int need_to_reoriginate = 0; - - set_mpls_te_router_addr (value); - - if (OspfMplsTE.status == disabled) - goto out; - - for (ALL_LIST_ELEMENTS (OspfMplsTE.iflist, node, nnode, lp)) - { - if ((lp->area == NULL) || IS_FLOOD_AS (lp->type)) - continue; - - if (!CHECK_FLAG (lp->flags, LPFLG_LSA_ENGAGED)) - { - need_to_reoriginate = 1; - break; - } - } - - for (ALL_LIST_ELEMENTS (OspfMplsTE.iflist, node, nnode, lp)) - { - if ((lp->area == NULL) || IS_FLOOD_AS (lp->type)) - continue; - - if (need_to_reoriginate) - SET_FLAG (lp->flags, LPFLG_LSA_FORCED_REFRESH); - else - ospf_mpls_te_lsa_schedule (lp, REFRESH_THIS_LSA); - } - - if (need_to_reoriginate) - ospf_mpls_te_foreach_area (ospf_mpls_te_lsa_schedule, REORIGINATE_THIS_LSA); - } + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4 = 2; + struct te_tlv_router_addr *ra = &OspfMplsTE.router_addr; + struct in_addr value; + + if (!inet_aton(argv[idx_ipv4]->arg, &value)) { + vty_out(vty, "Please specify Router-Addr by A.B.C.D\n"); + return CMD_WARNING; + } + + if (ntohs(ra->header.type) == 0 + || ntohl(ra->value.s_addr) != ntohl(value.s_addr)) { + struct listnode *node, *nnode; + struct mpls_te_link *lp; + int need_to_reoriginate = 0; + + set_mpls_te_router_addr(value); + + if (OspfMplsTE.status == disabled) + goto out; + + for (ALL_LIST_ELEMENTS(OspfMplsTE.iflist, node, nnode, lp)) { + if ((lp->area == NULL) || IS_FLOOD_AS(lp->type)) + continue; + + if (!CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED)) { + need_to_reoriginate = 1; + break; + } + } + + for (ALL_LIST_ELEMENTS(OspfMplsTE.iflist, node, nnode, lp)) { + if ((lp->area == NULL) || IS_FLOOD_AS(lp->type)) + continue; + + if (need_to_reoriginate) + SET_FLAG(lp->flags, LPFLG_LSA_FORCED_REFRESH); + else + ospf_mpls_te_lsa_schedule(lp, REFRESH_THIS_LSA); + } + + if (need_to_reoriginate) + ospf_mpls_te_foreach_area(ospf_mpls_te_lsa_schedule, + REORIGINATE_THIS_LSA); + } out: - return CMD_SUCCESS; -} - -static int -set_inter_as_mode (struct vty *vty, const char *mode_name, - const char *area_id) -{ - enum inter_as_mode mode; - struct listnode *node; - struct mpls_te_link *lp; - int format; - - if (OspfMplsTE.status == enabled) - { - - /* Read and Check inter_as mode */ - if (strcmp (mode_name, "as") == 0) - mode = AS; - else if (strcmp (mode_name, "area") == 0) - { - mode = Area; - VTY_GET_OSPF_AREA_ID (OspfMplsTE.interas_areaid, format, area_id); - } - else - { - vty_out (vty,"Unknown mode. Please choose between as or area\n"); - return CMD_WARNING; - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("MPLS-TE: Inter-AS enable with %s flooding support", - mode2text[mode]); - - /* Register new callbacks regarding the flooding scope (AS or Area) */ - if (ospf_mpls_te_register (mode) < 0) - { - vty_out (vty, - "Internal error: Unable to register Inter-AS functions\n"); - return CMD_WARNING; - } - - /* Enable mode and re-originate LSA if needed */ - if ((OspfMplsTE.inter_as == Disable) && (mode != OspfMplsTE.inter_as)) - { - OspfMplsTE.inter_as = mode; - /* Re-originate all InterAS-TEv2 LSA */ - for (ALL_LIST_ELEMENTS_RO (OspfMplsTE.iflist, node, lp)) - { - if (IS_INTER_AS (lp->type)) - { - if (mode == AS) - lp->type |= FLOOD_AS; - else - lp->type |= FLOOD_AREA; - ospf_mpls_te_lsa_schedule (lp, REORIGINATE_THIS_LSA); - } - } - } - else - { - vty_out (vty, "Please change Inter-AS support to disable first before going to mode %s\n", - mode2text[mode]); - return CMD_WARNING; - } - } - else - { - vty_out (vty, "mpls-te has not been turned on\n"); - return CMD_WARNING; - } - return CMD_SUCCESS; + return CMD_SUCCESS; +} + +static int set_inter_as_mode(struct vty *vty, const char *mode_name, + const char *area_id) +{ + enum inter_as_mode mode; + struct listnode *node; + struct mpls_te_link *lp; + int format; + + if (OspfMplsTE.status == enabled) { + + /* Read and Check inter_as mode */ + if (strcmp(mode_name, "as") == 0) + mode = AS; + else if (strcmp(mode_name, "area") == 0) { + mode = Area; + VTY_GET_OSPF_AREA_ID(OspfMplsTE.interas_areaid, format, + area_id); + } else { + vty_out(vty, + "Unknown mode. Please choose between as or area\n"); + return CMD_WARNING; + } + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "MPLS-TE: Inter-AS enable with %s flooding support", + mode2text[mode]); + + /* Register new callbacks regarding the flooding scope (AS or + * Area) */ + if (ospf_mpls_te_register(mode) < 0) { + vty_out(vty, + "Internal error: Unable to register Inter-AS functions\n"); + return CMD_WARNING; + } + + /* Enable mode and re-originate LSA if needed */ + if ((OspfMplsTE.inter_as == Disable) + && (mode != OspfMplsTE.inter_as)) { + OspfMplsTE.inter_as = mode; + /* Re-originate all InterAS-TEv2 LSA */ + for (ALL_LIST_ELEMENTS_RO(OspfMplsTE.iflist, node, + lp)) { + if (IS_INTER_AS(lp->type)) { + if (mode == AS) + lp->type |= FLOOD_AS; + else + lp->type |= FLOOD_AREA; + ospf_mpls_te_lsa_schedule( + lp, REORIGINATE_THIS_LSA); + } + } + } else { + vty_out(vty, + "Please change Inter-AS support to disable first before going to mode %s\n", + mode2text[mode]); + return CMD_WARNING; + } + } else { + vty_out(vty, "mpls-te has not been turned on\n"); + return CMD_WARNING; + } + return CMD_SUCCESS; } @@ -2449,7 +2421,7 @@ DEFUN (ospf_mpls_te_inter_as_as, "Configure MPLS-TE Inter-AS support\n" "AS native mode self originate INTER_AS LSA with Type 11 (as flooding scope)\n") { - return set_inter_as_mode (vty, "as", ""); + return set_inter_as_mode(vty, "as", ""); } DEFUN (ospf_mpls_te_inter_as_area, @@ -2461,8 +2433,8 @@ DEFUN (ospf_mpls_te_inter_as_area, "OSPF area ID in IP format\n" "OSPF area ID as decimal value\n") { - int idx_ipv4_number = 3; - return set_inter_as_mode (vty, "area", argv[idx_ipv4_number]->arg); + int idx_ipv4_number = 3; + return set_inter_as_mode(vty, "area", argv[idx_ipv4_number]->arg); } DEFUN (no_ospf_mpls_te_inter_as, @@ -2473,25 +2445,26 @@ DEFUN (no_ospf_mpls_te_inter_as, "Disable MPLS-TE Inter-AS support\n") { - struct listnode *node, *nnode; - struct mpls_te_link *lp; + struct listnode *node, *nnode; + struct mpls_te_link *lp; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("MPLS-TE: Inter-AS support OFF"); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("MPLS-TE: Inter-AS support OFF"); - if ((OspfMplsTE.status == enabled) && (OspfMplsTE.inter_as != Disable)) - { - OspfMplsTE.inter_as = Disable; - /* Flush all Inter-AS LSA */ - for (ALL_LIST_ELEMENTS (OspfMplsTE.iflist, node, nnode, lp)) - if (IS_INTER_AS (lp->type) && CHECK_FLAG (lp->flags, LPFLG_LSA_ENGAGED)) - ospf_mpls_te_lsa_schedule (lp, FLUSH_THIS_LSA); - } + if ((OspfMplsTE.status == enabled) + && (OspfMplsTE.inter_as != Disable)) { + OspfMplsTE.inter_as = Disable; + /* Flush all Inter-AS LSA */ + for (ALL_LIST_ELEMENTS(OspfMplsTE.iflist, node, nnode, lp)) + if (IS_INTER_AS(lp->type) + && CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED)) + ospf_mpls_te_lsa_schedule(lp, FLUSH_THIS_LSA); + } - /* Deregister the Callbacks for Inter-AS suport */ - ospf_mpls_te_unregister (); + /* Deregister the Callbacks for Inter-AS suport */ + ospf_mpls_te_unregister(); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (show_ip_ospf_mpls_te_router, @@ -2503,97 +2476,100 @@ DEFUN (show_ip_ospf_mpls_te_router, "MPLS-TE information\n" "MPLS-TE Router parameters\n") { - if (OspfMplsTE.status == enabled) - { - vty_out (vty, "--- MPLS-TE router parameters ---\n"); - - if (ntohs (OspfMplsTE.router_addr.header.type) != 0) - show_vty_router_addr (vty, &OspfMplsTE.router_addr.header); - else if (vty != NULL) - vty_out (vty, " N/A\n"); - } - return CMD_SUCCESS; -} - -static void -show_mpls_te_link_sub (struct vty *vty, struct interface *ifp) -{ - struct mpls_te_link *lp; - - if ((OspfMplsTE.status == enabled) - && HAS_LINK_PARAMS(ifp) - && !if_is_loopback (ifp) - && if_is_up (ifp) - && ((lp = lookup_linkparams_by_ifp (ifp)) != NULL)) - { - /* Continue only if interface is not passive or support Inter-AS TEv2 */ - if (!(ospf_oi_count (ifp) > 0)) - { - if (IS_INTER_AS (lp->type)) - { - vty_out (vty, "-- Inter-AS TEv2 link parameters for %s --\n", - ifp->name); - } - else - { - /* MPLS-TE is not activate on this interface */ - /* or this interface is passive and Inter-AS TEv2 is not activate */ - vty_out (vty, " %s: MPLS-TE is disabled on this interface\n", - ifp->name); - return; - } - } - else - { - vty_out (vty, "-- MPLS-TE link parameters for %s --\n", - ifp->name); - } - - if (TLV_TYPE(lp->link_type) != 0) - show_vty_link_subtlv_link_type (vty, &lp->link_type.header); - if (TLV_TYPE(lp->link_id) != 0) - show_vty_link_subtlv_link_id (vty, &lp->link_id.header); - if (TLV_TYPE(lp->lclif_ipaddr) != 0) - show_vty_link_subtlv_lclif_ipaddr (vty, &lp->lclif_ipaddr.header); - if (TLV_TYPE(lp->rmtif_ipaddr) != 0) - show_vty_link_subtlv_rmtif_ipaddr (vty, &lp->rmtif_ipaddr.header); - if (TLV_TYPE(lp->rip) != 0) - show_vty_link_subtlv_rip (vty, &lp->rip.header); - if (TLV_TYPE(lp->ras) != 0) - show_vty_link_subtlv_ras (vty, &lp->ras.header); - if (TLV_TYPE(lp->te_metric) != 0) - show_vty_link_subtlv_te_metric (vty, &lp->te_metric.header); - if (TLV_TYPE(lp->max_bw) != 0) - show_vty_link_subtlv_max_bw (vty, &lp->max_bw.header); - if (TLV_TYPE(lp->max_rsv_bw) != 0) - show_vty_link_subtlv_max_rsv_bw (vty, &lp->max_rsv_bw.header); - if (TLV_TYPE(lp->unrsv_bw) != 0) - show_vty_link_subtlv_unrsv_bw (vty, &lp->unrsv_bw.header); - if (TLV_TYPE(lp->rsc_clsclr) != 0) - show_vty_link_subtlv_rsc_clsclr (vty, &lp->rsc_clsclr.header); - if (TLV_TYPE(lp->av_delay) != 0) - show_vty_link_subtlv_av_delay (vty, &lp->av_delay.header); - if (TLV_TYPE(lp->mm_delay) != 0) - show_vty_link_subtlv_mm_delay (vty, &lp->mm_delay.header); - if (TLV_TYPE(lp->delay_var) != 0) - show_vty_link_subtlv_delay_var (vty, &lp->delay_var.header); - if (TLV_TYPE(lp->pkt_loss) != 0) - show_vty_link_subtlv_pkt_loss (vty, &lp->pkt_loss.header); - if (TLV_TYPE(lp->res_bw) != 0) - show_vty_link_subtlv_res_bw (vty, &lp->res_bw.header); - if (TLV_TYPE(lp->ava_bw) != 0) - show_vty_link_subtlv_ava_bw (vty, &lp->ava_bw.header); - if (TLV_TYPE(lp->use_bw) != 0) - show_vty_link_subtlv_use_bw (vty, &lp->use_bw.header); - vty_out (vty, "---------------\n\n"); - } - else - { - vty_out (vty, " %s: MPLS-TE is disabled on this interface\n", - ifp->name); - } - - return; + if (OspfMplsTE.status == enabled) { + vty_out(vty, "--- MPLS-TE router parameters ---\n"); + + if (ntohs(OspfMplsTE.router_addr.header.type) != 0) + show_vty_router_addr(vty, + &OspfMplsTE.router_addr.header); + else if (vty != NULL) + vty_out(vty, " N/A\n"); + } + return CMD_SUCCESS; +} + +static void show_mpls_te_link_sub(struct vty *vty, struct interface *ifp) +{ + struct mpls_te_link *lp; + + if ((OspfMplsTE.status == enabled) && HAS_LINK_PARAMS(ifp) + && !if_is_loopback(ifp) && if_is_up(ifp) + && ((lp = lookup_linkparams_by_ifp(ifp)) != NULL)) { + /* Continue only if interface is not passive or support Inter-AS + * TEv2 */ + if (!(ospf_oi_count(ifp) > 0)) { + if (IS_INTER_AS(lp->type)) { + vty_out(vty, + "-- Inter-AS TEv2 link parameters for %s --\n", + ifp->name); + } else { + /* MPLS-TE is not activate on this interface */ + /* or this interface is passive and Inter-AS + * TEv2 is not activate */ + vty_out(vty, + " %s: MPLS-TE is disabled on this interface\n", + ifp->name); + return; + } + } else { + vty_out(vty, "-- MPLS-TE link parameters for %s --\n", + ifp->name); + } + + if (TLV_TYPE(lp->link_type) != 0) + show_vty_link_subtlv_link_type(vty, + &lp->link_type.header); + if (TLV_TYPE(lp->link_id) != 0) + show_vty_link_subtlv_link_id(vty, &lp->link_id.header); + if (TLV_TYPE(lp->lclif_ipaddr) != 0) + show_vty_link_subtlv_lclif_ipaddr( + vty, &lp->lclif_ipaddr.header); + if (TLV_TYPE(lp->rmtif_ipaddr) != 0) + show_vty_link_subtlv_rmtif_ipaddr( + vty, &lp->rmtif_ipaddr.header); + if (TLV_TYPE(lp->rip) != 0) + show_vty_link_subtlv_rip(vty, &lp->rip.header); + if (TLV_TYPE(lp->ras) != 0) + show_vty_link_subtlv_ras(vty, &lp->ras.header); + if (TLV_TYPE(lp->te_metric) != 0) + show_vty_link_subtlv_te_metric(vty, + &lp->te_metric.header); + if (TLV_TYPE(lp->max_bw) != 0) + show_vty_link_subtlv_max_bw(vty, &lp->max_bw.header); + if (TLV_TYPE(lp->max_rsv_bw) != 0) + show_vty_link_subtlv_max_rsv_bw(vty, + &lp->max_rsv_bw.header); + if (TLV_TYPE(lp->unrsv_bw) != 0) + show_vty_link_subtlv_unrsv_bw(vty, + &lp->unrsv_bw.header); + if (TLV_TYPE(lp->rsc_clsclr) != 0) + show_vty_link_subtlv_rsc_clsclr(vty, + &lp->rsc_clsclr.header); + if (TLV_TYPE(lp->av_delay) != 0) + show_vty_link_subtlv_av_delay(vty, + &lp->av_delay.header); + if (TLV_TYPE(lp->mm_delay) != 0) + show_vty_link_subtlv_mm_delay(vty, + &lp->mm_delay.header); + if (TLV_TYPE(lp->delay_var) != 0) + show_vty_link_subtlv_delay_var(vty, + &lp->delay_var.header); + if (TLV_TYPE(lp->pkt_loss) != 0) + show_vty_link_subtlv_pkt_loss(vty, + &lp->pkt_loss.header); + if (TLV_TYPE(lp->res_bw) != 0) + show_vty_link_subtlv_res_bw(vty, &lp->res_bw.header); + if (TLV_TYPE(lp->ava_bw) != 0) + show_vty_link_subtlv_ava_bw(vty, &lp->ava_bw.header); + if (TLV_TYPE(lp->use_bw) != 0) + show_vty_link_subtlv_use_bw(vty, &lp->use_bw.header); + vty_out(vty, "---------------\n\n"); + } else { + vty_out(vty, " %s: MPLS-TE is disabled on this interface\n", + ifp->name); + } + + return; } DEFUN (show_ip_ospf_mpls_te_link, @@ -2606,40 +2582,40 @@ DEFUN (show_ip_ospf_mpls_te_link, "Interface information\n" "Interface name\n") { - int idx_interface = 5; - struct interface *ifp; - struct listnode *node, *nnode; - - /* Show All Interfaces. */ - if (argc == 5) - { - for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), node, nnode, ifp)) - show_mpls_te_link_sub (vty, ifp); - } - /* Interface name is specified. */ - else - { - if ((ifp = if_lookup_by_name (argv[idx_interface]->arg, VRF_DEFAULT)) == NULL) - vty_out (vty, "No such interface name\n"); - else - show_mpls_te_link_sub (vty, ifp); - } - - return CMD_SUCCESS; -} - -static void -ospf_mpls_te_register_vty (void) -{ - install_element (VIEW_NODE, &show_ip_ospf_mpls_te_router_cmd); - install_element (VIEW_NODE, &show_ip_ospf_mpls_te_link_cmd); - - install_element (OSPF_NODE, &ospf_mpls_te_on_cmd); - install_element (OSPF_NODE, &no_ospf_mpls_te_cmd); - install_element (OSPF_NODE, &ospf_mpls_te_router_addr_cmd); - install_element (OSPF_NODE, &ospf_mpls_te_inter_as_cmd); - install_element (OSPF_NODE, &ospf_mpls_te_inter_as_area_cmd); - install_element (OSPF_NODE, &no_ospf_mpls_te_inter_as_cmd); - - return; + int idx_interface = 5; + struct interface *ifp; + struct listnode *node, *nnode; + + /* Show All Interfaces. */ + if (argc == 5) { + for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), node, nnode, + ifp)) + show_mpls_te_link_sub(vty, ifp); + } + /* Interface name is specified. */ + else { + if ((ifp = if_lookup_by_name(argv[idx_interface]->arg, + VRF_DEFAULT)) + == NULL) + vty_out(vty, "No such interface name\n"); + else + show_mpls_te_link_sub(vty, ifp); + } + + return CMD_SUCCESS; +} + +static void ospf_mpls_te_register_vty(void) +{ + install_element(VIEW_NODE, &show_ip_ospf_mpls_te_router_cmd); + install_element(VIEW_NODE, &show_ip_ospf_mpls_te_link_cmd); + + install_element(OSPF_NODE, &ospf_mpls_te_on_cmd); + install_element(OSPF_NODE, &no_ospf_mpls_te_cmd); + install_element(OSPF_NODE, &ospf_mpls_te_router_addr_cmd); + install_element(OSPF_NODE, &ospf_mpls_te_inter_as_cmd); + install_element(OSPF_NODE, &ospf_mpls_te_inter_as_area_cmd); + install_element(OSPF_NODE, &no_ospf_mpls_te_inter_as_cmd); + + return; } diff --git a/ospfd/ospf_te.h b/ospfd/ospf_te.h index 885180bc1..4ee9139a3 100644 --- a/ospfd/ospf_te.h +++ b/ospfd/ospf_te.h @@ -98,52 +98,45 @@ * Following section defines TLV (tag, length, value) structures, * used for Traffic Engineering. */ -struct te_tlv_header -{ - u_int16_t type; /* TE_TLV_XXX (see below) */ - u_int16_t length; /* Value portion only, in octets */ +struct te_tlv_header { + u_int16_t type; /* TE_TLV_XXX (see below) */ + u_int16_t length; /* Value portion only, in octets */ }; -#define TLV_HDR_SIZE \ - (sizeof (struct te_tlv_header)) +#define TLV_HDR_SIZE (sizeof(struct te_tlv_header)) -#define TLV_BODY_SIZE(tlvh) \ - (ROUNDUP (ntohs ((tlvh)->length), sizeof (u_int32_t))) +#define TLV_BODY_SIZE(tlvh) (ROUNDUP(ntohs((tlvh)->length), sizeof(u_int32_t))) -#define TLV_SIZE(tlvh) \ - (TLV_HDR_SIZE + TLV_BODY_SIZE(tlvh)) +#define TLV_SIZE(tlvh) (TLV_HDR_SIZE + TLV_BODY_SIZE(tlvh)) -#define TLV_HDR_TOP(lsah) \ +#define TLV_HDR_TOP(lsah) \ (struct te_tlv_header *)((char *)(lsah) + OSPF_LSA_HEADER_SIZE) -#define TLV_HDR_NEXT(tlvh) \ +#define TLV_HDR_NEXT(tlvh) \ (struct te_tlv_header *)((char *)(tlvh) + TLV_SIZE(tlvh)) -#define TLV_HDR_SUBTLV(tlvh) \ +#define TLV_HDR_SUBTLV(tlvh) \ (struct te_tlv_header *)((char *)(tlvh) + TLV_HDR_SIZE) #define TLV_TYPE(tlvh) tlvh.header.type #define TLV_LEN(tlvh) tlvh.header.length #define TLV_HDR(tlvh) tlvh.header - /* * Following section defines TLV body parts. */ /* Router Address TLV */ /* Mandatory */ #define TE_TLV_ROUTER_ADDR 1 -struct te_tlv_router_addr -{ - struct te_tlv_header header; /* Value length is 4 octets. */ - struct in_addr value; +struct te_tlv_router_addr { + struct te_tlv_header header; /* Value length is 4 octets. */ + struct in_addr value; }; /* Link TLV */ #define TE_TLV_LINK 2 -struct te_tlv_link -{ - struct te_tlv_header header; - /* A set of link-sub-TLVs will follow. */ +struct te_tlv_link { + struct te_tlv_header header; + /* A set of link-sub-TLVs will follow. */ }; #define TE_LINK_SUBTLV_DEF_SIZE 4 @@ -151,105 +144,94 @@ struct te_tlv_link /* Link Type Sub-TLV */ /* Mandatory */ #define TE_LINK_SUBTLV_LINK_TYPE 1 #define TE_LINK_SUBTLV_TYPE_SIZE 1 -struct te_link_subtlv_link_type -{ - struct te_tlv_header header; /* Value length is 1 octet. */ - struct - { +struct te_link_subtlv_link_type { + struct te_tlv_header header; /* Value length is 1 octet. */ + struct { #define LINK_TYPE_SUBTLV_VALUE_PTP 1 #define LINK_TYPE_SUBTLV_VALUE_MA 2 - u_char value; - u_char padding[3]; - } link_type; + u_char value; + u_char padding[3]; + } link_type; }; /* Link Sub-TLV: Link ID */ /* Mandatory */ #define TE_LINK_SUBTLV_LINK_ID 2 -struct te_link_subtlv_link_id -{ - struct te_tlv_header header; /* Value length is 4 octets. */ - struct in_addr value; /* Same as router-lsa's link-id. */ +struct te_link_subtlv_link_id { + struct te_tlv_header header; /* Value length is 4 octets. */ + struct in_addr value; /* Same as router-lsa's link-id. */ }; /* Link Sub-TLV: Local Interface IP Address */ /* Optional */ #define TE_LINK_SUBTLV_LCLIF_IPADDR 3 -struct te_link_subtlv_lclif_ipaddr -{ - struct te_tlv_header header; /* Value length is 4 x N octets. */ - struct in_addr value[1]; /* Local IP address(es). */ +struct te_link_subtlv_lclif_ipaddr { + struct te_tlv_header header; /* Value length is 4 x N octets. */ + struct in_addr value[1]; /* Local IP address(es). */ }; /* Link Sub-TLV: Remote Interface IP Address */ /* Optional */ #define TE_LINK_SUBTLV_RMTIF_IPADDR 4 -struct te_link_subtlv_rmtif_ipaddr -{ - struct te_tlv_header header; /* Value length is 4 x N octets. */ - struct in_addr value[1]; /* Neighbor's IP address(es). */ +struct te_link_subtlv_rmtif_ipaddr { + struct te_tlv_header header; /* Value length is 4 x N octets. */ + struct in_addr value[1]; /* Neighbor's IP address(es). */ }; /* Link Sub-TLV: Traffic Engineering Metric */ /* Optional */ #define TE_LINK_SUBTLV_TE_METRIC 5 -struct te_link_subtlv_te_metric -{ - struct te_tlv_header header; /* Value length is 4 octets. */ - u_int32_t value; /* Link metric for TE purpose. */ +struct te_link_subtlv_te_metric { + struct te_tlv_header header; /* Value length is 4 octets. */ + u_int32_t value; /* Link metric for TE purpose. */ }; /* Link Sub-TLV: Maximum Bandwidth */ /* Optional */ #define TE_LINK_SUBTLV_MAX_BW 6 -struct te_link_subtlv_max_bw -{ - struct te_tlv_header header; /* Value length is 4 octets. */ - float value; /* bytes/sec */ +struct te_link_subtlv_max_bw { + struct te_tlv_header header; /* Value length is 4 octets. */ + float value; /* bytes/sec */ }; /* Link Sub-TLV: Maximum Reservable Bandwidth */ /* Optional */ #define TE_LINK_SUBTLV_MAX_RSV_BW 7 -struct te_link_subtlv_max_rsv_bw -{ - struct te_tlv_header header; /* Value length is 4 octets. */ - float value; /* bytes/sec */ +struct te_link_subtlv_max_rsv_bw { + struct te_tlv_header header; /* Value length is 4 octets. */ + float value; /* bytes/sec */ }; /* Link Sub-TLV: Unreserved Bandwidth */ /* Optional */ #define TE_LINK_SUBTLV_UNRSV_BW 8 #define TE_LINK_SUBTLV_UNRSV_SIZE 32 -struct te_link_subtlv_unrsv_bw -{ - struct te_tlv_header header; /* Value length is 32 octets. */ - float value[MAX_CLASS_TYPE]; /* One for each priority level. */ +struct te_link_subtlv_unrsv_bw { + struct te_tlv_header header; /* Value length is 32 octets. */ + float value[MAX_CLASS_TYPE]; /* One for each priority level. */ }; /* Link Sub-TLV: Resource Class/Color */ /* Optional */ #define TE_LINK_SUBTLV_RSC_CLSCLR 9 -struct te_link_subtlv_rsc_clsclr -{ - struct te_tlv_header header; /* Value length is 4 octets. */ - u_int32_t value; /* Admin. group membership. */ +struct te_link_subtlv_rsc_clsclr { + struct te_tlv_header header; /* Value length is 4 octets. */ + u_int32_t value; /* Admin. group membership. */ }; /* For RFC6827 */ /* Local and Remote TE Router ID */ #define TE_LINK_SUBTLV_LRRID 10 #define TE_LINK_SUBTLV_LRRID_SIZE 8 -struct te_link_subtlv_lrrid -{ - struct te_tlv_header header; /* Value length is 8 octets. */ - struct in_addr local; /* Local TE Router Identifier */ - struct in_addr remote; /* Remote TE Router Identifier */ +struct te_link_subtlv_lrrid { + struct te_tlv_header header; /* Value length is 8 octets. */ + struct in_addr local; /* Local TE Router Identifier */ + struct in_addr remote; /* Remote TE Router Identifier */ }; /* RFC4203: Link Local/Remote Identifiers */ #define TE_LINK_SUBTLV_LLRI 11 #define TE_LINK_SUBTLV_LLRI_SIZE 8 -struct te_link_subtlv_llri -{ - struct te_tlv_header header; /* Value length is 8 octets. */ - u_int32_t local; /* Link Local Identifier */ - u_int32_t remote; /* Link Remote Identifier */ +struct te_link_subtlv_llri { + struct te_tlv_header header; /* Value length is 8 octets. */ + u_int32_t local; /* Link Local Identifier */ + u_int32_t remote; /* Link Remote Identifier */ }; -/* Inter-RA Export Upward sub-TLV (12) and Inter-RA Export Downward sub-TLV (13) (RFC6827bis) are not yet supported */ +/* Inter-RA Export Upward sub-TLV (12) and Inter-RA Export Downward sub-TLV (13) + * (RFC6827bis) are not yet supported */ /* SUBTLV 14-16 (RFC4203) are not yet supported */ /* Bandwidth Constraints sub-TLV (17) (RFC4124) is not yet supported */ /* SUBLV 18-20 are for OSPFv3 TE (RFC5329). see ospf6d */ @@ -257,18 +239,16 @@ struct te_link_subtlv_llri /* For RFC 5392 */ /* Remote AS Number sub-TLV */ #define TE_LINK_SUBTLV_RAS 21 -struct te_link_subtlv_ras -{ - struct te_tlv_header header; /* Value length is 4 octets. */ - u_int32_t value; /* Remote AS number */ +struct te_link_subtlv_ras { + struct te_tlv_header header; /* Value length is 4 octets. */ + u_int32_t value; /* Remote AS number */ }; /* IPv4 Remote ASBR ID Sub-TLV */ #define TE_LINK_SUBTLV_RIP 22 -struct te_link_subtlv_rip -{ - struct te_tlv_header header; /* Value length is 4 octets. */ - struct in_addr value; /* Remote ASBR IP address */ +struct te_link_subtlv_rip { + struct te_tlv_header header; /* Value length is 4 octets. */ + struct in_addr value; /* Remote ASBR IP address */ }; /* SUBTLV 24 is IPv6 Remote ASBR ID (RFC5392). see ospf6d */ @@ -280,63 +260,64 @@ struct te_link_subtlv_rip /* RFC7471 */ /* Link Sub-TLV: Average Link Delay */ /* Optional */ #define TE_LINK_SUBTLV_AV_DELAY 27 -struct te_link_subtlv_av_delay -{ - struct te_tlv_header header; /* Value length is 4 bytes. */ - u_int32_t value; /* delay in micro-seconds only 24 bits => 0 ... 16777215 - with Anomalous Bit as Upper most bit */ +struct te_link_subtlv_av_delay { + struct te_tlv_header header; /* Value length is 4 bytes. */ + u_int32_t + value; /* delay in micro-seconds only 24 bits => 0 ... 16777215 + with Anomalous Bit as Upper most bit */ }; /* Link Sub-TLV: Low/High Link Delay */ #define TE_LINK_SUBTLV_MM_DELAY 28 #define TE_LINK_SUBTLV_MM_DELAY_SIZE 8 -struct te_link_subtlv_mm_delay -{ - struct te_tlv_header header; /* Value length is 8 bytes. */ - u_int32_t low; /* low delay in micro-seconds only 24 bits => 0 ... 16777215 - with Anomalous Bit (A) as Upper most bit */ - u_int32_t high; /* high delay in micro-seconds only 24 bits => 0 ... 16777215 */ +struct te_link_subtlv_mm_delay { + struct te_tlv_header header; /* Value length is 8 bytes. */ + u_int32_t low; /* low delay in micro-seconds only 24 bits => 0 ... + 16777215 + with Anomalous Bit (A) as Upper most bit */ + u_int32_t high; /* high delay in micro-seconds only 24 bits => 0 ... + 16777215 */ }; /* Link Sub-TLV: Link Delay Variation i.e. Jitter */ #define TE_LINK_SUBTLV_DELAY_VAR 29 -struct te_link_subtlv_delay_var -{ - struct te_tlv_header header; /* Value length is 4 bytes. */ - u_int32_t value; /* interval in micro-seconds only 24 bits => 0 ... 16777215 */ +struct te_link_subtlv_delay_var { + struct te_tlv_header header; /* Value length is 4 bytes. */ + u_int32_t value; /* interval in micro-seconds only 24 bits => 0 ... + 16777215 */ }; /* Link Sub-TLV: Routine Unidirectional Link Packet Loss */ #define TE_LINK_SUBTLV_PKT_LOSS 30 -struct te_link_subtlv_pkt_loss -{ - struct te_tlv_header header; /* Value length is 4 bytes. */ - u_int32_t value; /* in percentage of total traffic only 24 bits (2^24 - 2) - with Anomalous Bit as Upper most bit */ +struct te_link_subtlv_pkt_loss { + struct te_tlv_header header; /* Value length is 4 bytes. */ + u_int32_t + value; /* in percentage of total traffic only 24 bits (2^24 - 2) + with Anomalous Bit as Upper most bit */ }; /* Link Sub-TLV: Unidirectional Residual Bandwidth */ /* Optional */ #define TE_LINK_SUBTLV_RES_BW 31 -struct te_link_subtlv_res_bw -{ - struct te_tlv_header header; /* Value length is 4 bytes. */ - float value; /* bandwidth in IEEE floating point format with units in bytes per second */ +struct te_link_subtlv_res_bw { + struct te_tlv_header header; /* Value length is 4 bytes. */ + float value; /* bandwidth in IEEE floating point format with units in + bytes per second */ }; /* Link Sub-TLV: Unidirectional Available Bandwidth */ /* Optional */ #define TE_LINK_SUBTLV_AVA_BW 32 -struct te_link_subtlv_ava_bw -{ - struct te_tlv_header header; /* Value length is 4 octets. */ - float value; /* bandwidth in IEEE floating point format with units in bytes per second */ +struct te_link_subtlv_ava_bw { + struct te_tlv_header header; /* Value length is 4 octets. */ + float value; /* bandwidth in IEEE floating point format with units in + bytes per second */ }; /* Link Sub-TLV: Unidirectional Utilized Bandwidth */ /* Optional */ #define TE_LINK_SUBTLV_USE_BW 33 -struct te_link_subtlv_use_bw -{ - struct te_tlv_header header; /* Value length is 4 octets. */ - float value; /* bandwidth in IEEE floating point format with units in bytes per second */ +struct te_link_subtlv_use_bw { + struct te_tlv_header header; /* Value length is 4 octets. */ + float value; /* bandwidth in IEEE floating point format with units in + bytes per second */ }; #define TE_LINK_SUBTLV_MAX 34 /* Last SUBTLV + 1 */ @@ -345,121 +326,121 @@ struct te_link_subtlv_use_bw #define MPLS_TE_MINIMUM_BANDWIDTH 1.0 /* Reasonable? *//* XXX */ /* Following declaration concerns the MPLS-TE and LINk-TE management */ -typedef enum _opcode_t -{ REORIGINATE_THIS_LSA, REFRESH_THIS_LSA, FLUSH_THIS_LSA } opcode_t; +typedef enum _opcode_t { + REORIGINATE_THIS_LSA, + REFRESH_THIS_LSA, + FLUSH_THIS_LSA +} opcode_t; -typedef enum _status_t -{ disabled, enabled } status_t; +typedef enum _status_t { disabled, enabled } status_t; /* Mode for Inter-AS Opaque-LSA */ enum inter_as_mode { Disable, AS, Area }; -struct te_link_subtlv -{ - struct te_tlv_header header; - union - { - u_int32_t link_type; - struct in_addr link_id; - struct in_addr lclif; - struct in_addr rmtif; - u_int32_t te_metric; - float max_bw; - float max_rsv_bw; - float unrsv[8]; - u_int32_t rsc_clsclr; - u_int32_t llri[2]; - u_int32_t ras; - struct in_addr rip; - struct in_addr lrrid[2]; - u_int32_t av_delay; - u_int32_t mm_delay; - u_int32_t delay_var; - u_int32_t pkt_loss; - float res_bw; - float ava_bw; - float use_bw; - } value; +struct te_link_subtlv { + struct te_tlv_header header; + union { + u_int32_t link_type; + struct in_addr link_id; + struct in_addr lclif; + struct in_addr rmtif; + u_int32_t te_metric; + float max_bw; + float max_rsv_bw; + float unrsv[8]; + u_int32_t rsc_clsclr; + u_int32_t llri[2]; + u_int32_t ras; + struct in_addr rip; + struct in_addr lrrid[2]; + u_int32_t av_delay; + u_int32_t mm_delay; + u_int32_t delay_var; + u_int32_t pkt_loss; + float res_bw; + float ava_bw; + float use_bw; + } value; }; /* Following structure are internal use only. */ -struct ospf_mpls_te -{ - /* Status of MPLS-TE: enable or disbale */ - status_t status; +struct ospf_mpls_te { + /* Status of MPLS-TE: enable or disbale */ + status_t status; - /* RFC5392 */ - enum inter_as_mode inter_as; - struct in_addr interas_areaid; + /* RFC5392 */ + enum inter_as_mode inter_as; + struct in_addr interas_areaid; - /* List elements are zebra-interfaces (ifp), not ospf-interfaces (oi). */ - struct list *iflist; + /* List elements are zebra-interfaces (ifp), not ospf-interfaces (oi). + */ + struct list *iflist; - /* Store Router-TLV in network byte order. */ - struct te_tlv_router_addr router_addr; + /* Store Router-TLV in network byte order. */ + struct te_tlv_router_addr router_addr; }; -struct mpls_te_link -{ - /* - * According to MPLS-TE (draft) specification, 24-bit Opaque-ID field - * is subdivided into 8-bit "unused" field and 16-bit "instance" field. - * In this implementation, each Link-TLV has its own instance. - */ - u_int32_t instance; - - /* Reference pointer to a Zebra-interface. */ - struct interface *ifp; - - /* Area info in which this MPLS-TE link belongs to. */ - struct ospf_area *area; - - /* Flags to manage this link parameters. */ - u_int32_t flags; - - /* Type of MPLS-TE link: RFC3630, RFC5392, RFC5392 emulated, RFC6827 */ - u_int8_t type; - - /* Store Link-TLV in network byte order. */ - /* RFC3630 & RFC6827 / RFC 6827 */ - struct te_tlv_link link_header; - struct te_link_subtlv_link_type link_type; - struct te_link_subtlv_link_id link_id; - struct te_link_subtlv_lclif_ipaddr lclif_ipaddr; - struct te_link_subtlv_rmtif_ipaddr rmtif_ipaddr; - struct te_link_subtlv_te_metric te_metric; - struct te_link_subtlv_max_bw max_bw; - struct te_link_subtlv_max_rsv_bw max_rsv_bw; - struct te_link_subtlv_unrsv_bw unrsv_bw; - struct te_link_subtlv_rsc_clsclr rsc_clsclr; - /* RFC4203 */ - struct te_link_subtlv_llri llri; - /* RFC5392 */ - struct te_link_subtlv_ras ras; - struct te_link_subtlv_rip rip; - /* RFC6827 */ - struct te_link_subtlv_lrrid lrrid; - /* RFC7471 */ - struct te_link_subtlv_av_delay av_delay; - struct te_link_subtlv_mm_delay mm_delay; - struct te_link_subtlv_delay_var delay_var; - struct te_link_subtlv_pkt_loss pkt_loss; - struct te_link_subtlv_res_bw res_bw; - struct te_link_subtlv_ava_bw ava_bw; - struct te_link_subtlv_use_bw use_bw; - - struct in_addr adv_router; - struct in_addr id; +struct mpls_te_link { + /* + * According to MPLS-TE (draft) specification, 24-bit Opaque-ID field + * is subdivided into 8-bit "unused" field and 16-bit "instance" field. + * In this implementation, each Link-TLV has its own instance. + */ + u_int32_t instance; + + /* Reference pointer to a Zebra-interface. */ + struct interface *ifp; + + /* Area info in which this MPLS-TE link belongs to. */ + struct ospf_area *area; + + /* Flags to manage this link parameters. */ + u_int32_t flags; + + /* Type of MPLS-TE link: RFC3630, RFC5392, RFC5392 emulated, RFC6827 */ + u_int8_t type; + + /* Store Link-TLV in network byte order. */ + /* RFC3630 & RFC6827 / RFC 6827 */ + struct te_tlv_link link_header; + struct te_link_subtlv_link_type link_type; + struct te_link_subtlv_link_id link_id; + struct te_link_subtlv_lclif_ipaddr lclif_ipaddr; + struct te_link_subtlv_rmtif_ipaddr rmtif_ipaddr; + struct te_link_subtlv_te_metric te_metric; + struct te_link_subtlv_max_bw max_bw; + struct te_link_subtlv_max_rsv_bw max_rsv_bw; + struct te_link_subtlv_unrsv_bw unrsv_bw; + struct te_link_subtlv_rsc_clsclr rsc_clsclr; + /* RFC4203 */ + struct te_link_subtlv_llri llri; + /* RFC5392 */ + struct te_link_subtlv_ras ras; + struct te_link_subtlv_rip rip; + /* RFC6827 */ + struct te_link_subtlv_lrrid lrrid; + /* RFC7471 */ + struct te_link_subtlv_av_delay av_delay; + struct te_link_subtlv_mm_delay mm_delay; + struct te_link_subtlv_delay_var delay_var; + struct te_link_subtlv_pkt_loss pkt_loss; + struct te_link_subtlv_res_bw res_bw; + struct te_link_subtlv_ava_bw ava_bw; + struct te_link_subtlv_use_bw use_bw; + + struct in_addr adv_router; + struct in_addr id; }; /* Prototypes. */ -extern int ospf_mpls_te_init (void); -extern void ospf_mpls_te_term (void); -extern struct ospf_mpls_te *get_ospf_mpls_te (void); -extern void ospf_mpls_te_update_if (struct interface *); -extern void ospf_mpls_te_lsa_schedule (struct mpls_te_link *, opcode_t); -extern u_int32_t get_mpls_te_instance_value (void); -extern void set_linkparams_llri (struct mpls_te_link *, u_int32_t, u_int32_t); -extern void set_linkparams_lrrid (struct mpls_te_link *, struct in_addr, struct in_addr); +extern int ospf_mpls_te_init(void); +extern void ospf_mpls_te_term(void); +extern struct ospf_mpls_te *get_ospf_mpls_te(void); +extern void ospf_mpls_te_update_if(struct interface *); +extern void ospf_mpls_te_lsa_schedule(struct mpls_te_link *, opcode_t); +extern u_int32_t get_mpls_te_instance_value(void); +extern void set_linkparams_llri(struct mpls_te_link *, u_int32_t, u_int32_t); +extern void set_linkparams_lrrid(struct mpls_te_link *, struct in_addr, + struct in_addr); #endif /* _ZEBRA_OSPF_MPLS_TE_H */ diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index f6387b759..55d6c27e8 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -53,88 +53,77 @@ #include "ospfd/ospf_dump.h" #include "ospfd/ospf_bfd.h" -static const char *ospf_network_type_str[] = -{ - "Null", - "POINTOPOINT", - "BROADCAST", - "NBMA", - "POINTOMULTIPOINT", - "VIRTUALLINK", - "LOOPBACK" -}; +static const char *ospf_network_type_str[] = { + "Null", "POINTOPOINT", "BROADCAST", "NBMA", "POINTOMULTIPOINT", + "VIRTUALLINK", "LOOPBACK"}; /* Utility functions. */ -int -str2area_id (const char *str, struct in_addr *area_id, int *area_id_fmt) +int str2area_id(const char *str, struct in_addr *area_id, int *area_id_fmt) { - char *ep; + char *ep; - area_id->s_addr = htonl (strtoul (str, &ep, 10)); - if (*ep && !inet_aton (str, area_id)) - return -1; + area_id->s_addr = htonl(strtoul(str, &ep, 10)); + if (*ep && !inet_aton(str, area_id)) + return -1; - *area_id_fmt = *ep ? OSPF_AREA_ID_FMT_DOTTEDQUAD : OSPF_AREA_ID_FMT_DECIMAL; + *area_id_fmt = + *ep ? OSPF_AREA_ID_FMT_DOTTEDQUAD : OSPF_AREA_ID_FMT_DECIMAL; - return 0; + return 0; } -void -area_id2str (char *buf, int length, struct in_addr *area_id, int area_id_fmt) +void area_id2str(char *buf, int length, struct in_addr *area_id, + int area_id_fmt) { - memset (buf, 0, length); + memset(buf, 0, length); - if (area_id_fmt == OSPF_AREA_ID_FMT_DOTTEDQUAD) - strncpy (buf, inet_ntoa (*area_id), length); - else - sprintf (buf, "%lu", (unsigned long) ntohl (area_id->s_addr)); + if (area_id_fmt == OSPF_AREA_ID_FMT_DOTTEDQUAD) + strncpy(buf, inet_ntoa(*area_id), length); + else + sprintf(buf, "%lu", (unsigned long)ntohl(area_id->s_addr)); } -static int -str2metric (const char *str, int *metric) +static int str2metric(const char *str, int *metric) { - /* Sanity check. */ - if (str == NULL) - return 0; + /* Sanity check. */ + if (str == NULL) + return 0; - *metric = strtol (str, NULL, 10); - if (*metric < 0 && *metric > 16777214) - { - /* vty_out (vty, "OSPF metric value is invalid\n"); */ - return 0; - } + *metric = strtol(str, NULL, 10); + if (*metric < 0 && *metric > 16777214) { + /* vty_out (vty, "OSPF metric value is invalid\n"); */ + return 0; + } - return 1; + return 1; } -static int -str2metric_type (const char *str, int *metric_type) +static int str2metric_type(const char *str, int *metric_type) { - /* Sanity check. */ - if (str == NULL) - return 0; + /* Sanity check. */ + if (str == NULL) + return 0; - if (strncmp (str, "1", 1) == 0) - *metric_type = EXTERNAL_METRIC_TYPE_1; - else if (strncmp (str, "2", 1) == 0) - *metric_type = EXTERNAL_METRIC_TYPE_2; - else - return 0; + if (strncmp(str, "1", 1) == 0) + *metric_type = EXTERNAL_METRIC_TYPE_1; + else if (strncmp(str, "2", 1) == 0) + *metric_type = EXTERNAL_METRIC_TYPE_2; + else + return 0; - return 1; + return 1; } -int -ospf_oi_count (struct interface *ifp) +int ospf_oi_count(struct interface *ifp) { - struct route_node *rn; - int i = 0; + struct route_node *rn; + int i = 0; - for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn)) - if (rn->info) - i++; + for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) + if (rn->info) + i++; - return i; + return i; } DEFUN_NOSH (router_ospf, @@ -144,33 +133,32 @@ DEFUN_NOSH (router_ospf, "Start OSPF configuration\n" "Instance ID\n") { - struct ospf *ospf; - u_short instance = 0; + struct ospf *ospf; + u_short instance = 0; - ospf = ospf_lookup(); - if (!ospf) - { - vty_out (vty, "There isn't active ospf instance \n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (argc > 2) - instance = strtoul (argv[2]->arg, NULL, 10); - - /* The following logic to set the vty qobj index is in place to be able - to ignore the commands which dont belong to this instance. */ - if (ospf->instance != instance) - VTY_PUSH_CONTEXT_NULL(OSPF_NODE); - else - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Config command 'router ospf %d' received", instance); - ospf->oi_running = 1; - VTY_PUSH_CONTEXT(OSPF_NODE, ospf); - ospf_router_id_update (ospf); - } - - return CMD_SUCCESS; + ospf = ospf_lookup(); + if (!ospf) { + vty_out(vty, "There isn't active ospf instance \n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (argc > 2) + instance = strtoul(argv[2]->arg, NULL, 10); + + /* The following logic to set the vty qobj index is in place to be able + to ignore the commands which dont belong to this instance. */ + if (ospf->instance != instance) + VTY_PUSH_CONTEXT_NULL(OSPF_NODE); + else { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Config command 'router ospf %d' received", + instance); + ospf->oi_running = 1; + VTY_PUSH_CONTEXT(OSPF_NODE, ospf); + ospf_router_id_update(ospf); + } + + return CMD_SUCCESS; } DEFUN (no_router_ospf, @@ -181,18 +169,18 @@ DEFUN (no_router_ospf, "Start OSPF configuration\n" "Instance ID\n") { - struct ospf *ospf; - u_short instance = 0; + struct ospf *ospf; + u_short instance = 0; - if (argc > 3) - instance = strtoul(argv[3]->arg, NULL, 10); + if (argc > 3) + instance = strtoul(argv[3]->arg, NULL, 10); - if ((ospf = ospf_lookup_instance (instance)) == NULL) - return CMD_SUCCESS; + if ((ospf = ospf_lookup_instance(instance)) == NULL) + return CMD_SUCCESS; - ospf_finish (ospf); + ospf_finish(ospf); - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -203,33 +191,32 @@ DEFUN (ospf_router_id, "router-id for the OSPF process\n" "OSPF router-id in IP address format\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4 = 2; - struct listnode *node; - struct ospf_area *area; - struct in_addr router_id; - int ret; - - ret = inet_aton (argv[idx_ipv4]->arg, &router_id); - if (!ret) - { - vty_out (vty, "Please specify Router ID by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - ospf->router_id_static = router_id; - - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - if (area->full_nbrs) - { - vty_out (vty, "For this router-id change to take effect," - " save config and restart ospfd\n"); - return CMD_SUCCESS; - } - - ospf_router_id_update (ospf); - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4 = 2; + struct listnode *node; + struct ospf_area *area; + struct in_addr router_id; + int ret; + + ret = inet_aton(argv[idx_ipv4]->arg, &router_id); + if (!ret) { + vty_out(vty, "Please specify Router ID by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ospf->router_id_static = router_id; + + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) + if (area->full_nbrs) { + vty_out(vty, + "For this router-id change to take effect," + " save config and restart ospfd\n"); + return CMD_SUCCESS; + } + + ospf_router_id_update(ospf); + + return CMD_SUCCESS; } DEFUN_HIDDEN (ospf_router_id_old, @@ -238,33 +225,32 @@ DEFUN_HIDDEN (ospf_router_id_old, "router-id for the OSPF process\n" "OSPF router-id in IP address format\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4 = 1; - struct listnode *node; - struct ospf_area *area; - struct in_addr router_id; - int ret; - - ret = inet_aton (argv[idx_ipv4]->arg, &router_id); - if (!ret) - { - vty_out (vty, "Please specify Router ID by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - ospf->router_id_static = router_id; - - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - if (area->full_nbrs) - { - vty_out (vty, "For this router-id change to take effect," - " save config and restart ospfd\n"); - return CMD_SUCCESS; - } - - ospf_router_id_update (ospf); + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4 = 1; + struct listnode *node; + struct ospf_area *area; + struct in_addr router_id; + int ret; + + ret = inet_aton(argv[idx_ipv4]->arg, &router_id); + if (!ret) { + vty_out(vty, "Please specify Router ID by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } - return CMD_SUCCESS; + ospf->router_id_static = router_id; + + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) + if (area->full_nbrs) { + vty_out(vty, + "For this router-id change to take effect," + " save config and restart ospfd\n"); + return CMD_SUCCESS; + } + + ospf_router_id_update(ospf); + + return CMD_SUCCESS; } DEFUN (no_ospf_router_id, @@ -275,87 +261,85 @@ DEFUN (no_ospf_router_id, "router-id for the OSPF process\n" "OSPF router-id in IP address format\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - struct listnode *node; - struct ospf_area *area; + VTY_DECLVAR_CONTEXT(ospf, ospf); + struct listnode *node; + struct ospf_area *area; + + ospf->router_id_static.s_addr = 0; - ospf->router_id_static.s_addr = 0; + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) + if (area->full_nbrs) { + vty_out(vty, + "For this router-id change to take effect," + " save config and restart ospfd\n"); + return CMD_SUCCESS; + } - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - if (area->full_nbrs) - { - vty_out (vty, "For this router-id change to take effect," - " save config and restart ospfd\n"); - return CMD_SUCCESS; - } + ospf_router_id_update(ospf); - ospf_router_id_update (ospf); + return CMD_SUCCESS; +} - return CMD_SUCCESS; + +static void ospf_passive_interface_default(struct ospf *ospf, u_char newval) +{ + struct listnode *ln; + struct interface *ifp; + struct ospf_interface *oi; + + ospf->passive_interface_default = newval; + + for (ALL_LIST_ELEMENTS_RO(om->iflist, ln, ifp)) { + if (ifp && OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp), + passive_interface)) + UNSET_IF_PARAM(IF_DEF_PARAMS(ifp), passive_interface); + } + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, ln, oi)) { + if (OSPF_IF_PARAM_CONFIGURED(oi->params, passive_interface)) + UNSET_IF_PARAM(oi->params, passive_interface); + /* update multicast memberships */ + ospf_if_set_multicast(oi); + } } +static void ospf_passive_interface_update_addr(struct ospf *ospf, + struct interface *ifp, + struct ospf_if_params *params, + u_char value, + struct in_addr addr) +{ + u_char dflt; -static void -ospf_passive_interface_default (struct ospf *ospf, u_char newval) -{ - struct listnode *ln; - struct interface *ifp; - struct ospf_interface *oi; - - ospf->passive_interface_default = newval; - - for (ALL_LIST_ELEMENTS_RO (om->iflist, ln, ifp)) - { - if (ifp && - OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (ifp), passive_interface)) - UNSET_IF_PARAM (IF_DEF_PARAMS (ifp), passive_interface); - } - for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, ln, oi)) - { - if (OSPF_IF_PARAM_CONFIGURED (oi->params, passive_interface)) - UNSET_IF_PARAM (oi->params, passive_interface); - /* update multicast memberships */ - ospf_if_set_multicast(oi); - } -} - -static void -ospf_passive_interface_update_addr (struct ospf *ospf, struct interface *ifp, - struct ospf_if_params *params, u_char value, - struct in_addr addr) -{ - u_char dflt; - - params->passive_interface = value; - if (params != IF_DEF_PARAMS (ifp)) - { - if (OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (ifp), passive_interface)) - dflt = IF_DEF_PARAMS (ifp)->passive_interface; - else - dflt = ospf->passive_interface_default; - - if (value != dflt) - SET_IF_PARAM (params, passive_interface); - else - UNSET_IF_PARAM (params, passive_interface); - - ospf_free_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - } -} - -static void -ospf_passive_interface_update (struct ospf *ospf, struct interface *ifp, - struct ospf_if_params *params, u_char value) -{ - params->passive_interface = value; - if (params == IF_DEF_PARAMS (ifp)) - { - if (value != ospf->passive_interface_default) - SET_IF_PARAM (params, passive_interface); - else - UNSET_IF_PARAM (params, passive_interface); - } + params->passive_interface = value; + if (params != IF_DEF_PARAMS(ifp)) { + if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp), + passive_interface)) + dflt = IF_DEF_PARAMS(ifp)->passive_interface; + else + dflt = ospf->passive_interface_default; + + if (value != dflt) + SET_IF_PARAM(params, passive_interface); + else + UNSET_IF_PARAM(params, passive_interface); + + ospf_free_if_params(ifp, addr); + ospf_if_update_params(ifp, addr); + } +} + +static void ospf_passive_interface_update(struct ospf *ospf, + struct interface *ifp, + struct ospf_if_params *params, + u_char value) +{ + params->passive_interface = value; + if (params == IF_DEF_PARAMS(ifp)) { + if (value != ospf->passive_interface_default) + SET_IF_PARAM(params, passive_interface); + else + UNSET_IF_PARAM(params, passive_interface); + } } DEFUN (ospf_passive_interface, @@ -366,64 +350,62 @@ DEFUN (ospf_passive_interface, "IPv4 address\n" "Suppress routing updates on interfaces by default\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4 = 2; - struct interface *ifp; - struct in_addr addr = { .s_addr = INADDR_ANY }; - int ret; - struct ospf_if_params *params; - struct route_node *rn; - - if (strmatch(argv[1]->text, "default")) - { - ospf_passive_interface_default (ospf, OSPF_IF_PASSIVE); - return CMD_SUCCESS; - } - - ifp = if_get_by_name (argv[1]->arg, VRF_DEFAULT); - - params = IF_DEF_PARAMS (ifp); - - if (argc == 3) - { - ret = inet_aton(argv[idx_ipv4]->arg, &addr); - if (!ret) - { - vty_out (vty, "Please specify interface address by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - params = ospf_get_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - ospf_passive_interface_update_addr (ospf, ifp, params, - OSPF_IF_PASSIVE, addr); - } - - ospf_passive_interface_update (ospf, ifp, params, OSPF_IF_PASSIVE); - - /* XXX We should call ospf_if_set_multicast on exactly those - * interfaces for which the passive property changed. It is too much - * work to determine this set, so we do this for every interface. - * This is safe and reasonable because ospf_if_set_multicast uses a - * record of joined groups to avoid systems calls if the desired - * memberships match the current memership. - */ - - for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next (rn)) - { - struct ospf_interface *oi = rn->info; - - if (oi && (OSPF_IF_PARAM(oi, passive_interface) == OSPF_IF_PASSIVE)) - ospf_if_set_multicast(oi); - } - /* - * XXX It is not clear what state transitions the interface needs to - * undergo when going from active to passive. Fixing this will - * require precise identification of interfaces having such a - * transition. - */ - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4 = 2; + struct interface *ifp; + struct in_addr addr = {.s_addr = INADDR_ANY}; + int ret; + struct ospf_if_params *params; + struct route_node *rn; + + if (strmatch(argv[1]->text, "default")) { + ospf_passive_interface_default(ospf, OSPF_IF_PASSIVE); + return CMD_SUCCESS; + } + + ifp = if_get_by_name(argv[1]->arg, VRF_DEFAULT); + + params = IF_DEF_PARAMS(ifp); + + if (argc == 3) { + ret = inet_aton(argv[idx_ipv4]->arg, &addr); + if (!ret) { + vty_out(vty, + "Please specify interface address by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + params = ospf_get_if_params(ifp, addr); + ospf_if_update_params(ifp, addr); + ospf_passive_interface_update_addr(ospf, ifp, params, + OSPF_IF_PASSIVE, addr); + } + + ospf_passive_interface_update(ospf, ifp, params, OSPF_IF_PASSIVE); + + /* XXX We should call ospf_if_set_multicast on exactly those + * interfaces for which the passive property changed. It is too much + * work to determine this set, so we do this for every interface. + * This is safe and reasonable because ospf_if_set_multicast uses a + * record of joined groups to avoid systems calls if the desired + * memberships match the current memership. + */ + + for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) { + struct ospf_interface *oi = rn->info; + + if (oi && (OSPF_IF_PARAM(oi, passive_interface) + == OSPF_IF_PASSIVE)) + ospf_if_set_multicast(oi); + } + /* + * XXX It is not clear what state transitions the interface needs to + * undergo when going from active to passive. Fixing this will + * require precise identification of interfaces having such a + * transition. + */ + + return CMD_SUCCESS; } DEFUN (no_ospf_passive_interface, @@ -435,61 +417,58 @@ DEFUN (no_ospf_passive_interface, "IPv4 address\n" "Allow routing updates on interfaces by default\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4 = 3; - struct interface *ifp; - struct in_addr addr = { .s_addr = INADDR_ANY }; - struct ospf_if_params *params; - int ret; - struct route_node *rn; - - if (strmatch(argv[2]->text, "default")) - { - ospf_passive_interface_default (ospf, OSPF_IF_ACTIVE); - return CMD_SUCCESS; - } - - ifp = if_get_by_name (argv[2]->arg, VRF_DEFAULT); - - params = IF_DEF_PARAMS (ifp); - - if (argc == 4) - { - ret = inet_aton(argv[idx_ipv4]->arg, &addr); - if (!ret) - { - vty_out (vty, "Please specify interface address by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4 = 3; + struct interface *ifp; + struct in_addr addr = {.s_addr = INADDR_ANY}; + struct ospf_if_params *params; + int ret; + struct route_node *rn; + + if (strmatch(argv[2]->text, "default")) { + ospf_passive_interface_default(ospf, OSPF_IF_ACTIVE); + return CMD_SUCCESS; } - params = ospf_lookup_if_params (ifp, addr); - if (params == NULL) - return CMD_SUCCESS; - ospf_passive_interface_update_addr (ospf, ifp, params, OSPF_IF_ACTIVE, - addr); - } - ospf_passive_interface_update (ospf, ifp, params, OSPF_IF_ACTIVE); - - /* XXX We should call ospf_if_set_multicast on exactly those - * interfaces for which the passive property changed. It is too much - * work to determine this set, so we do this for every interface. - * This is safe and reasonable because ospf_if_set_multicast uses a - * record of joined groups to avoid systems calls if the desired - * memberships match the current memership. - */ - for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next (rn)) - { - struct ospf_interface *oi = rn->info; - - if (oi && (OSPF_IF_PARAM(oi, passive_interface) == OSPF_IF_ACTIVE)) - ospf_if_set_multicast(oi); - } + ifp = if_get_by_name(argv[2]->arg, VRF_DEFAULT); - return CMD_SUCCESS; + params = IF_DEF_PARAMS(ifp); + + if (argc == 4) { + ret = inet_aton(argv[idx_ipv4]->arg, &addr); + if (!ret) { + vty_out(vty, + "Please specify interface address by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + params = ospf_lookup_if_params(ifp, addr); + if (params == NULL) + return CMD_SUCCESS; + ospf_passive_interface_update_addr(ospf, ifp, params, + OSPF_IF_ACTIVE, addr); + } + ospf_passive_interface_update(ospf, ifp, params, OSPF_IF_ACTIVE); + + /* XXX We should call ospf_if_set_multicast on exactly those + * interfaces for which the passive property changed. It is too much + * work to determine this set, so we do this for every interface. + * This is safe and reasonable because ospf_if_set_multicast uses a + * record of joined groups to avoid systems calls if the desired + * memberships match the current memership. + */ + for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) { + struct ospf_interface *oi = rn->info; + + if (oi + && (OSPF_IF_PARAM(oi, passive_interface) == OSPF_IF_ACTIVE)) + ospf_if_set_multicast(oi); + } + + return CMD_SUCCESS; } - DEFUN (ospf_network_area, ospf_network_area_cmd, "network A.B.C.D/M area <A.B.C.D|(0-4294967295)>", @@ -499,37 +478,36 @@ DEFUN (ospf_network_area, "OSPF area ID in IP address format\n" "OSPF area ID as a decimal value\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_prefixlen = 1; - int idx_ipv4_number = 3; - struct prefix_ipv4 p; - struct in_addr area_id; - int ret, format; - - if (ospf->instance) - { - vty_out (vty, "The network command is not supported in multi-instance ospf\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (ospf->if_ospf_cli_count > 0) - { - vty_out (vty, "Please remove all ip ospf area x.x.x.x commands first.\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* Get network prefix and Area ID. */ - str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p); - VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg); - - ret = ospf_network_set (ospf, &p, area_id, format); - if (ret == 0) - { - vty_out (vty, "There is already same network statement.\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_prefixlen = 1; + int idx_ipv4_number = 3; + struct prefix_ipv4 p; + struct in_addr area_id; + int ret, format; + + if (ospf->instance) { + vty_out(vty, + "The network command is not supported in multi-instance ospf\n"); + return CMD_WARNING_CONFIG_FAILED; + } - return CMD_SUCCESS; + if (ospf->if_ospf_cli_count > 0) { + vty_out(vty, + "Please remove all ip ospf area x.x.x.x commands first.\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + /* Get network prefix and Area ID. */ + str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p); + VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg); + + ret = ospf_network_set(ospf, &p, area_id, format); + if (ret == 0) { + vty_out(vty, "There is already same network statement.\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + return CMD_SUCCESS; } DEFUN (no_ospf_network_area, @@ -542,31 +520,31 @@ DEFUN (no_ospf_network_area, "OSPF area ID in IP address format\n" "OSPF area ID as a decimal value\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_prefixlen = 2; - int idx_ipv4_number = 4; - struct prefix_ipv4 p; - struct in_addr area_id; - int ret, format; - - if (ospf->instance) - { - vty_out (vty, "The network command is not supported in multi-instance ospf\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* Get network prefix and Area ID. */ - str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p); - VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg); - - ret = ospf_network_unset (ospf, &p, area_id); - if (ret == 0) - { - vty_out (vty, "Can't find specified network area configuration.\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_prefixlen = 2; + int idx_ipv4_number = 4; + struct prefix_ipv4 p; + struct in_addr area_id; + int ret, format; + + if (ospf->instance) { + vty_out(vty, + "The network command is not supported in multi-instance ospf\n"); + return CMD_WARNING_CONFIG_FAILED; + } - return CMD_SUCCESS; + /* Get network prefix and Area ID. */ + str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p); + VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg); + + ret = ospf_network_unset(ospf, &p, area_id); + if (ret == 0) { + vty_out(vty, + "Can't find specified network area configuration.\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + return CMD_SUCCESS; } DEFUN (ospf_area_range, @@ -581,26 +559,25 @@ DEFUN (ospf_area_range, "User specified metric for this range\n" "Advertised metric for this range\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_number = 1; - int idx_ipv4_prefixlen = 3; - int idx_cost = 6; - struct prefix_ipv4 p; - struct in_addr area_id; - int format; - u_int32_t cost; - - VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg); - str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p); - - ospf_area_range_set (ospf, area_id, &p, OSPF_AREA_RANGE_ADVERTISE); - if (argc > 5) - { - cost = strtoul(argv[idx_cost]->arg, NULL, 10); - ospf_area_range_cost_set (ospf, area_id, &p, cost); - } + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_number = 1; + int idx_ipv4_prefixlen = 3; + int idx_cost = 6; + struct prefix_ipv4 p; + struct in_addr area_id; + int format; + u_int32_t cost; + + VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg); + str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p); + + ospf_area_range_set(ospf, area_id, &p, OSPF_AREA_RANGE_ADVERTISE); + if (argc > 5) { + cost = strtoul(argv[idx_cost]->arg, NULL, 10); + ospf_area_range_cost_set(ospf, area_id, &p, cost); + } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (ospf_area_range_cost, @@ -614,25 +591,26 @@ DEFUN (ospf_area_range_cost, "User specified metric for this range\n" "Advertised metric for this range\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_number = 1; - int idx_ipv4_prefixlen = 3; - int idx_cost = 5; - struct prefix_ipv4 p; - struct in_addr area_id; - int format; - u_int32_t cost; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_number = 1; + int idx_ipv4_prefixlen = 3; + int idx_cost = 5; + struct prefix_ipv4 p; + struct in_addr area_id; + int format; + u_int32_t cost; - VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg); - str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p); + VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg); + str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p); - ospf_area_range_set (ospf, area_id, &p, OSPF_AREA_RANGE_ADVERTISE); - ospf_area_display_format_set (ospf, ospf_area_get (ospf, area_id), format); + ospf_area_range_set(ospf, area_id, &p, OSPF_AREA_RANGE_ADVERTISE); + ospf_area_display_format_set(ospf, ospf_area_get(ospf, area_id), + format); - cost = strtoul(argv[idx_cost]->arg, NULL, 10); - ospf_area_range_cost_set (ospf, area_id, &p, cost); + cost = strtoul(argv[idx_cost]->arg, NULL, 10); + ospf_area_range_cost_set(ospf, area_id, &p, cost); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (ospf_area_range_not_advertise, @@ -645,20 +623,21 @@ DEFUN (ospf_area_range_not_advertise, "Area range prefix\n" "DoNotAdvertise this range\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_number = 1; - int idx_ipv4_prefixlen = 3; - struct prefix_ipv4 p; - struct in_addr area_id; - int format; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_number = 1; + int idx_ipv4_prefixlen = 3; + struct prefix_ipv4 p; + struct in_addr area_id; + int format; - VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg); - str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p); + VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg); + str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p); - ospf_area_range_set (ospf, area_id, &p, 0); - ospf_area_display_format_set (ospf, ospf_area_get (ospf, area_id), format); + ospf_area_range_set(ospf, area_id, &p, 0); + ospf_area_display_format_set(ospf, ospf_area_get(ospf, area_id), + format); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ospf_area_range, @@ -677,19 +656,19 @@ DEFUN (no_ospf_area_range, "Advertised metric for this range\n" "DoNotAdvertise this range\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_number = 2; - int idx_ipv4_prefixlen = 4; - struct prefix_ipv4 p; - struct in_addr area_id; - int format; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_number = 2; + int idx_ipv4_prefixlen = 4; + struct prefix_ipv4 p; + struct in_addr area_id; + int format; - VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg); - str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p); + VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg); + str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p); - ospf_area_range_unset (ospf, area_id, &p); + ospf_area_range_unset(ospf, area_id, &p); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (ospf_area_range_substitute, @@ -703,22 +682,23 @@ DEFUN (ospf_area_range_substitute, "Announce area range as another prefix\n" "Network prefix to be announced instead of range\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_number = 1; - int idx_ipv4_prefixlen = 3; - int idx_ipv4_prefixlen_2 = 5; - struct prefix_ipv4 p, s; - struct in_addr area_id; - int format; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_number = 1; + int idx_ipv4_prefixlen = 3; + int idx_ipv4_prefixlen_2 = 5; + struct prefix_ipv4 p, s; + struct in_addr area_id; + int format; - VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg); - str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p); - str2prefix_ipv4(argv[idx_ipv4_prefixlen_2]->arg, &s); + VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg); + str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p); + str2prefix_ipv4(argv[idx_ipv4_prefixlen_2]->arg, &s); - ospf_area_range_substitute_set (ospf, area_id, &p, &s); - ospf_area_display_format_set (ospf, ospf_area_get (ospf, area_id), format); + ospf_area_range_substitute_set(ospf, area_id, &p, &s); + ospf_area_display_format_set(ospf, ospf_area_get(ospf, area_id), + format); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ospf_area_range_substitute, @@ -733,21 +713,21 @@ DEFUN (no_ospf_area_range_substitute, "Announce area range as another prefix\n" "Network prefix to be announced instead of range\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_number = 2; - int idx_ipv4_prefixlen = 4; - int idx_ipv4_prefixlen_2 = 6; - struct prefix_ipv4 p, s; - struct in_addr area_id; - int format; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_number = 2; + int idx_ipv4_prefixlen = 4; + int idx_ipv4_prefixlen_2 = 6; + struct prefix_ipv4 p, s; + struct in_addr area_id; + int format; - VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg); - str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p); - str2prefix_ipv4(argv[idx_ipv4_prefixlen_2]->arg, &s); + VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg); + str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p); + str2prefix_ipv4(argv[idx_ipv4_prefixlen_2]->arg, &s); - ospf_area_range_substitute_unset (ospf, area_id, &p); + ospf_area_range_substitute_unset(ospf, area_id, &p); - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -762,243 +742,232 @@ DEFUN (no_ospf_area_range_substitute, bacckend handler. This is to drastically reduce the verbeage required to coe up with a reasonably compatible Cisco VLink command - - Matthew Grant <grantma@anathoth.gen.nz> + - Matthew Grant <grantma@anathoth.gen.nz> Wed, 21 Feb 2001 15:13:52 +1300 */ -/* Configuration data for virtual links - */ +/* Configuration data for virtual links + */ struct ospf_vl_config_data { - struct vty *vty; /* vty stuff */ - struct in_addr area_id; /* area ID from command line */ - int area_id_fmt; /* command line area ID format */ - struct in_addr vl_peer; /* command line vl_peer */ - int auth_type; /* Authehntication type, if given */ - char *auth_key; /* simple password if present */ - int crypto_key_id; /* Cryptographic key ID */ - char *md5_key; /* MD5 authentication key */ - int hello_interval; /* Obvious what these are... */ - int retransmit_interval; - int transmit_delay; - int dead_interval; + struct vty *vty; /* vty stuff */ + struct in_addr area_id; /* area ID from command line */ + int area_id_fmt; /* command line area ID format */ + struct in_addr vl_peer; /* command line vl_peer */ + int auth_type; /* Authehntication type, if given */ + char *auth_key; /* simple password if present */ + int crypto_key_id; /* Cryptographic key ID */ + char *md5_key; /* MD5 authentication key */ + int hello_interval; /* Obvious what these are... */ + int retransmit_interval; + int transmit_delay; + int dead_interval; }; -static void -ospf_vl_config_data_init (struct ospf_vl_config_data *vl_config, - struct vty *vty) +static void ospf_vl_config_data_init(struct ospf_vl_config_data *vl_config, + struct vty *vty) { - memset (vl_config, 0, sizeof (struct ospf_vl_config_data)); - vl_config->auth_type = OSPF_AUTH_CMD_NOTSEEN; - vl_config->vty = vty; + memset(vl_config, 0, sizeof(struct ospf_vl_config_data)); + vl_config->auth_type = OSPF_AUTH_CMD_NOTSEEN; + vl_config->vty = vty; } static struct ospf_vl_data * -ospf_find_vl_data (struct ospf *ospf, struct ospf_vl_config_data *vl_config) -{ - struct ospf_area *area; - struct ospf_vl_data *vl_data; - struct vty *vty; - struct in_addr area_id; - - vty = vl_config->vty; - area_id = vl_config->area_id; - - if (area_id.s_addr == OSPF_AREA_BACKBONE) - { - vty_out (vty, - "Configuring VLs over the backbone is not allowed\n"); - return NULL; - } - area = ospf_area_get (ospf, area_id); - ospf_area_display_format_set (ospf, area, vl_config->area_id_fmt); - - if (area->external_routing != OSPF_AREA_DEFAULT) - { - if (vl_config->area_id_fmt == OSPF_AREA_ID_FMT_DOTTEDQUAD) - vty_out (vty, "Area %s is %s\n", - inet_ntoa (area_id), - area->external_routing == OSPF_AREA_NSSA?"nssa":"stub"); - else - vty_out (vty, "Area %ld is %s\n", - (u_long)ntohl (area_id.s_addr), - area->external_routing == OSPF_AREA_NSSA?"nssa":"stub"); - return NULL; - } - - if ((vl_data = ospf_vl_lookup (ospf, area, vl_config->vl_peer)) == NULL) - { - vl_data = ospf_vl_data_new (area, vl_config->vl_peer); - if (vl_data->vl_oi == NULL) - { - vl_data->vl_oi = ospf_vl_new (ospf, vl_data); - ospf_vl_add (ospf, vl_data); - ospf_spf_calculate_schedule (ospf, SPF_FLAG_CONFIG_CHANGE); +ospf_find_vl_data(struct ospf *ospf, struct ospf_vl_config_data *vl_config) +{ + struct ospf_area *area; + struct ospf_vl_data *vl_data; + struct vty *vty; + struct in_addr area_id; + + vty = vl_config->vty; + area_id = vl_config->area_id; + + if (area_id.s_addr == OSPF_AREA_BACKBONE) { + vty_out(vty, + "Configuring VLs over the backbone is not allowed\n"); + return NULL; + } + area = ospf_area_get(ospf, area_id); + ospf_area_display_format_set(ospf, area, vl_config->area_id_fmt); + + if (area->external_routing != OSPF_AREA_DEFAULT) { + if (vl_config->area_id_fmt == OSPF_AREA_ID_FMT_DOTTEDQUAD) + vty_out(vty, "Area %s is %s\n", inet_ntoa(area_id), + area->external_routing == OSPF_AREA_NSSA + ? "nssa" + : "stub"); + else + vty_out(vty, "Area %ld is %s\n", + (u_long)ntohl(area_id.s_addr), + area->external_routing == OSPF_AREA_NSSA + ? "nssa" + : "stub"); + return NULL; + } + + if ((vl_data = ospf_vl_lookup(ospf, area, vl_config->vl_peer)) + == NULL) { + vl_data = ospf_vl_data_new(area, vl_config->vl_peer); + if (vl_data->vl_oi == NULL) { + vl_data->vl_oi = ospf_vl_new(ospf, vl_data); + ospf_vl_add(ospf, vl_data); + ospf_spf_calculate_schedule(ospf, + SPF_FLAG_CONFIG_CHANGE); + } } - } - return vl_data; + return vl_data; } -static int -ospf_vl_set_security (struct ospf_vl_data *vl_data, - struct ospf_vl_config_data *vl_config) -{ - struct crypt_key *ck; - struct vty *vty; - struct interface *ifp = vl_data->vl_oi->ifp; - - vty = vl_config->vty; - - if (vl_config->auth_type != OSPF_AUTH_CMD_NOTSEEN) - { - SET_IF_PARAM (IF_DEF_PARAMS (ifp), auth_type); - IF_DEF_PARAMS (ifp)->auth_type = vl_config->auth_type; - } - - if (vl_config->auth_key) - { - memset(IF_DEF_PARAMS (ifp)->auth_simple, 0, OSPF_AUTH_SIMPLE_SIZE+1); - strncpy ((char *) IF_DEF_PARAMS (ifp)->auth_simple, vl_config->auth_key, - OSPF_AUTH_SIMPLE_SIZE); - } - else if (vl_config->md5_key) - { - if (ospf_crypt_key_lookup (IF_DEF_PARAMS (ifp)->auth_crypt, vl_config->crypto_key_id) - != NULL) - { - vty_out (vty, "OSPF: Key %d already exists\n", - vl_config->crypto_key_id); - return CMD_WARNING_CONFIG_FAILED; - } - ck = ospf_crypt_key_new (); - ck->key_id = vl_config->crypto_key_id; - memset(ck->auth_key, 0, OSPF_AUTH_MD5_SIZE+1); - strncpy ((char *) ck->auth_key, vl_config->md5_key, OSPF_AUTH_MD5_SIZE); - - ospf_crypt_key_add (IF_DEF_PARAMS (ifp)->auth_crypt, ck); - } - else if (vl_config->crypto_key_id != 0) - { - /* Delete a key */ - - if (ospf_crypt_key_lookup (IF_DEF_PARAMS (ifp)->auth_crypt, - vl_config->crypto_key_id) == NULL) - { - vty_out (vty, "OSPF: Key %d does not exist\n", - vl_config->crypto_key_id); - return CMD_WARNING_CONFIG_FAILED; +static int ospf_vl_set_security(struct ospf_vl_data *vl_data, + struct ospf_vl_config_data *vl_config) +{ + struct crypt_key *ck; + struct vty *vty; + struct interface *ifp = vl_data->vl_oi->ifp; + + vty = vl_config->vty; + + if (vl_config->auth_type != OSPF_AUTH_CMD_NOTSEEN) { + SET_IF_PARAM(IF_DEF_PARAMS(ifp), auth_type); + IF_DEF_PARAMS(ifp)->auth_type = vl_config->auth_type; } - - ospf_crypt_key_delete (IF_DEF_PARAMS (ifp)->auth_crypt, vl_config->crypto_key_id); - } - - return CMD_SUCCESS; + if (vl_config->auth_key) { + memset(IF_DEF_PARAMS(ifp)->auth_simple, 0, + OSPF_AUTH_SIMPLE_SIZE + 1); + strncpy((char *)IF_DEF_PARAMS(ifp)->auth_simple, + vl_config->auth_key, OSPF_AUTH_SIMPLE_SIZE); + } else if (vl_config->md5_key) { + if (ospf_crypt_key_lookup(IF_DEF_PARAMS(ifp)->auth_crypt, + vl_config->crypto_key_id) + != NULL) { + vty_out(vty, "OSPF: Key %d already exists\n", + vl_config->crypto_key_id); + return CMD_WARNING_CONFIG_FAILED; + } + ck = ospf_crypt_key_new(); + ck->key_id = vl_config->crypto_key_id; + memset(ck->auth_key, 0, OSPF_AUTH_MD5_SIZE + 1); + strncpy((char *)ck->auth_key, vl_config->md5_key, + OSPF_AUTH_MD5_SIZE); + + ospf_crypt_key_add(IF_DEF_PARAMS(ifp)->auth_crypt, ck); + } else if (vl_config->crypto_key_id != 0) { + /* Delete a key */ + + if (ospf_crypt_key_lookup(IF_DEF_PARAMS(ifp)->auth_crypt, + vl_config->crypto_key_id) + == NULL) { + vty_out(vty, "OSPF: Key %d does not exist\n", + vl_config->crypto_key_id); + return CMD_WARNING_CONFIG_FAILED; + } + + ospf_crypt_key_delete(IF_DEF_PARAMS(ifp)->auth_crypt, + vl_config->crypto_key_id); + } + + return CMD_SUCCESS; } -static int -ospf_vl_set_timers (struct ospf_vl_data *vl_data, - struct ospf_vl_config_data *vl_config) -{ - struct interface *ifp = vl_data->vl_oi->ifp; - /* Virtual Link data initialised to defaults, so only set - if a value given */ - if (vl_config->hello_interval) - { - SET_IF_PARAM (IF_DEF_PARAMS (ifp), v_hello); - IF_DEF_PARAMS (ifp)->v_hello = vl_config->hello_interval; - } - - if (vl_config->dead_interval) - { - SET_IF_PARAM (IF_DEF_PARAMS (ifp), v_wait); - IF_DEF_PARAMS (ifp)->v_wait = vl_config->dead_interval; - } - - if (vl_config->retransmit_interval) - { - SET_IF_PARAM (IF_DEF_PARAMS (ifp), retransmit_interval); - IF_DEF_PARAMS (ifp)->retransmit_interval = vl_config->retransmit_interval; - } - - if (vl_config->transmit_delay) - { - SET_IF_PARAM (IF_DEF_PARAMS (ifp), transmit_delay); - IF_DEF_PARAMS (ifp)->transmit_delay = vl_config->transmit_delay; - } - - return CMD_SUCCESS; +static int ospf_vl_set_timers(struct ospf_vl_data *vl_data, + struct ospf_vl_config_data *vl_config) +{ + struct interface *ifp = vl_data->vl_oi->ifp; + /* Virtual Link data initialised to defaults, so only set + if a value given */ + if (vl_config->hello_interval) { + SET_IF_PARAM(IF_DEF_PARAMS(ifp), v_hello); + IF_DEF_PARAMS(ifp)->v_hello = vl_config->hello_interval; + } + + if (vl_config->dead_interval) { + SET_IF_PARAM(IF_DEF_PARAMS(ifp), v_wait); + IF_DEF_PARAMS(ifp)->v_wait = vl_config->dead_interval; + } + + if (vl_config->retransmit_interval) { + SET_IF_PARAM(IF_DEF_PARAMS(ifp), retransmit_interval); + IF_DEF_PARAMS(ifp)->retransmit_interval = + vl_config->retransmit_interval; + } + + if (vl_config->transmit_delay) { + SET_IF_PARAM(IF_DEF_PARAMS(ifp), transmit_delay); + IF_DEF_PARAMS(ifp)->transmit_delay = vl_config->transmit_delay; + } + + return CMD_SUCCESS; } /* The business end of all of the above */ -static int -ospf_vl_set (struct ospf *ospf, struct ospf_vl_config_data *vl_config) -{ - struct ospf_vl_data *vl_data; - int ret; - - vl_data = ospf_find_vl_data (ospf, vl_config); - if (!vl_data) - return CMD_WARNING_CONFIG_FAILED; - - /* Process this one first as it can have a fatal result, which can - only logically occur if the virtual link exists already - Thus a command error does not result in a change to the - running configuration such as unexpectedly altered timer - values etc.*/ - ret = ospf_vl_set_security (vl_data, vl_config); - if (ret != CMD_SUCCESS) - return ret; - - /* Set any time based parameters, these area already range checked */ - - ret = ospf_vl_set_timers (vl_data, vl_config); - if (ret != CMD_SUCCESS) - return ret; +static int ospf_vl_set(struct ospf *ospf, struct ospf_vl_config_data *vl_config) +{ + struct ospf_vl_data *vl_data; + int ret; - return CMD_SUCCESS; + vl_data = ospf_find_vl_data(ospf, vl_config); + if (!vl_data) + return CMD_WARNING_CONFIG_FAILED; + /* Process this one first as it can have a fatal result, which can + only logically occur if the virtual link exists already + Thus a command error does not result in a change to the + running configuration such as unexpectedly altered timer + values etc.*/ + ret = ospf_vl_set_security(vl_data, vl_config); + if (ret != CMD_SUCCESS) + return ret; + + /* Set any time based parameters, these area already range checked */ + + ret = ospf_vl_set_timers(vl_data, vl_config); + if (ret != CMD_SUCCESS) + return ret; + + return CMD_SUCCESS; } /* This stuff exists to make specifying all the alias commands A LOT simpler */ -#define VLINK_HELPSTR_IPADDR \ - "OSPF area parameters\n" \ - "OSPF area ID in IP address format\n" \ - "OSPF area ID as a decimal value\n" \ - "Configure a virtual link\n" \ - "Router ID of the remote ABR\n" - -#define VLINK_HELPSTR_AUTHTYPE_SIMPLE \ - "Enable authentication on this virtual link\n" \ - "dummy string \n" - -#define VLINK_HELPSTR_AUTHTYPE_ALL \ - VLINK_HELPSTR_AUTHTYPE_SIMPLE \ - "Use null authentication\n" \ - "Use message-digest authentication\n" - -#define VLINK_HELPSTR_TIME_PARAM \ - "Time between HELLO packets\n" \ - "Seconds\n" \ - "Time between retransmitting lost link state advertisements\n" \ - "Seconds\n" \ - "Link state transmit delay\n" \ - "Seconds\n" \ - "Interval time after which a neighbor is declared down\n" \ - "Seconds\n" \ - -#define VLINK_HELPSTR_AUTH_SIMPLE \ - "Authentication password (key)\n" \ - "The OSPF password (key)" - -#define VLINK_HELPSTR_AUTH_MD5 \ - "Message digest authentication password (key)\n" \ - "dummy string \n" \ - "Key ID\n" \ - "Use MD5 algorithm\n" \ - "The OSPF password (key)" +#define VLINK_HELPSTR_IPADDR \ + "OSPF area parameters\n" \ + "OSPF area ID in IP address format\n" \ + "OSPF area ID as a decimal value\n" \ + "Configure a virtual link\n" \ + "Router ID of the remote ABR\n" + +#define VLINK_HELPSTR_AUTHTYPE_SIMPLE \ + "Enable authentication on this virtual link\n" \ + "dummy string \n" + +#define VLINK_HELPSTR_AUTHTYPE_ALL \ + VLINK_HELPSTR_AUTHTYPE_SIMPLE \ + "Use null authentication\n" \ + "Use message-digest authentication\n" + +#define VLINK_HELPSTR_TIME_PARAM \ + "Time between HELLO packets\n" \ + "Seconds\n" \ + "Time between retransmitting lost link state advertisements\n" \ + "Seconds\n" \ + "Link state transmit delay\n" \ + "Seconds\n" \ + "Interval time after which a neighbor is declared down\n" \ + "Seconds\n" + +#define VLINK_HELPSTR_AUTH_SIMPLE \ + "Authentication password (key)\n" \ + "The OSPF password (key)" + +#define VLINK_HELPSTR_AUTH_MD5 \ + "Message digest authentication password (key)\n" \ + "dummy string \n" \ + "Key ID\n" \ + "Use MD5 algorithm\n" \ + "The OSPF password (key)" DEFUN (ospf_area_vlink, ospf_area_vlink_cmd, @@ -1012,111 +981,115 @@ DEFUN (ospf_area_vlink, "Use MD5 algorithm\n" \ "The OSPF password (key)") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_number = 1; - int idx_ipv4 = 3; - struct ospf_vl_config_data vl_config; - char auth_key[OSPF_AUTH_SIMPLE_SIZE+1]; - char md5_key[OSPF_AUTH_MD5_SIZE+1]; - int i; - int ret; - - ospf_vl_config_data_init(&vl_config, vty); - - /* Read off first 2 parameters and check them */ - ret = str2area_id (argv[idx_ipv4_number]->arg, &vl_config.area_id, - &vl_config.area_id_fmt); - if (ret < 0) - { - vty_out (vty, "OSPF area ID is invalid\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - ret = inet_aton (argv[idx_ipv4]->arg, &vl_config.vl_peer); - if (! ret) - { - vty_out (vty, "Please specify valid Router ID as a.b.c.d\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (argc <=4) - { - /* Thats all folks! - BUGS B. strikes again!!!*/ - - return ospf_vl_set (ospf, &vl_config); - } - - /* Deal with other parameters */ - for (i=5; i < argc; i++) - { - - /* vty_out (vty, "argv[%d]->arg - %s\n", i, argv[i]->text); */ - - switch (argv[i]->arg[0]) - { + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_number = 1; + int idx_ipv4 = 3; + struct ospf_vl_config_data vl_config; + char auth_key[OSPF_AUTH_SIMPLE_SIZE + 1]; + char md5_key[OSPF_AUTH_MD5_SIZE + 1]; + int i; + int ret; + + ospf_vl_config_data_init(&vl_config, vty); + + /* Read off first 2 parameters and check them */ + ret = str2area_id(argv[idx_ipv4_number]->arg, &vl_config.area_id, + &vl_config.area_id_fmt); + if (ret < 0) { + vty_out(vty, "OSPF area ID is invalid\n"); + return CMD_WARNING_CONFIG_FAILED; + } - case 'a': - if (i >5 || strncmp (argv[i]->arg, "authentication-", 15) == 0) - { - /* authentication-key - this option can occur anywhere on - command line. At start of command line - must check for authentication option. */ - memset (auth_key, 0, OSPF_AUTH_SIMPLE_SIZE + 1); - strncpy (auth_key, argv[i+1]->text, OSPF_AUTH_SIMPLE_SIZE); - vl_config.auth_key = auth_key; - i++; - } - else if (strncmp (argv[i]->arg, "authentication", 14) == 0) - { - /* authentication - this option can only occur at start - of command line */ - vl_config.auth_type = OSPF_AUTH_SIMPLE; - if ((i+1) < argc) - { - if (strncmp (argv[i+1]->arg, "n", 1) == 0) - { - /* "authentication null" */ - vl_config.auth_type = OSPF_AUTH_NULL; - i++; - } - else if (strncmp (argv[i+1]->arg, "m", 1) == 0 - && !strmatch(argv[i + 1]->text, "message-digest-")) - { - /* "authentication message-digest" */ - vl_config.auth_type = OSPF_AUTH_CRYPTOGRAPHIC; - i++; - } - } - } - break; - - case 'm': - /* message-digest-key */ - i++; - if (i < argc) - { - vl_config.crypto_key_id = strtol (argv[i]->arg, NULL, 10); - if (vl_config.crypto_key_id < 0) - return CMD_WARNING_CONFIG_FAILED; - i++; - if (i < argc) - { - memset(md5_key, 0, OSPF_AUTH_MD5_SIZE+1); - strncpy (md5_key, argv[i]->arg, OSPF_AUTH_MD5_SIZE); - vl_config.md5_key = md5_key; - } - } - else - vl_config.md5_key = NULL; - break; + ret = inet_aton(argv[idx_ipv4]->arg, &vl_config.vl_peer); + if (!ret) { + vty_out(vty, "Please specify valid Router ID as a.b.c.d\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (argc <= 4) { + /* Thats all folks! - BUGS B. strikes again!!!*/ + + return ospf_vl_set(ospf, &vl_config); } - } + /* Deal with other parameters */ + for (i = 5; i < argc; i++) { + + /* vty_out (vty, "argv[%d]->arg - %s\n", i, argv[i]->text); */ + + switch (argv[i]->arg[0]) { + + case 'a': + if (i > 5 + || strncmp(argv[i]->arg, "authentication-", 15) + == 0) { + /* authentication-key - this option can occur + anywhere on + command line. At start + of command line + must check for + authentication option. */ + memset(auth_key, 0, OSPF_AUTH_SIMPLE_SIZE + 1); + strncpy(auth_key, argv[i + 1]->text, + OSPF_AUTH_SIMPLE_SIZE); + vl_config.auth_key = auth_key; + i++; + } else if (strncmp(argv[i]->arg, "authentication", 14) + == 0) { + /* authentication - this option can only occur + at start + of command line */ + vl_config.auth_type = OSPF_AUTH_SIMPLE; + if ((i + 1) < argc) { + if (strncmp(argv[i + 1]->arg, "n", 1) + == 0) { + /* "authentication null" */ + vl_config.auth_type = + OSPF_AUTH_NULL; + i++; + } else if ( + strncmp(argv[i + 1]->arg, "m", + 1) + == 0 + && !strmatch( + argv[i + 1]->text, + "message-digest-")) { + /* "authentication + * message-digest" */ + vl_config.auth_type = + OSPF_AUTH_CRYPTOGRAPHIC; + i++; + } + } + } + break; + + case 'm': + /* message-digest-key */ + i++; + if (i < argc) { + vl_config.crypto_key_id = + strtol(argv[i]->arg, NULL, 10); + if (vl_config.crypto_key_id < 0) + return CMD_WARNING_CONFIG_FAILED; + i++; + if (i < argc) { + memset(md5_key, 0, + OSPF_AUTH_MD5_SIZE + 1); + strncpy(md5_key, argv[i]->arg, + OSPF_AUTH_MD5_SIZE); + vl_config.md5_key = md5_key; + } + } else + vl_config.md5_key = NULL; + break; + } + } - /* Action configuration */ - return ospf_vl_set (ospf, &vl_config); + /* Action configuration */ + return ospf_vl_set(ospf, &vl_config); } DEFUN (no_ospf_area_vlink, @@ -1132,100 +1105,97 @@ DEFUN (no_ospf_area_vlink, "Use MD5 algorithm\n" \ "The OSPF password (key)") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_number = 2; - int idx_ipv4 = 4; - struct ospf_area *area; - struct ospf_vl_config_data vl_config; - struct ospf_vl_data *vl_data = NULL; - char auth_key[OSPF_AUTH_SIMPLE_SIZE+1]; - int i; - int ret, format; - - ospf_vl_config_data_init(&vl_config, vty); - - ret = str2area_id (argv[idx_ipv4_number]->arg, &vl_config.area_id, &format); - if (ret < 0) - { - vty_out (vty, "OSPF area ID is invalid\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - area = ospf_area_lookup_by_area_id (ospf, vl_config.area_id); - if (!area) - { - vty_out (vty, "Area does not exist\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - ret = inet_aton (argv[idx_ipv4]->arg, &vl_config.vl_peer); - if (! ret) - { - vty_out (vty, "Please specify valid Router ID as a.b.c.d\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (argc <=5) - { - /* Basic VLink no command */ - /* Thats all folks! - BUGS B. strikes again!!!*/ - if ((vl_data = ospf_vl_lookup (ospf, area, vl_config.vl_peer))) - ospf_vl_delete (ospf, vl_data); - - ospf_area_check_free (ospf, vl_config.area_id); - - return CMD_SUCCESS; - } - - /* If we are down here, we are reseting parameters */ - - /* Deal with other parameters */ - for (i=6; i < argc; i++) - { - /* vty_out (vty, "argv[%d] - %s\n", i, argv[i]); */ - - switch (argv[i]->arg[0]) - { + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_number = 2; + int idx_ipv4 = 4; + struct ospf_area *area; + struct ospf_vl_config_data vl_config; + struct ospf_vl_data *vl_data = NULL; + char auth_key[OSPF_AUTH_SIMPLE_SIZE + 1]; + int i; + int ret, format; + + ospf_vl_config_data_init(&vl_config, vty); + + ret = str2area_id(argv[idx_ipv4_number]->arg, &vl_config.area_id, + &format); + if (ret < 0) { + vty_out(vty, "OSPF area ID is invalid\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + area = ospf_area_lookup_by_area_id(ospf, vl_config.area_id); + if (!area) { + vty_out(vty, "Area does not exist\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = inet_aton(argv[idx_ipv4]->arg, &vl_config.vl_peer); + if (!ret) { + vty_out(vty, "Please specify valid Router ID as a.b.c.d\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (argc <= 5) { + /* Basic VLink no command */ + /* Thats all folks! - BUGS B. strikes again!!!*/ + if ((vl_data = ospf_vl_lookup(ospf, area, vl_config.vl_peer))) + ospf_vl_delete(ospf, vl_data); + + ospf_area_check_free(ospf, vl_config.area_id); + + return CMD_SUCCESS; + } - case 'a': - if (i > 2 || strncmp (argv[i]->text, "authentication-", 15) == 0) - { - /* authentication-key - this option can occur anywhere on - command line. At start of command line - must check for authentication option. */ - memset (auth_key, 0, OSPF_AUTH_SIMPLE_SIZE + 1); - vl_config.auth_key = auth_key; - } - else if (strncmp (argv[i]->text, "authentication", 14) == 0) - { - /* authentication - this option can only occur at start - of command line */ - vl_config.auth_type = OSPF_AUTH_NOTSET; - } - break; - - case 'm': - /* message-digest-key */ - /* Delete one key */ - i++; - if (i < argc) - { - vl_config.crypto_key_id = strtol (argv[i]->arg, NULL, 10); - if (vl_config.crypto_key_id < 0) - return CMD_WARNING_CONFIG_FAILED; - vl_config.md5_key = NULL; - } - else - return CMD_WARNING_CONFIG_FAILED; - break; - - } - } - - - /* Action configuration */ - - return ospf_vl_set (ospf, &vl_config); + /* If we are down here, we are reseting parameters */ + + /* Deal with other parameters */ + for (i = 6; i < argc; i++) { + /* vty_out (vty, "argv[%d] - %s\n", i, argv[i]); */ + + switch (argv[i]->arg[0]) { + + case 'a': + if (i > 2 + || strncmp(argv[i]->text, "authentication-", 15) + == 0) { + /* authentication-key - this option can occur + anywhere on + command line. At start + of command line + must check for + authentication option. */ + memset(auth_key, 0, OSPF_AUTH_SIMPLE_SIZE + 1); + vl_config.auth_key = auth_key; + } else if (strncmp(argv[i]->text, "authentication", 14) + == 0) { + /* authentication - this option can only occur + at start + of command line */ + vl_config.auth_type = OSPF_AUTH_NOTSET; + } + break; + + case 'm': + /* message-digest-key */ + /* Delete one key */ + i++; + if (i < argc) { + vl_config.crypto_key_id = + strtol(argv[i]->arg, NULL, 10); + if (vl_config.crypto_key_id < 0) + return CMD_WARNING_CONFIG_FAILED; + vl_config.md5_key = NULL; + } else + return CMD_WARNING_CONFIG_FAILED; + break; + } + } + + + /* Action configuration */ + + return ospf_vl_set(ospf, &vl_config); } DEFUN (ospf_area_vlink_intervals, @@ -1234,43 +1204,44 @@ DEFUN (ospf_area_vlink_intervals, VLINK_HELPSTR_IPADDR VLINK_HELPSTR_TIME_PARAM) { - VTY_DECLVAR_CONTEXT(ospf, ospf); - struct ospf_vl_config_data vl_config; - int ret = 0; - - ospf_vl_config_data_init(&vl_config, vty); - - char *area_id = argv[1]->arg; - char *router_id = argv[3]->arg; - - ret = str2area_id (area_id, &vl_config.area_id, &vl_config.area_id_fmt); - if (ret < 0) - { - vty_out (vty, "OSPF area ID is invalid\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - ret = inet_aton (router_id, &vl_config.vl_peer); - if (! ret) - { - vty_out (vty, "Please specify valid Router ID as a.b.c.d\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - for (int idx = 4; idx < argc; idx++) - { - if (strmatch (argv[idx]->text, "hello-interval")) - vl_config.hello_interval = strtol(argv[++idx]->arg, NULL, 10); - else if (strmatch (argv[idx]->text, "retransmit-interval")) - vl_config.retransmit_interval = strtol(argv[++idx]->arg, NULL, 10); - else if (strmatch (argv[idx]->text, "transmit-delay")) - vl_config.transmit_delay = strtol(argv[++idx]->arg, NULL, 10); - else if (strmatch (argv[idx]->text, "dead-interval")) - vl_config.dead_interval = strtol(argv[++idx]->arg, NULL, 10); - } - - /* Action configuration */ - return ospf_vl_set (ospf, &vl_config); + VTY_DECLVAR_CONTEXT(ospf, ospf); + struct ospf_vl_config_data vl_config; + int ret = 0; + + ospf_vl_config_data_init(&vl_config, vty); + + char *area_id = argv[1]->arg; + char *router_id = argv[3]->arg; + + ret = str2area_id(area_id, &vl_config.area_id, &vl_config.area_id_fmt); + if (ret < 0) { + vty_out(vty, "OSPF area ID is invalid\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = inet_aton(router_id, &vl_config.vl_peer); + if (!ret) { + vty_out(vty, "Please specify valid Router ID as a.b.c.d\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + for (int idx = 4; idx < argc; idx++) { + if (strmatch(argv[idx]->text, "hello-interval")) + vl_config.hello_interval = + strtol(argv[++idx]->arg, NULL, 10); + else if (strmatch(argv[idx]->text, "retransmit-interval")) + vl_config.retransmit_interval = + strtol(argv[++idx]->arg, NULL, 10); + else if (strmatch(argv[idx]->text, "transmit-delay")) + vl_config.transmit_delay = + strtol(argv[++idx]->arg, NULL, 10); + else if (strmatch(argv[idx]->text, "dead-interval")) + vl_config.dead_interval = + strtol(argv[++idx]->arg, NULL, 10); + } + + /* Action configuration */ + return ospf_vl_set(ospf, &vl_config); } DEFUN (no_ospf_area_vlink_intervals, @@ -1280,43 +1251,42 @@ DEFUN (no_ospf_area_vlink_intervals, VLINK_HELPSTR_IPADDR VLINK_HELPSTR_TIME_PARAM) { - VTY_DECLVAR_CONTEXT(ospf, ospf); - struct ospf_vl_config_data vl_config; - int ret = 0; - - ospf_vl_config_data_init(&vl_config, vty); - - char *area_id = argv[2]->arg; - char *router_id = argv[4]->arg; - - ret = str2area_id (area_id, &vl_config.area_id, &vl_config.area_id_fmt); - if (ret < 0) - { - vty_out (vty, "OSPF area ID is invalid\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - ret = inet_aton (router_id, &vl_config.vl_peer); - if (! ret) - { - vty_out (vty, "Please specify valid Router ID as a.b.c.d\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - for (int idx = 5; idx < argc; idx++) - { - if (strmatch (argv[idx]->text, "hello-interval")) - vl_config.hello_interval = OSPF_HELLO_INTERVAL_DEFAULT; - else if (strmatch (argv[idx]->text, "retransmit-interval")) - vl_config.retransmit_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT; - else if (strmatch (argv[idx]->text, "transmit-delay")) - vl_config.transmit_delay = OSPF_TRANSMIT_DELAY_DEFAULT; - else if (strmatch (argv[idx]->text, "dead-interval")) - vl_config.dead_interval = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT; - } - - /* Action configuration */ - return ospf_vl_set (ospf, &vl_config); + VTY_DECLVAR_CONTEXT(ospf, ospf); + struct ospf_vl_config_data vl_config; + int ret = 0; + + ospf_vl_config_data_init(&vl_config, vty); + + char *area_id = argv[2]->arg; + char *router_id = argv[4]->arg; + + ret = str2area_id(area_id, &vl_config.area_id, &vl_config.area_id_fmt); + if (ret < 0) { + vty_out(vty, "OSPF area ID is invalid\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = inet_aton(router_id, &vl_config.vl_peer); + if (!ret) { + vty_out(vty, "Please specify valid Router ID as a.b.c.d\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + for (int idx = 5; idx < argc; idx++) { + if (strmatch(argv[idx]->text, "hello-interval")) + vl_config.hello_interval = OSPF_HELLO_INTERVAL_DEFAULT; + else if (strmatch(argv[idx]->text, "retransmit-interval")) + vl_config.retransmit_interval = + OSPF_RETRANSMIT_INTERVAL_DEFAULT; + else if (strmatch(argv[idx]->text, "transmit-delay")) + vl_config.transmit_delay = OSPF_TRANSMIT_DELAY_DEFAULT; + else if (strmatch(argv[idx]->text, "dead-interval")) + vl_config.dead_interval = + OSPF_ROUTER_DEAD_INTERVAL_DEFAULT; + } + + /* Action configuration */ + return ospf_vl_set(ospf, &vl_config); } DEFUN (ospf_area_shortcut, @@ -1330,35 +1300,37 @@ DEFUN (ospf_area_shortcut, "Enable shortcutting through the area\n" "Disable shortcutting through the area\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_number = 1; - int idx_enable_disable = 3; - struct ospf_area *area; - struct in_addr area_id; - int mode; - int format; - - VTY_GET_OSPF_AREA_ID_NO_BB ("shortcut", area_id, format, argv[idx_ipv4_number]->arg); - - area = ospf_area_get (ospf, area_id); - ospf_area_display_format_set (ospf, area, format); - - if (strncmp (argv[idx_enable_disable]->arg, "de", 2) == 0) - mode = OSPF_SHORTCUT_DEFAULT; - else if (strncmp (argv[idx_enable_disable]->arg, "di", 2) == 0) - mode = OSPF_SHORTCUT_DISABLE; - else if (strncmp (argv[idx_enable_disable]->arg, "e", 1) == 0) - mode = OSPF_SHORTCUT_ENABLE; - else - return CMD_WARNING_CONFIG_FAILED; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_number = 1; + int idx_enable_disable = 3; + struct ospf_area *area; + struct in_addr area_id; + int mode; + int format; + + VTY_GET_OSPF_AREA_ID_NO_BB("shortcut", area_id, format, + argv[idx_ipv4_number]->arg); + + area = ospf_area_get(ospf, area_id); + ospf_area_display_format_set(ospf, area, format); + + if (strncmp(argv[idx_enable_disable]->arg, "de", 2) == 0) + mode = OSPF_SHORTCUT_DEFAULT; + else if (strncmp(argv[idx_enable_disable]->arg, "di", 2) == 0) + mode = OSPF_SHORTCUT_DISABLE; + else if (strncmp(argv[idx_enable_disable]->arg, "e", 1) == 0) + mode = OSPF_SHORTCUT_ENABLE; + else + return CMD_WARNING_CONFIG_FAILED; - ospf_area_shortcut_set (ospf, area, mode); + ospf_area_shortcut_set(ospf, area, mode); - if (ospf->abr_type != OSPF_ABR_SHORTCUT) - vty_out (vty, "Shortcut area setting will take effect " - "only when the router is configured as Shortcut ABR\n"); + if (ospf->abr_type != OSPF_ABR_SHORTCUT) + vty_out(vty, + "Shortcut area setting will take effect " + "only when the router is configured as Shortcut ABR\n"); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ospf_area_shortcut, @@ -1372,21 +1344,22 @@ DEFUN (no_ospf_area_shortcut, "Deconfigure enabled shortcutting through the area\n" "Deconfigure disabled shortcutting through the area\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_number = 2; - struct ospf_area *area; - struct in_addr area_id; - int format; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_number = 2; + struct ospf_area *area; + struct in_addr area_id; + int format; - VTY_GET_OSPF_AREA_ID_NO_BB ("shortcut", area_id, format, argv[idx_ipv4_number]->arg); + VTY_GET_OSPF_AREA_ID_NO_BB("shortcut", area_id, format, + argv[idx_ipv4_number]->arg); - area = ospf_area_lookup_by_area_id (ospf, area_id); - if (!area) - return CMD_SUCCESS; + area = ospf_area_lookup_by_area_id(ospf, area_id); + if (!area) + return CMD_SUCCESS; - ospf_area_shortcut_unset (ospf, area); + ospf_area_shortcut_unset(ospf, area); - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -1398,24 +1371,26 @@ DEFUN (ospf_area_stub, "OSPF area ID as a decimal value\n" "Configure OSPF area as stub\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_number = 1; - struct in_addr area_id; - int ret, format; - - VTY_GET_OSPF_AREA_ID_NO_BB ("stub", area_id, format, argv[idx_ipv4_number]->arg); - - ret = ospf_area_stub_set (ospf, area_id); - ospf_area_display_format_set (ospf, ospf_area_get (ospf, area_id), format); - if (ret == 0) - { - vty_out (vty, "First deconfigure all virtual link through this area\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_number = 1; + struct in_addr area_id; + int ret, format; + + VTY_GET_OSPF_AREA_ID_NO_BB("stub", area_id, format, + argv[idx_ipv4_number]->arg); + + ret = ospf_area_stub_set(ospf, area_id); + ospf_area_display_format_set(ospf, ospf_area_get(ospf, area_id), + format); + if (ret == 0) { + vty_out(vty, + "First deconfigure all virtual link through this area\n"); + return CMD_WARNING_CONFIG_FAILED; + } - ospf_area_no_summary_unset (ospf, area_id); + ospf_area_no_summary_unset(ospf, area_id); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (ospf_area_stub_no_summary, @@ -1427,24 +1402,26 @@ DEFUN (ospf_area_stub_no_summary, "Configure OSPF area as stub\n" "Do not inject inter-area routes into stub\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_number = 1; - struct in_addr area_id; - int ret, format; - - VTY_GET_OSPF_AREA_ID_NO_BB ("stub", area_id, format, argv[idx_ipv4_number]->arg); - - ret = ospf_area_stub_set (ospf, area_id); - ospf_area_display_format_set (ospf, ospf_area_get (ospf, area_id), format); - if (ret == 0) - { - vty_out (vty, "%% Area cannot be stub as it contains a virtual link\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_number = 1; + struct in_addr area_id; + int ret, format; + + VTY_GET_OSPF_AREA_ID_NO_BB("stub", area_id, format, + argv[idx_ipv4_number]->arg); + + ret = ospf_area_stub_set(ospf, area_id); + ospf_area_display_format_set(ospf, ospf_area_get(ospf, area_id), + format); + if (ret == 0) { + vty_out(vty, + "%% Area cannot be stub as it contains a virtual link\n"); + return CMD_WARNING_CONFIG_FAILED; + } - ospf_area_no_summary_set (ospf, area_id); + ospf_area_no_summary_set(ospf, area_id); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ospf_area_stub, @@ -1456,17 +1433,18 @@ DEFUN (no_ospf_area_stub, "OSPF area ID as a decimal value\n" "Configure OSPF area as stub\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_number = 2; - struct in_addr area_id; - int format; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_number = 2; + struct in_addr area_id; + int format; - VTY_GET_OSPF_AREA_ID_NO_BB ("stub", area_id, format, argv[idx_ipv4_number]->arg); + VTY_GET_OSPF_AREA_ID_NO_BB("stub", area_id, format, + argv[idx_ipv4_number]->arg); - ospf_area_stub_unset (ospf, area_id); - ospf_area_no_summary_unset (ospf, area_id); + ospf_area_stub_unset(ospf, area_id); + ospf_area_no_summary_unset(ospf, area_id); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ospf_area_stub_no_summary, @@ -1479,61 +1457,59 @@ DEFUN (no_ospf_area_stub_no_summary, "Configure OSPF area as stub\n" "Do not inject inter-area routes into area\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_number = 2; - struct in_addr area_id; - int format; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_number = 2; + struct in_addr area_id; + int format; - VTY_GET_OSPF_AREA_ID_NO_BB ("stub", area_id, format, argv[idx_ipv4_number]->arg); - ospf_area_no_summary_unset (ospf, area_id); + VTY_GET_OSPF_AREA_ID_NO_BB("stub", area_id, format, + argv[idx_ipv4_number]->arg); + ospf_area_no_summary_unset(ospf, area_id); - return CMD_SUCCESS; + return CMD_SUCCESS; } -static int -ospf_area_nssa_cmd_handler (struct vty *vty, int argc, struct cmd_token **argv, - int nosum) +static int ospf_area_nssa_cmd_handler(struct vty *vty, int argc, + struct cmd_token **argv, int nosum) { - VTY_DECLVAR_CONTEXT(ospf, ospf); - struct in_addr area_id; - int ret, format; - - VTY_GET_OSPF_AREA_ID_NO_BB ("NSSA", area_id, format, argv[1]->arg); - - ret = ospf_area_nssa_set (ospf, area_id); - ospf_area_display_format_set (ospf, ospf_area_get (ospf, area_id), format); - if (ret == 0) - { - vty_out (vty, "%% Area cannot be nssa as it contains a virtual link\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (argc > 3) - { - if (strncmp (argv[3]->text, "translate-c", 11) == 0) - ospf_area_nssa_translator_role_set (ospf, area_id, - OSPF_NSSA_ROLE_CANDIDATE); - else if (strncmp (argv[3]->text, "translate-n", 11) == 0) - ospf_area_nssa_translator_role_set (ospf, area_id, - OSPF_NSSA_ROLE_NEVER); - else if (strncmp (argv[3]->text, "translate-a", 11) == 0) - ospf_area_nssa_translator_role_set (ospf, area_id, - OSPF_NSSA_ROLE_ALWAYS); - } - else - { - ospf_area_nssa_translator_role_set (ospf, area_id, - OSPF_NSSA_ROLE_CANDIDATE); - } - - if (nosum) - ospf_area_no_summary_set (ospf, area_id); - else - ospf_area_no_summary_unset (ospf, area_id); - - ospf_schedule_abr_task (ospf); - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(ospf, ospf); + struct in_addr area_id; + int ret, format; + + VTY_GET_OSPF_AREA_ID_NO_BB("NSSA", area_id, format, argv[1]->arg); + + ret = ospf_area_nssa_set(ospf, area_id); + ospf_area_display_format_set(ospf, ospf_area_get(ospf, area_id), + format); + if (ret == 0) { + vty_out(vty, + "%% Area cannot be nssa as it contains a virtual link\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (argc > 3) { + if (strncmp(argv[3]->text, "translate-c", 11) == 0) + ospf_area_nssa_translator_role_set( + ospf, area_id, OSPF_NSSA_ROLE_CANDIDATE); + else if (strncmp(argv[3]->text, "translate-n", 11) == 0) + ospf_area_nssa_translator_role_set( + ospf, area_id, OSPF_NSSA_ROLE_NEVER); + else if (strncmp(argv[3]->text, "translate-a", 11) == 0) + ospf_area_nssa_translator_role_set( + ospf, area_id, OSPF_NSSA_ROLE_ALWAYS); + } else { + ospf_area_nssa_translator_role_set(ospf, area_id, + OSPF_NSSA_ROLE_CANDIDATE); + } + + if (nosum) + ospf_area_no_summary_set(ospf, area_id); + else + ospf_area_no_summary_unset(ospf, area_id); + + ospf_schedule_abr_task(ospf); + + return CMD_SUCCESS; } DEFUN (ospf_area_nssa_translate_no_summary, @@ -1548,7 +1524,7 @@ DEFUN (ospf_area_nssa_translate_no_summary, "Configure NSSA-ABR to always translate\n" "Do not inject inter-area routes into nssa\n") { - return ospf_area_nssa_cmd_handler (vty, argc, argv, 1); + return ospf_area_nssa_cmd_handler(vty, argc, argv, 1); } DEFUN (ospf_area_nssa_translate, @@ -1562,7 +1538,7 @@ DEFUN (ospf_area_nssa_translate, "Configure NSSA-ABR to never translate\n" "Configure NSSA-ABR to always translate\n") { - return ospf_area_nssa_cmd_handler (vty, argc, argv, 0); + return ospf_area_nssa_cmd_handler(vty, argc, argv, 0); } DEFUN (ospf_area_nssa, @@ -1573,7 +1549,7 @@ DEFUN (ospf_area_nssa, "OSPF area ID as a decimal value\n" "Configure OSPF area as nssa\n") { - return ospf_area_nssa_cmd_handler (vty, argc, argv, 0); + return ospf_area_nssa_cmd_handler(vty, argc, argv, 0); } DEFUN (ospf_area_nssa_no_summary, @@ -1585,7 +1561,7 @@ DEFUN (ospf_area_nssa_no_summary, "Configure OSPF area as nssa\n" "Do not inject inter-area routes into nssa\n") { - return ospf_area_nssa_cmd_handler (vty, argc, argv, 1); + return ospf_area_nssa_cmd_handler(vty, argc, argv, 1); } DEFUN (no_ospf_area_nssa, @@ -1601,19 +1577,20 @@ DEFUN (no_ospf_area_nssa, "Configure NSSA-ABR to always translate\n" "Do not inject inter-area routes into nssa\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_number = 2; - struct in_addr area_id; - int format; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_number = 2; + struct in_addr area_id; + int format; - VTY_GET_OSPF_AREA_ID_NO_BB ("NSSA", area_id, format, argv[idx_ipv4_number]->arg); + VTY_GET_OSPF_AREA_ID_NO_BB("NSSA", area_id, format, + argv[idx_ipv4_number]->arg); - ospf_area_nssa_unset (ospf, area_id); - ospf_area_no_summary_unset (ospf, area_id); + ospf_area_nssa_unset(ospf, area_id); + ospf_area_no_summary_unset(ospf, area_id); - ospf_schedule_abr_task (ospf); + ospf_schedule_abr_task(ospf); - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -1626,39 +1603,40 @@ DEFUN (ospf_area_default_cost, "Set the summary-default cost of a NSSA or stub area\n" "Stub's advertised default summary cost\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_number = 1; - int idx_number = 3; - struct ospf_area *area; - struct in_addr area_id; - u_int32_t cost; - int format; - struct prefix_ipv4 p; - - VTY_GET_OSPF_AREA_ID_NO_BB ("default-cost", area_id, format, argv[idx_ipv4_number]->arg); - cost = strtoul(argv[idx_number]->arg, NULL, 10); - - area = ospf_area_get (ospf, area_id); - ospf_area_display_format_set (ospf, area, format); - - if (area->external_routing == OSPF_AREA_DEFAULT) - { - vty_out (vty, "The area is neither stub, nor NSSA\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - area->default_cost = cost; - - p.family = AF_INET; - p.prefix.s_addr = OSPF_DEFAULT_DESTINATION; - p.prefixlen = 0; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_stub_defaults(): " - "announcing 0.0.0.0/0 to area %s", - inet_ntoa (area->area_id)); - ospf_abr_announce_network_to_area (&p, area->default_cost, area); + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_number = 1; + int idx_number = 3; + struct ospf_area *area; + struct in_addr area_id; + u_int32_t cost; + int format; + struct prefix_ipv4 p; + + VTY_GET_OSPF_AREA_ID_NO_BB("default-cost", area_id, format, + argv[idx_ipv4_number]->arg); + cost = strtoul(argv[idx_number]->arg, NULL, 10); + + area = ospf_area_get(ospf, area_id); + ospf_area_display_format_set(ospf, area, format); + + if (area->external_routing == OSPF_AREA_DEFAULT) { + vty_out(vty, "The area is neither stub, nor NSSA\n"); + return CMD_WARNING_CONFIG_FAILED; + } - return CMD_SUCCESS; + area->default_cost = cost; + + p.family = AF_INET; + p.prefix.s_addr = OSPF_DEFAULT_DESTINATION; + p.prefixlen = 0; + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_stub_defaults(): " + "announcing 0.0.0.0/0 to area %s", + inet_ntoa(area->area_id)); + ospf_abr_announce_network_to_area(&p, area->default_cost, area); + + return CMD_SUCCESS; } DEFUN (no_ospf_area_default_cost, @@ -1671,40 +1649,41 @@ DEFUN (no_ospf_area_default_cost, "Set the summary-default cost of a NSSA or stub area\n" "Stub's advertised default summary cost\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_number = 2; - struct ospf_area *area; - struct in_addr area_id; - int format; - struct prefix_ipv4 p; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_number = 2; + struct ospf_area *area; + struct in_addr area_id; + int format; + struct prefix_ipv4 p; - VTY_GET_OSPF_AREA_ID_NO_BB ("default-cost", area_id, format, argv[idx_ipv4_number]->arg); + VTY_GET_OSPF_AREA_ID_NO_BB("default-cost", area_id, format, + argv[idx_ipv4_number]->arg); - area = ospf_area_lookup_by_area_id (ospf, area_id); - if (area == NULL) - return CMD_SUCCESS; + area = ospf_area_lookup_by_area_id(ospf, area_id); + if (area == NULL) + return CMD_SUCCESS; - if (area->external_routing == OSPF_AREA_DEFAULT) - { - vty_out (vty, "The area is neither stub, nor NSSA\n"); - return CMD_WARNING_CONFIG_FAILED; - } + if (area->external_routing == OSPF_AREA_DEFAULT) { + vty_out(vty, "The area is neither stub, nor NSSA\n"); + return CMD_WARNING_CONFIG_FAILED; + } - area->default_cost = 1; + area->default_cost = 1; - p.family = AF_INET; - p.prefix.s_addr = OSPF_DEFAULT_DESTINATION; - p.prefixlen = 0; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_announce_stub_defaults(): " - "announcing 0.0.0.0/0 to area %s", - inet_ntoa (area->area_id)); - ospf_abr_announce_network_to_area (&p, area->default_cost, area); + p.family = AF_INET; + p.prefix.s_addr = OSPF_DEFAULT_DESTINATION; + p.prefixlen = 0; + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "ospf_abr_announce_stub_defaults(): " + "announcing 0.0.0.0/0 to area %s", + inet_ntoa(area->area_id)); + ospf_abr_announce_network_to_area(&p, area->default_cost, area); - ospf_area_check_free (ospf, area_id); + ospf_area_check_free(ospf, area_id); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (ospf_area_export_list, @@ -1716,19 +1695,19 @@ DEFUN (ospf_area_export_list, "Set the filter for networks announced to other areas\n" "Name of the access-list\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_number = 1; - struct ospf_area *area; - struct in_addr area_id; - int format; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_number = 1; + struct ospf_area *area; + struct in_addr area_id; + int format; - VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg); + VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg); - area = ospf_area_get (ospf, area_id); - ospf_area_display_format_set (ospf, area, format); - ospf_area_export_list_set (ospf, area, argv[3]->arg); + area = ospf_area_get(ospf, area_id); + ospf_area_display_format_set(ospf, area, format); + ospf_area_export_list_set(ospf, area, argv[3]->arg); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ospf_area_export_list, @@ -1741,21 +1720,21 @@ DEFUN (no_ospf_area_export_list, "Unset the filter for networks announced to other areas\n" "Name of the access-list\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_number = 2; - struct ospf_area *area; - struct in_addr area_id; - int format; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_number = 2; + struct ospf_area *area; + struct in_addr area_id; + int format; - VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg); + VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg); - area = ospf_area_lookup_by_area_id (ospf, area_id); - if (area == NULL) - return CMD_SUCCESS; + area = ospf_area_lookup_by_area_id(ospf, area_id); + if (area == NULL) + return CMD_SUCCESS; - ospf_area_export_list_unset (ospf, area); + ospf_area_export_list_unset(ospf, area); - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -1768,19 +1747,19 @@ DEFUN (ospf_area_import_list, "Set the filter for networks from other areas announced to the specified one\n" "Name of the access-list\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_number = 1; - struct ospf_area *area; - struct in_addr area_id; - int format; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_number = 1; + struct ospf_area *area; + struct in_addr area_id; + int format; - VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg); + VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg); - area = ospf_area_get (ospf, area_id); - ospf_area_display_format_set (ospf, area, format); - ospf_area_import_list_set (ospf, area, argv[3]->arg); + area = ospf_area_get(ospf, area_id); + ospf_area_display_format_set(ospf, area, format); + ospf_area_import_list_set(ospf, area, argv[3]->arg); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ospf_area_import_list, @@ -1793,21 +1772,21 @@ DEFUN (no_ospf_area_import_list, "Unset the filter for networks announced to other areas\n" "Name of the access-list\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_number = 2; - struct ospf_area *area; - struct in_addr area_id; - int format; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_number = 2; + struct ospf_area *area; + struct in_addr area_id; + int format; - VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg); + VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg); - area = ospf_area_lookup_by_area_id (ospf, area_id); - if (area == NULL) - return CMD_SUCCESS; + area = ospf_area_lookup_by_area_id(ospf, area_id); + if (area == NULL) + return CMD_SUCCESS; - ospf_area_import_list_unset (ospf, area); + ospf_area_import_list_unset(ospf, area); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (ospf_area_filter_list, @@ -1822,40 +1801,37 @@ DEFUN (ospf_area_filter_list, "Filter networks sent to this area\n" "Filter networks sent from this area\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_number = 1; - int idx_word = 4; - int idx_in_out = 5; - struct ospf_area *area; - struct in_addr area_id; - struct prefix_list *plist; - int format; - - VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg); - - area = ospf_area_get (ospf, area_id); - ospf_area_display_format_set (ospf, area, format); - plist = prefix_list_lookup (AFI_IP, argv[idx_word]->arg); - if (strncmp (argv[idx_in_out]->arg, "in", 2) == 0) - { - PREFIX_LIST_IN (area) = plist; - if (PREFIX_NAME_IN (area)) - free (PREFIX_NAME_IN (area)); - - PREFIX_NAME_IN (area) = strdup (argv[idx_word]->arg); - ospf_schedule_abr_task (ospf); - } - else - { - PREFIX_LIST_OUT (area) = plist; - if (PREFIX_NAME_OUT (area)) - free (PREFIX_NAME_OUT (area)); - - PREFIX_NAME_OUT (area) = strdup (argv[idx_word]->arg); - ospf_schedule_abr_task (ospf); - } + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_number = 1; + int idx_word = 4; + int idx_in_out = 5; + struct ospf_area *area; + struct in_addr area_id; + struct prefix_list *plist; + int format; + + VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg); + + area = ospf_area_get(ospf, area_id); + ospf_area_display_format_set(ospf, area, format); + plist = prefix_list_lookup(AFI_IP, argv[idx_word]->arg); + if (strncmp(argv[idx_in_out]->arg, "in", 2) == 0) { + PREFIX_LIST_IN(area) = plist; + if (PREFIX_NAME_IN(area)) + free(PREFIX_NAME_IN(area)); + + PREFIX_NAME_IN(area) = strdup(argv[idx_word]->arg); + ospf_schedule_abr_task(ospf); + } else { + PREFIX_LIST_OUT(area) = plist; + if (PREFIX_NAME_OUT(area)) + free(PREFIX_NAME_OUT(area)); + + PREFIX_NAME_OUT(area) = strdup(argv[idx_word]->arg); + ospf_schedule_abr_task(ospf); + } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ospf_area_filter_list, @@ -1871,49 +1847,48 @@ DEFUN (no_ospf_area_filter_list, "Filter networks sent to this area\n" "Filter networks sent from this area\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_number = 2; - int idx_word = 5; - int idx_in_out = 6; - struct ospf_area *area; - struct in_addr area_id; - int format; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_number = 2; + int idx_word = 5; + int idx_in_out = 6; + struct ospf_area *area; + struct in_addr area_id; + int format; - VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg); + VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg); - if ((area = ospf_area_lookup_by_area_id (ospf, area_id)) == NULL) - return CMD_SUCCESS; - - if (strncmp (argv[idx_in_out]->arg, "in", 2) == 0) - { - if (PREFIX_NAME_IN (area)) - if (strcmp (PREFIX_NAME_IN (area), argv[idx_word]->arg) != 0) - return CMD_SUCCESS; + if ((area = ospf_area_lookup_by_area_id(ospf, area_id)) == NULL) + return CMD_SUCCESS; - PREFIX_LIST_IN (area) = NULL; - if (PREFIX_NAME_IN (area)) - free (PREFIX_NAME_IN (area)); + if (strncmp(argv[idx_in_out]->arg, "in", 2) == 0) { + if (PREFIX_NAME_IN(area)) + if (strcmp(PREFIX_NAME_IN(area), argv[idx_word]->arg) + != 0) + return CMD_SUCCESS; - PREFIX_NAME_IN (area) = NULL; + PREFIX_LIST_IN(area) = NULL; + if (PREFIX_NAME_IN(area)) + free(PREFIX_NAME_IN(area)); - ospf_schedule_abr_task (ospf); - } - else - { - if (PREFIX_NAME_OUT (area)) - if (strcmp (PREFIX_NAME_OUT (area), argv[idx_word]->arg) != 0) - return CMD_SUCCESS; + PREFIX_NAME_IN(area) = NULL; - PREFIX_LIST_OUT (area) = NULL; - if (PREFIX_NAME_OUT (area)) - free (PREFIX_NAME_OUT (area)); + ospf_schedule_abr_task(ospf); + } else { + if (PREFIX_NAME_OUT(area)) + if (strcmp(PREFIX_NAME_OUT(area), argv[idx_word]->arg) + != 0) + return CMD_SUCCESS; - PREFIX_NAME_OUT (area) = NULL; + PREFIX_LIST_OUT(area) = NULL; + if (PREFIX_NAME_OUT(area)) + free(PREFIX_NAME_OUT(area)); - ospf_schedule_abr_task (ospf); - } + PREFIX_NAME_OUT(area) = NULL; - return CMD_SUCCESS; + ospf_schedule_abr_task(ospf); + } + + return CMD_SUCCESS; } @@ -1926,19 +1901,19 @@ DEFUN (ospf_area_authentication_message_digest, "Enable authentication\n" "Use message-digest authentication\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_number = 1; - struct ospf_area *area; - struct in_addr area_id; - int format; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_number = 1; + struct ospf_area *area; + struct in_addr area_id; + int format; - VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg); + VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg); - area = ospf_area_get (ospf, area_id); - ospf_area_display_format_set (ospf, area, format); - area->auth_type = OSPF_AUTH_CRYPTOGRAPHIC; + area = ospf_area_get(ospf, area_id); + ospf_area_display_format_set(ospf, area, format); + area->auth_type = OSPF_AUTH_CRYPTOGRAPHIC; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (ospf_area_authentication, @@ -1949,19 +1924,19 @@ DEFUN (ospf_area_authentication, "OSPF area ID as a decimal value\n" "Enable authentication\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_number = 1; - struct ospf_area *area; - struct in_addr area_id; - int format; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_number = 1; + struct ospf_area *area; + struct in_addr area_id; + int format; - VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg); + VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg); - area = ospf_area_get (ospf, area_id); - ospf_area_display_format_set (ospf, area, format); - area->auth_type = OSPF_AUTH_SIMPLE; + area = ospf_area_get(ospf, area_id); + ospf_area_display_format_set(ospf, area, format); + area->auth_type = OSPF_AUTH_SIMPLE; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ospf_area_authentication, @@ -1973,23 +1948,23 @@ DEFUN (no_ospf_area_authentication, "OSPF area ID as a decimal value\n" "Enable authentication\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4_number = 2; - struct ospf_area *area; - struct in_addr area_id; - int format; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4_number = 2; + struct ospf_area *area; + struct in_addr area_id; + int format; - VTY_GET_OSPF_AREA_ID (area_id, format, argv[idx_ipv4_number]->arg); + VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg); - area = ospf_area_lookup_by_area_id (ospf, area_id); - if (area == NULL) - return CMD_SUCCESS; + area = ospf_area_lookup_by_area_id(ospf, area_id); + if (area == NULL) + return CMD_SUCCESS; - area->auth_type = OSPF_AUTH_NULL; + area->auth_type = OSPF_AUTH_NULL; - ospf_area_check_free (ospf, area_id); - - return CMD_SUCCESS; + ospf_area_check_free(ospf, area_id); + + return CMD_SUCCESS; } @@ -2003,29 +1978,28 @@ DEFUN (ospf_abr_type, "Shortcut ABR\n" "Standard behavior (RFC2328)\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_vendor = 2; - u_char abr_type = OSPF_ABR_UNKNOWN; - - if (strncmp (argv[idx_vendor]->arg, "c", 1) == 0) - abr_type = OSPF_ABR_CISCO; - else if (strncmp (argv[idx_vendor]->arg, "i", 1) == 0) - abr_type = OSPF_ABR_IBM; - else if (strncmp (argv[idx_vendor]->arg, "sh", 2) == 0) - abr_type = OSPF_ABR_SHORTCUT; - else if (strncmp (argv[idx_vendor]->arg, "st", 2) == 0) - abr_type = OSPF_ABR_STAND; - else - return CMD_WARNING_CONFIG_FAILED; - - /* If ABR type value is changed, schedule ABR task. */ - if (ospf->abr_type != abr_type) - { - ospf->abr_type = abr_type; - ospf_schedule_abr_task (ospf); - } + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_vendor = 2; + u_char abr_type = OSPF_ABR_UNKNOWN; + + if (strncmp(argv[idx_vendor]->arg, "c", 1) == 0) + abr_type = OSPF_ABR_CISCO; + else if (strncmp(argv[idx_vendor]->arg, "i", 1) == 0) + abr_type = OSPF_ABR_IBM; + else if (strncmp(argv[idx_vendor]->arg, "sh", 2) == 0) + abr_type = OSPF_ABR_SHORTCUT; + else if (strncmp(argv[idx_vendor]->arg, "st", 2) == 0) + abr_type = OSPF_ABR_STAND; + else + return CMD_WARNING_CONFIG_FAILED; - return CMD_SUCCESS; + /* If ABR type value is changed, schedule ABR task. */ + if (ospf->abr_type != abr_type) { + ospf->abr_type = abr_type; + ospf_schedule_abr_task(ospf); + } + + return CMD_SUCCESS; } DEFUN (no_ospf_abr_type, @@ -2039,29 +2013,28 @@ DEFUN (no_ospf_abr_type, "Shortcut ABR\n" "Standard ABR\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_vendor = 3; - u_char abr_type = OSPF_ABR_UNKNOWN; - - if (strncmp (argv[idx_vendor]->arg, "c", 1) == 0) - abr_type = OSPF_ABR_CISCO; - else if (strncmp (argv[idx_vendor]->arg, "i", 1) == 0) - abr_type = OSPF_ABR_IBM; - else if (strncmp (argv[idx_vendor]->arg, "sh", 2) == 0) - abr_type = OSPF_ABR_SHORTCUT; - else if (strncmp (argv[idx_vendor]->arg, "st", 2) == 0) - abr_type = OSPF_ABR_STAND; - else - return CMD_WARNING_CONFIG_FAILED; - - /* If ABR type value is changed, schedule ABR task. */ - if (ospf->abr_type == abr_type) - { - ospf->abr_type = OSPF_ABR_DEFAULT; - ospf_schedule_abr_task (ospf); - } + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_vendor = 3; + u_char abr_type = OSPF_ABR_UNKNOWN; + + if (strncmp(argv[idx_vendor]->arg, "c", 1) == 0) + abr_type = OSPF_ABR_CISCO; + else if (strncmp(argv[idx_vendor]->arg, "i", 1) == 0) + abr_type = OSPF_ABR_IBM; + else if (strncmp(argv[idx_vendor]->arg, "sh", 2) == 0) + abr_type = OSPF_ABR_SHORTCUT; + else if (strncmp(argv[idx_vendor]->arg, "st", 2) == 0) + abr_type = OSPF_ABR_STAND; + else + return CMD_WARNING_CONFIG_FAILED; - return CMD_SUCCESS; + /* If ABR type value is changed, schedule ABR task. */ + if (ospf->abr_type == abr_type) { + ospf->abr_type = OSPF_ABR_DEFAULT; + ospf_schedule_abr_task(ospf); + } + + return CMD_SUCCESS; } DEFUN (ospf_log_adjacency_changes, @@ -2069,11 +2042,11 @@ DEFUN (ospf_log_adjacency_changes, "log-adjacency-changes", "Log changes in adjacency state\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); + VTY_DECLVAR_CONTEXT(ospf, ospf); - SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES); - UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL); - return CMD_SUCCESS; + SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES); + UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL); + return CMD_SUCCESS; } DEFUN (ospf_log_adjacency_changes_detail, @@ -2082,11 +2055,11 @@ DEFUN (ospf_log_adjacency_changes_detail, "Log changes in adjacency state\n" "Log all state changes\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); + VTY_DECLVAR_CONTEXT(ospf, ospf); - SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES); - SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL); - return CMD_SUCCESS; + SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES); + SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL); + return CMD_SUCCESS; } DEFUN (no_ospf_log_adjacency_changes, @@ -2095,11 +2068,11 @@ DEFUN (no_ospf_log_adjacency_changes, NO_STR "Log changes in adjacency state\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); + VTY_DECLVAR_CONTEXT(ospf, ospf); - UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL); - UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES); - return CMD_SUCCESS; + UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL); + UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES); + return CMD_SUCCESS; } DEFUN (no_ospf_log_adjacency_changes_detail, @@ -2109,10 +2082,10 @@ DEFUN (no_ospf_log_adjacency_changes_detail, "Log changes in adjacency state\n" "Log all state changes\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); + VTY_DECLVAR_CONTEXT(ospf, ospf); - UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL); - return CMD_SUCCESS; + UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL); + return CMD_SUCCESS; } DEFUN (ospf_compatible_rfc1583, @@ -2121,14 +2094,13 @@ DEFUN (ospf_compatible_rfc1583, "OSPF compatibility list\n" "compatible with RFC 1583\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); + VTY_DECLVAR_CONTEXT(ospf, ospf); - if (!CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE)) - { - SET_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE); - ospf_spf_calculate_schedule (ospf, SPF_FLAG_CONFIG_CHANGE); - } - return CMD_SUCCESS; + if (!CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE)) { + SET_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE); + ospf_spf_calculate_schedule(ospf, SPF_FLAG_CONFIG_CHANGE); + } + return CMD_SUCCESS; } DEFUN (no_ospf_compatible_rfc1583, @@ -2138,41 +2110,35 @@ DEFUN (no_ospf_compatible_rfc1583, "OSPF compatibility list\n" "compatible with RFC 1583\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); + VTY_DECLVAR_CONTEXT(ospf, ospf); - if (CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE)) - { - UNSET_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE); - ospf_spf_calculate_schedule (ospf, SPF_FLAG_CONFIG_CHANGE); - } - return CMD_SUCCESS; + if (CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE)) { + UNSET_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE); + ospf_spf_calculate_schedule(ospf, SPF_FLAG_CONFIG_CHANGE); + } + return CMD_SUCCESS; } -ALIAS (ospf_compatible_rfc1583, - ospf_rfc1583_flag_cmd, - "ospf rfc1583compatibility", - "OSPF specific commands\n" - "Enable the RFC1583Compatibility flag\n") +ALIAS(ospf_compatible_rfc1583, ospf_rfc1583_flag_cmd, + "ospf rfc1583compatibility", + "OSPF specific commands\n" + "Enable the RFC1583Compatibility flag\n") -ALIAS (no_ospf_compatible_rfc1583, - no_ospf_rfc1583_flag_cmd, - "no ospf rfc1583compatibility", - NO_STR - "OSPF specific commands\n" - "Disable the RFC1583Compatibility flag\n") +ALIAS(no_ospf_compatible_rfc1583, no_ospf_rfc1583_flag_cmd, + "no ospf rfc1583compatibility", NO_STR + "OSPF specific commands\n" + "Disable the RFC1583Compatibility flag\n") -static int -ospf_timers_spf_set (struct vty *vty, unsigned int delay, - unsigned int hold, - unsigned int max) +static int ospf_timers_spf_set(struct vty *vty, unsigned int delay, + unsigned int hold, unsigned int max) { - VTY_DECLVAR_CONTEXT(ospf, ospf); + VTY_DECLVAR_CONTEXT(ospf, ospf); - ospf->spf_delay = delay; - ospf->spf_holdtime = hold; - ospf->spf_max_holdtime = max; - - return CMD_SUCCESS; + ospf->spf_delay = delay; + ospf->spf_holdtime = hold; + ospf->spf_max_holdtime = max; + + return CMD_SUCCESS; } DEFUN (ospf_timers_min_ls_interval, @@ -2184,21 +2150,20 @@ DEFUN (ospf_timers_min_ls_interval, "All LSA types\n" "Delay (msec) between sending LSAs\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_number = 4; - unsigned int interval; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_number = 4; + unsigned int interval; - if (argc < 5) - { - vty_out (vty, "Insufficient arguments\n"); - return CMD_WARNING_CONFIG_FAILED; - } + if (argc < 5) { + vty_out(vty, "Insufficient arguments\n"); + return CMD_WARNING_CONFIG_FAILED; + } - interval = strtoul(argv[idx_number]->arg, NULL, 10); + interval = strtoul(argv[idx_number]->arg, NULL, 10); - ospf->min_ls_interval = interval; + ospf->min_ls_interval = interval; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ospf_timers_min_ls_interval, @@ -2211,10 +2176,10 @@ DEFUN (no_ospf_timers_min_ls_interval, "All LSA types\n" "Delay (msec) between sending LSAs\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - ospf->min_ls_interval = OSPF_MIN_LS_INTERVAL; + VTY_DECLVAR_CONTEXT(ospf, ospf); + ospf->min_ls_interval = OSPF_MIN_LS_INTERVAL; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -2226,21 +2191,20 @@ DEFUN (ospf_timers_min_ls_arrival, "OSPF minimum arrival interval delay\n" "Delay (msec) between accepted LSAs\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_number = 3; - unsigned int arrival; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_number = 3; + unsigned int arrival; - if (argc < 4) - { - vty_out (vty, "Insufficient arguments\n"); - return CMD_WARNING_CONFIG_FAILED; - } + if (argc < 4) { + vty_out(vty, "Insufficient arguments\n"); + return CMD_WARNING_CONFIG_FAILED; + } - arrival = strtoul(argv[idx_number]->arg, NULL, 10); + arrival = strtoul(argv[idx_number]->arg, NULL, 10); - ospf->min_ls_arrival = arrival; + ospf->min_ls_arrival = arrival; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ospf_timers_min_ls_arrival, @@ -2252,11 +2216,11 @@ DEFUN (no_ospf_timers_min_ls_arrival, "OSPF minimum arrival interval delay\n" "Delay (msec) between accepted LSAs\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); + VTY_DECLVAR_CONTEXT(ospf, ospf); - ospf->min_ls_arrival = OSPF_MIN_LS_ARRIVAL; + ospf->min_ls_arrival = OSPF_MIN_LS_ARRIVAL; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -2270,22 +2234,21 @@ DEFUN (ospf_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; - - if (argc < 6) - { - vty_out (vty, "Insufficient arguments\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - 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 ospf_timers_spf_set (vty, delay, hold, max); + int idx_number = 3; + int idx_number_2 = 4; + int idx_number_3 = 5; + unsigned int delay, hold, max; + + if (argc < 6) { + vty_out(vty, "Insufficient arguments\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + 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 ospf_timers_spf_set(vty, delay, hold, max); } DEFUN (no_ospf_timers_throttle_spf, @@ -2299,10 +2262,9 @@ DEFUN (no_ospf_timers_throttle_spf, "Initial hold time (msec) between consecutive SPF calculations\n" "Maximum hold time (msec)\n") { - return ospf_timers_spf_set (vty, - OSPF_SPF_DELAY_DEFAULT, - OSPF_SPF_HOLDTIME_DEFAULT, - OSPF_SPF_MAX_HOLDTIME_DEFAULT); + return ospf_timers_spf_set(vty, OSPF_SPF_DELAY_DEFAULT, + OSPF_SPF_HOLDTIME_DEFAULT, + OSPF_SPF_MAX_HOLDTIME_DEFAULT); } @@ -2314,21 +2276,20 @@ DEFUN (ospf_timers_lsa, "Minimum delay in receiving new version of a LSA\n" "Delay in milliseconds\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_number = 3; - unsigned int minarrival; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_number = 3; + unsigned int minarrival; - if (argc < 4) - { - vty_out (vty, "Insufficient number of arguments\n"); - return CMD_WARNING_CONFIG_FAILED; - } + if (argc < 4) { + vty_out(vty, "Insufficient number of arguments\n"); + return CMD_WARNING_CONFIG_FAILED; + } - minarrival = strtoul(argv[idx_number]->arg, NULL, 10); + minarrival = strtoul(argv[idx_number]->arg, NULL, 10); - ospf->min_ls_arrival = minarrival; + ospf->min_ls_arrival = minarrival; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ospf_timers_lsa, @@ -2340,21 +2301,20 @@ DEFUN (no_ospf_timers_lsa, "Minimum delay in receiving new version of a LSA\n" "Delay in milliseconds\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - unsigned int minarrival; + VTY_DECLVAR_CONTEXT(ospf, ospf); + unsigned int minarrival; - if (argc > 4) - { - minarrival = strtoul(argv[4]->arg, NULL, 10); + if (argc > 4) { + minarrival = strtoul(argv[4]->arg, NULL, 10); - if (ospf->min_ls_arrival != minarrival || - minarrival == OSPF_MIN_LS_ARRIVAL) - return CMD_SUCCESS; - } + if (ospf->min_ls_arrival != minarrival + || minarrival == OSPF_MIN_LS_ARRIVAL) + return CMD_SUCCESS; + } - ospf->min_ls_arrival = OSPF_MIN_LS_ARRIVAL; + ospf->min_ls_arrival = OSPF_MIN_LS_ARRIVAL; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (ospf_neighbor, @@ -2367,31 +2327,31 @@ DEFUN (ospf_neighbor, "Dead Neighbor Polling interval\n" "Seconds\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4 = 1; - int idx_pri = 3; - int idx_poll = 5; - struct in_addr nbr_addr; - unsigned int priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT; - unsigned int interval = OSPF_POLL_INTERVAL_DEFAULT; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4 = 1; + int idx_pri = 3; + int idx_poll = 5; + struct in_addr nbr_addr; + unsigned int priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT; + unsigned int interval = OSPF_POLL_INTERVAL_DEFAULT; - inet_aton(argv[idx_ipv4]->arg, &nbr_addr); + inet_aton(argv[idx_ipv4]->arg, &nbr_addr); - if (argc > 2) - priority = strtoul(argv[idx_pri]->arg, NULL, 10); + if (argc > 2) + priority = strtoul(argv[idx_pri]->arg, NULL, 10); - if (argc > 4) - interval = strtoul(argv[idx_poll]->arg, NULL, 10); + if (argc > 4) + interval = strtoul(argv[idx_poll]->arg, NULL, 10); - ospf_nbr_nbma_set (ospf, nbr_addr); + ospf_nbr_nbma_set(ospf, nbr_addr); - if (argc > 2) - ospf_nbr_nbma_priority_set (ospf, nbr_addr, priority); + if (argc > 2) + ospf_nbr_nbma_priority_set(ospf, nbr_addr, priority); - if (argc > 4) - ospf_nbr_nbma_poll_interval_set (ospf, nbr_addr, interval); + if (argc > 4) + ospf_nbr_nbma_poll_interval_set(ospf, nbr_addr, interval); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (ospf_neighbor_poll_interval, @@ -2404,28 +2364,28 @@ DEFUN (ospf_neighbor_poll_interval, "OSPF priority of non-broadcast neighbor\n" "Priority\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4 = 1; - int idx_poll = 3; - int idx_pri = 5; - struct in_addr nbr_addr; - unsigned int priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT; - unsigned int interval = OSPF_POLL_INTERVAL_DEFAULT; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4 = 1; + int idx_poll = 3; + int idx_pri = 5; + struct in_addr nbr_addr; + unsigned int priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT; + unsigned int interval = OSPF_POLL_INTERVAL_DEFAULT; - inet_aton(argv[idx_ipv4]->arg, &nbr_addr); + inet_aton(argv[idx_ipv4]->arg, &nbr_addr); - interval = strtoul(argv[idx_poll]->arg, NULL, 10); + interval = strtoul(argv[idx_poll]->arg, NULL, 10); - if (argc > 4) - priority = strtoul(argv[idx_pri]->arg, NULL, 10); + if (argc > 4) + priority = strtoul(argv[idx_pri]->arg, NULL, 10); - ospf_nbr_nbma_set (ospf, nbr_addr); - ospf_nbr_nbma_poll_interval_set (ospf, nbr_addr, interval); + ospf_nbr_nbma_set(ospf, nbr_addr); + ospf_nbr_nbma_poll_interval_set(ospf, nbr_addr, interval); - if (argc > 4) - ospf_nbr_nbma_priority_set (ospf, nbr_addr, priority); + if (argc > 4) + ospf_nbr_nbma_priority_set(ospf, nbr_addr, priority); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ospf_neighbor, @@ -2439,15 +2399,15 @@ DEFUN (no_ospf_neighbor, "Dead Neighbor Polling interval\n" "Seconds\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4 = 2; - struct in_addr nbr_addr; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4 = 2; + struct in_addr nbr_addr; - inet_aton(argv[idx_ipv4]->arg, &nbr_addr); + inet_aton(argv[idx_ipv4]->arg, &nbr_addr); - (void)ospf_nbr_nbma_unset (ospf, nbr_addr); + (void)ospf_nbr_nbma_unset(ospf, nbr_addr); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ospf_neighbor_poll, @@ -2461,15 +2421,15 @@ DEFUN (no_ospf_neighbor_poll, "Neighbor Priority\n" "Priority\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ipv4 = 2; - struct in_addr nbr_addr; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ipv4 = 2; + struct in_addr nbr_addr; - inet_aton(argv[idx_ipv4]->arg, &nbr_addr); + inet_aton(argv[idx_ipv4]->arg, &nbr_addr); - (void)ospf_nbr_nbma_unset (ospf, nbr_addr); + (void)ospf_nbr_nbma_unset(ospf, nbr_addr); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (ospf_refresh_timer, @@ -2479,16 +2439,17 @@ DEFUN (ospf_refresh_timer, "Set refresh timer\n" "Timer value in seconds\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_number = 2; - unsigned int interval; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_number = 2; + unsigned int interval; - interval = strtoul(argv[idx_number]->arg, NULL, 10); - interval = (interval / OSPF_LSA_REFRESHER_GRANULARITY) * OSPF_LSA_REFRESHER_GRANULARITY; + interval = strtoul(argv[idx_number]->arg, NULL, 10); + interval = (interval / OSPF_LSA_REFRESHER_GRANULARITY) + * OSPF_LSA_REFRESHER_GRANULARITY; - ospf_timers_refresh_set (ospf, interval); + ospf_timers_refresh_set(ospf, interval); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ospf_refresh_timer, @@ -2499,22 +2460,21 @@ DEFUN (no_ospf_refresh_timer, "Unset refresh timer\n" "Timer value in seconds\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_number = 3; - unsigned int interval; - - if (argc == 1) - { - interval = strtoul(argv[idx_number]->arg, NULL, 10); - - if (ospf->lsa_refresh_interval != interval || - interval == OSPF_LSA_REFRESH_INTERVAL_DEFAULT) - return CMD_SUCCESS; - } + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_number = 3; + unsigned int interval; - ospf_timers_refresh_unset (ospf); + if (argc == 1) { + interval = strtoul(argv[idx_number]->arg, NULL, 10); - return CMD_SUCCESS; + if (ospf->lsa_refresh_interval != interval + || interval == OSPF_LSA_REFRESH_INTERVAL_DEFAULT) + return CMD_SUCCESS; + } + + ospf_timers_refresh_unset(ospf); + + return CMD_SUCCESS; } @@ -2525,28 +2485,27 @@ DEFUN (ospf_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(ospf, ospf); - int idx_number = 2; - u_int32_t refbw; - struct listnode *node; - struct interface *ifp; - - 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) == ospf->ref_bandwidth) - return CMD_SUCCESS; - - ospf->ref_bandwidth = refbw; - for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp)) - ospf_if_recalculate_output_cost (ifp); - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_number = 2; + u_int32_t refbw; + struct listnode *node; + struct interface *ifp; + + 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) == ospf->ref_bandwidth) + return CMD_SUCCESS; + + ospf->ref_bandwidth = refbw; + for (ALL_LIST_ELEMENTS_RO(om->iflist, node, ifp)) + ospf_if_recalculate_output_cost(ifp); + + return CMD_SUCCESS; } DEFUN (no_ospf_auto_cost_reference_bandwidth, @@ -2557,21 +2516,22 @@ DEFUN (no_ospf_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(ospf, ospf); - struct listnode *node, *nnode; - struct interface *ifp; + VTY_DECLVAR_CONTEXT(ospf, ospf); + struct listnode *node, *nnode; + struct interface *ifp; - if (ospf->ref_bandwidth == OSPF_DEFAULT_REF_BANDWIDTH) - return CMD_SUCCESS; - - ospf->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH; - vty_out (vty, "%% OSPF: Reference bandwidth is changed.\n"); - vty_out (vty, " Please ensure reference bandwidth is consistent across all routers\n"); - - for (ALL_LIST_ELEMENTS (om->iflist, node, nnode, ifp)) - ospf_if_recalculate_output_cost (ifp); - - return CMD_SUCCESS; + if (ospf->ref_bandwidth == OSPF_DEFAULT_REF_BANDWIDTH) + return CMD_SUCCESS; + + ospf->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH; + vty_out(vty, "%% OSPF: Reference bandwidth is changed.\n"); + vty_out(vty, + " Please ensure reference bandwidth is consistent across all routers\n"); + + for (ALL_LIST_ELEMENTS(om->iflist, node, nnode, ifp)) + ospf_if_recalculate_output_cost(ifp); + + return CMD_SUCCESS; } DEFUN (ospf_write_multiplier, @@ -2581,31 +2541,28 @@ DEFUN (ospf_write_multiplier, "Write multiplier\n" "Maximum number of interface serviced per write\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_number; - u_int32_t write_oi_count; - - if (argc == 3) - idx_number = 2; - else - idx_number = 1; - - write_oi_count = strtol (argv[idx_number]->arg, NULL, 10); - if (write_oi_count < 1 || write_oi_count > 100) - { - vty_out (vty, "write-multiplier value is invalid\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - ospf->write_oi_count = write_oi_count; - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_number; + u_int32_t write_oi_count; + + if (argc == 3) + idx_number = 2; + else + idx_number = 1; + + write_oi_count = strtol(argv[idx_number]->arg, NULL, 10); + if (write_oi_count < 1 || write_oi_count > 100) { + vty_out(vty, "write-multiplier value is invalid\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ospf->write_oi_count = write_oi_count; + return CMD_SUCCESS; } -ALIAS (ospf_write_multiplier, - write_multiplier_cmd, - "write-multiplier (1-100)", - "Write multiplier\n" - "Maximum number of interface serviced per write\n") +ALIAS(ospf_write_multiplier, write_multiplier_cmd, "write-multiplier (1-100)", + "Write multiplier\n" + "Maximum number of interface serviced per write\n") DEFUN (no_ospf_write_multiplier, no_ospf_write_multiplier_cmd, @@ -2615,564 +2572,618 @@ DEFUN (no_ospf_write_multiplier, "Write multiplier\n" "Maximum number of interface serviced per write\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); + VTY_DECLVAR_CONTEXT(ospf, ospf); - ospf->write_oi_count = OSPF_WRITE_INTERFACE_COUNT_DEFAULT; - return CMD_SUCCESS; + ospf->write_oi_count = OSPF_WRITE_INTERFACE_COUNT_DEFAULT; + return CMD_SUCCESS; } -ALIAS (no_ospf_write_multiplier, - no_write_multiplier_cmd, - "no write-multiplier (1-100)", - NO_STR - "Write multiplier\n" - "Maximum number of interface serviced per write\n") +ALIAS(no_ospf_write_multiplier, no_write_multiplier_cmd, + "no write-multiplier (1-100)", NO_STR + "Write multiplier\n" + "Maximum number of interface serviced per write\n") + +const char *ospf_abr_type_descr_str[] = {"Unknown", "Standard (RFC2328)", + "Alternative IBM", "Alternative Cisco", + "Alternative Shortcut"}; + +const char *ospf_shortcut_mode_descr_str[] = {"Default", "Enabled", "Disabled"}; + +static void show_ip_ospf_area(struct vty *vty, struct ospf_area *area, + json_object *json_areas, u_char use_json) +{ + json_object *json_area = NULL; + + if (use_json) + json_area = json_object_new_object(); + + /* Show Area ID. */ + if (!use_json) + vty_out(vty, " Area ID: %s", inet_ntoa(area->area_id)); + + /* Show Area type/mode. */ + if (OSPF_IS_AREA_BACKBONE(area)) { + if (use_json) + json_object_boolean_true_add(json_area, "backbone"); + else + vty_out(vty, " (Backbone)\n"); + } else { + if (use_json) { + if (area->external_routing == OSPF_AREA_STUB) { + if (area->no_summary) + json_object_boolean_true_add( + json_area, "stubNoSummary"); + if (area->shortcut_configured) + json_object_boolean_true_add( + json_area, "stubShortcut"); + } else if (area->external_routing == OSPF_AREA_NSSA) { + if (area->no_summary) + json_object_boolean_true_add( + json_area, "nssaNoSummary"); + if (area->shortcut_configured) + json_object_boolean_true_add( + json_area, "nssaShortcut"); + } -const char *ospf_abr_type_descr_str[] = -{ - "Unknown", - "Standard (RFC2328)", - "Alternative IBM", - "Alternative Cisco", - "Alternative Shortcut" -}; + json_object_string_add( + json_area, "shortcuttingMode", + ospf_shortcut_mode_descr_str + [area->shortcut_configured]); + if (area->shortcut_capability) + json_object_boolean_true_add(json_area, + "sBitConcensus"); + } else { + if (area->external_routing == OSPF_AREA_STUB) + vty_out(vty, " (Stub%s%s)", + area->no_summary ? ", no summary" : "", + area->shortcut_configured ? "; " : ""); + else if (area->external_routing == OSPF_AREA_NSSA) + vty_out(vty, " (NSSA%s%s)", + area->no_summary ? ", no summary" : "", + area->shortcut_configured ? "; " : ""); + + vty_out(vty, "\n"); + vty_out(vty, " Shortcutting mode: %s", + ospf_shortcut_mode_descr_str + [area->shortcut_configured]); + vty_out(vty, ", S-bit consensus: %s\n", + area->shortcut_capability ? "ok" : "no"); + } + } -const char *ospf_shortcut_mode_descr_str[] = -{ - "Default", - "Enabled", - "Disabled" -}; + /* Show number of interfaces */ + if (use_json) { + json_object_int_add(json_area, "areaIfTotalCounter", + listcount(area->oiflist)); + json_object_int_add(json_area, "areaIfActiveCounter", + area->act_ints); + } else + vty_out(vty, + " Number of interfaces in this area: Total: %d, " + "Active: %d\n", + listcount(area->oiflist), area->act_ints); + + if (area->external_routing == OSPF_AREA_NSSA) { + if (use_json) { + json_object_boolean_true_add(json_area, "nssa"); + if (!IS_OSPF_ABR(area->ospf)) + json_object_boolean_false_add(json_area, "abr"); + else if (area->NSSATranslatorState) { + json_object_boolean_true_add(json_area, "abr"); + if (area->NSSATranslatorRole + == OSPF_NSSA_ROLE_CANDIDATE) + json_object_boolean_true_add( + json_area, + "nssaTranslatorElected"); + else if (area->NSSATranslatorRole + == OSPF_NSSA_ROLE_ALWAYS) + json_object_boolean_true_add( + json_area, + "nssaTranslatorAlways"); + } else { + json_object_boolean_true_add(json_area, "abr"); + if (area->NSSATranslatorRole + == OSPF_NSSA_ROLE_CANDIDATE) + json_object_boolean_false_add( + json_area, + "nssaTranslatorElected"); + else + json_object_boolean_true_add( + json_area, + "nssaTranslatorNever"); + } + } else { + vty_out(vty, + " It is an NSSA configuration. \n Elected NSSA/ABR performs type-7/type-5 LSA translation. \n"); + if (!IS_OSPF_ABR(area->ospf)) + vty_out(vty, + " It is not ABR, therefore not Translator. \n"); + else if (area->NSSATranslatorState) { + vty_out(vty, " We are an ABR and "); + if (area->NSSATranslatorRole + == OSPF_NSSA_ROLE_CANDIDATE) + vty_out(vty, + "the NSSA Elected Translator. \n"); + else if (area->NSSATranslatorRole + == OSPF_NSSA_ROLE_ALWAYS) + vty_out(vty, + "always an NSSA Translator. \n"); + } else { + vty_out(vty, " We are an ABR, but "); + if (area->NSSATranslatorRole + == OSPF_NSSA_ROLE_CANDIDATE) + vty_out(vty, + "not the NSSA Elected Translator. \n"); + else + vty_out(vty, + "never an NSSA Translator. \n"); + } + } + } -static void -show_ip_ospf_area (struct vty *vty, struct ospf_area *area, json_object *json_areas, u_char use_json) -{ - json_object *json_area = NULL; - - if (use_json) - json_area = json_object_new_object(); - - /* Show Area ID. */ - if (!use_json) - vty_out (vty, " Area ID: %s", inet_ntoa (area->area_id)); - - /* Show Area type/mode. */ - if (OSPF_IS_AREA_BACKBONE (area)) - { - if (use_json) - json_object_boolean_true_add(json_area, "backbone"); - else - vty_out (vty, " (Backbone)\n"); - } - else - { - if (use_json) - { - if (area->external_routing == OSPF_AREA_STUB) - { - if (area->no_summary) - json_object_boolean_true_add(json_area, "stubNoSummary"); - if (area->shortcut_configured) - json_object_boolean_true_add(json_area, "stubShortcut"); - } - else if (area->external_routing == OSPF_AREA_NSSA) - { - if (area->no_summary) - json_object_boolean_true_add(json_area, "nssaNoSummary"); - if (area->shortcut_configured) - json_object_boolean_true_add(json_area, "nssaShortcut"); - } - - json_object_string_add(json_area,"shortcuttingMode", - ospf_shortcut_mode_descr_str[area->shortcut_configured]); - if (area->shortcut_capability) - json_object_boolean_true_add(json_area,"sBitConcensus"); - } - else - { - if (area->external_routing == OSPF_AREA_STUB) - vty_out (vty, " (Stub%s%s)", - area->no_summary ? ", no summary" : "", - area->shortcut_configured ? "; " : ""); - else if (area->external_routing == OSPF_AREA_NSSA) - vty_out (vty, " (NSSA%s%s)", - area->no_summary ? ", no summary" : "", - area->shortcut_configured ? "; " : ""); - - vty_out (vty, "\n"); - vty_out (vty, " Shortcutting mode: %s", - ospf_shortcut_mode_descr_str[area->shortcut_configured]); - vty_out (vty, ", S-bit consensus: %s\n", - area->shortcut_capability ? "ok" : "no"); - } - } - - /* Show number of interfaces */ - if (use_json) - { - json_object_int_add(json_area, "areaIfTotalCounter", listcount (area->oiflist)); - json_object_int_add(json_area, "areaIfActiveCounter", area->act_ints); - } - else - vty_out (vty, " Number of interfaces in this area: Total: %d, " - "Active: %d\n", listcount (area->oiflist), - area->act_ints); - - if (area->external_routing == OSPF_AREA_NSSA) - { - if (use_json) - { - json_object_boolean_true_add(json_area, "nssa"); - if (! IS_OSPF_ABR (area->ospf)) - json_object_boolean_false_add(json_area, "abr"); - else if (area->NSSATranslatorState) - { - json_object_boolean_true_add(json_area, "abr"); - if (area->NSSATranslatorRole == OSPF_NSSA_ROLE_CANDIDATE) - json_object_boolean_true_add(json_area, "nssaTranslatorElected"); - else if (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS) - json_object_boolean_true_add(json_area, "nssaTranslatorAlways"); - } - else - { - json_object_boolean_true_add(json_area, "abr"); - if (area->NSSATranslatorRole == OSPF_NSSA_ROLE_CANDIDATE) - json_object_boolean_false_add(json_area, "nssaTranslatorElected"); - else - json_object_boolean_true_add(json_area, "nssaTranslatorNever"); - } - } - else - { - vty_out (vty, " It is an NSSA configuration. \n Elected NSSA/ABR performs type-7/type-5 LSA translation. \n"); - if (! IS_OSPF_ABR (area->ospf)) - vty_out (vty, " It is not ABR, therefore not Translator. \n"); - else if (area->NSSATranslatorState) - { - vty_out (vty, " We are an ABR and "); - if (area->NSSATranslatorRole == OSPF_NSSA_ROLE_CANDIDATE) - vty_out (vty, "the NSSA Elected Translator. \n"); - else if (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS) - vty_out (vty, "always an NSSA Translator. \n"); - } - else - { - vty_out (vty, " We are an ABR, but "); - if (area->NSSATranslatorRole == OSPF_NSSA_ROLE_CANDIDATE) - vty_out (vty, "not the NSSA Elected Translator. \n"); - else - vty_out (vty, "never an NSSA Translator. \n"); - } - } - } - - /* Stub-router state for this area */ - if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED)) - { - char timebuf[OSPF_TIME_DUMP_SIZE]; - - if (use_json) - { - json_object_boolean_true_add(json_area, "originStubMaxDistRouterLsa"); - if (CHECK_FLAG(area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED)) - json_object_boolean_true_add(json_area, "indefiniteActiveAdmin"); - if (area->t_stub_router) - { - long time_store; - time_store = monotime_until(&area->t_stub_router->u.sands, NULL) / 1000LL; - json_object_int_add(json_area, "activeStartupRemainderMsecs", time_store); - } - } - else - { - vty_out (vty, " Originating stub / maximum-distance Router-LSA\n"); - if (CHECK_FLAG(area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED)) - vty_out (vty, " Administratively activated (indefinitely)\n"); - if (area->t_stub_router) - vty_out (vty, " Active from startup, %s remaining\n", - ospf_timer_dump (area->t_stub_router, timebuf, - sizeof(timebuf))); - } - } - - if (use_json) - { - /* Show number of fully adjacent neighbors. */ - json_object_int_add(json_area, "nbrFullAdjacentCounter", area->full_nbrs); - - /* Show authentication type. */ - if (area->auth_type == OSPF_AUTH_NULL) - json_object_string_add(json_area, "authentication", "authenticationNone"); - else if (area->auth_type == OSPF_AUTH_SIMPLE) - json_object_string_add(json_area, "authentication", "authenticationSimplePassword"); - else if (area->auth_type == OSPF_AUTH_CRYPTOGRAPHIC) - json_object_string_add(json_area, "authentication", "authenticationMessageDigest"); - - if (!OSPF_IS_AREA_BACKBONE (area)) - json_object_int_add(json_area, "virtualAdjacenciesPassingCounter", area->full_vls); - - /* Show SPF calculation times. */ - json_object_int_add(json_area, "spfExecutedCounter", area->spf_calculation); - json_object_int_add(json_area, "lsaNumber", area->lsdb->total); - json_object_int_add(json_area, "lsaRouterNumber", ospf_lsdb_count (area->lsdb, OSPF_ROUTER_LSA)); - json_object_int_add(json_area, "lsaRouterChecksum", ospf_lsdb_checksum (area->lsdb, OSPF_ROUTER_LSA)); - json_object_int_add(json_area, "lsaNetworkNumber", ospf_lsdb_count (area->lsdb, OSPF_NETWORK_LSA)); - json_object_int_add(json_area, "lsaNetworkChecksum", ospf_lsdb_checksum (area->lsdb, OSPF_NETWORK_LSA)); - json_object_int_add(json_area, "lsaSummaryNumber", ospf_lsdb_count (area->lsdb, OSPF_SUMMARY_LSA)); - json_object_int_add(json_area, "lsaSummaryChecksum", ospf_lsdb_checksum (area->lsdb, OSPF_SUMMARY_LSA)); - json_object_int_add(json_area, "lsaAsbrNumber", ospf_lsdb_count (area->lsdb, OSPF_ASBR_SUMMARY_LSA)); - json_object_int_add(json_area, "lsaAsbrChecksum", ospf_lsdb_checksum (area->lsdb, OSPF_ASBR_SUMMARY_LSA)); - json_object_int_add(json_area, "lsaNssaNumber", ospf_lsdb_count (area->lsdb, OSPF_AS_NSSA_LSA)); - json_object_int_add(json_area, "lsaNssaChecksum", ospf_lsdb_checksum (area->lsdb, OSPF_AS_NSSA_LSA)); - } - else - { - /* Show number of fully adjacent neighbors. */ - vty_out (vty, " Number of fully adjacent neighbors in this area:" - " %d\n", area->full_nbrs); - - /* Show authentication type. */ - vty_out (vty, " Area has "); - if (area->auth_type == OSPF_AUTH_NULL) - vty_out (vty, "no authentication\n"); - else if (area->auth_type == OSPF_AUTH_SIMPLE) - vty_out (vty, "simple password authentication\n"); - else if (area->auth_type == OSPF_AUTH_CRYPTOGRAPHIC) - vty_out (vty, "message digest authentication\n"); - - if (!OSPF_IS_AREA_BACKBONE (area)) - vty_out (vty, " Number of full virtual adjacencies going through" - " this area: %d\n", area->full_vls); - - /* Show SPF calculation times. */ - vty_out (vty, " SPF algorithm executed %d times\n", - area->spf_calculation); - - /* Show number of LSA. */ - vty_out (vty, " Number of LSA %ld\n", area->lsdb->total); - vty_out (vty, " Number of router LSA %ld. Checksum Sum 0x%08x\n", - ospf_lsdb_count (area->lsdb, OSPF_ROUTER_LSA), - ospf_lsdb_checksum (area->lsdb, OSPF_ROUTER_LSA)); - vty_out (vty, " Number of network LSA %ld. Checksum Sum 0x%08x\n", - ospf_lsdb_count (area->lsdb, OSPF_NETWORK_LSA), - ospf_lsdb_checksum (area->lsdb, OSPF_NETWORK_LSA)); - vty_out (vty, " Number of summary LSA %ld. Checksum Sum 0x%08x\n", - ospf_lsdb_count (area->lsdb, OSPF_SUMMARY_LSA), - ospf_lsdb_checksum (area->lsdb, OSPF_SUMMARY_LSA)); - vty_out (vty, " Number of ASBR summary LSA %ld. Checksum Sum 0x%08x\n", - ospf_lsdb_count (area->lsdb, OSPF_ASBR_SUMMARY_LSA), - ospf_lsdb_checksum (area->lsdb, OSPF_ASBR_SUMMARY_LSA)); - vty_out (vty, " Number of NSSA LSA %ld. Checksum Sum 0x%08x\n", - ospf_lsdb_count (area->lsdb, OSPF_AS_NSSA_LSA), - ospf_lsdb_checksum (area->lsdb, OSPF_AS_NSSA_LSA)); - } - - if (use_json) - { - json_object_int_add(json_area, "lsaOpaqueLinkNumber", ospf_lsdb_count (area->lsdb, OSPF_OPAQUE_LINK_LSA)); - json_object_int_add(json_area, "lsaOpaqueLinkChecksum", ospf_lsdb_checksum (area->lsdb, OSPF_OPAQUE_LINK_LSA)); - json_object_int_add(json_area, "lsaOpaqueAreaNumber", ospf_lsdb_count (area->lsdb, OSPF_OPAQUE_AREA_LSA)); - json_object_int_add(json_area, "lsaOpaqueAreaChecksum", ospf_lsdb_checksum (area->lsdb, OSPF_OPAQUE_AREA_LSA)); - } - else - { - vty_out (vty, " Number of opaque link LSA %ld. Checksum Sum 0x%08x\n", - ospf_lsdb_count (area->lsdb, OSPF_OPAQUE_LINK_LSA), - ospf_lsdb_checksum (area->lsdb, OSPF_OPAQUE_LINK_LSA)); - vty_out (vty, " Number of opaque area LSA %ld. Checksum Sum 0x%08x\n", - ospf_lsdb_count (area->lsdb, OSPF_OPAQUE_AREA_LSA), - ospf_lsdb_checksum (area->lsdb, OSPF_OPAQUE_AREA_LSA)); - } - - if (use_json) - json_object_object_add(json_areas, inet_ntoa (area->area_id), json_area); - else - vty_out (vty, "\n"); + /* Stub-router state for this area */ + if (CHECK_FLAG(area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED)) { + char timebuf[OSPF_TIME_DUMP_SIZE]; + + if (use_json) { + json_object_boolean_true_add( + json_area, "originStubMaxDistRouterLsa"); + if (CHECK_FLAG(area->stub_router_state, + OSPF_AREA_ADMIN_STUB_ROUTED)) + json_object_boolean_true_add( + json_area, "indefiniteActiveAdmin"); + if (area->t_stub_router) { + long time_store; + time_store = + monotime_until( + &area->t_stub_router->u.sands, + NULL) + / 1000LL; + json_object_int_add( + json_area, + "activeStartupRemainderMsecs", + time_store); + } + } else { + vty_out(vty, + " Originating stub / maximum-distance Router-LSA\n"); + if (CHECK_FLAG(area->stub_router_state, + OSPF_AREA_ADMIN_STUB_ROUTED)) + vty_out(vty, + " Administratively activated (indefinitely)\n"); + if (area->t_stub_router) + vty_out(vty, + " Active from startup, %s remaining\n", + ospf_timer_dump(area->t_stub_router, + timebuf, + sizeof(timebuf))); + } + } + + if (use_json) { + /* Show number of fully adjacent neighbors. */ + json_object_int_add(json_area, "nbrFullAdjacentCounter", + area->full_nbrs); + + /* Show authentication type. */ + if (area->auth_type == OSPF_AUTH_NULL) + json_object_string_add(json_area, "authentication", + "authenticationNone"); + else if (area->auth_type == OSPF_AUTH_SIMPLE) + json_object_string_add(json_area, "authentication", + "authenticationSimplePassword"); + else if (area->auth_type == OSPF_AUTH_CRYPTOGRAPHIC) + json_object_string_add(json_area, "authentication", + "authenticationMessageDigest"); + + if (!OSPF_IS_AREA_BACKBONE(area)) + json_object_int_add(json_area, + "virtualAdjacenciesPassingCounter", + area->full_vls); + + /* Show SPF calculation times. */ + json_object_int_add(json_area, "spfExecutedCounter", + area->spf_calculation); + json_object_int_add(json_area, "lsaNumber", area->lsdb->total); + json_object_int_add( + json_area, "lsaRouterNumber", + ospf_lsdb_count(area->lsdb, OSPF_ROUTER_LSA)); + json_object_int_add( + json_area, "lsaRouterChecksum", + ospf_lsdb_checksum(area->lsdb, OSPF_ROUTER_LSA)); + json_object_int_add( + json_area, "lsaNetworkNumber", + ospf_lsdb_count(area->lsdb, OSPF_NETWORK_LSA)); + json_object_int_add( + json_area, "lsaNetworkChecksum", + ospf_lsdb_checksum(area->lsdb, OSPF_NETWORK_LSA)); + json_object_int_add( + json_area, "lsaSummaryNumber", + ospf_lsdb_count(area->lsdb, OSPF_SUMMARY_LSA)); + json_object_int_add( + json_area, "lsaSummaryChecksum", + ospf_lsdb_checksum(area->lsdb, OSPF_SUMMARY_LSA)); + json_object_int_add( + json_area, "lsaAsbrNumber", + ospf_lsdb_count(area->lsdb, OSPF_ASBR_SUMMARY_LSA)); + json_object_int_add( + json_area, "lsaAsbrChecksum", + ospf_lsdb_checksum(area->lsdb, OSPF_ASBR_SUMMARY_LSA)); + json_object_int_add( + json_area, "lsaNssaNumber", + ospf_lsdb_count(area->lsdb, OSPF_AS_NSSA_LSA)); + json_object_int_add( + json_area, "lsaNssaChecksum", + ospf_lsdb_checksum(area->lsdb, OSPF_AS_NSSA_LSA)); + } else { + /* Show number of fully adjacent neighbors. */ + vty_out(vty, + " Number of fully adjacent neighbors in this area:" + " %d\n", + area->full_nbrs); + + /* Show authentication type. */ + vty_out(vty, " Area has "); + if (area->auth_type == OSPF_AUTH_NULL) + vty_out(vty, "no authentication\n"); + else if (area->auth_type == OSPF_AUTH_SIMPLE) + vty_out(vty, "simple password authentication\n"); + else if (area->auth_type == OSPF_AUTH_CRYPTOGRAPHIC) + vty_out(vty, "message digest authentication\n"); + + if (!OSPF_IS_AREA_BACKBONE(area)) + vty_out(vty, + " Number of full virtual adjacencies going through" + " this area: %d\n", + area->full_vls); + + /* Show SPF calculation times. */ + vty_out(vty, " SPF algorithm executed %d times\n", + area->spf_calculation); + + /* Show number of LSA. */ + vty_out(vty, " Number of LSA %ld\n", area->lsdb->total); + vty_out(vty, + " Number of router LSA %ld. Checksum Sum 0x%08x\n", + ospf_lsdb_count(area->lsdb, OSPF_ROUTER_LSA), + ospf_lsdb_checksum(area->lsdb, OSPF_ROUTER_LSA)); + vty_out(vty, + " Number of network LSA %ld. Checksum Sum 0x%08x\n", + ospf_lsdb_count(area->lsdb, OSPF_NETWORK_LSA), + ospf_lsdb_checksum(area->lsdb, OSPF_NETWORK_LSA)); + vty_out(vty, + " Number of summary LSA %ld. Checksum Sum 0x%08x\n", + ospf_lsdb_count(area->lsdb, OSPF_SUMMARY_LSA), + ospf_lsdb_checksum(area->lsdb, OSPF_SUMMARY_LSA)); + vty_out(vty, + " Number of ASBR summary LSA %ld. Checksum Sum 0x%08x\n", + ospf_lsdb_count(area->lsdb, OSPF_ASBR_SUMMARY_LSA), + ospf_lsdb_checksum(area->lsdb, OSPF_ASBR_SUMMARY_LSA)); + vty_out(vty, " Number of NSSA LSA %ld. Checksum Sum 0x%08x\n", + ospf_lsdb_count(area->lsdb, OSPF_AS_NSSA_LSA), + ospf_lsdb_checksum(area->lsdb, OSPF_AS_NSSA_LSA)); + } + + if (use_json) { + json_object_int_add( + json_area, "lsaOpaqueLinkNumber", + ospf_lsdb_count(area->lsdb, OSPF_OPAQUE_LINK_LSA)); + json_object_int_add( + json_area, "lsaOpaqueLinkChecksum", + ospf_lsdb_checksum(area->lsdb, OSPF_OPAQUE_LINK_LSA)); + json_object_int_add( + json_area, "lsaOpaqueAreaNumber", + ospf_lsdb_count(area->lsdb, OSPF_OPAQUE_AREA_LSA)); + json_object_int_add( + json_area, "lsaOpaqueAreaChecksum", + ospf_lsdb_checksum(area->lsdb, OSPF_OPAQUE_AREA_LSA)); + } else { + vty_out(vty, + " Number of opaque link LSA %ld. Checksum Sum 0x%08x\n", + ospf_lsdb_count(area->lsdb, OSPF_OPAQUE_LINK_LSA), + ospf_lsdb_checksum(area->lsdb, OSPF_OPAQUE_LINK_LSA)); + vty_out(vty, + " Number of opaque area LSA %ld. Checksum Sum 0x%08x\n", + ospf_lsdb_count(area->lsdb, OSPF_OPAQUE_AREA_LSA), + ospf_lsdb_checksum(area->lsdb, OSPF_OPAQUE_AREA_LSA)); + } + + if (use_json) + json_object_object_add(json_areas, inet_ntoa(area->area_id), + json_area); + else + vty_out(vty, "\n"); } -static int -show_ip_ospf_common (struct vty *vty, struct ospf *ospf, u_char use_json) -{ - struct listnode *node, *nnode; - struct ospf_area * area; - struct timeval result; - char timebuf[OSPF_TIME_DUMP_SIZE]; - json_object *json = NULL; - json_object *json_areas = NULL; - - if (use_json) - { - json = json_object_new_object(); - json_areas = json_object_new_object(); - } - - if (ospf->instance) - { - if (use_json) - { - json_object_int_add(json, "ospfInstance", ospf->instance); - } - else - { - vty_out (vty, "\nOSPF Instance: %d\n\n", ospf->instance); - } - } - - /* Show Router ID. */ - if (use_json) - { - json_object_string_add(json, "routerId", inet_ntoa (ospf->router_id)); - } - else - { - vty_out (vty, " OSPF Routing Process, Router ID: %s\n", - inet_ntoa (ospf->router_id)); - } - - /* Graceful shutdown */ - if (ospf->t_deferred_shutdown) - { - if (use_json) - { - long time_store; - time_store = monotime_until(&ospf->t_deferred_shutdown->u.sands, NULL) / 1000LL; - json_object_int_add(json, "deferredShutdownMsecs", time_store); - } - else - { - vty_out (vty, " Deferred shutdown in progress, %s remaining\n", - ospf_timer_dump (ospf->t_deferred_shutdown, - timebuf, sizeof (timebuf))); - } - } - - /* Show capability. */ - if (use_json) - { - json_object_boolean_true_add(json, "tosRoutesOnly"); - json_object_boolean_true_add(json, "rfc2328Conform"); - if (CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE)) - { - json_object_boolean_true_add(json, "rfc1583Compatibility"); - } - } - else - { - vty_out (vty, " Supports only single TOS (TOS0) routes\n"); - vty_out (vty, " This implementation conforms to RFC2328\n"); - vty_out (vty, " RFC1583Compatibility flag is %s\n", - CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE) ? - "enabled" : "disabled"); - } - - if (use_json) - { - if (CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE)) - { - json_object_boolean_true_add(json, "opaqueCapable"); - } - } - else - { - vty_out (vty, " OpaqueCapability flag is %s\n", - CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE) ? "enabled" : "disabled"); - } - - /* Show stub-router configuration */ - if (ospf->stub_router_startup_time != OSPF_STUB_ROUTER_UNCONFIGURED - || ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED) - { - if (use_json) - { - json_object_boolean_true_add(json, "stubAdvertisement"); - if (ospf->stub_router_startup_time != OSPF_STUB_ROUTER_UNCONFIGURED) - json_object_int_add(json,"postStartEnabledMsecs", ospf->stub_router_startup_time / 1000); - if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED) - json_object_int_add(json,"preShutdownEnabledMsecs", ospf->stub_router_shutdown_time / 1000); - } - else - { - vty_out (vty, " Stub router advertisement is configured\n"); - if (ospf->stub_router_startup_time != OSPF_STUB_ROUTER_UNCONFIGURED) - vty_out (vty, " Enabled for %us after start-up\n", - ospf->stub_router_startup_time); - if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED) - vty_out (vty, " Enabled for %us prior to full shutdown\n", - ospf->stub_router_shutdown_time); - } - } - - /* Show SPF timers. */ - if (use_json) - { - json_object_int_add(json, "spfScheduleDelayMsecs", ospf->spf_delay); - json_object_int_add(json, "holdtimeMinMsecs", ospf->spf_holdtime); - json_object_int_add(json, "holdtimeMaxMsecs", ospf->spf_max_holdtime); - json_object_int_add(json, "holdtimeMultplier", ospf->spf_hold_multiplier); - } - else - { - vty_out (vty, " Initial SPF scheduling delay %d millisec(s)\n" - " Minimum hold time between consecutive SPFs %d millisec(s)\n" - " Maximum hold time between consecutive SPFs %d millisec(s)\n" - " Hold time multiplier is currently %d\n", - ospf->spf_delay, - ospf->spf_holdtime, - ospf->spf_max_holdtime, - ospf->spf_hold_multiplier); - } - - if (use_json) - { - if (ospf->ts_spf.tv_sec || ospf->ts_spf.tv_usec) - { - long time_store = 0; - - time_store = monotime_since(&ospf->ts_spf, NULL) / 1000LL; - json_object_int_add(json, "spfLastExecutedMsecs", time_store); - - time_store = (1000 * ospf->ts_spf_duration.tv_sec) + (ospf->ts_spf_duration.tv_usec / 1000); - json_object_int_add(json, "spfLastDurationMsecs", time_store); - } - else - json_object_boolean_true_add(json, "spfHasNotRun"); - } - else - { - vty_out (vty, " SPF algorithm "); - if (ospf->ts_spf.tv_sec || ospf->ts_spf.tv_usec) - { - monotime_since(&ospf->ts_spf, &result); - vty_out (vty, "last executed %s ago\n", - ospf_timeval_dump (&result, timebuf, sizeof (timebuf))); - vty_out (vty, " Last SPF duration %s\n", - ospf_timeval_dump (&ospf->ts_spf_duration, timebuf, sizeof (timebuf))); - } - else - vty_out (vty, "has not been run\n"); - } - - if (use_json) - { - if (ospf->t_spf_calc) - { - long time_store; - time_store = monotime_until(&ospf->t_spf_calc->u.sands, NULL) / 1000LL; - json_object_int_add(json, "spfTimerDueInMsecs", time_store); - } - - json_object_int_add(json, "lsaMinIntervalMsecs", ospf->min_ls_interval); - json_object_int_add(json, "lsaMinArrivalMsecs", ospf->min_ls_arrival); - /* Show write multiplier values */ - json_object_int_add(json, "writeMultiplier", ospf->write_oi_count); - /* Show refresh parameters. */ - json_object_int_add(json, "refreshTimerMsecs", ospf->lsa_refresh_interval * 1000); - } - else - { - vty_out (vty, " SPF timer %s%s\n", - (ospf->t_spf_calc ? "due in " : "is "), - ospf_timer_dump (ospf->t_spf_calc, timebuf, sizeof (timebuf))); - - vty_out (vty, " LSA minimum interval %d msecs\n", - ospf->min_ls_interval); - vty_out (vty, " LSA minimum arrival %d msecs\n", - ospf->min_ls_arrival); - - /* Show write multiplier values */ - vty_out (vty, " Write Multiplier set to %d \n", - ospf->write_oi_count); - - /* Show refresh parameters. */ - vty_out (vty, " Refresh timer %d secs\n", - ospf->lsa_refresh_interval); - } - - /* Show ABR/ASBR flags. */ - if (CHECK_FLAG (ospf->flags, OSPF_FLAG_ABR)) - { - if (use_json) - json_object_string_add(json, "abrType", ospf_abr_type_descr_str[ospf->abr_type]); - else - vty_out (vty, " This router is an ABR, ABR type is: %s\n", - ospf_abr_type_descr_str[ospf->abr_type]); - } - if (CHECK_FLAG (ospf->flags, OSPF_FLAG_ASBR)) - { - if (use_json) - json_object_string_add(json, "asbrRouter", "injectingExternalRoutingInformation"); - else - vty_out (vty, " This router is an ASBR " - "(injecting external routing information)\n"); - } - - /* Show Number of AS-external-LSAs. */ - if (use_json) - { - json_object_int_add(json, "lsaExternalCounter", - ospf_lsdb_count (ospf->lsdb, OSPF_AS_EXTERNAL_LSA)); - json_object_int_add(json, "lsaExternalChecksum", - ospf_lsdb_checksum (ospf->lsdb, OSPF_AS_EXTERNAL_LSA)); - } - else - { - vty_out (vty, " Number of external LSA %ld. Checksum Sum 0x%08x\n", - ospf_lsdb_count (ospf->lsdb, OSPF_AS_EXTERNAL_LSA), - ospf_lsdb_checksum (ospf->lsdb, OSPF_AS_EXTERNAL_LSA)); - } - - if (use_json) - { - json_object_int_add(json, "lsaAsopaqueCounter", - ospf_lsdb_count (ospf->lsdb, OSPF_OPAQUE_AS_LSA)); - json_object_int_add(json, "lsaAsOpaqueChecksum", - ospf_lsdb_checksum (ospf->lsdb, OSPF_OPAQUE_AS_LSA)); - } - else - { - vty_out (vty, " Number of opaque AS LSA %ld. Checksum Sum 0x%08x\n", - ospf_lsdb_count (ospf->lsdb, OSPF_OPAQUE_AS_LSA), - ospf_lsdb_checksum (ospf->lsdb, OSPF_OPAQUE_AS_LSA)); - } - - /* Show number of areas attached. */ - if (use_json) - json_object_int_add(json, "attachedAreaCounter", listcount (ospf->areas)); - else - vty_out (vty, " Number of areas attached to this router: %d\n", - listcount (ospf->areas)); - - if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES)) - { - if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL)) - { - if (use_json) - json_object_boolean_true_add(json, "adjacencyChangesLoggedAll"); - else - vty_out(vty, " All adjacency changes are logged\n"); - } - else - { - if (use_json) - json_object_boolean_true_add(json, "adjacencyChangesLogged"); - else - vty_out(vty, " Adjacency changes are logged\n"); - } - } - /* Show each area status. */ - for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area)) - show_ip_ospf_area (vty, area, json_areas, use_json); - - if (use_json) - { - json_object_object_add(json, "areas", json_areas); - vty_out (vty, "%s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); - json_object_free(json); - } - else - vty_out (vty, "\n"); +static int show_ip_ospf_common(struct vty *vty, struct ospf *ospf, + u_char use_json) +{ + struct listnode *node, *nnode; + struct ospf_area *area; + struct timeval result; + char timebuf[OSPF_TIME_DUMP_SIZE]; + json_object *json = NULL; + json_object *json_areas = NULL; - return CMD_SUCCESS; + if (use_json) { + json = json_object_new_object(); + json_areas = json_object_new_object(); + } + + if (ospf->instance) { + if (use_json) { + json_object_int_add(json, "ospfInstance", + ospf->instance); + } else { + vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); + } + } + + /* Show Router ID. */ + if (use_json) { + json_object_string_add(json, "routerId", + inet_ntoa(ospf->router_id)); + } else { + vty_out(vty, " OSPF Routing Process, Router ID: %s\n", + inet_ntoa(ospf->router_id)); + } + + /* Graceful shutdown */ + if (ospf->t_deferred_shutdown) { + if (use_json) { + long time_store; + time_store = + monotime_until( + &ospf->t_deferred_shutdown->u.sands, + NULL) + / 1000LL; + json_object_int_add(json, "deferredShutdownMsecs", + time_store); + } else { + vty_out(vty, + " Deferred shutdown in progress, %s remaining\n", + ospf_timer_dump(ospf->t_deferred_shutdown, + timebuf, sizeof(timebuf))); + } + } + + /* Show capability. */ + if (use_json) { + json_object_boolean_true_add(json, "tosRoutesOnly"); + json_object_boolean_true_add(json, "rfc2328Conform"); + if (CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE)) { + json_object_boolean_true_add(json, + "rfc1583Compatibility"); + } + } else { + vty_out(vty, " Supports only single TOS (TOS0) routes\n"); + vty_out(vty, " This implementation conforms to RFC2328\n"); + vty_out(vty, " RFC1583Compatibility flag is %s\n", + CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE) + ? "enabled" + : "disabled"); + } + + if (use_json) { + if (CHECK_FLAG(ospf->config, OSPF_OPAQUE_CAPABLE)) { + json_object_boolean_true_add(json, "opaqueCapable"); + } + } else { + vty_out(vty, " OpaqueCapability flag is %s\n", + CHECK_FLAG(ospf->config, OSPF_OPAQUE_CAPABLE) + ? "enabled" + : "disabled"); + } + + /* Show stub-router configuration */ + if (ospf->stub_router_startup_time != OSPF_STUB_ROUTER_UNCONFIGURED + || ospf->stub_router_shutdown_time + != OSPF_STUB_ROUTER_UNCONFIGURED) { + if (use_json) { + json_object_boolean_true_add(json, "stubAdvertisement"); + if (ospf->stub_router_startup_time + != OSPF_STUB_ROUTER_UNCONFIGURED) + json_object_int_add( + json, "postStartEnabledMsecs", + ospf->stub_router_startup_time / 1000); + if (ospf->stub_router_shutdown_time + != OSPF_STUB_ROUTER_UNCONFIGURED) + json_object_int_add( + json, "preShutdownEnabledMsecs", + ospf->stub_router_shutdown_time / 1000); + } else { + vty_out(vty, + " Stub router advertisement is configured\n"); + if (ospf->stub_router_startup_time + != OSPF_STUB_ROUTER_UNCONFIGURED) + vty_out(vty, + " Enabled for %us after start-up\n", + ospf->stub_router_startup_time); + if (ospf->stub_router_shutdown_time + != OSPF_STUB_ROUTER_UNCONFIGURED) + vty_out(vty, + " Enabled for %us prior to full shutdown\n", + ospf->stub_router_shutdown_time); + } + } + + /* Show SPF timers. */ + if (use_json) { + json_object_int_add(json, "spfScheduleDelayMsecs", + ospf->spf_delay); + json_object_int_add(json, "holdtimeMinMsecs", + ospf->spf_holdtime); + json_object_int_add(json, "holdtimeMaxMsecs", + ospf->spf_max_holdtime); + json_object_int_add(json, "holdtimeMultplier", + ospf->spf_hold_multiplier); + } else { + vty_out(vty, + " Initial SPF scheduling delay %d millisec(s)\n" + " Minimum hold time between consecutive SPFs %d millisec(s)\n" + " Maximum hold time between consecutive SPFs %d millisec(s)\n" + " Hold time multiplier is currently %d\n", + ospf->spf_delay, ospf->spf_holdtime, + ospf->spf_max_holdtime, ospf->spf_hold_multiplier); + } + + if (use_json) { + if (ospf->ts_spf.tv_sec || ospf->ts_spf.tv_usec) { + long time_store = 0; + + time_store = + monotime_since(&ospf->ts_spf, NULL) / 1000LL; + json_object_int_add(json, "spfLastExecutedMsecs", + time_store); + + time_store = (1000 * ospf->ts_spf_duration.tv_sec) + + (ospf->ts_spf_duration.tv_usec / 1000); + json_object_int_add(json, "spfLastDurationMsecs", + time_store); + } else + json_object_boolean_true_add(json, "spfHasNotRun"); + } else { + vty_out(vty, " SPF algorithm "); + if (ospf->ts_spf.tv_sec || ospf->ts_spf.tv_usec) { + monotime_since(&ospf->ts_spf, &result); + vty_out(vty, "last executed %s ago\n", + ospf_timeval_dump(&result, timebuf, + sizeof(timebuf))); + vty_out(vty, " Last SPF duration %s\n", + ospf_timeval_dump(&ospf->ts_spf_duration, + timebuf, sizeof(timebuf))); + } else + vty_out(vty, "has not been run\n"); + } + + if (use_json) { + if (ospf->t_spf_calc) { + long time_store; + time_store = + monotime_until(&ospf->t_spf_calc->u.sands, NULL) + / 1000LL; + json_object_int_add(json, "spfTimerDueInMsecs", + time_store); + } + + json_object_int_add(json, "lsaMinIntervalMsecs", + ospf->min_ls_interval); + json_object_int_add(json, "lsaMinArrivalMsecs", + ospf->min_ls_arrival); + /* Show write multiplier values */ + json_object_int_add(json, "writeMultiplier", + ospf->write_oi_count); + /* Show refresh parameters. */ + json_object_int_add(json, "refreshTimerMsecs", + ospf->lsa_refresh_interval * 1000); + } else { + vty_out(vty, " SPF timer %s%s\n", + (ospf->t_spf_calc ? "due in " : "is "), + ospf_timer_dump(ospf->t_spf_calc, timebuf, + sizeof(timebuf))); + + vty_out(vty, " LSA minimum interval %d msecs\n", + ospf->min_ls_interval); + vty_out(vty, " LSA minimum arrival %d msecs\n", + ospf->min_ls_arrival); + + /* Show write multiplier values */ + vty_out(vty, " Write Multiplier set to %d \n", + ospf->write_oi_count); + + /* Show refresh parameters. */ + vty_out(vty, " Refresh timer %d secs\n", + ospf->lsa_refresh_interval); + } + + /* Show ABR/ASBR flags. */ + if (CHECK_FLAG(ospf->flags, OSPF_FLAG_ABR)) { + if (use_json) + json_object_string_add( + json, "abrType", + ospf_abr_type_descr_str[ospf->abr_type]); + else + vty_out(vty, + " This router is an ABR, ABR type is: %s\n", + ospf_abr_type_descr_str[ospf->abr_type]); + } + if (CHECK_FLAG(ospf->flags, OSPF_FLAG_ASBR)) { + if (use_json) + json_object_string_add( + json, "asbrRouter", + "injectingExternalRoutingInformation"); + else + vty_out(vty, + " This router is an ASBR " + "(injecting external routing information)\n"); + } + + /* Show Number of AS-external-LSAs. */ + if (use_json) { + json_object_int_add( + json, "lsaExternalCounter", + ospf_lsdb_count(ospf->lsdb, OSPF_AS_EXTERNAL_LSA)); + json_object_int_add( + json, "lsaExternalChecksum", + ospf_lsdb_checksum(ospf->lsdb, OSPF_AS_EXTERNAL_LSA)); + } else { + vty_out(vty, + " Number of external LSA %ld. Checksum Sum 0x%08x\n", + ospf_lsdb_count(ospf->lsdb, OSPF_AS_EXTERNAL_LSA), + ospf_lsdb_checksum(ospf->lsdb, OSPF_AS_EXTERNAL_LSA)); + } + + if (use_json) { + json_object_int_add( + json, "lsaAsopaqueCounter", + ospf_lsdb_count(ospf->lsdb, OSPF_OPAQUE_AS_LSA)); + json_object_int_add( + json, "lsaAsOpaqueChecksum", + ospf_lsdb_checksum(ospf->lsdb, OSPF_OPAQUE_AS_LSA)); + } else { + vty_out(vty, + " Number of opaque AS LSA %ld. Checksum Sum 0x%08x\n", + ospf_lsdb_count(ospf->lsdb, OSPF_OPAQUE_AS_LSA), + ospf_lsdb_checksum(ospf->lsdb, OSPF_OPAQUE_AS_LSA)); + } + + /* Show number of areas attached. */ + if (use_json) + json_object_int_add(json, "attachedAreaCounter", + listcount(ospf->areas)); + else + vty_out(vty, " Number of areas attached to this router: %d\n", + listcount(ospf->areas)); + + if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES)) { + if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL)) { + if (use_json) + json_object_boolean_true_add( + json, "adjacencyChangesLoggedAll"); + else + vty_out(vty, + " All adjacency changes are logged\n"); + } else { + if (use_json) + json_object_boolean_true_add( + json, "adjacencyChangesLogged"); + else + vty_out(vty, " Adjacency changes are logged\n"); + } + } + /* Show each area status. */ + for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) + show_ip_ospf_area(vty, area, json_areas, use_json); + + if (use_json) { + json_object_object_add(json, "areas", json_areas); + vty_out(vty, "%s\n", json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } else + vty_out(vty, "\n"); + + return CMD_SUCCESS; } DEFUN (show_ip_ospf, @@ -3183,13 +3194,13 @@ DEFUN (show_ip_ospf, "OSPF information\n" JSON_STR) { - struct ospf *ospf; - u_char uj = use_json(argc, argv); + struct ospf *ospf; + u_char uj = use_json(argc, argv); - if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) + return CMD_SUCCESS; - return (show_ip_ospf_common(vty, ospf, uj)); + return (show_ip_ospf_common(vty, ospf, uj)); } DEFUN (show_ip_ospf_instance, @@ -3201,360 +3212,407 @@ DEFUN (show_ip_ospf_instance, "Instance ID\n" JSON_STR) { - int idx_number = 3; - struct ospf *ospf; - u_short instance = 0; - u_char uj = use_json(argc, argv); + int idx_number = 3; + struct ospf *ospf; + u_short instance = 0; + u_char uj = use_json(argc, argv); + + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if ((ospf = ospf_lookup_instance(instance)) == NULL + || !ospf->oi_running) + return CMD_SUCCESS; + + return (show_ip_ospf_common(vty, ospf, uj)); +} + +static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, + struct interface *ifp, + json_object *json_interface_sub, + u_char use_json) +{ + int is_up; + struct ospf_neighbor *nbr; + struct route_node *rn; + uint32_t bandwidth = ifp->bandwidth ? ifp->bandwidth : ifp->speed; + + /* Is interface up? */ + if (use_json) { + is_up = if_is_operative(ifp); + if (is_up) + json_object_boolean_true_add(json_interface_sub, + "ifUp"); + else + json_object_boolean_false_add(json_interface_sub, + "ifDown"); + + json_object_int_add(json_interface_sub, "ifIndex", + ifp->ifindex); + json_object_int_add(json_interface_sub, "mtuBytes", ifp->mtu); + json_object_int_add(json_interface_sub, "bandwidthMbit", + bandwidth); + json_object_string_add(json_interface_sub, "ifFlags", + if_flag_dump(ifp->flags)); + } else { + vty_out(vty, "%s is %s\n", ifp->name, + ((is_up = if_is_operative(ifp)) ? "up" : "down")); + vty_out(vty, " ifindex %u, MTU %u bytes, BW %u Mbit %s\n", + ifp->ifindex, ifp->mtu, bandwidth, + if_flag_dump(ifp->flags)); + } - instance = strtoul(argv[idx_number]->arg, NULL, 10); - if ((ospf = ospf_lookup_instance (instance)) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + /* Is interface OSPF enabled? */ + if (use_json) { + if (ospf_oi_count(ifp) == 0) { + json_object_boolean_false_add(json_interface_sub, + "ospfEnabled"); + return; + } else if (!is_up) { + json_object_boolean_false_add(json_interface_sub, + "ospfRunning"); + return; + } else + json_object_boolean_true_add(json_interface_sub, + "ospfEnabled"); + } else { + if (ospf_oi_count(ifp) == 0) { + vty_out(vty, " OSPF not enabled on this interface\n"); + return; + } else if (!is_up) { + vty_out(vty, + " OSPF is enabled, but not running on this interface\n"); + return; + } + } - return (show_ip_ospf_common(vty, ospf, uj)); -} - -static void -show_ip_ospf_interface_sub (struct vty *vty, struct ospf *ospf, struct interface *ifp, - json_object *json_interface_sub, u_char use_json) -{ - int is_up; - struct ospf_neighbor *nbr; - struct route_node *rn; - uint32_t bandwidth = ifp->bandwidth ? ifp->bandwidth : ifp->speed; - - /* Is interface up? */ - if (use_json) - { - is_up = if_is_operative(ifp); - if (is_up) - json_object_boolean_true_add(json_interface_sub, "ifUp"); - else - json_object_boolean_false_add(json_interface_sub, "ifDown"); - - json_object_int_add(json_interface_sub, "ifIndex", ifp->ifindex); - json_object_int_add(json_interface_sub, "mtuBytes", ifp->mtu); - json_object_int_add(json_interface_sub, "bandwidthMbit", bandwidth); - json_object_string_add(json_interface_sub, "ifFlags", if_flag_dump(ifp->flags)); - } - else - { - vty_out (vty, "%s is %s\n", ifp->name, - ((is_up = if_is_operative(ifp)) ? "up" : "down")); - vty_out (vty, " ifindex %u, MTU %u bytes, BW %u Mbit %s\n", - ifp->ifindex, ifp->mtu, bandwidth, if_flag_dump(ifp->flags)); - } - - /* Is interface OSPF enabled? */ - if (use_json) - { - if (ospf_oi_count(ifp) == 0) - { - json_object_boolean_false_add(json_interface_sub, "ospfEnabled"); - return; - } - else if (!is_up) - { - json_object_boolean_false_add(json_interface_sub, "ospfRunning"); - return; - } - else - json_object_boolean_true_add(json_interface_sub, "ospfEnabled"); - } - else - { - if (ospf_oi_count(ifp) == 0) - { - vty_out (vty, " OSPF not enabled on this interface\n"); - return; - } - else if (!is_up) - { - vty_out (vty, " OSPF is enabled, but not running on this interface\n"); - return; - } - } - - for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn)) - { - struct ospf_interface *oi = rn->info; - - if (oi == NULL) - continue; - - if (CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED)) - { - if (use_json) - json_object_boolean_true_add(json_interface_sub, "ifUnnumbered"); - else - vty_out (vty, " This interface is UNNUMBERED,"); - } - else - { - /* Show OSPF interface information. */ - if (use_json) - { - json_object_string_add(json_interface_sub, "ipAddress", inet_ntoa (oi->address->u.prefix4)); - json_object_int_add(json_interface_sub, "ipAddressPrefixlen", oi->address->prefixlen); - } - else - vty_out (vty, " Internet Address %s/%d,", - inet_ntoa (oi->address->u.prefix4), oi->address->prefixlen); - - if (oi->connected->destination || oi->type == OSPF_IFTYPE_VIRTUALLINK) - { - struct in_addr *dest; - const char *dstr; - - if (CONNECTED_PEER(oi->connected) - || oi->type == OSPF_IFTYPE_VIRTUALLINK) - dstr = "Peer"; - else - dstr = "Broadcast"; - - /* For Vlinks, showing the peer address is probably more - * * * * * informative than the local interface that is being used - * * * * */ - if (oi->type == OSPF_IFTYPE_VIRTUALLINK) - dest = &oi->vl_data->peer_addr; - else - dest = &oi->connected->destination->u.prefix4; - - if (use_json) - { - json_object_string_add(json_interface_sub, "ospfIfType", dstr); - if (oi->type == OSPF_IFTYPE_VIRTUALLINK) - json_object_string_add(json_interface_sub, "vlinkPeer", inet_ntoa (*dest)); - else - json_object_string_add(json_interface_sub, "localIfUsed", inet_ntoa (*dest)); - } - else - vty_out (vty, " %s %s,", dstr, inet_ntoa (*dest)); - } - } - if (use_json) - { - json_object_string_add(json_interface_sub, "area", ospf_area_desc_string (oi->area)); - if (OSPF_IF_PARAM(oi, mtu_ignore)) - json_object_boolean_true_add(json_interface_sub, "mtuMismatchDetect"); - json_object_string_add(json_interface_sub, "routerId", inet_ntoa (ospf->router_id)); - json_object_string_add(json_interface_sub, "networkType", ospf_network_type_str[oi->type]); - json_object_int_add(json_interface_sub, "cost", oi->output_cost); - json_object_int_add(json_interface_sub, "transmitDelayMsecs", 1000 / OSPF_IF_PARAM (oi,transmit_delay)); - json_object_string_add(json_interface_sub, "state", lookup_msg(ospf_ism_state_msg, oi->state, NULL)); - json_object_int_add(json_interface_sub, "priority", PRIORITY (oi)); - } - else - { - vty_out (vty, " Area %s\n", ospf_area_desc_string (oi->area)); - - vty_out (vty, " MTU mismatch detection: %s\n", - OSPF_IF_PARAM(oi, mtu_ignore) ? "disabled" : "enabled"); - - vty_out (vty, " Router ID %s, Network Type %s, Cost: %d\n", - inet_ntoa (ospf->router_id), ospf_network_type_str[oi->type], - oi->output_cost); - - vty_out (vty, " Transmit Delay is %d sec, State %s, Priority %d\n", - OSPF_IF_PARAM (oi,transmit_delay), lookup_msg(ospf_ism_state_msg, oi->state, NULL), - PRIORITY (oi)); - } - - /* Show DR information. */ - if (DR (oi).s_addr == 0) - { - if (!use_json) - vty_out (vty, " No backup designated router on this network\n"); - } - else - { - nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &BDR (oi)); - if (nbr == NULL) - { - if (!use_json) - vty_out (vty, " No backup designated router on this network\n"); - } - else - { - if (use_json) - { - json_object_string_add(json_interface_sub, "bdrId", inet_ntoa (nbr->router_id)); - json_object_string_add(json_interface_sub, "bdrAddress", inet_ntoa (nbr->address.u.prefix4)); - } - else - { - vty_out (vty, " Backup Designated Router (ID) %s,", - inet_ntoa (nbr->router_id)); - vty_out (vty, " Interface Address %s\n", - inet_ntoa (nbr->address.u.prefix4)); - } - } - } - - /* Next network-LSA sequence number we'll use, if we're elected DR */ - if (oi->params && ntohl (oi->params->network_lsa_seqnum) != OSPF_INITIAL_SEQUENCE_NUMBER) - { - if (use_json) - json_object_int_add(json_interface_sub, "networkLsaSequence", ntohl (oi->params->network_lsa_seqnum)); - else - vty_out (vty, " Saved Network-LSA sequence number 0x%x\n", - ntohl (oi->params->network_lsa_seqnum)); - } - - if (use_json) - { - if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS) - || OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) - { - if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS)) - json_object_boolean_true_add(json_interface_sub, "mcastMemberOspfAllRouters"); - if (OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) - json_object_boolean_true_add(json_interface_sub, "mcastMemberOspfDesignatedRouters"); - } - } - else - { - vty_out (vty, " Multicast group memberships:"); - if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS) - || OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) - { - if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS)) - vty_out (vty, " OSPFAllRouters"); - if (OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) - vty_out (vty, " OSPFDesignatedRouters"); - } - else - vty_out (vty, " <None>"); - vty_out (vty, "\n"); - } - - if (use_json) - { - if (OSPF_IF_PARAM (oi, fast_hello) == 0) - json_object_int_add(json_interface_sub, "timerMsecs", 1000 /OSPF_IF_PARAM (oi, v_hello)); - else - json_object_int_add(json_interface_sub, "timerMsecs", 1000 / OSPF_IF_PARAM (oi, fast_hello)); - json_object_int_add(json_interface_sub, "timerDeadMsecs", 1000 / OSPF_IF_PARAM (oi, v_wait)); - json_object_int_add(json_interface_sub, "timerWaitMsecs", 1000 / OSPF_IF_PARAM (oi, v_wait)); - json_object_int_add(json_interface_sub, "timerRetransmit", 1000 / OSPF_IF_PARAM (oi, retransmit_interval)); - } - else - { - vty_out (vty, " Timer intervals configured,"); - vty_out (vty, " Hello "); - if (OSPF_IF_PARAM (oi, fast_hello) == 0) - vty_out (vty, "%ds,", OSPF_IF_PARAM (oi, v_hello)); - else - vty_out (vty, "%dms,", 1000 / OSPF_IF_PARAM (oi, fast_hello)); - vty_out (vty, " Dead %ds, Wait %ds, Retransmit %d\n", - OSPF_IF_PARAM (oi, v_wait), - OSPF_IF_PARAM (oi, v_wait), - OSPF_IF_PARAM (oi, retransmit_interval)); - } - - if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_ACTIVE) - { - char timebuf[OSPF_TIME_DUMP_SIZE]; - if (use_json) - { - long time_store = 0; - if (oi->t_hello) - time_store = monotime_until(&oi->t_hello->u.sands, NULL) / 1000LL; - json_object_int_add(json_interface_sub, "timerHelloInMsecs", time_store); - } - else - vty_out (vty, " Hello due in %s\n", - ospf_timer_dump (oi->t_hello, timebuf, sizeof(timebuf))); - } - else /* passive-interface is set */ - { - if (use_json) - json_object_boolean_true_add(json_interface_sub, "timerPassiveIface"); - else - vty_out (vty, " No Hellos (Passive interface)\n"); - } - - if (use_json) - { - json_object_int_add(json_interface_sub, "nbrCount", ospf_nbr_count (oi, 0)); - json_object_int_add(json_interface_sub, "nbrAdjacentCount", ospf_nbr_count (oi, NSM_Full)); - } - else - vty_out (vty, " Neighbor Count is %d, Adjacent neighbor count is %d\n", - ospf_nbr_count (oi, 0), ospf_nbr_count (oi, NSM_Full)); - ospf_bfd_interface_show(vty, ifp, json_interface_sub, use_json); - } + for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) { + struct ospf_interface *oi = rn->info; + + if (oi == NULL) + continue; + + if (CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED)) { + if (use_json) + json_object_boolean_true_add(json_interface_sub, + "ifUnnumbered"); + else + vty_out(vty, " This interface is UNNUMBERED,"); + } else { + /* Show OSPF interface information. */ + if (use_json) { + json_object_string_add( + json_interface_sub, "ipAddress", + inet_ntoa(oi->address->u.prefix4)); + json_object_int_add(json_interface_sub, + "ipAddressPrefixlen", + oi->address->prefixlen); + } else + vty_out(vty, " Internet Address %s/%d,", + inet_ntoa(oi->address->u.prefix4), + oi->address->prefixlen); + + if (oi->connected->destination + || oi->type == OSPF_IFTYPE_VIRTUALLINK) { + struct in_addr *dest; + const char *dstr; + + if (CONNECTED_PEER(oi->connected) + || oi->type == OSPF_IFTYPE_VIRTUALLINK) + dstr = "Peer"; + else + dstr = "Broadcast"; + + /* For Vlinks, showing the peer address is + * probably more + * * * * * informative than the local + * interface that is being used + * * * * */ + if (oi->type == OSPF_IFTYPE_VIRTUALLINK) + dest = &oi->vl_data->peer_addr; + else + dest = &oi->connected->destination->u + .prefix4; + + if (use_json) { + json_object_string_add( + json_interface_sub, + "ospfIfType", dstr); + if (oi->type == OSPF_IFTYPE_VIRTUALLINK) + json_object_string_add( + json_interface_sub, + "vlinkPeer", + inet_ntoa(*dest)); + else + json_object_string_add( + json_interface_sub, + "localIfUsed", + inet_ntoa(*dest)); + } else + vty_out(vty, " %s %s,", dstr, + inet_ntoa(*dest)); + } + } + if (use_json) { + json_object_string_add(json_interface_sub, "area", + ospf_area_desc_string(oi->area)); + if (OSPF_IF_PARAM(oi, mtu_ignore)) + json_object_boolean_true_add( + json_interface_sub, + "mtuMismatchDetect"); + json_object_string_add(json_interface_sub, "routerId", + inet_ntoa(ospf->router_id)); + json_object_string_add(json_interface_sub, + "networkType", + ospf_network_type_str[oi->type]); + json_object_int_add(json_interface_sub, "cost", + oi->output_cost); + json_object_int_add( + json_interface_sub, "transmitDelayMsecs", + 1000 / OSPF_IF_PARAM(oi, transmit_delay)); + json_object_string_add(json_interface_sub, "state", + lookup_msg(ospf_ism_state_msg, + oi->state, NULL)); + json_object_int_add(json_interface_sub, "priority", + PRIORITY(oi)); + } else { + vty_out(vty, " Area %s\n", + ospf_area_desc_string(oi->area)); + + vty_out(vty, " MTU mismatch detection: %s\n", + OSPF_IF_PARAM(oi, mtu_ignore) ? "disabled" + : "enabled"); + + vty_out(vty, + " Router ID %s, Network Type %s, Cost: %d\n", + inet_ntoa(ospf->router_id), + ospf_network_type_str[oi->type], + oi->output_cost); + + vty_out(vty, + " Transmit Delay is %d sec, State %s, Priority %d\n", + OSPF_IF_PARAM(oi, transmit_delay), + lookup_msg(ospf_ism_state_msg, oi->state, NULL), + PRIORITY(oi)); + } + + /* Show DR information. */ + if (DR(oi).s_addr == 0) { + if (!use_json) + vty_out(vty, + " No backup designated router on this network\n"); + } else { + nbr = ospf_nbr_lookup_by_addr(oi->nbrs, &BDR(oi)); + if (nbr == NULL) { + if (!use_json) + vty_out(vty, + " No backup designated router on this network\n"); + } else { + if (use_json) { + json_object_string_add( + json_interface_sub, "bdrId", + inet_ntoa(nbr->router_id)); + json_object_string_add( + json_interface_sub, + "bdrAddress", + inet_ntoa(nbr->address.u + .prefix4)); + } else { + vty_out(vty, + " Backup Designated Router (ID) %s,", + inet_ntoa(nbr->router_id)); + vty_out(vty, " Interface Address %s\n", + inet_ntoa(nbr->address.u + .prefix4)); + } + } + } + + /* Next network-LSA sequence number we'll use, if we're elected + * DR */ + if (oi->params + && ntohl(oi->params->network_lsa_seqnum) + != OSPF_INITIAL_SEQUENCE_NUMBER) { + if (use_json) + json_object_int_add( + json_interface_sub, + "networkLsaSequence", + ntohl(oi->params->network_lsa_seqnum)); + else + vty_out(vty, + " Saved Network-LSA sequence number 0x%x\n", + ntohl(oi->params->network_lsa_seqnum)); + } + + if (use_json) { + if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS) + || OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) { + if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS)) + json_object_boolean_true_add( + json_interface_sub, + "mcastMemberOspfAllRouters"); + if (OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) + json_object_boolean_true_add( + json_interface_sub, + "mcastMemberOspfDesignatedRouters"); + } + } else { + vty_out(vty, " Multicast group memberships:"); + if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS) + || OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) { + if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS)) + vty_out(vty, " OSPFAllRouters"); + if (OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) + vty_out(vty, " OSPFDesignatedRouters"); + } else + vty_out(vty, " <None>"); + vty_out(vty, "\n"); + } + + if (use_json) { + if (OSPF_IF_PARAM(oi, fast_hello) == 0) + json_object_int_add( + json_interface_sub, "timerMsecs", + 1000 / OSPF_IF_PARAM(oi, v_hello)); + else + json_object_int_add( + json_interface_sub, "timerMsecs", + 1000 / OSPF_IF_PARAM(oi, fast_hello)); + json_object_int_add(json_interface_sub, + "timerDeadMsecs", + 1000 / OSPF_IF_PARAM(oi, v_wait)); + json_object_int_add(json_interface_sub, + "timerWaitMsecs", + 1000 / OSPF_IF_PARAM(oi, v_wait)); + json_object_int_add( + json_interface_sub, "timerRetransmit", + 1000 / OSPF_IF_PARAM(oi, retransmit_interval)); + } else { + vty_out(vty, " Timer intervals configured,"); + vty_out(vty, " Hello "); + if (OSPF_IF_PARAM(oi, fast_hello) == 0) + vty_out(vty, "%ds,", + OSPF_IF_PARAM(oi, v_hello)); + else + vty_out(vty, "%dms,", + 1000 / OSPF_IF_PARAM(oi, fast_hello)); + vty_out(vty, " Dead %ds, Wait %ds, Retransmit %d\n", + OSPF_IF_PARAM(oi, v_wait), + OSPF_IF_PARAM(oi, v_wait), + OSPF_IF_PARAM(oi, retransmit_interval)); + } + + if (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_ACTIVE) { + char timebuf[OSPF_TIME_DUMP_SIZE]; + if (use_json) { + long time_store = 0; + if (oi->t_hello) + time_store = + monotime_until( + &oi->t_hello->u.sands, + NULL) + / 1000LL; + json_object_int_add(json_interface_sub, + "timerHelloInMsecs", + time_store); + } else + vty_out(vty, " Hello due in %s\n", + ospf_timer_dump(oi->t_hello, timebuf, + sizeof(timebuf))); + } else /* passive-interface is set */ + { + if (use_json) + json_object_boolean_true_add( + json_interface_sub, + "timerPassiveIface"); + else + vty_out(vty, + " No Hellos (Passive interface)\n"); + } + + if (use_json) { + json_object_int_add(json_interface_sub, "nbrCount", + ospf_nbr_count(oi, 0)); + json_object_int_add(json_interface_sub, + "nbrAdjacentCount", + ospf_nbr_count(oi, NSM_Full)); + } else + vty_out(vty, + " Neighbor Count is %d, Adjacent neighbor count is %d\n", + ospf_nbr_count(oi, 0), + ospf_nbr_count(oi, NSM_Full)); + ospf_bfd_interface_show(vty, ifp, json_interface_sub, use_json); + } } -static int -show_ip_ospf_interface_common (struct vty *vty, struct ospf *ospf, int argc, - struct cmd_token **argv, int iface_argv, u_char use_json) -{ - struct interface *ifp; - struct listnode *node; - json_object *json = NULL; - json_object *json_interface_sub = NULL; - - if (use_json) - { - json = json_object_new_object(); - } - - if (ospf->instance) - { - if (use_json) - json_object_int_add(json, "ospfInstance", ospf->instance); - else - vty_out (vty, "\nOSPF Instance: %d\n\n", ospf->instance); - } - - if (argc == iface_argv) - { - /* Show All Interfaces.*/ - for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) - { - if (ospf_oi_count(ifp)) - { - if (use_json) - json_interface_sub = json_object_new_object(); - - show_ip_ospf_interface_sub (vty, ospf, ifp, json_interface_sub, use_json); - - if (use_json) - json_object_object_add (json, ifp->name, json_interface_sub); - } - } - } - else - { - /* Interface name is specified. */ - if ((ifp = if_lookup_by_name (argv[iface_argv]->arg, VRF_DEFAULT)) == NULL) - { - if (use_json) - json_object_boolean_true_add(json, "noSuchIface"); - else - vty_out (vty, "No such interface name\n"); - } - else - { - if (use_json) - json_interface_sub = json_object_new_object(); - - show_ip_ospf_interface_sub (vty, ospf, ifp, json_interface_sub, use_json); - - if (use_json) - json_object_object_add(json, ifp->name, json_interface_sub); - } - } - - if (use_json) - { - vty_out (vty, "%s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); - json_object_free(json); - } - else - vty_out (vty, "\n"); +static int show_ip_ospf_interface_common(struct vty *vty, struct ospf *ospf, + int argc, struct cmd_token **argv, + int iface_argv, u_char use_json) +{ + struct interface *ifp; + struct listnode *node; + json_object *json = NULL; + json_object *json_interface_sub = NULL; - return CMD_SUCCESS; + if (use_json) { + json = json_object_new_object(); + } + + if (ospf->instance) { + if (use_json) + json_object_int_add(json, "ospfInstance", + ospf->instance); + else + vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); + } + + if (argc == iface_argv) { + /* Show All Interfaces.*/ + for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { + if (ospf_oi_count(ifp)) { + if (use_json) + json_interface_sub = + json_object_new_object(); + + show_ip_ospf_interface_sub(vty, ospf, ifp, + json_interface_sub, + use_json); + + if (use_json) + json_object_object_add( + json, ifp->name, + json_interface_sub); + } + } + } else { + /* Interface name is specified. */ + if ((ifp = if_lookup_by_name(argv[iface_argv]->arg, + VRF_DEFAULT)) + == NULL) { + if (use_json) + json_object_boolean_true_add(json, + "noSuchIface"); + else + vty_out(vty, "No such interface name\n"); + } else { + if (use_json) + json_interface_sub = json_object_new_object(); + + show_ip_ospf_interface_sub( + vty, ospf, ifp, json_interface_sub, use_json); + + if (use_json) + json_object_object_add(json, ifp->name, + json_interface_sub); + } + } + + if (use_json) { + vty_out(vty, "%s\n", json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } else + vty_out(vty, "\n"); + + return CMD_SUCCESS; } DEFUN (show_ip_ospf_interface, @@ -3567,16 +3625,16 @@ DEFUN (show_ip_ospf_interface, "Interface name\n" JSON_STR) { - struct ospf *ospf; - u_char uj = use_json(argc, argv); + struct ospf *ospf; + u_char uj = use_json(argc, argv); - if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) + return CMD_SUCCESS; - if (uj) - argc--; + if (uj) + argc--; - return show_ip_ospf_interface_common(vty, ospf, argc, argv, 4, uj); + return show_ip_ospf_interface_common(vty, ospf, argc, argv, 4, uj); } DEFUN (show_ip_ospf_instance_interface, @@ -3590,129 +3648,182 @@ DEFUN (show_ip_ospf_instance_interface, "Interface name\n" JSON_STR) { - int idx_number = 3; - struct ospf *ospf; - u_short instance = 0; - u_char uj = use_json(argc, argv); + int idx_number = 3; + struct ospf *ospf; + u_short instance = 0; + u_char uj = use_json(argc, argv); + + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if ((ospf = ospf_lookup_instance(instance)) == NULL + || !ospf->oi_running) + return CMD_SUCCESS; + + if (uj) + argc--; + + return show_ip_ospf_interface_common(vty, ospf, argc, argv, 5, uj); +} + +static void show_ip_ospf_neighbour_header(struct vty *vty) +{ + vty_out(vty, "\n%-15s %3s %-15s %9s %-15s %-20s %5s %5s %5s\n", + "Neighbor ID", "Pri", "State", "Dead Time", "Address", + "Interface", "RXmtL", "RqstL", "DBsmL"); +} + +static void show_ip_ospf_neighbor_sub(struct vty *vty, + struct ospf_interface *oi, + json_object *json, u_char use_json) +{ + struct route_node *rn; + struct ospf_neighbor *nbr; + char msgbuf[16]; + char timebuf[OSPF_TIME_DUMP_SIZE]; + json_object *json_neighbor = NULL; + + for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) { + if ((nbr = rn->info)) { + /* Do not show myself. */ + if (nbr != oi->nbr_self) { + /* Down state is not shown. */ + if (nbr->state != NSM_Down) { + if (use_json) { + json_neighbor = + json_object_new_object(); + ospf_nbr_state_message( + nbr, msgbuf, 16); + + long time_store; + + time_store = + monotime_until( + &nbr->t_inactivity + ->u + .sands, + NULL) + / 1000LL; + + json_object_int_add( + json_neighbor, + "priority", + nbr->priority); + json_object_string_add( + json_neighbor, "state", + msgbuf); + json_object_int_add( + json_neighbor, + "deadTimeMsecs", + time_store); + json_object_string_add( + json_neighbor, + "address", + inet_ntoa(nbr->src)); + json_object_string_add( + json_neighbor, + "ifaceName", + IF_NAME(oi)); + json_object_int_add( + json_neighbor, + "retransmitCounter", + ospf_ls_retransmit_count( + nbr)); + json_object_int_add( + json_neighbor, + "requestCounter", + ospf_ls_request_count( + nbr)); + json_object_int_add( + json_neighbor, + "dbSummaryCounter", + ospf_db_summary_count( + nbr)); + if (nbr->state == NSM_Attempt + && nbr->router_id.s_addr + == 0) + json_object_object_add( + json, + "neighbor", + json_neighbor); + else + json_object_object_add( + json, + inet_ntoa( + nbr->router_id), + json_neighbor); + } else { + ospf_nbr_state_message( + nbr, msgbuf, 16); + + if (nbr->state == NSM_Attempt + && nbr->router_id.s_addr + == 0) + vty_out(vty, + "%-15s %3d %-15s ", + "-", + nbr->priority, + msgbuf); + else + vty_out(vty, + "%-15s %3d %-15s ", + inet_ntoa( + nbr->router_id), + nbr->priority, + msgbuf); + + vty_out(vty, "%9s ", + ospf_timer_dump( + nbr->t_inactivity, + timebuf, + sizeof(timebuf))); + vty_out(vty, "%-15s ", + inet_ntoa(nbr->src)); + vty_out(vty, + "%-20s %5ld %5ld %5d\n", + IF_NAME(oi), + ospf_ls_retransmit_count( + nbr), + ospf_ls_request_count( + nbr), + ospf_db_summary_count( + nbr)); + } + } + } + } + } +} - instance = strtoul(argv[idx_number]->arg, NULL, 10); - if ((ospf = ospf_lookup_instance (instance)) == NULL || !ospf->oi_running) - return CMD_SUCCESS; +static int show_ip_ospf_neighbor_common(struct vty *vty, struct ospf *ospf, + u_char use_json) +{ + struct ospf_interface *oi; + struct listnode *node; + json_object *json = NULL; - if (uj) - argc--; - - return show_ip_ospf_interface_common(vty, ospf, argc, argv, 5, uj); -} - -static void -show_ip_ospf_neighbour_header (struct vty *vty) -{ - vty_out (vty, "\n%-15s %3s %-15s %9s %-15s %-20s %5s %5s %5s\n", - "Neighbor ID", "Pri", "State", "Dead Time", - "Address", "Interface", "RXmtL", "RqstL", "DBsmL"); -} - -static void -show_ip_ospf_neighbor_sub (struct vty *vty, struct ospf_interface *oi, json_object *json, u_char use_json) -{ - struct route_node *rn; - struct ospf_neighbor *nbr; - char msgbuf[16]; - char timebuf[OSPF_TIME_DUMP_SIZE]; - json_object *json_neighbor = NULL; - - for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) - { - if ((nbr = rn->info)) - { - /* Do not show myself. */ - if (nbr != oi->nbr_self) - { - /* Down state is not shown. */ - if (nbr->state != NSM_Down) - { - if (use_json) - { - json_neighbor = json_object_new_object(); - ospf_nbr_state_message (nbr, msgbuf, 16); - - long time_store; - - time_store = monotime_until(&nbr->t_inactivity->u.sands, NULL) / 1000LL; - - json_object_int_add (json_neighbor, "priority", nbr->priority); - json_object_string_add (json_neighbor, "state", msgbuf); - json_object_int_add (json_neighbor, "deadTimeMsecs", time_store); - json_object_string_add (json_neighbor, "address", inet_ntoa (nbr->src)); - json_object_string_add (json_neighbor, "ifaceName", IF_NAME (oi)); - json_object_int_add (json_neighbor, "retransmitCounter", ospf_ls_retransmit_count (nbr)); - json_object_int_add (json_neighbor, "requestCounter", ospf_ls_request_count (nbr)); - json_object_int_add (json_neighbor, "dbSummaryCounter", ospf_db_summary_count (nbr)); - if (nbr->state == NSM_Attempt && nbr->router_id.s_addr == 0) - json_object_object_add(json, "neighbor", json_neighbor); - else - json_object_object_add(json, inet_ntoa (nbr->router_id), json_neighbor); - } - else - { - ospf_nbr_state_message (nbr, msgbuf, 16); - - if (nbr->state == NSM_Attempt && nbr->router_id.s_addr == 0) - vty_out (vty, "%-15s %3d %-15s ", - "-", nbr->priority, - msgbuf); - else - vty_out (vty, "%-15s %3d %-15s ", - inet_ntoa (nbr->router_id), nbr->priority, - msgbuf); - - vty_out (vty, "%9s ", - ospf_timer_dump (nbr->t_inactivity, timebuf, - sizeof(timebuf))); - vty_out (vty, "%-15s ", inet_ntoa (nbr->src)); - vty_out (vty, "%-20s %5ld %5ld %5d\n", - IF_NAME (oi), ospf_ls_retransmit_count (nbr), - ospf_ls_request_count (nbr), ospf_db_summary_count (nbr)); - } - } - } - } - } -} + if (use_json) + json = json_object_new_object(); + else + show_ip_ospf_neighbour_header(vty); + + if (ospf->instance) { + if (use_json) + json_object_int_add(json, "ospfInstance", + ospf->instance); + else + vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); + } -static int -show_ip_ospf_neighbor_common (struct vty *vty, struct ospf *ospf, u_char use_json) -{ - struct ospf_interface *oi; - struct listnode *node; - json_object *json = NULL; - - if (use_json) - json = json_object_new_object(); - else - show_ip_ospf_neighbour_header (vty); - - if (ospf->instance) - { - if (use_json) - json_object_int_add(json, "ospfInstance", ospf->instance); - else - vty_out (vty, "\nOSPF Instance: %d\n\n", ospf->instance); - } - - for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) - show_ip_ospf_neighbor_sub (vty, oi, json, use_json); - - if (use_json) - { - vty_out (vty, "%s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); - json_object_free(json); - } - else - vty_out (vty, "\n"); + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) + show_ip_ospf_neighbor_sub(vty, oi, json, use_json); - return CMD_SUCCESS; + if (use_json) { + vty_out(vty, "%s\n", json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } else + vty_out(vty, "\n"); + + return CMD_SUCCESS; } DEFUN (show_ip_ospf_neighbor, @@ -3724,13 +3835,13 @@ DEFUN (show_ip_ospf_neighbor, "Neighbor list\n" JSON_STR) { - struct ospf *ospf; - u_char uj = use_json(argc, argv); + struct ospf *ospf; + u_char uj = use_json(argc, argv); - if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) + return CMD_SUCCESS; - return show_ip_ospf_neighbor_common(vty, ospf, uj); + return show_ip_ospf_neighbor_common(vty, ospf, uj); } @@ -3744,86 +3855,95 @@ DEFUN (show_ip_ospf_instance_neighbor, "Neighbor list\n" JSON_STR) { - int idx_number = 3; - struct ospf *ospf; - u_short instance = 0; - u_char uj = use_json(argc, argv); + int idx_number = 3; + struct ospf *ospf; + u_short instance = 0; + u_char uj = use_json(argc, argv); - instance = strtoul(argv[idx_number]->arg, NULL, 10); - if ((ospf = ospf_lookup_instance(instance)) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if ((ospf = ospf_lookup_instance(instance)) == NULL + || !ospf->oi_running) + return CMD_SUCCESS; - return show_ip_ospf_neighbor_common(vty, ospf, uj); + return show_ip_ospf_neighbor_common(vty, ospf, uj); } -static int -show_ip_ospf_neighbor_all_common (struct vty *vty, struct ospf *ospf, u_char use_json) -{ - struct listnode *node; - struct ospf_interface *oi; - json_object *json = NULL; - json_object *json_neighbor_sub = NULL; - - if (use_json) - { - json = json_object_new_object(); - json_neighbor_sub = json_object_new_object(); - } - else - show_ip_ospf_neighbour_header (vty); - - if (ospf->instance) - { - if (use_json) - json_object_int_add(json, "ospfInstance", ospf->instance); - else - vty_out (vty, "\nOSPF Instance: %d\n\n", ospf->instance); - } - - for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) - { - struct listnode *nbr_node; - struct ospf_nbr_nbma *nbr_nbma; - - show_ip_ospf_neighbor_sub (vty, oi, json, use_json); - - /* print Down neighbor status */ - for (ALL_LIST_ELEMENTS_RO (oi->nbr_nbma, nbr_node, nbr_nbma)) - { - if (nbr_nbma->nbr == NULL - || nbr_nbma->nbr->state == NSM_Down) - { - if (use_json) - { - json_object_int_add (json_neighbor_sub, "nbrNbmaPriority", nbr_nbma->priority); - json_object_boolean_true_add (json_neighbor_sub, "nbrNbmaDown"); - json_object_string_add (json_neighbor_sub, "nbrNbmaIfaceName", IF_NAME (oi)); - json_object_int_add (json_neighbor_sub, "nbrNbmaRetransmitCounter", 0); - json_object_int_add (json_neighbor_sub, "nbrNbmaRequestCounter", 0); - json_object_int_add (json_neighbor_sub, "nbrNbmaDbSummaryCounter", 0); - json_object_object_add(json, inet_ntoa (nbr_nbma->addr), json_neighbor_sub); - } - else - { - vty_out (vty, "%-15s %3d %-15s %9s ", - "-", nbr_nbma->priority, "Down", "-"); - vty_out (vty, "%-15s %-20s %5d %5d %5d\n", - inet_ntoa (nbr_nbma->addr), IF_NAME (oi), - 0, 0, 0); - } - } - } - } - - if (use_json) - { - vty_out (vty, "%s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); - json_object_free(json); - } - else - vty_out (vty, "\n"); +static int show_ip_ospf_neighbor_all_common(struct vty *vty, struct ospf *ospf, + u_char use_json) +{ + struct listnode *node; + struct ospf_interface *oi; + json_object *json = NULL; + json_object *json_neighbor_sub = NULL; - return CMD_SUCCESS; + if (use_json) { + json = json_object_new_object(); + json_neighbor_sub = json_object_new_object(); + } else + show_ip_ospf_neighbour_header(vty); + + if (ospf->instance) { + if (use_json) + json_object_int_add(json, "ospfInstance", + ospf->instance); + else + vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); + } + + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) { + struct listnode *nbr_node; + struct ospf_nbr_nbma *nbr_nbma; + + show_ip_ospf_neighbor_sub(vty, oi, json, use_json); + + /* print Down neighbor status */ + for (ALL_LIST_ELEMENTS_RO(oi->nbr_nbma, nbr_node, nbr_nbma)) { + if (nbr_nbma->nbr == NULL + || nbr_nbma->nbr->state == NSM_Down) { + if (use_json) { + json_object_int_add(json_neighbor_sub, + "nbrNbmaPriority", + nbr_nbma->priority); + json_object_boolean_true_add( + json_neighbor_sub, + "nbrNbmaDown"); + json_object_string_add( + json_neighbor_sub, + "nbrNbmaIfaceName", + IF_NAME(oi)); + json_object_int_add( + json_neighbor_sub, + "nbrNbmaRetransmitCounter", 0); + json_object_int_add( + json_neighbor_sub, + "nbrNbmaRequestCounter", 0); + json_object_int_add( + json_neighbor_sub, + "nbrNbmaDbSummaryCounter", 0); + json_object_object_add( + json, inet_ntoa(nbr_nbma->addr), + json_neighbor_sub); + } else { + vty_out(vty, "%-15s %3d %-15s %9s ", + "-", nbr_nbma->priority, "Down", + "-"); + vty_out(vty, + "%-15s %-20s %5d %5d %5d\n", + inet_ntoa(nbr_nbma->addr), + IF_NAME(oi), 0, 0, 0); + } + } + } + } + + if (use_json) { + vty_out(vty, "%s\n", json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } else + vty_out(vty, "\n"); + + return CMD_SUCCESS; } DEFUN (show_ip_ospf_neighbor_all, @@ -3836,13 +3956,13 @@ DEFUN (show_ip_ospf_neighbor_all, "include down status neighbor\n" JSON_STR) { - struct ospf *ospf; - u_char uj = use_json(argc, argv); + struct ospf *ospf; + u_char uj = use_json(argc, argv); - if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) + return CMD_SUCCESS; - return show_ip_ospf_neighbor_all_common(vty, ospf, uj); + return show_ip_ospf_neighbor_all_common(vty, ospf, uj); } DEFUN (show_ip_ospf_instance_neighbor_all, @@ -3856,68 +3976,67 @@ DEFUN (show_ip_ospf_instance_neighbor_all, "include down status neighbor\n" JSON_STR) { - int idx_number = 3; - struct ospf *ospf; - u_short instance = 0; - u_char uj = use_json(argc, argv); + int idx_number = 3; + struct ospf *ospf; + u_short instance = 0; + u_char uj = use_json(argc, argv); - instance = strtoul(argv[idx_number]->arg, NULL, 10); - if ((ospf = ospf_lookup_instance(instance)) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if ((ospf = ospf_lookup_instance(instance)) == NULL + || !ospf->oi_running) + return CMD_SUCCESS; - return show_ip_ospf_neighbor_all_common(vty, ospf, uj); + return show_ip_ospf_neighbor_all_common(vty, ospf, uj); } -static int -show_ip_ospf_neighbor_int_common (struct vty *vty, struct ospf *ospf, int arg_base, - struct cmd_token **argv, u_char use_json) -{ - struct interface *ifp; - struct route_node *rn; - json_object *json = NULL; - - if (use_json) - json = json_object_new_object(); - else - show_ip_ospf_neighbour_header (vty); - - if (ospf->instance) - { - if (use_json) - json_object_int_add(json, "ospfInstance", ospf->instance); - else - vty_out (vty, "\nOSPF Instance: %d\n\n", ospf->instance); - } - - ifp = if_lookup_by_name (argv[arg_base]->arg, VRF_DEFAULT); - if (!ifp) - { - if (use_json) - json_object_boolean_true_add(json, "noSuchIface"); - else - vty_out (vty, "No such interface.\n"); - return CMD_WARNING; - } - - for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn)) - { - struct ospf_interface *oi = rn->info; - - if (oi == NULL) - continue; - - show_ip_ospf_neighbor_sub (vty, oi, json, use_json); - } - - if (use_json) - { - vty_out (vty, "%s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); - json_object_free(json); - } - else - vty_out (vty, "\n"); +static int show_ip_ospf_neighbor_int_common(struct vty *vty, struct ospf *ospf, + int arg_base, + struct cmd_token **argv, + u_char use_json) +{ + struct interface *ifp; + struct route_node *rn; + json_object *json = NULL; - return CMD_SUCCESS; + if (use_json) + json = json_object_new_object(); + else + show_ip_ospf_neighbour_header(vty); + + if (ospf->instance) { + if (use_json) + json_object_int_add(json, "ospfInstance", + ospf->instance); + else + vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); + } + + ifp = if_lookup_by_name(argv[arg_base]->arg, VRF_DEFAULT); + if (!ifp) { + if (use_json) + json_object_boolean_true_add(json, "noSuchIface"); + else + vty_out(vty, "No such interface.\n"); + return CMD_WARNING; + } + + for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) { + struct ospf_interface *oi = rn->info; + + if (oi == NULL) + continue; + + show_ip_ospf_neighbor_sub(vty, oi, json, use_json); + } + + if (use_json) { + vty_out(vty, "%s\n", json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } else + vty_out(vty, "\n"); + + return CMD_SUCCESS; } DEFUN (show_ip_ospf_neighbor_int, @@ -3930,13 +4049,13 @@ DEFUN (show_ip_ospf_neighbor_int, "Interface name\n" JSON_STR) { - struct ospf *ospf; - u_char uj = use_json(argc, argv); + struct ospf *ospf; + u_char uj = use_json(argc, argv); - if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) + return CMD_SUCCESS; - return show_ip_ospf_neighbor_int_common(vty, ospf, 0, argv, uj); + return show_ip_ospf_neighbor_int_common(vty, ospf, 0, argv, uj); } DEFUN (show_ip_ospf_instance_neighbor_int, @@ -3950,340 +4069,357 @@ DEFUN (show_ip_ospf_instance_neighbor_int, "Interface name\n" JSON_STR) { - int idx_number = 3; - struct ospf *ospf; - u_short instance = 0; - u_char uj = use_json(argc, argv); + int idx_number = 3; + struct ospf *ospf; + u_short instance = 0; + u_char uj = use_json(argc, argv); - instance = strtoul(argv[idx_number]->arg, NULL, 10); - if ((ospf = ospf_lookup_instance(instance)) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if ((ospf = ospf_lookup_instance(instance)) == NULL + || !ospf->oi_running) + return CMD_SUCCESS; - return show_ip_ospf_neighbor_int_common(vty, ospf, 1, argv, uj); -} - -static void -show_ip_ospf_nbr_nbma_detail_sub (struct vty *vty, struct ospf_interface *oi, struct ospf_nbr_nbma *nbr_nbma, - u_char use_json, json_object *json) -{ - char timebuf[OSPF_TIME_DUMP_SIZE]; - json_object *json_sub = NULL; - - if (use_json) - json_sub = json_object_new_object(); - else /* Show neighbor ID. */ - vty_out (vty, " Neighbor %s,", "-"); - - /* Show interface address. */ - if (use_json) - json_object_string_add(json_sub, "ifaceAddress", inet_ntoa (nbr_nbma->addr)); - else - vty_out (vty, " interface address %s\n", - inet_ntoa (nbr_nbma->addr)); - - /* Show Area ID. */ - if (use_json) - { - json_object_string_add(json_sub, "areaId", ospf_area_desc_string (oi->area)); - json_object_string_add(json_sub, "iface", IF_NAME (oi)); - } - else - vty_out (vty, " In the area %s via interface %s\n", - ospf_area_desc_string (oi->area), IF_NAME (oi)); - - /* Show neighbor priority and state. */ - if (use_json) - { - json_object_int_add(json_sub, "nbrPriority", nbr_nbma->priority); - json_object_string_add(json_sub, "nbrState", "down"); - } - else - vty_out (vty, " Neighbor priority is %d, State is %s,", - nbr_nbma->priority, "Down"); - - /* Show state changes. */ - if (use_json) - json_object_int_add(json_sub, "stateChangeCounter", nbr_nbma->state_change); - else - vty_out (vty, " %d state changes\n", nbr_nbma->state_change); - - /* Show PollInterval */ - if (use_json) - json_object_int_add(json_sub, "pollInterval", nbr_nbma->v_poll); - else - vty_out (vty, " Poll interval %d\n", nbr_nbma->v_poll); - - /* Show poll-interval timer. */ - if (use_json) - { - long time_store; - time_store = monotime_until(&nbr_nbma->t_poll->u.sands, NULL) / 1000LL; - json_object_int_add(json_sub, "pollIntervalTimerDueMsec", time_store); - } - else - vty_out (vty, " Poll timer due in %s\n", - ospf_timer_dump (nbr_nbma->t_poll, timebuf, sizeof(timebuf))); - - /* Show poll-interval timer thread. */ - if (use_json) - { - if (nbr_nbma->t_poll != NULL) - json_object_string_add(json_sub, "pollIntervalTimerThread", "on"); - } - else - vty_out (vty, " Thread Poll Timer %s\n", - nbr_nbma->t_poll != NULL ? "on" : "off"); - - if (use_json) - json_object_object_add(json, "noNbrId", json_sub); -} - -static void -show_ip_ospf_neighbor_detail_sub (struct vty *vty, struct ospf_interface *oi, - struct ospf_neighbor *nbr, u_char use_json, json_object *json) -{ - char timebuf[OSPF_TIME_DUMP_SIZE]; - json_object *json_sub = NULL; - - if (use_json) - json_sub = json_object_new_object(); - else - { - /* Show neighbor ID. */ - if (nbr->state == NSM_Attempt && nbr->router_id.s_addr == 0) - vty_out (vty, " Neighbor %s,", "-"); - else - vty_out (vty, " Neighbor %s,", inet_ntoa (nbr->router_id)); - } - - /* Show interface address. */ - if (use_json) - json_object_string_add(json_sub, "ifaceAddress", inet_ntoa (nbr->address.u.prefix4)); - else - vty_out (vty, " interface address %s\n", - inet_ntoa (nbr->address.u.prefix4)); - - /* Show Area ID. */ - if (use_json) - { - json_object_string_add(json_sub, "areaId", ospf_area_desc_string (oi->area)); - json_object_string_add(json_sub, "ifaceName", oi->ifp->name); - } - else - vty_out (vty, " In the area %s via interface %s\n", - ospf_area_desc_string (oi->area), oi->ifp->name); - - /* Show neighbor priority and state. */ - if (use_json) - { - json_object_int_add(json_sub, "nbrPriority", nbr->priority); - json_object_string_add(json_sub, "nbrState", lookup_msg(ospf_nsm_state_msg, nbr->state, NULL)); - } - else - vty_out (vty, " Neighbor priority is %d, State is %s,", - nbr->priority, lookup_msg(ospf_nsm_state_msg, nbr->state, NULL)); - - /* Show state changes. */ - if (use_json) - json_object_int_add(json_sub, "stateChangeCounter", nbr->state_change); - else - vty_out (vty, " %d state changes\n", nbr->state_change); - - if (nbr->ts_last_progress.tv_sec || nbr->ts_last_progress.tv_usec) - { - struct timeval res; - long time_store; - - time_store = monotime_since(&nbr->ts_last_progress, &res) / 1000LL; - if (use_json) - { - json_object_int_add(json_sub, "lastPrgrsvChangeMsec", time_store); - } - else - { - vty_out (vty, " Most recent state change statistics:\n"); - vty_out (vty, " Progressive change %s ago\n", - ospf_timeval_dump (&res, timebuf, sizeof(timebuf))); - } - } - - if (nbr->ts_last_regress.tv_sec || nbr->ts_last_regress.tv_usec) - { - struct timeval res; - long time_store; - - time_store = monotime_since(&nbr->ts_last_regress, &res) / 1000LL; - if (use_json) - { - json_object_int_add(json_sub, "lastRegressiveChangeMsec", time_store); - if (nbr->last_regress_str) - json_object_string_add(json_sub, "lastRegressiveChangeReason", nbr->last_regress_str); - } - else - { - vty_out (vty, " Regressive change %s ago, due to %s\n", - ospf_timeval_dump (&res, timebuf, sizeof(timebuf)), - (nbr->last_regress_str ? nbr->last_regress_str : "??")); - } - } - - /* Show Designated Rotuer ID. */ - if (use_json) - json_object_string_add(json_sub, "routerDesignatedId", inet_ntoa (nbr->d_router)); - else - vty_out (vty, " DR is %s,", inet_ntoa (nbr->d_router)); - - /* Show Backup Designated Rotuer ID. */ - if (use_json) - json_object_string_add(json_sub, "routerDesignatedBackupId", inet_ntoa (nbr->bd_router)); - else - vty_out (vty, " BDR is %s\n", inet_ntoa (nbr->bd_router)); - - /* Show options. */ - if (use_json) - { - json_object_int_add(json_sub, "optionsCounter", nbr->options); - json_object_string_add(json_sub, "optionsList", ospf_options_dump (nbr->options)); - } - else - vty_out (vty, " Options %d %s\n", nbr->options, - ospf_options_dump (nbr->options)); - - /* Show Router Dead interval timer. */ - if (use_json) - { - if (nbr->t_inactivity) - { - long time_store; - time_store = monotime_until(&nbr->t_inactivity->u.sands, NULL) / 1000LL; - json_object_int_add(json_sub, "routerDeadIntervalTimerDueMsec", time_store); - } - else - json_object_int_add(json_sub, "routerDeadIntervalTimerDueMsec", -1); - } - else - vty_out (vty, " Dead timer due in %s\n", - ospf_timer_dump (nbr->t_inactivity, timebuf, sizeof (timebuf))); - - /* Show Database Summary list. */ - if (use_json) - json_object_int_add(json_sub, "databaseSummaryListCounter", ospf_db_summary_count (nbr)); - else - vty_out (vty, " Database Summary List %d\n", - ospf_db_summary_count (nbr)); - - /* Show Link State Request list. */ - if (use_json) - json_object_int_add(json_sub, "linkStateRequestListCounter", ospf_ls_request_count (nbr)); - else - vty_out (vty, " Link State Request List %ld\n", - ospf_ls_request_count (nbr)); - - /* Show Link State Retransmission list. */ - if (use_json) - json_object_int_add(json_sub, "linkStateRetransmissionListCounter", ospf_ls_retransmit_count (nbr)); - else - vty_out (vty, " Link State Retransmission List %ld\n", - ospf_ls_retransmit_count (nbr)); - - /* Show inactivity timer thread. */ - if (use_json) - { - if (nbr->t_inactivity != NULL) - json_object_string_add(json_sub, "threadInactivityTimer", "on"); - } - else - vty_out (vty, " Thread Inactivity Timer %s\n", - nbr->t_inactivity != NULL ? "on" : "off"); - - /* Show Database Description retransmission thread. */ - if (use_json) - { - if (nbr->t_db_desc != NULL) - json_object_string_add(json_sub, "threadDatabaseDescriptionRetransmission", "on"); - } - else - vty_out (vty, " Thread Database Description Retransmision %s\n", - nbr->t_db_desc != NULL ? "on" : "off"); - - /* Show Link State Request Retransmission thread. */ - if (use_json) - { - if (nbr->t_ls_req != NULL) - json_object_string_add(json_sub, "threadLinkStateRequestRetransmission", "on"); - } - else - vty_out (vty, " Thread Link State Request Retransmission %s\n", - nbr->t_ls_req != NULL ? "on" : "off"); - - /* Show Link State Update Retransmission thread. */ - if (use_json) - { - if (nbr->t_ls_upd != NULL) - json_object_string_add(json_sub, "threadLinkStateUpdateRetransmission", "on"); - } - else - vty_out (vty, " Thread Link State Update Retransmission %s\n\n", - nbr->t_ls_upd != NULL ? "on" : "off"); - - if (use_json) - { - if (nbr->state == NSM_Attempt && nbr->router_id.s_addr == 0) - json_object_object_add(json, "noNbrId", json_sub); - else - json_object_object_add(json, inet_ntoa (nbr->router_id), json_sub); - } - - ospf_bfd_show_info(vty, nbr->bfd_info, json, use_json, 0); + return show_ip_ospf_neighbor_int_common(vty, ospf, 1, argv, uj); } -static int -show_ip_ospf_neighbor_id_common (struct vty *vty, struct ospf *ospf, - int arg_base, struct cmd_token **argv, u_char use_json) -{ - struct listnode *node; - struct ospf_neighbor *nbr; - struct ospf_interface *oi; - struct in_addr router_id; - int ret; - json_object *json = NULL; - - if (use_json) - json = json_object_new_object(); - - if (ospf->instance) - { - if (use_json) - json_object_int_add(json, "ospfInstance", ospf->instance); - else - vty_out (vty, "\nOSPF Instance: %d\n\n", ospf->instance); - } - - ret = inet_aton (argv[arg_base]->arg, &router_id); - if (!ret) - { - if (!use_json) - vty_out (vty, "Please specify Neighbor ID by A.B.C.D\n"); - return CMD_WARNING; - } - - for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) - { - if ((nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &router_id))) - { - show_ip_ospf_neighbor_detail_sub (vty, oi, nbr, use_json, json); - } - } - - if (use_json) - { - vty_out (vty, "%s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); - json_object_free(json); - } - else - vty_out (vty, "\n"); +static void show_ip_ospf_nbr_nbma_detail_sub(struct vty *vty, + struct ospf_interface *oi, + struct ospf_nbr_nbma *nbr_nbma, + u_char use_json, json_object *json) +{ + char timebuf[OSPF_TIME_DUMP_SIZE]; + json_object *json_sub = NULL; - return CMD_SUCCESS; + if (use_json) + json_sub = json_object_new_object(); + else /* Show neighbor ID. */ + vty_out(vty, " Neighbor %s,", "-"); + + /* Show interface address. */ + if (use_json) + json_object_string_add(json_sub, "ifaceAddress", + inet_ntoa(nbr_nbma->addr)); + else + vty_out(vty, " interface address %s\n", + inet_ntoa(nbr_nbma->addr)); + + /* Show Area ID. */ + if (use_json) { + json_object_string_add(json_sub, "areaId", + ospf_area_desc_string(oi->area)); + json_object_string_add(json_sub, "iface", IF_NAME(oi)); + } else + vty_out(vty, " In the area %s via interface %s\n", + ospf_area_desc_string(oi->area), IF_NAME(oi)); + + /* Show neighbor priority and state. */ + if (use_json) { + json_object_int_add(json_sub, "nbrPriority", + nbr_nbma->priority); + json_object_string_add(json_sub, "nbrState", "down"); + } else + vty_out(vty, " Neighbor priority is %d, State is %s,", + nbr_nbma->priority, "Down"); + + /* Show state changes. */ + if (use_json) + json_object_int_add(json_sub, "stateChangeCounter", + nbr_nbma->state_change); + else + vty_out(vty, " %d state changes\n", nbr_nbma->state_change); + + /* Show PollInterval */ + if (use_json) + json_object_int_add(json_sub, "pollInterval", nbr_nbma->v_poll); + else + vty_out(vty, " Poll interval %d\n", nbr_nbma->v_poll); + + /* Show poll-interval timer. */ + if (use_json) { + long time_store; + time_store = monotime_until(&nbr_nbma->t_poll->u.sands, NULL) + / 1000LL; + json_object_int_add(json_sub, "pollIntervalTimerDueMsec", + time_store); + } else + vty_out(vty, " Poll timer due in %s\n", + ospf_timer_dump(nbr_nbma->t_poll, timebuf, + sizeof(timebuf))); + + /* Show poll-interval timer thread. */ + if (use_json) { + if (nbr_nbma->t_poll != NULL) + json_object_string_add(json_sub, + "pollIntervalTimerThread", "on"); + } else + vty_out(vty, " Thread Poll Timer %s\n", + nbr_nbma->t_poll != NULL ? "on" : "off"); + + if (use_json) + json_object_object_add(json, "noNbrId", json_sub); +} + +static void show_ip_ospf_neighbor_detail_sub(struct vty *vty, + struct ospf_interface *oi, + struct ospf_neighbor *nbr, + u_char use_json, json_object *json) +{ + char timebuf[OSPF_TIME_DUMP_SIZE]; + json_object *json_sub = NULL; + + if (use_json) + json_sub = json_object_new_object(); + else { + /* Show neighbor ID. */ + if (nbr->state == NSM_Attempt && nbr->router_id.s_addr == 0) + vty_out(vty, " Neighbor %s,", "-"); + else + vty_out(vty, " Neighbor %s,", + inet_ntoa(nbr->router_id)); + } + + /* Show interface address. */ + if (use_json) + json_object_string_add(json_sub, "ifaceAddress", + inet_ntoa(nbr->address.u.prefix4)); + else + vty_out(vty, " interface address %s\n", + inet_ntoa(nbr->address.u.prefix4)); + + /* Show Area ID. */ + if (use_json) { + json_object_string_add(json_sub, "areaId", + ospf_area_desc_string(oi->area)); + json_object_string_add(json_sub, "ifaceName", oi->ifp->name); + } else + vty_out(vty, " In the area %s via interface %s\n", + ospf_area_desc_string(oi->area), oi->ifp->name); + + /* Show neighbor priority and state. */ + if (use_json) { + json_object_int_add(json_sub, "nbrPriority", nbr->priority); + json_object_string_add( + json_sub, "nbrState", + lookup_msg(ospf_nsm_state_msg, nbr->state, NULL)); + } else + vty_out(vty, " Neighbor priority is %d, State is %s,", + nbr->priority, + lookup_msg(ospf_nsm_state_msg, nbr->state, NULL)); + + /* Show state changes. */ + if (use_json) + json_object_int_add(json_sub, "stateChangeCounter", + nbr->state_change); + else + vty_out(vty, " %d state changes\n", nbr->state_change); + + if (nbr->ts_last_progress.tv_sec || nbr->ts_last_progress.tv_usec) { + struct timeval res; + long time_store; + + time_store = + monotime_since(&nbr->ts_last_progress, &res) / 1000LL; + if (use_json) { + json_object_int_add(json_sub, "lastPrgrsvChangeMsec", + time_store); + } else { + vty_out(vty, + " Most recent state change statistics:\n"); + vty_out(vty, " Progressive change %s ago\n", + ospf_timeval_dump(&res, timebuf, + sizeof(timebuf))); + } + } + + if (nbr->ts_last_regress.tv_sec || nbr->ts_last_regress.tv_usec) { + struct timeval res; + long time_store; + + time_store = + monotime_since(&nbr->ts_last_regress, &res) / 1000LL; + if (use_json) { + json_object_int_add(json_sub, + "lastRegressiveChangeMsec", + time_store); + if (nbr->last_regress_str) + json_object_string_add( + json_sub, "lastRegressiveChangeReason", + nbr->last_regress_str); + } else { + vty_out(vty, + " Regressive change %s ago, due to %s\n", + ospf_timeval_dump(&res, timebuf, + sizeof(timebuf)), + (nbr->last_regress_str ? nbr->last_regress_str + : "??")); + } + } + + /* Show Designated Rotuer ID. */ + if (use_json) + json_object_string_add(json_sub, "routerDesignatedId", + inet_ntoa(nbr->d_router)); + else + vty_out(vty, " DR is %s,", inet_ntoa(nbr->d_router)); + + /* Show Backup Designated Rotuer ID. */ + if (use_json) + json_object_string_add(json_sub, "routerDesignatedBackupId", + inet_ntoa(nbr->bd_router)); + else + vty_out(vty, " BDR is %s\n", inet_ntoa(nbr->bd_router)); + + /* Show options. */ + if (use_json) { + json_object_int_add(json_sub, "optionsCounter", nbr->options); + json_object_string_add(json_sub, "optionsList", + ospf_options_dump(nbr->options)); + } else + vty_out(vty, " Options %d %s\n", nbr->options, + ospf_options_dump(nbr->options)); + + /* Show Router Dead interval timer. */ + if (use_json) { + if (nbr->t_inactivity) { + long time_store; + time_store = monotime_until(&nbr->t_inactivity->u.sands, + NULL) + / 1000LL; + json_object_int_add(json_sub, + "routerDeadIntervalTimerDueMsec", + time_store); + } else + json_object_int_add( + json_sub, "routerDeadIntervalTimerDueMsec", -1); + } else + vty_out(vty, " Dead timer due in %s\n", + ospf_timer_dump(nbr->t_inactivity, timebuf, + sizeof(timebuf))); + + /* Show Database Summary list. */ + if (use_json) + json_object_int_add(json_sub, "databaseSummaryListCounter", + ospf_db_summary_count(nbr)); + else + vty_out(vty, " Database Summary List %d\n", + ospf_db_summary_count(nbr)); + + /* Show Link State Request list. */ + if (use_json) + json_object_int_add(json_sub, "linkStateRequestListCounter", + ospf_ls_request_count(nbr)); + else + vty_out(vty, " Link State Request List %ld\n", + ospf_ls_request_count(nbr)); + + /* Show Link State Retransmission list. */ + if (use_json) + json_object_int_add(json_sub, + "linkStateRetransmissionListCounter", + ospf_ls_retransmit_count(nbr)); + else + vty_out(vty, " Link State Retransmission List %ld\n", + ospf_ls_retransmit_count(nbr)); + + /* Show inactivity timer thread. */ + if (use_json) { + if (nbr->t_inactivity != NULL) + json_object_string_add(json_sub, + "threadInactivityTimer", "on"); + } else + vty_out(vty, " Thread Inactivity Timer %s\n", + nbr->t_inactivity != NULL ? "on" : "off"); + + /* Show Database Description retransmission thread. */ + if (use_json) { + if (nbr->t_db_desc != NULL) + json_object_string_add( + json_sub, + "threadDatabaseDescriptionRetransmission", + "on"); + } else + vty_out(vty, + " Thread Database Description Retransmision %s\n", + nbr->t_db_desc != NULL ? "on" : "off"); + + /* Show Link State Request Retransmission thread. */ + if (use_json) { + if (nbr->t_ls_req != NULL) + json_object_string_add( + json_sub, + "threadLinkStateRequestRetransmission", "on"); + } else + vty_out(vty, + " Thread Link State Request Retransmission %s\n", + nbr->t_ls_req != NULL ? "on" : "off"); + + /* Show Link State Update Retransmission thread. */ + if (use_json) { + if (nbr->t_ls_upd != NULL) + json_object_string_add( + json_sub, "threadLinkStateUpdateRetransmission", + "on"); + } else + vty_out(vty, + " Thread Link State Update Retransmission %s\n\n", + nbr->t_ls_upd != NULL ? "on" : "off"); + + if (use_json) { + if (nbr->state == NSM_Attempt && nbr->router_id.s_addr == 0) + json_object_object_add(json, "noNbrId", json_sub); + else + json_object_object_add(json, inet_ntoa(nbr->router_id), + json_sub); + } + + ospf_bfd_show_info(vty, nbr->bfd_info, json, use_json, 0); +} + +static int show_ip_ospf_neighbor_id_common(struct vty *vty, struct ospf *ospf, + int arg_base, + struct cmd_token **argv, + u_char use_json) +{ + struct listnode *node; + struct ospf_neighbor *nbr; + struct ospf_interface *oi; + struct in_addr router_id; + int ret; + json_object *json = NULL; + + if (use_json) + json = json_object_new_object(); + + if (ospf->instance) { + if (use_json) + json_object_int_add(json, "ospfInstance", + ospf->instance); + else + vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); + } + + ret = inet_aton(argv[arg_base]->arg, &router_id); + if (!ret) { + if (!use_json) + vty_out(vty, "Please specify Neighbor ID by A.B.C.D\n"); + return CMD_WARNING; + } + + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) { + if ((nbr = ospf_nbr_lookup_by_routerid(oi->nbrs, &router_id))) { + show_ip_ospf_neighbor_detail_sub(vty, oi, nbr, use_json, + json); + } + } + + if (use_json) { + vty_out(vty, "%s\n", json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } else + vty_out(vty, "\n"); + + return CMD_SUCCESS; } DEFUN (show_ip_ospf_neighbor_id, @@ -4296,13 +4432,13 @@ DEFUN (show_ip_ospf_neighbor_id, "Neighbor ID\n" JSON_STR) { - struct ospf *ospf; - u_char uj = use_json(argc, argv); + struct ospf *ospf; + u_char uj = use_json(argc, argv); - if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) + return CMD_SUCCESS; - return show_ip_ospf_neighbor_id_common(vty, ospf, 0, argv, uj); + return show_ip_ospf_neighbor_id_common(vty, ospf, 0, argv, uj); } DEFUN (show_ip_ospf_instance_neighbor_id, @@ -4316,65 +4452,63 @@ DEFUN (show_ip_ospf_instance_neighbor_id, "Neighbor ID\n" JSON_STR) { - int idx_number = 3; - struct ospf *ospf; - u_short instance = 0; - u_char uj = use_json(argc, argv); + int idx_number = 3; + struct ospf *ospf; + u_short instance = 0; + u_char uj = use_json(argc, argv); - instance = strtoul(argv[idx_number]->arg, NULL, 10); - if ((ospf = ospf_lookup_instance(instance)) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if ((ospf = ospf_lookup_instance(instance)) == NULL + || !ospf->oi_running) + return CMD_SUCCESS; - return show_ip_ospf_neighbor_id_common(vty, ospf, 1, argv, uj); + return show_ip_ospf_neighbor_id_common(vty, ospf, 1, argv, uj); } -static int -show_ip_ospf_neighbor_detail_common (struct vty *vty, struct ospf *ospf, u_char use_json) -{ - struct ospf_interface *oi; - struct listnode *node; - json_object *json = NULL; - - if (use_json) - json = json_object_new_object(); - - if (ospf->instance) - { - if (use_json) - json_object_int_add(json, "ospfInstance", ospf->instance); - else - vty_out (vty, "\nOSPF Instance: %d\n\n", ospf->instance); - } - - for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) - { - struct route_node *rn; - struct ospf_neighbor *nbr; - - for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) - { - if ((nbr = rn->info)) - { - if (nbr != oi->nbr_self) - { - if (nbr->state != NSM_Down) - { - show_ip_ospf_neighbor_detail_sub (vty, oi, nbr, use_json, json); - } - } - } - } - } - - if (use_json) - { - vty_out (vty, "%s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); - json_object_free(json); - } - else - vty_out (vty, "\n"); +static int show_ip_ospf_neighbor_detail_common(struct vty *vty, + struct ospf *ospf, + u_char use_json) +{ + struct ospf_interface *oi; + struct listnode *node; + json_object *json = NULL; - return CMD_SUCCESS; + if (use_json) + json = json_object_new_object(); + + if (ospf->instance) { + if (use_json) + json_object_int_add(json, "ospfInstance", + ospf->instance); + else + vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); + } + + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) { + struct route_node *rn; + struct ospf_neighbor *nbr; + + for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) { + if ((nbr = rn->info)) { + if (nbr != oi->nbr_self) { + if (nbr->state != NSM_Down) { + show_ip_ospf_neighbor_detail_sub( + vty, oi, nbr, use_json, + json); + } + } + } + } + } + + if (use_json) { + vty_out(vty, "%s\n", json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } else + vty_out(vty, "\n"); + + return CMD_SUCCESS; } DEFUN (show_ip_ospf_neighbor_detail, @@ -4387,13 +4521,13 @@ DEFUN (show_ip_ospf_neighbor_detail, "detail of all neighbors\n" JSON_STR) { - struct ospf *ospf; - u_char uj = use_json(argc, argv); + struct ospf *ospf; + u_char uj = use_json(argc, argv); - if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) + return CMD_SUCCESS; - return show_ip_ospf_neighbor_detail_common(vty, ospf, uj); + return show_ip_ospf_neighbor_detail_common(vty, ospf, uj); } DEFUN (show_ip_ospf_instance_neighbor_detail, @@ -4407,71 +4541,73 @@ DEFUN (show_ip_ospf_instance_neighbor_detail, "detail of all neighbors\n" JSON_STR) { - int idx_number = 3; - struct ospf *ospf; - u_short instance = 0; - u_char uj = use_json(argc, argv); + int idx_number = 3; + struct ospf *ospf; + u_short instance = 0; + u_char uj = use_json(argc, argv); - instance = strtoul(argv[idx_number]->arg, NULL, 10); - if ((ospf = ospf_lookup_instance (instance)) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if ((ospf = ospf_lookup_instance(instance)) == NULL + || !ospf->oi_running) + return CMD_SUCCESS; - return show_ip_ospf_neighbor_detail_common(vty, ospf, uj); + return show_ip_ospf_neighbor_detail_common(vty, ospf, uj); } -static int -show_ip_ospf_neighbor_detail_all_common (struct vty *vty, struct ospf *ospf, u_char use_json) -{ - struct listnode *node; - struct ospf_interface *oi; - json_object *json = NULL; - - if (use_json) - json = json_object_new_object(); - - if (ospf->instance) - { - if (use_json) - json_object_int_add(json, "ospfInstance", ospf->instance); - else - vty_out (vty, "\nOSPF Instance: %d\n\n", ospf->instance); - } - - for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) - { - struct route_node *rn; - struct ospf_neighbor *nbr; - struct ospf_nbr_nbma *nbr_nbma; - - for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) - if ((nbr = rn->info)) - if (nbr != oi->nbr_self) - if (nbr->state != NSM_Down) - show_ip_ospf_neighbor_detail_sub (vty, oi, rn->info, use_json, json); - - if (oi->type == OSPF_IFTYPE_NBMA) - { - struct listnode *nd; - - for (ALL_LIST_ELEMENTS_RO (oi->nbr_nbma, nd, nbr_nbma)) - { - if (nbr_nbma->nbr == NULL || nbr_nbma->nbr->state == NSM_Down) - show_ip_ospf_nbr_nbma_detail_sub (vty, oi, nbr_nbma, use_json, json); - } - } - } - - if (use_json) - { - vty_out (vty, "%s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); - json_object_free(json); - } - else - { - vty_out (vty, "\n"); - } +static int show_ip_ospf_neighbor_detail_all_common(struct vty *vty, + struct ospf *ospf, + u_char use_json) +{ + struct listnode *node; + struct ospf_interface *oi; + json_object *json = NULL; - return CMD_SUCCESS; + if (use_json) + json = json_object_new_object(); + + if (ospf->instance) { + if (use_json) + json_object_int_add(json, "ospfInstance", + ospf->instance); + else + vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); + } + + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) { + struct route_node *rn; + struct ospf_neighbor *nbr; + struct ospf_nbr_nbma *nbr_nbma; + + for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) + if ((nbr = rn->info)) + if (nbr != oi->nbr_self) + if (nbr->state != NSM_Down) + show_ip_ospf_neighbor_detail_sub( + vty, oi, rn->info, + use_json, json); + + if (oi->type == OSPF_IFTYPE_NBMA) { + struct listnode *nd; + + for (ALL_LIST_ELEMENTS_RO(oi->nbr_nbma, nd, nbr_nbma)) { + if (nbr_nbma->nbr == NULL + || nbr_nbma->nbr->state == NSM_Down) + show_ip_ospf_nbr_nbma_detail_sub( + vty, oi, nbr_nbma, use_json, + json); + } + } + } + + if (use_json) { + vty_out(vty, "%s\n", json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } else { + vty_out(vty, "\n"); + } + + return CMD_SUCCESS; } DEFUN (show_ip_ospf_neighbor_detail_all, @@ -4485,13 +4621,13 @@ DEFUN (show_ip_ospf_neighbor_detail_all, "include down status neighbor\n" JSON_STR) { - struct ospf *ospf; - u_char uj = use_json(argc, argv); + struct ospf *ospf; + u_char uj = use_json(argc, argv); - if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) + return CMD_SUCCESS; - return show_ip_ospf_neighbor_detail_all_common(vty, ospf, uj); + return show_ip_ospf_neighbor_detail_all_common(vty, ospf, uj); } DEFUN (show_ip_ospf_instance_neighbor_detail_all, @@ -4506,74 +4642,73 @@ DEFUN (show_ip_ospf_instance_neighbor_detail_all, "include down status neighbor\n" JSON_STR) { - int idx_number = 3; - struct ospf *ospf; - u_short instance = 0; - u_char uj = use_json(argc, argv); + int idx_number = 3; + struct ospf *ospf; + u_short instance = 0; + u_char uj = use_json(argc, argv); - instance = strtoul(argv[idx_number]->arg, NULL, 10); - if ((ospf = ospf_lookup_instance(instance)) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if ((ospf = ospf_lookup_instance(instance)) == NULL + || !ospf->oi_running) + return CMD_SUCCESS; - return show_ip_ospf_neighbor_detail_all_common(vty, ospf, uj); + return show_ip_ospf_neighbor_detail_all_common(vty, ospf, uj); } -static int -show_ip_ospf_neighbor_int_detail_common (struct vty *vty, struct ospf *ospf, - int arg_base, struct cmd_token **argv, u_char use_json) -{ - struct ospf_interface *oi; - struct interface *ifp; - struct route_node *rn, *nrn; - struct ospf_neighbor *nbr; - json_object *json = NULL; - - if (use_json) - json = json_object_new_object(); - - if (ospf->instance) - { - if (use_json) - json_object_int_add(json, "ospfInstance", ospf->instance); - else - vty_out (vty, "\nOSPF Instance: %d\n\n", ospf->instance); - } - - ifp = if_lookup_by_name (argv[arg_base]->arg, VRF_DEFAULT); - if (!ifp) - { - if (!use_json) - vty_out (vty, "No such interface.\n"); - return CMD_WARNING; - } - - for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn)) - { - if ((oi = rn->info)) - { - for (nrn = route_top (oi->nbrs); nrn; nrn = route_next (nrn)) - { - if ((nbr = nrn->info)) - { - if (nbr != oi->nbr_self) - { - if (nbr->state != NSM_Down) - show_ip_ospf_neighbor_detail_sub (vty, oi, nbr, use_json, json); - } - } - } - } - } - - if (use_json) - { - vty_out (vty, "%s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); - json_object_free(json); - } - else - vty_out (vty, "\n"); +static int show_ip_ospf_neighbor_int_detail_common(struct vty *vty, + struct ospf *ospf, + int arg_base, + struct cmd_token **argv, + u_char use_json) +{ + struct ospf_interface *oi; + struct interface *ifp; + struct route_node *rn, *nrn; + struct ospf_neighbor *nbr; + json_object *json = NULL; - return CMD_SUCCESS; + if (use_json) + json = json_object_new_object(); + + if (ospf->instance) { + if (use_json) + json_object_int_add(json, "ospfInstance", + ospf->instance); + else + vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); + } + + ifp = if_lookup_by_name(argv[arg_base]->arg, VRF_DEFAULT); + if (!ifp) { + if (!use_json) + vty_out(vty, "No such interface.\n"); + return CMD_WARNING; + } + + for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) { + if ((oi = rn->info)) { + for (nrn = route_top(oi->nbrs); nrn; + nrn = route_next(nrn)) { + if ((nbr = nrn->info)) { + if (nbr != oi->nbr_self) { + if (nbr->state != NSM_Down) + show_ip_ospf_neighbor_detail_sub( + vty, oi, nbr, + use_json, json); + } + } + } + } + } + + if (use_json) { + vty_out(vty, "%s\n", json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } else + vty_out(vty, "\n"); + + return CMD_SUCCESS; } DEFUN (show_ip_ospf_neighbor_int_detail, @@ -4587,13 +4722,13 @@ DEFUN (show_ip_ospf_neighbor_int_detail, "detail of all neighbors\n" JSON_STR) { - struct ospf *ospf; - u_char uj = use_json(argc, argv); + struct ospf *ospf; + u_char uj = use_json(argc, argv); - if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) + return CMD_SUCCESS; - return show_ip_ospf_neighbor_int_detail_common(vty, ospf, 0, argv, uj); + return show_ip_ospf_neighbor_int_detail_common(vty, ospf, 0, argv, uj); } DEFUN (show_ip_ospf_instance_neighbor_int_detail, @@ -4608,311 +4743,293 @@ DEFUN (show_ip_ospf_instance_neighbor_int_detail, "detail of all neighbors\n" JSON_STR) { - int idx_number = 3; - struct ospf *ospf; - u_short instance = 0; - u_char uj = use_json(argc, argv); + int idx_number = 3; + struct ospf *ospf; + u_short instance = 0; + u_char uj = use_json(argc, argv); - instance = strtoul(argv[idx_number]->arg, NULL, 10); - if ((ospf = ospf_lookup_instance(instance)) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if ((ospf = ospf_lookup_instance(instance)) == NULL + || !ospf->oi_running) + return CMD_SUCCESS; - return show_ip_ospf_neighbor_int_detail_common(vty, ospf, 1, argv, uj); + return show_ip_ospf_neighbor_int_detail_common(vty, ospf, 1, argv, uj); } /* Show functions */ -static int -show_lsa_summary (struct vty *vty, struct ospf_lsa *lsa, int self) -{ - struct router_lsa *rl; - struct summary_lsa *sl; - struct as_external_lsa *asel; - struct prefix_ipv4 p; - - if (lsa != NULL) - /* If self option is set, check LSA self flag. */ - if (self == 0 || IS_LSA_SELF (lsa)) - { - /* LSA common part show. */ - vty_out (vty, "%-15s ", inet_ntoa (lsa->data->id)); - vty_out (vty, "%-15s %4d 0x%08lx 0x%04x", - inet_ntoa (lsa->data->adv_router), LS_AGE (lsa), - (u_long)ntohl (lsa->data->ls_seqnum), ntohs (lsa->data->checksum)); - /* LSA specific part show. */ - switch (lsa->data->type) - { - case OSPF_ROUTER_LSA: - rl = (struct router_lsa *) lsa->data; - vty_out (vty, " %-d", ntohs (rl->links)); - break; - case OSPF_SUMMARY_LSA: - sl = (struct summary_lsa *) lsa->data; - - p.family = AF_INET; - p.prefix = sl->header.id; - p.prefixlen = ip_masklen (sl->mask); - apply_mask_ipv4 (&p); - - vty_out (vty, " %s/%d", inet_ntoa (p.prefix), p.prefixlen); - break; - case OSPF_AS_EXTERNAL_LSA: - case OSPF_AS_NSSA_LSA: - asel = (struct as_external_lsa *) lsa->data; - - p.family = AF_INET; - p.prefix = asel->header.id; - p.prefixlen = ip_masklen (asel->mask); - apply_mask_ipv4 (&p); - - vty_out (vty, " %s %s/%d [0x%lx]", - IS_EXTERNAL_METRIC (asel->e[0].tos) ? "E2" : "E1", - inet_ntoa (p.prefix), p.prefixlen, - (u_long)ntohl (asel->e[0].route_tag)); - break; - case OSPF_NETWORK_LSA: - case OSPF_ASBR_SUMMARY_LSA: - case OSPF_OPAQUE_LINK_LSA: - case OSPF_OPAQUE_AREA_LSA: - case OSPF_OPAQUE_AS_LSA: - default: - break; - } - vty_out (vty, "\n"); - } - - return 0; -} +static int show_lsa_summary(struct vty *vty, struct ospf_lsa *lsa, int self) +{ + struct router_lsa *rl; + struct summary_lsa *sl; + struct as_external_lsa *asel; + struct prefix_ipv4 p; + + if (lsa != NULL) + /* If self option is set, check LSA self flag. */ + if (self == 0 || IS_LSA_SELF(lsa)) { + /* LSA common part show. */ + vty_out(vty, "%-15s ", inet_ntoa(lsa->data->id)); + vty_out(vty, "%-15s %4d 0x%08lx 0x%04x", + inet_ntoa(lsa->data->adv_router), LS_AGE(lsa), + (u_long)ntohl(lsa->data->ls_seqnum), + ntohs(lsa->data->checksum)); + /* LSA specific part show. */ + switch (lsa->data->type) { + case OSPF_ROUTER_LSA: + rl = (struct router_lsa *)lsa->data; + vty_out(vty, " %-d", ntohs(rl->links)); + break; + case OSPF_SUMMARY_LSA: + sl = (struct summary_lsa *)lsa->data; + + p.family = AF_INET; + p.prefix = sl->header.id; + p.prefixlen = ip_masklen(sl->mask); + apply_mask_ipv4(&p); + + vty_out(vty, " %s/%d", inet_ntoa(p.prefix), + p.prefixlen); + break; + case OSPF_AS_EXTERNAL_LSA: + case OSPF_AS_NSSA_LSA: + asel = (struct as_external_lsa *)lsa->data; + + p.family = AF_INET; + p.prefix = asel->header.id; + p.prefixlen = ip_masklen(asel->mask); + apply_mask_ipv4(&p); + + vty_out(vty, " %s %s/%d [0x%lx]", + IS_EXTERNAL_METRIC(asel->e[0].tos) + ? "E2" + : "E1", + inet_ntoa(p.prefix), p.prefixlen, + (u_long)ntohl(asel->e[0].route_tag)); + break; + case OSPF_NETWORK_LSA: + case OSPF_ASBR_SUMMARY_LSA: + case OSPF_OPAQUE_LINK_LSA: + case OSPF_OPAQUE_AREA_LSA: + case OSPF_OPAQUE_AS_LSA: + default: + break; + } + vty_out(vty, "\n"); + } -static const char *show_database_desc[] = -{ - "unknown", - "Router Link States", - "Net Link States", - "Summary Link States", - "ASBR-Summary Link States", - "AS External Link States", - "Group Membership LSA", - "NSSA-external Link States", - "Type-8 LSA", - "Link-Local Opaque-LSA", - "Area-Local Opaque-LSA", - "AS-external Opaque-LSA", + return 0; +} + +static const char *show_database_desc[] = { + "unknown", + "Router Link States", + "Net Link States", + "Summary Link States", + "ASBR-Summary Link States", + "AS External Link States", + "Group Membership LSA", + "NSSA-external Link States", + "Type-8 LSA", + "Link-Local Opaque-LSA", + "Area-Local Opaque-LSA", + "AS-external Opaque-LSA", }; -static const char *show_database_header[] = -{ - "", - "Link ID ADV Router Age Seq# CkSum Link count", - "Link ID ADV Router Age Seq# CkSum", - "Link ID ADV Router Age Seq# CkSum Route", - "Link ID ADV Router Age Seq# CkSum", - "Link ID ADV Router Age Seq# CkSum Route", - " --- header for Group Member ----", - "Link ID ADV Router Age Seq# CkSum Route", - " --- type-8 ---", - "Opaque-Type/Id ADV Router Age Seq# CkSum", - "Opaque-Type/Id ADV Router Age Seq# CkSum", - "Opaque-Type/Id ADV Router Age Seq# CkSum", +static const char *show_database_header[] = { + "", + "Link ID ADV Router Age Seq# CkSum Link count", + "Link ID ADV Router Age Seq# CkSum", + "Link ID ADV Router Age Seq# CkSum Route", + "Link ID ADV Router Age Seq# CkSum", + "Link ID ADV Router Age Seq# CkSum Route", + " --- header for Group Member ----", + "Link ID ADV Router Age Seq# CkSum Route", + " --- type-8 ---", + "Opaque-Type/Id ADV Router Age Seq# CkSum", + "Opaque-Type/Id ADV Router Age Seq# CkSum", + "Opaque-Type/Id ADV Router Age Seq# CkSum", }; -static void -show_ip_ospf_database_header (struct vty *vty, struct ospf_lsa *lsa) -{ - struct router_lsa *rlsa = (struct router_lsa*) lsa->data; - - vty_out (vty, " LS age: %d\n", LS_AGE (lsa)); - vty_out (vty, " Options: 0x%-2x : %s\n", lsa->data->options, - ospf_options_dump(lsa->data->options)); - vty_out (vty, " LS Flags: 0x%-2x %s\n", - lsa->flags, - ((lsa->flags & OSPF_LSA_LOCAL_XLT) ? - "(Translated from Type-7)" : "")); - - if (lsa->data->type == OSPF_ROUTER_LSA) - { - vty_out (vty, " Flags: 0x%x" , rlsa->flags); - - if (rlsa->flags) - vty_out (vty, " :%s%s%s%s", - IS_ROUTER_LSA_BORDER (rlsa) ? " ABR" : "", - IS_ROUTER_LSA_EXTERNAL (rlsa) ? " ASBR" : "", - IS_ROUTER_LSA_VIRTUAL (rlsa) ? " VL-endpoint" : "", - IS_ROUTER_LSA_SHORTCUT (rlsa) ? " Shortcut" : ""); - - vty_out (vty, "\n"); - } - vty_out (vty, " LS Type: %s\n", - lookup_msg(ospf_lsa_type_msg, lsa->data->type, NULL)); - vty_out (vty, " Link State ID: %s %s\n", inet_ntoa (lsa->data->id), - lookup_msg(ospf_link_state_id_type_msg, lsa->data->type, NULL)); - vty_out (vty, " Advertising Router: %s\n", inet_ntoa (lsa->data->adv_router)); - vty_out (vty, " LS Seq Number: %08lx\n", (u_long)ntohl (lsa->data->ls_seqnum)); - vty_out (vty, " Checksum: 0x%04x\n", ntohs (lsa->data->checksum)); - vty_out (vty, " Length: %d\n\n", ntohs (lsa->data->length)); -} - -const char *link_type_desc[] = -{ - "(null)", - "another Router (point-to-point)", - "a Transit Network", - "Stub Network", - "a Virtual Link", +static void show_ip_ospf_database_header(struct vty *vty, struct ospf_lsa *lsa) +{ + struct router_lsa *rlsa = (struct router_lsa *)lsa->data; + + vty_out(vty, " LS age: %d\n", LS_AGE(lsa)); + vty_out(vty, " Options: 0x%-2x : %s\n", lsa->data->options, + ospf_options_dump(lsa->data->options)); + vty_out(vty, " LS Flags: 0x%-2x %s\n", lsa->flags, + ((lsa->flags & OSPF_LSA_LOCAL_XLT) ? "(Translated from Type-7)" + : "")); + + if (lsa->data->type == OSPF_ROUTER_LSA) { + vty_out(vty, " Flags: 0x%x", rlsa->flags); + + if (rlsa->flags) + vty_out(vty, " :%s%s%s%s", + IS_ROUTER_LSA_BORDER(rlsa) ? " ABR" : "", + IS_ROUTER_LSA_EXTERNAL(rlsa) ? " ASBR" : "", + IS_ROUTER_LSA_VIRTUAL(rlsa) ? " VL-endpoint" + : "", + IS_ROUTER_LSA_SHORTCUT(rlsa) ? " Shortcut" + : ""); + + vty_out(vty, "\n"); + } + vty_out(vty, " LS Type: %s\n", + lookup_msg(ospf_lsa_type_msg, lsa->data->type, NULL)); + vty_out(vty, " Link State ID: %s %s\n", inet_ntoa(lsa->data->id), + lookup_msg(ospf_link_state_id_type_msg, lsa->data->type, NULL)); + vty_out(vty, " Advertising Router: %s\n", + inet_ntoa(lsa->data->adv_router)); + vty_out(vty, " LS Seq Number: %08lx\n", + (u_long)ntohl(lsa->data->ls_seqnum)); + vty_out(vty, " Checksum: 0x%04x\n", ntohs(lsa->data->checksum)); + vty_out(vty, " Length: %d\n\n", ntohs(lsa->data->length)); +} + +const char *link_type_desc[] = { + "(null)", + "another Router (point-to-point)", + "a Transit Network", + "Stub Network", + "a Virtual Link", }; -const char *link_id_desc[] = -{ - "(null)", - "Neighboring Router ID", - "Designated Router address", - "Net", - "Neighboring Router ID", +const char *link_id_desc[] = { + "(null)", "Neighboring Router ID", "Designated Router address", + "Net", "Neighboring Router ID", }; -const char *link_data_desc[] = -{ - "(null)", - "Router Interface address", - "Router Interface address", - "Network Mask", - "Router Interface address", +const char *link_data_desc[] = { + "(null)", "Router Interface address", "Router Interface address", + "Network Mask", "Router Interface address", }; /* Show router-LSA each Link information. */ -static void -show_ip_ospf_database_router_links (struct vty *vty, - struct router_lsa *rl) -{ - int len, type; - unsigned int i; - - len = ntohs (rl->header.length) - 4; - for (i = 0; i < ntohs (rl->links) && len > 0; len -= 12, i++) - { - type = rl->link[i].type; - - vty_out (vty, " Link connected to: %s\n", - link_type_desc[type]); - vty_out (vty, " (Link ID) %s: %s\n", link_id_desc[type], - inet_ntoa (rl->link[i].link_id)); - vty_out (vty, " (Link Data) %s: %s\n", link_data_desc[type], - inet_ntoa (rl->link[i].link_data)); - vty_out (vty, " Number of TOS metrics: 0\n"); - vty_out (vty, " TOS 0 Metric: %d\n", - ntohs (rl->link[i].metric)); - vty_out (vty, "\n"); - } +static void show_ip_ospf_database_router_links(struct vty *vty, + struct router_lsa *rl) +{ + int len, type; + unsigned int i; + + len = ntohs(rl->header.length) - 4; + for (i = 0; i < ntohs(rl->links) && len > 0; len -= 12, i++) { + type = rl->link[i].type; + + vty_out(vty, " Link connected to: %s\n", + link_type_desc[type]); + vty_out(vty, " (Link ID) %s: %s\n", link_id_desc[type], + inet_ntoa(rl->link[i].link_id)); + vty_out(vty, " (Link Data) %s: %s\n", link_data_desc[type], + inet_ntoa(rl->link[i].link_data)); + vty_out(vty, " Number of TOS metrics: 0\n"); + vty_out(vty, " TOS 0 Metric: %d\n", + ntohs(rl->link[i].metric)); + vty_out(vty, "\n"); + } } /* Show router-LSA detail information. */ -static int -show_router_lsa_detail (struct vty *vty, struct ospf_lsa *lsa) +static int show_router_lsa_detail(struct vty *vty, struct ospf_lsa *lsa) { - if (lsa != NULL) - { - struct router_lsa *rl = (struct router_lsa *) lsa->data; + if (lsa != NULL) { + struct router_lsa *rl = (struct router_lsa *)lsa->data; - show_ip_ospf_database_header (vty, lsa); - - vty_out (vty, " Number of Links: %d\n\n", ntohs (rl->links)); + show_ip_ospf_database_header(vty, lsa); - show_ip_ospf_database_router_links (vty, rl); - vty_out (vty, "\n"); - } + vty_out(vty, " Number of Links: %d\n\n", ntohs(rl->links)); - return 0; + show_ip_ospf_database_router_links(vty, rl); + vty_out(vty, "\n"); + } + + return 0; } /* Show network-LSA detail information. */ -static int -show_network_lsa_detail (struct vty *vty, struct ospf_lsa *lsa) +static int show_network_lsa_detail(struct vty *vty, struct ospf_lsa *lsa) { - int length, i; + int length, i; - if (lsa != NULL) - { - struct network_lsa *nl = (struct network_lsa *) lsa->data; + if (lsa != NULL) { + struct network_lsa *nl = (struct network_lsa *)lsa->data; - show_ip_ospf_database_header (vty, lsa); + show_ip_ospf_database_header(vty, lsa); - vty_out (vty, " Network Mask: /%d\n", - ip_masklen (nl->mask)); + vty_out(vty, " Network Mask: /%d\n", ip_masklen(nl->mask)); - length = ntohs (lsa->data->length) - OSPF_LSA_HEADER_SIZE - 4; + length = ntohs(lsa->data->length) - OSPF_LSA_HEADER_SIZE - 4; - for (i = 0; length > 0; i++, length -= 4) - vty_out (vty, " Attached Router: %s\n", - inet_ntoa (nl->routers[i])); + for (i = 0; length > 0; i++, length -= 4) + vty_out(vty, " Attached Router: %s\n", + inet_ntoa(nl->routers[i])); - vty_out (vty, "\n"); - } + vty_out(vty, "\n"); + } - return 0; + return 0; } /* Show summary-LSA detail information. */ -static int -show_summary_lsa_detail (struct vty *vty, struct ospf_lsa *lsa) +static int show_summary_lsa_detail(struct vty *vty, struct ospf_lsa *lsa) { - if (lsa != NULL) - { - struct summary_lsa *sl = (struct summary_lsa *) lsa->data; + if (lsa != NULL) { + struct summary_lsa *sl = (struct summary_lsa *)lsa->data; - show_ip_ospf_database_header (vty, lsa); + show_ip_ospf_database_header(vty, lsa); - vty_out (vty, " Network Mask: /%d\n", ip_masklen (sl->mask)); - vty_out (vty, " TOS: 0 Metric: %d\n", GET_METRIC (sl->metric)); - vty_out (vty, "\n"); - } + vty_out(vty, " Network Mask: /%d\n", ip_masklen(sl->mask)); + vty_out(vty, " TOS: 0 Metric: %d\n", + GET_METRIC(sl->metric)); + vty_out(vty, "\n"); + } - return 0; + return 0; } /* Show summary-ASBR-LSA detail information. */ -static int -show_summary_asbr_lsa_detail (struct vty *vty, struct ospf_lsa *lsa) +static int show_summary_asbr_lsa_detail(struct vty *vty, struct ospf_lsa *lsa) { - if (lsa != NULL) - { - struct summary_lsa *sl = (struct summary_lsa *) lsa->data; + if (lsa != NULL) { + struct summary_lsa *sl = (struct summary_lsa *)lsa->data; - show_ip_ospf_database_header (vty, lsa); + show_ip_ospf_database_header(vty, lsa); - vty_out (vty, " Network Mask: /%d\n", - ip_masklen (sl->mask)); - vty_out (vty, " TOS: 0 Metric: %d\n", GET_METRIC (sl->metric)); - vty_out (vty, "\n"); - } + vty_out(vty, " Network Mask: /%d\n", ip_masklen(sl->mask)); + vty_out(vty, " TOS: 0 Metric: %d\n", + GET_METRIC(sl->metric)); + vty_out(vty, "\n"); + } - return 0; + return 0; } /* Show AS-external-LSA detail information. */ -static int -show_as_external_lsa_detail (struct vty *vty, struct ospf_lsa *lsa) -{ - if (lsa != NULL) - { - struct as_external_lsa *al = (struct as_external_lsa *) lsa->data; - - show_ip_ospf_database_header (vty, lsa); - - vty_out (vty, " Network Mask: /%d\n", - ip_masklen (al->mask)); - vty_out (vty, " Metric Type: %s\n", - IS_EXTERNAL_METRIC (al->e[0].tos) ? - "2 (Larger than any link state path)" : "1"); - vty_out (vty, " TOS: 0\n"); - vty_out (vty, " Metric: %d\n", - GET_METRIC (al->e[0].metric)); - vty_out (vty, " Forward Address: %s\n", - inet_ntoa (al->e[0].fwd_addr)); - - vty_out (vty, " External Route Tag: %"ROUTE_TAG_PRI"\n\n", - (route_tag_t)ntohl (al->e[0].route_tag)); - } +static int show_as_external_lsa_detail(struct vty *vty, struct ospf_lsa *lsa) +{ + if (lsa != NULL) { + struct as_external_lsa *al = + (struct as_external_lsa *)lsa->data; + + show_ip_ospf_database_header(vty, lsa); + + vty_out(vty, " Network Mask: /%d\n", ip_masklen(al->mask)); + vty_out(vty, " Metric Type: %s\n", + IS_EXTERNAL_METRIC(al->e[0].tos) + ? "2 (Larger than any link state path)" + : "1"); + vty_out(vty, " TOS: 0\n"); + vty_out(vty, " Metric: %d\n", + GET_METRIC(al->e[0].metric)); + vty_out(vty, " Forward Address: %s\n", + inet_ntoa(al->e[0].fwd_addr)); + + vty_out(vty, + " External Route Tag: %" ROUTE_TAG_PRI "\n\n", + (route_tag_t)ntohl(al->e[0].route_tag)); + } - return 0; + return 0; } #if 0 static int @@ -4940,273 +5057,253 @@ show_as_external_lsa_stdvty (struct ospf_lsa *lsa) } #endif /* Show AS-NSSA-LSA detail information. */ -static int -show_as_nssa_lsa_detail (struct vty *vty, struct ospf_lsa *lsa) -{ - if (lsa != NULL) - { - struct as_external_lsa *al = (struct as_external_lsa *) lsa->data; - - show_ip_ospf_database_header (vty, lsa); - - vty_out (vty, " Network Mask: /%d\n", - ip_masklen (al->mask)); - vty_out (vty, " Metric Type: %s\n", - IS_EXTERNAL_METRIC (al->e[0].tos) ? - "2 (Larger than any link state path)" : "1"); - vty_out (vty, " TOS: 0\n"); - vty_out (vty, " Metric: %d\n", - GET_METRIC (al->e[0].metric)); - vty_out (vty, " NSSA: Forward Address: %s\n", - inet_ntoa (al->e[0].fwd_addr)); - - vty_out (vty, " External Route Tag: %"ROUTE_TAG_PRI"\n\n", - (route_tag_t)ntohl (al->e[0].route_tag)); - } +static int show_as_nssa_lsa_detail(struct vty *vty, struct ospf_lsa *lsa) +{ + if (lsa != NULL) { + struct as_external_lsa *al = + (struct as_external_lsa *)lsa->data; + + show_ip_ospf_database_header(vty, lsa); + + vty_out(vty, " Network Mask: /%d\n", ip_masklen(al->mask)); + vty_out(vty, " Metric Type: %s\n", + IS_EXTERNAL_METRIC(al->e[0].tos) + ? "2 (Larger than any link state path)" + : "1"); + vty_out(vty, " TOS: 0\n"); + vty_out(vty, " Metric: %d\n", + GET_METRIC(al->e[0].metric)); + vty_out(vty, " NSSA: Forward Address: %s\n", + inet_ntoa(al->e[0].fwd_addr)); + + vty_out(vty, + " External Route Tag: %" ROUTE_TAG_PRI "\n\n", + (route_tag_t)ntohl(al->e[0].route_tag)); + } - return 0; + return 0; } -static int -show_func_dummy (struct vty *vty, struct ospf_lsa *lsa) +static int show_func_dummy(struct vty *vty, struct ospf_lsa *lsa) { - return 0; + return 0; } -static int -show_opaque_lsa_detail (struct vty *vty, struct ospf_lsa *lsa) +static int show_opaque_lsa_detail(struct vty *vty, struct ospf_lsa *lsa) { - if (lsa != NULL) - { - show_ip_ospf_database_header (vty, lsa); - show_opaque_info_detail (vty, lsa); + if (lsa != NULL) { + show_ip_ospf_database_header(vty, lsa); + show_opaque_info_detail(vty, lsa); - vty_out (vty, "\n"); - } - return 0; + vty_out(vty, "\n"); + } + return 0; +} + +int (*show_function[])(struct vty *, struct ospf_lsa *) = { + NULL, + show_router_lsa_detail, + show_network_lsa_detail, + show_summary_lsa_detail, + show_summary_asbr_lsa_detail, + show_as_external_lsa_detail, + show_func_dummy, + show_as_nssa_lsa_detail, /* almost same as external */ + NULL, /* type-8 */ + show_opaque_lsa_detail, + show_opaque_lsa_detail, + show_opaque_lsa_detail, +}; + +static void show_lsa_prefix_set(struct vty *vty, struct prefix_ls *lp, + struct in_addr *id, struct in_addr *adv_router) +{ + memset(lp, 0, sizeof(struct prefix_ls)); + lp->family = 0; + if (id == NULL) + lp->prefixlen = 0; + else if (adv_router == NULL) { + lp->prefixlen = 32; + lp->id = *id; + } else { + lp->prefixlen = 64; + lp->id = *id; + lp->adv_router = *adv_router; + } } -int (*show_function[])(struct vty *, struct ospf_lsa *) = -{ - NULL, - show_router_lsa_detail, - show_network_lsa_detail, - show_summary_lsa_detail, - show_summary_asbr_lsa_detail, - show_as_external_lsa_detail, - show_func_dummy, - show_as_nssa_lsa_detail, /* almost same as external */ - NULL, /* type-8 */ - show_opaque_lsa_detail, - show_opaque_lsa_detail, - show_opaque_lsa_detail, -}; +static void show_lsa_detail_proc(struct vty *vty, struct route_table *rt, + struct in_addr *id, struct in_addr *adv_router) +{ + struct prefix_ls lp; + struct route_node *rn, *start; + struct ospf_lsa *lsa; -static void -show_lsa_prefix_set (struct vty *vty, struct prefix_ls *lp, struct in_addr *id, - struct in_addr *adv_router) -{ - memset (lp, 0, sizeof (struct prefix_ls)); - lp->family = 0; - if (id == NULL) - lp->prefixlen = 0; - else if (adv_router == NULL) - { - lp->prefixlen = 32; - lp->id = *id; - } - else - { - lp->prefixlen = 64; - lp->id = *id; - lp->adv_router = *adv_router; - } -} - -static void -show_lsa_detail_proc (struct vty *vty, struct route_table *rt, - struct in_addr *id, struct in_addr *adv_router) -{ - struct prefix_ls lp; - struct route_node *rn, *start; - struct ospf_lsa *lsa; - - show_lsa_prefix_set (vty, &lp, id, adv_router); - start = route_node_get (rt, (struct prefix *) &lp); - if (start) - { - route_lock_node (start); - for (rn = start; rn; rn = route_next_until (rn, start)) - if ((lsa = rn->info)) - { - if (show_function[lsa->data->type] != NULL) - show_function[lsa->data->type] (vty, lsa); - } - route_unlock_node (start); - } + show_lsa_prefix_set(vty, &lp, id, adv_router); + start = route_node_get(rt, (struct prefix *)&lp); + if (start) { + route_lock_node(start); + for (rn = start; rn; rn = route_next_until(rn, start)) + if ((lsa = rn->info)) { + if (show_function[lsa->data->type] != NULL) + show_function[lsa->data->type](vty, + lsa); + } + route_unlock_node(start); + } } /* Show detail LSA information -- if id is NULL then show all LSAs. */ -static void -show_lsa_detail (struct vty *vty, struct ospf *ospf, int type, - struct in_addr *id, struct in_addr *adv_router) -{ - struct listnode *node; - struct ospf_area *area; - - switch (type) - { - case OSPF_AS_EXTERNAL_LSA: - case OSPF_OPAQUE_AS_LSA: - vty_out (vty, " %s \n\n", - show_database_desc[type]); - show_lsa_detail_proc (vty, AS_LSDB (ospf, type), id, adv_router); - break; - default: - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - vty_out (vty, "\n %s (Area %s)\n\n", show_database_desc[type], - ospf_area_desc_string (area)); - show_lsa_detail_proc (vty, AREA_LSDB (area, type), id, adv_router); - } - break; - } -} - -static void -show_lsa_detail_adv_router_proc (struct vty *vty, struct route_table *rt, - struct in_addr *adv_router) -{ - struct route_node *rn; - struct ospf_lsa *lsa; - - for (rn = route_top (rt); rn; rn = route_next (rn)) - if ((lsa = rn->info)) - if (IPV4_ADDR_SAME (adv_router, &lsa->data->adv_router)) - { - if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)) - continue; - if (show_function[lsa->data->type] != NULL) - show_function[lsa->data->type] (vty, lsa); +static void show_lsa_detail(struct vty *vty, struct ospf *ospf, int type, + struct in_addr *id, struct in_addr *adv_router) +{ + struct listnode *node; + struct ospf_area *area; + + switch (type) { + case OSPF_AS_EXTERNAL_LSA: + case OSPF_OPAQUE_AS_LSA: + vty_out(vty, " %s \n\n", + show_database_desc[type]); + show_lsa_detail_proc(vty, AS_LSDB(ospf, type), id, adv_router); + break; + default: + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + vty_out(vty, "\n %s (Area %s)\n\n", + show_database_desc[type], + ospf_area_desc_string(area)); + show_lsa_detail_proc(vty, AREA_LSDB(area, type), id, + adv_router); + } + break; } } +static void show_lsa_detail_adv_router_proc(struct vty *vty, + struct route_table *rt, + struct in_addr *adv_router) +{ + struct route_node *rn; + struct ospf_lsa *lsa; + + for (rn = route_top(rt); rn; rn = route_next(rn)) + if ((lsa = rn->info)) + if (IPV4_ADDR_SAME(adv_router, + &lsa->data->adv_router)) { + if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT)) + continue; + if (show_function[lsa->data->type] != NULL) + show_function[lsa->data->type](vty, + lsa); + } +} + /* Show detail LSA information. */ -static void -show_lsa_detail_adv_router (struct vty *vty, struct ospf *ospf, int type, - struct in_addr *adv_router) -{ - struct listnode *node; - struct ospf_area *area; - - switch (type) - { - case OSPF_AS_EXTERNAL_LSA: - case OSPF_OPAQUE_AS_LSA: - vty_out (vty, " %s \n\n", - show_database_desc[type]); - show_lsa_detail_adv_router_proc (vty, AS_LSDB (ospf, type), - adv_router); - break; - default: - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - vty_out (vty, "\n %s (Area %s)\n\n", show_database_desc[type], - ospf_area_desc_string (area)); - show_lsa_detail_adv_router_proc (vty, AREA_LSDB (area, type), - adv_router); - } - break; - } -} - -static void -show_ip_ospf_database_summary (struct vty *vty, struct ospf *ospf, int self) -{ - struct ospf_lsa *lsa; - struct route_node *rn; - struct ospf_area *area; - struct listnode *node; - int type; - - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - for (type = OSPF_MIN_LSA; type < OSPF_MAX_LSA; type++) - { - switch (type) - { - case OSPF_AS_EXTERNAL_LSA: - case OSPF_OPAQUE_AS_LSA: - continue; - default: - break; - } - if (ospf_lsdb_count_self (area->lsdb, type) > 0 || - (!self && ospf_lsdb_count (area->lsdb, type) > 0)) - { - vty_out (vty, " %s (Area %s)\n\n", - show_database_desc[type], - ospf_area_desc_string (area)); - vty_out (vty, "%s\n", show_database_header[type]); - - LSDB_LOOP (AREA_LSDB (area, type), rn, lsa) - show_lsa_summary (vty, lsa, self); - - vty_out (vty, "\n"); - } - } - } - - for (type = OSPF_MIN_LSA; type < OSPF_MAX_LSA; type++) - { - switch (type) - { - case OSPF_AS_EXTERNAL_LSA: - case OSPF_OPAQUE_AS_LSA: - break; - default: - continue; - } - if (ospf_lsdb_count_self (ospf->lsdb, type) || - (!self && ospf_lsdb_count (ospf->lsdb, type))) - { - vty_out (vty, " %s\n\n", - show_database_desc[type]); - vty_out (vty, "%s\n", show_database_header[type]); - - LSDB_LOOP (AS_LSDB (ospf, type), rn, lsa) - show_lsa_summary (vty, lsa, self); - - vty_out (vty, "\n"); - } - } - - vty_out (vty, "\n"); -} - -static void -show_ip_ospf_database_maxage (struct vty *vty, struct ospf *ospf) -{ - struct route_node *rn; - - vty_out (vty, "\n MaxAge Link States:\n\n"); - - for (rn = route_top (ospf->maxage_lsa); rn; rn = route_next (rn)) - { - struct ospf_lsa *lsa; - - if ((lsa = rn->info) != NULL) - { - vty_out (vty, "Link type: %d\n", lsa->data->type); - vty_out (vty, "Link State ID: %s\n", - inet_ntoa (lsa->data->id)); - vty_out (vty, "Advertising Router: %s\n", - inet_ntoa (lsa->data->adv_router)); - vty_out (vty, "LSA lock count: %d\n", lsa->lock); - vty_out (vty, "\n"); +static void show_lsa_detail_adv_router(struct vty *vty, struct ospf *ospf, + int type, struct in_addr *adv_router) +{ + struct listnode *node; + struct ospf_area *area; + + switch (type) { + case OSPF_AS_EXTERNAL_LSA: + case OSPF_OPAQUE_AS_LSA: + vty_out(vty, " %s \n\n", + show_database_desc[type]); + show_lsa_detail_adv_router_proc(vty, AS_LSDB(ospf, type), + adv_router); + break; + default: + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + vty_out(vty, "\n %s (Area %s)\n\n", + show_database_desc[type], + ospf_area_desc_string(area)); + show_lsa_detail_adv_router_proc( + vty, AREA_LSDB(area, type), adv_router); + } + break; + } +} + +static void show_ip_ospf_database_summary(struct vty *vty, struct ospf *ospf, + int self) +{ + struct ospf_lsa *lsa; + struct route_node *rn; + struct ospf_area *area; + struct listnode *node; + int type; + + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + for (type = OSPF_MIN_LSA; type < OSPF_MAX_LSA; type++) { + switch (type) { + case OSPF_AS_EXTERNAL_LSA: + case OSPF_OPAQUE_AS_LSA: + continue; + default: + break; + } + if (ospf_lsdb_count_self(area->lsdb, type) > 0 + || (!self + && ospf_lsdb_count(area->lsdb, type) > 0)) { + vty_out(vty, " %s (Area %s)\n\n", + show_database_desc[type], + ospf_area_desc_string(area)); + vty_out(vty, "%s\n", + show_database_header[type]); + + LSDB_LOOP(AREA_LSDB(area, type), rn, lsa) + show_lsa_summary(vty, lsa, self); + + vty_out(vty, "\n"); + } + } + } + + for (type = OSPF_MIN_LSA; type < OSPF_MAX_LSA; type++) { + switch (type) { + case OSPF_AS_EXTERNAL_LSA: + case OSPF_OPAQUE_AS_LSA: + break; + default: + continue; + } + if (ospf_lsdb_count_self(ospf->lsdb, type) + || (!self && ospf_lsdb_count(ospf->lsdb, type))) { + vty_out(vty, " %s\n\n", + show_database_desc[type]); + vty_out(vty, "%s\n", show_database_header[type]); + + LSDB_LOOP(AS_LSDB(ospf, type), rn, lsa) + show_lsa_summary(vty, lsa, self); + + vty_out(vty, "\n"); + } + } + + vty_out(vty, "\n"); +} + +static void show_ip_ospf_database_maxage(struct vty *vty, struct ospf *ospf) +{ + struct route_node *rn; + + vty_out(vty, "\n MaxAge Link States:\n\n"); + + for (rn = route_top(ospf->maxage_lsa); rn; rn = route_next(rn)) { + struct ospf_lsa *lsa; + + if ((lsa = rn->info) != NULL) { + vty_out(vty, "Link type: %d\n", lsa->data->type); + vty_out(vty, "Link State ID: %s\n", + inet_ntoa(lsa->data->id)); + vty_out(vty, "Advertising Router: %s\n", + inet_ntoa(lsa->data->adv_router)); + vty_out(vty, "LSA lock count: %d\n", lsa->lock); + vty_out(vty, "\n"); + } } - } } #define OSPF_LSA_TYPE_NSSA_DESC "NSSA external link state\n" @@ -5217,98 +5314,89 @@ show_ip_ospf_database_maxage (struct vty *vty, struct ospf *ospf) #define OSPF_LSA_TYPE_OPAQUE_AS_DESC "Link AS Opaque-LSA\n" #define OSPF_LSA_TYPE_OPAQUE_CMD_STR "|opaque-link|opaque-area|opaque-as" -#define OSPF_LSA_TYPES_DESC \ - "ASBR summary link states\n" \ - "External link states\n" \ - "Network link states\n" \ - "Router link states\n" \ - "Network summary link states\n" \ - OSPF_LSA_TYPE_NSSA_DESC \ - OSPF_LSA_TYPE_OPAQUE_LINK_DESC \ - OSPF_LSA_TYPE_OPAQUE_AREA_DESC \ - OSPF_LSA_TYPE_OPAQUE_AS_DESC +#define OSPF_LSA_TYPES_DESC \ + "ASBR summary link states\n" \ + "External link states\n" \ + "Network link states\n" \ + "Router link states\n" \ + "Network summary link states\n" OSPF_LSA_TYPE_NSSA_DESC \ + OSPF_LSA_TYPE_OPAQUE_LINK_DESC OSPF_LSA_TYPE_OPAQUE_AREA_DESC \ + OSPF_LSA_TYPE_OPAQUE_AS_DESC + +static int show_ip_ospf_database_common(struct vty *vty, struct ospf *ospf, + int arg_base, int argc, + struct cmd_token **argv) +{ + int idx_type = 4; + int type, ret; + struct in_addr id, adv_router; + + if (ospf->instance) + vty_out(vty, "\nOSPF Instance: %d\n", ospf->instance); + + vty_out(vty, "\n OSPF Router with ID (%s)\n\n", + inet_ntoa(ospf->router_id)); + + /* Show all LSA. */ + if (argc == arg_base + 4) { + show_ip_ospf_database_summary(vty, ospf, 0); + return CMD_SUCCESS; + } -static int -show_ip_ospf_database_common (struct vty *vty, struct ospf *ospf, - int arg_base, int argc, struct cmd_token **argv) -{ - int idx_type = 4; - int type, ret; - struct in_addr id, adv_router; - - if (ospf->instance) - vty_out (vty, "\nOSPF Instance: %d\n", ospf->instance); - - vty_out (vty, "\n OSPF Router with ID (%s)\n\n", - inet_ntoa (ospf->router_id)); - - /* Show all LSA. */ - if (argc == arg_base + 4) - { - show_ip_ospf_database_summary (vty, ospf, 0); - return CMD_SUCCESS; - } - - /* Set database type to show. */ - if (strncmp (argv[arg_base + idx_type]->text, "r", 1) == 0) - type = OSPF_ROUTER_LSA; - else if (strncmp (argv[arg_base + idx_type]->text, "ne", 2) == 0) - type = OSPF_NETWORK_LSA; - else if (strncmp (argv[arg_base + idx_type]->text, "ns", 2) == 0) - type = OSPF_AS_NSSA_LSA; - else if (strncmp (argv[arg_base + idx_type]->text, "su", 2) == 0) - type = OSPF_SUMMARY_LSA; - else if (strncmp (argv[arg_base + idx_type]->text, "a", 1) == 0) - type = OSPF_ASBR_SUMMARY_LSA; - else if (strncmp (argv[arg_base + idx_type]->text, "e", 1) == 0) - type = OSPF_AS_EXTERNAL_LSA; - else if (strncmp (argv[arg_base + idx_type]->text, "se", 2) == 0) - { - show_ip_ospf_database_summary (vty, ospf, 1); - return CMD_SUCCESS; - } - else if (strncmp (argv[arg_base + idx_type]->text, "m", 1) == 0) - { - show_ip_ospf_database_maxage (vty, ospf); - return CMD_SUCCESS; - } - else if (strncmp (argv[arg_base + idx_type]->text, "opaque-l", 8) == 0) - type = OSPF_OPAQUE_LINK_LSA; - else if (strncmp (argv[arg_base + idx_type]->text, "opaque-ar", 9) == 0) - type = OSPF_OPAQUE_AREA_LSA; - else if (strncmp (argv[arg_base + idx_type]->text, "opaque-as", 9) == 0) - type = OSPF_OPAQUE_AS_LSA; - else - return CMD_WARNING; - - /* `show ip ospf database LSA'. */ - if (argc == arg_base + 5) - show_lsa_detail (vty, ospf, type, NULL, NULL); - else if (argc >= arg_base + 6) - { - ret = inet_aton (argv[arg_base + 5]->arg, &id); - if (!ret) - return CMD_WARNING; - - /* `show ip ospf database LSA ID'. */ - if (argc == arg_base + 6) - show_lsa_detail (vty, ospf, type, &id, NULL); - /* `show ip ospf database LSA ID adv-router ADV_ROUTER'. */ - else if (argc == arg_base + 7) - { - if (strncmp (argv[arg_base + 6]->text, "s", 1) == 0) - adv_router = ospf->router_id; - else - { - ret = inet_aton (argv[arg_base + 7]->arg, &adv_router); - if (!ret) + /* Set database type to show. */ + if (strncmp(argv[arg_base + idx_type]->text, "r", 1) == 0) + type = OSPF_ROUTER_LSA; + else if (strncmp(argv[arg_base + idx_type]->text, "ne", 2) == 0) + type = OSPF_NETWORK_LSA; + else if (strncmp(argv[arg_base + idx_type]->text, "ns", 2) == 0) + type = OSPF_AS_NSSA_LSA; + else if (strncmp(argv[arg_base + idx_type]->text, "su", 2) == 0) + type = OSPF_SUMMARY_LSA; + else if (strncmp(argv[arg_base + idx_type]->text, "a", 1) == 0) + type = OSPF_ASBR_SUMMARY_LSA; + else if (strncmp(argv[arg_base + idx_type]->text, "e", 1) == 0) + type = OSPF_AS_EXTERNAL_LSA; + else if (strncmp(argv[arg_base + idx_type]->text, "se", 2) == 0) { + show_ip_ospf_database_summary(vty, ospf, 1); + return CMD_SUCCESS; + } else if (strncmp(argv[arg_base + idx_type]->text, "m", 1) == 0) { + show_ip_ospf_database_maxage(vty, ospf); + return CMD_SUCCESS; + } else if (strncmp(argv[arg_base + idx_type]->text, "opaque-l", 8) == 0) + type = OSPF_OPAQUE_LINK_LSA; + else if (strncmp(argv[arg_base + idx_type]->text, "opaque-ar", 9) == 0) + type = OSPF_OPAQUE_AREA_LSA; + else if (strncmp(argv[arg_base + idx_type]->text, "opaque-as", 9) == 0) + type = OSPF_OPAQUE_AS_LSA; + else return CMD_WARNING; - } - show_lsa_detail (vty, ospf, type, &id, &adv_router); + + /* `show ip ospf database LSA'. */ + if (argc == arg_base + 5) + show_lsa_detail(vty, ospf, type, NULL, NULL); + else if (argc >= arg_base + 6) { + ret = inet_aton(argv[arg_base + 5]->arg, &id); + if (!ret) + return CMD_WARNING; + + /* `show ip ospf database LSA ID'. */ + if (argc == arg_base + 6) + show_lsa_detail(vty, ospf, type, &id, NULL); + /* `show ip ospf database LSA ID adv-router ADV_ROUTER'. */ + else if (argc == arg_base + 7) { + if (strncmp(argv[arg_base + 6]->text, "s", 1) == 0) + adv_router = ospf->router_id; + else { + ret = inet_aton(argv[arg_base + 7]->arg, + &adv_router); + if (!ret) + return CMD_WARNING; + } + show_lsa_detail(vty, ospf, type, &id, &adv_router); + } } - } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (show_ip_ospf_database_max, @@ -5321,12 +5409,12 @@ DEFUN (show_ip_ospf_database_max, "LSAs in MaxAge list\n" "Self-originated link states\n") { - struct ospf *ospf; + struct ospf *ospf; - if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) + return CMD_SUCCESS; - return (show_ip_ospf_database_common(vty, ospf, 0, argc, argv)); + return (show_ip_ospf_database_common(vty, ospf, 0, argc, argv)); } DEFUN (show_ip_ospf_instance_database, @@ -5343,23 +5431,22 @@ DEFUN (show_ip_ospf_instance_database, "Advertising Router link states\n" "Advertising Router (as an IP address)\n") { - struct ospf *ospf; - u_short instance = 0; + struct ospf *ospf; + u_short instance = 0; - int idx = 0; - if (argv_find (argv, argc, "(1-65535)", &idx)) - { - instance = strtoul(argv[idx]->arg, NULL, 10); - ospf = ospf_lookup_instance (instance); - } - else { - ospf = ospf_lookup(); - } + int idx = 0; + if (argv_find(argv, argc, "(1-65535)", &idx)) { + instance = strtoul(argv[idx]->arg, NULL, 10); + ospf = ospf_lookup_instance(instance); + } else { + ospf = ospf_lookup(); + } - if (!ospf || !ospf->oi_running) - return CMD_SUCCESS; + if (!ospf || !ospf->oi_running) + return CMD_SUCCESS; - return (show_ip_ospf_database_common(vty, ospf, idx ? 1 : 0, argc, argv)); + return (show_ip_ospf_database_common(vty, ospf, idx ? 1 : 0, argc, + argv)); } DEFUN (show_ip_ospf_instance_database_max, @@ -5373,68 +5460,69 @@ DEFUN (show_ip_ospf_instance_database_max, "LSAs in MaxAge list\n" "Self-originated link states\n") { - int idx_number = 3; - struct ospf *ospf; - u_short instance = 0; - - instance = strtoul(argv[idx_number]->arg, NULL, 10); - - if ((ospf = ospf_lookup_instance (instance)) == NULL || !ospf->oi_running) - return CMD_SUCCESS; - - return (show_ip_ospf_database_common(vty, ospf, 1, argc, argv)); -} + int idx_number = 3; + struct ospf *ospf; + u_short instance = 0; + + instance = strtoul(argv[idx_number]->arg, NULL, 10); + + if ((ospf = ospf_lookup_instance(instance)) == NULL + || !ospf->oi_running) + return CMD_SUCCESS; + + return (show_ip_ospf_database_common(vty, ospf, 1, argc, argv)); +} + + +static int show_ip_ospf_database_type_adv_router_common(struct vty *vty, + struct ospf *ospf, + int arg_base, int argc, + struct cmd_token **argv) +{ + int idx_type = 4; + int type, ret; + struct in_addr adv_router; + + if (ospf->instance) + vty_out(vty, "\nOSPF Instance: %d\n", ospf->instance); + + vty_out(vty, "\n OSPF Router with ID (%s)\n\n", + inet_ntoa(ospf->router_id)); + + /* Set database type to show. */ + if (strncmp(argv[arg_base + idx_type]->text, "r", 1) == 0) + type = OSPF_ROUTER_LSA; + else if (strncmp(argv[arg_base + idx_type]->text, "ne", 2) == 0) + type = OSPF_NETWORK_LSA; + else if (strncmp(argv[arg_base + idx_type]->text, "ns", 2) == 0) + type = OSPF_AS_NSSA_LSA; + else if (strncmp(argv[arg_base + idx_type]->text, "s", 1) == 0) + type = OSPF_SUMMARY_LSA; + else if (strncmp(argv[arg_base + idx_type]->text, "a", 1) == 0) + type = OSPF_ASBR_SUMMARY_LSA; + else if (strncmp(argv[arg_base + idx_type]->text, "e", 1) == 0) + type = OSPF_AS_EXTERNAL_LSA; + else if (strncmp(argv[arg_base + idx_type]->text, "opaque-l", 8) == 0) + type = OSPF_OPAQUE_LINK_LSA; + else if (strncmp(argv[arg_base + idx_type]->text, "opaque-ar", 9) == 0) + type = OSPF_OPAQUE_AREA_LSA; + else if (strncmp(argv[arg_base + idx_type]->text, "opaque-as", 9) == 0) + type = OSPF_OPAQUE_AS_LSA; + else + return CMD_WARNING; + /* `show ip ospf database LSA adv-router ADV_ROUTER'. */ + if (strncmp(argv[arg_base + 5]->text, "s", 1) == 0) + adv_router = ospf->router_id; + else { + ret = inet_aton(argv[arg_base + 6]->arg, &adv_router); + if (!ret) + return CMD_WARNING; + } -static int -show_ip_ospf_database_type_adv_router_common (struct vty *vty, struct ospf *ospf, - int arg_base, int argc, struct cmd_token **argv) -{ - int idx_type = 4; - int type, ret; - struct in_addr adv_router; - - if (ospf->instance) - vty_out (vty, "\nOSPF Instance: %d\n", ospf->instance); - - vty_out (vty, "\n OSPF Router with ID (%s)\n\n", - inet_ntoa (ospf->router_id)); - - /* Set database type to show. */ - if (strncmp (argv[arg_base + idx_type]->text, "r", 1) == 0) - type = OSPF_ROUTER_LSA; - else if (strncmp (argv[arg_base + idx_type]->text, "ne", 2) == 0) - type = OSPF_NETWORK_LSA; - else if (strncmp (argv[arg_base + idx_type]->text, "ns", 2) == 0) - type = OSPF_AS_NSSA_LSA; - else if (strncmp (argv[arg_base + idx_type]->text, "s", 1) == 0) - type = OSPF_SUMMARY_LSA; - else if (strncmp (argv[arg_base + idx_type]->text, "a", 1) == 0) - type = OSPF_ASBR_SUMMARY_LSA; - else if (strncmp (argv[arg_base + idx_type]->text, "e", 1) == 0) - type = OSPF_AS_EXTERNAL_LSA; - else if (strncmp (argv[arg_base + idx_type]->text, "opaque-l", 8) == 0) - type = OSPF_OPAQUE_LINK_LSA; - else if (strncmp (argv[arg_base + idx_type]->text, "opaque-ar", 9) == 0) - type = OSPF_OPAQUE_AREA_LSA; - else if (strncmp (argv[arg_base + idx_type]->text, "opaque-as", 9) == 0) - type = OSPF_OPAQUE_AS_LSA; - else - return CMD_WARNING; - - /* `show ip ospf database LSA adv-router ADV_ROUTER'. */ - if (strncmp (argv[arg_base + 5]->text, "s", 1) == 0) - adv_router = ospf->router_id; - else - { - ret = inet_aton (argv[arg_base + 6]->arg, &adv_router); - if (!ret) - return CMD_WARNING; - } - - show_lsa_detail_adv_router (vty, ospf, type, &adv_router); + show_lsa_detail_adv_router(vty, ospf, type, &adv_router); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (show_ip_ospf_instance_database_type_adv_router, @@ -5450,22 +5538,21 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router, "Advertising Router (as an IP address)\n" "Self-originated link states\n") { - struct ospf *ospf; - u_short instance = 0; - int idx = 0; + struct ospf *ospf; + u_short instance = 0; + int idx = 0; - if (argv_find(argv, argc, "(1-65535)", &idx)) - { - instance = strtoul(argv[idx]->arg, NULL, 10); - ospf = ospf_lookup_instance(instance); - } - else - ospf = ospf_lookup(); + if (argv_find(argv, argc, "(1-65535)", &idx)) { + instance = strtoul(argv[idx]->arg, NULL, 10); + ospf = ospf_lookup_instance(instance); + } else + ospf = ospf_lookup(); - if (!ospf || !ospf->oi_running) - return CMD_SUCCESS; + if (!ospf || !ospf->oi_running) + return CMD_SUCCESS; - return (show_ip_ospf_database_type_adv_router_common(vty, ospf, idx ? 1 : 0, argc, argv)); + return (show_ip_ospf_database_type_adv_router_common( + vty, ospf, idx ? 1 : 0, argc, argv)); } DEFUN (ip_ospf_authentication_args, @@ -5478,46 +5565,43 @@ DEFUN (ip_ospf_authentication_args, "Use message-digest authentication\n" "Address of interface\n") { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx_encryption = 3; - int idx_ipv4 = 4; - struct in_addr addr; - int ret; - struct ospf_if_params *params; - - params = IF_DEF_PARAMS (ifp); - - if (argc == 5) - { - ret = inet_aton(argv[idx_ipv4]->arg, &addr); - if (!ret) - { - vty_out (vty, "Please specify interface address by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx_encryption = 3; + int idx_ipv4 = 4; + struct in_addr addr; + int ret; + struct ospf_if_params *params; + + params = IF_DEF_PARAMS(ifp); + + if (argc == 5) { + ret = inet_aton(argv[idx_ipv4]->arg, &addr); + if (!ret) { + vty_out(vty, + "Please specify interface address by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } - params = ospf_get_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - } + params = ospf_get_if_params(ifp, addr); + ospf_if_update_params(ifp, addr); + } - /* Handle null authentication */ - if ( argv[idx_encryption]->arg[0] == 'n' ) - { - SET_IF_PARAM (params, auth_type); - params->auth_type = OSPF_AUTH_NULL; - return CMD_SUCCESS; - } + /* Handle null authentication */ + if (argv[idx_encryption]->arg[0] == 'n') { + SET_IF_PARAM(params, auth_type); + params->auth_type = OSPF_AUTH_NULL; + return CMD_SUCCESS; + } - /* Handle message-digest authentication */ - if ( argv[idx_encryption]->arg[0] == 'm' ) - { - SET_IF_PARAM (params, auth_type); - params->auth_type = OSPF_AUTH_CRYPTOGRAPHIC; - return CMD_SUCCESS; - } + /* Handle message-digest authentication */ + if (argv[idx_encryption]->arg[0] == 'm') { + SET_IF_PARAM(params, auth_type); + params->auth_type = OSPF_AUTH_CRYPTOGRAPHIC; + return CMD_SUCCESS; + } - vty_out (vty, "You shouldn't get here!\n"); - return CMD_WARNING_CONFIG_FAILED; + vty_out(vty, "You shouldn't get here!\n"); + return CMD_WARNING_CONFIG_FAILED; } DEFUN (ip_ospf_authentication, @@ -5528,31 +5612,30 @@ DEFUN (ip_ospf_authentication, "Enable authentication on this interface\n" "Address of interface") { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx_ipv4 = 3; - struct in_addr addr; - int ret; - struct ospf_if_params *params; - - params = IF_DEF_PARAMS (ifp); - - if (argc == 4) - { - ret = inet_aton(argv[idx_ipv4]->arg, &addr); - if (!ret) - { - vty_out (vty, "Please specify interface address by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx_ipv4 = 3; + struct in_addr addr; + int ret; + struct ospf_if_params *params; + + params = IF_DEF_PARAMS(ifp); + + if (argc == 4) { + ret = inet_aton(argv[idx_ipv4]->arg, &addr); + if (!ret) { + vty_out(vty, + "Please specify interface address by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + params = ospf_get_if_params(ifp, addr); + ospf_if_update_params(ifp, addr); } - params = ospf_get_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - } - - SET_IF_PARAM (params, auth_type); - params->auth_type = OSPF_AUTH_SIMPLE; + SET_IF_PARAM(params, auth_type); + params->auth_type = OSPF_AUTH_SIMPLE; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ip_ospf_authentication_args, @@ -5566,86 +5649,75 @@ DEFUN (no_ip_ospf_authentication_args, "Use message-digest authentication\n" "Address of interface") { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx_encryption = 4; - int idx_ipv4 = 5; - struct in_addr addr; - int ret; - struct ospf_if_params *params; - struct route_node *rn; - int auth_type; - - params = IF_DEF_PARAMS (ifp); - - if (argc == 6) - { - ret = inet_aton(argv[idx_ipv4]->arg, &addr); - if (!ret) - { - vty_out (vty, "Please specify interface address by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx_encryption = 4; + int idx_ipv4 = 5; + struct in_addr addr; + int ret; + struct ospf_if_params *params; + struct route_node *rn; + int auth_type; + + params = IF_DEF_PARAMS(ifp); + + if (argc == 6) { + ret = inet_aton(argv[idx_ipv4]->arg, &addr); + if (!ret) { + vty_out(vty, + "Please specify interface address by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } - params = ospf_lookup_if_params (ifp, addr); - if (params == NULL) - { - vty_out (vty, "Ip Address specified is unknown\n"); - return CMD_WARNING_CONFIG_FAILED; - } - params->auth_type = OSPF_AUTH_NOTSET; - UNSET_IF_PARAM (params, auth_type); - if (params != IF_DEF_PARAMS (ifp)) - { - ospf_free_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - } - } - else - { - if ( argv[idx_encryption]->arg[0] == 'n' ) - { - auth_type = OSPF_AUTH_NULL; - } - else if ( argv[idx_encryption]->arg[0] == 'm' ) - { - auth_type = OSPF_AUTH_CRYPTOGRAPHIC; - } - else - { - vty_out (vty, "Unexpected input encountered\n"); - return CMD_WARNING_CONFIG_FAILED; - } - /* - * Here we have a case where the user has entered - * 'no ip ospf authentication (null | message_digest )' - * we need to find if we have any ip addresses underneath it that - * correspond to the associated type. - */ - if (params->auth_type == auth_type) - { - params->auth_type = OSPF_AUTH_NOTSET; - UNSET_IF_PARAM (params, auth_type); - } - - for (rn = route_top (IF_OIFS_PARAMS (ifp)); rn; rn = route_next (rn)) - { - if ((params = rn->info)) - { - if (params->auth_type == auth_type) - { - params->auth_type = OSPF_AUTH_NOTSET; - UNSET_IF_PARAM (params, auth_type); - if (params != IF_DEF_PARAMS (ifp)) - { - ospf_free_if_params (ifp, rn->p.u.prefix4); - ospf_if_update_params(ifp, rn->p.u.prefix4); - } + params = ospf_lookup_if_params(ifp, addr); + if (params == NULL) { + vty_out(vty, "Ip Address specified is unknown\n"); + return CMD_WARNING_CONFIG_FAILED; + } + params->auth_type = OSPF_AUTH_NOTSET; + UNSET_IF_PARAM(params, auth_type); + if (params != IF_DEF_PARAMS(ifp)) { + ospf_free_if_params(ifp, addr); + ospf_if_update_params(ifp, addr); + } + } else { + if (argv[idx_encryption]->arg[0] == 'n') { + auth_type = OSPF_AUTH_NULL; + } else if (argv[idx_encryption]->arg[0] == 'm') { + auth_type = OSPF_AUTH_CRYPTOGRAPHIC; + } else { + vty_out(vty, "Unexpected input encountered\n"); + return CMD_WARNING_CONFIG_FAILED; + } + /* + * Here we have a case where the user has entered + * 'no ip ospf authentication (null | message_digest )' + * we need to find if we have any ip addresses underneath it + * that + * correspond to the associated type. + */ + if (params->auth_type == auth_type) { + params->auth_type = OSPF_AUTH_NOTSET; + UNSET_IF_PARAM(params, auth_type); + } + + for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; + rn = route_next(rn)) { + if ((params = rn->info)) { + if (params->auth_type == auth_type) { + params->auth_type = OSPF_AUTH_NOTSET; + UNSET_IF_PARAM(params, auth_type); + if (params != IF_DEF_PARAMS(ifp)) { + ospf_free_if_params( + ifp, rn->p.u.prefix4); + ospf_if_update_params( + ifp, rn->p.u.prefix4); + } + } + } } - } } - } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ip_ospf_authentication, @@ -5657,76 +5729,71 @@ DEFUN (no_ip_ospf_authentication, "Enable authentication on this interface\n" "Address of interface") { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx_ipv4 = 4; - struct in_addr addr; - int ret; - struct ospf_if_params *params; - struct route_node *rn; - - params = IF_DEF_PARAMS (ifp); - - if (argc == 5) - { - ret = inet_aton(argv[idx_ipv4]->arg, &addr); - if (!ret) - { - vty_out (vty, "Please specify interface address by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx_ipv4 = 4; + struct in_addr addr; + int ret; + struct ospf_if_params *params; + struct route_node *rn; + + params = IF_DEF_PARAMS(ifp); + + if (argc == 5) { + ret = inet_aton(argv[idx_ipv4]->arg, &addr); + if (!ret) { + vty_out(vty, + "Please specify interface address by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } - params = ospf_lookup_if_params (ifp, addr); - if (params == NULL) - { - vty_out (vty, "Ip Address specified is unknown\n"); - return CMD_WARNING_CONFIG_FAILED; - } + params = ospf_lookup_if_params(ifp, addr); + if (params == NULL) { + vty_out(vty, "Ip Address specified is unknown\n"); + return CMD_WARNING_CONFIG_FAILED; + } - params->auth_type = OSPF_AUTH_NOTSET; - UNSET_IF_PARAM (params, auth_type); - if (params != IF_DEF_PARAMS (ifp)) - { - ospf_free_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - } - } - else - { - /* - * When a user enters 'no ip ospf authentication' - * We should remove all authentication types from - * the interface. - */ - if ((params->auth_type == OSPF_AUTH_NULL) || - (params->auth_type == OSPF_AUTH_CRYPTOGRAPHIC) || - (params->auth_type == OSPF_AUTH_SIMPLE)) - { - params->auth_type = OSPF_AUTH_NOTSET; - UNSET_IF_PARAM (params, auth_type); - } - - for (rn = route_top (IF_OIFS_PARAMS (ifp)); rn; rn = route_next (rn)) - { - if ((params = rn->info)) - { + params->auth_type = OSPF_AUTH_NOTSET; + UNSET_IF_PARAM(params, auth_type); + if (params != IF_DEF_PARAMS(ifp)) { + ospf_free_if_params(ifp, addr); + ospf_if_update_params(ifp, addr); + } + } else { + /* + * When a user enters 'no ip ospf authentication' + * We should remove all authentication types from + * the interface. + */ + if ((params->auth_type == OSPF_AUTH_NULL) + || (params->auth_type == OSPF_AUTH_CRYPTOGRAPHIC) + || (params->auth_type == OSPF_AUTH_SIMPLE)) { + params->auth_type = OSPF_AUTH_NOTSET; + UNSET_IF_PARAM(params, auth_type); + } - if ((params->auth_type == OSPF_AUTH_NULL) || - (params->auth_type == OSPF_AUTH_CRYPTOGRAPHIC) || - (params->auth_type == OSPF_AUTH_SIMPLE)) - { - params->auth_type = OSPF_AUTH_NOTSET; - UNSET_IF_PARAM (params, auth_type); - if (params != IF_DEF_PARAMS (ifp)) - { - ospf_free_if_params (ifp, rn->p.u.prefix4); - ospf_if_update_params(ifp, rn->p.u.prefix4); - } + for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; + rn = route_next(rn)) { + if ((params = rn->info)) { + + if ((params->auth_type == OSPF_AUTH_NULL) + || (params->auth_type + == OSPF_AUTH_CRYPTOGRAPHIC) + || (params->auth_type + == OSPF_AUTH_SIMPLE)) { + params->auth_type = OSPF_AUTH_NOTSET; + UNSET_IF_PARAM(params, auth_type); + if (params != IF_DEF_PARAMS(ifp)) { + ospf_free_if_params( + ifp, rn->p.u.prefix4); + ospf_if_update_params( + ifp, rn->p.u.prefix4); + } + } + } } - } } - } - - return CMD_SUCCESS; + + return CMD_SUCCESS; } @@ -5739,30 +5806,30 @@ DEFUN (ip_ospf_authentication_key, "The OSPF password (key)\n" "Address of interface") { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx = 0; - struct in_addr addr; - struct ospf_if_params *params; - - params = IF_DEF_PARAMS (ifp); + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx = 0; + struct in_addr addr; + struct ospf_if_params *params; - if (argv_find (argv, argc, "A.B.C.D", &idx)) - { - if (!inet_aton(argv[idx]->arg, &addr)) - { - vty_out (vty, "Please specify interface address by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; - } + params = IF_DEF_PARAMS(ifp); - params = ospf_get_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - } + if (argv_find(argv, argc, "A.B.C.D", &idx)) { + if (!inet_aton(argv[idx]->arg, &addr)) { + vty_out(vty, + "Please specify interface address by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } - memset (params->auth_simple, 0, OSPF_AUTH_SIMPLE_SIZE + 1); - strncpy ((char *) params->auth_simple, argv[3]->arg, OSPF_AUTH_SIMPLE_SIZE); - SET_IF_PARAM (params, auth_simple); + params = ospf_get_if_params(ifp, addr); + ospf_if_update_params(ifp, addr); + } - return CMD_SUCCESS; + memset(params->auth_simple, 0, OSPF_AUTH_SIMPLE_SIZE + 1); + strncpy((char *)params->auth_simple, argv[3]->arg, + OSPF_AUTH_SIMPLE_SIZE); + SET_IF_PARAM(params, auth_simple); + + return CMD_SUCCESS; } DEFUN_HIDDEN (ospf_authentication_key, @@ -5773,7 +5840,7 @@ DEFUN_HIDDEN (ospf_authentication_key, "The OSPF password (key)\n" "Address of interface\n") { - return ip_ospf_authentication_key (self, vty, argc, argv); + return ip_ospf_authentication_key(self, vty, argc, argv); } DEFUN (no_ip_ospf_authentication_key, @@ -5785,35 +5852,33 @@ DEFUN (no_ip_ospf_authentication_key, "Authentication password (key)\n" "The OSPF password (key)") { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx = 0; - struct in_addr addr; - struct ospf_if_params *params; - params = IF_DEF_PARAMS (ifp); + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx = 0; + struct in_addr addr; + struct ospf_if_params *params; + params = IF_DEF_PARAMS(ifp); + + if (argv_find(argv, argc, "A.B.C.D", &idx)) { + if (!inet_aton(argv[idx]->arg, &addr)) { + vty_out(vty, + "Please specify interface address by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } - if (argv_find (argv, argc, "A.B.C.D", &idx)) - { - if (!inet_aton(argv[idx]->arg, &addr)) - { - vty_out (vty, "Please specify interface address by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; + params = ospf_lookup_if_params(ifp, addr); + if (params == NULL) + return CMD_SUCCESS; } - params = ospf_lookup_if_params (ifp, addr); - if (params == NULL) - return CMD_SUCCESS; - } - - memset (params->auth_simple, 0, OSPF_AUTH_SIMPLE_SIZE); - UNSET_IF_PARAM (params, auth_simple); + memset(params->auth_simple, 0, OSPF_AUTH_SIMPLE_SIZE); + UNSET_IF_PARAM(params, auth_simple); - if (params != IF_DEF_PARAMS (ifp)) - { - ospf_free_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - } + if (params != IF_DEF_PARAMS(ifp)) { + ospf_free_if_params(ifp, addr); + ospf_if_update_params(ifp, addr); + } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN_HIDDEN (no_ospf_authentication_key, @@ -5824,7 +5889,7 @@ DEFUN_HIDDEN (no_ospf_authentication_key, "Authentication password (key)\n" "The OSPF password (key)") { - return no_ip_ospf_authentication_key (self, vty, argc, argv); + return no_ip_ospf_authentication_key(self, vty, argc, argv); } DEFUN (ip_ospf_message_digest_key, @@ -5838,48 +5903,46 @@ DEFUN (ip_ospf_message_digest_key, "The OSPF password (key)\n" "Address of interface\n") { - VTY_DECLVAR_CONTEXT(interface, ifp); - struct crypt_key *ck; - u_char key_id; - struct in_addr addr; - struct ospf_if_params *params; - - params = IF_DEF_PARAMS (ifp); - int idx = 0; - - argv_find (argv, argc, "(1-255)", &idx); - char *keyid = argv[idx]->arg; - argv_find (argv, argc, "KEY", &idx); - char *cryptkey = argv[idx]->arg; - - if (argv_find (argv, argc, "A.B.C.D", &idx)) - { - if (!inet_aton(argv[idx]->arg, &addr)) - { - vty_out (vty, "Please specify interface address by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; + VTY_DECLVAR_CONTEXT(interface, ifp); + struct crypt_key *ck; + u_char key_id; + struct in_addr addr; + struct ospf_if_params *params; + + params = IF_DEF_PARAMS(ifp); + int idx = 0; + + argv_find(argv, argc, "(1-255)", &idx); + char *keyid = argv[idx]->arg; + argv_find(argv, argc, "KEY", &idx); + char *cryptkey = argv[idx]->arg; + + if (argv_find(argv, argc, "A.B.C.D", &idx)) { + if (!inet_aton(argv[idx]->arg, &addr)) { + vty_out(vty, + "Please specify interface address by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + params = ospf_get_if_params(ifp, addr); + ospf_if_update_params(ifp, addr); } - params = ospf_get_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - } + key_id = strtol(keyid, NULL, 10); + if (ospf_crypt_key_lookup(params->auth_crypt, key_id) != NULL) { + vty_out(vty, "OSPF: Key %d already exists\n", key_id); + return CMD_WARNING_CONFIG_FAILED; + } - key_id = strtol (keyid, NULL, 10); - if (ospf_crypt_key_lookup (params->auth_crypt, key_id) != NULL) - { - vty_out (vty, "OSPF: Key %d already exists\n", key_id); - return CMD_WARNING_CONFIG_FAILED; - } + ck = ospf_crypt_key_new(); + ck->key_id = (u_char)key_id; + memset(ck->auth_key, 0, OSPF_AUTH_MD5_SIZE + 1); + strncpy((char *)ck->auth_key, cryptkey, OSPF_AUTH_MD5_SIZE); - ck = ospf_crypt_key_new (); - ck->key_id = (u_char) key_id; - memset (ck->auth_key, 0, OSPF_AUTH_MD5_SIZE+1); - strncpy ((char *) ck->auth_key, cryptkey, OSPF_AUTH_MD5_SIZE); + ospf_crypt_key_add(params->auth_crypt, ck); + SET_IF_PARAM(params, auth_crypt); - ospf_crypt_key_add (params->auth_crypt, ck); - SET_IF_PARAM (params, auth_crypt); - - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN_HIDDEN (ospf_message_digest_key, @@ -5892,7 +5955,7 @@ DEFUN_HIDDEN (ospf_message_digest_key, "The OSPF password (key)\n" "Address of interface\n") { - return ip_ospf_message_digest_key (self, vty, argc, argv); + return ip_ospf_message_digest_key(self, vty, argc, argv); } DEFUN (no_ip_ospf_message_digest_key, @@ -5907,47 +5970,44 @@ DEFUN (no_ip_ospf_message_digest_key, "The OSPF password (key)\n" "Address of interface\n") { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx = 0; - struct crypt_key *ck; - int key_id; - struct in_addr addr; - struct ospf_if_params *params; - params = IF_DEF_PARAMS (ifp); - - argv_find (argv, argc, "(1-255)", &idx); - char *keyid = argv[idx]->arg; + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx = 0; + struct crypt_key *ck; + int key_id; + struct in_addr addr; + struct ospf_if_params *params; + params = IF_DEF_PARAMS(ifp); + + argv_find(argv, argc, "(1-255)", &idx); + char *keyid = argv[idx]->arg; + + if (argv_find(argv, argc, "A.B.C.D", &idx)) { + if (!inet_aton(argv[idx]->arg, &addr)) { + vty_out(vty, + "Please specify interface address by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } - if (argv_find (argv, argc, "A.B.C.D", &idx)) - { - if (!inet_aton(argv[idx]->arg, &addr)) - { - vty_out (vty, "Please specify interface address by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; + params = ospf_lookup_if_params(ifp, addr); + if (params == NULL) + return CMD_SUCCESS; } - params = ospf_lookup_if_params (ifp, addr); - if (params == NULL) - return CMD_SUCCESS; - } - - key_id = strtol (keyid, NULL, 10); - ck = ospf_crypt_key_lookup (params->auth_crypt, key_id); - if (ck == NULL) - { - vty_out (vty, "OSPF: Key %d does not exist\n", key_id); - return CMD_WARNING_CONFIG_FAILED; - } + key_id = strtol(keyid, NULL, 10); + ck = ospf_crypt_key_lookup(params->auth_crypt, key_id); + if (ck == NULL) { + vty_out(vty, "OSPF: Key %d does not exist\n", key_id); + return CMD_WARNING_CONFIG_FAILED; + } - ospf_crypt_key_delete (params->auth_crypt, key_id); + ospf_crypt_key_delete(params->auth_crypt, key_id); - if (params != IF_DEF_PARAMS (ifp)) - { - ospf_free_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - } + if (params != IF_DEF_PARAMS(ifp)) { + ospf_free_if_params(ifp, addr); + ospf_if_update_params(ifp, addr); + } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN_HIDDEN (no_ospf_message_digest_key, @@ -5959,7 +6019,7 @@ DEFUN_HIDDEN (no_ospf_message_digest_key, "Key ID\n" "Address of interface") { - return no_ip_ospf_message_digest_key (self, vty, argc, argv); + return no_ip_ospf_message_digest_key(self, vty, argc, argv); } DEFUN (ip_ospf_cost, @@ -5971,38 +6031,38 @@ DEFUN (ip_ospf_cost, "Cost\n" "Address of interface\n") { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx = 0; - u_int32_t cost; - struct in_addr addr; - struct ospf_if_params *params; - params = IF_DEF_PARAMS (ifp); - - // get arguments - char *coststr = NULL, *ifaddr = NULL; - coststr = argv_find (argv, argc, "(1-65535)", &idx) ? argv[idx]->arg : NULL; - ifaddr = argv_find (argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL; - - cost = strtol (coststr, NULL, 10); + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx = 0; + u_int32_t cost; + struct in_addr addr; + struct ospf_if_params *params; + params = IF_DEF_PARAMS(ifp); + + // get arguments + char *coststr = NULL, *ifaddr = NULL; + coststr = argv_find(argv, argc, "(1-65535)", &idx) ? argv[idx]->arg + : NULL; + ifaddr = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL; + + cost = strtol(coststr, NULL, 10); + + if (ifaddr) { + if (!inet_aton(ifaddr, &addr)) { + vty_out(vty, + "Please specify interface address by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } - if (ifaddr) - { - if(!inet_aton(ifaddr, &addr)) - { - vty_out (vty, "Please specify interface address by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; + params = ospf_get_if_params(ifp, addr); + ospf_if_update_params(ifp, addr); } - params = ospf_get_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - } + SET_IF_PARAM(params, output_cost_cmd); + params->output_cost_cmd = cost; - SET_IF_PARAM (params, output_cost_cmd); - params->output_cost_cmd = cost; + ospf_if_recalculate_output_cost(ifp); - ospf_if_recalculate_output_cost (ifp); - - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN_HIDDEN (ospf_cost, @@ -6013,7 +6073,7 @@ DEFUN_HIDDEN (ospf_cost, "Cost\n" "Address of interface\n") { - return ip_ospf_cost (self, vty, argc, argv); + return ip_ospf_cost(self, vty, argc, argv); } DEFUN (no_ip_ospf_cost, @@ -6024,45 +6084,43 @@ DEFUN (no_ip_ospf_cost, "Interface cost\n" "Address of interface") { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx = 0; - struct in_addr addr; - struct ospf_if_params *params; + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx = 0; + struct in_addr addr; + struct ospf_if_params *params; - params = IF_DEF_PARAMS (ifp); + params = IF_DEF_PARAMS(ifp); - // get arguments - char *ifaddr = NULL; - ifaddr = argv_find (argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL; + // get arguments + char *ifaddr = NULL; + ifaddr = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL; - /* According to the semantics we are mimicking "no ip ospf cost N" is - * always treated as "no ip ospf cost" regardless of the actual value - * of N already configured for the interface. Thus ignore cost. */ + /* According to the semantics we are mimicking "no ip ospf cost N" is + * always treated as "no ip ospf cost" regardless of the actual value + * of N already configured for the interface. Thus ignore cost. */ - if (ifaddr) - { - if (!inet_aton(ifaddr, &addr)) - { - vty_out (vty, "Please specify interface address by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; - } + if (ifaddr) { + if (!inet_aton(ifaddr, &addr)) { + vty_out(vty, + "Please specify interface address by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } - params = ospf_lookup_if_params (ifp, addr); - if (params == NULL) - return CMD_SUCCESS; - } + params = ospf_lookup_if_params(ifp, addr); + if (params == NULL) + return CMD_SUCCESS; + } - UNSET_IF_PARAM (params, output_cost_cmd); + UNSET_IF_PARAM(params, output_cost_cmd); - if (params != IF_DEF_PARAMS (ifp)) - { - ospf_free_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - } + if (params != IF_DEF_PARAMS(ifp)) { + ospf_free_if_params(ifp, addr); + ospf_if_update_params(ifp, addr); + } - ospf_if_recalculate_output_cost (ifp); + ospf_if_recalculate_output_cost(ifp); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN_HIDDEN (no_ospf_cost, @@ -6074,98 +6132,86 @@ DEFUN_HIDDEN (no_ospf_cost, "Cost\n" "Address of interface\n") { - return no_ip_ospf_cost (self, vty, argc, argv); + return no_ip_ospf_cost(self, vty, argc, argv); } -static void -ospf_nbr_timer_update (struct ospf_interface *oi) +static void ospf_nbr_timer_update(struct ospf_interface *oi) { - struct route_node *rn; - struct ospf_neighbor *nbr; + struct route_node *rn; + struct ospf_neighbor *nbr; - for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) - if ((nbr = rn->info)) - { - nbr->v_inactivity = OSPF_IF_PARAM (oi, v_wait); - nbr->v_db_desc = OSPF_IF_PARAM (oi, retransmit_interval); - nbr->v_ls_req = OSPF_IF_PARAM (oi, retransmit_interval); - nbr->v_ls_upd = OSPF_IF_PARAM (oi, retransmit_interval); - } + for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) + if ((nbr = rn->info)) { + nbr->v_inactivity = OSPF_IF_PARAM(oi, v_wait); + nbr->v_db_desc = OSPF_IF_PARAM(oi, retransmit_interval); + nbr->v_ls_req = OSPF_IF_PARAM(oi, retransmit_interval); + nbr->v_ls_upd = OSPF_IF_PARAM(oi, retransmit_interval); + } } -static int -ospf_vty_dead_interval_set (struct vty *vty, const char *interval_str, - const char *nbr_str, - const char *fast_hello_str) -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - u_int32_t seconds; - u_char hellomult; - struct in_addr addr; - int ret; - struct ospf_if_params *params; - struct ospf_interface *oi; - struct route_node *rn; - - params = IF_DEF_PARAMS (ifp); - - if (nbr_str) - { - ret = inet_aton(nbr_str, &addr); - if (!ret) - { - vty_out (vty, "Please specify interface address by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - params = ospf_get_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - } - - if (interval_str) - { - seconds = strtoul(interval_str, NULL, 10); - - /* reset fast_hello too, just to be sure */ - UNSET_IF_PARAM (params, fast_hello); - params->fast_hello = OSPF_FAST_HELLO_DEFAULT; - } - else if (fast_hello_str) - { - hellomult = strtoul(fast_hello_str, NULL, 10); - /* 1s dead-interval with sub-second hellos desired */ - seconds = OSPF_ROUTER_DEAD_INTERVAL_MINIMAL; - SET_IF_PARAM (params, fast_hello); - params->fast_hello = hellomult; - } - else - { - vty_out (vty, "Please specify dead-interval or hello-multiplier\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - SET_IF_PARAM (params, v_wait); - params->v_wait = seconds; - - /* Update timer values in neighbor structure. */ - if (nbr_str) - { - struct ospf *ospf; - if ((ospf = ospf_lookup())) - { - oi = ospf_if_lookup_by_local_addr (ospf, ifp, addr); - if (oi) - ospf_nbr_timer_update (oi); - } - } - else - { - for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn)) - if ((oi = rn->info)) - ospf_nbr_timer_update (oi); - } +static int ospf_vty_dead_interval_set(struct vty *vty, const char *interval_str, + const char *nbr_str, + const char *fast_hello_str) +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + u_int32_t seconds; + u_char hellomult; + struct in_addr addr; + int ret; + struct ospf_if_params *params; + struct ospf_interface *oi; + struct route_node *rn; - return CMD_SUCCESS; + params = IF_DEF_PARAMS(ifp); + + if (nbr_str) { + ret = inet_aton(nbr_str, &addr); + if (!ret) { + vty_out(vty, + "Please specify interface address by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + params = ospf_get_if_params(ifp, addr); + ospf_if_update_params(ifp, addr); + } + + if (interval_str) { + seconds = strtoul(interval_str, NULL, 10); + + /* reset fast_hello too, just to be sure */ + UNSET_IF_PARAM(params, fast_hello); + params->fast_hello = OSPF_FAST_HELLO_DEFAULT; + } else if (fast_hello_str) { + hellomult = strtoul(fast_hello_str, NULL, 10); + /* 1s dead-interval with sub-second hellos desired */ + seconds = OSPF_ROUTER_DEAD_INTERVAL_MINIMAL; + SET_IF_PARAM(params, fast_hello); + params->fast_hello = hellomult; + } else { + vty_out(vty, + "Please specify dead-interval or hello-multiplier\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + SET_IF_PARAM(params, v_wait); + params->v_wait = seconds; + + /* Update timer values in neighbor structure. */ + if (nbr_str) { + struct ospf *ospf; + if ((ospf = ospf_lookup())) { + oi = ospf_if_lookup_by_local_addr(ospf, ifp, addr); + if (oi) + ospf_nbr_timer_update(oi); + } + } else { + for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) + if ((oi = rn->info)) + ospf_nbr_timer_update(oi); + } + + return CMD_SUCCESS; } DEFUN (ip_ospf_dead_interval, @@ -6177,10 +6223,13 @@ DEFUN (ip_ospf_dead_interval, "Seconds\n" "Address of interface\n") { - int idx = 0; - char *interval = argv_find (argv, argc, "(1-65535)", &idx) ? argv[idx]->arg : NULL; - char *ifaddr = argv_find (argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL; - return ospf_vty_dead_interval_set (vty, interval, ifaddr, NULL); + int idx = 0; + char *interval = argv_find(argv, argc, "(1-65535)", &idx) + ? argv[idx]->arg + : NULL; + char *ifaddr = + argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL; + return ospf_vty_dead_interval_set(vty, interval, ifaddr, NULL); } @@ -6192,7 +6241,7 @@ DEFUN_HIDDEN (ospf_dead_interval, "Seconds\n" "Address of interface\n") { - return ip_ospf_dead_interval (self, vty, argc, argv); + return ip_ospf_dead_interval(self, vty, argc, argv); } DEFUN (ip_ospf_dead_interval_minimal, @@ -6206,12 +6255,14 @@ DEFUN (ip_ospf_dead_interval_minimal, "Number of Hellos to send each second\n" "Address of interface\n") { - int idx_number = 5; - int idx_ipv4 = 6; - if (argc == 7) - return ospf_vty_dead_interval_set (vty, NULL, argv[idx_ipv4]->arg, argv[idx_number]->arg); - else - return ospf_vty_dead_interval_set (vty, NULL, NULL, argv[idx_number]->arg); + int idx_number = 5; + int idx_ipv4 = 6; + if (argc == 7) + return ospf_vty_dead_interval_set( + vty, NULL, argv[idx_ipv4]->arg, argv[idx_number]->arg); + else + return ospf_vty_dead_interval_set(vty, NULL, NULL, + argv[idx_number]->arg); } DEFUN (no_ip_ospf_dead_interval, @@ -6224,62 +6275,56 @@ DEFUN (no_ip_ospf_dead_interval, "Seconds\n" "Address of interface") { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx_ipv4 = argc - 1; - struct in_addr addr = { .s_addr = 0L}; - int ret; - struct ospf_if_params *params; - struct ospf_interface *oi; - struct route_node *rn; + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx_ipv4 = argc - 1; + struct in_addr addr = {.s_addr = 0L}; + int ret; + struct ospf_if_params *params; + struct ospf_interface *oi; + struct route_node *rn; + + params = IF_DEF_PARAMS(ifp); + + if (argv[idx_ipv4]->type == IPV4_TKN) { + ret = inet_aton(argv[idx_ipv4]->arg, &addr); + if (!ret) { + vty_out(vty, + "Please specify interface address by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } - params = IF_DEF_PARAMS (ifp); + params = ospf_lookup_if_params(ifp, addr); + if (params == NULL) + return CMD_SUCCESS; + } - if (argv[idx_ipv4]->type == IPV4_TKN) - { - ret = inet_aton(argv[idx_ipv4]->arg, &addr); - if (!ret) - { - vty_out (vty, "Please specify interface address by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; + UNSET_IF_PARAM(params, v_wait); + params->v_wait = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT; + + UNSET_IF_PARAM(params, fast_hello); + params->fast_hello = OSPF_FAST_HELLO_DEFAULT; + + if (params != IF_DEF_PARAMS(ifp)) { + ospf_free_if_params(ifp, addr); + ospf_if_update_params(ifp, addr); } - params = ospf_lookup_if_params (ifp, addr); - if (params == NULL) - return CMD_SUCCESS; - } - - UNSET_IF_PARAM (params, v_wait); - params->v_wait = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT; - - UNSET_IF_PARAM (params, fast_hello); - params->fast_hello = OSPF_FAST_HELLO_DEFAULT; - - if (params != IF_DEF_PARAMS (ifp)) - { - ospf_free_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - } - - /* Update timer values in neighbor structure. */ - if (argc == 1) - { - struct ospf *ospf; - - if ((ospf = ospf_lookup())) - { - oi = ospf_if_lookup_by_local_addr (ospf, ifp, addr); - if (oi) - ospf_nbr_timer_update (oi); - } - } - else - { - for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn)) - if ((oi = rn->info)) - ospf_nbr_timer_update (oi); - } + /* Update timer values in neighbor structure. */ + if (argc == 1) { + struct ospf *ospf; - return CMD_SUCCESS; + if ((ospf = ospf_lookup())) { + oi = ospf_if_lookup_by_local_addr(ospf, ifp, addr); + if (oi) + ospf_nbr_timer_update(oi); + } + } else { + for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) + if ((oi = rn->info)) + ospf_nbr_timer_update(oi); + } + + return CMD_SUCCESS; } DEFUN_HIDDEN (no_ospf_dead_interval, @@ -6291,7 +6336,7 @@ DEFUN_HIDDEN (no_ospf_dead_interval, "Seconds\n" "Address of interface") { - return no_ip_ospf_dead_interval (self, vty, argc, argv); + return no_ip_ospf_dead_interval(self, vty, argc, argv); } DEFUN (ip_ospf_hello_interval, @@ -6303,32 +6348,31 @@ DEFUN (ip_ospf_hello_interval, "Seconds\n" "Address of interface\n") { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx = 0; - struct in_addr addr; - struct ospf_if_params *params; - params = IF_DEF_PARAMS (ifp); - u_int32_t seconds = 0; - - argv_find (argv, argc, "(1-65535)", &idx); - seconds = strtol (argv[idx]->arg, NULL, 10); - - if (argv_find (argv, argc, "A.B.C.D", &idx)) - { - if(!inet_aton(argv[idx]->arg, &addr)) - { - vty_out (vty, "Please specify interface address by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; - } + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx = 0; + struct in_addr addr; + struct ospf_if_params *params; + params = IF_DEF_PARAMS(ifp); + u_int32_t seconds = 0; + + argv_find(argv, argc, "(1-65535)", &idx); + seconds = strtol(argv[idx]->arg, NULL, 10); + + if (argv_find(argv, argc, "A.B.C.D", &idx)) { + if (!inet_aton(argv[idx]->arg, &addr)) { + vty_out(vty, + "Please specify interface address by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } - params = ospf_get_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - } + params = ospf_get_if_params(ifp, addr); + ospf_if_update_params(ifp, addr); + } - SET_IF_PARAM (params, v_hello); - params->v_hello = seconds; + SET_IF_PARAM(params, v_hello); + params->v_hello = seconds; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN_HIDDEN (ospf_hello_interval, @@ -6339,7 +6383,7 @@ DEFUN_HIDDEN (ospf_hello_interval, "Seconds\n" "Address of interface\n") { - return ip_ospf_hello_interval (self, vty, argc, argv); + return ip_ospf_hello_interval(self, vty, argc, argv); } DEFUN (no_ip_ospf_hello_interval, @@ -6352,36 +6396,34 @@ DEFUN (no_ip_ospf_hello_interval, "Seconds\n" "Address of interface\n") { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx = 0; - struct in_addr addr; - struct ospf_if_params *params; + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx = 0; + struct in_addr addr; + struct ospf_if_params *params; - params = IF_DEF_PARAMS (ifp); + params = IF_DEF_PARAMS(ifp); - if (argv_find (argv, argc, "A.B.C.D", &idx)) - { - if(!inet_aton(argv[idx]->arg, &addr)) - { - vty_out (vty, "Please specify interface address by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; - } + if (argv_find(argv, argc, "A.B.C.D", &idx)) { + if (!inet_aton(argv[idx]->arg, &addr)) { + vty_out(vty, + "Please specify interface address by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } - params = ospf_lookup_if_params (ifp, addr); - if (params == NULL) - return CMD_SUCCESS; - } + params = ospf_lookup_if_params(ifp, addr); + if (params == NULL) + return CMD_SUCCESS; + } - UNSET_IF_PARAM (params, v_hello); - params->v_hello = OSPF_HELLO_INTERVAL_DEFAULT; + UNSET_IF_PARAM(params, v_hello); + params->v_hello = OSPF_HELLO_INTERVAL_DEFAULT; - if (params != IF_DEF_PARAMS (ifp)) - { - ospf_free_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - } + if (params != IF_DEF_PARAMS(ifp)) { + ospf_free_if_params(ifp, addr); + ospf_if_update_params(ifp, addr); + } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN_HIDDEN (no_ospf_hello_interval, @@ -6393,7 +6435,7 @@ DEFUN_HIDDEN (no_ospf_hello_interval, "Seconds\n" "Address of interface\n") { - return no_ip_ospf_hello_interval (self, vty, argc, argv); + return no_ip_ospf_hello_interval(self, vty, argc, argv); } DEFUN (ip_ospf_network, @@ -6407,48 +6449,46 @@ DEFUN (ip_ospf_network, "Specify OSPF point-to-multipoint network\n" "Specify OSPF point-to-point network\n") { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx = 0; - int old_type = IF_DEF_PARAMS (ifp)->type; - struct route_node *rn; - - if (old_type == OSPF_IFTYPE_LOOPBACK) - { - vty_out (vty, "This is a loopback interface. Can't set network type.\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (argv_find (argv, argc, "broadcast", &idx)) - IF_DEF_PARAMS (ifp)->type = OSPF_IFTYPE_BROADCAST; - else if (argv_find (argv, argc, "non-broadcast", &idx)) - IF_DEF_PARAMS (ifp)->type = OSPF_IFTYPE_NBMA; - else if (argv_find (argv, argc, "point-to-multipoint", &idx)) - IF_DEF_PARAMS (ifp)->type = OSPF_IFTYPE_POINTOMULTIPOINT; - else if (argv_find (argv, argc, "point-to-point", &idx)) - IF_DEF_PARAMS (ifp)->type = OSPF_IFTYPE_POINTOPOINT; - - if (IF_DEF_PARAMS (ifp)->type == old_type) - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx = 0; + int old_type = IF_DEF_PARAMS(ifp)->type; + struct route_node *rn; - SET_IF_PARAM (IF_DEF_PARAMS (ifp), type); + if (old_type == OSPF_IFTYPE_LOOPBACK) { + vty_out(vty, + "This is a loopback interface. Can't set network type.\n"); + return CMD_WARNING_CONFIG_FAILED; + } - for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn)) - { - struct ospf_interface *oi = rn->info; + if (argv_find(argv, argc, "broadcast", &idx)) + IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_BROADCAST; + else if (argv_find(argv, argc, "non-broadcast", &idx)) + IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_NBMA; + else if (argv_find(argv, argc, "point-to-multipoint", &idx)) + IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_POINTOMULTIPOINT; + else if (argv_find(argv, argc, "point-to-point", &idx)) + IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_POINTOPOINT; - if (!oi) - continue; - - oi->type = IF_DEF_PARAMS (ifp)->type; - - if (oi->state > ISM_Down) - { - OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceDown); - OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceUp); + if (IF_DEF_PARAMS(ifp)->type == old_type) + return CMD_SUCCESS; + + SET_IF_PARAM(IF_DEF_PARAMS(ifp), type); + + for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) { + struct ospf_interface *oi = rn->info; + + if (!oi) + continue; + + oi->type = IF_DEF_PARAMS(ifp)->type; + + if (oi->state > ISM_Down) { + OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceDown); + OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceUp); + } } - } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN_HIDDEN (ospf_network, @@ -6461,7 +6501,7 @@ DEFUN_HIDDEN (ospf_network, "Specify OSPF point-to-multipoint network\n" "Specify OSPF point-to-point network\n") { - return ip_ospf_network (self, vty, argc, argv); + return ip_ospf_network(self, vty, argc, argv); } DEFUN (no_ip_ospf_network, @@ -6476,32 +6516,30 @@ DEFUN (no_ip_ospf_network, "Specify OSPF point-to-multipoint network\n" "Specify OSPF point-to-point network\n") { - VTY_DECLVAR_CONTEXT(interface, ifp); - int old_type = IF_DEF_PARAMS (ifp)->type; - struct route_node *rn; + VTY_DECLVAR_CONTEXT(interface, ifp); + int old_type = IF_DEF_PARAMS(ifp)->type; + struct route_node *rn; - IF_DEF_PARAMS (ifp)->type = ospf_default_iftype(ifp); + IF_DEF_PARAMS(ifp)->type = ospf_default_iftype(ifp); - if (IF_DEF_PARAMS (ifp)->type == old_type) - return CMD_SUCCESS; + if (IF_DEF_PARAMS(ifp)->type == old_type) + return CMD_SUCCESS; - for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn)) - { - struct ospf_interface *oi = rn->info; + for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) { + struct ospf_interface *oi = rn->info; - if (!oi) - continue; + if (!oi) + continue; - oi->type = IF_DEF_PARAMS (ifp)->type; + oi->type = IF_DEF_PARAMS(ifp)->type; - if (oi->state > ISM_Down) - { - OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceDown); - OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceUp); + if (oi->state > ISM_Down) { + OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceDown); + OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceUp); + } } - } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN_HIDDEN (no_ospf_network, @@ -6515,7 +6553,7 @@ DEFUN_HIDDEN (no_ospf_network, "Specify OSPF point-to-multipoint network\n" "Specify OSPF point-to-point network\n") { - return no_ip_ospf_network (self, vty, argc, argv); + return no_ip_ospf_network(self, vty, argc, argv); } DEFUN (ip_ospf_priority, @@ -6527,47 +6565,44 @@ DEFUN (ip_ospf_priority, "Priority\n" "Address of interface") { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx = 0; - long priority; - struct route_node *rn; - struct in_addr addr; - struct ospf_if_params *params; - params = IF_DEF_PARAMS (ifp); - - argv_find (argv, argc, "(0-255)", &idx); - priority = strtol (argv[idx]->arg, NULL, 10); + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx = 0; + long priority; + struct route_node *rn; + struct in_addr addr; + struct ospf_if_params *params; + params = IF_DEF_PARAMS(ifp); + + argv_find(argv, argc, "(0-255)", &idx); + priority = strtol(argv[idx]->arg, NULL, 10); + + if (argv_find(argv, argc, "A.B.C.D", &idx)) { + if (!inet_aton(argv[idx]->arg, &addr)) { + vty_out(vty, + "Please specify interface address by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } - if (argv_find (argv, argc, "A.B.C.D", &idx)) - { - if (!inet_aton(argv[idx]->arg, &addr)) - { - vty_out (vty, "Please specify interface address by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; + params = ospf_get_if_params(ifp, addr); + ospf_if_update_params(ifp, addr); } - params = ospf_get_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - } - - SET_IF_PARAM (params, priority); - params->priority = priority; + SET_IF_PARAM(params, priority); + params->priority = priority; - for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn)) - { - struct ospf_interface *oi = rn->info; + for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) { + struct ospf_interface *oi = rn->info; - if (!oi) - continue; + if (!oi) + continue; - if (PRIORITY (oi) != OSPF_IF_PARAM (oi, priority)) - { - PRIORITY (oi) = OSPF_IF_PARAM (oi, priority); - OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange); + if (PRIORITY(oi) != OSPF_IF_PARAM(oi, priority)) { + PRIORITY(oi) = OSPF_IF_PARAM(oi, priority); + OSPF_ISM_EVENT_SCHEDULE(oi, ISM_NeighborChange); + } } - } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN_HIDDEN (ospf_priority, @@ -6578,7 +6613,7 @@ DEFUN_HIDDEN (ospf_priority, "Priority\n" "Address of interface") { - return ip_ospf_priority (self, vty, argc, argv); + return ip_ospf_priority(self, vty, argc, argv); } DEFUN (no_ip_ospf_priority, @@ -6591,51 +6626,47 @@ DEFUN (no_ip_ospf_priority, "Priority\n" "Address of interface") { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx = 0; - struct route_node *rn; - struct in_addr addr; - struct ospf_if_params *params; - - params = IF_DEF_PARAMS (ifp); - - if (argv_find (argv, argc, "A.B.C.D", &idx)) - { - if (!inet_aton(argv[idx]->arg, &addr)) - { - vty_out (vty, "Please specify interface address by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx = 0; + struct route_node *rn; + struct in_addr addr; + struct ospf_if_params *params; + + params = IF_DEF_PARAMS(ifp); + + if (argv_find(argv, argc, "A.B.C.D", &idx)) { + if (!inet_aton(argv[idx]->arg, &addr)) { + vty_out(vty, + "Please specify interface address by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + params = ospf_lookup_if_params(ifp, addr); + if (params == NULL) + return CMD_SUCCESS; } - params = ospf_lookup_if_params (ifp, addr); - if (params == NULL) - return CMD_SUCCESS; - } - - UNSET_IF_PARAM (params, priority); - params->priority = OSPF_ROUTER_PRIORITY_DEFAULT; - - if (params != IF_DEF_PARAMS (ifp)) - { - ospf_free_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - } - - for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn)) - { - struct ospf_interface *oi = rn->info; - - if (!oi) - continue; - - if (PRIORITY (oi) != OSPF_IF_PARAM (oi, priority)) - { - PRIORITY (oi) = OSPF_IF_PARAM (oi, priority); - OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange); + UNSET_IF_PARAM(params, priority); + params->priority = OSPF_ROUTER_PRIORITY_DEFAULT; + + if (params != IF_DEF_PARAMS(ifp)) { + ospf_free_if_params(ifp, addr); + ospf_if_update_params(ifp, addr); } - } - - return CMD_SUCCESS; + + for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) { + struct ospf_interface *oi = rn->info; + + if (!oi) + continue; + + if (PRIORITY(oi) != OSPF_IF_PARAM(oi, priority)) { + PRIORITY(oi) = OSPF_IF_PARAM(oi, priority); + OSPF_ISM_EVENT_SCHEDULE(oi, ISM_NeighborChange); + } + } + + return CMD_SUCCESS; } DEFUN_HIDDEN (no_ospf_priority, @@ -6647,7 +6678,7 @@ DEFUN_HIDDEN (no_ospf_priority, "Priority\n" "Address of interface") { - return no_ip_ospf_priority (self, vty, argc, argv); + return no_ip_ospf_priority(self, vty, argc, argv); } DEFUN (ip_ospf_retransmit_interval, @@ -6659,32 +6690,31 @@ DEFUN (ip_ospf_retransmit_interval, "Seconds\n" "Address of interface") { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx = 0; - u_int32_t seconds; - struct in_addr addr; - struct ospf_if_params *params; - params = IF_DEF_PARAMS (ifp); - - argv_find (argv, argc, "(3-65535)", &idx); - seconds = strtol (argv[idx]->arg, NULL, 10); + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx = 0; + u_int32_t seconds; + struct in_addr addr; + struct ospf_if_params *params; + params = IF_DEF_PARAMS(ifp); + + argv_find(argv, argc, "(3-65535)", &idx); + seconds = strtol(argv[idx]->arg, NULL, 10); + + if (argv_find(argv, argc, "A.B.C.D", &idx)) { + if (!inet_aton(argv[idx]->arg, &addr)) { + vty_out(vty, + "Please specify interface address by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } - if (argv_find (argv, argc, "A.B.C.D", &idx)) - { - if (!inet_aton(argv[idx]->arg, &addr)) - { - vty_out (vty, "Please specify interface address by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; + params = ospf_get_if_params(ifp, addr); + ospf_if_update_params(ifp, addr); } - params = ospf_get_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - } + SET_IF_PARAM(params, retransmit_interval); + params->retransmit_interval = seconds; - SET_IF_PARAM (params, retransmit_interval); - params->retransmit_interval = seconds; - - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN_HIDDEN (ospf_retransmit_interval, @@ -6695,7 +6725,7 @@ DEFUN_HIDDEN (ospf_retransmit_interval, "Seconds\n" "Address of interface") { - return ip_ospf_retransmit_interval (self, vty, argc, argv); + return ip_ospf_retransmit_interval(self, vty, argc, argv); } DEFUN (no_ip_ospf_retransmit_interval, @@ -6708,36 +6738,34 @@ DEFUN (no_ip_ospf_retransmit_interval, "Seconds\n" "Address of interface\n") { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx = 0; - struct in_addr addr; - struct ospf_if_params *params; + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx = 0; + struct in_addr addr; + struct ospf_if_params *params; - params = IF_DEF_PARAMS (ifp); + params = IF_DEF_PARAMS(ifp); - if (argv_find (argv, argc, "A.B.C.D", &idx)) - { - if (!inet_aton(argv[idx]->arg, &addr)) - { - vty_out (vty, "Please specify interface address by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; - } + if (argv_find(argv, argc, "A.B.C.D", &idx)) { + if (!inet_aton(argv[idx]->arg, &addr)) { + vty_out(vty, + "Please specify interface address by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } - params = ospf_lookup_if_params (ifp, addr); - if (params == NULL) - return CMD_SUCCESS; - } + params = ospf_lookup_if_params(ifp, addr); + if (params == NULL) + return CMD_SUCCESS; + } - UNSET_IF_PARAM (params, retransmit_interval); - params->retransmit_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT; + UNSET_IF_PARAM(params, retransmit_interval); + params->retransmit_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT; - if (params != IF_DEF_PARAMS (ifp)) - { - ospf_free_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - } + if (params != IF_DEF_PARAMS(ifp)) { + ospf_free_if_params(ifp, addr); + ospf_if_update_params(ifp, addr); + } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN_HIDDEN (no_ospf_retransmit_interval, @@ -6749,7 +6777,7 @@ DEFUN_HIDDEN (no_ospf_retransmit_interval, "Seconds\n" "Address of interface\n") { - return no_ip_ospf_retransmit_interval (self, vty, argc, argv); + return no_ip_ospf_retransmit_interval(self, vty, argc, argv); } DEFUN (ip_ospf_transmit_delay, @@ -6761,32 +6789,31 @@ DEFUN (ip_ospf_transmit_delay, "Seconds\n" "Address of interface") { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx = 0; - u_int32_t seconds; - struct in_addr addr; - struct ospf_if_params *params; - - params = IF_DEF_PARAMS (ifp); - argv_find (argv, argc, "(1-65535)", &idx); - seconds = strtol (argv[idx]->arg, NULL, 10); + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx = 0; + u_int32_t seconds; + struct in_addr addr; + struct ospf_if_params *params; + + params = IF_DEF_PARAMS(ifp); + argv_find(argv, argc, "(1-65535)", &idx); + seconds = strtol(argv[idx]->arg, NULL, 10); + + if (argv_find(argv, argc, "A.B.C.D", &idx)) { + if (!inet_aton(argv[idx]->arg, &addr)) { + vty_out(vty, + "Please specify interface address by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } - if (argv_find (argv, argc, "A.B.C.D", &idx)) - { - if (!inet_aton(argv[idx]->arg, &addr)) - { - vty_out (vty, "Please specify interface address by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; + params = ospf_get_if_params(ifp, addr); + ospf_if_update_params(ifp, addr); } - params = ospf_get_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - } - - SET_IF_PARAM (params, transmit_delay); - params->transmit_delay = seconds; + SET_IF_PARAM(params, transmit_delay); + params->transmit_delay = seconds; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN_HIDDEN (ospf_transmit_delay, @@ -6797,7 +6824,7 @@ DEFUN_HIDDEN (ospf_transmit_delay, "Seconds\n" "Address of interface") { - return ip_ospf_transmit_delay (self, vty, argc, argv); + return ip_ospf_transmit_delay(self, vty, argc, argv); } DEFUN (no_ip_ospf_transmit_delay, @@ -6809,36 +6836,34 @@ DEFUN (no_ip_ospf_transmit_delay, "Link state transmit delay\n" "Address of interface") { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx = 0; - struct in_addr addr; - struct ospf_if_params *params; - - params = IF_DEF_PARAMS (ifp); + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx = 0; + struct in_addr addr; + struct ospf_if_params *params; - if (argv_find (argv, argc, "A.B.C.D", &idx)) - { - if (!inet_aton(argv[idx]->arg, &addr)) - { - vty_out (vty, "Please specify interface address by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; - } + params = IF_DEF_PARAMS(ifp); - params = ospf_lookup_if_params (ifp, addr); - if (params == NULL) - return CMD_SUCCESS; - } + if (argv_find(argv, argc, "A.B.C.D", &idx)) { + if (!inet_aton(argv[idx]->arg, &addr)) { + vty_out(vty, + "Please specify interface address by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } - UNSET_IF_PARAM (params, transmit_delay); - params->transmit_delay = OSPF_TRANSMIT_DELAY_DEFAULT; + params = ospf_lookup_if_params(ifp, addr); + if (params == NULL) + return CMD_SUCCESS; + } - if (params != IF_DEF_PARAMS (ifp)) - { - ospf_free_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - } + UNSET_IF_PARAM(params, transmit_delay); + params->transmit_delay = OSPF_TRANSMIT_DELAY_DEFAULT; - return CMD_SUCCESS; + if (params != IF_DEF_PARAMS(ifp)) { + ospf_free_if_params(ifp, addr); + ospf_if_update_params(ifp, addr); + } + + return CMD_SUCCESS; } @@ -6849,7 +6874,7 @@ DEFUN_HIDDEN (no_ospf_transmit_delay, "OSPF interface commands\n" "Link state transmit delay\n") { - return no_ip_ospf_transmit_delay (self, vty, argc, argv); + return no_ip_ospf_transmit_delay(self, vty, argc, argv); } DEFUN (ip_ospf_area, @@ -6863,87 +6888,81 @@ DEFUN (ip_ospf_area, "OSPF area ID as a decimal value\n" "Address of interface\n") { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx = 0; - int format, ret; - struct in_addr area_id; - struct in_addr addr; - struct ospf_if_params *params; - struct route_node *rn; - struct ospf *ospf; - u_short instance = 0; - char *areaid; - - if (argv_find (argv, argc, "(1-65535)", &idx)) - instance = strtol (argv[idx]->arg, NULL, 10); - - argv_find (argv, argc, "area", &idx); - areaid = argv[idx + 1]->arg; - - ospf = ospf_lookup_instance (instance); - if (ospf == NULL) - { - params = IF_DEF_PARAMS (ifp); - if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) - { - UNSET_IF_PARAM (params, if_area); - ospf_interface_area_unset (ifp); - ospf = ospf_lookup(); - ospf->if_ospf_cli_count--; - } - return CMD_SUCCESS; - } - - ret = str2area_id (areaid, &area_id, &format); - if (ret < 0) - { - vty_out (vty, "Please specify area by A.B.C.D|<0-4294967295>\n"); - return CMD_WARNING_CONFIG_FAILED; - } - if (memcmp (ifp->name, "VLINK", 5) == 0) - { - vty_out (vty, "Cannot enable OSPF on a virtual link.\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - params = IF_DEF_PARAMS (ifp); - if (OSPF_IF_PARAM_CONFIGURED(params, if_area) && !IPV4_ADDR_SAME(¶ms->if_area, &area_id)) - { - vty_out (vty, - "Must remove previous area config before changing ospf area \n"); - return CMD_WARNING_CONFIG_FAILED; - } - - // Check if we have an address arg and proccess it - if (argc == idx + 3) { - inet_aton(argv[idx+2]->arg, &addr); - // update/create address-level params - params = ospf_get_if_params ((ifp), (addr)); - if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) - { - vty_out (vty, - "Must remove previous area/address config before changing ospf area"); - return CMD_WARNING_CONFIG_FAILED; - } - ospf_if_update_params ((ifp), (addr)); - } - - for (rn = route_top (ospf->networks); rn; rn = route_next (rn)) - { - if (rn->info != NULL) - { - vty_out (vty, "Please remove all network commands first.\n"); - return CMD_WARNING_CONFIG_FAILED; - } - } - - /* enable ospf on this interface with area_id */ - SET_IF_PARAM (params, if_area); - params->if_area = area_id; - ospf_interface_area_set (ifp); - ospf->if_ospf_cli_count++; + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx = 0; + int format, ret; + struct in_addr area_id; + struct in_addr addr; + struct ospf_if_params *params; + struct route_node *rn; + struct ospf *ospf; + u_short instance = 0; + char *areaid; + + if (argv_find(argv, argc, "(1-65535)", &idx)) + instance = strtol(argv[idx]->arg, NULL, 10); + + argv_find(argv, argc, "area", &idx); + areaid = argv[idx + 1]->arg; + + ospf = ospf_lookup_instance(instance); + if (ospf == NULL) { + params = IF_DEF_PARAMS(ifp); + if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) { + UNSET_IF_PARAM(params, if_area); + ospf_interface_area_unset(ifp); + ospf = ospf_lookup(); + ospf->if_ospf_cli_count--; + } + return CMD_SUCCESS; + } - return CMD_SUCCESS; + ret = str2area_id(areaid, &area_id, &format); + if (ret < 0) { + vty_out(vty, "Please specify area by A.B.C.D|<0-4294967295>\n"); + return CMD_WARNING_CONFIG_FAILED; + } + if (memcmp(ifp->name, "VLINK", 5) == 0) { + vty_out(vty, "Cannot enable OSPF on a virtual link.\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + params = IF_DEF_PARAMS(ifp); + if (OSPF_IF_PARAM_CONFIGURED(params, if_area) + && !IPV4_ADDR_SAME(¶ms->if_area, &area_id)) { + vty_out(vty, + "Must remove previous area config before changing ospf area \n"); + return CMD_WARNING_CONFIG_FAILED; + } + + // Check if we have an address arg and proccess it + if (argc == idx + 3) { + inet_aton(argv[idx + 2]->arg, &addr); + // update/create address-level params + params = ospf_get_if_params((ifp), (addr)); + if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) { + vty_out(vty, + "Must remove previous area/address config before changing ospf area"); + return CMD_WARNING_CONFIG_FAILED; + } + ospf_if_update_params((ifp), (addr)); + } + + for (rn = route_top(ospf->networks); rn; rn = route_next(rn)) { + if (rn->info != NULL) { + vty_out(vty, + "Please remove all network commands first.\n"); + return CMD_WARNING_CONFIG_FAILED; + } + } + + /* enable ospf on this interface with area_id */ + SET_IF_PARAM(params, if_area); + params->if_area = area_id; + ospf_interface_area_set(ifp); + ospf->if_ospf_cli_count++; + + return CMD_SUCCESS; } DEFUN (no_ip_ospf_area, @@ -6958,47 +6977,45 @@ DEFUN (no_ip_ospf_area, "OSPF area ID as a decimal value\n" "Address of interface\n") { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx = 0; - struct ospf *ospf; - struct ospf_if_params *params; - u_short instance = 0; - struct in_addr addr; - - if (argv_find (argv, argc, "(1-65535)", &idx)) - instance = strtol (argv[idx]->arg, NULL, 10); - - if ((ospf = ospf_lookup_instance (instance)) == NULL) - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx = 0; + struct ospf *ospf; + struct ospf_if_params *params; + u_short instance = 0; + struct in_addr addr; + + if (argv_find(argv, argc, "(1-65535)", &idx)) + instance = strtol(argv[idx]->arg, NULL, 10); + + if ((ospf = ospf_lookup_instance(instance)) == NULL) + return CMD_SUCCESS; + + argv_find(argv, argc, "area", &idx); + + // Check if we have an address arg and proccess it + if (argc == idx + 3) { + inet_aton(argv[idx + 2]->arg, &addr); + params = ospf_lookup_if_params(ifp, addr); + if ((params) == NULL) + return CMD_SUCCESS; + } else + params = IF_DEF_PARAMS(ifp); + + if (!OSPF_IF_PARAM_CONFIGURED(params, if_area)) { + vty_out(vty, + "Can't find specified interface area configuration.\n"); + return CMD_WARNING_CONFIG_FAILED; + } - argv_find (argv, argc, "area", &idx); - - // Check if we have an address arg and proccess it - if (argc == idx + 3) { - inet_aton(argv[idx+2]->arg, &addr); - params = ospf_lookup_if_params (ifp, addr); - if ((params) == NULL) - return CMD_SUCCESS; - } - else - params = IF_DEF_PARAMS (ifp); - - if (!OSPF_IF_PARAM_CONFIGURED(params, if_area)) - { - vty_out (vty, "Can't find specified interface area configuration.\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - UNSET_IF_PARAM (params, if_area); - if (params != IF_DEF_PARAMS ((ifp))) - { - ospf_free_if_params ((ifp), (addr)); - ospf_if_update_params ((ifp), (addr)); - } - - ospf_interface_area_unset (ifp); - ospf->if_ospf_cli_count--; - return CMD_SUCCESS; + UNSET_IF_PARAM(params, if_area); + if (params != IF_DEF_PARAMS((ifp))) { + ospf_free_if_params((ifp), (addr)); + ospf_if_update_params((ifp), (addr)); + } + + ospf_interface_area_unset(ifp); + ospf->if_ospf_cli_count--; + return CMD_SUCCESS; } DEFUN (ospf_redistribute_source, @@ -7013,42 +7030,41 @@ DEFUN (ospf_redistribute_source, "Route map reference\n" "Pointer to route-map entries\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_protocol = 1; - int source; - int type = -1; - int metric = -1; - struct ospf_redist *red; - int idx = 0; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_protocol = 1; + int source; + int type = -1; + int metric = -1; + struct ospf_redist *red; + int idx = 0; - if (!ospf) - return CMD_SUCCESS; + if (!ospf) + return CMD_SUCCESS; + + /* Get distribute source. */ + source = proto_redistnum(AFI_IP, argv[idx_protocol]->text); + if (source < 0) + return CMD_WARNING_CONFIG_FAILED; + + red = ospf_redist_add(ospf, source, 0); - /* Get distribute source. */ - source = proto_redistnum(AFI_IP, argv[idx_protocol]->text); - if (source < 0) - return CMD_WARNING_CONFIG_FAILED; - - red = ospf_redist_add(ospf, source, 0); - - /* Get metric value. */ - if (argv_find (argv, argc, "(0-16777214)", &idx)) { - if (!str2metric (argv[idx]->arg, &metric)) - return CMD_WARNING_CONFIG_FAILED; - } - /* Get metric type. */ - else if (argv_find (argv, argc, "(1-2)", &idx)) { - if (!str2metric_type (argv[idx]->arg, &type)) - return CMD_WARNING_CONFIG_FAILED; - } - /* Get route-map */ - else if (argv_find (argv, argc, "WORD", &idx)) { - ospf_routemap_set (red, argv[idx]->arg); - } - else - ospf_routemap_unset (red); - - return ospf_redistribute_set (ospf, source, 0, type, metric); + /* Get metric value. */ + if (argv_find(argv, argc, "(0-16777214)", &idx)) { + if (!str2metric(argv[idx]->arg, &metric)) + return CMD_WARNING_CONFIG_FAILED; + } + /* Get metric type. */ + else if (argv_find(argv, argc, "(1-2)", &idx)) { + if (!str2metric_type(argv[idx]->arg, &type)) + return CMD_WARNING_CONFIG_FAILED; + } + /* Get route-map */ + else if (argv_find(argv, argc, "WORD", &idx)) { + ospf_routemap_set(red, argv[idx]->arg); + } else + ospf_routemap_unset(red); + + return ospf_redistribute_set(ospf, source, 0, type, metric); } DEFUN (no_ospf_redistribute_source, @@ -7064,21 +7080,21 @@ DEFUN (no_ospf_redistribute_source, "Route map reference\n" "Pointer to route-map entries\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_protocol = 2; - int source; - struct ospf_redist *red; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_protocol = 2; + int source; + struct ospf_redist *red; - source = proto_redistnum(AFI_IP, argv[idx_protocol]->text); - if (source < 0) - return CMD_WARNING_CONFIG_FAILED; + source = proto_redistnum(AFI_IP, argv[idx_protocol]->text); + if (source < 0) + return CMD_WARNING_CONFIG_FAILED; - red = ospf_redist_lookup(ospf, source, 0); - if (!red) - return CMD_SUCCESS; + red = ospf_redist_lookup(ospf, source, 0); + if (!red) + return CMD_SUCCESS; - ospf_routemap_unset (red); - return ospf_redistribute_unset (ospf, source, 0); + ospf_routemap_unset(red); + return ospf_redistribute_unset(ospf, source, 0); } DEFUN (ospf_redistribute_instance_source, @@ -7095,58 +7111,57 @@ DEFUN (ospf_redistribute_instance_source, "Route map reference\n" "Pointer to route-map entries\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ospf_table = 1; - int idx_number = 2; - int idx = 3; - int source; - int type = -1; - int metric = -1; - u_short instance; - struct ospf_redist *red; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ospf_table = 1; + int idx_number = 2; + int idx = 3; + int source; + int type = -1; + int metric = -1; + u_short instance; + struct ospf_redist *red; - if (!ospf) - return CMD_SUCCESS; + if (!ospf) + return CMD_SUCCESS; - source = proto_redistnum (AFI_IP, argv[idx_ospf_table]->text); + source = proto_redistnum(AFI_IP, argv[idx_ospf_table]->text); - instance = strtoul(argv[idx_number]->arg, NULL, 10); + instance = strtoul(argv[idx_number]->arg, NULL, 10); - if (!ospf) - return CMD_SUCCESS; + if (!ospf) + return CMD_SUCCESS; - if ((source == ZEBRA_ROUTE_OSPF) && !ospf->instance) - { - vty_out (vty, "Instance redistribution in non-instanced OSPF not allowed\n"); - return CMD_WARNING_CONFIG_FAILED; - } + if ((source == ZEBRA_ROUTE_OSPF) && !ospf->instance) { + vty_out(vty, + "Instance redistribution in non-instanced OSPF not allowed\n"); + return CMD_WARNING_CONFIG_FAILED; + } - if ((source == ZEBRA_ROUTE_OSPF) && (ospf->instance == instance)) - { - vty_out (vty, "Same instance OSPF redistribution not allowed\n"); - return CMD_WARNING_CONFIG_FAILED; - } + if ((source == ZEBRA_ROUTE_OSPF) && (ospf->instance == instance)) { + vty_out(vty, "Same instance OSPF redistribution not allowed\n"); + return CMD_WARNING_CONFIG_FAILED; + } - /* Get metric value. */ - if (argv_find (argv, argc, "metric", &idx)) - if (!str2metric (argv[idx+1]->arg, &metric)) - return CMD_WARNING_CONFIG_FAILED; + /* Get metric value. */ + if (argv_find(argv, argc, "metric", &idx)) + if (!str2metric(argv[idx + 1]->arg, &metric)) + return CMD_WARNING_CONFIG_FAILED; - idx = 3; - /* Get metric type. */ - if (argv_find (argv, argc, "metric-type", &idx)) - if (!str2metric_type (argv[idx+1]->arg, &type)) - return CMD_WARNING_CONFIG_FAILED; + idx = 3; + /* Get metric type. */ + if (argv_find(argv, argc, "metric-type", &idx)) + if (!str2metric_type(argv[idx + 1]->arg, &type)) + return CMD_WARNING_CONFIG_FAILED; - red = ospf_redist_add(ospf, source, instance); + red = ospf_redist_add(ospf, source, instance); - idx = 3; - if (argv_find (argv, argc, "route-map", &idx)) - ospf_routemap_set (red, argv[idx+1]->arg); - else - ospf_routemap_unset (red); + idx = 3; + if (argv_find(argv, argc, "route-map", &idx)) + ospf_routemap_set(red, argv[idx + 1]->arg); + else + ospf_routemap_unset(red); - return ospf_redistribute_set (ospf, source, instance, type, metric); + return ospf_redistribute_set(ospf, source, instance, type, metric); } DEFUN (no_ospf_redistribute_instance_source, @@ -7164,38 +7179,37 @@ DEFUN (no_ospf_redistribute_instance_source, "Route map reference\n" "Pointer to route-map entries\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_ospf_table = 2; - int idx_number = 3; - u_int instance; - struct ospf_redist *red; - int source; - - if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0) - source = ZEBRA_ROUTE_OSPF; - else - source = ZEBRA_ROUTE_TABLE; - - instance = strtoul(argv[idx_number]->arg, NULL, 10); - - if ((source == ZEBRA_ROUTE_OSPF) && !ospf->instance) - { - vty_out (vty, "Instance redistribution in non-instanced OSPF not allowed\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if ((source == ZEBRA_ROUTE_OSPF) && (ospf->instance == instance)) - { - vty_out (vty, "Same instance OSPF redistribution not allowed\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - red = ospf_redist_lookup(ospf, source, instance); - if (!red) - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_ospf_table = 2; + int idx_number = 3; + u_int instance; + struct ospf_redist *red; + int source; + + if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0) + source = ZEBRA_ROUTE_OSPF; + else + source = ZEBRA_ROUTE_TABLE; + + instance = strtoul(argv[idx_number]->arg, NULL, 10); + + if ((source == ZEBRA_ROUTE_OSPF) && !ospf->instance) { + vty_out(vty, + "Instance redistribution in non-instanced OSPF not allowed\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if ((source == ZEBRA_ROUTE_OSPF) && (ospf->instance == instance)) { + vty_out(vty, "Same instance OSPF redistribution not allowed\n"); + return CMD_WARNING_CONFIG_FAILED; + } - ospf_routemap_unset (red); - return ospf_redistribute_unset (ospf, source, instance); + red = ospf_redist_lookup(ospf, source, instance); + if (!red) + return CMD_SUCCESS; + + ospf_routemap_unset(red); + return ospf_redistribute_unset(ospf, source, instance); } DEFUN (ospf_distribute_list_out, @@ -7206,18 +7220,18 @@ DEFUN (ospf_distribute_list_out, OUT_STR FRR_REDIST_HELP_STR_OSPFD) { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_word = 1; - int source; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_word = 1; + int source; - char *proto = argv[argc - 1]->text; + char *proto = argv[argc - 1]->text; - /* Get distribute source. */ - source = proto_redistnum(AFI_IP, proto); - if (source < 0) - return CMD_WARNING_CONFIG_FAILED; + /* Get distribute source. */ + source = proto_redistnum(AFI_IP, proto); + if (source < 0) + return CMD_WARNING_CONFIG_FAILED; - return ospf_distribute_list_out_set (ospf, source, argv[idx_word]->arg); + return ospf_distribute_list_out_set(ospf, source, argv[idx_word]->arg); } DEFUN (no_ospf_distribute_list_out, @@ -7229,16 +7243,17 @@ DEFUN (no_ospf_distribute_list_out, OUT_STR FRR_REDIST_HELP_STR_OSPFD) { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_word = 2; - int source; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_word = 2; + int source; - char *proto = argv[argc - 1]->text; - source = proto_redistnum(AFI_IP, proto); - if (source < 0) - return CMD_WARNING_CONFIG_FAILED; + char *proto = argv[argc - 1]->text; + source = proto_redistnum(AFI_IP, proto); + if (source < 0) + return CMD_WARNING_CONFIG_FAILED; - return ospf_distribute_list_out_unset (ospf, source, argv[idx_word]->arg); + return ospf_distribute_list_out_unset(ospf, source, + argv[idx_word]->arg); } /* Default information originate. */ @@ -7255,36 +7270,36 @@ DEFUN (ospf_default_information_originate, "Route map reference\n" "Pointer to route-map entries\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int default_originate = DEFAULT_ORIGINATE_ZEBRA; - int type = -1; - int metric = -1; - struct ospf_redist *red; - int idx = 0; - - red = ospf_redist_add(ospf, DEFAULT_ROUTE, 0); - - /* Check whether "always" was specified */ - if (argv_find (argv, argc, "always", &idx)) - default_originate = DEFAULT_ORIGINATE_ALWAYS; - /* Get metric value */ - else if (argv_find (argv, argc, "(0-16777214)", &idx)) { - if (!str2metric (argv[idx]->arg, &metric)) - return CMD_WARNING_CONFIG_FAILED; - } - /* Get metric type. */ - else if (argv_find (argv, argc, "(1-2)", &idx)) { - if (!str2metric_type (argv[idx]->arg, &type)) - return CMD_WARNING_CONFIG_FAILED; - } - /* Get route-map */ - else if (argv_find (argv, argc, "WORD", &idx)) - ospf_routemap_set (red, argv[idx]->arg); - else - ospf_routemap_unset (red); - - return ospf_redistribute_default_set (ospf, default_originate, - type, metric); + VTY_DECLVAR_CONTEXT(ospf, ospf); + int default_originate = DEFAULT_ORIGINATE_ZEBRA; + int type = -1; + int metric = -1; + struct ospf_redist *red; + int idx = 0; + + red = ospf_redist_add(ospf, DEFAULT_ROUTE, 0); + + /* Check whether "always" was specified */ + if (argv_find(argv, argc, "always", &idx)) + default_originate = DEFAULT_ORIGINATE_ALWAYS; + /* Get metric value */ + else if (argv_find(argv, argc, "(0-16777214)", &idx)) { + if (!str2metric(argv[idx]->arg, &metric)) + return CMD_WARNING_CONFIG_FAILED; + } + /* Get metric type. */ + else if (argv_find(argv, argc, "(1-2)", &idx)) { + if (!str2metric_type(argv[idx]->arg, &type)) + return CMD_WARNING_CONFIG_FAILED; + } + /* Get route-map */ + else if (argv_find(argv, argc, "WORD", &idx)) + ospf_routemap_set(red, argv[idx]->arg); + else + ospf_routemap_unset(red); + + return ospf_redistribute_default_set(ospf, default_originate, type, + metric); } DEFUN (no_ospf_default_information_originate, @@ -7301,29 +7316,29 @@ DEFUN (no_ospf_default_information_originate, "Route map reference\n" "Pointer to route-map entries\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - struct prefix_ipv4 p; - struct ospf_external *ext; - struct ospf_redist *red; + VTY_DECLVAR_CONTEXT(ospf, ospf); + struct prefix_ipv4 p; + struct ospf_external *ext; + struct ospf_redist *red; - p.family = AF_INET; - p.prefix.s_addr = 0; - p.prefixlen = 0; + p.family = AF_INET; + p.prefix.s_addr = 0; + p.prefixlen = 0; - ospf_external_lsa_flush (ospf, DEFAULT_ROUTE, &p, 0); + ospf_external_lsa_flush(ospf, DEFAULT_ROUTE, &p, 0); - if ((ext = ospf_external_lookup(DEFAULT_ROUTE, 0)) && - EXTERNAL_INFO (ext)) { - ospf_external_info_delete (DEFAULT_ROUTE, 0, p); - ospf_external_del (DEFAULT_ROUTE, 0); - } + if ((ext = ospf_external_lookup(DEFAULT_ROUTE, 0)) + && EXTERNAL_INFO(ext)) { + ospf_external_info_delete(DEFAULT_ROUTE, 0, p); + ospf_external_del(DEFAULT_ROUTE, 0); + } - red = ospf_redist_lookup(ospf, DEFAULT_ROUTE, 0); - if (!red) - return CMD_SUCCESS; + red = ospf_redist_lookup(ospf, DEFAULT_ROUTE, 0); + if (!red) + return CMD_SUCCESS; - ospf_routemap_unset (red); - return ospf_redistribute_default_unset (ospf); + ospf_routemap_unset(red); + return ospf_redistribute_default_unset(ospf); } DEFUN (ospf_default_metric, @@ -7332,16 +7347,16 @@ DEFUN (ospf_default_metric, "Set metric of redistributed routes\n" "Default metric\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_number = 1; - int metric = -1; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_number = 1; + int metric = -1; - if (!str2metric (argv[idx_number]->arg, &metric)) - return CMD_WARNING_CONFIG_FAILED; + if (!str2metric(argv[idx_number]->arg, &metric)) + return CMD_WARNING_CONFIG_FAILED; - ospf->default_metric = metric; + ospf->default_metric = metric; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ospf_default_metric, @@ -7351,11 +7366,11 @@ DEFUN (no_ospf_default_metric, "Set metric of redistributed routes\n" "Default metric\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); + VTY_DECLVAR_CONTEXT(ospf, ospf); - ospf->default_metric = -1; + ospf->default_metric = -1; - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -7365,12 +7380,12 @@ DEFUN (ospf_distance, "Administrative distance\n" "OSPF Administrative distance\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_number = 1; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_number = 1; - ospf->distance_all = atoi (argv[idx_number]->arg); + ospf->distance_all = atoi(argv[idx_number]->arg); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ospf_distance, @@ -7380,11 +7395,11 @@ DEFUN (no_ospf_distance, "Administrative distance\n" "OSPF Administrative distance\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); + VTY_DECLVAR_CONTEXT(ospf, ospf); - ospf->distance_all = 0; + ospf->distance_all = 0; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ospf_distance_ospf, @@ -7400,20 +7415,20 @@ DEFUN (no_ospf_distance_ospf, "External routes\n" "Distance for external routes\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx = 0; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx = 0; - if (!ospf) - return CMD_SUCCESS; + if (!ospf) + return CMD_SUCCESS; - if (argv_find (argv, argc, "intra-area", &idx) || argc == 3) - idx = ospf->distance_intra = 0; - if (argv_find (argv, argc, "inter-area", &idx) || argc == 3) - idx = ospf->distance_inter = 0; - if (argv_find (argv, argc, "external", &idx) || argc == 3) - ospf->distance_external = 0; + if (argv_find(argv, argc, "intra-area", &idx) || argc == 3) + idx = ospf->distance_intra = 0; + if (argv_find(argv, argc, "inter-area", &idx) || argc == 3) + idx = ospf->distance_inter = 0; + if (argv_find(argv, argc, "external", &idx) || argc == 3) + ospf->distance_external = 0; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (ospf_distance_ospf, @@ -7428,19 +7443,19 @@ DEFUN (ospf_distance_ospf, "External routes\n" "Distance for external routes\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx = 0; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx = 0; - if (argv_find (argv, argc, "intra-area", &idx)) - ospf->distance_intra = atoi(argv[idx + 1]->arg); - idx = 0; - if (argv_find (argv, argc, "inter-area", &idx)) - ospf->distance_inter = atoi(argv[idx + 1]->arg); - idx = 0; - if (argv_find (argv, argc, "external", &idx)) - ospf->distance_external = atoi(argv[idx + 1]->arg); + if (argv_find(argv, argc, "intra-area", &idx)) + ospf->distance_intra = atoi(argv[idx + 1]->arg); + idx = 0; + if (argv_find(argv, argc, "inter-area", &idx)) + ospf->distance_inter = atoi(argv[idx + 1]->arg); + idx = 0; + if (argv_find(argv, argc, "external", &idx)) + ospf->distance_external = atoi(argv[idx + 1]->arg); - return CMD_SUCCESS; + return CMD_SUCCESS; } #if 0 @@ -7535,38 +7550,35 @@ DEFUN (ip_ospf_mtu_ignore, "Disable MTU mismatch detection on this interface\n" "Address of interface") { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx_ipv4 = 3; - struct in_addr addr; - int ret; - - struct ospf_if_params *params; - params = IF_DEF_PARAMS (ifp); - - if (argc == 4) - { - ret = inet_aton(argv[idx_ipv4]->arg, &addr); - if (!ret) - { - vty_out (vty, "Please specify interface address by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; - } - params = ospf_get_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - } - params->mtu_ignore = 1; - if (params->mtu_ignore != OSPF_MTU_IGNORE_DEFAULT) - SET_IF_PARAM (params, mtu_ignore); - else - { - UNSET_IF_PARAM (params, mtu_ignore); - if (params != IF_DEF_PARAMS (ifp)) - { - ospf_free_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - } - } - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx_ipv4 = 3; + struct in_addr addr; + int ret; + + struct ospf_if_params *params; + params = IF_DEF_PARAMS(ifp); + + if (argc == 4) { + ret = inet_aton(argv[idx_ipv4]->arg, &addr); + if (!ret) { + vty_out(vty, + "Please specify interface address by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } + params = ospf_get_if_params(ifp, addr); + ospf_if_update_params(ifp, addr); + } + params->mtu_ignore = 1; + if (params->mtu_ignore != OSPF_MTU_IGNORE_DEFAULT) + SET_IF_PARAM(params, mtu_ignore); + else { + UNSET_IF_PARAM(params, mtu_ignore); + if (params != IF_DEF_PARAMS(ifp)) { + ospf_free_if_params(ifp, addr); + ospf_if_update_params(ifp, addr); + } + } + return CMD_SUCCESS; } DEFUN (no_ip_ospf_mtu_ignore, @@ -7577,38 +7589,35 @@ DEFUN (no_ip_ospf_mtu_ignore, "Disable MTU mismatch detection on this interface\n" "Address of interface") { - VTY_DECLVAR_CONTEXT(interface, ifp); - int idx_ipv4 = 4; - struct in_addr addr; - int ret; - - struct ospf_if_params *params; - params = IF_DEF_PARAMS (ifp); - - if (argc == 5) - { - ret = inet_aton(argv[idx_ipv4]->arg, &addr); - if (!ret) - { - vty_out (vty, "Please specify interface address by A.B.C.D\n"); - return CMD_WARNING_CONFIG_FAILED; - } - params = ospf_get_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - } - params->mtu_ignore = 0; - if (params->mtu_ignore != OSPF_MTU_IGNORE_DEFAULT) - SET_IF_PARAM (params, mtu_ignore); - else - { - UNSET_IF_PARAM (params, mtu_ignore); - if (params != IF_DEF_PARAMS (ifp)) - { - ospf_free_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - } - } - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(interface, ifp); + int idx_ipv4 = 4; + struct in_addr addr; + int ret; + + struct ospf_if_params *params; + params = IF_DEF_PARAMS(ifp); + + if (argc == 5) { + ret = inet_aton(argv[idx_ipv4]->arg, &addr); + if (!ret) { + vty_out(vty, + "Please specify interface address by A.B.C.D\n"); + return CMD_WARNING_CONFIG_FAILED; + } + params = ospf_get_if_params(ifp, addr); + ospf_if_update_params(ifp, addr); + } + params->mtu_ignore = 0; + if (params->mtu_ignore != OSPF_MTU_IGNORE_DEFAULT) + SET_IF_PARAM(params, mtu_ignore); + else { + UNSET_IF_PARAM(params, mtu_ignore); + if (params != IF_DEF_PARAMS(ifp)) { + ospf_free_if_params(ifp, addr); + ospf_if_update_params(ifp, addr); + } + } + return CMD_SUCCESS; } @@ -7619,22 +7628,22 @@ DEFUN (ospf_max_metric_router_lsa_admin, "Advertise own Router-LSA with infinite distance (stub router)\n" "Administratively applied, for an indefinite period\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - struct listnode *ln; - struct ospf_area *area; + VTY_DECLVAR_CONTEXT(ospf, ospf); + struct listnode *ln; + struct ospf_area *area; - for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area)) - { - SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED); - - if (!CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED)) - ospf_router_lsa_update_area (area); - } + for (ALL_LIST_ELEMENTS_RO(ospf->areas, ln, area)) { + SET_FLAG(area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED); - /* Allows for areas configured later to get the property */ - ospf->stub_router_admin_set = OSPF_STUB_ROUTER_ADMINISTRATIVE_SET; + if (!CHECK_FLAG(area->stub_router_state, + OSPF_AREA_IS_STUB_ROUTED)) + ospf_router_lsa_update_area(area); + } - return CMD_SUCCESS; + /* Allows for areas configured later to get the property */ + ospf->stub_router_admin_set = OSPF_STUB_ROUTER_ADMINISTRATIVE_SET; + + return CMD_SUCCESS; } DEFUN (no_ospf_max_metric_router_lsa_admin, @@ -7645,24 +7654,25 @@ DEFUN (no_ospf_max_metric_router_lsa_admin, "Advertise own Router-LSA with infinite distance (stub router)\n" "Administratively applied, for an indefinite period\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - struct listnode *ln; - struct ospf_area *area; - - for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area)) - { - UNSET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED); - - /* Don't trample on the start-up stub timer */ - if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED) - && !area->t_stub_router) - { - UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED); - ospf_router_lsa_update_area (area); - } - } - ospf->stub_router_admin_set = OSPF_STUB_ROUTER_ADMINISTRATIVE_UNSET; - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(ospf, ospf); + struct listnode *ln; + struct ospf_area *area; + + for (ALL_LIST_ELEMENTS_RO(ospf->areas, ln, area)) { + UNSET_FLAG(area->stub_router_state, + OSPF_AREA_ADMIN_STUB_ROUTED); + + /* Don't trample on the start-up stub timer */ + if (CHECK_FLAG(area->stub_router_state, + OSPF_AREA_IS_STUB_ROUTED) + && !area->t_stub_router) { + UNSET_FLAG(area->stub_router_state, + OSPF_AREA_IS_STUB_ROUTED); + ospf_router_lsa_update_area(area); + } + } + ospf->stub_router_admin_set = OSPF_STUB_ROUTER_ADMINISTRATIVE_UNSET; + return CMD_SUCCESS; } DEFUN (ospf_max_metric_router_lsa_startup, @@ -7673,21 +7683,20 @@ DEFUN (ospf_max_metric_router_lsa_startup, "Automatically advertise stub Router-LSA on startup of OSPF\n" "Time (seconds) to advertise self as stub-router\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_number = 3; - unsigned int seconds; - - if (argc != 1) - { - vty_out (vty, "%% Must supply stub-router period"); - return CMD_WARNING_CONFIG_FAILED; - } - - seconds = strtoul(argv[idx_number]->arg, NULL, 10); - - ospf->stub_router_startup_time = seconds; - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_number = 3; + unsigned int seconds; + + if (argc != 1) { + vty_out(vty, "%% Must supply stub-router period"); + return CMD_WARNING_CONFIG_FAILED; + } + + seconds = strtoul(argv[idx_number]->arg, NULL, 10); + + ospf->stub_router_startup_time = seconds; + + return CMD_SUCCESS; } DEFUN (no_ospf_max_metric_router_lsa_startup, @@ -7699,25 +7708,26 @@ DEFUN (no_ospf_max_metric_router_lsa_startup, "Automatically advertise stub Router-LSA on startup of OSPF\n" "Time (seconds) to advertise self as stub-router\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - struct listnode *ln; - struct ospf_area *area; - - ospf->stub_router_startup_time = OSPF_STUB_ROUTER_UNCONFIGURED; - - for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area)) - { - SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED); - OSPF_TIMER_OFF (area->t_stub_router); - - /* Don't trample on admin stub routed */ - if (!CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED)) - { - UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED); - ospf_router_lsa_update_area (area); - } - } - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(ospf, ospf); + struct listnode *ln; + struct ospf_area *area; + + ospf->stub_router_startup_time = OSPF_STUB_ROUTER_UNCONFIGURED; + + for (ALL_LIST_ELEMENTS_RO(ospf->areas, ln, area)) { + SET_FLAG(area->stub_router_state, + OSPF_AREA_WAS_START_STUB_ROUTED); + OSPF_TIMER_OFF(area->t_stub_router); + + /* Don't trample on admin stub routed */ + if (!CHECK_FLAG(area->stub_router_state, + OSPF_AREA_ADMIN_STUB_ROUTED)) { + UNSET_FLAG(area->stub_router_state, + OSPF_AREA_IS_STUB_ROUTED); + ospf_router_lsa_update_area(area); + } + } + return CMD_SUCCESS; } @@ -7729,21 +7739,20 @@ DEFUN (ospf_max_metric_router_lsa_shutdown, "Advertise stub-router prior to full shutdown of OSPF\n" "Time (seconds) to wait till full shutdown\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); - int idx_number = 3; - unsigned int seconds; - - if (argc != 1) - { - vty_out (vty, "%% Must supply stub-router shutdown period"); - return CMD_WARNING_CONFIG_FAILED; - } - - seconds = strtoul(argv[idx_number]->arg, NULL, 10); - - ospf->stub_router_shutdown_time = seconds; - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(ospf, ospf); + int idx_number = 3; + unsigned int seconds; + + if (argc != 1) { + vty_out(vty, "%% Must supply stub-router shutdown period"); + return CMD_WARNING_CONFIG_FAILED; + } + + seconds = strtoul(argv[idx_number]->arg, NULL, 10); + + ospf->stub_router_shutdown_time = seconds; + + return CMD_SUCCESS; } DEFUN (no_ospf_max_metric_router_lsa_shutdown, @@ -7755,203 +7764,236 @@ DEFUN (no_ospf_max_metric_router_lsa_shutdown, "Advertise stub-router prior to full shutdown of OSPF\n" "Time (seconds) to wait till full shutdown\n") { - VTY_DECLVAR_CONTEXT(ospf, ospf); + VTY_DECLVAR_CONTEXT(ospf, ospf); - ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED; - - return CMD_SUCCESS; + ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED; + + return CMD_SUCCESS; } -static void -config_write_stub_router (struct vty *vty, struct ospf *ospf) -{ - struct listnode *ln; - struct ospf_area *area; - - if (ospf->stub_router_startup_time != OSPF_STUB_ROUTER_UNCONFIGURED) - vty_out (vty, " max-metric router-lsa on-startup %u\n", - ospf->stub_router_startup_time); - if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED) - vty_out (vty, " max-metric router-lsa on-shutdown %u\n", - ospf->stub_router_shutdown_time); - for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area)) - { - if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED)) - { - vty_out (vty, " max-metric router-lsa administrative\n"); - break; - } - } - return; -} - -static void -show_ip_ospf_route_network (struct vty *vty, struct route_table *rt) -{ - struct route_node *rn; - struct ospf_route *or; - struct listnode *pnode, *pnnode; - struct ospf_path *path; - - vty_out (vty, "============ OSPF network routing table ============\n"); - - for (rn = route_top (rt); rn; rn = route_next (rn)) - if ((or = rn->info) != NULL) - { - char buf1[19]; - snprintf (buf1, 19, "%s/%d", - inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen); - - switch (or->path_type) - { - case OSPF_PATH_INTER_AREA: - if (or->type == OSPF_DESTINATION_NETWORK) - vty_out (vty, "N IA %-18s [%d] area: %s\n", buf1, or->cost, - inet_ntoa (or->u.std.area_id)); - else if (or->type == OSPF_DESTINATION_DISCARD) - vty_out (vty, "D IA %-18s Discard entry\n", buf1); - break; - case OSPF_PATH_INTRA_AREA: - vty_out (vty, "N %-18s [%d] area: %s\n", buf1, or->cost, - inet_ntoa (or->u.std.area_id)); - break; - default: - break; - } - - if (or->type == OSPF_DESTINATION_NETWORK) - for (ALL_LIST_ELEMENTS (or->paths, pnode, pnnode, path)) - { - if (if_lookup_by_index(path->ifindex, VRF_DEFAULT)) - { - if (path->nexthop.s_addr == 0) - vty_out (vty, "%24s directly attached to %s\n", - "", ifindex2ifname (path->ifindex, VRF_DEFAULT)); - else - vty_out (vty, "%24s via %s, %s\n", "", - inet_ntoa (path->nexthop), - ifindex2ifname (path->ifindex, VRF_DEFAULT)); - } - } - } - vty_out (vty, "\n"); -} - -static void -show_ip_ospf_route_router (struct vty *vty, struct route_table *rtrs) -{ - struct route_node *rn; - struct ospf_route *or; - struct listnode *pnode; - struct listnode *node; - struct ospf_path *path; - - vty_out (vty, "============ OSPF router routing table =============\n"); - for (rn = route_top (rtrs); rn; rn = route_next (rn)) - if (rn->info) - { - int flag = 0; - - vty_out (vty, "R %-15s ", inet_ntoa (rn->p.u.prefix4)); - - for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, or)) - { - if (flag++) - vty_out (vty, "%24s", ""); - - /* Show path. */ - vty_out (vty, "%s [%d] area: %s", - (or->path_type == OSPF_PATH_INTER_AREA ? "IA" : " "), - or->cost, inet_ntoa (or->u.std.area_id)); - /* Show flags. */ - vty_out (vty, "%s%s\n", - (or->u.std.flags & ROUTER_LSA_BORDER ? ", ABR" : ""), - (or->u.std.flags & ROUTER_LSA_EXTERNAL ? ", ASBR" : "")); - - for (ALL_LIST_ELEMENTS_RO (or->paths, pnode, path)) - { - if (if_lookup_by_index(path->ifindex, VRF_DEFAULT)) - { - if (path->nexthop.s_addr == 0) - vty_out (vty, "%24s directly attached to %s\n", - "", ifindex2ifname (path->ifindex, VRF_DEFAULT)); - else - vty_out (vty, "%24s via %s, %s\n", "", - inet_ntoa (path->nexthop), - ifindex2ifname (path->ifindex, VRF_DEFAULT)); +static void config_write_stub_router(struct vty *vty, struct ospf *ospf) +{ + struct listnode *ln; + struct ospf_area *area; + + if (ospf->stub_router_startup_time != OSPF_STUB_ROUTER_UNCONFIGURED) + vty_out(vty, " max-metric router-lsa on-startup %u\n", + ospf->stub_router_startup_time); + if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED) + vty_out(vty, " max-metric router-lsa on-shutdown %u\n", + ospf->stub_router_shutdown_time); + for (ALL_LIST_ELEMENTS_RO(ospf->areas, ln, area)) { + if (CHECK_FLAG(area->stub_router_state, + OSPF_AREA_ADMIN_STUB_ROUTED)) { + vty_out(vty, " max-metric router-lsa administrative\n"); + break; + } + } + return; +} + +static void show_ip_ospf_route_network(struct vty *vty, struct route_table *rt) +{ + struct route_node *rn; + struct ospf_route * or ; + struct listnode *pnode, *pnnode; + struct ospf_path *path; + + vty_out(vty, "============ OSPF network routing table ============\n"); + + for (rn = route_top(rt); rn; rn = route_next(rn)) + if ((or = rn->info) != NULL) { + char buf1[19]; + snprintf(buf1, 19, "%s/%d", inet_ntoa(rn->p.u.prefix4), + rn->p.prefixlen); + + switch (or->path_type) { + case OSPF_PATH_INTER_AREA: + if (or->type == OSPF_DESTINATION_NETWORK) + vty_out(vty, + "N IA %-18s [%d] area: %s\n", + buf1, or->cost, + inet_ntoa(or->u.std.area_id)); + else if (or->type == OSPF_DESTINATION_DISCARD) + vty_out(vty, + "D IA %-18s Discard entry\n", + buf1); + break; + case OSPF_PATH_INTRA_AREA: + vty_out(vty, "N %-18s [%d] area: %s\n", + buf1, or->cost, + inet_ntoa(or->u.std.area_id)); + break; + default: + break; + } + + if (or->type == OSPF_DESTINATION_NETWORK) + for (ALL_LIST_ELEMENTS(or->paths, pnode, pnnode, + path)) { + if (if_lookup_by_index(path->ifindex, + VRF_DEFAULT)) { + if (path->nexthop.s_addr == 0) + vty_out(vty, + "%24s directly attached to %s\n", + "", + ifindex2ifname( + path->ifindex, + VRF_DEFAULT)); + else + vty_out(vty, + "%24s via %s, %s\n", + "", + inet_ntoa( + path->nexthop), + ifindex2ifname( + path->ifindex, + VRF_DEFAULT)); + } + } + } + vty_out(vty, "\n"); +} + +static void show_ip_ospf_route_router(struct vty *vty, struct route_table *rtrs) +{ + struct route_node *rn; + struct ospf_route * or ; + struct listnode *pnode; + struct listnode *node; + struct ospf_path *path; + + vty_out(vty, "============ OSPF router routing table =============\n"); + for (rn = route_top(rtrs); rn; rn = route_next(rn)) + if (rn->info) { + int flag = 0; + + vty_out(vty, "R %-15s ", + inet_ntoa(rn->p.u.prefix4)); + + for (ALL_LIST_ELEMENTS_RO((struct list *)rn->info, node, + or)) { + if (flag++) + vty_out(vty, "%24s", ""); + + /* Show path. */ + vty_out(vty, "%s [%d] area: %s", + (or->path_type == OSPF_PATH_INTER_AREA + ? "IA" + : " "), + or->cost, inet_ntoa(or->u.std.area_id)); + /* Show flags. */ + vty_out(vty, "%s%s\n", + (or->u.std.flags & ROUTER_LSA_BORDER + ? ", ABR" + : ""), + (or->u.std.flags & ROUTER_LSA_EXTERNAL + ? ", ASBR" + : "")); + + for (ALL_LIST_ELEMENTS_RO(or->paths, pnode, + path)) { + if (if_lookup_by_index(path->ifindex, + VRF_DEFAULT)) { + if (path->nexthop.s_addr == 0) + vty_out(vty, + "%24s directly attached to %s\n", + "", + ifindex2ifname( + path->ifindex, + VRF_DEFAULT)); + else + vty_out(vty, + "%24s via %s, %s\n", + "", + inet_ntoa( + path->nexthop), + ifindex2ifname( + path->ifindex, + VRF_DEFAULT)); + } + } + } + } + vty_out(vty, "\n"); +} + +static void show_ip_ospf_route_external(struct vty *vty, struct route_table *rt) +{ + struct route_node *rn; + struct ospf_route *er; + struct listnode *pnode, *pnnode; + struct ospf_path *path; + + vty_out(vty, "============ OSPF external routing table ===========\n"); + for (rn = route_top(rt); rn; rn = route_next(rn)) + if ((er = rn->info) != NULL) { + char buf1[19]; + snprintf(buf1, 19, "%s/%d", inet_ntoa(rn->p.u.prefix4), + rn->p.prefixlen); + + switch (er->path_type) { + case OSPF_PATH_TYPE1_EXTERNAL: + vty_out(vty, + "N E1 %-18s [%d] tag: %" ROUTE_TAG_PRI + "\n", + buf1, er->cost, er->u.ext.tag); + break; + case OSPF_PATH_TYPE2_EXTERNAL: + vty_out(vty, + "N E2 %-18s [%d/%d] tag: %" ROUTE_TAG_PRI + "\n", + buf1, er->cost, er->u.ext.type2_cost, + er->u.ext.tag); + break; + } + + for (ALL_LIST_ELEMENTS(er->paths, pnode, pnnode, + path)) { + if (if_lookup_by_index(path->ifindex, + VRF_DEFAULT)) { + if (path->nexthop.s_addr == 0) + vty_out(vty, + "%24s directly attached to %s\n", + "", + ifindex2ifname( + path->ifindex, + VRF_DEFAULT)); + else + vty_out(vty, + "%24s via %s, %s\n", + "", + inet_ntoa( + path->nexthop), + ifindex2ifname( + path->ifindex, + VRF_DEFAULT)); + } } - } - } - } - vty_out (vty, "\n"); -} - -static void -show_ip_ospf_route_external (struct vty *vty, struct route_table *rt) -{ - struct route_node *rn; - struct ospf_route *er; - struct listnode *pnode, *pnnode; - struct ospf_path *path; - - vty_out (vty, "============ OSPF external routing table ===========\n"); - for (rn = route_top (rt); rn; rn = route_next (rn)) - if ((er = rn->info) != NULL) - { - char buf1[19]; - snprintf (buf1, 19, "%s/%d", - inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen); - - switch (er->path_type) - { - case OSPF_PATH_TYPE1_EXTERNAL: - vty_out (vty, "N E1 %-18s [%d] tag: %"ROUTE_TAG_PRI"\n", buf1, - er->cost, er->u.ext.tag); - break; - case OSPF_PATH_TYPE2_EXTERNAL: - vty_out (vty, "N E2 %-18s [%d/%d] tag: %"ROUTE_TAG_PRI"\n", buf1, er->cost, - er->u.ext.type2_cost, er->u.ext.tag); - break; - } - - for (ALL_LIST_ELEMENTS (er->paths, pnode, pnnode, path)) - { - if (if_lookup_by_index(path->ifindex, VRF_DEFAULT)) - { - if (path->nexthop.s_addr == 0) - vty_out (vty, "%24s directly attached to %s\n", - "", ifindex2ifname (path->ifindex, VRF_DEFAULT)); - else - vty_out (vty, "%24s via %s, %s\n", "", - inet_ntoa (path->nexthop), - ifindex2ifname (path->ifindex, VRF_DEFAULT)); - } - } - } - vty_out (vty, "\n"); + } + vty_out(vty, "\n"); } -static int -show_ip_ospf_border_routers_common (struct vty *vty, struct ospf *ospf) +static int show_ip_ospf_border_routers_common(struct vty *vty, + struct ospf *ospf) { - if (ospf->instance) - vty_out (vty, "\nOSPF Instance: %d\n\n", ospf->instance); + if (ospf->instance) + vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); - if (ospf->new_table == NULL) - { - vty_out (vty, "No OSPF routing information exist\n"); - return CMD_SUCCESS; - } + if (ospf->new_table == NULL) { + vty_out(vty, "No OSPF routing information exist\n"); + return CMD_SUCCESS; + } - /* Show Network routes. - show_ip_ospf_route_network (vty, ospf->new_table); */ + /* Show Network routes. + show_ip_ospf_route_network (vty, ospf->new_table); */ - /* Show Router routes. */ - show_ip_ospf_route_router (vty, ospf->new_rtrs); + /* Show Router routes. */ + show_ip_ospf_route_router(vty, ospf->new_rtrs); - vty_out (vty, "\n"); + vty_out(vty, "\n"); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (show_ip_ospf_border_routers, @@ -7962,12 +8004,12 @@ DEFUN (show_ip_ospf_border_routers, "OSPF information\n" "Show all the ABR's and ASBR's\n") { - struct ospf *ospf; + struct ospf *ospf; - if ((ospf = ospf_lookup ()) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) + return CMD_SUCCESS; - return show_ip_ospf_border_routers_common(vty, ospf); + return show_ip_ospf_border_routers_common(vty, ospf); } DEFUN (show_ip_ospf_instance_border_routers, @@ -7979,41 +8021,40 @@ DEFUN (show_ip_ospf_instance_border_routers, "Instance ID\n" "Show all the ABR's and ASBR's\n") { - int idx_number = 3; - struct ospf *ospf; - u_short instance = 0; + int idx_number = 3; + struct ospf *ospf; + u_short instance = 0; - instance = strtoul(argv[idx_number]->arg, NULL, 10); - if ((ospf = ospf_lookup_instance (instance)) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if ((ospf = ospf_lookup_instance(instance)) == NULL + || !ospf->oi_running) + return CMD_SUCCESS; - return show_ip_ospf_border_routers_common(vty, ospf); + return show_ip_ospf_border_routers_common(vty, ospf); } -static int -show_ip_ospf_route_common (struct vty *vty, struct ospf *ospf) +static int show_ip_ospf_route_common(struct vty *vty, struct ospf *ospf) { - if (ospf->instance) - vty_out (vty, "\nOSPF Instance: %d\n\n", ospf->instance); + if (ospf->instance) + vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); - if (ospf->new_table == NULL) - { - vty_out (vty, "No OSPF routing information exist\n"); - return CMD_SUCCESS; - } + if (ospf->new_table == NULL) { + vty_out(vty, "No OSPF routing information exist\n"); + return CMD_SUCCESS; + } - /* Show Network routes. */ - show_ip_ospf_route_network (vty, ospf->new_table); + /* Show Network routes. */ + show_ip_ospf_route_network(vty, ospf->new_table); - /* Show Router routes. */ - show_ip_ospf_route_router (vty, ospf->new_rtrs); + /* Show Router routes. */ + show_ip_ospf_route_router(vty, ospf->new_rtrs); - /* Show AS External routes. */ - show_ip_ospf_route_external (vty, ospf->old_external_route); + /* Show AS External routes. */ + show_ip_ospf_route_external(vty, ospf->old_external_route); - vty_out (vty, "\n"); + vty_out(vty, "\n"); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (show_ip_ospf_route, @@ -8024,12 +8065,12 @@ DEFUN (show_ip_ospf_route, "OSPF information\n" "OSPF routing table\n") { - struct ospf *ospf; + struct ospf *ospf; - if ((ospf = ospf_lookup ()) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running) + return CMD_SUCCESS; - return show_ip_ospf_route_common(vty, ospf); + return show_ip_ospf_route_common(vty, ospf); } DEFUN (show_ip_ospf_instance_route, @@ -8041,907 +8082,902 @@ DEFUN (show_ip_ospf_instance_route, "Instance ID\n" "OSPF routing table\n") { - int idx_number = 3; - struct ospf *ospf; - u_short instance = 0; + int idx_number = 3; + struct ospf *ospf; + u_short instance = 0; - instance = strtoul(argv[idx_number]->arg, NULL, 10); - if ((ospf = ospf_lookup_instance (instance)) == NULL || !ospf->oi_running) - return CMD_SUCCESS; + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if ((ospf = ospf_lookup_instance(instance)) == NULL + || !ospf->oi_running) + return CMD_SUCCESS; - return show_ip_ospf_route_common(vty, ospf); + return show_ip_ospf_route_common(vty, ospf); } -const char *ospf_abr_type_str[] = -{ - "unknown", - "standard", - "ibm", - "cisco", - "shortcut" -}; +const char *ospf_abr_type_str[] = {"unknown", "standard", "ibm", "cisco", + "shortcut"}; -const char *ospf_shortcut_mode_str[] = -{ - "default", - "enable", - "disable" -}; +const char *ospf_shortcut_mode_str[] = {"default", "enable", "disable"}; -const char *ospf_int_type_str[] = -{ - "unknown", /* should never be used. */ - "point-to-point", - "broadcast", - "non-broadcast", - "point-to-multipoint", - "virtual-link", /* should never be used. */ - "loopback" -}; +const char *ospf_int_type_str[] = {"unknown", /* should never be used. */ + "point-to-point", "broadcast", + "non-broadcast", "point-to-multipoint", + "virtual-link", /* should never be used. */ + "loopback"}; /* Configuration write function for ospfd. */ -static int -config_write_interface (struct vty *vty) -{ - struct listnode *n1, *n2; - struct interface *ifp; - struct crypt_key *ck; - int write = 0; - struct route_node *rn = NULL; - struct ospf_if_params *params; - struct ospf *ospf = ospf_lookup(); - - for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), n1, ifp)) - { - if (memcmp (ifp->name, "VLINK", 5) == 0) - continue; - - if (ifp->ifindex == IFINDEX_DELETED) - continue; - - vty_out (vty, "!\n"); - vty_out (vty, "interface %s\n", ifp->name); - if (ifp->desc) - vty_out (vty, " description %s\n", ifp->desc); - - write++; - - params = IF_DEF_PARAMS (ifp); - - do { - /* Interface Network print. */ - if (OSPF_IF_PARAM_CONFIGURED (params, type) && - params->type != OSPF_IFTYPE_LOOPBACK) - { - if (params->type != ospf_default_iftype(ifp)) - { - vty_out (vty, " ip ospf network %s", - ospf_int_type_str[params->type]); - if (params != IF_DEF_PARAMS (ifp)) - vty_out (vty, " %s", inet_ntoa (rn->p.u.prefix4)); - vty_out (vty, "\n"); - } - } - - /* OSPF interface authentication print */ - if (OSPF_IF_PARAM_CONFIGURED (params, auth_type) && - params->auth_type != OSPF_AUTH_NOTSET) - { - const char *auth_str; - - /* Translation tables are not that much help here due to syntax - of the simple option */ - switch (params->auth_type) - { - - case OSPF_AUTH_NULL: - auth_str = " null"; - break; - - case OSPF_AUTH_SIMPLE: - auth_str = ""; - break; - - case OSPF_AUTH_CRYPTOGRAPHIC: - auth_str = " message-digest"; - break; - - default: - auth_str = ""; - break; - } - - vty_out (vty, " ip ospf authentication%s", auth_str); - if (params != IF_DEF_PARAMS (ifp)) - vty_out (vty, " %s", inet_ntoa (rn->p.u.prefix4)); - vty_out (vty, "\n"); - } - - /* Simple Authentication Password print. */ - if (OSPF_IF_PARAM_CONFIGURED (params, auth_simple) && - params->auth_simple[0] != '\0') - { - vty_out (vty, " ip ospf authentication-key %s", - params->auth_simple); - if (params != IF_DEF_PARAMS (ifp)) - vty_out (vty, " %s", inet_ntoa (rn->p.u.prefix4)); - vty_out (vty, "\n"); - } - - /* Cryptographic Authentication Key print. */ - for (ALL_LIST_ELEMENTS_RO (params->auth_crypt, n2, ck)) - { - vty_out (vty, " ip ospf message-digest-key %d md5 %s", - ck->key_id, ck->auth_key); - if (params != IF_DEF_PARAMS (ifp)) - vty_out (vty, " %s", inet_ntoa (rn->p.u.prefix4)); - vty_out (vty, "\n"); - } - - /* Interface Output Cost print. */ - if (OSPF_IF_PARAM_CONFIGURED (params, output_cost_cmd)) - { - vty_out (vty, " ip ospf cost %u", params->output_cost_cmd); - if (params != IF_DEF_PARAMS (ifp)) - vty_out (vty, " %s", inet_ntoa (rn->p.u.prefix4)); - vty_out (vty, "\n"); - } - - /* Hello Interval print. */ - if (OSPF_IF_PARAM_CONFIGURED (params, v_hello) && - params->v_hello != OSPF_HELLO_INTERVAL_DEFAULT) - { - vty_out (vty, " ip ospf hello-interval %u", params->v_hello); - if (params != IF_DEF_PARAMS (ifp)) - vty_out (vty, " %s", inet_ntoa (rn->p.u.prefix4)); - vty_out (vty, "\n"); - } - - - /* Router Dead Interval print. */ - if (OSPF_IF_PARAM_CONFIGURED (params, v_wait) && - params->v_wait != OSPF_ROUTER_DEAD_INTERVAL_DEFAULT) - { - vty_out (vty, " ip ospf dead-interval "); - - /* fast hello ? */ - if (OSPF_IF_PARAM_CONFIGURED (params, fast_hello)) - vty_out (vty, "minimal hello-multiplier %d", - params->fast_hello); - else - vty_out (vty, "%u", params->v_wait); - - if (params != IF_DEF_PARAMS (ifp)) - vty_out (vty, " %s", inet_ntoa (rn->p.u.prefix4)); - vty_out (vty, "\n"); - } - - /* Router Priority print. */ - if (OSPF_IF_PARAM_CONFIGURED (params, priority) && - params->priority != OSPF_ROUTER_PRIORITY_DEFAULT) - { - vty_out (vty, " ip ospf priority %u", params->priority); - if (params != IF_DEF_PARAMS (ifp)) - vty_out (vty, " %s", inet_ntoa (rn->p.u.prefix4)); - vty_out (vty, "\n"); - } - - /* Retransmit Interval print. */ - if (OSPF_IF_PARAM_CONFIGURED (params, retransmit_interval) && - params->retransmit_interval != OSPF_RETRANSMIT_INTERVAL_DEFAULT) - { - vty_out (vty, " ip ospf retransmit-interval %u", - params->retransmit_interval); - if (params != IF_DEF_PARAMS (ifp)) - vty_out (vty, " %s", inet_ntoa (rn->p.u.prefix4)); - vty_out (vty, "\n"); - } - - /* Transmit Delay print. */ - if (OSPF_IF_PARAM_CONFIGURED (params, transmit_delay) && - params->transmit_delay != OSPF_TRANSMIT_DELAY_DEFAULT) - { - vty_out (vty, " ip ospf transmit-delay %u", params->transmit_delay); - if (params != IF_DEF_PARAMS (ifp)) - vty_out (vty, " %s", inet_ntoa (rn->p.u.prefix4)); - vty_out (vty, "\n"); - } - - /* Area print. */ - if (OSPF_IF_PARAM_CONFIGURED (params, if_area)) - { - if (ospf->instance) - vty_out (vty, " ip ospf %d", ospf->instance); - else - vty_out (vty, " ip ospf"); - - vty_out (vty, " area %s", inet_ntoa (params->if_area)); - if (params != IF_DEF_PARAMS (ifp)) - vty_out (vty, " %s", inet_ntoa (rn->p.u.prefix4)); - vty_out (vty, "\n"); - } - - /* bfd print. */ - ospf_bfd_write_config(vty, params); - - /* MTU ignore print. */ - if (OSPF_IF_PARAM_CONFIGURED (params, mtu_ignore) && - params->mtu_ignore != OSPF_MTU_IGNORE_DEFAULT) - { - if (params->mtu_ignore == 0) - vty_out (vty, " no ip ospf mtu-ignore"); - else - vty_out (vty, " ip ospf mtu-ignore"); - if (params != IF_DEF_PARAMS (ifp)) - vty_out (vty, " %s", inet_ntoa (rn->p.u.prefix4)); - vty_out (vty, "\n"); - } - - - while (1) - { - if (rn == NULL) - rn = route_top (IF_OIFS_PARAMS (ifp)); - else - rn = route_next (rn); - - if (rn == NULL) - break; - params = rn->info; - if (params != NULL) - break; - } - } while (rn); - - ospf_opaque_config_write_if (vty, ifp); - } - - return write; +static int config_write_interface(struct vty *vty) +{ + struct listnode *n1, *n2; + struct interface *ifp; + struct crypt_key *ck; + int write = 0; + struct route_node *rn = NULL; + struct ospf_if_params *params; + struct ospf *ospf = ospf_lookup(); + + for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), n1, ifp)) { + if (memcmp(ifp->name, "VLINK", 5) == 0) + continue; + + if (ifp->ifindex == IFINDEX_DELETED) + continue; + + vty_out(vty, "!\n"); + vty_out(vty, "interface %s\n", ifp->name); + if (ifp->desc) + vty_out(vty, " description %s\n", ifp->desc); + + write++; + + params = IF_DEF_PARAMS(ifp); + + do { + /* Interface Network print. */ + if (OSPF_IF_PARAM_CONFIGURED(params, type) + && params->type != OSPF_IFTYPE_LOOPBACK) { + if (params->type != ospf_default_iftype(ifp)) { + vty_out(vty, " ip ospf network %s", + ospf_int_type_str + [params->type]); + if (params != IF_DEF_PARAMS(ifp)) + vty_out(vty, " %s", + inet_ntoa( + rn->p.u.prefix4)); + vty_out(vty, "\n"); + } + } + + /* OSPF interface authentication print */ + if (OSPF_IF_PARAM_CONFIGURED(params, auth_type) + && params->auth_type != OSPF_AUTH_NOTSET) { + const char *auth_str; + + /* Translation tables are not that much help + here due to syntax + of the simple option */ + switch (params->auth_type) { + + case OSPF_AUTH_NULL: + auth_str = " null"; + break; + + case OSPF_AUTH_SIMPLE: + auth_str = ""; + break; + + case OSPF_AUTH_CRYPTOGRAPHIC: + auth_str = " message-digest"; + break; + + default: + auth_str = ""; + break; + } + + vty_out(vty, " ip ospf authentication%s", + auth_str); + if (params != IF_DEF_PARAMS(ifp)) + vty_out(vty, " %s", + inet_ntoa(rn->p.u.prefix4)); + vty_out(vty, "\n"); + } + + /* Simple Authentication Password print. */ + if (OSPF_IF_PARAM_CONFIGURED(params, auth_simple) + && params->auth_simple[0] != '\0') { + vty_out(vty, " ip ospf authentication-key %s", + params->auth_simple); + if (params != IF_DEF_PARAMS(ifp)) + vty_out(vty, " %s", + inet_ntoa(rn->p.u.prefix4)); + vty_out(vty, "\n"); + } + + /* Cryptographic Authentication Key print. */ + for (ALL_LIST_ELEMENTS_RO(params->auth_crypt, n2, ck)) { + vty_out(vty, + " ip ospf message-digest-key %d md5 %s", + ck->key_id, ck->auth_key); + if (params != IF_DEF_PARAMS(ifp)) + vty_out(vty, " %s", + inet_ntoa(rn->p.u.prefix4)); + vty_out(vty, "\n"); + } + + /* Interface Output Cost print. */ + if (OSPF_IF_PARAM_CONFIGURED(params, output_cost_cmd)) { + vty_out(vty, " ip ospf cost %u", + params->output_cost_cmd); + if (params != IF_DEF_PARAMS(ifp)) + vty_out(vty, " %s", + inet_ntoa(rn->p.u.prefix4)); + vty_out(vty, "\n"); + } + + /* Hello Interval print. */ + if (OSPF_IF_PARAM_CONFIGURED(params, v_hello) + && params->v_hello != OSPF_HELLO_INTERVAL_DEFAULT) { + vty_out(vty, " ip ospf hello-interval %u", + params->v_hello); + if (params != IF_DEF_PARAMS(ifp)) + vty_out(vty, " %s", + inet_ntoa(rn->p.u.prefix4)); + vty_out(vty, "\n"); + } + + + /* Router Dead Interval print. */ + if (OSPF_IF_PARAM_CONFIGURED(params, v_wait) + && params->v_wait + != OSPF_ROUTER_DEAD_INTERVAL_DEFAULT) { + vty_out(vty, " ip ospf dead-interval "); + + /* fast hello ? */ + if (OSPF_IF_PARAM_CONFIGURED(params, + fast_hello)) + vty_out(vty, + "minimal hello-multiplier %d", + params->fast_hello); + else + vty_out(vty, "%u", params->v_wait); + + if (params != IF_DEF_PARAMS(ifp)) + vty_out(vty, " %s", + inet_ntoa(rn->p.u.prefix4)); + vty_out(vty, "\n"); + } + + /* Router Priority print. */ + if (OSPF_IF_PARAM_CONFIGURED(params, priority) + && params->priority + != OSPF_ROUTER_PRIORITY_DEFAULT) { + vty_out(vty, " ip ospf priority %u", + params->priority); + if (params != IF_DEF_PARAMS(ifp)) + vty_out(vty, " %s", + inet_ntoa(rn->p.u.prefix4)); + vty_out(vty, "\n"); + } + + /* Retransmit Interval print. */ + if (OSPF_IF_PARAM_CONFIGURED(params, + retransmit_interval) + && params->retransmit_interval + != OSPF_RETRANSMIT_INTERVAL_DEFAULT) { + vty_out(vty, " ip ospf retransmit-interval %u", + params->retransmit_interval); + if (params != IF_DEF_PARAMS(ifp)) + vty_out(vty, " %s", + inet_ntoa(rn->p.u.prefix4)); + vty_out(vty, "\n"); + } + + /* Transmit Delay print. */ + if (OSPF_IF_PARAM_CONFIGURED(params, transmit_delay) + && params->transmit_delay + != OSPF_TRANSMIT_DELAY_DEFAULT) { + vty_out(vty, " ip ospf transmit-delay %u", + params->transmit_delay); + if (params != IF_DEF_PARAMS(ifp)) + vty_out(vty, " %s", + inet_ntoa(rn->p.u.prefix4)); + vty_out(vty, "\n"); + } + + /* Area print. */ + if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) { + if (ospf->instance) + vty_out(vty, " ip ospf %d", + ospf->instance); + else + vty_out(vty, " ip ospf"); + + vty_out(vty, " area %s", + inet_ntoa(params->if_area)); + if (params != IF_DEF_PARAMS(ifp)) + vty_out(vty, " %s", + inet_ntoa(rn->p.u.prefix4)); + vty_out(vty, "\n"); + } + + /* bfd print. */ + ospf_bfd_write_config(vty, params); + + /* MTU ignore print. */ + if (OSPF_IF_PARAM_CONFIGURED(params, mtu_ignore) + && params->mtu_ignore != OSPF_MTU_IGNORE_DEFAULT) { + if (params->mtu_ignore == 0) + vty_out(vty, " no ip ospf mtu-ignore"); + else + vty_out(vty, " ip ospf mtu-ignore"); + if (params != IF_DEF_PARAMS(ifp)) + vty_out(vty, " %s", + inet_ntoa(rn->p.u.prefix4)); + vty_out(vty, "\n"); + } + + + while (1) { + if (rn == NULL) + rn = route_top(IF_OIFS_PARAMS(ifp)); + else + rn = route_next(rn); + + if (rn == NULL) + break; + params = rn->info; + if (params != NULL) + break; + } + } while (rn); + + ospf_opaque_config_write_if(vty, ifp); + } + + return write; } -static int -config_write_network_area (struct vty *vty, struct ospf *ospf) +static int config_write_network_area(struct vty *vty, struct ospf *ospf) { - struct route_node *rn; - u_char buf[INET_ADDRSTRLEN]; + struct route_node *rn; + u_char buf[INET_ADDRSTRLEN]; - /* `network area' print. */ - for (rn = route_top (ospf->networks); rn; rn = route_next (rn)) - if (rn->info) - { - struct ospf_network *n = rn->info; + /* `network area' print. */ + for (rn = route_top(ospf->networks); rn; rn = route_next(rn)) + if (rn->info) { + struct ospf_network *n = rn->info; - memset (buf, 0, INET_ADDRSTRLEN); + memset(buf, 0, INET_ADDRSTRLEN); - /* Create Area ID string by specified Area ID format. */ - if (n->area_id_fmt == OSPF_AREA_ID_FMT_DOTTEDQUAD) - strncpy ((char *) buf, inet_ntoa (n->area_id), INET_ADDRSTRLEN); - else - sprintf ((char *) buf, "%lu", - (unsigned long int) ntohl (n->area_id.s_addr)); + /* Create Area ID string by specified Area ID format. */ + if (n->area_id_fmt == OSPF_AREA_ID_FMT_DOTTEDQUAD) + strncpy((char *)buf, inet_ntoa(n->area_id), + INET_ADDRSTRLEN); + else + sprintf((char *)buf, "%lu", + (unsigned long int)ntohl( + n->area_id.s_addr)); - /* Network print. */ - vty_out (vty, " network %s/%d area %s\n", - inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen, - buf); - } + /* Network print. */ + vty_out(vty, " network %s/%d area %s\n", + inet_ntoa(rn->p.u.prefix4), rn->p.prefixlen, + buf); + } - return 0; + return 0; } -static int -config_write_ospf_area (struct vty *vty, struct ospf *ospf) +static int config_write_ospf_area(struct vty *vty, struct ospf *ospf) { - struct listnode *node; - struct ospf_area *area; - u_char buf[INET_ADDRSTRLEN]; + struct listnode *node; + struct ospf_area *area; + u_char buf[INET_ADDRSTRLEN]; - /* Area configuration print. */ - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - struct route_node *rn1; + /* Area configuration print. */ + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + struct route_node *rn1; - area_id2str ((char *) buf, INET_ADDRSTRLEN, &area->area_id, - area->area_id_fmt); + area_id2str((char *)buf, INET_ADDRSTRLEN, &area->area_id, + area->area_id_fmt); - if (area->auth_type != OSPF_AUTH_NULL) - { - if (area->auth_type == OSPF_AUTH_SIMPLE) - vty_out (vty, " area %s authentication\n", buf); - else - vty_out (vty, " area %s authentication message-digest\n", - buf); - } + if (area->auth_type != OSPF_AUTH_NULL) { + if (area->auth_type == OSPF_AUTH_SIMPLE) + vty_out(vty, " area %s authentication\n", buf); + else + vty_out(vty, + " area %s authentication message-digest\n", + buf); + } - if (area->shortcut_configured != OSPF_SHORTCUT_DEFAULT) - vty_out (vty, " area %s shortcut %s\n", buf, - ospf_shortcut_mode_str[area->shortcut_configured]); + if (area->shortcut_configured != OSPF_SHORTCUT_DEFAULT) + vty_out(vty, " area %s shortcut %s\n", buf, + ospf_shortcut_mode_str + [area->shortcut_configured]); + + if ((area->external_routing == OSPF_AREA_STUB) + || (area->external_routing == OSPF_AREA_NSSA)) { + if (area->external_routing == OSPF_AREA_STUB) + vty_out(vty, " area %s stub", buf); + else if (area->external_routing == OSPF_AREA_NSSA) { + vty_out(vty, " area %s nssa", buf); + switch (area->NSSATranslatorRole) { + case OSPF_NSSA_ROLE_NEVER: + vty_out(vty, " translate-never"); + break; + case OSPF_NSSA_ROLE_ALWAYS: + vty_out(vty, " translate-always"); + break; + case OSPF_NSSA_ROLE_CANDIDATE: + default: + vty_out(vty, " translate-candidate"); + } + } - if ((area->external_routing == OSPF_AREA_STUB) - || (area->external_routing == OSPF_AREA_NSSA) - ) - { - if (area->external_routing == OSPF_AREA_STUB) - vty_out (vty, " area %s stub", buf); - else if (area->external_routing == OSPF_AREA_NSSA) - { - vty_out (vty, " area %s nssa", buf); - switch (area->NSSATranslatorRole) - { - case OSPF_NSSA_ROLE_NEVER: - vty_out (vty, " translate-never"); - break; - case OSPF_NSSA_ROLE_ALWAYS: - vty_out (vty, " translate-always"); - break; - case OSPF_NSSA_ROLE_CANDIDATE: - default: - vty_out (vty, " translate-candidate"); - } - } - - if (area->no_summary) - vty_out (vty, " no-summary"); - - vty_out (vty, "\n"); - - if (area->default_cost != 1) - vty_out (vty, " area %s default-cost %d\n", buf, - area->default_cost); - } - - for (rn1 = route_top (area->ranges); rn1; rn1 = route_next (rn1)) - if (rn1->info) - { - struct ospf_area_range *range = rn1->info; - - vty_out (vty, " area %s range %s/%d", buf, - inet_ntoa (rn1->p.u.prefix4), rn1->p.prefixlen); - - if (range->cost_config != OSPF_AREA_RANGE_COST_UNSPEC) - vty_out (vty, " cost %d", range->cost_config); - - if (!CHECK_FLAG (range->flags, OSPF_AREA_RANGE_ADVERTISE)) - vty_out (vty, " not-advertise"); - - if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE)) - vty_out (vty, " substitute %s/%d", - inet_ntoa (range->subst_addr), range->subst_masklen); - - vty_out (vty, "\n"); - } - - if (EXPORT_NAME (area)) - vty_out (vty, " area %s export-list %s\n", buf, - EXPORT_NAME (area)); - - if (IMPORT_NAME (area)) - vty_out (vty, " area %s import-list %s\n", buf, - IMPORT_NAME (area)); - - if (PREFIX_NAME_IN (area)) - vty_out (vty, " area %s filter-list prefix %s in\n", buf, - PREFIX_NAME_IN (area)); - - if (PREFIX_NAME_OUT (area)) - vty_out (vty, " area %s filter-list prefix %s out\n", buf, - PREFIX_NAME_OUT (area)); - } + if (area->no_summary) + vty_out(vty, " no-summary"); - return 0; -} + vty_out(vty, "\n"); -static int -config_write_ospf_nbr_nbma (struct vty *vty, struct ospf *ospf) -{ - struct ospf_nbr_nbma *nbr_nbma; - struct route_node *rn; + if (area->default_cost != 1) + vty_out(vty, " area %s default-cost %d\n", buf, + area->default_cost); + } - /* Static Neighbor configuration print. */ - for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn)) - if ((nbr_nbma = rn->info)) - { - vty_out (vty, " neighbor %s", inet_ntoa (nbr_nbma->addr)); + for (rn1 = route_top(area->ranges); rn1; rn1 = route_next(rn1)) + if (rn1->info) { + struct ospf_area_range *range = rn1->info; - if (nbr_nbma->priority != OSPF_NEIGHBOR_PRIORITY_DEFAULT) - vty_out (vty, " priority %d", nbr_nbma->priority); + vty_out(vty, " area %s range %s/%d", buf, + inet_ntoa(rn1->p.u.prefix4), + rn1->p.prefixlen); - if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT) - vty_out (vty, " poll-interval %d", nbr_nbma->v_poll); + if (range->cost_config + != OSPF_AREA_RANGE_COST_UNSPEC) + vty_out(vty, " cost %d", + range->cost_config); - vty_out (vty, "\n"); - } + if (!CHECK_FLAG(range->flags, + OSPF_AREA_RANGE_ADVERTISE)) + vty_out(vty, " not-advertise"); - return 0; + if (CHECK_FLAG(range->flags, + OSPF_AREA_RANGE_SUBSTITUTE)) + vty_out(vty, " substitute %s/%d", + inet_ntoa(range->subst_addr), + range->subst_masklen); + + vty_out(vty, "\n"); + } + + if (EXPORT_NAME(area)) + vty_out(vty, " area %s export-list %s\n", buf, + EXPORT_NAME(area)); + + if (IMPORT_NAME(area)) + vty_out(vty, " area %s import-list %s\n", buf, + IMPORT_NAME(area)); + + if (PREFIX_NAME_IN(area)) + vty_out(vty, " area %s filter-list prefix %s in\n", buf, + PREFIX_NAME_IN(area)); + + if (PREFIX_NAME_OUT(area)) + vty_out(vty, " area %s filter-list prefix %s out\n", + buf, PREFIX_NAME_OUT(area)); + } + + return 0; } -static int -config_write_virtual_link (struct vty *vty, struct ospf *ospf) +static int config_write_ospf_nbr_nbma(struct vty *vty, struct ospf *ospf) { - struct listnode *node; - struct ospf_vl_data *vl_data; - char buf[INET_ADDRSTRLEN]; + struct ospf_nbr_nbma *nbr_nbma; + struct route_node *rn; - /* Virtual-Link print */ - for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data)) - { - struct listnode *n2; - struct crypt_key *ck; - struct ospf_interface *oi; + /* Static Neighbor configuration print. */ + for (rn = route_top(ospf->nbr_nbma); rn; rn = route_next(rn)) + if ((nbr_nbma = rn->info)) { + vty_out(vty, " neighbor %s", inet_ntoa(nbr_nbma->addr)); - if (vl_data != NULL) - { - memset (buf, 0, INET_ADDRSTRLEN); - - area_id2str (buf, sizeof(buf), &vl_data->vl_area_id, vl_data->vl_area_id_fmt); - oi = vl_data->vl_oi; - - /* timers */ - if (OSPF_IF_PARAM (oi, v_hello) != OSPF_HELLO_INTERVAL_DEFAULT || - OSPF_IF_PARAM (oi, v_wait) != OSPF_ROUTER_DEAD_INTERVAL_DEFAULT || - OSPF_IF_PARAM (oi, retransmit_interval) != OSPF_RETRANSMIT_INTERVAL_DEFAULT || - OSPF_IF_PARAM (oi, transmit_delay) != OSPF_TRANSMIT_DELAY_DEFAULT) - vty_out (vty, " area %s virtual-link %s hello-interval %d retransmit-interval %d transmit-delay %d dead-interval %d\n", - buf, - inet_ntoa (vl_data->vl_peer), - OSPF_IF_PARAM (oi, v_hello), - OSPF_IF_PARAM (oi, retransmit_interval), - OSPF_IF_PARAM (oi, transmit_delay), - OSPF_IF_PARAM (oi, v_wait)); - else - vty_out (vty, " area %s virtual-link %s\n", buf, - inet_ntoa (vl_data->vl_peer)); - /* Auth key */ - if (IF_DEF_PARAMS (vl_data->vl_oi->ifp)->auth_simple[0] != '\0') - vty_out (vty, " area %s virtual-link %s authentication-key %s\n", - buf, - inet_ntoa (vl_data->vl_peer), - IF_DEF_PARAMS (vl_data->vl_oi->ifp)->auth_simple); - /* md5 keys */ - for (ALL_LIST_ELEMENTS_RO (IF_DEF_PARAMS (vl_data->vl_oi->ifp)->auth_crypt, - n2, ck)) - vty_out (vty, " area %s virtual-link %s" - " message-digest-key %d md5 %s\n", - buf, - inet_ntoa (vl_data->vl_peer), - ck->key_id, ck->auth_key); - - } - } + if (nbr_nbma->priority + != OSPF_NEIGHBOR_PRIORITY_DEFAULT) + vty_out(vty, " priority %d", + nbr_nbma->priority); - return 0; + if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT) + vty_out(vty, " poll-interval %d", + nbr_nbma->v_poll); + + vty_out(vty, "\n"); + } + + return 0; +} + +static int config_write_virtual_link(struct vty *vty, struct ospf *ospf) +{ + struct listnode *node; + struct ospf_vl_data *vl_data; + char buf[INET_ADDRSTRLEN]; + + /* Virtual-Link print */ + for (ALL_LIST_ELEMENTS_RO(ospf->vlinks, node, vl_data)) { + struct listnode *n2; + struct crypt_key *ck; + struct ospf_interface *oi; + + if (vl_data != NULL) { + memset(buf, 0, INET_ADDRSTRLEN); + + area_id2str(buf, sizeof(buf), &vl_data->vl_area_id, + vl_data->vl_area_id_fmt); + oi = vl_data->vl_oi; + + /* timers */ + if (OSPF_IF_PARAM(oi, v_hello) + != OSPF_HELLO_INTERVAL_DEFAULT + || OSPF_IF_PARAM(oi, v_wait) + != OSPF_ROUTER_DEAD_INTERVAL_DEFAULT + || OSPF_IF_PARAM(oi, retransmit_interval) + != OSPF_RETRANSMIT_INTERVAL_DEFAULT + || OSPF_IF_PARAM(oi, transmit_delay) + != OSPF_TRANSMIT_DELAY_DEFAULT) + vty_out(vty, + " area %s virtual-link %s hello-interval %d retransmit-interval %d transmit-delay %d dead-interval %d\n", + buf, inet_ntoa(vl_data->vl_peer), + OSPF_IF_PARAM(oi, v_hello), + OSPF_IF_PARAM(oi, retransmit_interval), + OSPF_IF_PARAM(oi, transmit_delay), + OSPF_IF_PARAM(oi, v_wait)); + else + vty_out(vty, " area %s virtual-link %s\n", buf, + inet_ntoa(vl_data->vl_peer)); + /* Auth key */ + if (IF_DEF_PARAMS(vl_data->vl_oi->ifp)->auth_simple[0] + != '\0') + vty_out(vty, + " area %s virtual-link %s authentication-key %s\n", + buf, inet_ntoa(vl_data->vl_peer), + IF_DEF_PARAMS(vl_data->vl_oi->ifp) + ->auth_simple); + /* md5 keys */ + for (ALL_LIST_ELEMENTS_RO( + IF_DEF_PARAMS(vl_data->vl_oi->ifp) + ->auth_crypt, + n2, ck)) + vty_out(vty, + " area %s virtual-link %s" + " message-digest-key %d md5 %s\n", + buf, inet_ntoa(vl_data->vl_peer), + ck->key_id, ck->auth_key); + } + } + + return 0; } -static int -config_write_ospf_redistribute (struct vty *vty, struct ospf *ospf) +static int config_write_ospf_redistribute(struct vty *vty, struct ospf *ospf) { - int type; + int type; - /* redistribute print. */ - for (type = 0; type < ZEBRA_ROUTE_MAX; type++) - { - struct list *red_list; - struct listnode *node; - struct ospf_redist *red; + /* redistribute print. */ + for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { + struct list *red_list; + struct listnode *node; + struct ospf_redist *red; - red_list = ospf->redist[type]; - if (!red_list) - continue; + red_list = ospf->redist[type]; + if (!red_list) + continue; - for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) - { - vty_out (vty, " redistribute %s", zebra_route_string(type)); - if (red->instance) - vty_out (vty, " %d", red->instance); + for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) { + vty_out(vty, " redistribute %s", + zebra_route_string(type)); + if (red->instance) + vty_out(vty, " %d", red->instance); - if (red->dmetric.value >= 0) - vty_out (vty, " metric %d", red->dmetric.value); + if (red->dmetric.value >= 0) + vty_out(vty, " metric %d", red->dmetric.value); - if (red->dmetric.type == EXTERNAL_METRIC_TYPE_1) - vty_out (vty, " metric-type 1"); + if (red->dmetric.type == EXTERNAL_METRIC_TYPE_1) + vty_out(vty, " metric-type 1"); - if (ROUTEMAP_NAME (red)) - vty_out (vty, " route-map %s", ROUTEMAP_NAME (red)); + if (ROUTEMAP_NAME(red)) + vty_out(vty, " route-map %s", + ROUTEMAP_NAME(red)); - vty_out (vty, "\n"); - } - } + vty_out(vty, "\n"); + } + } - return 0; + return 0; } -static int -config_write_ospf_default_metric (struct vty *vty, struct ospf *ospf) +static int config_write_ospf_default_metric(struct vty *vty, struct ospf *ospf) { - if (ospf->default_metric != -1) - vty_out (vty, " default-metric %d\n", ospf->default_metric); - return 0; + if (ospf->default_metric != -1) + vty_out(vty, " default-metric %d\n", ospf->default_metric); + return 0; } -static int -config_write_ospf_distribute (struct vty *vty, struct ospf *ospf) -{ - int type; - struct ospf_redist *red; - - if (ospf) - { - /* distribute-list print. */ - for (type = 0; type < ZEBRA_ROUTE_MAX; type++) - if (DISTRIBUTE_NAME (ospf, type)) - vty_out (vty, " distribute-list %s out %s\n", - DISTRIBUTE_NAME (ospf, type), - zebra_route_string(type)); - - /* default-information print. */ - if (ospf->default_originate != DEFAULT_ORIGINATE_NONE) - { - vty_out (vty, " default-information originate"); - if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS) - vty_out (vty, " always"); +static int config_write_ospf_distribute(struct vty *vty, struct ospf *ospf) +{ + int type; + struct ospf_redist *red; - red = ospf_redist_lookup(ospf, DEFAULT_ROUTE, 0); - if (red) - { - if (red->dmetric.value >= 0) - vty_out (vty, " metric %d", - red->dmetric.value); - if (red->dmetric.type == EXTERNAL_METRIC_TYPE_1) - vty_out (vty, " metric-type 1"); + if (ospf) { + /* distribute-list print. */ + for (type = 0; type < ZEBRA_ROUTE_MAX; type++) + if (DISTRIBUTE_NAME(ospf, type)) + vty_out(vty, " distribute-list %s out %s\n", + DISTRIBUTE_NAME(ospf, type), + zebra_route_string(type)); - if (ROUTEMAP_NAME (red)) - vty_out (vty, " route-map %s", - ROUTEMAP_NAME (red)); - } - - vty_out (vty, "\n"); - } + /* default-information print. */ + if (ospf->default_originate != DEFAULT_ORIGINATE_NONE) { + vty_out(vty, " default-information originate"); + if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS) + vty_out(vty, " always"); - } + red = ospf_redist_lookup(ospf, DEFAULT_ROUTE, 0); + if (red) { + if (red->dmetric.value >= 0) + vty_out(vty, " metric %d", + red->dmetric.value); + if (red->dmetric.type == EXTERNAL_METRIC_TYPE_1) + vty_out(vty, " metric-type 1"); - return 0; + if (ROUTEMAP_NAME(red)) + vty_out(vty, " route-map %s", + ROUTEMAP_NAME(red)); + } + + vty_out(vty, "\n"); + } + } + + return 0; } -static int -config_write_ospf_distance (struct vty *vty, struct ospf *ospf) -{ - struct route_node *rn; - struct ospf_distance *odistance; - - if (ospf->distance_all) - vty_out (vty, " distance %d\n", ospf->distance_all); - - if (ospf->distance_intra - || ospf->distance_inter - || ospf->distance_external) - { - vty_out (vty, " distance ospf"); - - if (ospf->distance_intra) - vty_out (vty, " intra-area %d", ospf->distance_intra); - if (ospf->distance_inter) - vty_out (vty, " inter-area %d", ospf->distance_inter); - if (ospf->distance_external) - vty_out (vty, " external %d", ospf->distance_external); - - vty_out (vty, "\n"); - } - - for (rn = route_top (ospf->distance_table); rn; rn = route_next (rn)) - if ((odistance = rn->info) != NULL) - { - vty_out (vty, " distance %d %s/%d %s\n", odistance->distance, - inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen, - odistance->access_list ? odistance->access_list : ""); - } - return 0; +static int config_write_ospf_distance(struct vty *vty, struct ospf *ospf) +{ + struct route_node *rn; + struct ospf_distance *odistance; + + if (ospf->distance_all) + vty_out(vty, " distance %d\n", ospf->distance_all); + + if (ospf->distance_intra || ospf->distance_inter + || ospf->distance_external) { + vty_out(vty, " distance ospf"); + + if (ospf->distance_intra) + vty_out(vty, " intra-area %d", ospf->distance_intra); + if (ospf->distance_inter) + vty_out(vty, " inter-area %d", ospf->distance_inter); + if (ospf->distance_external) + vty_out(vty, " external %d", ospf->distance_external); + + vty_out(vty, "\n"); + } + + for (rn = route_top(ospf->distance_table); rn; rn = route_next(rn)) + if ((odistance = rn->info) != NULL) { + vty_out(vty, " distance %d %s/%d %s\n", + odistance->distance, inet_ntoa(rn->p.u.prefix4), + rn->p.prefixlen, + odistance->access_list ? odistance->access_list + : ""); + } + return 0; } /* OSPF configuration write function. */ -static int -ospf_config_write (struct vty *vty) -{ - struct ospf *ospf; - struct interface *ifp; - struct ospf_interface *oi; - struct listnode *node; - int write = 0; - - ospf = ospf_lookup (); - if (ospf != NULL && ospf->oi_running) - { - /* `router ospf' print. */ - if (ospf->instance) - vty_out (vty, "router ospf %d\n", ospf->instance); - else - vty_out (vty, "router ospf\n"); - - write++; - - if (!ospf->networks) - return write; - - /* Router ID print. */ - if (ospf->router_id_static.s_addr != 0) - vty_out (vty, " ospf router-id %s\n", - inet_ntoa (ospf->router_id_static)); - - /* ABR type print. */ - if (ospf->abr_type != OSPF_ABR_DEFAULT) - vty_out (vty, " ospf abr-type %s\n", - ospf_abr_type_str[ospf->abr_type]); - - /* log-adjacency-changes flag print. */ - if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES)) - { - if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL)) - vty_out(vty, " log-adjacency-changes detail\n"); - else if (!DFLT_OSPF_LOG_ADJACENCY_CHANGES) - vty_out(vty, " log-adjacency-changes\n"); - } - else if (DFLT_OSPF_LOG_ADJACENCY_CHANGES) - { - vty_out(vty, " no log-adjacency-changes\n"); - } - - /* RFC1583 compatibility flag print -- Compatible with CISCO 12.1. */ - if (CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE)) - vty_out (vty, " compatible rfc1583\n"); - - /* auto-cost reference-bandwidth configuration. */ - if (ospf->ref_bandwidth != OSPF_DEFAULT_REF_BANDWIDTH) - { - vty_out (vty, "! Important: ensure reference bandwidth " - "is consistent across all routers\n"); - vty_out (vty, " auto-cost reference-bandwidth %d\n", - ospf->ref_bandwidth); - } - - /* SPF timers print. */ - if (ospf->spf_delay != OSPF_SPF_DELAY_DEFAULT || - ospf->spf_holdtime != OSPF_SPF_HOLDTIME_DEFAULT || - ospf->spf_max_holdtime != OSPF_SPF_MAX_HOLDTIME_DEFAULT) - vty_out (vty, " timers throttle spf %d %d %d\n", - ospf->spf_delay, ospf->spf_holdtime, - ospf->spf_max_holdtime); - - /* LSA timers print. */ - if (ospf->min_ls_interval != OSPF_MIN_LS_INTERVAL) - vty_out (vty, " timers throttle lsa all %d\n", - ospf->min_ls_interval); - if (ospf->min_ls_arrival != OSPF_MIN_LS_ARRIVAL) - vty_out (vty, " timers lsa min-arrival %d\n", - ospf->min_ls_arrival); - - /* Write multiplier print. */ - if (ospf->write_oi_count != OSPF_WRITE_INTERFACE_COUNT_DEFAULT) - vty_out (vty, " ospf write-multiplier %d\n", - ospf->write_oi_count); - - /* Max-metric router-lsa print */ - config_write_stub_router (vty, ospf); - - /* SPF refresh parameters print. */ - if (ospf->lsa_refresh_interval != OSPF_LSA_REFRESH_INTERVAL_DEFAULT) - vty_out (vty, " refresh timer %d\n", - ospf->lsa_refresh_interval); - - /* Redistribute information print. */ - config_write_ospf_redistribute (vty, ospf); - - /* passive-interface print. */ - if (ospf->passive_interface_default == OSPF_IF_PASSIVE) - vty_out (vty, " passive-interface default\n"); - - for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp)) - if (OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (ifp), passive_interface) - && IF_DEF_PARAMS (ifp)->passive_interface != - ospf->passive_interface_default) - { - vty_out (vty, " %spassive-interface %s\n", - IF_DEF_PARAMS (ifp)->passive_interface ? "" : "no ", - ifp->name); - } - for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) - { - if (!OSPF_IF_PARAM_CONFIGURED (oi->params, passive_interface)) - continue; - if (OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (oi->ifp), - passive_interface)) - { - if (oi->params->passive_interface == IF_DEF_PARAMS (oi->ifp)->passive_interface) - continue; - } - else if (oi->params->passive_interface == ospf->passive_interface_default) - continue; - - vty_out (vty, " %spassive-interface %s %s\n", - oi->params->passive_interface ? "" : "no ", - oi->ifp->name, - inet_ntoa (oi->address->u.prefix4)); - } - - /* Network area print. */ - config_write_network_area (vty, ospf); - - /* Area config print. */ - config_write_ospf_area (vty, ospf); - - /* static neighbor print. */ - config_write_ospf_nbr_nbma (vty, ospf); - - /* Virtual-Link print. */ - config_write_virtual_link (vty, ospf); - - /* Default metric configuration. */ - config_write_ospf_default_metric (vty, ospf); - - /* Distribute-list and default-information print. */ - config_write_ospf_distribute (vty, ospf); - - /* Distance configuration. */ - config_write_ospf_distance (vty, ospf); - - ospf_opaque_config_write_router (vty, ospf); - } - - return write; -} - -void -ospf_vty_show_init (void) -{ - /* "show ip ospf" commands. */ - install_element (VIEW_NODE, &show_ip_ospf_cmd); - - install_element (VIEW_NODE, &show_ip_ospf_instance_cmd); - - /* "show ip ospf database" commands. */ - install_element (VIEW_NODE, &show_ip_ospf_database_max_cmd); - - install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_adv_router_cmd); - install_element (VIEW_NODE, &show_ip_ospf_instance_database_cmd); - install_element (VIEW_NODE, &show_ip_ospf_instance_database_max_cmd); - - /* "show ip ospf interface" commands. */ - install_element (VIEW_NODE, &show_ip_ospf_interface_cmd); - - install_element (VIEW_NODE, &show_ip_ospf_instance_interface_cmd); - - /* "show ip ospf neighbor" commands. */ - install_element (VIEW_NODE, &show_ip_ospf_neighbor_int_detail_cmd); - install_element (VIEW_NODE, &show_ip_ospf_neighbor_int_cmd); - install_element (VIEW_NODE, &show_ip_ospf_neighbor_id_cmd); - install_element (VIEW_NODE, &show_ip_ospf_neighbor_detail_all_cmd); - install_element (VIEW_NODE, &show_ip_ospf_neighbor_detail_cmd); - install_element (VIEW_NODE, &show_ip_ospf_neighbor_cmd); - install_element (VIEW_NODE, &show_ip_ospf_neighbor_all_cmd); - - install_element (VIEW_NODE, &show_ip_ospf_instance_neighbor_int_detail_cmd); - install_element (VIEW_NODE, &show_ip_ospf_instance_neighbor_int_cmd); - install_element (VIEW_NODE, &show_ip_ospf_instance_neighbor_id_cmd); - install_element (VIEW_NODE, &show_ip_ospf_instance_neighbor_detail_all_cmd); - install_element (VIEW_NODE, &show_ip_ospf_instance_neighbor_detail_cmd); - install_element (VIEW_NODE, &show_ip_ospf_instance_neighbor_cmd); - install_element (VIEW_NODE, &show_ip_ospf_instance_neighbor_all_cmd); - - /* "show ip ospf route" commands. */ - install_element (VIEW_NODE, &show_ip_ospf_route_cmd); - install_element (VIEW_NODE, &show_ip_ospf_border_routers_cmd); - - install_element (VIEW_NODE, &show_ip_ospf_instance_route_cmd); - install_element (VIEW_NODE, &show_ip_ospf_instance_border_routers_cmd); +static int ospf_config_write(struct vty *vty) +{ + struct ospf *ospf; + struct interface *ifp; + struct ospf_interface *oi; + struct listnode *node; + int write = 0; + + ospf = ospf_lookup(); + if (ospf != NULL && ospf->oi_running) { + /* `router ospf' print. */ + if (ospf->instance) + vty_out(vty, "router ospf %d\n", ospf->instance); + else + vty_out(vty, "router ospf\n"); + + write++; + + if (!ospf->networks) + return write; + + /* Router ID print. */ + if (ospf->router_id_static.s_addr != 0) + vty_out(vty, " ospf router-id %s\n", + inet_ntoa(ospf->router_id_static)); + + /* ABR type print. */ + if (ospf->abr_type != OSPF_ABR_DEFAULT) + vty_out(vty, " ospf abr-type %s\n", + ospf_abr_type_str[ospf->abr_type]); + + /* log-adjacency-changes flag print. */ + if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES)) { + if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL)) + vty_out(vty, " log-adjacency-changes detail\n"); + else if (!DFLT_OSPF_LOG_ADJACENCY_CHANGES) + vty_out(vty, " log-adjacency-changes\n"); + } else if (DFLT_OSPF_LOG_ADJACENCY_CHANGES) { + vty_out(vty, " no log-adjacency-changes\n"); + } + + /* RFC1583 compatibility flag print -- Compatible with CISCO + * 12.1. */ + if (CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE)) + vty_out(vty, " compatible rfc1583\n"); + + /* auto-cost reference-bandwidth configuration. */ + if (ospf->ref_bandwidth != OSPF_DEFAULT_REF_BANDWIDTH) { + vty_out(vty, + "! Important: ensure reference bandwidth " + "is consistent across all routers\n"); + vty_out(vty, " auto-cost reference-bandwidth %d\n", + ospf->ref_bandwidth); + } + + /* SPF timers print. */ + if (ospf->spf_delay != OSPF_SPF_DELAY_DEFAULT + || ospf->spf_holdtime != OSPF_SPF_HOLDTIME_DEFAULT + || ospf->spf_max_holdtime != OSPF_SPF_MAX_HOLDTIME_DEFAULT) + vty_out(vty, " timers throttle spf %d %d %d\n", + ospf->spf_delay, ospf->spf_holdtime, + ospf->spf_max_holdtime); + + /* LSA timers print. */ + if (ospf->min_ls_interval != OSPF_MIN_LS_INTERVAL) + vty_out(vty, " timers throttle lsa all %d\n", + ospf->min_ls_interval); + if (ospf->min_ls_arrival != OSPF_MIN_LS_ARRIVAL) + vty_out(vty, " timers lsa min-arrival %d\n", + ospf->min_ls_arrival); + + /* Write multiplier print. */ + if (ospf->write_oi_count != OSPF_WRITE_INTERFACE_COUNT_DEFAULT) + vty_out(vty, " ospf write-multiplier %d\n", + ospf->write_oi_count); + + /* Max-metric router-lsa print */ + config_write_stub_router(vty, ospf); + + /* SPF refresh parameters print. */ + if (ospf->lsa_refresh_interval + != OSPF_LSA_REFRESH_INTERVAL_DEFAULT) + vty_out(vty, " refresh timer %d\n", + ospf->lsa_refresh_interval); + + /* Redistribute information print. */ + config_write_ospf_redistribute(vty, ospf); + + /* passive-interface print. */ + if (ospf->passive_interface_default == OSPF_IF_PASSIVE) + vty_out(vty, " passive-interface default\n"); + + for (ALL_LIST_ELEMENTS_RO(om->iflist, node, ifp)) + if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp), + passive_interface) + && IF_DEF_PARAMS(ifp)->passive_interface + != ospf->passive_interface_default) { + vty_out(vty, " %spassive-interface %s\n", + IF_DEF_PARAMS(ifp)->passive_interface + ? "" + : "no ", + ifp->name); + } + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) { + if (!OSPF_IF_PARAM_CONFIGURED(oi->params, + passive_interface)) + continue; + if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(oi->ifp), + passive_interface)) { + if (oi->params->passive_interface + == IF_DEF_PARAMS(oi->ifp) + ->passive_interface) + continue; + } else if (oi->params->passive_interface + == ospf->passive_interface_default) + continue; + + vty_out(vty, " %spassive-interface %s %s\n", + oi->params->passive_interface ? "" : "no ", + oi->ifp->name, + inet_ntoa(oi->address->u.prefix4)); + } + + /* Network area print. */ + config_write_network_area(vty, ospf); + + /* Area config print. */ + config_write_ospf_area(vty, ospf); + + /* static neighbor print. */ + config_write_ospf_nbr_nbma(vty, ospf); + + /* Virtual-Link print. */ + config_write_virtual_link(vty, ospf); + + /* Default metric configuration. */ + config_write_ospf_default_metric(vty, ospf); + + /* Distribute-list and default-information print. */ + config_write_ospf_distribute(vty, ospf); + + /* Distance configuration. */ + config_write_ospf_distance(vty, ospf); + + ospf_opaque_config_write_router(vty, ospf); + } + + return write; +} + +void ospf_vty_show_init(void) +{ + /* "show ip ospf" commands. */ + install_element(VIEW_NODE, &show_ip_ospf_cmd); + + install_element(VIEW_NODE, &show_ip_ospf_instance_cmd); + + /* "show ip ospf database" commands. */ + install_element(VIEW_NODE, &show_ip_ospf_database_max_cmd); + + install_element(VIEW_NODE, + &show_ip_ospf_instance_database_type_adv_router_cmd); + install_element(VIEW_NODE, &show_ip_ospf_instance_database_cmd); + install_element(VIEW_NODE, &show_ip_ospf_instance_database_max_cmd); + + /* "show ip ospf interface" commands. */ + install_element(VIEW_NODE, &show_ip_ospf_interface_cmd); + + install_element(VIEW_NODE, &show_ip_ospf_instance_interface_cmd); + + /* "show ip ospf neighbor" commands. */ + install_element(VIEW_NODE, &show_ip_ospf_neighbor_int_detail_cmd); + install_element(VIEW_NODE, &show_ip_ospf_neighbor_int_cmd); + install_element(VIEW_NODE, &show_ip_ospf_neighbor_id_cmd); + install_element(VIEW_NODE, &show_ip_ospf_neighbor_detail_all_cmd); + install_element(VIEW_NODE, &show_ip_ospf_neighbor_detail_cmd); + install_element(VIEW_NODE, &show_ip_ospf_neighbor_cmd); + install_element(VIEW_NODE, &show_ip_ospf_neighbor_all_cmd); + + install_element(VIEW_NODE, + &show_ip_ospf_instance_neighbor_int_detail_cmd); + install_element(VIEW_NODE, &show_ip_ospf_instance_neighbor_int_cmd); + install_element(VIEW_NODE, &show_ip_ospf_instance_neighbor_id_cmd); + install_element(VIEW_NODE, + &show_ip_ospf_instance_neighbor_detail_all_cmd); + install_element(VIEW_NODE, &show_ip_ospf_instance_neighbor_detail_cmd); + install_element(VIEW_NODE, &show_ip_ospf_instance_neighbor_cmd); + install_element(VIEW_NODE, &show_ip_ospf_instance_neighbor_all_cmd); + + /* "show ip ospf route" commands. */ + install_element(VIEW_NODE, &show_ip_ospf_route_cmd); + install_element(VIEW_NODE, &show_ip_ospf_border_routers_cmd); + + install_element(VIEW_NODE, &show_ip_ospf_instance_route_cmd); + install_element(VIEW_NODE, &show_ip_ospf_instance_border_routers_cmd); } /* ospfd's interface node. */ -static struct cmd_node interface_node = -{ - INTERFACE_NODE, - "%s(config-if)# ", - 1 -}; +static struct cmd_node interface_node = {INTERFACE_NODE, "%s(config-if)# ", 1}; /* Initialization of OSPF interface. */ -static void -ospf_vty_if_init (void) -{ - /* Install interface node. */ - install_node (&interface_node, config_write_interface); - if_cmd_init (); - - /* "ip ospf authentication" commands. */ - install_element (INTERFACE_NODE, &ip_ospf_authentication_args_addr_cmd); - install_element (INTERFACE_NODE, &ip_ospf_authentication_addr_cmd); - install_element (INTERFACE_NODE, &no_ip_ospf_authentication_args_addr_cmd); - install_element (INTERFACE_NODE, &no_ip_ospf_authentication_addr_cmd); - install_element (INTERFACE_NODE, &ip_ospf_authentication_key_addr_cmd); - install_element (INTERFACE_NODE, &no_ip_ospf_authentication_key_authkey_addr_cmd); - install_element (INTERFACE_NODE, &no_ospf_authentication_key_authkey_addr_cmd); - - /* "ip ospf message-digest-key" commands. */ - install_element (INTERFACE_NODE, &ip_ospf_message_digest_key_cmd); - install_element (INTERFACE_NODE, &no_ip_ospf_message_digest_key_cmd); - - /* "ip ospf cost" commands. */ - install_element (INTERFACE_NODE, &ip_ospf_cost_cmd); - install_element (INTERFACE_NODE, &no_ip_ospf_cost_cmd); - - /* "ip ospf mtu-ignore" commands. */ - install_element (INTERFACE_NODE, &ip_ospf_mtu_ignore_addr_cmd); - install_element (INTERFACE_NODE, &no_ip_ospf_mtu_ignore_addr_cmd); - - /* "ip ospf dead-interval" commands. */ - install_element (INTERFACE_NODE, &ip_ospf_dead_interval_cmd); - install_element (INTERFACE_NODE, &ip_ospf_dead_interval_minimal_addr_cmd); - install_element (INTERFACE_NODE, &no_ip_ospf_dead_interval_cmd); - - /* "ip ospf hello-interval" commands. */ - install_element (INTERFACE_NODE, &ip_ospf_hello_interval_cmd); - install_element (INTERFACE_NODE, &no_ip_ospf_hello_interval_cmd); - - /* "ip ospf network" commands. */ - install_element (INTERFACE_NODE, &ip_ospf_network_cmd); - install_element (INTERFACE_NODE, &no_ip_ospf_network_cmd); - - /* "ip ospf priority" commands. */ - install_element (INTERFACE_NODE, &ip_ospf_priority_cmd); - install_element (INTERFACE_NODE, &no_ip_ospf_priority_cmd); - - /* "ip ospf retransmit-interval" commands. */ - install_element (INTERFACE_NODE, &ip_ospf_retransmit_interval_addr_cmd); - install_element (INTERFACE_NODE, &no_ip_ospf_retransmit_interval_addr_cmd); - - /* "ip ospf transmit-delay" commands. */ - install_element (INTERFACE_NODE, &ip_ospf_transmit_delay_addr_cmd); - install_element (INTERFACE_NODE, &no_ip_ospf_transmit_delay_addr_cmd); - - /* "ip ospf area" commands. */ - install_element (INTERFACE_NODE, &ip_ospf_area_cmd); - install_element (INTERFACE_NODE, &no_ip_ospf_area_cmd); - - /* These commands are compatibitliy for previous version. */ - install_element (INTERFACE_NODE, &ospf_authentication_key_cmd); - install_element (INTERFACE_NODE, &ospf_message_digest_key_cmd); - install_element (INTERFACE_NODE, &no_ospf_message_digest_key_cmd); - install_element (INTERFACE_NODE, &ospf_dead_interval_cmd); - install_element (INTERFACE_NODE, &no_ospf_dead_interval_cmd); - install_element (INTERFACE_NODE, &ospf_hello_interval_cmd); - install_element (INTERFACE_NODE, &no_ospf_hello_interval_cmd); - install_element (INTERFACE_NODE, &ospf_cost_cmd); - install_element (INTERFACE_NODE, &no_ospf_cost_cmd); - install_element (INTERFACE_NODE, &ospf_network_cmd); - install_element (INTERFACE_NODE, &no_ospf_network_cmd); - install_element (INTERFACE_NODE, &ospf_priority_cmd); - install_element (INTERFACE_NODE, &no_ospf_priority_cmd); - install_element (INTERFACE_NODE, &ospf_retransmit_interval_cmd); - install_element (INTERFACE_NODE, &no_ospf_retransmit_interval_cmd); - install_element (INTERFACE_NODE, &ospf_transmit_delay_cmd); - install_element (INTERFACE_NODE, &no_ospf_transmit_delay_cmd); -} - -static void -ospf_vty_zebra_init (void) -{ - install_element (OSPF_NODE, &ospf_redistribute_source_cmd); - install_element (OSPF_NODE, &no_ospf_redistribute_source_cmd); - install_element (OSPF_NODE, &ospf_redistribute_instance_source_cmd); - install_element (OSPF_NODE, &no_ospf_redistribute_instance_source_cmd); - - install_element (OSPF_NODE, &ospf_distribute_list_out_cmd); - install_element (OSPF_NODE, &no_ospf_distribute_list_out_cmd); - - install_element (OSPF_NODE, &ospf_default_information_originate_cmd); - install_element (OSPF_NODE, &no_ospf_default_information_originate_cmd); - - install_element (OSPF_NODE, &ospf_default_metric_cmd); - install_element (OSPF_NODE, &no_ospf_default_metric_cmd); - - install_element (OSPF_NODE, &ospf_distance_cmd); - install_element (OSPF_NODE, &no_ospf_distance_cmd); - install_element (OSPF_NODE, &no_ospf_distance_ospf_cmd); - install_element (OSPF_NODE, &ospf_distance_ospf_cmd); +static void ospf_vty_if_init(void) +{ + /* Install interface node. */ + install_node(&interface_node, config_write_interface); + if_cmd_init(); + + /* "ip ospf authentication" commands. */ + install_element(INTERFACE_NODE, &ip_ospf_authentication_args_addr_cmd); + install_element(INTERFACE_NODE, &ip_ospf_authentication_addr_cmd); + install_element(INTERFACE_NODE, + &no_ip_ospf_authentication_args_addr_cmd); + install_element(INTERFACE_NODE, &no_ip_ospf_authentication_addr_cmd); + install_element(INTERFACE_NODE, &ip_ospf_authentication_key_addr_cmd); + install_element(INTERFACE_NODE, + &no_ip_ospf_authentication_key_authkey_addr_cmd); + install_element(INTERFACE_NODE, + &no_ospf_authentication_key_authkey_addr_cmd); + + /* "ip ospf message-digest-key" commands. */ + install_element(INTERFACE_NODE, &ip_ospf_message_digest_key_cmd); + install_element(INTERFACE_NODE, &no_ip_ospf_message_digest_key_cmd); + + /* "ip ospf cost" commands. */ + install_element(INTERFACE_NODE, &ip_ospf_cost_cmd); + install_element(INTERFACE_NODE, &no_ip_ospf_cost_cmd); + + /* "ip ospf mtu-ignore" commands. */ + install_element(INTERFACE_NODE, &ip_ospf_mtu_ignore_addr_cmd); + install_element(INTERFACE_NODE, &no_ip_ospf_mtu_ignore_addr_cmd); + + /* "ip ospf dead-interval" commands. */ + install_element(INTERFACE_NODE, &ip_ospf_dead_interval_cmd); + install_element(INTERFACE_NODE, + &ip_ospf_dead_interval_minimal_addr_cmd); + install_element(INTERFACE_NODE, &no_ip_ospf_dead_interval_cmd); + + /* "ip ospf hello-interval" commands. */ + install_element(INTERFACE_NODE, &ip_ospf_hello_interval_cmd); + install_element(INTERFACE_NODE, &no_ip_ospf_hello_interval_cmd); + + /* "ip ospf network" commands. */ + install_element(INTERFACE_NODE, &ip_ospf_network_cmd); + install_element(INTERFACE_NODE, &no_ip_ospf_network_cmd); + + /* "ip ospf priority" commands. */ + install_element(INTERFACE_NODE, &ip_ospf_priority_cmd); + install_element(INTERFACE_NODE, &no_ip_ospf_priority_cmd); + + /* "ip ospf retransmit-interval" commands. */ + install_element(INTERFACE_NODE, &ip_ospf_retransmit_interval_addr_cmd); + install_element(INTERFACE_NODE, + &no_ip_ospf_retransmit_interval_addr_cmd); + + /* "ip ospf transmit-delay" commands. */ + install_element(INTERFACE_NODE, &ip_ospf_transmit_delay_addr_cmd); + install_element(INTERFACE_NODE, &no_ip_ospf_transmit_delay_addr_cmd); + + /* "ip ospf area" commands. */ + install_element(INTERFACE_NODE, &ip_ospf_area_cmd); + install_element(INTERFACE_NODE, &no_ip_ospf_area_cmd); + + /* These commands are compatibitliy for previous version. */ + install_element(INTERFACE_NODE, &ospf_authentication_key_cmd); + install_element(INTERFACE_NODE, &ospf_message_digest_key_cmd); + install_element(INTERFACE_NODE, &no_ospf_message_digest_key_cmd); + install_element(INTERFACE_NODE, &ospf_dead_interval_cmd); + install_element(INTERFACE_NODE, &no_ospf_dead_interval_cmd); + install_element(INTERFACE_NODE, &ospf_hello_interval_cmd); + install_element(INTERFACE_NODE, &no_ospf_hello_interval_cmd); + install_element(INTERFACE_NODE, &ospf_cost_cmd); + install_element(INTERFACE_NODE, &no_ospf_cost_cmd); + install_element(INTERFACE_NODE, &ospf_network_cmd); + install_element(INTERFACE_NODE, &no_ospf_network_cmd); + install_element(INTERFACE_NODE, &ospf_priority_cmd); + install_element(INTERFACE_NODE, &no_ospf_priority_cmd); + install_element(INTERFACE_NODE, &ospf_retransmit_interval_cmd); + install_element(INTERFACE_NODE, &no_ospf_retransmit_interval_cmd); + install_element(INTERFACE_NODE, &ospf_transmit_delay_cmd); + install_element(INTERFACE_NODE, &no_ospf_transmit_delay_cmd); +} + +static void ospf_vty_zebra_init(void) +{ + install_element(OSPF_NODE, &ospf_redistribute_source_cmd); + install_element(OSPF_NODE, &no_ospf_redistribute_source_cmd); + install_element(OSPF_NODE, &ospf_redistribute_instance_source_cmd); + install_element(OSPF_NODE, &no_ospf_redistribute_instance_source_cmd); + + install_element(OSPF_NODE, &ospf_distribute_list_out_cmd); + install_element(OSPF_NODE, &no_ospf_distribute_list_out_cmd); + + install_element(OSPF_NODE, &ospf_default_information_originate_cmd); + install_element(OSPF_NODE, &no_ospf_default_information_originate_cmd); + + install_element(OSPF_NODE, &ospf_default_metric_cmd); + install_element(OSPF_NODE, &no_ospf_default_metric_cmd); + + install_element(OSPF_NODE, &ospf_distance_cmd); + install_element(OSPF_NODE, &no_ospf_distance_cmd); + install_element(OSPF_NODE, &no_ospf_distance_ospf_cmd); + install_element(OSPF_NODE, &ospf_distance_ospf_cmd); #if 0 install_element (OSPF_NODE, &ospf_distance_source_cmd); install_element (OSPF_NODE, &no_ospf_distance_source_cmd); @@ -8950,22 +8986,17 @@ ospf_vty_zebra_init (void) #endif /* 0 */ } -static struct cmd_node ospf_node = -{ - OSPF_NODE, - "%s(config-router)# ", - 1 -}; +static struct cmd_node ospf_node = {OSPF_NODE, "%s(config-router)# ", 1}; -static void -ospf_interface_clear (struct interface *ifp) +static void ospf_interface_clear(struct interface *ifp) { - if (!if_is_operative (ifp)) return; + if (!if_is_operative(ifp)) + return; - if (IS_DEBUG_OSPF (ism, ISM_EVENTS)) - zlog_debug("ISM[%s]: clear by reset", ifp->name); + if (IS_DEBUG_OSPF(ism, ISM_EVENTS)) + zlog_debug("ISM[%s]: clear by reset", ifp->name); - ospf_if_reset(ifp); + ospf_if_reset(ifp); } DEFUN (clear_ip_ospf_interface, @@ -8977,175 +9008,167 @@ DEFUN (clear_ip_ospf_interface, "Interface information\n" "Interface name\n") { - int idx_ifname = 4; - struct interface *ifp; - struct listnode *node; - - if (argc == 4) /* Clear all the ospfv2 interfaces. */ - { - for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) - ospf_interface_clear(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 name\n"); - else - ospf_interface_clear(ifp); - } + int idx_ifname = 4; + struct interface *ifp; + struct listnode *node; - return CMD_SUCCESS; + if (argc == 4) /* Clear all the ospfv2 interfaces. */ + { + for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) + ospf_interface_clear(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 name\n"); + else + ospf_interface_clear(ifp); + } + + return CMD_SUCCESS; } -void -ospf_vty_clear_init (void) +void ospf_vty_clear_init(void) { - install_element (ENABLE_NODE, &clear_ip_ospf_interface_cmd); + install_element(ENABLE_NODE, &clear_ip_ospf_interface_cmd); } /* Install OSPF related vty commands. */ -void -ospf_vty_init (void) -{ - /* Install ospf top node. */ - install_node (&ospf_node, ospf_config_write); - - /* "router ospf" commands. */ - install_element (CONFIG_NODE, &router_ospf_cmd); - install_element (CONFIG_NODE, &no_router_ospf_cmd); - - - install_default (OSPF_NODE); - - /* "ospf router-id" commands. */ - install_element (OSPF_NODE, &ospf_router_id_cmd); - install_element (OSPF_NODE, &ospf_router_id_old_cmd); - install_element (OSPF_NODE, &no_ospf_router_id_cmd); - - /* "passive-interface" commands. */ - install_element (OSPF_NODE, &ospf_passive_interface_addr_cmd); - install_element (OSPF_NODE, &no_ospf_passive_interface_addr_cmd); - - /* "ospf abr-type" commands. */ - install_element (OSPF_NODE, &ospf_abr_type_cmd); - install_element (OSPF_NODE, &no_ospf_abr_type_cmd); - - /* "ospf log-adjacency-changes" commands. */ - install_element (OSPF_NODE, &ospf_log_adjacency_changes_cmd); - install_element (OSPF_NODE, &ospf_log_adjacency_changes_detail_cmd); - install_element (OSPF_NODE, &no_ospf_log_adjacency_changes_cmd); - install_element (OSPF_NODE, &no_ospf_log_adjacency_changes_detail_cmd); - - /* "ospf rfc1583-compatible" commands. */ - install_element (OSPF_NODE, &ospf_compatible_rfc1583_cmd); - install_element (OSPF_NODE, &no_ospf_compatible_rfc1583_cmd); - install_element (OSPF_NODE, &ospf_rfc1583_flag_cmd); - install_element (OSPF_NODE, &no_ospf_rfc1583_flag_cmd); - - /* "network area" commands. */ - install_element (OSPF_NODE, &ospf_network_area_cmd); - install_element (OSPF_NODE, &no_ospf_network_area_cmd); - - /* "area authentication" commands. */ - install_element (OSPF_NODE, &ospf_area_authentication_message_digest_cmd); - install_element (OSPF_NODE, &ospf_area_authentication_cmd); - install_element (OSPF_NODE, &no_ospf_area_authentication_cmd); - - /* "area range" commands. */ - install_element (OSPF_NODE, &ospf_area_range_cmd); - install_element (OSPF_NODE, &ospf_area_range_cost_cmd); - install_element (OSPF_NODE, &ospf_area_range_not_advertise_cmd); - install_element (OSPF_NODE, &no_ospf_area_range_cmd); - install_element (OSPF_NODE, &ospf_area_range_substitute_cmd); - install_element (OSPF_NODE, &no_ospf_area_range_substitute_cmd); - - /* "area virtual-link" commands. */ - install_element (OSPF_NODE, &ospf_area_vlink_cmd); - install_element (OSPF_NODE, &ospf_area_vlink_intervals_cmd); - install_element (OSPF_NODE, &no_ospf_area_vlink_cmd); - install_element (OSPF_NODE, &no_ospf_area_vlink_intervals_cmd); - - - - - - - - - - - /* "area stub" commands. */ - install_element (OSPF_NODE, &ospf_area_stub_no_summary_cmd); - install_element (OSPF_NODE, &ospf_area_stub_cmd); - install_element (OSPF_NODE, &no_ospf_area_stub_no_summary_cmd); - install_element (OSPF_NODE, &no_ospf_area_stub_cmd); - - /* "area nssa" commands. */ - install_element (OSPF_NODE, &ospf_area_nssa_cmd); - install_element (OSPF_NODE, &ospf_area_nssa_translate_no_summary_cmd); - install_element (OSPF_NODE, &ospf_area_nssa_translate_cmd); - install_element (OSPF_NODE, &ospf_area_nssa_no_summary_cmd); - install_element (OSPF_NODE, &no_ospf_area_nssa_cmd); - - install_element (OSPF_NODE, &ospf_area_default_cost_cmd); - install_element (OSPF_NODE, &no_ospf_area_default_cost_cmd); - - install_element (OSPF_NODE, &ospf_area_shortcut_cmd); - install_element (OSPF_NODE, &no_ospf_area_shortcut_cmd); - - install_element (OSPF_NODE, &ospf_area_export_list_cmd); - install_element (OSPF_NODE, &no_ospf_area_export_list_cmd); - - install_element (OSPF_NODE, &ospf_area_filter_list_cmd); - install_element (OSPF_NODE, &no_ospf_area_filter_list_cmd); - - install_element (OSPF_NODE, &ospf_area_import_list_cmd); - install_element (OSPF_NODE, &no_ospf_area_import_list_cmd); - - /* SPF timer commands */ - install_element (OSPF_NODE, &ospf_timers_throttle_spf_cmd); - install_element (OSPF_NODE, &no_ospf_timers_throttle_spf_cmd); - - /* LSA timers commands */ - install_element (OSPF_NODE, &ospf_timers_min_ls_interval_cmd); - install_element (OSPF_NODE, &no_ospf_timers_min_ls_interval_cmd); - install_element (OSPF_NODE, &ospf_timers_min_ls_arrival_cmd); - install_element (OSPF_NODE, &no_ospf_timers_min_ls_arrival_cmd); - install_element (OSPF_NODE, &ospf_timers_lsa_cmd); - install_element (OSPF_NODE, &no_ospf_timers_lsa_cmd); - - /* refresh timer commands */ - install_element (OSPF_NODE, &ospf_refresh_timer_cmd); - install_element (OSPF_NODE, &no_ospf_refresh_timer_val_cmd); - - /* max-metric commands */ - install_element (OSPF_NODE, &ospf_max_metric_router_lsa_admin_cmd); - install_element (OSPF_NODE, &no_ospf_max_metric_router_lsa_admin_cmd); - install_element (OSPF_NODE, &ospf_max_metric_router_lsa_startup_cmd); - install_element (OSPF_NODE, &no_ospf_max_metric_router_lsa_startup_cmd); - install_element (OSPF_NODE, &ospf_max_metric_router_lsa_shutdown_cmd); - install_element (OSPF_NODE, &no_ospf_max_metric_router_lsa_shutdown_cmd); - - /* reference bandwidth commands */ - install_element (OSPF_NODE, &ospf_auto_cost_reference_bandwidth_cmd); - install_element (OSPF_NODE, &no_ospf_auto_cost_reference_bandwidth_cmd); - - /* "neighbor" commands. */ - install_element (OSPF_NODE, &ospf_neighbor_cmd); - install_element (OSPF_NODE, &ospf_neighbor_poll_interval_cmd); - install_element (OSPF_NODE, &no_ospf_neighbor_cmd); - install_element (OSPF_NODE, &no_ospf_neighbor_poll_cmd); - - /* write multiplier commands */ - install_element (OSPF_NODE, &ospf_write_multiplier_cmd); - install_element (OSPF_NODE, &write_multiplier_cmd); - install_element (OSPF_NODE, &no_ospf_write_multiplier_cmd); - install_element (OSPF_NODE, &no_write_multiplier_cmd); - - /* Init interface related vty commands. */ - ospf_vty_if_init (); - - /* Init zebra related vty commands. */ - ospf_vty_zebra_init (); +void ospf_vty_init(void) +{ + /* Install ospf top node. */ + install_node(&ospf_node, ospf_config_write); + + /* "router ospf" commands. */ + install_element(CONFIG_NODE, &router_ospf_cmd); + install_element(CONFIG_NODE, &no_router_ospf_cmd); + + + install_default(OSPF_NODE); + + /* "ospf router-id" commands. */ + install_element(OSPF_NODE, &ospf_router_id_cmd); + install_element(OSPF_NODE, &ospf_router_id_old_cmd); + install_element(OSPF_NODE, &no_ospf_router_id_cmd); + + /* "passive-interface" commands. */ + install_element(OSPF_NODE, &ospf_passive_interface_addr_cmd); + install_element(OSPF_NODE, &no_ospf_passive_interface_addr_cmd); + + /* "ospf abr-type" commands. */ + install_element(OSPF_NODE, &ospf_abr_type_cmd); + install_element(OSPF_NODE, &no_ospf_abr_type_cmd); + + /* "ospf log-adjacency-changes" commands. */ + install_element(OSPF_NODE, &ospf_log_adjacency_changes_cmd); + install_element(OSPF_NODE, &ospf_log_adjacency_changes_detail_cmd); + install_element(OSPF_NODE, &no_ospf_log_adjacency_changes_cmd); + install_element(OSPF_NODE, &no_ospf_log_adjacency_changes_detail_cmd); + + /* "ospf rfc1583-compatible" commands. */ + install_element(OSPF_NODE, &ospf_compatible_rfc1583_cmd); + install_element(OSPF_NODE, &no_ospf_compatible_rfc1583_cmd); + install_element(OSPF_NODE, &ospf_rfc1583_flag_cmd); + install_element(OSPF_NODE, &no_ospf_rfc1583_flag_cmd); + + /* "network area" commands. */ + install_element(OSPF_NODE, &ospf_network_area_cmd); + install_element(OSPF_NODE, &no_ospf_network_area_cmd); + + /* "area authentication" commands. */ + install_element(OSPF_NODE, + &ospf_area_authentication_message_digest_cmd); + install_element(OSPF_NODE, &ospf_area_authentication_cmd); + install_element(OSPF_NODE, &no_ospf_area_authentication_cmd); + + /* "area range" commands. */ + install_element(OSPF_NODE, &ospf_area_range_cmd); + install_element(OSPF_NODE, &ospf_area_range_cost_cmd); + install_element(OSPF_NODE, &ospf_area_range_not_advertise_cmd); + install_element(OSPF_NODE, &no_ospf_area_range_cmd); + install_element(OSPF_NODE, &ospf_area_range_substitute_cmd); + install_element(OSPF_NODE, &no_ospf_area_range_substitute_cmd); + + /* "area virtual-link" commands. */ + install_element(OSPF_NODE, &ospf_area_vlink_cmd); + install_element(OSPF_NODE, &ospf_area_vlink_intervals_cmd); + install_element(OSPF_NODE, &no_ospf_area_vlink_cmd); + install_element(OSPF_NODE, &no_ospf_area_vlink_intervals_cmd); + + + /* "area stub" commands. */ + install_element(OSPF_NODE, &ospf_area_stub_no_summary_cmd); + install_element(OSPF_NODE, &ospf_area_stub_cmd); + install_element(OSPF_NODE, &no_ospf_area_stub_no_summary_cmd); + install_element(OSPF_NODE, &no_ospf_area_stub_cmd); + + /* "area nssa" commands. */ + install_element(OSPF_NODE, &ospf_area_nssa_cmd); + install_element(OSPF_NODE, &ospf_area_nssa_translate_no_summary_cmd); + install_element(OSPF_NODE, &ospf_area_nssa_translate_cmd); + install_element(OSPF_NODE, &ospf_area_nssa_no_summary_cmd); + install_element(OSPF_NODE, &no_ospf_area_nssa_cmd); + + install_element(OSPF_NODE, &ospf_area_default_cost_cmd); + install_element(OSPF_NODE, &no_ospf_area_default_cost_cmd); + + install_element(OSPF_NODE, &ospf_area_shortcut_cmd); + install_element(OSPF_NODE, &no_ospf_area_shortcut_cmd); + + install_element(OSPF_NODE, &ospf_area_export_list_cmd); + install_element(OSPF_NODE, &no_ospf_area_export_list_cmd); + + install_element(OSPF_NODE, &ospf_area_filter_list_cmd); + install_element(OSPF_NODE, &no_ospf_area_filter_list_cmd); + + install_element(OSPF_NODE, &ospf_area_import_list_cmd); + install_element(OSPF_NODE, &no_ospf_area_import_list_cmd); + + /* SPF timer commands */ + install_element(OSPF_NODE, &ospf_timers_throttle_spf_cmd); + install_element(OSPF_NODE, &no_ospf_timers_throttle_spf_cmd); + + /* LSA timers commands */ + install_element(OSPF_NODE, &ospf_timers_min_ls_interval_cmd); + install_element(OSPF_NODE, &no_ospf_timers_min_ls_interval_cmd); + install_element(OSPF_NODE, &ospf_timers_min_ls_arrival_cmd); + install_element(OSPF_NODE, &no_ospf_timers_min_ls_arrival_cmd); + install_element(OSPF_NODE, &ospf_timers_lsa_cmd); + install_element(OSPF_NODE, &no_ospf_timers_lsa_cmd); + + /* refresh timer commands */ + install_element(OSPF_NODE, &ospf_refresh_timer_cmd); + install_element(OSPF_NODE, &no_ospf_refresh_timer_val_cmd); + + /* max-metric commands */ + install_element(OSPF_NODE, &ospf_max_metric_router_lsa_admin_cmd); + install_element(OSPF_NODE, &no_ospf_max_metric_router_lsa_admin_cmd); + install_element(OSPF_NODE, &ospf_max_metric_router_lsa_startup_cmd); + install_element(OSPF_NODE, &no_ospf_max_metric_router_lsa_startup_cmd); + install_element(OSPF_NODE, &ospf_max_metric_router_lsa_shutdown_cmd); + install_element(OSPF_NODE, &no_ospf_max_metric_router_lsa_shutdown_cmd); + + /* reference bandwidth commands */ + install_element(OSPF_NODE, &ospf_auto_cost_reference_bandwidth_cmd); + install_element(OSPF_NODE, &no_ospf_auto_cost_reference_bandwidth_cmd); + + /* "neighbor" commands. */ + install_element(OSPF_NODE, &ospf_neighbor_cmd); + install_element(OSPF_NODE, &ospf_neighbor_poll_interval_cmd); + install_element(OSPF_NODE, &no_ospf_neighbor_cmd); + install_element(OSPF_NODE, &no_ospf_neighbor_poll_cmd); + + /* write multiplier commands */ + install_element(OSPF_NODE, &ospf_write_multiplier_cmd); + install_element(OSPF_NODE, &write_multiplier_cmd); + install_element(OSPF_NODE, &no_ospf_write_multiplier_cmd); + install_element(OSPF_NODE, &no_write_multiplier_cmd); + + /* Init interface related vty commands. */ + ospf_vty_if_init(); + + /* Init zebra related vty commands. */ + ospf_vty_zebra_init(); } diff --git a/ospfd/ospf_vty.h b/ospfd/ospf_vty.h index ba7b24ed9..9fd0c3ed4 100644 --- a/ospfd/ospf_vty.h +++ b/ospfd/ospf_vty.h @@ -22,38 +22,36 @@ #define _QUAGGA_OSPF_VTY_H /* Macros. */ -#define VTY_GET_OSPF_AREA_ID(V,F,STR) \ -{ \ - int retv; \ - retv = str2area_id ((STR), &(V), &(F)); \ - if (retv < 0) \ - { \ - vty_out (vty, "%% Invalid OSPF area ID\n"); \ - return CMD_WARNING; \ - } \ -} +#define VTY_GET_OSPF_AREA_ID(V, F, STR) \ + { \ + int retv; \ + retv = str2area_id((STR), &(V), &(F)); \ + if (retv < 0) { \ + vty_out(vty, "%% Invalid OSPF area ID\n"); \ + return CMD_WARNING; \ + } \ + } -#define VTY_GET_OSPF_AREA_ID_NO_BB(NAME,V,F,STR) \ -{ \ - int retv; \ - retv = str2area_id ((STR), &(V), &(F)); \ - if (retv < 0) \ - { \ - vty_out (vty, "%% Invalid OSPF area ID\n"); \ - return CMD_WARNING; \ - } \ - if (OSPF_IS_AREA_ID_BACKBONE ((V))) \ - { \ - vty_out (vty, "%% You can't configure %s to backbone\n", \ - NAME); \ - } \ -} +#define VTY_GET_OSPF_AREA_ID_NO_BB(NAME, V, F, STR) \ + { \ + int retv; \ + retv = str2area_id((STR), &(V), &(F)); \ + if (retv < 0) { \ + vty_out(vty, "%% Invalid OSPF area ID\n"); \ + return CMD_WARNING; \ + } \ + if (OSPF_IS_AREA_ID_BACKBONE((V))) { \ + vty_out(vty, \ + "%% You can't configure %s to backbone\n", \ + NAME); \ + } \ + } /* Prototypes. */ -extern void ospf_vty_init (void); -extern void ospf_vty_show_init (void); -extern void ospf_vty_clear_init (void); -extern int str2area_id (const char *, struct in_addr *, int *); -extern void area_id2str (char *, int, struct in_addr *, int); +extern void ospf_vty_init(void); +extern void ospf_vty_show_init(void); +extern void ospf_vty_clear_init(void); +extern int str2area_id(const char *, struct in_addr *, int *); +extern void area_id2str(char *, int, struct in_addr *, int); #endif /* _QUAGGA_OSPF_VTY_H */ diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index e262bd8aa..c6b0955da 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -51,8 +51,8 @@ #include "ospfd/ospf_zebra.h" #include "ospfd/ospf_te.h" -DEFINE_HOOK(ospf_if_update, (struct interface *ifp), (ifp)) -DEFINE_HOOK(ospf_if_delete, (struct interface *ifp), (ifp)) +DEFINE_HOOK(ospf_if_update, (struct interface * ifp), (ifp)) +DEFINE_HOOK(ospf_if_delete, (struct interface * ifp), (ifp)) /* Zebra structure to hold current status. */ struct zclient *zclient = NULL; @@ -62,1536 +62,1479 @@ extern struct thread_master *master; struct in_addr router_id_zebra; /* Router-id update message from zebra. */ -static int -ospf_router_id_update_zebra (int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int ospf_router_id_update_zebra(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct ospf *ospf; - struct prefix router_id; - zebra_router_id_update_read(zclient->ibuf,&router_id); - - if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE)) - { - char buf[PREFIX2STR_BUFFER]; - prefix2str(&router_id, buf, sizeof(buf)); - zlog_debug("Zebra rcvd: router id update %s", buf); - } - - router_id_zebra = router_id.u.prefix4; - - ospf = ospf_lookup (); - - if (ospf != NULL) - ospf_router_id_update (ospf); - - return 0; + struct ospf *ospf; + struct prefix router_id; + zebra_router_id_update_read(zclient->ibuf, &router_id); + + if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) { + char buf[PREFIX2STR_BUFFER]; + prefix2str(&router_id, buf, sizeof(buf)); + zlog_debug("Zebra rcvd: router id update %s", buf); + } + + router_id_zebra = router_id.u.prefix4; + + ospf = ospf_lookup(); + + if (ospf != NULL) + ospf_router_id_update(ospf); + + return 0; } /* Inteface addition message from zebra. */ -static int -ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length, - vrf_id_t vrf_id) +static int ospf_interface_add(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct interface *ifp; + struct interface *ifp; - ifp = zebra_interface_add_read (zclient->ibuf, vrf_id); + ifp = zebra_interface_add_read(zclient->ibuf, vrf_id); - if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE)) - zlog_debug ("Zebra: interface add %s[%u] index %d flags %llx metric %d mtu %d", - ifp->name, ifp->vrf_id, ifp->ifindex, (unsigned long long)ifp->flags, - ifp->metric, ifp->mtu); + if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) + zlog_debug( + "Zebra: interface add %s[%u] index %d flags %llx metric %d mtu %d", + ifp->name, ifp->vrf_id, ifp->ifindex, + (unsigned long long)ifp->flags, ifp->metric, ifp->mtu); - assert (ifp->info); + assert(ifp->info); - if (!OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (ifp), type)) - { - SET_IF_PARAM (IF_DEF_PARAMS (ifp), type); - IF_DEF_PARAMS (ifp)->type = ospf_default_iftype(ifp); - } + if (!OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp), type)) { + SET_IF_PARAM(IF_DEF_PARAMS(ifp), type); + IF_DEF_PARAMS(ifp)->type = ospf_default_iftype(ifp); + } - ospf_if_update (NULL, ifp); + ospf_if_update(NULL, ifp); - hook_call(ospf_if_update, ifp); + hook_call(ospf_if_update, ifp); - return 0; + return 0; } -static int -ospf_interface_delete (int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int ospf_interface_delete(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct interface *ifp; - struct stream *s; - struct route_node *rn; + struct interface *ifp; + struct stream *s; + struct route_node *rn; - s = zclient->ibuf; - /* zebra_interface_state_read() updates interface structure in iflist */ - ifp = zebra_interface_state_read (s, vrf_id); + s = zclient->ibuf; + /* zebra_interface_state_read() updates interface structure in iflist */ + ifp = zebra_interface_state_read(s, vrf_id); - if (ifp == NULL) - return 0; + if (ifp == NULL) + 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_DEBUG_OSPF (zebra, ZEBRA_INTERFACE)) - zlog_debug - ("Zebra: interface delete %s[%u] index %d flags %llx metric %d mtu %d", - ifp->name, ifp->vrf_id, ifp->ifindex, (unsigned long long)ifp->flags, ifp->metric, ifp->mtu); + if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) + zlog_debug( + "Zebra: interface delete %s[%u] index %d flags %llx metric %d mtu %d", + ifp->name, ifp->vrf_id, ifp->ifindex, + (unsigned long long)ifp->flags, ifp->metric, ifp->mtu); - hook_call(ospf_if_delete, ifp); + hook_call(ospf_if_delete, ifp); - for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn)) - if (rn->info) - ospf_if_free ((struct ospf_interface *) rn->info); + for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) + if (rn->info) + ospf_if_free((struct ospf_interface *)rn->info); - ifp->ifindex = IFINDEX_DELETED; - return 0; + ifp->ifindex = IFINDEX_DELETED; + return 0; } -static struct interface * -zebra_interface_if_lookup (struct stream *s, vrf_id_t vrf_id) +static struct interface *zebra_interface_if_lookup(struct stream *s, + vrf_id_t vrf_id) { - char ifname_tmp[INTERFACE_NAMSIZ]; + char ifname_tmp[INTERFACE_NAMSIZ]; - /* Read interface name. */ - stream_get (ifname_tmp, s, INTERFACE_NAMSIZ); + /* Read interface name. */ + stream_get(ifname_tmp, s, INTERFACE_NAMSIZ); - /* And look it up. */ - return if_lookup_by_name_len(ifname_tmp, - strnlen(ifname_tmp, INTERFACE_NAMSIZ), - VRF_DEFAULT); + /* And look it up. */ + return if_lookup_by_name_len( + ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ), VRF_DEFAULT); } -static int -ospf_interface_state_up (int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int ospf_interface_state_up(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct interface *ifp; - struct ospf_interface *oi; - struct route_node *rn; - - ifp = zebra_interface_if_lookup (zclient->ibuf, vrf_id); - - if (ifp == NULL) - return 0; - - /* Interface is already up. */ - if (if_is_operative (ifp)) - { - /* Temporarily keep ifp values. */ - struct interface if_tmp; - memcpy (&if_tmp, ifp, sizeof (struct interface)); - - zebra_interface_if_set_value (zclient->ibuf, ifp); - - if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE)) - zlog_debug ("Zebra: Interface[%s] state update speed %u -> %u, bw %d -> %d", - ifp->name, if_tmp.speed, ifp->speed, if_tmp.bandwidth, ifp->bandwidth); - - ospf_if_recalculate_output_cost (ifp); - - if (if_tmp.mtu != ifp->mtu) - { - if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE)) - zlog_debug ("Zebra: Interface[%s] MTU change %u -> %u.", - ifp->name, if_tmp.mtu, ifp->mtu); - - /* Must reset the interface (simulate down/up) when MTU changes. */ - ospf_if_reset(ifp); + struct interface *ifp; + struct ospf_interface *oi; + struct route_node *rn; + + ifp = zebra_interface_if_lookup(zclient->ibuf, vrf_id); + + if (ifp == NULL) + return 0; + + /* Interface is already up. */ + if (if_is_operative(ifp)) { + /* Temporarily keep ifp values. */ + struct interface if_tmp; + memcpy(&if_tmp, ifp, sizeof(struct interface)); + + zebra_interface_if_set_value(zclient->ibuf, ifp); + + if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) + zlog_debug( + "Zebra: Interface[%s] state update speed %u -> %u, bw %d -> %d", + ifp->name, if_tmp.speed, ifp->speed, + if_tmp.bandwidth, ifp->bandwidth); + + ospf_if_recalculate_output_cost(ifp); + + if (if_tmp.mtu != ifp->mtu) { + if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) + zlog_debug( + "Zebra: Interface[%s] MTU change %u -> %u.", + ifp->name, if_tmp.mtu, ifp->mtu); + + /* Must reset the interface (simulate down/up) when MTU + * changes. */ + ospf_if_reset(ifp); + } + return 0; } - return 0; - } - zebra_interface_if_set_value (zclient->ibuf, ifp); + zebra_interface_if_set_value(zclient->ibuf, ifp); - if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE)) - zlog_debug ("Zebra: Interface[%s] state change to up.", ifp->name); + if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) + zlog_debug("Zebra: Interface[%s] state change to up.", + ifp->name); - for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn)) - { - if ((oi = rn->info) == NULL) - continue; + for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) { + if ((oi = rn->info) == NULL) + continue; - ospf_if_up (oi); - } + ospf_if_up(oi); + } - return 0; + return 0; } -static int -ospf_interface_state_down (int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int ospf_interface_state_down(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct interface *ifp; - struct ospf_interface *oi; - struct route_node *node; + struct interface *ifp; + struct ospf_interface *oi; + struct route_node *node; - ifp = zebra_interface_state_read (zclient->ibuf, vrf_id); + ifp = zebra_interface_state_read(zclient->ibuf, vrf_id); - if (ifp == NULL) - return 0; + if (ifp == NULL) + return 0; - if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE)) - zlog_debug ("Zebra: Interface[%s] state change to down.", ifp->name); + if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) + zlog_debug("Zebra: Interface[%s] state change to down.", + ifp->name); - for (node = route_top (IF_OIFS (ifp)); node; node = route_next (node)) - { - if ((oi = node->info) == NULL) - continue; - ospf_if_down (oi); - } + for (node = route_top(IF_OIFS(ifp)); node; node = route_next(node)) { + if ((oi = node->info) == NULL) + continue; + ospf_if_down(oi); + } - return 0; + return 0; } -static int -ospf_interface_address_add (int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int ospf_interface_address_add(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct connected *c; + struct connected *c; - c = zebra_interface_address_read (command, zclient->ibuf, vrf_id); + c = zebra_interface_address_read(command, zclient->ibuf, vrf_id); - if (c == NULL) - return 0; + if (c == NULL) + return 0; - if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE)) - { - char buf[PREFIX2STR_BUFFER]; - prefix2str(c->address, buf, sizeof(buf)); - zlog_debug("Zebra: interface %s address add %s", c->ifp->name, buf); - } + if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) { + char buf[PREFIX2STR_BUFFER]; + prefix2str(c->address, buf, sizeof(buf)); + zlog_debug("Zebra: interface %s address add %s", c->ifp->name, + buf); + } - ospf_if_update (NULL, c->ifp); + ospf_if_update(NULL, c->ifp); - hook_call(ospf_if_update, c->ifp); + hook_call(ospf_if_update, c->ifp); - return 0; + return 0; } -static int -ospf_interface_address_delete (int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int ospf_interface_address_delete(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct connected *c; - struct interface *ifp; - struct ospf_interface *oi; - struct route_node *rn; - struct prefix p; - - c = zebra_interface_address_read (command, zclient->ibuf, vrf_id); - - if (c == NULL) - return 0; - - if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE)) - { - char buf[PREFIX2STR_BUFFER]; - prefix2str(c->address, buf, sizeof(buf)); - zlog_debug("Zebra: interface %s address delete %s", c->ifp->name, buf); - } + struct connected *c; + struct interface *ifp; + struct ospf_interface *oi; + struct route_node *rn; + struct prefix p; + + c = zebra_interface_address_read(command, zclient->ibuf, vrf_id); + + if (c == NULL) + return 0; + + if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) { + char buf[PREFIX2STR_BUFFER]; + prefix2str(c->address, buf, sizeof(buf)); + zlog_debug("Zebra: interface %s address delete %s", + c->ifp->name, buf); + } - ifp = c->ifp; - p = *c->address; - p.prefixlen = IPV4_MAX_PREFIXLEN; + ifp = c->ifp; + p = *c->address; + p.prefixlen = IPV4_MAX_PREFIXLEN; - rn = route_node_lookup (IF_OIFS (ifp), &p); - if (!rn) - { - connected_free (c); - return 0; - } + rn = route_node_lookup(IF_OIFS(ifp), &p); + if (!rn) { + connected_free(c); + return 0; + } - assert (rn->info); - oi = rn->info; - route_unlock_node (rn); + assert(rn->info); + oi = rn->info; + route_unlock_node(rn); - /* Call interface hook functions to clean up */ - ospf_if_free (oi); + /* Call interface hook functions to clean up */ + ospf_if_free(oi); - hook_call(ospf_if_update, c->ifp); + hook_call(ospf_if_update, c->ifp); - connected_free (c); + connected_free(c); - return 0; + return 0; } -static int -ospf_interface_link_params (int command, struct zclient *zclient, - zebra_size_t length) +static int ospf_interface_link_params(int command, struct zclient *zclient, + zebra_size_t length) { - struct interface *ifp; + struct interface *ifp; - ifp = zebra_interface_link_params_read (zclient->ibuf); + ifp = zebra_interface_link_params_read(zclient->ibuf); - if (ifp == NULL) - return 0; + if (ifp == NULL) + return 0; - /* Update TE TLV */ - ospf_mpls_te_update_if (ifp); + /* Update TE TLV */ + ospf_mpls_te_update_if(ifp); - return 0; + return 0; } -void -ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or) +void ospf_zebra_add(struct prefix_ipv4 *p, struct ospf_route * or) { - u_char message; - u_char distance; - u_int32_t flags; - int psize; - struct stream *s; - struct ospf_path *path; - struct listnode *node; - struct ospf *ospf = ospf_lookup (); - - if ((ospf->instance && - redist_check_instance(&zclient->mi_redist[AFI_IP][ZEBRA_ROUTE_OSPF], ospf->instance)) - || - vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_OSPF], VRF_DEFAULT)) - { - message = 0; - flags = 0; - - /* OSPF pass nexthop and metric */ - SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP); - SET_FLAG (message, ZAPI_MESSAGE_METRIC); - - /* Distance value. */ - distance = ospf_distance_apply (p, or); - if (distance) - SET_FLAG (message, ZAPI_MESSAGE_DISTANCE); - - /* Check if path type is ASE */ - if (((or->path_type == OSPF_PATH_TYPE1_EXTERNAL) || - (or->path_type == OSPF_PATH_TYPE2_EXTERNAL)) && - (or->u.ext.tag > 0) && (or->u.ext.tag <= ROUTE_TAG_MAX)) - SET_FLAG (message, ZAPI_MESSAGE_TAG); - - /* Make packet. */ - s = zclient->obuf; - stream_reset (s); - - /* Put command, type, flags, message. */ - zclient_create_header (s, ZEBRA_IPV4_ROUTE_ADD, VRF_DEFAULT); - stream_putc (s, ZEBRA_ROUTE_OSPF); - stream_putw (s, ospf->instance); - stream_putl (s, flags); - stream_putc (s, message); - stream_putw (s, SAFI_UNICAST); - - /* Put prefix information. */ - psize = PSIZE (p->prefixlen); - stream_putc (s, p->prefixlen); - stream_write (s, (u_char *) & p->prefix, psize); - - /* Nexthop count. */ - stream_putc (s, or->paths->count); - - /* Nexthop, ifindex, distance and metric information. */ - for (ALL_LIST_ELEMENTS_RO (or->paths, node, path)) - { + u_char message; + u_char distance; + u_int32_t flags; + int psize; + struct stream *s; + struct ospf_path *path; + struct listnode *node; + struct ospf *ospf = ospf_lookup(); + + if ((ospf->instance + && redist_check_instance( + &zclient->mi_redist[AFI_IP][ZEBRA_ROUTE_OSPF], + ospf->instance)) + || vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_OSPF], + VRF_DEFAULT)) { + message = 0; + flags = 0; + + /* OSPF pass nexthop and metric */ + SET_FLAG(message, ZAPI_MESSAGE_NEXTHOP); + SET_FLAG(message, ZAPI_MESSAGE_METRIC); + + /* Distance value. */ + distance = ospf_distance_apply(p, or); + if (distance) + SET_FLAG(message, ZAPI_MESSAGE_DISTANCE); + + /* Check if path type is ASE */ + if (((or->path_type == OSPF_PATH_TYPE1_EXTERNAL) + || (or->path_type == OSPF_PATH_TYPE2_EXTERNAL)) + && (or->u.ext.tag > 0) && (or->u.ext.tag <= ROUTE_TAG_MAX)) + SET_FLAG(message, ZAPI_MESSAGE_TAG); + + /* Make packet. */ + s = zclient->obuf; + stream_reset(s); + + /* Put command, type, flags, message. */ + zclient_create_header(s, ZEBRA_IPV4_ROUTE_ADD, VRF_DEFAULT); + stream_putc(s, ZEBRA_ROUTE_OSPF); + stream_putw(s, ospf->instance); + stream_putl(s, flags); + stream_putc(s, message); + stream_putw(s, SAFI_UNICAST); + + /* Put prefix information. */ + psize = PSIZE(p->prefixlen); + stream_putc(s, p->prefixlen); + stream_write(s, (u_char *)&p->prefix, psize); + + /* Nexthop count. */ + stream_putc(s, or->paths->count); + + /* Nexthop, ifindex, distance and metric information. */ + for (ALL_LIST_ELEMENTS_RO(or->paths, node, path)) { #ifdef HAVE_NETLINK - if (path->unnumbered || - (path->nexthop.s_addr != INADDR_ANY && - path->ifindex != 0)) - { - stream_putc (s, NEXTHOP_TYPE_IPV4_IFINDEX); - stream_put_in_addr (s, &path->nexthop); - stream_putl (s, path->ifindex); - } - else if (path->nexthop.s_addr != INADDR_ANY) - { - stream_putc (s, NEXTHOP_TYPE_IPV4); - stream_put_in_addr (s, &path->nexthop); - } - else - { - stream_putc (s, NEXTHOP_TYPE_IFINDEX); - if (path->ifindex) - stream_putl (s, path->ifindex); - else - stream_putl (s, 0); - } + if (path->unnumbered + || (path->nexthop.s_addr != INADDR_ANY + && path->ifindex != 0)) { + stream_putc(s, NEXTHOP_TYPE_IPV4_IFINDEX); + stream_put_in_addr(s, &path->nexthop); + stream_putl(s, path->ifindex); + } else if (path->nexthop.s_addr != INADDR_ANY) { + stream_putc(s, NEXTHOP_TYPE_IPV4); + stream_put_in_addr(s, &path->nexthop); + } else { + stream_putc(s, NEXTHOP_TYPE_IFINDEX); + if (path->ifindex) + stream_putl(s, path->ifindex); + else + stream_putl(s, 0); + } #else /* HAVE_NETLINK */ - if (path->nexthop.s_addr != INADDR_ANY && - path->ifindex != 0) - { - stream_putc (s, NEXTHOP_TYPE_IPV4_IFINDEX); - stream_put_in_addr (s, &path->nexthop); - stream_putl (s, path->ifindex); - } - else if (path->nexthop.s_addr != INADDR_ANY) - { - stream_putc (s, NEXTHOP_TYPE_IPV4); - stream_put_in_addr (s, &path->nexthop); - } - else - { - stream_putc (s, NEXTHOP_TYPE_IFINDEX); - if (path->ifindex) - stream_putl (s, path->ifindex); - else - stream_putl (s, 0); - } + if (path->nexthop.s_addr != INADDR_ANY + && path->ifindex != 0) { + stream_putc(s, NEXTHOP_TYPE_IPV4_IFINDEX); + stream_put_in_addr(s, &path->nexthop); + stream_putl(s, path->ifindex); + } else if (path->nexthop.s_addr != INADDR_ANY) { + stream_putc(s, NEXTHOP_TYPE_IPV4); + stream_put_in_addr(s, &path->nexthop); + } else { + stream_putc(s, NEXTHOP_TYPE_IFINDEX); + if (path->ifindex) + stream_putl(s, path->ifindex); + else + stream_putl(s, 0); + } #endif /* HAVE_NETLINK */ - if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE)) - { - char buf[2][INET_ADDRSTRLEN]; - zlog_debug("Zebra: Route add %s/%d nexthop %s, ifindex=%d", - inet_ntop(AF_INET, &p->prefix, - buf[0], sizeof(buf[0])), - p->prefixlen, - inet_ntop(AF_INET, &path->nexthop, - buf[1], sizeof(buf[1])), - path->ifindex); - } - } - - if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE)) - stream_putc (s, distance); - if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC)) - { - if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL) - stream_putl (s, or->cost + or->u.ext.type2_cost); - else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL) - stream_putl (s, or->u.ext.type2_cost); - else - stream_putl (s, or->cost); - } - - if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG)) - stream_putl (s, or->u.ext.tag); - - stream_putw_at (s, 0, stream_get_endp (s)); - - zclient_send_message(zclient); - } + if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) { + char buf[2][INET_ADDRSTRLEN]; + zlog_debug( + "Zebra: Route add %s/%d nexthop %s, ifindex=%d", + inet_ntop(AF_INET, &p->prefix, buf[0], + sizeof(buf[0])), + p->prefixlen, + inet_ntop(AF_INET, &path->nexthop, + buf[1], sizeof(buf[1])), + path->ifindex); + } + } + + if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE)) + stream_putc(s, distance); + if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC)) { + if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL) + stream_putl(s, or->cost + or->u.ext.type2_cost); + else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL) + stream_putl(s, or->u.ext.type2_cost); + else + stream_putl(s, or->cost); + } + + if (CHECK_FLAG(message, ZAPI_MESSAGE_TAG)) + stream_putl(s, or->u.ext.tag); + + stream_putw_at(s, 0, stream_get_endp(s)); + + zclient_send_message(zclient); + } } -void -ospf_zebra_delete (struct prefix_ipv4 *p, struct ospf_route *or) +void ospf_zebra_delete(struct prefix_ipv4 *p, struct ospf_route * or) { - u_char message; - u_char distance; - u_int32_t flags; - int psize; - struct stream *s; - struct ospf_path *path; - struct listnode *node; - struct ospf *ospf = ospf_lookup (); - - if ((ospf->instance && - redist_check_instance(&zclient->mi_redist[AFI_IP][ZEBRA_ROUTE_OSPF], ospf->instance)) - || - vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_OSPF], VRF_DEFAULT)) - { - message = 0; - flags = 0; - /* Distance value. */ - distance = ospf_distance_apply (p, or); - /* Make packet. */ - s = zclient->obuf; - stream_reset (s); - - /* Put command, type, flags, message. */ - zclient_create_header (s, ZEBRA_IPV4_ROUTE_DELETE, VRF_DEFAULT); - stream_putc (s, ZEBRA_ROUTE_OSPF); - stream_putw (s, ospf->instance); - stream_putl (s, flags); - stream_putc (s, message); - stream_putw (s, SAFI_UNICAST); - - /* Put prefix information. */ - psize = PSIZE (p->prefixlen); - stream_putc (s, p->prefixlen); - stream_write (s, (u_char *) & p->prefix, psize); - - /* Nexthop count. */ - stream_putc (s, or->paths->count); - - /* Nexthop, ifindex, distance and metric information. */ - for (ALL_LIST_ELEMENTS_RO (or->paths, node, path)) - { - if (path->nexthop.s_addr != INADDR_ANY && - path->ifindex != 0) - { - stream_putc (s, NEXTHOP_TYPE_IPV4_IFINDEX); - stream_put_in_addr (s, &path->nexthop); - stream_putl (s, path->ifindex); - } - else if (path->nexthop.s_addr != INADDR_ANY) - { - stream_putc (s, NEXTHOP_TYPE_IPV4); - stream_put_in_addr (s, &path->nexthop); - } - else - { - stream_putc (s, NEXTHOP_TYPE_IFINDEX); - stream_putl (s, path->ifindex); - } - - if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE)) - { - char buf[2][INET_ADDRSTRLEN]; - zlog_debug("Zebra: Route delete %s/%d nexthop %s", - inet_ntop(AF_INET, &p->prefix, - buf[0], sizeof(buf[0])), - p->prefixlen, - inet_ntop(AF_INET, &path->nexthop, - buf[1], sizeof(buf[1]))); - } - } - - if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE)) - stream_putc (s, distance); - if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC)) - { - if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL) - stream_putl (s, or->cost + or->u.ext.type2_cost); - else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL) - stream_putl (s, or->u.ext.type2_cost); - else - stream_putl (s, or->cost); + u_char message; + u_char distance; + u_int32_t flags; + int psize; + struct stream *s; + struct ospf_path *path; + struct listnode *node; + struct ospf *ospf = ospf_lookup(); + + if ((ospf->instance + && redist_check_instance( + &zclient->mi_redist[AFI_IP][ZEBRA_ROUTE_OSPF], + ospf->instance)) + || vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_OSPF], + VRF_DEFAULT)) { + message = 0; + flags = 0; + /* Distance value. */ + distance = ospf_distance_apply(p, or); + /* Make packet. */ + s = zclient->obuf; + stream_reset(s); + + /* Put command, type, flags, message. */ + zclient_create_header(s, ZEBRA_IPV4_ROUTE_DELETE, VRF_DEFAULT); + stream_putc(s, ZEBRA_ROUTE_OSPF); + stream_putw(s, ospf->instance); + stream_putl(s, flags); + stream_putc(s, message); + stream_putw(s, SAFI_UNICAST); + + /* Put prefix information. */ + psize = PSIZE(p->prefixlen); + stream_putc(s, p->prefixlen); + stream_write(s, (u_char *)&p->prefix, psize); + + /* Nexthop count. */ + stream_putc(s, or->paths->count); + + /* Nexthop, ifindex, distance and metric information. */ + for (ALL_LIST_ELEMENTS_RO(or->paths, node, path)) { + if (path->nexthop.s_addr != INADDR_ANY + && path->ifindex != 0) { + stream_putc(s, NEXTHOP_TYPE_IPV4_IFINDEX); + stream_put_in_addr(s, &path->nexthop); + stream_putl(s, path->ifindex); + } else if (path->nexthop.s_addr != INADDR_ANY) { + stream_putc(s, NEXTHOP_TYPE_IPV4); + stream_put_in_addr(s, &path->nexthop); + } else { + stream_putc(s, NEXTHOP_TYPE_IFINDEX); + stream_putl(s, path->ifindex); + } + + if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) { + char buf[2][INET_ADDRSTRLEN]; + zlog_debug( + "Zebra: Route delete %s/%d nexthop %s", + inet_ntop(AF_INET, &p->prefix, buf[0], + sizeof(buf[0])), + p->prefixlen, + inet_ntop(AF_INET, &path->nexthop, + buf[1], sizeof(buf[1]))); + } + } + + if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE)) + stream_putc(s, distance); + if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC)) { + if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL) + stream_putl(s, or->cost + or->u.ext.type2_cost); + else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL) + stream_putl(s, or->u.ext.type2_cost); + else + stream_putl(s, or->cost); + } + + stream_putw_at(s, 0, stream_get_endp(s)); + + zclient_send_message(zclient); } - - stream_putw_at (s, 0, stream_get_endp (s)); - - zclient_send_message(zclient); - } } -void -ospf_zebra_add_discard (struct prefix_ipv4 *p) +void ospf_zebra_add_discard(struct prefix_ipv4 *p) { - struct zapi_ipv4 api; - struct ospf *ospf = ospf_lookup (); - - if ((ospf->instance && - redist_check_instance(&zclient->mi_redist[AFI_IP][ZEBRA_ROUTE_OSPF], ospf->instance)) - || - vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_OSPF], VRF_DEFAULT)) - { - api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_OSPF; - api.instance = ospf->instance; - api.flags = ZEBRA_FLAG_BLACKHOLE; - api.message = 0; - api.safi = SAFI_UNICAST; - SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = 0; - api.ifindex_num = 0; - api.tag = 0; - - zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, p, &api); - - if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug ("Zebra: Route add discard %s/%d", - inet_ntoa (p->prefix), p->prefixlen); - } + struct zapi_ipv4 api; + struct ospf *ospf = ospf_lookup(); + + if ((ospf->instance + && redist_check_instance( + &zclient->mi_redist[AFI_IP][ZEBRA_ROUTE_OSPF], + ospf->instance)) + || vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_OSPF], + VRF_DEFAULT)) { + api.vrf_id = VRF_DEFAULT; + api.type = ZEBRA_ROUTE_OSPF; + api.instance = ospf->instance; + api.flags = ZEBRA_FLAG_BLACKHOLE; + api.message = 0; + api.safi = SAFI_UNICAST; + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + api.nexthop_num = 0; + api.ifindex_num = 0; + api.tag = 0; + + zapi_ipv4_route(ZEBRA_IPV4_ROUTE_ADD, zclient, p, &api); + + if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) + zlog_debug("Zebra: Route add discard %s/%d", + inet_ntoa(p->prefix), p->prefixlen); + } } -void -ospf_zebra_delete_discard (struct prefix_ipv4 *p) +void ospf_zebra_delete_discard(struct prefix_ipv4 *p) { - struct zapi_ipv4 api; - struct ospf *ospf = ospf_lookup (); - - if ((ospf->instance && - redist_check_instance(&zclient->mi_redist[AFI_IP][ZEBRA_ROUTE_OSPF], ospf->instance)) - || - vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_OSPF], VRF_DEFAULT)) - { - api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_OSPF; - api.instance = ospf->instance; - api.flags = ZEBRA_FLAG_BLACKHOLE; - api.message = 0; - api.safi = SAFI_UNICAST; - SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = 0; - api.ifindex_num = 0; - api.tag = 0; - - zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api); - - if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug ("Zebra: Route delete discard %s/%d", - inet_ntoa (p->prefix), p->prefixlen); - - } + struct zapi_ipv4 api; + struct ospf *ospf = ospf_lookup(); + + if ((ospf->instance + && redist_check_instance( + &zclient->mi_redist[AFI_IP][ZEBRA_ROUTE_OSPF], + ospf->instance)) + || vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_OSPF], + VRF_DEFAULT)) { + api.vrf_id = VRF_DEFAULT; + api.type = ZEBRA_ROUTE_OSPF; + api.instance = ospf->instance; + api.flags = ZEBRA_FLAG_BLACKHOLE; + api.message = 0; + api.safi = SAFI_UNICAST; + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + api.nexthop_num = 0; + api.ifindex_num = 0; + api.tag = 0; + + zapi_ipv4_route(ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api); + + if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) + zlog_debug("Zebra: Route delete discard %s/%d", + inet_ntoa(p->prefix), p->prefixlen); + } } -struct ospf_external * -ospf_external_lookup (u_char type, u_short instance) +struct ospf_external *ospf_external_lookup(u_char type, u_short instance) { - struct list *ext_list; - struct listnode *node; - struct ospf_external *ext; + struct list *ext_list; + struct listnode *node; + struct ospf_external *ext; - ext_list = om->external[type]; - if (!ext_list) - return(NULL); + ext_list = om->external[type]; + if (!ext_list) + return (NULL); - for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) - if (ext->instance == instance) - return ext; + for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) + if (ext->instance == instance) + return ext; - return NULL; + return NULL; } -struct ospf_external * -ospf_external_add (u_char type, u_short instance) +struct ospf_external *ospf_external_add(u_char type, u_short instance) { - struct list *ext_list; - struct ospf_external *ext; + struct list *ext_list; + struct ospf_external *ext; - ext = ospf_external_lookup(type, instance); - if (ext) - return ext; + ext = ospf_external_lookup(type, instance); + if (ext) + return ext; - if (!om->external[type]) - om->external[type] = list_new(); + if (!om->external[type]) + om->external[type] = list_new(); - ext_list = om->external[type]; - ext = (struct ospf_external *)calloc (1, sizeof(struct ospf_external)); - ext->instance = instance; - EXTERNAL_INFO (ext) = route_table_init (); + ext_list = om->external[type]; + ext = (struct ospf_external *)calloc(1, sizeof(struct ospf_external)); + ext->instance = instance; + EXTERNAL_INFO(ext) = route_table_init(); - listnode_add(ext_list, ext); + listnode_add(ext_list, ext); - return ext; + return ext; } -void -ospf_external_del (u_char type, u_short instance) +void ospf_external_del(u_char type, u_short instance) { - struct ospf_external *ext; - - ext = ospf_external_lookup(type, instance); - - if (ext) - { - if (EXTERNAL_INFO (ext)) - route_table_finish(EXTERNAL_INFO (ext)); - - listnode_delete(om->external[type], ext); - if (!om->external[type]->count) - { - list_free(om->external[type]); - om->external[type] = NULL; - } - } + struct ospf_external *ext; + + ext = ospf_external_lookup(type, instance); + + if (ext) { + if (EXTERNAL_INFO(ext)) + route_table_finish(EXTERNAL_INFO(ext)); + + listnode_delete(om->external[type], ext); + if (!om->external[type]->count) { + list_free(om->external[type]); + om->external[type] = NULL; + } + } } -struct ospf_redist * -ospf_redist_lookup (struct ospf *ospf, u_char type, u_short instance) +struct ospf_redist *ospf_redist_lookup(struct ospf *ospf, u_char type, + u_short instance) { - struct list *red_list; - struct listnode *node; - struct ospf_redist *red; + struct list *red_list; + struct listnode *node; + struct ospf_redist *red; - red_list = ospf->redist[type]; - if (!red_list) - return(NULL); + red_list = ospf->redist[type]; + if (!red_list) + return (NULL); - for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) - if (red->instance == instance) - return red; + for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) + if (red->instance == instance) + return red; - return NULL; + return NULL; } -struct ospf_redist * -ospf_redist_add (struct ospf *ospf, u_char type, u_short instance) +struct ospf_redist *ospf_redist_add(struct ospf *ospf, u_char type, + u_short instance) { - struct list *red_list; - struct ospf_redist *red; + struct list *red_list; + struct ospf_redist *red; - red = ospf_redist_lookup(ospf, type, instance); - if (red) - return red; + red = ospf_redist_lookup(ospf, type, instance); + if (red) + return red; - if (!ospf->redist[type]) - ospf->redist[type] = list_new(); + if (!ospf->redist[type]) + ospf->redist[type] = list_new(); - red_list = ospf->redist[type]; - red = (struct ospf_redist *)calloc (1, sizeof(struct ospf_redist)); - red->instance = instance; - red->dmetric.type = -1; - red->dmetric.value = -1; + red_list = ospf->redist[type]; + red = (struct ospf_redist *)calloc(1, sizeof(struct ospf_redist)); + red->instance = instance; + red->dmetric.type = -1; + red->dmetric.value = -1; - listnode_add(red_list, red); + listnode_add(red_list, red); - return red; + return red; } -void -ospf_redist_del (struct ospf *ospf, u_char type, u_short instance) +void ospf_redist_del(struct ospf *ospf, u_char type, u_short instance) { - struct ospf_redist *red; - - red = ospf_redist_lookup(ospf, type, instance); - - if (red) - { - listnode_delete(ospf->redist[type], red); - if (!ospf->redist[type]->count) - { - list_free(ospf->redist[type]); - ospf->redist[type] = NULL; - } - } + struct ospf_redist *red; + + red = ospf_redist_lookup(ospf, type, instance); + + if (red) { + listnode_delete(ospf->redist[type], red); + if (!ospf->redist[type]->count) { + list_free(ospf->redist[type]); + ospf->redist[type] = NULL; + } + } } -int -ospf_is_type_redistributed (int type, u_short instance) +int ospf_is_type_redistributed(int type, u_short instance) { - return (DEFAULT_ROUTE_TYPE (type) ? - vrf_bitmap_check (zclient->default_information, VRF_DEFAULT) : - ((instance && redist_check_instance(&zclient->mi_redist[AFI_IP][type], instance)) - || (!instance && vrf_bitmap_check (zclient->redist[AFI_IP][type], VRF_DEFAULT)))); + return (DEFAULT_ROUTE_TYPE(type) + ? vrf_bitmap_check(zclient->default_information, + VRF_DEFAULT) + : ((instance + && redist_check_instance( + &zclient->mi_redist[AFI_IP][type], + instance)) + || (!instance + && vrf_bitmap_check( + zclient->redist[AFI_IP][type], + VRF_DEFAULT)))); } -int -ospf_redistribute_set (struct ospf *ospf, int type, u_short instance, int mtype, - int mvalue) +int ospf_redistribute_set(struct ospf *ospf, int type, u_short instance, + int mtype, int mvalue) { - int force = 0; - struct ospf_redist *red; - - red = ospf_redist_lookup(ospf, type, instance); - if (ospf_is_type_redistributed (type, instance)) - { - if (mtype != red->dmetric.type) - { - red->dmetric.type = mtype; - force = LSA_REFRESH_FORCE; - } - if (mvalue != red->dmetric.value) - { - red->dmetric.value = mvalue; - force = LSA_REFRESH_FORCE; - } - - ospf_external_lsa_refresh_type (ospf, type, instance, force); - - if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug ("Redistribute[%s][%d]: Refresh Type[%d], Metric[%d]", - ospf_redist_string(type), instance, - metric_type (ospf, type, instance), - metric_value (ospf, type, instance)); - - return CMD_SUCCESS; - } - - red->dmetric.type = mtype; - red->dmetric.value = mvalue; - - ospf_external_add(type, instance); - - zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type, - instance, VRF_DEFAULT); - - if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug ("Redistribute[%s][%d]: Start Type[%d], Metric[%d]", - ospf_redist_string(type), instance, - metric_type (ospf, type, instance), metric_value (ospf, type, instance)); - - ospf_asbr_status_update (ospf, ++ospf->redistribute); - - return CMD_SUCCESS; + int force = 0; + struct ospf_redist *red; + + red = ospf_redist_lookup(ospf, type, instance); + if (ospf_is_type_redistributed(type, instance)) { + if (mtype != red->dmetric.type) { + red->dmetric.type = mtype; + force = LSA_REFRESH_FORCE; + } + if (mvalue != red->dmetric.value) { + red->dmetric.value = mvalue; + force = LSA_REFRESH_FORCE; + } + + ospf_external_lsa_refresh_type(ospf, type, instance, force); + + if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) + zlog_debug( + "Redistribute[%s][%d]: Refresh Type[%d], Metric[%d]", + ospf_redist_string(type), instance, + metric_type(ospf, type, instance), + metric_value(ospf, type, instance)); + + return CMD_SUCCESS; + } + + red->dmetric.type = mtype; + red->dmetric.value = mvalue; + + ospf_external_add(type, instance); + + zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type, + instance, VRF_DEFAULT); + + if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) + zlog_debug("Redistribute[%s][%d]: Start Type[%d], Metric[%d]", + ospf_redist_string(type), instance, + metric_type(ospf, type, instance), + metric_value(ospf, type, instance)); + + ospf_asbr_status_update(ospf, ++ospf->redistribute); + + return CMD_SUCCESS; } -int -ospf_redistribute_unset (struct ospf *ospf, int type, u_short instance) +int ospf_redistribute_unset(struct ospf *ospf, int type, u_short instance) { - if (type == zclient->redist_default && instance == zclient->instance) - return CMD_SUCCESS; + if (type == zclient->redist_default && instance == zclient->instance) + return CMD_SUCCESS; - if (!ospf_is_type_redistributed (type, instance)) - return CMD_SUCCESS; + if (!ospf_is_type_redistributed(type, instance)) + return CMD_SUCCESS; - zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, type, - instance, VRF_DEFAULT); + zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, type, + instance, VRF_DEFAULT); - if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug ("Redistribute[%s][%d]: Stop", - ospf_redist_string(type), instance); + if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) + zlog_debug("Redistribute[%s][%d]: Stop", + ospf_redist_string(type), instance); - ospf_redist_del (ospf, type, instance); + ospf_redist_del(ospf, type, instance); - /* Remove the routes from OSPF table. */ - ospf_redistribute_withdraw (ospf, type, instance); + /* Remove the routes from OSPF table. */ + ospf_redistribute_withdraw(ospf, type, instance); - ospf_external_del(type, instance); + ospf_external_del(type, instance); - ospf_asbr_status_update (ospf, --ospf->redistribute); + ospf_asbr_status_update(ospf, --ospf->redistribute); - return CMD_SUCCESS; + return CMD_SUCCESS; } -int -ospf_redistribute_default_set (struct ospf *ospf, int originate, - int mtype, int mvalue) +int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype, + int mvalue) { - struct ospf_redist *red; + struct ospf_redist *red; - ospf->default_originate = originate; + ospf->default_originate = originate; - red = ospf_redist_add(ospf, DEFAULT_ROUTE, 0); - red->dmetric.type = mtype; - red->dmetric.value = mvalue; + red = ospf_redist_add(ospf, DEFAULT_ROUTE, 0); + red->dmetric.type = mtype; + red->dmetric.value = mvalue; - ospf_external_add(DEFAULT_ROUTE, 0); + ospf_external_add(DEFAULT_ROUTE, 0); - if (ospf_is_type_redistributed (DEFAULT_ROUTE, 0)) - { - /* if ospf->default_originate changes value, is calling - ospf_external_lsa_refresh_default sufficient to implement - the change? */ - ospf_external_lsa_refresh_default (ospf); + if (ospf_is_type_redistributed(DEFAULT_ROUTE, 0)) { + /* if ospf->default_originate changes value, is calling + ospf_external_lsa_refresh_default sufficient to implement + the change? */ + ospf_external_lsa_refresh_default(ospf); - if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug ("Redistribute[%s]: Refresh Type[%d], Metric[%d]", - ospf_redist_string(DEFAULT_ROUTE), - metric_type (ospf, DEFAULT_ROUTE, 0), - metric_value (ospf, DEFAULT_ROUTE, 0)); - return CMD_SUCCESS; - } + if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) + zlog_debug( + "Redistribute[%s]: Refresh Type[%d], Metric[%d]", + ospf_redist_string(DEFAULT_ROUTE), + metric_type(ospf, DEFAULT_ROUTE, 0), + metric_value(ospf, DEFAULT_ROUTE, 0)); + return CMD_SUCCESS; + } - zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient, - VRF_DEFAULT); + zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient, + VRF_DEFAULT); - if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug ("Redistribute[DEFAULT]: Start Type[%d], Metric[%d]", - metric_type (ospf, DEFAULT_ROUTE, 0), - metric_value (ospf, DEFAULT_ROUTE, 0)); + if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) + zlog_debug("Redistribute[DEFAULT]: Start Type[%d], Metric[%d]", + metric_type(ospf, DEFAULT_ROUTE, 0), + metric_value(ospf, DEFAULT_ROUTE, 0)); - if (ospf->router_id.s_addr == 0) - ospf->external_origin |= (1 << DEFAULT_ROUTE); - else - thread_add_timer(master, ospf_default_originate_timer, ospf, 1, NULL); + if (ospf->router_id.s_addr == 0) + ospf->external_origin |= (1 << DEFAULT_ROUTE); + else + thread_add_timer(master, ospf_default_originate_timer, ospf, 1, + NULL); - ospf_asbr_status_update (ospf, ++ospf->redistribute); + ospf_asbr_status_update(ospf, ++ospf->redistribute); - return CMD_SUCCESS; + return CMD_SUCCESS; } -int -ospf_redistribute_default_unset (struct ospf *ospf) +int ospf_redistribute_default_unset(struct ospf *ospf) { - if (!ospf_is_type_redistributed (DEFAULT_ROUTE, 0)) - return CMD_SUCCESS; + if (!ospf_is_type_redistributed(DEFAULT_ROUTE, 0)) + return CMD_SUCCESS; - ospf->default_originate = DEFAULT_ORIGINATE_NONE; - ospf_redist_del(ospf, DEFAULT_ROUTE, 0); + ospf->default_originate = DEFAULT_ORIGINATE_NONE; + ospf_redist_del(ospf, DEFAULT_ROUTE, 0); - zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient, - VRF_DEFAULT); + zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient, + VRF_DEFAULT); - if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug ("Redistribute[DEFAULT]: Stop"); + if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) + zlog_debug("Redistribute[DEFAULT]: Stop"); - //Pending: how does the external_info cleanup work in this case? + // Pending: how does the external_info cleanup work in this case? - ospf_asbr_status_update (ospf, --ospf->redistribute); + ospf_asbr_status_update(ospf, --ospf->redistribute); - return CMD_SUCCESS; + return CMD_SUCCESS; } -static int -ospf_external_lsa_originate_check (struct ospf *ospf, - struct external_info *ei) +static int ospf_external_lsa_originate_check(struct ospf *ospf, + struct external_info *ei) { - /* If prefix is multicast, then do not originate LSA. */ - if (IN_MULTICAST (htonl (ei->p.prefix.s_addr))) - { - zlog_info ("LSA[Type5:%s]: Not originate AS-external-LSA, " - "Prefix belongs multicast", inet_ntoa (ei->p.prefix)); - return 0; - } - - /* Take care of default-originate. */ - if (is_prefix_default (&ei->p)) - if (ospf->default_originate == DEFAULT_ORIGINATE_NONE) - { - zlog_info ("LSA[Type5:0.0.0.0]: Not originate AS-external-LSA " - "for default"); - return 0; - } - - return 1; + /* If prefix is multicast, then do not originate LSA. */ + if (IN_MULTICAST(htonl(ei->p.prefix.s_addr))) { + zlog_info( + "LSA[Type5:%s]: Not originate AS-external-LSA, " + "Prefix belongs multicast", + inet_ntoa(ei->p.prefix)); + return 0; + } + + /* Take care of default-originate. */ + if (is_prefix_default(&ei->p)) + if (ospf->default_originate == DEFAULT_ORIGINATE_NONE) { + zlog_info( + "LSA[Type5:0.0.0.0]: Not originate AS-external-LSA " + "for default"); + return 0; + } + + return 1; } /* If connected prefix is OSPF enable interface, then do not announce. */ -int -ospf_distribute_check_connected (struct ospf *ospf, struct external_info *ei) +int ospf_distribute_check_connected(struct ospf *ospf, struct external_info *ei) { - struct listnode *node; - struct ospf_interface *oi; + struct listnode *node; + struct ospf_interface *oi; - for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) - if (prefix_match (oi->address, (struct prefix *) &ei->p)) - return 0; - return 1; + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) + if (prefix_match(oi->address, (struct prefix *)&ei->p)) + return 0; + return 1; } /* return 1 if external LSA must be originated, 0 otherwise */ -int -ospf_redistribute_check (struct ospf *ospf, - struct external_info *ei, int *changed) +int ospf_redistribute_check(struct ospf *ospf, struct external_info *ei, + int *changed) { - struct route_map_set_values save_values; - struct prefix_ipv4 *p = &ei->p; - struct ospf_redist *red; - u_char type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type; - u_short instance = is_prefix_default (&ei->p) ? 0 : ei->instance; - - if (changed) - *changed = 0; - - if (!ospf_external_lsa_originate_check (ospf, ei)) - return 0; - - /* Take care connected route. */ - if (type == ZEBRA_ROUTE_CONNECT && - !ospf_distribute_check_connected (ospf, ei)) - return 0; - - if (!DEFAULT_ROUTE_TYPE (type) && DISTRIBUTE_NAME (ospf, type)) - /* distirbute-list exists, but access-list may not? */ - if (DISTRIBUTE_LIST (ospf, type)) - if (access_list_apply (DISTRIBUTE_LIST (ospf, type), p) == FILTER_DENY) - { - if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug ("Redistribute[%s]: %s/%d filtered by ditribute-list.", - ospf_redist_string(type), - inet_ntoa (p->prefix), p->prefixlen); - return 0; - } - - save_values = ei->route_map_set; - ospf_reset_route_map_set_values (&ei->route_map_set); - - /* apply route-map if needed */ - red = ospf_redist_lookup (ospf, type, instance); - if (red && ROUTEMAP_NAME(red)) - { - int ret; - - ret = route_map_apply (ROUTEMAP (red), (struct prefix *) p, - RMAP_OSPF, ei); - - if (ret == RMAP_DENYMATCH) - { - ei->route_map_set = save_values; - if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug ("Redistribute[%s]: %s/%d filtered by route-map.", - ospf_redist_string(type), - inet_ntoa (p->prefix), p->prefixlen); - return 0; - } - - /* check if 'route-map set' changed something */ - if (changed) - *changed = !ospf_route_map_set_compare (&ei->route_map_set, - &save_values); - } - - return 1; + struct route_map_set_values save_values; + struct prefix_ipv4 *p = &ei->p; + struct ospf_redist *red; + u_char type = is_prefix_default(&ei->p) ? DEFAULT_ROUTE : ei->type; + u_short instance = is_prefix_default(&ei->p) ? 0 : ei->instance; + + if (changed) + *changed = 0; + + if (!ospf_external_lsa_originate_check(ospf, ei)) + return 0; + + /* Take care connected route. */ + if (type == ZEBRA_ROUTE_CONNECT + && !ospf_distribute_check_connected(ospf, ei)) + return 0; + + if (!DEFAULT_ROUTE_TYPE(type) && DISTRIBUTE_NAME(ospf, type)) + /* distirbute-list exists, but access-list may not? */ + if (DISTRIBUTE_LIST(ospf, type)) + if (access_list_apply(DISTRIBUTE_LIST(ospf, type), p) + == FILTER_DENY) { + if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) + zlog_debug( + "Redistribute[%s]: %s/%d filtered by ditribute-list.", + ospf_redist_string(type), + inet_ntoa(p->prefix), + p->prefixlen); + return 0; + } + + save_values = ei->route_map_set; + ospf_reset_route_map_set_values(&ei->route_map_set); + + /* apply route-map if needed */ + red = ospf_redist_lookup(ospf, type, instance); + if (red && ROUTEMAP_NAME(red)) { + int ret; + + ret = route_map_apply(ROUTEMAP(red), (struct prefix *)p, + RMAP_OSPF, ei); + + if (ret == RMAP_DENYMATCH) { + ei->route_map_set = save_values; + if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) + zlog_debug( + "Redistribute[%s]: %s/%d filtered by route-map.", + ospf_redist_string(type), + inet_ntoa(p->prefix), p->prefixlen); + return 0; + } + + /* check if 'route-map set' changed something */ + if (changed) + *changed = !ospf_route_map_set_compare( + &ei->route_map_set, &save_values); + } + + return 1; } /* OSPF route-map set for redistribution */ -void -ospf_routemap_set (struct ospf_redist *red, const char *name) +void ospf_routemap_set(struct ospf_redist *red, const char *name) { - if (ROUTEMAP_NAME (red)) - free (ROUTEMAP_NAME (red)); + if (ROUTEMAP_NAME(red)) + free(ROUTEMAP_NAME(red)); - ROUTEMAP_NAME (red) = strdup (name); - ROUTEMAP (red) = route_map_lookup_by_name (name); + ROUTEMAP_NAME(red) = strdup(name); + ROUTEMAP(red) = route_map_lookup_by_name(name); } -void -ospf_routemap_unset (struct ospf_redist *red) +void ospf_routemap_unset(struct ospf_redist *red) { - if (ROUTEMAP_NAME (red)) - free (ROUTEMAP_NAME (red)); + if (ROUTEMAP_NAME(red)) + free(ROUTEMAP_NAME(red)); - ROUTEMAP_NAME (red) = NULL; - ROUTEMAP (red) = NULL; + ROUTEMAP_NAME(red) = NULL; + ROUTEMAP(red) = NULL; } /* Zebra route add and delete treatment. */ -static int -ospf_zebra_read_ipv4 (int command, struct zclient *zclient, - zebra_size_t length, vrf_id_t vrf_id) +static int ospf_zebra_read_ipv4(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct stream *s; - struct zapi_ipv4 api; - unsigned long ifindex; - struct in_addr nexthop; - struct prefix_ipv4 p; - struct external_info *ei; - struct ospf *ospf; - int i; - - s = zclient->ibuf; - ifindex = 0; - nexthop.s_addr = 0; - - /* Type, flags, message. */ - api.type = stream_getc (s); - api.instance = stream_getw (s); - api.flags = stream_getl (s); - api.message = stream_getc (s); - - /* IPv4 prefix. */ - memset (&p, 0, sizeof (struct prefix_ipv4)); - p.family = AF_INET; - p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, stream_getc (s)); - stream_get (&p.prefix, s, PSIZE (p.prefixlen)); - - if (IPV4_NET127(ntohl(p.prefix.s_addr))) - return 0; - - /* Nexthop, ifindex, distance, metric. */ - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) - { - api.nexthop_num = stream_getc (s); - nexthop.s_addr = stream_get_ipv4 (s); - } - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) - { - api.ifindex_num = stream_getc (s); - /* XXX assert(api.ifindex_num == 1); */ - ifindex = stream_getl (s); - } - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE)) - api.distance = stream_getc (s); - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) - api.metric = stream_getl (s); - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG)) - api.tag = stream_getl (s); - else - api.tag = 0; - - ospf = ospf_lookup (); - if (ospf == NULL) - return 0; - - if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD) - { - /* XXX|HACK|TODO|FIXME: - * Maybe we should ignore reject/blackhole routes? Testing shows that - * there is no problems though and this is only way to "summarize" - * routes in ASBR at the moment. Maybe we need just a better generalised - * solution for these types? - * - * if ( CHECK_FLAG (api.flags, ZEBRA_FLAG_BLACKHOLE) - * || CHECK_FLAG (api.flags, ZEBRA_FLAG_REJECT)) - * return 0; - */ - - /* Protocol tag overwrites all other tag value send by zebra */ - if (ospf->dtag[api.type] > 0) - api.tag = ospf->dtag[api.type]; - - /* - * Given zebra sends update for a prefix via ADD message, it should - * be considered as an implicit DEL for that prefix with other source - * types. - */ - for (i = 0; i < ZEBRA_ROUTE_MAX; i++) - if (i != api.type) - ospf_external_info_delete(i, api.instance, p); - - ei = ospf_external_info_add (api.type, api.instance, p, ifindex, - nexthop, api.tag); - if (ei == NULL) + struct stream *s; + struct zapi_ipv4 api; + unsigned long ifindex; + struct in_addr nexthop; + struct prefix_ipv4 p; + struct external_info *ei; + struct ospf *ospf; + int i; + + s = zclient->ibuf; + ifindex = 0; + nexthop.s_addr = 0; + + /* Type, flags, message. */ + api.type = stream_getc(s); + api.instance = stream_getw(s); + api.flags = stream_getl(s); + api.message = stream_getc(s); + + /* IPv4 prefix. */ + memset(&p, 0, sizeof(struct prefix_ipv4)); + p.family = AF_INET; + p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, stream_getc(s)); + stream_get(&p.prefix, s, PSIZE(p.prefixlen)); + + if (IPV4_NET127(ntohl(p.prefix.s_addr))) + return 0; + + /* Nexthop, ifindex, distance, metric. */ + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { + api.nexthop_num = stream_getc(s); + nexthop.s_addr = stream_get_ipv4(s); + } + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) { + api.ifindex_num = stream_getc(s); + /* XXX assert(api.ifindex_num == 1); */ + ifindex = stream_getl(s); + } + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) + api.distance = stream_getc(s); + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) + api.metric = stream_getl(s); + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_TAG)) + api.tag = stream_getl(s); + else + api.tag = 0; + + ospf = ospf_lookup(); + if (ospf == NULL) + return 0; + + if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD) { + /* XXX|HACK|TODO|FIXME: + * Maybe we should ignore reject/blackhole routes? Testing shows + * that + * there is no problems though and this is only way to + * "summarize" + * routes in ASBR at the moment. Maybe we need just a better + * generalised + * solution for these types? + * + * if ( CHECK_FLAG (api.flags, ZEBRA_FLAG_BLACKHOLE) + * || CHECK_FLAG (api.flags, ZEBRA_FLAG_REJECT)) + * return 0; + */ + + /* Protocol tag overwrites all other tag value send by zebra */ + if (ospf->dtag[api.type] > 0) + api.tag = ospf->dtag[api.type]; + + /* + * Given zebra sends update for a prefix via ADD message, it + * should + * be considered as an implicit DEL for that prefix with other + * source + * types. + */ + for (i = 0; i < ZEBRA_ROUTE_MAX; i++) + if (i != api.type) + ospf_external_info_delete(i, api.instance, p); + + ei = ospf_external_info_add(api.type, api.instance, p, ifindex, + nexthop, api.tag); + if (ei == NULL) { + /* Nothing has changed, so nothing to do; return */ + return 0; + } + if (ospf->router_id.s_addr == 0) + /* Set flags to generate AS-external-LSA originate event + for each redistributed protocols later. */ + ospf->external_origin |= (1 << api.type); + else { + if (ei) { + if (is_prefix_default(&p)) + ospf_external_lsa_refresh_default(ospf); + else { + struct ospf_lsa *current; + + current = ospf_external_info_find_lsa( + ospf, &ei->p); + if (!current) + ospf_external_lsa_originate( + ospf, ei); + else { + if (IS_DEBUG_OSPF( + zebra, + ZEBRA_REDISTRIBUTE)) + zlog_debug( + "ospf_zebra_read_ipv4() : %s refreshing LSA", + inet_ntoa( + p.prefix)); + ospf_external_lsa_refresh( + ospf, current, ei, + LSA_REFRESH_FORCE); + } + } + } + } + } else /* if (command == ZEBRA_REDISTRIBUTE_IPV4_DEL) */ { - /* Nothing has changed, so nothing to do; return */ - return 0; + ospf_external_info_delete(api.type, api.instance, p); + if (is_prefix_default(&p)) + ospf_external_lsa_refresh_default(ospf); + else + ospf_external_lsa_flush(ospf, api.type, &p, + ifindex /*, nexthop */); } - if (ospf->router_id.s_addr == 0) - /* Set flags to generate AS-external-LSA originate event - for each redistributed protocols later. */ - ospf->external_origin |= (1 << api.type); - else - { - if (ei) - { - if (is_prefix_default (&p)) - ospf_external_lsa_refresh_default (ospf); - else - { - struct ospf_lsa *current; - - current = ospf_external_info_find_lsa (ospf, &ei->p); - if (!current) - ospf_external_lsa_originate (ospf, ei); - else - { - if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug ("ospf_zebra_read_ipv4() : %s refreshing LSA", - inet_ntoa (p.prefix)); - ospf_external_lsa_refresh (ospf, current, - ei, LSA_REFRESH_FORCE); - } - } - } - } - } - else /* if (command == ZEBRA_REDISTRIBUTE_IPV4_DEL) */ - { - ospf_external_info_delete (api.type, api.instance, p); - if (is_prefix_default (&p)) - ospf_external_lsa_refresh_default (ospf); - else - ospf_external_lsa_flush (ospf, api.type, &p, ifindex /*, nexthop */); - } - - return 0; + + return 0; } -int -ospf_distribute_list_out_set (struct ospf *ospf, int type, const char *name) +int ospf_distribute_list_out_set(struct ospf *ospf, int type, const char *name) { - /* Lookup access-list for distribute-list. */ - DISTRIBUTE_LIST (ospf, type) = access_list_lookup (AFI_IP, name); + /* Lookup access-list for distribute-list. */ + DISTRIBUTE_LIST(ospf, type) = access_list_lookup(AFI_IP, name); - /* Clear previous distribute-name. */ - if (DISTRIBUTE_NAME (ospf, type)) - free (DISTRIBUTE_NAME (ospf, type)); + /* Clear previous distribute-name. */ + if (DISTRIBUTE_NAME(ospf, type)) + free(DISTRIBUTE_NAME(ospf, type)); - /* Set distribute-name. */ - DISTRIBUTE_NAME (ospf, type) = strdup (name); + /* Set distribute-name. */ + DISTRIBUTE_NAME(ospf, type) = strdup(name); - /* If access-list have been set, schedule update timer. */ - if (DISTRIBUTE_LIST (ospf, type)) - ospf_distribute_list_update (ospf, type, 0); + /* If access-list have been set, schedule update timer. */ + if (DISTRIBUTE_LIST(ospf, type)) + ospf_distribute_list_update(ospf, type, 0); - return CMD_SUCCESS; + return CMD_SUCCESS; } -int -ospf_distribute_list_out_unset (struct ospf *ospf, int type, const char *name) +int ospf_distribute_list_out_unset(struct ospf *ospf, int type, + const char *name) { - /* Schedule update timer. */ - if (DISTRIBUTE_LIST (ospf, type)) - ospf_distribute_list_update (ospf, type, 0); + /* Schedule update timer. */ + if (DISTRIBUTE_LIST(ospf, type)) + ospf_distribute_list_update(ospf, type, 0); - /* Unset distribute-list. */ - DISTRIBUTE_LIST (ospf, type) = NULL; + /* Unset distribute-list. */ + DISTRIBUTE_LIST(ospf, type) = NULL; - /* Clear distribute-name. */ - if (DISTRIBUTE_NAME (ospf, type)) - free (DISTRIBUTE_NAME (ospf, type)); + /* Clear distribute-name. */ + if (DISTRIBUTE_NAME(ospf, type)) + free(DISTRIBUTE_NAME(ospf, type)); - DISTRIBUTE_NAME (ospf, type) = NULL; + DISTRIBUTE_NAME(ospf, type) = NULL; - return CMD_SUCCESS; + return CMD_SUCCESS; } /* distribute-list update timer. */ -static int -ospf_distribute_list_update_timer (struct thread *thread) +static int ospf_distribute_list_update_timer(struct thread *thread) { - struct route_node *rn; - struct external_info *ei; - struct route_table *rt; - struct ospf_lsa *lsa; - int type, default_refresh = 0; - struct ospf *ospf; - - ospf = ospf_lookup (); - if (ospf == NULL) - return 0; - - ospf->t_distribute_update = NULL; - - zlog_info ("Zebra[Redistribute]: distribute-list update timer fired!"); - - /* foreach all external info. */ - for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) - { - struct list *ext_list; - struct listnode *node; - struct ospf_external *ext; - - ext_list = om->external[type]; - if (!ext_list) - continue; - - for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) - { - rt = ext->external_info; - if (!rt) - continue; - for (rn = route_top (rt); rn; rn = route_next (rn)) - if ((ei = rn->info) != NULL) - { - if (is_prefix_default (&ei->p)) - default_refresh = 1; - else if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p))) - ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_IF_CHANGED); - else - ospf_external_lsa_originate (ospf, ei); - } - } - } - if (default_refresh) - ospf_external_lsa_refresh_default (ospf); - return 0; + struct route_node *rn; + struct external_info *ei; + struct route_table *rt; + struct ospf_lsa *lsa; + int type, default_refresh = 0; + struct ospf *ospf; + + ospf = ospf_lookup(); + if (ospf == NULL) + return 0; + + ospf->t_distribute_update = NULL; + + zlog_info("Zebra[Redistribute]: distribute-list update timer fired!"); + + /* foreach all external info. */ + for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) { + struct list *ext_list; + struct listnode *node; + struct ospf_external *ext; + + ext_list = om->external[type]; + if (!ext_list) + continue; + + for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) { + rt = ext->external_info; + if (!rt) + continue; + for (rn = route_top(rt); rn; rn = route_next(rn)) + if ((ei = rn->info) != NULL) { + if (is_prefix_default(&ei->p)) + default_refresh = 1; + else if ( + (lsa = ospf_external_info_find_lsa( + ospf, &ei->p))) + ospf_external_lsa_refresh( + ospf, lsa, ei, + LSA_REFRESH_IF_CHANGED); + else + ospf_external_lsa_originate( + ospf, ei); + } + } + } + if (default_refresh) + ospf_external_lsa_refresh_default(ospf); + return 0; } /* Update distribute-list and set timer to apply access-list. */ -void -ospf_distribute_list_update (struct ospf *ospf, uintptr_t type, - u_short instance) +void ospf_distribute_list_update(struct ospf *ospf, uintptr_t type, + u_short instance) { - struct route_table *rt; - struct ospf_external *ext; - - /* External info does not exist. */ - ext = ospf_external_lookup(type, instance); - if (!ext || !(rt = EXTERNAL_INFO (ext))) - return; - - /* If exists previously invoked thread, then let it continue. */ - if (ospf->t_distribute_update) - return; - - /* Set timer. */ - ospf->t_distribute_update = NULL; - thread_add_timer_msec(master, ospf_distribute_list_update_timer, (void *)type, ospf->min_ls_interval, - &ospf->t_distribute_update); + struct route_table *rt; + struct ospf_external *ext; + + /* External info does not exist. */ + ext = ospf_external_lookup(type, instance); + if (!ext || !(rt = EXTERNAL_INFO(ext))) + return; + + /* If exists previously invoked thread, then let it continue. */ + if (ospf->t_distribute_update) + return; + + /* Set timer. */ + ospf->t_distribute_update = NULL; + thread_add_timer_msec(master, ospf_distribute_list_update_timer, + (void *)type, ospf->min_ls_interval, + &ospf->t_distribute_update); } /* If access-list is updated, apply some check. */ -static void -ospf_filter_update (struct access_list *access) +static void ospf_filter_update(struct access_list *access) { - struct ospf *ospf; - int type; - int abr_inv = 0; - struct ospf_area *area; - struct listnode *node; - - /* If OSPF instance does not exist, return right now. */ - ospf = ospf_lookup (); - if (ospf == NULL) - return; - - /* Update distribute-list, and apply filter. */ - for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) - { - struct list *red_list; - struct listnode *node; - struct ospf_redist *red; - - red_list = ospf->redist[type]; - if (red_list) - for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) - { - if (ROUTEMAP (red)) - { - /* if route-map is not NULL it may be using this access list */ - ospf_distribute_list_update (ospf, type, red->instance); - } - } - - /* There is place for route-map for default-information (ZEBRA_ROUTE_MAX), - * but no distribute list. */ - if (type == ZEBRA_ROUTE_MAX) - break; - - if (DISTRIBUTE_NAME (ospf, type)) - { - /* Keep old access-list for distribute-list. */ - struct access_list *old = DISTRIBUTE_LIST (ospf, type); - - /* Update access-list for distribute-list. */ - DISTRIBUTE_LIST (ospf, type) = - access_list_lookup (AFI_IP, DISTRIBUTE_NAME (ospf, type)); - - /* No update for this distribute type. */ - if (old == NULL && DISTRIBUTE_LIST (ospf, type) == NULL) - continue; - - /* Schedule distribute-list update timer. */ - if (DISTRIBUTE_LIST (ospf, type) == NULL || - strcmp (DISTRIBUTE_NAME (ospf, type), access->name) == 0) - ospf_distribute_list_update (ospf, type, 0); - } - } - - /* Update Area access-list. */ - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - if (EXPORT_NAME (area)) - { - EXPORT_LIST (area) = NULL; - abr_inv++; - } - - if (IMPORT_NAME (area)) - { - IMPORT_LIST (area) = NULL; - abr_inv++; - } - } - - /* Schedule ABR tasks -- this will be changed -- takada. */ - if (IS_OSPF_ABR (ospf) && abr_inv) - ospf_schedule_abr_task (ospf); + struct ospf *ospf; + int type; + int abr_inv = 0; + struct ospf_area *area; + struct listnode *node; + + /* If OSPF instance does not exist, return right now. */ + ospf = ospf_lookup(); + if (ospf == NULL) + return; + + /* Update distribute-list, and apply filter. */ + for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) { + struct list *red_list; + struct listnode *node; + struct ospf_redist *red; + + red_list = ospf->redist[type]; + if (red_list) + for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) { + if (ROUTEMAP(red)) { + /* if route-map is not NULL it may be + * using this access list */ + ospf_distribute_list_update( + ospf, type, red->instance); + } + } + + /* There is place for route-map for default-information + * (ZEBRA_ROUTE_MAX), + * but no distribute list. */ + if (type == ZEBRA_ROUTE_MAX) + break; + + if (DISTRIBUTE_NAME(ospf, type)) { + /* Keep old access-list for distribute-list. */ + struct access_list *old = DISTRIBUTE_LIST(ospf, type); + + /* Update access-list for distribute-list. */ + DISTRIBUTE_LIST(ospf, type) = access_list_lookup( + AFI_IP, DISTRIBUTE_NAME(ospf, type)); + + /* No update for this distribute type. */ + if (old == NULL && DISTRIBUTE_LIST(ospf, type) == NULL) + continue; + + /* Schedule distribute-list update timer. */ + if (DISTRIBUTE_LIST(ospf, type) == NULL + || strcmp(DISTRIBUTE_NAME(ospf, type), access->name) + == 0) + ospf_distribute_list_update(ospf, type, 0); + } + } + + /* Update Area access-list. */ + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + if (EXPORT_NAME(area)) { + EXPORT_LIST(area) = NULL; + abr_inv++; + } + + if (IMPORT_NAME(area)) { + IMPORT_LIST(area) = NULL; + abr_inv++; + } + } + + /* Schedule ABR tasks -- this will be changed -- takada. */ + if (IS_OSPF_ABR(ospf) && abr_inv) + ospf_schedule_abr_task(ospf); } /* If prefix-list is updated, do some updates. */ -void -ospf_prefix_list_update (struct prefix_list *plist) +void ospf_prefix_list_update(struct prefix_list *plist) { - struct ospf *ospf; - int type; - int abr_inv = 0; - struct ospf_area *area; - struct listnode *node; - - /* If OSPF instatnce does not exist, return right now. */ - ospf = ospf_lookup (); - if (ospf == NULL) - return; - - /* Update all route-maps which are used as redistribution filters. - * They might use prefix-list. - */ - for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) - { - struct list *red_list; - struct listnode *node; - struct ospf_redist *red; - - red_list = ospf->redist[type]; - if (red_list) - for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) - { - if (ROUTEMAP (red)) - { - /* if route-map is not NULL it may be using this prefix list */ - ospf_distribute_list_update (ospf, type, red->instance); - } - } - } - - /* Update area filter-lists. */ - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - /* Update filter-list in. */ - if (PREFIX_NAME_IN (area)) - if (strcmp (PREFIX_NAME_IN (area), prefix_list_name (plist)) == 0) - { - PREFIX_LIST_IN (area) = - prefix_list_lookup (AFI_IP, PREFIX_NAME_IN (area)); - abr_inv++; - } - - /* Update filter-list out. */ - if (PREFIX_NAME_OUT (area)) - if (strcmp (PREFIX_NAME_OUT (area), prefix_list_name (plist)) == 0) - { - PREFIX_LIST_IN (area) = - prefix_list_lookup (AFI_IP, PREFIX_NAME_OUT (area)); - abr_inv++; - } - } - - /* Schedule ABR task. */ - if (IS_OSPF_ABR (ospf) && abr_inv) - ospf_schedule_abr_task (ospf); + struct ospf *ospf; + int type; + int abr_inv = 0; + struct ospf_area *area; + struct listnode *node; + + /* If OSPF instatnce does not exist, return right now. */ + ospf = ospf_lookup(); + if (ospf == NULL) + return; + + /* Update all route-maps which are used as redistribution filters. + * They might use prefix-list. + */ + for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) { + struct list *red_list; + struct listnode *node; + struct ospf_redist *red; + + red_list = ospf->redist[type]; + if (red_list) + for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) { + if (ROUTEMAP(red)) { + /* if route-map is not NULL it may be + * using this prefix list */ + ospf_distribute_list_update( + ospf, type, red->instance); + } + } + } + + /* Update area filter-lists. */ + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + /* Update filter-list in. */ + if (PREFIX_NAME_IN(area)) + if (strcmp(PREFIX_NAME_IN(area), + prefix_list_name(plist)) + == 0) { + PREFIX_LIST_IN(area) = prefix_list_lookup( + AFI_IP, PREFIX_NAME_IN(area)); + abr_inv++; + } + + /* Update filter-list out. */ + if (PREFIX_NAME_OUT(area)) + if (strcmp(PREFIX_NAME_OUT(area), + prefix_list_name(plist)) + == 0) { + PREFIX_LIST_IN(area) = prefix_list_lookup( + AFI_IP, PREFIX_NAME_OUT(area)); + abr_inv++; + } + } + + /* Schedule ABR task. */ + if (IS_OSPF_ABR(ospf) && abr_inv) + ospf_schedule_abr_task(ospf); } -static struct ospf_distance * -ospf_distance_new (void) +static struct ospf_distance *ospf_distance_new(void) { - return XCALLOC (MTYPE_OSPF_DISTANCE, sizeof (struct ospf_distance)); + return XCALLOC(MTYPE_OSPF_DISTANCE, sizeof(struct ospf_distance)); } -static void -ospf_distance_free (struct ospf_distance *odistance) +static void ospf_distance_free(struct ospf_distance *odistance) { - XFREE (MTYPE_OSPF_DISTANCE, odistance); + XFREE(MTYPE_OSPF_DISTANCE, odistance); } -int -ospf_distance_set (struct vty *vty, struct ospf *ospf, - const char *distance_str, - const char *ip_str, - const char *access_list_str) +int ospf_distance_set(struct vty *vty, struct ospf *ospf, + const char *distance_str, const char *ip_str, + const char *access_list_str) { - int ret; - struct prefix_ipv4 p; - u_char distance; - struct route_node *rn; - struct ospf_distance *odistance; - - ret = str2prefix_ipv4 (ip_str, &p); - if (ret == 0) - { - vty_out (vty, "Malformed prefix\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - distance = atoi (distance_str); - - /* Get OSPF distance node. */ - rn = route_node_get (ospf->distance_table, (struct prefix *) &p); - if (rn->info) - { - odistance = rn->info; - route_unlock_node (rn); - } - else - { - odistance = ospf_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_ipv4 p; + u_char distance; + struct route_node *rn; + struct ospf_distance *odistance; + + ret = str2prefix_ipv4(ip_str, &p); + if (ret == 0) { + vty_out(vty, "Malformed prefix\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + distance = atoi(distance_str); + + /* Get OSPF distance node. */ + rn = route_node_get(ospf->distance_table, (struct prefix *)&p); + if (rn->info) { + odistance = rn->info; + route_unlock_node(rn); + } else { + odistance = ospf_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 -ospf_distance_unset (struct vty *vty, struct ospf *ospf, - const char *distance_str, - const char *ip_str, char - const *access_list_str) +int ospf_distance_unset(struct vty *vty, struct ospf *ospf, + const char *distance_str, const char *ip_str, + char const *access_list_str) { - int ret; - struct prefix_ipv4 p; - struct route_node *rn; - struct ospf_distance *odistance; - - ret = str2prefix_ipv4 (ip_str, &p); - if (ret == 0) - { - vty_out (vty, "Malformed prefix\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - rn = route_node_lookup (ospf->distance_table, (struct prefix *) &p); - if (!rn) - { - vty_out (vty, "Can't find specified prefix\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - odistance = rn->info; - - if (odistance->access_list) - free (odistance->access_list); - ospf_distance_free (odistance); - - rn->info = NULL; - route_unlock_node (rn); - route_unlock_node (rn); - - return CMD_SUCCESS; + int ret; + struct prefix_ipv4 p; + struct route_node *rn; + struct ospf_distance *odistance; + + ret = str2prefix_ipv4(ip_str, &p); + if (ret == 0) { + vty_out(vty, "Malformed prefix\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + rn = route_node_lookup(ospf->distance_table, (struct prefix *)&p); + if (!rn) { + vty_out(vty, "Can't find specified prefix\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + odistance = rn->info; + + if (odistance->access_list) + free(odistance->access_list); + ospf_distance_free(odistance); + + rn->info = NULL; + route_unlock_node(rn); + route_unlock_node(rn); + + return CMD_SUCCESS; } -void -ospf_distance_reset (struct ospf *ospf) +void ospf_distance_reset(struct ospf *ospf) { - struct route_node *rn; - struct ospf_distance *odistance; - - for (rn = route_top (ospf->distance_table); rn; rn = route_next (rn)) - if ((odistance = rn->info) != NULL) - { - if (odistance->access_list) - free (odistance->access_list); - ospf_distance_free (odistance); - rn->info = NULL; - route_unlock_node (rn); - } + struct route_node *rn; + struct ospf_distance *odistance; + + for (rn = route_top(ospf->distance_table); rn; rn = route_next(rn)) + if ((odistance = rn->info) != NULL) { + if (odistance->access_list) + free(odistance->access_list); + ospf_distance_free(odistance); + rn->info = NULL; + route_unlock_node(rn); + } } -u_char -ospf_distance_apply (struct prefix_ipv4 *p, struct ospf_route *or) +u_char ospf_distance_apply(struct prefix_ipv4 *p, struct ospf_route * or) { - struct ospf *ospf; + struct ospf *ospf; - ospf = ospf_lookup (); - if (ospf == NULL) - return 0; + ospf = ospf_lookup(); + if (ospf == NULL) + return 0; - if (ospf->distance_intra) - if (or->path_type == OSPF_PATH_INTRA_AREA) - return ospf->distance_intra; + if (ospf->distance_intra) + if (or->path_type == OSPF_PATH_INTRA_AREA) + return ospf->distance_intra; - if (ospf->distance_inter) - if (or->path_type == OSPF_PATH_INTER_AREA) - return ospf->distance_inter; + if (ospf->distance_inter) + if (or->path_type == OSPF_PATH_INTER_AREA) + return ospf->distance_inter; - if (ospf->distance_external) - if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL - || or->path_type == OSPF_PATH_TYPE2_EXTERNAL) - return ospf->distance_external; + if (ospf->distance_external) + if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL || + or->path_type == OSPF_PATH_TYPE2_EXTERNAL) + return ospf->distance_external; - if (ospf->distance_all) - return ospf->distance_all; + if (ospf->distance_all) + return ospf->distance_all; - return 0; + return 0; } -static void -ospf_zebra_connected (struct zclient *zclient) +static void ospf_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 -ospf_zebra_init (struct thread_master *master, u_short instance) +void ospf_zebra_init(struct thread_master *master, u_short instance) { - /* Allocate zebra structure. */ - zclient = zclient_new(master); - zclient_init (zclient, ZEBRA_ROUTE_OSPF, instance); - zclient->zebra_connected = ospf_zebra_connected; - zclient->router_id_update = ospf_router_id_update_zebra; - zclient->interface_add = ospf_interface_add; - zclient->interface_delete = ospf_interface_delete; - zclient->interface_up = ospf_interface_state_up; - zclient->interface_down = ospf_interface_state_down; - zclient->interface_address_add = ospf_interface_address_add; - zclient->interface_address_delete = ospf_interface_address_delete; - zclient->interface_link_params = ospf_interface_link_params; - - zclient->redistribute_route_ipv4_add = ospf_zebra_read_ipv4; - zclient->redistribute_route_ipv4_del = ospf_zebra_read_ipv4; - - access_list_add_hook (ospf_filter_update); - access_list_delete_hook (ospf_filter_update); - prefix_list_add_hook (ospf_prefix_list_update); - prefix_list_delete_hook (ospf_prefix_list_update); + /* Allocate zebra structure. */ + zclient = zclient_new(master); + zclient_init(zclient, ZEBRA_ROUTE_OSPF, instance); + zclient->zebra_connected = ospf_zebra_connected; + zclient->router_id_update = ospf_router_id_update_zebra; + zclient->interface_add = ospf_interface_add; + zclient->interface_delete = ospf_interface_delete; + zclient->interface_up = ospf_interface_state_up; + zclient->interface_down = ospf_interface_state_down; + zclient->interface_address_add = ospf_interface_address_add; + zclient->interface_address_delete = ospf_interface_address_delete; + zclient->interface_link_params = ospf_interface_link_params; + + zclient->redistribute_route_ipv4_add = ospf_zebra_read_ipv4; + zclient->redistribute_route_ipv4_del = ospf_zebra_read_ipv4; + + access_list_add_hook(ospf_filter_update); + access_list_delete_hook(ospf_filter_update); + prefix_list_add_hook(ospf_prefix_list_update); + prefix_list_delete_hook(ospf_prefix_list_update); } diff --git a/ospfd/ospf_zebra.h b/ospfd/ospf_zebra.h index c0b99a95a..6fa9e33dd 100644 --- a/ospfd/ospf_zebra.h +++ b/ospfd/ospf_zebra.h @@ -32,55 +32,53 @@ #define DEFAULT_ROUTE_TYPE(T) ((T) == DEFAULT_ROUTE) /* OSPF distance. */ -struct ospf_distance -{ - /* Distance value for the IP source prefix. */ - u_char distance; +struct ospf_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; }; /* Prototypes */ -extern void ospf_zebra_add (struct prefix_ipv4 *, struct ospf_route *); -extern void ospf_zebra_delete (struct prefix_ipv4 *, struct ospf_route *); +extern void ospf_zebra_add(struct prefix_ipv4 *, struct ospf_route *); +extern void ospf_zebra_delete(struct prefix_ipv4 *, struct ospf_route *); -extern void ospf_zebra_add_discard (struct prefix_ipv4 *); -extern void ospf_zebra_delete_discard (struct prefix_ipv4 *); +extern void ospf_zebra_add_discard(struct prefix_ipv4 *); +extern void ospf_zebra_delete_discard(struct prefix_ipv4 *); -extern int ospf_redistribute_check (struct ospf *, struct external_info *, - int *); -extern int ospf_distribute_check_connected (struct ospf *, - struct external_info *); -extern void ospf_distribute_list_update (struct ospf *, uintptr_t, u_short); +extern int ospf_redistribute_check(struct ospf *, struct external_info *, + int *); +extern int ospf_distribute_check_connected(struct ospf *, + struct external_info *); +extern void ospf_distribute_list_update(struct ospf *, uintptr_t, u_short); -extern int ospf_is_type_redistributed (int, u_short); -extern void ospf_distance_reset (struct ospf *); -extern u_char ospf_distance_apply (struct prefix_ipv4 *, struct ospf_route *); -extern struct ospf_external *ospf_external_lookup (u_char, u_short); -extern struct ospf_external *ospf_external_add (u_char, u_short); -extern void ospf_external_del (u_char, u_short); -extern struct ospf_redist *ospf_redist_lookup (struct ospf *, u_char, u_short); -extern struct ospf_redist *ospf_redist_add (struct ospf *, u_char, u_short); -extern void ospf_redist_del (struct ospf *, u_char, u_short); +extern int ospf_is_type_redistributed(int, u_short); +extern void ospf_distance_reset(struct ospf *); +extern u_char ospf_distance_apply(struct prefix_ipv4 *, struct ospf_route *); +extern struct ospf_external *ospf_external_lookup(u_char, u_short); +extern struct ospf_external *ospf_external_add(u_char, u_short); +extern void ospf_external_del(u_char, u_short); +extern struct ospf_redist *ospf_redist_lookup(struct ospf *, u_char, u_short); +extern struct ospf_redist *ospf_redist_add(struct ospf *, u_char, u_short); +extern void ospf_redist_del(struct ospf *, u_char, u_short); -extern int ospf_redistribute_set (struct ospf *, int, u_short, int, int); -extern int ospf_redistribute_unset (struct ospf *, int, u_short); -extern int ospf_redistribute_default_set (struct ospf *, int, int, int); -extern int ospf_redistribute_default_unset (struct ospf *); -extern int ospf_distribute_list_out_set (struct ospf *, int, const char *); -extern int ospf_distribute_list_out_unset (struct ospf *, int, const char *); -extern void ospf_routemap_set (struct ospf_redist *, const char *); -extern void ospf_routemap_unset (struct ospf_redist *); -extern int ospf_distance_set (struct vty *, struct ospf *, const char *, - const char *, const char *); -extern int ospf_distance_unset (struct vty *, struct ospf *, const char *, - const char *, const char *); +extern int ospf_redistribute_set(struct ospf *, int, u_short, int, int); +extern int ospf_redistribute_unset(struct ospf *, int, u_short); +extern int ospf_redistribute_default_set(struct ospf *, int, int, int); +extern int ospf_redistribute_default_unset(struct ospf *); +extern int ospf_distribute_list_out_set(struct ospf *, int, const char *); +extern int ospf_distribute_list_out_unset(struct ospf *, int, const char *); +extern void ospf_routemap_set(struct ospf_redist *, const char *); +extern void ospf_routemap_unset(struct ospf_redist *); +extern int ospf_distance_set(struct vty *, struct ospf *, const char *, + const char *, const char *); +extern int ospf_distance_unset(struct vty *, struct ospf *, const char *, + const char *, const char *); extern void ospf_zebra_init(struct thread_master *, u_short); -DECLARE_HOOK(ospf_if_update, (struct interface *ifp), (ifp)) -DECLARE_HOOK(ospf_if_delete, (struct interface *ifp), (ifp)) +DECLARE_HOOK(ospf_if_update, (struct interface * ifp), (ifp)) +DECLARE_HOOK(ospf_if_delete, (struct interface * ifp), (ifp)) #endif /* _ZEBRA_OSPF_ZEBRA_H */ - diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 9af9f7f31..cee2244dd 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -30,7 +30,7 @@ #include "memory.h" #include "stream.h" #include "log.h" -#include "sockunion.h" /* for inet_aton () */ +#include "sockunion.h" /* for inet_aton () */ #include "zclient.h" #include "plist.h" #include "sockopt.h" @@ -68,331 +68,328 @@ extern struct zclient *zclient; extern struct in_addr router_id_zebra; -static void ospf_remove_vls_through_area (struct ospf *, struct ospf_area *); -static void ospf_network_free (struct ospf *, struct ospf_network *); -static void ospf_area_free (struct ospf_area *); -static void ospf_network_run (struct prefix *, struct ospf_area *); -static void ospf_network_run_interface (struct ospf *, struct interface *, - struct prefix *, struct ospf_area *); -static void ospf_network_run_subnet (struct ospf *, struct connected *, - struct prefix *, struct ospf_area *); -static int ospf_network_match_iface (const struct connected *, - const struct prefix *); -static void ospf_finish_final (struct ospf *); +static void ospf_remove_vls_through_area(struct ospf *, struct ospf_area *); +static void ospf_network_free(struct ospf *, struct ospf_network *); +static void ospf_area_free(struct ospf_area *); +static void ospf_network_run(struct prefix *, struct ospf_area *); +static void ospf_network_run_interface(struct ospf *, struct interface *, + struct prefix *, struct ospf_area *); +static void ospf_network_run_subnet(struct ospf *, struct connected *, + struct prefix *, struct ospf_area *); +static int ospf_network_match_iface(const struct connected *, + const struct prefix *); +static void ospf_finish_final(struct ospf *); #define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1 -void -ospf_router_id_update (struct ospf *ospf) +void ospf_router_id_update(struct ospf *ospf) { - struct in_addr router_id, router_id_old; - struct ospf_interface *oi; - struct interface *ifp; - struct listnode *node; - int type; - - if (!ospf->oi_running) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Router ospf not configured -- Router-ID update postponed"); - return; - } - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Router-ID[OLD:%s]: Update", inet_ntoa (ospf->router_id)); - - router_id_old = ospf->router_id; - - /* Select the router ID based on these priorities: - 1. Statically assigned router ID is always the first choice. - 2. If there is no statically assigned router ID, then try to stick - with the most recent value, since changing router ID's is very - disruptive. - 3. Last choice: just go with whatever the zebra daemon recommends. - */ - if (ospf->router_id_static.s_addr != 0) - router_id = ospf->router_id_static; - else if (ospf->router_id.s_addr != 0) - router_id = ospf->router_id; - else - router_id = router_id_zebra; - - - if (!IPV4_ADDR_SAME (&router_id_old, &router_id)) - { + struct in_addr router_id, router_id_old; + struct ospf_interface *oi; + struct interface *ifp; + struct listnode *node; + int type; - for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) - { - /* Some nbrs are identified by router_id, these needs - * to be rebuilt. Possible optimization would be to do - * oi->nbr_self->router_id = router_id for - * !(virtual | ptop) links - */ - ospf_nbr_self_reset (oi, router_id); + if (!ospf->oi_running) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "Router ospf not configured -- Router-ID update postponed"); + return; } - /* If AS-external-LSA is queued, then flush those LSAs. */ - if (router_id_old.s_addr == 0 && ospf->external_origin) - { - /* Originate each redistributed external route. */ - for (type = 0; type < ZEBRA_ROUTE_MAX; type++) - if (ospf->external_origin & (1 << type)) - thread_add_event(master, ospf_external_lsa_originate_timer, - ospf, type, NULL); - /* Originate Deafult. */ - if (ospf->external_origin & (1 << ZEBRA_ROUTE_MAX)) - thread_add_event(master, ospf_default_originate_timer, ospf, 0, - NULL); - - ospf->external_origin = 0; + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Router-ID[OLD:%s]: Update", + inet_ntoa(ospf->router_id)); + + router_id_old = ospf->router_id; + + /* Select the router ID based on these priorities: + 1. Statically assigned router ID is always the first choice. + 2. If there is no statically assigned router ID, then try to stick + with the most recent value, since changing router ID's is very + disruptive. + 3. Last choice: just go with whatever the zebra daemon recommends. + */ + if (ospf->router_id_static.s_addr != 0) + router_id = ospf->router_id_static; + else if (ospf->router_id.s_addr != 0) + router_id = ospf->router_id; + else + router_id = router_id_zebra; + + + if (!IPV4_ADDR_SAME(&router_id_old, &router_id)) { + + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) { + /* Some nbrs are identified by router_id, these needs + * to be rebuilt. Possible optimization would be to do + * oi->nbr_self->router_id = router_id for + * !(virtual | ptop) links + */ + ospf_nbr_self_reset(oi, router_id); + } + + /* If AS-external-LSA is queued, then flush those LSAs. */ + if (router_id_old.s_addr == 0 && ospf->external_origin) { + /* Originate each redistributed external route. */ + for (type = 0; type < ZEBRA_ROUTE_MAX; type++) + if (ospf->external_origin & (1 << type)) + thread_add_event( + master, + ospf_external_lsa_originate_timer, + ospf, type, NULL); + /* Originate Deafult. */ + if (ospf->external_origin & (1 << ZEBRA_ROUTE_MAX)) + thread_add_event(master, + ospf_default_originate_timer, + ospf, 0, NULL); + + ospf->external_origin = 0; + } + + /* Flush (inline) all external LSAs based on the OSPF_LSA_SELF + * flag */ + if (ospf->lsdb) { + struct route_node *rn; + struct ospf_lsa *lsa; + + LSDB_LOOP(EXTERNAL_LSDB(ospf), rn, lsa) + if (IS_LSA_SELF(lsa)) + ospf_lsa_flush_schedule(ospf, lsa); + } + + ospf->router_id = router_id; + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Router-ID[NEW:%s]: Update", + inet_ntoa(ospf->router_id)); + + /* Flush (inline) all external LSAs which now match the new + router-id, + need to adjust the OSPF_LSA_SELF flag, so the flush doesnt + hit + asserts in ospf_refresher_unregister_lsa(). This step is + needed + because the current quagga code does look-up for + self-originated LSAs + based on the self router-id alone but expects OSPF_LSA_SELF + to be + properly set */ + if (ospf->lsdb) { + struct route_node *rn; + struct ospf_lsa *lsa; + + LSDB_LOOP(EXTERNAL_LSDB(ospf), rn, lsa) + { + /* AdvRouter and Router ID is the same. */ + if (IPV4_ADDR_SAME(&lsa->data->adv_router, + &ospf->router_id)) { + SET_FLAG(lsa->flags, + OSPF_LSA_SELF_CHECKED); + SET_FLAG(lsa->flags, OSPF_LSA_SELF); + ospf_lsa_flush_schedule(ospf, lsa); + } + } + } + + /* Originate each redistributed external route. */ + for (type = 0; type < ZEBRA_ROUTE_MAX; type++) + thread_add_event(master, + ospf_external_lsa_originate_timer, + ospf, type, NULL); + thread_add_event(master, ospf_default_originate_timer, ospf, 0, + NULL); + + /* update router-lsa's for each area */ + ospf_router_lsa_update(ospf); + + /* update ospf_interface's */ + for (ALL_LIST_ELEMENTS_RO(om->iflist, node, ifp)) + ospf_if_update(ospf, ifp); } - - /* Flush (inline) all external LSAs based on the OSPF_LSA_SELF flag */ - if (ospf->lsdb) - { - struct route_node *rn; - struct ospf_lsa *lsa; - - LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa) - if (IS_LSA_SELF(lsa)) - ospf_lsa_flush_schedule(ospf, lsa); - } - - ospf->router_id = router_id; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Router-ID[NEW:%s]: Update", inet_ntoa (ospf->router_id)); - - /* Flush (inline) all external LSAs which now match the new router-id, - need to adjust the OSPF_LSA_SELF flag, so the flush doesnt hit - asserts in ospf_refresher_unregister_lsa(). This step is needed - because the current quagga code does look-up for self-originated LSAs - based on the self router-id alone but expects OSPF_LSA_SELF to be - properly set */ - if (ospf->lsdb) - { - struct route_node *rn; - struct ospf_lsa *lsa; - - LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa) - { - /* AdvRouter and Router ID is the same. */ - if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id)) - { - SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED); - SET_FLAG (lsa->flags, OSPF_LSA_SELF); - ospf_lsa_flush_schedule(ospf, lsa); - } - } - } - - /* Originate each redistributed external route. */ - for (type = 0; type < ZEBRA_ROUTE_MAX; type++) - thread_add_event(master, ospf_external_lsa_originate_timer, ospf, - type, NULL); - thread_add_event(master, ospf_default_originate_timer, ospf, 0, NULL); - - /* update router-lsa's for each area */ - ospf_router_lsa_update (ospf); - - /* update ospf_interface's */ - for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp)) - ospf_if_update (ospf, ifp); - } } /* For OSPF area sort by area id. */ -static int -ospf_area_id_cmp (struct ospf_area *a1, struct ospf_area *a2) +static int ospf_area_id_cmp(struct ospf_area *a1, struct ospf_area *a2) { - if (ntohl (a1->area_id.s_addr) > ntohl (a2->area_id.s_addr)) - return 1; - if (ntohl (a1->area_id.s_addr) < ntohl (a2->area_id.s_addr)) - return -1; - return 0; + if (ntohl(a1->area_id.s_addr) > ntohl(a2->area_id.s_addr)) + return 1; + if (ntohl(a1->area_id.s_addr) < ntohl(a2->area_id.s_addr)) + return -1; + return 0; } /* Allocate new ospf structure. */ -static struct ospf * -ospf_new (u_short instance) +static struct ospf *ospf_new(u_short instance) { - int i; + int i; - struct ospf *new = XCALLOC (MTYPE_OSPF_TOP, sizeof (struct ospf)); + struct ospf *new = XCALLOC(MTYPE_OSPF_TOP, sizeof(struct ospf)); - new->instance = instance; - new->router_id.s_addr = htonl (0); - new->router_id_static.s_addr = htonl (0); + new->instance = instance; + new->router_id.s_addr = htonl(0); + new->router_id_static.s_addr = htonl(0); - new->abr_type = OSPF_ABR_DEFAULT; - new->oiflist = list_new (); - new->vlinks = list_new (); - new->areas = list_new (); - new->areas->cmp = (int (*)(void *, void *)) ospf_area_id_cmp; - new->networks = route_table_init (); - new->nbr_nbma = route_table_init (); + new->abr_type = OSPF_ABR_DEFAULT; + new->oiflist = list_new(); + new->vlinks = list_new(); + new->areas = list_new(); + new->areas->cmp = (int (*)(void *, void *))ospf_area_id_cmp; + new->networks = route_table_init(); + new->nbr_nbma = route_table_init(); - new->lsdb = ospf_lsdb_new (); + new->lsdb = ospf_lsdb_new(); - new->default_originate = DEFAULT_ORIGINATE_NONE; + new->default_originate = DEFAULT_ORIGINATE_NONE; - new->passive_interface_default = OSPF_IF_ACTIVE; - - new->new_external_route = route_table_init (); - new->old_external_route = route_table_init (); - new->external_lsas = route_table_init (); - - new->stub_router_startup_time = OSPF_STUB_ROUTER_UNCONFIGURED; - new->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED; - new->stub_router_admin_set = OSPF_STUB_ROUTER_ADMINISTRATIVE_UNSET; + new->passive_interface_default = OSPF_IF_ACTIVE; - /* Distribute parameter init. */ - for (i = 0; i <= ZEBRA_ROUTE_MAX; i++) - { - new->dtag[i] = 0; - } - new->default_metric = -1; - new->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH; - - /* LSA timers */ - new->min_ls_interval = OSPF_MIN_LS_INTERVAL; - new->min_ls_arrival = OSPF_MIN_LS_ARRIVAL; - - /* SPF timer value init. */ - new->spf_delay = OSPF_SPF_DELAY_DEFAULT; - new->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT; - new->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT; - new->spf_hold_multiplier = 1; - - /* MaxAge init. */ - new->maxage_delay = OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT; - new->maxage_lsa = route_table_init(); - new->t_maxage_walker = NULL; - thread_add_timer(master, ospf_lsa_maxage_walker, new, OSPF_LSA_MAXAGE_CHECK_INTERVAL, - &new->t_maxage_walker); - - /* Distance table init. */ - new->distance_table = route_table_init (); - - new->lsa_refresh_queue.index = 0; - new->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT; - new->t_lsa_refresher = NULL; - thread_add_timer(master, ospf_lsa_refresh_walker, new, new->lsa_refresh_interval, - &new->t_lsa_refresher); - new->lsa_refresher_started = monotime(NULL); - - if ((new->fd = ospf_sock_init()) < 0) - { - zlog_err("ospf_new: fatal error: ospf_sock_init was unable to open " - "a socket"); - exit(1); - } - if ((new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE+1)) == NULL) - { - zlog_err("ospf_new: fatal error: stream_new(%u) failed allocating ibuf", - OSPF_MAX_PACKET_SIZE+1); - exit(1); - } - new->t_read = NULL; - thread_add_read(master, ospf_read, new, new->fd, &new->t_read); - new->oi_write_q = list_new (); - new->write_oi_count = OSPF_WRITE_INTERFACE_COUNT_DEFAULT; - - /* Enable "log-adjacency-changes" */ + new->new_external_route = route_table_init(); + new->old_external_route = route_table_init(); + new->external_lsas = route_table_init(); + + new->stub_router_startup_time = OSPF_STUB_ROUTER_UNCONFIGURED; + new->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED; + new->stub_router_admin_set = OSPF_STUB_ROUTER_ADMINISTRATIVE_UNSET; + + /* Distribute parameter init. */ + for (i = 0; i <= ZEBRA_ROUTE_MAX; i++) { + new->dtag[i] = 0; + } + new->default_metric = -1; + new->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH; + + /* LSA timers */ + new->min_ls_interval = OSPF_MIN_LS_INTERVAL; + new->min_ls_arrival = OSPF_MIN_LS_ARRIVAL; + + /* SPF timer value init. */ + new->spf_delay = OSPF_SPF_DELAY_DEFAULT; + new->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT; + new->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT; + new->spf_hold_multiplier = 1; + + /* MaxAge init. */ + new->maxage_delay = OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT; + new->maxage_lsa = route_table_init(); + new->t_maxage_walker = NULL; + thread_add_timer(master, ospf_lsa_maxage_walker, new, + OSPF_LSA_MAXAGE_CHECK_INTERVAL, &new->t_maxage_walker); + + /* Distance table init. */ + new->distance_table = route_table_init(); + + new->lsa_refresh_queue.index = 0; + new->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT; + new->t_lsa_refresher = NULL; + thread_add_timer(master, ospf_lsa_refresh_walker, new, + new->lsa_refresh_interval, &new->t_lsa_refresher); + new->lsa_refresher_started = monotime(NULL); + + if ((new->fd = ospf_sock_init()) < 0) { + zlog_err( + "ospf_new: fatal error: ospf_sock_init was unable to open " + "a socket"); + exit(1); + } + if ((new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE + 1)) == NULL) { + zlog_err( + "ospf_new: fatal error: stream_new(%u) failed allocating ibuf", + OSPF_MAX_PACKET_SIZE + 1); + exit(1); + } + new->t_read = NULL; + thread_add_read(master, ospf_read, new, new->fd, &new->t_read); + new->oi_write_q = list_new(); + new->write_oi_count = OSPF_WRITE_INTERFACE_COUNT_DEFAULT; + +/* Enable "log-adjacency-changes" */ #if DFLT_OSPF_LOG_ADJACENCY_CHANGES - SET_FLAG(new->config, OSPF_LOG_ADJACENCY_CHANGES); + SET_FLAG(new->config, OSPF_LOG_ADJACENCY_CHANGES); #endif - QOBJ_REG (new, ospf); + QOBJ_REG(new, ospf); - return new; + return new; } -struct ospf * -ospf_lookup () +struct ospf *ospf_lookup() { - if (listcount (om->ospf) == 0) - return NULL; + if (listcount(om->ospf) == 0) + return NULL; - return listgetdata ((struct listnode *)listhead (om->ospf)); + return listgetdata((struct listnode *)listhead(om->ospf)); } -struct ospf * -ospf_lookup_instance (u_short instance) +struct ospf *ospf_lookup_instance(u_short instance) { - struct ospf *ospf; - struct listnode *node, *nnode; + struct ospf *ospf; + struct listnode *node, *nnode; - if (listcount (om->ospf) == 0) - return NULL; + if (listcount(om->ospf) == 0) + return NULL; - for (ALL_LIST_ELEMENTS (om->ospf, node, nnode, ospf)) - if ((ospf->instance == 0 && instance == 0) - || (ospf->instance && instance && ospf->instance == instance)) - return ospf; + for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf)) + if ((ospf->instance == 0 && instance == 0) + || (ospf->instance && instance + && ospf->instance == instance)) + return ospf; - return NULL; + return NULL; } -static int -ospf_is_ready (struct ospf *ospf) +static int ospf_is_ready(struct ospf *ospf) { - /* OSPF must be on and Router-ID must be configured. */ - if (!ospf || ospf->router_id.s_addr == 0) - return 0; - - return 1; + /* OSPF must be on and Router-ID must be configured. */ + if (!ospf || ospf->router_id.s_addr == 0) + return 0; + + return 1; } -static void -ospf_add (struct ospf *ospf) +static void ospf_add(struct ospf *ospf) { - listnode_add (om->ospf, ospf); + listnode_add(om->ospf, ospf); } -static void -ospf_delete (struct ospf *ospf) +static void ospf_delete(struct ospf *ospf) { - listnode_delete (om->ospf, ospf); + listnode_delete(om->ospf, ospf); } -struct ospf * -ospf_get () +struct ospf *ospf_get() { - struct ospf *ospf; + struct ospf *ospf; - ospf = ospf_lookup (); - if (ospf == NULL) - { - ospf = ospf_new (0); - ospf_add (ospf); + ospf = ospf_lookup(); + if (ospf == NULL) { + ospf = ospf_new(0); + ospf_add(ospf); - if (ospf->router_id_static.s_addr == 0) - ospf_router_id_update (ospf); + if (ospf->router_id_static.s_addr == 0) + ospf_router_id_update(ospf); - ospf_opaque_type11_lsa_init (ospf); - } + ospf_opaque_type11_lsa_init(ospf); + } - return ospf; + return ospf; } -struct ospf * -ospf_get_instance (u_short instance) +struct ospf *ospf_get_instance(u_short instance) { - struct ospf *ospf; + struct ospf *ospf; - ospf = ospf_lookup_instance (instance); - if (ospf == NULL) - { - ospf = ospf_new (instance); - ospf_add (ospf); + ospf = ospf_lookup_instance(instance); + if (ospf == NULL) { + ospf = ospf_new(instance); + ospf_add(ospf); - if (ospf->router_id_static.s_addr == 0) - ospf_router_id_update (ospf); + if (ospf->router_id_static.s_addr == 0) + ospf_router_id_update(ospf); - ospf_opaque_type11_lsa_init (ospf); - } + ospf_opaque_type11_lsa_init(ospf); + } - return ospf; + return ospf; } /* Handle the second half of deferred shutdown. This is called either @@ -403,633 +400,592 @@ ospf_get_instance (u_short instance) * to complete shutdown of this ospf instance. Possibly exit if the * whole process is being shutdown and this was the last OSPF instance. */ -static void -ospf_deferred_shutdown_finish (struct ospf *ospf) -{ - ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED; - OSPF_TIMER_OFF (ospf->t_deferred_shutdown); - - ospf_finish_final (ospf); - - /* *ospf is now invalid */ - - /* ospfd being shut-down? If so, was this the last ospf instance? */ - if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN) - && (listcount (om->ospf) == 0)) - { - exit (0); - } +static void ospf_deferred_shutdown_finish(struct ospf *ospf) +{ + ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED; + OSPF_TIMER_OFF(ospf->t_deferred_shutdown); + + ospf_finish_final(ospf); + + /* *ospf is now invalid */ - return; + /* ospfd being shut-down? If so, was this the last ospf instance? */ + if (CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN) + && (listcount(om->ospf) == 0)) { + exit(0); + } + + return; } /* Timer thread for G-R */ -static int -ospf_deferred_shutdown_timer (struct thread *t) +static int ospf_deferred_shutdown_timer(struct thread *t) { - struct ospf *ospf = THREAD_ARG(t); - - ospf_deferred_shutdown_finish (ospf); - - return 0; + struct ospf *ospf = THREAD_ARG(t); + + ospf_deferred_shutdown_finish(ospf); + + return 0; } /* Check whether deferred-shutdown must be scheduled, otherwise call * down directly into second-half of instance shutdown. */ -static void -ospf_deferred_shutdown_check (struct ospf *ospf) -{ - unsigned long timeout; - struct listnode *ln; - struct ospf_area *area; - - /* deferred shutdown already running? */ - if (ospf->t_deferred_shutdown) - return; - - /* Should we try push out max-metric LSAs? */ - if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED) - { - for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area)) - { - SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED); - - if (!CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED)) - ospf_router_lsa_update_area (area); - } - timeout = ospf->stub_router_shutdown_time; - } - else - { - /* No timer needed */ - ospf_deferred_shutdown_finish (ospf); - return; - } - - OSPF_TIMER_ON (ospf->t_deferred_shutdown, ospf_deferred_shutdown_timer, - timeout); - return; +static void ospf_deferred_shutdown_check(struct ospf *ospf) +{ + unsigned long timeout; + struct listnode *ln; + struct ospf_area *area; + + /* deferred shutdown already running? */ + if (ospf->t_deferred_shutdown) + return; + + /* Should we try push out max-metric LSAs? */ + if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED) { + for (ALL_LIST_ELEMENTS_RO(ospf->areas, ln, area)) { + SET_FLAG(area->stub_router_state, + OSPF_AREA_ADMIN_STUB_ROUTED); + + if (!CHECK_FLAG(area->stub_router_state, + OSPF_AREA_IS_STUB_ROUTED)) + ospf_router_lsa_update_area(area); + } + timeout = ospf->stub_router_shutdown_time; + } else { + /* No timer needed */ + ospf_deferred_shutdown_finish(ospf); + return; + } + + OSPF_TIMER_ON(ospf->t_deferred_shutdown, ospf_deferred_shutdown_timer, + timeout); + return; } /* Shut down the entire process */ -void -ospf_terminate (void) -{ - struct ospf *ospf; - struct listnode *node, *nnode; - - /* shutdown already in progress */ - if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN)) - return; - - SET_FLAG (om->options, OSPF_MASTER_SHUTDOWN); - - /* exit immediately if OSPF not actually running */ - if (listcount(om->ospf) == 0) - exit(0); - - bfd_gbl_exit(); - for (ALL_LIST_ELEMENTS (om->ospf, node, nnode, ospf)) - ospf_finish (ospf); - - /* Deliberately go back up, hopefully to thread scheduler, as - * One or more ospf_finish()'s may have deferred shutdown to a timer - * thread - */ - zclient_stop (zclient); - zclient_free (zclient); -} - -void -ospf_finish (struct ospf *ospf) -{ - /* let deferred shutdown decide */ - ospf_deferred_shutdown_check (ospf); - - /* if ospf_deferred_shutdown returns, then ospf_finish_final is - * deferred to expiry of G-S timer thread. Return back up, hopefully - * to thread scheduler. - */ - return; +void ospf_terminate(void) +{ + struct ospf *ospf; + struct listnode *node, *nnode; + + /* shutdown already in progress */ + if (CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN)) + return; + + SET_FLAG(om->options, OSPF_MASTER_SHUTDOWN); + + /* exit immediately if OSPF not actually running */ + if (listcount(om->ospf) == 0) + exit(0); + + bfd_gbl_exit(); + for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf)) + ospf_finish(ospf); + + /* Deliberately go back up, hopefully to thread scheduler, as + * One or more ospf_finish()'s may have deferred shutdown to a timer + * thread + */ + zclient_stop(zclient); + zclient_free(zclient); +} + +void ospf_finish(struct ospf *ospf) +{ + /* let deferred shutdown decide */ + ospf_deferred_shutdown_check(ospf); + + /* if ospf_deferred_shutdown returns, then ospf_finish_final is + * deferred to expiry of G-S timer thread. Return back up, hopefully + * to thread scheduler. + */ + return; } /* Final cleanup of ospf instance */ -static void -ospf_finish_final (struct ospf *ospf) +static void ospf_finish_final(struct ospf *ospf) { - struct route_node *rn; - struct ospf_nbr_nbma *nbr_nbma; - struct ospf_lsa *lsa; - struct interface *ifp; - struct ospf_interface *oi; - struct ospf_area *area; - struct ospf_vl_data *vl_data; - struct listnode *node, *nnode; - int i; - u_short instance = 0; - - QOBJ_UNREG (ospf); - - ospf_opaque_type11_lsa_term (ospf); - - /* be nice if this worked, but it doesn't */ - /*ospf_flush_self_originated_lsas_now (ospf);*/ - - /* Unregister redistribution */ - for (i = 0; i < ZEBRA_ROUTE_MAX; i++) - { - struct list *red_list; - struct ospf_redist *red; + struct route_node *rn; + struct ospf_nbr_nbma *nbr_nbma; + struct ospf_lsa *lsa; + struct interface *ifp; + struct ospf_interface *oi; + struct ospf_area *area; + struct ospf_vl_data *vl_data; + struct listnode *node, *nnode; + int i; + u_short instance = 0; - red_list = ospf->redist[i]; - if (!red_list) - continue; + QOBJ_UNREG(ospf); - for (ALL_LIST_ELEMENTS(red_list, node, nnode, red)) - ospf_redistribute_unset (ospf, i, red->instance); - } - ospf_redistribute_default_unset (ospf); - - for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area)) - ospf_remove_vls_through_area (ospf, area); - - for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data)) - ospf_vl_delete (ospf, vl_data); - - list_delete (ospf->vlinks); - - /* Remove any ospf interface config params */ - for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) - { - struct ospf_if_params *params; + ospf_opaque_type11_lsa_term(ospf); - params = IF_DEF_PARAMS (ifp); - if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) - UNSET_IF_PARAM (params, if_area); - } + /* be nice if this worked, but it doesn't */ + /*ospf_flush_self_originated_lsas_now (ospf);*/ - /* Reset interface. */ - for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) - ospf_if_free (oi); + /* Unregister redistribution */ + for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { + struct list *red_list; + struct ospf_redist *red; - /* Clear static neighbors */ - for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn)) - if ((nbr_nbma = rn->info)) - { - OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll); + red_list = ospf->redist[i]; + if (!red_list) + continue; - if (nbr_nbma->nbr) - { - nbr_nbma->nbr->nbr_nbma = NULL; - nbr_nbma->nbr = NULL; - } + for (ALL_LIST_ELEMENTS(red_list, node, nnode, red)) + ospf_redistribute_unset(ospf, i, red->instance); + } + ospf_redistribute_default_unset(ospf); - if (nbr_nbma->oi) - { - listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma); - nbr_nbma->oi = NULL; - } + for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) + ospf_remove_vls_through_area(ospf, area); - XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma); - } + for (ALL_LIST_ELEMENTS(ospf->vlinks, node, nnode, vl_data)) + ospf_vl_delete(ospf, vl_data); - route_table_finish (ospf->nbr_nbma); + list_delete(ospf->vlinks); - /* Clear networks and Areas. */ - for (rn = route_top (ospf->networks); rn; rn = route_next (rn)) - { - struct ospf_network *network; + /* Remove any ospf interface config params */ + for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { + struct ospf_if_params *params; - if ((network = rn->info) != NULL) - { - ospf_network_free (ospf, network); - rn->info = NULL; - route_unlock_node (rn); + params = IF_DEF_PARAMS(ifp); + if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) + UNSET_IF_PARAM(params, if_area); } - } - for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area)) - { - listnode_delete (ospf->areas, area); - ospf_area_free (area); - } + /* Reset interface. */ + for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) + ospf_if_free(oi); - /* Cancel all timers. */ - OSPF_TIMER_OFF (ospf->t_external_lsa); - OSPF_TIMER_OFF (ospf->t_spf_calc); - OSPF_TIMER_OFF (ospf->t_ase_calc); - OSPF_TIMER_OFF (ospf->t_maxage); - OSPF_TIMER_OFF (ospf->t_maxage_walker); - OSPF_TIMER_OFF (ospf->t_abr_task); - OSPF_TIMER_OFF (ospf->t_asbr_check); - OSPF_TIMER_OFF (ospf->t_distribute_update); - OSPF_TIMER_OFF (ospf->t_lsa_refresher); - OSPF_TIMER_OFF (ospf->t_read); - OSPF_TIMER_OFF (ospf->t_write); - OSPF_TIMER_OFF (ospf->t_opaque_lsa_self); - - close (ospf->fd); - stream_free(ospf->ibuf); - - LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa) - ospf_discard_from_db (ospf, ospf->lsdb, lsa); - LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa) - ospf_discard_from_db (ospf, ospf->lsdb, lsa); - - ospf_lsdb_delete_all (ospf->lsdb); - ospf_lsdb_free (ospf->lsdb); - - for (rn = route_top (ospf->maxage_lsa); rn; rn = route_next (rn)) - { - struct ospf_lsa *lsa; + /* Clear static neighbors */ + for (rn = route_top(ospf->nbr_nbma); rn; rn = route_next(rn)) + if ((nbr_nbma = rn->info)) { + OSPF_POLL_TIMER_OFF(nbr_nbma->t_poll); - if ((lsa = rn->info) != NULL) - { - ospf_lsa_unlock (&lsa); - rn->info = NULL; + if (nbr_nbma->nbr) { + nbr_nbma->nbr->nbr_nbma = NULL; + nbr_nbma->nbr = NULL; + } + + if (nbr_nbma->oi) { + listnode_delete(nbr_nbma->oi->nbr_nbma, + nbr_nbma); + nbr_nbma->oi = NULL; + } + + XFREE(MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma); + } + + route_table_finish(ospf->nbr_nbma); + + /* Clear networks and Areas. */ + for (rn = route_top(ospf->networks); rn; rn = route_next(rn)) { + struct ospf_network *network; + + if ((network = rn->info) != NULL) { + ospf_network_free(ospf, network); + rn->info = NULL; + route_unlock_node(rn); + } } - route_unlock_node (rn); - } - route_table_finish (ospf->maxage_lsa); - if (ospf->old_table) - ospf_route_table_free (ospf->old_table); - if (ospf->new_table) - { - ospf_route_delete (ospf->new_table); - ospf_route_table_free (ospf->new_table); - } - if (ospf->old_rtrs) - ospf_rtrs_free (ospf->old_rtrs); - if (ospf->new_rtrs) - ospf_rtrs_free (ospf->new_rtrs); - if (ospf->new_external_route) - { - ospf_route_delete (ospf->new_external_route); - ospf_route_table_free (ospf->new_external_route); - } - if (ospf->old_external_route) - { - ospf_route_delete (ospf->old_external_route); - ospf_route_table_free (ospf->old_external_route); - } - if (ospf->external_lsas) - { - ospf_ase_external_lsas_finish (ospf->external_lsas); - } + for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) { + listnode_delete(ospf->areas, area); + ospf_area_free(area); + } - list_delete (ospf->areas); - - for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++) - { - struct list *ext_list; - struct listnode *node; - struct ospf_external *ext; - - ext_list = om->external[i]; - if (!ext_list) - continue; - - for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) - { - if (ext->external_info) - for (rn = route_top (ext->external_info); rn; rn = route_next (rn)) - { - if (rn->info == NULL) - continue; - - XFREE (MTYPE_OSPF_EXTERNAL_INFO, rn->info); - rn->info = NULL; - route_unlock_node (rn); - } - } - } + /* Cancel all timers. */ + OSPF_TIMER_OFF(ospf->t_external_lsa); + OSPF_TIMER_OFF(ospf->t_spf_calc); + OSPF_TIMER_OFF(ospf->t_ase_calc); + OSPF_TIMER_OFF(ospf->t_maxage); + OSPF_TIMER_OFF(ospf->t_maxage_walker); + OSPF_TIMER_OFF(ospf->t_abr_task); + OSPF_TIMER_OFF(ospf->t_asbr_check); + OSPF_TIMER_OFF(ospf->t_distribute_update); + OSPF_TIMER_OFF(ospf->t_lsa_refresher); + OSPF_TIMER_OFF(ospf->t_read); + OSPF_TIMER_OFF(ospf->t_write); + OSPF_TIMER_OFF(ospf->t_opaque_lsa_self); + + close(ospf->fd); + stream_free(ospf->ibuf); + + LSDB_LOOP(OPAQUE_AS_LSDB(ospf), rn, lsa) + ospf_discard_from_db(ospf, ospf->lsdb, lsa); + LSDB_LOOP(EXTERNAL_LSDB(ospf), rn, lsa) + ospf_discard_from_db(ospf, ospf->lsdb, lsa); + + ospf_lsdb_delete_all(ospf->lsdb); + ospf_lsdb_free(ospf->lsdb); + + for (rn = route_top(ospf->maxage_lsa); rn; rn = route_next(rn)) { + struct ospf_lsa *lsa; + + if ((lsa = rn->info) != NULL) { + ospf_lsa_unlock(&lsa); + rn->info = NULL; + } + route_unlock_node(rn); + } + route_table_finish(ospf->maxage_lsa); + + if (ospf->old_table) + ospf_route_table_free(ospf->old_table); + if (ospf->new_table) { + ospf_route_delete(ospf->new_table); + ospf_route_table_free(ospf->new_table); + } + if (ospf->old_rtrs) + ospf_rtrs_free(ospf->old_rtrs); + if (ospf->new_rtrs) + ospf_rtrs_free(ospf->new_rtrs); + if (ospf->new_external_route) { + ospf_route_delete(ospf->new_external_route); + ospf_route_table_free(ospf->new_external_route); + } + if (ospf->old_external_route) { + ospf_route_delete(ospf->old_external_route); + ospf_route_table_free(ospf->old_external_route); + } + if (ospf->external_lsas) { + ospf_ase_external_lsas_finish(ospf->external_lsas); + } - ospf_distance_reset (ospf); - route_table_finish (ospf->distance_table); + list_delete(ospf->areas); + + for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++) { + struct list *ext_list; + struct listnode *node; + struct ospf_external *ext; + + ext_list = om->external[i]; + if (!ext_list) + continue; + + for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) { + if (ext->external_info) + for (rn = route_top(ext->external_info); rn; + rn = route_next(rn)) { + if (rn->info == NULL) + continue; + + XFREE(MTYPE_OSPF_EXTERNAL_INFO, + rn->info); + rn->info = NULL; + route_unlock_node(rn); + } + } + } - if (!CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN)) - instance = ospf->instance; + ospf_distance_reset(ospf); + route_table_finish(ospf->distance_table); - ospf_delete (ospf); + if (!CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN)) + instance = ospf->instance; - XFREE (MTYPE_OSPF_TOP, ospf); + ospf_delete(ospf); - if (!CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN)) - ospf_get_instance(instance); + XFREE(MTYPE_OSPF_TOP, ospf); + if (!CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN)) + ospf_get_instance(instance); } /* allocate new OSPF Area object */ -static struct ospf_area * -ospf_area_new (struct ospf *ospf, struct in_addr area_id) +static struct ospf_area *ospf_area_new(struct ospf *ospf, + struct in_addr area_id) { - struct ospf_area *new; + struct ospf_area *new; - /* Allocate new config_network. */ - new = XCALLOC (MTYPE_OSPF_AREA, sizeof (struct ospf_area)); + /* Allocate new config_network. */ + new = XCALLOC(MTYPE_OSPF_AREA, sizeof(struct ospf_area)); - new->ospf = ospf; + new->ospf = ospf; - new->area_id = area_id; - new->area_id_fmt = OSPF_AREA_ID_FMT_DOTTEDQUAD; + new->area_id = area_id; + new->area_id_fmt = OSPF_AREA_ID_FMT_DOTTEDQUAD; - new->external_routing = OSPF_AREA_DEFAULT; - new->default_cost = 1; - new->auth_type = OSPF_AUTH_NULL; - - /* New LSDB init. */ - new->lsdb = ospf_lsdb_new (); + new->external_routing = OSPF_AREA_DEFAULT; + new->default_cost = 1; + new->auth_type = OSPF_AUTH_NULL; - /* Self-originated LSAs initialize. */ - new->router_lsa_self = NULL; + /* New LSDB init. */ + new->lsdb = ospf_lsdb_new(); - ospf_opaque_type10_lsa_init (new); + /* Self-originated LSAs initialize. */ + new->router_lsa_self = NULL; - new->oiflist = list_new (); - new->ranges = route_table_init (); + ospf_opaque_type10_lsa_init(new); - if (area_id.s_addr == OSPF_AREA_BACKBONE) - ospf->backbone = new; + new->oiflist = list_new(); + new->ranges = route_table_init(); - return new; + if (area_id.s_addr == OSPF_AREA_BACKBONE) + ospf->backbone = new; + + return new; } -static void -ospf_area_free (struct ospf_area *area) +static void ospf_area_free(struct ospf_area *area) { - struct route_node *rn; - struct ospf_lsa *lsa; + struct route_node *rn; + struct ospf_lsa *lsa; + + /* Free LSDBs. */ + LSDB_LOOP(ROUTER_LSDB(area), rn, lsa) + ospf_discard_from_db(area->ospf, area->lsdb, lsa); + LSDB_LOOP(NETWORK_LSDB(area), rn, lsa) + ospf_discard_from_db(area->ospf, area->lsdb, lsa); + LSDB_LOOP(SUMMARY_LSDB(area), rn, lsa) + ospf_discard_from_db(area->ospf, area->lsdb, lsa); + LSDB_LOOP(ASBR_SUMMARY_LSDB(area), rn, lsa) + ospf_discard_from_db(area->ospf, area->lsdb, lsa); - /* Free LSDBs. */ - LSDB_LOOP (ROUTER_LSDB (area), rn, lsa) - ospf_discard_from_db (area->ospf, area->lsdb, lsa); - LSDB_LOOP (NETWORK_LSDB (area), rn, lsa) - ospf_discard_from_db (area->ospf, area->lsdb, lsa); - LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa) - ospf_discard_from_db (area->ospf, area->lsdb, lsa); - LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa) - ospf_discard_from_db (area->ospf, area->lsdb, lsa); + LSDB_LOOP(NSSA_LSDB(area), rn, lsa) + ospf_discard_from_db(area->ospf, area->lsdb, lsa); + LSDB_LOOP(OPAQUE_AREA_LSDB(area), rn, lsa) + ospf_discard_from_db(area->ospf, area->lsdb, lsa); + LSDB_LOOP(OPAQUE_LINK_LSDB(area), rn, lsa) + ospf_discard_from_db(area->ospf, area->lsdb, lsa); - LSDB_LOOP (NSSA_LSDB (area), rn, lsa) - ospf_discard_from_db (area->ospf, area->lsdb, lsa); - LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa) - ospf_discard_from_db (area->ospf, area->lsdb, lsa); - LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa) - ospf_discard_from_db (area->ospf, area->lsdb, lsa); + ospf_lsdb_delete_all(area->lsdb); + ospf_lsdb_free(area->lsdb); - ospf_lsdb_delete_all (area->lsdb); - ospf_lsdb_free (area->lsdb); + ospf_lsa_unlock(&area->router_lsa_self); - ospf_lsa_unlock (&area->router_lsa_self); - - route_table_finish (area->ranges); - list_delete (area->oiflist); + route_table_finish(area->ranges); + list_delete(area->oiflist); - if (EXPORT_NAME (area)) - free (EXPORT_NAME (area)); + if (EXPORT_NAME(area)) + free(EXPORT_NAME(area)); - if (IMPORT_NAME (area)) - free (IMPORT_NAME (area)); + if (IMPORT_NAME(area)) + free(IMPORT_NAME(area)); - /* Cancel timer. */ - OSPF_TIMER_OFF (area->t_stub_router); - OSPF_TIMER_OFF (area->t_opaque_lsa_self); - - if (OSPF_IS_AREA_BACKBONE (area)) - area->ospf->backbone = NULL; + /* Cancel timer. */ + OSPF_TIMER_OFF(area->t_stub_router); + OSPF_TIMER_OFF(area->t_opaque_lsa_self); - XFREE (MTYPE_OSPF_AREA, area); + if (OSPF_IS_AREA_BACKBONE(area)) + area->ospf->backbone = NULL; + + XFREE(MTYPE_OSPF_AREA, area); } -void -ospf_area_check_free (struct ospf *ospf, struct in_addr area_id) +void ospf_area_check_free(struct ospf *ospf, struct in_addr area_id) { - struct ospf_area *area; + struct ospf_area *area; - area = ospf_area_lookup_by_area_id (ospf, area_id); - if (area && - listcount (area->oiflist) == 0 && - area->ranges->top == NULL && - area->shortcut_configured == OSPF_SHORTCUT_DEFAULT && - area->external_routing == OSPF_AREA_DEFAULT && - area->no_summary == 0 && - area->default_cost == 1 && - EXPORT_NAME (area) == NULL && - IMPORT_NAME (area) == NULL && - area->auth_type == OSPF_AUTH_NULL) - { - listnode_delete (ospf->areas, area); - ospf_area_free (area); - } + area = ospf_area_lookup_by_area_id(ospf, area_id); + if (area && listcount(area->oiflist) == 0 && area->ranges->top == NULL + && area->shortcut_configured == OSPF_SHORTCUT_DEFAULT + && area->external_routing == OSPF_AREA_DEFAULT + && area->no_summary == 0 && area->default_cost == 1 + && EXPORT_NAME(area) == NULL && IMPORT_NAME(area) == NULL + && area->auth_type == OSPF_AUTH_NULL) { + listnode_delete(ospf->areas, area); + ospf_area_free(area); + } } -struct ospf_area * -ospf_area_get (struct ospf *ospf, struct in_addr area_id) +struct ospf_area *ospf_area_get(struct ospf *ospf, struct in_addr area_id) { - struct ospf_area *area; - - area = ospf_area_lookup_by_area_id (ospf, area_id); - if (!area) - { - area = ospf_area_new (ospf, area_id); - listnode_add_sort (ospf->areas, area); - ospf_check_abr_status (ospf); - if (ospf->stub_router_admin_set == OSPF_STUB_ROUTER_ADMINISTRATIVE_SET) - { - SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED); - } - } + struct ospf_area *area; + + area = ospf_area_lookup_by_area_id(ospf, area_id); + if (!area) { + area = ospf_area_new(ospf, area_id); + listnode_add_sort(ospf->areas, area); + ospf_check_abr_status(ospf); + if (ospf->stub_router_admin_set + == OSPF_STUB_ROUTER_ADMINISTRATIVE_SET) { + SET_FLAG(area->stub_router_state, + OSPF_AREA_ADMIN_STUB_ROUTED); + } + } - return area; + return area; } -struct ospf_area * -ospf_area_lookup_by_area_id (struct ospf *ospf, struct in_addr area_id) +struct ospf_area *ospf_area_lookup_by_area_id(struct ospf *ospf, + struct in_addr area_id) { - struct ospf_area *area; - struct listnode *node; + struct ospf_area *area; + struct listnode *node; - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - if (IPV4_ADDR_SAME (&area->area_id, &area_id)) - return area; + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) + if (IPV4_ADDR_SAME(&area->area_id, &area_id)) + return area; - return NULL; + return NULL; } -void -ospf_area_add_if (struct ospf_area *area, struct ospf_interface *oi) +void ospf_area_add_if(struct ospf_area *area, struct ospf_interface *oi) { - listnode_add (area->oiflist, oi); + listnode_add(area->oiflist, oi); } -void -ospf_area_del_if (struct ospf_area *area, struct ospf_interface *oi) +void ospf_area_del_if(struct ospf_area *area, struct ospf_interface *oi) { - listnode_delete (area->oiflist, oi); + listnode_delete(area->oiflist, oi); } - -static void -add_ospf_interface (struct connected *co, struct ospf_area *area) +static void add_ospf_interface(struct connected *co, struct ospf_area *area) { - struct ospf_interface *oi; - - oi = ospf_if_new (area->ospf, co->ifp, co->address); - oi->connected = co; + struct ospf_interface *oi; - oi->area = area; + oi = ospf_if_new(area->ospf, co->ifp, co->address); + oi->connected = co; - oi->params = ospf_lookup_if_params (co->ifp, oi->address->u.prefix4); - oi->output_cost = ospf_if_get_output_cost (oi); + oi->area = area; - /* Relate ospf interface to ospf instance. */ - oi->ospf = area->ospf; + oi->params = ospf_lookup_if_params(co->ifp, oi->address->u.prefix4); + oi->output_cost = ospf_if_get_output_cost(oi); - /* update network type as interface flag */ - /* If network type is specified previously, - skip network type setting. */ - oi->type = IF_DEF_PARAMS (co->ifp)->type; + /* Relate ospf interface to ospf instance. */ + oi->ospf = area->ospf; - /* Add pseudo neighbor. */ - ospf_nbr_self_reset (oi, oi->ospf->router_id); + /* update network type as interface flag */ + /* If network type is specified previously, + skip network type setting. */ + oi->type = IF_DEF_PARAMS(co->ifp)->type; - ospf_area_add_if (oi->area, oi); + /* Add pseudo neighbor. */ + ospf_nbr_self_reset(oi, oi->ospf->router_id); - /* - * if router_id is not configured, dont bring up - * interfaces. - * ospf_router_id_update() will call ospf_if_update - * whenever r-id is configured instead. - */ - if ((area->ospf->router_id.s_addr != 0) - && if_is_operative (co->ifp)) - ospf_if_up (oi); + ospf_area_add_if(oi->area, oi); + /* + * if router_id is not configured, dont bring up + * interfaces. + * ospf_router_id_update() will call ospf_if_update + * whenever r-id is configured instead. + */ + if ((area->ospf->router_id.s_addr != 0) && if_is_operative(co->ifp)) + ospf_if_up(oi); } static void update_redistributed(struct ospf *ospf, int add_to_ospf) { - struct route_node *rn; - struct external_info *ei; - struct ospf_external *ext; - - if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT, 0)) - if ((ext = ospf_external_lookup(ZEBRA_ROUTE_CONNECT, 0)) && - EXTERNAL_INFO (ext)) - { - for (rn = route_top (EXTERNAL_INFO (ext)); - rn; rn = route_next (rn)) - { - if ((ei = rn->info) != NULL) - { - if (add_to_ospf) - { - if (ospf_external_info_find_lsa (ospf, &ei->p)) - if (!ospf_distribute_check_connected (ospf, ei)) - ospf_external_lsa_flush (ospf, ei->type, &ei->p, - ei->ifindex /*, ei->nexthop */); - } - else - { - if (!ospf_external_info_find_lsa (ospf, &ei->p)) - if (ospf_distribute_check_connected (ospf, ei)) - ospf_external_lsa_originate (ospf, ei); - } - } - } - } + struct route_node *rn; + struct external_info *ei; + struct ospf_external *ext; + + if (ospf_is_type_redistributed(ZEBRA_ROUTE_CONNECT, 0)) + if ((ext = ospf_external_lookup(ZEBRA_ROUTE_CONNECT, 0)) + && EXTERNAL_INFO(ext)) { + for (rn = route_top(EXTERNAL_INFO(ext)); rn; + rn = route_next(rn)) { + if ((ei = rn->info) != NULL) { + if (add_to_ospf) { + if (ospf_external_info_find_lsa( + ospf, &ei->p)) + if (!ospf_distribute_check_connected( + ospf, ei)) + ospf_external_lsa_flush( + ospf, + ei->type, + &ei->p, + ei->ifindex /*, ei->nexthop */); + } else { + if (!ospf_external_info_find_lsa( + ospf, &ei->p)) + if (ospf_distribute_check_connected( + ospf, ei)) + ospf_external_lsa_originate( + ospf, + ei); + } + } + } + } } /* Config network statement related functions. */ -static struct ospf_network * -ospf_network_new (struct in_addr area_id) +static struct ospf_network *ospf_network_new(struct in_addr area_id) { - struct ospf_network *new; - new = XCALLOC (MTYPE_OSPF_NETWORK, sizeof (struct ospf_network)); + struct ospf_network *new; + new = XCALLOC(MTYPE_OSPF_NETWORK, sizeof(struct ospf_network)); - new->area_id = area_id; - new->area_id_fmt = OSPF_AREA_ID_FMT_DOTTEDQUAD; - - return new; + new->area_id = area_id; + new->area_id_fmt = OSPF_AREA_ID_FMT_DOTTEDQUAD; + + return new; } -static void -ospf_network_free (struct ospf *ospf, struct ospf_network *network) +static void ospf_network_free(struct ospf *ospf, struct ospf_network *network) { - ospf_area_check_free (ospf, network->area_id); - ospf_schedule_abr_task (ospf); - XFREE (MTYPE_OSPF_NETWORK, network); + ospf_area_check_free(ospf, network->area_id); + ospf_schedule_abr_task(ospf); + XFREE(MTYPE_OSPF_NETWORK, network); } -int -ospf_network_set (struct ospf *ospf, struct prefix_ipv4 *p, - struct in_addr area_id, int df) +int ospf_network_set(struct ospf *ospf, struct prefix_ipv4 *p, + struct in_addr area_id, int df) { - struct ospf_network *network; - struct ospf_area *area; - struct route_node *rn; + struct ospf_network *network; + struct ospf_area *area; + struct route_node *rn; - rn = route_node_get (ospf->networks, (struct prefix *)p); - if (rn->info) - { - /* There is already same network statement. */ - route_unlock_node (rn); - return 0; - } + rn = route_node_get(ospf->networks, (struct prefix *)p); + if (rn->info) { + /* There is already same network statement. */ + route_unlock_node(rn); + return 0; + } - rn->info = network = ospf_network_new (area_id); - network->area_id_fmt = df; - area = ospf_area_get (ospf, area_id); - ospf_area_display_format_set (ospf, area, df); + rn->info = network = ospf_network_new(area_id); + network->area_id_fmt = df; + area = ospf_area_get(ospf, area_id); + ospf_area_display_format_set(ospf, area, df); - /* Run network config now. */ - ospf_network_run ((struct prefix *)p, area); + /* Run network config now. */ + ospf_network_run((struct prefix *)p, area); - /* Update connected redistribute. */ - update_redistributed(ospf, 1); /* interfaces possibly added */ + /* Update connected redistribute. */ + update_redistributed(ospf, 1); /* interfaces possibly added */ - ospf_area_check_free (ospf, area_id); + ospf_area_check_free(ospf, area_id); - return 1; + return 1; } -int -ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p, - struct in_addr area_id) +int ospf_network_unset(struct ospf *ospf, struct prefix_ipv4 *p, + struct in_addr area_id) { - struct route_node *rn; - struct ospf_network *network; - struct listnode *node, *nnode; - struct ospf_interface *oi; + struct route_node *rn; + struct ospf_network *network; + struct listnode *node, *nnode; + struct ospf_interface *oi; - rn = route_node_lookup (ospf->networks, (struct prefix *)p); - if (rn == NULL) - return 0; + rn = route_node_lookup(ospf->networks, (struct prefix *)p); + if (rn == NULL) + return 0; - network = rn->info; - route_unlock_node (rn); - if (!IPV4_ADDR_SAME (&area_id, &network->area_id)) - return 0; + network = rn->info; + route_unlock_node(rn); + if (!IPV4_ADDR_SAME(&area_id, &network->area_id)) + return 0; - ospf_network_free (ospf, rn->info); - rn->info = NULL; - route_unlock_node (rn); /* initial reference */ + ospf_network_free(ospf, rn->info); + rn->info = NULL; + route_unlock_node(rn); /* initial reference */ - /* Find interfaces that not configured already. */ - for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) - { - ospf_network_run_subnet (ospf, oi->connected, NULL, NULL); - } - - /* Update connected redistribute. */ - update_redistributed(ospf, 0); /* interfaces possibly removed */ - ospf_area_check_free (ospf, area_id); + /* Find interfaces that not configured already. */ + for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) { + ospf_network_run_subnet(ospf, oi->connected, NULL, NULL); + } - return 1; + /* Update connected redistribute. */ + update_redistributed(ospf, 0); /* interfaces possibly removed */ + ospf_area_check_free(ospf, area_id); + + return 1; } /* Ensure there's an OSPF instance, as "ip ospf area" enabled OSPF means @@ -1037,69 +993,67 @@ ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p, * * Otherwise, doesn't do anything different to ospf_if_update for now */ -void -ospf_interface_area_set (struct interface *ifp) +void ospf_interface_area_set(struct interface *ifp) { - struct ospf *ospf = ospf_get(); - - ospf_if_update (ospf, ifp); - /* if_update does a update_redistributed */ - - return; + struct ospf *ospf = ospf_get(); + + ospf_if_update(ospf, ifp); + /* if_update does a update_redistributed */ + + return; } -void -ospf_interface_area_unset (struct interface *ifp) +void ospf_interface_area_unset(struct interface *ifp) { - struct route_node *rn_oi; - struct ospf *ospf; + struct route_node *rn_oi; + struct ospf *ospf; - ospf = ospf_lookup (); - if (!ospf) - return; /* Ospf not ready yet */ + ospf = ospf_lookup(); + if (!ospf) + return; /* Ospf not ready yet */ - /* Find interfaces that may need to be removed. */ - for (rn_oi = route_top (IF_OIFS (ifp)); rn_oi; rn_oi = route_next (rn_oi)) - { - struct ospf_interface *oi; - - if ( (oi = rn_oi->info) == NULL) - continue; - - if (oi->type == OSPF_IFTYPE_VIRTUALLINK) - continue; - - ospf_network_run_subnet (ospf, oi->connected, NULL, NULL); - } + /* Find interfaces that may need to be removed. */ + for (rn_oi = route_top(IF_OIFS(ifp)); rn_oi; + rn_oi = route_next(rn_oi)) { + struct ospf_interface *oi; + + if ((oi = rn_oi->info) == NULL) + continue; + + if (oi->type == OSPF_IFTYPE_VIRTUALLINK) + continue; + + ospf_network_run_subnet(ospf, oi->connected, NULL, NULL); + } - /* Update connected redistribute. */ - update_redistributed(ospf, 0); /* interfaces possibly removed */ + /* Update connected redistribute. */ + update_redistributed(ospf, 0); /* interfaces possibly removed */ } /* Check whether interface matches given network * returns: 1, true. 0, false */ -static int -ospf_network_match_iface(const struct connected *co, const struct prefix *net) +static int ospf_network_match_iface(const struct connected *co, + const struct prefix *net) { - /* new approach: more elegant and conceptually clean */ - return prefix_match_network_statement(net, CONNECTED_PREFIX(co)); + /* new approach: more elegant and conceptually clean */ + return prefix_match_network_statement(net, CONNECTED_PREFIX(co)); } -static void -ospf_update_interface_area (struct connected *co, struct ospf_area *area) +static void ospf_update_interface_area(struct connected *co, + struct ospf_area *area) { - struct ospf_interface *oi = ospf_if_table_lookup (co->ifp, co->address); - - /* nothing to be done case */ - if (oi && oi->area == area){ - return; - } - - if (oi) - ospf_if_free (oi); - - add_ospf_interface (co, area); + struct ospf_interface *oi = ospf_if_table_lookup(co->ifp, co->address); + + /* nothing to be done case */ + if (oi && oi->area == area) { + return; + } + + if (oi) + ospf_if_free(oi); + + add_ospf_interface(co, area); } /* Run OSPF for the given subnet, taking into account the following @@ -1111,399 +1065,379 @@ ospf_update_interface_area (struct connected *co, struct ospf_area *area) * - If no specific network prefix/area is supplied, whether there's * a matching network configured. */ -static void -ospf_network_run_subnet (struct ospf *ospf, struct connected *co, - struct prefix *p, struct ospf_area *given_area) -{ - struct ospf_interface *oi; - struct ospf_if_params *params; - struct ospf_area *area = NULL; - struct route_node *rn; - int configed = 0; - - if (CHECK_FLAG(co->flags, ZEBRA_IFA_SECONDARY)) - return; - - if (co->address->family != AF_INET) - return; - - /* Try determine the appropriate area for this interface + address - * Start by checking interface config - */ - params = ospf_lookup_if_params (co->ifp, co->address->u.prefix4); - if ( params && OSPF_IF_PARAM_CONFIGURED(params, if_area)) - area = ospf_area_get (ospf, params->if_area); - else{ - params = IF_DEF_PARAMS (co->ifp); - if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) - area = ospf_area_get (ospf, params->if_area); - } +static void ospf_network_run_subnet(struct ospf *ospf, struct connected *co, + struct prefix *p, + struct ospf_area *given_area) +{ + struct ospf_interface *oi; + struct ospf_if_params *params; + struct ospf_area *area = NULL; + struct route_node *rn; + int configed = 0; + + if (CHECK_FLAG(co->flags, ZEBRA_IFA_SECONDARY)) + return; + + if (co->address->family != AF_INET) + return; + + /* Try determine the appropriate area for this interface + address + * Start by checking interface config + */ + params = ospf_lookup_if_params(co->ifp, co->address->u.prefix4); + if (params && OSPF_IF_PARAM_CONFIGURED(params, if_area)) + area = ospf_area_get(ospf, params->if_area); + else { + params = IF_DEF_PARAMS(co->ifp); + if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) + area = ospf_area_get(ospf, params->if_area); + } - /* If we've found an interface and/or addr specific area, then we're - * done - */ - if (area) - { - ospf_update_interface_area (co, area); - return; - } - - /* Otherwise, only remaining possibility is a matching network statement */ - if (p) - { - assert (given_area != NULL); - - /* Which either was supplied as a parameter.. (e.g. cause a new - * network/area was just added).. - */ - if (p->family == co->address->family - && ospf_network_match_iface (co, p)) - ospf_update_interface_area (co, given_area); - - return; - } - - /* Else we have to search the existing network/area config to see - * if any match.. - */ - for (rn = route_top (ospf->networks); rn; rn = route_next (rn)) - if (rn->info != NULL - && ospf_network_match_iface (co, &rn->p)) - { - struct ospf_network *network = (struct ospf_network *) rn->info; - area = ospf_area_get (ospf, network->area_id); - ospf_update_interface_area (co, area); - configed = 1; - } - - /* If the subnet isn't in any area, deconfigure */ - if (!configed && (oi = ospf_if_table_lookup (co->ifp, co->address))) - ospf_if_free (oi); -} - -static void -ospf_network_run_interface (struct ospf *ospf, struct interface *ifp, - struct prefix *p, - struct ospf_area *given_area) -{ - struct listnode *cnode; - struct connected *co; - - if (memcmp (ifp->name, "VLINK", 5) == 0) - return; - - /* Network prefix without area is nonsensical */ - if (p) - assert (given_area != NULL); - - /* if interface prefix is match specified prefix, - then create socket and join multicast group. */ - for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co)) - ospf_network_run_subnet (ospf, co, p, given_area); -} - -static void -ospf_network_run (struct prefix *p, struct ospf_area *area) -{ - struct interface *ifp; - struct listnode *node; + /* If we've found an interface and/or addr specific area, then we're + * done + */ + if (area) { + ospf_update_interface_area(co, area); + return; + } - /* Schedule Router ID Update. */ - if (area->ospf->router_id.s_addr == 0) - ospf_router_id_update (area->ospf); - - /* Get target interface. */ - for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp)) - ospf_network_run_interface (area->ospf, ifp, p, area); -} - -void -ospf_ls_upd_queue_empty (struct ospf_interface *oi) -{ - struct route_node *rn; - struct listnode *node, *nnode; - struct list *lst; - struct ospf_lsa *lsa; - - /* empty ls update queue */ - for (rn = route_top (oi->ls_upd_queue); rn; - rn = route_next (rn)) - if ((lst = (struct list *) rn->info)) - { - for (ALL_LIST_ELEMENTS (lst, node, nnode, lsa)) - ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */ - list_free (lst); - rn->info = NULL; - } - - /* remove update event */ - if (oi->t_ls_upd_event) - { - thread_cancel (oi->t_ls_upd_event); - oi->t_ls_upd_event = NULL; - } + /* Otherwise, only remaining possibility is a matching network statement + */ + if (p) { + assert(given_area != NULL); + + /* Which either was supplied as a parameter.. (e.g. cause a new + * network/area was just added).. + */ + if (p->family == co->address->family + && ospf_network_match_iface(co, p)) + ospf_update_interface_area(co, given_area); + + return; + } + + /* Else we have to search the existing network/area config to see + * if any match.. + */ + for (rn = route_top(ospf->networks); rn; rn = route_next(rn)) + if (rn->info != NULL && ospf_network_match_iface(co, &rn->p)) { + struct ospf_network *network = + (struct ospf_network *)rn->info; + area = ospf_area_get(ospf, network->area_id); + ospf_update_interface_area(co, area); + configed = 1; + } + + /* If the subnet isn't in any area, deconfigure */ + if (!configed && (oi = ospf_if_table_lookup(co->ifp, co->address))) + ospf_if_free(oi); } -void -ospf_if_update (struct ospf *ospf, struct interface *ifp) +static void ospf_network_run_interface(struct ospf *ospf, struct interface *ifp, + struct prefix *p, + struct ospf_area *given_area) { - if (!ospf) - ospf = ospf_lookup (); + struct listnode *cnode; + struct connected *co; + + if (memcmp(ifp->name, "VLINK", 5) == 0) + return; - /* OSPF must be ready. */ - if (!ospf_is_ready (ospf)) - return; - - ospf_network_run_interface (ospf, ifp, NULL, NULL); - - /* Update connected redistribute. */ - update_redistributed(ospf, 1); + /* Network prefix without area is nonsensical */ + if (p) + assert(given_area != NULL); + + /* if interface prefix is match specified prefix, + then create socket and join multicast group. */ + for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, co)) + ospf_network_run_subnet(ospf, co, p, given_area); } -void -ospf_remove_vls_through_area (struct ospf *ospf, struct ospf_area *area) +static void ospf_network_run(struct prefix *p, struct ospf_area *area) { - struct listnode *node, *nnode; - struct ospf_vl_data *vl_data; + struct interface *ifp; + struct listnode *node; + + /* Schedule Router ID Update. */ + if (area->ospf->router_id.s_addr == 0) + ospf_router_id_update(area->ospf); - for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data)) - if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id)) - ospf_vl_delete (ospf, vl_data); + /* Get target interface. */ + for (ALL_LIST_ELEMENTS_RO(om->iflist, node, ifp)) + ospf_network_run_interface(area->ospf, ifp, p, area); } +void ospf_ls_upd_queue_empty(struct ospf_interface *oi) +{ + struct route_node *rn; + struct listnode *node, *nnode; + struct list *lst; + struct ospf_lsa *lsa; + + /* empty ls update queue */ + for (rn = route_top(oi->ls_upd_queue); rn; rn = route_next(rn)) + if ((lst = (struct list *)rn->info)) { + for (ALL_LIST_ELEMENTS(lst, node, nnode, lsa)) + ospf_lsa_unlock(&lsa); /* oi->ls_upd_queue */ + list_free(lst); + rn->info = NULL; + } + + /* remove update event */ + if (oi->t_ls_upd_event) { + thread_cancel(oi->t_ls_upd_event); + oi->t_ls_upd_event = NULL; + } +} -static const struct message ospf_area_type_msg[] = +void ospf_if_update(struct ospf *ospf, struct interface *ifp) { - { OSPF_AREA_DEFAULT, "Default" }, - { OSPF_AREA_STUB, "Stub" }, - { OSPF_AREA_NSSA, "NSSA" }, - { 0 } -}; + if (!ospf) + ospf = ospf_lookup(); + + /* OSPF must be ready. */ + if (!ospf_is_ready(ospf)) + return; + + ospf_network_run_interface(ospf, ifp, NULL, NULL); + + /* Update connected redistribute. */ + update_redistributed(ospf, 1); +} -static void -ospf_area_type_set (struct ospf_area *area, int type) +void ospf_remove_vls_through_area(struct ospf *ospf, struct ospf_area *area) { - struct listnode *node; - struct ospf_interface *oi; + struct listnode *node, *nnode; + struct ospf_vl_data *vl_data; - if (area->external_routing == type) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Area[%s]: Types are the same, ignored.", - inet_ntoa (area->area_id)); - return; - } + for (ALL_LIST_ELEMENTS(ospf->vlinks, node, nnode, vl_data)) + if (IPV4_ADDR_SAME(&vl_data->vl_area_id, &area->area_id)) + ospf_vl_delete(ospf, vl_data); +} - area->external_routing = type; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Area[%s]: Configured as %s", inet_ntoa (area->area_id), - lookup_msg(ospf_area_type_msg, type, NULL)); +static const struct message ospf_area_type_msg[] = { + {OSPF_AREA_DEFAULT, "Default"}, + {OSPF_AREA_STUB, "Stub"}, + {OSPF_AREA_NSSA, "NSSA"}, + {0}}; - switch (area->external_routing) - { - case OSPF_AREA_DEFAULT: - for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi)) - if (oi->nbr_self != NULL) - { - UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP); - SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E); - } - break; - case OSPF_AREA_STUB: - for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi)) - if (oi->nbr_self != NULL) - { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("setting options on %s accordingly", IF_NAME (oi)); - UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP); - UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E); - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("options set on %s: %x", - IF_NAME (oi), OPTIONS (oi)); - } - break; - case OSPF_AREA_NSSA: - for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi)) - if (oi->nbr_self != NULL) - { - zlog_debug ("setting nssa options on %s accordingly", IF_NAME (oi)); - UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E); - SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP); - zlog_debug ("options set on %s: %x", IF_NAME (oi), OPTIONS (oi)); - } - break; - default: - break; - } +static void ospf_area_type_set(struct ospf_area *area, int type) +{ + struct listnode *node; + struct ospf_interface *oi; + + if (area->external_routing == type) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Area[%s]: Types are the same, ignored.", + inet_ntoa(area->area_id)); + return; + } - ospf_router_lsa_update_area (area); - ospf_schedule_abr_task (area->ospf); + area->external_routing = type; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Area[%s]: Configured as %s", + inet_ntoa(area->area_id), + lookup_msg(ospf_area_type_msg, type, NULL)); + + switch (area->external_routing) { + case OSPF_AREA_DEFAULT: + for (ALL_LIST_ELEMENTS_RO(area->oiflist, node, oi)) + if (oi->nbr_self != NULL) { + UNSET_FLAG(oi->nbr_self->options, + OSPF_OPTION_NP); + SET_FLAG(oi->nbr_self->options, OSPF_OPTION_E); + } + break; + case OSPF_AREA_STUB: + for (ALL_LIST_ELEMENTS_RO(area->oiflist, node, oi)) + if (oi->nbr_self != NULL) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "setting options on %s accordingly", + IF_NAME(oi)); + UNSET_FLAG(oi->nbr_self->options, + OSPF_OPTION_NP); + UNSET_FLAG(oi->nbr_self->options, + OSPF_OPTION_E); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("options set on %s: %x", + IF_NAME(oi), OPTIONS(oi)); + } + break; + case OSPF_AREA_NSSA: + for (ALL_LIST_ELEMENTS_RO(area->oiflist, node, oi)) + if (oi->nbr_self != NULL) { + zlog_debug( + "setting nssa options on %s accordingly", + IF_NAME(oi)); + UNSET_FLAG(oi->nbr_self->options, + OSPF_OPTION_E); + SET_FLAG(oi->nbr_self->options, OSPF_OPTION_NP); + zlog_debug("options set on %s: %x", IF_NAME(oi), + OPTIONS(oi)); + } + break; + default: + break; + } + + ospf_router_lsa_update_area(area); + ospf_schedule_abr_task(area->ospf); } -int -ospf_area_shortcut_set (struct ospf *ospf, struct ospf_area *area, int mode) +int ospf_area_shortcut_set(struct ospf *ospf, struct ospf_area *area, int mode) { - if (area->shortcut_configured == mode) - return 0; + if (area->shortcut_configured == mode) + return 0; - area->shortcut_configured = mode; - ospf_router_lsa_update_area (area); - ospf_schedule_abr_task (ospf); + area->shortcut_configured = mode; + ospf_router_lsa_update_area(area); + ospf_schedule_abr_task(ospf); - ospf_area_check_free (ospf, area->area_id); + ospf_area_check_free(ospf, area->area_id); - return 1; + return 1; } -int -ospf_area_shortcut_unset (struct ospf *ospf, struct ospf_area *area) +int ospf_area_shortcut_unset(struct ospf *ospf, struct ospf_area *area) { - area->shortcut_configured = OSPF_SHORTCUT_DEFAULT; - ospf_router_lsa_update_area (area); - ospf_area_check_free (ospf, area->area_id); - ospf_schedule_abr_task (ospf); + area->shortcut_configured = OSPF_SHORTCUT_DEFAULT; + ospf_router_lsa_update_area(area); + ospf_area_check_free(ospf, area->area_id); + ospf_schedule_abr_task(ospf); - return 1; + return 1; } -static int -ospf_area_vlink_count (struct ospf *ospf, struct ospf_area *area) +static int ospf_area_vlink_count(struct ospf *ospf, struct ospf_area *area) { - struct ospf_vl_data *vl; - struct listnode *node; - int count = 0; + struct ospf_vl_data *vl; + struct listnode *node; + int count = 0; - for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl)) - if (IPV4_ADDR_SAME (&vl->vl_area_id, &area->area_id)) - count++; + for (ALL_LIST_ELEMENTS_RO(ospf->vlinks, node, vl)) + if (IPV4_ADDR_SAME(&vl->vl_area_id, &area->area_id)) + count++; - return count; + return count; } -int -ospf_area_display_format_set (struct ospf *ospf, struct ospf_area *area, int df) +int ospf_area_display_format_set(struct ospf *ospf, struct ospf_area *area, + int df) { - area->area_id_fmt = df; + area->area_id_fmt = df; - return 1; + return 1; } -int -ospf_area_stub_set (struct ospf *ospf, struct in_addr area_id) +int ospf_area_stub_set(struct ospf *ospf, struct in_addr area_id) { - struct ospf_area *area; + struct ospf_area *area; - area = ospf_area_get (ospf, area_id); - if (ospf_area_vlink_count (ospf, area)) - return 0; + area = ospf_area_get(ospf, area_id); + if (ospf_area_vlink_count(ospf, area)) + return 0; - if (area->external_routing != OSPF_AREA_STUB) - ospf_area_type_set (area, OSPF_AREA_STUB); + if (area->external_routing != OSPF_AREA_STUB) + ospf_area_type_set(area, OSPF_AREA_STUB); - return 1; + return 1; } -int -ospf_area_stub_unset (struct ospf *ospf, struct in_addr area_id) +int ospf_area_stub_unset(struct ospf *ospf, struct in_addr area_id) { - struct ospf_area *area; + struct ospf_area *area; - area = ospf_area_lookup_by_area_id (ospf, area_id); - if (area == NULL) - return 1; + area = ospf_area_lookup_by_area_id(ospf, area_id); + if (area == NULL) + return 1; - if (area->external_routing == OSPF_AREA_STUB) - ospf_area_type_set (area, OSPF_AREA_DEFAULT); + if (area->external_routing == OSPF_AREA_STUB) + ospf_area_type_set(area, OSPF_AREA_DEFAULT); - ospf_area_check_free (ospf, area_id); + ospf_area_check_free(ospf, area_id); - return 1; + return 1; } -int -ospf_area_no_summary_set (struct ospf *ospf, struct in_addr area_id) +int ospf_area_no_summary_set(struct ospf *ospf, struct in_addr area_id) { - struct ospf_area *area; + struct ospf_area *area; - area = ospf_area_get (ospf, area_id); - area->no_summary = 1; + area = ospf_area_get(ospf, area_id); + area->no_summary = 1; - return 1; + return 1; } -int -ospf_area_no_summary_unset (struct ospf *ospf, struct in_addr area_id) +int ospf_area_no_summary_unset(struct ospf *ospf, struct in_addr area_id) { - struct ospf_area *area; + struct ospf_area *area; - area = ospf_area_lookup_by_area_id (ospf, area_id); - if (area == NULL) - return 0; + area = ospf_area_lookup_by_area_id(ospf, area_id); + if (area == NULL) + return 0; - area->no_summary = 0; - ospf_area_check_free (ospf, area_id); + area->no_summary = 0; + ospf_area_check_free(ospf, area_id); - return 1; + return 1; } -int -ospf_area_nssa_set (struct ospf *ospf, struct in_addr area_id) +int ospf_area_nssa_set(struct ospf *ospf, struct in_addr area_id) { - struct ospf_area *area; + struct ospf_area *area; - area = ospf_area_get (ospf, area_id); - if (ospf_area_vlink_count (ospf, area)) - return 0; + area = ospf_area_get(ospf, area_id); + if (ospf_area_vlink_count(ospf, area)) + return 0; - if (area->external_routing != OSPF_AREA_NSSA) - { - ospf_area_type_set (area, OSPF_AREA_NSSA); - ospf->anyNSSA++; - } + if (area->external_routing != OSPF_AREA_NSSA) { + ospf_area_type_set(area, OSPF_AREA_NSSA); + ospf->anyNSSA++; + } - /* set NSSA area defaults */ - area->no_summary = 0; - area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE; - area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED; - area->NSSATranslatorStabilityInterval = OSPF_NSSA_TRANS_STABLE_DEFAULT; + /* set NSSA area defaults */ + area->no_summary = 0; + area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE; + area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED; + area->NSSATranslatorStabilityInterval = OSPF_NSSA_TRANS_STABLE_DEFAULT; - return 1; + return 1; } -int -ospf_area_nssa_unset (struct ospf *ospf, struct in_addr area_id) +int ospf_area_nssa_unset(struct ospf *ospf, struct in_addr area_id) { - struct ospf_area *area; + struct ospf_area *area; - area = ospf_area_lookup_by_area_id (ospf, area_id); - if (area == NULL) - return 0; + area = ospf_area_lookup_by_area_id(ospf, area_id); + if (area == NULL) + return 0; - if (area->external_routing == OSPF_AREA_NSSA) - { - ospf->anyNSSA--; - ospf_area_type_set (area, OSPF_AREA_DEFAULT); - } + if (area->external_routing == OSPF_AREA_NSSA) { + ospf->anyNSSA--; + ospf_area_type_set(area, OSPF_AREA_DEFAULT); + } - ospf_area_check_free (ospf, area_id); + ospf_area_check_free(ospf, area_id); - return 1; + return 1; } -int -ospf_area_nssa_translator_role_set (struct ospf *ospf, struct in_addr area_id, - int role) +int ospf_area_nssa_translator_role_set(struct ospf *ospf, + struct in_addr area_id, int role) { - struct ospf_area *area; + struct ospf_area *area; - area = ospf_area_lookup_by_area_id (ospf, area_id); - if (area == NULL) - return 0; + area = ospf_area_lookup_by_area_id(ospf, area_id); + if (area == NULL) + return 0; - area->NSSATranslatorRole = role; + area->NSSATranslatorRole = role; - return 1; + return 1; } #if 0 @@ -1526,276 +1460,258 @@ ospf_area_nssa_translator_role_unset (struct ospf *ospf, } #endif -int -ospf_area_export_list_set (struct ospf *ospf, - struct ospf_area *area, const char *list_name) +int ospf_area_export_list_set(struct ospf *ospf, struct ospf_area *area, + const char *list_name) { - struct access_list *list; - list = access_list_lookup (AFI_IP, list_name); + struct access_list *list; + list = access_list_lookup(AFI_IP, list_name); - 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 (list_name); - ospf_schedule_abr_task (ospf); + EXPORT_NAME(area) = strdup(list_name); + ospf_schedule_abr_task(ospf); - return 1; + return 1; } -int -ospf_area_export_list_unset (struct ospf *ospf, struct ospf_area * area) +int ospf_area_export_list_unset(struct ospf *ospf, struct ospf_area *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; + EXPORT_NAME(area) = NULL; - ospf_area_check_free (ospf, area->area_id); - - ospf_schedule_abr_task (ospf); + ospf_area_check_free(ospf, area->area_id); - return 1; + ospf_schedule_abr_task(ospf); + + return 1; } -int -ospf_area_import_list_set (struct ospf *ospf, struct ospf_area *area, - const char *name) +int ospf_area_import_list_set(struct ospf *ospf, struct ospf_area *area, + const char *name) { - struct access_list *list; - list = access_list_lookup (AFI_IP, name); + struct access_list *list; + list = access_list_lookup(AFI_IP, name); - 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 (name); - ospf_schedule_abr_task (ospf); + IMPORT_NAME(area) = strdup(name); + ospf_schedule_abr_task(ospf); - return 1; + return 1; } -int -ospf_area_import_list_unset (struct ospf *ospf, struct ospf_area * area) +int ospf_area_import_list_unset(struct ospf *ospf, struct ospf_area *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; - ospf_area_check_free (ospf, area->area_id); + IMPORT_NAME(area) = NULL; + ospf_area_check_free(ospf, area->area_id); - ospf_schedule_abr_task (ospf); + ospf_schedule_abr_task(ospf); - return 1; + return 1; } -int -ospf_timers_refresh_set (struct ospf *ospf, int interval) +int ospf_timers_refresh_set(struct ospf *ospf, int interval) { - int time_left; + int time_left; - if (ospf->lsa_refresh_interval == interval) - return 1; + if (ospf->lsa_refresh_interval == interval) + return 1; - time_left = ospf->lsa_refresh_interval - - (monotime(NULL) - ospf->lsa_refresher_started); - - if (time_left > interval) - { - OSPF_TIMER_OFF (ospf->t_lsa_refresher); - thread_add_timer(master, ospf_lsa_refresh_walker, ospf, interval, - &ospf->t_lsa_refresher); - } - ospf->lsa_refresh_interval = interval; + time_left = ospf->lsa_refresh_interval + - (monotime(NULL) - ospf->lsa_refresher_started); - return 1; + if (time_left > interval) { + OSPF_TIMER_OFF(ospf->t_lsa_refresher); + thread_add_timer(master, ospf_lsa_refresh_walker, ospf, + interval, &ospf->t_lsa_refresher); + } + ospf->lsa_refresh_interval = interval; + + return 1; } -int -ospf_timers_refresh_unset (struct ospf *ospf) +int ospf_timers_refresh_unset(struct ospf *ospf) { - int time_left; + int time_left; - time_left = ospf->lsa_refresh_interval - - (monotime(NULL) - ospf->lsa_refresher_started); + time_left = ospf->lsa_refresh_interval + - (monotime(NULL) - ospf->lsa_refresher_started); - if (time_left > OSPF_LSA_REFRESH_INTERVAL_DEFAULT) - { - OSPF_TIMER_OFF (ospf->t_lsa_refresher); - ospf->t_lsa_refresher = NULL; - thread_add_timer(master, ospf_lsa_refresh_walker, ospf, OSPF_LSA_REFRESH_INTERVAL_DEFAULT, - &ospf->t_lsa_refresher); - } + if (time_left > OSPF_LSA_REFRESH_INTERVAL_DEFAULT) { + OSPF_TIMER_OFF(ospf->t_lsa_refresher); + ospf->t_lsa_refresher = NULL; + thread_add_timer(master, ospf_lsa_refresh_walker, ospf, + OSPF_LSA_REFRESH_INTERVAL_DEFAULT, + &ospf->t_lsa_refresher); + } - ospf->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT; + ospf->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT; - return 1; + return 1; } -static struct ospf_nbr_nbma * -ospf_nbr_nbma_new (void) +static struct ospf_nbr_nbma *ospf_nbr_nbma_new(void) { - struct ospf_nbr_nbma *nbr_nbma; + struct ospf_nbr_nbma *nbr_nbma; - nbr_nbma = XCALLOC (MTYPE_OSPF_NEIGHBOR_STATIC, - sizeof (struct ospf_nbr_nbma)); + nbr_nbma = XCALLOC(MTYPE_OSPF_NEIGHBOR_STATIC, + sizeof(struct ospf_nbr_nbma)); - nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT; - nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT; + nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT; + nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT; - return nbr_nbma; + return nbr_nbma; } -static void -ospf_nbr_nbma_free (struct ospf_nbr_nbma *nbr_nbma) +static void ospf_nbr_nbma_free(struct ospf_nbr_nbma *nbr_nbma) { - XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma); + XFREE(MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma); } -static void -ospf_nbr_nbma_delete (struct ospf *ospf, struct ospf_nbr_nbma *nbr_nbma) +static void ospf_nbr_nbma_delete(struct ospf *ospf, + struct ospf_nbr_nbma *nbr_nbma) { - struct route_node *rn; - struct prefix_ipv4 p; + struct route_node *rn; + struct prefix_ipv4 p; - p.family = AF_INET; - p.prefix = nbr_nbma->addr; - p.prefixlen = IPV4_MAX_BITLEN; + p.family = AF_INET; + p.prefix = nbr_nbma->addr; + p.prefixlen = IPV4_MAX_BITLEN; - rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p); - if (rn) - { - ospf_nbr_nbma_free (rn->info); - rn->info = NULL; - route_unlock_node (rn); - route_unlock_node (rn); - } + rn = route_node_lookup(ospf->nbr_nbma, (struct prefix *)&p); + if (rn) { + ospf_nbr_nbma_free(rn->info); + rn->info = NULL; + route_unlock_node(rn); + route_unlock_node(rn); + } } -static void -ospf_nbr_nbma_down (struct ospf_nbr_nbma *nbr_nbma) +static void ospf_nbr_nbma_down(struct ospf_nbr_nbma *nbr_nbma) { - OSPF_TIMER_OFF (nbr_nbma->t_poll); + OSPF_TIMER_OFF(nbr_nbma->t_poll); - if (nbr_nbma->nbr) - { - nbr_nbma->nbr->nbr_nbma = NULL; - OSPF_NSM_EVENT_EXECUTE (nbr_nbma->nbr, NSM_KillNbr); - } + if (nbr_nbma->nbr) { + nbr_nbma->nbr->nbr_nbma = NULL; + OSPF_NSM_EVENT_EXECUTE(nbr_nbma->nbr, NSM_KillNbr); + } - if (nbr_nbma->oi) - listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma); + if (nbr_nbma->oi) + listnode_delete(nbr_nbma->oi->nbr_nbma, nbr_nbma); } -static void -ospf_nbr_nbma_add (struct ospf_nbr_nbma *nbr_nbma, - struct ospf_interface *oi) +static void ospf_nbr_nbma_add(struct ospf_nbr_nbma *nbr_nbma, + struct ospf_interface *oi) { - struct ospf_neighbor *nbr; - struct route_node *rn; - struct prefix p; + struct ospf_neighbor *nbr; + struct route_node *rn; + struct prefix p; - if (oi->type != OSPF_IFTYPE_NBMA) - return; + if (oi->type != OSPF_IFTYPE_NBMA) + return; - if (nbr_nbma->nbr != NULL) - return; + if (nbr_nbma->nbr != NULL) + return; - if (IPV4_ADDR_SAME (&oi->nbr_self->address.u.prefix4, &nbr_nbma->addr)) - return; - - nbr_nbma->oi = oi; - listnode_add (oi->nbr_nbma, nbr_nbma); + if (IPV4_ADDR_SAME(&oi->nbr_self->address.u.prefix4, &nbr_nbma->addr)) + return; - /* Get neighbor information from table. */ - p.family = AF_INET; - p.prefixlen = IPV4_MAX_BITLEN; - p.u.prefix4 = nbr_nbma->addr; + nbr_nbma->oi = oi; + listnode_add(oi->nbr_nbma, nbr_nbma); - rn = route_node_get (oi->nbrs, (struct prefix *)&p); - if (rn->info) - { - nbr = rn->info; - nbr->nbr_nbma = nbr_nbma; - nbr_nbma->nbr = nbr; + /* Get neighbor information from table. */ + p.family = AF_INET; + p.prefixlen = IPV4_MAX_BITLEN; + p.u.prefix4 = nbr_nbma->addr; - route_unlock_node (rn); - } - else - { - nbr = rn->info = ospf_nbr_new (oi); - nbr->state = NSM_Down; - nbr->src = nbr_nbma->addr; - nbr->nbr_nbma = nbr_nbma; - nbr->priority = nbr_nbma->priority; - nbr->address = p; + rn = route_node_get(oi->nbrs, (struct prefix *)&p); + if (rn->info) { + nbr = rn->info; + nbr->nbr_nbma = nbr_nbma; + nbr_nbma->nbr = nbr; - nbr_nbma->nbr = nbr; + route_unlock_node(rn); + } else { + nbr = rn->info = ospf_nbr_new(oi); + nbr->state = NSM_Down; + nbr->src = nbr_nbma->addr; + nbr->nbr_nbma = nbr_nbma; + nbr->priority = nbr_nbma->priority; + nbr->address = p; - OSPF_NSM_EVENT_EXECUTE (nbr, NSM_Start); - } + nbr_nbma->nbr = nbr; + + OSPF_NSM_EVENT_EXECUTE(nbr, NSM_Start); + } } -void -ospf_nbr_nbma_if_update (struct ospf *ospf, struct ospf_interface *oi) +void ospf_nbr_nbma_if_update(struct ospf *ospf, struct ospf_interface *oi) { - struct ospf_nbr_nbma *nbr_nbma; - struct route_node *rn; - struct prefix_ipv4 p; + struct ospf_nbr_nbma *nbr_nbma; + struct route_node *rn; + struct prefix_ipv4 p; - if (oi->type != OSPF_IFTYPE_NBMA) - return; + if (oi->type != OSPF_IFTYPE_NBMA) + return; - for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn)) - if ((nbr_nbma = rn->info)) - if (nbr_nbma->oi == NULL && nbr_nbma->nbr == NULL) - { - p.family = AF_INET; - p.prefix = nbr_nbma->addr; - p.prefixlen = IPV4_MAX_BITLEN; + for (rn = route_top(ospf->nbr_nbma); rn; rn = route_next(rn)) + if ((nbr_nbma = rn->info)) + if (nbr_nbma->oi == NULL && nbr_nbma->nbr == NULL) { + p.family = AF_INET; + p.prefix = nbr_nbma->addr; + p.prefixlen = IPV4_MAX_BITLEN; - if (prefix_match (oi->address, (struct prefix *)&p)) - ospf_nbr_nbma_add (nbr_nbma, oi); - } + if (prefix_match(oi->address, + (struct prefix *)&p)) + ospf_nbr_nbma_add(nbr_nbma, oi); + } } -struct ospf_nbr_nbma * -ospf_nbr_nbma_lookup (struct ospf *ospf, struct in_addr nbr_addr) +struct ospf_nbr_nbma *ospf_nbr_nbma_lookup(struct ospf *ospf, + struct in_addr nbr_addr) { - struct route_node *rn; - struct prefix_ipv4 p; + struct route_node *rn; + struct prefix_ipv4 p; - p.family = AF_INET; - p.prefix = nbr_addr; - p.prefixlen = IPV4_MAX_BITLEN; + p.family = AF_INET; + p.prefix = nbr_addr; + p.prefixlen = IPV4_MAX_BITLEN; - rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p); - if (rn) - { - route_unlock_node (rn); - return rn->info; - } - return NULL; + rn = route_node_lookup(ospf->nbr_nbma, (struct prefix *)&p); + if (rn) { + route_unlock_node(rn); + return rn->info; + } + return NULL; } -struct ospf_nbr_nbma * -ospf_nbr_nbma_lookup_next (struct ospf *ospf, struct in_addr *addr, int first) +struct ospf_nbr_nbma *ospf_nbr_nbma_lookup_next(struct ospf *ospf, + struct in_addr *addr, int first) { #if 0 struct ospf_nbr_nbma *nbr_nbma; struct listnode *node; #endif - if (ospf == NULL) - return NULL; + if (ospf == NULL) + return NULL; #if 0 for (ALL_LIST_ELEMENTS_RO (ospf->nbr_nbma, node, nbr_nbma)) @@ -1812,138 +1728,127 @@ ospf_nbr_nbma_lookup_next (struct ospf *ospf, struct in_addr *addr, int first) } } #endif - return NULL; + return NULL; } -int -ospf_nbr_nbma_set (struct ospf *ospf, struct in_addr nbr_addr) +int ospf_nbr_nbma_set(struct ospf *ospf, struct in_addr nbr_addr) { - struct ospf_nbr_nbma *nbr_nbma; - struct ospf_interface *oi; - struct prefix_ipv4 p; - struct route_node *rn; - struct listnode *node; + struct ospf_nbr_nbma *nbr_nbma; + struct ospf_interface *oi; + struct prefix_ipv4 p; + struct route_node *rn; + struct listnode *node; - nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr); - if (nbr_nbma) - return 0; + nbr_nbma = ospf_nbr_nbma_lookup(ospf, nbr_addr); + if (nbr_nbma) + return 0; - nbr_nbma = ospf_nbr_nbma_new (); - nbr_nbma->addr = nbr_addr; + nbr_nbma = ospf_nbr_nbma_new(); + nbr_nbma->addr = nbr_addr; - p.family = AF_INET; - p.prefix = nbr_addr; - p.prefixlen = IPV4_MAX_BITLEN; + p.family = AF_INET; + p.prefix = nbr_addr; + p.prefixlen = IPV4_MAX_BITLEN; - rn = route_node_get (ospf->nbr_nbma, (struct prefix *)&p); - if (rn->info) - route_unlock_node (rn); - rn->info = nbr_nbma; + rn = route_node_get(ospf->nbr_nbma, (struct prefix *)&p); + if (rn->info) + route_unlock_node(rn); + rn->info = nbr_nbma; - for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) - { - if (oi->type == OSPF_IFTYPE_NBMA) - if (prefix_match (oi->address, (struct prefix *)&p)) - { - ospf_nbr_nbma_add (nbr_nbma, oi); - break; - } - } + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) { + if (oi->type == OSPF_IFTYPE_NBMA) + if (prefix_match(oi->address, (struct prefix *)&p)) { + ospf_nbr_nbma_add(nbr_nbma, oi); + break; + } + } - return 1; + return 1; } -int -ospf_nbr_nbma_unset (struct ospf *ospf, struct in_addr nbr_addr) +int ospf_nbr_nbma_unset(struct ospf *ospf, struct in_addr nbr_addr) { - struct ospf_nbr_nbma *nbr_nbma; + struct ospf_nbr_nbma *nbr_nbma; - nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr); - if (nbr_nbma == NULL) - return 0; + nbr_nbma = ospf_nbr_nbma_lookup(ospf, nbr_addr); + if (nbr_nbma == NULL) + return 0; - ospf_nbr_nbma_down (nbr_nbma); - ospf_nbr_nbma_delete (ospf, nbr_nbma); + ospf_nbr_nbma_down(nbr_nbma); + ospf_nbr_nbma_delete(ospf, nbr_nbma); - return 1; + return 1; } -int -ospf_nbr_nbma_priority_set (struct ospf *ospf, struct in_addr nbr_addr, - u_char priority) +int ospf_nbr_nbma_priority_set(struct ospf *ospf, struct in_addr nbr_addr, + u_char priority) { - struct ospf_nbr_nbma *nbr_nbma; + struct ospf_nbr_nbma *nbr_nbma; - nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr); - if (nbr_nbma == NULL) - return 0; + nbr_nbma = ospf_nbr_nbma_lookup(ospf, nbr_addr); + if (nbr_nbma == NULL) + return 0; - if (nbr_nbma->priority != priority) - nbr_nbma->priority = priority; + if (nbr_nbma->priority != priority) + nbr_nbma->priority = priority; - return 1; + return 1; } -int -ospf_nbr_nbma_priority_unset (struct ospf *ospf, struct in_addr nbr_addr) +int ospf_nbr_nbma_priority_unset(struct ospf *ospf, struct in_addr nbr_addr) { - struct ospf_nbr_nbma *nbr_nbma; + struct ospf_nbr_nbma *nbr_nbma; - nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr); - if (nbr_nbma == NULL) - return 0; + nbr_nbma = ospf_nbr_nbma_lookup(ospf, nbr_addr); + if (nbr_nbma == NULL) + return 0; - if (nbr_nbma != OSPF_NEIGHBOR_PRIORITY_DEFAULT) - nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT; + if (nbr_nbma != OSPF_NEIGHBOR_PRIORITY_DEFAULT) + nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT; - return 1; + return 1; } -int -ospf_nbr_nbma_poll_interval_set (struct ospf *ospf, struct in_addr nbr_addr, - unsigned int interval) +int ospf_nbr_nbma_poll_interval_set(struct ospf *ospf, struct in_addr nbr_addr, + unsigned int interval) { - struct ospf_nbr_nbma *nbr_nbma; + struct ospf_nbr_nbma *nbr_nbma; - nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr); - if (nbr_nbma == NULL) - return 0; + nbr_nbma = ospf_nbr_nbma_lookup(ospf, nbr_addr); + if (nbr_nbma == NULL) + return 0; - if (nbr_nbma->v_poll != interval) - { - nbr_nbma->v_poll = interval; - if (nbr_nbma->oi && ospf_if_is_up (nbr_nbma->oi)) - { - OSPF_TIMER_OFF (nbr_nbma->t_poll); - OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer, - nbr_nbma->v_poll); + if (nbr_nbma->v_poll != interval) { + nbr_nbma->v_poll = interval; + if (nbr_nbma->oi && ospf_if_is_up(nbr_nbma->oi)) { + OSPF_TIMER_OFF(nbr_nbma->t_poll); + OSPF_POLL_TIMER_ON(nbr_nbma->t_poll, ospf_poll_timer, + nbr_nbma->v_poll); + } } - } - return 1; + return 1; } -int -ospf_nbr_nbma_poll_interval_unset (struct ospf *ospf, struct in_addr addr) +int ospf_nbr_nbma_poll_interval_unset(struct ospf *ospf, struct in_addr addr) { - struct ospf_nbr_nbma *nbr_nbma; + struct ospf_nbr_nbma *nbr_nbma; - nbr_nbma = ospf_nbr_nbma_lookup (ospf, addr); - if (nbr_nbma == NULL) - return 0; + nbr_nbma = ospf_nbr_nbma_lookup(ospf, addr); + if (nbr_nbma == NULL) + return 0; - if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT) - nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT; + if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT) + nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT; - return 1; + return 1; } -void -ospf_master_init (struct thread_master *master) +void ospf_master_init(struct thread_master *master) { - memset (&ospf_master, 0, sizeof (struct ospf_master)); + memset(&ospf_master, 0, sizeof(struct ospf_master)); - om = &ospf_master; - om->ospf = list_new (); - om->master = master; + om = &ospf_master; + om->ospf = list_new(); + om->master = master; } diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index b93f13728..4142f1a3e 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -49,14 +49,13 @@ #define OSPF_ALLSPFROUTERS 0xe0000005 /* 224.0.0.5 */ #define OSPF_ALLDROUTERS 0xe0000006 /* 224.0.0.6 */ - /* OSPF Authentication Type. */ #define OSPF_AUTH_NULL 0 #define OSPF_AUTH_SIMPLE 1 #define OSPF_AUTH_CRYPTOGRAPHIC 2 /* For Interface authentication setting default */ #define OSPF_AUTH_NOTSET -1 -/* For the consumption and sanity of the command handler */ +/* For the consumption and sanity of the command handler */ /* DO NIOT REMOVE!!! Need to detect whether a value has been given or not in VLink command handlers */ #define OSPF_AUTH_CMD_NOTSEEN -2 @@ -80,75 +79,70 @@ #define OSPF_LS_REFRESH_SHIFT (60 * 15) #define OSPF_LS_REFRESH_JITTER 60 -struct ospf_external -{ - u_short instance; - struct route_table *external_info; +struct ospf_external { + u_short instance; + struct route_table *external_info; }; /* OSPF master for system wide configuration and variables. */ -struct ospf_master -{ - /* OSPF instance. */ - struct list *ospf; +struct ospf_master { + /* OSPF instance. */ + struct list *ospf; - /* OSPF thread master. */ - struct thread_master *master; + /* OSPF thread master. */ + struct thread_master *master; - /* Zebra interface list. */ - struct list *iflist; + /* Zebra interface list. */ + struct list *iflist; - /* Redistributed external information. */ - struct list *external[ZEBRA_ROUTE_MAX + 1]; + /* Redistributed external information. */ + struct list *external[ZEBRA_ROUTE_MAX + 1]; #define EXTERNAL_INFO(E) (E->external_info) - /* Various OSPF global configuration. */ - u_char options; + /* Various OSPF global configuration. */ + u_char options; #define OSPF_MASTER_SHUTDOWN (1 << 0) /* deferred-shutdown */ }; -struct ospf_redist -{ - u_short instance; - - /* Redistribute metric info. */ - struct - { - int type; /* External metric type (E1 or E2). */ - int value; /* Value for static metric (24-bit). - -1 means metric value is not set. */ - } dmetric; - - /* For redistribute route map. */ - struct - { - char *name; - struct route_map *map; - } route_map; /* +1 is for default-information */ +struct ospf_redist { + u_short instance; + + /* Redistribute metric info. */ + struct { + int type; /* External metric type (E1 or E2). */ + int value; /* Value for static metric (24-bit). + -1 means metric value is not set. */ + } dmetric; + + /* For redistribute route map. */ + struct { + char *name; + struct route_map *map; + } route_map; /* +1 is for default-information */ #define ROUTEMAP_NAME(R) (R->route_map.name) #define ROUTEMAP(R) (R->route_map.map) }; /* OSPF instance structure. */ -struct ospf -{ - /* OSPF's running state based on the '[no] router ospf [<instance>]' config. */ - u_char oi_running; +struct ospf { + /* OSPF's running state based on the '[no] router ospf [<instance>]' + * config. */ + u_char oi_running; - /* OSPF instance ID */ - u_short instance; + /* OSPF instance ID */ + u_short instance; - /* OSPF Router ID. */ - struct in_addr router_id; /* Configured automatically. */ - struct in_addr router_id_static; /* Configured manually. */ + /* OSPF Router ID. */ + struct in_addr router_id; /* Configured automatically. */ + struct in_addr router_id_static; /* Configured manually. */ - /* ABR/ASBR internal flags. */ - u_char flags; + /* ABR/ASBR internal flags. */ + u_char flags; #define OSPF_FLAG_ABR 0x0001 #define OSPF_FLAG_ASBR 0x0002 - /* ABR type. */ - u_char abr_type; + /* ABR type. */ + u_char abr_type; #define OSPF_ABR_UNKNOWN 0 #define OSPF_ABR_STAND 1 #define OSPF_ABR_IBM 2 @@ -156,311 +150,320 @@ struct ospf #define OSPF_ABR_SHORTCUT 4 #define OSPF_ABR_DEFAULT OSPF_ABR_CISCO - /* NSSA ABR */ - u_char anyNSSA; /* Bump for every NSSA attached. */ + /* NSSA ABR */ + u_char anyNSSA; /* Bump for every NSSA attached. */ - /* Configured variables. */ - u_char config; + /* Configured variables. */ + u_char config; #define OSPF_RFC1583_COMPATIBLE (1 << 0) #define OSPF_OPAQUE_CAPABLE (1 << 2) #define OSPF_LOG_ADJACENCY_CHANGES (1 << 3) #define OSPF_LOG_ADJACENCY_DETAIL (1 << 4) - /* Opaque-LSA administrative flags. */ - u_char opaque; + /* Opaque-LSA administrative flags. */ + u_char opaque; #define OPAQUE_OPERATION_READY_BIT (1 << 0) - /* RFC3137 stub router. Configured time to stay stub / max-metric */ - unsigned int stub_router_startup_time; /* seconds */ - unsigned int stub_router_shutdown_time; /* seconds */ + /* RFC3137 stub router. Configured time to stay stub / max-metric */ + unsigned int stub_router_startup_time; /* seconds */ + unsigned int stub_router_shutdown_time; /* seconds */ + /* $FRR indent$ */ + /* clang-format off */ #define OSPF_STUB_ROUTER_UNCONFIGURED 0 - u_char stub_router_admin_set; + u_char stub_router_admin_set; #define OSPF_STUB_ROUTER_ADMINISTRATIVE_SET 1 #define OSPF_STUB_ROUTER_ADMINISTRATIVE_UNSET 0 #define OSPF_STUB_MAX_METRIC_SUMMARY_COST 0x00ff0000 - /* LSA timers */ - unsigned int min_ls_interval; /* minimum delay between LSAs (in msec) */ - unsigned int min_ls_arrival; /* minimum interarrival time between LSAs (in msec) */ - - /* 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 */ - - int default_originate; /* Default information originate. */ + /* LSA timers */ + unsigned int min_ls_interval; /* minimum delay between LSAs (in msec) */ + unsigned int min_ls_arrival; /* minimum interarrival time between LSAs + (in msec) */ + + /* 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 */ + + int default_originate; /* Default information originate. */ + /* $FRR indent$ */ + /* clang-format off */ #define DEFAULT_ORIGINATE_NONE 0 #define DEFAULT_ORIGINATE_ZEBRA 1 #define DEFAULT_ORIGINATE_ALWAYS 2 - u_int32_t ref_bandwidth; /* Reference Bandwidth (Kbps). */ - struct route_table *networks; /* OSPF config networks. */ - struct list *vlinks; /* Configured Virtual-Links. */ - struct list *areas; /* OSPF areas. */ - struct route_table *nbr_nbma; - struct ospf_area *backbone; /* Pointer to the Backbone Area. */ - - struct list *oiflist; /* ospf interfaces */ - u_char passive_interface_default; /* passive-interface default */ - - /* LSDB of AS-external-LSAs. */ - struct ospf_lsdb *lsdb; - - /* Flags. */ - int external_origin; /* AS-external-LSA origin flag. */ - int ase_calc; /* ASE calculation flag. */ - - struct list *opaque_lsa_self; /* Type-11 Opaque-LSAs */ - - /* Routing tables. */ - struct route_table *old_table; /* Old routing table. */ - struct route_table *new_table; /* Current routing table. */ - - struct route_table *old_rtrs; /* Old ABR/ASBR RT. */ - struct route_table *new_rtrs; /* New ABR/ASBR RT. */ - - struct route_table *new_external_route; /* New External Route. */ - struct route_table *old_external_route; /* Old External Route. */ - - struct route_table *external_lsas; /* Database of external LSAs, - prefix is LSA's adv. network*/ - - /* Time stamps */ - struct timeval ts_spf; /* SPF calculation time stamp. */ - struct timeval ts_spf_duration; /* Execution time of last SPF */ - - struct route_table *maxage_lsa; /* List of MaxAge LSA for deletion. */ - int redistribute; /* Num of redistributed protocols. */ - - /* Threads. */ - struct thread *t_abr_task; /* ABR task timer. */ - struct thread *t_asbr_check; /* ASBR check timer. */ - struct thread *t_distribute_update; /* Distirbute list update timer. */ - struct thread *t_spf_calc; /* SPF calculation timer. */ - struct thread *t_ase_calc; /* ASE calculation timer. */ - struct thread *t_external_lsa; /* AS-external-LSA origin timer. */ - struct thread *t_opaque_lsa_self; /* Type-11 Opaque-LSAs origin event. */ - - unsigned int maxage_delay; /* Delay on Maxage remover timer, sec */ - struct thread *t_maxage; /* MaxAge LSA remover timer. */ - struct thread *t_maxage_walker; /* MaxAge LSA checking timer. */ - - struct thread *t_deferred_shutdown; /* deferred/stub-router shutdown timer*/ - - struct thread *t_write; + u_int32_t ref_bandwidth; /* Reference Bandwidth (Kbps). */ + struct route_table *networks; /* OSPF config networks. */ + struct list *vlinks; /* Configured Virtual-Links. */ + struct list *areas; /* OSPF areas. */ + struct route_table *nbr_nbma; + struct ospf_area *backbone; /* Pointer to the Backbone Area. */ + + struct list *oiflist; /* ospf interfaces */ + u_char passive_interface_default; /* passive-interface default */ + + /* LSDB of AS-external-LSAs. */ + struct ospf_lsdb *lsdb; + + /* Flags. */ + int external_origin; /* AS-external-LSA origin flag. */ + int ase_calc; /* ASE calculation flag. */ + + struct list *opaque_lsa_self; /* Type-11 Opaque-LSAs */ + + /* Routing tables. */ + struct route_table *old_table; /* Old routing table. */ + struct route_table *new_table; /* Current routing table. */ + + struct route_table *old_rtrs; /* Old ABR/ASBR RT. */ + struct route_table *new_rtrs; /* New ABR/ASBR RT. */ + + struct route_table *new_external_route; /* New External Route. */ + struct route_table *old_external_route; /* Old External Route. */ + + struct route_table *external_lsas; /* Database of external LSAs, + prefix is LSA's adv. network*/ + + /* Time stamps */ + struct timeval ts_spf; /* SPF calculation time stamp. */ + struct timeval ts_spf_duration; /* Execution time of last SPF */ + + struct route_table *maxage_lsa; /* List of MaxAge LSA for deletion. */ + int redistribute; /* Num of redistributed protocols. */ + + /* Threads. */ + struct thread *t_abr_task; /* ABR task timer. */ + struct thread *t_asbr_check; /* ASBR check timer. */ + struct thread *t_distribute_update; /* Distirbute list update timer. */ + struct thread *t_spf_calc; /* SPF calculation timer. */ + struct thread *t_ase_calc; /* ASE calculation timer. */ + struct thread *t_external_lsa; /* AS-external-LSA origin timer. */ + struct thread + *t_opaque_lsa_self; /* Type-11 Opaque-LSAs origin event. */ + + unsigned int maxage_delay; /* Delay on Maxage remover timer, sec */ + struct thread *t_maxage; /* MaxAge LSA remover timer. */ + struct thread *t_maxage_walker; /* MaxAge LSA checking timer. */ + + struct thread + *t_deferred_shutdown; /* deferred/stub-router shutdown timer*/ + + struct thread *t_write; #define OSPF_WRITE_INTERFACE_COUNT_DEFAULT 20 - int write_oi_count; /* Num of packets sent per thread invocation */ - struct thread *t_read; - int fd; - struct stream *ibuf; - struct list *oi_write_q; - - /* Distribute lists out of other route sources. */ - struct - { - char *name; - struct access_list *list; - } dlist[ZEBRA_ROUTE_MAX]; + int write_oi_count; /* Num of packets sent per thread invocation */ + struct thread *t_read; + int fd; + struct stream *ibuf; + struct list *oi_write_q; + + /* Distribute lists out of other route sources. */ + struct { + char *name; + struct access_list *list; + } dlist[ZEBRA_ROUTE_MAX]; #define DISTRIBUTE_NAME(O,T) (O)->dlist[T].name #define DISTRIBUTE_LIST(O,T) (O)->dlist[T].list - /* OSPF redistribute configuration */ - struct list *redist[ZEBRA_ROUTE_MAX + 1]; + /* OSPF redistribute configuration */ + struct list *redist[ZEBRA_ROUTE_MAX + 1]; - /* Redistribute tag info. */ - route_tag_t dtag[ZEBRA_ROUTE_MAX + 1]; //Pending: cant configure as of now + /* Redistribute tag info. */ + route_tag_t + dtag[ZEBRA_ROUTE_MAX + 1]; // Pending: cant configure as of now - int default_metric; /* Default metric for redistribute. */ + int default_metric; /* Default metric for redistribute. */ #define OSPF_LSA_REFRESHER_GRANULARITY 10 -#define OSPF_LSA_REFRESHER_SLOTS ((OSPF_LS_REFRESH_TIME + \ - OSPF_LS_REFRESH_SHIFT)/OSPF_LSA_REFRESHER_GRANULARITY + 1) - struct - { - u_int16_t index; - struct list *qs[OSPF_LSA_REFRESHER_SLOTS]; - } lsa_refresh_queue; - - struct thread *t_lsa_refresher; - time_t lsa_refresher_started; +#define OSPF_LSA_REFRESHER_SLOTS \ + ((OSPF_LS_REFRESH_TIME + OSPF_LS_REFRESH_SHIFT) \ + / OSPF_LSA_REFRESHER_GRANULARITY \ + + 1) + struct { + u_int16_t index; + struct list *qs[OSPF_LSA_REFRESHER_SLOTS]; + } lsa_refresh_queue; + + struct thread *t_lsa_refresher; + time_t lsa_refresher_started; #define OSPF_LSA_REFRESH_INTERVAL_DEFAULT 10 - u_int16_t lsa_refresh_interval; - - /* Distance parameter. */ - u_char distance_all; - u_char distance_intra; - u_char distance_inter; - u_char distance_external; - - /* Statistics for LSA origination. */ - u_int32_t lsa_originate_count; - - /* Statistics for LSA used for new instantiation. */ - u_int32_t rx_lsa_count; - - /* Counter of "ip ospf area x.x.x.x" */ - u_int32_t if_ospf_cli_count; - - struct route_table *distance_table; - - QOBJ_FIELDS + u_int16_t lsa_refresh_interval; + + /* Distance parameter. */ + u_char distance_all; + u_char distance_intra; + u_char distance_inter; + u_char distance_external; + + /* Statistics for LSA origination. */ + u_int32_t lsa_originate_count; + + /* Statistics for LSA used for new instantiation. */ + u_int32_t rx_lsa_count; + + /* Counter of "ip ospf area x.x.x.x" */ + u_int32_t if_ospf_cli_count; + + struct route_table *distance_table; + + QOBJ_FIELDS }; DECLARE_QOBJ_TYPE(ospf) /* OSPF area structure. */ -struct ospf_area -{ - /* OSPF instance. */ - struct ospf *ospf; +struct ospf_area { + /* OSPF instance. */ + struct ospf *ospf; - /* Zebra interface list belonging to the area. */ - struct list *oiflist; + /* Zebra interface list belonging to the area. */ + struct list *oiflist; - /* Area ID. */ - struct in_addr area_id; + /* Area ID. */ + struct in_addr area_id; - /* Area ID format. */ - int area_id_fmt; + /* Area ID format. */ + int area_id_fmt; #define OSPF_AREA_ID_FMT_DOTTEDQUAD 1 #define OSPF_AREA_ID_FMT_DECIMAL 2 - /* Address range. */ - struct list *address_range; + /* Address range. */ + struct list *address_range; - /* Configured variables. */ - int external_routing; /* ExternalRoutingCapability. */ - int no_summary; /* Don't inject summaries into stub.*/ - int shortcut_configured; /* Area configured as shortcut. */ + /* Configured variables. */ + int external_routing; /* ExternalRoutingCapability. */ + int no_summary; /* Don't inject summaries into stub.*/ + int shortcut_configured; /* Area configured as shortcut. */ + /* $FRR indent$ */ + /* clang-format off */ #define OSPF_SHORTCUT_DEFAULT 0 #define OSPF_SHORTCUT_ENABLE 1 #define OSPF_SHORTCUT_DISABLE 2 - int shortcut_capability; /* Other ABRs agree on S-bit */ - u_int32_t default_cost; /* StubDefaultCost. */ - int auth_type; /* Authentication type. */ - + int shortcut_capability; /* Other ABRs agree on S-bit */ + u_int32_t default_cost; /* StubDefaultCost. */ + int auth_type; /* Authentication type. */ - u_char NSSATranslatorRole; /* NSSA configured role */ + + u_char NSSATranslatorRole; /* NSSA configured role */ + /* $FRR indent$ */ + /* clang-format off */ #define OSPF_NSSA_ROLE_NEVER 0 #define OSPF_NSSA_ROLE_CANDIDATE 1 #define OSPF_NSSA_ROLE_ALWAYS 2 - u_char NSSATranslatorState; /* NSSA operational role */ + u_char NSSATranslatorState; /* NSSA operational role */ + /* $FRR indent$ */ + /* clang-format off */ #define OSPF_NSSA_TRANSLATE_DISABLED 0 #define OSPF_NSSA_TRANSLATE_ENABLED 1 - int NSSATranslatorStabilityInterval; - - u_char transit; /* TransitCapability. */ + int NSSATranslatorStabilityInterval; + + u_char transit; /* TransitCapability. */ + /* $FRR indent$ */ + /* clang-format off */ #define OSPF_TRANSIT_FALSE 0 #define OSPF_TRANSIT_TRUE 1 - struct route_table *ranges; /* Configured Area Ranges. */ - - /* RFC3137 stub router state flags for area */ - u_char stub_router_state; + struct route_table *ranges; /* Configured Area Ranges. */ + + /* RFC3137 stub router state flags for area */ + u_char stub_router_state; #define OSPF_AREA_ADMIN_STUB_ROUTED (1 << 0) /* admin stub-router set */ #define OSPF_AREA_IS_STUB_ROUTED (1 << 1) /* stub-router active */ #define OSPF_AREA_WAS_START_STUB_ROUTED (1 << 2) /* startup SR was done */ - - /* Area related LSDBs[Type1-4]. */ - struct ospf_lsdb *lsdb; - - /* Self-originated LSAs. */ - struct ospf_lsa *router_lsa_self; - struct list *opaque_lsa_self; /* Type-10 Opaque-LSAs */ - - /* Area announce list. */ - struct - { - char *name; - struct access_list *list; - } _export; + /* Area related LSDBs[Type1-4]. */ + struct ospf_lsdb *lsdb; + + /* Self-originated LSAs. */ + struct ospf_lsa *router_lsa_self; + struct list *opaque_lsa_self; /* Type-10 Opaque-LSAs */ + + /* 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_LIST_IN(A) (A)->plist_in.list #define PREFIX_NAME_IN(A) (A)->plist_in.name - struct - { - char *name; - struct prefix_list *list; - } plist_out; + struct { + char *name; + struct prefix_list *list; + } plist_out; #define PREFIX_LIST_OUT(A) (A)->plist_out.list #define PREFIX_NAME_OUT(A) (A)->plist_out.name - /* Shortest Path Tree. */ - struct vertex *spf; + /* Shortest Path Tree. */ + struct vertex *spf; - /* Threads. */ - struct thread *t_stub_router; /* Stub-router timer */ - struct thread *t_opaque_lsa_self; /* Type-10 Opaque-LSAs origin. */ + /* Threads. */ + struct thread *t_stub_router; /* Stub-router timer */ + struct thread *t_opaque_lsa_self; /* Type-10 Opaque-LSAs origin. */ - /* Statistics field. */ - u_int32_t spf_calculation; /* SPF Calculation Count. */ + /* Statistics field. */ + u_int32_t spf_calculation; /* SPF Calculation Count. */ - /* Time stamps. */ - struct timeval ts_spf; /* SPF calculation time stamp. */ + /* Time stamps. */ + struct timeval ts_spf; /* SPF calculation time stamp. */ - /* Router count. */ - u_int32_t abr_count; /* ABR router in this area. */ - u_int32_t asbr_count; /* ASBR router in this area. */ + /* Router count. */ + u_int32_t abr_count; /* ABR router in this area. */ + u_int32_t asbr_count; /* ASBR router in this area. */ - /* Counters. */ - u_int32_t act_ints; /* Active interfaces. */ - u_int32_t full_nbrs; /* Fully adjacent neighbors. */ - u_int32_t full_vls; /* Fully adjacent virtual neighbors. */ + /* Counters. */ + u_int32_t act_ints; /* Active interfaces. */ + u_int32_t full_nbrs; /* Fully adjacent neighbors. */ + u_int32_t full_vls; /* Fully adjacent virtual neighbors. */ }; /* OSPF config network structure. */ -struct ospf_network -{ - /* Area ID. */ - struct in_addr area_id; - int area_id_fmt; +struct ospf_network { + /* Area ID. */ + struct in_addr area_id; + int area_id_fmt; }; /* OSPF NBMA neighbor structure. */ -struct ospf_nbr_nbma -{ - /* Neighbor IP address. */ - struct in_addr addr; +struct ospf_nbr_nbma { + /* Neighbor IP address. */ + struct in_addr addr; - /* OSPF interface. */ - struct ospf_interface *oi; + /* OSPF interface. */ + struct ospf_interface *oi; - /* OSPF neighbor structure. */ - struct ospf_neighbor *nbr; + /* OSPF neighbor structure. */ + struct ospf_neighbor *nbr; - /* Neighbor priority. */ - u_char priority; + /* Neighbor priority. */ + u_char priority; - /* Poll timer value. */ - u_int32_t v_poll; + /* Poll timer value. */ + u_int32_t v_poll; - /* Poll timer thread. */ - struct thread *t_poll; + /* Poll timer thread. */ + struct thread *t_poll; - /* State change. */ - u_int32_t state_change; + /* State change. */ + u_int32_t state_change; }; /* Macro. */ -#define OSPF_AREA_SAME(X,Y) \ - (memcmp ((X->area_id), (Y->area_id), IPV4_MAX_BYTELEN) == 0) +#define OSPF_AREA_SAME(X, Y) \ + (memcmp((X->area_id), (Y->area_id), IPV4_MAX_BYTELEN) == 0) #define IS_OSPF_ABR(O) ((O)->flags & OSPF_FLAG_ABR) #define IS_OSPF_ASBR(O) ((O)->flags & OSPF_FLAG_ASBR) @@ -470,27 +473,26 @@ struct ospf_nbr_nbma #ifdef roundup # define ROUNDUP(val, gran) roundup(val, gran) -#else /* roundup */ +#else /* roundup */ # define ROUNDUP(val, gran) (((val) - 1 | (gran) - 1) + 1) #endif /* roundup */ -#define LSA_OPTIONS_GET(area) \ - (((area)->external_routing == OSPF_AREA_DEFAULT) ? OSPF_OPTION_E : 0) -#define LSA_OPTIONS_NSSA_GET(area) \ - (((area)->external_routing == OSPF_AREA_NSSA) ? OSPF_OPTION_NP : 0) +#define LSA_OPTIONS_GET(area) \ + (((area)->external_routing == OSPF_AREA_DEFAULT) ? OSPF_OPTION_E : 0) +#define LSA_OPTIONS_NSSA_GET(area) \ + (((area)->external_routing == OSPF_AREA_NSSA) ? OSPF_OPTION_NP : 0) #define OSPF_TIMER_ON(T,F,V) thread_add_timer (master,(F),ospf,(V),&(T)) #define OSPF_AREA_TIMER_ON(T,F,V) thread_add_timer (master, (F), area, (V), &(T)) #define OSPF_POLL_TIMER_ON(T,F,V) thread_add_timer (master, (F), nbr_nbma, (V), &(T)) #define OSPF_POLL_TIMER_OFF(X) OSPF_TIMER_OFF((X)) -#define OSPF_TIMER_OFF(X) \ - do { \ - if (X) \ - { \ - thread_cancel (X); \ - (X) = NULL; \ - } \ - } while (0) +#define OSPF_TIMER_OFF(X) \ + do { \ + if (X) { \ + thread_cancel(X); \ + (X) = NULL; \ + } \ + } while (0) /* Extern variables. */ extern struct ospf_master *om; @@ -501,68 +503,67 @@ extern int ospf_zlog; /* Prototypes. */ extern const char *ospf_redist_string(u_int route_type); -extern struct ospf *ospf_lookup (void); -extern struct ospf *ospf_lookup_instance (u_short); -extern struct ospf *ospf_get (void); -extern struct ospf *ospf_get_instance (u_short); -extern void ospf_finish (struct ospf *); -extern void ospf_router_id_update (struct ospf *ospf); -extern int ospf_network_set (struct ospf *, struct prefix_ipv4 *, - struct in_addr, int); -extern int ospf_network_unset (struct ospf *, struct prefix_ipv4 *, - struct in_addr); -extern int ospf_area_display_format_set (struct ospf *, struct ospf_area *area, - int df); -extern int ospf_area_stub_set (struct ospf *, struct in_addr); -extern int ospf_area_stub_unset (struct ospf *, struct in_addr); -extern int ospf_area_no_summary_set (struct ospf *, struct in_addr); -extern int ospf_area_no_summary_unset (struct ospf *, struct in_addr); -extern int ospf_area_nssa_set (struct ospf *, struct in_addr); -extern int ospf_area_nssa_unset (struct ospf *, struct in_addr); -extern int ospf_area_nssa_translator_role_set (struct ospf *, struct in_addr, - int); -extern int ospf_area_export_list_set (struct ospf *, struct ospf_area *, - const char *); -extern int ospf_area_export_list_unset (struct ospf *, struct ospf_area *); -extern int ospf_area_import_list_set (struct ospf *, struct ospf_area *, - const char *); -extern int ospf_area_import_list_unset (struct ospf *, struct ospf_area *); -extern int ospf_area_shortcut_set (struct ospf *, struct ospf_area *, int); -extern int ospf_area_shortcut_unset (struct ospf *, struct ospf_area *); -extern int ospf_timers_refresh_set (struct ospf *, int); -extern int ospf_timers_refresh_unset (struct ospf *); -extern int ospf_nbr_nbma_set (struct ospf *, struct in_addr); -extern int ospf_nbr_nbma_unset (struct ospf *, struct in_addr); -extern int ospf_nbr_nbma_priority_set (struct ospf *, struct in_addr, u_char); -extern int ospf_nbr_nbma_priority_unset (struct ospf *, struct in_addr); -extern int ospf_nbr_nbma_poll_interval_set (struct ospf *, struct in_addr, - unsigned int); -extern int ospf_nbr_nbma_poll_interval_unset (struct ospf *, struct in_addr); -extern void ospf_prefix_list_update (struct prefix_list *); -extern void ospf_init (void); -extern void ospf_if_update (struct ospf *, struct interface *); -extern void ospf_ls_upd_queue_empty (struct ospf_interface *); -extern void ospf_terminate (void); -extern void ospf_nbr_nbma_if_update (struct ospf *, struct ospf_interface *); -extern struct ospf_nbr_nbma *ospf_nbr_nbma_lookup (struct ospf *, - struct in_addr); -extern struct ospf_nbr_nbma *ospf_nbr_nbma_lookup_next (struct ospf *, - struct in_addr *, - int); -extern int ospf_oi_count (struct interface *); - -extern struct ospf_area *ospf_area_get (struct ospf *, struct in_addr); -extern void ospf_area_check_free (struct ospf *, struct in_addr); -extern struct ospf_area *ospf_area_lookup_by_area_id (struct ospf *, - struct in_addr); -extern void ospf_area_add_if (struct ospf_area *, struct ospf_interface *); -extern void ospf_area_del_if (struct ospf_area *, struct ospf_interface *); - -extern void ospf_interface_area_set (struct interface *); -extern void ospf_interface_area_unset (struct interface *); - -extern void ospf_route_map_init (void); - -extern void ospf_master_init (struct thread_master *master); +extern struct ospf *ospf_lookup(void); +extern struct ospf *ospf_lookup_instance(u_short); +extern struct ospf *ospf_get(void); +extern struct ospf *ospf_get_instance(u_short); +extern void ospf_finish(struct ospf *); +extern void ospf_router_id_update(struct ospf *ospf); +extern int ospf_network_set(struct ospf *, struct prefix_ipv4 *, struct in_addr, + int); +extern int ospf_network_unset(struct ospf *, struct prefix_ipv4 *, + struct in_addr); +extern int ospf_area_display_format_set(struct ospf *, struct ospf_area *area, + int df); +extern int ospf_area_stub_set(struct ospf *, struct in_addr); +extern int ospf_area_stub_unset(struct ospf *, struct in_addr); +extern int ospf_area_no_summary_set(struct ospf *, struct in_addr); +extern int ospf_area_no_summary_unset(struct ospf *, struct in_addr); +extern int ospf_area_nssa_set(struct ospf *, struct in_addr); +extern int ospf_area_nssa_unset(struct ospf *, struct in_addr); +extern int ospf_area_nssa_translator_role_set(struct ospf *, struct in_addr, + int); +extern int ospf_area_export_list_set(struct ospf *, struct ospf_area *, + const char *); +extern int ospf_area_export_list_unset(struct ospf *, struct ospf_area *); +extern int ospf_area_import_list_set(struct ospf *, struct ospf_area *, + const char *); +extern int ospf_area_import_list_unset(struct ospf *, struct ospf_area *); +extern int ospf_area_shortcut_set(struct ospf *, struct ospf_area *, int); +extern int ospf_area_shortcut_unset(struct ospf *, struct ospf_area *); +extern int ospf_timers_refresh_set(struct ospf *, int); +extern int ospf_timers_refresh_unset(struct ospf *); +extern int ospf_nbr_nbma_set(struct ospf *, struct in_addr); +extern int ospf_nbr_nbma_unset(struct ospf *, struct in_addr); +extern int ospf_nbr_nbma_priority_set(struct ospf *, struct in_addr, u_char); +extern int ospf_nbr_nbma_priority_unset(struct ospf *, struct in_addr); +extern int ospf_nbr_nbma_poll_interval_set(struct ospf *, struct in_addr, + unsigned int); +extern int ospf_nbr_nbma_poll_interval_unset(struct ospf *, struct in_addr); +extern void ospf_prefix_list_update(struct prefix_list *); +extern void ospf_init(void); +extern void ospf_if_update(struct ospf *, struct interface *); +extern void ospf_ls_upd_queue_empty(struct ospf_interface *); +extern void ospf_terminate(void); +extern void ospf_nbr_nbma_if_update(struct ospf *, struct ospf_interface *); +extern struct ospf_nbr_nbma *ospf_nbr_nbma_lookup(struct ospf *, + struct in_addr); +extern struct ospf_nbr_nbma *ospf_nbr_nbma_lookup_next(struct ospf *, + struct in_addr *, int); +extern int ospf_oi_count(struct interface *); + +extern struct ospf_area *ospf_area_get(struct ospf *, struct in_addr); +extern void ospf_area_check_free(struct ospf *, struct in_addr); +extern struct ospf_area *ospf_area_lookup_by_area_id(struct ospf *, + struct in_addr); +extern void ospf_area_add_if(struct ospf_area *, struct ospf_interface *); +extern void ospf_area_del_if(struct ospf_area *, struct ospf_interface *); + +extern void ospf_interface_area_set(struct interface *); +extern void ospf_interface_area_unset(struct interface *); + +extern void ospf_route_map_init(void); + +extern void ospf_master_init(struct thread_master *master); #endif /* _ZEBRA_OSPFD_H */ |