blob: 77b024e5ecd6f066f9359f1c4b816be8d80e1eb3 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* BGP nexthop scan
2 Copyright (C) 2000 Kunihiro Ishiguro
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
20
21#include <zebra.h>
22
23#include "command.h"
24#include "thread.h"
25#include "prefix.h"
26#include "zclient.h"
27#include "stream.h"
28#include "network.h"
29#include "log.h"
30#include "memory.h"
31
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. */
41
42struct bgp_nexthop_cache *zlookup_query (struct in_addr);
43#ifdef HAVE_IPV6
44struct bgp_nexthop_cache *zlookup_query_ipv6 (struct in6_addr *);
45#endif /* HAVE_IPV6 */
46
47/* Only one BGP scan thread are activated at the same time. */
48struct thread *bgp_scan_thread = NULL;
49
50/* BGP import thread */
51struct thread *bgp_import_thread = NULL;
52
53/* BGP scan interval. */
54int bgp_scan_interval;
55
56/* BGP import interval. */
57int bgp_import_interval;
58
59/* Route table for next-hop lookup cache. */
60struct bgp_table *bgp_nexthop_cache_ipv4;
61struct bgp_table *cache1;
62struct bgp_table *cache2;
63
64/* Route table for next-hop lookup cache. */
65struct bgp_table *bgp_nexthop_cache_ipv6;
66struct bgp_table *cache6_1;
67struct bgp_table *cache6_2;
68
69/* Route table for connected route. */
70struct bgp_table *bgp_connected_ipv4;
71
72/* Route table for connected route. */
73struct bgp_table *bgp_connected_ipv6;
74
75/* BGP nexthop lookup query client. */
76static struct zclient *zlookup = NULL;
77
78/* BGP process function. */
79int bgp_process (struct bgp *, struct bgp_node *, afi_t, safi_t);
80
81/* Add nexthop to the end of the list. */
82void
83bnc_nexthop_add (struct bgp_nexthop_cache *bnc, struct nexthop *nexthop)
84{
85 struct nexthop *last;
86
87 for (last = bnc->nexthop; last && last->next; last = last->next)
88 ;
89 if (last)
90 last->next = nexthop;
91 else
92 bnc->nexthop = nexthop;
93 nexthop->prev = last;
94}
95
96void
97bnc_nexthop_free (struct bgp_nexthop_cache *bnc)
98{
99 struct nexthop *nexthop;
100 struct nexthop *next = NULL;
101
102 for (nexthop = bnc->nexthop; nexthop; nexthop = next)
103 {
104 next = nexthop->next;
105 XFREE (MTYPE_NEXTHOP, nexthop);
106 }
107}
108
109struct bgp_nexthop_cache *
110bnc_new ()
111{
112 struct bgp_nexthop_cache *new;
113
114 new = XMALLOC (MTYPE_BGP_NEXTHOP_CACHE, sizeof (struct bgp_nexthop_cache));
115 memset (new, 0, sizeof (struct bgp_nexthop_cache));
116 return new;
117}
118
119void
120bnc_free (struct bgp_nexthop_cache *bnc)
121{
122 bnc_nexthop_free (bnc);
123 XFREE (MTYPE_BGP_NEXTHOP_CACHE, bnc);
124}
125
126int
127bgp_nexthop_same (struct nexthop *next1, struct nexthop *next2)
128{
129 if (next1->type != next2->type)
130 return 0;
131
132 switch (next1->type)
133 {
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 */
156 }
157 return 1;
158}
159
160int
161bgp_nexthop_cache_changed (struct bgp_nexthop_cache *bnc1,
162 struct bgp_nexthop_cache *bnc2)
163{
164 int i;
165 struct nexthop *next1, *next2;
166
167 if (bnc1->nexthop_num != bnc2->nexthop_num)
168 return 1;
169
170 next1 = bnc1->nexthop;
171 next2 = bnc2->nexthop;
172
173 for (i = 0; i < bnc1->nexthop_num; i++)
174 {
175 if (! bgp_nexthop_same (next1, next2))
176 return 1;
177
178 next1 = next1->next;
179 next2 = next2->next;
180 }
181 return 0;
182}
183
184/* If nexthop exists on connected network return 1. */
185int
186bgp_nexthop_check_ebgp (afi_t afi, struct attr *attr)
187{
188 struct bgp_node *rn;
189
190 /* If zebra is not enabled return */
191 if (zlookup->sock < 0)
192 return 1;
193
194 /* Lookup the address is onlink or not. */
195 if (afi == AFI_IP)
196 {
197 rn = bgp_node_match_ipv4 (bgp_connected_ipv4, &attr->nexthop);
198 if (rn)
199 {
200 bgp_unlock_node (rn);
201 return 1;
202 }
203 }
204#ifdef HAVE_IPV6
205 else if (afi == AFI_IP6)
206 {
207 if (attr->mp_nexthop_len == 32)
208 return 1;
209 else if (attr->mp_nexthop_len == 16)
210 {
211 if (IN6_IS_ADDR_LINKLOCAL (&attr->mp_nexthop_global))
212 return 1;
213
214 rn = bgp_node_match_ipv6 (bgp_connected_ipv6,
215 &attr->mp_nexthop_global);
216 if (rn)
217 {
218 bgp_unlock_node (rn);
219 return 1;
220 }
221 }
222 }
223#endif /* HAVE_IPV6 */
224 return 0;
225}
226
227#ifdef HAVE_IPV6
228/* Check specified next-hop is reachable or not. */
229int
230bgp_nexthop_lookup_ipv6 (struct peer *peer, struct bgp_info *ri, int *changed,
231 int *metricchanged)
232{
233 struct bgp_node *rn;
234 struct prefix p;
235 struct bgp_nexthop_cache *bnc;
236 struct attr *attr;
237
238 /* If lookup is not enabled, return valid. */
239 if (zlookup->sock < 0)
240 {
241 ri->igpmetric = 0;
242 return 1;
243 }
244
245 /* Only check IPv6 global address only nexthop. */
246 attr = ri->attr;
247
248 if (attr->mp_nexthop_len != 16
249 || IN6_IS_ADDR_LINKLOCAL (&attr->mp_nexthop_global))
250 return 1;
251
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;
256
257 /* IBGP or ebgp-multihop */
258 rn = bgp_node_get (bgp_nexthop_cache_ipv6, &p);
259
260 if (rn->info)
261 {
262 bnc = rn->info;
263 bgp_unlock_node (rn);
264 }
265 else
266 {
267 bnc = zlookup_query_ipv6 (&attr->mp_nexthop_global);
268 if (bnc)
269 {
270 struct bgp_table *old;
271 struct bgp_node *oldrn;
272 struct bgp_nexthop_cache *oldbnc;
273
274 if (changed)
275 {
276 if (bgp_nexthop_cache_ipv6 == cache6_1)
277 old = cache6_2;
278 else
279 old = cache6_1;
280
281 oldrn = bgp_node_lookup (old, &p);
282 if (oldrn)
283 {
284 oldbnc = oldrn->info;
285
286 bnc->changed = bgp_nexthop_cache_changed (bnc, oldbnc);
287
288 if (bnc->metric != oldbnc->metric)
289 bnc->metricchanged = 1;
290 }
291 }
292 }
293 else
294 {
295 bnc = bnc_new ();
296 bnc->valid = 0;
297 }
298 rn->info = bnc;
299 }
300
301 if (changed)
302 *changed = bnc->changed;
303
304 if (metricchanged)
305 *metricchanged = bnc->metricchanged;
306
307 if (bnc->valid)
308 ri->igpmetric = bnc->metric;
309 else
310 ri->igpmetric = 0;
311
312 return bnc->valid;
313}
314#endif /* HAVE_IPV6 */
315
316/* Check specified next-hop is reachable or not. */
317int
318bgp_nexthop_lookup (afi_t afi, struct peer *peer, struct bgp_info *ri,
319 int *changed, int *metricchanged)
320{
321 struct bgp_node *rn;
322 struct prefix p;
323 struct bgp_nexthop_cache *bnc;
324 struct in_addr addr;
325
326 /* If lookup is not enabled, return valid. */
327 if (zlookup->sock < 0)
328 {
329 ri->igpmetric = 0;
330 return 1;
331 }
332
333#ifdef HAVE_IPV6
334 if (afi == AFI_IP6)
335 return bgp_nexthop_lookup_ipv6 (peer, ri, changed, metricchanged);
336#endif /* HAVE_IPV6 */
337
338 addr = ri->attr->nexthop;
339
340 memset (&p, 0, sizeof (struct prefix));
341 p.family = AF_INET;
342 p.prefixlen = IPV4_MAX_BITLEN;
343 p.u.prefix4 = addr;
344
345 /* IBGP or ebgp-multihop */
346 rn = bgp_node_get (bgp_nexthop_cache_ipv4, &p);
347
348 if (rn->info)
349 {
350 bnc = rn->info;
351 bgp_unlock_node (rn);
352 }
353 else
354 {
355 bnc = zlookup_query (addr);
356 if (bnc)
357 {
358 struct bgp_table *old;
359 struct bgp_node *oldrn;
360 struct bgp_nexthop_cache *oldbnc;
361
362 if (changed)
363 {
364 if (bgp_nexthop_cache_ipv4 == cache1)
365 old = cache2;
366 else
367 old = cache1;
368
369 oldrn = bgp_node_lookup (old, &p);
370 if (oldrn)
371 {
372 oldbnc = oldrn->info;
373
374 bnc->changed = bgp_nexthop_cache_changed (bnc, oldbnc);
375
376 if (bnc->metric != oldbnc->metric)
377 bnc->metricchanged = 1;
378 }
379 }
380 }
381 else
382 {
383 bnc = bnc_new ();
384 bnc->valid = 0;
385 }
386 rn->info = bnc;
387 }
388
389 if (changed)
390 *changed = bnc->changed;
391
392 if (metricchanged)
393 *metricchanged = bnc->metricchanged;
394
395 if (bnc->valid)
396 ri->igpmetric = bnc->metric;
397 else
398 ri->igpmetric = 0;
399
400 return bnc->valid;
401}
402
403/* Reset and free all BGP nexthop cache. */
404void
405bgp_nexthop_cache_reset (struct bgp_table *table)
406{
407 struct bgp_node *rn;
408 struct bgp_nexthop_cache *bnc;
409
410 for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
411 if ((bnc = rn->info) != NULL)
412 {
413 bnc_free (bnc);
414 rn->info = NULL;
415 bgp_unlock_node (rn);
416 }
417}
418
419void
420bgp_scan_ipv4 ()
421{
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;
432
433 /* Change cache. */
434 if (bgp_nexthop_cache_ipv4 == cache1)
435 bgp_nexthop_cache_ipv4 = cache2;
436 else
437 bgp_nexthop_cache_ipv4 = cache1;
438
439 /* Get default bgp. */
440 bgp = bgp_get_default ();
441 if (bgp == NULL)
442 return;
443
444 /* Maximum prefix check */
445 LIST_LOOP (bgp->peer, peer, nn)
446 {
447 if (peer->status != Established)
448 continue;
449
450 if (peer->afc[AFI_IP][SAFI_UNICAST])
451 bgp_maximum_prefix_overflow (peer, AFI_IP, SAFI_UNICAST);
452 if (peer->afc[AFI_IP][SAFI_MULTICAST])
453 bgp_maximum_prefix_overflow (peer, AFI_IP, SAFI_MULTICAST);
454 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
455 bgp_maximum_prefix_overflow (peer, AFI_IP, SAFI_MPLS_VPN);
456 }
457
458 for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_UNICAST]); rn;
459 rn = bgp_route_next (rn))
460 {
461 for (bi = rn->info; bi; bi = next)
462 {
463 next = bi->next;
464
465 if (bi->type == ZEBRA_ROUTE_BGP && bi->sub_type == BGP_ROUTE_NORMAL)
466 {
467 changed = 0;
468 metricchanged = 0;
469
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);
475
476 current = CHECK_FLAG (bi->flags, BGP_INFO_VALID) ? 1 : 0;
477
478 if (changed)
479 SET_FLAG (bi->flags, BGP_INFO_IGP_CHANGED);
480 else
481 UNSET_FLAG (bi->flags, BGP_INFO_IGP_CHANGED);
482
483 if (valid != current)
484 {
485 if (CHECK_FLAG (bi->flags, BGP_INFO_VALID))
486 {
487 bgp_aggregate_decrement (bgp, &rn->p, bi,
488 AFI_IP, SAFI_UNICAST);
489 UNSET_FLAG (bi->flags, BGP_INFO_VALID);
490 }
491 else
492 {
493 SET_FLAG (bi->flags, BGP_INFO_VALID);
494 bgp_aggregate_increment (bgp, &rn->p, bi,
495 AFI_IP, SAFI_UNICAST);
496 }
497 }
498
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);
505 }
506 }
507 bgp_process (bgp, rn, AFI_IP, SAFI_UNICAST);
508 }
509
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);
515}
516
517#ifdef HAVE_IPV6
518void
519bgp_scan_ipv6 ()
520{
521 struct bgp_node *rn;
522 struct bgp *bgp;
523 struct bgp_info *bi;
524 struct bgp_info *next;
525 struct peer *peer;
526 struct listnode *nn;
527 int valid;
528 int current;
529 int changed;
530 int metricchanged;
531
532 /* Change cache. */
533 if (bgp_nexthop_cache_ipv6 == cache6_1)
534 bgp_nexthop_cache_ipv6 = cache6_2;
535 else
536 bgp_nexthop_cache_ipv6 = cache6_1;
537
538 /* Get default bgp. */
539 bgp = bgp_get_default ();
540 if (bgp == NULL)
541 return;
542
543 /* Maximum prefix check */
544 LIST_LOOP (bgp->peer, peer, nn)
545 {
546 if (peer->status != Established)
547 continue;
548
549 if (peer->afc[AFI_IP6][SAFI_UNICAST])
550 bgp_maximum_prefix_overflow (peer, AFI_IP6, SAFI_UNICAST);
551 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
552 bgp_maximum_prefix_overflow (peer, AFI_IP6, SAFI_MULTICAST);
553 }
554
555 for (rn = bgp_table_top (bgp->rib[AFI_IP6][SAFI_UNICAST]); rn;
556 rn = bgp_route_next (rn))
557 {
558 for (bi = rn->info; bi; bi = next)
559 {
560 next = bi->next;
561
562 if (bi->type == ZEBRA_ROUTE_BGP && bi->sub_type == BGP_ROUTE_NORMAL)
563 {
564 changed = 0;
565 metricchanged = 0;
566
567 if (peer_sort (bi->peer) == BGP_PEER_EBGP && bi->peer->ttl == 1)
568 valid = 1;
569 else
570 valid = bgp_nexthop_lookup_ipv6 (bi->peer, bi,
571 &changed, &metricchanged);
572
573 current = CHECK_FLAG (bi->flags, BGP_INFO_VALID) ? 1 : 0;
574
575 if (changed)
576 SET_FLAG (bi->flags, BGP_INFO_IGP_CHANGED);
577 else
578 UNSET_FLAG (bi->flags, BGP_INFO_IGP_CHANGED);
579
580 if (valid != current)
581 {
582 if (CHECK_FLAG (bi->flags, BGP_INFO_VALID))
583 {
584 bgp_aggregate_decrement (bgp, &rn->p, bi,
585 AFI_IP6, SAFI_UNICAST);
586 UNSET_FLAG (bi->flags, BGP_INFO_VALID);
587 }
588 else
589 {
590 SET_FLAG (bi->flags, BGP_INFO_VALID);
591 bgp_aggregate_increment (bgp, &rn->p, bi,
592 AFI_IP6, SAFI_UNICAST);
593 }
594 }
595
596 if (CHECK_FLAG (bgp->af_flags[AFI_IP6][SAFI_UNICAST],
597 BGP_CONFIG_DAMPENING)
598 && bi->damp_info )
599 if (bgp_damp_scan (bi, AFI_IP6, SAFI_UNICAST))
600 bgp_aggregate_increment (bgp, &rn->p, bi,
601 AFI_IP6, SAFI_UNICAST);
602 }
603 }
604 bgp_process (bgp, rn, AFI_IP6, SAFI_UNICAST);
605 }
606
607 /* Flash old cache. */
608 if (bgp_nexthop_cache_ipv6 == cache6_1)
609 bgp_nexthop_cache_reset (cache6_2);
610 else
611 bgp_nexthop_cache_reset (cache6_1);
612}
613#endif /* HAVE_IPV6 */
614
615/* BGP scan thread. This thread check nexthop reachability. */
616int
617bgp_scan (struct thread *t)
618{
619 bgp_scan_thread =
620 thread_add_timer (master, bgp_scan, NULL, bgp_scan_interval);
621
622 if (BGP_DEBUG (normal, NORMAL))
623 zlog_info ("Performing BGP general scanning");
624
625 bgp_scan_ipv4 ();
626
627#ifdef HAVE_IPV6
628 bgp_scan_ipv6 ();
629#endif /* HAVE_IPV6 */
630
631 return 0;
632}
633
634struct bgp_connected
635{
636 unsigned int refcnt;
637};
638
639void
640bgp_connected_add (struct connected *ifc)
641{
642 struct prefix p;
643 struct prefix *addr;
644 struct prefix *dest;
645 struct interface *ifp;
646 struct bgp_node *rn;
647 struct bgp_connected *bc;
648
649 ifp = ifc->ifp;
650
651 if (! ifp)
652 return;
653
654 if (if_is_loopback (ifp))
655 return;
656
657 addr = ifc->address;
658 dest = ifc->destination;
659
660 if (addr->family == AF_INET)
661 {
662 memset (&p, 0, sizeof (struct prefix));
663 p.family = AF_INET;
664 p.prefixlen = addr->prefixlen;
665
paul00df0c12002-12-13 21:07:36 +0000666 if (ifc_pointopoint (ifc))
paul718e3742002-12-13 20:15:29 +0000667 p.u.prefix4 = dest->u.prefix4;
668 else
669 p.u.prefix4 = addr->u.prefix4;
670
671 apply_mask_ipv4 ((struct prefix_ipv4 *) &p);
672
673 if (prefix_ipv4_any ((struct prefix_ipv4 *) &p))
674 return;
675
676 rn = bgp_node_get (bgp_connected_ipv4, (struct prefix *) &p);
677 if (rn->info)
678 {
679 bc = rn->info;
680 bc->refcnt++;
681 }
682 else
683 {
684 bc = XMALLOC (0, sizeof (struct bgp_connected));
685 memset (bc, 0, sizeof (struct bgp_connected));
686 bc->refcnt = 1;
687 rn->info = bc;
688 }
689 }
690#ifdef HAVE_IPV6
691 if (addr->family == AF_INET6)
692 {
693 memset (&p, 0, sizeof (struct prefix));
694 p.family = AF_INET6;
695 p.prefixlen = addr->prefixlen;
696
paul00df0c12002-12-13 21:07:36 +0000697 if (ifc_pointopoint (ifc))
paul718e3742002-12-13 20:15:29 +0000698 p.u.prefix6 = dest->u.prefix6;
699 else
700 p.u.prefix6 = addr->u.prefix6;
701
702 apply_mask_ipv6 ((struct prefix_ipv6 *) &p);
703
704 if (IN6_IS_ADDR_UNSPECIFIED (&p.u.prefix6))
705 return;
706
707 if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
708 return;
709
710 rn = bgp_node_get (bgp_connected_ipv6, (struct prefix *) &p);
711 if (rn->info)
712 {
713 bc = rn->info;
714 bc->refcnt++;
715 }
716 else
717 {
718 bc = XMALLOC (0, sizeof (struct bgp_connected));
719 memset (bc, 0, sizeof (struct bgp_connected));
720 bc->refcnt = 1;
721 rn->info = bc;
722 }
723 }
724#endif /* HAVE_IPV6 */
725}
726
727void
728bgp_connected_delete (struct connected *ifc)
729{
730 struct prefix p;
731 struct prefix *addr;
732 struct prefix *dest;
733 struct interface *ifp;
734 struct bgp_node *rn;
735 struct bgp_connected *bc;
736
737 ifp = ifc->ifp;
738
739 if (if_is_loopback (ifp))
740 return;
741
742 addr = ifc->address;
743 dest = ifc->destination;
744
745 if (addr->family == AF_INET)
746 {
747 memset (&p, 0, sizeof (struct prefix));
748 p.family = AF_INET;
749 p.prefixlen = addr->prefixlen;
750
paul00df0c12002-12-13 21:07:36 +0000751 if (ifc_pointopoint (ifc))
paul718e3742002-12-13 20:15:29 +0000752 p.u.prefix4 = dest->u.prefix4;
753 else
754 p.u.prefix4 = addr->u.prefix4;
755
756 apply_mask_ipv4 ((struct prefix_ipv4 *) &p);
757
758 if (prefix_ipv4_any ((struct prefix_ipv4 *) &p))
759 return;
760
761 rn = bgp_node_lookup (bgp_connected_ipv4, &p);
762 if (! rn)
763 return;
764
765 bc = rn->info;
766 bc->refcnt--;
767 if (bc->refcnt == 0)
768 {
769 XFREE (0, bc);
770 rn->info = NULL;
771 }
772 bgp_unlock_node (rn);
773 bgp_unlock_node (rn);
774 }
775#ifdef HAVE_IPV6
776 else if (addr->family == AF_INET6)
777 {
778 memset (&p, 0, sizeof (struct prefix));
779 p.family = AF_INET6;
780 p.prefixlen = addr->prefixlen;
781
paul00df0c12002-12-13 21:07:36 +0000782 if (ifc_pointopoint (ifc))
paul718e3742002-12-13 20:15:29 +0000783 p.u.prefix6 = dest->u.prefix6;
784 else
785 p.u.prefix6 = addr->u.prefix6;
786
787 apply_mask_ipv6 ((struct prefix_ipv6 *) &p);
788
789 if (IN6_IS_ADDR_UNSPECIFIED (&p.u.prefix6))
790 return;
791
792 if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
793 return;
794
795 rn = bgp_node_lookup (bgp_connected_ipv6, (struct prefix *) &p);
796 if (! rn)
797 return;
798
799 bc = rn->info;
800 bc->refcnt--;
801 if (bc->refcnt == 0)
802 {
803 XFREE (0, bc);
804 rn->info = NULL;
805 }
806 bgp_unlock_node (rn);
807 bgp_unlock_node (rn);
808 }
809#endif /* HAVE_IPV6 */
810}
811
812int
813bgp_nexthop_self (afi_t afi, struct attr *attr)
814{
815 listnode node;
816 listnode node2;
817 struct interface *ifp;
818 struct connected *ifc;
819 struct prefix *p;
820
821 for (node = listhead (iflist); node; nextnode (node))
822 {
823 ifp = getdata (node);
824
825 for (node2 = listhead (ifp->connected); node2; nextnode (node2))
826 {
827 ifc = getdata (node2);
828 p = ifc->address;
829
830 if (p && p->family == AF_INET
831 && IPV4_ADDR_SAME (&p->u.prefix4, &attr->nexthop))
832 return 1;
833 }
834 }
835 return 0;
836}
837
838struct bgp_nexthop_cache *
839zlookup_read ()
840{
841 struct stream *s;
842 u_int16_t length;
843 u_char command;
844 int nbytes;
845 struct in_addr raddr;
846 u_int32_t metric;
847 int i;
848 u_char nexthop_num;
849 struct nexthop *nexthop;
850 struct bgp_nexthop_cache *bnc;
851
852 s = zlookup->ibuf;
853 stream_reset (s);
854
855 nbytes = stream_read (s, zlookup->sock, 2);
856 length = stream_getw (s);
857
858 nbytes = stream_read (s, zlookup->sock, length - 2);
859 command = stream_getc (s);
860 raddr.s_addr = stream_get_ipv4 (s);
861 metric = stream_getl (s);
862 nexthop_num = stream_getc (s);
863
864 if (nexthop_num)
865 {
866 bnc = bnc_new ();
867 bnc->valid = 1;
868 bnc->metric = metric;
869 bnc->nexthop_num = nexthop_num;
870
871 for (i = 0; i < nexthop_num; i++)
872 {
873 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
874 memset (nexthop, 0, sizeof (struct nexthop));
875 nexthop->type = stream_getc (s);
876 switch (nexthop->type)
877 {
878 case ZEBRA_NEXTHOP_IPV4:
879 nexthop->gate.ipv4.s_addr = stream_get_ipv4 (s);
880 break;
881 case ZEBRA_NEXTHOP_IFINDEX:
882 case ZEBRA_NEXTHOP_IFNAME:
883 nexthop->ifindex = stream_getl (s);
884 break;
885 }
886 bnc_nexthop_add (bnc, nexthop);
887 }
888 }
889 else
890 return NULL;
891
892 return bnc;
893}
894
895struct bgp_nexthop_cache *
896zlookup_query (struct in_addr addr)
897{
898 int ret;
899 struct stream *s;
900
901 /* Check socket. */
902 if (zlookup->sock < 0)
903 return NULL;
904
905 s = zlookup->obuf;
906 stream_reset (s);
907 stream_putw (s, 7);
908 stream_putc (s, ZEBRA_IPV4_NEXTHOP_LOOKUP);
909 stream_put_in_addr (s, &addr);
910
911 ret = writen (zlookup->sock, s->data, 7);
912 if (ret < 0)
913 {
914 zlog_err ("can't write to zlookup->sock");
915 close (zlookup->sock);
916 zlookup->sock = -1;
917 return NULL;
918 }
919 if (ret == 0)
920 {
921 zlog_err ("zlookup->sock connection closed");
922 close (zlookup->sock);
923 zlookup->sock = -1;
924 return NULL;
925 }
926
927 return zlookup_read ();
928}
929
930#ifdef HAVE_IPV6
931struct bgp_nexthop_cache *
932zlookup_read_ipv6 ()
933{
934 struct stream *s;
935 u_int16_t length;
936 u_char command;
937 int nbytes;
938 struct in6_addr raddr;
939 u_int32_t metric;
940 int i;
941 u_char nexthop_num;
942 struct nexthop *nexthop;
943 struct bgp_nexthop_cache *bnc;
944
945 s = zlookup->ibuf;
946 stream_reset (s);
947
948 nbytes = stream_read (s, zlookup->sock, 2);
949 length = stream_getw (s);
950
951 nbytes = stream_read (s, zlookup->sock, length - 2);
952 command = stream_getc (s);
953
954 stream_get (&raddr, s, 16);
955
956 metric = stream_getl (s);
957 nexthop_num = stream_getc (s);
958
959 if (nexthop_num)
960 {
961 bnc = bnc_new ();
962 bnc->valid = 1;
963 bnc->metric = metric;
964 bnc->nexthop_num = nexthop_num;
965
966 for (i = 0; i < nexthop_num; i++)
967 {
968 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
969 memset (nexthop, 0, sizeof (struct nexthop));
970 nexthop->type = stream_getc (s);
971 switch (nexthop->type)
972 {
973 case ZEBRA_NEXTHOP_IPV6:
974 stream_get (&nexthop->gate.ipv6, s, 16);
975 break;
976 case ZEBRA_NEXTHOP_IPV6_IFINDEX:
977 case ZEBRA_NEXTHOP_IPV6_IFNAME:
978 stream_get (&nexthop->gate.ipv6, s, 16);
979 nexthop->ifindex = stream_getl (s);
980 break;
981 case ZEBRA_NEXTHOP_IFINDEX:
982 case ZEBRA_NEXTHOP_IFNAME:
983 nexthop->ifindex = stream_getl (s);
984 break;
985 }
986 bnc_nexthop_add (bnc, nexthop);
987 }
988 }
989 else
990 return NULL;
991
992 return bnc;
993}
994
995struct bgp_nexthop_cache *
996zlookup_query_ipv6 (struct in6_addr *addr)
997{
998 int ret;
999 struct stream *s;
1000
1001 /* Check socket. */
1002 if (zlookup->sock < 0)
1003 return NULL;
1004
1005 s = zlookup->obuf;
1006 stream_reset (s);
1007 stream_putw (s, 19);
1008 stream_putc (s, ZEBRA_IPV6_NEXTHOP_LOOKUP);
1009 stream_put (s, addr, 16);
1010
1011 ret = writen (zlookup->sock, s->data, 19);
1012 if (ret < 0)
1013 {
1014 zlog_err ("can't write to zlookup->sock");
1015 close (zlookup->sock);
1016 zlookup->sock = -1;
1017 return NULL;
1018 }
1019 if (ret == 0)
1020 {
1021 zlog_err ("zlookup->sock connection closed");
1022 close (zlookup->sock);
1023 zlookup->sock = -1;
1024 return NULL;
1025 }
1026
1027 return zlookup_read_ipv6 ();
1028}
1029#endif /* HAVE_IPV6 */
1030
1031int
1032bgp_import_check (struct prefix *p, u_int32_t *igpmetric, struct in_addr *igpnexthop)
1033{
1034 struct stream *s;
1035 int ret;
1036 u_int16_t length;
1037 u_char command;
1038 int nbytes;
1039 struct in_addr addr;
1040 struct in_addr nexthop;
1041 u_int32_t metric = 0;
1042 u_char nexthop_num;
1043 u_char nexthop_type;
1044
1045 /* If lookup connection is not available return valid. */
1046 if (zlookup->sock < 0)
1047 {
1048 if (igpmetric)
1049 *igpmetric = 0;
1050 return 1;
1051 }
1052
1053 /* Send query to the lookup connection */
1054 s = zlookup->obuf;
1055 stream_reset (s);
1056 stream_putw (s, 8);
1057 stream_putc (s, ZEBRA_IPV4_IMPORT_LOOKUP);
1058 stream_putc (s, p->prefixlen);
1059 stream_put_in_addr (s, &p->u.prefix4);
1060
1061 /* Write the packet. */
1062 ret = writen (zlookup->sock, s->data, 8);
1063
1064 if (ret < 0)
1065 {
1066 zlog_err ("can't write to zlookup->sock");
1067 close (zlookup->sock);
1068 zlookup->sock = -1;
1069 return 1;
1070 }
1071 if (ret == 0)
1072 {
1073 zlog_err ("zlookup->sock connection closed");
1074 close (zlookup->sock);
1075 zlookup->sock = -1;
1076 return 1;
1077 }
1078
1079 /* Get result. */
1080 stream_reset (s);
1081
1082 /* Fetch length. */
1083 nbytes = stream_read (s, zlookup->sock, 2);
1084 length = stream_getw (s);
1085
1086 /* Fetch whole data. */
1087 nbytes = stream_read (s, zlookup->sock, length - 2);
1088 command = stream_getc (s);
1089 addr.s_addr = stream_get_ipv4 (s);
1090 metric = stream_getl (s);
1091 nexthop_num = stream_getc (s);
1092
1093 /* Set IGP metric value. */
1094 if (igpmetric)
1095 *igpmetric = metric;
1096
1097 /* If there is nexthop then this is active route. */
1098 if (nexthop_num)
1099 {
1100 nexthop.s_addr = 0;
1101 nexthop_type = stream_getc (s);
1102 if (nexthop_type == ZEBRA_NEXTHOP_IPV4)
1103 {
1104 nexthop.s_addr = stream_get_ipv4 (s);
1105 if (igpnexthop)
1106 *igpnexthop = nexthop;
1107 }
1108 else
1109 *igpnexthop = nexthop;
1110
1111 return 1;
1112 }
1113 else
1114 return 0;
1115}
1116
1117/* Scan all configured BGP route then check the route exists in IGP or
1118 not. */
1119int
1120bgp_import (struct thread *t)
1121{
paul6cbbc3c2003-04-28 17:11:02 +00001122 struct bgp_master *bm;
paul718e3742002-12-13 20:15:29 +00001123 struct bgp *bgp;
1124 struct bgp_node *rn;
1125 struct bgp_static *bgp_static;
paul6cbbc3c2003-04-28 17:11:02 +00001126 struct listnode *nn;
paul718e3742002-12-13 20:15:29 +00001127 int valid;
1128 u_int32_t metric;
1129 struct in_addr nexthop;
1130 afi_t afi;
1131 safi_t safi;
1132
1133 bgp_import_thread =
1134 thread_add_timer (master, bgp_import, NULL, bgp_import_interval);
1135
paul6cbbc3c2003-04-28 17:11:02 +00001136 bm = bgp_get_master ();
1137 if (! bm)
paul718e3742002-12-13 20:15:29 +00001138 return 0;
1139
paul6cbbc3c2003-04-28 17:11:02 +00001140 LIST_LOOP (bm->bgp, bgp, nn)
1141 {
1142 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1143 for (safi = SAFI_UNICAST; safi < SAFI_MPLS_VPN; safi++)
1144 for (rn = bgp_table_top (bgp->route[afi][safi]); rn;
1145 rn = bgp_route_next (rn))
1146 if ((bgp_static = rn->info) != NULL)
paul718e3742002-12-13 20:15:29 +00001147 {
paul6cbbc3c2003-04-28 17:11:02 +00001148 if (bgp_static->backdoor)
1149 continue;
paul718e3742002-12-13 20:15:29 +00001150
paul6cbbc3c2003-04-28 17:11:02 +00001151 valid = bgp_static->valid;
1152 metric = bgp_static->igpmetric;
1153 nexthop = bgp_static->igpnexthop;
1154
1155 if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK)
1156 && afi == AFI_IP && safi == SAFI_UNICAST)
1157 bgp_static->valid = bgp_import_check (&rn->p, &bgp_static->igpmetric,
1158 &bgp_static->igpnexthop);
paul718e3742002-12-13 20:15:29 +00001159 else
paul6cbbc3c2003-04-28 17:11:02 +00001160 {
1161 bgp_static->valid = 1;
1162 bgp_static->igpmetric = 0;
1163 bgp_static->igpnexthop.s_addr = 0;
1164 }
1165
1166 if (bgp_static->valid != valid)
1167 {
1168 if (bgp_static->valid)
1169 bgp_static_update (bgp, &rn->p, bgp_static, afi, safi);
1170 else
1171 bgp_static_withdraw (bgp, &rn->p, afi, safi);
1172 }
1173 else if (bgp_static->valid)
1174 {
1175 if (bgp_static->igpmetric != metric
1176 || bgp_static->igpnexthop.s_addr != nexthop.s_addr
1177 || bgp_static->rmap.name)
1178 bgp_static_update (bgp, &rn->p, bgp_static, afi, safi);
1179 }
paul718e3742002-12-13 20:15:29 +00001180 }
paul6cbbc3c2003-04-28 17:11:02 +00001181 }
paul718e3742002-12-13 20:15:29 +00001182 return 0;
1183}
1184
1185/* Connect to zebra for nexthop lookup. */
1186int
1187zlookup_connect (struct thread *t)
1188{
1189 struct zclient *zlookup;
1190
1191 zlookup = THREAD_ARG (t);
1192 zlookup->t_connect = NULL;
1193
1194 if (zlookup->sock != -1)
1195 return 0;
1196
1197#ifdef HAVE_TCP_ZEBRA
1198 zlookup->sock = zclient_socket ();
1199#else
1200 zlookup->sock = zclient_socket_un (ZEBRA_SERV_PATH);
1201#endif /* HAVE_TCP_ZEBRA */
1202 if (zlookup->sock < 0)
1203 return -1;
1204
paul718e3742002-12-13 20:15:29 +00001205 return 0;
1206}
1207
1208/* Check specified multiaccess next-hop. */
1209int
1210bgp_multiaccess_check_v4 (struct in_addr nexthop, char *peer)
1211{
1212 struct bgp_node *rn1;
1213 struct bgp_node *rn2;
1214 struct prefix p1;
1215 struct prefix p2;
1216 struct in_addr addr;
1217 int ret;
1218
1219 ret = inet_aton (peer, &addr);
1220 if (! ret)
1221 return 0;
1222
1223 memset (&p1, 0, sizeof (struct prefix));
1224 p1.family = AF_INET;
1225 p1.prefixlen = IPV4_MAX_BITLEN;
1226 p1.u.prefix4 = nexthop;
1227 memset (&p2, 0, sizeof (struct prefix));
1228 p2.family = AF_INET;
1229 p2.prefixlen = IPV4_MAX_BITLEN;
1230 p2.u.prefix4 = addr;
1231
1232 /* If bgp scan is not enabled, return invalid. */
1233 if (zlookup->sock < 0)
1234 return 0;
1235
1236 rn1 = bgp_node_match (bgp_connected_ipv4, &p1);
1237 if (! rn1)
1238 return 0;
1239
1240 rn2 = bgp_node_match (bgp_connected_ipv4, &p2);
1241 if (! rn2)
1242 return 0;
1243
1244 if (rn1 == rn2)
1245 return 1;
1246
1247 return 0;
1248}
1249
1250DEFUN (bgp_scan_time,
1251 bgp_scan_time_cmd,
1252 "bgp scan-time <5-60>",
1253 "BGP specific commands\n"
1254 "Configure background scanner interval\n"
1255 "Scanner interval (seconds)\n")
1256{
1257 bgp_scan_interval = atoi (argv[0]);
1258
1259 if (bgp_scan_thread)
1260 {
1261 thread_cancel (bgp_scan_thread);
1262 bgp_scan_thread =
1263 thread_add_timer (master, bgp_scan, NULL, bgp_scan_interval);
1264 }
1265
1266 return CMD_SUCCESS;
1267}
1268
1269DEFUN (no_bgp_scan_time,
1270 no_bgp_scan_time_cmd,
1271 "no bgp scan-time",
1272 NO_STR
1273 "BGP specific commands\n"
1274 "Configure background scanner interval\n")
1275{
1276 bgp_scan_interval = BGP_SCAN_INTERVAL_DEFAULT;
1277
1278 if (bgp_scan_thread)
1279 {
1280 thread_cancel (bgp_scan_thread);
1281 bgp_scan_thread =
1282 thread_add_timer (master, bgp_scan, NULL, bgp_scan_interval);
1283 }
1284
1285 return CMD_SUCCESS;
1286}
1287
1288ALIAS (no_bgp_scan_time,
1289 no_bgp_scan_time_val_cmd,
1290 "no bgp scan-time <5-60>",
1291 NO_STR
1292 "BGP specific commands\n"
1293 "Configure background scanner interval\n"
1294 "Scanner interval (seconds)\n")
1295
1296DEFUN (show_ip_bgp_scan,
1297 show_ip_bgp_scan_cmd,
1298 "show ip bgp scan",
1299 SHOW_STR
1300 IP_STR
1301 BGP_STR
1302 "BGP scan status\n")
1303{
1304 struct bgp_node *rn;
1305 struct bgp_nexthop_cache *bnc;
1306
1307 if (bgp_scan_thread)
1308 vty_out (vty, "BGP scan is running%s", VTY_NEWLINE);
1309 else
1310 vty_out (vty, "BGP scan is not running%s", VTY_NEWLINE);
1311 vty_out (vty, "BGP scan interval is %d%s", bgp_scan_interval, VTY_NEWLINE);
1312
1313 vty_out (vty, "Current BGP nexthop cache:%s", VTY_NEWLINE);
1314 for (rn = bgp_table_top (bgp_nexthop_cache_ipv4); rn; rn = bgp_route_next (rn))
1315 if ((bnc = rn->info) != NULL)
1316 {
1317 if (bnc->valid)
1318 vty_out (vty, " %s valid [IGP metric %d]%s",
1319 inet_ntoa (rn->p.u.prefix4), bnc->metric, VTY_NEWLINE);
1320 else
1321 vty_out (vty, " %s invalid%s",
1322 inet_ntoa (rn->p.u.prefix4), VTY_NEWLINE);
1323 }
1324
1325#ifdef HAVE_IPV6
1326 {
1327 char buf[BUFSIZ];
1328 for (rn = bgp_table_top (bgp_nexthop_cache_ipv6); rn; rn = bgp_route_next (rn))
1329 if ((bnc = rn->info) != NULL)
1330 {
1331 if (bnc->valid)
1332 vty_out (vty, " %s valid [IGP metric %d]%s",
1333 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1334 bnc->metric, VTY_NEWLINE);
1335 else
1336 vty_out (vty, " %s invalid%s",
1337 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1338 VTY_NEWLINE);
1339 }
1340 }
1341#endif /* HAVE_IPV6 */
1342
1343 vty_out (vty, "BGP connected route:%s", VTY_NEWLINE);
1344 for (rn = bgp_table_top (bgp_connected_ipv4); rn; rn = bgp_route_next (rn))
1345 if (rn->info != NULL)
1346 vty_out (vty, " %s/%d%s", inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
1347 VTY_NEWLINE);
1348
1349#ifdef HAVE_IPV6
1350 {
1351 char buf[BUFSIZ];
1352
1353 for (rn = bgp_table_top (bgp_connected_ipv6); rn; rn = bgp_route_next (rn))
1354 if (rn->info != NULL)
1355 vty_out (vty, " %s/%d%s",
1356 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1357 rn->p.prefixlen,
1358 VTY_NEWLINE);
1359 }
1360#endif /* HAVE_IPV6 */
1361
1362 return CMD_SUCCESS;
1363}
1364
1365int
1366bgp_config_write_scan_time (struct vty *vty)
1367{
1368 if (bgp_scan_interval != BGP_SCAN_INTERVAL_DEFAULT)
1369 vty_out (vty, " bgp scan-time %d%s", bgp_scan_interval, VTY_NEWLINE);
1370 return CMD_SUCCESS;
1371}
1372
1373void
1374bgp_scan_init ()
1375{
1376 zlookup = zclient_new ();
1377 zlookup->sock = -1;
1378 zlookup->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1379 zlookup->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1380 zlookup->t_connect = thread_add_event (master, zlookup_connect, zlookup, 0);
1381
1382 bgp_scan_interval = BGP_SCAN_INTERVAL_DEFAULT;
1383 bgp_import_interval = BGP_IMPORT_INTERVAL_DEFAULT;
1384
1385 cache1 = bgp_table_init ();
1386 cache2 = bgp_table_init ();
1387 bgp_nexthop_cache_ipv4 = cache1;
1388
1389 bgp_connected_ipv4 = bgp_table_init ();
1390
1391#ifdef HAVE_IPV6
1392 cache6_1 = bgp_table_init ();
1393 cache6_2 = bgp_table_init ();
1394 bgp_nexthop_cache_ipv6 = cache6_1;
1395 bgp_connected_ipv6 = bgp_table_init ();
1396#endif /* HAVE_IPV6 */
1397
1398 /* Make BGP scan thread. */
1399 bgp_scan_thread = thread_add_timer (master, bgp_scan, NULL, bgp_scan_interval);
paul6cbbc3c2003-04-28 17:11:02 +00001400 /* Make BGP import there. */
1401 bgp_import_thread = thread_add_timer (master, bgp_import, NULL, 0);
paul718e3742002-12-13 20:15:29 +00001402
1403 install_element (BGP_NODE, &bgp_scan_time_cmd);
1404 install_element (BGP_NODE, &no_bgp_scan_time_cmd);
1405 install_element (BGP_NODE, &no_bgp_scan_time_val_cmd);
1406 install_element (VIEW_NODE, &show_ip_bgp_scan_cmd);
1407 install_element (ENABLE_NODE, &show_ip_bgp_scan_cmd);
1408}