Line data Source code
1 : /*
2 : * Zebra EVPN MAC Data structures and definitions
3 : * These are "internal" to this function.
4 : * Copyright (C) 2016, 2017 Cumulus Networks, Inc.
5 : * Copyright (C) 2020 Volta Networks.
6 : *
7 : * This file is part of FRR.
8 : *
9 : * FRR is free software; you can redistribute it and/or modify it
10 : * under the terms of the GNU General Public License as published by the
11 : * Free Software Foundation; either version 2, or (at your option) any
12 : * later version.
13 : *
14 : * FRR is distributed in the hope that it will be useful, but
15 : * WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : * General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with FRR; see the file COPYING. If not, write to the Free
21 : * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22 : * 02111-1307, USA.
23 : */
24 :
25 : #ifndef _ZEBRA_EVPN_MAC_H
26 : #define _ZEBRA_EVPN_MAC_H
27 :
28 : #ifdef __cplusplus
29 : extern "C" {
30 : #endif
31 :
32 :
33 : struct host_rb_entry {
34 : RB_ENTRY(host_rb_entry) hl_entry;
35 :
36 : struct prefix p;
37 : };
38 :
39 : RB_HEAD(host_rb_tree_entry, host_rb_entry);
40 0 : RB_PROTOTYPE(host_rb_tree_entry, host_rb_entry, hl_entry,
41 : host_rb_entry_compare);
42 : /*
43 : * MAC hash table.
44 : *
45 : * This table contains the MAC addresses pertaining to this VNI.
46 : * This includes local MACs learnt on an attached VLAN that maps
47 : * to this VNI as well as remote MACs learnt and installed by BGP.
48 : * Local MACs will be known either on a VLAN sub-interface or
49 : * on (port, VLAN); however, it is sufficient for zebra to maintain
50 : * against the VNI i.e., it does not need to retain the local "port"
51 : * information. The correct VNI will be obtained as zebra maintains
52 : * the mapping (of VLAN to VNI).
53 : */
54 : struct zebra_mac {
55 : /* MAC address. */
56 : struct ethaddr macaddr;
57 :
58 : /* When modifying flags please fixup zebra_evpn_zebra_mac_flag_dump */
59 : uint32_t flags;
60 : #define ZEBRA_MAC_LOCAL 0x01
61 : #define ZEBRA_MAC_REMOTE 0x02
62 : #define ZEBRA_MAC_AUTO 0x04 /* Auto created for neighbor. */
63 : #define ZEBRA_MAC_STICKY 0x08 /* Static MAC */
64 : #define ZEBRA_MAC_REMOTE_RMAC 0x10 /* remote router mac */
65 : #define ZEBRA_MAC_DEF_GW 0x20
66 : /* remote VTEP advertised MAC as default GW */
67 : #define ZEBRA_MAC_REMOTE_DEF_GW 0x40
68 : #define ZEBRA_MAC_DUPLICATE 0x80
69 : #define ZEBRA_MAC_FPM_SENT 0x100 /* whether or not this entry was sent. */
70 : /* MAC is locally active on an ethernet segment peer */
71 : #define ZEBRA_MAC_ES_PEER_ACTIVE 0x200
72 : /* MAC has been proxy-advertised by peers. This means we need to
73 : * keep the entry for forwarding but cannot advertise it
74 : */
75 : #define ZEBRA_MAC_ES_PEER_PROXY 0x400
76 : /* We have not been able to independently establish that the host is
77 : * local connected but one or more ES peers claims it is.
78 : * We will maintain the entry for forwarding purposes and continue
79 : * to advertise it as locally attached but with a "proxy" flag
80 : */
81 : #define ZEBRA_MAC_LOCAL_INACTIVE 0x800
82 : /* The MAC entry was created because of advertise_svi_mac */
83 : #define ZEBRA_MAC_SVI 0x1000
84 :
85 : #define ZEBRA_MAC_ALL_LOCAL_FLAGS (ZEBRA_MAC_LOCAL | ZEBRA_MAC_LOCAL_INACTIVE)
86 : #define ZEBRA_MAC_ALL_PEER_FLAGS \
87 : (ZEBRA_MAC_ES_PEER_PROXY | ZEBRA_MAC_ES_PEER_ACTIVE)
88 :
89 : /* back pointer to zevpn */
90 : struct zebra_evpn *zevpn;
91 :
92 : /* Local or remote info.
93 : * Note: fwd_info is only relevant if mac->es is NULL.
94 : */
95 : union {
96 : struct {
97 : ifindex_t ifindex;
98 : ns_id_t ns_id;
99 : vlanid_t vid;
100 : } local;
101 :
102 : struct in_addr r_vtep_ip;
103 : } fwd_info;
104 :
105 : /* Local or remote ES */
106 : struct zebra_evpn_es *es;
107 : /* memory used to link the mac to the es */
108 : struct listnode es_listnode;
109 :
110 : /* access-port/bridge member. only relevant for local macs that
111 : * are associated with a zero-ESI,
112 : * XXX - this belongs in fwd_info.local; however fwd_info is
113 : * being cleared and memset to zero in different ways that can
114 : * mess up the links.
115 : */
116 : struct interface *ifp;
117 : /* memory used to link the mac to the ifp */
118 : struct listnode ifp_listnode;
119 :
120 : /* Mobility sequence numbers associated with this entry. */
121 : uint32_t rem_seq;
122 : uint32_t loc_seq;
123 :
124 : /* List of neigh associated with this mac */
125 : struct list *neigh_list;
126 :
127 : /* List of nexthop associated with this RMAC */
128 : struct list *nh_list;
129 :
130 : /* Duplicate mac detection */
131 : uint32_t dad_count;
132 :
133 : struct thread *dad_mac_auto_recovery_timer;
134 :
135 : struct timeval detect_start_time;
136 :
137 : time_t dad_dup_detect_time;
138 :
139 : /* used for ageing out the PEER_ACTIVE flag */
140 : struct thread *hold_timer;
141 :
142 : /* number of neigh entries (using this mac) that have
143 : * ZEBRA_MAC_ES_PEER_ACTIVE or ZEBRA_NEIGH_ES_PEER_PROXY
144 : */
145 : uint32_t sync_neigh_cnt;
146 :
147 : time_t uptime;
148 : };
149 :
150 : /*
151 : * Context for MAC hash walk - used by callbacks.
152 : */
153 : struct mac_walk_ctx {
154 : struct zebra_evpn *zevpn; /* EVPN hash */
155 : struct zebra_vrf *zvrf; /* VRF - for client notification. */
156 : int uninstall; /* uninstall from kernel? */
157 : int upd_client; /* uninstall from client? */
158 :
159 : uint32_t flags;
160 : #define DEL_LOCAL_MAC 0x1
161 : #define DEL_REMOTE_MAC 0x2
162 : #define DEL_ALL_MAC (DEL_LOCAL_MAC | DEL_REMOTE_MAC)
163 : #define DEL_REMOTE_MAC_FROM_VTEP 0x4
164 : #define SHOW_REMOTE_MAC_FROM_VTEP 0x8
165 :
166 : struct in_addr r_vtep_ip; /* To walk MACs from specific VTEP */
167 :
168 : struct vty *vty; /* Used by VTY handlers */
169 : uint32_t count; /* Used by VTY handlers */
170 : struct json_object *json; /* Used for JSON Output */
171 : bool print_dup; /* Used to print dup addr list */
172 : };
173 :
174 : struct rmac_walk_ctx {
175 : struct vty *vty;
176 : struct json_object *json;
177 : };
178 :
179 : /**************************** SYNC MAC handling *****************************/
180 : /* if the mac has been added of a mac-route from the peer
181 : * or if it is being referenced by a neigh added by the
182 : * peer we cannot let it age out i.e. we set the static bit
183 : * in the dataplane
184 : */
185 0 : static inline bool zebra_evpn_mac_is_static(struct zebra_mac *mac)
186 : {
187 0 : return ((mac->flags & ZEBRA_MAC_ALL_PEER_FLAGS) || mac->sync_neigh_cnt);
188 : }
189 :
190 : /* mac needs to be locally active or active on an ES peer */
191 0 : static inline bool zebra_evpn_mac_is_ready_for_bgp(uint32_t flags)
192 : {
193 0 : return (flags & ZEBRA_MAC_LOCAL)
194 0 : && (!(flags & ZEBRA_MAC_LOCAL_INACTIVE)
195 0 : || (flags & ZEBRA_MAC_ES_PEER_ACTIVE));
196 : }
197 :
198 : void zebra_evpn_mac_stop_hold_timer(struct zebra_mac *mac);
199 :
200 0 : static inline void zebra_evpn_mac_clear_sync_info(struct zebra_mac *mac)
201 : {
202 0 : UNSET_FLAG(mac->flags, ZEBRA_MAC_ALL_PEER_FLAGS);
203 0 : zebra_evpn_mac_stop_hold_timer(mac);
204 : }
205 :
206 0 : static inline bool zebra_evpn_mac_in_use(struct zebra_mac *mac)
207 : {
208 0 : return !list_isempty(mac->neigh_list)
209 0 : || CHECK_FLAG(mac->flags, ZEBRA_MAC_SVI);
210 : }
211 :
212 : struct hash *zebra_mac_db_create(const char *desc);
213 : uint32_t num_valid_macs(struct zebra_evpn *zevi);
214 : uint32_t num_dup_detected_macs(struct zebra_evpn *zevi);
215 : int zebra_evpn_rem_mac_uninstall(struct zebra_evpn *zevi, struct zebra_mac *mac,
216 : bool force);
217 : int zebra_evpn_rem_mac_install(struct zebra_evpn *zevi, struct zebra_mac *mac,
218 : bool was_static);
219 : void zebra_evpn_deref_ip2mac(struct zebra_evpn *zevi, struct zebra_mac *mac);
220 : struct zebra_mac *zebra_evpn_mac_lookup(struct zebra_evpn *zevi,
221 : const struct ethaddr *mac);
222 : struct zebra_mac *zebra_evpn_mac_add(struct zebra_evpn *zevi,
223 : const struct ethaddr *macaddr);
224 : struct zebra_mac *zebra_evpn_mac_add_auto(struct zebra_evpn *zevi,
225 : const struct ethaddr *macaddr);
226 : int zebra_evpn_mac_del(struct zebra_evpn *zevi, struct zebra_mac *mac);
227 : int zebra_evpn_macip_send_msg_to_client(uint32_t id,
228 : const struct ethaddr *macaddr,
229 : const struct ipaddr *ip, uint8_t flags,
230 : uint32_t seq, int state,
231 : struct zebra_evpn_es *es, uint16_t cmd);
232 : void zebra_evpn_print_mac(struct zebra_mac *mac, void *ctxt, json_object *json);
233 : void zebra_evpn_print_mac_hash(struct hash_bucket *bucket, void *ctxt);
234 : void zebra_evpn_print_mac_hash_detail(struct hash_bucket *bucket, void *ctxt);
235 : int zebra_evpn_sync_mac_dp_install(struct zebra_mac *mac, bool set_inactive,
236 : bool force_clear_static, const char *caller);
237 : void zebra_evpn_mac_send_add_del_to_client(struct zebra_mac *mac,
238 : bool old_bgp_ready,
239 : bool new_bgp_ready);
240 :
241 : void zebra_evpn_mac_del_all(struct zebra_evpn *zevi, int uninstall,
242 : int upd_client, uint32_t flags);
243 : int zebra_evpn_mac_send_add_to_client(vni_t vni, const struct ethaddr *macaddr,
244 : uint32_t mac_flags, uint32_t seq,
245 : struct zebra_evpn_es *es);
246 : int zebra_evpn_mac_send_del_to_client(vni_t vni, const struct ethaddr *macaddr,
247 : uint32_t flags, bool force);
248 : void zebra_evpn_send_mac_list_to_client(struct zebra_evpn *zevi);
249 : struct zebra_mac *zebra_evpn_proc_sync_mac_update(struct zebra_evpn *zevi,
250 : const struct ethaddr *macaddr,
251 : uint16_t ipa_len,
252 : const struct ipaddr *ipaddr,
253 : uint8_t flags, uint32_t seq,
254 : const esi_t *esi);
255 : void zebra_evpn_sync_mac_del(struct zebra_mac *mac);
256 : void zebra_evpn_rem_mac_del(struct zebra_evpn *zevi, struct zebra_mac *mac);
257 : void zebra_evpn_print_dad_mac_hash(struct hash_bucket *bucket, void *ctxt);
258 : void zebra_evpn_print_dad_mac_hash_detail(struct hash_bucket *bucket,
259 : void *ctxt);
260 : int zebra_evpn_mac_remote_macip_add(struct zebra_evpn *zevpn,
261 : struct zebra_vrf *zvrf,
262 : const struct ethaddr *macaddr,
263 : struct in_addr vtep_ip, uint8_t flags,
264 : uint32_t seq, const esi_t *esi);
265 :
266 : int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf,
267 : struct zebra_evpn *zevpn,
268 : struct interface *ifp,
269 : const struct ethaddr *macaddr, vlanid_t vid,
270 : bool sticky, bool local_inactive,
271 : bool dp_static, struct zebra_mac *mac);
272 : int zebra_evpn_del_local_mac(struct zebra_evpn *zevpn, struct zebra_mac *mac,
273 : bool clear_static);
274 : void zebra_evpn_mac_gw_macip_add(struct interface *ifp,
275 : struct zebra_evpn *zevpn,
276 : const struct ipaddr *ip,
277 : struct zebra_mac **macp,
278 : const struct ethaddr *macaddr,
279 : vlanid_t vlan_id, bool def_gw);
280 : void zebra_evpn_mac_svi_add(struct interface *ifp, struct zebra_evpn *zevpn);
281 : void zebra_evpn_mac_svi_del(struct interface *ifp, struct zebra_evpn *zevpn);
282 : void zebra_evpn_mac_ifp_del(struct interface *ifp);
283 : void zebra_evpn_mac_clear_fwd_info(struct zebra_mac *zmac);
284 :
285 : #ifdef __cplusplus
286 : }
287 : #endif
288 :
289 : #endif /*_ZEBRA_EVPN_MAC_H */
|