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