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