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