]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_vxlan_private.h
zebra: header changes for l2 vni bum-mcast-grp handling
[mirror_frr.git] / zebra / zebra_vxlan_private.h
1 /*
2 * Zebra VxLAN (EVPN) Data structures and definitions
3 * These are "internal" to this function.
4 * Copyright (C) 2016, 2017 Cumulus Networks, Inc.
5 *
6 * This file is part of FRR.
7 *
8 * FRR is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2, or (at your option) any
11 * later version.
12 *
13 * FRR is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with FRR; see the file COPYING. If not, write to the Free
20 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21 * 02111-1307, USA.
22 */
23
24 #ifndef _ZEBRA_VXLAN_PRIVATE_H
25 #define _ZEBRA_VXLAN_PRIVATE_H
26
27 #include <zebra.h>
28
29 #include "if.h"
30 #include "linklist.h"
31 #include "zebra_vxlan.h"
32
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36
37 #define ERR_STR_SZ 256
38
39 /* definitions */
40 typedef struct zebra_vni_t_ zebra_vni_t;
41 typedef struct zebra_vtep_t_ zebra_vtep_t;
42 typedef struct zebra_mac_t_ zebra_mac_t;
43 typedef struct zebra_neigh_t_ zebra_neigh_t;
44 typedef struct zebra_l3vni_t_ zebra_l3vni_t;
45
46 /*
47 * VTEP info
48 *
49 * Right now, this just has each remote VTEP's IP address.
50 */
51 struct zebra_vtep_t_ {
52 /* Remote IP. */
53 /* NOTE: Can only be IPv4 right now. */
54 struct in_addr vtep_ip;
55
56 /* Links. */
57 struct zebra_vtep_t_ *next;
58 struct zebra_vtep_t_ *prev;
59 };
60
61
62 /*
63 * VNI hash table
64 *
65 * Contains information pertaining to a VNI:
66 * - the list of remote VTEPs (with this VNI)
67 */
68 struct zebra_vni_t_ {
69 /* VNI - key */
70 vni_t vni;
71
72 /* Flag for advertising gw macip */
73 uint8_t advertise_gw_macip;
74
75 /* Flag for advertising svi macip */
76 uint8_t advertise_svi_macip;
77
78 /* Flag for advertising gw macip */
79 uint8_t advertise_subnet;
80
81 /* Corresponding VxLAN interface. */
82 struct interface *vxlan_if;
83
84 /* List of remote VTEPs */
85 zebra_vtep_t *vteps;
86
87 /* Local IP */
88 struct in_addr local_vtep_ip;
89
90 /* PIM-SM MDT group for BUM flooding */
91 struct in_addr mcast_grp;
92
93 /* tenant VRF, if any */
94 vrf_id_t vrf_id;
95
96 /* List of local or remote MAC */
97 struct hash *mac_table;
98
99 /* List of local or remote neighbors (MAC+IP) */
100 struct hash *neigh_table;
101 };
102
103 /* L3 VNI hash table */
104 struct zebra_l3vni_t_ {
105
106 /* VNI key */
107 vni_t vni;
108
109 /* vrf_id */
110 vrf_id_t vrf_id;
111
112 uint32_t filter;
113 #define PREFIX_ROUTES_ONLY (1 << 0) /* l3-vni used for prefix routes only */
114
115 /* Local IP */
116 struct in_addr local_vtep_ip;
117
118 /* kernel interface for l3vni */
119 struct interface *vxlan_if;
120
121 /* SVI interface corresponding to the l3vni */
122 struct interface *svi_if;
123
124 /* list of L2 VNIs associated with the L3 VNI */
125 struct list *l2vnis;
126
127 /* list of remote router-macs */
128 struct hash *rmac_table;
129
130 /* list of remote vtep-ip neigh */
131 struct hash *nh_table;
132 };
133
134 /* get the vx-intf name for l3vni */
135 static inline const char *zl3vni_vxlan_if_name(zebra_l3vni_t *zl3vni)
136 {
137 return zl3vni->vxlan_if ? zl3vni->vxlan_if->name : "None";
138 }
139
140 /* get the svi intf name for l3vni */
141 static inline const char *zl3vni_svi_if_name(zebra_l3vni_t *zl3vni)
142 {
143 return zl3vni->svi_if ? zl3vni->svi_if->name : "None";
144 }
145
146 /* get the vrf name for l3vni */
147 static inline const char *zl3vni_vrf_name(zebra_l3vni_t *zl3vni)
148 {
149 return vrf_id_to_name(zl3vni->vrf_id);
150 }
151
152 /* get the rmac string */
153 static inline const char *zl3vni_rmac2str(zebra_l3vni_t *zl3vni, char *buf,
154 int size)
155 {
156 char *ptr;
157
158 if (!buf)
159 ptr = (char *)XMALLOC(MTYPE_TMP,
160 ETHER_ADDR_STRLEN * sizeof(char));
161 else {
162 assert(size >= ETHER_ADDR_STRLEN);
163 ptr = buf;
164 }
165
166 if (zl3vni->svi_if)
167 snprintf(ptr, (ETHER_ADDR_STRLEN),
168 "%02x:%02x:%02x:%02x:%02x:%02x",
169 (uint8_t)zl3vni->svi_if->hw_addr[0],
170 (uint8_t)zl3vni->svi_if->hw_addr[1],
171 (uint8_t)zl3vni->svi_if->hw_addr[2],
172 (uint8_t)zl3vni->svi_if->hw_addr[3],
173 (uint8_t)zl3vni->svi_if->hw_addr[4],
174 (uint8_t)zl3vni->svi_if->hw_addr[5]);
175 else
176 snprintf(ptr, ETHER_ADDR_STRLEN, "None");
177
178 return ptr;
179 }
180
181 /*
182 * l3-vni is oper up when:
183 * 0. if EVPN is enabled (advertise-all-vni cfged)
184 * 1. it is associated to a vxlan-intf
185 * 2. Associated vxlan-intf is oper up
186 * 3. it is associated to an SVI
187 * 4. associated SVI is oper up
188 */
189 static inline int is_l3vni_oper_up(zebra_l3vni_t *zl3vni)
190 {
191 return (is_evpn_enabled() && zl3vni && (zl3vni->vrf_id != VRF_UNKNOWN)
192 && zl3vni->vxlan_if && if_is_operative(zl3vni->vxlan_if)
193 && zl3vni->svi_if && if_is_operative(zl3vni->svi_if));
194 }
195
196 static inline const char *zl3vni_state2str(zebra_l3vni_t *zl3vni)
197 {
198 if (!zl3vni)
199 return NULL;
200
201 if (is_l3vni_oper_up(zl3vni))
202 return "Up";
203 else
204 return "Down";
205
206 return NULL;
207 }
208
209 static inline vrf_id_t zl3vni_vrf_id(zebra_l3vni_t *zl3vni)
210 {
211 return zl3vni->vrf_id;
212 }
213
214 static inline void zl3vni_get_rmac(zebra_l3vni_t *zl3vni, struct ethaddr *rmac)
215 {
216 if (!zl3vni)
217 return;
218
219 if (!is_l3vni_oper_up(zl3vni))
220 return;
221
222 if (zl3vni->svi_if && if_is_operative(zl3vni->svi_if))
223 memcpy(rmac->octet, zl3vni->svi_if->hw_addr, ETH_ALEN);
224 }
225
226 struct host_rb_entry {
227 RB_ENTRY(host_rb_entry) hl_entry;
228
229 struct prefix p;
230 };
231
232 RB_HEAD(host_rb_tree_entry, host_rb_entry);
233 RB_PROTOTYPE(host_rb_tree_entry, host_rb_entry, hl_entry,
234 host_rb_entry_compare);
235 /*
236 * MAC hash table.
237 *
238 * This table contains the MAC addresses pertaining to this VNI.
239 * This includes local MACs learnt on an attached VLAN that maps
240 * to this VNI as well as remote MACs learnt and installed by BGP.
241 * Local MACs will be known either on a VLAN sub-interface or
242 * on (port, VLAN); however, it is sufficient for zebra to maintain
243 * against the VNI i.e., it does not need to retain the local "port"
244 * information. The correct VNI will be obtained as zebra maintains
245 * the mapping (of VLAN to VNI).
246 */
247 struct zebra_mac_t_ {
248 /* MAC address. */
249 struct ethaddr macaddr;
250
251 uint32_t flags;
252 #define ZEBRA_MAC_LOCAL 0x01
253 #define ZEBRA_MAC_REMOTE 0x02
254 #define ZEBRA_MAC_AUTO 0x04 /* Auto created for neighbor. */
255 #define ZEBRA_MAC_STICKY 0x08 /* Static MAC */
256 #define ZEBRA_MAC_REMOTE_RMAC 0x10 /* remote router mac */
257 #define ZEBRA_MAC_DEF_GW 0x20
258 /* remote VTEP advertised MAC as default GW */
259 #define ZEBRA_MAC_REMOTE_DEF_GW 0x40
260 #define ZEBRA_MAC_DUPLICATE 0x80
261
262 /* back pointer to zvni */
263 zebra_vni_t *zvni;
264
265 /* Local or remote info. */
266 union {
267 struct {
268 ifindex_t ifindex;
269 vlanid_t vid;
270 } local;
271
272 struct in_addr r_vtep_ip;
273 } fwd_info;
274
275 /* Mobility sequence numbers associated with this entry. */
276 uint32_t rem_seq;
277 uint32_t loc_seq;
278
279 /* List of neigh associated with this mac */
280 struct list *neigh_list;
281
282 /* list of hosts pointing to this remote RMAC */
283 struct host_rb_tree_entry host_rb;
284
285 /* Duplicate mac detection */
286 uint32_t dad_count;
287
288 struct thread *dad_mac_auto_recovery_timer;
289
290 struct timeval detect_start_time;
291
292 time_t dad_dup_detect_time;
293 };
294
295 /*
296 * Context for MAC hash walk - used by callbacks.
297 */
298 struct mac_walk_ctx {
299 zebra_vni_t *zvni; /* VNI hash */
300 struct zebra_vrf *zvrf; /* VRF - for client notification. */
301 int uninstall; /* uninstall from kernel? */
302 int upd_client; /* uninstall from client? */
303
304 uint32_t flags;
305 #define DEL_LOCAL_MAC 0x1
306 #define DEL_REMOTE_MAC 0x2
307 #define DEL_ALL_MAC (DEL_LOCAL_MAC | DEL_REMOTE_MAC)
308 #define DEL_REMOTE_MAC_FROM_VTEP 0x4
309 #define SHOW_REMOTE_MAC_FROM_VTEP 0x8
310
311 struct in_addr r_vtep_ip; /* To walk MACs from specific VTEP */
312
313 struct vty *vty; /* Used by VTY handlers */
314 uint32_t count; /* Used by VTY handlers */
315 struct json_object *json; /* Used for JSON Output */
316 bool print_dup; /* Used to print dup addr list */
317 };
318
319 struct rmac_walk_ctx {
320 struct vty *vty;
321 struct json_object *json;
322 };
323
324 #define IS_ZEBRA_NEIGH_ACTIVE(n) (n->state == ZEBRA_NEIGH_ACTIVE)
325
326 #define IS_ZEBRA_NEIGH_INACTIVE(n) (n->state == ZEBRA_NEIGH_INACTIVE)
327
328 #define ZEBRA_NEIGH_SET_ACTIVE(n) n->state = ZEBRA_NEIGH_ACTIVE
329
330 #define ZEBRA_NEIGH_SET_INACTIVE(n) n->state = ZEBRA_NEIGH_INACTIVE
331
332 /*
333 * Neighbor hash table.
334 *
335 * This table contains the neighbors (IP to MAC bindings) pertaining to
336 * this VNI. This includes local neighbors learnt on the attached VLAN
337 * device that maps to this VNI as well as remote neighbors learnt and
338 * installed by BGP.
339 * Local neighbors will be known against the VLAN device (SVI); however,
340 * it is sufficient for zebra to maintain against the VNI. The correct
341 * VNI will be obtained as zebra maintains the mapping (of VLAN to VNI).
342 */
343 struct zebra_neigh_t_ {
344 /* IP address. */
345 struct ipaddr ip;
346
347 /* MAC address. */
348 struct ethaddr emac;
349
350 /* Underlying interface. */
351 ifindex_t ifindex;
352
353 zebra_vni_t *zvni;
354
355 uint32_t flags;
356 #define ZEBRA_NEIGH_LOCAL 0x01
357 #define ZEBRA_NEIGH_REMOTE 0x02
358 #define ZEBRA_NEIGH_REMOTE_NH 0x04 /* neigh entry for remote vtep */
359 #define ZEBRA_NEIGH_DEF_GW 0x08
360 #define ZEBRA_NEIGH_ROUTER_FLAG 0x10
361 #define ZEBRA_NEIGH_DUPLICATE 0x20
362
363 enum zebra_neigh_state state;
364
365 /* Remote VTEP IP - applicable only for remote neighbors. */
366 struct in_addr r_vtep_ip;
367
368 /*
369 * Mobility sequence numbers associated with this entry. The rem_seq
370 * represents the sequence number from the client (BGP) for the most
371 * recent add or update of this entry while the loc_seq represents
372 * the sequence number informed (or to be informed) by zebra to BGP
373 * for this entry.
374 */
375 uint32_t rem_seq;
376 uint32_t loc_seq;
377
378 /* list of hosts pointing to this remote NH entry */
379 struct host_rb_tree_entry host_rb;
380
381 /* Duplicate ip detection */
382 uint32_t dad_count;
383
384 struct thread *dad_ip_auto_recovery_timer;
385
386 struct timeval detect_start_time;
387
388 time_t dad_dup_detect_time;
389 };
390
391 /*
392 * Context for neighbor hash walk - used by callbacks.
393 */
394 struct neigh_walk_ctx {
395 zebra_vni_t *zvni; /* VNI hash */
396 struct zebra_vrf *zvrf; /* VRF - for client notification. */
397 int uninstall; /* uninstall from kernel? */
398 int upd_client; /* uninstall from client? */
399
400 uint32_t flags;
401 #define DEL_LOCAL_NEIGH 0x1
402 #define DEL_REMOTE_NEIGH 0x2
403 #define DEL_ALL_NEIGH (DEL_LOCAL_NEIGH | DEL_REMOTE_NEIGH)
404 #define DEL_REMOTE_NEIGH_FROM_VTEP 0x4
405 #define SHOW_REMOTE_NEIGH_FROM_VTEP 0x8
406
407 struct in_addr r_vtep_ip; /* To walk neighbors from specific VTEP */
408
409 struct vty *vty; /* Used by VTY handlers */
410 uint32_t count; /* Used by VTY handlers */
411 uint8_t addr_width; /* Used by VTY handlers */
412 struct json_object *json; /* Used for JSON Output */
413 };
414
415 /* context for neigh hash walk - update l3vni and rmac */
416 struct neigh_l3info_walk_ctx {
417
418 zebra_vni_t *zvni;
419 zebra_l3vni_t *zl3vni;
420 int add;
421 };
422
423 struct nh_walk_ctx {
424
425 struct vty *vty;
426 struct json_object *json;
427 };
428
429 #ifdef __cplusplus
430 }
431 #endif
432
433 #endif /* _ZEBRA_VXLAN_PRIVATE_H */