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