]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_nht.c
lib,zebra,bgpd: Fix for nexthop as IPv4 mapped IPv6 address
[mirror_frr.git] / bgpd / bgp_nht.c
CommitLineData
fb018d25
DS
1/* BGP Nexthop tracking
2 * Copyright (C) 2013 Cumulus Networks, Inc.
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
896014f4
DL
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
fb018d25
DS
19 */
20
21#include <zebra.h>
22
23#include "command.h"
24#include "thread.h"
25#include "prefix.h"
26#include "zclient.h"
27#include "stream.h"
28#include "network.h"
29#include "log.h"
30#include "memory.h"
31#include "nexthop.h"
7076bb2f 32#include "vrf.h"
039f3a34 33#include "filter.h"
fb018d25
DS
34
35#include "bgpd/bgpd.h"
36#include "bgpd/bgp_table.h"
37#include "bgpd/bgp_route.h"
38#include "bgpd/bgp_attr.h"
39#include "bgpd/bgp_nexthop.h"
40#include "bgpd/bgp_debug.h"
14454c9f 41#include "bgpd/bgp_errors.h"
fb018d25 42#include "bgpd/bgp_nht.h"
ffd0c037 43#include "bgpd/bgp_fsm.h"
afbb1c59 44#include "bgpd/bgp_zebra.h"
0378bcaa 45#include "bgpd/bgp_flowspec_util.h"
7c312383 46#include "bgpd/bgp_evpn.h"
9e15d76a 47#include "bgpd/bgp_rd.h"
fb018d25
DS
48
49extern struct zclient *zclient;
fb018d25 50
078430f6 51static void register_zebra_rnh(struct bgp_nexthop_cache *bnc,
d62a17ae 52 int is_bgp_static_route);
078430f6
DS
53static void unregister_zebra_rnh(struct bgp_nexthop_cache *bnc,
54 int is_bgp_static_route);
fb018d25 55static void evaluate_paths(struct bgp_nexthop_cache *bnc);
40381db7 56static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p);
fb018d25 57
d62a17ae 58static int bgp_isvalid_nexthop(struct bgp_nexthop_cache *bnc)
d4d9d757 59{
d62a17ae 60 return (bgp_zebra_num_connects() == 0
61 || (bnc && CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID)));
d4d9d757
LB
62}
63
960035b2
PZ
64static int bgp_isvalid_labeled_nexthop(struct bgp_nexthop_cache *bnc)
65{
66 return (bgp_zebra_num_connects() == 0
67 || (bnc && CHECK_FLAG(bnc->flags, BGP_NEXTHOP_LABELED_VALID)));
68}
69
d62a17ae 70static void bgp_unlink_nexthop_check(struct bgp_nexthop_cache *bnc)
fb018d25 71{
d5c4bac9 72 if (LIST_EMPTY(&(bnc->paths)) && !bnc->nht_info) {
d62a17ae 73 if (BGP_DEBUG(nht, NHT)) {
74 char buf[PREFIX2STR_BUFFER];
8c1a4c10
DS
75 zlog_debug("bgp_unlink_nexthop: freeing bnc %s(%s)",
76 bnc_str(bnc, buf, PREFIX2STR_BUFFER),
77 bnc->bgp->name_pretty);
d62a17ae 78 }
79 unregister_zebra_rnh(bnc,
80 CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE));
9bcb3eef
DS
81 bgp_dest_set_bgp_nexthop_info(bnc->dest, NULL);
82 bgp_dest_unlock_node(bnc->dest);
83 bnc->dest = NULL;
d62a17ae 84 bnc_free(bnc);
fb018d25 85 }
fb018d25
DS
86}
87
4b7e6066 88void bgp_unlink_nexthop(struct bgp_path_info *path)
f9164b1d 89{
d62a17ae 90 struct bgp_nexthop_cache *bnc = path->nexthop;
91
92 if (!bnc)
93 return;
f9164b1d 94
7f040da1 95 path_nh_map(path, NULL, false);
f9164b1d 96
d62a17ae 97 bgp_unlink_nexthop_check(bnc);
f9164b1d
PJ
98}
99
d62a17ae 100void bgp_unlink_nexthop_by_peer(struct peer *peer)
f9164b1d 101{
d62a17ae 102 struct prefix p;
9bcb3eef 103 struct bgp_dest *dest;
d62a17ae 104 struct bgp_nexthop_cache *bnc;
105 afi_t afi = family2afi(peer->su.sa.sa_family);
106
107 if (!sockunion2hostprefix(&peer->su, &p))
108 return;
109
9bcb3eef 110 dest = bgp_node_get(peer->bgp->nexthop_cache_table[afi], &p);
d62a17ae 111
9bcb3eef 112 bnc = bgp_dest_get_bgp_nexthop_info(dest);
14315f2d 113 if (!bnc)
d62a17ae 114 return;
115
d62a17ae 116 /* cleanup the peer reference */
117 bnc->nht_info = NULL;
118
119 bgp_unlink_nexthop_check(bnc);
f9164b1d
PJ
120}
121
960035b2
PZ
122/*
123 * A route and its nexthop might belong to different VRFs. Therefore,
124 * we need both the bgp_route and bgp_nexthop pointers.
125 */
126int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
40381db7 127 afi_t afi, struct bgp_path_info *pi,
d62a17ae 128 struct peer *peer, int connected)
fb018d25 129{
9bcb3eef 130 struct bgp_dest *dest;
d62a17ae 131 struct bgp_nexthop_cache *bnc;
132 struct prefix p;
133 int is_bgp_static_route = 0;
b54892e0 134 const struct prefix *bnc_p;
d62a17ae 135
40381db7
DS
136 if (pi) {
137 is_bgp_static_route = ((pi->type == ZEBRA_ROUTE_BGP)
138 && (pi->sub_type == BGP_ROUTE_STATIC))
d62a17ae 139 ? 1
140 : 0;
141
142 /* Since Extended Next-hop Encoding (RFC5549) support, we want
143 to derive
144 address-family from the next-hop. */
145 if (!is_bgp_static_route)
40381db7 146 afi = BGP_ATTR_NEXTHOP_AFI_IP6(pi->attr) ? AFI_IP6
d62a17ae 147 : AFI_IP;
148
92d6f769
K
149 /* Validation for the ipv4 mapped ipv6 nexthop. */
150 if (IS_MAPPED_IPV6(&pi->attr->mp_nexthop_global)) {
151 afi = AFI_IP;
152 }
153
2951a7a4 154 /* This will return true if the global IPv6 NH is a link local
d62a17ae 155 * addr */
40381db7 156 if (make_prefix(afi, pi, &p) < 0)
d62a17ae 157 return 1;
158 } else if (peer) {
d62a17ae 159 if (!sockunion2hostprefix(&peer->su, &p)) {
160 if (BGP_DEBUG(nht, NHT)) {
161 zlog_debug(
162 "%s: Attempting to register with unknown AFI %d (not %d or %d)",
15569c58 163 __func__, afi, AFI_IP, AFI_IP6);
d62a17ae 164 }
165 return 0;
166 }
167 } else
168 return 0;
169
170 if (is_bgp_static_route)
9bcb3eef 171 dest = bgp_node_get(bgp_nexthop->import_check_table[afi], &p);
d62a17ae 172 else
9bcb3eef 173 dest = bgp_node_get(bgp_nexthop->nexthop_cache_table[afi], &p);
d62a17ae 174
9bcb3eef 175 bnc = bgp_dest_get_bgp_nexthop_info(dest);
14315f2d 176 if (!bnc) {
d62a17ae 177 bnc = bnc_new();
9bcb3eef
DS
178 bgp_dest_set_bgp_nexthop_info(dest, bnc);
179 bnc->dest = dest;
960035b2 180 bnc->bgp = bgp_nexthop;
9bcb3eef 181 bgp_dest_lock_node(dest);
d62a17ae 182 if (BGP_DEBUG(nht, NHT)) {
183 char buf[PREFIX2STR_BUFFER];
184
8c1a4c10
DS
185 zlog_debug("Allocated bnc %s(%s) peer %p",
186 bnc_str(bnc, buf, PREFIX2STR_BUFFER),
187 bnc->bgp->name_pretty, peer);
d62a17ae 188 }
fc9a856f 189 }
d62a17ae 190
9bcb3eef 191 bnc_p = bgp_dest_get_prefix(bnc->dest);
b54892e0 192
9bcb3eef 193 bgp_dest_unlock_node(dest);
d62a17ae 194 if (is_bgp_static_route) {
195 SET_FLAG(bnc->flags, BGP_STATIC_ROUTE);
196
197 /* If we're toggling the type, re-register */
892fedb6 198 if ((CHECK_FLAG(bgp_route->flags, BGP_FLAG_IMPORT_CHECK))
d62a17ae 199 && !CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH)) {
200 SET_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH);
201 UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
202 UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID);
892fedb6
DA
203 } else if ((!CHECK_FLAG(bgp_route->flags,
204 BGP_FLAG_IMPORT_CHECK))
d62a17ae 205 && CHECK_FLAG(bnc->flags,
206 BGP_STATIC_ROUTE_EXACT_MATCH)) {
207 UNSET_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH);
208 UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
209 UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID);
210 }
078430f6 211 }
d62a17ae 212 /* When nexthop is already known, but now requires 'connected'
213 * resolution,
214 * re-register it. The reverse scenario where the nexthop currently
215 * requires
216 * 'connected' resolution does not need a re-register (i.e., we treat
217 * 'connected-required' as an override) except in the scenario where
218 * this
219 * is actually a case of tracking a peer for connectivity (e.g., after
220 * disable connected-check).
221 * NOTE: We don't track the number of paths separately for 'connected-
222 * required' vs 'connected-not-required' as this change is not a common
223 * scenario.
224 */
225 else if (connected && !CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED)) {
226 SET_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED);
227 UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
228 UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID);
229 } else if (peer && !connected
230 && CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED)) {
231 UNSET_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED);
232 UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
233 UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID);
078430f6 234 }
960035b2 235 if (bgp_route->inst_type == BGP_INSTANCE_TYPE_VIEW) {
1ee0a2df
DS
236 SET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
237 SET_FLAG(bnc->flags, BGP_NEXTHOP_VALID);
b54892e0
DS
238 } else if (!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED)
239 && !is_default_host_route(bnc_p))
d62a17ae 240 register_zebra_rnh(bnc, is_bgp_static_route);
1eb6c3ea 241
40381db7 242 if (pi && pi->nexthop != bnc) {
d62a17ae 243 /* Unlink from existing nexthop cache, if any. This will also
244 * free
245 * the nexthop cache entry, if appropriate.
246 */
40381db7 247 bgp_unlink_nexthop(pi);
d62a17ae 248
7f040da1
DS
249 /* updates NHT pi list reference */
250 path_nh_map(pi, bnc, true);
d62a17ae 251
252 if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID) && bnc->metric)
40381db7
DS
253 (bgp_path_info_extra_get(pi))->igpmetric = bnc->metric;
254 else if (pi->extra)
255 pi->extra->igpmetric = 0;
d62a17ae 256 } else if (peer)
257 bnc->nht_info = (void *)peer; /* NHT peer reference */
258
259 /*
260 * We are cheating here. Views have no associated underlying
261 * ability to detect nexthops. So when we have a view
262 * just tell everyone the nexthop is valid
263 */
960035b2 264 if (bgp_route->inst_type == BGP_INSTANCE_TYPE_VIEW)
d62a17ae 265 return 1;
266 else
267 return (bgp_isvalid_nexthop(bnc));
fb018d25
DS
268}
269
d62a17ae 270void bgp_delete_connected_nexthop(afi_t afi, struct peer *peer)
9a233a02 271{
9bcb3eef 272 struct bgp_dest *dest;
d62a17ae 273 struct bgp_nexthop_cache *bnc;
274 struct prefix p;
275
276 if (!peer)
277 return;
278
d62a17ae 279 if (!sockunion2hostprefix(&peer->su, &p))
280 return;
281
9bcb3eef 282 dest = bgp_node_lookup(
d62a17ae 283 peer->bgp->nexthop_cache_table[family2afi(p.family)], &p);
9bcb3eef 284 if (!dest) {
d62a17ae 285 if (BGP_DEBUG(nht, NHT))
8c1a4c10
DS
286 zlog_debug(
287 "Cannot find connected NHT node for peer %s(%s)",
288 peer->host, peer->bgp->name_pretty);
d62a17ae 289 return;
290 }
291
9bcb3eef 292 bnc = bgp_dest_get_bgp_nexthop_info(dest);
14315f2d
DS
293 if (!bnc) {
294 if (BGP_DEBUG(nht, NHT))
8c1a4c10
DS
295 zlog_debug(
296 "Cannot find connected NHT node for peer %s(%s) on route_node as expected",
297 peer->host, peer->bgp->name_pretty);
9bcb3eef 298 bgp_dest_unlock_node(dest);
14315f2d
DS
299 return;
300 }
9bcb3eef 301 bgp_dest_unlock_node(dest);
d62a17ae 302
303 if (bnc->nht_info != peer) {
304 if (BGP_DEBUG(nht, NHT))
305 zlog_debug(
8c1a4c10
DS
306 "Connected NHT %p node for peer %s(%s) points to %p",
307 bnc, peer->host, bnc->bgp->name_pretty,
308 bnc->nht_info);
d62a17ae 309 return;
310 }
311
312 bnc->nht_info = NULL;
313
314 if (LIST_EMPTY(&(bnc->paths))) {
315 if (BGP_DEBUG(nht, NHT))
8c1a4c10
DS
316 zlog_debug(
317 "Freeing connected NHT node %p for peer %s(%s)",
318 bnc, peer->host, bnc->bgp->name_pretty);
d62a17ae 319 unregister_zebra_rnh(bnc, 0);
9bcb3eef
DS
320 bgp_dest_set_bgp_nexthop_info(bnc->dest, NULL);
321 bgp_dest_unlock_node(bnc->dest);
d62a17ae 322 bnc_free(bnc);
323 }
9a233a02
DS
324}
325
d62a17ae 326void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)
fb018d25 327{
9bcb3eef 328 struct bgp_dest *dest = NULL;
d62a17ae 329 struct bgp_nexthop_cache *bnc;
330 struct nexthop *nexthop;
331 struct nexthop *oldnh;
332 struct nexthop *nhlist_head = NULL;
333 struct nexthop *nhlist_tail = NULL;
d62a17ae 334 int i;
335 struct bgp *bgp;
4a749e2c 336 struct zapi_route nhr;
d62a17ae 337
338 bgp = bgp_lookup_by_vrf_id(vrf_id);
339 if (!bgp) {
af4c2728 340 flog_err(
e50f7cfd 341 EC_BGP_NH_UPD,
a8bf7d9c 342 "parse nexthop update: instance not found for vrf_id %u",
d62a17ae 343 vrf_id);
344 return;
fb018d25 345 }
d62a17ae 346
7d30a959
DS
347 if (!zapi_nexthop_update_decode(zclient->ibuf, &nhr)) {
348 if (BGP_DEBUG(nht, NHT))
8c1a4c10 349 zlog_debug("%s[%s]: Failure to decode nexthop update",
15569c58 350 __func__, bgp->name_pretty);
7d30a959
DS
351 return;
352 }
d62a17ae 353
354 if (command == ZEBRA_NEXTHOP_UPDATE)
9bcb3eef 355 dest = bgp_node_lookup(
4a749e2c
DS
356 bgp->nexthop_cache_table[family2afi(nhr.prefix.family)],
357 &nhr.prefix);
d62a17ae 358 else if (command == ZEBRA_IMPORT_CHECK_UPDATE)
9bcb3eef 359 dest = bgp_node_lookup(
4a749e2c
DS
360 bgp->import_check_table[family2afi(nhr.prefix.family)],
361 &nhr.prefix);
d62a17ae 362
9bcb3eef 363 if (!dest) {
d62a17ae 364 if (BGP_DEBUG(nht, NHT)) {
365 char buf[PREFIX2STR_BUFFER];
4a749e2c 366 prefix2str(&nhr.prefix, buf, sizeof(buf));
8c1a4c10
DS
367 zlog_debug("parse nexthop update(%s(%s)): rn not found",
368 buf, bgp->name_pretty);
d62a17ae 369 }
d62a17ae 370 return;
fb018d25 371 }
d62a17ae 372
9bcb3eef 373 bnc = bgp_dest_get_bgp_nexthop_info(dest);
14315f2d
DS
374 if (!bnc) {
375 if (BGP_DEBUG(nht, NHT)) {
376 char buf[PREFIX2STR_BUFFER];
377
378 prefix2str(&nhr.prefix, buf, sizeof(buf));
8c1a4c10
DS
379 zlog_debug(
380 "parse nexthop update(%s(%s)): bnc node info not found",
381 buf, bgp->name_pretty);
14315f2d 382 }
9bcb3eef 383 bgp_dest_unlock_node(dest);
14315f2d
DS
384 return;
385 }
386
9bcb3eef 387 bgp_dest_unlock_node(dest);
d62a17ae 388 bnc->last_update = bgp_clock();
389 bnc->change_flags = 0;
d62a17ae 390
391 /* debug print the input */
392 if (BGP_DEBUG(nht, NHT)) {
393 char buf[PREFIX2STR_BUFFER];
4a749e2c 394 prefix2str(&nhr.prefix, buf, sizeof(buf));
d62a17ae 395 zlog_debug(
8c1a4c10
DS
396 "%s(%u): Rcvd NH update %s - metric %d/%d #nhops %d/%d flags 0x%x",
397 bnc->bgp->name_pretty, vrf_id, buf, nhr.metric,
398 bnc->metric, nhr.nexthop_num, bnc->nexthop_num,
399 bnc->flags);
d62a17ae 400 }
401
4a749e2c 402 if (nhr.metric != bnc->metric)
d62a17ae 403 bnc->change_flags |= BGP_NEXTHOP_METRIC_CHANGED;
404
4a749e2c 405 if (nhr.nexthop_num != bnc->nexthop_num)
d62a17ae 406 bnc->change_flags |= BGP_NEXTHOP_CHANGED;
407
4a749e2c 408 if (nhr.nexthop_num) {
6137a77d
DS
409 struct peer *peer = bnc->nht_info;
410
d62a17ae 411 /* notify bgp fsm if nbr ip goes from invalid->valid */
412 if (!bnc->nexthop_num)
413 UNSET_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED);
414
415 bnc->flags |= BGP_NEXTHOP_VALID;
4a749e2c
DS
416 bnc->metric = nhr.metric;
417 bnc->nexthop_num = nhr.nexthop_num;
418
960035b2
PZ
419 bnc->flags &= ~BGP_NEXTHOP_LABELED_VALID; /* check below */
420
4a749e2c 421 for (i = 0; i < nhr.nexthop_num; i++) {
960035b2
PZ
422 int num_labels = 0;
423
4a749e2c 424 nexthop = nexthop_from_zapi_nexthop(&nhr.nexthops[i]);
d62a17ae 425
6137a77d
DS
426 /*
427 * Turn on RA for the v6 nexthops
428 * we receive from bgp. This is to allow us
429 * to work with v4 routing over v6 nexthops
430 */
687a2b5d
DS
431 if (peer && !peer->ifp
432 && CHECK_FLAG(peer->flags,
433 PEER_FLAG_CAPABILITY_ENHE)
65f803e8
CS
434 && nhr.prefix.family == AF_INET6
435 && nexthop->type != NEXTHOP_TYPE_BLACKHOLE) {
6137a77d
DS
436 struct interface *ifp;
437
438 ifp = if_lookup_by_index(nexthop->ifindex,
439 nexthop->vrf_id);
8c9769e0
DS
440 if (ifp)
441 zclient_send_interface_radv_req(
442 zclient, nexthop->vrf_id, ifp,
443 true,
444 BGP_UNNUM_DEFAULT_RA_INTERVAL);
6137a77d 445 }
960035b2
PZ
446 /* There is at least one label-switched path */
447 if (nexthop->nh_label &&
448 nexthop->nh_label->num_labels) {
449
450 bnc->flags |= BGP_NEXTHOP_LABELED_VALID;
451 num_labels = nexthop->nh_label->num_labels;
452 }
453
d62a17ae 454 if (BGP_DEBUG(nht, NHT)) {
455 char buf[NEXTHOP_STRLEN];
456 zlog_debug(
960035b2
PZ
457 " nhop via %s (%d labels)",
458 nexthop2str(nexthop, buf, sizeof(buf)),
459 num_labels);
d62a17ae 460 }
461
462 if (nhlist_tail) {
463 nhlist_tail->next = nexthop;
464 nhlist_tail = nexthop;
465 } else {
466 nhlist_tail = nexthop;
467 nhlist_head = nexthop;
468 }
469
470 /* No need to evaluate the nexthop if we have already
471 * determined
472 * that there has been a change.
473 */
474 if (bnc->change_flags & BGP_NEXTHOP_CHANGED)
475 continue;
476
477 for (oldnh = bnc->nexthop; oldnh; oldnh = oldnh->next)
78fba41b 478 if (nexthop_same(oldnh, nexthop))
d62a17ae 479 break;
480
481 if (!oldnh)
482 bnc->change_flags |= BGP_NEXTHOP_CHANGED;
483 }
484 bnc_nexthop_free(bnc);
485 bnc->nexthop = nhlist_head;
486 } else {
487 bnc->flags &= ~BGP_NEXTHOP_VALID;
4a749e2c 488 bnc->nexthop_num = nhr.nexthop_num;
d62a17ae 489
490 /* notify bgp fsm if nbr ip goes from valid->invalid */
491 UNSET_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED);
492
493 bnc_nexthop_free(bnc);
494 bnc->nexthop = NULL;
495 }
496
497 evaluate_paths(bnc);
fb018d25
DS
498}
499
ee7ca6c0 500/*
501 * Cleanup nexthop registration and status information for BGP nexthops
502 * pertaining to this VRF. This is invoked upon VRF deletion.
503 */
504void bgp_cleanup_nexthops(struct bgp *bgp)
505{
506 afi_t afi;
9bcb3eef 507 struct bgp_dest *dest;
ee7ca6c0 508 struct bgp_nexthop_cache *bnc;
509
510 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
511 if (!bgp->nexthop_cache_table[afi])
512 continue;
513
9bcb3eef
DS
514 for (dest = bgp_table_top(bgp->nexthop_cache_table[afi]); dest;
515 dest = bgp_route_next(dest)) {
516 bnc = bgp_dest_get_bgp_nexthop_info(dest);
57f7feb6 517 if (!bnc)
ee7ca6c0 518 continue;
519
520 /* Clear relevant flags. */
521 UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID);
522 UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
523 UNSET_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED);
524 }
525 }
526}
527
fb018d25
DS
528/**
529 * make_prefix - make a prefix structure from the path (essentially
530 * path's node.
531 */
40381db7 532static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p)
fb018d25 533{
078430f6 534
40381db7
DS
535 int is_bgp_static = ((pi->type == ZEBRA_ROUTE_BGP)
536 && (pi->sub_type == BGP_ROUTE_STATIC))
d62a17ae 537 ? 1
538 : 0;
9bcb3eef
DS
539 struct bgp_dest *net = pi->net;
540 const struct prefix *p_orig = bgp_dest_get_prefix(net);
92d6f769 541 struct in_addr ipv4;
0378bcaa
PG
542
543 if (p_orig->family == AF_FLOWSPEC) {
544 if (!pi->peer)
545 return -1;
546 return bgp_flowspec_get_first_nh(pi->peer->bgp,
547 pi, p);
548 }
d62a17ae 549 memset(p, 0, sizeof(struct prefix));
550 switch (afi) {
551 case AFI_IP:
552 p->family = AF_INET;
553 if (is_bgp_static) {
b54892e0
DS
554 p->u.prefix4 = p_orig->u.prefix4;
555 p->prefixlen = p_orig->prefixlen;
d62a17ae 556 } else {
92d6f769
K
557 if (IS_MAPPED_IPV6(&pi->attr->mp_nexthop_global)) {
558 ipv4_mapped_ipv6_to_ipv4(
559 &pi->attr->mp_nexthop_global, &ipv4);
560 p->u.prefix4 = ipv4;
561 p->prefixlen = IPV4_MAX_BITLEN;
562 } else {
563 p->u.prefix4 = pi->attr->nexthop;
564 p->prefixlen = IPV4_MAX_BITLEN;
565 }
d62a17ae 566 }
567 break;
568 case AFI_IP6:
d62a17ae 569 p->family = AF_INET6;
570
571 if (is_bgp_static) {
b54892e0
DS
572 p->u.prefix6 = p_orig->u.prefix6;
573 p->prefixlen = p_orig->prefixlen;
d62a17ae 574 } else {
606fdbb1
DA
575 /* If we receive MP_REACH nexthop with ::(LL)
576 * or LL(LL), use LL address as nexthop cache.
577 */
578 if (pi->attr->mp_nexthop_len
579 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
580 && (IN6_IS_ADDR_UNSPECIFIED(
581 &pi->attr->mp_nexthop_global)
582 || IN6_IS_ADDR_LINKLOCAL(
583 &pi->attr->mp_nexthop_global)))
584 p->u.prefix6 = pi->attr->mp_nexthop_local;
585 else
586 p->u.prefix6 = pi->attr->mp_nexthop_global;
d62a17ae 587 p->prefixlen = IPV6_MAX_BITLEN;
588 }
589 break;
590 default:
591 if (BGP_DEBUG(nht, NHT)) {
592 zlog_debug(
593 "%s: Attempting to make prefix with unknown AFI %d (not %d or %d)",
15569c58 594 __func__, afi, AFI_IP, AFI_IP6);
d62a17ae 595 }
596 break;
65740e1b 597 }
d62a17ae 598 return 0;
fb018d25
DS
599}
600
601/**
078430f6 602 * sendmsg_zebra_rnh -- Format and send a nexthop register/Unregister
fb018d25
DS
603 * command to Zebra.
604 * ARGUMENTS:
605 * struct bgp_nexthop_cache *bnc -- the nexthop structure.
078430f6 606 * int command -- command to send to zebra
fb018d25
DS
607 * RETURNS:
608 * void.
609 */
d62a17ae 610static void sendmsg_zebra_rnh(struct bgp_nexthop_cache *bnc, int command)
fb018d25 611{
b54892e0 612 const struct prefix *p;
3c192540 613 bool exact_match = false;
d62a17ae 614 int ret;
615
3c192540 616 if (!zclient)
d62a17ae 617 return;
618
619 /* Don't try to register if Zebra doesn't know of this instance. */
bb4ef1ae
DS
620 if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bnc->bgp)) {
621 if (BGP_DEBUG(zebra, ZEBRA))
15569c58
DA
622 zlog_debug(
623 "%s: No zebra instance to talk to, not installing NHT entry",
624 __func__);
d62a17ae 625 return;
bb4ef1ae 626 }
d62a17ae 627
1ee0a2df
DS
628 if (!bgp_zebra_num_connects()) {
629 if (BGP_DEBUG(zebra, ZEBRA))
15569c58
DA
630 zlog_debug(
631 "%s: We have not connected yet, cannot send nexthops",
632 __func__);
1ee0a2df 633 }
9bcb3eef 634 p = bgp_dest_get_prefix(bnc->dest);
996c9314
LB
635 if ((command == ZEBRA_NEXTHOP_REGISTER
636 || command == ZEBRA_IMPORT_ROUTE_REGISTER)
637 && (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED)
638 || CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH)))
3c192540 639 exact_match = true;
d62a17ae 640
960035b2
PZ
641 if (BGP_DEBUG(zebra, ZEBRA)) {
642 char buf[PREFIX2STR_BUFFER];
643
644 prefix2str(p, buf, PREFIX2STR_BUFFER);
645 zlog_debug("%s: sending cmd %s for %s (vrf %s)",
646 __func__, zserv_command_string(command), buf,
8c1a4c10 647 bnc->bgp->name_pretty);
960035b2
PZ
648 }
649
996c9314
LB
650 ret = zclient_send_rnh(zclient, command, p, exact_match,
651 bnc->bgp->vrf_id);
d62a17ae 652 /* TBD: handle the failure */
653 if (ret < 0)
e50f7cfd 654 flog_warn(EC_BGP_ZEBRA_SEND,
f162a5b9 655 "sendmsg_nexthop: zclient_send_message() failed");
d62a17ae 656
657 if ((command == ZEBRA_NEXTHOP_REGISTER)
658 || (command == ZEBRA_IMPORT_ROUTE_REGISTER))
659 SET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
660 else if ((command == ZEBRA_NEXTHOP_UNREGISTER)
661 || (command == ZEBRA_IMPORT_ROUTE_UNREGISTER))
662 UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
663 return;
fb018d25
DS
664}
665
666/**
078430f6
DS
667 * register_zebra_rnh - register a NH/route with Zebra for notification
668 * when the route or the route to the nexthop changes.
fb018d25 669 * ARGUMENTS:
078430f6 670 * struct bgp_nexthop_cache *bnc
fb018d25
DS
671 * RETURNS:
672 * void.
673 */
d62a17ae 674static void register_zebra_rnh(struct bgp_nexthop_cache *bnc,
675 int is_bgp_import_route)
fb018d25 676{
d62a17ae 677 /* Check if we have already registered */
678 if (bnc->flags & BGP_NEXTHOP_REGISTERED)
679 return;
680 if (is_bgp_import_route)
681 sendmsg_zebra_rnh(bnc, ZEBRA_IMPORT_ROUTE_REGISTER);
682 else
683 sendmsg_zebra_rnh(bnc, ZEBRA_NEXTHOP_REGISTER);
fb018d25
DS
684}
685
686/**
078430f6 687 * unregister_zebra_rnh -- Unregister the route/nexthop from Zebra.
fb018d25 688 * ARGUMENTS:
078430f6 689 * struct bgp_nexthop_cache *bnc
fb018d25
DS
690 * RETURNS:
691 * void.
692 */
d62a17ae 693static void unregister_zebra_rnh(struct bgp_nexthop_cache *bnc,
694 int is_bgp_import_route)
fb018d25 695{
d62a17ae 696 /* Check if we have already registered */
697 if (!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED))
698 return;
699
700 if (is_bgp_import_route)
701 sendmsg_zebra_rnh(bnc, ZEBRA_IMPORT_ROUTE_UNREGISTER);
702 else
703 sendmsg_zebra_rnh(bnc, ZEBRA_NEXTHOP_UNREGISTER);
fb018d25
DS
704}
705
706/**
707 * evaluate_paths - Evaluate the paths/nets associated with a nexthop.
708 * ARGUMENTS:
709 * struct bgp_nexthop_cache *bnc -- the nexthop structure.
710 * RETURNS:
711 * void.
712 */
d62a17ae 713static void evaluate_paths(struct bgp_nexthop_cache *bnc)
fb018d25 714{
9bcb3eef 715 struct bgp_dest *dest;
4b7e6066 716 struct bgp_path_info *path;
d62a17ae 717 int afi;
718 struct peer *peer = (struct peer *)bnc->nht_info;
719 struct bgp_table *table;
720 safi_t safi;
960035b2 721 struct bgp *bgp_path;
b54892e0 722 const struct prefix *p;
d62a17ae 723
724 if (BGP_DEBUG(nht, NHT)) {
725 char buf[PREFIX2STR_BUFFER];
726 bnc_str(bnc, buf, PREFIX2STR_BUFFER);
727 zlog_debug(
9e15d76a 728 "NH update for %s %s flags 0x%x chgflags 0x%x - evaluate paths",
8c1a4c10
DS
729 buf, bnc->bgp->name_pretty, bnc->flags,
730 bnc->change_flags);
fb018d25
DS
731 }
732
a2addae8 733 LIST_FOREACH (path, &(bnc->paths), nh_thread) {
d62a17ae 734 if (!(path->type == ZEBRA_ROUTE_BGP
735 && ((path->sub_type == BGP_ROUTE_NORMAL)
960035b2
PZ
736 || (path->sub_type == BGP_ROUTE_STATIC)
737 || (path->sub_type == BGP_ROUTE_IMPORTED))))
d62a17ae 738 continue;
739
9bcb3eef
DS
740 dest = path->net;
741 assert(dest && bgp_dest_table(dest));
742 p = bgp_dest_get_prefix(dest);
b54892e0 743 afi = family2afi(p->family);
9bcb3eef 744 table = bgp_dest_table(dest);
d62a17ae 745 safi = table->safi;
746
960035b2
PZ
747 /*
748 * handle routes from other VRFs (they can have a
749 * nexthop in THIS VRF). bgp_path is the bgp instance
750 * that owns the route referencing this nexthop.
751 */
752 bgp_path = table->bgp;
753
754 /*
755 * Path becomes valid/invalid depending on whether the nexthop
d62a17ae 756 * reachable/unreachable.
960035b2
PZ
757 *
758 * In case of unicast routes that were imported from vpn
759 * and that have labels, they are valid only if there are
760 * nexthops with labels
d62a17ae 761 */
960035b2 762
34ea39b6 763 bool bnc_is_valid_nexthop = false;
764 bool path_valid = false;
960035b2
PZ
765
766 if (safi == SAFI_UNICAST &&
767 path->sub_type == BGP_ROUTE_IMPORTED &&
768 path->extra &&
769 path->extra->num_labels) {
770
771 bnc_is_valid_nexthop =
34ea39b6 772 bgp_isvalid_labeled_nexthop(bnc) ? true : false;
960035b2 773 } else {
e7cbe5e5
NT
774 if (bgp_update_martian_nexthop(
775 bnc->bgp, afi, safi, path->type,
9bcb3eef 776 path->sub_type, path->attr, dest)) {
e7cbe5e5
NT
777 if (BGP_DEBUG(nht, NHT))
778 zlog_debug(
779 "%s: prefix %pRN (vrf %s), ignoring path due to martian or self-next-hop",
9bcb3eef 780 __func__, dest, bgp_path->name);
e7cbe5e5
NT
781 } else
782 bnc_is_valid_nexthop =
34ea39b6 783 bgp_isvalid_nexthop(bnc) ? true : false;
960035b2
PZ
784 }
785
9e15d76a 786 if (BGP_DEBUG(nht, NHT)) {
787 char buf1[RD_ADDRSTRLEN];
960035b2 788
9bcb3eef
DS
789 if (dest->pdest) {
790 prefix_rd2str((struct prefix_rd *)bgp_dest_get_prefix(dest->pdest),
9e15d76a 791 buf1, sizeof(buf1));
792 zlog_debug(
793 "... eval path %d/%d %pRN RD %s %s flags 0x%x",
9bcb3eef 794 afi, safi, dest, buf1,
9e15d76a 795 bgp_path->name_pretty, path->flags);
796 } else
797 zlog_debug(
798 "... eval path %d/%d %pRN %s flags 0x%x",
9bcb3eef 799 afi, safi, dest, bgp_path->name_pretty,
9e15d76a 800 path->flags);
801 }
d62a17ae 802
0139efe0 803 /* Skip paths marked for removal or as history. */
804 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)
805 || CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
806 continue;
807
d62a17ae 808 /* Copy the metric to the path. Will be used for bestpath
809 * computation */
810 if (bgp_isvalid_nexthop(bnc) && bnc->metric)
18ee8310
DS
811 (bgp_path_info_extra_get(path))->igpmetric =
812 bnc->metric;
d62a17ae 813 else if (path->extra)
814 path->extra->igpmetric = 0;
815
816 if (CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_METRIC_CHANGED)
817 || CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_CHANGED))
1defdda8 818 SET_FLAG(path->flags, BGP_PATH_IGP_CHANGED);
d62a17ae 819
34ea39b6 820 path_valid = !!CHECK_FLAG(path->flags, BGP_PATH_VALID);
821 if (path_valid != bnc_is_valid_nexthop) {
822 if (path_valid) {
823 /* No longer valid, clear flag; also for EVPN
824 * routes, unimport from VRFs if needed.
825 */
826 bgp_aggregate_decrement(bgp_path, p, path, afi,
827 safi);
9bcb3eef 828 bgp_path_info_unset_flag(dest, path,
34ea39b6 829 BGP_PATH_VALID);
830 if (safi == SAFI_EVPN &&
9bcb3eef 831 bgp_evpn_is_prefix_nht_supported(bgp_dest_get_prefix(dest)))
34ea39b6 832 bgp_evpn_unimport_route(bgp_path,
9bcb3eef 833 afi, safi, bgp_dest_get_prefix(dest), path);
34ea39b6 834 } else {
835 /* Path becomes valid, set flag; also for EVPN
836 * routes, import from VRFs if needed.
837 */
9bcb3eef 838 bgp_path_info_set_flag(dest, path,
34ea39b6 839 BGP_PATH_VALID);
840 bgp_aggregate_increment(bgp_path, p, path, afi,
841 safi);
842 if (safi == SAFI_EVPN &&
9bcb3eef 843 bgp_evpn_is_prefix_nht_supported(bgp_dest_get_prefix(dest)))
34ea39b6 844 bgp_evpn_import_route(bgp_path,
9bcb3eef 845 afi, safi, bgp_dest_get_prefix(dest), path);
34ea39b6 846 }
7c312383
AD
847 }
848
9bcb3eef 849 bgp_process(bgp_path, dest, afi, safi);
d62a17ae 850 }
fc9a856f 851
1e91f1d1
DS
852 if (peer) {
853 int valid_nexthops = bgp_isvalid_nexthop(bnc);
854
855 if (valid_nexthops)
856 peer->last_reset = PEER_DOWN_WAITING_OPEN;
857 else
858 peer->last_reset = PEER_DOWN_WAITING_NHT;
859
860 if (!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED)) {
861 if (BGP_DEBUG(nht, NHT))
15569c58
DA
862 zlog_debug(
863 "%s: Updating peer (%s(%s)) status with NHT",
864 __func__, peer->host,
865 peer->bgp->name_pretty);
1e91f1d1
DS
866 bgp_fsm_event_update(peer, valid_nexthops);
867 SET_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED);
868 }
d62a17ae 869 }
fc9a856f 870
d62a17ae 871 RESET_FLAG(bnc->change_flags);
fb018d25
DS
872}
873
874/**
875 * path_nh_map - make or break path-to-nexthop association.
876 * ARGUMENTS:
877 * path - pointer to the path structure
878 * bnc - pointer to the nexthop structure
879 * make - if set, make the association. if unset, just break the existing
880 * association.
881 */
7f040da1
DS
882void path_nh_map(struct bgp_path_info *path, struct bgp_nexthop_cache *bnc,
883 bool make)
fb018d25 884{
d62a17ae 885 if (path->nexthop) {
886 LIST_REMOVE(path, nh_thread);
887 path->nexthop->path_count--;
888 path->nexthop = NULL;
889 }
890 if (make) {
891 LIST_INSERT_HEAD(&(bnc->paths), path, nh_thread);
892 path->nexthop = bnc;
893 path->nexthop->path_count++;
894 }
fb018d25 895}
1ee0a2df
DS
896
897/*
898 * This function is called to register nexthops to zebra
899 * as that we may have tried to install the nexthops
900 * before we actually have a zebra connection
901 */
902void bgp_nht_register_nexthops(struct bgp *bgp)
903{
9bcb3eef 904 struct bgp_dest *dest;
1ee0a2df
DS
905 struct bgp_nexthop_cache *bnc;
906 afi_t afi;
907
908 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
909 if (!bgp->nexthop_cache_table[afi])
910 continue;
911
9bcb3eef
DS
912 for (dest = bgp_table_top(bgp->nexthop_cache_table[afi]); dest;
913 dest = bgp_route_next(dest)) {
914 bnc = bgp_dest_get_bgp_nexthop_info(dest);
1ee0a2df
DS
915
916 if (!bnc)
917 continue;
918
919 register_zebra_rnh(bnc, 0);
920 }
921 }
922}
1ea03b90 923
b3a3290e 924void bgp_nht_reg_enhe_cap_intfs(struct peer *peer)
1ea03b90
DS
925{
926 struct bgp *bgp;
9bcb3eef 927 struct bgp_dest *dest;
1ea03b90
DS
928 struct bgp_nexthop_cache *bnc;
929 struct nexthop *nhop;
930 struct interface *ifp;
931 struct prefix p;
932
933 if (peer->ifp)
934 return;
935
936 bgp = peer->bgp;
937
938 if (!bgp->nexthop_cache_table[AFI_IP6])
939 return;
940
941 if (!sockunion2hostprefix(&peer->su, &p)) {
b3a3290e
DS
942 zlog_warn("%s: Unable to convert sockunion to prefix for %s",
943 __func__, peer->host);
1ea03b90
DS
944 return;
945 }
946
947 if (p.family != AF_INET6)
948 return;
9bcb3eef
DS
949 dest = bgp_node_lookup(bgp->nexthop_cache_table[AFI_IP6], &p);
950 if (!dest)
32fbbd9c 951 return;
1ea03b90 952
9bcb3eef 953 bnc = bgp_dest_get_bgp_nexthop_info(dest);
1ea03b90
DS
954 if (!bnc)
955 return;
956
957 if (peer != bnc->nht_info)
958 return;
959
960 for (nhop = bnc->nexthop; nhop; nhop = nhop->next) {
8c9769e0
DS
961 ifp = if_lookup_by_index(nhop->ifindex, nhop->vrf_id);
962
963 if (!ifp)
964 continue;
965
1ea03b90
DS
966 zclient_send_interface_radv_req(zclient,
967 nhop->vrf_id,
968 ifp, true,
969 BGP_UNNUM_DEFAULT_RA_INTERVAL);
970 }
971}
b3a3290e
DS
972
973void bgp_nht_dereg_enhe_cap_intfs(struct peer *peer)
974{
975 struct bgp *bgp;
9bcb3eef 976 struct bgp_dest *dest;
b3a3290e
DS
977 struct bgp_nexthop_cache *bnc;
978 struct nexthop *nhop;
979 struct interface *ifp;
980 struct prefix p;
981
982 if (peer->ifp)
983 return;
984
985 bgp = peer->bgp;
986
987 if (!bgp->nexthop_cache_table[AFI_IP6])
988 return;
989
990 if (!sockunion2hostprefix(&peer->su, &p)) {
991 zlog_warn("%s: Unable to convert sockunion to prefix for %s",
992 __func__, peer->host);
993 return;
994 }
995
996 if (p.family != AF_INET6)
997 return;
998
9bcb3eef
DS
999 dest = bgp_node_lookup(bgp->nexthop_cache_table[AFI_IP6], &p);
1000 if (!dest)
b3a3290e
DS
1001 return;
1002
9bcb3eef 1003 bnc = bgp_dest_get_bgp_nexthop_info(dest);
b3a3290e
DS
1004 if (!bnc)
1005 return;
1006
1007 if (peer != bnc->nht_info)
1008 return;
1009
1010 for (nhop = bnc->nexthop; nhop; nhop = nhop->next) {
1011 ifp = if_lookup_by_index(nhop->ifindex, nhop->vrf_id);
1012
68cecc3b
DS
1013 if (!ifp)
1014 continue;
1015
b3a3290e
DS
1016 zclient_send_interface_radv_req(zclient, nhop->vrf_id, ifp, 0,
1017 0);
1018 }
1019}