/src/frr/zebra/zebra_evpn_neigh.h
Line | Count | Source (jump to first uncovered line) |
1 | | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | | /* |
3 | | * Zebra EVPN Neighbor 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_NEIGH_H |
10 | | #define _ZEBRA_EVPN_NEIGH_H |
11 | | |
12 | | #ifdef __cplusplus |
13 | | extern "C" { |
14 | | #endif |
15 | | |
16 | 0 | #define IS_ZEBRA_NEIGH_ACTIVE(n) (n->state == ZEBRA_NEIGH_ACTIVE) |
17 | | |
18 | 0 | #define IS_ZEBRA_NEIGH_INACTIVE(n) (n->state == ZEBRA_NEIGH_INACTIVE) |
19 | | |
20 | 0 | #define ZEBRA_NEIGH_SET_ACTIVE(n) n->state = ZEBRA_NEIGH_ACTIVE |
21 | | |
22 | 0 | #define ZEBRA_NEIGH_SET_INACTIVE(n) n->state = ZEBRA_NEIGH_INACTIVE |
23 | | |
24 | | /* |
25 | | * Neighbor hash table. |
26 | | * |
27 | | * This table contains the neighbors (IP to MAC bindings) pertaining to |
28 | | * this VNI. This includes local neighbors learnt on the attached VLAN |
29 | | * device that maps to this VNI as well as remote neighbors learnt and |
30 | | * installed by BGP. |
31 | | * Local neighbors will be known against the VLAN device (SVI); however, |
32 | | * it is sufficient for zebra to maintain against the VNI. The correct |
33 | | * VNI will be obtained as zebra maintains the mapping (of VLAN to VNI). |
34 | | */ |
35 | | struct zebra_neigh { |
36 | | /* IP address. */ |
37 | | struct ipaddr ip; |
38 | | |
39 | | /* MAC address. */ |
40 | | struct ethaddr emac; |
41 | | |
42 | | /* Back pointer to MAC. Only applicable to hosts in a L2-VNI. */ |
43 | | struct zebra_mac *mac; |
44 | | |
45 | | /* Underlying interface. */ |
46 | | ifindex_t ifindex; |
47 | | |
48 | | struct zebra_evpn *zevpn; |
49 | | |
50 | | /* Refcnt - Only used by SVD neighs currently */ |
51 | | uint32_t refcnt; |
52 | | |
53 | | uint32_t flags; |
54 | 0 | #define ZEBRA_NEIGH_LOCAL 0x01 |
55 | 0 | #define ZEBRA_NEIGH_REMOTE 0x02 |
56 | 0 | #define ZEBRA_NEIGH_REMOTE_NH 0x04 /* neigh entry for remote vtep */ |
57 | | #define ZEBRA_NEIGH_DEF_GW 0x08 |
58 | 0 | #define ZEBRA_NEIGH_ROUTER_FLAG 0x10 |
59 | | #define ZEBRA_NEIGH_DUPLICATE 0x20 |
60 | | #define ZEBRA_NEIGH_SVI_IP 0x40 |
61 | | /* rxed from an ES peer */ |
62 | 0 | #define ZEBRA_NEIGH_ES_PEER_ACTIVE 0x80 |
63 | | /* rxed from an ES peer as a proxy advertisement */ |
64 | 0 | #define ZEBRA_NEIGH_ES_PEER_PROXY 0x100 |
65 | | /* We have not been able to independently establish that the host |
66 | | * is local connected |
67 | | */ |
68 | 0 | #define ZEBRA_NEIGH_LOCAL_INACTIVE 0x200 |
69 | | #define ZEBRA_NEIGH_ALL_LOCAL_FLAGS \ |
70 | | (ZEBRA_NEIGH_LOCAL | ZEBRA_NEIGH_LOCAL_INACTIVE) |
71 | | #define ZEBRA_NEIGH_ALL_PEER_FLAGS \ |
72 | 0 | (ZEBRA_NEIGH_ES_PEER_PROXY | ZEBRA_NEIGH_ES_PEER_ACTIVE) |
73 | | |
74 | | enum zebra_neigh_state state; |
75 | | |
76 | | /* Remote VTEP IP - applicable only for remote neighbors. */ |
77 | | struct in_addr r_vtep_ip; |
78 | | |
79 | | /* |
80 | | * Mobility sequence numbers associated with this entry. The rem_seq |
81 | | * represents the sequence number from the client (BGP) for the most |
82 | | * recent add or update of this entry while the loc_seq represents |
83 | | * the sequence number informed (or to be informed) by zebra to BGP |
84 | | * for this entry. |
85 | | */ |
86 | | uint32_t rem_seq; |
87 | | uint32_t loc_seq; |
88 | | |
89 | | /* list of hosts pointing to this remote NH entry */ |
90 | | struct host_rb_tree_entry host_rb; |
91 | | |
92 | | /* Duplicate ip detection */ |
93 | | uint32_t dad_count; |
94 | | |
95 | | struct event *dad_ip_auto_recovery_timer; |
96 | | |
97 | | struct timeval detect_start_time; |
98 | | |
99 | | time_t dad_dup_detect_time; |
100 | | |
101 | | time_t uptime; |
102 | | |
103 | | /* used for ageing out the PEER_ACTIVE flag */ |
104 | | struct event *hold_timer; |
105 | | }; |
106 | | |
107 | | /* |
108 | | * Context for neighbor hash walk - used by callbacks. |
109 | | */ |
110 | | struct neigh_walk_ctx { |
111 | | struct zebra_evpn *zevpn; /* VNI hash */ |
112 | | struct zebra_vrf *zvrf; /* VRF - for client notification. */ |
113 | | int uninstall; /* uninstall from kernel? */ |
114 | | int upd_client; /* uninstall from client? */ |
115 | | |
116 | | uint32_t flags; |
117 | 0 | #define DEL_LOCAL_NEIGH 0x1 |
118 | 0 | #define DEL_REMOTE_NEIGH 0x2 |
119 | 0 | #define DEL_ALL_NEIGH (DEL_LOCAL_NEIGH | DEL_REMOTE_NEIGH) |
120 | 0 | #define DEL_REMOTE_NEIGH_FROM_VTEP 0x4 |
121 | 0 | #define SHOW_REMOTE_NEIGH_FROM_VTEP 0x8 |
122 | | |
123 | | struct in_addr r_vtep_ip; /* To walk neighbors from specific VTEP */ |
124 | | |
125 | | struct vty *vty; /* Used by VTY handlers */ |
126 | | uint32_t count; /* Used by VTY handlers */ |
127 | | uint8_t addr_width; /* Used by VTY handlers */ |
128 | | struct json_object *json; /* Used for JSON Output */ |
129 | | }; |
130 | | |
131 | | /**************************** SYNC neigh handling **************************/ |
132 | | static inline bool zebra_evpn_neigh_is_static(struct zebra_neigh *neigh) |
133 | 0 | { |
134 | 0 | return !!(neigh->flags & ZEBRA_NEIGH_ALL_PEER_FLAGS); |
135 | 0 | } Unexecuted instantiation: zebra_l2_bridge_if.c:zebra_evpn_neigh_is_static Unexecuted instantiation: zebra_evpn.c:zebra_evpn_neigh_is_static Unexecuted instantiation: zebra_evpn_mac.c:zebra_evpn_neigh_is_static Unexecuted instantiation: zebra_evpn_neigh.c:zebra_evpn_neigh_is_static Unexecuted instantiation: zebra_vxlan.c:zebra_evpn_neigh_is_static Unexecuted instantiation: zebra_vxlan_if.c:zebra_evpn_neigh_is_static |
136 | | |
137 | | static inline bool zebra_evpn_neigh_is_ready_for_bgp(struct zebra_neigh *n) |
138 | 0 | { |
139 | 0 | bool mac_ready; |
140 | 0 | bool neigh_ready; |
141 | |
|
142 | 0 | mac_ready = !!(n->mac->flags & ZEBRA_MAC_LOCAL); |
143 | 0 | neigh_ready = |
144 | 0 | ((n->flags & ZEBRA_NEIGH_LOCAL) && IS_ZEBRA_NEIGH_ACTIVE(n) |
145 | 0 | && (!(n->flags & ZEBRA_NEIGH_LOCAL_INACTIVE) |
146 | 0 | || (n->flags & ZEBRA_NEIGH_ES_PEER_ACTIVE))) |
147 | 0 | ? true |
148 | 0 | : false; |
149 | |
|
150 | 0 | return mac_ready && neigh_ready; |
151 | 0 | } Unexecuted instantiation: zebra_l2_bridge_if.c:zebra_evpn_neigh_is_ready_for_bgp Unexecuted instantiation: zebra_evpn.c:zebra_evpn_neigh_is_ready_for_bgp Unexecuted instantiation: zebra_evpn_mac.c:zebra_evpn_neigh_is_ready_for_bgp Unexecuted instantiation: zebra_evpn_neigh.c:zebra_evpn_neigh_is_ready_for_bgp Unexecuted instantiation: zebra_vxlan.c:zebra_evpn_neigh_is_ready_for_bgp Unexecuted instantiation: zebra_vxlan_if.c:zebra_evpn_neigh_is_ready_for_bgp |
152 | | |
153 | | static inline void zebra_evpn_neigh_stop_hold_timer(struct zebra_neigh *n) |
154 | 0 | { |
155 | 0 | if (!n->hold_timer) |
156 | 0 | return; |
157 | | |
158 | 0 | if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH) |
159 | 0 | zlog_debug("sync-neigh vni %u ip %pIA mac %pEA 0x%x hold stop", |
160 | 0 | n->zevpn->vni, &n->ip, &n->emac, n->flags); |
161 | 0 | EVENT_OFF(n->hold_timer); |
162 | 0 | } Unexecuted instantiation: zebra_l2_bridge_if.c:zebra_evpn_neigh_stop_hold_timer Unexecuted instantiation: zebra_evpn.c:zebra_evpn_neigh_stop_hold_timer Unexecuted instantiation: zebra_evpn_mac.c:zebra_evpn_neigh_stop_hold_timer Unexecuted instantiation: zebra_evpn_neigh.c:zebra_evpn_neigh_stop_hold_timer Unexecuted instantiation: zebra_vxlan.c:zebra_evpn_neigh_stop_hold_timer Unexecuted instantiation: zebra_vxlan_if.c:zebra_evpn_neigh_stop_hold_timer |
163 | | |
164 | | void zebra_evpn_sync_neigh_static_chg(struct zebra_neigh *n, bool old_n_static, |
165 | | bool new_n_static, bool defer_n_dp, |
166 | | bool defer_mac_dp, const char *caller); |
167 | | |
168 | | static inline bool zebra_evpn_neigh_clear_sync_info(struct zebra_neigh *n) |
169 | 0 | { |
170 | 0 | bool old_n_static = false; |
171 | 0 | bool new_n_static = false; |
172 | |
|
173 | 0 | if (n->flags & ZEBRA_NEIGH_ALL_PEER_FLAGS) { |
174 | 0 | if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH) |
175 | 0 | zlog_debug("sync-neigh vni %u ip %pIA mac %pEA 0x%x clear", |
176 | 0 | n->zevpn->vni, &n->ip, &n->emac, n->flags); |
177 | |
|
178 | 0 | old_n_static = zebra_evpn_neigh_is_static(n); |
179 | 0 | UNSET_FLAG(n->flags, ZEBRA_NEIGH_ALL_PEER_FLAGS); |
180 | 0 | new_n_static = zebra_evpn_neigh_is_static(n); |
181 | 0 | if (old_n_static != new_n_static) |
182 | 0 | zebra_evpn_sync_neigh_static_chg( |
183 | 0 | n, old_n_static, new_n_static, |
184 | 0 | true /*defer_dp)*/, false /*defer_mac_dp*/, |
185 | 0 | __func__); |
186 | 0 | } |
187 | 0 | zebra_evpn_neigh_stop_hold_timer(n); |
188 | | |
189 | | /* if the neigh static flag changed inform that a dp |
190 | | * re-install maybe needed |
191 | | */ |
192 | 0 | return old_n_static != new_n_static; |
193 | 0 | } Unexecuted instantiation: zebra_l2_bridge_if.c:zebra_evpn_neigh_clear_sync_info Unexecuted instantiation: zebra_evpn.c:zebra_evpn_neigh_clear_sync_info Unexecuted instantiation: zebra_evpn_mac.c:zebra_evpn_neigh_clear_sync_info Unexecuted instantiation: zebra_evpn_neigh.c:zebra_evpn_neigh_clear_sync_info Unexecuted instantiation: zebra_vxlan.c:zebra_evpn_neigh_clear_sync_info Unexecuted instantiation: zebra_vxlan_if.c:zebra_evpn_neigh_clear_sync_info |
194 | | |
195 | | int remote_neigh_count(struct zebra_mac *zmac); |
196 | | |
197 | | int neigh_list_cmp(void *p1, void *p2); |
198 | | struct hash *zebra_neigh_db_create(const char *desc); |
199 | | uint32_t num_dup_detected_neighs(struct zebra_evpn *zevpn); |
200 | | void zebra_evpn_find_neigh_addr_width(struct hash_bucket *bucket, void *ctxt); |
201 | | int remote_neigh_count(struct zebra_mac *zmac); |
202 | | int zebra_evpn_rem_neigh_install(struct zebra_evpn *zevpn, |
203 | | struct zebra_neigh *n, bool was_static); |
204 | | void zebra_evpn_install_neigh_hash(struct hash_bucket *bucket, void *ctxt); |
205 | | int zebra_evpn_neigh_send_add_to_client(vni_t vni, const struct ipaddr *ip, |
206 | | const struct ethaddr *macaddr, |
207 | | struct zebra_mac *zmac, |
208 | | uint32_t neigh_flags, uint32_t seq); |
209 | | int zebra_evpn_neigh_send_del_to_client(vni_t vni, struct ipaddr *ip, |
210 | | struct ethaddr *macaddr, uint32_t flags, |
211 | | int state, bool force); |
212 | | bool zebra_evpn_neigh_is_bgp_seq_ok(struct zebra_evpn *zevpn, |
213 | | struct zebra_neigh *n, |
214 | | const struct ethaddr *macaddr, uint32_t seq, |
215 | | bool sync); |
216 | | int zebra_evpn_neigh_del(struct zebra_evpn *zevpn, struct zebra_neigh *n); |
217 | | void zebra_evpn_sync_neigh_del(struct zebra_neigh *n); |
218 | | struct zebra_neigh *zebra_evpn_proc_sync_neigh_update( |
219 | | struct zebra_evpn *zevpn, struct zebra_neigh *n, uint16_t ipa_len, |
220 | | const struct ipaddr *ipaddr, uint8_t flags, uint32_t seq, |
221 | | const esi_t *esi, struct zebra_mac *mac); |
222 | | void zebra_evpn_neigh_del_all(struct zebra_evpn *zevpn, int uninstall, |
223 | | int upd_client, uint32_t flags); |
224 | | struct zebra_neigh *zebra_evpn_neigh_lookup(struct zebra_evpn *zevpn, |
225 | | const struct ipaddr *ip); |
226 | | |
227 | | int zebra_evpn_rem_neigh_install(struct zebra_evpn *zevpn, |
228 | | struct zebra_neigh *n, bool was_static); |
229 | | void zebra_evpn_process_neigh_on_remote_mac_add(struct zebra_evpn *zevpn, |
230 | | struct zebra_mac *zmac); |
231 | | void zebra_evpn_process_neigh_on_local_mac_del(struct zebra_evpn *zevpn, |
232 | | struct zebra_mac *zmac); |
233 | | void zebra_evpn_process_neigh_on_local_mac_change(struct zebra_evpn *zevpn, |
234 | | struct zebra_mac *zmac, |
235 | | bool seq_change, |
236 | | bool es_change); |
237 | | void zebra_evpn_process_neigh_on_remote_mac_del(struct zebra_evpn *zevpn, |
238 | | struct zebra_mac *zmac); |
239 | | int zebra_evpn_local_neigh_update(struct zebra_evpn *zevpn, |
240 | | struct interface *ifp, |
241 | | const struct ipaddr *ip, |
242 | | const struct ethaddr *macaddr, bool is_router, |
243 | | bool local_inactive, bool dp_static); |
244 | | int zebra_evpn_remote_neigh_update(struct zebra_evpn *zevpn, |
245 | | struct interface *ifp, |
246 | | const struct ipaddr *ip, |
247 | | const struct ethaddr *macaddr, |
248 | | uint16_t state); |
249 | | void zebra_evpn_send_neigh_to_client(struct zebra_evpn *zevpn); |
250 | | void zebra_evpn_clear_dup_neigh_hash(struct hash_bucket *bucket, void *ctxt); |
251 | | void zebra_evpn_print_neigh(struct zebra_neigh *n, void *ctxt, |
252 | | json_object *json); |
253 | | void zebra_evpn_print_neigh_hash(struct hash_bucket *bucket, void *ctxt); |
254 | | void zebra_evpn_print_neigh_hdr(struct vty *vty, struct neigh_walk_ctx *wctx); |
255 | | void zebra_evpn_print_neigh_hash_detail(struct hash_bucket *bucket, void *ctxt); |
256 | | void zebra_evpn_print_dad_neigh_hash(struct hash_bucket *bucket, void *ctxt); |
257 | | void zebra_evpn_print_dad_neigh_hash_detail(struct hash_bucket *bucket, |
258 | | void *ctxt); |
259 | | void zebra_evpn_neigh_remote_macip_add(struct zebra_evpn *zevpn, |
260 | | struct zebra_vrf *zvrf, |
261 | | const struct ipaddr *ipaddr, |
262 | | struct zebra_mac *mac, |
263 | | struct in_addr vtep_ip, uint8_t flags, |
264 | | uint32_t seq); |
265 | | int zebra_evpn_neigh_gw_macip_add(struct interface *ifp, |
266 | | struct zebra_evpn *zevpn, struct ipaddr *ip, |
267 | | struct zebra_mac *mac); |
268 | | void zebra_evpn_neigh_remote_uninstall(struct zebra_evpn *zevpn, |
269 | | struct zebra_vrf *zvrf, |
270 | | struct zebra_neigh *n, |
271 | | struct zebra_mac *mac, |
272 | | const struct ipaddr *ipaddr); |
273 | | int zebra_evpn_neigh_del_ip(struct zebra_evpn *zevpn, const struct ipaddr *ip); |
274 | | |
275 | | |
276 | | #ifdef __cplusplus |
277 | | } |
278 | | #endif |
279 | | |
280 | | #endif /*_ZEBRA_EVPN_NEIGH_H */ |