]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_nexthop.c
Initial revision
[mirror_frr.git] / bgpd / bgp_nexthop.c
CommitLineData
718e3744 1/* 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\f
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\f
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\f
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\f
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
666 if (if_is_pointopoint (ifp))
667 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
697 if (if_is_pointopoint (ifp))
698 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
751 if (if_is_pointopoint (ifp))
752 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
782 if (if_is_pointopoint (ifp))
783 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\f
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{
1122 struct bgp *bgp;
1123 struct bgp_node *rn;
1124 struct bgp_static *bgp_static;
1125 int valid;
1126 u_int32_t metric;
1127 struct in_addr nexthop;
1128 afi_t afi;
1129 safi_t safi;
1130
1131 bgp_import_thread =
1132 thread_add_timer (master, bgp_import, NULL, bgp_import_interval);
1133
1134 bgp = bgp_get_default ();
1135 if (! bgp)
1136 return 0;
1137
1138 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1139 for (safi = SAFI_UNICAST; safi < SAFI_MPLS_VPN; safi++)
1140 for (rn = bgp_table_top (bgp->route[afi][safi]); rn;
1141 rn = bgp_route_next (rn))
1142 if ((bgp_static = rn->info) != NULL)
1143 {
1144 if (bgp_static->backdoor)
1145 continue;
1146
1147 valid = bgp_static->valid;
1148 metric = bgp_static->igpmetric;
1149 nexthop = bgp_static->igpnexthop;
1150
1151 if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK)
1152 && afi == AFI_IP && safi == SAFI_UNICAST)
1153 bgp_static->valid = bgp_import_check (&rn->p, &bgp_static->igpmetric,
1154 &bgp_static->igpnexthop);
1155 else
1156 {
1157 bgp_static->valid = 1;
1158 bgp_static->igpmetric = 0;
1159 bgp_static->igpnexthop.s_addr = 0;
1160 }
1161
1162 if (bgp_static->valid != valid)
1163 {
1164 if (bgp_static->valid)
1165 bgp_static_update (bgp, &rn->p, bgp_static, afi, safi);
1166 else
1167 bgp_static_withdraw (bgp, &rn->p, afi, safi);
1168 }
1169 else if (bgp_static->valid)
1170 {
1171 if (bgp_static->igpmetric != metric
1172 || bgp_static->igpnexthop.s_addr != nexthop.s_addr
1173 || bgp_static->rmap.name)
1174 bgp_static_update (bgp, &rn->p, bgp_static, afi, safi);
1175 }
1176 }
1177 return 0;
1178}
1179
1180/* Connect to zebra for nexthop lookup. */
1181int
1182zlookup_connect (struct thread *t)
1183{
1184 struct zclient *zlookup;
1185
1186 zlookup = THREAD_ARG (t);
1187 zlookup->t_connect = NULL;
1188
1189 if (zlookup->sock != -1)
1190 return 0;
1191
1192#ifdef HAVE_TCP_ZEBRA
1193 zlookup->sock = zclient_socket ();
1194#else
1195 zlookup->sock = zclient_socket_un (ZEBRA_SERV_PATH);
1196#endif /* HAVE_TCP_ZEBRA */
1197 if (zlookup->sock < 0)
1198 return -1;
1199
1200 /* Make BGP import there. */
1201 bgp_import_thread =
1202 thread_add_timer (master, bgp_import, NULL, 0);
1203
1204 return 0;
1205}
1206
1207/* Check specified multiaccess next-hop. */
1208int
1209bgp_multiaccess_check_v4 (struct in_addr nexthop, char *peer)
1210{
1211 struct bgp_node *rn1;
1212 struct bgp_node *rn2;
1213 struct prefix p1;
1214 struct prefix p2;
1215 struct in_addr addr;
1216 int ret;
1217
1218 ret = inet_aton (peer, &addr);
1219 if (! ret)
1220 return 0;
1221
1222 memset (&p1, 0, sizeof (struct prefix));
1223 p1.family = AF_INET;
1224 p1.prefixlen = IPV4_MAX_BITLEN;
1225 p1.u.prefix4 = nexthop;
1226 memset (&p2, 0, sizeof (struct prefix));
1227 p2.family = AF_INET;
1228 p2.prefixlen = IPV4_MAX_BITLEN;
1229 p2.u.prefix4 = addr;
1230
1231 /* If bgp scan is not enabled, return invalid. */
1232 if (zlookup->sock < 0)
1233 return 0;
1234
1235 rn1 = bgp_node_match (bgp_connected_ipv4, &p1);
1236 if (! rn1)
1237 return 0;
1238
1239 rn2 = bgp_node_match (bgp_connected_ipv4, &p2);
1240 if (! rn2)
1241 return 0;
1242
1243 if (rn1 == rn2)
1244 return 1;
1245
1246 return 0;
1247}
1248\f
1249DEFUN (bgp_scan_time,
1250 bgp_scan_time_cmd,
1251 "bgp scan-time <5-60>",
1252 "BGP specific commands\n"
1253 "Configure background scanner interval\n"
1254 "Scanner interval (seconds)\n")
1255{
1256 bgp_scan_interval = atoi (argv[0]);
1257
1258 if (bgp_scan_thread)
1259 {
1260 thread_cancel (bgp_scan_thread);
1261 bgp_scan_thread =
1262 thread_add_timer (master, bgp_scan, NULL, bgp_scan_interval);
1263 }
1264
1265 return CMD_SUCCESS;
1266}
1267
1268DEFUN (no_bgp_scan_time,
1269 no_bgp_scan_time_cmd,
1270 "no bgp scan-time",
1271 NO_STR
1272 "BGP specific commands\n"
1273 "Configure background scanner interval\n")
1274{
1275 bgp_scan_interval = BGP_SCAN_INTERVAL_DEFAULT;
1276
1277 if (bgp_scan_thread)
1278 {
1279 thread_cancel (bgp_scan_thread);
1280 bgp_scan_thread =
1281 thread_add_timer (master, bgp_scan, NULL, bgp_scan_interval);
1282 }
1283
1284 return CMD_SUCCESS;
1285}
1286
1287ALIAS (no_bgp_scan_time,
1288 no_bgp_scan_time_val_cmd,
1289 "no bgp scan-time <5-60>",
1290 NO_STR
1291 "BGP specific commands\n"
1292 "Configure background scanner interval\n"
1293 "Scanner interval (seconds)\n")
1294
1295DEFUN (show_ip_bgp_scan,
1296 show_ip_bgp_scan_cmd,
1297 "show ip bgp scan",
1298 SHOW_STR
1299 IP_STR
1300 BGP_STR
1301 "BGP scan status\n")
1302{
1303 struct bgp_node *rn;
1304 struct bgp_nexthop_cache *bnc;
1305
1306 if (bgp_scan_thread)
1307 vty_out (vty, "BGP scan is running%s", VTY_NEWLINE);
1308 else
1309 vty_out (vty, "BGP scan is not running%s", VTY_NEWLINE);
1310 vty_out (vty, "BGP scan interval is %d%s", bgp_scan_interval, VTY_NEWLINE);
1311
1312 vty_out (vty, "Current BGP nexthop cache:%s", VTY_NEWLINE);
1313 for (rn = bgp_table_top (bgp_nexthop_cache_ipv4); rn; rn = bgp_route_next (rn))
1314 if ((bnc = rn->info) != NULL)
1315 {
1316 if (bnc->valid)
1317 vty_out (vty, " %s valid [IGP metric %d]%s",
1318 inet_ntoa (rn->p.u.prefix4), bnc->metric, VTY_NEWLINE);
1319 else
1320 vty_out (vty, " %s invalid%s",
1321 inet_ntoa (rn->p.u.prefix4), VTY_NEWLINE);
1322 }
1323
1324#ifdef HAVE_IPV6
1325 {
1326 char buf[BUFSIZ];
1327 for (rn = bgp_table_top (bgp_nexthop_cache_ipv6); rn; rn = bgp_route_next (rn))
1328 if ((bnc = rn->info) != NULL)
1329 {
1330 if (bnc->valid)
1331 vty_out (vty, " %s valid [IGP metric %d]%s",
1332 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1333 bnc->metric, VTY_NEWLINE);
1334 else
1335 vty_out (vty, " %s invalid%s",
1336 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1337 VTY_NEWLINE);
1338 }
1339 }
1340#endif /* HAVE_IPV6 */
1341
1342 vty_out (vty, "BGP connected route:%s", VTY_NEWLINE);
1343 for (rn = bgp_table_top (bgp_connected_ipv4); rn; rn = bgp_route_next (rn))
1344 if (rn->info != NULL)
1345 vty_out (vty, " %s/%d%s", inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
1346 VTY_NEWLINE);
1347
1348#ifdef HAVE_IPV6
1349 {
1350 char buf[BUFSIZ];
1351
1352 for (rn = bgp_table_top (bgp_connected_ipv6); rn; rn = bgp_route_next (rn))
1353 if (rn->info != NULL)
1354 vty_out (vty, " %s/%d%s",
1355 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
1356 rn->p.prefixlen,
1357 VTY_NEWLINE);
1358 }
1359#endif /* HAVE_IPV6 */
1360
1361 return CMD_SUCCESS;
1362}
1363
1364int
1365bgp_config_write_scan_time (struct vty *vty)
1366{
1367 if (bgp_scan_interval != BGP_SCAN_INTERVAL_DEFAULT)
1368 vty_out (vty, " bgp scan-time %d%s", bgp_scan_interval, VTY_NEWLINE);
1369 return CMD_SUCCESS;
1370}
1371
1372void
1373bgp_scan_init ()
1374{
1375 zlookup = zclient_new ();
1376 zlookup->sock = -1;
1377 zlookup->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1378 zlookup->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1379 zlookup->t_connect = thread_add_event (master, zlookup_connect, zlookup, 0);
1380
1381 bgp_scan_interval = BGP_SCAN_INTERVAL_DEFAULT;
1382 bgp_import_interval = BGP_IMPORT_INTERVAL_DEFAULT;
1383
1384 cache1 = bgp_table_init ();
1385 cache2 = bgp_table_init ();
1386 bgp_nexthop_cache_ipv4 = cache1;
1387
1388 bgp_connected_ipv4 = bgp_table_init ();
1389
1390#ifdef HAVE_IPV6
1391 cache6_1 = bgp_table_init ();
1392 cache6_2 = bgp_table_init ();
1393 bgp_nexthop_cache_ipv6 = cache6_1;
1394 bgp_connected_ipv6 = bgp_table_init ();
1395#endif /* HAVE_IPV6 */
1396
1397 /* Make BGP scan thread. */
1398 bgp_scan_thread = thread_add_timer (master, bgp_scan, NULL, bgp_scan_interval);
1399
1400 install_element (BGP_NODE, &bgp_scan_time_cmd);
1401 install_element (BGP_NODE, &no_bgp_scan_time_cmd);
1402 install_element (BGP_NODE, &no_bgp_scan_time_val_cmd);
1403 install_element (VIEW_NODE, &show_ip_bgp_scan_cmd);
1404 install_element (ENABLE_NODE, &show_ip_bgp_scan_cmd);
1405}