frr/zebra/rib.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

649 lines
17 KiB
C
Raw Normal View History

// SPDX-License-Identifier: GPL-2.0-or-later
2002-12-13 21:15:29 +01:00
/*
* Routing Information Base header
* Copyright (C) 1997 Kunihiro Ishiguro
*/
#ifndef _ZEBRA_RIB_H
#define _ZEBRA_RIB_H
#include "zebra.h"
#include "memory.h"
#include "hook.h"
#include "typesafe.h"
#include "linklist.h"
#include "prefix.h"
zebra: add structure to hold per-prefix state in RIB Add the rib_dest_t structure to hold per-prefix state in the routing information base. This gives us an appropriate place to maintain the queueing state of a route_node. Queuing state was previously being stored on the first rib in the list of ribs hanging off the route_node. * zebra/rib.h - Add new structure rib_dest_t. - Remove the rn_status field from 'struct rib', it is no longer required. - Add macros (RNODE_FOREACH_RIB, RNODE_FOREACH_RIB_SAFE) for walking all 'struct ribs' corresponding to a route_node. These hide the fact that there is an intermediate rib_dest_t structure. - Add a few utility inlines to go between a rib_dest_t and associated structures. * zebra/zebra_rib.c - rib_link()/rib_unlink() Tweak for new behavior, where the 'info' pointer of a route_node points to a rib_dest_t. The list of ribs for a prefix now hangs off of the dest. Change the way we ref count route_nodes. We now hold a single ref count on a route_node if there is a corresponding rib_dest_t. - Maintain the queuing state of a route_node on the flags field of the rib_dest_t. - Add the rib_gc_dest() function, which deletes a rib_dest_t if it is no longer required. A rib_dest_t can be deleted iff there are no struct ribs hanging off of it. - Call rib_gc_dest() any time we unlink a rib from the rib_dest_t. Currently we only need to call it once, just before we return from rib_process(). * zebra/{redistribute,zebra_rib,zebra_snmp,zebra_vty}.c Use new macros to walk over route_node ribs. * lib/memtypes.c Add memory type for rib_dest_t. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-13 23:48:53 +01:00
#include "table.h"
zebra: add module to communicate routes to FPM Enhance zebra to send routes to the (optional) Forwarding Path Manager component using the interface defined by fpm/fpm.h. * configure.ac - Add --enable-fpm flag. The FPM-related code in zebra is activated only if the build is configured with '--enable-fpm'. - Add HAVE_NETLINK automake conditional. This allows us to conditionally build netlink-dependent C code. * zebra/{rib.h,zebra_rib.c} - Add the 'fpm_q_entries' field to the rib_dest_t structure. This allows dests to be placed on the fpm queue. - Define a couple new rib_dest_t flags that hold FPM-related state. - Invoke the zfpm_trigger_update() function for a route_node whenever the information to be sent to the FPM changes. - rib_can_delete_dest(): Return FALSE if we have to update the FPM about the given dest. This ensures that the dest is not deleted even if there are no ribs hanging off of it. * zebra/zebra_fpm.c This file holds most of the code for interacting with the FPM. - If quagga was configured with '--enable-fpm', periodically try to connect to the FPM. - When the connection comes up, enqueue all relevent dests to the FPM queue. - When the FPM socket is readable, dequeue the next rib_dest_t from the FPM queue, encode it in to a message and send the message to the FPM. - When the connection to the FPM goes down, remove all dests from the FPM queue, and then start trying to connect to the FPM again. - Expose the following new operational commands: show zebra fpm stats clear zebra fpm stats * zebra/zebra_fpm_netlink.c - zfpm_netlink_encode_route(): Function to encode information about a rib_dest_t in netlink format. * zebra/zebra_fpm_private.h Private header file for the zebra FPM module. * zebra/zebra_fpm.h Header file exported by zebra FPM module to the rest of zebra. * zebra/debug.c Add the 'debug zebra fpm' command. * zebra/main.c Initialize the zebra-FPM code on startup. * zebra/misc_null.c Add stub for zfpm_trigger_update(). * zebra/Makefile.am - Include new file zebra_fpm.c in build. - Include zebra_fpm_netlink.c in build if HAVE_NETLINK is defined. * vtysh/Makefile.am Include zebra_fpm.c in list of files that define cli commands. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-13 23:48:59 +01:00
#include "queue.h"
#include "nexthop.h"
#include "nexthop_group.h"
#include "vrf.h"
#include "if.h"
#include "mpls.h"
#include "srcdest_table.h"
#include "zebra/zebra_nhg.h"
#ifdef __cplusplus
extern "C" {
#endif
DECLARE_MGROUP(ZEBRA);
DECLARE_MTYPE(RE);
PREDECL_LIST(rnh_list);
/* Nexthop structure. */
struct rnh {
uint8_t flags;
2021-09-24 21:51:18 +02:00
#define ZEBRA_NHT_CONNECTED 0x1
#define ZEBRA_NHT_DELETED 0x2
#define ZEBRA_NHT_RESOLVE_VIA_DEFAULT 0x4
/* VRF identifier. */
vrf_id_t vrf_id;
afi_t afi;
safi_t safi;
uint32_t seqno;
struct route_entry *state;
struct prefix resolved_route;
struct list *client_list;
/* pseudowires dependent on this nh */
struct list *zebra_pseudowire_list;
struct route_node *node;
/*
* if this has been filtered for the client
*/
int filtered[ZEBRA_ROUTE_MAX];
struct rnh_list_item rnh_list_item;
};
2002-12-13 21:15:29 +01:00
#define DISTANCE_INFINITY 255
#define ZEBRA_KERNEL_TABLE_MAX 252 /* support for no more than this rt tables */
2002-12-13 21:15:29 +01:00
PREDECL_LIST(re_list);
struct re_opaque {
uint16_t length;
uint8_t data[];
};
struct route_entry {
2002-12-13 21:15:29 +01:00
/* Link list. */
struct re_list_item next;
/* Nexthop group, shared/refcounted, based on the nexthop(s)
* provided by the owner of the route
*/
struct nhg_hash_entry *nhe;
/* Nexthop group hash entry IDs. The "installed" id is the id
* used in linux/netlink, if available.
*/
uint32_t nhe_id;
uint32_t nhe_installed_id;
/* Type of this route. */
2002-12-13 21:15:29 +01:00
int type;
/* VRF identifier. */
vrf_id_t vrf_id;
2002-12-13 21:15:29 +01:00
/* Which routing table */
uint32_t table;
/* Metric */
uint32_t metric;
/* MTU */
uint32_t mtu;
uint32_t nexthop_mtu;
[zebra] Bug #268, Fix race between add/delete of routes, sanitise rib queueing 2006-07-27 Paul Jakma <paul.jakma@sun.com> * rib.h: (struct rib) Add a route_node rn_status flag field, this has to be copied every time head RIB of a route_node changes. Remove the rib lock field, not needed - see below. Add a status field for RIB-private flags. * zebra_rib.c: Add a global for the workqueue hold time, useful for testing. (general) Fix for bug #268. Problem originally detailed by Simon Bryden in [quagga-dev 4001]. Essentially, add/delete of a RIB must happen /before/ the queue. Best-path selection (ie rib_process) and reaping of freed RIBs can then be done after queueing. Only the route_node is queued - no important RIB state (i.e. whether a RIB is to be deleted) is queued. (struct zebra_queue_node_t) Disappears, no longer need to track multiple things on the queue, only the route_node. (rib_{lock,unlock}) removed, RIBs no longer need to be refcounted, no longer queued. (rib_queue_qnode_del) Removed, deleted RIBs no longer deleted via the queue. (rib_queue_add_qnode) deleted (rib_queue_add) Only the route_node is queued for best-path selection, we can check whether it is already queued or not and avoid queueing same node twice - struct rib * argument is not needed. (rib_link/unlink) (un)link RIB from route_node. (rib_{add,del}node) Front-end to updates of a RIB. (rib_process) Reap any deleted RIBs via rib_unlink. Unset the route_node 'QUEUED' flag. (General) Remove calls to rib_queue_add where add/del node was called - not needed, update calls where not. Ignore RIB_ENTRY_REMOVEd ribs in loops through route_nodes
2006-07-27 23:49:00 +02:00
/* Flags of this route.
* This flag's definition is in lib/zclient.h ZEBRA_FLAG_* and is
* exposed to clients via Zserv
[zebra] Bug #268, Fix race between add/delete of routes, sanitise rib queueing 2006-07-27 Paul Jakma <paul.jakma@sun.com> * rib.h: (struct rib) Add a route_node rn_status flag field, this has to be copied every time head RIB of a route_node changes. Remove the rib lock field, not needed - see below. Add a status field for RIB-private flags. * zebra_rib.c: Add a global for the workqueue hold time, useful for testing. (general) Fix for bug #268. Problem originally detailed by Simon Bryden in [quagga-dev 4001]. Essentially, add/delete of a RIB must happen /before/ the queue. Best-path selection (ie rib_process) and reaping of freed RIBs can then be done after queueing. Only the route_node is queued - no important RIB state (i.e. whether a RIB is to be deleted) is queued. (struct zebra_queue_node_t) Disappears, no longer need to track multiple things on the queue, only the route_node. (rib_{lock,unlock}) removed, RIBs no longer need to be refcounted, no longer queued. (rib_queue_qnode_del) Removed, deleted RIBs no longer deleted via the queue. (rib_queue_add_qnode) deleted (rib_queue_add) Only the route_node is queued for best-path selection, we can check whether it is already queued or not and avoid queueing same node twice - struct rib * argument is not needed. (rib_link/unlink) (un)link RIB from route_node. (rib_{add,del}node) Front-end to updates of a RIB. (rib_process) Reap any deleted RIBs via rib_unlink. Unset the route_node 'QUEUED' flag. (General) Remove calls to rib_queue_add where add/del node was called - not needed, update calls where not. Ignore RIB_ENTRY_REMOVEd ribs in loops through route_nodes
2006-07-27 23:49:00 +02:00
*/
uint32_t flags;
[zebra] Bug #268, Fix race between add/delete of routes, sanitise rib queueing 2006-07-27 Paul Jakma <paul.jakma@sun.com> * rib.h: (struct rib) Add a route_node rn_status flag field, this has to be copied every time head RIB of a route_node changes. Remove the rib lock field, not needed - see below. Add a status field for RIB-private flags. * zebra_rib.c: Add a global for the workqueue hold time, useful for testing. (general) Fix for bug #268. Problem originally detailed by Simon Bryden in [quagga-dev 4001]. Essentially, add/delete of a RIB must happen /before/ the queue. Best-path selection (ie rib_process) and reaping of freed RIBs can then be done after queueing. Only the route_node is queued - no important RIB state (i.e. whether a RIB is to be deleted) is queued. (struct zebra_queue_node_t) Disappears, no longer need to track multiple things on the queue, only the route_node. (rib_{lock,unlock}) removed, RIBs no longer need to be refcounted, no longer queued. (rib_queue_qnode_del) Removed, deleted RIBs no longer deleted via the queue. (rib_queue_add_qnode) deleted (rib_queue_add) Only the route_node is queued for best-path selection, we can check whether it is already queued or not and avoid queueing same node twice - struct rib * argument is not needed. (rib_link/unlink) (un)link RIB from route_node. (rib_{add,del}node) Front-end to updates of a RIB. (rib_process) Reap any deleted RIBs via rib_unlink. Unset the route_node 'QUEUED' flag. (General) Remove calls to rib_queue_add where add/del node was called - not needed, update calls where not. Ignore RIB_ENTRY_REMOVEd ribs in loops through route_nodes
2006-07-27 23:49:00 +02:00
/* RIB internal status */
uint32_t status;
#define ROUTE_ENTRY_REMOVED 0x1
/* The Route Entry has changed */
#define ROUTE_ENTRY_CHANGED 0x2
/* The Label has changed on the Route entry */
#define ROUTE_ENTRY_LABELS_CHANGED 0x4
/* Route is queued for Installation into the Data Plane */
#define ROUTE_ENTRY_QUEUED 0x8
/* Route is installed into the Data Plane */
#define ROUTE_ENTRY_INSTALLED 0x10
/* Route has Failed installation into the Data Plane in some manner */
#define ROUTE_ENTRY_FAILED 0x20
/* Route has a 'fib' set of nexthops, probably because the installed set
* differs from the rib/normal set of nexthops.
*/
#define ROUTE_ENTRY_USE_FIB_NHG 0x40
zebra: Fix handling of recursive routes when processing closely in time When zebra receives routes from upper level protocols it decodes the zapi message and places the routes on the metaQ for processing. Suppose we have a route A that is already installed by some routing protocol. And there is a route B that has a nexthop that will be recursively resolved through A. Imagine if a route replace operation for A is going to happen from an upper level protocol at about the same time the route B is going to be installed into zebra. If these routes are received, and decoded, at about the same time there exists a chance that the metaQ will contain both of them at the same time. If the order of installation is [ B, A ]. B will be resolved correctly through A and installed, A will be processed and re-installed into the FIB. If the nexthops have changed for A then the owner of B should be notified about the change( and B can do the correct action here and decide to withdraw or re-install ). Now imagine if the order of routes received for processing on the metaQ is [ A, B ]. A will be received, processed and sent to the dataplane for reinstall. B will then be pulled off the metaQ and fail the install since A is in a `not Installed` state. Let's loosen the restriction in nexthop resolution for B such that if the route we are dependent on is a route replace operation allow the resolution to suceed. This requires zebra to track a new route state( ROUTE_ENTRY_ROUTE_REPLACING ) that can be looked at during nexthop resolution. I believe this is ok because A is a route replace operation, which could result in this: -route install failed, in which case B should be nht'ing and will receive the nht failure and the upper level protocol should remove B. -route install succeeded, no nexthop changes. In this case allowing the resolution for B is ok, NHT will not notify the upper level protocol so no action is needed. -route install succeeded, nexthops changes. In this case allowing the resolution for B is ok, NHT will notify the upper level protocol and it can decide to reinstall B or not based upon it's own algorithm. This set of events was found by the bgp_distance_change topotest(s). Effectively the tests were looking for the bug ( A, B order in the metaQ ) as the `correct` state. When under very heavy load, the A, B ordering caused A to just be installed and fully resolved in the dataplane before B is gotten to( which is entirely possible ). Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2022-10-21 13:20:44 +02:00
/*
* Route entries that are going to the dplane for a Route Replace
* let's note the fact that this is happening. This will
* be useful when zebra is determing if a route can be
* used for nexthops
*/
#define ROUTE_ENTRY_ROUTE_REPLACING 0x80
[zebra] Bug #268, Fix race between add/delete of routes, sanitise rib queueing 2006-07-27 Paul Jakma <paul.jakma@sun.com> * rib.h: (struct rib) Add a route_node rn_status flag field, this has to be copied every time head RIB of a route_node changes. Remove the rib lock field, not needed - see below. Add a status field for RIB-private flags. * zebra_rib.c: Add a global for the workqueue hold time, useful for testing. (general) Fix for bug #268. Problem originally detailed by Simon Bryden in [quagga-dev 4001]. Essentially, add/delete of a RIB must happen /before/ the queue. Best-path selection (ie rib_process) and reaping of freed RIBs can then be done after queueing. Only the route_node is queued - no important RIB state (i.e. whether a RIB is to be deleted) is queued. (struct zebra_queue_node_t) Disappears, no longer need to track multiple things on the queue, only the route_node. (rib_{lock,unlock}) removed, RIBs no longer need to be refcounted, no longer queued. (rib_queue_qnode_del) Removed, deleted RIBs no longer deleted via the queue. (rib_queue_add_qnode) deleted (rib_queue_add) Only the route_node is queued for best-path selection, we can check whether it is already queued or not and avoid queueing same node twice - struct rib * argument is not needed. (rib_link/unlink) (un)link RIB from route_node. (rib_{add,del}node) Front-end to updates of a RIB. (rib_process) Reap any deleted RIBs via rib_unlink. Unset the route_node 'QUEUED' flag. (General) Remove calls to rib_queue_add where add/del node was called - not needed, update calls where not. Ignore RIB_ENTRY_REMOVEd ribs in loops through route_nodes
2006-07-27 23:49:00 +02:00
/* Sequence value incremented for each dataplane operation */
uint32_t dplane_sequence;
/* Source protocol instance */
uint16_t instance;
/* Distance. */
uint8_t distance;
2024-02-05 20:15:29 +01:00
/* Tag */
route_tag_t tag;
/* Uptime. */
time_t uptime;
struct re_opaque *opaque;
2024-02-05 20:15:29 +01:00
/* Nexthop group from FIB (optional), reflecting what is actually
* installed in the FIB if that differs. The 'backup' group is used
* when backup nexthops are present in the route's nhg.
*/
struct nexthop_group fib_ng;
struct nexthop_group fib_backup_ng;
2002-12-13 21:15:29 +01:00
};
#define RIB_SYSTEM_ROUTE(R) RSYSTEM_ROUTE((R)->type)
#define RIB_KERNEL_ROUTE(R) RKERNEL_ROUTE((R)->type)
/* Define route types that are equivalent to "connected". */
#define RIB_CONNECTED_ROUTE(R) \
((R)->type == ZEBRA_ROUTE_CONNECT || (R)->type == ZEBRA_ROUTE_LOCAL || (R)->type == ZEBRA_ROUTE_NHRP)
/* meta-queue structure:
* sub-queue 0: nexthop group objects
* sub-queue 1: EVPN/VxLAN objects
* sub-queue 2: Early Route Processing
* sub-queue 3: Early Label Processing
* sub-queue 4: connected
* sub-queue 5: kernel
* sub-queue 6: static
* sub-queue 7: RIP, RIPng, OSPF, OSPF6, IS-IS, EIGRP, NHRP
* sub-queue 8: iBGP, eBGP
* sub-queue 9: any other origin (if any) typically those that
* don't generate routes
*/
#define MQ_SIZE 11
zebra: fix assert in process_subq_route Bug is reporoduced in case of switching interfaces betwean VRFs. ospf6d is enabled and configured in each VRF. 'dest' can be removed from the route node in the time when the same route node waiting processing in another sub-queue. A route node must only be in one sub-queue at a time. Details: 1. Config: interface if0 ipv6 address 2001:db8:cafe:2::2/64 ipv6 nat inside ipv6 ospf6 area 0.0.0.51 ipv6 ospf6 cost 10 vrf test2 exit ! interface if1 ipv6 address 2001:db8:cafe:4::1/64 ipv6 nat outside ipv6 ospf6 area 0.0.0.0 ipv6 ospf6 cost 10 vrf test2 exit ! router ospf6 ospf6 router-id 2.2.2.2 exit ! router ospf6 vrf test1 ospf6 router-id 2.2.2.2 exit ! router ospf6 vrf test2 ospf6 router-id 2.2.2.2 exit I just quickly switched interfaces between different VRFs (default/test1/test2). 2. Log messages: Aug 02 16:51:56 ubuntu zebra[386985]: [MFYWV-KH3MC] process_subq_early_route_add: (0:?):2001:db8:cafe:2::/64: Inserting route rn 0x56267593de90, re 0x56267595ae40 (connected) existing 0x0, same_count 0 Aug 02 16:51:56 ubuntu zebra[386985]: [Q4T2G-E2SQF] process_subq_early_route_add: dumping RE entry 0x56267595ae40 for 2001:db8:cafe:2::/64 vrf default(0) Aug 02 16:51:56 ubuntu zebra[386985]: [GCGMT-SQR82] rib_link: (0:?):2001:db8:cafe:2::/64: rn 0x56267593de90 adding dest Aug 02 16:51:56 ubuntu zebra[386985]: [JF0K0-DVHWH] rib_meta_queue_add: (0:254):2001:db8:cafe:2::/64: queued rn 0x56267593de90 into sub-queue Connected Routes Aug 02 16:51:56 ubuntu zebra[386985]: [QE6V0-J8BG5] rib_delnode: (0:254):2001:db8:cafe:2::/64: rn 0x56267593de90, re 0x56267595ae40, removing Aug 02 16:51:56 ubuntu zebra[386985]: [KMPGN-JBRKW] rib_meta_queue_add: (0:254):2001:db8:cafe:2::/64: rn 0x56267593de90 is already queued in sub-queue Connected Routes Aug 02 16:51:56 ubuntu zebra[386985]: [MFYWV-KH3MC] process_subq_early_route_add: (0:254):2001:db8:cafe:2::/64: Inserting route rn 0x56267593de90, re 0x56267595abf0 (ospf6) existing 0x0, same_count 1 Aug 02 16:51:56 ubuntu zebra[386985]: [Q4T2G-E2SQF] process_subq_early_route_add: dumping RE entry 0x56267595abf0 for 2001:db8:cafe:2::/64 vrf default(0) Aug 02 16:51:56 ubuntu zebra[386985]: [KMPGN-JBRKW] rib_meta_queue_add: (0:254):2001:db8:cafe:2::/64: rn 0x56267593de90 is already queued in sub-queue Connected Routes Aug 02 16:51:56 ubuntu zebra[386985]: [YEYFX-TDSC2] process_subq_early_route_add: (0:254):2001:db8:cafe:2::/64: rn 0x56267593de90, removing unneeded re 0x56267595ae40 Aug 02 16:51:56 ubuntu zebra[386985]: [Y53JX-CBC5H] rib_unlink: (0:254):2001:db8:cafe:2::/64: rn 0x56267593de90, re 0x56267595ae40 Aug 02 16:51:56 ubuntu zebra[386985]: [QE6V0-J8BG5] rib_delnode: (0:254):2001:db8:cafe:2::/64: rn 0x56267593de90, re 0x56267595abf0, removing Aug 02 16:51:56 ubuntu zebra[386985]: [JF0K0-DVHWH] rib_meta_queue_add: (0:254):2001:db8:cafe:2::/64: queued rn 0x56267593de90 into sub-queue RIP/OSPF/ISIS/EIGRP/NHRP Routes Aug 02 16:51:56 ubuntu zebra[386985]: [NZNZ4-7P54Y] default(0:254):2001:db8:cafe:2::/64: Processing rn 0x56267593de90 Aug 02 16:51:56 ubuntu zebra[386985]: [ZJVZ4-XEGPF] default(0:254):2001:db8:cafe:2::/64: Examine re 0x56267595abf0 (ospf6) status: Removed Changed flags: None dist 110 metric 10 Aug 02 16:51:56 ubuntu zebra[386985]: [NM15X-X83N9] rib_process: (0:254):2001:db8:cafe:2::/64: rn 0x56267593de90, removing re 0x56267595abf0 Aug 02 16:51:56 ubuntu zebra[386985]: [Y53JX-CBC5H] rib_unlink: (0:254):2001:db8:cafe:2::/64: rn 0x56267593de90, re 0x56267595abf0 Aug 02 16:51:56 ubuntu zebra[386985]: [KT8QQ-45WQ0] rib_gc_dest: (0:?):2001:db8:cafe:2::/64: removing dest from table Aug 02 16:51:56 ubuntu zebra[386985]: [HH6N2-PDCJS] default(0:0):2001:db8:cafe:2::/64 rn 0x56267593de90 dequeued from sub-queue Connected Routes 3. ...and then assert: (gdb) bt #0 __pthread_kill_implementation (no_tid=0, signo=6, threadid=140662163115136) at ./nptl/pthread_kill.c:44 #1 __pthread_kill_internal (signo=6, threadid=140662163115136) at ./nptl/pthread_kill.c:78 #2 __GI___pthread_kill (threadid=140662163115136, signo=signo@entry=6) at ./nptl/pthread_kill.c:89 #3 0x00007fee76753476 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26 #4 0x00007fee767397f3 in __GI_abort () at ./stdlib/abort.c:79 #5 0x00007fee76a420fd in _zlog_assert_failed () from target:/usr/lib/x86_64-linux-gnu/frr/libfrr.so.0 #6 0x0000562674efe0f0 in process_subq_route (qindex=7 '\a', lnode=0x562675940c60) at zebra/zebra_rib.c:2540 #7 process_subq (qindex=META_QUEUE_NOTBGP, subq=0x562675574580) at zebra/zebra_rib.c:3055 #8 meta_queue_process (dummy=<optimized out>, data=0x56267556d430) at zebra/zebra_rib.c:3091 #9 0x00007fee76a386e8 in work_queue_run () from target:/usr/lib/x86_64-linux-gnu/frr/libfrr.so.0 #10 0x00007fee76a31c91 in thread_call () from target:/usr/lib/x86_64-linux-gnu/frr/libfrr.so.0 #11 0x00007fee769ee528 in frr_run () from target:/usr/lib/x86_64-linux-gnu/frr/libfrr.so.0 #12 0x0000562674e97ec5 in main (argc=5, argv=0x7ffd1e275958) at zebra/main.c:478 (gdb) print lnode->data $10 = (void *) 0x56267593de90 (gdb) p/x *(struct route_node *)0x56267593de90 $11 = { p = { family = 0xa, prefixlen = 0x40, u = { prefix = 0x20, prefix4 = { s_addr = 0xb80d0120 }, prefix6 = { __in6_u = { __u6_addr8 = {0x20, 0x1, 0xd, 0xb8, 0xca, 0xfe, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, __u6_addr16 = {0x120, 0xb80d, 0xfeca, 0x200, 0x0, 0x0, 0x0, 0x0}, __u6_addr32 = {0xb80d0120, 0x200feca, 0x0, 0x0} } }, ... table = 0x5626755ae010, parent = 0x5626755ae070, link = {0x0, 0x0}, lock = 0x4, nodehash = { hi = { next = 0x5626755ae0d0, hashval = 0xebe8bdbf } }, info = 0x0 3. What's happen: We removed unneeded re 0x56267595ae40 while adding re 0x56267595abf0. It was the last connected re, but rn 0x56267593de90 is still in the connected sub-queue. Then rib_delnode was called for 0x56267595abf0. (rn 0x56267593de90 is still in the connected sub-queue). rib_delnode have called rib_meta_queue_add which have checked, that rn is absent in sub-queue RIP/OSPF/ISIS/EIGRP/NHRP and have added rn in the second sub-queue. Fixes: d7ac4c4d88 ("zebra: Introduce early route processing on the MetaQ") Signed-off-by: Pavel Ivashchenko <pivashchenko@nfware.com>
2023-08-03 16:01:51 +02:00
/* For checking that an object has already queued in some sub-queue */
#define MQ_BIT_MASK ((1 << MQ_SIZE) - 1)
struct meta_queue {
struct list *subq[MQ_SIZE];
uint32_t size; /* sum of lengths of all subqueues */
};
zebra: add structure to hold per-prefix state in RIB Add the rib_dest_t structure to hold per-prefix state in the routing information base. This gives us an appropriate place to maintain the queueing state of a route_node. Queuing state was previously being stored on the first rib in the list of ribs hanging off the route_node. * zebra/rib.h - Add new structure rib_dest_t. - Remove the rn_status field from 'struct rib', it is no longer required. - Add macros (RNODE_FOREACH_RIB, RNODE_FOREACH_RIB_SAFE) for walking all 'struct ribs' corresponding to a route_node. These hide the fact that there is an intermediate rib_dest_t structure. - Add a few utility inlines to go between a rib_dest_t and associated structures. * zebra/zebra_rib.c - rib_link()/rib_unlink() Tweak for new behavior, where the 'info' pointer of a route_node points to a rib_dest_t. The list of ribs for a prefix now hangs off of the dest. Change the way we ref count route_nodes. We now hold a single ref count on a route_node if there is a corresponding rib_dest_t. - Maintain the queuing state of a route_node on the flags field of the rib_dest_t. - Add the rib_gc_dest() function, which deletes a rib_dest_t if it is no longer required. A rib_dest_t can be deleted iff there are no struct ribs hanging off of it. - Call rib_gc_dest() any time we unlink a rib from the rib_dest_t. Currently we only need to call it once, just before we return from rib_process(). * zebra/{redistribute,zebra_rib,zebra_snmp,zebra_vty}.c Use new macros to walk over route_node ribs. * lib/memtypes.c Add memory type for rib_dest_t. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-13 23:48:53 +01:00
/*
* Structure that represents a single destination (prefix).
*/
typedef struct rib_dest_t_ {
/*
* Back pointer to the route node for this destination. This helps
* us get to the prefix that this structure is for.
*/
struct route_node *rnode;
/*
* Doubly-linked list of routes for this prefix.
*/
struct re_list_head routes;
zebra: add structure to hold per-prefix state in RIB Add the rib_dest_t structure to hold per-prefix state in the routing information base. This gives us an appropriate place to maintain the queueing state of a route_node. Queuing state was previously being stored on the first rib in the list of ribs hanging off the route_node. * zebra/rib.h - Add new structure rib_dest_t. - Remove the rn_status field from 'struct rib', it is no longer required. - Add macros (RNODE_FOREACH_RIB, RNODE_FOREACH_RIB_SAFE) for walking all 'struct ribs' corresponding to a route_node. These hide the fact that there is an intermediate rib_dest_t structure. - Add a few utility inlines to go between a rib_dest_t and associated structures. * zebra/zebra_rib.c - rib_link()/rib_unlink() Tweak for new behavior, where the 'info' pointer of a route_node points to a rib_dest_t. The list of ribs for a prefix now hangs off of the dest. Change the way we ref count route_nodes. We now hold a single ref count on a route_node if there is a corresponding rib_dest_t. - Maintain the queuing state of a route_node on the flags field of the rib_dest_t. - Add the rib_gc_dest() function, which deletes a rib_dest_t if it is no longer required. A rib_dest_t can be deleted iff there are no struct ribs hanging off of it. - Call rib_gc_dest() any time we unlink a rib from the rib_dest_t. Currently we only need to call it once, just before we return from rib_process(). * zebra/{redistribute,zebra_rib,zebra_snmp,zebra_vty}.c Use new macros to walk over route_node ribs. * lib/memtypes.c Add memory type for rib_dest_t. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-13 23:48:53 +01:00
struct route_entry *selected_fib;
zebra: add structure to hold per-prefix state in RIB Add the rib_dest_t structure to hold per-prefix state in the routing information base. This gives us an appropriate place to maintain the queueing state of a route_node. Queuing state was previously being stored on the first rib in the list of ribs hanging off the route_node. * zebra/rib.h - Add new structure rib_dest_t. - Remove the rn_status field from 'struct rib', it is no longer required. - Add macros (RNODE_FOREACH_RIB, RNODE_FOREACH_RIB_SAFE) for walking all 'struct ribs' corresponding to a route_node. These hide the fact that there is an intermediate rib_dest_t structure. - Add a few utility inlines to go between a rib_dest_t and associated structures. * zebra/zebra_rib.c - rib_link()/rib_unlink() Tweak for new behavior, where the 'info' pointer of a route_node points to a rib_dest_t. The list of ribs for a prefix now hangs off of the dest. Change the way we ref count route_nodes. We now hold a single ref count on a route_node if there is a corresponding rib_dest_t. - Maintain the queuing state of a route_node on the flags field of the rib_dest_t. - Add the rib_gc_dest() function, which deletes a rib_dest_t if it is no longer required. A rib_dest_t can be deleted iff there are no struct ribs hanging off of it. - Call rib_gc_dest() any time we unlink a rib from the rib_dest_t. Currently we only need to call it once, just before we return from rib_process(). * zebra/{redistribute,zebra_rib,zebra_snmp,zebra_vty}.c Use new macros to walk over route_node ribs. * lib/memtypes.c Add memory type for rib_dest_t. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-13 23:48:53 +01:00
/*
* Flags, see below.
*/
uint32_t flags;
zebra: add structure to hold per-prefix state in RIB Add the rib_dest_t structure to hold per-prefix state in the routing information base. This gives us an appropriate place to maintain the queueing state of a route_node. Queuing state was previously being stored on the first rib in the list of ribs hanging off the route_node. * zebra/rib.h - Add new structure rib_dest_t. - Remove the rn_status field from 'struct rib', it is no longer required. - Add macros (RNODE_FOREACH_RIB, RNODE_FOREACH_RIB_SAFE) for walking all 'struct ribs' corresponding to a route_node. These hide the fact that there is an intermediate rib_dest_t structure. - Add a few utility inlines to go between a rib_dest_t and associated structures. * zebra/zebra_rib.c - rib_link()/rib_unlink() Tweak for new behavior, where the 'info' pointer of a route_node points to a rib_dest_t. The list of ribs for a prefix now hangs off of the dest. Change the way we ref count route_nodes. We now hold a single ref count on a route_node if there is a corresponding rib_dest_t. - Maintain the queuing state of a route_node on the flags field of the rib_dest_t. - Add the rib_gc_dest() function, which deletes a rib_dest_t if it is no longer required. A rib_dest_t can be deleted iff there are no struct ribs hanging off of it. - Call rib_gc_dest() any time we unlink a rib from the rib_dest_t. Currently we only need to call it once, just before we return from rib_process(). * zebra/{redistribute,zebra_rib,zebra_snmp,zebra_vty}.c Use new macros to walk over route_node ribs. * lib/memtypes.c Add memory type for rib_dest_t. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-13 23:48:53 +01:00
/*
* The list of nht prefixes that have ended up
* depending on this route node.
* After route processing is returned from
* the data plane we will run evaluate_rnh
* on these prefixes.
*/
struct rnh_list_head nht;
zebra: add module to communicate routes to FPM Enhance zebra to send routes to the (optional) Forwarding Path Manager component using the interface defined by fpm/fpm.h. * configure.ac - Add --enable-fpm flag. The FPM-related code in zebra is activated only if the build is configured with '--enable-fpm'. - Add HAVE_NETLINK automake conditional. This allows us to conditionally build netlink-dependent C code. * zebra/{rib.h,zebra_rib.c} - Add the 'fpm_q_entries' field to the rib_dest_t structure. This allows dests to be placed on the fpm queue. - Define a couple new rib_dest_t flags that hold FPM-related state. - Invoke the zfpm_trigger_update() function for a route_node whenever the information to be sent to the FPM changes. - rib_can_delete_dest(): Return FALSE if we have to update the FPM about the given dest. This ensures that the dest is not deleted even if there are no ribs hanging off of it. * zebra/zebra_fpm.c This file holds most of the code for interacting with the FPM. - If quagga was configured with '--enable-fpm', periodically try to connect to the FPM. - When the connection comes up, enqueue all relevent dests to the FPM queue. - When the FPM socket is readable, dequeue the next rib_dest_t from the FPM queue, encode it in to a message and send the message to the FPM. - When the connection to the FPM goes down, remove all dests from the FPM queue, and then start trying to connect to the FPM again. - Expose the following new operational commands: show zebra fpm stats clear zebra fpm stats * zebra/zebra_fpm_netlink.c - zfpm_netlink_encode_route(): Function to encode information about a rib_dest_t in netlink format. * zebra/zebra_fpm_private.h Private header file for the zebra FPM module. * zebra/zebra_fpm.h Header file exported by zebra FPM module to the rest of zebra. * zebra/debug.c Add the 'debug zebra fpm' command. * zebra/main.c Initialize the zebra-FPM code on startup. * zebra/misc_null.c Add stub for zfpm_trigger_update(). * zebra/Makefile.am - Include new file zebra_fpm.c in build. - Include zebra_fpm_netlink.c in build if HAVE_NETLINK is defined. * vtysh/Makefile.am Include zebra_fpm.c in list of files that define cli commands. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-13 23:48:59 +01:00
/*
* Linkage to put dest on the FPM processing queue.
*/
TAILQ_ENTRY(rib_dest_t_) fpm_q_entries;
zebra: add structure to hold per-prefix state in RIB Add the rib_dest_t structure to hold per-prefix state in the routing information base. This gives us an appropriate place to maintain the queueing state of a route_node. Queuing state was previously being stored on the first rib in the list of ribs hanging off the route_node. * zebra/rib.h - Add new structure rib_dest_t. - Remove the rn_status field from 'struct rib', it is no longer required. - Add macros (RNODE_FOREACH_RIB, RNODE_FOREACH_RIB_SAFE) for walking all 'struct ribs' corresponding to a route_node. These hide the fact that there is an intermediate rib_dest_t structure. - Add a few utility inlines to go between a rib_dest_t and associated structures. * zebra/zebra_rib.c - rib_link()/rib_unlink() Tweak for new behavior, where the 'info' pointer of a route_node points to a rib_dest_t. The list of ribs for a prefix now hangs off of the dest. Change the way we ref count route_nodes. We now hold a single ref count on a route_node if there is a corresponding rib_dest_t. - Maintain the queuing state of a route_node on the flags field of the rib_dest_t. - Add the rib_gc_dest() function, which deletes a rib_dest_t if it is no longer required. A rib_dest_t can be deleted iff there are no struct ribs hanging off of it. - Call rib_gc_dest() any time we unlink a rib from the rib_dest_t. Currently we only need to call it once, just before we return from rib_process(). * zebra/{redistribute,zebra_rib,zebra_snmp,zebra_vty}.c Use new macros to walk over route_node ribs. * lib/memtypes.c Add memory type for rib_dest_t. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-13 23:48:53 +01:00
} rib_dest_t;
DECLARE_LIST(rnh_list, struct rnh, rnh_list_item);
DECLARE_LIST(re_list, struct route_entry, next);
zebra: add structure to hold per-prefix state in RIB Add the rib_dest_t structure to hold per-prefix state in the routing information base. This gives us an appropriate place to maintain the queueing state of a route_node. Queuing state was previously being stored on the first rib in the list of ribs hanging off the route_node. * zebra/rib.h - Add new structure rib_dest_t. - Remove the rn_status field from 'struct rib', it is no longer required. - Add macros (RNODE_FOREACH_RIB, RNODE_FOREACH_RIB_SAFE) for walking all 'struct ribs' corresponding to a route_node. These hide the fact that there is an intermediate rib_dest_t structure. - Add a few utility inlines to go between a rib_dest_t and associated structures. * zebra/zebra_rib.c - rib_link()/rib_unlink() Tweak for new behavior, where the 'info' pointer of a route_node points to a rib_dest_t. The list of ribs for a prefix now hangs off of the dest. Change the way we ref count route_nodes. We now hold a single ref count on a route_node if there is a corresponding rib_dest_t. - Maintain the queuing state of a route_node on the flags field of the rib_dest_t. - Add the rib_gc_dest() function, which deletes a rib_dest_t if it is no longer required. A rib_dest_t can be deleted iff there are no struct ribs hanging off of it. - Call rib_gc_dest() any time we unlink a rib from the rib_dest_t. Currently we only need to call it once, just before we return from rib_process(). * zebra/{redistribute,zebra_rib,zebra_snmp,zebra_vty}.c Use new macros to walk over route_node ribs. * lib/memtypes.c Add memory type for rib_dest_t. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-13 23:48:53 +01:00
#define RIB_ROUTE_QUEUED(x) (1 << (x))
// If MQ_SIZE is modified this value needs to be updated.
#define RIB_ROUTE_ANY_QUEUED 0x3F
zebra: add structure to hold per-prefix state in RIB Add the rib_dest_t structure to hold per-prefix state in the routing information base. This gives us an appropriate place to maintain the queueing state of a route_node. Queuing state was previously being stored on the first rib in the list of ribs hanging off the route_node. * zebra/rib.h - Add new structure rib_dest_t. - Remove the rn_status field from 'struct rib', it is no longer required. - Add macros (RNODE_FOREACH_RIB, RNODE_FOREACH_RIB_SAFE) for walking all 'struct ribs' corresponding to a route_node. These hide the fact that there is an intermediate rib_dest_t structure. - Add a few utility inlines to go between a rib_dest_t and associated structures. * zebra/zebra_rib.c - rib_link()/rib_unlink() Tweak for new behavior, where the 'info' pointer of a route_node points to a rib_dest_t. The list of ribs for a prefix now hangs off of the dest. Change the way we ref count route_nodes. We now hold a single ref count on a route_node if there is a corresponding rib_dest_t. - Maintain the queuing state of a route_node on the flags field of the rib_dest_t. - Add the rib_gc_dest() function, which deletes a rib_dest_t if it is no longer required. A rib_dest_t can be deleted iff there are no struct ribs hanging off of it. - Call rib_gc_dest() any time we unlink a rib from the rib_dest_t. Currently we only need to call it once, just before we return from rib_process(). * zebra/{redistribute,zebra_rib,zebra_snmp,zebra_vty}.c Use new macros to walk over route_node ribs. * lib/memtypes.c Add memory type for rib_dest_t. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-13 23:48:53 +01:00
/*
* The maximum qindex that can be used.
*/
#define ZEBRA_MAX_QINDEX (MQ_SIZE - 1)
zebra: add module to communicate routes to FPM Enhance zebra to send routes to the (optional) Forwarding Path Manager component using the interface defined by fpm/fpm.h. * configure.ac - Add --enable-fpm flag. The FPM-related code in zebra is activated only if the build is configured with '--enable-fpm'. - Add HAVE_NETLINK automake conditional. This allows us to conditionally build netlink-dependent C code. * zebra/{rib.h,zebra_rib.c} - Add the 'fpm_q_entries' field to the rib_dest_t structure. This allows dests to be placed on the fpm queue. - Define a couple new rib_dest_t flags that hold FPM-related state. - Invoke the zfpm_trigger_update() function for a route_node whenever the information to be sent to the FPM changes. - rib_can_delete_dest(): Return FALSE if we have to update the FPM about the given dest. This ensures that the dest is not deleted even if there are no ribs hanging off of it. * zebra/zebra_fpm.c This file holds most of the code for interacting with the FPM. - If quagga was configured with '--enable-fpm', periodically try to connect to the FPM. - When the connection comes up, enqueue all relevent dests to the FPM queue. - When the FPM socket is readable, dequeue the next rib_dest_t from the FPM queue, encode it in to a message and send the message to the FPM. - When the connection to the FPM goes down, remove all dests from the FPM queue, and then start trying to connect to the FPM again. - Expose the following new operational commands: show zebra fpm stats clear zebra fpm stats * zebra/zebra_fpm_netlink.c - zfpm_netlink_encode_route(): Function to encode information about a rib_dest_t in netlink format. * zebra/zebra_fpm_private.h Private header file for the zebra FPM module. * zebra/zebra_fpm.h Header file exported by zebra FPM module to the rest of zebra. * zebra/debug.c Add the 'debug zebra fpm' command. * zebra/main.c Initialize the zebra-FPM code on startup. * zebra/misc_null.c Add stub for zfpm_trigger_update(). * zebra/Makefile.am - Include new file zebra_fpm.c in build. - Include zebra_fpm_netlink.c in build if HAVE_NETLINK is defined. * vtysh/Makefile.am Include zebra_fpm.c in list of files that define cli commands. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-13 23:48:59 +01:00
/*
* This flag indicates that a given prefix has been 'advertised' to
* the FPM to be installed in the forwarding plane.
*/
#define RIB_DEST_SENT_TO_FPM (1 << (ZEBRA_MAX_QINDEX + 1))
/*
* This flag is set when we need to send an update to the FPM about a
* dest.
*/
#define RIB_DEST_UPDATE_FPM (1 << (ZEBRA_MAX_QINDEX + 2))
#define RIB_DEST_UPDATE_LSPS (1 << (ZEBRA_MAX_QINDEX + 3))
zebra: add structure to hold per-prefix state in RIB Add the rib_dest_t structure to hold per-prefix state in the routing information base. This gives us an appropriate place to maintain the queueing state of a route_node. Queuing state was previously being stored on the first rib in the list of ribs hanging off the route_node. * zebra/rib.h - Add new structure rib_dest_t. - Remove the rn_status field from 'struct rib', it is no longer required. - Add macros (RNODE_FOREACH_RIB, RNODE_FOREACH_RIB_SAFE) for walking all 'struct ribs' corresponding to a route_node. These hide the fact that there is an intermediate rib_dest_t structure. - Add a few utility inlines to go between a rib_dest_t and associated structures. * zebra/zebra_rib.c - rib_link()/rib_unlink() Tweak for new behavior, where the 'info' pointer of a route_node points to a rib_dest_t. The list of ribs for a prefix now hangs off of the dest. Change the way we ref count route_nodes. We now hold a single ref count on a route_node if there is a corresponding rib_dest_t. - Maintain the queuing state of a route_node on the flags field of the rib_dest_t. - Add the rib_gc_dest() function, which deletes a rib_dest_t if it is no longer required. A rib_dest_t can be deleted iff there are no struct ribs hanging off of it. - Call rib_gc_dest() any time we unlink a rib from the rib_dest_t. Currently we only need to call it once, just before we return from rib_process(). * zebra/{redistribute,zebra_rib,zebra_snmp,zebra_vty}.c Use new macros to walk over route_node ribs. * lib/memtypes.c Add memory type for rib_dest_t. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-13 23:48:53 +01:00
/*
* Macro to iterate over each route for a destination (prefix).
*/
#define RE_DEST_FOREACH_ROUTE(dest, re) \
for ((re) = (dest) ? re_list_first(&((dest)->routes)) : NULL; (re); \
(re) = re_list_next(&((dest)->routes), (re)))
zebra: add structure to hold per-prefix state in RIB Add the rib_dest_t structure to hold per-prefix state in the routing information base. This gives us an appropriate place to maintain the queueing state of a route_node. Queuing state was previously being stored on the first rib in the list of ribs hanging off the route_node. * zebra/rib.h - Add new structure rib_dest_t. - Remove the rn_status field from 'struct rib', it is no longer required. - Add macros (RNODE_FOREACH_RIB, RNODE_FOREACH_RIB_SAFE) for walking all 'struct ribs' corresponding to a route_node. These hide the fact that there is an intermediate rib_dest_t structure. - Add a few utility inlines to go between a rib_dest_t and associated structures. * zebra/zebra_rib.c - rib_link()/rib_unlink() Tweak for new behavior, where the 'info' pointer of a route_node points to a rib_dest_t. The list of ribs for a prefix now hangs off of the dest. Change the way we ref count route_nodes. We now hold a single ref count on a route_node if there is a corresponding rib_dest_t. - Maintain the queuing state of a route_node on the flags field of the rib_dest_t. - Add the rib_gc_dest() function, which deletes a rib_dest_t if it is no longer required. A rib_dest_t can be deleted iff there are no struct ribs hanging off of it. - Call rib_gc_dest() any time we unlink a rib from the rib_dest_t. Currently we only need to call it once, just before we return from rib_process(). * zebra/{redistribute,zebra_rib,zebra_snmp,zebra_vty}.c Use new macros to walk over route_node ribs. * lib/memtypes.c Add memory type for rib_dest_t. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-13 23:48:53 +01:00
/*
* Same as above, but allows the current node to be unlinked.
*/
#define RE_DEST_FOREACH_ROUTE_SAFE(dest, re, next) \
for ((re) = (dest) ? re_list_first(&((dest)->routes)) : NULL; \
(re) && ((next) = re_list_next(&((dest)->routes), (re)), 1); \
(re) = (next))
zebra: add structure to hold per-prefix state in RIB Add the rib_dest_t structure to hold per-prefix state in the routing information base. This gives us an appropriate place to maintain the queueing state of a route_node. Queuing state was previously being stored on the first rib in the list of ribs hanging off the route_node. * zebra/rib.h - Add new structure rib_dest_t. - Remove the rn_status field from 'struct rib', it is no longer required. - Add macros (RNODE_FOREACH_RIB, RNODE_FOREACH_RIB_SAFE) for walking all 'struct ribs' corresponding to a route_node. These hide the fact that there is an intermediate rib_dest_t structure. - Add a few utility inlines to go between a rib_dest_t and associated structures. * zebra/zebra_rib.c - rib_link()/rib_unlink() Tweak for new behavior, where the 'info' pointer of a route_node points to a rib_dest_t. The list of ribs for a prefix now hangs off of the dest. Change the way we ref count route_nodes. We now hold a single ref count on a route_node if there is a corresponding rib_dest_t. - Maintain the queuing state of a route_node on the flags field of the rib_dest_t. - Add the rib_gc_dest() function, which deletes a rib_dest_t if it is no longer required. A rib_dest_t can be deleted iff there are no struct ribs hanging off of it. - Call rib_gc_dest() any time we unlink a rib from the rib_dest_t. Currently we only need to call it once, just before we return from rib_process(). * zebra/{redistribute,zebra_rib,zebra_snmp,zebra_vty}.c Use new macros to walk over route_node ribs. * lib/memtypes.c Add memory type for rib_dest_t. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-13 23:48:53 +01:00
#define RE_DEST_FIRST_ROUTE(dest, re) \
((re) = (dest) ? re_list_first(&((dest)->routes)) : NULL)
#define RE_DEST_NEXT_ROUTE(dest, re) \
((re) = (dest) ? re_list_next(&((dest)->routes), (re)) : NULL)
#define RNODE_FOREACH_RE(rn, re) \
RE_DEST_FOREACH_ROUTE (rib_dest_from_rnode(rn), re)
zebra: add structure to hold per-prefix state in RIB Add the rib_dest_t structure to hold per-prefix state in the routing information base. This gives us an appropriate place to maintain the queueing state of a route_node. Queuing state was previously being stored on the first rib in the list of ribs hanging off the route_node. * zebra/rib.h - Add new structure rib_dest_t. - Remove the rn_status field from 'struct rib', it is no longer required. - Add macros (RNODE_FOREACH_RIB, RNODE_FOREACH_RIB_SAFE) for walking all 'struct ribs' corresponding to a route_node. These hide the fact that there is an intermediate rib_dest_t structure. - Add a few utility inlines to go between a rib_dest_t and associated structures. * zebra/zebra_rib.c - rib_link()/rib_unlink() Tweak for new behavior, where the 'info' pointer of a route_node points to a rib_dest_t. The list of ribs for a prefix now hangs off of the dest. Change the way we ref count route_nodes. We now hold a single ref count on a route_node if there is a corresponding rib_dest_t. - Maintain the queuing state of a route_node on the flags field of the rib_dest_t. - Add the rib_gc_dest() function, which deletes a rib_dest_t if it is no longer required. A rib_dest_t can be deleted iff there are no struct ribs hanging off of it. - Call rib_gc_dest() any time we unlink a rib from the rib_dest_t. Currently we only need to call it once, just before we return from rib_process(). * zebra/{redistribute,zebra_rib,zebra_snmp,zebra_vty}.c Use new macros to walk over route_node ribs. * lib/memtypes.c Add memory type for rib_dest_t. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-13 23:48:53 +01:00
#define RNODE_FOREACH_RE_SAFE(rn, re, next) \
RE_DEST_FOREACH_ROUTE_SAFE (rib_dest_from_rnode(rn), re, next)
zebra: add structure to hold per-prefix state in RIB Add the rib_dest_t structure to hold per-prefix state in the routing information base. This gives us an appropriate place to maintain the queueing state of a route_node. Queuing state was previously being stored on the first rib in the list of ribs hanging off the route_node. * zebra/rib.h - Add new structure rib_dest_t. - Remove the rn_status field from 'struct rib', it is no longer required. - Add macros (RNODE_FOREACH_RIB, RNODE_FOREACH_RIB_SAFE) for walking all 'struct ribs' corresponding to a route_node. These hide the fact that there is an intermediate rib_dest_t structure. - Add a few utility inlines to go between a rib_dest_t and associated structures. * zebra/zebra_rib.c - rib_link()/rib_unlink() Tweak for new behavior, where the 'info' pointer of a route_node points to a rib_dest_t. The list of ribs for a prefix now hangs off of the dest. Change the way we ref count route_nodes. We now hold a single ref count on a route_node if there is a corresponding rib_dest_t. - Maintain the queuing state of a route_node on the flags field of the rib_dest_t. - Add the rib_gc_dest() function, which deletes a rib_dest_t if it is no longer required. A rib_dest_t can be deleted iff there are no struct ribs hanging off of it. - Call rib_gc_dest() any time we unlink a rib from the rib_dest_t. Currently we only need to call it once, just before we return from rib_process(). * zebra/{redistribute,zebra_rib,zebra_snmp,zebra_vty}.c Use new macros to walk over route_node ribs. * lib/memtypes.c Add memory type for rib_dest_t. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-13 23:48:53 +01:00
#define RNODE_FIRST_RE(rn, re) RE_DEST_FIRST_ROUTE(rib_dest_from_rnode(rn), re)
#define RNODE_NEXT_RE(rn, re) RE_DEST_NEXT_ROUTE(rib_dest_from_rnode(rn), re)
/*
* rib_table_info_t
*
* Structure that is hung off of a route_table that holds information about
* the table.
*/
struct rib_table_info {
/*
lib, zebra: move "struct vrf" to be a lib module Previously "struct vrf" is defined locally in zebra. Now it is moved to be a lib module. This is the first step to support multi-VRF in quagga. The implementation is splitted into small patches for the purpose of easy review. * lib: "struct vrf" with basic members is defined in vrf.c. The member "void *info" is for user data. Some basic functions are defined in vrf.c for adding/deleting/ looking up a VRF, scanning the VRF table and initializing the VRF module. The type "vrf_id_t" is defined specificly for VRF ID. * zebra: The previous "struct vrf" is re-defined as "struct zebra_vrf"; and previous "vrf" variables are renamed to "zvrf". The previous "struct vrf" related functions are removed from zbera_rib.c. New functions are defined to maintain the new "struct zebra_vrf". The names vrf_xxx are reserved for the functions in VRF module. So: - the previous vrf_table() are renamed to zebra_vrf_table(); - the previous vrf_static_table() are renamed to zebra_vrf_static_table(). The main logic is not changed. BTW: Add a statement to zebra_snmp.c telling that the SNMP is running only for the MIBs in the default VRF. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Vincent JARDIN <vincent.jardin@6wind.com> Signed-off-by: David Lamparter <equinox@opensourcerouting.org> Conflicts: lib/Makefile.am zebra/zebra_rib.c zebra/zebra_vty.c Conflicts: lib/Makefile.am lib/memtypes.c zebra/rib.h zebra/zebra_rib.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zebra_vty.c
2015-05-22 11:39:56 +02:00
* Back pointer to zebra_vrf.
*/
lib, zebra: move "struct vrf" to be a lib module Previously "struct vrf" is defined locally in zebra. Now it is moved to be a lib module. This is the first step to support multi-VRF in quagga. The implementation is splitted into small patches for the purpose of easy review. * lib: "struct vrf" with basic members is defined in vrf.c. The member "void *info" is for user data. Some basic functions are defined in vrf.c for adding/deleting/ looking up a VRF, scanning the VRF table and initializing the VRF module. The type "vrf_id_t" is defined specificly for VRF ID. * zebra: The previous "struct vrf" is re-defined as "struct zebra_vrf"; and previous "vrf" variables are renamed to "zvrf". The previous "struct vrf" related functions are removed from zbera_rib.c. New functions are defined to maintain the new "struct zebra_vrf". The names vrf_xxx are reserved for the functions in VRF module. So: - the previous vrf_table() are renamed to zebra_vrf_table(); - the previous vrf_static_table() are renamed to zebra_vrf_static_table(). The main logic is not changed. BTW: Add a statement to zebra_snmp.c telling that the SNMP is running only for the MIBs in the default VRF. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Vincent JARDIN <vincent.jardin@6wind.com> Signed-off-by: David Lamparter <equinox@opensourcerouting.org> Conflicts: lib/Makefile.am zebra/zebra_rib.c zebra/zebra_vty.c Conflicts: lib/Makefile.am lib/memtypes.c zebra/rib.h zebra/zebra_rib.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zebra_vty.c
2015-05-22 11:39:56 +02:00
struct zebra_vrf *zvrf;
afi_t afi;
safi_t safi;
uint32_t table_id;
};
enum rib_tables_iter_state {
RIB_TABLES_ITER_S_INIT,
RIB_TABLES_ITER_S_ITERATING,
RIB_TABLES_ITER_S_DONE
};
/*
* Structure that holds state for iterating over all tables in the
* Routing Information Base.
*/
typedef struct rib_tables_iter_t_ {
lib, zebra: move "struct vrf" to be a lib module Previously "struct vrf" is defined locally in zebra. Now it is moved to be a lib module. This is the first step to support multi-VRF in quagga. The implementation is splitted into small patches for the purpose of easy review. * lib: "struct vrf" with basic members is defined in vrf.c. The member "void *info" is for user data. Some basic functions are defined in vrf.c for adding/deleting/ looking up a VRF, scanning the VRF table and initializing the VRF module. The type "vrf_id_t" is defined specificly for VRF ID. * zebra: The previous "struct vrf" is re-defined as "struct zebra_vrf"; and previous "vrf" variables are renamed to "zvrf". The previous "struct vrf" related functions are removed from zbera_rib.c. New functions are defined to maintain the new "struct zebra_vrf". The names vrf_xxx are reserved for the functions in VRF module. So: - the previous vrf_table() are renamed to zebra_vrf_table(); - the previous vrf_static_table() are renamed to zebra_vrf_static_table(). The main logic is not changed. BTW: Add a statement to zebra_snmp.c telling that the SNMP is running only for the MIBs in the default VRF. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Vincent JARDIN <vincent.jardin@6wind.com> Signed-off-by: David Lamparter <equinox@opensourcerouting.org> Conflicts: lib/Makefile.am zebra/zebra_rib.c zebra/zebra_vty.c Conflicts: lib/Makefile.am lib/memtypes.c zebra/rib.h zebra/zebra_rib.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zebra_vty.c
2015-05-22 11:39:56 +02:00
vrf_id_t vrf_id;
int afi_safi_ix;
enum rib_tables_iter_state state;
} rib_tables_iter_t;
/* Events/reasons triggering a RIB update. */
enum rib_update_event {
RIB_UPDATE_INTERFACE_DOWN,
RIB_UPDATE_KERNEL,
RIB_UPDATE_RMAP_CHANGE,
RIB_UPDATE_OTHER,
RIB_UPDATE_MAX
};
zebra: Cleanup ctx leak on shutdown and turn off event two things: On shutdown cleanup any events associated with the update walker. Also do not allow new events to be created. Fixes this mem-leak: ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790:Direct leak of 8 byte(s) in 1 object(s) allocated from: ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790- #0 0x7f0dd0b08037 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154 ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790- #1 0x7f0dd06c19f9 in qcalloc lib/memory.c:105 ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790- #2 0x55b42fb605bc in rib_update_ctx_init zebra/zebra_rib.c:4383 ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790- #3 0x55b42fb6088f in rib_update zebra/zebra_rib.c:4421 ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790- #4 0x55b42fa00344 in netlink_link_change zebra/if_netlink.c:2221 ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790- #5 0x55b42fa24622 in netlink_information_fetch zebra/kernel_netlink.c:399 ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790- #6 0x55b42fa28c02 in netlink_parse_info zebra/kernel_netlink.c:1183 ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790- #7 0x55b42fa24951 in kernel_read zebra/kernel_netlink.c:493 ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790- #8 0x7f0dd0797f0c in event_call lib/event.c:1995 ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790- #9 0x7f0dd0684fd9 in frr_run lib/libfrr.c:1185 ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790- #10 0x55b42fa30caa in main zebra/main.c:465 ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790- #11 0x7f0dd01b5d09 in __libc_start_main ../csu/libc-start.c:308 ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790- ./msdp_topo1.test_msdp_topo1/r2.zebra.asan.1117790-SUMMARY: AddressSanitizer: 8 byte(s) leaked in 1 allocation(s). Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2023-03-31 15:08:23 +02:00
void rib_update_finish(void);
int route_entry_update_nhe(struct route_entry *re,
struct nhg_hash_entry *new_nhghe);
/* NHG replace has happend, we have to update route_entry pointers to new one */
zebra: Fix zebra crash when replacing NHE during shutdown During replace of a NHE from upper proto in zebra_nhg_proto_add(), - rib_handle_nhg_replace() is invoked with old NHE where we walk all RNs/REs & replace the re->nhe whose address points to old NHE. - In this walk, if prev re->nhe refcnt is decremented to 0, we free up the memory which the old NHE is pointing to. Later in zebra_nhg_proto_add(), we end up accessing this freed memory and crash. Logs: 1380766 2023/08/16 22:34:11.994671 ZEBRA: [WDEB1-93HCZ] zebra_nhg_decrement_ref: nhe 0x56091d890840 (70312519[2756/2762/2810]) 2 => 1 1380773 2023/08/16 22:34:11.994678 ZEBRA: [WDEB1-93HCZ] zebra_nhg_decrement_ref: nhe 0x56091d890840 (70312519[2756/2762/2810]) 1 => 0 1380777 2023/08/16 22:34:11.994844 ZEBRA: [JE46R-G2NEE] zebra_nhg_release: nhe 0x56091d890840 (70312519[2756/2762/2810]) 1380778 2023/08/16 22:34:11.994849 ZEBRA: [SCDBM-4H062] zebra_nhg_free: nhe 0x56091d890840 (70312519[2756/2762/2810]), refcnt 0 1380782 2023/08/16 22:34:11.995000 ZEBRA: [SCDBM-4H062] zebra_nhg_free: nhe 0x56091d890840 (0[]), refcnt 0 1380783 2023/08/16 22:34:11.995011 ZEBRA: lib/memory.c:84: mt_count_free(): assertion (mt->n_alloc) failed Backtrace: 0  0x00007f833f5f48eb in raise () from /lib/x86_64-linux-gnu/libc.so.6 1  0x00007f833f5df535 in abort () from /lib/x86_64-linux-gnu/libc.so.6 2  0x00007f833f636648 in ?? () from /lib/x86_64-linux-gnu/libc.so.6 3  0x00007f833f63cd6a in ?? () from /lib/x86_64-linux-gnu/libc.so.6 4  0x00007f833f63cfb4 in ?? () from /lib/x86_64-linux-gnu/libc.so.6 5  0x00007f833f63fbc8 in ?? () from /lib/x86_64-linux-gnu/libc.so.6 6  0x00007f833f64172a in malloc () from /lib/x86_64-linux-gnu/libc.so.6 7  0x00007f833f6c3fd2 in backtrace_symbols () from /lib/x86_64-linux-gnu/libc.so.6 8  0x00007f833f9013fc in zlog_backtrace_sigsafe (priority=priority@entry=2, program_counter=program_counter@entry=0x7f833f5f48eb <raise+267>) at lib/log.c:222 9  0x00007f833f901593 in zlog_signal (signo=signo@entry=6, action=action@entry=0x7f833f988ee8 "aborting...", siginfo_v=siginfo_v@entry=0x7ffee1ce4a30,     program_counter=program_counter@entry=0x7f833f5f48eb <raise+267>) at lib/log.c:154 10 0x00007f833f92dbd1 in core_handler (signo=6, siginfo=0x7ffee1ce4a30, context=<optimized out>) at lib/sigevent.c:254 11 <signal handler called> 12 0x00007f833f5f48eb in raise () from /lib/x86_64-linux-gnu/libc.so.6 13 0x00007f833f5df535 in abort () from /lib/x86_64-linux-gnu/libc.so.6 14 0x00007f833f958f96 in _zlog_assert_failed (xref=xref@entry=0x7f833f9e4080 <_xref.10705>, extra=extra@entry=0x0) at lib/zlog.c:680 15 0x00007f833f905400 in mt_count_free (mt=0x7f833fa02800 <MTYPE_NH_LABEL>, ptr=0x51) at lib/memory.c:84 16 mt_count_free (ptr=0x51, mt=0x7f833fa02800 <MTYPE_NH_LABEL>) at lib/memory.c:80 17 qfree (mt=0x7f833fa02800 <MTYPE_NH_LABEL>, ptr=0x51) at lib/memory.c:140 18 0x00007f833f90799c in nexthop_del_labels (nexthop=nexthop@entry=0x56091d776640) at lib/nexthop.c:563 19 0x00007f833f907b91 in nexthop_free (nexthop=0x56091d776640) at lib/nexthop.c:393 20 0x00007f833f907be8 in nexthops_free (nexthop=<optimized out>) at lib/nexthop.c:408 21 0x000056091c21aa76 in zebra_nhg_free_members (nhe=0x56091d890840) at zebra/zebra_nhg.c:1628 22 zebra_nhg_free (nhe=0x56091d890840) at zebra/zebra_nhg.c:1628 23 0x000056091c21bab2 in zebra_nhg_proto_add (id=<optimized out>, type=9, instance=<optimized out>, session=0, nhg=nhg@entry=0x56091d7da028, afi=afi@entry=AFI_UNSPEC)     at zebra/zebra_nhg.c:3532 24 0x000056091c22bc4e in process_subq_nhg (lnode=0x56091d88c540) at zebra/zebra_rib.c:2689 25 process_subq (qindex=META_QUEUE_NHG, subq=0x56091d24cea0) at zebra/zebra_rib.c:3290 26 meta_queue_process (dummy=<optimized out>, data=0x56091d24d4c0) at zebra/zebra_rib.c:3343 27 0x00007f833f9492c8 in work_queue_run (thread=0x7ffee1ce55a0) at lib/workqueue.c:285 28 0x00007f833f93f60d in thread_call (thread=thread@entry=0x7ffee1ce55a0) at lib/thread.c:2008 29 0x00007f833f8f9888 in frr_run (master=0x56091d068660) at lib/libfrr.c:1223 30 0x000056091c1b8366 in main (argc=12, argv=0x7ffee1ce5988) at zebra/main.c:551 Issue: 3492162 Ticket# 3492162 Signed-off-by: Chirag Shah <chirag@nvidia.com> Signed-off-by: Rajasekar Raja <rajasekarr@nvidia.com>
2023-08-17 09:47:05 +02:00
int rib_handle_nhg_replace(struct nhg_hash_entry *old_entry,
struct nhg_hash_entry *new_entry);
#define route_entry_dump(prefix, src, re) _route_entry_dump(__func__, prefix, src, re)
extern void _route_entry_dump(const char *func, union prefixconstptr pp,
union prefixconstptr src_pp,
const struct route_entry *re);
void zebra_rib_route_entry_free(struct route_entry *re);
struct route_entry *
zebra_rib_route_entry_new(vrf_id_t vrf_id, int type, uint8_t instance,
uint32_t flags, uint32_t nhe_id, uint32_t table_id,
uint32_t metric, uint32_t mtu, uint8_t distance,
route_tag_t tag);
#define ZEBRA_RIB_LOOKUP_ERROR -1
#define ZEBRA_RIB_FOUND_EXACT 0
#define ZEBRA_RIB_FOUND_NOGATE 1
#define ZEBRA_RIB_FOUND_CONNECTED 2
#define ZEBRA_RIB_NOTFOUND 3
extern int is_zebra_valid_kernel_table(uint32_t table_id);
extern int is_zebra_main_routing_table(uint32_t table_id);
extern int zebra_check_addr(const struct prefix *p);
2002-12-13 21:15:29 +01:00
extern void rib_delnode(struct route_node *rn, struct route_entry *re);
extern void rib_install_kernel(struct route_node *rn, struct route_entry *re,
struct route_entry *old);
extern void rib_uninstall_kernel(struct route_node *rn, struct route_entry *re);
/* NOTE:
* All rib_add function will not just add prefix into RIB, but
* also implicitly withdraw equal prefix of same type. */
extern int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
unsigned short instance, uint32_t flags, struct prefix *p,
struct prefix_ipv6 *src_p, const struct nexthop *nh,
uint32_t nhe_id, uint32_t table_id, uint32_t metric,
uint32_t mtu, uint8_t distance, route_tag_t tag,
bool startup);
/*
* Multipath route apis.
*/
extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
struct prefix_ipv6 *src_p, struct route_entry *re,
struct nexthop_group *ng, bool startup);
/*
* -1 -> some sort of error
* 0 -> an add
* 1 -> an update
*/
extern int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p,
struct prefix_ipv6 *src_p,
struct route_entry *re,
struct nhg_hash_entry *nhe, bool startup);
extern void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
unsigned short instance, uint32_t flags,
const struct prefix *p, const struct prefix_ipv6 *src_p,
const struct nexthop *nh, uint32_t nhe_id,
uint32_t table_id, uint32_t metric, uint8_t distance,
bool fromkernel);
extern struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,
const union g_addr *addr,
struct route_node **rn_out);
extern struct route_entry *rib_match_multicast(afi_t afi, vrf_id_t vrf_id,
union g_addr *gaddr,
struct route_node **rn_out);
extern void rib_update(enum rib_update_event event);
extern void rib_update_table(struct route_table *table,
enum rib_update_event event, int rtype);
extern void rib_sweep_route(struct event *t);
extern void rib_sweep_table(struct route_table *table);
extern void rib_close_table(struct route_table *table);
extern void zebra_rib_init(void);
extern void zebra_rib_terminate(void);
extern unsigned long rib_score_proto(uint8_t proto, unsigned short instance);
extern unsigned long rib_score_proto_table(uint8_t proto,
unsigned short instance,
struct route_table *table);
extern int rib_queue_add(struct route_node *rn);
struct nhg_ctx; /* Forward declaration */
/* Enqueue incoming nhg from OS for processing */
extern int rib_queue_nhg_ctx_add(struct nhg_ctx *ctx);
/* Enqueue incoming nhg from proto daemon for processing */
extern int rib_queue_nhe_add(struct nhg_hash_entry *nhe);
extern int rib_queue_nhe_del(struct nhg_hash_entry *nhe);
/* Enqueue evpn route for processing */
int zebra_rib_queue_evpn_route_add(vrf_id_t vrf_id, const struct ethaddr *rmac,
const struct ipaddr *vtep_ip,
const struct prefix *host_prefix);
int zebra_rib_queue_evpn_route_del(vrf_id_t vrf_id,
const struct ipaddr *vtep_ip,
const struct prefix *host_prefix);
/* Enqueue EVPN remote ES for processing */
int zebra_rib_queue_evpn_rem_es_add(const esi_t *esi,
const struct in_addr *vtep_ip,
bool esr_rxed, uint8_t df_alg,
uint16_t df_pref);
int zebra_rib_queue_evpn_rem_es_del(const esi_t *esi,
const struct in_addr *vtep_ip);
/* Enqueue EVPN remote macip update for processing */
int zebra_rib_queue_evpn_rem_macip_del(vni_t vni, const struct ethaddr *macaddr,
const struct ipaddr *ip,
struct in_addr vtep_ip);
int zebra_rib_queue_evpn_rem_macip_add(vni_t vni, const struct ethaddr *macaddr,
const struct ipaddr *ipaddr,
uint8_t flags, uint32_t seq,
struct in_addr vtep_ip,
const esi_t *esi);
/* Enqueue VXLAN remote vtep update for processing */
int zebra_rib_queue_evpn_rem_vtep_add(vrf_id_t vrf_id, vni_t vni,
struct in_addr vtep_ip,
int flood_control);
int zebra_rib_queue_evpn_rem_vtep_del(vrf_id_t vrf_id, vni_t vni,
struct in_addr vtep_ip);
extern void meta_queue_free(struct meta_queue *mq, struct zebra_vrf *zvrf);
extern int zebra_rib_labeled_unicast(struct route_entry *re);
2002-12-13 21:15:29 +01:00
extern struct route_table *rib_table_ipv6;
extern void rib_unlink(struct route_node *rn, struct route_entry *re);
zebra: add structure to hold per-prefix state in RIB Add the rib_dest_t structure to hold per-prefix state in the routing information base. This gives us an appropriate place to maintain the queueing state of a route_node. Queuing state was previously being stored on the first rib in the list of ribs hanging off the route_node. * zebra/rib.h - Add new structure rib_dest_t. - Remove the rn_status field from 'struct rib', it is no longer required. - Add macros (RNODE_FOREACH_RIB, RNODE_FOREACH_RIB_SAFE) for walking all 'struct ribs' corresponding to a route_node. These hide the fact that there is an intermediate rib_dest_t structure. - Add a few utility inlines to go between a rib_dest_t and associated structures. * zebra/zebra_rib.c - rib_link()/rib_unlink() Tweak for new behavior, where the 'info' pointer of a route_node points to a rib_dest_t. The list of ribs for a prefix now hangs off of the dest. Change the way we ref count route_nodes. We now hold a single ref count on a route_node if there is a corresponding rib_dest_t. - Maintain the queuing state of a route_node on the flags field of the rib_dest_t. - Add the rib_gc_dest() function, which deletes a rib_dest_t if it is no longer required. A rib_dest_t can be deleted iff there are no struct ribs hanging off of it. - Call rib_gc_dest() any time we unlink a rib from the rib_dest_t. Currently we only need to call it once, just before we return from rib_process(). * zebra/{redistribute,zebra_rib,zebra_snmp,zebra_vty}.c Use new macros to walk over route_node ribs. * lib/memtypes.c Add memory type for rib_dest_t. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-13 23:48:53 +01:00
extern int rib_gc_dest(struct route_node *rn);
extern struct route_table *rib_tables_iter_next(rib_tables_iter_t *iter);
zebra: add structure to hold per-prefix state in RIB Add the rib_dest_t structure to hold per-prefix state in the routing information base. This gives us an appropriate place to maintain the queueing state of a route_node. Queuing state was previously being stored on the first rib in the list of ribs hanging off the route_node. * zebra/rib.h - Add new structure rib_dest_t. - Remove the rn_status field from 'struct rib', it is no longer required. - Add macros (RNODE_FOREACH_RIB, RNODE_FOREACH_RIB_SAFE) for walking all 'struct ribs' corresponding to a route_node. These hide the fact that there is an intermediate rib_dest_t structure. - Add a few utility inlines to go between a rib_dest_t and associated structures. * zebra/zebra_rib.c - rib_link()/rib_unlink() Tweak for new behavior, where the 'info' pointer of a route_node points to a rib_dest_t. The list of ribs for a prefix now hangs off of the dest. Change the way we ref count route_nodes. We now hold a single ref count on a route_node if there is a corresponding rib_dest_t. - Maintain the queuing state of a route_node on the flags field of the rib_dest_t. - Add the rib_gc_dest() function, which deletes a rib_dest_t if it is no longer required. A rib_dest_t can be deleted iff there are no struct ribs hanging off of it. - Call rib_gc_dest() any time we unlink a rib from the rib_dest_t. Currently we only need to call it once, just before we return from rib_process(). * zebra/{redistribute,zebra_rib,zebra_snmp,zebra_vty}.c Use new macros to walk over route_node ribs. * lib/memtypes.c Add memory type for rib_dest_t. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-13 23:48:53 +01:00
extern uint8_t route_distance(int type);
extern void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq,
bool rt_delete);
extern void rib_update_handle_vrf_all(enum rib_update_event event, int rtype);
/*
* rib_find_rn_from_ctx
*
* Returns a lock increased route_node for the appropriate
* table and prefix specified by the context. Developer
* should unlock the node when done.
*/
extern struct route_node *
rib_find_rn_from_ctx(const struct zebra_dplane_ctx *ctx);
zebra: add structure to hold per-prefix state in RIB Add the rib_dest_t structure to hold per-prefix state in the routing information base. This gives us an appropriate place to maintain the queueing state of a route_node. Queuing state was previously being stored on the first rib in the list of ribs hanging off the route_node. * zebra/rib.h - Add new structure rib_dest_t. - Remove the rn_status field from 'struct rib', it is no longer required. - Add macros (RNODE_FOREACH_RIB, RNODE_FOREACH_RIB_SAFE) for walking all 'struct ribs' corresponding to a route_node. These hide the fact that there is an intermediate rib_dest_t structure. - Add a few utility inlines to go between a rib_dest_t and associated structures. * zebra/zebra_rib.c - rib_link()/rib_unlink() Tweak for new behavior, where the 'info' pointer of a route_node points to a rib_dest_t. The list of ribs for a prefix now hangs off of the dest. Change the way we ref count route_nodes. We now hold a single ref count on a route_node if there is a corresponding rib_dest_t. - Maintain the queuing state of a route_node on the flags field of the rib_dest_t. - Add the rib_gc_dest() function, which deletes a rib_dest_t if it is no longer required. A rib_dest_t can be deleted iff there are no struct ribs hanging off of it. - Call rib_gc_dest() any time we unlink a rib from the rib_dest_t. Currently we only need to call it once, just before we return from rib_process(). * zebra/{redistribute,zebra_rib,zebra_snmp,zebra_vty}.c Use new macros to walk over route_node ribs. * lib/memtypes.c Add memory type for rib_dest_t. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-13 23:48:53 +01:00
/*
* Inline functions.
*/
/*
* rib_table_info
*/
static inline struct rib_table_info *rib_table_info(struct route_table *table)
{
return (struct rib_table_info *)route_table_get_info(table);
}
zebra: add structure to hold per-prefix state in RIB Add the rib_dest_t structure to hold per-prefix state in the routing information base. This gives us an appropriate place to maintain the queueing state of a route_node. Queuing state was previously being stored on the first rib in the list of ribs hanging off the route_node. * zebra/rib.h - Add new structure rib_dest_t. - Remove the rn_status field from 'struct rib', it is no longer required. - Add macros (RNODE_FOREACH_RIB, RNODE_FOREACH_RIB_SAFE) for walking all 'struct ribs' corresponding to a route_node. These hide the fact that there is an intermediate rib_dest_t structure. - Add a few utility inlines to go between a rib_dest_t and associated structures. * zebra/zebra_rib.c - rib_link()/rib_unlink() Tweak for new behavior, where the 'info' pointer of a route_node points to a rib_dest_t. The list of ribs for a prefix now hangs off of the dest. Change the way we ref count route_nodes. We now hold a single ref count on a route_node if there is a corresponding rib_dest_t. - Maintain the queuing state of a route_node on the flags field of the rib_dest_t. - Add the rib_gc_dest() function, which deletes a rib_dest_t if it is no longer required. A rib_dest_t can be deleted iff there are no struct ribs hanging off of it. - Call rib_gc_dest() any time we unlink a rib from the rib_dest_t. Currently we only need to call it once, just before we return from rib_process(). * zebra/{redistribute,zebra_rib,zebra_snmp,zebra_vty}.c Use new macros to walk over route_node ribs. * lib/memtypes.c Add memory type for rib_dest_t. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-13 23:48:53 +01:00
/*
* rib_dest_from_rnode
*/
static inline rib_dest_t *rib_dest_from_rnode(struct route_node *rn)
{
return (rib_dest_t *)rn->info;
}
/*
* rnode_to_ribs
*
* Returns a pointer to the list of routes corresponding to the given
* route_node.
*/
static inline struct route_entry *rnode_to_ribs(struct route_node *rn)
{
rib_dest_t *dest;
dest = rib_dest_from_rnode(rn);
if (!dest)
return NULL;
return re_list_first(&dest->routes);
zebra: add structure to hold per-prefix state in RIB Add the rib_dest_t structure to hold per-prefix state in the routing information base. This gives us an appropriate place to maintain the queueing state of a route_node. Queuing state was previously being stored on the first rib in the list of ribs hanging off the route_node. * zebra/rib.h - Add new structure rib_dest_t. - Remove the rn_status field from 'struct rib', it is no longer required. - Add macros (RNODE_FOREACH_RIB, RNODE_FOREACH_RIB_SAFE) for walking all 'struct ribs' corresponding to a route_node. These hide the fact that there is an intermediate rib_dest_t structure. - Add a few utility inlines to go between a rib_dest_t and associated structures. * zebra/zebra_rib.c - rib_link()/rib_unlink() Tweak for new behavior, where the 'info' pointer of a route_node points to a rib_dest_t. The list of ribs for a prefix now hangs off of the dest. Change the way we ref count route_nodes. We now hold a single ref count on a route_node if there is a corresponding rib_dest_t. - Maintain the queuing state of a route_node on the flags field of the rib_dest_t. - Add the rib_gc_dest() function, which deletes a rib_dest_t if it is no longer required. A rib_dest_t can be deleted iff there are no struct ribs hanging off of it. - Call rib_gc_dest() any time we unlink a rib from the rib_dest_t. Currently we only need to call it once, just before we return from rib_process(). * zebra/{redistribute,zebra_rib,zebra_snmp,zebra_vty}.c Use new macros to walk over route_node ribs. * lib/memtypes.c Add memory type for rib_dest_t. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-13 23:48:53 +01:00
}
/*
* rib_dest_prefix
*/
static inline struct prefix *rib_dest_prefix(rib_dest_t *dest)
{
return &dest->rnode->p;
}
/*
* rib_dest_af
*
* Returns the address family that the destination is for.
*/
static inline uint8_t rib_dest_af(rib_dest_t *dest)
zebra: add structure to hold per-prefix state in RIB Add the rib_dest_t structure to hold per-prefix state in the routing information base. This gives us an appropriate place to maintain the queueing state of a route_node. Queuing state was previously being stored on the first rib in the list of ribs hanging off the route_node. * zebra/rib.h - Add new structure rib_dest_t. - Remove the rn_status field from 'struct rib', it is no longer required. - Add macros (RNODE_FOREACH_RIB, RNODE_FOREACH_RIB_SAFE) for walking all 'struct ribs' corresponding to a route_node. These hide the fact that there is an intermediate rib_dest_t structure. - Add a few utility inlines to go between a rib_dest_t and associated structures. * zebra/zebra_rib.c - rib_link()/rib_unlink() Tweak for new behavior, where the 'info' pointer of a route_node points to a rib_dest_t. The list of ribs for a prefix now hangs off of the dest. Change the way we ref count route_nodes. We now hold a single ref count on a route_node if there is a corresponding rib_dest_t. - Maintain the queuing state of a route_node on the flags field of the rib_dest_t. - Add the rib_gc_dest() function, which deletes a rib_dest_t if it is no longer required. A rib_dest_t can be deleted iff there are no struct ribs hanging off of it. - Call rib_gc_dest() any time we unlink a rib from the rib_dest_t. Currently we only need to call it once, just before we return from rib_process(). * zebra/{redistribute,zebra_rib,zebra_snmp,zebra_vty}.c Use new macros to walk over route_node ribs. * lib/memtypes.c Add memory type for rib_dest_t. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-13 23:48:53 +01:00
{
return dest->rnode->p.family;
}
/*
* rib_dest_table
*/
static inline struct route_table *rib_dest_table(rib_dest_t *dest)
{
return srcdest_rnode_table(dest->rnode);
zebra: add structure to hold per-prefix state in RIB Add the rib_dest_t structure to hold per-prefix state in the routing information base. This gives us an appropriate place to maintain the queueing state of a route_node. Queuing state was previously being stored on the first rib in the list of ribs hanging off the route_node. * zebra/rib.h - Add new structure rib_dest_t. - Remove the rn_status field from 'struct rib', it is no longer required. - Add macros (RNODE_FOREACH_RIB, RNODE_FOREACH_RIB_SAFE) for walking all 'struct ribs' corresponding to a route_node. These hide the fact that there is an intermediate rib_dest_t structure. - Add a few utility inlines to go between a rib_dest_t and associated structures. * zebra/zebra_rib.c - rib_link()/rib_unlink() Tweak for new behavior, where the 'info' pointer of a route_node points to a rib_dest_t. The list of ribs for a prefix now hangs off of the dest. Change the way we ref count route_nodes. We now hold a single ref count on a route_node if there is a corresponding rib_dest_t. - Maintain the queuing state of a route_node on the flags field of the rib_dest_t. - Add the rib_gc_dest() function, which deletes a rib_dest_t if it is no longer required. A rib_dest_t can be deleted iff there are no struct ribs hanging off of it. - Call rib_gc_dest() any time we unlink a rib from the rib_dest_t. Currently we only need to call it once, just before we return from rib_process(). * zebra/{redistribute,zebra_rib,zebra_snmp,zebra_vty}.c Use new macros to walk over route_node ribs. * lib/memtypes.c Add memory type for rib_dest_t. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-13 23:48:53 +01:00
}
/*
* rib_dest_vrf
*/
lib, zebra: move "struct vrf" to be a lib module Previously "struct vrf" is defined locally in zebra. Now it is moved to be a lib module. This is the first step to support multi-VRF in quagga. The implementation is splitted into small patches for the purpose of easy review. * lib: "struct vrf" with basic members is defined in vrf.c. The member "void *info" is for user data. Some basic functions are defined in vrf.c for adding/deleting/ looking up a VRF, scanning the VRF table and initializing the VRF module. The type "vrf_id_t" is defined specificly for VRF ID. * zebra: The previous "struct vrf" is re-defined as "struct zebra_vrf"; and previous "vrf" variables are renamed to "zvrf". The previous "struct vrf" related functions are removed from zbera_rib.c. New functions are defined to maintain the new "struct zebra_vrf". The names vrf_xxx are reserved for the functions in VRF module. So: - the previous vrf_table() are renamed to zebra_vrf_table(); - the previous vrf_static_table() are renamed to zebra_vrf_static_table(). The main logic is not changed. BTW: Add a statement to zebra_snmp.c telling that the SNMP is running only for the MIBs in the default VRF. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Vincent JARDIN <vincent.jardin@6wind.com> Signed-off-by: David Lamparter <equinox@opensourcerouting.org> Conflicts: lib/Makefile.am zebra/zebra_rib.c zebra/zebra_vty.c Conflicts: lib/Makefile.am lib/memtypes.c zebra/rib.h zebra/zebra_rib.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zebra_vty.c
2015-05-22 11:39:56 +02:00
static inline struct zebra_vrf *rib_dest_vrf(rib_dest_t *dest)
{
lib, zebra: move "struct vrf" to be a lib module Previously "struct vrf" is defined locally in zebra. Now it is moved to be a lib module. This is the first step to support multi-VRF in quagga. The implementation is splitted into small patches for the purpose of easy review. * lib: "struct vrf" with basic members is defined in vrf.c. The member "void *info" is for user data. Some basic functions are defined in vrf.c for adding/deleting/ looking up a VRF, scanning the VRF table and initializing the VRF module. The type "vrf_id_t" is defined specificly for VRF ID. * zebra: The previous "struct vrf" is re-defined as "struct zebra_vrf"; and previous "vrf" variables are renamed to "zvrf". The previous "struct vrf" related functions are removed from zbera_rib.c. New functions are defined to maintain the new "struct zebra_vrf". The names vrf_xxx are reserved for the functions in VRF module. So: - the previous vrf_table() are renamed to zebra_vrf_table(); - the previous vrf_static_table() are renamed to zebra_vrf_static_table(). The main logic is not changed. BTW: Add a statement to zebra_snmp.c telling that the SNMP is running only for the MIBs in the default VRF. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Vincent JARDIN <vincent.jardin@6wind.com> Signed-off-by: David Lamparter <equinox@opensourcerouting.org> Conflicts: lib/Makefile.am zebra/zebra_rib.c zebra/zebra_vty.c Conflicts: lib/Makefile.am lib/memtypes.c zebra/rib.h zebra/zebra_rib.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zebra_vty.c
2015-05-22 11:39:56 +02:00
return rib_table_info(rib_dest_table(dest))->zvrf;
}
/*
* Create the rib_dest_t and attach it to the specified node
*/
extern rib_dest_t *zebra_rib_create_dest(struct route_node *rn);
/*
* rib_tables_iter_init
*/
static inline void rib_tables_iter_init(rib_tables_iter_t *iter)
{
memset(iter, 0, sizeof(*iter));
iter->state = RIB_TABLES_ITER_S_INIT;
}
/*
* rib_tables_iter_started
*
* Returns true if this iterator has started iterating over the set of
* tables.
*/
static inline int rib_tables_iter_started(rib_tables_iter_t *iter)
{
return iter->state != RIB_TABLES_ITER_S_INIT;
}
/*
* rib_tables_iter_cleanup
*/
static inline void rib_tables_iter_cleanup(rib_tables_iter_t *iter)
{
iter->state = RIB_TABLES_ITER_S_DONE;
}
DECLARE_HOOK(rib_update, (struct route_node * rn, const char *reason),
(rn, reason));
DECLARE_HOOK(rib_shutdown, (struct route_node * rn), (rn));
/*
* Access installed/fib nexthops, which may be a subset of the
* rib nexthops.
*/
static inline struct nexthop_group *rib_get_fib_nhg(struct route_entry *re)
{
/* If the fib set is a subset of the active rib set,
* use the dedicated fib list.
*/
if (CHECK_FLAG(re->status, ROUTE_ENTRY_USE_FIB_NHG))
return &(re->fib_ng);
else
return &(re->nhe->nhg);
}
/*
* Access backup nexthop-group that represents the installed backup nexthops;
* any installed backup will be on the fib list.
*/
static inline struct nexthop_group *rib_get_fib_backup_nhg(
struct route_entry *re)
{
return &(re->fib_backup_ng);
}
extern void zebra_gr_process_client(afi_t afi, vrf_id_t vrf_id, uint8_t proto,
uint8_t instance, time_t restart_time);
extern int rib_add_gr_run(afi_t afi, vrf_id_t vrf_id, uint8_t proto,
uint8_t instance, time_t restart_time);
extern void zebra_vty_init(void);
extern uint32_t zebra_rib_dplane_results_count(void);
extern pid_t pid;
extern uint32_t rt_table_main_id;
void route_entry_dump_nh(const struct route_entry *re, const char *straddr,
const struct vrf *re_vrf,
const struct nexthop *nexthop);
/* Name of hook calls */
#define ZEBRA_ON_RIB_PROCESS_HOOK_CALL "on_rib_process_dplane_results"
#ifdef __cplusplus
}
#endif
2002-12-13 21:15:29 +01:00
#endif /*_ZEBRA_RIB_H */