1 /* BGP Nexthop tracking
2 * Copyright (C) 2013 Cumulus Networks, Inc.
4 * This file is part of GNU Zebra.
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
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.
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
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 #include "bgpd/bgp_evpn.h"
48 extern struct zclient
*zclient
;
50 static void register_zebra_rnh(struct bgp_nexthop_cache
*bnc
,
51 int is_bgp_static_route
);
52 static void unregister_zebra_rnh(struct bgp_nexthop_cache
*bnc
,
53 int is_bgp_static_route
);
54 static void evaluate_paths(struct bgp_nexthop_cache
*bnc
);
55 static int make_prefix(int afi
, struct bgp_path_info
*pi
, struct prefix
*p
);
57 static int bgp_isvalid_nexthop(struct bgp_nexthop_cache
*bnc
)
59 return (bgp_zebra_num_connects() == 0
60 || (bnc
&& CHECK_FLAG(bnc
->flags
, BGP_NEXTHOP_VALID
)));
63 static int bgp_isvalid_labeled_nexthop(struct bgp_nexthop_cache
*bnc
)
65 return (bgp_zebra_num_connects() == 0
66 || (bnc
&& CHECK_FLAG(bnc
->flags
, BGP_NEXTHOP_LABELED_VALID
)));
69 static void bgp_unlink_nexthop_check(struct bgp_nexthop_cache
*bnc
)
71 if (LIST_EMPTY(&(bnc
->paths
)) && !bnc
->nht_info
) {
72 if (BGP_DEBUG(nht
, NHT
)) {
73 char buf
[PREFIX2STR_BUFFER
];
74 zlog_debug("bgp_unlink_nexthop: freeing bnc %s(%s)",
75 bnc_str(bnc
, buf
, PREFIX2STR_BUFFER
),
76 bnc
->bgp
->name_pretty
);
78 unregister_zebra_rnh(bnc
,
79 CHECK_FLAG(bnc
->flags
, BGP_STATIC_ROUTE
));
80 bgp_node_set_bgp_nexthop_info(bnc
->node
, NULL
);
81 bgp_unlock_node(bnc
->node
);
87 void bgp_unlink_nexthop(struct bgp_path_info
*path
)
89 struct bgp_nexthop_cache
*bnc
= path
->nexthop
;
94 path_nh_map(path
, NULL
, false);
96 bgp_unlink_nexthop_check(bnc
);
99 void bgp_unlink_nexthop_by_peer(struct peer
*peer
)
103 struct bgp_nexthop_cache
*bnc
;
104 afi_t afi
= family2afi(peer
->su
.sa
.sa_family
);
106 if (!sockunion2hostprefix(&peer
->su
, &p
))
109 rn
= bgp_node_get(peer
->bgp
->nexthop_cache_table
[afi
], &p
);
111 bnc
= bgp_node_get_bgp_nexthop_info(rn
);
115 /* cleanup the peer reference */
116 bnc
->nht_info
= NULL
;
118 bgp_unlink_nexthop_check(bnc
);
122 * A route and its nexthop might belong to different VRFs. Therefore,
123 * we need both the bgp_route and bgp_nexthop pointers.
125 int bgp_find_or_add_nexthop(struct bgp
*bgp_route
, struct bgp
*bgp_nexthop
,
126 afi_t afi
, struct bgp_path_info
*pi
,
127 struct peer
*peer
, int connected
)
130 struct bgp_nexthop_cache
*bnc
;
132 int is_bgp_static_route
= 0;
135 is_bgp_static_route
= ((pi
->type
== ZEBRA_ROUTE_BGP
)
136 && (pi
->sub_type
== BGP_ROUTE_STATIC
))
140 /* Since Extended Next-hop Encoding (RFC5549) support, we want
142 address-family from the next-hop. */
143 if (!is_bgp_static_route
)
144 afi
= BGP_ATTR_NEXTHOP_AFI_IP6(pi
->attr
) ? AFI_IP6
147 /* This will return true if the global IPv6 NH is a link local
149 if (make_prefix(afi
, pi
, &p
) < 0)
152 if (!sockunion2hostprefix(&peer
->su
, &p
)) {
153 if (BGP_DEBUG(nht
, NHT
)) {
155 "%s: Attempting to register with unknown AFI %d (not %d or %d)",
156 __FUNCTION__
, afi
, AFI_IP
, AFI_IP6
);
163 if (is_bgp_static_route
)
164 rn
= bgp_node_get(bgp_nexthop
->import_check_table
[afi
], &p
);
166 rn
= bgp_node_get(bgp_nexthop
->nexthop_cache_table
[afi
], &p
);
168 bnc
= bgp_node_get_bgp_nexthop_info(rn
);
171 bgp_node_set_bgp_nexthop_info(rn
, bnc
);
173 bnc
->bgp
= bgp_nexthop
;
175 if (BGP_DEBUG(nht
, NHT
)) {
176 char buf
[PREFIX2STR_BUFFER
];
178 zlog_debug("Allocated bnc %s(%s) peer %p",
179 bnc_str(bnc
, buf
, PREFIX2STR_BUFFER
),
180 bnc
->bgp
->name_pretty
, peer
);
185 if (is_bgp_static_route
) {
186 SET_FLAG(bnc
->flags
, BGP_STATIC_ROUTE
);
188 /* If we're toggling the type, re-register */
189 if ((bgp_flag_check(bgp_route
, BGP_FLAG_IMPORT_CHECK
))
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
);
194 } else if ((!bgp_flag_check(bgp_route
, BGP_FLAG_IMPORT_CHECK
))
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
);
202 /* When nexthop is already known, but now requires 'connected'
204 * re-register it. The reverse scenario where the nexthop currently
206 * 'connected' resolution does not need a re-register (i.e., we treat
207 * 'connected-required' as an override) except in the scenario where
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
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
);
225 if (bgp_route
->inst_type
== BGP_INSTANCE_TYPE_VIEW
) {
226 SET_FLAG(bnc
->flags
, BGP_NEXTHOP_REGISTERED
);
227 SET_FLAG(bnc
->flags
, BGP_NEXTHOP_VALID
);
228 } else if (!CHECK_FLAG(bnc
->flags
, BGP_NEXTHOP_REGISTERED
) &&
229 !is_default_host_route(&bnc
->node
->p
))
230 register_zebra_rnh(bnc
, is_bgp_static_route
);
232 if (pi
&& pi
->nexthop
!= bnc
) {
233 /* Unlink from existing nexthop cache, if any. This will also
235 * the nexthop cache entry, if appropriate.
237 bgp_unlink_nexthop(pi
);
239 /* updates NHT pi list reference */
240 path_nh_map(pi
, bnc
, true);
242 if (CHECK_FLAG(bnc
->flags
, BGP_NEXTHOP_VALID
) && bnc
->metric
)
243 (bgp_path_info_extra_get(pi
))->igpmetric
= bnc
->metric
;
245 pi
->extra
->igpmetric
= 0;
247 bnc
->nht_info
= (void *)peer
; /* NHT peer reference */
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
254 if (bgp_route
->inst_type
== BGP_INSTANCE_TYPE_VIEW
)
257 return (bgp_isvalid_nexthop(bnc
));
260 void bgp_delete_connected_nexthop(afi_t afi
, struct peer
*peer
)
263 struct bgp_nexthop_cache
*bnc
;
269 if (!sockunion2hostprefix(&peer
->su
, &p
))
272 rn
= bgp_node_lookup(
273 peer
->bgp
->nexthop_cache_table
[family2afi(p
.family
)], &p
);
275 if (BGP_DEBUG(nht
, NHT
))
277 "Cannot find connected NHT node for peer %s(%s)",
278 peer
->host
, peer
->bgp
->name_pretty
);
282 bnc
= bgp_node_get_bgp_nexthop_info(rn
);
284 if (BGP_DEBUG(nht
, NHT
))
286 "Cannot find connected NHT node for peer %s(%s) on route_node as expected",
287 peer
->host
, peer
->bgp
->name_pretty
);
293 if (bnc
->nht_info
!= peer
) {
294 if (BGP_DEBUG(nht
, NHT
))
296 "Connected NHT %p node for peer %s(%s) points to %p",
297 bnc
, peer
->host
, bnc
->bgp
->name_pretty
,
302 bnc
->nht_info
= NULL
;
304 if (LIST_EMPTY(&(bnc
->paths
))) {
305 if (BGP_DEBUG(nht
, NHT
))
307 "Freeing connected NHT node %p for peer %s(%s)",
308 bnc
, peer
->host
, bnc
->bgp
->name_pretty
);
309 unregister_zebra_rnh(bnc
, 0);
310 bgp_node_set_bgp_nexthop_info(bnc
->node
, NULL
);
311 bgp_unlock_node(bnc
->node
);
316 void bgp_parse_nexthop_update(int command
, vrf_id_t vrf_id
)
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
;
326 struct zapi_route nhr
;
328 bgp
= bgp_lookup_by_vrf_id(vrf_id
);
332 "parse nexthop update: instance not found for vrf_id %u",
337 if (!zapi_nexthop_update_decode(zclient
->ibuf
, &nhr
)) {
338 if (BGP_DEBUG(nht
, NHT
))
339 zlog_debug("%s[%s]: Failure to decode nexthop update",
340 __PRETTY_FUNCTION__
, bgp
->name_pretty
);
344 if (command
== ZEBRA_NEXTHOP_UPDATE
)
345 rn
= bgp_node_lookup(
346 bgp
->nexthop_cache_table
[family2afi(nhr
.prefix
.family
)],
348 else if (command
== ZEBRA_IMPORT_CHECK_UPDATE
)
349 rn
= bgp_node_lookup(
350 bgp
->import_check_table
[family2afi(nhr
.prefix
.family
)],
354 if (BGP_DEBUG(nht
, NHT
)) {
355 char buf
[PREFIX2STR_BUFFER
];
356 prefix2str(&nhr
.prefix
, buf
, sizeof(buf
));
357 zlog_debug("parse nexthop update(%s(%s)): rn not found",
358 buf
, bgp
->name_pretty
);
363 bnc
= bgp_node_get_bgp_nexthop_info(rn
);
365 if (BGP_DEBUG(nht
, NHT
)) {
366 char buf
[PREFIX2STR_BUFFER
];
368 prefix2str(&nhr
.prefix
, buf
, sizeof(buf
));
370 "parse nexthop update(%s(%s)): bnc node info not found",
371 buf
, bgp
->name_pretty
);
378 bnc
->last_update
= bgp_clock();
379 bnc
->change_flags
= 0;
381 /* debug print the input */
382 if (BGP_DEBUG(nht
, NHT
)) {
383 char buf
[PREFIX2STR_BUFFER
];
384 prefix2str(&nhr
.prefix
, buf
, sizeof(buf
));
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
,
392 if (nhr
.metric
!= bnc
->metric
)
393 bnc
->change_flags
|= BGP_NEXTHOP_METRIC_CHANGED
;
395 if (nhr
.nexthop_num
!= bnc
->nexthop_num
)
396 bnc
->change_flags
|= BGP_NEXTHOP_CHANGED
;
398 if (nhr
.nexthop_num
) {
399 struct peer
*peer
= bnc
->nht_info
;
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
);
405 bnc
->flags
|= BGP_NEXTHOP_VALID
;
406 bnc
->metric
= nhr
.metric
;
407 bnc
->nexthop_num
= nhr
.nexthop_num
;
409 bnc
->flags
&= ~BGP_NEXTHOP_LABELED_VALID
; /* check below */
411 for (i
= 0; i
< nhr
.nexthop_num
; i
++) {
414 nexthop
= nexthop_from_zapi_nexthop(&nhr
.nexthops
[i
]);
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
421 if (peer
&& !peer
->ifp
422 && CHECK_FLAG(peer
->flags
,
423 PEER_FLAG_CAPABILITY_ENHE
)
424 && nhr
.prefix
.family
== AF_INET6
425 && nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
) {
426 struct interface
*ifp
;
428 ifp
= if_lookup_by_index(nexthop
->ifindex
,
430 zclient_send_interface_radv_req(
431 zclient
, nexthop
->vrf_id
, ifp
, true,
432 BGP_UNNUM_DEFAULT_RA_INTERVAL
);
434 /* There is at least one label-switched path */
435 if (nexthop
->nh_label
&&
436 nexthop
->nh_label
->num_labels
) {
438 bnc
->flags
|= BGP_NEXTHOP_LABELED_VALID
;
439 num_labels
= nexthop
->nh_label
->num_labels
;
442 if (BGP_DEBUG(nht
, NHT
)) {
443 char buf
[NEXTHOP_STRLEN
];
445 " nhop via %s (%d labels)",
446 nexthop2str(nexthop
, buf
, sizeof(buf
)),
451 nhlist_tail
->next
= nexthop
;
452 nhlist_tail
= nexthop
;
454 nhlist_tail
= nexthop
;
455 nhlist_head
= nexthop
;
458 /* No need to evaluate the nexthop if we have already
460 * that there has been a change.
462 if (bnc
->change_flags
& BGP_NEXTHOP_CHANGED
)
465 for (oldnh
= bnc
->nexthop
; oldnh
; oldnh
= oldnh
->next
)
466 if (nexthop_same(oldnh
, nexthop
))
470 bnc
->change_flags
|= BGP_NEXTHOP_CHANGED
;
472 bnc_nexthop_free(bnc
);
473 bnc
->nexthop
= nhlist_head
;
475 bnc
->flags
&= ~BGP_NEXTHOP_VALID
;
476 bnc
->nexthop_num
= nhr
.nexthop_num
;
478 /* notify bgp fsm if nbr ip goes from valid->invalid */
479 UNSET_FLAG(bnc
->flags
, BGP_NEXTHOP_PEER_NOTIFIED
);
481 bnc_nexthop_free(bnc
);
489 * Cleanup nexthop registration and status information for BGP nexthops
490 * pertaining to this VRF. This is invoked upon VRF deletion.
492 void bgp_cleanup_nexthops(struct bgp
*bgp
)
496 struct bgp_nexthop_cache
*bnc
;
498 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
499 if (!bgp
->nexthop_cache_table
[afi
])
502 for (rn
= bgp_table_top(bgp
->nexthop_cache_table
[afi
]); rn
;
503 rn
= bgp_route_next(rn
)) {
504 bnc
= bgp_node_get_bgp_nexthop_info(rn
);
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
);
517 * make_prefix - make a prefix structure from the path (essentially
520 static int make_prefix(int afi
, struct bgp_path_info
*pi
, struct prefix
*p
)
523 int is_bgp_static
= ((pi
->type
== ZEBRA_ROUTE_BGP
)
524 && (pi
->sub_type
== BGP_ROUTE_STATIC
))
527 struct bgp_node
*net
= pi
->net
;
528 struct prefix
*p_orig
= &net
->p
;
530 if (p_orig
->family
== AF_FLOWSPEC
) {
533 return bgp_flowspec_get_first_nh(pi
->peer
->bgp
,
536 memset(p
, 0, sizeof(struct prefix
));
541 p
->u
.prefix4
= pi
->net
->p
.u
.prefix4
;
542 p
->prefixlen
= pi
->net
->p
.prefixlen
;
544 p
->u
.prefix4
= pi
->attr
->nexthop
;
545 p
->prefixlen
= IPV4_MAX_BITLEN
;
549 p
->family
= AF_INET6
;
552 p
->u
.prefix6
= pi
->net
->p
.u
.prefix6
;
553 p
->prefixlen
= pi
->net
->p
.prefixlen
;
555 p
->u
.prefix6
= pi
->attr
->mp_nexthop_global
;
556 p
->prefixlen
= IPV6_MAX_BITLEN
;
560 if (BGP_DEBUG(nht
, NHT
)) {
562 "%s: Attempting to make prefix with unknown AFI %d (not %d or %d)",
563 __FUNCTION__
, afi
, AFI_IP
, AFI_IP6
);
571 * sendmsg_zebra_rnh -- Format and send a nexthop register/Unregister
574 * struct bgp_nexthop_cache *bnc -- the nexthop structure.
575 * int command -- command to send to zebra
579 static void sendmsg_zebra_rnh(struct bgp_nexthop_cache
*bnc
, int command
)
582 bool exact_match
= false;
588 /* Don't try to register if Zebra doesn't know of this instance. */
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__
);
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__
);
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
)))
608 if (BGP_DEBUG(zebra
, ZEBRA
)) {
609 char buf
[PREFIX2STR_BUFFER
];
611 prefix2str(p
, buf
, PREFIX2STR_BUFFER
);
612 zlog_debug("%s: sending cmd %s for %s (vrf %s)",
613 __func__
, zserv_command_string(command
), buf
,
614 bnc
->bgp
->name_pretty
);
617 ret
= zclient_send_rnh(zclient
, command
, p
, exact_match
,
619 /* TBD: handle the failure */
621 flog_warn(EC_BGP_ZEBRA_SEND
,
622 "sendmsg_nexthop: zclient_send_message() failed");
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
);
634 * register_zebra_rnh - register a NH/route with Zebra for notification
635 * when the route or the route to the nexthop changes.
637 * struct bgp_nexthop_cache *bnc
641 static void register_zebra_rnh(struct bgp_nexthop_cache
*bnc
,
642 int is_bgp_import_route
)
644 /* Check if we have already registered */
645 if (bnc
->flags
& BGP_NEXTHOP_REGISTERED
)
647 if (is_bgp_import_route
)
648 sendmsg_zebra_rnh(bnc
, ZEBRA_IMPORT_ROUTE_REGISTER
);
650 sendmsg_zebra_rnh(bnc
, ZEBRA_NEXTHOP_REGISTER
);
654 * unregister_zebra_rnh -- Unregister the route/nexthop from Zebra.
656 * struct bgp_nexthop_cache *bnc
660 static void unregister_zebra_rnh(struct bgp_nexthop_cache
*bnc
,
661 int is_bgp_import_route
)
663 /* Check if we have already registered */
664 if (!CHECK_FLAG(bnc
->flags
, BGP_NEXTHOP_REGISTERED
))
667 if (is_bgp_import_route
)
668 sendmsg_zebra_rnh(bnc
, ZEBRA_IMPORT_ROUTE_UNREGISTER
);
670 sendmsg_zebra_rnh(bnc
, ZEBRA_NEXTHOP_UNREGISTER
);
674 * evaluate_paths - Evaluate the paths/nets associated with a nexthop.
676 * struct bgp_nexthop_cache *bnc -- the nexthop structure.
680 static void evaluate_paths(struct bgp_nexthop_cache
*bnc
)
683 struct bgp_path_info
*path
;
685 struct peer
*peer
= (struct peer
*)bnc
->nht_info
;
686 struct bgp_table
*table
;
688 struct bgp
*bgp_path
;
690 if (BGP_DEBUG(nht
, NHT
)) {
691 char buf
[PREFIX2STR_BUFFER
];
692 bnc_str(bnc
, buf
, PREFIX2STR_BUFFER
);
694 "NH update for %s(%s) - flags 0x%x chgflags 0x%x - evaluate paths",
695 buf
, bnc
->bgp
->name_pretty
, bnc
->flags
,
699 LIST_FOREACH (path
, &(bnc
->paths
), nh_thread
) {
700 if (!(path
->type
== ZEBRA_ROUTE_BGP
701 && ((path
->sub_type
== BGP_ROUTE_NORMAL
)
702 || (path
->sub_type
== BGP_ROUTE_STATIC
)
703 || (path
->sub_type
== BGP_ROUTE_IMPORTED
))))
707 assert(rn
&& bgp_node_table(rn
));
708 afi
= family2afi(rn
->p
.family
);
709 table
= bgp_node_table(rn
);
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.
717 bgp_path
= table
->bgp
;
720 * Path becomes valid/invalid depending on whether the nexthop
721 * reachable/unreachable.
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
728 int bnc_is_valid_nexthop
= 0;
730 if (safi
== SAFI_UNICAST
&&
731 path
->sub_type
== BGP_ROUTE_IMPORTED
&&
733 path
->extra
->num_labels
) {
735 bnc_is_valid_nexthop
=
736 bgp_isvalid_labeled_nexthop(bnc
) ? 1 : 0;
738 bnc_is_valid_nexthop
=
739 bgp_isvalid_nexthop(bnc
) ? 1 : 0;
742 if (BGP_DEBUG(nht
, NHT
)) {
743 char buf
[PREFIX_STRLEN
];
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 "));
751 if ((CHECK_FLAG(path
->flags
, BGP_PATH_VALID
) ? 1 : 0)
752 != bnc_is_valid_nexthop
) {
753 if (CHECK_FLAG(path
->flags
, BGP_PATH_VALID
)) {
754 bgp_aggregate_decrement(bgp_path
, &rn
->p
,
756 bgp_path_info_unset_flag(rn
, path
,
759 bgp_path_info_set_flag(rn
, path
,
761 bgp_aggregate_increment(bgp_path
, &rn
->p
,
766 /* Copy the metric to the path. Will be used for bestpath
768 if (bgp_isvalid_nexthop(bnc
) && bnc
->metric
)
769 (bgp_path_info_extra_get(path
))->igpmetric
=
771 else if (path
->extra
)
772 path
->extra
->igpmetric
= 0;
774 if (CHECK_FLAG(bnc
->change_flags
, BGP_NEXTHOP_METRIC_CHANGED
)
775 || CHECK_FLAG(bnc
->change_flags
, BGP_NEXTHOP_CHANGED
))
776 SET_FLAG(path
->flags
, BGP_PATH_IGP_CHANGED
);
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
,
784 bgp_evpn_unimport_route(bgp_path
, afi
, safi
,
788 bgp_process(bgp_path
, rn
, afi
, safi
);
791 if (peer
&& !CHECK_FLAG(bnc
->flags
, BGP_NEXTHOP_PEER_NOTIFIED
)) {
792 if (BGP_DEBUG(nht
, NHT
))
793 zlog_debug("%s: Updating peer (%s(%s)) status with NHT",
794 __FUNCTION__
, peer
->host
,
795 peer
->bgp
->name_pretty
);
796 bgp_fsm_event_update(peer
, bgp_isvalid_nexthop(bnc
));
797 SET_FLAG(bnc
->flags
, BGP_NEXTHOP_PEER_NOTIFIED
);
800 RESET_FLAG(bnc
->change_flags
);
804 * path_nh_map - make or break path-to-nexthop association.
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
811 void path_nh_map(struct bgp_path_info
*path
, struct bgp_nexthop_cache
*bnc
,
815 LIST_REMOVE(path
, nh_thread
);
816 path
->nexthop
->path_count
--;
817 path
->nexthop
= NULL
;
820 LIST_INSERT_HEAD(&(bnc
->paths
), path
, nh_thread
);
822 path
->nexthop
->path_count
++;
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
831 void bgp_nht_register_nexthops(struct bgp
*bgp
)
834 struct bgp_nexthop_cache
*bnc
;
837 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
838 if (!bgp
->nexthop_cache_table
[afi
])
841 for (rn
= bgp_table_top(bgp
->nexthop_cache_table
[afi
]); rn
;
842 rn
= bgp_route_next(rn
)) {
843 bnc
= bgp_node_get_bgp_nexthop_info(rn
);
848 register_zebra_rnh(bnc
, 0);
853 void bgp_nht_register_enhe_capability_interfaces(struct peer
*peer
)
857 struct bgp_nexthop_cache
*bnc
;
858 struct nexthop
*nhop
;
859 struct interface
*ifp
;
867 if (!bgp
->nexthop_cache_table
[AFI_IP6
])
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__
);
877 if (p
.family
!= AF_INET6
)
879 rn
= bgp_node_lookup(bgp
->nexthop_cache_table
[AFI_IP6
], &p
);
883 bnc
= bgp_node_get_bgp_nexthop_info(rn
);
887 if (peer
!= bnc
->nht_info
)
890 for (nhop
= bnc
->nexthop
; nhop
; nhop
= nhop
->next
) {
891 ifp
= if_lookup_by_index(nhop
->ifindex
,
893 zclient_send_interface_radv_req(zclient
,
896 BGP_UNNUM_DEFAULT_RA_INTERVAL
);