diff options
Diffstat (limited to 'ospfd/ospf_interface.c')
| -rw-r--r-- | ospfd/ospf_interface.c | 174 |
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); |
