frr/ospfd/ospf_abr.c

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

1858 lines
47 KiB
C
Raw Normal View History

2002-12-13 21:15:29 +01:00
/*
* OSPF ABR functions.
* Copyright (C) 1999, 2000 Alex Zinin, Toshiaki Takada
*
* This file is part of GNU Zebra.
*
* GNU Zebra is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
2002-12-13 21:15:29 +01:00
* GNU Zebra is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; see the file COPYING; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2002-12-13 21:15:29 +01:00
*/
#include <zebra.h>
#include "thread.h"
#include "memory.h"
#include "linklist.h"
#include "prefix.h"
#include "if.h"
#include "table.h"
#include "vty.h"
#include "filter.h"
#include "plist.h"
#include "log.h"
#include "ospfd/ospfd.h"
#include "ospfd/ospf_interface.h"
#include "ospfd/ospf_ism.h"
#include "ospfd/ospf_asbr.h"
#include "ospfd/ospf_lsa.h"
#include "ospfd/ospf_lsdb.h"
#include "ospfd/ospf_neighbor.h"
#include "ospfd/ospf_nsm.h"
#include "ospfd/ospf_spf.h"
#include "ospfd/ospf_route.h"
#include "ospfd/ospf_ia.h"
#include "ospfd/ospf_flood.h"
#include "ospfd/ospf_abr.h"
#include "ospfd/ospf_ase.h"
#include "ospfd/ospf_zebra.h"
#include "ospfd/ospf_dump.h"
#include "ospfd/ospf_errors.h"
2002-12-13 21:15:29 +01:00
static struct ospf_area_range *ospf_area_range_new(struct prefix_ipv4 *p)
{
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;
return range;
}
static void ospf_area_range_free(struct 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)
{
struct route_node *rn;
struct prefix_ipv4 p;
2002-12-13 21:15:29 +01:00
p.family = AF_INET;
p.prefixlen = range->masklen;
p.prefix = range->addr;
apply_mask_ipv4(&p);
2002-12-13 21:15:29 +01:00
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)
2002-12-13 21:15:29 +01:00
{
struct ospf_area_range *range = rn->info;
2002-12-13 21:15:29 +01:00
if (range->specifics != 0)
ospf_delete_discard_route(area->ospf, area->ospf->new_table,
(struct prefix_ipv4 *)&rn->p);
2002-12-13 21:15:29 +01:00
ospf_area_range_free(range);
rn->info = NULL;
route_unlock_node(rn);
route_unlock_node(rn);
2002-12-13 21:15:29 +01:00
}
struct ospf_area_range *ospf_area_range_lookup(struct ospf_area *area,
struct prefix_ipv4 *p)
{
struct route_node *rn;
2002-12-13 21:15:29 +01:00
rn = route_node_lookup(area->ranges, (struct prefix *)p);
if (rn) {
route_unlock_node(rn);
return rn->info;
}
return NULL;
}
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
struct ospf_area_range *ospf_area_range_lookup_next(struct ospf_area *area,
struct in_addr *range_net,
int first)
2002-12-13 21:15:29 +01:00
{
struct route_node *rn;
struct prefix_ipv4 p;
struct ospf_area_range *find;
2002-12-13 21:15:29 +01:00
p.family = AF_INET;
p.prefixlen = IPV4_MAX_BITLEN;
p.prefix = *range_net;
apply_mask_ipv4(&p);
2002-12-13 21:15:29 +01:00
if (first)
rn = route_top(area->ranges);
else {
rn = route_node_get(area->ranges, (struct prefix *)&p);
rn = route_next(rn);
}
2002-12-13 21:15:29 +01:00
for (; rn; rn = route_next(rn))
if (rn->info)
break;
2002-12-13 21:15:29 +01:00
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)
{
struct route_node *node;
2002-12-13 21:15:29 +01:00
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 *range;
struct ospf_area *area;
struct listnode *node;
2002-12-13 21:15:29 +01:00
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
if ((range = ospf_area_range_match(area, p)))
2002-12-13 21:15:29 +01:00
return range;
return NULL;
}
int ospf_area_range_active(struct ospf_area_range *range)
{
return range->specifics;
}
static int ospf_area_actively_attached(struct ospf_area *area)
{
return area->act_ints;
}
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);
2002-12-13 21:15:29 +01:00
if (area == NULL)
return 0;
2002-12-13 21:15:29 +01:00
range = ospf_area_range_lookup(area, p);
if (range != NULL) {
ospfd: handling of OSPF_AREA_RANGE_ADVERTISE flag Issue: # https://github.com/FRRouting/frr/issues/1836 Issue 1: if the router ospf current configuration is "area 0.0.0.2 range 1.0.0.0/24 cost 23" and user try to configure "area 0.0.0.2 range 1.0.0.0/24 not-advertise", the existing o/p is "area 0.0.0.2 range 1.0.0.0/24 cost 23 not-advertise". The keywords "not-advertise" & "cost" are multually exclusive, so they should not come together. The vice versa way configuration is working fine. Fix: When ospf area range "not-advertise", the cost should be initialized to OSPF_AREA_RANGE_COST_UNSPEC. Issue 2: if the router ospf current configuration "area 0.0.0.2 range 1.0.0.0/24 substitute 2.0.0.0/24" and user try to configure "area 0.0.0.2 range 1.0.0.0/24 not-advertise" the existing o/p is "area 0.0.0.2 range 1.0.0.0/24 not-advertise substitute 2.0.0.0/24". The keywords "not-advertise" & "substiture" are multually exclusive, so they should not come together. The vice versa way configuration is working fine. Fix: When ospf area range "not-advertise" is configured, ospf_area_range_substitute_unset() should be get called. Issue 3: if the router ospf6 current configuration is "area 0.0.0.2 range 2001::/64 cost 23" and user try to configure "area 0.0.0.2 range 2001::/64 advertise", the existing o/p is area 0.0.0.2 range 2001::/64. The keyword "cost 23" disappears. Fix: When ospf area range "advertise" is configured and the range is not NULL, the cost should not be modified. Signed-off-by: Sarita Patra <saritap@vmware.com>
2018-09-25 06:44:23 +02:00
if (!CHECK_FLAG(advertise, OSPF_AREA_RANGE_ADVERTISE))
range->cost_config = OSPF_AREA_RANGE_COST_UNSPEC;
2002-12-13 21:15:29 +01:00
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);
2002-12-13 21:15:29 +01:00
} else {
range = ospf_area_range_new(p);
ospf_area_range_add(area, range);
ospf_schedule_abr_task(ospf);
2002-12-13 21:15:29 +01:00
}
2002-12-13 21:15:29 +01:00
if (CHECK_FLAG(advertise, OSPF_AREA_RANGE_ADVERTISE))
SET_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE);
ospfd: handling of OSPF_AREA_RANGE_ADVERTISE flag Issue: # https://github.com/FRRouting/frr/issues/1836 Issue 1: if the router ospf current configuration is "area 0.0.0.2 range 1.0.0.0/24 cost 23" and user try to configure "area 0.0.0.2 range 1.0.0.0/24 not-advertise", the existing o/p is "area 0.0.0.2 range 1.0.0.0/24 cost 23 not-advertise". The keywords "not-advertise" & "cost" are multually exclusive, so they should not come together. The vice versa way configuration is working fine. Fix: When ospf area range "not-advertise", the cost should be initialized to OSPF_AREA_RANGE_COST_UNSPEC. Issue 2: if the router ospf current configuration "area 0.0.0.2 range 1.0.0.0/24 substitute 2.0.0.0/24" and user try to configure "area 0.0.0.2 range 1.0.0.0/24 not-advertise" the existing o/p is "area 0.0.0.2 range 1.0.0.0/24 not-advertise substitute 2.0.0.0/24". The keywords "not-advertise" & "substiture" are multually exclusive, so they should not come together. The vice versa way configuration is working fine. Fix: When ospf area range "not-advertise" is configured, ospf_area_range_substitute_unset() should be get called. Issue 3: if the router ospf6 current configuration is "area 0.0.0.2 range 2001::/64 cost 23" and user try to configure "area 0.0.0.2 range 2001::/64 advertise", the existing o/p is area 0.0.0.2 range 2001::/64. The keyword "cost 23" disappears. Fix: When ospf area range "advertise" is configured and the range is not NULL, the cost should not be modified. Signed-off-by: Sarita Patra <saritap@vmware.com>
2018-09-25 06:44:23 +02:00
else {
2002-12-13 21:15:29 +01:00
UNSET_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE);
ospfd: handling of OSPF_AREA_RANGE_ADVERTISE flag Issue: # https://github.com/FRRouting/frr/issues/1836 Issue 1: if the router ospf current configuration is "area 0.0.0.2 range 1.0.0.0/24 cost 23" and user try to configure "area 0.0.0.2 range 1.0.0.0/24 not-advertise", the existing o/p is "area 0.0.0.2 range 1.0.0.0/24 cost 23 not-advertise". The keywords "not-advertise" & "cost" are multually exclusive, so they should not come together. The vice versa way configuration is working fine. Fix: When ospf area range "not-advertise", the cost should be initialized to OSPF_AREA_RANGE_COST_UNSPEC. Issue 2: if the router ospf current configuration "area 0.0.0.2 range 1.0.0.0/24 substitute 2.0.0.0/24" and user try to configure "area 0.0.0.2 range 1.0.0.0/24 not-advertise" the existing o/p is "area 0.0.0.2 range 1.0.0.0/24 not-advertise substitute 2.0.0.0/24". The keywords "not-advertise" & "substiture" are multually exclusive, so they should not come together. The vice versa way configuration is working fine. Fix: When ospf area range "not-advertise" is configured, ospf_area_range_substitute_unset() should be get called. Issue 3: if the router ospf6 current configuration is "area 0.0.0.2 range 2001::/64 cost 23" and user try to configure "area 0.0.0.2 range 2001::/64 advertise", the existing o/p is area 0.0.0.2 range 2001::/64. The keyword "cost 23" disappears. Fix: When ospf area range "advertise" is configured and the range is not NULL, the cost should not be modified. Signed-off-by: Sarita Patra <saritap@vmware.com>
2018-09-25 06:44:23 +02:00
range->cost_config = OSPF_AREA_RANGE_COST_UNSPEC;
}
2002-12-13 21:15:29 +01:00
return 1;
}
int ospf_area_range_cost_set(struct ospf *ospf, struct in_addr area_id,
struct prefix_ipv4 *p, uint32_t cost)
2002-12-13 21:15:29 +01:00
{
struct ospf_area *area;
struct ospf_area_range *range;
area = ospf_area_get(ospf, area_id);
2002-12-13 21:15:29 +01:00
if (area == NULL)
return 0;
range = ospf_area_range_lookup(area, p);
2002-12-13 21:15:29 +01:00
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);
2002-12-13 21:15:29 +01:00
}
return 1;
}
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;
2002-12-13 21:15:29 +01:00
area = ospf_area_lookup_by_area_id(ospf, area_id);
2002-12-13 21:15:29 +01:00
if (area == NULL)
return 0;
rn = route_node_lookup(area->ranges, (struct prefix *)p);
if (rn == NULL)
2002-12-13 21:15:29 +01:00
return 0;
if (ospf_area_range_active(rn->info))
ospf_schedule_abr_task(ospf);
2002-12-13 21:15:29 +01:00
ospf_area_range_delete(area, rn);
2002-12-13 21:15:29 +01:00
return 1;
}
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);
2002-12-13 21:15:29 +01:00
range = ospf_area_range_lookup(area, p);
2002-12-13 21:15:29 +01:00
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);
2002-12-13 21:15:29 +01:00
} else {
range = ospf_area_range_new(p);
ospf_area_range_add(area, range);
ospf_schedule_abr_task(ospf);
2002-12-13 21:15:29 +01:00
}
2002-12-13 21:15:29 +01:00
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;
2002-12-13 21:15:29 +01:00
return 1;
}
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;
area = ospf_area_lookup_by_area_id(ospf, area_id);
2002-12-13 21:15:29 +01:00
if (area == 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);
2002-12-13 21:15:29 +01:00
UNSET_FLAG(range->flags, OSPF_AREA_RANGE_SUBSTITUTE);
range->subst_addr.s_addr = INADDR_ANY;
2002-12-13 21:15:29 +01:00
range->subst_masklen = 0;
return 1;
}
int ospf_act_bb_connection(struct ospf *ospf)
2002-12-13 21:15:29 +01:00
{
struct ospf_interface *oi;
struct listnode *node;
int full_nbrs = 0;
if (ospf->backbone == NULL)
2002-12-13 21:15:29 +01:00
return 0;
for (ALL_LIST_ELEMENTS_RO(ospf->backbone->oiflist, node, oi)) {
struct ospf_neighbor *nbr;
struct route_node *rn;
for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
nbr = rn->info;
if (!nbr)
continue;
if (nbr->state == NSM_Full
|| OSPF_GR_IS_ACTIVE_HELPER(nbr))
full_nbrs++;
}
}
return full_nbrs;
2002-12-13 21:15:29 +01:00
}
/* Determine whether this router is elected translator or not for 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;
char buf[PREFIX_STRLEN];
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 %pI4 asserts Nt",
&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_ntop(AF_INET, best, buf, sizeof(buf)) :
"<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
*/
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)) {
uint8_t 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 %pI4",
&area->area_id);
if (!IS_OSPF_ABR(area->ospf)) {
if (IS_DEBUG_OSPF(nssa, NSSA))
zlog_debug(
"ospf_abr_nssa_check_status: not ABR");
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
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);
}
}
}
2002-12-13 21:15:29 +01:00
/* Check area border router status. */
void ospf_check_abr_status(struct ospf *ospf)
2002-12-13 21:15:29 +01:00
{
struct ospf_area *area;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
int bb_configured = 0;
int bb_act_attached = 0;
int areas_configured = 0;
int areas_act_attached = 0;
uint8_t new_flags = ospf->flags;
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_check_abr_status(): Start");
for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) {
2002-12-13 21:15:29 +01:00
if (listcount(area->oiflist)) {
areas_configured++;
2002-12-13 21:15:29 +01:00
if (OSPF_IS_AREA_BACKBONE(area))
bb_configured = 1;
}
2002-12-13 21:15:29 +01:00
if (ospf_area_actively_attached(area)) {
areas_act_attached++;
2002-12-13 21:15:29 +01:00
if (OSPF_IS_AREA_BACKBONE(area))
bb_act_attached = 1;
}
2002-12-13 21:15:29 +01:00
}
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",
2002-12-13 21:15:29 +01:00
bb_act_attached);
zlog_debug("ospf_check_abr_status(): areas_configured: %d",
2002-12-13 21:15:29 +01:00
areas_configured);
zlog_debug("ospf_check_abr_status(): areas_act_attached: %d",
2002-12-13 21:15:29 +01:00
areas_act_attached);
}
2002-12-13 21:15:29 +01:00
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;
2002-12-13 21:15:29 +01:00
case OSPF_ABR_IBM:
if ((areas_act_attached > 1) && bb_configured)
SET_FLAG(new_flags, OSPF_FLAG_ABR);
else
2002-12-13 21:15:29 +01:00
UNSET_FLAG(new_flags, OSPF_FLAG_ABR);
break;
2002-12-13 21:15:29 +01:00
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:
2002-12-13 21:15:29 +01:00
break;
}
2002-12-13 21:15:29 +01:00
if (new_flags != ospf->flags) {
ospf_spf_calculate_schedule(ospf, SPF_FLAG_ABR_STATUS_CHANGE);
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
2002-12-13 21:15:29 +01:00
"ospf_check_abr_status(): new router flags: %x",
new_flags);
2002-12-13 21:15:29 +01:00
ospf->flags = new_flags;
ospf_router_lsa_update(ospf);
2002-12-13 21:15:29 +01:00
}
}
static void ospf_abr_update_aggregate(struct ospf_area_range *range,
struct ospf_route * or,
struct ospf_area *area)
2002-12-13 21:15:29 +01:00
{
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;
2002-12-13 21:15:29 +01:00
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) {
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_update_aggregate(): use configured cost %d",
range->cost_config);
2002-12-13 21:15:29 +01:00
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 */
}
2002-12-13 21:15:29 +01:00
if (or->cost > range->cost) {
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_update_aggregate(): update to %d",
or->cost);
2002-12-13 21:15:29 +01:00
range->cost = or->cost;
}
}
2002-12-13 21:15:29 +01:00
range->specifics++;
}
static void set_metric(struct ospf_lsa *lsa, uint32_t metric)
2002-12-13 21:15:29 +01:00
{
struct summary_lsa *header;
uint8_t *mp;
2002-12-13 21:15:29 +01:00
metric = htonl(metric);
mp = (uint8_t *)&metric;
2002-12-13 21:15:29 +01:00
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)
2002-12-13 21:15:29 +01:00
{
/* Incoming Type-7 or later aggregated Type-7
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
*
* 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
*/
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
struct ospf_lsa *old = NULL, *new = NULL;
struct as_external_lsa *ext7;
struct prefix_ipv4 p;
2002-12-13 21:15:29 +01:00
if (!CHECK_FLAG(lsa->data->options, OSPF_OPTION_NP)) {
if (IS_DEBUG_OSPF_NSSA)
zlog_debug(
"ospf_abr_translate_nssa(): LSA Id %pI4, P-bit off, NO Translation",
&lsa->data->id);
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
return 1;
2002-12-13 21:15:29 +01:00
}
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_NSSA)
zlog_debug(
"ospf_abr_translate_nssa(): LSA Id %pI4, TRANSLATING 7 to 5",
&lsa->data->id);
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
ext7 = (struct as_external_lsa *)(lsa->data);
p.prefix = lsa->data->id;
p.prefixlen = ip_masklen(ext7->mask);
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
if (ext7->e[0].fwd_addr.s_addr == OSPF_DEFAULT_DESTINATION) {
if (IS_DEBUG_OSPF_NSSA)
zlog_debug(
"ospf_abr_translate_nssa(): LSA Id %pI4, Forward address is 0, NO Translation",
&lsa->data->id);
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
return 1;
}
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
/* try find existing AS-External LSA for this prefix */
old = ospf_external_info_find_lsa(area->ospf, &p);
ospfd: flush type 5 when type 7 is removed When the ASBR stops announcing a prefix into the NSSA area, the LSA type 7 is removed from the area. However the ABR is refreshing the type 5 in its LSDB while removing the Type 7 LSA. Routers outside the area do not get an update. With the following topology: r1---r2---r3, with r3 being the ASBR announcing type 7 LSA: r3 configuration router ospf redistribute static network 10.0.23.0/24 area 1 area 1 nssa ! We stop announcing prefix 3.3.3.3 in the ASBR r3# conf r3(config)# router ospf r3(config-router)# no redistribute static r3(config-router)# r2 (ABR) r2# sh ip os database NSSA-external Link States (Area 0.0.0.1 [NSSA]) Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 33.33.33.33 3600 0x8000002f 0x13be E2 3.3.3.3/32 [0x0] <-- flushed AS External Link States Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 7 0x8000002f 0x73c7 E2 3.3.3.3/32 [0x0] <-- refreshed(?) With PR#7086 the LSA type 5 is flushed from the LSDB in r2 and the change is announced to routers outside the area (r1) r2# sh ip os da NSSA-external Link States (Area 0.0.0.1 [NSSA]) Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 33.33.33.33 3600 0x80000002 0x6d91 E2 3.3.3.3/32 [0x0] <-- flushed AS External Link States Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 3600 0x80000002 0xcd9a E2 3.3.3.3/32 [0x0] <-- flushed r1# sh ip os da AS External Link States Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 3600 0x80000002 0xcd9a E2 3.3.3.3/32 [0x0] <-- flushed Unfortunately I just realized that with PR#7086 I'm introducing a new bug, as Type-5 LSA are not being refreshed when reaching MaxAge r2# sh ip os da NSSA-external Link States (Area 0.0.0.1 [NSSA]) Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 33.33.33.33 35 0x80000002 0x6d91 E2 3.3.3.3/32 [0x0] <--- refreshed AS External Link States Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 3600 0x80000002 0xcd9a E2 3.3.3.3/32 [0x0] <--- not refreshed! So this PR should fix the original issue and the bug introduced later, so when stopping redistribution in the ASBR, both type 5 and type 7 are flushed: r2# sh ip os da NSSA-external Link States (Area 0.0.0.1 [NSSA]) Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 33.33.33.33 3600 0x80000002 0x6d91 E2 3.3.3.3/32 [0x0] AS External Link States Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 3600 0x80000002 0xcd9a E2 3.3.3.3/32 [0x0] Routers outside the area are also notified r1# sh ip os da Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 3600 0x80000002 0xcd9a E2 3.3.3.3/32 [0x0] Re-enabling redistribution, both LSA will be advertised again r3# conf r3(config)# router ospf r3(config-router)# no redistribute static r3(config-router)# redistribute static r3(config-router)# r2# sh ip os da NSSA-external Link States (Area 0.0.0.1 [NSSA]) Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 33.33.33.33 19 0x80000001 0x6f90 E2 3.3.3.3/32 [0x0] AS External Link States Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 11 0x80000001 0xcf99 E2 3.3.3.3/32 [0x0] and they are refreshed when reaching MaxAge NSSA-external Link States (Area 0.0.0.1 [NSSA]) Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 33.33.33.33 10 0x80000002 0x6d91 E2 3.3.3.3/32 [0x0] <-- Seq 2 AS External Link States Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 2 0x80000002 0xcd9a E2 3.3.3.3/32 [0x0] <-- Seq 2 Signed-off-by: ckishimo <carles.kishimoto@gmail.com>
2020-09-28 23:26:18 +02:00
if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE)) {
/* if type-7 is removed, remove old translated type-5 lsa */
if (old) {
UNSET_FLAG(old->flags, OSPF_LSA_APPROVED);
if (IS_DEBUG_OSPF_NSSA)
zlog_debug(
"ospf_abr_translate_nssa(): remove old translated LSA id %pI4",
&old->data->id);
}
ospfd: flush type 5 when type 7 is removed When the ASBR stops announcing a prefix into the NSSA area, the LSA type 7 is removed from the area. However the ABR is refreshing the type 5 in its LSDB while removing the Type 7 LSA. Routers outside the area do not get an update. With the following topology: r1---r2---r3, with r3 being the ASBR announcing type 7 LSA: r3 configuration router ospf redistribute static network 10.0.23.0/24 area 1 area 1 nssa ! We stop announcing prefix 3.3.3.3 in the ASBR r3# conf r3(config)# router ospf r3(config-router)# no redistribute static r3(config-router)# r2 (ABR) r2# sh ip os database NSSA-external Link States (Area 0.0.0.1 [NSSA]) Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 33.33.33.33 3600 0x8000002f 0x13be E2 3.3.3.3/32 [0x0] <-- flushed AS External Link States Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 7 0x8000002f 0x73c7 E2 3.3.3.3/32 [0x0] <-- refreshed(?) With PR#7086 the LSA type 5 is flushed from the LSDB in r2 and the change is announced to routers outside the area (r1) r2# sh ip os da NSSA-external Link States (Area 0.0.0.1 [NSSA]) Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 33.33.33.33 3600 0x80000002 0x6d91 E2 3.3.3.3/32 [0x0] <-- flushed AS External Link States Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 3600 0x80000002 0xcd9a E2 3.3.3.3/32 [0x0] <-- flushed r1# sh ip os da AS External Link States Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 3600 0x80000002 0xcd9a E2 3.3.3.3/32 [0x0] <-- flushed Unfortunately I just realized that with PR#7086 I'm introducing a new bug, as Type-5 LSA are not being refreshed when reaching MaxAge r2# sh ip os da NSSA-external Link States (Area 0.0.0.1 [NSSA]) Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 33.33.33.33 35 0x80000002 0x6d91 E2 3.3.3.3/32 [0x0] <--- refreshed AS External Link States Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 3600 0x80000002 0xcd9a E2 3.3.3.3/32 [0x0] <--- not refreshed! So this PR should fix the original issue and the bug introduced later, so when stopping redistribution in the ASBR, both type 5 and type 7 are flushed: r2# sh ip os da NSSA-external Link States (Area 0.0.0.1 [NSSA]) Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 33.33.33.33 3600 0x80000002 0x6d91 E2 3.3.3.3/32 [0x0] AS External Link States Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 3600 0x80000002 0xcd9a E2 3.3.3.3/32 [0x0] Routers outside the area are also notified r1# sh ip os da Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 3600 0x80000002 0xcd9a E2 3.3.3.3/32 [0x0] Re-enabling redistribution, both LSA will be advertised again r3# conf r3(config)# router ospf r3(config-router)# no redistribute static r3(config-router)# redistribute static r3(config-router)# r2# sh ip os da NSSA-external Link States (Area 0.0.0.1 [NSSA]) Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 33.33.33.33 19 0x80000001 0x6f90 E2 3.3.3.3/32 [0x0] AS External Link States Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 11 0x80000001 0xcf99 E2 3.3.3.3/32 [0x0] and they are refreshed when reaching MaxAge NSSA-external Link States (Area 0.0.0.1 [NSSA]) Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 33.33.33.33 10 0x80000002 0x6d91 E2 3.3.3.3/32 [0x0] <-- Seq 2 AS External Link States Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 2 0x80000002 0xcd9a E2 3.3.3.3/32 [0x0] <-- Seq 2 Signed-off-by: ckishimo <carles.kishimoto@gmail.com>
2020-09-28 23:26:18 +02:00
/* if type-7 is removed and type-5 does not exist, do not
* originate */
return 1;
}
ospfd: flush type 5 when type 7 is removed When the ASBR stops announcing a prefix into the NSSA area, the LSA type 7 is removed from the area. However the ABR is refreshing the type 5 in its LSDB while removing the Type 7 LSA. Routers outside the area do not get an update. With the following topology: r1---r2---r3, with r3 being the ASBR announcing type 7 LSA: r3 configuration router ospf redistribute static network 10.0.23.0/24 area 1 area 1 nssa ! We stop announcing prefix 3.3.3.3 in the ASBR r3# conf r3(config)# router ospf r3(config-router)# no redistribute static r3(config-router)# r2 (ABR) r2# sh ip os database NSSA-external Link States (Area 0.0.0.1 [NSSA]) Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 33.33.33.33 3600 0x8000002f 0x13be E2 3.3.3.3/32 [0x0] <-- flushed AS External Link States Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 7 0x8000002f 0x73c7 E2 3.3.3.3/32 [0x0] <-- refreshed(?) With PR#7086 the LSA type 5 is flushed from the LSDB in r2 and the change is announced to routers outside the area (r1) r2# sh ip os da NSSA-external Link States (Area 0.0.0.1 [NSSA]) Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 33.33.33.33 3600 0x80000002 0x6d91 E2 3.3.3.3/32 [0x0] <-- flushed AS External Link States Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 3600 0x80000002 0xcd9a E2 3.3.3.3/32 [0x0] <-- flushed r1# sh ip os da AS External Link States Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 3600 0x80000002 0xcd9a E2 3.3.3.3/32 [0x0] <-- flushed Unfortunately I just realized that with PR#7086 I'm introducing a new bug, as Type-5 LSA are not being refreshed when reaching MaxAge r2# sh ip os da NSSA-external Link States (Area 0.0.0.1 [NSSA]) Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 33.33.33.33 35 0x80000002 0x6d91 E2 3.3.3.3/32 [0x0] <--- refreshed AS External Link States Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 3600 0x80000002 0xcd9a E2 3.3.3.3/32 [0x0] <--- not refreshed! So this PR should fix the original issue and the bug introduced later, so when stopping redistribution in the ASBR, both type 5 and type 7 are flushed: r2# sh ip os da NSSA-external Link States (Area 0.0.0.1 [NSSA]) Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 33.33.33.33 3600 0x80000002 0x6d91 E2 3.3.3.3/32 [0x0] AS External Link States Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 3600 0x80000002 0xcd9a E2 3.3.3.3/32 [0x0] Routers outside the area are also notified r1# sh ip os da Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 3600 0x80000002 0xcd9a E2 3.3.3.3/32 [0x0] Re-enabling redistribution, both LSA will be advertised again r3# conf r3(config)# router ospf r3(config-router)# no redistribute static r3(config-router)# redistribute static r3(config-router)# r2# sh ip os da NSSA-external Link States (Area 0.0.0.1 [NSSA]) Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 33.33.33.33 19 0x80000001 0x6f90 E2 3.3.3.3/32 [0x0] AS External Link States Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 11 0x80000001 0xcf99 E2 3.3.3.3/32 [0x0] and they are refreshed when reaching MaxAge NSSA-external Link States (Area 0.0.0.1 [NSSA]) Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 33.33.33.33 10 0x80000002 0x6d91 E2 3.3.3.3/32 [0x0] <-- Seq 2 AS External Link States Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 2 0x80000002 0xcd9a E2 3.3.3.3/32 [0x0] <-- Seq 2 Signed-off-by: ckishimo <carles.kishimoto@gmail.com>
2020-09-28 23:26:18 +02:00
if (old && CHECK_FLAG(old->flags, OSPF_LSA_APPROVED)) {
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
if (IS_DEBUG_OSPF_NSSA)
zlog_debug(
"ospf_abr_translate_nssa(): found old translated LSA Id %pI4, refreshing",
&old->data->id);
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
/* 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 %pI4",
&old->data->id);
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
}
} else {
/* no existing external route for this LSA Id
* originate translated LSA
*/
ospfd: add support for suppress_fa This command will trigger the OSPF forwarding address suppression in translated type-5 LSAs, causing a NSSA ABR to use 0.0.0.0 as a forwarding address instead of copying the address from the type-7 LSA Example: In a topology like: R1 --- R2(ABR) --- R3(ASBR) R3 is announcing a type-7 LSA that is translated to type-5 by the R2 ABR. The forwarding address in the type-5 is by default copied from the type-7 r1# sh ip os da external AS External Link States LS age: 6 Options: 0x2 : *|-|-|-|-|-|E|- LS Flags: 0x6 LS Type: AS-external-LSA Link State ID: 3.3.3.3 (External Network Number) Advertising Router: 10.0.25.2 LS Seq Number: 80000001 Checksum: 0xcf99 Length: 36 Network Mask: /32 Metric Type: 2 (Larger than any link state path) TOS: 0 Metric: 20 Forward Address: 10.0.23.3 <--- address copied from type-7 lsa External Route Tag: 0 r2# sh ip os database NSSA-external Link States (Area 0.0.0.1 [NSSA]) Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.23.3 8 0x80000001 0x431d E2 3.3.3.3/32 [0x0] AS External Link States Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 0 0x80000001 0xcf99 E2 3.3.3.3/32 [0x0] r2# conf t r2(config)# router ospf r2(config-router)# area 1 nssa suppress-fa r2(config-router)# exit r2(config)# exit r2# sh ip os database NSSA-external Link States (Area 0.0.0.1 [NSSA]) Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.23.3 66 0x80000001 0x431d E2 3.3.3.3/32 [0x0] AS External Link States Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 16 0x80000002 0x0983 E2 3.3.3.3/32 [0x0] r1# sh ip os da external OSPF Router with ID (11.11.11.11) AS External Link States LS age: 34 Options: 0x2 : *|-|-|-|-|-|E|- LS Flags: 0x6 LS Type: AS-external-LSA Link State ID: 3.3.3.3 (External Network Number) Advertising Router: 10.0.25.2 LS Seq Number: 80000002 Checksum: 0x0983 Length: 36 Network Mask: /32 Metric Type: 2 (Larger than any link state path) TOS: 0 Metric: 20 Forward Address: 0.0.0.0 <--- address set to 0 External Route Tag: 0 r2# conf t r2(config)# router ospf r2(config-router)# no area 1 nssa suppress-fa r2(config-router)# exit r1# sh ip os da external OSPF Router with ID (11.11.11.11) AS External Link States LS age: 1 Options: 0x2 : *|-|-|-|-|-|E|- LS Flags: 0x6 LS Type: AS-external-LSA Link State ID: 3.3.3.3 (External Network Number) Advertising Router: 10.0.25.2 LS Seq Number: 80000003 Checksum: 0xcb9b Length: 36 Network Mask: /32 Metric Type: 2 (Larger than any link state path) TOS: 0 Metric: 20 Forward Address: 0.0.0.0 <--- address set to 0 External Route Tag: 0 r2# conf t r2(config)# router ospf r2(config-router)# no area 1 nssa suppress-fa r2(config-router)# exit r1# sh ip os da external OSPF Router with ID (11.11.11.11) AS External Link States LS age: 1 Options: 0x2 : *|-|-|-|-|-|E|- LS Flags: 0x6 LS Type: AS-external-LSA Link State ID: 3.3.3.3 (External Network Number) Advertising Router: 10.0.25.2 LS Seq Number: 80000003 Checksum: 0xcb9b Length: 36 Network Mask: /32 Metric Type: 2 (Larger than any link state path) TOS: 0 Metric: 20 Forward Address: 10.0.23.3 <--- address copied from type-7 lsa External Route Tag: 0 Signed-off-by: ckishimo <carles.kishimoto@gmail.com>
2020-11-02 15:28:52 +01:00
if (ospf_translated_nssa_originate(area->ospf, lsa, old)
== NULL) {
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
if (IS_DEBUG_OSPF_NSSA)
zlog_debug(
"ospf_abr_translate_nssa(): Could not translate Type-7 for %pI4 to Type-5",
&lsa->data->id);
return 1;
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
}
}
2002-12-13 21:15:29 +01:00
/* Area where Aggregate testing will be inserted, just like summary
advertisements */
/* ospf_abr_check_nssa_range (p_arg, lsa-> cost, lsa -> area); */
2002-12-13 21:15:29 +01:00
return 0;
}
static void ospf_abr_translate_nssa_range(struct prefix_ipv4 *p, uint32_t cost)
2002-12-13 21:15:29 +01:00
{
/* 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, uint32_t cost,
2002-12-13 21:15:29 +01:00
struct ospf_area *area)
{
struct ospf_lsa *lsa, *old = NULL;
struct summary_lsa *sl = NULL;
uint32_t full_cost;
2002-12-13 21:15:29 +01:00
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, p,
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
area->ospf->router_id);
2002-12-13 21:15:29 +01:00
if (old) {
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_announce_network_to_area(): old summary found");
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
sl = (struct summary_lsa *)old->data;
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_announce_network_to_area(): old metric: %d, new metric: %d",
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
GET_METRIC(sl->metric), cost);
if ((GET_METRIC(sl->metric) == full_cost)
&& ((old->flags & OSPF_LSA_IN_MAXAGE) == 0)) {
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
/* unchanged. simply reapprove it */
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_announce_network_to_area(): old summary approved");
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
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) {
flog_warn(EC_OSPF_LSA_MISSING,
"%s: Could not refresh %pFX to %pI4",
__func__, (struct prefix *)p,
&area->area_id);
return;
}
SET_FLAG(lsa->flags, OSPF_LSA_APPROVED);
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
/* This will flood through area. */
}
2002-12-13 21:15:29 +01:00
} else {
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_announce_network_to_area(): creating new summary");
lsa = ospf_summary_lsa_originate(p, full_cost, area);
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
/* This will flood through area. */
if (!lsa) {
flog_warn(EC_OSPF_LSA_MISSING,
"%s: Could not originate %pFX to %pi4",
__func__, (struct prefix *)p,
&area->area_id);
return;
}
2002-12-13 21:15:29 +01:00
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");
}
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_announce_network_to_area(): Stop");
2002-12-13 21:15:29 +01:00
}
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;
2002-12-13 21:15:29 +01:00
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;
2002-12-13 21:15:29 +01:00
return 0;
}
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
static int ospf_abr_should_accept(struct prefix_ipv4 *p, struct ospf_area *area)
2002-12-13 21:15:29 +01:00
{
if (IMPORT_NAME(area)) {
if (IMPORT_LIST(area) == NULL)
IMPORT_LIST(area) =
access_list_lookup(AFI_IP, IMPORT_NAME(area));
2002-12-13 21:15:29 +01:00
if (IMPORT_LIST(area))
if (access_list_apply(IMPORT_LIST(area), p)
== FILTER_DENY)
return 0;
}
return 1;
}
static int ospf_abr_plist_in_check(struct ospf_area *area,
struct ospf_route * or,
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
struct prefix_ipv4 *p)
2002-12-13 21:15:29 +01:00
{
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,
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
struct prefix_ipv4 *p)
2002-12-13 21:15:29 +01:00
{
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,
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
struct ospf_route * or)
2002-12-13 21:15:29 +01:00
{
struct ospf_area_range *range;
struct ospf_area *area, *or_area;
struct listnode *node;
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_announce_network(): Start");
2002-12-13 21:15:29 +01:00
or_area = ospf_area_lookup_by_area_id(ospf, or->u.std.area_id);
2002-12-13 21:15:29 +01:00
assert(or_area);
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_announce_network(): looking at area %pI4",
&area->area_id);
2002-12-13 21:15:29 +01:00
if (IPV4_ADDR_SAME(& or->u.std.area_id, &area->area_id))
continue;
if (ospf_abr_nexthops_belong_to_area(or, area))
continue;
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
if (!ospf_abr_should_accept(p, area)) {
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_announce_network(): prefix %pFX was denied by import-list",
p);
2002-12-13 21:15:29 +01:00
continue;
}
2002-12-13 21:15:29 +01:00
if (!ospf_abr_plist_in_check(area, or, p)) {
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_announce_network(): prefix %pFX was denied by prefix-list",
p);
2002-12-13 21:15:29 +01:00
continue;
}
2002-12-13 21:15:29 +01:00
if (area->external_routing != OSPF_AREA_DEFAULT
&& area->no_summary) {
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_announce_network(): area %pI4 is stub and no_summary",
&area->area_id);
2002-12-13 21:15:29 +01:00
continue;
}
2002-12-13 21:15:29 +01:00
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 %pFX",
p);
2002-12-13 21:15:29 +01:00
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
if (!OSPF_IS_AREA_BACKBONE(area))
ospf_abr_announce_network_to_area(p, or->cost,
area);
}
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
if (or->path_type == OSPF_PATH_INTRA_AREA) {
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_announce_network(): this is intra-area route to %pFX",
p);
2002-12-13 21:15:29 +01:00
if ((range = ospf_area_range_match(or_area, p))
&& !ospf_area_is_transit(area))
2002-12-13 21:15:29 +01:00
ospf_abr_update_aggregate(range, or, area);
else
2002-12-13 21:15:29 +01:00
ospf_abr_announce_network_to_area(p, or->cost,
area);
}
2002-12-13 21:15:29 +01:00
}
}
2002-12-13 21:15:29 +01:00
static int ospf_abr_should_announce(struct ospf *ospf, struct prefix_ipv4 *p,
struct ospf_route * or)
{
struct ospf_area *area;
2002-12-13 21:15:29 +01:00
area = ospf_area_lookup_by_area_id(ospf, or->u.std.area_id);
2002-12-13 21:15:29 +01:00
assert(area);
2002-12-13 21:15:29 +01:00
if (EXPORT_NAME(area)) {
if (EXPORT_LIST(area) == NULL)
EXPORT_LIST(area) =
access_list_lookup(AFI_IP, EXPORT_NAME(area));
2002-12-13 21:15:29 +01:00
if (EXPORT_LIST(area))
if (access_list_apply(EXPORT_LIST(area), p)
== FILTER_DENY)
return 0;
}
return 1;
}
2002-12-13 21:15:29 +01:00
static void ospf_abr_process_nssa_translates(struct ospf *ospf)
{
2002-12-13 21:15:29 +01:00
/* Scan through all NSSA_LSDB records for all areas;
2002-12-13 21:15:29 +01:00
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;
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_NSSA)
zlog_debug("ospf_abr_process_nssa_translates(): Start");
2002-12-13 21:15:29 +01:00
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
if (!area->NSSATranslatorState)
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
continue; /* skip if not translator */
2002-12-13 21:15:29 +01:00
if (area->external_routing != OSPF_AREA_NSSA)
continue; /* skip if not Nssa Area */
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_NSSA)
zlog_debug(
"ospf_abr_process_nssa_translates(): looking at area %pI4",
&area->area_id);
LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
ospf_abr_translate_nssa(area, lsa);
2002-12-13 21:15:29 +01:00
}
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
if (IS_DEBUG_OSPF_NSSA)
zlog_debug("ospf_abr_process_nssa_translates(): Stop");
2002-12-13 21:15:29 +01:00
}
static void ospf_abr_process_network_rt(struct ospf *ospf,
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
struct route_table *rt)
2002-12-13 21:15:29 +01:00
{
struct ospf_area *area;
struct ospf_route * or ;
struct route_node *rn;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_process_network_rt(): Start");
2002-12-13 21:15:29 +01:00
for (rn = route_top(rt); rn; rn = route_next(rn)) {
if ((or = rn->info) == NULL)
continue;
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 %pI4 no longer exists",
&or->u.std.area_id);
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
continue;
2002-12-13 21:15:29 +01:00
}
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_process_network_rt(): this is a route to %pFX",
&rn->p);
2002-12-13 21:15:29 +01:00
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");
2002-12-13 21:15:29 +01:00
continue;
}
if (or->cost >= OSPF_LS_INFINITY) {
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_process_network_rt(): this route's cost is infinity, skipping");
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
continue;
2002-12-13 21:15:29 +01:00
}
if (or->type == OSPF_DESTINATION_DISCARD) {
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_process_network_rt(): this is a discard entry, skipping");
2002-12-13 21:15:29 +01:00
continue;
}
if (
or->path_type == OSPF_PATH_INTRA_AREA
&& !ospf_abr_should_announce(
ospf, (struct prefix_ipv4 *)&rn->p,
or)) {
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_process_network_rt(): denied by export-list");
2002-12-13 21:15:29 +01:00
continue;
}
if (
or->path_type == OSPF_PATH_INTRA_AREA
&& !ospf_abr_plist_out_check(
area, or,
(struct prefix_ipv4 *)&rn->p)) {
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_process_network_rt(): denied by prefix-list");
2002-12-13 21:15:29 +01:00
continue;
}
2002-12-13 21:15:29 +01:00
if ((or->path_type == OSPF_PATH_INTER_AREA)
&& !OSPF_IS_AREA_ID_BACKBONE(or->u.std.area_id)) {
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_process_network_rt(): this is route is not backbone one, skipping");
2002-12-13 21:15:29 +01:00
continue;
}
2002-12-13 21:15:29 +01:00
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) {
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_process_network_rt(): ALT ABR: No BB connection, skip not intra-area routes");
2002-12-13 21:15:29 +01:00
continue;
}
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_process_network_rt(): announcing");
ospf_abr_announce_network(ospf, (struct prefix_ipv4 *)&rn->p,
2002-12-13 21:15:29 +01:00
or);
}
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_process_network_rt(): Stop");
2002-12-13 21:15:29 +01:00
}
static void ospf_abr_announce_rtr_to_area(struct prefix_ipv4 *p, uint32_t cost,
2002-12-13 21:15:29 +01:00
struct ospf_area *area)
{
2002-12-13 21:15:29 +01:00
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");
2002-12-13 21:15:29 +01:00
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
old = ospf_lsa_lookup_by_prefix(area->lsdb, OSPF_ASBR_SUMMARY_LSA, p,
area->ospf->router_id);
2002-12-13 21:15:29 +01:00
if (old) {
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_announce_rtr_to_area(): old summary found");
2002-12-13 21:15:29 +01:00
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",
2002-12-13 21:15:29 +01:00
GET_METRIC(slsa->metric), cost);
}
if (old && (GET_METRIC(slsa->metric) == cost)
&& ((old->flags & OSPF_LSA_IN_MAXAGE) == 0)) {
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_announce_rtr_to_area(): old summary approved");
2002-12-13 21:15:29 +01:00
SET_FLAG(old->flags, OSPF_LSA_APPROVED);
} else {
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_announce_rtr_to_area(): 2.2");
if (old) {
2002-12-13 21:15:29 +01:00
set_metric(old, cost);
lsa = ospf_lsa_refresh(area->ospf, old);
} else
2002-12-13 21:15:29 +01:00
lsa = ospf_summary_asbr_lsa_originate(p, cost, area);
if (!lsa) {
flog_warn(EC_OSPF_LSA_MISSING,
"%s: Could not refresh/originate %pFX to %pI4",
__func__, (struct prefix *)p,
&area->area_id);
return;
}
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_announce_rtr_to_area(): flooding new version of summary");
2002-12-13 21:15:29 +01:00
/*
zlog_info ("ospf_abr_announce_rtr_to_area(): creating new
2002-12-13 21:15:29 +01:00
summary");
lsa = ospf_summary_asbr_lsa (p, cost, area, old); */
SET_FLAG(lsa->flags, OSPF_LSA_APPROVED);
/* ospf_flood_through_area (area, NULL, lsa);*/
2002-12-13 21:15:29 +01:00
}
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_announce_rtr_to_area(): Stop");
2002-12-13 21:15:29 +01:00
}
2002-12-13 21:15:29 +01:00
static void ospf_abr_announce_rtr(struct ospf *ospf, struct prefix_ipv4 *p,
struct ospf_route * or)
{
struct listnode *node;
struct ospf_area *area;
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_announce_rtr(): Start");
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_announce_rtr(): looking at area %pI4",
&area->area_id);
if (IPV4_ADDR_SAME(& or->u.std.area_id, &area->area_id))
2002-12-13 21:15:29 +01:00
continue;
if (ospf_abr_nexthops_belong_to_area(or, area))
2002-12-13 21:15:29 +01:00
continue;
/* RFC3101: Do not generate ASBR type 4 LSA if NSSA ABR */
if (or->u.std.external_routing == OSPF_AREA_NSSA) {
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_announce_rtr(): do not generate LSA Type-4 %pI4 from NSSA",
&p->prefix);
continue;
}
2002-12-13 21:15:29 +01:00
if (area->external_routing != OSPF_AREA_DEFAULT) {
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_announce_rtr(): area %pI4 doesn't support external routing",
&area->area_id);
2002-12-13 21:15:29 +01:00
continue;
}
if (or->path_type == OSPF_PATH_INTER_AREA) {
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_announce_rtr(): this is inter-area route to %pI4",
&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) {
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_announce_rtr(): this is intra-area route to %pI4",
&p->prefix);
ospf_abr_announce_rtr_to_area(p, or->cost, area);
2002-12-13 21:15:29 +01:00
}
}
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_announce_rtr(): Stop");
}
2002-12-13 21:15:29 +01:00
static void ospf_abr_process_router_rt(struct ospf *ospf,
struct route_table *rt)
2002-12-13 21:15:29 +01:00
{
struct ospf_route * or ;
struct route_node *rn;
2002-12-13 21:15:29 +01:00
struct list *l;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_process_router_rt(): Start");
2002-12-13 21:15:29 +01:00
for (rn = route_top(rt); rn; rn = route_next(rn)) {
struct listnode *node, *nnode;
char flag = 0;
struct ospf_route *best = NULL;
2002-12-13 21:15:29 +01:00
if (rn->info == NULL)
continue;
l = rn->info;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_process_router_rt(): this is a route to %pI4",
&rn->p.u.prefix4);
2002-12-13 21:15:29 +01:00
for (ALL_LIST_ELEMENTS(l, node, nnode, or)) {
if (!ospf_area_lookup_by_area_id(ospf,
or->u.std.area_id)) {
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_process_router_rt(): area %pI4 no longer exists",
&or->u.std.area_id);
2002-12-13 21:15:29 +01:00
continue;
}
2002-12-13 21:15:29 +01:00
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");
2002-12-13 21:15:29 +01:00
continue;
}
2002-12-13 21:15:29 +01:00
if (!flag) {
best = ospf_find_asbr_route(
ospf, rt, (struct prefix_ipv4 *)&rn->p);
2002-12-13 21:15:29 +01:00
flag = 1;
}
2002-12-13 21:15:29 +01:00
if (best == NULL)
continue;
2002-12-13 21:15:29 +01:00
if (or != best) {
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_process_router_rt(): This route is not the best among possible, skipping");
2002-12-13 21:15:29 +01:00
continue;
}
if (
or->path_type == OSPF_PATH_INTER_AREA
&& !OSPF_IS_AREA_ID_BACKBONE(
or->u.std.area_id)) {
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_process_router_rt(): This route is not a backbone one, skipping");
2002-12-13 21:15:29 +01:00
continue;
}
2002-12-13 21:15:29 +01:00
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");
2002-12-13 21:15:29 +01:00
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) {
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_process_network_rt(): ALT ABR: No BB connection, skip not intra-area routes");
2002-12-13 21:15:29 +01:00
continue;
}
ospf_abr_announce_rtr(ospf,
2002-12-13 21:15:29 +01:00
(struct prefix_ipv4 *)&rn->p, or);
}
2002-12-13 21:15:29 +01:00
}
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_process_router_rt(): Stop");
2002-12-13 21:15:29 +01:00
}
static void
2002-12-13 21:15:29 +01:00
ospf_abr_unapprove_translates(struct ospf *ospf) /* For NSSA Translations */
{
struct ospf_lsa *lsa;
struct route_node *rn;
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_NSSA)
zlog_debug("ospf_abr_unapprove_translates(): Start");
2002-12-13 21:15:29 +01:00
/* NSSA Translator is not checked, because it may have gone away,
and we would want to flush any residuals anyway */
2002-12-13 21:15:29 +01:00
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 %pI4",
&lsa->data->id);
}
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_NSSA)
zlog_debug("ospf_abr_unapprove_translates(): Stop");
2002-12-13 21:15:29 +01:00
}
static void ospf_abr_unapprove_summaries(struct ospf *ospf)
2002-12-13 21:15:29 +01:00
{
struct listnode *node;
struct ospf_area *area;
struct route_node *rn;
2002-12-13 21:15:29 +01:00
struct ospf_lsa *lsa;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_unapprove_summaries(): Start");
2002-12-13 21:15:29 +01:00
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_unapprove_summaries(): considering area %pI4",
&area->area_id);
2002-12-13 21:15:29 +01:00
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 %pI4",
&lsa->data->id);
UNSET_FLAG(lsa->flags, OSPF_LSA_APPROVED);
}
2002-12-13 21:15:29 +01:00
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 %pI4",
&lsa->data->id);
UNSET_FLAG(lsa->flags, OSPF_LSA_APPROVED);
}
}
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_unapprove_summaries(): Stop");
}
2002-12-13 21:15:29 +01:00
static void ospf_abr_prepare_aggregates(struct ospf *ospf)
{
2002-12-13 21:15:29 +01:00
struct listnode *node;
struct route_node *rn;
2002-12-13 21:15:29 +01:00
struct ospf_area_range *range;
struct ospf_area *area;
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_prepare_aggregates(): Start");
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
2002-12-13 21:15:29 +01:00
for (rn = route_top(area->ranges); rn; rn = route_next(rn))
if ((range = rn->info) != NULL) {
range->cost = 0;
range->specifics = 0;
}
}
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_prepare_aggregates(): Stop");
}
2002-12-13 21:15:29 +01:00
static void ospf_abr_announce_aggregates(struct ospf *ospf)
2002-12-13 21:15:29 +01:00
{
struct ospf_area *area, *ar;
2002-12-13 21:15:29 +01:00
struct ospf_area_range *range;
struct route_node *rn;
struct prefix p;
struct listnode *node, *n;
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_announce_aggregates(): Start");
2002-12-13 21:15:29 +01:00
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_announce_aggregates(): looking at area %pI4",
&area->area_id);
2002-12-13 21:15:29 +01:00
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");
2002-12-13 21:15:29 +01:00
continue;
}
2002-12-13 21:15:29 +01:00
p.family = AF_INET;
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
p.u.prefix4 = range->addr;
2002-12-13 21:15:29 +01:00
p.prefixlen = range->masklen;
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_announce_aggregates(): this is range: %pFX",
&p);
2002-12-13 21:15:29 +01:00
if (CHECK_FLAG(range->flags,
OSPF_AREA_RANGE_SUBSTITUTE)) {
p.family = AF_INET;
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
p.u.prefix4 = range->subst_addr;
2002-12-13 21:15:29 +01:00
p.prefixlen = range->subst_masklen;
}
2002-12-13 21:15:29 +01:00
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)) {
2002-12-13 21:15:29 +01:00
if (ar == area)
continue;
2002-12-13 21:15:29 +01:00
/* We do not check nexthops
here, because
intra-area routes can be
associated with
one area only */
2002-12-13 21:15:29 +01:00
/* backbone routes are not
summarized
when announced into transit
areas */
2002-12-13 21:15:29 +01:00
if (ospf_area_is_transit(ar)
&& OSPF_IS_AREA_BACKBONE(
area)) {
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_announce_aggregates(): Skipping announcement of BB aggregate into a transit area");
2002-12-13 21:15:29 +01:00
continue;
}
ospf_abr_announce_network_to_area(
(struct prefix_ipv4
*)&p,
range->cost, ar);
}
}
}
}
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_announce_aggregates(): Stop");
2002-12-13 21:15:29 +01:00
}
static void
ospf_abr_send_nssa_aggregates(struct ospf *ospf) /* temporarily turned off */
2002-12-13 21:15:29 +01:00
{
struct listnode *node; /*, n; */
struct ospf_area *area; /*, *ar; */
struct route_node *rn;
2002-12-13 21:15:29 +01:00
struct ospf_area_range *range;
struct prefix_ipv4 p;
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_NSSA)
zlog_debug("ospf_abr_send_nssa_aggregates(): Start");
2002-12-13 21:15:29 +01:00
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 %pI4",
&area->area_id);
for (rn = route_top(area->ranges); rn; rn = route_next(rn)) {
if (rn->info == NULL)
2002-12-13 21:15:29 +01:00
continue;
2002-12-13 21:15:29 +01:00
range = rn->info;
if (!CHECK_FLAG(range->flags,
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
OSPF_AREA_RANGE_ADVERTISE)) {
if (IS_DEBUG_OSPF_NSSA)
zlog_debug(
"ospf_abr_send_nssa_aggregates(): discarding suppress-ranges");
2002-12-13 21:15:29 +01:00
continue;
}
2002-12-13 21:15:29 +01:00
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: %pFX",
&p);
if (CHECK_FLAG(range->flags,
OSPF_AREA_RANGE_SUBSTITUTE)) {
2002-12-13 21:15:29 +01:00
p.family = AF_INET;
p.prefix = range->subst_addr;
p.prefixlen = range->subst_masklen;
}
2002-12-13 21:15:29 +01:00
if (range->specifics) {
if (IS_DEBUG_OSPF_NSSA)
zlog_debug(
"ospf_abr_send_nssa_aggregates(): active range");
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
/* Fetch LSA-Type-7 from aggregate prefix, and
* then
* translate, Install (as Type-5), Approve, and
* Flood
*/
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
ospf_abr_translate_nssa_range(&p, range->cost);
}
} /* all area ranges*/
2002-12-13 21:15:29 +01:00
} /* all areas */
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_NSSA)
zlog_debug("ospf_abr_send_nssa_aggregates(): Stop");
2002-12-13 21:15:29 +01:00
}
static void ospf_abr_announce_stub_defaults(struct ospf *ospf)
2002-12-13 21:15:29 +01:00
{
struct listnode *node;
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
struct ospf_area *area;
struct prefix_ipv4 p;
2002-12-13 21:15:29 +01:00
if (!IS_OSPF_ABR(ospf))
2002-12-13 21:15:29 +01:00
return;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_announce_stub_defaults(): Start");
2002-12-13 21:15:29 +01:00
p.family = AF_INET;
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
p.prefix.s_addr = OSPF_DEFAULT_DESTINATION;
2002-12-13 21:15:29 +01:00
p.prefixlen = 0;
2002-12-13 21:15:29 +01:00
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_announce_stub_defaults(): looking at area %pI4",
&area->area_id);
2002-12-13 21:15:29 +01:00
if ((area->external_routing != OSPF_AREA_STUB)
&& (area->external_routing != OSPF_AREA_NSSA))
2002-12-13 21:15:29 +01:00
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 %pI4",
&area->area_id);
2002-12-13 21:15:29 +01:00
ospf_abr_announce_network_to_area(&p, area->default_cost, area);
}
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_announce_stub_defaults(): Stop");
2002-12-13 21:15:29 +01:00
}
static int ospf_abr_remove_unapproved_translates_apply(struct ospf *ospf,
struct ospf_lsa *lsa)
2002-12-13 21:15:29 +01:00
{
if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT)
2002-12-13 21:15:29 +01:00
&& !CHECK_FLAG(lsa->flags, OSPF_LSA_APPROVED)) {
zlog_info(
"ospf_abr_remove_unapproved_translates(): removing unapproved translates, ID: %pI4",
&lsa->data->id);
2002-12-13 21:15:29 +01:00
/* FLUSH THROUGHOUT AS */
ospf_lsa_flush_as(ospf, lsa);
2002-12-13 21:15:29 +01:00
/* DISCARD from LSDB */
2002-12-13 21:15:29 +01:00
}
return 0;
}
static void ospf_abr_remove_unapproved_translates(struct ospf *ospf)
2002-12-13 21:15:29 +01:00
{
struct route_node *rn;
2002-12-13 21:15:29 +01:00
struct ospf_lsa *lsa;
/* All AREA PROCESS should have APPROVED necessary LSAs */
/* Remove any left over and not APPROVED */
2002-12-13 21:15:29 +01:00
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);
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_NSSA)
zlog_debug("ospf_abr_remove_unapproved_translates(): Stop");
2002-12-13 21:15:29 +01:00
}
static void ospf_abr_remove_unapproved_summaries(struct ospf *ospf)
2002-12-13 21:15:29 +01:00
{
struct listnode *node;
2002-12-13 21:15:29 +01:00
struct ospf_area *area;
struct route_node *rn;
struct ospf_lsa *lsa;
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_remove_unapproved_summaries(): Start");
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_remove_unapproved_summaries(): looking at area %pI4",
&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);
2002-12-13 21:15:29 +01:00
}
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_remove_unapproved_summaries(): Stop");
2002-12-13 21:15:29 +01:00
}
static void ospf_abr_manage_discard_routes(struct ospf *ospf)
2002-12-13 21:15:29 +01:00
{
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
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, ospf->new_table,
area,
(struct prefix_ipv4
*)&rn->p);
else
ospf_delete_discard_route(
ospf, ospf->new_table,
(struct prefix_ipv4
*)&rn->p);
}
2002-12-13 21:15:29 +01:00
}
/* This is the function taking care about ABR NSSA, i.e. NSSA
Translator, -LSA aggregation and flooding. For all NSSAs
Any SELF-AS-LSA is in the Type-5 LSDB and Type-7 LSDB. These LSA's
are refreshed from the Type-5 LSDB, installed into the Type-7 LSDB
with the P-bit set.
Any received Type-5s are legal for an ABR, else illegal for IR.
Received Type-7s are installed, by area, with incoming P-bit. They
are flooded; if the Elected NSSA Translator, then P-bit off.
Additionally, this ABR will place "translated type-7's" into the
Type-5 LSDB in order to keep track of APPROVAL or not.
It will scan through every area, looking for Type-7 LSAs with P-Bit
SET. The Type-7's are either AS-FLOODED & 5-INSTALLED or
AGGREGATED. Later, the AGGREGATED LSAs are AS-FLOODED &
5-INSTALLED.
5-INSTALLED is into the Type-5 LSDB; Any UNAPPROVED Type-5 LSAs
left over are FLUSHED and DISCARDED.
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 */
2002-12-13 21:15:29 +01:00
{
ospfd: introduce support for Graceful Restart (restarting mode) RFC 3623 specifies the Graceful Restart enhancement to the OSPF routing protocol. This PR implements support for the restarting mode, whereas the helper mode was implemented by #6811. This work is based on #6782, which implemented the pre-restart part and settled the foundations for the post-restart part (behavioral changes, GR exit conditions, and on-exit actions). Here's a quick summary of how the GR restarting mode works: * GR can be enabled on a per-instance basis using the `graceful-restart [grace-period (1-1800)]` command; * To perform a graceful shutdown, the `graceful-restart prepare ospf` EXEC-level command needs to be issued before restarting the ospfd daemon (there's no specific requirement on how the daemon should be restarted); * `graceful-restart prepare ospf` will initiate the graceful restart for all GR-enabled instances by taking the following actions: o Flooding Grace-LSAs over all interfaces o Freezing the OSPF routes in the RIB o Saving the end of the grace period in non-volatile memory (a JSON file stored in `$frr_statedir`) * Once ospfd is started again, it will follow the procedures described in RFC 3623 until it detects it's time to exit the graceful restart (either successfully or unsuccessfully). Testing done: * New topotest featuring a multi-area OSPF topology (including stub and NSSA areas); * Successful interop tests against IOS-XR routers acting as helpers. Co-authored-by: GalaxyGorilla <sascha@netdef.org> Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2021-05-31 15:27:51 +02:00
if (ospf->gr_info.restart_in_progress)
return;
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_NSSA)
zlog_debug("Check for NSSA-ABR Tasks():");
if (!IS_OSPF_ABR(ospf))
2002-12-13 21:15:29 +01:00
return;
if (!ospf->anyNSSA)
2002-12-13 21:15:29 +01:00
return;
2002-12-13 21:15:29 +01:00
/* Each area must confirm TranslatorRole */
if (IS_DEBUG_OSPF_NSSA)
zlog_debug("ospf_abr_nssa_task(): Start");
2002-12-13 21:15:29 +01:00
/* 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);
2002-12-13 21:15:29 +01:00
/* 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 */
2002-12-13 21:15:29 +01:00
/* For all NSSAs, Type-7s, translate to 5's, INSTALL/FLOOD, or
* Aggregate as Type-7
* Install or Approve in Type-5 Global LSDB
*/
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_NSSA)
zlog_debug("ospf_abr_nssa_task(): process translates");
ospf_abr_process_nssa_translates(ospf);
2002-12-13 21:15:29 +01:00
/* 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
*/
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_NSSA)
zlog_debug("ospf_abr_nssa_task(): send NSSA aggregates");
ospf_abr_send_nssa_aggregates(ospf); /*TURNED OFF FOR NOW */
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
/* Send any NSSA defaults as Type-5
*if (IS_DEBUG_OSPF_NSSA)
* zlog_debug ("ospf_abr_nssa_task(): announce nssa defaults");
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
*ospf_abr_announce_nssa_defaults (ospf);
* havnt a clue what above is supposed to do.
*/
2002-12-13 21:15:29 +01:00
/* 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 */
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_NSSA)
zlog_debug("ospf_abr_nssa_task(): Stop");
2002-12-13 21:15:29 +01:00
}
/* This is the function taking care about ABR stuff, i.e.
summary-LSA origination and flooding. */
void ospf_abr_task(struct ospf *ospf)
2002-12-13 21:15:29 +01:00
{
ospfd: introduce support for Graceful Restart (restarting mode) RFC 3623 specifies the Graceful Restart enhancement to the OSPF routing protocol. This PR implements support for the restarting mode, whereas the helper mode was implemented by #6811. This work is based on #6782, which implemented the pre-restart part and settled the foundations for the post-restart part (behavioral changes, GR exit conditions, and on-exit actions). Here's a quick summary of how the GR restarting mode works: * GR can be enabled on a per-instance basis using the `graceful-restart [grace-period (1-1800)]` command; * To perform a graceful shutdown, the `graceful-restart prepare ospf` EXEC-level command needs to be issued before restarting the ospfd daemon (there's no specific requirement on how the daemon should be restarted); * `graceful-restart prepare ospf` will initiate the graceful restart for all GR-enabled instances by taking the following actions: o Flooding Grace-LSAs over all interfaces o Freezing the OSPF routes in the RIB o Saving the end of the grace period in non-volatile memory (a JSON file stored in `$frr_statedir`) * Once ospfd is started again, it will follow the procedures described in RFC 3623 until it detects it's time to exit the graceful restart (either successfully or unsuccessfully). Testing done: * New topotest featuring a multi-area OSPF topology (including stub and NSSA areas); * Successful interop tests against IOS-XR routers acting as helpers. Co-authored-by: GalaxyGorilla <sascha@netdef.org> Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2021-05-31 15:27:51 +02:00
if (ospf->gr_info.restart_in_progress)
return;
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_task(): Start");
if (ospf->new_table == NULL || ospf->new_rtrs == NULL) {
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_abr_task(): Routing tables are not yet ready");
2002-12-13 21:15:29 +01:00
return;
}
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_task(): unapprove summaries");
ospf_abr_unapprove_summaries(ospf);
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_task(): prepare aggregates");
ospf_abr_prepare_aggregates(ospf);
if (IS_OSPF_ABR(ospf)) {
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_task(): process network RT");
ospf_abr_process_network_rt(ospf, ospf->new_table);
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_task(): process router RT");
ospf_abr_process_router_rt(ospf, ospf->new_rtrs);
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_task(): announce aggregates");
ospf_abr_announce_aggregates(ospf);
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_task(): announce stub defaults");
ospf_abr_announce_stub_defaults(ospf);
2002-12-13 21:15:29 +01:00
}
2002-12-13 21:15:29 +01:00
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);
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_abr_task(): Stop");
2002-12-13 21:15:29 +01:00
}
static int ospf_abr_task_timer(struct thread *thread)
2002-12-13 21:15:29 +01:00
{
struct ospf *ospf = THREAD_ARG(thread);
ospf->t_abr_task = 0;
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("Running ABR task on timer");
2002-12-13 21:15:29 +01:00
ospf_check_abr_status(ospf);
2003-07-12 Paul Jakma <paul@dishone.st> * (global): Add/fixup NSSA ABR translation functionality * ospfd.h: Adjust the NSSA ROLE defines. Rename STATE to TRANSLATE. Rename the LSA_NSSA_GET define to LSA_OPTIONS_NSSA_GET. * ospfd.c: Adjust to match changes to ospfd.h * ospf_te.c: Adjust to match change to LSA_NSSA_GET. * ospf_lsa.h: slights reformatting. Add new NSSA functions, ospf_translated_nssa_compare() (not currently used), ospf_translated_nssa_refresh() and ospf_translated_nssa_originate(). * ospf_lsa.c: Implemented aforementioned new functions. Fix up several NSSA hooks to /not/ be called for Type-5s which are translated. Add additional hooks. Set the ROUTER_LSA_NT bit in router-lsa flags if ABR does translation. New function, ospf_lsa_translated_nssa_new() implemented. Dont register translated LSAs for refreshing - instead we implicitly rely on the ASBR refreshing the Type-7, and refresh the translated Type-5 at the same time. Some minor reformatting. Extra debug info added. Also, existing debug statements modified to report LSA Id. * ospf_flood.c: call ospf_translated_nssa_refresh() when refreshing Type-7. minor reformatting. * ospf_dump.c: Dump NSSA LSAs. * ospf_asbr.h: slight reformatting. Export ospf_external_route_lookup() (though, not used. probably will undo this). * ospf_abr.c: Slight reformatting in many places. Update to match ospfd.h changes. (ospf_abr_translate_nssa): make it work, using the new ospf_lsa translation functions. (Several places): change struct prefix * to struct prefix_ipv4 *. (might as well do the casts at higher levels). Add more debug info. (ospf_abr_announce_stub_defaults): announce default to NSSA areas too. (ospf_abr_announce_nssa_defaults): do nothing. this function probably should die. (see ospf_abr_announce_stub_defaults). (ospf_abr_task_timer): run NSSA tasks.
2003-07-12 23:30:57 +02:00
ospf_abr_nssa_check_status(ospf);
2002-12-13 21:15:29 +01:00
ospf_abr_task(ospf);
ospf_abr_nssa_task(ospf); /* if nssa-abr, then scan Type-7 LSDB */
2002-12-13 21:15:29 +01:00
return 0;
2002-12-13 21:15:29 +01:00
}
void ospf_schedule_abr_task(struct ospf *ospf)
2002-12-13 21:15:29 +01:00
{
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);
2002-12-13 21:15:29 +01:00
}