2023-02-08 13:17:09 +01:00
|
|
|
// 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
|
|
|
|
|
2016-10-01 20:42:34 +02:00
|
|
|
#include "zebra.h"
|
2021-03-22 20:02:17 +01:00
|
|
|
#include "memory.h"
|
2017-02-13 00:29:37 +01:00
|
|
|
#include "hook.h"
|
2019-05-01 00:04:57 +02:00
|
|
|
#include "typesafe.h"
|
2015-05-22 11:40:07 +02:00
|
|
|
#include "linklist.h"
|
2005-11-24 16:15:17 +01:00
|
|
|
#include "prefix.h"
|
2012-11-13 23:48:53 +01:00
|
|
|
#include "table.h"
|
2012-11-13 23:48:59 +01:00
|
|
|
#include "queue.h"
|
2015-05-20 02:40:34 +02:00
|
|
|
#include "nexthop.h"
|
2018-01-26 16:12:35 +01:00
|
|
|
#include "nexthop_group.h"
|
2016-02-01 18:56:42 +01:00
|
|
|
#include "vrf.h"
|
2016-05-04 02:04:43 +02:00
|
|
|
#include "if.h"
|
2016-04-16 04:19:37 +02:00
|
|
|
#include "mpls.h"
|
2016-12-05 20:05:30 +01:00
|
|
|
#include "srcdest_table.h"
|
2019-11-21 21:05:52 +01:00
|
|
|
#include "zebra/zebra_nhg.h"
|
2005-11-24 16:15:17 +01:00
|
|
|
|
2019-03-25 15:11:55 +01:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2021-03-22 20:02:17 +01:00
|
|
|
DECLARE_MGROUP(ZEBRA);
|
|
|
|
|
|
|
|
DECLARE_MTYPE(RE);
|
|
|
|
|
2019-05-01 00:04:57 +02:00
|
|
|
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
|
2022-03-12 14:27:22 +01:00
|
|
|
#define ZEBRA_NHT_RESOLVE_VIA_DEFAULT 0x4
|
2019-05-01 00:04:57 +02:00
|
|
|
|
|
|
|
/* VRF identifier. */
|
|
|
|
vrf_id_t vrf_id;
|
|
|
|
|
|
|
|
afi_t afi;
|
2021-09-24 22:36:27 +02:00
|
|
|
safi_t safi;
|
2019-05-01 00:04:57 +02:00
|
|
|
|
|
|
|
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
|
2015-05-20 03:03:42 +02:00
|
|
|
#define ZEBRA_KERNEL_TABLE_MAX 252 /* support for no more than this rt tables */
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2019-05-02 22:57:03 +02:00
|
|
|
PREDECL_LIST(re_list);
|
|
|
|
|
2021-11-09 15:35:54 +01:00
|
|
|
struct re_opaque {
|
2020-12-05 02:01:51 +01:00
|
|
|
uint16_t length;
|
|
|
|
uint8_t data[];
|
|
|
|
};
|
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
struct route_entry {
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Link list. */
|
2019-05-02 22:57:03 +02:00
|
|
|
struct re_list_item next;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-11-22 21:30:53 +01:00
|
|
|
/* Nexthop group, shared/refcounted, based on the nexthop(s)
|
|
|
|
* provided by the owner of the route
|
|
|
|
*/
|
|
|
|
struct nhg_hash_entry *nhe;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-11-22 21:30:53 +01:00
|
|
|
/* Nexthop group from FIB (optional), reflecting what is actually
|
2020-05-22 22:36:30 +02:00
|
|
|
* installed in the FIB if that differs. The 'backup' group is used
|
|
|
|
* when backup nexthops are present in the route's nhg.
|
2019-11-22 21:30:53 +01:00
|
|
|
*/
|
2019-03-25 22:25:46 +01:00
|
|
|
struct nexthop_group fib_ng;
|
2020-05-22 22:36:30 +02:00
|
|
|
struct nexthop_group fib_backup_ng;
|
2019-03-25 22:25:46 +01:00
|
|
|
|
2021-10-05 21:32:23 +02:00
|
|
|
/* Nexthop group hash entry IDs. The "installed" id is the id
|
|
|
|
* used in linux/netlink, if available.
|
|
|
|
*/
|
2019-03-08 16:16:52 +01:00
|
|
|
uint32_t nhe_id;
|
2021-10-05 21:32:23 +02:00
|
|
|
uint32_t nhe_installed_id;
|
2019-02-26 14:16:11 +01:00
|
|
|
|
2016-10-01 20:42:34 +02:00
|
|
|
/* Tag */
|
|
|
|
route_tag_t tag;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2006-03-30 15:32:09 +02:00
|
|
|
/* Uptime. */
|
|
|
|
time_t uptime;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-12-24 20:22:03 +01:00
|
|
|
/* Type of this route. */
|
2002-12-13 21:15:29 +01:00
|
|
|
int type;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-22 11:40:02 +02:00
|
|
|
/* VRF identifier. */
|
|
|
|
vrf_id_t vrf_id;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Which routing table */
|
2015-05-20 03:04:26 +02:00
|
|
|
uint32_t table;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2006-03-30 15:32:09 +02:00
|
|
|
/* Metric */
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t metric;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-11-02 15:50:07 +01:00
|
|
|
/* MTU */
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t mtu;
|
|
|
|
uint32_t nexthop_mtu;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
[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/zebra.h ZEBRA_FLAG_* and is exposed
|
|
|
|
* to clients via Zserv
|
|
|
|
*/
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t flags;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
[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 */
|
2019-01-03 19:35:58 +01:00
|
|
|
uint32_t status;
|
2017-06-01 13:26:25 +02:00
|
|
|
#define ROUTE_ENTRY_REMOVED 0x1
|
2019-01-03 19:35:58 +01:00
|
|
|
/* The Route Entry has changed */
|
2019-07-29 20:53:58 +02:00
|
|
|
#define ROUTE_ENTRY_CHANGED 0x2
|
2019-01-03 19:35:58 +01:00
|
|
|
/* The Label has changed on the Route entry */
|
2019-07-29 20:53:58 +02:00
|
|
|
#define ROUTE_ENTRY_LABELS_CHANGED 0x4
|
2019-01-03 19:35:58 +01:00
|
|
|
/* Route is queued for Installation into the Data Plane */
|
2019-07-29 20:53:58 +02:00
|
|
|
#define ROUTE_ENTRY_QUEUED 0x8
|
2019-01-03 19:35:58 +01:00
|
|
|
/* Route is installed into the Data Plane */
|
2019-07-29 20:53:58 +02:00
|
|
|
#define ROUTE_ENTRY_INSTALLED 0x10
|
2019-01-03 19:35:58 +01:00
|
|
|
/* Route has Failed installation into the Data Plane in some manner */
|
2019-07-29 20:53:58 +02:00
|
|
|
#define ROUTE_ENTRY_FAILED 0x20
|
2020-07-17 19:07:31 +02:00
|
|
|
/* 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
|
|
|
|
2018-05-23 18:20:43 +02:00
|
|
|
/* Sequence value incremented for each dataplane operation */
|
|
|
|
uint32_t dplane_sequence;
|
2019-02-15 17:57:22 +01:00
|
|
|
|
|
|
|
/* Source protocol instance */
|
|
|
|
uint16_t instance;
|
|
|
|
|
|
|
|
/* Distance. */
|
|
|
|
uint8_t distance;
|
2020-12-05 02:01:51 +01:00
|
|
|
|
2021-11-09 15:35:54 +01:00
|
|
|
struct re_opaque *opaque;
|
2002-12-13 21:15:29 +01:00
|
|
|
};
|
|
|
|
|
2019-05-13 23:32:33 +02:00
|
|
|
#define RIB_SYSTEM_ROUTE(R) RSYSTEM_ROUTE((R)->type)
|
2019-01-29 20:06:25 +01:00
|
|
|
|
2019-05-13 23:32:33 +02:00
|
|
|
#define RIB_KERNEL_ROUTE(R) RKERNEL_ROUTE((R)->type)
|
2019-01-29 20:06:25 +01:00
|
|
|
|
2023-06-28 14:11:41 +02:00
|
|
|
/* Define route types that are equivalent to "connected". */
|
|
|
|
#define RIB_CONNECTED_ROUTE(R) \
|
|
|
|
((R)->type == ZEBRA_ROUTE_CONNECT || (R)->type == ZEBRA_ROUTE_NHRP)
|
|
|
|
|
2008-06-02 14:03:22 +02:00
|
|
|
/* meta-queue structure:
|
2019-05-15 00:03:29 +02:00
|
|
|
* sub-queue 0: nexthop group objects
|
2021-04-19 17:12:51 +02:00
|
|
|
* sub-queue 1: EVPN/VxLAN objects
|
2022-08-02 19:57:18 +02:00
|
|
|
* 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
|
2020-10-01 20:58:37 +02:00
|
|
|
* don't generate routes
|
2008-06-02 14:03:22 +02:00
|
|
|
*/
|
2023-03-29 21:27:09 +02:00
|
|
|
#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)
|
|
|
|
|
2008-06-02 14:03:22 +02:00
|
|
|
struct meta_queue {
|
|
|
|
struct list *subq[MQ_SIZE];
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t size; /* sum of lengths of all subqueues */
|
2008-06-02 14:03:22 +02:00
|
|
|
};
|
|
|
|
|
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.
|
|
|
|
*/
|
2019-05-02 22:57:03 +02:00
|
|
|
struct re_list_head routes;
|
2012-11-13 23:48:53 +01:00
|
|
|
|
2017-11-30 20:03:07 +01:00
|
|
|
struct route_entry *selected_fib;
|
|
|
|
|
2012-11-13 23:48:53 +01:00
|
|
|
/*
|
|
|
|
* Flags, see below.
|
|
|
|
*/
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t flags;
|
2012-11-13 23:48:53 +01:00
|
|
|
|
2019-02-06 16:23:58 +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.
|
|
|
|
*/
|
2019-05-01 00:04:57 +02:00
|
|
|
struct rnh_list_head nht;
|
2019-02-06 16:23:58 +01:00
|
|
|
|
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;
|
|
|
|
|
2012-11-13 23:48:53 +01:00
|
|
|
} rib_dest_t;
|
|
|
|
|
2019-05-01 00:04:57 +02:00
|
|
|
DECLARE_LIST(rnh_list, struct rnh, rnh_list_item);
|
2019-05-02 22:57:03 +02:00
|
|
|
DECLARE_LIST(re_list, struct route_entry, next);
|
2019-05-01 00:04:57 +02:00
|
|
|
|
2012-11-13 23:48:53 +01:00
|
|
|
#define RIB_ROUTE_QUEUED(x) (1 << (x))
|
2017-09-25 14:10:24 +02:00
|
|
|
// If MQ_SIZE is modified this value needs to be updated.
|
2019-05-15 00:03:29 +02:00
|
|
|
#define RIB_ROUTE_ANY_QUEUED 0x3F
|
2012-11-13 23:48:53 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The maximum qindex that can be used.
|
|
|
|
*/
|
|
|
|
#define ZEBRA_MAX_QINDEX (MQ_SIZE - 1)
|
|
|
|
|
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))
|
|
|
|
|
2019-02-08 23:14:30 +01:00
|
|
|
#define RIB_DEST_UPDATE_LSPS (1 << (ZEBRA_MAX_QINDEX + 3))
|
|
|
|
|
2012-11-13 23:48:53 +01:00
|
|
|
/*
|
|
|
|
* Macro to iterate over each route for a destination (prefix).
|
|
|
|
*/
|
2017-06-01 13:26:25 +02:00
|
|
|
#define RE_DEST_FOREACH_ROUTE(dest, re) \
|
2019-05-02 22:57:03 +02:00
|
|
|
for ((re) = (dest) ? re_list_first(&((dest)->routes)) : NULL; (re); \
|
|
|
|
(re) = re_list_next(&((dest)->routes), (re)))
|
2012-11-13 23:48:53 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Same as above, but allows the current node to be unlinked.
|
|
|
|
*/
|
2017-06-01 13:26:25 +02:00
|
|
|
#define RE_DEST_FOREACH_ROUTE_SAFE(dest, re, next) \
|
2019-05-02 22:57:03 +02:00
|
|
|
for ((re) = (dest) ? re_list_first(&((dest)->routes)) : NULL; \
|
|
|
|
(re) && ((next) = re_list_next(&((dest)->routes), (re)), 1); \
|
|
|
|
(re) = (next))
|
2012-11-13 23:48:53 +01:00
|
|
|
|
2020-03-25 05:41:49 +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)
|
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
#define RNODE_FOREACH_RE(rn, re) \
|
|
|
|
RE_DEST_FOREACH_ROUTE (rib_dest_from_rnode(rn), re)
|
2012-11-13 23:48:53 +01:00
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
#define RNODE_FOREACH_RE_SAFE(rn, re, next) \
|
|
|
|
RE_DEST_FOREACH_ROUTE_SAFE (rib_dest_from_rnode(rn), re, next)
|
2012-11-13 23:48:53 +01:00
|
|
|
|
2020-03-25 05:41:49 +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)
|
|
|
|
|
2012-11-13 23:48:54 +01:00
|
|
|
/*
|
|
|
|
* rib_table_info_t
|
|
|
|
*
|
|
|
|
* Structure that is hung off of a route_table that holds information about
|
|
|
|
* the table.
|
|
|
|
*/
|
2020-05-07 14:59:27 +02:00
|
|
|
struct rib_table_info {
|
2012-11-13 23:48:54 +01:00
|
|
|
|
|
|
|
/*
|
2015-05-22 11:39:56 +02:00
|
|
|
* Back pointer to zebra_vrf.
|
2012-11-13 23:48:54 +01:00
|
|
|
*/
|
2015-05-22 11:39:56 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
2012-11-13 23:48:54 +01:00
|
|
|
afi_t afi;
|
|
|
|
safi_t safi;
|
2018-11-13 16:26:21 +01:00
|
|
|
uint32_t table_id;
|
2020-05-07 14:59:27 +02:00
|
|
|
};
|
2012-11-13 23:48:54 +01:00
|
|
|
|
2020-05-07 14:57:04 +02:00
|
|
|
enum rib_tables_iter_state {
|
2012-11-13 23:48:55 +01:00
|
|
|
RIB_TABLES_ITER_S_INIT,
|
|
|
|
RIB_TABLES_ITER_S_ITERATING,
|
|
|
|
RIB_TABLES_ITER_S_DONE
|
2020-05-07 14:57:04 +02:00
|
|
|
};
|
2012-11-13 23:48:55 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Structure that holds state for iterating over all tables in the
|
|
|
|
* Routing Information Base.
|
|
|
|
*/
|
|
|
|
typedef struct rib_tables_iter_t_ {
|
2015-05-22 11:39:56 +02:00
|
|
|
vrf_id_t vrf_id;
|
2012-11-13 23:48:55 +01:00
|
|
|
int afi_safi_ix;
|
|
|
|
|
2020-05-07 14:57:04 +02:00
|
|
|
enum rib_tables_iter_state state;
|
2012-11-13 23:48:55 +01:00
|
|
|
} rib_tables_iter_t;
|
|
|
|
|
Zebra: Schedule RIB processing based on trigger event
Currently, when RIB processing is initiated (i.e., by calling rib_update()),
all routes are queued for processing. This is not desirable in all situations
because, sometimes the protocol may have an alternate path. In addition,
with NHT tracking nexthops, there are situations when NHT should be kicked
off first and that can trigger subsequent RIB processing.
This patch addresses this by introducing the notion of a trigger event. This
is only for the situation when the entire RIB is walked. The current triggers
- based on when rib_update() is invoked - are "interface change" and "route-
map change". In the former case, only the relevant routes are walked and
scheduled, in the latter case, currently all routes are scheduled for
processing.
Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Ticket: CM-7662
Reviewed By: CCR-3905
Note: The initial defect in this area was CM-7420. This was addressed in
2.5.4 with an interim change that only walked static routes upon interface
down. The change was considered a bit risky to do for interface up etc. Also,
this did not address scenarios like CM-7662. The current fix addresses CM-7662.
2015-12-09 01:55:43 +01:00
|
|
|
/* Events/reasons triggering a RIB update. */
|
2020-05-07 15:47:23 +02:00
|
|
|
enum rib_update_event {
|
2019-10-17 21:38:54 +02:00
|
|
|
RIB_UPDATE_KERNEL,
|
Zebra: Schedule RIB processing based on trigger event
Currently, when RIB processing is initiated (i.e., by calling rib_update()),
all routes are queued for processing. This is not desirable in all situations
because, sometimes the protocol may have an alternate path. In addition,
with NHT tracking nexthops, there are situations when NHT should be kicked
off first and that can trigger subsequent RIB processing.
This patch addresses this by introducing the notion of a trigger event. This
is only for the situation when the entire RIB is walked. The current triggers
- based on when rib_update() is invoked - are "interface change" and "route-
map change". In the former case, only the relevant routes are walked and
scheduled, in the latter case, currently all routes are scheduled for
processing.
Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Ticket: CM-7662
Reviewed By: CCR-3905
Note: The initial defect in this area was CM-7420. This was addressed in
2.5.4 with an interim change that only walked static routes upon interface
down. The change was considered a bit risky to do for interface up etc. Also,
this did not address scenarios like CM-7662. The current fix addresses CM-7662.
2015-12-09 01:55:43 +01:00
|
|
|
RIB_UPDATE_RMAP_CHANGE,
|
2019-10-17 21:38:54 +02:00
|
|
|
RIB_UPDATE_OTHER,
|
|
|
|
RIB_UPDATE_MAX
|
2020-05-07 15:47:23 +02:00
|
|
|
};
|
2023-03-31 15:08:23 +02:00
|
|
|
void rib_update_finish(void);
|
Zebra: Schedule RIB processing based on trigger event
Currently, when RIB processing is initiated (i.e., by calling rib_update()),
all routes are queued for processing. This is not desirable in all situations
because, sometimes the protocol may have an alternate path. In addition,
with NHT tracking nexthops, there are situations when NHT should be kicked
off first and that can trigger subsequent RIB processing.
This patch addresses this by introducing the notion of a trigger event. This
is only for the situation when the entire RIB is walked. The current triggers
- based on when rib_update() is invoked - are "interface change" and "route-
map change". In the former case, only the relevant routes are walked and
scheduled, in the latter case, currently all routes are scheduled for
processing.
Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Ticket: CM-7662
Reviewed By: CCR-3905
Note: The initial defect in this area was CM-7420. This was addressed in
2.5.4 with an interim change that only walked static routes upon interface
down. The change was considered a bit risky to do for interface up etc. Also,
this did not address scenarios like CM-7662. The current fix addresses CM-7662.
2015-12-09 01:55:43 +01:00
|
|
|
|
2020-05-14 15:57:23 +02:00
|
|
|
int route_entry_update_nhe(struct route_entry *re,
|
|
|
|
struct nhg_hash_entry *new_nhghe);
|
2017-06-01 13:26:25 +02:00
|
|
|
|
2020-05-20 21:47:12 +02:00
|
|
|
/* 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);
|
2020-05-20 21:47:12 +02:00
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
#define route_entry_dump(prefix, src, re) _route_entry_dump(__func__, prefix, src, re)
|
2018-03-16 17:53:00 +01:00
|
|
|
extern void _route_entry_dump(const char *func, union prefixconstptr pp,
|
|
|
|
union prefixconstptr src_pp,
|
|
|
|
const struct route_entry *re);
|
2015-01-06 19:53:24 +01:00
|
|
|
|
2022-08-10 01:56:08 +02:00
|
|
|
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);
|
|
|
|
|
2007-08-13 18:03:06 +02:00
|
|
|
#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
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
extern int is_zebra_valid_kernel_table(uint32_t table_id);
|
|
|
|
extern int is_zebra_main_routing_table(uint32_t table_id);
|
2018-07-10 22:02:03 +02:00
|
|
|
extern int zebra_check_addr(const struct prefix *p);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
extern void rib_delnode(struct route_node *rn, struct route_entry *re);
|
2017-11-14 15:57:37 +01:00
|
|
|
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);
|
2016-09-01 13:20:02 +02:00
|
|
|
|
2005-09-24 16:00:26 +02:00
|
|
|
/* NOTE:
|
2016-08-24 10:01:20 +02:00
|
|
|
* All rib_add function will not just add prefix into RIB, but
|
2005-09-24 16:00:26 +02:00
|
|
|
* also implicitly withdraw equal prefix of same type. */
|
2018-02-08 15:12:12 +01:00
|
|
|
extern int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
2020-10-15 19:41:30 +02:00
|
|
|
unsigned short instance, uint32_t flags, struct prefix *p,
|
2017-08-28 01:30:16 +02:00
|
|
|
struct prefix_ipv6 *src_p, const struct nexthop *nh,
|
2019-03-11 15:55:53 +01:00
|
|
|
uint32_t nhe_id, uint32_t table_id, uint32_t metric,
|
2021-06-24 18:23:33 +02:00
|
|
|
uint32_t mtu, uint8_t distance, route_tag_t tag,
|
|
|
|
bool startup);
|
2019-12-24 20:22:03 +01:00
|
|
|
/*
|
|
|
|
* Multipath route apis.
|
|
|
|
*/
|
2018-03-16 17:53:00 +01:00
|
|
|
extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
|
2019-11-22 21:30:53 +01:00
|
|
|
struct prefix_ipv6 *src_p, struct route_entry *re,
|
2021-06-24 18:23:33 +02:00
|
|
|
struct nexthop_group *ng, bool startup);
|
2021-08-09 14:01:06 +02:00
|
|
|
/*
|
|
|
|
* -1 -> some sort of error
|
|
|
|
* 0 -> an add
|
|
|
|
* 1 -> an update
|
|
|
|
*/
|
2019-12-24 20:22:03 +01:00
|
|
|
extern int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p,
|
|
|
|
struct prefix_ipv6 *src_p,
|
|
|
|
struct route_entry *re,
|
2021-06-24 18:23:33 +02:00
|
|
|
struct nhg_hash_entry *nhe, bool startup);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-12-12 18:11:27 +01:00
|
|
|
extern void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
2020-10-15 19:41:30 +02:00
|
|
|
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, uint8_t distance,
|
2020-12-10 16:24:47 +01:00
|
|
|
bool fromkernel);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-03-16 17:53:00 +01:00
|
|
|
extern struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,
|
2021-06-10 22:48:22 +02:00
|
|
|
const union g_addr *addr,
|
2016-08-24 06:48:37 +02:00
|
|
|
struct route_node **rn_out);
|
2023-02-13 18:13:42 +01:00
|
|
|
extern struct route_entry *rib_match_multicast(afi_t afi, vrf_id_t vrf_id,
|
|
|
|
union g_addr *gaddr,
|
|
|
|
struct route_node **rn_out);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-03-16 17:53:00 +01:00
|
|
|
extern struct route_entry *rib_lookup_ipv4(struct prefix_ipv4 *p,
|
|
|
|
vrf_id_t vrf_id);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-05-07 15:47:23 +02:00
|
|
|
extern void rib_update(enum rib_update_event event);
|
2018-08-17 17:47:48 +02:00
|
|
|
extern void rib_update_table(struct route_table *table,
|
2020-10-01 15:54:53 +02:00
|
|
|
enum rib_update_event event, int rtype);
|
2022-03-01 22:18:12 +01:00
|
|
|
extern void rib_sweep_route(struct event *t);
|
2018-03-16 17:53:00 +01:00
|
|
|
extern void rib_sweep_table(struct route_table *table);
|
|
|
|
extern void rib_close_table(struct route_table *table);
|
2005-06-28 19:17:12 +02:00
|
|
|
extern void rib_init(void);
|
2018-03-27 21:13:34 +02:00
|
|
|
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,
|
2018-03-16 04:30:17 +01:00
|
|
|
struct route_table *table);
|
2019-05-15 00:03:29 +02:00
|
|
|
|
|
|
|
extern int rib_queue_add(struct route_node *rn);
|
|
|
|
|
|
|
|
struct nhg_ctx; /* Forward declaration */
|
|
|
|
|
2021-04-15 20:20:39 +02:00
|
|
|
/* 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);
|
2019-05-15 00:03:29 +02:00
|
|
|
|
2021-04-19 17:12:51 +02:00
|
|
|
/* 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);
|
2021-04-19 21:25:27 +02:00
|
|
|
/* 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);
|
2021-04-20 15:14:46 +02:00
|
|
|
/* 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);
|
2021-04-19 17:12:51 +02:00
|
|
|
|
2022-08-09 19:09:16 +02:00
|
|
|
extern void meta_queue_free(struct meta_queue *mq, struct zebra_vrf *zvrf);
|
2017-06-01 13:26:25 +02:00
|
|
|
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;
|
|
|
|
|
2018-03-16 17:53:00 +01:00
|
|
|
extern void rib_unlink(struct route_node *rn, struct route_entry *re);
|
2012-11-13 23:48:53 +01:00
|
|
|
extern int rib_gc_dest(struct route_node *rn);
|
2012-11-13 23:48:55 +01:00
|
|
|
extern struct route_table *rib_tables_iter_next(rib_tables_iter_t *iter);
|
2012-11-13 23:48:53 +01:00
|
|
|
|
2017-09-25 14:41:33 +02:00
|
|
|
extern uint8_t route_distance(int type);
|
2016-04-16 04:19:37 +02:00
|
|
|
|
2021-06-14 03:48:35 +02:00
|
|
|
extern void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq,
|
|
|
|
bool rt_delete);
|
2019-02-06 16:23:58 +01:00
|
|
|
|
2023-05-31 17:40:07 +02:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
2022-01-14 18:50:51 +01:00
|
|
|
extern struct route_node *
|
|
|
|
rib_find_rn_from_ctx(const struct zebra_dplane_ctx *ctx);
|
|
|
|
|
2012-11-13 23:48:53 +01:00
|
|
|
/*
|
|
|
|
* Inline functions.
|
|
|
|
*/
|
|
|
|
|
2012-11-13 23:48:54 +01:00
|
|
|
/*
|
|
|
|
* rib_table_info
|
|
|
|
*/
|
2020-05-07 14:59:27 +02:00
|
|
|
static inline struct rib_table_info *rib_table_info(struct route_table *table)
|
2012-11-13 23:48:54 +01:00
|
|
|
{
|
2020-05-07 14:59:27 +02:00
|
|
|
return (struct rib_table_info *)route_table_get_info(table);
|
2012-11-13 23:48:54 +01:00
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
2019-05-02 22:57:03 +02:00
|
|
|
return re_list_first(&dest->routes);
|
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.
|
|
|
|
*/
|
2018-03-27 21:13:34 +02:00
|
|
|
static inline uint8_t rib_dest_af(rib_dest_t *dest)
|
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)
|
|
|
|
{
|
2016-12-05 20:05:30 +01:00
|
|
|
return srcdest_rnode_table(dest->rnode);
|
2012-11-13 23:48:53 +01:00
|
|
|
}
|
|
|
|
|
2012-11-13 23:48:54 +01:00
|
|
|
/*
|
|
|
|
* rib_dest_vrf
|
|
|
|
*/
|
2015-05-22 11:39:56 +02:00
|
|
|
static inline struct zebra_vrf *rib_dest_vrf(rib_dest_t *dest)
|
2012-11-13 23:48:54 +01:00
|
|
|
{
|
2015-05-22 11:39:56 +02:00
|
|
|
return rib_table_info(rib_dest_table(dest))->zvrf;
|
2012-11-13 23:48:54 +01:00
|
|
|
}
|
|
|
|
|
2019-02-06 20:21:36 +01:00
|
|
|
/*
|
|
|
|
* Create the rib_dest_t and attach it to the specified node
|
|
|
|
*/
|
|
|
|
extern rib_dest_t *zebra_rib_create_dest(struct route_node *rn);
|
|
|
|
|
2012-11-13 23:48:55 +01:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
*
|
2019-07-01 19:26:05 +02:00
|
|
|
* Returns true if this iterator has started iterating over the set of
|
2012-11-13 23:48:55 +01:00
|
|
|
* 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;
|
|
|
|
}
|
|
|
|
|
2017-02-13 00:29:37 +01:00
|
|
|
DECLARE_HOOK(rib_update, (struct route_node * rn, const char *reason),
|
|
|
|
(rn, reason));
|
2022-09-25 01:00:14 +02:00
|
|
|
DECLARE_HOOK(rib_shutdown, (struct route_node * rn), (rn));
|
2017-02-13 00:29:37 +01:00
|
|
|
|
2019-03-25 22:25:46 +01:00
|
|
|
/*
|
2020-07-17 19:07:31 +02:00
|
|
|
* Access installed/fib nexthops, which may be a subset of the
|
|
|
|
* rib nexthops.
|
2019-03-25 22:25:46 +01:00
|
|
|
*/
|
2020-05-22 22:36:30 +02:00
|
|
|
static inline struct nexthop_group *rib_get_fib_nhg(struct route_entry *re)
|
2019-03-25 22:25:46 +01:00
|
|
|
{
|
2020-07-17 19:07:31 +02:00
|
|
|
/* 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))
|
2019-03-25 22:25:46 +01:00
|
|
|
return &(re->fib_ng);
|
|
|
|
else
|
2020-02-25 14:29:46 +01:00
|
|
|
return &(re->nhe->nhg);
|
2019-03-25 22:25:46 +01:00
|
|
|
}
|
2017-12-08 00:35:29 +01:00
|
|
|
|
2020-05-22 22:36:30 +02:00
|
|
|
/*
|
2020-07-17 19:07:31 +02:00
|
|
|
* Access backup nexthop-group that represents the installed backup nexthops;
|
|
|
|
* any installed backup will be on the fib list.
|
2020-05-22 22:36:30 +02:00
|
|
|
*/
|
|
|
|
static inline struct nexthop_group *rib_get_fib_backup_nhg(
|
|
|
|
struct route_entry *re)
|
|
|
|
{
|
2020-07-17 19:07:31 +02:00
|
|
|
return &(re->fib_backup_ng);
|
2020-05-22 22:36:30 +02:00
|
|
|
}
|
|
|
|
|
2023-03-29 21:27:09 +02:00
|
|
|
extern void zebra_gr_process_client(afi_t afi, vrf_id_t vrf_id, uint8_t proto,
|
|
|
|
uint8_t instance);
|
|
|
|
|
|
|
|
extern int rib_add_gr_run(afi_t afi, vrf_id_t vrf_id, uint8_t proto,
|
|
|
|
uint8_t instance);
|
|
|
|
|
2017-12-08 00:35:29 +01:00
|
|
|
extern void zebra_vty_init(void);
|
2018-03-01 11:10:47 +01:00
|
|
|
|
2017-12-08 00:35:29 +01:00
|
|
|
extern pid_t pid;
|
|
|
|
|
2018-05-18 21:41:46 +02:00
|
|
|
extern bool v6_rr_semantics;
|
2019-03-25 15:11:55 +01:00
|
|
|
|
2023-08-22 13:27:59 +02:00
|
|
|
extern uint32_t rt_table_main_id;
|
|
|
|
|
2023-02-10 14:39:33 +01:00
|
|
|
/* Name of hook calls */
|
|
|
|
#define ZEBRA_ON_RIB_PROCESS_HOOK_CALL "on_rib_process_dplane_results"
|
|
|
|
|
2019-03-25 15:11:55 +01:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
#endif /*_ZEBRA_RIB_H */
|