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