1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* Zebra Router header.
3 * Copyright (C) 2018 Cumulus Networks, Inc.
6 #ifndef __ZEBRA_ROUTER_H__
7 #define __ZEBRA_ROUTER_H__
11 #include "zebra/zebra_ns.h"
18 * This header file contains the idea of a router and as such
19 * owns data that is associated with a router from zebra's
23 struct zebra_router_table
{
24 RB_ENTRY(zebra_router_table
) zebra_router_table_entry
;
31 struct route_table
*table
;
33 RB_HEAD(zebra_router_table_head
, zebra_router_table
);
34 RB_PROTOTYPE(zebra_router_table_head
, zebra_router_table
,
35 zebra_router_table_entry
, zebra_router_table_entry_compare
)
37 /* RPF lookup behaviour */
39 MCAST_NO_CONFIG
= 0, /* MIX_MRIB_FIRST, but no show in config write */
40 MCAST_MRIB_ONLY
, /* MRIB only */
41 MCAST_URIB_ONLY
, /* URIB only */
42 MCAST_MIX_MRIB_FIRST
, /* MRIB, if nothing at all then URIB */
43 MCAST_MIX_DISTANCE
, /* MRIB & URIB, lower distance wins */
44 MCAST_MIX_PFXLEN
, /* MRIB & URIB, longer prefix wins */
45 /* on equal value, MRIB wins for last 2 */
48 /* An interface can be error-disabled if a protocol (such as EVPN or
49 * VRRP) detects a problem with keeping it operationally-up.
50 * If any of the protodown bits are set protodown-on is programmed
51 * in the dataplane. This results in a carrier/L1 down on the
54 enum protodown_reasons
{
55 /* A process outside of FRR's control protodowned the interface */
56 ZEBRA_PROTODOWN_EXTERNAL
= (1 << 0),
57 /* On startup local ESs are held down for some time to
58 * allow the underlay to converge and EVPN routes to
61 ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY
= (1 << 1),
62 /* If all the uplinks are down the switch has lost access
63 * to the VxLAN overlay and must shut down the access
64 * ports to allow servers to re-direct their traffic to
65 * other switches on the Ethernet Segment
67 ZEBRA_PROTODOWN_EVPN_UPLINK_DOWN
= (1 << 2),
68 ZEBRA_PROTODOWN_EVPN_ALL
= (ZEBRA_PROTODOWN_EVPN_UPLINK_DOWN
|
69 ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY
),
70 ZEBRA_PROTODOWN_VRRP
= (1 << 3),
71 /* This reason used exclusively for testing */
72 ZEBRA_PROTODOWN_SHARP
= (1 << 4),
73 /* Just used to clear our fields on shutdown, externel not included */
74 ZEBRA_PROTODOWN_ALL
= (ZEBRA_PROTODOWN_EVPN_ALL
| ZEBRA_PROTODOWN_VRRP
|
75 ZEBRA_PROTODOWN_SHARP
)
77 #define ZEBRA_PROTODOWN_RC_STR_LEN 80
79 struct zebra_mlag_info
{
80 /* Role this zebra router is playing */
83 /* The peerlink being used for mlag */
85 ifindex_t peerlink_ifindex
;
87 /* The system mac being used */
90 * Zebra will open the communication channel with MLAGD only if any
91 * clients are interested and it is controlled dynamically based on
92 * client registers & un-registers.
94 uint32_t clients_interested_cnt
;
96 /* coomunication channel with MLAGD is established */
99 /* connection retry timer is running */
102 /* Holds the client data(unencoded) that need to be pushed to MCLAGD*/
103 struct stream_fifo
*mlag_fifo
;
106 * A new Kernel thread will be created to post the data to MCLAGD.
107 * where as, read will be performed from the zebra main thread, because
108 * read involves accessing client registartion data structures.
110 struct frr_pthread
*zebra_pth_mlag
;
112 /* MLAG Thread context 'master' */
113 struct event_loop
*th_master
;
116 * Event for Initial MLAG Connection setup & Data Read
117 * Read can be performed only after successful connection establishment,
121 struct event
*t_read
;
122 /* Event for MLAG write */
123 struct event
*t_write
;
126 struct zebra_router
{
127 atomic_bool in_shutdown
;
130 struct event_loop
*master
;
132 /* Lists of clients who have connected to us */
133 struct list
*client_list
;
135 /* List of clients in GR */
136 struct list
*stale_client_list
;
138 struct zebra_router_table_head tables
;
140 /* L3-VNI hash table (for EVPN). Only in default instance */
141 struct hash
*l3vni_table
;
143 /* Tables and other global info maintained for EVPN multihoming */
144 struct zebra_evpn_mh_info
*mh_info
;
146 struct zebra_neigh_info
*neigh_info
;
148 /* EVPN MH broadcast domains indexed by the VID */
149 struct hash
*evpn_vlan_table
;
151 struct hash
*rules_hash
;
153 struct hash
*ipset_hash
;
155 struct hash
*ipset_entry_hash
;
157 struct hash
*iptable_hash
;
159 struct hash
*qdisc_hash
;
160 struct hash
*class_hash
;
161 struct hash
*filter_hash
;
163 /* A sequence number used for tracking routes */
164 _Atomic
uint32_t sequence_num
;
167 #define ZEBRA_RIB_PROCESS_HOLD_TIME 10
168 #define ZEBRA_RIB_PROCESS_RETRY_TIME 1
169 struct work_queue
*ribq
;
171 /* Meta Queue Information */
172 struct meta_queue
*mq
;
175 struct work_queue
*lsp_process_q
;
177 #define ZEBRA_ZAPI_PACKETS_TO_PROCESS 1000
178 _Atomic
uint32_t packets_to_process
;
180 /* Mlag information for the router */
181 struct zebra_mlag_info mlag_info
;
184 * The EVPN instance, if any
186 struct zebra_vrf
*evpn_vrf
;
188 uint32_t multipath_num
;
190 /* RPF Lookup behavior */
191 enum multicast_mode ipv4_multicast_mode
;
194 * Time for when we sweep the rib from old routes
197 struct event
*sweeper
;
200 * The hash of nexthop groups associated with this router
203 struct hash
*nhgs_id
;
206 * Does the underlying system provide an asic offload
212 * If the asic is notifying us about successful nexthop
213 * allocation/control. Some developers have made their
214 * asic take control of how many nexthops/ecmp they can
215 * have and will report what is successfull or not
217 bool asic_notification_nexthop_control
;
221 bool all_mc_forwardingv4
, default_mc_forwardingv4
;
222 bool all_mc_forwardingv6
, default_mc_forwardingv6
;
223 bool all_linkdownv4
, default_linkdownv4
;
224 bool all_linkdownv6
, default_linkdownv6
;
226 #define ZEBRA_DEFAULT_NHG_KEEP_TIMER 180
229 /* Should we allow non FRR processes to delete our routes */
233 #define GRACEFUL_RESTART_TIME 60
235 extern struct zebra_router zrouter
;
236 extern uint32_t rcvbufsize
;
238 extern void zebra_router_init(bool asic_offload
, bool notify_on_ack
);
239 extern void zebra_router_cleanup(void);
240 extern void zebra_router_terminate(void);
242 extern struct zebra_router_table
*zebra_router_find_zrt(struct zebra_vrf
*zvrf
,
244 afi_t afi
, safi_t safi
);
245 extern struct route_table
*zebra_router_find_table(struct zebra_vrf
*zvrf
,
246 uint32_t tableid
, afi_t afi
,
248 extern struct route_table
*zebra_router_get_table(struct zebra_vrf
*zvrf
,
249 uint32_t tableid
, afi_t afi
,
251 extern void zebra_router_release_table(struct zebra_vrf
*zvrf
, uint32_t tableid
,
252 afi_t afi
, safi_t safi
);
254 extern int zebra_router_config_write(struct vty
*vty
);
256 extern void zebra_router_sweep_route(void);
257 extern void zebra_router_sweep_nhgs(void);
259 extern void zebra_router_show_table_summary(struct vty
*vty
);
261 extern uint32_t zebra_router_get_next_sequence(void);
263 static inline vrf_id_t
zebra_vrf_get_evpn_id(void)
265 return zrouter
.evpn_vrf
? zvrf_id(zrouter
.evpn_vrf
) : VRF_DEFAULT
;
267 static inline struct zebra_vrf
*zebra_vrf_get_evpn(void)
269 return zrouter
.evpn_vrf
? zrouter
.evpn_vrf
270 : zebra_vrf_lookup_by_id(VRF_DEFAULT
);
273 extern void multicast_mode_ipv4_set(enum multicast_mode mode
);
275 extern enum multicast_mode
multicast_mode_ipv4_get(void);
277 extern bool zebra_router_notify_on_ack(void);
279 static inline void zebra_router_set_supports_nhgs(bool support
)
281 zrouter
.supports_nhgs
= support
;
284 static inline bool zebra_router_in_shutdown(void)
286 return atomic_load_explicit(&zrouter
.in_shutdown
, memory_order_relaxed
);
289 /* zebra_northbound.c */
290 extern const struct frr_yang_module_info frr_zebra_info
;