2 Copyright (C) 2000 Kunihiro Ishiguro
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
17 along with GNU Zebra; see the file COPYING. If not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
32 #include "bgpd/bgpd.h"
33 #include "bgpd/bgp_table.h"
34 #include "bgpd/bgp_route.h"
35 #include "bgpd/bgp_attr.h"
36 #include "bgpd/bgp_nexthop.h"
37 #include "bgpd/bgp_debug.h"
38 #include "bgpd/bgp_damp.h"
39 #include "zebra/rib.h"
40 #include "zebra/zserv.h" /* For ZEBRA_SERV_PATH. */
42 struct bgp_nexthop_cache
*zlookup_query (struct in_addr
);
44 struct bgp_nexthop_cache
*zlookup_query_ipv6 (struct in6_addr
*);
45 #endif /* HAVE_IPV6 */
47 /* Only one BGP scan thread are activated at the same time. */
48 static struct thread
*bgp_scan_thread
= NULL
;
50 /* BGP import thread */
51 static struct thread
*bgp_import_thread
= NULL
;
53 /* BGP scan interval. */
54 static int bgp_scan_interval
;
56 /* BGP import interval. */
57 static int bgp_import_interval
;
59 /* Route table for next-hop lookup cache. */
60 static struct bgp_table
*bgp_nexthop_cache_table
[AFI_MAX
];
61 static struct bgp_table
*cache1_table
[AFI_MAX
];
62 static struct bgp_table
*cache2_table
[AFI_MAX
];
64 /* Route table for connected route. */
65 static struct bgp_table
*bgp_connected_table
[AFI_MAX
];
67 /* BGP nexthop lookup query client. */
68 struct zclient
*zlookup
= NULL
;
70 /* Add nexthop to the end of the list. */
72 bnc_nexthop_add (struct bgp_nexthop_cache
*bnc
, struct nexthop
*nexthop
)
76 for (last
= bnc
->nexthop
; last
&& last
->next
; last
= last
->next
)
81 bnc
->nexthop
= nexthop
;
86 bnc_nexthop_free (struct bgp_nexthop_cache
*bnc
)
88 struct nexthop
*nexthop
;
89 struct nexthop
*next
= NULL
;
91 for (nexthop
= bnc
->nexthop
; nexthop
; nexthop
= next
)
94 XFREE (MTYPE_NEXTHOP
, nexthop
);
98 static struct bgp_nexthop_cache
*
101 return XCALLOC (MTYPE_BGP_NEXTHOP_CACHE
, sizeof (struct bgp_nexthop_cache
));
105 bnc_free (struct bgp_nexthop_cache
*bnc
)
107 bnc_nexthop_free (bnc
);
108 XFREE (MTYPE_BGP_NEXTHOP_CACHE
, bnc
);
112 bgp_nexthop_same (struct nexthop
*next1
, struct nexthop
*next2
)
114 if (next1
->type
!= next2
->type
)
119 case ZEBRA_NEXTHOP_IPV4
:
120 if (! IPV4_ADDR_SAME (&next1
->gate
.ipv4
, &next2
->gate
.ipv4
))
123 case ZEBRA_NEXTHOP_IFINDEX
:
124 case ZEBRA_NEXTHOP_IFNAME
:
125 if (next1
->ifindex
!= next2
->ifindex
)
129 case ZEBRA_NEXTHOP_IPV6
:
130 if (! IPV6_ADDR_SAME (&next1
->gate
.ipv6
, &next2
->gate
.ipv6
))
133 case ZEBRA_NEXTHOP_IPV6_IFINDEX
:
134 case ZEBRA_NEXTHOP_IPV6_IFNAME
:
135 if (! IPV6_ADDR_SAME (&next1
->gate
.ipv6
, &next2
->gate
.ipv6
))
137 if (next1
->ifindex
!= next2
->ifindex
)
140 #endif /* HAVE_IPV6 */
149 bgp_nexthop_cache_different (struct bgp_nexthop_cache
*bnc1
,
150 struct bgp_nexthop_cache
*bnc2
)
153 struct nexthop
*next1
, *next2
;
155 if (bnc1
->nexthop_num
!= bnc2
->nexthop_num
)
158 next1
= bnc1
->nexthop
;
159 next2
= bnc2
->nexthop
;
161 for (i
= 0; i
< bnc1
->nexthop_num
; i
++)
163 if (! bgp_nexthop_same (next1
, next2
))
172 /* If nexthop exists on connected network return 1. */
174 bgp_nexthop_onlink (afi_t afi
, struct attr
*attr
)
178 /* Lookup the address is onlink or not. */
181 rn
= bgp_node_match_ipv4 (bgp_connected_table
[AFI_IP
], &attr
->nexthop
);
184 bgp_unlock_node (rn
);
189 else if (afi
== AFI_IP6
)
191 if (attr
->extra
->mp_nexthop_len
== 32)
193 else if (attr
->extra
->mp_nexthop_len
== 16)
195 if (IN6_IS_ADDR_LINKLOCAL (&attr
->extra
->mp_nexthop_global
))
198 rn
= bgp_node_match_ipv6 (bgp_connected_table
[AFI_IP6
],
199 &attr
->extra
->mp_nexthop_global
);
202 bgp_unlock_node (rn
);
207 #endif /* HAVE_IPV6 */
212 /* Check specified next-hop is reachable or not. */
214 bgp_nexthop_lookup_ipv6 (struct peer
*peer
, struct bgp_info
*ri
, int *changed
,
219 struct bgp_nexthop_cache
*bnc
;
222 /* Only check IPv6 global address only nexthop. */
225 if (attr
->extra
->mp_nexthop_len
!= 16
226 || IN6_IS_ADDR_LINKLOCAL (&attr
->extra
->mp_nexthop_global
))
229 memset (&p
, 0, sizeof (struct prefix
));
231 p
.prefixlen
= IPV6_MAX_BITLEN
;
232 p
.u
.prefix6
= attr
->extra
->mp_nexthop_global
;
234 /* IBGP or ebgp-multihop */
235 rn
= bgp_node_get (bgp_nexthop_cache_table
[AFI_IP6
], &p
);
240 bgp_unlock_node (rn
);
244 if (NULL
== (bnc
= zlookup_query_ipv6 (&attr
->extra
->mp_nexthop_global
)))
250 struct bgp_table
*old
;
251 struct bgp_node
*oldrn
;
253 if (bgp_nexthop_cache_table
[AFI_IP6
] == cache1_table
[AFI_IP6
])
254 old
= cache2_table
[AFI_IP6
];
256 old
= cache1_table
[AFI_IP6
];
258 oldrn
= bgp_node_lookup (old
, &p
);
261 struct bgp_nexthop_cache
*oldbnc
= oldrn
->info
;
263 bnc
->changed
= bgp_nexthop_cache_different (bnc
, oldbnc
);
265 if (bnc
->metric
!= oldbnc
->metric
)
266 bnc
->metricchanged
= 1;
268 bgp_unlock_node (oldrn
);
276 *changed
= bnc
->changed
;
279 *metricchanged
= bnc
->metricchanged
;
281 if (bnc
->valid
&& bnc
->metric
)
282 (bgp_info_extra_get (ri
))->igpmetric
= bnc
->metric
;
284 ri
->extra
->igpmetric
= 0;
288 #endif /* HAVE_IPV6 */
290 /* Check specified next-hop is reachable or not. */
292 bgp_nexthop_lookup (afi_t afi
, struct peer
*peer
, struct bgp_info
*ri
,
293 int *changed
, int *metricchanged
)
297 struct bgp_nexthop_cache
*bnc
;
302 return bgp_nexthop_lookup_ipv6 (peer
, ri
, changed
, metricchanged
);
303 #endif /* HAVE_IPV6 */
305 addr
= ri
->attr
->nexthop
;
307 memset (&p
, 0, sizeof (struct prefix
));
309 p
.prefixlen
= IPV4_MAX_BITLEN
;
312 /* IBGP or ebgp-multihop */
313 rn
= bgp_node_get (bgp_nexthop_cache_table
[AFI_IP
], &p
);
318 bgp_unlock_node (rn
);
322 if (NULL
== (bnc
= zlookup_query (addr
)))
328 struct bgp_table
*old
;
329 struct bgp_node
*oldrn
;
331 if (bgp_nexthop_cache_table
[AFI_IP
] == cache1_table
[AFI_IP
])
332 old
= cache2_table
[AFI_IP
];
334 old
= cache1_table
[AFI_IP
];
336 oldrn
= bgp_node_lookup (old
, &p
);
339 struct bgp_nexthop_cache
*oldbnc
= oldrn
->info
;
341 bnc
->changed
= bgp_nexthop_cache_different (bnc
, oldbnc
);
343 if (bnc
->metric
!= oldbnc
->metric
)
344 bnc
->metricchanged
= 1;
346 bgp_unlock_node (oldrn
);
354 *changed
= bnc
->changed
;
357 *metricchanged
= bnc
->metricchanged
;
359 if (bnc
->valid
&& bnc
->metric
)
360 (bgp_info_extra_get(ri
))->igpmetric
= bnc
->metric
;
362 ri
->extra
->igpmetric
= 0;
367 /* Reset and free all BGP nexthop cache. */
369 bgp_nexthop_cache_reset (struct bgp_table
*table
)
372 struct bgp_nexthop_cache
*bnc
;
374 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
375 if ((bnc
= rn
->info
) != NULL
)
379 bgp_unlock_node (rn
);
384 bgp_scan (afi_t afi
, safi_t safi
)
389 struct bgp_info
*next
;
391 struct listnode
*node
, *nnode
;
398 if (bgp_nexthop_cache_table
[afi
] == cache1_table
[afi
])
399 bgp_nexthop_cache_table
[afi
] = cache2_table
[afi
];
401 bgp_nexthop_cache_table
[afi
] = cache1_table
[afi
];
403 /* Get default bgp. */
404 bgp
= bgp_get_default ();
408 /* Maximum prefix check */
409 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
411 if (peer
->status
!= Established
)
414 if (peer
->afc
[afi
][SAFI_UNICAST
])
415 bgp_maximum_prefix_overflow (peer
, afi
, SAFI_UNICAST
, 1);
416 if (peer
->afc
[afi
][SAFI_MULTICAST
])
417 bgp_maximum_prefix_overflow (peer
, afi
, SAFI_MULTICAST
, 1);
418 if (peer
->afc
[afi
][SAFI_MPLS_VPN
])
419 bgp_maximum_prefix_overflow (peer
, afi
, SAFI_MPLS_VPN
, 1);
422 for (rn
= bgp_table_top (bgp
->rib
[afi
][SAFI_UNICAST
]); rn
;
423 rn
= bgp_route_next (rn
))
425 for (bi
= rn
->info
; bi
; bi
= next
)
429 if (bi
->type
== ZEBRA_ROUTE_BGP
&& bi
->sub_type
== BGP_ROUTE_NORMAL
)
434 if (peer_sort (bi
->peer
) == BGP_PEER_EBGP
&& bi
->peer
->ttl
== 1)
435 valid
= bgp_nexthop_onlink (afi
, bi
->attr
);
437 valid
= bgp_nexthop_lookup (afi
, bi
->peer
, bi
,
438 &changed
, &metricchanged
);
440 current
= CHECK_FLAG (bi
->flags
, BGP_INFO_VALID
) ? 1 : 0;
443 SET_FLAG (bi
->flags
, BGP_INFO_IGP_CHANGED
);
445 UNSET_FLAG (bi
->flags
, BGP_INFO_IGP_CHANGED
);
447 if (valid
!= current
)
449 if (CHECK_FLAG (bi
->flags
, BGP_INFO_VALID
))
451 bgp_aggregate_decrement (bgp
, &rn
->p
, bi
,
453 bgp_info_unset_flag (rn
, bi
, BGP_INFO_VALID
);
457 bgp_info_set_flag (rn
, bi
, BGP_INFO_VALID
);
458 bgp_aggregate_increment (bgp
, &rn
->p
, bi
,
463 if (CHECK_FLAG (bgp
->af_flags
[afi
][SAFI_UNICAST
],
464 BGP_CONFIG_DAMPENING
)
465 && bi
->extra
&& bi
->extra
->damp_info
)
466 if (bgp_damp_scan (bi
, afi
, SAFI_UNICAST
))
467 bgp_aggregate_increment (bgp
, &rn
->p
, bi
,
471 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
474 /* Flash old cache. */
475 if (bgp_nexthop_cache_table
[afi
] == cache1_table
[afi
])
476 bgp_nexthop_cache_reset (cache2_table
[afi
]);
478 bgp_nexthop_cache_reset (cache1_table
[afi
]);
480 if (BGP_DEBUG (events
, EVENTS
))
483 zlog_debug ("scanning IPv4 Unicast routing tables");
484 else if (afi
== AFI_IP6
)
485 zlog_debug ("scanning IPv6 Unicast routing tables");
489 /* BGP scan thread. This thread check nexthop reachability. */
491 bgp_scan_timer (struct thread
*t
)
494 thread_add_timer (master
, bgp_scan_timer
, NULL
, bgp_scan_interval
);
496 if (BGP_DEBUG (events
, EVENTS
))
497 zlog_debug ("Performing BGP general scanning");
499 bgp_scan (AFI_IP
, SAFI_UNICAST
);
502 bgp_scan (AFI_IP6
, SAFI_UNICAST
);
503 #endif /* HAVE_IPV6 */
508 struct bgp_connected_ref
514 bgp_connected_add (struct connected
*ifc
)
518 struct interface
*ifp
;
520 struct bgp_connected_ref
*bc
;
527 if (if_is_loopback (ifp
))
532 if (addr
->family
== AF_INET
)
534 PREFIX_COPY_IPV4(&p
, CONNECTED_PREFIX(ifc
));
535 apply_mask_ipv4 ((struct prefix_ipv4
*) &p
);
537 if (prefix_ipv4_any ((struct prefix_ipv4
*) &p
))
540 rn
= bgp_node_get (bgp_connected_table
[AFI_IP
], (struct prefix
*) &p
);
548 bc
= XCALLOC (MTYPE_BGP_CONN
, sizeof (struct bgp_connected_ref
));
554 else if (addr
->family
== AF_INET6
)
556 PREFIX_COPY_IPV6(&p
, CONNECTED_PREFIX(ifc
));
557 apply_mask_ipv6 ((struct prefix_ipv6
*) &p
);
559 if (IN6_IS_ADDR_UNSPECIFIED (&p
.u
.prefix6
))
562 if (IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
565 rn
= bgp_node_get (bgp_connected_table
[AFI_IP6
], (struct prefix
*) &p
);
573 bc
= XCALLOC (MTYPE_BGP_CONN
, sizeof (struct bgp_connected_ref
));
578 #endif /* HAVE_IPV6 */
582 bgp_connected_delete (struct connected
*ifc
)
586 struct interface
*ifp
;
588 struct bgp_connected_ref
*bc
;
592 if (if_is_loopback (ifp
))
597 if (addr
->family
== AF_INET
)
599 PREFIX_COPY_IPV4(&p
, CONNECTED_PREFIX(ifc
));
600 apply_mask_ipv4 ((struct prefix_ipv4
*) &p
);
602 if (prefix_ipv4_any ((struct prefix_ipv4
*) &p
))
605 rn
= bgp_node_lookup (bgp_connected_table
[AFI_IP
], &p
);
613 XFREE (MTYPE_BGP_CONN
, bc
);
616 bgp_unlock_node (rn
);
617 bgp_unlock_node (rn
);
620 else if (addr
->family
== AF_INET6
)
622 PREFIX_COPY_IPV6(&p
, CONNECTED_PREFIX(ifc
));
623 apply_mask_ipv6 ((struct prefix_ipv6
*) &p
);
625 if (IN6_IS_ADDR_UNSPECIFIED (&p
.u
.prefix6
))
628 if (IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
631 rn
= bgp_node_lookup (bgp_connected_table
[AFI_IP6
], (struct prefix
*) &p
);
639 XFREE (MTYPE_BGP_CONN
, bc
);
642 bgp_unlock_node (rn
);
643 bgp_unlock_node (rn
);
645 #endif /* HAVE_IPV6 */
649 bgp_nexthop_self (afi_t afi
, struct attr
*attr
)
651 struct listnode
*node
;
652 struct listnode
*node2
;
653 struct interface
*ifp
;
654 struct connected
*ifc
;
657 for (ALL_LIST_ELEMENTS_RO (iflist
, node
, ifp
))
659 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, node2
, ifc
))
663 if (p
&& p
->family
== AF_INET
664 && IPV4_ADDR_SAME (&p
->u
.prefix4
, &attr
->nexthop
))
671 static struct bgp_nexthop_cache
*
680 struct in_addr raddr
;
684 struct nexthop
*nexthop
;
685 struct bgp_nexthop_cache
*bnc
;
690 nbytes
= stream_read (s
, zlookup
->sock
, 2);
691 length
= stream_getw (s
);
693 nbytes
= stream_read (s
, zlookup
->sock
, length
- 2);
694 marker
= stream_getc (s
);
695 version
= stream_getc (s
);
697 if (version
!= ZSERV_VERSION
|| marker
!= ZEBRA_HEADER_MARKER
)
699 zlog_err("%s: socket %d version mismatch, marker %d, version %d",
700 __func__
, zlookup
->sock
, marker
, version
);
704 command
= stream_getw (s
);
706 raddr
.s_addr
= stream_get_ipv4 (s
);
707 metric
= stream_getl (s
);
708 nexthop_num
= stream_getc (s
);
714 bnc
->metric
= metric
;
715 bnc
->nexthop_num
= nexthop_num
;
717 for (i
= 0; i
< nexthop_num
; i
++)
719 nexthop
= XCALLOC (MTYPE_NEXTHOP
, sizeof (struct nexthop
));
720 nexthop
->type
= stream_getc (s
);
721 switch (nexthop
->type
)
723 case ZEBRA_NEXTHOP_IPV4
:
724 nexthop
->gate
.ipv4
.s_addr
= stream_get_ipv4 (s
);
726 case ZEBRA_NEXTHOP_IFINDEX
:
727 case ZEBRA_NEXTHOP_IFNAME
:
728 nexthop
->ifindex
= stream_getl (s
);
734 bnc_nexthop_add (bnc
, nexthop
);
743 struct bgp_nexthop_cache
*
744 zlookup_query (struct in_addr addr
)
750 if (zlookup
->sock
< 0)
755 zclient_create_header (s
, ZEBRA_IPV4_NEXTHOP_LOOKUP
);
756 stream_put_in_addr (s
, &addr
);
758 stream_putw_at (s
, 0, stream_get_endp (s
));
760 ret
= writen (zlookup
->sock
, s
->data
, stream_get_endp (s
));
763 zlog_err ("can't write to zlookup->sock");
764 close (zlookup
->sock
);
770 zlog_err ("zlookup->sock connection closed");
771 close (zlookup
->sock
);
776 return zlookup_read ();
780 static struct bgp_nexthop_cache
*
781 zlookup_read_ipv6 (void)
785 u_char version
, marker
;
788 struct in6_addr raddr
;
792 struct nexthop
*nexthop
;
793 struct bgp_nexthop_cache
*bnc
;
798 nbytes
= stream_read (s
, zlookup
->sock
, 2);
799 length
= stream_getw (s
);
801 nbytes
= stream_read (s
, zlookup
->sock
, length
- 2);
802 marker
= stream_getc (s
);
803 version
= stream_getc (s
);
805 if (version
!= ZSERV_VERSION
|| marker
!= ZEBRA_HEADER_MARKER
)
807 zlog_err("%s: socket %d version mismatch, marker %d, version %d",
808 __func__
, zlookup
->sock
, marker
, version
);
812 command
= stream_getw (s
);
814 stream_get (&raddr
, s
, 16);
816 metric
= stream_getl (s
);
817 nexthop_num
= stream_getc (s
);
823 bnc
->metric
= metric
;
824 bnc
->nexthop_num
= nexthop_num
;
826 for (i
= 0; i
< nexthop_num
; i
++)
828 nexthop
= XCALLOC (MTYPE_NEXTHOP
, sizeof (struct nexthop
));
829 nexthop
->type
= stream_getc (s
);
830 switch (nexthop
->type
)
832 case ZEBRA_NEXTHOP_IPV6
:
833 stream_get (&nexthop
->gate
.ipv6
, s
, 16);
835 case ZEBRA_NEXTHOP_IPV6_IFINDEX
:
836 case ZEBRA_NEXTHOP_IPV6_IFNAME
:
837 stream_get (&nexthop
->gate
.ipv6
, s
, 16);
838 nexthop
->ifindex
= stream_getl (s
);
840 case ZEBRA_NEXTHOP_IFINDEX
:
841 case ZEBRA_NEXTHOP_IFNAME
:
842 nexthop
->ifindex
= stream_getl (s
);
848 bnc_nexthop_add (bnc
, nexthop
);
857 struct bgp_nexthop_cache
*
858 zlookup_query_ipv6 (struct in6_addr
*addr
)
864 if (zlookup
->sock
< 0)
869 zclient_create_header (s
, ZEBRA_IPV6_NEXTHOP_LOOKUP
);
870 stream_put (s
, addr
, 16);
871 stream_putw_at (s
, 0, stream_get_endp (s
));
873 ret
= writen (zlookup
->sock
, s
->data
, stream_get_endp (s
));
876 zlog_err ("can't write to zlookup->sock");
877 close (zlookup
->sock
);
883 zlog_err ("zlookup->sock connection closed");
884 close (zlookup
->sock
);
889 return zlookup_read_ipv6 ();
891 #endif /* HAVE_IPV6 */
894 bgp_import_check (struct prefix
*p
, u_int32_t
*igpmetric
,
895 struct in_addr
*igpnexthop
)
899 u_int16_t length
, command
;
900 u_char version
, marker
;
903 struct in_addr nexthop
;
904 u_int32_t metric
= 0;
908 /* If lookup connection is not available return valid. */
909 if (zlookup
->sock
< 0)
916 /* Send query to the lookup connection */
919 zclient_create_header (s
, ZEBRA_IPV4_IMPORT_LOOKUP
);
921 stream_putc (s
, p
->prefixlen
);
922 stream_put_in_addr (s
, &p
->u
.prefix4
);
924 stream_putw_at (s
, 0, stream_get_endp (s
));
926 /* Write the packet. */
927 ret
= writen (zlookup
->sock
, s
->data
, stream_get_endp (s
));
931 zlog_err ("can't write to zlookup->sock");
932 close (zlookup
->sock
);
938 zlog_err ("zlookup->sock connection closed");
939 close (zlookup
->sock
);
948 nbytes
= stream_read (s
, zlookup
->sock
, 2);
949 length
= stream_getw (s
);
951 /* Fetch whole data. */
952 nbytes
= stream_read (s
, zlookup
->sock
, length
- 2);
953 marker
= stream_getc (s
);
954 version
= stream_getc (s
);
956 if (version
!= ZSERV_VERSION
|| marker
!= ZEBRA_HEADER_MARKER
)
958 zlog_err("%s: socket %d version mismatch, marker %d, version %d",
959 __func__
, zlookup
->sock
, marker
, version
);
963 command
= stream_getw (s
);
965 addr
.s_addr
= stream_get_ipv4 (s
);
966 metric
= stream_getl (s
);
967 nexthop_num
= stream_getc (s
);
969 /* Set IGP metric value. */
973 /* If there is nexthop then this is active route. */
977 nexthop_type
= stream_getc (s
);
978 if (nexthop_type
== ZEBRA_NEXTHOP_IPV4
)
980 nexthop
.s_addr
= stream_get_ipv4 (s
);
982 *igpnexthop
= nexthop
;
985 *igpnexthop
= nexthop
;
993 /* Scan all configured BGP route then check the route exists in IGP or
996 bgp_import (struct thread
*t
)
1000 struct bgp_static
*bgp_static
;
1001 struct listnode
*node
, *nnode
;
1004 struct in_addr nexthop
;
1009 thread_add_timer (master
, bgp_import
, NULL
, bgp_import_interval
);
1011 if (BGP_DEBUG (events
, EVENTS
))
1012 zlog_debug ("Import timer expired.");
1014 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
1016 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
1017 for (safi
= SAFI_UNICAST
; safi
< SAFI_MPLS_VPN
; safi
++)
1018 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
;
1019 rn
= bgp_route_next (rn
))
1020 if ((bgp_static
= rn
->info
) != NULL
)
1022 if (bgp_static
->backdoor
)
1025 valid
= bgp_static
->valid
;
1026 metric
= bgp_static
->igpmetric
;
1027 nexthop
= bgp_static
->igpnexthop
;
1029 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
)
1030 && afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1031 bgp_static
->valid
= bgp_import_check (&rn
->p
, &bgp_static
->igpmetric
,
1032 &bgp_static
->igpnexthop
);
1035 bgp_static
->valid
= 1;
1036 bgp_static
->igpmetric
= 0;
1037 bgp_static
->igpnexthop
.s_addr
= 0;
1040 if (bgp_static
->valid
!= valid
)
1042 if (bgp_static
->valid
)
1043 bgp_static_update (bgp
, &rn
->p
, bgp_static
, afi
, safi
);
1045 bgp_static_withdraw (bgp
, &rn
->p
, afi
, safi
);
1047 else if (bgp_static
->valid
)
1049 if (bgp_static
->igpmetric
!= metric
1050 || bgp_static
->igpnexthop
.s_addr
!= nexthop
.s_addr
1051 || bgp_static
->rmap
.name
)
1052 bgp_static_update (bgp
, &rn
->p
, bgp_static
, afi
, safi
);
1059 /* Connect to zebra for nexthop lookup. */
1061 zlookup_connect (struct thread
*t
)
1063 struct zclient
*zlookup
;
1065 zlookup
= THREAD_ARG (t
);
1066 zlookup
->t_connect
= NULL
;
1068 if (zlookup
->sock
!= -1)
1071 if (zclient_socket_connect (zlookup
) < 0)
1077 /* Check specified multiaccess next-hop. */
1079 bgp_multiaccess_check_v4 (struct in_addr nexthop
, char *peer
)
1081 struct bgp_node
*rn1
;
1082 struct bgp_node
*rn2
;
1085 struct in_addr addr
;
1088 ret
= inet_aton (peer
, &addr
);
1092 memset (&p1
, 0, sizeof (struct prefix
));
1093 p1
.family
= AF_INET
;
1094 p1
.prefixlen
= IPV4_MAX_BITLEN
;
1095 p1
.u
.prefix4
= nexthop
;
1096 memset (&p2
, 0, sizeof (struct prefix
));
1097 p2
.family
= AF_INET
;
1098 p2
.prefixlen
= IPV4_MAX_BITLEN
;
1099 p2
.u
.prefix4
= addr
;
1101 /* If bgp scan is not enabled, return invalid. */
1102 if (zlookup
->sock
< 0)
1105 rn1
= bgp_node_match (bgp_connected_table
[AFI_IP
], &p1
);
1108 bgp_unlock_node (rn1
);
1110 rn2
= bgp_node_match (bgp_connected_table
[AFI_IP
], &p2
);
1113 bgp_unlock_node (rn2
);
1115 /* This is safe, even with above unlocks, since we are just
1116 comparing pointers to the objects, not the objects themselves. */
1123 DEFUN (bgp_scan_time
,
1125 "bgp scan-time <5-60>",
1126 "BGP specific commands\n"
1127 "Configure background scanner interval\n"
1128 "Scanner interval (seconds)\n")
1130 bgp_scan_interval
= atoi (argv
[0]);
1132 if (bgp_scan_thread
)
1134 thread_cancel (bgp_scan_thread
);
1136 thread_add_timer (master
, bgp_scan_timer
, NULL
, bgp_scan_interval
);
1142 DEFUN (no_bgp_scan_time
,
1143 no_bgp_scan_time_cmd
,
1146 "BGP specific commands\n"
1147 "Configure background scanner interval\n")
1149 bgp_scan_interval
= BGP_SCAN_INTERVAL_DEFAULT
;
1151 if (bgp_scan_thread
)
1153 thread_cancel (bgp_scan_thread
);
1155 thread_add_timer (master
, bgp_scan_timer
, NULL
, bgp_scan_interval
);
1161 ALIAS (no_bgp_scan_time
,
1162 no_bgp_scan_time_val_cmd
,
1163 "no bgp scan-time <5-60>",
1165 "BGP specific commands\n"
1166 "Configure background scanner interval\n"
1167 "Scanner interval (seconds)\n")
1170 show_ip_bgp_scan_tables (struct vty
*vty
, const char detail
)
1172 struct bgp_node
*rn
;
1173 struct bgp_nexthop_cache
*bnc
;
1174 char buf
[INET6_ADDRSTRLEN
];
1177 if (bgp_scan_thread
)
1178 vty_out (vty
, "BGP scan is running%s", VTY_NEWLINE
);
1180 vty_out (vty
, "BGP scan is not running%s", VTY_NEWLINE
);
1181 vty_out (vty
, "BGP scan interval is %d%s", bgp_scan_interval
, VTY_NEWLINE
);
1183 vty_out (vty
, "Current BGP nexthop cache:%s", VTY_NEWLINE
);
1184 for (rn
= bgp_table_top (bgp_nexthop_cache_table
[AFI_IP
]); rn
; rn
= bgp_route_next (rn
))
1185 if ((bnc
= rn
->info
) != NULL
)
1189 vty_out (vty
, " %s valid [IGP metric %d]%s",
1190 inet_ntop (AF_INET
, &rn
->p
.u
.prefix4
, buf
, INET6_ADDRSTRLEN
), bnc
->metric
, VTY_NEWLINE
);
1192 for (i
= 0; i
< bnc
->nexthop_num
; i
++)
1193 switch (bnc
->nexthop
[i
].type
)
1195 case NEXTHOP_TYPE_IPV4
:
1196 vty_out (vty
, " gate %s%s", inet_ntop (AF_INET
, &bnc
->nexthop
[i
].gate
.ipv4
, buf
, INET6_ADDRSTRLEN
), VTY_NEWLINE
);
1198 case NEXTHOP_TYPE_IFINDEX
:
1199 vty_out (vty
, " ifidx %u%s", bnc
->nexthop
[i
].ifindex
, VTY_NEWLINE
);
1202 vty_out (vty
, " invalid nexthop type %u%s", bnc
->nexthop
[i
].type
, VTY_NEWLINE
);
1206 vty_out (vty
, " %s invalid%s",
1207 inet_ntop (AF_INET
, &rn
->p
.u
.prefix4
, buf
, INET6_ADDRSTRLEN
), VTY_NEWLINE
);
1212 for (rn
= bgp_table_top (bgp_nexthop_cache_table
[AFI_IP6
]);
1214 rn
= bgp_route_next (rn
))
1215 if ((bnc
= rn
->info
) != NULL
)
1219 vty_out (vty
, " %s valid [IGP metric %d]%s",
1220 inet_ntop (AF_INET6
, &rn
->p
.u
.prefix6
, buf
, INET6_ADDRSTRLEN
),
1221 bnc
->metric
, VTY_NEWLINE
);
1223 for (i
= 0; i
< bnc
->nexthop_num
; i
++)
1224 switch (bnc
->nexthop
[i
].type
)
1226 case NEXTHOP_TYPE_IPV6
:
1227 vty_out (vty
, " gate %s%s", inet_ntop (AF_INET6
, &bnc
->nexthop
[i
].gate
.ipv6
, buf
, INET6_ADDRSTRLEN
), VTY_NEWLINE
);
1229 case NEXTHOP_TYPE_IFINDEX
:
1230 vty_out (vty
, " ifidx %u%s", bnc
->nexthop
[i
].ifindex
, VTY_NEWLINE
);
1233 vty_out (vty
, " invalid nexthop type %u%s", bnc
->nexthop
[i
].type
, VTY_NEWLINE
);
1237 vty_out (vty
, " %s invalid%s",
1238 inet_ntop (AF_INET6
, &rn
->p
.u
.prefix6
, buf
, INET6_ADDRSTRLEN
),
1242 #endif /* HAVE_IPV6 */
1244 vty_out (vty
, "BGP connected route:%s", VTY_NEWLINE
);
1245 for (rn
= bgp_table_top (bgp_connected_table
[AFI_IP
]);
1247 rn
= bgp_route_next (rn
))
1248 if (rn
->info
!= NULL
)
1249 vty_out (vty
, " %s/%d%s", inet_ntoa (rn
->p
.u
.prefix4
), rn
->p
.prefixlen
,
1254 for (rn
= bgp_table_top (bgp_connected_table
[AFI_IP6
]);
1256 rn
= bgp_route_next (rn
))
1257 if (rn
->info
!= NULL
)
1258 vty_out (vty
, " %s/%d%s",
1259 inet_ntop (AF_INET6
, &rn
->p
.u
.prefix6
, buf
, INET6_ADDRSTRLEN
),
1263 #endif /* HAVE_IPV6 */
1268 DEFUN (show_ip_bgp_scan
,
1269 show_ip_bgp_scan_cmd
,
1274 "BGP scan status\n")
1276 return show_ip_bgp_scan_tables (vty
, 0);
1279 DEFUN (show_ip_bgp_scan_detail
,
1280 show_ip_bgp_scan_detail_cmd
,
1281 "show ip bgp scan detail",
1286 "More detailed output\n")
1288 return show_ip_bgp_scan_tables (vty
, 1);
1292 bgp_config_write_scan_time (struct vty
*vty
)
1294 if (bgp_scan_interval
!= BGP_SCAN_INTERVAL_DEFAULT
)
1295 vty_out (vty
, " bgp scan-time %d%s", bgp_scan_interval
, VTY_NEWLINE
);
1300 bgp_scan_init (void)
1302 zlookup
= zclient_new ();
1304 zlookup
->t_connect
= thread_add_event (master
, zlookup_connect
, zlookup
, 0);
1306 bgp_scan_interval
= BGP_SCAN_INTERVAL_DEFAULT
;
1307 bgp_import_interval
= BGP_IMPORT_INTERVAL_DEFAULT
;
1309 cache1_table
[AFI_IP
] = bgp_table_init (AFI_IP
, SAFI_UNICAST
);
1310 cache2_table
[AFI_IP
] = bgp_table_init (AFI_IP
, SAFI_UNICAST
);
1311 bgp_nexthop_cache_table
[AFI_IP
] = cache1_table
[AFI_IP
];
1313 bgp_connected_table
[AFI_IP
] = bgp_table_init (AFI_IP
, SAFI_UNICAST
);
1316 cache1_table
[AFI_IP6
] = bgp_table_init (AFI_IP6
, SAFI_UNICAST
);
1317 cache2_table
[AFI_IP6
] = bgp_table_init (AFI_IP6
, SAFI_UNICAST
);
1318 bgp_nexthop_cache_table
[AFI_IP6
] = cache1_table
[AFI_IP6
];
1319 bgp_connected_table
[AFI_IP6
] = bgp_table_init (AFI_IP6
, SAFI_UNICAST
);
1320 #endif /* HAVE_IPV6 */
1322 /* Make BGP scan thread. */
1323 bgp_scan_thread
= thread_add_timer (master
, bgp_scan_timer
,
1324 NULL
, bgp_scan_interval
);
1325 /* Make BGP import there. */
1326 bgp_import_thread
= thread_add_timer (master
, bgp_import
, NULL
, 0);
1328 install_element (BGP_NODE
, &bgp_scan_time_cmd
);
1329 install_element (BGP_NODE
, &no_bgp_scan_time_cmd
);
1330 install_element (BGP_NODE
, &no_bgp_scan_time_val_cmd
);
1331 install_element (VIEW_NODE
, &show_ip_bgp_scan_cmd
);
1332 install_element (VIEW_NODE
, &show_ip_bgp_scan_detail_cmd
);
1333 install_element (RESTRICTED_NODE
, &show_ip_bgp_scan_cmd
);
1334 install_element (ENABLE_NODE
, &show_ip_bgp_scan_cmd
);
1335 install_element (ENABLE_NODE
, &show_ip_bgp_scan_detail_cmd
);
1339 bgp_scan_finish (void)
1341 /* Only the current one needs to be reset. */
1342 bgp_nexthop_cache_reset (bgp_nexthop_cache_table
[AFI_IP
]);
1344 bgp_table_unlock (cache1_table
[AFI_IP
]);
1345 cache1_table
[AFI_IP
] = NULL
;
1347 bgp_table_unlock (cache2_table
[AFI_IP
]);
1348 cache2_table
[AFI_IP
] = NULL
;
1350 bgp_table_unlock (bgp_connected_table
[AFI_IP
]);
1351 bgp_connected_table
[AFI_IP
] = NULL
;
1354 /* Only the current one needs to be reset. */
1355 bgp_nexthop_cache_reset (bgp_nexthop_cache_table
[AFI_IP6
]);
1357 bgp_table_unlock (cache1_table
[AFI_IP6
]);
1358 cache1_table
[AFI_IP6
] = NULL
;
1360 bgp_table_unlock (cache2_table
[AFI_IP6
]);
1361 cache2_table
[AFI_IP6
] = NULL
;
1363 bgp_table_unlock (bgp_connected_table
[AFI_IP6
]);
1364 bgp_connected_table
[AFI_IP6
] = NULL
;
1365 #endif /* HAVE_IPV6 */