Line data Source code
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 : #include "zebra_evpn.h"
33 : #include "zebra_evpn_mac.h"
34 :
35 : #ifdef __cplusplus
36 : extern "C" {
37 : #endif
38 :
39 : #define ERR_STR_SZ 256
40 :
41 : /* L3 VNI hash table */
42 : struct zebra_l3vni {
43 :
44 : /* VNI key */
45 : vni_t vni;
46 :
47 : /* vrf_id */
48 : vrf_id_t vrf_id;
49 :
50 : uint32_t filter;
51 : #define PREFIX_ROUTES_ONLY (1 << 0) /* l3-vni used for prefix routes only */
52 :
53 : /* Local IP */
54 : struct in_addr local_vtep_ip;
55 :
56 : /* kernel interface for l3vni */
57 : struct interface *vxlan_if;
58 :
59 : /* SVI interface corresponding to the l3vni */
60 : struct interface *svi_if;
61 :
62 : struct interface *mac_vlan_if;
63 :
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 */
75 0 : static inline const char *zl3vni_vxlan_if_name(struct zebra_l3vni *zl3vni)
76 : {
77 0 : return zl3vni->vxlan_if ? zl3vni->vxlan_if->name : "None";
78 : }
79 :
80 : /* get the svi intf name for l3vni */
81 0 : static inline const char *zl3vni_svi_if_name(struct zebra_l3vni *zl3vni)
82 : {
83 0 : return zl3vni->svi_if ? zl3vni->svi_if->name : "None";
84 : }
85 :
86 : /* get the vrf name for l3vni */
87 0 : static inline const char *zl3vni_vrf_name(struct zebra_l3vni *zl3vni)
88 : {
89 0 : return vrf_id_to_name(zl3vni->vrf_id);
90 : }
91 :
92 : /* get the rmac string */
93 0 : static inline const char *zl3vni_rmac2str(struct zebra_l3vni *zl3vni, char *buf,
94 : int size)
95 : {
96 0 : char *ptr;
97 :
98 0 : if (!buf)
99 0 : ptr = XMALLOC(MTYPE_TMP, ETHER_ADDR_STRLEN * sizeof(char));
100 : else {
101 0 : assert(size >= ETHER_ADDR_STRLEN);
102 : ptr = buf;
103 : }
104 :
105 0 : if (zl3vni->mac_vlan_if)
106 0 : snprintf(ptr, (ETHER_ADDR_STRLEN),
107 : "%02x:%02x:%02x:%02x:%02x:%02x",
108 0 : (uint8_t)zl3vni->mac_vlan_if->hw_addr[0],
109 0 : (uint8_t)zl3vni->mac_vlan_if->hw_addr[1],
110 0 : (uint8_t)zl3vni->mac_vlan_if->hw_addr[2],
111 0 : (uint8_t)zl3vni->mac_vlan_if->hw_addr[3],
112 0 : (uint8_t)zl3vni->mac_vlan_if->hw_addr[4],
113 0 : (uint8_t)zl3vni->mac_vlan_if->hw_addr[5]);
114 0 : else if (zl3vni->svi_if)
115 0 : snprintf(ptr, (ETHER_ADDR_STRLEN),
116 : "%02x:%02x:%02x:%02x:%02x:%02x",
117 0 : (uint8_t)zl3vni->svi_if->hw_addr[0],
118 0 : (uint8_t)zl3vni->svi_if->hw_addr[1],
119 0 : (uint8_t)zl3vni->svi_if->hw_addr[2],
120 0 : (uint8_t)zl3vni->svi_if->hw_addr[3],
121 0 : (uint8_t)zl3vni->svi_if->hw_addr[4],
122 0 : (uint8_t)zl3vni->svi_if->hw_addr[5]);
123 : else
124 0 : snprintf(ptr, ETHER_ADDR_STRLEN, "None");
125 :
126 0 : return ptr;
127 : }
128 :
129 : /* get the sys mac string */
130 0 : static inline const char *zl3vni_sysmac2str(struct zebra_l3vni *zl3vni,
131 : char *buf, int size)
132 : {
133 0 : char *ptr;
134 :
135 0 : if (!buf)
136 0 : ptr = XMALLOC(MTYPE_TMP, ETHER_ADDR_STRLEN * sizeof(char));
137 : else {
138 0 : assert(size >= ETHER_ADDR_STRLEN);
139 : ptr = buf;
140 : }
141 :
142 0 : if (zl3vni->svi_if)
143 0 : snprintf(ptr, (ETHER_ADDR_STRLEN),
144 : "%02x:%02x:%02x:%02x:%02x:%02x",
145 0 : (uint8_t)zl3vni->svi_if->hw_addr[0],
146 0 : (uint8_t)zl3vni->svi_if->hw_addr[1],
147 0 : (uint8_t)zl3vni->svi_if->hw_addr[2],
148 0 : (uint8_t)zl3vni->svi_if->hw_addr[3],
149 0 : (uint8_t)zl3vni->svi_if->hw_addr[4],
150 0 : (uint8_t)zl3vni->svi_if->hw_addr[5]);
151 : else
152 0 : snprintf(ptr, ETHER_ADDR_STRLEN, "None");
153 :
154 0 : return ptr;
155 : }
156 :
157 : /*
158 : * l3-vni is oper up when:
159 : * 0. if EVPN is enabled (advertise-all-vni cfged)
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 : */
165 0 : static inline int is_l3vni_oper_up(struct zebra_l3vni *zl3vni)
166 : {
167 0 : return (is_evpn_enabled() && zl3vni && (zl3vni->vrf_id != VRF_UNKNOWN)
168 0 : && zl3vni->vxlan_if && if_is_operative(zl3vni->vxlan_if)
169 0 : && zl3vni->svi_if && if_is_operative(zl3vni->svi_if));
170 : }
171 :
172 0 : static inline const char *zl3vni_state2str(struct zebra_l3vni *zl3vni)
173 : {
174 0 : if (!zl3vni)
175 : return NULL;
176 :
177 0 : if (is_l3vni_oper_up(zl3vni))
178 : return "Up";
179 : else
180 0 : return "Down";
181 :
182 : return NULL;
183 : }
184 :
185 0 : static inline vrf_id_t zl3vni_vrf_id(struct zebra_l3vni *zl3vni)
186 : {
187 0 : return zl3vni->vrf_id;
188 : }
189 :
190 0 : static inline void zl3vni_get_svi_rmac(struct zebra_l3vni *zl3vni,
191 : struct ethaddr *rmac)
192 : {
193 0 : if (!zl3vni)
194 : return;
195 :
196 0 : if (!is_l3vni_oper_up(zl3vni))
197 : return;
198 :
199 0 : if (zl3vni->svi_if && if_is_operative(zl3vni->svi_if))
200 0 : memcpy(rmac->octet, zl3vni->svi_if->hw_addr, ETH_ALEN);
201 : }
202 :
203 :
204 : /* context for neigh hash walk - update l3vni and rmac */
205 : struct neigh_l3info_walk_ctx {
206 :
207 : struct zebra_evpn *zevpn;
208 : struct zebra_l3vni *zl3vni;
209 : int add;
210 : };
211 :
212 : struct nh_walk_ctx {
213 :
214 : struct vty *vty;
215 : struct json_object *json;
216 : };
217 :
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);
223 : extern vni_t vni_id_from_svi(struct interface *ifp, struct interface *br_if);
224 :
225 : DECLARE_HOOK(zebra_rmac_update,
226 : (struct zebra_mac * rmac, struct zebra_l3vni *zl3vni, bool delete,
227 : const char *reason),
228 : (rmac, zl3vni, delete, reason));
229 :
230 :
231 : #ifdef __cplusplus
232 : }
233 : #endif
234 :
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 : */
246 : struct zebra_vxlan_sg {
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;
255 : };
256 :
257 : extern struct zebra_evpn *zevpn_lookup(vni_t vni);
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);
262 : extern bool zebra_evpn_do_dup_addr_detect(struct zebra_vrf *zvrf);
263 :
264 : #endif /* _ZEBRA_VXLAN_PRIVATE_H */
|