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
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_nht.h"
41 #include "bgpd/bgp_debug.h"
42 #include "bgpd/bgp_damp.h"
43 #include "zebra/rib.h"
44 #include "zebra/zserv.h" /* For ZEBRA_SERV_PATH. */
46 extern struct zclient
*zclient
;
48 struct bgp_nexthop_cache
*zlookup_query (struct in_addr
);
50 struct bgp_nexthop_cache
*zlookup_query_ipv6 (struct in6_addr
*);
51 #endif /* HAVE_IPV6 */
53 /* Only one BGP scan thread are activated at the same time. */
54 static struct thread
*bgp_scan_thread
= NULL
;
56 /* BGP import thread */
57 static struct thread
*bgp_import_thread
= NULL
;
59 /* BGP scan interval. */
60 static int bgp_scan_interval
;
62 /* BGP import interval. */
63 static int bgp_import_interval
;
65 /* Route table for next-hop lookup cache. */
66 struct bgp_table
*bgp_nexthop_cache_table
[AFI_MAX
];
67 static struct bgp_table
*cache1_table
[AFI_MAX
];
68 static struct bgp_table
*cache2_table
[AFI_MAX
];
70 /* Route table for connected route. */
71 static struct bgp_table
*bgp_connected_table
[AFI_MAX
];
73 /* BGP nexthop lookup query client. */
74 struct zclient
*zlookup
= NULL
;
77 bnc_str (struct bgp_nexthop_cache
*bnc
, char *buf
, int size
)
79 prefix2str(&(bnc
->node
->p
), buf
, size
);
83 /* Add nexthop to the end of the list. */
85 bnc_nexthop_add (struct bgp_nexthop_cache
*bnc
, struct nexthop
*nexthop
)
89 for (last
= bnc
->nexthop
; last
&& last
->next
; last
= last
->next
)
94 bnc
->nexthop
= nexthop
;
99 bnc_nexthop_free (struct bgp_nexthop_cache
*bnc
)
101 struct nexthop
*nexthop
;
102 struct nexthop
*next
= NULL
;
104 for (nexthop
= bnc
->nexthop
; nexthop
; nexthop
= next
)
106 next
= nexthop
->next
;
107 XFREE (MTYPE_NEXTHOP
, nexthop
);
111 struct bgp_nexthop_cache
*
114 struct bgp_nexthop_cache
*bnc
;
116 bnc
= XCALLOC (MTYPE_BGP_NEXTHOP_CACHE
, sizeof (struct bgp_nexthop_cache
));
117 LIST_INIT(&(bnc
->paths
));
122 bnc_free (struct bgp_nexthop_cache
*bnc
)
124 bnc_nexthop_free (bnc
);
125 XFREE (MTYPE_BGP_NEXTHOP_CACHE
, bnc
);
129 bgp_nexthop_cache_different (struct bgp_nexthop_cache
*bnc1
,
130 struct bgp_nexthop_cache
*bnc2
)
133 struct nexthop
*next1
, *next2
;
135 if (bnc1
->nexthop_num
!= bnc2
->nexthop_num
)
138 next1
= bnc1
->nexthop
;
139 next2
= bnc2
->nexthop
;
141 for (i
= 0; i
< bnc1
->nexthop_num
; i
++)
143 if (! nexthop_same_no_recurse (next1
, next2
))
152 /* If nexthop exists on connected network return 1. */
154 bgp_nexthop_onlink (afi_t afi
, struct attr
*attr
)
158 /* If zebra is not enabled return */
159 if (zlookup
->sock
< 0)
162 /* Lookup the address is onlink or not. */
165 rn
= bgp_node_match_ipv4 (bgp_connected_table
[AFI_IP
], &attr
->nexthop
);
168 bgp_unlock_node (rn
);
173 else if (afi
== AFI_IP6
)
175 if (attr
->extra
->mp_nexthop_len
== 32)
177 else if (attr
->extra
->mp_nexthop_len
== 16)
179 if (IN6_IS_ADDR_LINKLOCAL (&attr
->extra
->mp_nexthop_global
))
182 rn
= bgp_node_match_ipv6 (bgp_connected_table
[AFI_IP6
],
183 &attr
->extra
->mp_nexthop_global
);
186 bgp_unlock_node (rn
);
191 #endif /* HAVE_IPV6 */
196 /* Check specified next-hop is reachable or not. */
198 bgp_nexthop_lookup_ipv6 (struct peer
*peer
, struct bgp_info
*ri
, int *changed
,
203 struct bgp_nexthop_cache
*bnc
;
206 /* If lookup is not enabled, return valid. */
207 if (zlookup
->sock
< 0)
210 ri
->extra
->igpmetric
= 0;
214 /* Only check IPv6 global address only nexthop. */
217 if (attr
->extra
->mp_nexthop_len
!= 16
218 || IN6_IS_ADDR_LINKLOCAL (&attr
->extra
->mp_nexthop_global
))
221 memset (&p
, 0, sizeof (struct prefix
));
223 p
.prefixlen
= IPV6_MAX_BITLEN
;
224 p
.u
.prefix6
= attr
->extra
->mp_nexthop_global
;
226 /* IBGP or ebgp-multihop */
227 rn
= bgp_node_get (bgp_nexthop_cache_table
[AFI_IP6
], &p
);
232 bgp_unlock_node (rn
);
236 if (NULL
== (bnc
= zlookup_query_ipv6 (&attr
->extra
->mp_nexthop_global
)))
242 struct bgp_table
*old
;
243 struct bgp_node
*oldrn
;
245 if (bgp_nexthop_cache_table
[AFI_IP6
] == cache1_table
[AFI_IP6
])
246 old
= cache2_table
[AFI_IP6
];
248 old
= cache1_table
[AFI_IP6
];
250 oldrn
= bgp_node_lookup (old
, &p
);
253 struct bgp_nexthop_cache
*oldbnc
= oldrn
->info
;
255 bnc
->changed
= bgp_nexthop_cache_different (bnc
, oldbnc
);
257 if (bnc
->metric
!= oldbnc
->metric
)
258 bnc
->metricchanged
= 1;
260 bgp_unlock_node (oldrn
);
268 *changed
= bnc
->changed
;
271 *metricchanged
= bnc
->metricchanged
;
273 if (bnc
->valid
&& bnc
->metric
)
274 (bgp_info_extra_get (ri
))->igpmetric
= bnc
->metric
;
276 ri
->extra
->igpmetric
= 0;
280 #endif /* HAVE_IPV6 */
282 /* Check specified next-hop is reachable or not. */
284 bgp_nexthop_lookup (afi_t afi
, struct peer
*peer
, struct bgp_info
*ri
,
285 int *changed
, int *metricchanged
)
289 struct bgp_nexthop_cache
*bnc
;
292 /* If lookup is not enabled, return valid. */
293 if (zlookup
->sock
< 0)
296 ri
->extra
->igpmetric
= 0;
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
;
399 if (bgp_nexthop_cache_table
[afi
] == cache1_table
[afi
])
400 bgp_nexthop_cache_table
[afi
] = cache2_table
[afi
];
402 bgp_nexthop_cache_table
[afi
] = cache1_table
[afi
];
405 /* Get default bgp. */
406 bgp
= bgp_get_default ();
410 /* Maximum prefix check */
411 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
413 if (peer
->status
!= Established
)
416 if (peer
->afc
[afi
][SAFI_UNICAST
])
417 bgp_maximum_prefix_overflow (peer
, afi
, SAFI_UNICAST
, 1);
418 if (peer
->afc
[afi
][SAFI_MULTICAST
])
419 bgp_maximum_prefix_overflow (peer
, afi
, SAFI_MULTICAST
, 1);
420 if (peer
->afc
[afi
][SAFI_MPLS_VPN
])
421 bgp_maximum_prefix_overflow (peer
, afi
, SAFI_MPLS_VPN
, 1);
424 for (rn
= bgp_table_top (bgp
->rib
[afi
][SAFI_UNICAST
]); rn
;
425 rn
= bgp_route_next (rn
))
427 for (bi
= rn
->info
; bi
; bi
= next
)
431 if (bi
->type
== ZEBRA_ROUTE_BGP
&& bi
->sub_type
== BGP_ROUTE_NORMAL
)
437 if (bi
->peer
->sort
== BGP_PEER_EBGP
&& bi
->peer
->ttl
== 1
438 && !CHECK_FLAG(bi
->peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
))
439 valid
= bgp_nexthop_onlink (afi
, bi
->attr
);
441 valid
= bgp_nexthop_lookup (afi
, bi
->peer
, bi
,
442 &changed
, &metricchanged
);
444 current
= CHECK_FLAG (bi
->flags
, BGP_INFO_VALID
) ? 1 : 0;
447 SET_FLAG (bi
->flags
, BGP_INFO_IGP_CHANGED
);
449 UNSET_FLAG (bi
->flags
, BGP_INFO_IGP_CHANGED
);
451 if (valid
!= current
)
453 if (CHECK_FLAG (bi
->flags
, BGP_INFO_VALID
))
455 bgp_aggregate_decrement (bgp
, &rn
->p
, bi
,
457 bgp_info_unset_flag (rn
, bi
, BGP_INFO_VALID
);
461 bgp_info_set_flag (rn
, bi
, BGP_INFO_VALID
);
462 bgp_aggregate_increment (bgp
, &rn
->p
, bi
,
468 if (CHECK_FLAG (bgp
->af_flags
[afi
][SAFI_UNICAST
],
469 BGP_CONFIG_DAMPENING
)
470 && bi
->extra
&& bi
->extra
->damp_info
)
471 if (bgp_damp_scan (bi
, afi
, SAFI_UNICAST
))
472 bgp_aggregate_increment (bgp
, &rn
->p
, bi
,
476 bgp_process (bgp
, rn
, afi
, SAFI_UNICAST
);
480 /* Flash old cache. */
481 if (bgp_nexthop_cache_table
[afi
] == cache1_table
[afi
])
482 bgp_nexthop_cache_reset (cache2_table
[afi
]);
484 bgp_nexthop_cache_reset (cache1_table
[afi
]);
487 if (BGP_DEBUG (events
, EVENTS
))
490 zlog_debug ("scanning IPv4 Unicast routing tables");
491 else if (afi
== AFI_IP6
)
492 zlog_debug ("scanning IPv6 Unicast routing tables");
495 /* Reevaluate default-originate route-maps and announce/withdraw
496 * default route if neccesary. */
497 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
499 if (peer
->status
== Established
500 && CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_DEFAULT_ORIGINATE
)
501 && peer
->default_rmap
[afi
][safi
].name
)
502 bgp_default_originate (peer
, afi
, safi
, 0);
506 /* BGP scan thread. This thread check nexthop reachability. */
508 bgp_scan_timer (struct thread
*t
)
511 thread_add_timer (master
, bgp_scan_timer
, NULL
, bgp_scan_interval
);
513 if (BGP_DEBUG (events
, EVENTS
))
514 zlog_debug ("Performing BGP general scanning");
516 bgp_scan (AFI_IP
, SAFI_UNICAST
);
519 bgp_scan (AFI_IP6
, SAFI_UNICAST
);
520 #endif /* HAVE_IPV6 */
525 /* BGP own address structure */
532 static struct hash
*bgp_address_hash
;
535 bgp_address_hash_alloc (void *p
)
537 struct in_addr
*val
= p
;
538 struct bgp_addr
*addr
;
540 addr
= XMALLOC (MTYPE_BGP_ADDR
, sizeof (struct bgp_addr
));
542 addr
->addr
.s_addr
= val
->s_addr
;
548 bgp_address_hash_key_make (void *p
)
550 const struct bgp_addr
*addr
= p
;
552 return jhash_1word(addr
->addr
.s_addr
, 0);
556 bgp_address_hash_cmp (const void *p1
, const void *p2
)
558 const struct bgp_addr
*addr1
= p1
;
559 const struct bgp_addr
*addr2
= p2
;
561 return addr1
->addr
.s_addr
== addr2
->addr
.s_addr
;
565 bgp_address_init (void)
567 bgp_address_hash
= hash_create (bgp_address_hash_key_make
,
568 bgp_address_hash_cmp
);
572 bgp_address_add (struct prefix
*p
)
575 struct bgp_addr
*addr
;
577 tmp
.addr
= p
->u
.prefix4
;
579 addr
= hash_get (bgp_address_hash
, &tmp
, bgp_address_hash_alloc
);
587 bgp_address_del (struct prefix
*p
)
590 struct bgp_addr
*addr
;
592 tmp
.addr
= p
->u
.prefix4
;
594 addr
= hash_lookup (bgp_address_hash
, &tmp
);
595 /* may have been deleted earlier by bgp_interface_down() */
601 if (addr
->refcnt
== 0)
603 hash_release (bgp_address_hash
, addr
);
604 XFREE (MTYPE_BGP_ADDR
, addr
);
609 struct bgp_connected_ref
615 bgp_connected_add (struct connected
*ifc
)
619 struct interface
*ifp
;
621 struct bgp_connected_ref
*bc
;
628 if (if_is_loopback (ifp
))
633 if (addr
->family
== AF_INET
)
635 PREFIX_COPY_IPV4(&p
, CONNECTED_PREFIX(ifc
));
636 apply_mask_ipv4 ((struct prefix_ipv4
*) &p
);
638 if (prefix_ipv4_any ((struct prefix_ipv4
*) &p
))
641 bgp_address_add (addr
);
643 rn
= bgp_node_get (bgp_connected_table
[AFI_IP
], (struct prefix
*) &p
);
651 bc
= XCALLOC (MTYPE_BGP_CONN
, sizeof (struct bgp_connected_ref
));
657 else if (addr
->family
== AF_INET6
)
659 PREFIX_COPY_IPV6(&p
, CONNECTED_PREFIX(ifc
));
660 apply_mask_ipv6 ((struct prefix_ipv6
*) &p
);
662 if (IN6_IS_ADDR_UNSPECIFIED (&p
.u
.prefix6
))
665 if (IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
668 rn
= bgp_node_get (bgp_connected_table
[AFI_IP6
], (struct prefix
*) &p
);
676 bc
= XCALLOC (MTYPE_BGP_CONN
, sizeof (struct bgp_connected_ref
));
681 #endif /* HAVE_IPV6 */
685 bgp_connected_delete (struct connected
*ifc
)
689 struct interface
*ifp
;
691 struct bgp_connected_ref
*bc
;
695 if (if_is_loopback (ifp
))
700 if (addr
->family
== AF_INET
)
702 PREFIX_COPY_IPV4(&p
, CONNECTED_PREFIX(ifc
));
703 apply_mask_ipv4 ((struct prefix_ipv4
*) &p
);
705 if (prefix_ipv4_any ((struct prefix_ipv4
*) &p
))
708 bgp_address_del (addr
);
710 rn
= bgp_node_lookup (bgp_connected_table
[AFI_IP
], &p
);
718 XFREE (MTYPE_BGP_CONN
, bc
);
721 bgp_unlock_node (rn
);
722 bgp_unlock_node (rn
);
725 else if (addr
->family
== AF_INET6
)
727 PREFIX_COPY_IPV6(&p
, CONNECTED_PREFIX(ifc
));
728 apply_mask_ipv6 ((struct prefix_ipv6
*) &p
);
730 if (IN6_IS_ADDR_UNSPECIFIED (&p
.u
.prefix6
))
733 if (IN6_IS_ADDR_LINKLOCAL (&p
.u
.prefix6
))
736 rn
= bgp_node_lookup (bgp_connected_table
[AFI_IP6
], (struct prefix
*) &p
);
744 XFREE (MTYPE_BGP_CONN
, bc
);
747 bgp_unlock_node (rn
);
748 bgp_unlock_node (rn
);
750 #endif /* HAVE_IPV6 */
754 bgp_nexthop_self (struct attr
*attr
)
756 struct bgp_addr tmp
, *addr
;
758 tmp
.addr
= attr
->nexthop
;
760 addr
= hash_lookup (bgp_address_hash
, &tmp
);
767 static struct bgp_nexthop_cache
*
776 struct in_addr raddr
;
780 struct nexthop
*nexthop
;
781 struct bgp_nexthop_cache
*bnc
;
786 nbytes
= stream_read (s
, zlookup
->sock
, 2);
787 length
= stream_getw (s
);
789 nbytes
= stream_read (s
, zlookup
->sock
, length
- 2);
790 marker
= stream_getc (s
);
791 version
= stream_getc (s
);
793 if (version
!= ZSERV_VERSION
|| marker
!= ZEBRA_HEADER_MARKER
)
795 zlog_err("%s: socket %d version mismatch, marker %d, version %d",
796 __func__
, zlookup
->sock
, marker
, version
);
800 command
= stream_getw (s
);
802 raddr
.s_addr
= stream_get_ipv4 (s
);
803 metric
= stream_getl (s
);
804 nexthop_num
= stream_getc (s
);
810 bnc
->metric
= metric
;
811 bnc
->nexthop_num
= nexthop_num
;
813 for (i
= 0; i
< nexthop_num
; i
++)
815 nexthop
= XCALLOC (MTYPE_NEXTHOP
, sizeof (struct nexthop
));
816 nexthop
->type
= stream_getc (s
);
817 switch (nexthop
->type
)
819 case ZEBRA_NEXTHOP_IPV4
:
820 nexthop
->gate
.ipv4
.s_addr
= stream_get_ipv4 (s
);
822 case ZEBRA_NEXTHOP_IPV4_IFINDEX
:
823 nexthop
->gate
.ipv4
.s_addr
= stream_get_ipv4 (s
);
824 nexthop
->ifindex
= stream_getl (s
);
826 case ZEBRA_NEXTHOP_IFINDEX
:
827 case ZEBRA_NEXTHOP_IFNAME
:
828 nexthop
->ifindex
= stream_getl (s
);
834 bnc_nexthop_add (bnc
, nexthop
);
843 struct bgp_nexthop_cache
*
844 zlookup_query (struct in_addr addr
)
850 if (zlookup
->sock
< 0)
855 zclient_create_header (s
, ZEBRA_IPV4_NEXTHOP_LOOKUP
);
856 stream_put_in_addr (s
, &addr
);
858 stream_putw_at (s
, 0, stream_get_endp (s
));
860 ret
= writen (zlookup
->sock
, s
->data
, stream_get_endp (s
));
863 zlog_err ("can't write to zlookup->sock");
864 close (zlookup
->sock
);
870 zlog_err ("zlookup->sock connection closed");
871 close (zlookup
->sock
);
876 return zlookup_read ();
880 static struct bgp_nexthop_cache
*
881 zlookup_read_ipv6 (void)
885 u_char version
, marker
;
888 struct in6_addr raddr
;
892 struct nexthop
*nexthop
;
893 struct bgp_nexthop_cache
*bnc
;
898 nbytes
= stream_read (s
, zlookup
->sock
, 2);
899 length
= stream_getw (s
);
901 nbytes
= stream_read (s
, zlookup
->sock
, length
- 2);
902 marker
= stream_getc (s
);
903 version
= stream_getc (s
);
905 if (version
!= ZSERV_VERSION
|| marker
!= ZEBRA_HEADER_MARKER
)
907 zlog_err("%s: socket %d version mismatch, marker %d, version %d",
908 __func__
, zlookup
->sock
, marker
, version
);
912 command
= stream_getw (s
);
914 stream_get (&raddr
, s
, 16);
916 metric
= stream_getl (s
);
917 nexthop_num
= stream_getc (s
);
923 bnc
->metric
= metric
;
924 bnc
->nexthop_num
= nexthop_num
;
926 for (i
= 0; i
< nexthop_num
; i
++)
928 nexthop
= XCALLOC (MTYPE_NEXTHOP
, sizeof (struct nexthop
));
929 nexthop
->type
= stream_getc (s
);
930 switch (nexthop
->type
)
932 case ZEBRA_NEXTHOP_IPV6
:
933 stream_get (&nexthop
->gate
.ipv6
, s
, 16);
935 case ZEBRA_NEXTHOP_IPV6_IFINDEX
:
936 case ZEBRA_NEXTHOP_IPV6_IFNAME
:
937 stream_get (&nexthop
->gate
.ipv6
, s
, 16);
938 nexthop
->ifindex
= stream_getl (s
);
940 case ZEBRA_NEXTHOP_IFINDEX
:
941 case ZEBRA_NEXTHOP_IFNAME
:
942 nexthop
->ifindex
= stream_getl (s
);
948 bnc_nexthop_add (bnc
, nexthop
);
957 struct bgp_nexthop_cache
*
958 zlookup_query_ipv6 (struct in6_addr
*addr
)
964 if (zlookup
->sock
< 0)
969 zclient_create_header (s
, ZEBRA_IPV6_NEXTHOP_LOOKUP
);
970 stream_put (s
, addr
, 16);
971 stream_putw_at (s
, 0, stream_get_endp (s
));
973 ret
= writen (zlookup
->sock
, s
->data
, stream_get_endp (s
));
976 zlog_err ("can't write to zlookup->sock");
977 close (zlookup
->sock
);
983 zlog_err ("zlookup->sock connection closed");
984 close (zlookup
->sock
);
989 return zlookup_read_ipv6 ();
991 #endif /* HAVE_IPV6 */
994 bgp_import_check (struct prefix
*p
, u_int32_t
*igpmetric
,
995 struct in_addr
*igpnexthop
)
999 u_int16_t length
, command
;
1000 u_char version
, marker
;
1002 struct in_addr addr
;
1003 struct in_addr nexthop
;
1004 u_int32_t metric
= 0;
1006 u_char nexthop_type
;
1008 /* If lookup connection is not available return valid. */
1009 if (zlookup
->sock
< 0)
1016 /* Send query to the lookup connection */
1019 zclient_create_header (s
, ZEBRA_IPV4_IMPORT_LOOKUP
);
1021 stream_putc (s
, p
->prefixlen
);
1022 stream_put_in_addr (s
, &p
->u
.prefix4
);
1024 stream_putw_at (s
, 0, stream_get_endp (s
));
1026 /* Write the packet. */
1027 ret
= writen (zlookup
->sock
, s
->data
, stream_get_endp (s
));
1031 zlog_err ("can't write to zlookup->sock");
1032 close (zlookup
->sock
);
1038 zlog_err ("zlookup->sock connection closed");
1039 close (zlookup
->sock
);
1048 nbytes
= stream_read (s
, zlookup
->sock
, 2);
1049 length
= stream_getw (s
);
1051 /* Fetch whole data. */
1052 nbytes
= stream_read (s
, zlookup
->sock
, length
- 2);
1053 marker
= stream_getc (s
);
1054 version
= stream_getc (s
);
1056 if (version
!= ZSERV_VERSION
|| marker
!= ZEBRA_HEADER_MARKER
)
1058 zlog_err("%s: socket %d version mismatch, marker %d, version %d",
1059 __func__
, zlookup
->sock
, marker
, version
);
1063 command
= stream_getw (s
);
1065 addr
.s_addr
= stream_get_ipv4 (s
);
1066 metric
= stream_getl (s
);
1067 nexthop_num
= stream_getc (s
);
1069 /* Set IGP metric value. */
1071 *igpmetric
= metric
;
1073 /* If there is nexthop then this is active route. */
1077 nexthop_type
= stream_getc (s
);
1078 switch (nexthop_type
)
1080 case ZEBRA_NEXTHOP_IPV4
:
1081 nexthop
.s_addr
= stream_get_ipv4 (s
);
1083 case ZEBRA_NEXTHOP_IPV4_IFINDEX
:
1084 nexthop
.s_addr
= stream_get_ipv4 (s
);
1085 /* ifindex */ (void)stream_getl (s
);
1091 *igpnexthop
= nexthop
;
1099 /* Scan all configured BGP route then check the route exists in IGP or
1102 bgp_import (struct thread
*t
)
1105 struct bgp_node
*rn
;
1106 struct bgp_static
*bgp_static
;
1107 struct listnode
*node
, *nnode
;
1110 struct in_addr nexthop
;
1115 thread_add_timer (master
, bgp_import
, NULL
, bgp_import_interval
);
1117 if (BGP_DEBUG (events
, EVENTS
))
1118 zlog_debug ("Import timer expired.");
1120 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
1122 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
1123 for (safi
= SAFI_UNICAST
; safi
< SAFI_MPLS_VPN
; safi
++)
1124 for (rn
= bgp_table_top (bgp
->route
[afi
][safi
]); rn
;
1125 rn
= bgp_route_next (rn
))
1126 if ((bgp_static
= rn
->info
) != NULL
)
1128 if (bgp_static
->backdoor
)
1131 valid
= bgp_static
->valid
;
1132 metric
= bgp_static
->igpmetric
;
1133 nexthop
= bgp_static
->igpnexthop
;
1135 if (bgp_flag_check (bgp
, BGP_FLAG_IMPORT_CHECK
)
1136 && afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1137 bgp_static
->valid
= bgp_import_check (&rn
->p
, &bgp_static
->igpmetric
,
1138 &bgp_static
->igpnexthop
);
1141 bgp_static
->valid
= 1;
1142 bgp_static
->igpmetric
= 0;
1143 bgp_static
->igpnexthop
.s_addr
= 0;
1146 if (bgp_static
->valid
!= valid
)
1148 if (bgp_static
->valid
)
1149 bgp_static_update (bgp
, &rn
->p
, bgp_static
, afi
, safi
);
1151 bgp_static_withdraw (bgp
, &rn
->p
, afi
, safi
);
1153 else if (bgp_static
->valid
)
1155 if (bgp_static
->igpmetric
!= metric
1156 || bgp_static
->igpnexthop
.s_addr
!= nexthop
.s_addr
1157 || bgp_static
->rmap
.name
)
1158 bgp_static_update (bgp
, &rn
->p
, bgp_static
, afi
, safi
);
1165 /* Connect to zebra for nexthop lookup. */
1167 zlookup_connect (struct thread
*t
)
1169 struct zclient
*zlookup
;
1171 zlookup
= THREAD_ARG (t
);
1172 zlookup
->t_connect
= NULL
;
1174 if (zlookup
->sock
!= -1)
1177 if (zclient_socket_connect (zlookup
) < 0)
1183 /* Check specified multiaccess next-hop. */
1185 bgp_multiaccess_check_v4 (struct in_addr nexthop
, char *peer
)
1187 struct bgp_node
*rn1
;
1188 struct bgp_node
*rn2
;
1191 struct in_addr addr
;
1194 ret
= inet_aton (peer
, &addr
);
1198 memset (&p1
, 0, sizeof (struct prefix
));
1199 p1
.family
= AF_INET
;
1200 p1
.prefixlen
= IPV4_MAX_BITLEN
;
1201 p1
.u
.prefix4
= nexthop
;
1202 memset (&p2
, 0, sizeof (struct prefix
));
1203 p2
.family
= AF_INET
;
1204 p2
.prefixlen
= IPV4_MAX_BITLEN
;
1205 p2
.u
.prefix4
= addr
;
1207 /* If bgp scan is not enabled, return invalid. */
1208 if (zlookup
->sock
< 0)
1211 rn1
= bgp_node_match (bgp_connected_table
[AFI_IP
], &p1
);
1214 bgp_unlock_node (rn1
);
1216 rn2
= bgp_node_match (bgp_connected_table
[AFI_IP
], &p2
);
1219 bgp_unlock_node (rn2
);
1221 /* This is safe, even with above unlocks, since we are just
1222 comparing pointers to the objects, not the objects themselves. */
1229 DEFUN (bgp_scan_time
,
1231 "bgp scan-time <5-60>",
1232 "BGP specific commands\n"
1233 "Configure background scanner interval\n"
1234 "Scanner interval (seconds)\n")
1236 bgp_scan_interval
= atoi (argv
[0]);
1238 if (bgp_scan_thread
)
1240 thread_cancel (bgp_scan_thread
);
1242 thread_add_timer (master
, bgp_scan_timer
, NULL
, bgp_scan_interval
);
1248 DEFUN (no_bgp_scan_time
,
1249 no_bgp_scan_time_cmd
,
1252 "BGP specific commands\n"
1253 "Configure background scanner interval\n")
1255 bgp_scan_interval
= BGP_SCAN_INTERVAL_DEFAULT
;
1257 if (bgp_scan_thread
)
1259 thread_cancel (bgp_scan_thread
);
1261 thread_add_timer (master
, bgp_scan_timer
, NULL
, bgp_scan_interval
);
1267 ALIAS (no_bgp_scan_time
,
1268 no_bgp_scan_time_val_cmd
,
1269 "no bgp scan-time <5-60>",
1271 "BGP specific commands\n"
1272 "Configure background scanner interval\n"
1273 "Scanner interval (seconds)\n")
1276 show_ip_bgp_scan_tables (struct vty
*vty
, const char detail
)
1278 struct bgp_node
*rn
;
1279 char buf
[INET6_ADDRSTRLEN
];
1280 struct nexthop
*nexthop
;
1282 if (bgp_scan_thread
)
1283 vty_out (vty
, "BGP scan is running%s", VTY_NEWLINE
);
1285 vty_out (vty
, "BGP scan is not running%s", VTY_NEWLINE
);
1286 vty_out (vty
, "BGP scan interval is %d%s", bgp_scan_interval
, VTY_NEWLINE
);
1288 #if BGP_SCAN_NEXTHOP
1289 vty_out (vty
, "Current BGP nexthop cache:%s", VTY_NEWLINE
);
1290 for (rn
= bgp_table_top (bgp_nexthop_cache_table
[AFI_IP
]); rn
; rn
= bgp_route_next (rn
))
1291 if ((bnc
= rn
->info
) != NULL
)
1295 vty_out (vty
, " %s valid [IGP metric %d]%s",
1296 inet_ntop (AF_INET
, &rn
->p
.u
.prefix4
, buf
, INET6_ADDRSTRLEN
), bnc
->metric
, VTY_NEWLINE
);
1298 for (nexthop
= bnc
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
1299 switch (nexthop
->type
)
1301 case NEXTHOP_TYPE_IPV4
:
1302 vty_out (vty
, " gate %s%s", inet_ntop (AF_INET
, &nexthop
->gate
.ipv4
, buf
, INET6_ADDRSTRLEN
), VTY_NEWLINE
);
1304 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1305 vty_out (vty
, " gate %s", inet_ntop (AF_INET
, &nexthop
->gate
.ipv4
, buf
, INET6_ADDRSTRLEN
));
1306 vty_out (vty
, " ifidx %u%s", nexthop
->ifindex
, VTY_NEWLINE
);
1308 case NEXTHOP_TYPE_IFINDEX
:
1309 vty_out (vty
, " ifidx %u%s", nexthop
->ifindex
, VTY_NEWLINE
);
1312 vty_out (vty
, " invalid nexthop type %u%s", nexthop
->type
, VTY_NEWLINE
);
1316 vty_out (vty
, " %s invalid%s",
1317 inet_ntop (AF_INET
, &rn
->p
.u
.prefix4
, buf
, INET6_ADDRSTRLEN
), VTY_NEWLINE
);
1322 for (rn
= bgp_table_top (bgp_nexthop_cache_table
[AFI_IP6
]);
1324 rn
= bgp_route_next (rn
))
1325 if ((bnc
= rn
->info
) != NULL
)
1329 vty_out (vty
, " %s valid [IGP metric %d]%s",
1330 inet_ntop (AF_INET6
, &rn
->p
.u
.prefix6
, buf
, INET6_ADDRSTRLEN
),
1331 bnc
->metric
, VTY_NEWLINE
);
1333 for (nexthop
= bnc
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
1334 switch (nexthop
->type
)
1336 case NEXTHOP_TYPE_IPV6
:
1337 vty_out (vty
, " gate %s%s", inet_ntop (AF_INET6
, &nexthop
->gate
.ipv6
, buf
, INET6_ADDRSTRLEN
), VTY_NEWLINE
);
1339 case NEXTHOP_TYPE_IFINDEX
:
1340 vty_out (vty
, " ifidx %u%s", nexthop
->ifindex
, VTY_NEWLINE
);
1343 vty_out (vty
, " invalid nexthop type %u%s", nexthop
->type
, VTY_NEWLINE
);
1347 vty_out (vty
, " %s invalid%s",
1348 inet_ntop (AF_INET6
, &rn
->p
.u
.prefix6
, buf
, INET6_ADDRSTRLEN
),
1352 #endif /* HAVE_IPV6 */
1354 vty_out (vty
, "BGP next-hop tracking is on%s", VTY_NEWLINE
);
1356 vty_out (vty
, "BGP connected route:%s", VTY_NEWLINE
);
1357 for (rn
= bgp_table_top (bgp_connected_table
[AFI_IP
]);
1359 rn
= bgp_route_next (rn
))
1360 if (rn
->info
!= NULL
)
1361 vty_out (vty
, " %s/%d%s", inet_ntoa (rn
->p
.u
.prefix4
), rn
->p
.prefixlen
,
1366 for (rn
= bgp_table_top (bgp_connected_table
[AFI_IP6
]);
1368 rn
= bgp_route_next (rn
))
1369 if (rn
->info
!= NULL
)
1370 vty_out (vty
, " %s/%d%s",
1371 inet_ntop (AF_INET6
, &rn
->p
.u
.prefix6
, buf
, INET6_ADDRSTRLEN
),
1375 #endif /* HAVE_IPV6 */
1381 show_ip_bgp_nexthop_table (struct vty
*vty
, int detail
)
1383 struct bgp_node
*rn
;
1384 struct bgp_nexthop_cache
*bnc
;
1385 char buf
[INET6_ADDRSTRLEN
];
1386 struct nexthop
*nexthop
;
1390 vty_out (vty
, "Current BGP nexthop cache:%s", VTY_NEWLINE
);
1391 for (rn
= bgp_table_top (bgp_nexthop_cache_table
[AFI_IP
]); rn
; rn
= bgp_route_next (rn
))
1392 if ((bnc
= rn
->info
) != NULL
)
1394 if (CHECK_FLAG(bnc
->flags
, BGP_NEXTHOP_VALID
))
1396 vty_out (vty
, " %s valid [IGP metric %d], #paths %d%s",
1397 inet_ntop (AF_INET
, &rn
->p
.u
.prefix4
, buf
, INET6_ADDRSTRLEN
),
1398 bnc
->metric
, bnc
->path_count
, VTY_NEWLINE
);
1400 for (nexthop
= bnc
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
1401 switch (nexthop
->type
)
1403 case NEXTHOP_TYPE_IPV4
:
1404 vty_out (vty
, " gate %s%s",
1405 inet_ntop (AF_INET
, &nexthop
->gate
.ipv4
, buf
,
1406 INET6_ADDRSTRLEN
), VTY_NEWLINE
);
1408 case NEXTHOP_TYPE_IFINDEX
:
1409 vty_out (vty
, " if %s%s",
1410 ifindex2ifname(nexthop
->ifindex
), VTY_NEWLINE
);
1412 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1413 vty_out (vty
, " gate %s, if %s%s",
1414 inet_ntop(AF_INET
, &nexthop
->gate
.ipv4
, buf
,
1416 ifindex2ifname(nexthop
->ifindex
), VTY_NEWLINE
);
1419 vty_out (vty
, " invalid nexthop type %u%s",
1420 nexthop
->type
, VTY_NEWLINE
);
1424 vty_out (vty
, " %s invalid%s",
1425 inet_ntop (AF_INET
, &rn
->p
.u
.prefix4
, buf
, INET6_ADDRSTRLEN
), VTY_NEWLINE
);
1426 #ifdef HAVE_CLOCK_MONOTONIC
1427 tbuf
= time(NULL
) - (bgp_clock() - bnc
->last_update
);
1428 vty_out (vty
, " Last update: %s", ctime(&tbuf
));
1430 vty_out (vty
, " Last update: %s", ctime(&bnc
->uptime
));
1431 #endif /* HAVE_CLOCK_MONOTONIC */
1433 vty_out(vty
, "%s", VTY_NEWLINE
);
1438 for (rn
= bgp_table_top (bgp_nexthop_cache_table
[AFI_IP6
]);
1440 rn
= bgp_route_next (rn
))
1441 if ((bnc
= rn
->info
) != NULL
)
1443 if (CHECK_FLAG(bnc
->flags
, BGP_NEXTHOP_VALID
))
1445 vty_out (vty
, " %s valid [IGP metric %d]%s",
1446 inet_ntop (AF_INET6
, &rn
->p
.u
.prefix6
, buf
,
1448 bnc
->metric
, VTY_NEWLINE
);
1450 for (nexthop
= bnc
->nexthop
; nexthop
; nexthop
= nexthop
->next
)
1451 switch (nexthop
->type
)
1453 case NEXTHOP_TYPE_IPV6
:
1454 vty_out (vty
, " gate %s%s",
1455 inet_ntop (AF_INET6
, &nexthop
->gate
.ipv6
,
1456 buf
, INET6_ADDRSTRLEN
), VTY_NEWLINE
);
1458 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1459 vty_out(vty
, " gate %s, if %s%s",
1460 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
1462 ifindex2ifname(nexthop
->ifindex
),
1465 case NEXTHOP_TYPE_IFINDEX
:
1466 vty_out (vty
, " ifidx %u%s", nexthop
->ifindex
,
1470 vty_out (vty
, " invalid nexthop type %u%s",
1471 nexthop
->type
, VTY_NEWLINE
);
1475 vty_out (vty
, " %s invalid%s",
1476 inet_ntop (AF_INET6
, &rn
->p
.u
.prefix6
, buf
, INET6_ADDRSTRLEN
),
1478 #ifdef HAVE_CLOCK_MONOTONIC
1479 tbuf
= time(NULL
) - (bgp_clock() - bnc
->last_update
);
1480 vty_out (vty
, " Last update: %s", ctime(&tbuf
));
1482 vty_out (vty
, " Last update: %s", ctime(&bnc
->uptime
));
1483 #endif /* HAVE_CLOCK_MONOTONIC */
1485 vty_out(vty
, "%s", VTY_NEWLINE
);
1488 #endif /* HAVE_IPV6 */
1492 DEFUN (show_ip_bgp_scan
,
1493 show_ip_bgp_scan_cmd
,
1498 "BGP scan status\n")
1500 return show_ip_bgp_scan_tables (vty
, 0);
1503 DEFUN (show_ip_bgp_scan_detail
,
1504 show_ip_bgp_scan_detail_cmd
,
1505 "show ip bgp scan detail",
1510 "More detailed output\n")
1512 return show_ip_bgp_scan_tables (vty
, 1);
1515 DEFUN (show_ip_bgp_nexthop
,
1516 show_ip_bgp_nexthop_cmd
,
1517 "show ip bgp nexthop",
1521 "BGP nexthop table\n")
1523 return show_ip_bgp_nexthop_table (vty
, 0);
1526 DEFUN (show_ip_bgp_nexthop_detail
,
1527 show_ip_bgp_nexthop_detail_cmd
,
1528 "show ip bgp nexthop detail",
1532 "BGP nexthop table\n")
1534 return show_ip_bgp_nexthop_table (vty
, 1);
1538 bgp_config_write_scan_time (struct vty
*vty
)
1540 if (bgp_scan_interval
!= BGP_SCAN_INTERVAL_DEFAULT
)
1541 vty_out (vty
, " bgp scan-time %d%s", bgp_scan_interval
, VTY_NEWLINE
);
1546 bgp_scan_init (void)
1548 zlookup
= zclient_new ();
1550 zlookup
->t_connect
= thread_add_event (master
, zlookup_connect
, zlookup
, 0);
1552 bgp_scan_interval
= BGP_SCAN_INTERVAL_DEFAULT
;
1553 bgp_import_interval
= BGP_IMPORT_INTERVAL_DEFAULT
;
1555 cache1_table
[AFI_IP
] = bgp_table_init (AFI_IP
, SAFI_UNICAST
);
1556 cache2_table
[AFI_IP
] = bgp_table_init (AFI_IP
, SAFI_UNICAST
);
1557 bgp_nexthop_cache_table
[AFI_IP
] = cache1_table
[AFI_IP
];
1559 bgp_connected_table
[AFI_IP
] = bgp_table_init (AFI_IP
, SAFI_UNICAST
);
1562 cache1_table
[AFI_IP6
] = bgp_table_init (AFI_IP6
, SAFI_UNICAST
);
1563 cache2_table
[AFI_IP6
] = bgp_table_init (AFI_IP6
, SAFI_UNICAST
);
1564 bgp_nexthop_cache_table
[AFI_IP6
] = cache1_table
[AFI_IP6
];
1565 bgp_connected_table
[AFI_IP6
] = bgp_table_init (AFI_IP6
, SAFI_UNICAST
);
1566 #endif /* HAVE_IPV6 */
1568 /* Make BGP scan thread. */
1569 bgp_scan_thread
= thread_add_timer (master
, bgp_scan_timer
,
1570 NULL
, bgp_scan_interval
);
1571 /* Make BGP import there. */
1572 bgp_import_thread
= thread_add_timer (master
, bgp_import
, NULL
, 0);
1574 install_element (BGP_NODE
, &bgp_scan_time_cmd
);
1575 install_element (BGP_NODE
, &no_bgp_scan_time_cmd
);
1576 install_element (BGP_NODE
, &no_bgp_scan_time_val_cmd
);
1577 install_element (VIEW_NODE
, &show_ip_bgp_scan_cmd
);
1578 install_element (VIEW_NODE
, &show_ip_bgp_scan_detail_cmd
);
1579 install_element (VIEW_NODE
, &show_ip_bgp_nexthop_cmd
);
1580 install_element (VIEW_NODE
, &show_ip_bgp_nexthop_detail_cmd
);
1581 install_element (RESTRICTED_NODE
, &show_ip_bgp_scan_cmd
);
1582 install_element (ENABLE_NODE
, &show_ip_bgp_scan_cmd
);
1583 install_element (ENABLE_NODE
, &show_ip_bgp_nexthop_cmd
);
1584 install_element (ENABLE_NODE
, &show_ip_bgp_nexthop_detail_cmd
);
1585 install_element (ENABLE_NODE
, &show_ip_bgp_scan_detail_cmd
);
1589 bgp_scan_finish (void)
1591 /* Only the current one needs to be reset. */
1592 bgp_nexthop_cache_reset (bgp_nexthop_cache_table
[AFI_IP
]);
1594 bgp_table_unlock (cache1_table
[AFI_IP
]);
1595 cache1_table
[AFI_IP
] = NULL
;
1597 bgp_table_unlock (cache2_table
[AFI_IP
]);
1598 cache2_table
[AFI_IP
] = NULL
;
1600 bgp_table_unlock (bgp_connected_table
[AFI_IP
]);
1601 bgp_connected_table
[AFI_IP
] = NULL
;
1604 /* Only the current one needs to be reset. */
1605 bgp_nexthop_cache_reset (bgp_nexthop_cache_table
[AFI_IP6
]);
1607 bgp_table_unlock (cache1_table
[AFI_IP6
]);
1608 cache1_table
[AFI_IP6
] = NULL
;
1610 bgp_table_unlock (cache2_table
[AFI_IP6
]);
1611 cache2_table
[AFI_IP6
] = NULL
;
1613 bgp_table_unlock (bgp_connected_table
[AFI_IP6
]);
1614 bgp_connected_table
[AFI_IP6
] = NULL
;
1615 #endif /* HAVE_IPV6 */