usbmodeswitch: Updated to v.1.2.6 from shibby's branch.
[tomato.git] / release / src / router / zebra / bgpd / bgp_nexthop.c
blobd4b5ec62352002f2e7607ae95c1919f86e90c379
1 /* BGP nexthop scan
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
9 later version.
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
19 02111-1307, USA. */
21 #include <zebra.h>
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"
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);
43 #ifdef HAVE_IPV6
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 struct thread *bgp_scan_thread = NULL;
50 /* BGP import thread */
51 struct thread *bgp_import_thread = NULL;
53 /* BGP scan interval. */
54 int bgp_scan_interval;
56 /* BGP import interval. */
57 int bgp_import_interval;
59 /* Route table for next-hop lookup cache. */
60 struct bgp_table *bgp_nexthop_cache_ipv4;
61 struct bgp_table *cache1;
62 struct bgp_table *cache2;
64 /* Route table for next-hop lookup cache. */
65 struct bgp_table *bgp_nexthop_cache_ipv6;
66 struct bgp_table *cache6_1;
67 struct bgp_table *cache6_2;
69 /* Route table for connected route. */
70 struct bgp_table *bgp_connected_ipv4;
72 /* Route table for connected route. */
73 struct bgp_table *bgp_connected_ipv6;
75 /* BGP nexthop lookup query client. */
76 static struct zclient *zlookup = NULL;
78 /* BGP process function. */
79 int bgp_process (struct bgp *, struct bgp_node *, afi_t, safi_t);
81 /* Add nexthop to the end of the list. */
82 void
83 bnc_nexthop_add (struct bgp_nexthop_cache *bnc, struct nexthop *nexthop)
85 struct nexthop *last;
87 for (last = bnc->nexthop; last && last->next; last = last->next)
89 if (last)
90 last->next = nexthop;
91 else
92 bnc->nexthop = nexthop;
93 nexthop->prev = last;
96 void
97 bnc_nexthop_free (struct bgp_nexthop_cache *bnc)
99 struct nexthop *nexthop;
100 struct nexthop *next = NULL;
102 for (nexthop = bnc->nexthop; nexthop; nexthop = next)
104 next = nexthop->next;
105 XFREE (MTYPE_NEXTHOP, nexthop);
109 struct bgp_nexthop_cache *
110 bnc_new ()
112 struct bgp_nexthop_cache *new;
114 new = XMALLOC (MTYPE_BGP_NEXTHOP_CACHE, sizeof (struct bgp_nexthop_cache));
115 memset (new, 0, sizeof (struct bgp_nexthop_cache));
116 return new;
119 void
120 bnc_free (struct bgp_nexthop_cache *bnc)
122 bnc_nexthop_free (bnc);
123 XFREE (MTYPE_BGP_NEXTHOP_CACHE, bnc);
127 bgp_nexthop_same (struct nexthop *next1, struct nexthop *next2)
129 if (next1->type != next2->type)
130 return 0;
132 switch (next1->type)
134 case ZEBRA_NEXTHOP_IPV4:
135 if (! IPV4_ADDR_SAME (&next1->gate.ipv4, &next2->gate.ipv4))
136 return 0;
137 break;
138 case ZEBRA_NEXTHOP_IFINDEX:
139 case ZEBRA_NEXTHOP_IFNAME:
140 if (next1->ifindex != next2->ifindex)
141 return 0;
142 break;
143 #ifdef HAVE_IPV6
144 case ZEBRA_NEXTHOP_IPV6:
145 if (! IPV6_ADDR_SAME (&next1->gate.ipv6, &next2->gate.ipv6))
146 return 0;
147 break;
148 case ZEBRA_NEXTHOP_IPV6_IFINDEX:
149 case ZEBRA_NEXTHOP_IPV6_IFNAME:
150 if (! IPV6_ADDR_SAME (&next1->gate.ipv6, &next2->gate.ipv6))
151 return 0;
152 if (next1->ifindex != next2->ifindex)
153 return 0;
154 break;
155 #endif /* HAVE_IPV6 */
157 return 1;
161 bgp_nexthop_cache_changed (struct bgp_nexthop_cache *bnc1,
162 struct bgp_nexthop_cache *bnc2)
164 int i;
165 struct nexthop *next1, *next2;
167 if (bnc1->nexthop_num != bnc2->nexthop_num)
168 return 1;
170 next1 = bnc1->nexthop;
171 next2 = bnc2->nexthop;
173 for (i = 0; i < bnc1->nexthop_num; i++)
175 if (! bgp_nexthop_same (next1, next2))
176 return 1;
178 next1 = next1->next;
179 next2 = next2->next;
181 return 0;
184 /* If nexthop exists on connected network return 1. */
186 bgp_nexthop_check_ebgp (afi_t afi, struct attr *attr)
188 struct bgp_node *rn;
190 /* If zebra is not enabled return */
191 if (zlookup->sock < 0)
192 return 1;
194 /* Lookup the address is onlink or not. */
195 if (afi == AFI_IP)
197 rn = bgp_node_match_ipv4 (bgp_connected_ipv4, &attr->nexthop);
198 if (rn)
200 bgp_unlock_node (rn);
201 return 1;
204 #ifdef HAVE_IPV6
205 else if (afi == AFI_IP6)
207 if (attr->mp_nexthop_len == 32)
208 return 1;
209 else if (attr->mp_nexthop_len == 16)
211 if (IN6_IS_ADDR_LINKLOCAL (&attr->mp_nexthop_global))
212 return 1;
214 rn = bgp_node_match_ipv6 (bgp_connected_ipv6,
215 &attr->mp_nexthop_global);
216 if (rn)
218 bgp_unlock_node (rn);
219 return 1;
223 #endif /* HAVE_IPV6 */
224 return 0;
227 #ifdef HAVE_IPV6
228 /* Check specified next-hop is reachable or not. */
230 bgp_nexthop_lookup_ipv6 (struct peer *peer, struct bgp_info *ri, int *changed,
231 int *metricchanged)
233 struct bgp_node *rn;
234 struct prefix p;
235 struct bgp_nexthop_cache *bnc;
236 struct attr *attr;
238 /* If lookup is not enabled, return valid. */
239 if (zlookup->sock < 0)
241 ri->igpmetric = 0;
242 return 1;
245 /* Only check IPv6 global address only nexthop. */
246 attr = ri->attr;
248 if (attr->mp_nexthop_len != 16
249 || IN6_IS_ADDR_LINKLOCAL (&attr->mp_nexthop_global))
250 return 1;
252 memset (&p, 0, sizeof (struct prefix));
253 p.family = AF_INET6;
254 p.prefixlen = IPV6_MAX_BITLEN;
255 p.u.prefix6 = attr->mp_nexthop_global;
257 /* IBGP or ebgp-multihop */
258 rn = bgp_node_get (bgp_nexthop_cache_ipv6, &p);
260 if (rn->info)
262 bnc = rn->info;
263 bgp_unlock_node (rn);
265 else
267 bnc = zlookup_query_ipv6 (&attr->mp_nexthop_global);
268 if (bnc)
270 struct bgp_table *old;
271 struct bgp_node *oldrn;
272 struct bgp_nexthop_cache *oldbnc;
274 if (changed)
276 if (bgp_nexthop_cache_ipv6 == cache6_1)
277 old = cache6_2;
278 else
279 old = cache6_1;
281 oldrn = bgp_node_lookup (old, &p);
282 if (oldrn)
284 oldbnc = oldrn->info;
286 bnc->changed = bgp_nexthop_cache_changed (bnc, oldbnc);
288 if (bnc->metric != oldbnc->metric)
289 bnc->metricchanged = 1;
293 else
295 bnc = bnc_new ();
296 bnc->valid = 0;
298 rn->info = bnc;
301 if (changed)
302 *changed = bnc->changed;
304 if (metricchanged)
305 *metricchanged = bnc->metricchanged;
307 if (bnc->valid)
308 ri->igpmetric = bnc->metric;
309 else
310 ri->igpmetric = 0;
312 return bnc->valid;
314 #endif /* HAVE_IPV6 */
316 /* Check specified next-hop is reachable or not. */
318 bgp_nexthop_lookup (afi_t afi, struct peer *peer, struct bgp_info *ri,
319 int *changed, int *metricchanged)
321 struct bgp_node *rn;
322 struct prefix p;
323 struct bgp_nexthop_cache *bnc;
324 struct in_addr addr;
326 /* If lookup is not enabled, return valid. */
327 if (zlookup->sock < 0)
329 ri->igpmetric = 0;
330 return 1;
333 #ifdef HAVE_IPV6
334 if (afi == AFI_IP6)
335 return bgp_nexthop_lookup_ipv6 (peer, ri, changed, metricchanged);
336 #endif /* HAVE_IPV6 */
338 addr = ri->attr->nexthop;
340 memset (&p, 0, sizeof (struct prefix));
341 p.family = AF_INET;
342 p.prefixlen = IPV4_MAX_BITLEN;
343 p.u.prefix4 = addr;
345 /* IBGP or ebgp-multihop */
346 rn = bgp_node_get (bgp_nexthop_cache_ipv4, &p);
348 if (rn->info)
350 bnc = rn->info;
351 bgp_unlock_node (rn);
353 else
355 bnc = zlookup_query (addr);
356 if (bnc)
358 struct bgp_table *old;
359 struct bgp_node *oldrn;
360 struct bgp_nexthop_cache *oldbnc;
362 if (changed)
364 if (bgp_nexthop_cache_ipv4 == cache1)
365 old = cache2;
366 else
367 old = cache1;
369 oldrn = bgp_node_lookup (old, &p);
370 if (oldrn)
372 oldbnc = oldrn->info;
374 bnc->changed = bgp_nexthop_cache_changed (bnc, oldbnc);
376 if (bnc->metric != oldbnc->metric)
377 bnc->metricchanged = 1;
381 else
383 bnc = bnc_new ();
384 bnc->valid = 0;
386 rn->info = bnc;
389 if (changed)
390 *changed = bnc->changed;
392 if (metricchanged)
393 *metricchanged = bnc->metricchanged;
395 if (bnc->valid)
396 ri->igpmetric = bnc->metric;
397 else
398 ri->igpmetric = 0;
400 return bnc->valid;
403 /* Reset and free all BGP nexthop cache. */
404 void
405 bgp_nexthop_cache_reset (struct bgp_table *table)
407 struct bgp_node *rn;
408 struct bgp_nexthop_cache *bnc;
410 for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
411 if ((bnc = rn->info) != NULL)
413 bnc_free (bnc);
414 rn->info = NULL;
415 bgp_unlock_node (rn);
419 void
420 bgp_scan_ipv4 ()
422 struct bgp_node *rn;
423 struct bgp *bgp;
424 struct bgp_info *bi;
425 struct bgp_info *next;
426 struct peer *peer;
427 struct listnode *nn;
428 int valid;
429 int current;
430 int changed;
431 int metricchanged;
433 /* Change cache. */
434 if (bgp_nexthop_cache_ipv4 == cache1)
435 bgp_nexthop_cache_ipv4 = cache2;
436 else
437 bgp_nexthop_cache_ipv4 = cache1;
439 /* Get default bgp. */
440 bgp = bgp_get_default ();
441 if (bgp == NULL)
442 return;
444 /* Maximum prefix check */
445 LIST_LOOP (bgp->peer, peer, nn)
447 if (peer->status != Established)
448 continue;
450 if (peer->afc[AFI_IP][SAFI_UNICAST])
451 bgp_maximum_prefix_overflow (peer, AFI_IP, SAFI_UNICAST, 1);
452 if (peer->afc[AFI_IP][SAFI_MULTICAST])
453 bgp_maximum_prefix_overflow (peer, AFI_IP, SAFI_MULTICAST, 1);
454 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
455 bgp_maximum_prefix_overflow (peer, AFI_IP, SAFI_MPLS_VPN, 1);
458 for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_UNICAST]); rn;
459 rn = bgp_route_next (rn))
461 for (bi = rn->info; bi; bi = next)
463 next = bi->next;
465 if (bi->type == ZEBRA_ROUTE_BGP && bi->sub_type == BGP_ROUTE_NORMAL)
467 changed = 0;
468 metricchanged = 0;
470 if (peer_sort (bi->peer) == BGP_PEER_EBGP && bi->peer->ttl == 1)
471 valid = bgp_nexthop_check_ebgp (AFI_IP, bi->attr);
472 else
473 valid = bgp_nexthop_lookup (AFI_IP, bi->peer, bi,
474 &changed, &metricchanged);
476 current = CHECK_FLAG (bi->flags, BGP_INFO_VALID) ? 1 : 0;
478 if (changed)
479 SET_FLAG (bi->flags, BGP_INFO_IGP_CHANGED);
480 else
481 UNSET_FLAG (bi->flags, BGP_INFO_IGP_CHANGED);
483 if (valid != current)
485 if (CHECK_FLAG (bi->flags, BGP_INFO_VALID))
487 bgp_aggregate_decrement (bgp, &rn->p, bi,
488 AFI_IP, SAFI_UNICAST);
489 UNSET_FLAG (bi->flags, BGP_INFO_VALID);
491 else
493 SET_FLAG (bi->flags, BGP_INFO_VALID);
494 bgp_aggregate_increment (bgp, &rn->p, bi,
495 AFI_IP, SAFI_UNICAST);
499 if (CHECK_FLAG (bgp->af_flags[AFI_IP][SAFI_UNICAST],
500 BGP_CONFIG_DAMPENING)
501 && bi->damp_info )
502 if (bgp_damp_scan (bi, AFI_IP, SAFI_UNICAST))
503 bgp_aggregate_increment (bgp, &rn->p, bi,
504 AFI_IP, SAFI_UNICAST);
507 bgp_process (bgp, rn, AFI_IP, SAFI_UNICAST);
510 /* Flash old cache. */
511 if (bgp_nexthop_cache_ipv4 == cache1)
512 bgp_nexthop_cache_reset (cache2);
513 else
514 bgp_nexthop_cache_reset (cache1);
516 if (BGP_DEBUG (events, EVENTS))
517 zlog_info ("scanning IPv4 Unicast routing tables");
520 #ifdef HAVE_IPV6
521 void
522 bgp_scan_ipv6 ()
524 struct bgp_node *rn;
525 struct bgp *bgp;
526 struct bgp_info *bi;
527 struct bgp_info *next;
528 struct peer *peer;
529 struct listnode *nn;
530 int valid;
531 int current;
532 int changed;
533 int metricchanged;
535 /* Change cache. */
536 if (bgp_nexthop_cache_ipv6 == cache6_1)
537 bgp_nexthop_cache_ipv6 = cache6_2;
538 else
539 bgp_nexthop_cache_ipv6 = cache6_1;
541 /* Get default bgp. */
542 bgp = bgp_get_default ();
543 if (bgp == NULL)
544 return;
546 /* Maximum prefix check */
547 LIST_LOOP (bgp->peer, peer, nn)
549 if (peer->status != Established)
550 continue;
552 if (peer->afc[AFI_IP6][SAFI_UNICAST])
553 bgp_maximum_prefix_overflow (peer, AFI_IP6, SAFI_UNICAST, 1);
554 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
555 bgp_maximum_prefix_overflow (peer, AFI_IP6, SAFI_MULTICAST, 1);
558 for (rn = bgp_table_top (bgp->rib[AFI_IP6][SAFI_UNICAST]); rn;
559 rn = bgp_route_next (rn))
561 for (bi = rn->info; bi; bi = next)
563 next = bi->next;
565 if (bi->type == ZEBRA_ROUTE_BGP && bi->sub_type == BGP_ROUTE_NORMAL)
567 changed = 0;
568 metricchanged = 0;
570 if (peer_sort (bi->peer) == BGP_PEER_EBGP && bi->peer->ttl == 1)
571 valid = 1;
572 else
573 valid = bgp_nexthop_lookup_ipv6 (bi->peer, bi,
574 &changed, &metricchanged);
576 current = CHECK_FLAG (bi->flags, BGP_INFO_VALID) ? 1 : 0;
578 if (changed)
579 SET_FLAG (bi->flags, BGP_INFO_IGP_CHANGED);
580 else
581 UNSET_FLAG (bi->flags, BGP_INFO_IGP_CHANGED);
583 if (valid != current)
585 if (CHECK_FLAG (bi->flags, BGP_INFO_VALID))
587 bgp_aggregate_decrement (bgp, &rn->p, bi,
588 AFI_IP6, SAFI_UNICAST);
589 UNSET_FLAG (bi->flags, BGP_INFO_VALID);
591 else
593 SET_FLAG (bi->flags, BGP_INFO_VALID);
594 bgp_aggregate_increment (bgp, &rn->p, bi,
595 AFI_IP6, SAFI_UNICAST);
599 if (CHECK_FLAG (bgp->af_flags[AFI_IP6][SAFI_UNICAST],
600 BGP_CONFIG_DAMPENING)
601 && bi->damp_info )
602 if (bgp_damp_scan (bi, AFI_IP6, SAFI_UNICAST))
603 bgp_aggregate_increment (bgp, &rn->p, bi,
604 AFI_IP6, SAFI_UNICAST);
607 bgp_process (bgp, rn, AFI_IP6, SAFI_UNICAST);
610 /* Flash old cache. */
611 if (bgp_nexthop_cache_ipv6 == cache6_1)
612 bgp_nexthop_cache_reset (cache6_2);
613 else
614 bgp_nexthop_cache_reset (cache6_1);
616 if (BGP_DEBUG (events, EVENTS))
617 zlog_info ("scanning IPv6 Unicast routing tables");
619 #endif /* HAVE_IPV6 */
621 /* BGP scan thread. This thread check nexthop reachability. */
623 bgp_scan (struct thread *t)
625 bgp_scan_thread =
626 thread_add_timer (master, bgp_scan, NULL, bgp_scan_interval);
628 if (BGP_DEBUG (events, EVENTS))
629 zlog_info ("Performing BGP general scanning");
631 bgp_scan_ipv4 ();
633 #ifdef HAVE_IPV6
634 bgp_scan_ipv6 ();
635 #endif /* HAVE_IPV6 */
637 return 0;
640 struct bgp_connected
642 unsigned int refcnt;
645 void
646 bgp_connected_add (struct connected *ifc)
648 struct prefix p;
649 struct prefix *addr;
650 struct prefix *dest;
651 struct interface *ifp;
652 struct bgp_node *rn;
653 struct bgp_connected *bc;
655 ifp = ifc->ifp;
657 if (! ifp)
658 return;
660 if (if_is_loopback (ifp))
661 return;
663 addr = ifc->address;
664 dest = ifc->destination;
666 if (addr->family == AF_INET)
668 memset (&p, 0, sizeof (struct prefix));
669 p.family = AF_INET;
670 p.prefixlen = addr->prefixlen;
672 if (if_is_pointopoint (ifp))
673 p.u.prefix4 = dest->u.prefix4;
674 else
675 p.u.prefix4 = addr->u.prefix4;
677 apply_mask_ipv4 ((struct prefix_ipv4 *) &p);
679 if (prefix_ipv4_any ((struct prefix_ipv4 *) &p))
680 return;
682 rn = bgp_node_get (bgp_connected_ipv4, (struct prefix *) &p);
683 if (rn->info)
685 bc = rn->info;
686 bc->refcnt++;
688 else
690 bc = XMALLOC (0, sizeof (struct bgp_connected));
691 memset (bc, 0, sizeof (struct bgp_connected));
692 bc->refcnt = 1;
693 rn->info = bc;
696 #ifdef HAVE_IPV6
697 if (addr->family == AF_INET6)
699 memset (&p, 0, sizeof (struct prefix));
700 p.family = AF_INET6;
701 p.prefixlen = addr->prefixlen;
703 if (if_is_pointopoint (ifp))
704 p.u.prefix6 = dest->u.prefix6;
705 else
706 p.u.prefix6 = addr->u.prefix6;
708 apply_mask_ipv6 ((struct prefix_ipv6 *) &p);
710 if (IN6_IS_ADDR_UNSPECIFIED (&p.u.prefix6))
711 return;
713 if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
714 return;
716 rn = bgp_node_get (bgp_connected_ipv6, (struct prefix *) &p);
717 if (rn->info)
719 bc = rn->info;
720 bc->refcnt++;
722 else
724 bc = XMALLOC (0, sizeof (struct bgp_connected));
725 memset (bc, 0, sizeof (struct bgp_connected));
726 bc->refcnt = 1;
727 rn->info = bc;
730 #endif /* HAVE_IPV6 */
733 void
734 bgp_connected_delete (struct connected *ifc)
736 struct prefix p;
737 struct prefix *addr;
738 struct prefix *dest;
739 struct interface *ifp;
740 struct bgp_node *rn;
741 struct bgp_connected *bc;
743 ifp = ifc->ifp;
745 if (if_is_loopback (ifp))
746 return;
748 addr = ifc->address;
749 dest = ifc->destination;
751 if (addr->family == AF_INET)
753 memset (&p, 0, sizeof (struct prefix));
754 p.family = AF_INET;
755 p.prefixlen = addr->prefixlen;
757 if (if_is_pointopoint (ifp))
758 p.u.prefix4 = dest->u.prefix4;
759 else
760 p.u.prefix4 = addr->u.prefix4;
762 apply_mask_ipv4 ((struct prefix_ipv4 *) &p);
764 if (prefix_ipv4_any ((struct prefix_ipv4 *) &p))
765 return;
767 rn = bgp_node_lookup (bgp_connected_ipv4, &p);
768 if (! rn)
769 return;
771 bc = rn->info;
772 bc->refcnt--;
773 if (bc->refcnt == 0)
775 XFREE (0, bc);
776 rn->info = NULL;
778 bgp_unlock_node (rn);
779 bgp_unlock_node (rn);
781 #ifdef HAVE_IPV6
782 else if (addr->family == AF_INET6)
784 memset (&p, 0, sizeof (struct prefix));
785 p.family = AF_INET6;
786 p.prefixlen = addr->prefixlen;
788 if (if_is_pointopoint (ifp))
789 p.u.prefix6 = dest->u.prefix6;
790 else
791 p.u.prefix6 = addr->u.prefix6;
793 apply_mask_ipv6 ((struct prefix_ipv6 *) &p);
795 if (IN6_IS_ADDR_UNSPECIFIED (&p.u.prefix6))
796 return;
798 if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
799 return;
801 rn = bgp_node_lookup (bgp_connected_ipv6, (struct prefix *) &p);
802 if (! rn)
803 return;
805 bc = rn->info;
806 bc->refcnt--;
807 if (bc->refcnt == 0)
809 XFREE (0, bc);
810 rn->info = NULL;
812 bgp_unlock_node (rn);
813 bgp_unlock_node (rn);
815 #endif /* HAVE_IPV6 */
819 bgp_nexthop_self (afi_t afi, struct attr *attr)
821 listnode node;
822 listnode node2;
823 struct interface *ifp;
824 struct connected *ifc;
825 struct prefix *p;
827 for (node = listhead (iflist); node; nextnode (node))
829 ifp = getdata (node);
831 for (node2 = listhead (ifp->connected); node2; nextnode (node2))
833 ifc = getdata (node2);
834 p = ifc->address;
836 if (p && p->family == AF_INET
837 && IPV4_ADDR_SAME (&p->u.prefix4, &attr->nexthop))
838 return 1;
841 return 0;
844 struct bgp_nexthop_cache *
845 zlookup_read ()
847 struct stream *s;
848 u_int16_t length;
849 u_char command;
850 int nbytes;
851 struct in_addr raddr;
852 u_int32_t metric;
853 int i;
854 u_char nexthop_num;
855 struct nexthop *nexthop;
856 struct bgp_nexthop_cache *bnc;
858 s = zlookup->ibuf;
859 stream_reset (s);
861 nbytes = stream_read (s, zlookup->sock, 2);
862 length = stream_getw (s);
864 nbytes = stream_read (s, zlookup->sock, length - 2);
865 command = stream_getc (s);
866 raddr.s_addr = stream_get_ipv4 (s);
867 metric = stream_getl (s);
868 nexthop_num = stream_getc (s);
870 if (nexthop_num)
872 bnc = bnc_new ();
873 bnc->valid = 1;
874 bnc->metric = metric;
875 bnc->nexthop_num = nexthop_num;
877 for (i = 0; i < nexthop_num; i++)
879 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
880 memset (nexthop, 0, sizeof (struct nexthop));
881 nexthop->type = stream_getc (s);
882 switch (nexthop->type)
884 case ZEBRA_NEXTHOP_IPV4:
885 nexthop->gate.ipv4.s_addr = stream_get_ipv4 (s);
886 break;
887 case ZEBRA_NEXTHOP_IFINDEX:
888 case ZEBRA_NEXTHOP_IFNAME:
889 nexthop->ifindex = stream_getl (s);
890 break;
892 bnc_nexthop_add (bnc, nexthop);
895 else
896 return NULL;
898 return bnc;
901 struct bgp_nexthop_cache *
902 zlookup_query (struct in_addr addr)
904 int ret;
905 struct stream *s;
907 /* Check socket. */
908 if (zlookup->sock < 0)
909 return NULL;
911 s = zlookup->obuf;
912 stream_reset (s);
913 stream_putw (s, 7);
914 stream_putc (s, ZEBRA_IPV4_NEXTHOP_LOOKUP);
915 stream_put_in_addr (s, &addr);
917 ret = writen (zlookup->sock, s->data, 7);
918 if (ret < 0)
920 zlog_err ("can't write to zlookup->sock");
921 close (zlookup->sock);
922 zlookup->sock = -1;
923 return NULL;
925 if (ret == 0)
927 zlog_err ("zlookup->sock connection closed");
928 close (zlookup->sock);
929 zlookup->sock = -1;
930 return NULL;
933 return zlookup_read ();
936 #ifdef HAVE_IPV6
937 struct bgp_nexthop_cache *
938 zlookup_read_ipv6 ()
940 struct stream *s;
941 u_int16_t length;
942 u_char command;
943 int nbytes;
944 struct in6_addr raddr;
945 u_int32_t metric;
946 int i;
947 u_char nexthop_num;
948 struct nexthop *nexthop;
949 struct bgp_nexthop_cache *bnc;
951 s = zlookup->ibuf;
952 stream_reset (s);
954 nbytes = stream_read (s, zlookup->sock, 2);
955 length = stream_getw (s);
957 nbytes = stream_read (s, zlookup->sock, length - 2);
958 command = stream_getc (s);
960 stream_get (&raddr, s, 16);
962 metric = stream_getl (s);
963 nexthop_num = stream_getc (s);
965 if (nexthop_num)
967 bnc = bnc_new ();
968 bnc->valid = 1;
969 bnc->metric = metric;
970 bnc->nexthop_num = nexthop_num;
972 for (i = 0; i < nexthop_num; i++)
974 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
975 memset (nexthop, 0, sizeof (struct nexthop));
976 nexthop->type = stream_getc (s);
977 switch (nexthop->type)
979 case ZEBRA_NEXTHOP_IPV6:
980 stream_get (&nexthop->gate.ipv6, s, 16);
981 break;
982 case ZEBRA_NEXTHOP_IPV6_IFINDEX:
983 case ZEBRA_NEXTHOP_IPV6_IFNAME:
984 stream_get (&nexthop->gate.ipv6, s, 16);
985 nexthop->ifindex = stream_getl (s);
986 break;
987 case ZEBRA_NEXTHOP_IFINDEX:
988 case ZEBRA_NEXTHOP_IFNAME:
989 nexthop->ifindex = stream_getl (s);
990 break;
992 bnc_nexthop_add (bnc, nexthop);
995 else
996 return NULL;
998 return bnc;
1001 struct bgp_nexthop_cache *
1002 zlookup_query_ipv6 (struct in6_addr *addr)
1004 int ret;
1005 struct stream *s;
1007 /* Check socket. */
1008 if (zlookup->sock < 0)
1009 return NULL;
1011 s = zlookup->obuf;
1012 stream_reset (s);
1013 stream_putw (s, 19);
1014 stream_putc (s, ZEBRA_IPV6_NEXTHOP_LOOKUP);
1015 stream_put (s, addr, 16);
1017 ret = writen (zlookup->sock, s->data, 19);
1018 if (ret < 0)
1020 zlog_err ("can't write to zlookup->sock");
1021 close (zlookup->sock);
1022 zlookup->sock = -1;
1023 return NULL;
1025 if (ret == 0)
1027 zlog_err ("zlookup->sock connection closed");
1028 close (zlookup->sock);
1029 zlookup->sock = -1;
1030 return NULL;
1033 return zlookup_read_ipv6 ();
1035 #endif /* HAVE_IPV6 */
1038 bgp_import_check (struct prefix *p, u_int32_t *igpmetric, struct in_addr *igpnexthop)
1040 struct stream *s;
1041 int ret;
1042 u_int16_t length;
1043 u_char command;
1044 int nbytes;
1045 struct in_addr addr;
1046 struct in_addr nexthop;
1047 u_int32_t metric = 0;
1048 u_char nexthop_num;
1049 u_char nexthop_type;
1051 /* If lookup connection is not available return valid. */
1052 if (zlookup->sock < 0)
1054 if (igpmetric)
1055 *igpmetric = 0;
1056 return 1;
1059 /* Send query to the lookup connection */
1060 s = zlookup->obuf;
1061 stream_reset (s);
1062 stream_putw (s, 8);
1063 stream_putc (s, ZEBRA_IPV4_IMPORT_LOOKUP);
1064 stream_putc (s, p->prefixlen);
1065 stream_put_in_addr (s, &p->u.prefix4);
1067 /* Write the packet. */
1068 ret = writen (zlookup->sock, s->data, 8);
1070 if (ret < 0)
1072 zlog_err ("can't write to zlookup->sock");
1073 close (zlookup->sock);
1074 zlookup->sock = -1;
1075 return 1;
1077 if (ret == 0)
1079 zlog_err ("zlookup->sock connection closed");
1080 close (zlookup->sock);
1081 zlookup->sock = -1;
1082 return 1;
1085 /* Get result. */
1086 stream_reset (s);
1088 /* Fetch length. */
1089 nbytes = stream_read (s, zlookup->sock, 2);
1090 length = stream_getw (s);
1092 /* Fetch whole data. */
1093 nbytes = stream_read (s, zlookup->sock, length - 2);
1094 command = stream_getc (s);
1095 addr.s_addr = stream_get_ipv4 (s);
1096 metric = stream_getl (s);
1097 nexthop_num = stream_getc (s);
1099 /* Set IGP metric value. */
1100 if (igpmetric)
1101 *igpmetric = metric;
1103 /* If there is nexthop then this is active route. */
1104 if (nexthop_num)
1106 nexthop.s_addr = 0;
1107 nexthop_type = stream_getc (s);
1108 if (nexthop_type == ZEBRA_NEXTHOP_IPV4)
1110 nexthop.s_addr = stream_get_ipv4 (s);
1111 if (igpnexthop)
1112 *igpnexthop = nexthop;
1114 else
1115 *igpnexthop = nexthop;
1117 return 1;
1119 else
1120 return 0;
1123 /* Scan all configured BGP route then check the route exists in IGP or
1124 not. */
1126 bgp_import (struct thread *t)
1128 struct bgp *bgp;
1129 struct bgp_node *rn;
1130 struct bgp_static *bgp_static;
1131 struct listnode *nn;
1132 int valid;
1133 u_int32_t metric;
1134 struct in_addr nexthop;
1135 afi_t afi;
1136 safi_t safi;
1138 bgp_import_thread =
1139 thread_add_timer (master, bgp_import, NULL, bgp_import_interval);
1141 if (BGP_DEBUG (events, EVENTS))
1142 zlog_info ("Import timer expired.");
1144 LIST_LOOP (bm->bgp, bgp, nn)
1146 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1147 for (safi = SAFI_UNICAST; safi < SAFI_MPLS_VPN; safi++)
1148 for (rn = bgp_table_top (bgp->route[afi][safi]); rn;
1149 rn = bgp_route_next (rn))
1150 if ((bgp_static = rn->info) != NULL)
1152 if (bgp_static->backdoor)
1153 continue;
1155 valid = bgp_static->valid;
1156 metric = bgp_static->igpmetric;
1157 nexthop = bgp_static->igpnexthop;
1159 if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK)
1160 && afi == AFI_IP && safi == SAFI_UNICAST)
1161 bgp_static->valid = bgp_import_check (&rn->p, &bgp_static->igpmetric,
1162 &bgp_static->igpnexthop);
1163 else
1165 bgp_static->valid = 1;
1166 bgp_static->igpmetric = 0;
1167 bgp_static->igpnexthop.s_addr = 0;
1170 if (bgp_static->valid != valid)
1172 if (bgp_static->valid)
1173 bgp_static_update (bgp, &rn->p, bgp_static, afi, safi);
1174 else
1175 bgp_static_withdraw (bgp, &rn->p, afi, safi);
1177 else if (bgp_static->valid)
1179 if (bgp_static->igpmetric != metric
1180 || bgp_static->igpnexthop.s_addr != nexthop.s_addr
1181 || bgp_static->rmap.name)
1182 bgp_static_update (bgp, &rn->p, bgp_static, afi, safi);
1186 return 0;
1189 /* Connect to zebra for nexthop lookup. */
1191 zlookup_connect (struct thread *t)
1193 struct zclient *zlookup;
1195 zlookup = THREAD_ARG (t);
1196 zlookup->t_connect = NULL;
1198 if (zlookup->sock != -1)
1199 return 0;
1201 #ifdef HAVE_TCP_ZEBRA
1202 zlookup->sock = zclient_socket ();
1203 #else
1204 zlookup->sock = zclient_socket_un (ZEBRA_SERV_PATH);
1205 #endif /* HAVE_TCP_ZEBRA */
1206 if (zlookup->sock < 0)
1207 return -1;
1209 return 0;
1212 /* Check specified multiaccess next-hop. */
1214 bgp_multiaccess_check_v4 (struct in_addr nexthop, char *peer)
1216 struct bgp_node *rn1;
1217 struct bgp_node *rn2;
1218 struct prefix p1;
1219 struct prefix p2;
1220 struct in_addr addr;
1221 int ret;
1223 ret = inet_aton (peer, &addr);
1224 if (! ret)
1225 return 0;
1227 memset (&p1, 0, sizeof (struct prefix));
1228 p1.family = AF_INET;
1229 p1.prefixlen = IPV4_MAX_BITLEN;
1230 p1.u.prefix4 = nexthop;
1231 memset (&p2, 0, sizeof (struct prefix));
1232 p2.family = AF_INET;
1233 p2.prefixlen = IPV4_MAX_BITLEN;
1234 p2.u.prefix4 = addr;
1236 /* If bgp scan is not enabled, return invalid. */
1237 if (zlookup->sock < 0)
1238 return 0;
1240 rn1 = bgp_node_match (bgp_connected_ipv4, &p1);
1241 if (! rn1)
1242 return 0;
1244 rn2 = bgp_node_match (bgp_connected_ipv4, &p2);
1245 if (! rn2)
1246 return 0;
1248 if (rn1 == rn2)
1249 return 1;
1251 return 0;
1254 DEFUN (bgp_scan_time,
1255 bgp_scan_time_cmd,
1256 "bgp scan-time <5-60>",
1257 "BGP specific commands\n"
1258 "Configure background scanner interval\n"
1259 "Scanner interval (seconds)\n")
1261 bgp_scan_interval = atoi (argv[0]);
1263 if (bgp_scan_thread)
1265 thread_cancel (bgp_scan_thread);
1266 bgp_scan_thread =
1267 thread_add_timer (master, bgp_scan, NULL, bgp_scan_interval);
1270 return CMD_SUCCESS;
1273 DEFUN (no_bgp_scan_time,
1274 no_bgp_scan_time_cmd,
1275 "no bgp scan-time",
1276 NO_STR
1277 "BGP specific commands\n"
1278 "Configure background scanner interval\n")
1280 bgp_scan_interval = BGP_SCAN_INTERVAL_DEFAULT;
1282 if (bgp_scan_thread)
1284 thread_cancel (bgp_scan_thread);
1285 bgp_scan_thread =
1286 thread_add_timer (master, bgp_scan, NULL, bgp_scan_interval);
1289 return CMD_SUCCESS;
1292 ALIAS (no_bgp_scan_time,
1293 no_bgp_scan_time_val_cmd,
1294 "no bgp scan-time <5-60>",
1295 NO_STR
1296 "BGP specific commands\n"
1297 "Configure background scanner interval\n"
1298 "Scanner interval (seconds)\n");
1300 DEFUN (show_ip_bgp_scan,
1301 show_ip_bgp_scan_cmd,
1302 "show ip bgp scan",
1303 SHOW_STR
1304 IP_STR
1305 BGP_STR
1306 "BGP scan status\n")
1308 struct bgp_node *rn;
1309 struct bgp_nexthop_cache *bnc;
1311 if (bgp_scan_thread)
1312 vty_out (vty, "BGP scan is running%s", VTY_NEWLINE);
1313 else
1314 vty_out (vty, "BGP scan is not running%s", VTY_NEWLINE);
1315 vty_out (vty, "BGP scan interval is %d%s", bgp_scan_interval, VTY_NEWLINE);
1317 vty_out (vty, "Current BGP nexthop cache:%s", VTY_NEWLINE);
1318 for (rn = bgp_table_top (bgp_nexthop_cache_ipv4); rn; rn = bgp_route_next (rn))
1319 if ((bnc = rn->info) != NULL)
1321 if (bnc->valid)
1322 vty_out (vty, " %s valid [IGP metric %d]%s",
1323 inet_ntoa (rn->p.u.prefix4), bnc->metric, VTY_NEWLINE);
1324 else
1325 vty_out (vty, " %s invalid%s",
1326 inet_ntoa (rn->p.u.prefix4), VTY_NEWLINE);
1329 #ifdef HAVE_IPV6
1331 char buf[BUFSIZ];
1332 for (rn = bgp_table_top (bgp_nexthop_cache_ipv6); rn; rn = bgp_route_next (rn))
1333 if ((bnc = rn->info) != NULL)
1335 if (bnc->valid)
1336 vty_out (vty, " %s valid [IGP metric %d]%s",
1337 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1338 bnc->metric, VTY_NEWLINE);
1339 else
1340 vty_out (vty, " %s invalid%s",
1341 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1342 VTY_NEWLINE);
1345 #endif /* HAVE_IPV6 */
1347 vty_out (vty, "BGP connected route:%s", VTY_NEWLINE);
1348 for (rn = bgp_table_top (bgp_connected_ipv4); rn; rn = bgp_route_next (rn))
1349 if (rn->info != NULL)
1350 vty_out (vty, " %s/%d%s", inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
1351 VTY_NEWLINE);
1353 #ifdef HAVE_IPV6
1355 char buf[BUFSIZ];
1357 for (rn = bgp_table_top (bgp_connected_ipv6); rn; rn = bgp_route_next (rn))
1358 if (rn->info != NULL)
1359 vty_out (vty, " %s/%d%s",
1360 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1361 rn->p.prefixlen,
1362 VTY_NEWLINE);
1364 #endif /* HAVE_IPV6 */
1366 return CMD_SUCCESS;
1370 bgp_config_write_scan_time (struct vty *vty)
1372 if (bgp_scan_interval != BGP_SCAN_INTERVAL_DEFAULT)
1373 vty_out (vty, " bgp scan-time %d%s", bgp_scan_interval, VTY_NEWLINE);
1374 return CMD_SUCCESS;
1377 void
1378 bgp_scan_init ()
1380 zlookup = zclient_new ();
1381 zlookup->sock = -1;
1382 zlookup->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1383 zlookup->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1384 zlookup->t_connect = thread_add_event (master, zlookup_connect, zlookup, 0);
1386 bgp_scan_interval = BGP_SCAN_INTERVAL_DEFAULT;
1387 bgp_import_interval = BGP_IMPORT_INTERVAL_DEFAULT;
1389 cache1 = bgp_table_init ();
1390 cache2 = bgp_table_init ();
1391 bgp_nexthop_cache_ipv4 = cache1;
1393 bgp_connected_ipv4 = bgp_table_init ();
1395 #ifdef HAVE_IPV6
1396 cache6_1 = bgp_table_init ();
1397 cache6_2 = bgp_table_init ();
1398 bgp_nexthop_cache_ipv6 = cache6_1;
1399 bgp_connected_ipv6 = bgp_table_init ();
1400 #endif /* HAVE_IPV6 */
1402 /* Make BGP scan thread. */
1403 bgp_scan_thread = thread_add_timer (master, bgp_scan, NULL, bgp_scan_interval);
1404 /* Make BGP import there. */
1405 bgp_import_thread = thread_add_timer (master, bgp_import, NULL, 0);
1407 install_element (BGP_NODE, &bgp_scan_time_cmd);
1408 install_element (BGP_NODE, &no_bgp_scan_time_cmd);
1409 install_element (BGP_NODE, &no_bgp_scan_time_val_cmd);
1410 install_element (VIEW_NODE, &show_ip_bgp_scan_cmd);
1411 install_element (ENABLE_NODE, &show_ip_bgp_scan_cmd);