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