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