mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-13 17:40:04 +00:00
+ fix bug#326 by rib_lookup_and_pushup()
This commit is contained in:
parent
dea04441fb
commit
20e5ff0a88
@ -1,3 +1,9 @@
|
||||
2008-02-26 Denis Ovsienko
|
||||
* zebra_rib.[ch]: (rib_lookup_and_pushup) New function, which makes sure,
|
||||
that if_set_prefix() has nothing in its way of assigning an address.
|
||||
* ioctl.c: (if_set_prefix) Use rib_lookup_and_pushup() to resolve
|
||||
bug #326.
|
||||
|
||||
2008-01-11 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
|
||||
|
||||
* ioctl.c: If HAVE_BSD_LINK_DETECT is defined, include <net/if_media.h>
|
||||
|
@ -196,6 +196,7 @@ if_set_prefix (struct interface *ifp, struct connected *ifc)
|
||||
struct prefix_ipv4 *p;
|
||||
|
||||
p = (struct prefix_ipv4 *) ifc->address;
|
||||
rib_lookup_and_pushup (p);
|
||||
|
||||
memset (&addreq, 0, sizeof addreq);
|
||||
strncpy ((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name);
|
||||
|
@ -212,6 +212,7 @@ extern struct nexthop *nexthop_blackhole_add (struct rib *);
|
||||
extern struct nexthop *nexthop_ipv4_add (struct rib *, struct in_addr *,
|
||||
struct in_addr *);
|
||||
extern void rib_lookup_and_dump (struct prefix_ipv4 *);
|
||||
extern void rib_lookup_and_pushup (struct prefix_ipv4 *);
|
||||
extern void rib_dump (const char *, const struct prefix_ipv4 *, const struct rib *);
|
||||
extern int rib_lookup_ipv4_route (struct prefix_ipv4 *, union sockunion *);
|
||||
#define ZEBRA_RIB_LOOKUP_ERROR -1
|
||||
|
@ -1614,6 +1614,62 @@ void rib_lookup_and_dump (struct prefix_ipv4 * p)
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if requested address assignment will fail due to another
|
||||
* route being installed by zebra in FIB already. Take necessary
|
||||
* actions, if needed: remove such a route from FIB and deSELECT
|
||||
* corresponding RIB entry. Then put affected RN into RIBQ head.
|
||||
*/
|
||||
void rib_lookup_and_pushup (struct prefix_ipv4 * p)
|
||||
{
|
||||
struct route_table *table;
|
||||
struct route_node *rn;
|
||||
struct rib *rib;
|
||||
unsigned changed = 0;
|
||||
|
||||
if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
|
||||
{
|
||||
zlog_err ("%s: vrf_table() returned NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
/* No matches would be the simplest case. */
|
||||
if (NULL == (rn = route_node_lookup (table, (struct prefix *) p)))
|
||||
return;
|
||||
|
||||
/* Unlock node. */
|
||||
route_unlock_node (rn);
|
||||
|
||||
/* Check all RIB entries. In case any changes have to be done, requeue
|
||||
* the RN into RIBQ head. If the routing message about the new connected
|
||||
* route (generated by the IP address we are going to assign very soon)
|
||||
* comes before the RIBQ is processed, the new RIB entry will join
|
||||
* RIBQ record already on head. This is necessary for proper revalidation
|
||||
* of the rest of the RIB.
|
||||
*/
|
||||
for (rib = rn->info; rib; rib = rib->next)
|
||||
{
|
||||
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
|
||||
! RIB_SYSTEM_ROUTE (rib))
|
||||
{
|
||||
changed = 1;
|
||||
if (IS_ZEBRA_DEBUG_RIB)
|
||||
{
|
||||
char buf[INET_ADDRSTRLEN];
|
||||
inet_ntop (rn->p.family, &p->prefix, buf, INET_ADDRSTRLEN);
|
||||
zlog_debug ("%s: freeing way for connected prefix %s/%d", __func__, buf, p->prefixlen);
|
||||
rib_dump (__func__, (struct prefix_ipv4 *)&rn->p, rib);
|
||||
}
|
||||
rib_uninstall (rn, rib);
|
||||
}
|
||||
}
|
||||
if (changed)
|
||||
{
|
||||
work_queue_aim_head (zebrad.ribq, 1);
|
||||
rib_queue_add (&zebrad, rn);
|
||||
work_queue_aim_head (zebrad.ribq, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user