]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/interface.c
Merge pull request #5789 from donaldsharp/bgp_ebgp_reason
[mirror_frr.git] / zebra / interface.c
index 4754762b979c67bbdd2239b6406a863137adc290..bcb833b8d8f019b1ed7532533345b9a5bb2c4e42 100644 (file)
@@ -161,6 +161,7 @@ static int if_zebra_new_hook(struct interface *ifp)
                rtadv->HomeAgentLifetime =
                        -1; /* derive from AdvDefaultLifetime */
                rtadv->AdvIntervalOption = 0;
+               rtadv->UseFastRexmit = true;
                rtadv->DefaultPreference = RTADV_PREF_MEDIUM;
 
                rtadv->AdvPrefixList = list_new();
@@ -189,17 +190,31 @@ static int if_zebra_new_hook(struct interface *ifp)
        return 0;
 }
 
-static void if_nhg_dependents_release(struct interface *ifp)
+static void if_nhg_dependents_check_valid(struct nhg_hash_entry *nhe)
 {
-       if (!if_nhg_dependents_is_empty(ifp)) {
-               struct nhg_connected *rb_node_dep = NULL;
-               struct zebra_if *zif = (struct zebra_if *)ifp->info;
+       zebra_nhg_check_valid(nhe);
+       if (!CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_VALID))
+               /* Assuming uninstalled as well here */
+               UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED);
+}
 
-               frr_each (nhg_connected_tree, &zif->nhg_dependents,
-                         rb_node_dep) {
-                       rb_node_dep->nhe->ifp = NULL;
-                       zebra_nhg_set_invalid(rb_node_dep->nhe);
-               }
+static void if_down_nhg_dependents(const struct interface *ifp)
+{
+       struct nhg_connected *rb_node_dep = NULL;
+       struct zebra_if *zif = (struct zebra_if *)ifp->info;
+
+       frr_each(nhg_connected_tree, &zif->nhg_dependents, rb_node_dep)
+               if_nhg_dependents_check_valid(rb_node_dep->nhe);
+}
+
+static void if_nhg_dependents_release(const struct interface *ifp)
+{
+       struct nhg_connected *rb_node_dep = NULL;
+       struct zebra_if *zif = (struct zebra_if *)ifp->info;
+
+       frr_each(nhg_connected_tree, &zif->nhg_dependents, rb_node_dep) {
+               rb_node_dep->nhe->ifp = NULL; /* Null it out */
+               if_nhg_dependents_check_valid(rb_node_dep->nhe);
        }
 }
 
@@ -724,7 +739,7 @@ static void if_delete_connected(struct interface *ifp)
                                                        ZEBRA_IFC_CONFIGURED)) {
                                                listnode_delete(ifp->connected,
                                                                ifc);
-                                               connected_free(ifc);
+                                               connected_free(&ifc);
                                        } else
                                                last = node;
                                }
@@ -745,7 +760,7 @@ static void if_delete_connected(struct interface *ifp)
                                last = node;
                        else {
                                listnode_delete(ifp->connected, ifc);
-                               connected_free(ifc);
+                               connected_free(&ifc);
                        }
                } else {
                        last = node;
@@ -815,7 +830,7 @@ void if_delete_update(struct interface *ifp)
                if (IS_ZEBRA_DEBUG_KERNEL)
                        zlog_debug("interface %s is being deleted from the system",
                                   ifp->name);
-               if_delete(ifp);
+               if_delete(&ifp);
        }
 }
 
@@ -998,19 +1013,6 @@ bool if_nhg_dependents_is_empty(const struct interface *ifp)
        return false;
 }
 
-static void if_down_nhg_dependents(const struct interface *ifp)
-{
-       if (!if_nhg_dependents_is_empty(ifp)) {
-               struct nhg_connected *rb_node_dep = NULL;
-               struct zebra_if *zif = (struct zebra_if *)ifp->info;
-
-               frr_each (nhg_connected_tree, &zif->nhg_dependents,
-                         rb_node_dep) {
-                       zebra_nhg_set_invalid(rb_node_dep->nhe);
-               }
-       }
-}
-
 /* Interface is up. */
 void if_up(struct interface *ifp)
 {
@@ -1036,7 +1038,8 @@ void if_up(struct interface *ifp)
 #if defined(HAVE_RTADV)
        /* Enable fast tx of RA if enabled && RA interval is not in msecs */
        if (zif->rtadv.AdvSendAdvertisements
-           && (zif->rtadv.MaxRtrAdvInterval >= 1000)) {
+           && (zif->rtadv.MaxRtrAdvInterval >= 1000)
+           && zif->rtadv.UseFastRexmit) {
                zif->rtadv.inFastRexmit = 1;
                zif->rtadv.NumFastReXmitsRemain = RTADV_NUM_FAST_REXMITS;
        }
@@ -1059,7 +1062,9 @@ void if_up(struct interface *ifp)
                                                    zif->link_ifindex);
                if (link_if)
                        zebra_vxlan_svi_up(ifp, link_if);
-       }
+       } else if (IS_ZEBRA_IF_MACVLAN(ifp))
+               zebra_vxlan_macvlan_up(ifp);
+
 }
 
 /* Interface goes down.  We have to manage different behavior of based
@@ -1091,7 +1096,8 @@ void if_down(struct interface *ifp)
                                                    zif->link_ifindex);
                if (link_if)
                        zebra_vxlan_svi_down(ifp, link_if);
-       }
+       } else if (IS_ZEBRA_IF_MACVLAN(ifp))
+               zebra_vxlan_macvlan_down(ifp);
 
 
        /* Notify to the protocol daemons. */
@@ -1971,6 +1977,8 @@ DEFUN (shutdown_if,
        struct zebra_if *if_data;
 
        if (ifp->ifindex != IFINDEX_INTERNAL) {
+               /* send RA lifetime of 0 before stopping. rfc4861/6.2.5 */
+               rtadv_stop_ra(ifp);
                ret = if_unset_flags(ifp, IFF_UP);
                if (ret < 0) {
                        vty_out(vty, "Can't shutdown interface\n");
@@ -2877,7 +2885,7 @@ static int ip_address_uninstall(struct vty *vty, struct interface *ifp,
        if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
            || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
                listnode_delete(ifp->connected, ifc);
-               connected_free(ifc);
+               connected_free(&ifc);
                return CMD_WARNING_CONFIG_FAILED;
        }
 
@@ -3102,7 +3110,7 @@ static int ipv6_address_uninstall(struct vty *vty, struct interface *ifp,
        if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
            || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
                listnode_delete(ifp->connected, ifc);
-               connected_free(ifc);
+               connected_free(&ifc);
                return CMD_WARNING_CONFIG_FAILED;
        }