#include "log.h"
#include "sockunion.h" /* for inet_aton () */
#include "zclient.h"
+#include "routemap.h"
#include "plist.h"
#include "sockopt.h"
#include "bfd.h"
struct ospf_master *om;
extern struct zclient *zclient;
-extern struct in_addr router_id_zebra;
-extern struct zebra_privs_t ospfd_privs;
static void ospf_remove_vls_through_area(struct ospf *, struct ospf_area *);
else if (ospf->router_id.s_addr != 0)
router_id = ospf->router_id;
else
- router_id = router_id_zebra;
+ router_id = ospf->router_id_zebra;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("Router-ID[OLD:%s]: Update to %s",
- inet_ntoa(ospf->router_id),
- inet_ntoa(router_id_old));
+ inet_ntoa(ospf->router_id), inet_ntoa(router_id));
if (!IPV4_ADDR_SAME(&router_id_old, &router_id)) {
struct route_node *rn;
struct ospf_lsa *lsa;
- LSDB_LOOP(EXTERNAL_LSDB(ospf), rn, lsa)
- if (IS_LSA_SELF(lsa))
- ospf_lsa_flush_schedule(ospf, lsa);
+ LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa)
+ if (IS_LSA_SELF(lsa))
+ ospf_lsa_flush_schedule(ospf, lsa);
}
ospf->router_id = router_id;
struct route_node *rn;
struct ospf_lsa *lsa;
- LSDB_LOOP(EXTERNAL_LSDB(ospf), rn, lsa)
- {
+ LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa) {
/* AdvRouter and Router ID is the same. */
if (IPV4_ADDR_SAME(&lsa->data->adv_router,
&ospf->router_id)) {
new->name = XSTRDUP(MTYPE_OSPF_TOP, name);
vrf = vrf_lookup_by_name(new->name);
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("%s: Create new ospf instance with vrf_name %s vrf_id %d",
- __PRETTY_FUNCTION__, name, new->vrf_id);
+ zlog_debug(
+ "%s: Create new ospf instance with vrf_name %s vrf_id %u",
+ __PRETTY_FUNCTION__, name, new->vrf_id);
if (vrf)
ospf_vrf_link(new, vrf);
} else {
new->lsa_refresh_interval, &new->t_lsa_refresher);
new->lsa_refresher_started = monotime(NULL);
- if ((ospf_sock_init(new)) < 0) {
- zlog_err(
- "ospf_new: fatal error: ospf_sock_init was unable to open "
- "a socket");
- exit(1);
- }
if ((new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE + 1)) == NULL) {
zlog_err(
"ospf_new: fatal error: stream_new(%u) failed allocating ibuf",
exit(1);
}
new->t_read = NULL;
- thread_add_read(master, ospf_read, new, new->fd, &new->t_read);
new->oi_write_q = list_new();
new->write_oi_count = OSPF_WRITE_INTERFACE_COUNT_DEFAULT;
QOBJ_REG(new, ospf);
+ new->fd = -1;
+ if ((ospf_sock_init(new)) < 0) {
+ if (new->vrf_id != VRF_UNKNOWN)
+ zlog_warn(
+ "%s: ospf_sock_init is unable to open a socket",
+ __func__);
+ return new;
+ }
+ thread_add_read(master, ospf_read, new, new->fd, &new->t_read);
+
return new;
}
struct listnode *node, *nnode;
for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf)) {
- if ((ospf->instance == instance) &&
- ((ospf->name == NULL && name == NULL) ||
- (ospf->name && name && strcmp(ospf->name, name) == 0)))
+ if ((ospf->instance == instance)
+ && ((ospf->name == NULL && name == NULL)
+ || (ospf->name && name
+ && strcmp(ospf->name, name) == 0)))
return ospf;
}
return NULL;
ospf_router_id_update(ospf);
else {
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("%s: ospf VRF (id %d) is not active yet, skip router id update"
- , __PRETTY_FUNCTION__,
- ospf->vrf_id);
+ zlog_debug(
+ "%s: ospf VRF (id %d) is not active yet, skip router id update",
+ __PRETTY_FUNCTION__,
+ ospf->vrf_id);
}
ospf_router_id_update(ospf);
}
if (!vrf)
return NULL;
return (vrf->info) ? (struct ospf *)vrf->info : NULL;
-
}
/* It should only be used when processing incoming info update from zebra.
for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf))
if ((ospf->name == NULL && vrf_name == NULL)
- || (ospf->name && vrf_name &&
- strcmp(ospf->name, vrf_name) == 0))
+ || (ospf->name && vrf_name
+ && strcmp(ospf->name, vrf_name) == 0))
return ospf;
return NULL;
}
for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf))
ospf_finish(ospf);
+ /* Cleanup route maps */
+ route_map_add_hook(NULL);
+ route_map_delete_hook(NULL);
+ route_map_event_hook(NULL);
+ route_map_finish();
+
+ /* reverse prefix_list_init */
+ prefix_list_add_hook(NULL);
+ prefix_list_delete_hook(NULL);
+ prefix_list_reset();
+
+ /* Cleanup vrf info */
+ ospf_vrf_terminate();
+
/* Deliberately go back up, hopefully to thread scheduler, as
* One or more ospf_finish()'s may have deferred shutdown to a timer
* thread
ospf_opaque_type11_lsa_term(ospf);
- /* be nice if this worked, but it doesn't */
- /*ospf_flush_self_originated_lsas_now (ospf);*/
+ ospf_opaque_finish();
+
+ ospf_flush_self_originated_lsas_now(ospf);
/* Unregister redistribution */
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
OSPF_TIMER_OFF(ospf->t_read);
OSPF_TIMER_OFF(ospf->t_write);
OSPF_TIMER_OFF(ospf->t_opaque_lsa_self);
+ OSPF_TIMER_OFF(ospf->t_sr_update);
close(ospf->fd);
stream_free(ospf->ibuf);
- LSDB_LOOP(OPAQUE_AS_LSDB(ospf), rn, lsa)
- ospf_discard_from_db(ospf, ospf->lsdb, lsa);
- LSDB_LOOP(EXTERNAL_LSDB(ospf), rn, lsa)
- ospf_discard_from_db(ospf, ospf->lsdb, lsa);
+ LSDB_LOOP (OPAQUE_AS_LSDB(ospf), rn, lsa)
+ ospf_discard_from_db(ospf, ospf->lsdb, lsa);
+ LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa)
+ ospf_discard_from_db(ospf, ospf->lsdb, lsa);
ospf_lsdb_delete_all(ospf->lsdb);
ospf_lsdb_free(ospf->lsdb);
struct listnode *node;
struct ospf_external *ext;
- ext_list = om->external[i];
+ ext_list = ospf->external[i];
if (!ext_list)
continue;
ospf_opaque_type10_lsa_term(area);
/* Free LSDBs. */
- LSDB_LOOP(ROUTER_LSDB(area), rn, lsa)
- ospf_discard_from_db(area->ospf, area->lsdb, lsa);
- LSDB_LOOP(NETWORK_LSDB(area), rn, lsa)
- ospf_discard_from_db(area->ospf, area->lsdb, lsa);
- LSDB_LOOP(SUMMARY_LSDB(area), rn, lsa)
- ospf_discard_from_db(area->ospf, area->lsdb, lsa);
- LSDB_LOOP(ASBR_SUMMARY_LSDB(area), rn, lsa)
- ospf_discard_from_db(area->ospf, area->lsdb, lsa);
-
- LSDB_LOOP(NSSA_LSDB(area), rn, lsa)
- ospf_discard_from_db(area->ospf, area->lsdb, lsa);
- LSDB_LOOP(OPAQUE_AREA_LSDB(area), rn, lsa)
- ospf_discard_from_db(area->ospf, area->lsdb, lsa);
- LSDB_LOOP(OPAQUE_LINK_LSDB(area), rn, lsa)
- ospf_discard_from_db(area->ospf, area->lsdb, lsa);
+ LSDB_LOOP (ROUTER_LSDB(area), rn, lsa)
+ ospf_discard_from_db(area->ospf, area->lsdb, lsa);
+ LSDB_LOOP (NETWORK_LSDB(area), rn, lsa)
+ ospf_discard_from_db(area->ospf, area->lsdb, lsa);
+ LSDB_LOOP (SUMMARY_LSDB(area), rn, lsa)
+ ospf_discard_from_db(area->ospf, area->lsdb, lsa);
+ LSDB_LOOP (ASBR_SUMMARY_LSDB(area), rn, lsa)
+ ospf_discard_from_db(area->ospf, area->lsdb, lsa);
+
+ LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
+ ospf_discard_from_db(area->ospf, area->lsdb, lsa);
+ LSDB_LOOP (OPAQUE_AREA_LSDB(area), rn, lsa)
+ ospf_discard_from_db(area->ospf, area->lsdb, lsa);
+ LSDB_LOOP (OPAQUE_LINK_LSDB(area), rn, lsa)
+ ospf_discard_from_db(area->ospf, area->lsdb, lsa);
- ospf_opaque_type10_lsa_term(area);
ospf_lsdb_delete_all(area->lsdb);
ospf_lsdb_free(area->lsdb);
struct external_info *ei;
struct ospf_external *ext;
- if (ospf_is_type_redistributed(ospf, ZEBRA_ROUTE_CONNECT, 0))
- if ((ext = ospf_external_lookup(ZEBRA_ROUTE_CONNECT, 0))
- && EXTERNAL_INFO(ext)) {
+ if (ospf_is_type_redistributed(ospf, ZEBRA_ROUTE_CONNECT, 0)) {
+ ext = ospf_external_lookup(ospf, ZEBRA_ROUTE_CONNECT, 0);
+ if ((ext) && EXTERNAL_INFO(ext)) {
for (rn = route_top(EXTERNAL_INFO(ext)); rn;
rn = route_next(rn)) {
- if ((ei = rn->info) != NULL) {
- if (add_to_ospf) {
- if (ospf_external_info_find_lsa(
- ospf, &ei->p))
- if (!ospf_distribute_check_connected(
- ospf, ei))
- ospf_external_lsa_flush(
- ospf,
- ei->type,
- &ei->p,
- ei->ifindex /*, ei->nexthop */);
- } else {
- if (!ospf_external_info_find_lsa(
- ospf, &ei->p))
- if (ospf_distribute_check_connected(
- ospf, ei))
- ospf_external_lsa_originate(
- ospf,
- ei);
- }
+ ei = rn->info;
+ if (ei == NULL)
+ continue;
+
+ if (add_to_ospf) {
+ if (ospf_external_info_find_lsa(ospf,
+ &ei->p))
+ if (!ospf_distribute_check_connected(
+ ospf, ei))
+ ospf_external_lsa_flush(
+ ospf, ei->type,
+ &ei->p,
+ ei->ifindex /*, ei->nexthop */);
+ } else {
+ if (!ospf_external_info_find_lsa(
+ ospf, &ei->p))
+ if (ospf_distribute_check_connected(
+ ospf, ei))
+ ospf_external_lsa_originate(
+ ospf, ei);
}
}
}
+ }
}
/* Config network statement related functions. */
rn = route_node_get(ospf->networks, (struct prefix *)p);
if (rn->info) {
- /* There is already same network statement. */
+ network = rn->info;
route_unlock_node(rn);
- return 0;
+
+ if (IPV4_ADDR_SAME(&area_id, &network->area_id)) {
+ return 1;
+ } else {
+ /* There is already same network statement. */
+ return 0;
+ }
}
rn->info = network = ospf_network_new(area_id);
/* Find interfaces that are not configured already. */
for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) {
- if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
- continue;
+ if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
+ continue;
- ospf_network_run_subnet(ospf, oi->connected, NULL, NULL);
+ ospf_network_run_subnet(ospf, oi->connected, NULL, NULL);
}
/* Update connected redistribute. */
return;
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("%s: interface %s ifp->vrf_id %u ospf vrf %s vrf_id %u router_id %s",
- __PRETTY_FUNCTION__, ifp->name, ifp->vrf_id,
- ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id,
- inet_ntoa(ospf->router_id));
+ zlog_debug(
+ "%s: interface %s ifp->vrf_id %u ospf vrf %s vrf_id %u router_id %s",
+ __PRETTY_FUNCTION__, ifp->name, ifp->vrf_id,
+ ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id,
+ inet_ntoa(ospf->router_id));
/* OSPF must be ready. */
if (!ospf_is_ready(ospf))
static int ospf_vrf_new(struct vrf *vrf)
{
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("%s: VRF Created: %s(%d)", __PRETTY_FUNCTION__,
+ zlog_debug("%s: VRF Created: %s(%u)", __PRETTY_FUNCTION__,
vrf->name, vrf->vrf_id);
return 0;
static int ospf_vrf_delete(struct vrf *vrf)
{
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("%s: VRF Deletion: %s(%d)", __PRETTY_FUNCTION__,
+ zlog_debug("%s: VRF Deletion: %s(%u)", __PRETTY_FUNCTION__,
vrf->name, vrf->vrf_id);
return 0;
static int ospf_vrf_enable(struct vrf *vrf)
{
struct ospf *ospf = NULL;
- vrf_id_t old_vrf_id = VRF_DEFAULT;
+ vrf_id_t old_vrf_id;
+ int ret = 0;
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("%s: VRF %s id %d enabled",
- __PRETTY_FUNCTION__, vrf->name, vrf->vrf_id);
+ zlog_debug("%s: VRF %s id %u enabled", __PRETTY_FUNCTION__,
+ vrf->name, vrf->vrf_id);
ospf = ospf_lookup_by_name(vrf->name);
if (ospf) {
/* We have instance configured, link to VRF and make it "up". */
ospf_vrf_link(ospf, vrf);
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("%s: ospf linked to vrf %s vrf_id %d (old id %d)",
- __PRETTY_FUNCTION__, vrf->name, ospf->vrf_id,
- old_vrf_id);
+ zlog_debug(
+ "%s: ospf linked to vrf %s vrf_id %u (old id %u)",
+ __PRETTY_FUNCTION__, vrf->name, ospf->vrf_id,
+ old_vrf_id);
if (old_vrf_id != ospf->vrf_id) {
if (ospfd_privs.change(ZPRIVS_RAISE)) {
- zlog_err("ospf_sock_init: could not raise privs, %s",
- safe_strerror(errno));
+ zlog_err(
+ "ospf_sock_init: could not raise privs, %s",
+ safe_strerror(errno));
}
- if (ospf_bind_vrfdevice(ospf, ospf->fd) < 0)
- return 0;
+ ret = ospf_sock_init(ospf);
if (ospfd_privs.change(ZPRIVS_LOWER)) {
- zlog_err("ospf_sock_init: could not lower privs, %s",
- safe_strerror(errno));
+ zlog_err(
+ "ospf_sock_init: could not lower privs, %s",
+ safe_strerror(errno));
}
-
+ if (ret < 0 || ospf->fd <= 0)
+ return 0;
+ thread_add_read(master, ospf_read, ospf, ospf->fd,
+ &ospf->t_read);
ospf->oi_running = 1;
+ ospf_zebra_vrf_register(ospf);
ospf_router_id_update(ospf);
}
}
return 0;
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("%s: VRF %s id %d disabled.",
- __PRETTY_FUNCTION__, vrf->name, vrf->vrf_id);
+ zlog_debug("%s: VRF %s id %d disabled.", __PRETTY_FUNCTION__,
+ vrf->name, vrf->vrf_id);
ospf = ospf_lookup_by_name(vrf->name);
if (ospf) {
ospf->oi_running = 0;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("%s: ospf old_vrf_id %d unlinked",
- __PRETTY_FUNCTION__, old_vrf_id);
+ __PRETTY_FUNCTION__, old_vrf_id);
+ thread_cancel(ospf->t_read);
+ close(ospf->fd);
+ ospf->fd = -1;
}
/* Note: This is a callback, the VRF will be deleted by the caller. */
void ospf_vrf_init(void)
{
- vrf_init(ospf_vrf_new, ospf_vrf_enable,
- ospf_vrf_disable, ospf_vrf_delete);
+ vrf_init(ospf_vrf_new, ospf_vrf_enable, ospf_vrf_disable,
+ ospf_vrf_delete);
}
void ospf_vrf_terminate(void)