ports/net/quagga/files/patch-cvs-10-connroutechange
Sergey Matveychuk 88a19bc60d - A vendor patch. It fixes a bug#418 - changing address on an existing
interface doesn't cause static routes to be revalidated.

Approved by:	portmgr (erwin), maintainer
2007-11-12 20:53:30 +00:00

175 lines
5.2 KiB
Text
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

--- lib/linklist.c 15 Jun 2006 12:43:09 -0000 1.11
+++ lib/linklist.c 12 Nov 2007 14:41:09 -0000
@@ -158,6 +158,7 @@ listnode_add_after (struct list *list, s
pp->next = nn;
}
+ list->count++;
}
--- lib/workqueue.c 30 Mar 2006 14:45:47 -0000 1.8
+++ lib/workqueue.c 12 Nov 2007 14:41:09 -0000
@@ -66,6 +66,8 @@ work_queue_new (struct thread_master *m,
new->name = XSTRDUP (MTYPE_WORK_QUEUE_NAME, queue_name);
new->master = m;
+ SET_FLAG (new->flags, WQ_UNPLUGGED);
+ UNSET_FLAG (new->flags, WQ_AIM_HEAD);
if ( (new->items = list_new ()) == NULL)
{
@@ -103,7 +105,7 @@ static inline int
work_queue_schedule (struct work_queue *wq, unsigned int delay)
{
/* if appropriate, schedule work queue thread */
- if ( (wq->flags == WQ_UNPLUGGED)
+ if ( CHECK_FLAG (wq->flags, WQ_UNPLUGGED)
&& (wq->thread == NULL)
&& (listcount (wq->items) > 0) )
{
@@ -129,7 +131,10 @@ work_queue_add (struct work_queue *wq, v
}
item->data = data;
- listnode_add (wq->items, item);
+ if (CHECK_FLAG (wq->flags, WQ_AIM_HEAD))
+ listnode_add_after (wq->items, NULL, item);
+ else
+ listnode_add (wq->items, item);
work_queue_schedule (wq, wq->spec.hold);
@@ -186,7 +191,7 @@ DEFUN(show_work_queues,
for (ALL_LIST_ELEMENTS_RO ((&work_queues), node, wq))
{
vty_out (vty,"%c %8d %5d %8ld %7d %6d %6u %s%s",
- (wq->flags == WQ_PLUGGED ? 'P' : ' '),
+ (CHECK_FLAG (wq->flags, WQ_UNPLUGGED) ? ' ' : 'P'),
listcount (wq->items),
wq->spec.hold,
wq->runs,
@@ -211,7 +216,7 @@ work_queue_plug (struct work_queue *wq)
wq->thread = NULL;
- wq->flags = WQ_PLUGGED;
+ UNSET_FLAG (wq->flags, WQ_UNPLUGGED);
}
/* unplug queue, schedule it again, if appropriate
@@ -220,12 +225,21 @@ work_queue_plug (struct work_queue *wq)
void
work_queue_unplug (struct work_queue *wq)
{
- wq->flags = WQ_UNPLUGGED;
+ SET_FLAG (wq->flags, WQ_UNPLUGGED);
/* if thread isnt already waiting, add one */
work_queue_schedule (wq, wq->spec.hold);
}
+void
+work_queue_aim_head (struct work_queue *wq, const unsigned aim_head)
+{
+ if (aim_head)
+ SET_FLAG (wq->flags, WQ_AIM_HEAD);
+ else
+ UNSET_FLAG (wq->flags, WQ_AIM_HEAD);
+}
+
/* timer thread to process a work queue
* will reschedule itself if required,
* otherwise work_queue_item_add
--- lib/workqueue.h 30 Mar 2006 14:25:24 -0000 1.8
+++ lib/workqueue.h 12 Nov 2007 14:41:09 -0000
@@ -47,11 +47,8 @@ struct work_queue_item
unsigned short ran; /* # of times item has been run */
};
-enum work_queue_flags
-{
- WQ_UNPLUGGED = 0,
- WQ_PLUGGED = 1,
-};
+#define WQ_UNPLUGGED (1 << 0) /* available for draining */
+#define WQ_AIM_HEAD (1 << 1) /* add new items before list head, not after tail */
struct work_queue
{
@@ -101,7 +98,7 @@ struct work_queue
} cycles; /* cycle counts */
/* private state */
- enum work_queue_flags flags; /* user set flag */
+ u_int16_t flags; /* user set flag */
};
/* User API */
@@ -122,6 +119,8 @@ extern void work_queue_add (struct work_
extern void work_queue_plug (struct work_queue *wq);
/* unplug the queue, allow it to be drained again */
extern void work_queue_unplug (struct work_queue *wq);
+/* control the value for WQ_AIM_HEAD flag */
+extern void work_queue_aim_head (struct work_queue *wq, const unsigned);
/* Helpers, exported for thread.c and command.c */
extern int work_queue_run (struct thread *);
--- zebra/connected.c 2 May 2007 16:05:35 -0000 1.28
+++ zebra/connected.c 12 Nov 2007 14:41:10 -0000
@@ -35,6 +35,7 @@
#include "zebra/redistribute.h"
#include "zebra/interface.h"
#include "zebra/connected.h"
+extern struct zebra_t zebrad;
/* withdraw a connected address */
static void
@@ -187,8 +188,15 @@ connected_up_ipv4 (struct interface *ifp
if (prefix_ipv4_any (&p))
return;
+ /* Always push arriving/departing connected routes into the head of
+ * the working queue to make possible proper validation of the rest
+ * of the RIB queue (which will contain the whole RIB after the first
+ * call to rib_update()).
+ */
+ work_queue_aim_head (zebrad.ribq, 1);
rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, NULL, ifp->ifindex,
RT_TABLE_MAIN, ifp->metric, 0);
+ work_queue_aim_head (zebrad.ribq, 0);
rib_update ();
}
@@ -293,7 +301,10 @@ connected_down_ipv4 (struct interface *i
if (prefix_ipv4_any (&p))
return;
+ /* Same logic as for connected_up_ipv4(): push the changes into the head. */
+ work_queue_aim_head (zebrad.ribq, 1);
rib_delete_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0);
+ work_queue_aim_head (zebrad.ribq, 0);
rib_update ();
}
@@ -338,8 +349,10 @@ connected_up_ipv6 (struct interface *ifp
return;
#endif
+ work_queue_aim_head (zebrad.ribq, 1);
rib_add_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0,
ifp->metric, 0);
+ work_queue_aim_head (zebrad.ribq, 0);
rib_update ();
}
@@ -413,7 +426,9 @@ connected_down_ipv6 (struct interface *i
if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix))
return;
+ work_queue_aim_head (zebrad.ribq, 1);
rib_delete_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0);
+ work_queue_aim_head (zebrad.ribq, 0);
rib_update ();
}