]>
Commit | Line | Data |
---|---|---|
acddc0ed | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
18a7a601 | 2 | /* |
3 | * Zebra VxLAN (EVPN) Data structures and definitions | |
4 | * These are "internal" to this function. | |
5 | * Copyright (C) 2016, 2017 Cumulus Networks, Inc. | |
18a7a601 | 6 | */ |
7 | ||
8 | #ifndef _ZEBRA_VXLAN_PRIVATE_H | |
9 | #define _ZEBRA_VXLAN_PRIVATE_H | |
10 | ||
11 | #include <zebra.h> | |
12 | ||
18a7a601 | 13 | #include "if.h" |
14 | #include "linklist.h" | |
655b04d1 | 15 | #include "zebra_vxlan.h" |
0adeb5fd | 16 | #include "zebra_vxlan_if.h" |
b2998086 PR |
17 | #include "zebra_evpn.h" |
18 | #include "zebra_evpn_mac.h" | |
18a7a601 | 19 | |
51e94aa7 EDP |
20 | #ifdef __cplusplus |
21 | extern "C" { | |
22 | #endif | |
23 | ||
b7cfce93 MK |
24 | #define ERR_STR_SZ 256 |
25 | ||
b7cfce93 | 26 | /* L3 VNI hash table */ |
05843a27 | 27 | struct zebra_l3vni { |
b7cfce93 MK |
28 | |
29 | /* VNI key */ | |
30 | vni_t vni; | |
31 | ||
32 | /* vrf_id */ | |
33 | vrf_id_t vrf_id; | |
34 | ||
c48d9f5f MK |
35 | uint32_t filter; |
36 | #define PREFIX_ROUTES_ONLY (1 << 0) /* l3-vni used for prefix routes only */ | |
37 | ||
efde4f25 SR |
38 | /* Corresponding Bridge information */ |
39 | vlanid_t vid; | |
40 | struct interface *bridge_if; | |
41 | ||
b67a60d2 | 42 | /* Local IP */ |
43 | struct in_addr local_vtep_ip; | |
44 | ||
b7cfce93 MK |
45 | /* kernel interface for l3vni */ |
46 | struct interface *vxlan_if; | |
47 | ||
48 | /* SVI interface corresponding to the l3vni */ | |
49 | struct interface *svi_if; | |
50 | ||
06d9cde5 CS |
51 | struct interface *mac_vlan_if; |
52 | ||
b7cfce93 MK |
53 | /* list of L2 VNIs associated with the L3 VNI */ |
54 | struct list *l2vnis; | |
55 | ||
56 | /* list of remote router-macs */ | |
57 | struct hash *rmac_table; | |
58 | ||
59 | /* list of remote vtep-ip neigh */ | |
60 | struct hash *nh_table; | |
61 | }; | |
62 | ||
b260197d SW |
63 | #define IS_ZL3VNI_SVD_BACKED(zl3vni) \ |
64 | (zl3vni->vxlan_if && zl3vni->vxlan_if->info && \ | |
65 | IS_ZEBRA_VXLAN_IF_SVD((struct zebra_if *)zl3vni->vxlan_if->info)) | |
66 | ||
b7cfce93 | 67 | /* get the vx-intf name for l3vni */ |
05843a27 | 68 | static inline const char *zl3vni_vxlan_if_name(struct zebra_l3vni *zl3vni) |
b7cfce93 MK |
69 | { |
70 | return zl3vni->vxlan_if ? zl3vni->vxlan_if->name : "None"; | |
71 | } | |
72 | ||
73 | /* get the svi intf name for l3vni */ | |
05843a27 | 74 | static inline const char *zl3vni_svi_if_name(struct zebra_l3vni *zl3vni) |
b7cfce93 MK |
75 | { |
76 | return zl3vni->svi_if ? zl3vni->svi_if->name : "None"; | |
77 | } | |
78 | ||
79 | /* get the vrf name for l3vni */ | |
05843a27 | 80 | static inline const char *zl3vni_vrf_name(struct zebra_l3vni *zl3vni) |
b7cfce93 MK |
81 | { |
82 | return vrf_id_to_name(zl3vni->vrf_id); | |
83 | } | |
84 | ||
85 | /* get the rmac string */ | |
05843a27 | 86 | static inline const char *zl3vni_rmac2str(struct zebra_l3vni *zl3vni, char *buf, |
b7cfce93 MK |
87 | int size) |
88 | { | |
89 | char *ptr; | |
90 | ||
91 | if (!buf) | |
8264e9b7 | 92 | ptr = XMALLOC(MTYPE_TMP, ETHER_ADDR_STRLEN * sizeof(char)); |
b7cfce93 MK |
93 | else { |
94 | assert(size >= ETHER_ADDR_STRLEN); | |
95 | ptr = buf; | |
96 | } | |
97 | ||
28ad0501 CS |
98 | if (zl3vni->mac_vlan_if) |
99 | snprintf(ptr, (ETHER_ADDR_STRLEN), | |
100 | "%02x:%02x:%02x:%02x:%02x:%02x", | |
101 | (uint8_t)zl3vni->mac_vlan_if->hw_addr[0], | |
102 | (uint8_t)zl3vni->mac_vlan_if->hw_addr[1], | |
103 | (uint8_t)zl3vni->mac_vlan_if->hw_addr[2], | |
104 | (uint8_t)zl3vni->mac_vlan_if->hw_addr[3], | |
105 | (uint8_t)zl3vni->mac_vlan_if->hw_addr[4], | |
106 | (uint8_t)zl3vni->mac_vlan_if->hw_addr[5]); | |
107 | else if (zl3vni->svi_if) | |
108 | snprintf(ptr, (ETHER_ADDR_STRLEN), | |
109 | "%02x:%02x:%02x:%02x:%02x:%02x", | |
110 | (uint8_t)zl3vni->svi_if->hw_addr[0], | |
111 | (uint8_t)zl3vni->svi_if->hw_addr[1], | |
112 | (uint8_t)zl3vni->svi_if->hw_addr[2], | |
113 | (uint8_t)zl3vni->svi_if->hw_addr[3], | |
114 | (uint8_t)zl3vni->svi_if->hw_addr[4], | |
115 | (uint8_t)zl3vni->svi_if->hw_addr[5]); | |
116 | else | |
117 | snprintf(ptr, ETHER_ADDR_STRLEN, "None"); | |
118 | ||
119 | return ptr; | |
120 | } | |
121 | ||
122 | /* get the sys mac string */ | |
05843a27 DS |
123 | static inline const char *zl3vni_sysmac2str(struct zebra_l3vni *zl3vni, |
124 | char *buf, int size) | |
28ad0501 CS |
125 | { |
126 | char *ptr; | |
127 | ||
128 | if (!buf) | |
8264e9b7 | 129 | ptr = XMALLOC(MTYPE_TMP, ETHER_ADDR_STRLEN * sizeof(char)); |
28ad0501 CS |
130 | else { |
131 | assert(size >= ETHER_ADDR_STRLEN); | |
132 | ptr = buf; | |
133 | } | |
134 | ||
b7cfce93 MK |
135 | if (zl3vni->svi_if) |
136 | snprintf(ptr, (ETHER_ADDR_STRLEN), | |
137 | "%02x:%02x:%02x:%02x:%02x:%02x", | |
138 | (uint8_t)zl3vni->svi_if->hw_addr[0], | |
139 | (uint8_t)zl3vni->svi_if->hw_addr[1], | |
140 | (uint8_t)zl3vni->svi_if->hw_addr[2], | |
141 | (uint8_t)zl3vni->svi_if->hw_addr[3], | |
142 | (uint8_t)zl3vni->svi_if->hw_addr[4], | |
143 | (uint8_t)zl3vni->svi_if->hw_addr[5]); | |
144 | else | |
145 | snprintf(ptr, ETHER_ADDR_STRLEN, "None"); | |
146 | ||
147 | return ptr; | |
148 | } | |
149 | ||
150 | /* | |
151 | * l3-vni is oper up when: | |
655b04d1 | 152 | * 0. if EVPN is enabled (advertise-all-vni cfged) |
b7cfce93 MK |
153 | * 1. it is associated to a vxlan-intf |
154 | * 2. Associated vxlan-intf is oper up | |
155 | * 3. it is associated to an SVI | |
156 | * 4. associated SVI is oper up | |
157 | */ | |
05843a27 | 158 | static inline int is_l3vni_oper_up(struct zebra_l3vni *zl3vni) |
b7cfce93 | 159 | { |
996c9314 LB |
160 | return (is_evpn_enabled() && zl3vni && (zl3vni->vrf_id != VRF_UNKNOWN) |
161 | && zl3vni->vxlan_if && if_is_operative(zl3vni->vxlan_if) | |
162 | && zl3vni->svi_if && if_is_operative(zl3vni->svi_if)); | |
b7cfce93 MK |
163 | } |
164 | ||
05843a27 | 165 | static inline const char *zl3vni_state2str(struct zebra_l3vni *zl3vni) |
b7cfce93 MK |
166 | { |
167 | if (!zl3vni) | |
168 | return NULL; | |
169 | ||
170 | if (is_l3vni_oper_up(zl3vni)) | |
171 | return "Up"; | |
172 | else | |
173 | return "Down"; | |
174 | ||
175 | return NULL; | |
176 | } | |
177 | ||
05843a27 | 178 | static inline vrf_id_t zl3vni_vrf_id(struct zebra_l3vni *zl3vni) |
b7cfce93 MK |
179 | { |
180 | return zl3vni->vrf_id; | |
181 | } | |
182 | ||
05843a27 | 183 | static inline void zl3vni_get_svi_rmac(struct zebra_l3vni *zl3vni, |
06d9cde5 | 184 | struct ethaddr *rmac) |
b7cfce93 MK |
185 | { |
186 | if (!zl3vni) | |
187 | return; | |
188 | ||
189 | if (!is_l3vni_oper_up(zl3vni)) | |
190 | return; | |
191 | ||
192 | if (zl3vni->svi_if && if_is_operative(zl3vni->svi_if)) | |
193 | memcpy(rmac->octet, zl3vni->svi_if->hw_addr, ETH_ALEN); | |
194 | } | |
195 | ||
18a7a601 | 196 | |
b7cfce93 MK |
197 | /* context for neigh hash walk - update l3vni and rmac */ |
198 | struct neigh_l3info_walk_ctx { | |
199 | ||
f6371c34 | 200 | struct zebra_evpn *zevpn; |
05843a27 | 201 | struct zebra_l3vni *zl3vni; |
b7cfce93 MK |
202 | int add; |
203 | }; | |
204 | ||
205 | struct nh_walk_ctx { | |
206 | ||
207 | struct vty *vty; | |
208 | struct json_object *json; | |
209 | }; | |
210 | ||
05843a27 DS |
211 | extern struct zebra_l3vni *zl3vni_from_vrf(vrf_id_t vrf_id); |
212 | extern struct interface *zl3vni_map_to_vxlan_if(struct zebra_l3vni *zl3vni); | |
213 | extern struct interface *zl3vni_map_to_svi_if(struct zebra_l3vni *zl3vni); | |
214 | extern struct interface *zl3vni_map_to_mac_vlan_if(struct zebra_l3vni *zl3vni); | |
215 | extern struct zebra_l3vni *zl3vni_lookup(vni_t vni); | |
1b09e77e | 216 | extern vni_t vni_id_from_svi(struct interface *ifp, struct interface *br_if); |
a780a738 | 217 | |
3198b2b3 | 218 | DECLARE_HOOK(zebra_rmac_update, |
05843a27 | 219 | (struct zebra_mac * rmac, struct zebra_l3vni *zl3vni, bool delete, |
3198b2b3 DS |
220 | const char *reason), |
221 | (rmac, zl3vni, delete, reason)); | |
a780a738 | 222 | |
9d21b7c6 | 223 | |
51e94aa7 EDP |
224 | #ifdef __cplusplus |
225 | } | |
226 | #endif | |
227 | ||
8a93734c AK |
228 | /* |
229 | * Multicast hash table. | |
230 | * | |
231 | * This table contains - | |
232 | * 1. The (S, G) entries used for encapsulating and forwarding BUM traffic. | |
233 | * S is the local VTEP-IP and G is a BUM mcast group address. | |
234 | * 2. The (X, G) entries used for terminating a BUM flow. | |
235 | * Multiple L2-VNIs can share the same MDT hence the need to maintain | |
236 | * an aggregated table that pimd can consume without much | |
237 | * re-interpretation. | |
238 | */ | |
847f168d | 239 | struct zebra_vxlan_sg { |
8a93734c AK |
240 | struct zebra_vrf *zvrf; |
241 | ||
242 | struct prefix_sg sg; | |
243 | char sg_str[PREFIX_SG_STR_LEN]; | |
244 | ||
245 | /* For SG - num of L2 VNIs using this entry for sending BUM traffic */ | |
246 | /* For XG - num of SG using this as parent */ | |
247 | uint32_t ref_cnt; | |
847f168d | 248 | }; |
8a93734c | 249 | |
f6371c34 | 250 | extern struct zebra_evpn *zevpn_lookup(vni_t vni); |
3198b2b3 DS |
251 | extern void zebra_vxlan_sync_mac_dp_install(struct zebra_mac *mac, |
252 | bool set_inactive, | |
253 | bool force_clear_static, | |
254 | const char *caller); | |
b2ee2b71 | 255 | extern bool zebra_evpn_do_dup_addr_detect(struct zebra_vrf *zvrf); |
784d88aa SR |
256 | extern void zebra_vxlan_sg_ref(struct in_addr local_vtep_ip, |
257 | struct in_addr mcast_grp); | |
258 | extern void zebra_vxlan_sg_deref(struct in_addr local_vtep_ip, | |
259 | struct in_addr mcast_grp); | |
260 | extern void zebra_vxlan_process_l3vni_oper_up(struct zebra_l3vni *zl3vni); | |
261 | extern void zebra_vxlan_process_l3vni_oper_down(struct zebra_l3vni *zl3vni); | |
0adeb5fd | 262 | extern int zebra_evpn_vxlan_del(struct zebra_evpn *zevpn); |
ce5160c0 | 263 | |
18a7a601 | 264 | #endif /* _ZEBRA_VXLAN_PRIVATE_H */ |