mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-11 16:39:33 +00:00
[zebra] Fix forgetfulness wrt configured address on FreeBSD
2006-06-15 Paul Jakma <paul.jakma@sun.com> * (general) The key fixes are actually Andrew Schorr's. * interface.c: (ip_address_uninstall) Unset the configured flag. * connected.c: (connected_same) new helper, check whether two connected are same. (connected_implicit_withdraw) new helper, consolidation of existing code in connected_add_ipv{4,6}. Try filter out unneeded Zserv address delete/adds when address is exact same. Where old address is implicitely removed, be sure to preserve the IFC_CONFIGURED flag if set, fixes bug where configured addresses were being lost on FreeBSD.
This commit is contained in:
parent
630c97ce0f
commit
74ecdc9e74
@ -2,6 +2,16 @@
|
|||||||
|
|
||||||
* interface.c: (if_flag_dump_vty) redundant code, remove.
|
* interface.c: (if_flag_dump_vty) redundant code, remove.
|
||||||
(if_dump_vty) use libzebra if_flag_dump.
|
(if_dump_vty) use libzebra if_flag_dump.
|
||||||
|
(ip_address_uninstall) Unset the configured flag.
|
||||||
|
* connected.c: (connected_same) new helper, check whether
|
||||||
|
two connected are same.
|
||||||
|
(connected_implicit_withdraw) new helper, consolidation of
|
||||||
|
existing code in connected_add_ipv{4,6}.
|
||||||
|
Try filter out unneeded Zserv address delete/adds when
|
||||||
|
address is exact same.
|
||||||
|
Where old address is implicitely removed, be sure to preserve
|
||||||
|
the IFC_CONFIGURED flag if set, fixes bug where configured
|
||||||
|
addresses were being lost on FreeBSD (Andrew Schorr).
|
||||||
|
|
||||||
2006-05-21 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
|
2006-05-21 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
|
||||||
|
|
||||||
|
@ -111,6 +111,63 @@ connected_check (struct interface *ifp, struct prefix *p)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if two ifc's describe the same address */
|
||||||
|
static int
|
||||||
|
connected_same (struct connected *ifc1, struct connected *ifc2)
|
||||||
|
{
|
||||||
|
if (ifc1->ifp != ifc2->ifp)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (ifc1->destination)
|
||||||
|
if (!ifc2->destination)
|
||||||
|
return 0;
|
||||||
|
if (ifc2->destination)
|
||||||
|
if (!ifc1->destination)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (ifc1->destination && ifc2->destination)
|
||||||
|
if (!prefix_same (ifc1->destination, ifc2->destination))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (ifc1->flags != ifc2->flags)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle implicit withdrawals of addresses, where a system ADDs an address
|
||||||
|
* to an interface which already has the same address configured.
|
||||||
|
*
|
||||||
|
* Returns the struct connected which must be announced to clients,
|
||||||
|
* or NULL if nothing to do.
|
||||||
|
*/
|
||||||
|
static struct connected *
|
||||||
|
connected_implicit_withdraw (struct interface *ifp, struct connected *ifc)
|
||||||
|
{
|
||||||
|
struct connected *current;
|
||||||
|
|
||||||
|
/* Check same connected route. */
|
||||||
|
if ((current = connected_check (ifp, (struct prefix *) ifc->address)))
|
||||||
|
{
|
||||||
|
if (CHECK_FLAG(current->conf, ZEBRA_IFC_CONFIGURED))
|
||||||
|
SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
|
||||||
|
|
||||||
|
/* Avoid spurious withdraws, this might be just the kernel 'reflecting'
|
||||||
|
* back an address we have already added.
|
||||||
|
*/
|
||||||
|
if (connected_same (current, ifc))
|
||||||
|
{
|
||||||
|
/* nothing to do */
|
||||||
|
connected_free (ifc);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
UNSET_FLAG(current->conf, ZEBRA_IFC_CONFIGURED);
|
||||||
|
connected_withdraw (current); /* implicit withdraw - freebsd does this */
|
||||||
|
}
|
||||||
|
return ifc;
|
||||||
|
}
|
||||||
|
|
||||||
/* Called from if_up(). */
|
/* Called from if_up(). */
|
||||||
void
|
void
|
||||||
connected_up_ipv4 (struct interface *ifp, struct connected *ifc)
|
connected_up_ipv4 (struct interface *ifp, struct connected *ifc)
|
||||||
@ -157,7 +214,6 @@ connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr,
|
|||||||
{
|
{
|
||||||
struct prefix_ipv4 *p;
|
struct prefix_ipv4 *p;
|
||||||
struct connected *ifc;
|
struct connected *ifc;
|
||||||
struct connected *current;
|
|
||||||
|
|
||||||
/* Make connected structure. */
|
/* Make connected structure. */
|
||||||
ifc = connected_new ();
|
ifc = connected_new ();
|
||||||
@ -226,16 +282,9 @@ connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr,
|
|||||||
if (label)
|
if (label)
|
||||||
ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
|
ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
|
||||||
|
|
||||||
/* Check same connected route. */
|
/* nothing to do? */
|
||||||
if ((current = connected_check (ifp, (struct prefix *) ifc->address)))
|
if ((ifc = connected_implicit_withdraw (ifp, ifc)) == NULL)
|
||||||
{
|
return;
|
||||||
if (CHECK_FLAG(current->conf, ZEBRA_IFC_CONFIGURED))
|
|
||||||
{
|
|
||||||
SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
|
|
||||||
UNSET_FLAG(current->conf, ZEBRA_IFC_CONFIGURED);
|
|
||||||
}
|
|
||||||
connected_withdraw (current); /* implicit withdraw - freebsd does this */
|
|
||||||
}
|
|
||||||
|
|
||||||
connected_announce (ifp, ifc);
|
connected_announce (ifp, ifc);
|
||||||
}
|
}
|
||||||
@ -347,7 +396,6 @@ connected_add_ipv6 (struct interface *ifp, struct in6_addr *addr,
|
|||||||
{
|
{
|
||||||
struct prefix_ipv6 *p;
|
struct prefix_ipv6 *p;
|
||||||
struct connected *ifc;
|
struct connected *ifc;
|
||||||
struct connected *current;
|
|
||||||
|
|
||||||
/* Make connected structure. */
|
/* Make connected structure. */
|
||||||
ifc = connected_new ();
|
ifc = connected_new ();
|
||||||
@ -373,15 +421,8 @@ connected_add_ipv6 (struct interface *ifp, struct in6_addr *addr,
|
|||||||
if (label)
|
if (label)
|
||||||
ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
|
ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
|
||||||
|
|
||||||
if ((current = connected_check (ifp, (struct prefix *) ifc->address)))
|
if ((ifc = connected_implicit_withdraw (ifp, ifc)) == NULL)
|
||||||
{
|
return;
|
||||||
if (CHECK_FLAG(current->conf, ZEBRA_IFC_CONFIGURED))
|
|
||||||
{
|
|
||||||
SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
|
|
||||||
UNSET_FLAG(current->conf, ZEBRA_IFC_CONFIGURED);
|
|
||||||
}
|
|
||||||
connected_withdraw (current); /* implicit update of existing address */
|
|
||||||
}
|
|
||||||
|
|
||||||
connected_announce (ifp, ifc);
|
connected_announce (ifp, ifc);
|
||||||
}
|
}
|
||||||
|
@ -1273,6 +1273,8 @@ ip_address_uninstall (struct vty *vty, struct interface *ifp,
|
|||||||
if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
|
if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
|
|
||||||
|
UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
|
||||||
|
|
||||||
/* This is not real address or interface is not active. */
|
/* This is not real address or interface is not active. */
|
||||||
if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
|
if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
|
||||||
|| ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
|
|| ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
|
||||||
|
Loading…
Reference in New Issue
Block a user