mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 14:05:31 +00:00
2005-04-28 Paul Jakma <paul.jakma@sun.com>
* rib.h: (struct rib) Add lock field for refcounting. * zserv.h: (struct zebra_t) Add a ribq workqueue to the zebra 'master' struct. * zserv.c: (zread_ipv4_add) XMALLOC then memset should be XCALLOC. * zebra_rib.c: Clean up refcounting of route_node, make struct rib refcounted and convert rib_process to work-queue. In general, rib's should be rib_addnode'd and delnode'd to route_nodes, and these symmetrical functions will manage the locking of referenced route_node and freeing of struct rib - rather than having users manage each seperately - with much scope for bugs.. (newrib_free) removed and replaced with rib_lock (rib_lock) new function, check state of lock and increment. (rib_unlock) new function, check lock state and decrement. Free struct rib if refcount hits 0, freeing struct nexthop's, as newrib_free did. (rib_addnode) Add RIB to route_node, locking both. (rib_delnode) Delete RIB from route_node, unlocking each. (rib_process) Converted to a work-queue work function. Functional changes are minimal, just arguments, comments and whitespace. (rib_queue_add_qnode) Helper function to setup a ribq item. (rib_queue_add) Helper function, same arguments as old rib_process, to replace in callers of rib_process. (rib_queue_qnode_del) ribq deconstructor. (rib_queue_init) Create the ribq. (rib_init) call rib_queue_init. (remainder) Sanitise refcounting of route_node's. Convert to rib_queue_add, rib_addnode and rib_delnode. Change XMALLOC/memset to XCALLOC. Remove calls to nexthop_delete and nexthop_free.
This commit is contained in:
parent
8b70d0b04f
commit
4d38fdb421
@ -1,3 +1,35 @@
|
|||||||
|
2005-04-28 Paul Jakma <paul.jakma@sun.com>
|
||||||
|
|
||||||
|
* rib.h: (struct rib) Add lock field for refcounting.
|
||||||
|
* zserv.h: (struct zebra_t) Add a ribq workqueue to the zebra
|
||||||
|
'master' struct.
|
||||||
|
* zserv.c: (zread_ipv4_add) XMALLOC then memset should be XCALLOC.
|
||||||
|
* zebra_rib.c: Clean up refcounting of route_node, make struct rib
|
||||||
|
refcounted and convert rib_process to work-queue. In general,
|
||||||
|
rib's should be rib_addnode'd and delnode'd to route_nodes, and
|
||||||
|
these symmetrical functions will manage the locking of referenced
|
||||||
|
route_node and freeing of struct rib - rather than having users
|
||||||
|
manage each seperately - with much scope for bugs..
|
||||||
|
(newrib_free) removed and replaced with rib_lock
|
||||||
|
(rib_lock) new function, check state of lock and increment.
|
||||||
|
(rib_unlock) new function, check lock state and decrement. Free
|
||||||
|
struct rib if refcount hits 0, freeing struct nexthop's, as
|
||||||
|
newrib_free did.
|
||||||
|
(rib_addnode) Add RIB to route_node, locking both.
|
||||||
|
(rib_delnode) Delete RIB from route_node, unlocking each.
|
||||||
|
(rib_process) Converted to a work-queue work function.
|
||||||
|
Functional changes are minimal, just arguments, comments and
|
||||||
|
whitespace.
|
||||||
|
(rib_queue_add_qnode) Helper function to setup a ribq item.
|
||||||
|
(rib_queue_add) Helper function, same arguments as old
|
||||||
|
rib_process, to replace in callers of rib_process.
|
||||||
|
(rib_queue_qnode_del) ribq deconstructor.
|
||||||
|
(rib_queue_init) Create the ribq.
|
||||||
|
(rib_init) call rib_queue_init.
|
||||||
|
(remainder) Sanitise refcounting of route_node's. Convert to
|
||||||
|
rib_queue_add, rib_addnode and rib_delnode. Change XMALLOC/memset
|
||||||
|
to XCALLOC. Remove calls to nexthop_delete and nexthop_free.
|
||||||
|
|
||||||
2005-04-10 Paul Jakma <paul@dishone.st>
|
2005-04-10 Paul Jakma <paul@dishone.st>
|
||||||
|
|
||||||
* if_ioctl_solaris.c: (if_lookup_linklocal) fix order of args
|
* if_ioctl_solaris.c: (if_lookup_linklocal) fix order of args
|
||||||
|
@ -32,6 +32,9 @@ struct rib
|
|||||||
struct rib *next;
|
struct rib *next;
|
||||||
struct rib *prev;
|
struct rib *prev;
|
||||||
|
|
||||||
|
/* ref count */
|
||||||
|
unsigned int lock;
|
||||||
|
|
||||||
/* Type fo this route. */
|
/* Type fo this route. */
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
|
@ -29,6 +29,9 @@
|
|||||||
#include "if.h"
|
#include "if.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "sockunion.h"
|
#include "sockunion.h"
|
||||||
|
#include "linklist.h"
|
||||||
|
#include "thread.h"
|
||||||
|
#include "workqueue.h"
|
||||||
|
|
||||||
#include "zebra/rib.h"
|
#include "zebra/rib.h"
|
||||||
#include "zebra/rt.h"
|
#include "zebra/rt.h"
|
||||||
@ -57,6 +60,12 @@ struct
|
|||||||
{ZEBRA_ROUTE_ISIS, 115},
|
{ZEBRA_ROUTE_ISIS, 115},
|
||||||
{ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */}
|
{ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct zebra_queue_node_t
|
||||||
|
{
|
||||||
|
struct route_node *node;
|
||||||
|
struct rib *del;
|
||||||
|
};
|
||||||
|
|
||||||
/* Vector for routing table. */
|
/* Vector for routing table. */
|
||||||
vector vrf_vector;
|
vector vrf_vector;
|
||||||
@ -776,18 +785,35 @@ nexthop_active_update (struct route_node *rn, struct rib *rib, int set)
|
|||||||
#define RIB_SYSTEM_ROUTE(R) \
|
#define RIB_SYSTEM_ROUTE(R) \
|
||||||
((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
|
((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
|
||||||
|
|
||||||
void
|
static struct rib *
|
||||||
newrib_free (struct rib *rib)
|
rib_lock (struct rib *rib)
|
||||||
|
{
|
||||||
|
assert (rib->lock >= 0);
|
||||||
|
|
||||||
|
rib->lock++;
|
||||||
|
return rib;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct rib *
|
||||||
|
rib_unlock (struct rib *rib)
|
||||||
{
|
{
|
||||||
struct nexthop *nexthop;
|
struct nexthop *nexthop;
|
||||||
struct nexthop *next;
|
struct nexthop *next;
|
||||||
|
|
||||||
|
assert (rib->lock > 0);
|
||||||
|
rib->lock--;
|
||||||
|
|
||||||
|
if (rib->lock == 0)
|
||||||
|
{
|
||||||
for (nexthop = rib->nexthop; nexthop; nexthop = next)
|
for (nexthop = rib->nexthop; nexthop; nexthop = next)
|
||||||
{
|
{
|
||||||
next = nexthop->next;
|
next = nexthop->next;
|
||||||
nexthop_free (nexthop);
|
nexthop_free (nexthop);
|
||||||
}
|
}
|
||||||
XFREE (MTYPE_RIB, rib);
|
XFREE (MTYPE_RIB, rib);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return rib;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -854,16 +880,28 @@ rib_uninstall (struct route_node *rn, struct rib *rib)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Core function for processing routing information base. */
|
/* Core function for processing routing information base. */
|
||||||
void
|
wq_item_status
|
||||||
rib_process (struct route_node *rn, struct rib *del)
|
rib_process (struct zebra_queue_node_t *qnode)
|
||||||
{
|
{
|
||||||
struct rib *rib;
|
struct rib *rib;
|
||||||
struct rib *next;
|
struct rib *next;
|
||||||
struct rib *fib = NULL;
|
struct rib *fib = NULL;
|
||||||
struct rib *select = NULL;
|
struct rib *select = NULL;
|
||||||
|
struct rib *del = qnode->del;
|
||||||
|
struct route_node *rn = qnode->node;
|
||||||
int installed = 0;
|
int installed = 0;
|
||||||
struct nexthop *nexthop = NULL;
|
struct nexthop *nexthop = NULL;
|
||||||
|
|
||||||
|
assert (rn);
|
||||||
|
|
||||||
|
/* possibly should lock and unlock rib on each iteration. however, for
|
||||||
|
* now, we assume called functions are synchronous and dont delete RIBs
|
||||||
|
* (as the work-queue deconstructor for this function is supposed to be
|
||||||
|
* the canonical 'delete' path for RIBs). Further if called functions
|
||||||
|
* below were to made asynchronous they should themselves acquire any
|
||||||
|
* locks/refcounts as needed and not depend on this caller to do it for
|
||||||
|
* them
|
||||||
|
*/
|
||||||
for (rib = rn->info; rib; rib = next)
|
for (rib = rn->info; rib; rib = next)
|
||||||
{
|
{
|
||||||
next = rib->next;
|
next = rib->next;
|
||||||
@ -890,6 +928,12 @@ rib_process (struct route_node *rn, struct rib *del)
|
|||||||
if (del && CHECK_FLAG (del->flags, ZEBRA_FLAG_SELECTED))
|
if (del && CHECK_FLAG (del->flags, ZEBRA_FLAG_SELECTED))
|
||||||
fib = del;
|
fib = del;
|
||||||
|
|
||||||
|
/* We possibly should lock fib and select here However, all functions
|
||||||
|
* below are 'inline' and not asynchronous And if any were to be
|
||||||
|
* converted, they should manage references themselves really.. See
|
||||||
|
* previous comment above.
|
||||||
|
*/
|
||||||
|
|
||||||
/* Same route is selected. */
|
/* Same route is selected. */
|
||||||
if (select && select == fib)
|
if (select && select == fib)
|
||||||
{
|
{
|
||||||
@ -920,9 +964,10 @@ rib_process (struct route_node *rn, struct rib *del)
|
|||||||
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
|
||||||
installed = 1;
|
installed = 1;
|
||||||
}
|
}
|
||||||
if (! installed) rib_install_kernel (rn, select);
|
if (! installed)
|
||||||
|
rib_install_kernel (rn, select);
|
||||||
}
|
}
|
||||||
return;
|
return WQ_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Uninstall old rib from forwarding table. */
|
/* Uninstall old rib from forwarding table. */
|
||||||
@ -948,6 +993,98 @@ rib_process (struct route_node *rn, struct rib *del)
|
|||||||
SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
|
SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
|
||||||
redistribute_add (&rn->p, select);
|
redistribute_add (&rn->p, select);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return WQ_SUCCESS;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add work queue item to work queue and schedule processing */
|
||||||
|
void
|
||||||
|
rib_queue_add_qnode (struct zebra_t *zebra, struct zebra_queue_node_t *qnode)
|
||||||
|
{
|
||||||
|
route_lock_node (qnode->node);
|
||||||
|
|
||||||
|
if (IS_ZEBRA_DEBUG_EVENT)
|
||||||
|
zlog_info ("rib_queue_add_qnode: work queue added");
|
||||||
|
|
||||||
|
assert (zebra && qnode && qnode->node);
|
||||||
|
|
||||||
|
if (qnode->del)
|
||||||
|
rib_lock (qnode->del);
|
||||||
|
|
||||||
|
if (zebra->ribq == NULL)
|
||||||
|
{
|
||||||
|
zlog_err ("rib_queue_add_qnode: ribq work_queue does not exist!");
|
||||||
|
route_unlock_node (qnode->node);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
work_queue_add (zebra->ribq, qnode);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add route node and rib to work queue and schedule processing */
|
||||||
|
void
|
||||||
|
rib_queue_add (struct zebra_t *zebra, struct route_node *rn, struct rib *del)
|
||||||
|
{
|
||||||
|
struct zebra_queue_node_t *qnode;
|
||||||
|
|
||||||
|
assert (zebra && rn);
|
||||||
|
|
||||||
|
qnode = (struct zebra_queue_node_t *)
|
||||||
|
XCALLOC (MTYPE_RIB_QUEUE, sizeof (struct zebra_queue_node_t));
|
||||||
|
|
||||||
|
if (qnode == NULL)
|
||||||
|
{
|
||||||
|
zlog_err ("rib_queue_add: failed to allocate queue node memory, %s",
|
||||||
|
strerror (errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qnode->node = rn;
|
||||||
|
qnode->del = del;
|
||||||
|
|
||||||
|
rib_queue_add_qnode (zebra, qnode);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free zebra_queue_node_t */
|
||||||
|
void
|
||||||
|
rib_queue_qnode_del (struct zebra_queue_node_t *qnode)
|
||||||
|
{
|
||||||
|
route_unlock_node (qnode->node);
|
||||||
|
|
||||||
|
if (qnode->del)
|
||||||
|
rib_unlock (qnode->del);
|
||||||
|
|
||||||
|
XFREE (MTYPE_RIB_QUEUE, qnode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialise zebra rib work queue */
|
||||||
|
void
|
||||||
|
rib_queue_init (struct zebra_t *zebra)
|
||||||
|
{
|
||||||
|
assert (zebra);
|
||||||
|
|
||||||
|
if (! (zebra->ribq = work_queue_new (zebra->master,
|
||||||
|
"zebra_rib_work_queue")))
|
||||||
|
{
|
||||||
|
zlog_err ("rib_queue_init: could not initialise work queue!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fill in the work queue spec */
|
||||||
|
zebra->ribq->spec.workfunc = (wq_item_status (*) (void *))&rib_process;
|
||||||
|
zebra->ribq->spec.errorfunc = NULL;
|
||||||
|
zebra->ribq->spec.del_item_data = (void (*) (void *)) &rib_queue_qnode_del;
|
||||||
|
/* XXX: TODO: These should be runtime configurable via vty */
|
||||||
|
zebra->ribq->spec.max_retries = 3;
|
||||||
|
zebra->ribq->spec.hold = 500;
|
||||||
|
zebra->ribq->spec.delay = 10;
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add RIB to head of the route node. */
|
/* Add RIB to head of the route node. */
|
||||||
@ -956,6 +1093,11 @@ rib_addnode (struct route_node *rn, struct rib *rib)
|
|||||||
{
|
{
|
||||||
struct rib *head;
|
struct rib *head;
|
||||||
|
|
||||||
|
assert (rib && rn);
|
||||||
|
|
||||||
|
rib_lock (rib);
|
||||||
|
route_lock_node (rn);
|
||||||
|
|
||||||
head = rn->info;
|
head = rn->info;
|
||||||
if (head)
|
if (head)
|
||||||
head->prev = rib;
|
head->prev = rib;
|
||||||
@ -966,12 +1108,17 @@ rib_addnode (struct route_node *rn, struct rib *rib)
|
|||||||
void
|
void
|
||||||
rib_delnode (struct route_node *rn, struct rib *rib)
|
rib_delnode (struct route_node *rn, struct rib *rib)
|
||||||
{
|
{
|
||||||
|
assert (rn && rib);
|
||||||
|
|
||||||
if (rib->next)
|
if (rib->next)
|
||||||
rib->next->prev = rib->prev;
|
rib->next->prev = rib->prev;
|
||||||
if (rib->prev)
|
if (rib->prev)
|
||||||
rib->prev->next = rib->next;
|
rib->prev->next = rib->next;
|
||||||
else
|
else
|
||||||
rn->info = rib->next;
|
rn->info = rib->next;
|
||||||
|
|
||||||
|
rib_unlock (rib);
|
||||||
|
route_unlock_node (rn);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -1026,15 +1173,12 @@ rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
|
|||||||
else if (rib->type == type)
|
else if (rib->type == type)
|
||||||
{
|
{
|
||||||
same = rib;
|
same = rib;
|
||||||
rib_delnode (rn, same);
|
|
||||||
route_unlock_node (rn);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate new rib structure. */
|
/* Allocate new rib structure. */
|
||||||
rib = XMALLOC (MTYPE_RIB, sizeof (struct rib));
|
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
|
||||||
memset (rib, 0, sizeof (struct rib));
|
|
||||||
rib->type = type;
|
rib->type = type;
|
||||||
rib->distance = distance;
|
rib->distance = distance;
|
||||||
rib->flags = flags;
|
rib->flags = flags;
|
||||||
@ -1063,12 +1207,13 @@ rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
|
|||||||
rib_addnode (rn, rib);
|
rib_addnode (rn, rib);
|
||||||
|
|
||||||
/* Process this route node. */
|
/* Process this route node. */
|
||||||
rib_process (rn, same);
|
rib_queue_add (&zebrad, rn, same);
|
||||||
|
|
||||||
/* Free implicit route.*/
|
/* Free implicit route.*/
|
||||||
if (same)
|
if (same)
|
||||||
newrib_free (same);
|
rib_delnode (rn, same);
|
||||||
|
|
||||||
|
route_unlock_node (rn);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1084,7 +1229,6 @@ rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib)
|
|||||||
table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
|
table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
|
||||||
if (! table)
|
if (! table)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Make it sure prefixlen is applied to the prefix. */
|
/* Make it sure prefixlen is applied to the prefix. */
|
||||||
apply_mask_ipv4 (p);
|
apply_mask_ipv4 (p);
|
||||||
|
|
||||||
@ -1108,12 +1252,8 @@ rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib)
|
|||||||
{
|
{
|
||||||
if (same->type == rib->type && same->table == rib->table
|
if (same->type == rib->type && same->table == rib->table
|
||||||
&& same->type != ZEBRA_ROUTE_CONNECT)
|
&& same->type != ZEBRA_ROUTE_CONNECT)
|
||||||
{
|
|
||||||
rib_delnode (rn, same);
|
|
||||||
route_unlock_node (rn);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* If this route is kernel route, set FIB flag to the route. */
|
/* If this route is kernel route, set FIB flag to the route. */
|
||||||
if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
|
if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
|
||||||
@ -1124,12 +1264,13 @@ rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib)
|
|||||||
rib_addnode (rn, rib);
|
rib_addnode (rn, rib);
|
||||||
|
|
||||||
/* Process this route node. */
|
/* Process this route node. */
|
||||||
rib_process (rn, same);
|
rib_queue_add (&zebrad, rn, same);
|
||||||
|
|
||||||
/* Free implicit route.*/
|
/* Free implicit route.*/
|
||||||
if (same)
|
if (same)
|
||||||
newrib_free (same);
|
rib_delnode (rn, same);
|
||||||
|
|
||||||
|
route_unlock_node (rn);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1266,20 +1407,13 @@ rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Process changes. */
|
||||||
|
rib_queue_add (&zebrad, rn, same);
|
||||||
|
|
||||||
if (same)
|
if (same)
|
||||||
rib_delnode (rn, same);
|
rib_delnode (rn, same);
|
||||||
|
|
||||||
/* Process changes. */
|
|
||||||
rib_process (rn, same);
|
|
||||||
|
|
||||||
if (same)
|
|
||||||
{
|
|
||||||
newrib_free (same);
|
|
||||||
route_unlock_node (rn);
|
route_unlock_node (rn);
|
||||||
}
|
|
||||||
|
|
||||||
route_unlock_node (rn);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1319,13 +1453,12 @@ static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
|
|||||||
nexthop_blackhole_add (rib);
|
nexthop_blackhole_add (rib);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
rib_process (rn, NULL);
|
rib_queue_add (&zebrad, rn, NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* This is new static route. */
|
/* This is new static route. */
|
||||||
rib = XMALLOC (MTYPE_RIB, sizeof (struct rib));
|
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
|
||||||
memset (rib, 0, sizeof (struct rib));
|
|
||||||
|
|
||||||
rib->type = ZEBRA_ROUTE_STATIC;
|
rib->type = ZEBRA_ROUTE_STATIC;
|
||||||
rib->distance = si->distance;
|
rib->distance = si->distance;
|
||||||
@ -1352,7 +1485,7 @@ static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
|
|||||||
rib_addnode (rn, rib);
|
rib_addnode (rn, rib);
|
||||||
|
|
||||||
/* Process this prefix. */
|
/* Process this prefix. */
|
||||||
rib_process (rn, NULL);
|
rib_queue_add (&zebrad, rn, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1417,20 +1550,15 @@ static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
|
|||||||
/* Check nexthop. */
|
/* Check nexthop. */
|
||||||
if (rib->nexthop_num == 1)
|
if (rib->nexthop_num == 1)
|
||||||
{
|
{
|
||||||
|
rib_queue_add (&zebrad, rn, rib);
|
||||||
rib_delnode (rn, rib);
|
rib_delnode (rn, rib);
|
||||||
rib_process (rn, rib);
|
|
||||||
newrib_free (rib);
|
|
||||||
route_unlock_node (rn);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
|
||||||
rib_uninstall (rn, rib);
|
rib_uninstall (rn, rib);
|
||||||
nexthop_delete (rib, nexthop);
|
rib_queue_add (&zebrad, rn, rib);
|
||||||
nexthop_free (nexthop);
|
|
||||||
rib_process (rn, rib);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unlock node. */
|
/* Unlock node. */
|
||||||
route_unlock_node (rn);
|
route_unlock_node (rn);
|
||||||
}
|
}
|
||||||
@ -1671,15 +1799,13 @@ rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
|
|||||||
else if (rib->type == type)
|
else if (rib->type == type)
|
||||||
{
|
{
|
||||||
same = rib;
|
same = rib;
|
||||||
rib_delnode (rn, same);
|
|
||||||
route_unlock_node (rn);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate new rib structure. */
|
/* Allocate new rib structure. */
|
||||||
rib = XMALLOC (MTYPE_RIB, sizeof (struct rib));
|
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
|
||||||
memset (rib, 0, sizeof (struct rib));
|
|
||||||
rib->type = type;
|
rib->type = type;
|
||||||
rib->distance = distance;
|
rib->distance = distance;
|
||||||
rib->flags = flags;
|
rib->flags = flags;
|
||||||
@ -1708,12 +1834,13 @@ rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
|
|||||||
rib_addnode (rn, rib);
|
rib_addnode (rn, rib);
|
||||||
|
|
||||||
/* Process this route node. */
|
/* Process this route node. */
|
||||||
rib_process (rn, same);
|
rib_queue_add (&zebrad, rn, same);
|
||||||
|
|
||||||
/* Free implicit route.*/
|
/* Free implicit route.*/
|
||||||
if (same)
|
if (same)
|
||||||
newrib_free (same);
|
rib_delnode (rn, same);
|
||||||
|
|
||||||
|
route_unlock_node (rn);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1829,20 +1956,13 @@ rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Process changes. */
|
||||||
|
rib_queue_add (&zebrad, rn, same);
|
||||||
|
|
||||||
if (same)
|
if (same)
|
||||||
rib_delnode (rn, same);
|
rib_delnode (rn, same);
|
||||||
|
|
||||||
/* Process changes. */
|
|
||||||
rib_process (rn, same);
|
|
||||||
|
|
||||||
if (same)
|
|
||||||
{
|
|
||||||
newrib_free (same);
|
|
||||||
route_unlock_node (rn);
|
route_unlock_node (rn);
|
||||||
}
|
|
||||||
|
|
||||||
route_unlock_node (rn);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1883,13 +2003,12 @@ static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
|
|||||||
nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
|
nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
rib_process (rn, NULL);
|
rib_queue_add (&zebrad, rn, NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* This is new static route. */
|
/* This is new static route. */
|
||||||
rib = XMALLOC (MTYPE_RIB, sizeof (struct rib));
|
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
|
||||||
memset (rib, 0, sizeof (struct rib));
|
|
||||||
|
|
||||||
rib->type = ZEBRA_ROUTE_STATIC;
|
rib->type = ZEBRA_ROUTE_STATIC;
|
||||||
rib->distance = si->distance;
|
rib->distance = si->distance;
|
||||||
@ -1916,7 +2035,7 @@ static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
|
|||||||
rib_addnode (rn, rib);
|
rib_addnode (rn, rib);
|
||||||
|
|
||||||
/* Process this prefix. */
|
/* Process this prefix. */
|
||||||
rib_process (rn, NULL);
|
rib_queue_add (&zebrad, rn, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1982,19 +2101,14 @@ static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
|
|||||||
if (rib->nexthop_num == 1)
|
if (rib->nexthop_num == 1)
|
||||||
{
|
{
|
||||||
rib_delnode (rn, rib);
|
rib_delnode (rn, rib);
|
||||||
rib_process (rn, rib);
|
rib_queue_add (&zebrad, rn, rib);
|
||||||
newrib_free (rib);
|
|
||||||
route_unlock_node (rn);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
|
||||||
rib_uninstall (rn, rib);
|
rib_uninstall (rn, rib);
|
||||||
nexthop_delete (rib, nexthop);
|
rib_queue_add (&zebrad, rn, rib);
|
||||||
nexthop_free (nexthop);
|
|
||||||
rib_process (rn, rib);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unlock node. */
|
/* Unlock node. */
|
||||||
route_unlock_node (rn);
|
route_unlock_node (rn);
|
||||||
}
|
}
|
||||||
@ -2144,12 +2258,14 @@ rib_update ()
|
|||||||
table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
|
table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
|
||||||
if (table)
|
if (table)
|
||||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||||
rib_process (rn, NULL);
|
if (rn->info)
|
||||||
|
rib_queue_add (&zebrad, rn, NULL);
|
||||||
|
|
||||||
table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
|
table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
|
||||||
if (table)
|
if (table)
|
||||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||||
rib_process (rn, NULL);
|
if (rn->info)
|
||||||
|
rib_queue_add (&zebrad, rn, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Interface goes up. */
|
/* Interface goes up. */
|
||||||
@ -2182,11 +2298,7 @@ rib_weed_table (struct route_table *table)
|
|||||||
|
|
||||||
if (rib->table != zebrad.rtm_table_default &&
|
if (rib->table != zebrad.rtm_table_default &&
|
||||||
rib->table != RT_TABLE_MAIN)
|
rib->table != RT_TABLE_MAIN)
|
||||||
{
|
|
||||||
rib_delnode (rn, rib);
|
rib_delnode (rn, rib);
|
||||||
newrib_free (rib);
|
|
||||||
route_unlock_node (rn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2218,11 +2330,7 @@ rib_sweep_table (struct route_table *table)
|
|||||||
{
|
{
|
||||||
ret = rib_uninstall_kernel (rn, rib);
|
ret = rib_uninstall_kernel (rn, rib);
|
||||||
if (! ret)
|
if (! ret)
|
||||||
{
|
|
||||||
rib_delnode (rn, rib);
|
rib_delnode (rn, rib);
|
||||||
newrib_free (rib);
|
|
||||||
route_unlock_node (rn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2262,6 +2370,7 @@ rib_close ()
|
|||||||
void
|
void
|
||||||
rib_init ()
|
rib_init ()
|
||||||
{
|
{
|
||||||
|
rib_queue_init (&zebrad);
|
||||||
/* VRF initialization. */
|
/* VRF initialization. */
|
||||||
vrf_init ();
|
vrf_init ();
|
||||||
}
|
}
|
||||||
|
@ -780,8 +780,7 @@ zread_ipv4_add (struct zserv *client, u_short length)
|
|||||||
s = client->ibuf;
|
s = client->ibuf;
|
||||||
|
|
||||||
/* Allocate new rib. */
|
/* Allocate new rib. */
|
||||||
rib = XMALLOC (MTYPE_RIB, sizeof (struct rib));
|
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
|
||||||
memset (rib, 0, sizeof (struct rib));
|
|
||||||
|
|
||||||
/* Type, flags, message. */
|
/* Type, flags, message. */
|
||||||
rib->type = stream_getc (s);
|
rib->type = stream_getc (s);
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#define _ZEBRA_ZSERV_H
|
#define _ZEBRA_ZSERV_H
|
||||||
|
|
||||||
#include "rib.h"
|
#include "rib.h"
|
||||||
|
#include "workqueue.h"
|
||||||
|
|
||||||
/* Default port information. */
|
/* Default port information. */
|
||||||
#define ZEBRA_PORT 2600
|
#define ZEBRA_PORT 2600
|
||||||
@ -77,6 +78,8 @@ struct zebra_t
|
|||||||
/* default table */
|
/* default table */
|
||||||
int rtm_table_default;
|
int rtm_table_default;
|
||||||
|
|
||||||
|
/* rib work queue */
|
||||||
|
struct work_queue *ribq;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Count prefix size from mask length */
|
/* Count prefix size from mask length */
|
||||||
|
Loading…
Reference in New Issue
Block a user