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