rtadv->HomeAgentLifetime =
-1; /* derive from AdvDefaultLifetime */
rtadv->AdvIntervalOption = 0;
+ rtadv->UseFastRexmit = true;
rtadv->DefaultPreference = RTADV_PREF_MEDIUM;
rtadv->AdvPrefixList = list_new();
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);
}
}
ZEBRA_IFC_CONFIGURED)) {
listnode_delete(ifp->connected,
ifc);
- connected_free(ifc);
+ connected_free(&ifc);
} else
last = node;
}
last = node;
else {
listnode_delete(ifp->connected, ifc);
- connected_free(ifc);
+ connected_free(&ifc);
}
} else {
last = node;
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug("interface %s is being deleted from the system",
ifp->name);
- if_delete(ifp);
+ if_delete(&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)
{
#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;
}
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
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. */
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");
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;
}
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;
}