version 1.1.1.3, 2013/07/21 23:54:40
|
version 1.1.1.4, 2016/11/02 10:09:12
|
Line 53 Software Foundation, Inc., 59 Temple Place - Suite 330
|
Line 53 Software Foundation, Inc., 59 Temple Place - Suite 330
|
#include "ospfd/ospf_route.h" |
#include "ospfd/ospf_route.h" |
#include "ospfd/ospf_ase.h" |
#include "ospfd/ospf_ase.h" |
|
|
|
|
|
|
|
|
/* OSPF process wide configuration. */ |
/* OSPF process wide configuration. */ |
static struct ospf_master ospf_master; |
static struct ospf_master ospf_master; |
|
|
Line 64 struct ospf_master *om;
|
Line 64 struct ospf_master *om;
|
extern struct zclient *zclient; |
extern struct zclient *zclient; |
extern struct in_addr router_id_zebra; |
extern struct in_addr router_id_zebra; |
|
|
| |
static void ospf_remove_vls_through_area (struct ospf *, struct ospf_area *); |
static void ospf_remove_vls_through_area (struct ospf *, struct ospf_area *); |
static void ospf_network_free (struct ospf *, struct ospf_network *); |
static void ospf_network_free (struct ospf *, struct ospf_network *); |
static void ospf_area_free (struct ospf_area *); |
static void ospf_area_free (struct ospf_area *); |
static void ospf_network_run (struct prefix *, struct ospf_area *); |
static void ospf_network_run (struct prefix *, struct ospf_area *); |
static void ospf_network_run_interface (struct prefix *, struct ospf_area *, | static void ospf_network_run_interface (struct ospf *, struct interface *, |
struct interface *); | struct prefix *, struct ospf_area *); |
| static void ospf_network_run_subnet (struct ospf *, struct connected *, |
| struct prefix *, struct ospf_area *); |
static int ospf_network_match_iface (const struct connected *, |
static int ospf_network_match_iface (const struct connected *, |
const struct prefix *); |
const struct prefix *); |
static void ospf_finish_final (struct ospf *); |
static void ospf_finish_final (struct ospf *); |
|
|
#define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1 |
#define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1 |
| |
void |
void |
ospf_router_id_update (struct ospf *ospf) |
ospf_router_id_update (struct ospf *ospf) |
{ |
{ |
Line 112 ospf_router_id_update (struct ospf *ospf)
|
Line 114 ospf_router_id_update (struct ospf *ospf)
|
if (!IPV4_ADDR_SAME (&router_id_old, &router_id)) |
if (!IPV4_ADDR_SAME (&router_id_old, &router_id)) |
{ |
{ |
for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) |
for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) |
/* Update self-neighbor's router_id. */ | { |
oi->nbr_self->router_id = router_id; | /* Some nbrs are identified by router_id, these needs |
| * to be rebuilt. Possible optimization would be to do |
| * oi->nbr_self->router_id = router_id for |
| * !(virtual | ptop) links |
| */ |
| ospf_nbr_self_reset (oi); |
| } |
|
|
/* If AS-external-LSA is queued, then flush those LSAs. */ |
/* If AS-external-LSA is queued, then flush those LSAs. */ |
if (router_id_old.s_addr == 0 && ospf->external_origin) |
if (router_id_old.s_addr == 0 && ospf->external_origin) |
Line 139 ospf_router_id_update (struct ospf *ospf)
|
Line 147 ospf_router_id_update (struct ospf *ospf)
|
ospf_if_update (ospf, ifp); |
ospf_if_update (ospf, ifp); |
} |
} |
} |
} |
| |
/* For OSPF area sort by area id. */ |
/* For OSPF area sort by area id. */ |
static int |
static int |
ospf_area_id_cmp (struct ospf_area *a1, struct ospf_area *a2) |
ospf_area_id_cmp (struct ospf_area *a1, struct ospf_area *a2) |
Line 193 ospf_new (void)
|
Line 201 ospf_new (void)
|
new->default_metric = -1; |
new->default_metric = -1; |
new->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH; |
new->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH; |
|
|
|
/* LSA timers */ |
|
new->min_ls_interval = OSPF_MIN_LS_INTERVAL; |
|
new->min_ls_arrival = OSPF_MIN_LS_ARRIVAL; |
|
|
/* SPF timer value init. */ |
/* SPF timer value init. */ |
new->spf_delay = OSPF_SPF_DELAY_DEFAULT; |
new->spf_delay = OSPF_SPF_DELAY_DEFAULT; |
new->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT; |
new->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT; |
Line 200 ospf_new (void)
|
Line 212 ospf_new (void)
|
new->spf_hold_multiplier = 1; |
new->spf_hold_multiplier = 1; |
|
|
/* MaxAge init. */ |
/* MaxAge init. */ |
new->maxage_delay = OSFP_LSA_MAXAGE_REMOVE_DELAY_DEFAULT; | new->maxage_delay = OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT; |
new->maxage_lsa = route_table_init(); |
new->maxage_lsa = route_table_init(); |
new->t_maxage_walker = |
new->t_maxage_walker = |
thread_add_timer (master, ospf_lsa_maxage_walker, |
thread_add_timer (master, ospf_lsa_maxage_walker, |
Line 246 ospf_lookup ()
|
Line 258 ospf_lookup ()
|
return listgetdata (listhead (om->ospf)); |
return listgetdata (listhead (om->ospf)); |
} |
} |
|
|
|
static int |
|
ospf_is_ready (struct ospf *ospf) |
|
{ |
|
/* OSPF must be on and Router-ID must be configured. */ |
|
if (!ospf || ospf->router_id.s_addr == 0) |
|
return 0; |
|
|
|
return 1; |
|
} |
|
|
static void |
static void |
ospf_add (struct ospf *ospf) |
ospf_add (struct ospf *ospf) |
{ |
{ |
Line 272 ospf_get ()
|
Line 294 ospf_get ()
|
if (ospf->router_id_static.s_addr == 0) |
if (ospf->router_id_static.s_addr == 0) |
ospf_router_id_update (ospf); |
ospf_router_id_update (ospf); |
|
|
#ifdef HAVE_OPAQUE_LSA |
|
ospf_opaque_type11_lsa_init (ospf); |
ospf_opaque_type11_lsa_init (ospf); |
#endif /* HAVE_OPAQUE_LSA */ |
|
} |
} |
|
|
return ospf; |
return ospf; |
} |
} |
| |
/* Handle the second half of deferred shutdown. This is called either |
/* Handle the second half of deferred shutdown. This is called either |
* from the deferred-shutdown timer thread, or directly through |
* from the deferred-shutdown timer thread, or directly through |
* ospf_deferred_shutdown_check. |
* ospf_deferred_shutdown_check. |
Line 354 ospf_deferred_shutdown_check (struct ospf *ospf)
|
Line 374 ospf_deferred_shutdown_check (struct ospf *ospf)
|
timeout); |
timeout); |
return; |
return; |
} |
} |
| |
/* Shut down the entire process */ |
/* Shut down the entire process */ |
void |
void |
ospf_terminate (void) |
ospf_terminate (void) |
Line 407 ospf_finish_final (struct ospf *ospf)
|
Line 427 ospf_finish_final (struct ospf *ospf)
|
struct listnode *node, *nnode; |
struct listnode *node, *nnode; |
int i; |
int i; |
|
|
#ifdef HAVE_OPAQUE_LSA |
|
ospf_opaque_type11_lsa_term (ospf); |
ospf_opaque_type11_lsa_term (ospf); |
#endif /* HAVE_OPAQUE_LSA */ |
|
|
|
/* be nice if this worked, but it doesn't */ |
/* be nice if this worked, but it doesn't */ |
/*ospf_flush_self_originated_lsas_now (ospf);*/ |
/*ospf_flush_self_originated_lsas_now (ospf);*/ |
Line 485 ospf_finish_final (struct ospf *ospf)
|
Line 503 ospf_finish_final (struct ospf *ospf)
|
OSPF_TIMER_OFF (ospf->t_lsa_refresher); |
OSPF_TIMER_OFF (ospf->t_lsa_refresher); |
OSPF_TIMER_OFF (ospf->t_read); |
OSPF_TIMER_OFF (ospf->t_read); |
OSPF_TIMER_OFF (ospf->t_write); |
OSPF_TIMER_OFF (ospf->t_write); |
#ifdef HAVE_OPAQUE_LSA |
|
OSPF_TIMER_OFF (ospf->t_opaque_lsa_self); |
OSPF_TIMER_OFF (ospf->t_opaque_lsa_self); |
#endif |
|
|
|
close (ospf->fd); |
close (ospf->fd); |
stream_free(ospf->ibuf); |
stream_free(ospf->ibuf); |
|
|
#ifdef HAVE_OPAQUE_LSA |
|
LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa) |
LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa) |
ospf_discard_from_db (ospf, ospf->lsdb, lsa); |
ospf_discard_from_db (ospf, ospf->lsdb, lsa); |
#endif /* HAVE_OPAQUE_LSA */ |
|
LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa) |
LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa) |
ospf_discard_from_db (ospf, ospf->lsdb, lsa); |
ospf_discard_from_db (ospf, ospf->lsdb, lsa); |
|
|
Line 563 ospf_finish_final (struct ospf *ospf)
|
Line 577 ospf_finish_final (struct ospf *ospf)
|
XFREE (MTYPE_OSPF_TOP, ospf); |
XFREE (MTYPE_OSPF_TOP, ospf); |
} |
} |
|
|
| |
/* allocate new OSPF Area object */ |
/* allocate new OSPF Area object */ |
static struct ospf_area * |
static struct ospf_area * |
ospf_area_new (struct ospf *ospf, struct in_addr area_id) |
ospf_area_new (struct ospf *ospf, struct in_addr area_id) |
Line 587 ospf_area_new (struct ospf *ospf, struct in_addr area_
|
Line 601 ospf_area_new (struct ospf *ospf, struct in_addr area_
|
/* Self-originated LSAs initialize. */ |
/* Self-originated LSAs initialize. */ |
new->router_lsa_self = NULL; |
new->router_lsa_self = NULL; |
|
|
#ifdef HAVE_OPAQUE_LSA |
|
ospf_opaque_type10_lsa_init (new); |
ospf_opaque_type10_lsa_init (new); |
#endif /* HAVE_OPAQUE_LSA */ |
|
|
|
new->oiflist = list_new (); |
new->oiflist = list_new (); |
new->ranges = route_table_init (); |
new->ranges = route_table_init (); |
Line 618 ospf_area_free (struct ospf_area *area)
|
Line 630 ospf_area_free (struct ospf_area *area)
|
|
|
LSDB_LOOP (NSSA_LSDB (area), rn, lsa) |
LSDB_LOOP (NSSA_LSDB (area), rn, lsa) |
ospf_discard_from_db (area->ospf, area->lsdb, lsa); |
ospf_discard_from_db (area->ospf, area->lsdb, lsa); |
#ifdef HAVE_OPAQUE_LSA |
|
LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa) |
LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa) |
ospf_discard_from_db (area->ospf, area->lsdb, lsa); |
ospf_discard_from_db (area->ospf, area->lsdb, lsa); |
LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa) |
LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa) |
ospf_discard_from_db (area->ospf, area->lsdb, lsa); |
ospf_discard_from_db (area->ospf, area->lsdb, lsa); |
#endif /* HAVE_OPAQUE_LSA */ |
|
|
|
ospf_lsdb_delete_all (area->lsdb); |
ospf_lsdb_delete_all (area->lsdb); |
ospf_lsdb_free (area->lsdb); |
ospf_lsdb_free (area->lsdb); |
Line 641 ospf_area_free (struct ospf_area *area)
|
Line 651 ospf_area_free (struct ospf_area *area)
|
|
|
/* Cancel timer. */ |
/* Cancel timer. */ |
OSPF_TIMER_OFF (area->t_stub_router); |
OSPF_TIMER_OFF (area->t_stub_router); |
#ifdef HAVE_OPAQUE_LSA |
|
OSPF_TIMER_OFF (area->t_opaque_lsa_self); |
OSPF_TIMER_OFF (area->t_opaque_lsa_self); |
#endif /* HAVE_OPAQUE_LSA */ |
|
|
|
if (OSPF_IS_AREA_BACKBONE (area)) |
if (OSPF_IS_AREA_BACKBONE (area)) |
area->ospf->backbone = NULL; |
area->ospf->backbone = NULL; |
Line 719 ospf_area_del_if (struct ospf_area *area, struct ospf_
|
Line 727 ospf_area_del_if (struct ospf_area *area, struct ospf_
|
listnode_delete (area->oiflist, oi); |
listnode_delete (area->oiflist, oi); |
} |
} |
|
|
| |
/* Config network statement related functions. */ |
/* Config network statement related functions. */ |
static struct ospf_network * |
static struct ospf_network * |
ospf_network_new (struct in_addr area_id, int format) |
ospf_network_new (struct in_addr area_id, int format) |
Line 733 ospf_network_new (struct in_addr area_id, int format)
|
Line 741 ospf_network_new (struct in_addr area_id, int format)
|
return new; |
return new; |
} |
} |
|
|
|
static void |
|
add_ospf_interface (struct connected *co, struct ospf_area *area) |
|
{ |
|
struct ospf_interface *oi; |
|
|
|
oi = ospf_if_new (area->ospf, co->ifp, co->address); |
|
oi->connected = co; |
|
|
|
oi->area = area; |
|
|
|
oi->params = ospf_lookup_if_params (co->ifp, oi->address->u.prefix4); |
|
oi->output_cost = ospf_if_get_output_cost (oi); |
|
|
|
/* Add pseudo neighbor. */ |
|
ospf_nbr_add_self (oi); |
|
|
|
/* Relate ospf interface to ospf instance. */ |
|
oi->ospf = area->ospf; |
|
|
|
/* update network type as interface flag */ |
|
/* If network type is specified previously, |
|
skip network type setting. */ |
|
oi->type = IF_DEF_PARAMS (co->ifp)->type; |
|
|
|
ospf_area_add_if (oi->area, oi); |
|
|
|
/* if router_id is not configured, dont bring up |
|
* interfaces. |
|
* ospf_router_id_update() will call ospf_if_update |
|
* whenever r-id is configured instead. |
|
*/ |
|
if ((area->ospf->router_id.s_addr != 0) |
|
&& if_is_operative (co->ifp)) |
|
ospf_if_up (oi); |
|
} |
|
|
static void |
static void |
|
update_redistributed (struct ospf *ospf, int add_to_ospf) |
|
{ |
|
struct route_node *rn; |
|
struct external_info *ei; |
|
|
|
if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT)) |
|
if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT)) |
|
for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT)); |
|
rn; rn = route_next (rn)) |
|
if ((ei = rn->info) != NULL) |
|
{ |
|
if (add_to_ospf) |
|
{ |
|
if (ospf_external_info_find_lsa (ospf, &ei->p)) |
|
if (!ospf_distribute_check_connected (ospf, ei)) |
|
ospf_external_lsa_flush (ospf, ei->type, &ei->p, |
|
ei->ifindex /*, ei->nexthop */); |
|
} |
|
else |
|
{ |
|
if (!ospf_external_info_find_lsa (ospf, &ei->p)) |
|
if (ospf_distribute_check_connected (ospf, ei)) |
|
ospf_external_lsa_originate (ospf, ei); |
|
} |
|
} |
|
} |
|
|
|
static void |
ospf_network_free (struct ospf *ospf, struct ospf_network *network) |
ospf_network_free (struct ospf *ospf, struct ospf_network *network) |
{ |
{ |
ospf_area_check_free (ospf, network->area_id); |
ospf_area_check_free (ospf, network->area_id); |
Line 748 ospf_network_set (struct ospf *ospf, struct prefix_ipv
|
Line 820 ospf_network_set (struct ospf *ospf, struct prefix_ipv
|
struct ospf_network *network; |
struct ospf_network *network; |
struct ospf_area *area; |
struct ospf_area *area; |
struct route_node *rn; |
struct route_node *rn; |
struct external_info *ei; |
|
int ret = OSPF_AREA_ID_FORMAT_ADDRESS; |
int ret = OSPF_AREA_ID_FORMAT_ADDRESS; |
|
|
rn = route_node_get (ospf->networks, (struct prefix *)p); |
rn = route_node_get (ospf->networks, (struct prefix *)p); |
Line 766 ospf_network_set (struct ospf *ospf, struct prefix_ipv
|
Line 837 ospf_network_set (struct ospf *ospf, struct prefix_ipv
|
ospf_network_run ((struct prefix *)p, area); |
ospf_network_run ((struct prefix *)p, area); |
|
|
/* Update connected redistribute. */ |
/* Update connected redistribute. */ |
if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT)) | update_redistributed(ospf, 1); |
if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT)) | |
for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT)); | |
rn; rn = route_next (rn)) | |
if ((ei = rn->info) != NULL) | |
if (ospf_external_info_find_lsa (ospf, &ei->p)) | |
if (!ospf_distribute_check_connected (ospf, ei)) | |
ospf_external_lsa_flush (ospf, ei->type, &ei->p, | |
ei->ifindex /*, ei->nexthop */); | |
| |
ospf_area_check_free (ospf, area_id); |
ospf_area_check_free (ospf, area_id); |
|
|
return 1; |
return 1; |
Line 787 ospf_network_unset (struct ospf *ospf, struct prefix_i
|
Line 850 ospf_network_unset (struct ospf *ospf, struct prefix_i
|
{ |
{ |
struct route_node *rn; |
struct route_node *rn; |
struct ospf_network *network; |
struct ospf_network *network; |
struct external_info *ei; |
|
struct listnode *node, *nnode; |
struct listnode *node, *nnode; |
struct ospf_interface *oi; |
struct ospf_interface *oi; |
|
|
Line 807 ospf_network_unset (struct ospf *ospf, struct prefix_i
|
Line 869 ospf_network_unset (struct ospf *ospf, struct prefix_i
|
/* Find interfaces that not configured already. */ |
/* Find interfaces that not configured already. */ |
for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) |
for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) |
{ |
{ |
int found = 0; |
|
struct connected *co = oi->connected; |
|
|
|
if (oi->type == OSPF_IFTYPE_VIRTUALLINK) |
if (oi->type == OSPF_IFTYPE_VIRTUALLINK) |
continue; |
continue; |
|
|
for (rn = route_top (ospf->networks); rn; rn = route_next (rn)) | ospf_network_run_subnet (ospf, oi->connected, NULL, NULL); |
{ | |
if (rn->info == NULL) | |
continue; | |
| |
if (ospf_network_match_iface(co,&rn->p)) | |
{ | |
found = 1; | |
route_unlock_node (rn); | |
break; | |
} | |
} | |
| |
if (found == 0) | |
ospf_if_free (oi); | |
} |
} |
|
|
/* Update connected redistribute. */ |
/* Update connected redistribute. */ |
if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT)) | update_redistributed(ospf, 0); |
if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT)) | |
for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT)); | ospf_area_check_free (ospf, area_id); |
rn; rn = route_next (rn)) | |
if ((ei = rn->info) != NULL) | |
if (!ospf_external_info_find_lsa (ospf, &ei->p)) | |
if (ospf_distribute_check_connected (ospf, ei)) | |
ospf_external_lsa_originate (ospf, ei); | |
| |
return 1; |
return 1; |
} |
} |
|
|
|
/* Ensure there's an OSPF instance, as "ip ospf area" enabled OSPF means |
|
* there might not be any 'router ospf' config. |
|
* |
|
* Otherwise, doesn't do anything different to ospf_if_update for now |
|
*/ |
|
void |
|
ospf_interface_area_set (struct interface *ifp) |
|
{ |
|
struct ospf *ospf = ospf_get(); |
|
|
|
ospf_if_update (ospf, ifp); |
|
/* if_update does a update_redistributed */ |
|
|
|
return; |
|
} |
|
|
|
void |
|
ospf_interface_area_unset (struct interface *ifp) |
|
{ |
|
struct route_node *rn_oi; |
|
struct ospf *ospf; |
|
|
|
if ((ospf = ospf_lookup ()) == NULL) |
|
return; /* Ospf not ready yet */ |
|
|
|
/* Find interfaces that may need to be removed. */ |
|
for (rn_oi = route_top (IF_OIFS (ifp)); rn_oi; rn_oi = route_next (rn_oi)) |
|
{ |
|
struct ospf_interface *oi; |
|
|
|
if ( (oi = rn_oi->info) == NULL) |
|
continue; |
|
|
|
if (oi->type == OSPF_IFTYPE_VIRTUALLINK) |
|
continue; |
|
|
|
ospf_network_run_subnet (ospf, oi->connected, NULL, NULL); |
|
} |
|
|
|
/* Update connected redistribute. */ |
|
update_redistributed (ospf, 0); /* interfaces possibly removed */ |
|
|
|
return; |
|
} |
|
|
|
|
/* Check whether interface matches given network |
/* Check whether interface matches given network |
* returns: 1, true. 0, false |
* returns: 1, true. 0, false |
*/ |
*/ |
Line 854 ospf_network_match_iface(const struct connected *co, c
|
Line 940 ospf_network_match_iface(const struct connected *co, c
|
} |
} |
|
|
static void |
static void |
ospf_network_run_interface (struct prefix *p, struct ospf_area *area, | ospf_update_interface_area (struct connected *co, struct ospf_area *area) |
struct interface *ifp) | |
{ |
{ |
|
struct ospf_interface *oi = ospf_if_table_lookup (co->ifp, co->address); |
|
|
|
/* nothing to be done case */ |
|
if (oi && oi->area == area) |
|
return; |
|
|
|
if (oi) |
|
ospf_if_free (oi); |
|
|
|
add_ospf_interface (co, area); |
|
} |
|
|
|
/* Run OSPF for the given subnet, taking into account the following |
|
* possible sources of area configuration, in the given order of preference: |
|
* |
|
* - Whether there is interface+address specific area configuration |
|
* - Whether there is a default area for the interface |
|
* - Whether there is an area given as a parameter. |
|
* - If no specific network prefix/area is supplied, whether there's |
|
* a matching network configured. |
|
*/ |
|
static void |
|
ospf_network_run_subnet (struct ospf *ospf, struct connected *co, |
|
struct prefix *p, struct ospf_area *given_area) |
|
{ |
|
struct ospf_interface *oi; |
|
struct ospf_if_params *params; |
|
struct ospf_area *area = NULL; |
|
struct route_node *rn; |
|
int configed = 0; |
|
|
|
if (CHECK_FLAG(co->flags, ZEBRA_IFA_SECONDARY)) |
|
return; |
|
|
|
if (co->address->family != AF_INET) |
|
return; |
|
|
|
/* Try determine the appropriate area for this interface + address |
|
* Start by checking interface config |
|
*/ |
|
if (!(params = ospf_lookup_if_params (co->ifp, co->address->u.prefix4))) |
|
params = IF_DEF_PARAMS (co->ifp); |
|
|
|
if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) |
|
area = (ospf_area_get (ospf, params->if_area, |
|
OSPF_AREA_ID_FORMAT_ADDRESS)); |
|
|
|
/* If we've found an interface and/or addr specific area, then we're |
|
* done |
|
*/ |
|
if (area) |
|
{ |
|
ospf_update_interface_area (co, area); |
|
return; |
|
} |
|
|
|
/* Otherwise, only remaining possibility is a matching network statement */ |
|
if (p) |
|
{ |
|
assert (given_area != NULL); |
|
|
|
/* Which either was supplied as a parameter.. (e.g. cause a new |
|
* network/area was just added).. |
|
*/ |
|
if (p->family == co->address->family |
|
&& ospf_network_match_iface (co, p)) |
|
ospf_update_interface_area (co, given_area); |
|
|
|
return; |
|
} |
|
|
|
/* Else we have to search the existing network/area config to see |
|
* if any match.. |
|
*/ |
|
for (rn = route_top (ospf->networks); rn; rn = route_next (rn)) |
|
if (rn->info != NULL |
|
&& ospf_network_match_iface (co, &rn->p)) |
|
{ |
|
struct ospf_network *network = (struct ospf_network *) rn->info; |
|
area = ospf_area_get (ospf, network->area_id, network->format); |
|
ospf_update_interface_area (co, area); |
|
configed = 1; |
|
} |
|
|
|
/* If the subnet isn't in any area, deconfigure */ |
|
if (!configed && (oi = ospf_if_table_lookup (co->ifp, co->address))) |
|
ospf_if_free (oi); |
|
} |
|
|
|
static void |
|
ospf_network_run_interface (struct ospf *ospf, struct interface *ifp, |
|
struct prefix *p, |
|
struct ospf_area *given_area) |
|
{ |
struct listnode *cnode; |
struct listnode *cnode; |
struct connected *co; |
struct connected *co; |
|
|
if (memcmp (ifp->name, "VLINK", 5) == 0) |
if (memcmp (ifp->name, "VLINK", 5) == 0) |
return; |
return; |
|
|
|
/* Network prefix without area is nonsensical */ |
|
if (p) |
|
assert (given_area != NULL); |
|
|
/* if interface prefix is match specified prefix, |
/* if interface prefix is match specified prefix, |
then create socket and join multicast group. */ |
then create socket and join multicast group. */ |
for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co)) |
for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co)) |
{ | ospf_network_run_subnet (ospf, co, p, given_area); |
| |
if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY)) | |
continue; | |
| |
if (p->family == co->address->family | |
&& ! ospf_if_table_lookup(ifp, co->address) | |
&& ospf_network_match_iface(co,p)) | |
{ | |
struct ospf_interface *oi; | |
| |
oi = ospf_if_new (area->ospf, ifp, co->address); | |
oi->connected = co; | |
| |
oi->area = area; | |
| |
oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4); | |
oi->output_cost = ospf_if_get_output_cost (oi); | |
| |
/* Add pseudo neighbor. */ | |
ospf_nbr_add_self (oi); | |
| |
/* Relate ospf interface to ospf instance. */ | |
oi->ospf = area->ospf; | |
| |
/* update network type as interface flag */ | |
/* If network type is specified previously, | |
skip network type setting. */ | |
oi->type = IF_DEF_PARAMS (ifp)->type; | |
| |
ospf_area_add_if (oi->area, oi); | |
| |
/* if router_id is not configured, dont bring up | |
* interfaces. | |
* ospf_router_id_update() will call ospf_if_update | |
* whenever r-id is configured instead. | |
*/ | |
if ((area->ospf->router_id.s_addr != 0) | |
&& if_is_operative (ifp)) | |
ospf_if_up (oi); | |
} | |
} | |
} |
} |
|
|
static void |
static void |
Line 922 ospf_network_run (struct prefix *p, struct ospf_area *
|
Line 1064 ospf_network_run (struct prefix *p, struct ospf_area *
|
|
|
/* Get target interface. */ |
/* Get target interface. */ |
for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp)) |
for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp)) |
ospf_network_run_interface (p, area, ifp); | ospf_network_run_interface (area->ospf, ifp, p, area); |
} |
} |
|
|
void |
void |
Line 955 ospf_ls_upd_queue_empty (struct ospf_interface *oi)
|
Line 1097 ospf_ls_upd_queue_empty (struct ospf_interface *oi)
|
void |
void |
ospf_if_update (struct ospf *ospf, struct interface *ifp) |
ospf_if_update (struct ospf *ospf, struct interface *ifp) |
{ |
{ |
struct route_node *rn; |
|
struct ospf_network *network; |
|
struct ospf_area *area; |
|
|
|
if (!ospf) |
if (!ospf) |
ospf = ospf_lookup (); |
ospf = ospf_lookup (); |
|
|
/* OSPF must be on and Router-ID must be configured. */ | /* OSPF must be ready. */ |
if (!ospf || ospf->router_id.s_addr == 0) | if (!ospf_is_ready (ospf)) |
return; |
return; |
|
|
/* Run each netowrk for this interface. */ | ospf_network_run_interface (ospf, ifp, NULL, NULL); |
for (rn = route_top (ospf->networks); rn; rn = route_next (rn)) | |
if (rn->info != NULL) | /* Update connected redistribute. */ |
{ | update_redistributed(ospf, 1); |
network = (struct ospf_network *) rn->info; | |
area = ospf_area_get (ospf, network->area_id, network->format); | |
ospf_network_run_interface (&rn->p, area, ifp); | |
} | |
} |
} |
|
|
void |
void |
Line 987 ospf_remove_vls_through_area (struct ospf *ospf, struc
|
Line 1121 ospf_remove_vls_through_area (struct ospf *ospf, struc
|
ospf_vl_delete (ospf, vl_data); |
ospf_vl_delete (ospf, vl_data); |
} |
} |
|
|
| |
static const struct message ospf_area_type_msg[] = |
static const struct message ospf_area_type_msg[] = |
{ |
{ |
{ OSPF_AREA_DEFAULT, "Default" }, |
{ OSPF_AREA_DEFAULT, "Default" }, |
Line 1350 ospf_timers_refresh_unset (struct ospf *ospf)
|
Line 1484 ospf_timers_refresh_unset (struct ospf *ospf)
|
return 1; |
return 1; |
} |
} |
|
|
| |
static struct ospf_nbr_nbma * |
static struct ospf_nbr_nbma * |
ospf_nbr_nbma_new (void) |
ospf_nbr_nbma_new (void) |
{ |
{ |
Line 1547 ospf_nbr_nbma_set (struct ospf *ospf, struct in_addr n
|
Line 1681 ospf_nbr_nbma_set (struct ospf *ospf, struct in_addr n
|
p.prefixlen = IPV4_MAX_BITLEN; |
p.prefixlen = IPV4_MAX_BITLEN; |
|
|
rn = route_node_get (ospf->nbr_nbma, (struct prefix *)&p); |
rn = route_node_get (ospf->nbr_nbma, (struct prefix *)&p); |
|
if (rn->info) |
|
route_unlock_node (rn); |
rn->info = nbr_nbma; |
rn->info = nbr_nbma; |
|
|
for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) |
for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) |