Line data Source code
1 : /* Zebra Router header.
2 : * Copyright (C) 2018 Cumulus Networks, Inc.
3 : * Donald Sharp
4 : *
5 : * This file is part of FRR.
6 : *
7 : * FRR is free software; you can redistribute it and/or modify it
8 : * under the terms of the GNU General Public License as published by the
9 : * Free Software Foundation; either version 2, or (at your option) any
10 : * later version.
11 : *
12 : * FRR is distributed in the hope that it will be useful, but
13 : * WITHOUT ANY WARRANTY; without even the implied warranty of
14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : * General Public License for more details.
16 : *
17 : * You should have received a copy of the GNU General Public License
18 : * along with FRR; see the file COPYING. If not, write to the Free
19 : * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 : * 02111-1307, USA.
21 : */
22 : #ifndef __ZEBRA_ROUTER_H__
23 : #define __ZEBRA_ROUTER_H__
24 :
25 : #include "lib/mlag.h"
26 :
27 : #include "zebra/zebra_ns.h"
28 :
29 : #ifdef __cplusplus
30 : extern "C" {
31 : #endif
32 :
33 : /*
34 : * This header file contains the idea of a router and as such
35 : * owns data that is associated with a router from zebra's
36 : * perspective.
37 : */
38 :
39 : struct zebra_router_table {
40 : RB_ENTRY(zebra_router_table) zebra_router_table_entry;
41 :
42 : uint32_t tableid;
43 : afi_t afi;
44 : safi_t safi;
45 : ns_id_t ns_id;
46 :
47 : struct route_table *table;
48 : };
49 : RB_HEAD(zebra_router_table_head, zebra_router_table);
50 91 : RB_PROTOTYPE(zebra_router_table_head, zebra_router_table,
51 : zebra_router_table_entry, zebra_router_table_entry_compare)
52 :
53 : /* RPF lookup behaviour */
54 : enum multicast_mode {
55 : MCAST_NO_CONFIG = 0, /* MIX_MRIB_FIRST, but no show in config write */
56 : MCAST_MRIB_ONLY, /* MRIB only */
57 : MCAST_URIB_ONLY, /* URIB only */
58 : MCAST_MIX_MRIB_FIRST, /* MRIB, if nothing at all then URIB */
59 : MCAST_MIX_DISTANCE, /* MRIB & URIB, lower distance wins */
60 : MCAST_MIX_PFXLEN, /* MRIB & URIB, longer prefix wins */
61 : /* on equal value, MRIB wins for last 2 */
62 : };
63 :
64 : /* An interface can be error-disabled if a protocol (such as EVPN or
65 : * VRRP) detects a problem with keeping it operationally-up.
66 : * If any of the protodown bits are set protodown-on is programmed
67 : * in the dataplane. This results in a carrier/L1 down on the
68 : * physical device.
69 : */
70 : enum protodown_reasons {
71 : /* A process outside of FRR's control protodowned the interface */
72 : ZEBRA_PROTODOWN_EXTERNAL = (1 << 0),
73 : /* On startup local ESs are held down for some time to
74 : * allow the underlay to converge and EVPN routes to
75 : * get learnt
76 : */
77 : ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY = (1 << 1),
78 : /* If all the uplinks are down the switch has lost access
79 : * to the VxLAN overlay and must shut down the access
80 : * ports to allow servers to re-direct their traffic to
81 : * other switches on the Ethernet Segment
82 : */
83 : ZEBRA_PROTODOWN_EVPN_UPLINK_DOWN = (1 << 2),
84 : ZEBRA_PROTODOWN_EVPN_ALL = (ZEBRA_PROTODOWN_EVPN_UPLINK_DOWN |
85 : ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY),
86 : ZEBRA_PROTODOWN_VRRP = (1 << 3),
87 : /* This reason used exclusively for testing */
88 : ZEBRA_PROTODOWN_SHARP = (1 << 4),
89 : /* Just used to clear our fields on shutdown, externel not included */
90 : ZEBRA_PROTODOWN_ALL = (ZEBRA_PROTODOWN_EVPN_ALL | ZEBRA_PROTODOWN_VRRP |
91 : ZEBRA_PROTODOWN_SHARP)
92 : };
93 : #define ZEBRA_PROTODOWN_RC_STR_LEN 80
94 :
95 : struct zebra_mlag_info {
96 : /* Role this zebra router is playing */
97 : enum mlag_role role;
98 :
99 : /* The peerlink being used for mlag */
100 : char *peerlink;
101 : ifindex_t peerlink_ifindex;
102 :
103 : /* The system mac being used */
104 : struct ethaddr mac;
105 : /*
106 : * Zebra will open the communication channel with MLAGD only if any
107 : * clients are interested and it is controlled dynamically based on
108 : * client registers & un-registers.
109 : */
110 : uint32_t clients_interested_cnt;
111 :
112 : /* coomunication channel with MLAGD is established */
113 : bool connected;
114 :
115 : /* connection retry timer is running */
116 : bool timer_running;
117 :
118 : /* Holds the client data(unencoded) that need to be pushed to MCLAGD*/
119 : struct stream_fifo *mlag_fifo;
120 :
121 : /*
122 : * A new Kernel thread will be created to post the data to MCLAGD.
123 : * where as, read will be performed from the zebra main thread, because
124 : * read involves accessing client registartion data structures.
125 : */
126 : struct frr_pthread *zebra_pth_mlag;
127 :
128 : /* MLAG Thread context 'master' */
129 : struct thread_master *th_master;
130 :
131 : /*
132 : * Event for Initial MLAG Connection setup & Data Read
133 : * Read can be performed only after successful connection establishment,
134 : * so no issues.
135 : *
136 : */
137 : struct thread *t_read;
138 : /* Event for MLAG write */
139 : struct thread *t_write;
140 : };
141 :
142 : struct zebra_router {
143 : atomic_bool in_shutdown;
144 :
145 : /* Thread master */
146 : struct thread_master *master;
147 :
148 : /* Lists of clients who have connected to us */
149 : struct list *client_list;
150 :
151 : /* List of clients in GR */
152 : struct list *stale_client_list;
153 :
154 : struct zebra_router_table_head tables;
155 :
156 : /* L3-VNI hash table (for EVPN). Only in default instance */
157 : struct hash *l3vni_table;
158 :
159 : /* Tables and other global info maintained for EVPN multihoming */
160 : struct zebra_evpn_mh_info *mh_info;
161 :
162 : struct zebra_neigh_info *neigh_info;
163 :
164 : /* EVPN MH broadcast domains indexed by the VID */
165 : struct hash *evpn_vlan_table;
166 :
167 : struct hash *rules_hash;
168 :
169 : struct hash *ipset_hash;
170 :
171 : struct hash *ipset_entry_hash;
172 :
173 : struct hash *iptable_hash;
174 :
175 : struct hash *qdisc_hash;
176 : struct hash *class_hash;
177 : struct hash *filter_hash;
178 :
179 : /* A sequence number used for tracking routes */
180 : _Atomic uint32_t sequence_num;
181 :
182 : /* rib work queue */
183 : #define ZEBRA_RIB_PROCESS_HOLD_TIME 10
184 : #define ZEBRA_RIB_PROCESS_RETRY_TIME 1
185 : struct work_queue *ribq;
186 :
187 : /* Meta Queue Information */
188 : struct meta_queue *mq;
189 :
190 : /* LSP work queue */
191 : struct work_queue *lsp_process_q;
192 :
193 : #define ZEBRA_ZAPI_PACKETS_TO_PROCESS 1000
194 : _Atomic uint32_t packets_to_process;
195 :
196 : /* Mlag information for the router */
197 : struct zebra_mlag_info mlag_info;
198 :
199 : /*
200 : * The EVPN instance, if any
201 : */
202 : struct zebra_vrf *evpn_vrf;
203 :
204 : uint32_t multipath_num;
205 :
206 : /* RPF Lookup behavior */
207 : enum multicast_mode ipv4_multicast_mode;
208 :
209 : /*
210 : * Time for when we sweep the rib from old routes
211 : */
212 : time_t startup_time;
213 : struct thread *sweeper;
214 :
215 : /*
216 : * The hash of nexthop groups associated with this router
217 : */
218 : struct hash *nhgs;
219 : struct hash *nhgs_id;
220 :
221 : /*
222 : * Does the underlying system provide an asic offload
223 : */
224 : bool asic_offloaded;
225 : bool notify_on_ack;
226 :
227 : /*
228 : * If the asic is notifying us about successful nexthop
229 : * allocation/control. Some developers have made their
230 : * asic take control of how many nexthops/ecmp they can
231 : * have and will report what is successfull or not
232 : */
233 : bool asic_notification_nexthop_control;
234 :
235 : bool supports_nhgs;
236 :
237 : bool all_mc_forwardingv4, default_mc_forwardingv4;
238 : bool all_mc_forwardingv6, default_mc_forwardingv6;
239 : bool all_linkdownv4, default_linkdownv4;
240 : bool all_linkdownv6, default_linkdownv6;
241 :
242 : #define ZEBRA_DEFAULT_NHG_KEEP_TIMER 180
243 : uint32_t nhg_keep;
244 :
245 : /* Should we allow non FRR processes to delete our routes */
246 : bool allow_delete;
247 : };
248 :
249 : #define GRACEFUL_RESTART_TIME 60
250 :
251 : extern struct zebra_router zrouter;
252 : extern uint32_t rcvbufsize;
253 :
254 : extern void zebra_router_init(bool asic_offload, bool notify_on_ack);
255 : extern void zebra_router_cleanup(void);
256 : extern void zebra_router_terminate(void);
257 :
258 : extern struct zebra_router_table *zebra_router_find_zrt(struct zebra_vrf *zvrf,
259 : uint32_t tableid,
260 : afi_t afi, safi_t safi);
261 : extern struct route_table *zebra_router_find_table(struct zebra_vrf *zvrf,
262 : uint32_t tableid, afi_t afi,
263 : safi_t safi);
264 : extern struct route_table *zebra_router_get_table(struct zebra_vrf *zvrf,
265 : uint32_t tableid, afi_t afi,
266 : safi_t safi);
267 : extern void zebra_router_release_table(struct zebra_vrf *zvrf, uint32_t tableid,
268 : afi_t afi, safi_t safi);
269 :
270 : extern int zebra_router_config_write(struct vty *vty);
271 :
272 : extern void zebra_router_sweep_route(void);
273 : extern void zebra_router_sweep_nhgs(void);
274 :
275 : extern void zebra_router_show_table_summary(struct vty *vty);
276 :
277 : extern uint32_t zebra_router_get_next_sequence(void);
278 :
279 0 : static inline vrf_id_t zebra_vrf_get_evpn_id(void)
280 : {
281 0 : return zrouter.evpn_vrf ? zvrf_id(zrouter.evpn_vrf) : VRF_DEFAULT;
282 : }
283 31 : static inline struct zebra_vrf *zebra_vrf_get_evpn(void)
284 : {
285 31 : return zrouter.evpn_vrf ? zrouter.evpn_vrf
286 31 : : zebra_vrf_lookup_by_id(VRF_DEFAULT);
287 : }
288 :
289 : extern void multicast_mode_ipv4_set(enum multicast_mode mode);
290 :
291 : extern enum multicast_mode multicast_mode_ipv4_get(void);
292 :
293 : extern bool zebra_router_notify_on_ack(void);
294 :
295 3 : static inline void zebra_router_set_supports_nhgs(bool support)
296 : {
297 3 : zrouter.supports_nhgs = support;
298 : }
299 :
300 96 : static inline bool zebra_router_in_shutdown(void)
301 : {
302 96 : return atomic_load_explicit(&zrouter.in_shutdown, memory_order_relaxed);
303 : }
304 :
305 : /* zebra_northbound.c */
306 : extern const struct frr_yang_module_info frr_zebra_info;
307 :
308 : #ifdef __cplusplus
309 : }
310 : #endif
311 :
312 : #endif
|