]> git.proxmox.com Git - mirror_frr.git/blobdiff - ospfd/ospf_interface.c
Merge pull request #5468 from qlyoung/bgpd-remove-bgp-attr-dup
[mirror_frr.git] / ospfd / ospf_interface.c
index 387770870811b45a0867c63bb210648695d80beb..7ddffbcdbdc36d289b076f7a8ac27cd2d762cae1 100644 (file)
@@ -50,6 +50,8 @@
 DEFINE_QOBJ_TYPE(ospf_interface)
 DEFINE_HOOK(ospf_vl_add, (struct ospf_vl_data * vd), (vd))
 DEFINE_HOOK(ospf_vl_delete, (struct ospf_vl_data * vd), (vd))
+DEFINE_HOOK(ospf_if_update, (struct interface * ifp), (ifp))
+DEFINE_HOOK(ospf_if_delete, (struct interface * ifp), (ifp))
 
 int ospf_interface_neighbor_count(struct ospf_interface *oi)
 {
@@ -271,7 +273,7 @@ struct ospf_interface *ospf_if_new(struct ospf *ospf, struct interface *ifp,
        if (IS_DEBUG_OSPF_EVENT)
                zlog_debug("%s: ospf interface %s vrf %s id %u created",
                           __PRETTY_FUNCTION__, ifp->name,
-                          ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id);
+                          ospf_get_name(ospf), ospf->vrf_id);
 
        return oi;
 }
@@ -830,7 +832,7 @@ struct ospf_interface *ospf_vl_new(struct ospf *ospf,
        struct prefix_ipv4 *p;
 
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_debug("ospf_vl_new(): Start");
+               zlog_debug("ospf_vl_new()(%s): Start", ospf_get_name(ospf));
        if (vlink_count == OSPF_VL_MAX_COUNT) {
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
@@ -845,9 +847,9 @@ struct ospf_interface *ospf_vl_new(struct ospf *ospf,
                        ospf->vrf_id);
 
        snprintf(ifname, sizeof(ifname), "VLINK%u", vlink_count);
-       vi = if_create(ifname, ospf->vrf_id);
+       vi = if_create_name(ifname, ospf->vrf_id);
        /*
-        * if_create sets ZEBRA_INTERFACE_LINKDETECTION
+        * if_create_name sets ZEBRA_INTERFACE_LINKDETECTION
         * virtual links don't need this.
         */
        UNSET_FLAG(vi->status, ZEBRA_INTERFACE_LINKDETECTION);
@@ -900,11 +902,10 @@ struct ospf_interface *ospf_vl_new(struct ospf *ospf,
 
 static void ospf_vl_if_delete(struct ospf_vl_data *vl_data)
 {
-       struct interface *ifp = vl_data->vl_oi->ifp;
        vl_data->vl_oi->address->u.prefix4.s_addr = 0;
        vl_data->vl_oi->address->prefixlen = 0;
        ospf_if_free(vl_data->vl_oi);
-       if_delete(ifp);
+       if_delete(&vl_data->vl_oi->ifp);
        vlink_count--;
 }
 
@@ -1218,8 +1219,133 @@ uint8_t ospf_default_iftype(struct interface *ifp)
                return OSPF_IFTYPE_BROADCAST;
 }
 
+void ospf_if_interface(struct interface *ifp)
+{
+       hook_call(ospf_if_update, ifp);
+}
+
+static int ospf_ifp_create(struct interface *ifp)
+{
+       struct ospf *ospf = NULL;
+
+       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",
+                       ifp->name, ospf_vrf_id_to_name(ifp->vrf_id),
+                       ifp->vrf_id, ifp->ifindex,
+                       (unsigned long long)ifp->flags, ifp->metric, ifp->mtu,
+                       ifp->speed);
+
+       assert(ifp->info);
+
+       if (IF_DEF_PARAMS(ifp)
+           && !OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp), type)) {
+               SET_IF_PARAM(IF_DEF_PARAMS(ifp), type);
+               IF_DEF_PARAMS(ifp)->type = ospf_default_iftype(ifp);
+       }
+
+       ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
+       if (!ospf)
+               return 0;
+
+       ospf_if_recalculate_output_cost(ifp);
+
+       ospf_if_update(ospf, ifp);
+
+       hook_call(ospf_if_update, ifp);
+
+       return 0;
+}
+
+static int ospf_ifp_up(struct interface *ifp)
+{
+       struct ospf_interface *oi;
+       struct route_node *rn;
+
+       /* Interface is already up. */
+       if (if_is_operative(ifp)) {
+               /* Temporarily keep ifp values. */
+               struct interface if_tmp;
+               memcpy(&if_tmp, ifp, sizeof(struct interface));
+
+               if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
+                       zlog_debug(
+                               "Zebra: Interface[%s] state update speed %u -> %u, bw  %d -> %d",
+                               ifp->name, if_tmp.speed, ifp->speed,
+                               if_tmp.bandwidth, ifp->bandwidth);
+
+               ospf_if_recalculate_output_cost(ifp);
+
+               if (if_tmp.mtu != ifp->mtu) {
+                       if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
+                               zlog_debug(
+                                       "Zebra: Interface[%s] MTU change %u -> %u.",
+                                       ifp->name, if_tmp.mtu, ifp->mtu);
+
+                       /* Must reset the interface (simulate down/up) when MTU
+                        * changes. */
+                       ospf_if_reset(ifp);
+               }
+               return 0;
+       }
+
+       if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
+               zlog_debug("Zebra: Interface[%s] state change to up.",
+                          ifp->name);
+
+       for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
+               if ((oi = rn->info) == NULL)
+                       continue;
+
+               ospf_if_up(oi);
+       }
+
+       return 0;
+}
+
+static int ospf_ifp_down(struct interface *ifp)
+{
+       struct ospf_interface *oi;
+       struct route_node *node;
+
+       if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
+               zlog_debug("Zebra: Interface[%s] state change to down.",
+                          ifp->name);
+
+       for (node = route_top(IF_OIFS(ifp)); node; node = route_next(node)) {
+               if ((oi = node->info) == NULL)
+                       continue;
+               ospf_if_down(oi);
+       }
+
+       return 0;
+}
+
+static int ospf_ifp_destroy(struct interface *ifp)
+{
+       struct route_node *rn;
+
+       if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
+               zlog_debug(
+                       "Zebra: interface delete %s vrf %s[%u] index %d flags %llx metric %d mtu %d",
+                       ifp->name, ospf_vrf_id_to_name(ifp->vrf_id),
+                       ifp->vrf_id, ifp->ifindex,
+                       (unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
+
+       hook_call(ospf_if_delete, ifp);
+
+       for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn))
+               if (rn->info)
+                       ospf_if_free((struct ospf_interface *)rn->info);
+
+       return 0;
+}
+
 void ospf_if_init(void)
 {
+       if_zapi_callbacks(ospf_ifp_create, ospf_ifp_up,
+                         ospf_ifp_down, ospf_ifp_destroy);
+
        /* Initialize Zebra interface data structure. */
        hook_register_prio(if_add, 0, ospf_if_new_hook);
        hook_register_prio(if_del, 0, ospf_if_delete_hook);