/src/frr/zebra/zebra_evpn_neigh.h
Line  | Count  | Source  | 
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 */  |