]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_vxlan_private.h
zebra: set RTNH_F_ONLINK in nexthop creation
[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 /* Flood mode (one of enum vxlan_flood_control) based on the PMSI
56 * tunnel type advertised by the remote VTEP
57 */
58 int flood_control;
59
60 /* Links. */
61 struct zebra_vtep_t_ *next;
62 struct zebra_vtep_t_ *prev;
63 };
64
65
66 /*
67 * VNI hash table
68 *
69 * Contains information pertaining to a VNI:
70 * - the list of remote VTEPs (with this VNI)
71 */
72 struct zebra_vni_t_ {
73 /* VNI - key */
74 vni_t vni;
75
76 /* Flag for advertising gw macip */
77 uint8_t advertise_gw_macip;
78
79 /* Flag for advertising svi macip */
80 uint8_t advertise_svi_macip;
81
82 /* Flag for advertising gw macip */
83 uint8_t advertise_subnet;
84
85 /* Corresponding VxLAN interface. */
86 struct interface *vxlan_if;
87
88 /* List of remote VTEPs */
89 zebra_vtep_t *vteps;
90
91 /* Local IP */
92 struct in_addr local_vtep_ip;
93
94 /* PIM-SM MDT group for BUM flooding */
95 struct in_addr mcast_grp;
96
97 /* tenant VRF, if any */
98 vrf_id_t vrf_id;
99
100 /* List of local or remote MAC */
101 struct hash *mac_table;
102
103 /* List of local or remote neighbors (MAC+IP) */
104 struct hash *neigh_table;
105 };
106
107 /* L3 VNI hash table */
108 struct zebra_l3vni_t_ {
109
110 /* VNI key */
111 vni_t vni;
112
113 /* vrf_id */
114 vrf_id_t vrf_id;
115
116 uint32_t filter;
117 #define PREFIX_ROUTES_ONLY (1 << 0) /* l3-vni used for prefix routes only */
118
119 /* Local IP */
120 struct in_addr local_vtep_ip;
121
122 /* kernel interface for l3vni */
123 struct interface *vxlan_if;
124
125 /* SVI interface corresponding to the l3vni */
126 struct interface *svi_if;
127
128 struct interface *mac_vlan_if;
129
130 /* list of L2 VNIs associated with the L3 VNI */
131 struct list *l2vnis;
132
133 /* list of remote router-macs */
134 struct hash *rmac_table;
135
136 /* list of remote vtep-ip neigh */
137 struct hash *nh_table;
138 };
139
140 /* get the vx-intf name for l3vni */
141 static inline const char *zl3vni_vxlan_if_name(zebra_l3vni_t *zl3vni)
142 {
143 return zl3vni->vxlan_if ? zl3vni->vxlan_if->name : "None";
144 }
145
146 /* get the svi intf name for l3vni */
147 static inline const char *zl3vni_svi_if_name(zebra_l3vni_t *zl3vni)
148 {
149 return zl3vni->svi_if ? zl3vni->svi_if->name : "None";
150 }
151
152 /* get the vrf name for l3vni */
153 static inline const char *zl3vni_vrf_name(zebra_l3vni_t *zl3vni)
154 {
155 return vrf_id_to_name(zl3vni->vrf_id);
156 }
157
158 /* get the rmac string */
159 static inline const char *zl3vni_rmac2str(zebra_l3vni_t *zl3vni, char *buf,
160 int size)
161 {
162 char *ptr;
163
164 if (!buf)
165 ptr = (char *)XMALLOC(MTYPE_TMP,
166 ETHER_ADDR_STRLEN * sizeof(char));
167 else {
168 assert(size >= ETHER_ADDR_STRLEN);
169 ptr = buf;
170 }
171
172 if (zl3vni->mac_vlan_if)
173 snprintf(ptr, (ETHER_ADDR_STRLEN),
174 "%02x:%02x:%02x:%02x:%02x:%02x",
175 (uint8_t)zl3vni->mac_vlan_if->hw_addr[0],
176 (uint8_t)zl3vni->mac_vlan_if->hw_addr[1],
177 (uint8_t)zl3vni->mac_vlan_if->hw_addr[2],
178 (uint8_t)zl3vni->mac_vlan_if->hw_addr[3],
179 (uint8_t)zl3vni->mac_vlan_if->hw_addr[4],
180 (uint8_t)zl3vni->mac_vlan_if->hw_addr[5]);
181 else if (zl3vni->svi_if)
182 snprintf(ptr, (ETHER_ADDR_STRLEN),
183 "%02x:%02x:%02x:%02x:%02x:%02x",
184 (uint8_t)zl3vni->svi_if->hw_addr[0],
185 (uint8_t)zl3vni->svi_if->hw_addr[1],
186 (uint8_t)zl3vni->svi_if->hw_addr[2],
187 (uint8_t)zl3vni->svi_if->hw_addr[3],
188 (uint8_t)zl3vni->svi_if->hw_addr[4],
189 (uint8_t)zl3vni->svi_if->hw_addr[5]);
190 else
191 snprintf(ptr, ETHER_ADDR_STRLEN, "None");
192
193 return ptr;
194 }
195
196 /* get the sys mac string */
197 static inline const char *zl3vni_sysmac2str(zebra_l3vni_t *zl3vni, char *buf,
198 int size)
199 {
200 char *ptr;
201
202 if (!buf)
203 ptr = (char *)XMALLOC(MTYPE_TMP,
204 ETHER_ADDR_STRLEN * sizeof(char));
205 else {
206 assert(size >= ETHER_ADDR_STRLEN);
207 ptr = buf;
208 }
209
210 if (zl3vni->svi_if)
211 snprintf(ptr, (ETHER_ADDR_STRLEN),
212 "%02x:%02x:%02x:%02x:%02x:%02x",
213 (uint8_t)zl3vni->svi_if->hw_addr[0],
214 (uint8_t)zl3vni->svi_if->hw_addr[1],
215 (uint8_t)zl3vni->svi_if->hw_addr[2],
216 (uint8_t)zl3vni->svi_if->hw_addr[3],
217 (uint8_t)zl3vni->svi_if->hw_addr[4],
218 (uint8_t)zl3vni->svi_if->hw_addr[5]);
219 else
220 snprintf(ptr, ETHER_ADDR_STRLEN, "None");
221
222 return ptr;
223 }
224
225 /*
226 * l3-vni is oper up when:
227 * 0. if EVPN is enabled (advertise-all-vni cfged)
228 * 1. it is associated to a vxlan-intf
229 * 2. Associated vxlan-intf is oper up
230 * 3. it is associated to an SVI
231 * 4. associated SVI is oper up
232 */
233 static inline int is_l3vni_oper_up(zebra_l3vni_t *zl3vni)
234 {
235 return (is_evpn_enabled() && zl3vni && (zl3vni->vrf_id != VRF_UNKNOWN)
236 && zl3vni->vxlan_if && if_is_operative(zl3vni->vxlan_if)
237 && zl3vni->svi_if && if_is_operative(zl3vni->svi_if));
238 }
239
240 static inline const char *zl3vni_state2str(zebra_l3vni_t *zl3vni)
241 {
242 if (!zl3vni)
243 return NULL;
244
245 if (is_l3vni_oper_up(zl3vni))
246 return "Up";
247 else
248 return "Down";
249
250 return NULL;
251 }
252
253 static inline vrf_id_t zl3vni_vrf_id(zebra_l3vni_t *zl3vni)
254 {
255 return zl3vni->vrf_id;
256 }
257
258 static inline void zl3vni_get_svi_rmac(zebra_l3vni_t *zl3vni,
259 struct ethaddr *rmac)
260 {
261 if (!zl3vni)
262 return;
263
264 if (!is_l3vni_oper_up(zl3vni))
265 return;
266
267 if (zl3vni->svi_if && if_is_operative(zl3vni->svi_if))
268 memcpy(rmac->octet, zl3vni->svi_if->hw_addr, ETH_ALEN);
269 }
270
271 struct host_rb_entry {
272 RB_ENTRY(host_rb_entry) hl_entry;
273
274 struct prefix p;
275 };
276
277 RB_HEAD(host_rb_tree_entry, host_rb_entry);
278 RB_PROTOTYPE(host_rb_tree_entry, host_rb_entry, hl_entry,
279 host_rb_entry_compare);
280 /*
281 * MAC hash table.
282 *
283 * This table contains the MAC addresses pertaining to this VNI.
284 * This includes local MACs learnt on an attached VLAN that maps
285 * to this VNI as well as remote MACs learnt and installed by BGP.
286 * Local MACs will be known either on a VLAN sub-interface or
287 * on (port, VLAN); however, it is sufficient for zebra to maintain
288 * against the VNI i.e., it does not need to retain the local "port"
289 * information. The correct VNI will be obtained as zebra maintains
290 * the mapping (of VLAN to VNI).
291 */
292 struct zebra_mac_t_ {
293 /* MAC address. */
294 struct ethaddr macaddr;
295
296 uint32_t flags;
297 #define ZEBRA_MAC_LOCAL 0x01
298 #define ZEBRA_MAC_REMOTE 0x02
299 #define ZEBRA_MAC_AUTO 0x04 /* Auto created for neighbor. */
300 #define ZEBRA_MAC_STICKY 0x08 /* Static MAC */
301 #define ZEBRA_MAC_REMOTE_RMAC 0x10 /* remote router mac */
302 #define ZEBRA_MAC_DEF_GW 0x20
303 /* remote VTEP advertised MAC as default GW */
304 #define ZEBRA_MAC_REMOTE_DEF_GW 0x40
305 #define ZEBRA_MAC_DUPLICATE 0x80
306
307 /* back pointer to zvni */
308 zebra_vni_t *zvni;
309
310 /* Local or remote info. */
311 union {
312 struct {
313 ifindex_t ifindex;
314 vlanid_t vid;
315 } local;
316
317 struct in_addr r_vtep_ip;
318 } fwd_info;
319
320 /* Mobility sequence numbers associated with this entry. */
321 uint32_t rem_seq;
322 uint32_t loc_seq;
323
324 /* List of neigh associated with this mac */
325 struct list *neigh_list;
326
327 /* list of hosts pointing to this remote RMAC */
328 struct host_rb_tree_entry host_rb;
329
330 /* Duplicate mac detection */
331 uint32_t dad_count;
332
333 struct thread *dad_mac_auto_recovery_timer;
334
335 struct timeval detect_start_time;
336
337 time_t dad_dup_detect_time;
338 };
339
340 /*
341 * Context for MAC hash walk - used by callbacks.
342 */
343 struct mac_walk_ctx {
344 zebra_vni_t *zvni; /* VNI hash */
345 struct zebra_vrf *zvrf; /* VRF - for client notification. */
346 int uninstall; /* uninstall from kernel? */
347 int upd_client; /* uninstall from client? */
348
349 uint32_t flags;
350 #define DEL_LOCAL_MAC 0x1
351 #define DEL_REMOTE_MAC 0x2
352 #define DEL_ALL_MAC (DEL_LOCAL_MAC | DEL_REMOTE_MAC)
353 #define DEL_REMOTE_MAC_FROM_VTEP 0x4
354 #define SHOW_REMOTE_MAC_FROM_VTEP 0x8
355
356 struct in_addr r_vtep_ip; /* To walk MACs from specific VTEP */
357
358 struct vty *vty; /* Used by VTY handlers */
359 uint32_t count; /* Used by VTY handlers */
360 struct json_object *json; /* Used for JSON Output */
361 bool print_dup; /* Used to print dup addr list */
362 };
363
364 struct rmac_walk_ctx {
365 struct vty *vty;
366 struct json_object *json;
367 };
368
369 #define IS_ZEBRA_NEIGH_ACTIVE(n) (n->state == ZEBRA_NEIGH_ACTIVE)
370
371 #define IS_ZEBRA_NEIGH_INACTIVE(n) (n->state == ZEBRA_NEIGH_INACTIVE)
372
373 #define ZEBRA_NEIGH_SET_ACTIVE(n) n->state = ZEBRA_NEIGH_ACTIVE
374
375 #define ZEBRA_NEIGH_SET_INACTIVE(n) n->state = ZEBRA_NEIGH_INACTIVE
376
377 /*
378 * Neighbor hash table.
379 *
380 * This table contains the neighbors (IP to MAC bindings) pertaining to
381 * this VNI. This includes local neighbors learnt on the attached VLAN
382 * device that maps to this VNI as well as remote neighbors learnt and
383 * installed by BGP.
384 * Local neighbors will be known against the VLAN device (SVI); however,
385 * it is sufficient for zebra to maintain against the VNI. The correct
386 * VNI will be obtained as zebra maintains the mapping (of VLAN to VNI).
387 */
388 struct zebra_neigh_t_ {
389 /* IP address. */
390 struct ipaddr ip;
391
392 /* MAC address. */
393 struct ethaddr emac;
394
395 /* Underlying interface. */
396 ifindex_t ifindex;
397
398 zebra_vni_t *zvni;
399
400 uint32_t flags;
401 #define ZEBRA_NEIGH_LOCAL 0x01
402 #define ZEBRA_NEIGH_REMOTE 0x02
403 #define ZEBRA_NEIGH_REMOTE_NH 0x04 /* neigh entry for remote vtep */
404 #define ZEBRA_NEIGH_DEF_GW 0x08
405 #define ZEBRA_NEIGH_ROUTER_FLAG 0x10
406 #define ZEBRA_NEIGH_DUPLICATE 0x20
407 #define ZEBRA_NEIGH_SVI_IP 0x40
408
409 enum zebra_neigh_state state;
410
411 /* Remote VTEP IP - applicable only for remote neighbors. */
412 struct in_addr r_vtep_ip;
413
414 /*
415 * Mobility sequence numbers associated with this entry. The rem_seq
416 * represents the sequence number from the client (BGP) for the most
417 * recent add or update of this entry while the loc_seq represents
418 * the sequence number informed (or to be informed) by zebra to BGP
419 * for this entry.
420 */
421 uint32_t rem_seq;
422 uint32_t loc_seq;
423
424 /* list of hosts pointing to this remote NH entry */
425 struct host_rb_tree_entry host_rb;
426
427 /* Duplicate ip detection */
428 uint32_t dad_count;
429
430 struct thread *dad_ip_auto_recovery_timer;
431
432 struct timeval detect_start_time;
433
434 time_t dad_dup_detect_time;
435 };
436
437 /*
438 * Context for neighbor hash walk - used by callbacks.
439 */
440 struct neigh_walk_ctx {
441 zebra_vni_t *zvni; /* VNI hash */
442 struct zebra_vrf *zvrf; /* VRF - for client notification. */
443 int uninstall; /* uninstall from kernel? */
444 int upd_client; /* uninstall from client? */
445
446 uint32_t flags;
447 #define DEL_LOCAL_NEIGH 0x1
448 #define DEL_REMOTE_NEIGH 0x2
449 #define DEL_ALL_NEIGH (DEL_LOCAL_NEIGH | DEL_REMOTE_NEIGH)
450 #define DEL_REMOTE_NEIGH_FROM_VTEP 0x4
451 #define SHOW_REMOTE_NEIGH_FROM_VTEP 0x8
452
453 struct in_addr r_vtep_ip; /* To walk neighbors from specific VTEP */
454
455 struct vty *vty; /* Used by VTY handlers */
456 uint32_t count; /* Used by VTY handlers */
457 uint8_t addr_width; /* Used by VTY handlers */
458 struct json_object *json; /* Used for JSON Output */
459 };
460
461 /* context for neigh hash walk - update l3vni and rmac */
462 struct neigh_l3info_walk_ctx {
463
464 zebra_vni_t *zvni;
465 zebra_l3vni_t *zl3vni;
466 int add;
467 };
468
469 struct nh_walk_ctx {
470
471 struct vty *vty;
472 struct json_object *json;
473 };
474
475 extern zebra_l3vni_t *zl3vni_from_vrf(vrf_id_t vrf_id);
476 extern struct interface *zl3vni_map_to_vxlan_if(zebra_l3vni_t *zl3vni);
477 extern struct interface *zl3vni_map_to_svi_if(zebra_l3vni_t *zl3vni);
478 extern struct interface *zl3vni_map_to_mac_vlan_if(zebra_l3vni_t *zl3vni);
479
480 DECLARE_HOOK(zebra_rmac_update, (zebra_mac_t *rmac, zebra_l3vni_t *zl3vni,
481 bool delete, const char *reason), (rmac, zl3vni, delete, reason))
482
483
484 #ifdef __cplusplus
485 }
486 #endif
487
488 /*
489 * Multicast hash table.
490 *
491 * This table contains -
492 * 1. The (S, G) entries used for encapsulating and forwarding BUM traffic.
493 * S is the local VTEP-IP and G is a BUM mcast group address.
494 * 2. The (X, G) entries used for terminating a BUM flow.
495 * Multiple L2-VNIs can share the same MDT hence the need to maintain
496 * an aggregated table that pimd can consume without much
497 * re-interpretation.
498 */
499 typedef struct zebra_vxlan_sg_ {
500 struct zebra_vrf *zvrf;
501
502 struct prefix_sg sg;
503 char sg_str[PREFIX_SG_STR_LEN];
504
505 /* For SG - num of L2 VNIs using this entry for sending BUM traffic */
506 /* For XG - num of SG using this as parent */
507 uint32_t ref_cnt;
508 } zebra_vxlan_sg_t;
509
510 #endif /* _ZEBRA_VXLAN_PRIVATE_H */