summaryrefslogtreecommitdiff
path: root/ospfd/ospf_interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'ospfd/ospf_interface.c')
-rw-r--r--ospfd/ospf_interface.c174
1 files changed, 104 insertions, 70 deletions
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c
index 5742ece1f7..319db1efe2 100644
--- a/ospfd/ospf_interface.c
+++ b/ospfd/ospf_interface.c
@@ -101,6 +101,9 @@ int ospf_if_get_output_cost(struct ospf_interface *oi)
cost = 1;
else if (cost > 65535)
cost = 65535;
+
+ if (if_is_loopback(oi->ifp))
+ cost = 0;
}
return cost;
@@ -144,17 +147,11 @@ void ospf_if_reset(struct interface *ifp)
}
}
-void ospf_if_reset_variables(struct ospf_interface *oi)
+static void ospf_if_default_variables(struct ospf_interface *oi)
{
/* Set default values. */
- /* don't clear this flag. oi->flag = OSPF_IF_DISABLE; */
- if (oi->vl_data)
- oi->type = OSPF_IFTYPE_VIRTUALLINK;
- else
- /* preserve network-type */
- if (oi->type != OSPF_IFTYPE_NBMA)
- oi->type = OSPF_IFTYPE_BROADCAST;
+ oi->type = OSPF_IFTYPE_BROADCAST;
oi->state = ISM_Down;
@@ -251,7 +248,7 @@ struct ospf_interface *ospf_if_new(struct ospf *ospf, struct interface *ifp,
oi->ls_ack_direct.ls_ack = list_new();
/* Set default values. */
- ospf_if_reset_variables(oi);
+ ospf_if_default_variables(oi);
/* Set pseudo neighbor to Null */
oi->nbr_self = NULL;
@@ -268,6 +265,10 @@ struct ospf_interface *ospf_if_new(struct ospf *ospf, struct interface *ifp,
QOBJ_REG(oi, ospf_interface);
+ /* If first oi, check per-intf write socket */
+ if (ospf->oi_running && ospf->intf_socket_enabled)
+ ospf_ifp_sock_init(ifp);
+
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("%s: ospf interface %s vrf %s id %u created",
__func__, ifp->name, ospf_get_name(ospf),
@@ -324,12 +325,16 @@ void ospf_if_cleanup(struct ospf_interface *oi)
void ospf_if_free(struct ospf_interface *oi)
{
+ struct interface *ifp = oi->ifp;
+
ospf_if_down(oi);
ospf_fifo_free(oi->obuf);
assert(oi->state == ISM_Down);
+ ospf_opaque_type9_lsa_if_cleanup(oi);
+
ospf_opaque_type9_lsa_term(oi);
QOBJ_UNREG(oi);
@@ -358,6 +363,10 @@ void ospf_if_free(struct ospf_interface *oi)
event_cancel_event(master, oi);
+ /* If last oi, close per-interface socket */
+ if (ospf_oi_count(ifp) == 0)
+ ospf_ifp_sock_close(ifp);
+
memset(oi, 0, sizeof(*oi));
XFREE(MTYPE_OSPF_IF, oi);
}
@@ -367,26 +376,6 @@ int ospf_if_is_up(struct ospf_interface *oi)
return if_is_up(oi->ifp);
}
-struct ospf_interface *ospf_if_exists(struct ospf_interface *oic)
-{
- struct listnode *node;
- struct ospf *ospf;
- struct ospf_interface *oi;
-
- if (!oic)
- return NULL;
-
- ospf = oic->ospf;
- if (ospf == NULL)
- return NULL;
-
- for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi))
- if (oi == oic)
- return oi;
-
- return NULL;
-}
-
/* Lookup OSPF interface by router LSA posistion */
struct ospf_interface *ospf_if_lookup_by_lsa_pos(struct ospf_area *area,
int lsa_pos)
@@ -527,6 +516,7 @@ static struct ospf_if_params *ospf_new_if_params(void)
UNSET_IF_PARAM(oip, passive_interface);
UNSET_IF_PARAM(oip, v_hello);
UNSET_IF_PARAM(oip, fast_hello);
+ UNSET_IF_PARAM(oip, v_gr_hello_delay);
UNSET_IF_PARAM(oip, v_wait);
UNSET_IF_PARAM(oip, priority);
UNSET_IF_PARAM(oip, type);
@@ -534,6 +524,8 @@ static struct ospf_if_params *ospf_new_if_params(void)
UNSET_IF_PARAM(oip, auth_crypt);
UNSET_IF_PARAM(oip, auth_type);
UNSET_IF_PARAM(oip, if_area);
+ UNSET_IF_PARAM(oip, opaque_capable);
+ UNSET_IF_PARAM(oip, keychain_name);
oip->auth_crypt = list_new();
@@ -541,6 +533,8 @@ static struct ospf_if_params *ospf_new_if_params(void)
oip->is_v_wait_set = false;
oip->ptp_dmvpn = 0;
+ oip->p2mp_delay_reflood = OSPF_P2MP_DELAY_REFLOOD_DEFAULT;
+ oip->opaque_capable = OSPF_OPAQUE_CAPABLE_DEFAULT;
return oip;
}
@@ -549,6 +543,7 @@ static void ospf_del_if_params(struct interface *ifp,
struct ospf_if_params *oip)
{
list_delete(&oip->auth_crypt);
+ XFREE(MTYPE_OSPF_IF_PARAMS, oip->keychain_name);
ospf_interface_disable_bfd(ifp, oip);
ldp_sync_info_free(&(oip->ldp_sync_info));
XFREE(MTYPE_OSPF_IF_PARAMS, oip);
@@ -570,19 +565,22 @@ void ospf_free_if_params(struct interface *ifp, struct in_addr addr)
oip = rn->info;
route_unlock_node(rn);
- if (!OSPF_IF_PARAM_CONFIGURED(oip, output_cost_cmd)
- && !OSPF_IF_PARAM_CONFIGURED(oip, transmit_delay)
- && !OSPF_IF_PARAM_CONFIGURED(oip, retransmit_interval)
- && !OSPF_IF_PARAM_CONFIGURED(oip, passive_interface)
- && !OSPF_IF_PARAM_CONFIGURED(oip, v_hello)
- && !OSPF_IF_PARAM_CONFIGURED(oip, fast_hello)
- && !OSPF_IF_PARAM_CONFIGURED(oip, v_wait)
- && !OSPF_IF_PARAM_CONFIGURED(oip, priority)
- && !OSPF_IF_PARAM_CONFIGURED(oip, type)
- && !OSPF_IF_PARAM_CONFIGURED(oip, auth_simple)
- && !OSPF_IF_PARAM_CONFIGURED(oip, auth_type)
- && !OSPF_IF_PARAM_CONFIGURED(oip, if_area)
- && listcount(oip->auth_crypt) == 0) {
+ if (!OSPF_IF_PARAM_CONFIGURED(oip, output_cost_cmd) &&
+ !OSPF_IF_PARAM_CONFIGURED(oip, transmit_delay) &&
+ !OSPF_IF_PARAM_CONFIGURED(oip, retransmit_interval) &&
+ !OSPF_IF_PARAM_CONFIGURED(oip, passive_interface) &&
+ !OSPF_IF_PARAM_CONFIGURED(oip, v_hello) &&
+ !OSPF_IF_PARAM_CONFIGURED(oip, fast_hello) &&
+ !OSPF_IF_PARAM_CONFIGURED(oip, v_wait) &&
+ !OSPF_IF_PARAM_CONFIGURED(oip, priority) &&
+ !OSPF_IF_PARAM_CONFIGURED(oip, type) &&
+ !OSPF_IF_PARAM_CONFIGURED(oip, auth_simple) &&
+ !OSPF_IF_PARAM_CONFIGURED(oip, auth_type) &&
+ !OSPF_IF_PARAM_CONFIGURED(oip, if_area) &&
+ !OSPF_IF_PARAM_CONFIGURED(oip, opaque_capable) &&
+ !OSPF_IF_PARAM_CONFIGURED(oip, prefix_suppression) &&
+ !OSPF_IF_PARAM_CONFIGURED(oip, keychain_name) &&
+ listcount(oip->auth_crypt) == 0) {
ospf_del_if_params(ifp, oip);
rn->info = NULL;
route_unlock_node(rn);
@@ -676,6 +674,9 @@ int ospf_if_new_hook(struct interface *ifp)
SET_IF_PARAM(IF_DEF_PARAMS(ifp), fast_hello);
IF_DEF_PARAMS(ifp)->fast_hello = OSPF_FAST_HELLO_DEFAULT;
+ SET_IF_PARAM(IF_DEF_PARAMS(ifp), v_gr_hello_delay);
+ IF_DEF_PARAMS(ifp)->v_gr_hello_delay = OSPF_HELLO_DELAY_DEFAULT;
+
SET_IF_PARAM(IF_DEF_PARAMS(ifp), v_wait);
IF_DEF_PARAMS(ifp)->v_wait = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
@@ -685,6 +686,11 @@ int ospf_if_new_hook(struct interface *ifp)
SET_IF_PARAM(IF_DEF_PARAMS(ifp), auth_type);
IF_DEF_PARAMS(ifp)->auth_type = OSPF_AUTH_NOTSET;
+ SET_IF_PARAM(IF_DEF_PARAMS(ifp), opaque_capable);
+ IF_DEF_PARAMS(ifp)->opaque_capable = OSPF_OPAQUE_CAPABLE_DEFAULT;
+
+ IF_DEF_PARAMS(ifp)->prefix_suppression = OSPF_PREFIX_SUPPRESSION_DEFAULT;
+
rc = ospf_opaque_new_if(ifp);
return rc;
}
@@ -809,14 +815,41 @@ int ospf_if_up(struct ospf_interface *oi)
return 1;
}
-int ospf_if_down(struct ospf_interface *oi)
+/* This function will mark routes with next-hops matching the down
+ * OSPF interface as changed. It is used to assure routes that get
+ * removed from the zebra RIB when an interface goes down are
+ * reinstalled if the interface comes back up prior to an intervening
+ * SPF calculation.
+ */
+static void ospf_if_down_mark_routes_changed(struct route_table *table,
+ struct ospf_interface *oi)
{
- struct ospf *ospf;
struct route_node *rn;
struct ospf_route *or;
struct listnode *nh;
struct ospf_path *op;
+ for (rn = route_top(table); rn; rn = route_next(rn)) {
+ or = rn->info;
+
+ if (or == NULL)
+ continue;
+
+ for (nh = listhead(or->paths); nh;
+ nh = listnextnode_unchecked(nh)) {
+ op = listgetdata(nh);
+ if (op->ifindex == oi->ifp->ifindex) {
+ or->changed = true;
+ break;
+ }
+ }
+ }
+}
+
+int ospf_if_down(struct ospf_interface *oi)
+{
+ struct ospf *ospf;
+
if (oi == NULL)
return 0;
@@ -852,23 +885,11 @@ int ospf_if_down(struct ospf_interface *oi)
/* Shutdown packet reception and sending */
ospf_if_stream_unset(oi);
- if (!ospf->new_table)
- return 1;
- for (rn = route_top(ospf->new_table); rn; rn = route_next(rn)) {
- or = rn->info;
+ if (ospf->new_table)
+ ospf_if_down_mark_routes_changed(ospf->new_table, oi);
- if (!or)
- continue;
-
- for (nh = listhead(or->paths); nh;
- nh = listnextnode_unchecked(nh)) {
- op = listgetdata(nh);
- if (op->ifindex == oi->ifp->ifindex) {
- or->changed = true;
- break;
- }
- }
- }
+ if (ospf->new_external_route)
+ ospf_if_down_mark_routes_changed(ospf->new_external_route, oi);
return 1;
}
@@ -902,7 +923,7 @@ struct ospf_interface *ospf_vl_new(struct ospf *ospf,
{
struct ospf_interface *voi;
struct interface *vi;
- char ifname[INTERFACE_NAMSIZ];
+ char ifname[IFNAMSIZ];
struct ospf_area *area;
struct in_addr area_id;
struct connected *co;
@@ -932,7 +953,7 @@ struct ospf_interface *ospf_vl_new(struct ospf *ospf,
UNSET_FLAG(vi->status, ZEBRA_INTERFACE_LINKDETECTION);
co = connected_new();
co->ifp = vi;
- listnode_add(vi->connected, co);
+ if_connected_add_tail(vi->connected, co);
p = prefix_ipv4_new();
p->family = AF_INET;
@@ -1137,7 +1158,7 @@ static int ospf_vl_set_params(struct ospf_area *area,
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"found back link through VL");
- /* fallthru */
+ fallthrough;
case LSA_LINK_TYPE_TRANSIT:
case LSA_LINK_TYPE_POINTOPOINT:
if (!IPV4_ADDR_SAME(&vl_data->peer_addr,
@@ -1338,18 +1359,28 @@ static int ospf_ifp_create(struct interface *ifp)
if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
zlog_debug(
- "Zebra: interface add %s vrf %s[%u] index %d flags %llx metric %d mtu %d speed %u",
+ "Zebra: interface add %s vrf %s[%u] index %d flags %llx metric %d mtu %d speed %u status 0x%x",
ifp->name, ifp->vrf->name, ifp->vrf->vrf_id,
ifp->ifindex, (unsigned long long)ifp->flags,
- ifp->metric, ifp->mtu, ifp->speed);
+ ifp->metric, ifp->mtu, ifp->speed, ifp->status);
assert(ifp->info);
oii = ifp->info;
oii->curr_mtu = ifp->mtu;
- if (IF_DEF_PARAMS(ifp)
- && !OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp), type)) {
+ /* Change ospf type param based on following
+ * condition:
+ * ospf type params is not set (first creation),
+ * OR ospf param type is changed based on
+ * link event, currently only handle for
+ * loopback interface type, for other ospf interface,
+ * type can be set from user config which needs to be
+ * preserved.
+ */
+ if (IF_DEF_PARAMS(ifp) &&
+ (!OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp), type) ||
+ if_is_loopback(ifp))) {
SET_IF_PARAM(IF_DEF_PARAMS(ifp), type);
IF_DEF_PARAMS(ifp)->type = ospf_default_iftype(ifp);
}
@@ -1386,7 +1417,8 @@ static int ospf_ifp_up(struct interface *ifp)
/* Open per-intf write socket if configured */
ospf = ifp->vrf->info;
- if (ospf && ospf->intf_socket_enabled)
+
+ if (ospf && ospf->oi_running && ospf->intf_socket_enabled)
ospf_ifp_sock_init(ifp);
ospf_if_recalculate_output_cost(ifp);
@@ -1521,8 +1553,10 @@ void ospf_reset_hello_timer(struct interface *ifp, struct in_addr addr,
void ospf_if_init(void)
{
- if_zapi_callbacks(ospf_ifp_create, ospf_ifp_up,
- ospf_ifp_down, ospf_ifp_destroy);
+ hook_register_prio(if_real, 0, ospf_ifp_create);
+ hook_register_prio(if_up, 0, ospf_ifp_up);
+ hook_register_prio(if_down, 0, ospf_ifp_down);
+ hook_register_prio(if_unreal, 0, ospf_ifp_destroy);
/* Initialize Zebra interface data structure. */
hook_register_prio(if_add, 0, ospf_if_new_hook);