mirror of
https://git.freebsd.org/ports.git
synced 2025-06-28 08:00:31 -04:00
= A bugfix for FreeBSD users (Quagga bug #326): * 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. Approved by: maintainer (implicitly)
100 lines
3.5 KiB
Text
100 lines
3.5 KiB
Text
Index: zebra/ioctl.c
|
|
===================================================================
|
|
RCS file: /var/cvsroot/quagga/zebra/ioctl.c,v
|
|
retrieving revision 1.14
|
|
diff -u -r1.14 ioctl.c
|
|
--- zebra/ioctl.c 11 Jan 2008 15:57:13 -0000 1.14
|
|
+++ zebra/ioctl.c 20 Feb 2008 15:56:23 -0000
|
|
@@ -196,6 +196,7 @@
|
|
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);
|
|
Index: zebra/rib.h
|
|
===================================================================
|
|
RCS file: /var/cvsroot/quagga/zebra/rib.h,v
|
|
retrieving revision 1.14
|
|
diff -u -r1.14 rib.h
|
|
--- zebra/rib.h 13 Aug 2007 16:03:07 -0000 1.14
|
|
+++ zebra/rib.h 20 Feb 2008 15:56:23 -0000
|
|
@@ -212,6 +212,7 @@
|
|
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
|
|
Index: zebra/zebra_rib.c
|
|
===================================================================
|
|
RCS file: /var/cvsroot/quagga/zebra/zebra_rib.c,v
|
|
retrieving revision 1.42
|
|
diff -u -r1.42 zebra_rib.c
|
|
--- zebra/zebra_rib.c 8 Jan 2008 20:12:46 -0000 1.42
|
|
+++ zebra/zebra_rib.c 20 Feb 2008 15:56:23 -0000
|
|
@@ -1614,6 +1614,62 @@
|
|
}
|
|
}
|
|
|
|
+/* Check if requested address assignment will fail due to another
|
|
+ * non-CONNECTED route being installed 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->type != ZEBRA_ROUTE_CONNECT) // Should we leave ZEBRA_ROUTE_KERNEL intact as well?
|
|
+ {
|
|
+ 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)
|
|
{
|