]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/rfapi/vnc_import_bgp.c
bgpd: use loops to reduce code duplication
[mirror_frr.git] / bgpd / rfapi / vnc_import_bgp.c
1 /*
2 *
3 * Copyright 2009-2016, LabN Consulting, L.L.C.
4 *
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 *
20 */
21
22 /*
23 * File: vnc_import_bgp.c
24 * Purpose: Import routes from BGP unicast directly (not via zebra)
25 */
26
27 #include "lib/zebra.h"
28 #include "lib/prefix.h"
29 #include "lib/table.h"
30 #include "lib/vty.h"
31 #include "lib/log.h"
32 #include "lib/memory.h"
33 #include "lib/linklist.h"
34 #include "lib/plist.h"
35 #include "lib/routemap.h"
36
37 #include "bgpd/bgpd.h"
38 #include "bgpd/bgp_ecommunity.h"
39 #include "bgpd/bgp_attr.h"
40 #include "bgpd/bgp_mplsvpn.h" /* for RD_TYPE_IP */
41
42 #include "bgpd/rfapi/vnc_export_bgp.h"
43 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
44 #include "bgpd/rfapi/rfapi.h"
45 #include "bgpd/rfapi/rfapi_import.h"
46 #include "bgpd/rfapi/rfapi_private.h"
47 #include "bgpd/rfapi/rfapi_monitor.h"
48 #include "bgpd/rfapi/rfapi_vty.h"
49 #include "bgpd/rfapi/vnc_import_bgp.h"
50 #include "bgpd/rfapi/vnc_import_bgp_p.h"
51 #include "bgpd/rfapi/vnc_debug.h"
52
53 #define ENABLE_VNC_RHNCK
54
55 #define DEBUG_RHN_LIST 0
56
57 static struct rfapi_descriptor vncHDBgpDirect; /* dummy nve descriptor */
58 static struct rfapi_descriptor vncHDResolveNve; /* dummy nve descriptor */
59
60 /*
61 * For routes from another AS:
62 *
63 * If MED is set,
64 * LOCAL_PREF = 255 - MIN(255, MED)
65 * else
66 * LOCAL_PREF = default_local_pref
67 *
68 * For routes from the same AS:
69 *
70 * LOCAL_PREF unchanged
71 */
72 uint32_t
73 calc_local_pref (struct attr *attr, struct peer *peer)
74 {
75 uint32_t local_pref = 0;
76
77 if (!attr)
78 {
79 if (peer)
80 {
81 return peer->bgp->default_local_pref;
82 }
83 return bgp_get_default ()->default_local_pref;
84 }
85
86 if (peer && (peer->as != peer->bgp->as))
87 {
88 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
89 {
90 if (attr->med > 255)
91 {
92 local_pref = 0;
93 }
94 else
95 {
96 local_pref = 255 - attr->med;
97 }
98 }
99 else
100 {
101 local_pref = peer->bgp->default_local_pref;
102 }
103 }
104 else
105 {
106 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
107 {
108 local_pref = attr->local_pref;
109 }
110 else
111 {
112 if (peer && peer->bgp)
113 {
114 local_pref = peer->bgp->default_local_pref;
115 }
116 }
117 }
118
119 return local_pref;
120 }
121
122 static int
123 is_host_prefix (struct prefix *p)
124 {
125 switch (p->family)
126 {
127 case AF_INET:
128 return (p->prefixlen == 32);
129 case AF_INET6:
130 return (p->prefixlen == 128);
131 }
132 return 0;
133 }
134
135 /***********************************************************************
136 * RHN list
137 ***********************************************************************/
138
139 struct prefix_bag
140 {
141 struct prefix hpfx; /* ce address = unicast nexthop */
142 struct prefix upfx; /* unicast prefix */
143 struct bgp_info *ubi; /* unicast route */
144 };
145
146 static const u_char maskbit[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0,
147 0xf8, 0xfc, 0xfe, 0xff
148 };
149
150 int
151 vnc_prefix_cmp (void *pfx1, void *pfx2)
152 {
153 int offset;
154 int shift;
155 u_char mask;
156
157 struct prefix *p1 = pfx1;
158 struct prefix *p2 = pfx2;
159
160 if (p1->family < p2->family)
161 return -1;
162 if (p1->family > p2->family)
163 return 1;
164
165 if (p1->prefixlen < p2->prefixlen)
166 return -1;
167 if (p1->prefixlen > p2->prefixlen)
168 return 1;
169
170 offset = p1->prefixlen / 8;
171 shift = p1->prefixlen % 8;
172 if (shift == 0 && offset)
173 { /* catch aligned case */
174 offset--;
175 shift = 8;
176 }
177
178 /* Set both prefix's head pointer. */
179 const u_char *pp1 = (const u_char *) &p1->u.prefix;
180 const u_char *pp2 = (const u_char *) &p2->u.prefix;
181
182 while (offset--)
183 {
184 if (*pp1 < *pp2)
185 return -1;
186 if (*pp1 > *pp2)
187 return 1;
188 ++pp1;
189 ++pp2;
190 }
191
192 mask = maskbit[shift];
193 if ((*pp1 & mask) < (*pp2 & mask))
194 return -1;
195 if ((*pp1 & mask) > (*pp2 & mask))
196 return 1;
197
198 return 0;
199 }
200
201 static void
202 prefix_bag_free (void *pb)
203 {
204 XFREE (MTYPE_RFAPI_PREFIX_BAG, pb);
205 }
206
207 #if DEBUG_RHN_LIST
208 static void
209 print_rhn_list (const char *tag1, const char *tag2)
210 {
211 struct bgp *bgp = bgp_get_default ();
212 struct skiplist *sl = bgp->rfapi->resolve_nve_nexthop;
213 struct skiplistnode *p;
214 struct prefix_bag *pb;
215 int count = 0;
216
217 if (!sl)
218 {
219 zlog_debug ("%s: %s: RHN List is empty", (tag1 ? tag1 : ""),
220 (tag2 ? tag2 : ""));
221 return;
222 }
223
224 zlog_debug ("%s: %s: RHN list:", (tag1 ? tag1 : ""), (tag2 ? tag2 : ""));
225
226 /* XXX uses secret knowledge of skiplist structure */
227 for (p = sl->header->forward[0]; p; p = p->forward[0])
228 {
229 char kbuf[BUFSIZ];
230 char hbuf[BUFSIZ];
231 char ubuf[BUFSIZ];
232
233 pb = p->value;
234
235 prefix2str (p->key, kbuf, BUFSIZ);
236 prefix2str (&pb->hpfx, hbuf, BUFSIZ);
237 prefix2str (&pb->upfx, ubuf, BUFSIZ);
238
239 zlog_debug ("RHN Entry %d (q=%p): kpfx=%s, upfx=%s, hpfx=%s, ubi=%p",
240 ++count, p, kbuf, ubuf, hbuf, pb->ubi);
241 }
242 }
243 #endif
244
245 #ifdef ENABLE_VNC_RHNCK
246 static void
247 vnc_rhnck (char *tag)
248 {
249 struct bgp *bgp;
250 struct skiplist *sl;
251 struct skiplistnode *p;
252
253 bgp = bgp_get_default ();
254 sl = bgp->rfapi->resolve_nve_nexthop;
255
256 if (!sl)
257 return;
258
259 /* XXX uses secret knowledge of skiplist structure */
260 for (p = sl->header->forward[0]; p; p = p->forward[0])
261 {
262 struct prefix_bag *pb;
263 struct prefix *pkey;
264 afi_t afi;
265 struct prefix pfx_orig_nexthop;
266
267 memset (&pfx_orig_nexthop, 0, sizeof (struct prefix)); /* keep valgrind happy */
268
269 pkey = p->key;
270 pb = p->value;
271
272 afi = family2afi (pb->upfx.family);
273
274 rfapiUnicastNexthop2Prefix (afi, pb->ubi->attr, &pfx_orig_nexthop);
275
276 /* pb->hpfx, pb->ubi nexthop, pkey should all reflect the same pfx */
277 assert (!vnc_prefix_cmp (&pb->hpfx, pkey));
278 if (vnc_prefix_cmp (&pb->hpfx, &pfx_orig_nexthop))
279 {
280 char str_onh[BUFSIZ];
281 char str_nve_pfx[BUFSIZ];
282
283 prefix2str (&pfx_orig_nexthop, str_onh, BUFSIZ);
284 str_onh[BUFSIZ - 1] = 0;
285
286 prefix2str (&pb->hpfx, str_nve_pfx, BUFSIZ);
287 str_nve_pfx[BUFSIZ - 1] = 0;
288
289 zlog_debug
290 ("%s: %s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s",
291 __func__, tag, str_onh, str_nve_pfx);
292 assert (0);
293 }
294 }
295 zlog_debug ("%s: vnc_rhnck OK", tag);
296 }
297
298 #define VNC_RHNCK(n) do {char buf[BUFSIZ];sprintf(buf,"%s: %s", __func__, #n);vnc_rhnck(buf);} while (0)
299
300 #else
301
302 #define VNC_RHNCK(n)
303
304 #endif
305
306 /***********************************************************************
307 * Add/Delete Unicast Route
308 ***********************************************************************/
309
310 /*
311 * "Adding a Route" import process
312 */
313
314 /*
315 * extract and package information from the BGP unicast route.
316 * Return code 0 means OK, non-0 means drop.
317 *
318 * If return code is 0, caller MUST release ecom
319 */
320 static int
321 process_unicast_route (
322 struct bgp *bgp, /* in */
323 afi_t afi, /* in */
324 struct prefix *prefix, /* in */
325 struct bgp_info *info, /* in */
326 struct ecommunity **ecom, /* OUT */
327 struct prefix *unicast_nexthop) /* OUT */
328 {
329 struct rfapi_cfg *hc = bgp->rfapi_cfg;
330 struct peer *peer = info->peer;
331 struct attr *attr = info->attr;
332 struct attr hattr;
333 struct route_map *rmap = NULL;
334 struct prefix pfx_orig_nexthop;
335
336 memset (&pfx_orig_nexthop, 0, sizeof (struct prefix)); /* keep valgrind happy */
337
338 /*
339 * prefix list check
340 */
341 if (hc->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi])
342 {
343 zlog_debug ("%s: HC prefix list is set, checking", __func__);
344 if (prefix_list_apply
345 (hc->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi],
346 prefix) == PREFIX_DENY)
347 {
348 zlog_debug ("%s: prefix list returns DENY, blocking route",
349 __func__);
350 return -1;
351 }
352 zlog_debug ("%s: prefix list returns PASS, allowing route", __func__);
353 }
354
355 /* apply routemap, if any, later */
356 rmap = hc->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT];
357
358 /*
359 * Extract original nexthop, which we expect to be a NVE connected router
360 * Note that this is the nexthop before any possible application of policy
361 */
362 /*
363 * Incoming prefix is unicast. If v6, it is in multiprotocol area,
364 * but if v4 it is in attr->nexthop
365 */
366 rfapiUnicastNexthop2Prefix (afi, attr, &pfx_orig_nexthop);
367
368 /*
369 * route map handling
370 * This code is here because it allocates an interned attr which
371 * must be freed before we return. It's easier to put it after
372 * all of the possible returns above.
373 */
374 memset (&hattr, 0, sizeof (struct attr));
375 bgp_attr_dup (&hattr, attr); /* hattr becomes a ghost attr */
376
377 if (rmap)
378 {
379 struct bgp_info info;
380 route_map_result_t ret;
381
382 memset (&info, 0, sizeof (info));
383 info.peer = peer;
384 info.attr = &hattr;
385 ret = route_map_apply (rmap, prefix, RMAP_BGP, &info);
386 if (ret == RMAP_DENYMATCH)
387 {
388 bgp_attr_flush (&hattr);
389 bgp_attr_extra_free (&hattr);
390 zlog_debug ("%s: route map \"%s\" says DENY, returning", __func__,
391 rmap->name);
392 return -1;
393 }
394 }
395
396 /*
397 * Get the (possibly altered by policy) unicast nexthop
398 * for later lookup in the Import Table by caller
399 */
400 rfapiUnicastNexthop2Prefix (afi, &hattr, unicast_nexthop);
401
402 if (hattr.extra && hattr.extra->ecommunity)
403 *ecom = ecommunity_dup (hattr.extra->ecommunity);
404 else
405 *ecom = ecommunity_new ();
406
407 /*
408 * Done with hattr, clean up
409 */
410 bgp_attr_flush (&hattr);
411 bgp_attr_extra_free (&hattr);
412
413 /*
414 * Add EC that carries original NH of iBGP route (2 bytes = magic
415 * value indicating it came from an VNC gateway; default 5226, but
416 * must be user configurable). Note that this is the nexthop before
417 * any application of policy.
418 */
419 {
420 struct ecommunity_val vnc_gateway_magic;
421 uint16_t localadmin;
422
423 /* Using route origin extended community type */
424 memset (&vnc_gateway_magic, 0, sizeof (vnc_gateway_magic));
425 vnc_gateway_magic.val[0] = 0x01;
426 vnc_gateway_magic.val[1] = 0x03;
427
428 /* Only works for IPv4 nexthops */
429 if (prefix->family == AF_INET)
430 {
431 memcpy (vnc_gateway_magic.val + 2, &unicast_nexthop->u.prefix4, 4);
432 }
433 localadmin = htons (hc->resolve_nve_roo_local_admin);
434 memcpy (vnc_gateway_magic.val + 6, (char *) &localadmin, 2);
435
436 ecommunity_add_val (*ecom, &vnc_gateway_magic);
437 }
438
439 return 0;
440 }
441
442
443 static void
444 vnc_import_bgp_add_route_mode_resolve_nve_one_bi (
445 struct bgp *bgp,
446 afi_t afi,
447 struct bgp_info *bi, /* VPN bi */
448 struct prefix_rd *prd, /* RD */
449 struct prefix *prefix, /* unicast route prefix */
450 uint32_t *local_pref,/* NULL = no local_pref */
451 uint32_t *med, /* NULL = no med */
452 struct ecommunity *ecom) /* generated ecoms */
453 {
454 struct prefix un;
455 struct prefix nexthop;
456 struct rfapi_ip_addr nexthop_h;
457 uint32_t lifetime;
458 uint32_t *plifetime;
459 struct bgp_attr_encap_subtlv *encaptlvs;
460
461 zlog_debug ("%s: entry", __func__);
462
463 if (bi->type != ZEBRA_ROUTE_BGP && bi->type != ZEBRA_ROUTE_BGP_DIRECT)
464 {
465
466 return;
467 }
468 if (bi->sub_type != BGP_ROUTE_NORMAL &&
469 bi->sub_type != BGP_ROUTE_STATIC && bi->sub_type != BGP_ROUTE_RFP)
470 {
471
472 return;
473 }
474 if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED))
475 return;
476
477 vncHDResolveNve.peer = bi->peer;
478 if (!rfapiGetVncTunnelUnAddr (bi->attr, &un))
479 {
480 if (rfapiQprefix2Raddr (&un, &vncHDResolveNve.un_addr))
481 return;
482 }
483 else
484 {
485 memset (&vncHDResolveNve.un_addr, 0, sizeof (vncHDResolveNve.un_addr));
486 }
487
488 /* Use nexthop of VPN route as nexthop of constructed route */
489 rfapiNexthop2Prefix (bi->attr, &nexthop);
490 rfapiQprefix2Raddr (&nexthop, &nexthop_h);
491
492 if (rfapiGetVncLifetime (bi->attr, &lifetime))
493 {
494 plifetime = NULL;
495 }
496 else
497 {
498 plifetime = &lifetime;
499 }
500
501 if (bi->attr && bi->attr->extra)
502 {
503 encaptlvs = bi->attr->extra->vnc_subtlvs;
504 }
505 else
506 {
507 encaptlvs = NULL;
508 }
509
510 struct ecommunity *new_ecom = ecommunity_dup (ecom);
511
512 if (bi->attr && bi->attr->extra && bi->attr->extra->ecommunity)
513 ecommunity_merge (new_ecom, bi->attr->extra->ecommunity);
514
515 add_vnc_route (
516 &vncHDResolveNve,
517 bgp,
518 SAFI_MPLS_VPN,
519 prefix, /* unicast route prefix */
520 prd,
521 &nexthop_h, /* new nexthop */
522 local_pref,
523 plifetime,
524 (struct bgp_tea_options *) encaptlvs, /* RFP options */
525 NULL,
526 NULL,
527 new_ecom,
528 med, /* NULL => don't set med */
529 NULL, /* label: default */
530 ZEBRA_ROUTE_BGP_DIRECT,
531 BGP_ROUTE_REDISTRIBUTE,
532 RFAPI_AHR_RFPOPT_IS_VNCTLV); /* flags */
533
534 ecommunity_free (&new_ecom);
535
536 }
537
538 static void
539 vnc_import_bgp_add_route_mode_resolve_nve_one_rd (
540 struct prefix_rd *prd, /* RD */
541 struct bgp_table *table_rd, /* per-rd VPN route table */
542 afi_t afi,
543 struct bgp *bgp,
544 struct prefix *prefix, /* unicast prefix */
545 struct ecommunity *ecom, /* generated ecoms */
546 uint32_t *local_pref, /* NULL = no local_pref */
547 uint32_t *med, /* NULL = no med */
548 struct prefix *ubi_nexthop) /* unicast nexthop */
549 {
550 struct bgp_node *bn;
551 struct bgp_info *bi;
552
553 if (!table_rd)
554 return;
555
556 {
557 char str_nh[BUFSIZ];
558
559 prefix2str (ubi_nexthop, str_nh, BUFSIZ);
560 str_nh[BUFSIZ - 1] = 0;
561
562 zlog_debug ("%s: ubi_nexthop=%s", __func__, str_nh);
563 }
564
565 /* exact match */
566 bn = bgp_node_lookup (table_rd, ubi_nexthop);
567 if (!bn)
568 {
569 zlog_debug ("%s: no match in RD's table for ubi_nexthop", __func__);
570 return;
571 }
572
573 /* Iterate over bgp_info items at this node */
574 for (bi = bn->info; bi; bi = bi->next)
575 {
576
577 vnc_import_bgp_add_route_mode_resolve_nve_one_bi (bgp, afi, bi, /* VPN bi */
578 prd,
579 prefix,
580 local_pref,
581 med, ecom);
582 }
583
584 bgp_unlock_node (bn);
585 }
586
587 static void
588 vnc_import_bgp_add_route_mode_resolve_nve (
589 struct bgp *bgp,
590 struct prefix *prefix,/* unicast prefix */
591 struct bgp_info *info) /* unicast info */
592 {
593 afi_t afi = family2afi (prefix->family);
594 struct rfapi_cfg *hc = NULL;
595
596 struct prefix pfx_unicast_nexthop = { 0 }; /* happy valgrind */
597
598 struct ecommunity *ecom = NULL;
599 uint32_t local_pref;
600 uint32_t *med = NULL;
601
602 struct prefix_bag *pb;
603 struct bgp_node *bnp; /* prd table node */
604
605 /*debugging */
606 {
607 char str_pfx[BUFSIZ];
608 char str_nh[BUFSIZ];
609 struct prefix nh;
610
611 prefix2str (prefix, str_pfx, BUFSIZ);
612 str_pfx[BUFSIZ - 1] = 0;
613
614 nh.prefixlen = 0;
615 rfapiUnicastNexthop2Prefix (afi, info->attr, &nh);
616 if (nh.prefixlen)
617 {
618 prefix2str (&nh, str_nh, BUFSIZ);
619 str_nh[BUFSIZ - 1] = 0;
620 }
621 else
622 {
623 str_nh[0] = '?';
624 str_nh[1] = 0;
625 }
626
627 zlog_debug ("%s(bgp=%p, unicast prefix=%s, unicast nh=%s)",
628 __func__, bgp, str_pfx, str_nh);
629 }
630
631 if (info->type != ZEBRA_ROUTE_BGP)
632 {
633 zlog_debug ("%s: unicast type %d=\"%s\" is not %d=%s, skipping",
634 __func__, info->type, zebra_route_string (info->type),
635 ZEBRA_ROUTE_BGP, "ZEBRA_ROUTE_BGP");
636 return;
637 }
638
639 /*
640 * Preliminary checks
641 */
642
643 if (!afi)
644 {
645 zlog_err ("%s: can't get afi of prefix", __func__);
646 return;
647 }
648
649 if (!(hc = bgp->rfapi_cfg))
650 {
651 zlog_debug ("%s: bgp->rfapi_cfg is NULL, skipping", __func__);
652 return;
653 }
654
655 /* check vnc redist flag for bgp direct routes */
656 if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT])
657 {
658 zlog_debug
659 ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping",
660 __func__, afi);
661 return;
662 }
663
664
665 if (process_unicast_route (bgp, afi, prefix, info,
666 &ecom, &pfx_unicast_nexthop))
667 {
668
669 zlog_debug ("%s: process_unicast_route error, skipping", __func__);
670 return;
671 }
672
673 local_pref = calc_local_pref (info->attr, info->peer);
674 if (info->attr &&
675 (info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)))
676 {
677
678 med = &info->attr->med;
679 }
680
681
682 /*
683 * At this point, we have allocated:
684 *
685 * ecom ecommunity ptr, union of unicast and ROO parts (no NVE part)
686 *
687 * And we have set:
688 *
689 * pfx_unicast_nexthop nexthop of uncast route
690 */
691
692 if (!bgp->rfapi->resolve_nve_nexthop)
693 {
694 bgp->rfapi->resolve_nve_nexthop =
695 skiplist_new (SKIPLIST_FLAG_ALLOW_DUPLICATES, vnc_prefix_cmp,
696 prefix_bag_free);
697 }
698
699 pb = XCALLOC (MTYPE_RFAPI_PREFIX_BAG, sizeof (struct prefix_bag));
700 pb->hpfx = pfx_unicast_nexthop;
701 pb->ubi = info;
702 pb->upfx = *prefix;
703
704 bgp_info_lock (info); /* skiplist refers to it */
705 skiplist_insert (bgp->rfapi->resolve_nve_nexthop, &pb->hpfx, pb);
706
707 /*
708 * Iterate over RDs in VPN RIB. For each RD, look up unicast nexthop
709 * (exact match, /32). If an exact match is found, call add_vnc_route.
710 */
711
712 for (bnp = bgp_table_top (bgp->rib[afi][SAFI_MPLS_VPN]); bnp;
713 bnp = bgp_route_next (bnp))
714 {
715
716 struct bgp_table *table;
717
718 table = (struct bgp_table *) (bnp->info);
719
720 if (!table)
721 continue;
722
723 vnc_import_bgp_add_route_mode_resolve_nve_one_rd ((struct prefix_rd *)
724 &bnp->p, table, afi,
725 bgp, prefix, ecom,
726 &local_pref, med,
727 &pfx_unicast_nexthop);
728
729 }
730
731
732 if (ecom)
733 ecommunity_free (&ecom);
734
735 zlog_debug ("%s: done", __func__);
736 }
737
738
739 static void
740 vnc_import_bgp_add_route_mode_plain (struct bgp *bgp,
741 struct prefix *prefix,
742 struct bgp_info *info)
743 {
744 afi_t afi = family2afi (prefix->family);
745 struct peer *peer = info->peer;
746 struct attr *attr = info->attr;
747 struct attr hattr;
748 struct rfapi_cfg *hc = NULL;
749 struct attr *iattr = NULL;
750
751 struct rfapi_ip_addr vnaddr;
752 struct prefix vn_pfx_space;
753 struct prefix *vn_pfx = NULL;
754 int ahr_flags = 0;
755 struct ecommunity *ecom = NULL;
756 struct prefix_rd prd;
757 struct route_map *rmap = NULL;
758 uint32_t local_pref;
759 uint32_t *med = NULL;
760
761 {
762 char buf[BUFSIZ];
763
764 buf[0] = 0;
765 prefix2str (prefix, buf, BUFSIZ);
766 buf[BUFSIZ - 1] = 0;
767 zlog_debug ("%s(prefix=%s) entry", __func__, buf);
768 }
769
770 if (!afi)
771 {
772 zlog_err ("%s: can't get afi of prefix", __func__);
773 return;
774 }
775
776 if (!(hc = bgp->rfapi_cfg))
777 {
778 zlog_debug ("%s: bgp->rfapi_cfg is NULL, skipping", __func__);
779 return;
780 }
781
782 /* check vnc redist flag for bgp direct routes */
783 if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT])
784 {
785 zlog_debug
786 ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping",
787 __func__, afi);
788 return;
789 }
790
791 /*
792 * mode "plain" specific code
793 */
794 {
795 zlog_debug ("%s: NOT using redist RFG", __func__);
796
797 /*
798 * prefix list check
799 */
800 if (hc->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi])
801 {
802 zlog_debug ("%s: HC prefix list is set, checking", __func__);
803 if (prefix_list_apply
804 (hc->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi],
805 prefix) == PREFIX_DENY)
806 {
807 zlog_debug ("%s: prefix list returns DENY, blocking route",
808 __func__);
809 return;
810 }
811 zlog_debug ("%s: prefix list returns PASS, allowing route", __func__);
812 }
813
814 /* apply routemap, if any, later */
815 rmap = hc->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT];
816
817 /*
818 * Incoming prefix is unicast. If v6, it is in multiprotocol area,
819 * but if v4 it is in attr->nexthop
820 */
821 rfapiUnicastNexthop2Prefix (afi, attr, &vn_pfx_space);
822 vn_pfx = &vn_pfx_space;
823
824 /* UN address */
825 ahr_flags |= RFAPI_AHR_NO_TUNNEL_SUBTLV;
826 }
827
828 if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE))
829 {
830 char buf[BUFSIZ];
831
832 buf[0] = 0;
833 prefix2str (vn_pfx, buf, BUFSIZ);
834 buf[BUFSIZ - 1] = 0;
835 zlog_debug ("%s vn_pfx=%s", __func__, buf);
836 }
837
838 /*
839 * Compute VN address
840 */
841 if (rfapiQprefix2Raddr (vn_pfx, &vnaddr))
842 {
843 zlog_debug ("%s: redist VN invalid, skipping", __func__);
844 return;
845 }
846
847 /*
848 * route map handling
849 * This code is here because it allocates an interned attr which
850 * must be freed before we return. It's easier to put it after
851 * all of the possible returns above.
852 */
853 memset (&hattr, 0, sizeof (struct attr));
854 bgp_attr_dup (&hattr, attr); /* hattr becomes a ghost attr */
855
856 if (rmap)
857 {
858 struct bgp_info info;
859 route_map_result_t ret;
860
861 memset (&info, 0, sizeof (info));
862 info.peer = peer;
863 info.attr = &hattr;
864 ret = route_map_apply (rmap, prefix, RMAP_BGP, &info);
865 if (ret == RMAP_DENYMATCH)
866 {
867 bgp_attr_flush (&hattr);
868 bgp_attr_extra_free (&hattr);
869 zlog_debug ("%s: route map \"%s\" says DENY, returning", __func__,
870 rmap->name);
871 return;
872 }
873 }
874
875 iattr = bgp_attr_intern (&hattr);
876 bgp_attr_flush (&hattr);
877 bgp_attr_extra_free (&hattr);
878
879 /* Now iattr is an allocated interned attr */
880
881 /*
882 * Mode "plain" specific code
883 *
884 * Sets RD in dummy HD
885 * Allocates ecom
886 */
887 {
888 if (vnaddr.addr_family != AF_INET)
889 {
890 zlog_debug
891 ("%s: can't auto-assign RD, VN AF (%d) is not IPv4, skipping",
892 __func__, vnaddr.addr_family);
893 if (iattr)
894 {
895 bgp_attr_unintern (&iattr);
896 }
897 return;
898 }
899 memset (&prd, 0, sizeof (prd));
900 rfapi_set_autord_from_vn (&prd, &vnaddr);
901
902 if (iattr && iattr->extra && iattr->extra->ecommunity)
903 ecom = ecommunity_dup (iattr->extra->ecommunity);
904
905 }
906
907 local_pref = calc_local_pref (iattr, peer);
908
909 if (iattr && (iattr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)))
910 {
911 med = &iattr->med;
912 }
913
914 if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE))
915 {
916 char buf[BUFSIZ];
917
918 buf[0] = 0;
919 rfapiRfapiIpAddr2Str (&vnaddr, buf, BUFSIZ);
920 buf[BUFSIZ - 1] = 0;
921 zlog_debug ("%s: setting vnaddr to %s", __func__, buf);
922 }
923
924 vncHDBgpDirect.peer = peer;
925 add_vnc_route (&vncHDBgpDirect, bgp, SAFI_MPLS_VPN, prefix, &prd, &vnaddr, &local_pref, &(bgp->rfapi_cfg->redist_lifetime), NULL, /* RFP options */
926 NULL, NULL, ecom, med, /* med */
927 NULL, /* label: default */
928 ZEBRA_ROUTE_BGP_DIRECT, BGP_ROUTE_REDISTRIBUTE, ahr_flags);
929 vncHDBgpDirect.peer = NULL;
930
931 if (ecom)
932 ecommunity_free (&ecom);
933 }
934
935 static void
936 vnc_import_bgp_add_route_mode_nvegroup (struct bgp *bgp,
937 struct prefix *prefix,
938 struct bgp_info *info,
939 struct rfapi_nve_group_cfg *rfg)
940 {
941 afi_t afi = family2afi (prefix->family);
942 struct peer *peer = info->peer;
943 struct attr *attr = info->attr;
944 struct attr hattr;
945 struct rfapi_cfg *hc = NULL;
946 struct attr *iattr = NULL;
947
948 struct rfapi_ip_addr vnaddr;
949 struct prefix *vn_pfx = NULL;
950 int ahr_flags = 0;
951 struct ecommunity *ecom = NULL;
952 struct prefix_rd prd;
953 struct route_map *rmap = NULL;
954 uint32_t local_pref;
955
956 {
957 char buf[BUFSIZ];
958
959 buf[0] = 0;
960 prefix2str (prefix, buf, BUFSIZ);
961 buf[BUFSIZ - 1] = 0;
962 zlog_debug ("%s(prefix=%s) entry", __func__, buf);
963 }
964
965 assert (rfg);
966
967 if (!afi)
968 {
969 zlog_err ("%s: can't get afi of prefix", __func__);
970 return;
971 }
972
973 if (!(hc = bgp->rfapi_cfg))
974 {
975 zlog_debug ("%s: bgp->rfapi_cfg is NULL, skipping", __func__);
976 return;
977 }
978
979 /* check vnc redist flag for bgp direct routes */
980 if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT])
981 {
982 zlog_debug
983 ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping",
984 __func__, afi);
985 return;
986 }
987
988
989 /*
990 * RFG-specific code
991 */
992 {
993
994 struct rfapi_ip_prefix pfx_un;
995
996 zlog_debug ("%s: using redist RFG", __func__);
997
998 /*
999 * RFG prefix list check
1000 */
1001 if (rfg->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi])
1002 {
1003 zlog_debug ("%s: RFG prefix list is set, checking", __func__);
1004 if (prefix_list_apply
1005 (rfg->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi],
1006 prefix) == PREFIX_DENY)
1007 {
1008 zlog_debug ("%s: prefix list returns DENY, blocking route",
1009 __func__);
1010 return;
1011 }
1012 zlog_debug ("%s: prefix list returns PASS, allowing route", __func__);
1013 }
1014
1015 /* apply routemap, if any, later */
1016 rmap = rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT];
1017
1018 /*
1019 * export nve group's VN addr prefix must be a /32 which
1020 * will yield the VN addr to use
1021 */
1022 vn_pfx = &rfg->vn_prefix;
1023
1024 /*
1025 * UN Address
1026 */
1027 if (!is_host_prefix (&rfg->un_prefix))
1028 {
1029 /* NB prefixlen==0 means it has not been configured */
1030 zlog_debug ("%s: redist RFG UN pfx not host pfx (plen=%d), skipping",
1031 __func__, rfg->un_prefix.prefixlen);
1032 return;
1033 }
1034
1035 rfapiQprefix2Rprefix (&rfg->un_prefix, &pfx_un);
1036
1037 vncHDBgpDirect.un_addr = pfx_un.prefix;
1038 }
1039
1040 if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE))
1041 {
1042 char buf[BUFSIZ];
1043
1044 buf[0] = 0;
1045 prefix2str (vn_pfx, buf, BUFSIZ);
1046 buf[BUFSIZ - 1] = 0;
1047 zlog_debug ("%s vn_pfx=%s", __func__, buf);
1048 }
1049
1050 /*
1051 * Compute VN address
1052 */
1053 if (rfapiQprefix2Raddr (vn_pfx, &vnaddr))
1054 {
1055 zlog_debug ("%s: redist VN invalid, skipping", __func__);
1056 return;
1057 }
1058
1059 /*
1060 * route map handling
1061 * This code is here because it allocates an interned attr which
1062 * must be freed before we return. It's easier to put it after
1063 * all of the possible returns above.
1064 */
1065 memset (&hattr, 0, sizeof (struct attr));
1066 bgp_attr_dup (&hattr, attr); /* hattr becomes a ghost attr */
1067
1068 if (rmap)
1069 {
1070 struct bgp_info info;
1071 route_map_result_t ret;
1072
1073 memset (&info, 0, sizeof (info));
1074 info.peer = peer;
1075 info.attr = &hattr;
1076 ret = route_map_apply (rmap, prefix, RMAP_BGP, &info);
1077 if (ret == RMAP_DENYMATCH)
1078 {
1079 bgp_attr_flush (&hattr);
1080 bgp_attr_extra_free (&hattr);
1081 zlog_debug ("%s: route map \"%s\" says DENY, returning", __func__,
1082 rmap->name);
1083 return;
1084 }
1085 }
1086
1087 iattr = bgp_attr_intern (&hattr);
1088 bgp_attr_flush (&hattr);
1089 bgp_attr_extra_free (&hattr);
1090
1091 /* Now iattr is an allocated interned attr */
1092
1093 /*
1094 * RFG-specific code
1095 *
1096 * Sets RD in dummy HD
1097 * Allocates ecom
1098 */
1099 {
1100
1101 memset (&prd, 0, sizeof (prd));
1102 prd = rfg->rd;
1103 prd.family = AF_UNSPEC;
1104 prd.prefixlen = 64;
1105
1106 if (rfg->rd.family == AF_UNIX)
1107 {
1108 rfapi_set_autord_from_vn (&prd, &vnaddr);
1109 }
1110
1111 if (rfg->rt_export_list)
1112 ecom = ecommunity_dup (bgp->rfapi_cfg->rfg_redist->rt_export_list);
1113 else
1114 ecom = ecommunity_new ();
1115
1116 if (iattr && iattr->extra && iattr->extra->ecommunity)
1117 ecom = ecommunity_merge (ecom, iattr->extra->ecommunity);
1118 }
1119
1120 local_pref = calc_local_pref (iattr, peer);
1121
1122 if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE))
1123 {
1124 char buf[BUFSIZ];
1125
1126 buf[0] = 0;
1127 rfapiRfapiIpAddr2Str (&vnaddr, buf, BUFSIZ);
1128 buf[BUFSIZ - 1] = 0;
1129 zlog_debug ("%s: setting vnaddr to %s", __func__, buf);
1130 }
1131
1132 vncHDBgpDirect.peer = peer;
1133 add_vnc_route (
1134 &vncHDBgpDirect,
1135 bgp,
1136 SAFI_MPLS_VPN,
1137 prefix,
1138 &prd,
1139 &vnaddr,
1140 &local_pref,
1141 &(bgp->rfapi_cfg->redist_lifetime),
1142 NULL, /* RFP options */
1143 NULL,
1144 NULL,
1145 ecom,
1146 NULL, /* med */
1147 NULL, /* label: default */
1148 ZEBRA_ROUTE_BGP_DIRECT,
1149 BGP_ROUTE_REDISTRIBUTE,
1150 ahr_flags);
1151 vncHDBgpDirect.peer = NULL;
1152
1153 if (ecom)
1154 ecommunity_free (&ecom);
1155 }
1156
1157 static void
1158 vnc_import_bgp_del_route_mode_plain (struct bgp *bgp,
1159 struct prefix *prefix,
1160 struct bgp_info *info)
1161 {
1162 struct prefix_rd prd;
1163 afi_t afi = family2afi (prefix->family);
1164 struct prefix *vn_pfx = NULL;
1165 struct rfapi_ip_addr vnaddr;
1166 struct prefix vn_pfx_space;
1167
1168
1169 assert (afi);
1170
1171 /*
1172 * Compute VN address
1173 */
1174
1175 if (info && info->attr)
1176 {
1177 rfapiUnicastNexthop2Prefix (afi, info->attr, &vn_pfx_space);
1178 }
1179 else
1180 {
1181 zlog_debug ("%s: no attr, can't delete route", __func__);
1182 return;
1183 }
1184 vn_pfx = &vn_pfx_space;
1185
1186 vnaddr.addr_family = vn_pfx->family;
1187 switch (vn_pfx->family)
1188 {
1189 case AF_INET:
1190 if (vn_pfx->prefixlen != 32)
1191 {
1192 zlog_debug ("%s: redist VN plen (%d) != 32, skipping",
1193 __func__, vn_pfx->prefixlen);
1194 return;
1195 }
1196 vnaddr.addr.v4 = vn_pfx->u.prefix4;
1197 break;
1198
1199 case AF_INET6:
1200 if (vn_pfx->prefixlen != 128)
1201 {
1202 zlog_debug ("%s: redist VN plen (%d) != 128, skipping",
1203 __func__, vn_pfx->prefixlen);
1204 return;
1205 }
1206 vnaddr.addr.v6 = vn_pfx->u.prefix6;
1207 break;
1208
1209 default:
1210 zlog_debug ("%s: no redist RFG VN host pfx configured, skipping",
1211 __func__);
1212 return;
1213 }
1214
1215
1216 memset (&prd, 0, sizeof (prd));
1217 if (rfapi_set_autord_from_vn (&prd, &vnaddr))
1218 {
1219 zlog_debug ("%s: can't auto-assign RD, skipping", __func__);
1220 return;
1221 }
1222
1223 vncHDBgpDirect.peer = info->peer;
1224 zlog_debug ("%s: setting peer to %p", __func__, vncHDBgpDirect.peer);
1225 del_vnc_route (&vncHDBgpDirect,
1226 info->peer,
1227 bgp,
1228 SAFI_MPLS_VPN,
1229 prefix,
1230 &prd,
1231 ZEBRA_ROUTE_BGP_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL, 1);
1232
1233 vncHDBgpDirect.peer = NULL;
1234 }
1235
1236 static void
1237 vnc_import_bgp_del_route_mode_nvegroup (struct bgp *bgp,
1238 struct prefix *prefix,
1239 struct bgp_info *info)
1240 {
1241 struct prefix_rd prd;
1242 afi_t afi = family2afi (prefix->family);
1243 struct rfapi_nve_group_cfg *rfg = NULL;
1244 struct prefix *vn_pfx = NULL;
1245 struct rfapi_ip_addr vnaddr;
1246
1247
1248 assert (afi);
1249
1250 assert ((rfg = bgp->rfapi_cfg->rfg_redist));
1251
1252 /*
1253 * Compute VN address
1254 */
1255
1256 /*
1257 * export nve group's VN addr prefix must be a /32 which
1258 * will yield the VN addr to use
1259 */
1260 vn_pfx = &rfg->vn_prefix;
1261
1262
1263 vnaddr.addr_family = vn_pfx->family;
1264 switch (vn_pfx->family)
1265 {
1266 case AF_INET:
1267 if (vn_pfx->prefixlen != 32)
1268 {
1269 zlog_debug ("%s: redist VN plen (%d) != 32, skipping",
1270 __func__, vn_pfx->prefixlen);
1271 return;
1272 }
1273 vnaddr.addr.v4 = vn_pfx->u.prefix4;
1274 break;
1275
1276 case AF_INET6:
1277 if (vn_pfx->prefixlen != 128)
1278 {
1279 zlog_debug ("%s: redist VN plen (%d) != 128, skipping",
1280 __func__, vn_pfx->prefixlen);
1281 return;
1282 }
1283 vnaddr.addr.v6 = vn_pfx->u.prefix6;
1284 break;
1285
1286 default:
1287 zlog_debug ("%s: no redist RFG VN host pfx configured, skipping",
1288 __func__);
1289 return;
1290 }
1291
1292 memset (&prd, 0, sizeof (prd));
1293 prd = rfg->rd;
1294 prd.family = AF_UNSPEC;
1295 prd.prefixlen = 64;
1296
1297 if (rfg->rd.family == AF_UNIX)
1298 {
1299 /* means "auto" with VN addr */
1300 if (rfapi_set_autord_from_vn (&prd, &vnaddr))
1301 {
1302 zlog_debug ("%s: can't auto-assign RD, skipping", __func__);
1303 return;
1304 }
1305 }
1306
1307
1308 vncHDBgpDirect.peer = info->peer;
1309 zlog_debug ("%s: setting peer to %p", __func__, vncHDBgpDirect.peer);
1310 del_vnc_route (&vncHDBgpDirect,
1311 info->peer,
1312 bgp,
1313 SAFI_MPLS_VPN,
1314 prefix,
1315 &prd,
1316 ZEBRA_ROUTE_BGP_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL, 1);
1317
1318 vncHDBgpDirect.peer = NULL;
1319 }
1320
1321 static void
1322 vnc_import_bgp_del_route_mode_resolve_nve_one_bi (
1323 struct bgp *bgp,
1324 afi_t afi,
1325 struct bgp_info *bi, /* VPN bi */
1326 struct prefix_rd *prd, /* RD */
1327 struct prefix *prefix)/* unicast route prefix */
1328 {
1329 struct prefix un;
1330
1331 if (bi->type != ZEBRA_ROUTE_BGP && bi->type != ZEBRA_ROUTE_BGP_DIRECT)
1332 {
1333
1334 return;
1335 }
1336 if (bi->sub_type != BGP_ROUTE_NORMAL &&
1337 bi->sub_type != BGP_ROUTE_STATIC && bi->sub_type != BGP_ROUTE_RFP)
1338 {
1339
1340 return;
1341 }
1342 if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED))
1343 return;
1344
1345 vncHDResolveNve.peer = bi->peer;
1346 if (!rfapiGetVncTunnelUnAddr (bi->attr, &un))
1347 {
1348 if (rfapiQprefix2Raddr (&un, &vncHDResolveNve.un_addr))
1349 return;
1350 }
1351 else
1352 {
1353 memset (&vncHDResolveNve.un_addr, 0, sizeof (vncHDResolveNve.un_addr));
1354 }
1355
1356 del_vnc_route (&vncHDResolveNve, vncHDResolveNve.peer, bgp, SAFI_MPLS_VPN, prefix, /* unicast route prefix */
1357 prd, ZEBRA_ROUTE_BGP_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL, 0); /* flags */
1358
1359 }
1360
1361 static void
1362 vnc_import_bgp_del_route_mode_resolve_nve_one_rd (
1363 struct prefix_rd *prd,
1364 struct bgp_table *table_rd, /* per-rd VPN route table */
1365 afi_t afi,
1366 struct bgp *bgp,
1367 struct prefix *prefix, /* unicast prefix */
1368 struct prefix *ubi_nexthop) /* unicast bi's nexthop */
1369 {
1370 struct bgp_node *bn;
1371 struct bgp_info *bi;
1372
1373 if (!table_rd)
1374 return;
1375
1376 {
1377 char str_nh[BUFSIZ];
1378
1379 prefix2str (ubi_nexthop, str_nh, BUFSIZ);
1380 str_nh[BUFSIZ - 1] = 0;
1381
1382 zlog_debug ("%s: ubi_nexthop=%s", __func__, str_nh);
1383 }
1384
1385
1386 /* exact match */
1387 bn = bgp_node_lookup (table_rd, ubi_nexthop);
1388 if (!bn)
1389 {
1390 zlog_debug ("%s: no match in RD's table for ubi_nexthop", __func__);
1391 return;
1392 }
1393
1394 /* Iterate over bgp_info items at this node */
1395 for (bi = bn->info; bi; bi = bi->next)
1396 {
1397
1398 vnc_import_bgp_del_route_mode_resolve_nve_one_bi (bgp, afi, bi, /* VPN bi */
1399 prd, /* VPN RD */
1400 prefix); /* unicast route prefix */
1401 }
1402
1403 bgp_unlock_node (bn);
1404 }
1405
1406 static void
1407 vnc_import_bgp_del_route_mode_resolve_nve (struct bgp *bgp,
1408 afi_t afi,
1409 struct prefix *prefix,
1410 struct bgp_info *info)
1411 {
1412 struct ecommunity *ecom = NULL;
1413 struct prefix pfx_unicast_nexthop = { 0 }; /* happy valgrind */
1414
1415 //struct listnode *hnode;
1416 //struct rfapi_descriptor *rfd;
1417 struct prefix_bag *pb;
1418 void *cursor;
1419 struct skiplist *sl = bgp->rfapi->resolve_nve_nexthop;
1420 int rc;
1421 struct bgp_node *bnp; /* prd table node */
1422
1423 if (!sl)
1424 {
1425 zlog_debug ("%s: no RHN entries, skipping", __func__);
1426 return;
1427 }
1428
1429 if (info->type != ZEBRA_ROUTE_BGP)
1430 {
1431 zlog_debug ("%s: unicast type %d=\"%s\" is not %d=%s, skipping",
1432 __func__, info->type, zebra_route_string (info->type),
1433 ZEBRA_ROUTE_BGP, "ZEBRA_ROUTE_BGP");
1434 return;
1435 }
1436
1437 if (process_unicast_route (bgp, afi, prefix, info,
1438 &ecom, &pfx_unicast_nexthop))
1439 {
1440
1441 zlog_debug ("%s: process_unicast_route error, skipping", __func__);
1442 return;
1443 }
1444
1445 rc = skiplist_first_value (sl, &pfx_unicast_nexthop, (void *) &pb, &cursor);
1446 while (!rc)
1447 {
1448 if (pb->ubi == info)
1449 {
1450 skiplist_delete (sl, &pfx_unicast_nexthop, pb);
1451 bgp_info_unlock (info);
1452 break;
1453 }
1454 rc =
1455 skiplist_next_value (sl, &pfx_unicast_nexthop, (void *) &pb, &cursor);
1456 }
1457
1458 /*
1459 * Iterate over RDs in VPN RIB. For each RD, look up unicast nexthop
1460 * (exact match, /32). If an exact match is found, call add_vnc_route.
1461 */
1462
1463 for (bnp = bgp_table_top (bgp->rib[afi][SAFI_MPLS_VPN]); bnp;
1464 bnp = bgp_route_next (bnp))
1465 {
1466
1467 struct bgp_table *table;
1468
1469 table = (struct bgp_table *) (bnp->info);
1470
1471 if (!table)
1472 continue;
1473
1474 vnc_import_bgp_del_route_mode_resolve_nve_one_rd ((struct prefix_rd *) &bnp->p, table, afi, bgp, prefix, &pfx_unicast_nexthop); /* TBD how is this set? */
1475 }
1476
1477 if (ecom)
1478 ecommunity_free (&ecom);
1479 }
1480
1481
1482
1483
1484 /***********************************************************************
1485 * Add/Delete CE->NVE routes
1486 ***********************************************************************/
1487
1488 /*
1489 * Should be called whan a bi is added to VPN RIB. This function
1490 * will check if it is a host route and return immediately if not.
1491 */
1492 void
1493 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve (
1494 struct bgp *bgp,
1495 struct prefix_rd *prd, /* RD */
1496 struct bgp_table *table_rd, /* per-rd VPN route table */
1497 struct prefix *prefix, /* VPN prefix */
1498 struct bgp_info *bi) /* new VPN host route */
1499 {
1500 afi_t afi = family2afi (prefix->family);
1501 struct skiplist *sl = NULL;
1502 int rc;
1503 struct prefix_bag *pb;
1504 void *cursor;
1505 struct rfapi_cfg *hc = NULL;
1506
1507 zlog_debug ("%s: entry", __func__);
1508
1509 if (afi != AFI_IP && afi != AFI_IP6)
1510 {
1511 zlog_debug ("%s: bad afi %d, skipping", __func__, afi);
1512 return;
1513 }
1514
1515 if (!(hc = bgp->rfapi_cfg))
1516 {
1517 zlog_debug ("%s: bgp->rfapi_cfg is NULL, skipping", __func__);
1518 return;
1519 }
1520
1521 /* check vnc redist flag for bgp direct routes */
1522 if (!hc->redist[afi][ZEBRA_ROUTE_BGP_DIRECT])
1523 {
1524 zlog_debug
1525 ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping",
1526 __func__, afi);
1527 return;
1528 }
1529
1530 if (hc->redist_mode != VNC_REDIST_MODE_RESOLVE_NVE)
1531 {
1532 zlog_debug ("%s: not in resolve-nve mode, skipping", __func__);
1533 return;
1534 }
1535
1536 if (bgp && bgp->rfapi)
1537 sl = bgp->rfapi->resolve_nve_nexthop;
1538
1539 if (!sl)
1540 {
1541 zlog_debug ("%s: no resolve_nve_nexthop skiplist, skipping", __func__);
1542 return;
1543 }
1544
1545 if (!is_host_prefix (prefix))
1546 {
1547 zlog_debug ("%s: not host prefix, skipping", __func__);
1548 return;
1549 }
1550
1551 rc = skiplist_first_value (sl, prefix, (void *) &pb, &cursor);
1552 while (!rc)
1553 {
1554 struct ecommunity *ecom;
1555 struct prefix pfx_unicast_nexthop;
1556 uint32_t *med = NULL;
1557 uint32_t local_pref;
1558
1559 memset (&pfx_unicast_nexthop, 0, sizeof (struct prefix)); /* keep valgrind happy */
1560
1561 if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE))
1562 {
1563 char hbuf[BUFSIZ];
1564 char ubuf[BUFSIZ];
1565
1566 prefix2str (&pb->hpfx, hbuf, BUFSIZ);
1567 prefix2str (&pb->upfx, ubuf, BUFSIZ);
1568
1569 zlog_debug
1570 ("%s: examining RHN Entry (q=%p): upfx=%s, hpfx=%s, ubi=%p",
1571 __func__, cursor, ubuf, hbuf, pb->ubi);
1572 }
1573
1574 if (process_unicast_route (bgp, afi, &pb->upfx, pb->ubi,
1575 &ecom, &pfx_unicast_nexthop))
1576 {
1577
1578 zlog_debug ("%s: process_unicast_route error, skipping", __func__);
1579 continue;
1580 }
1581 local_pref = calc_local_pref (pb->ubi->attr, pb->ubi->peer);
1582
1583 if (pb->ubi->attr &&
1584 (pb->ubi->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)))
1585 {
1586
1587 med = &pb->ubi->attr->med;
1588 }
1589
1590 /*
1591 * Sanity check
1592 */
1593 if (vnc_prefix_cmp (&pfx_unicast_nexthop, prefix))
1594 {
1595 char str_unh[BUFSIZ];
1596 char str_nve_pfx[BUFSIZ];
1597
1598 prefix2str (&pfx_unicast_nexthop, str_unh, BUFSIZ);
1599 str_unh[BUFSIZ - 1] = 0;
1600
1601 prefix2str (prefix, str_nve_pfx, BUFSIZ);
1602 str_nve_pfx[BUFSIZ - 1] = 0;
1603
1604 zlog_debug
1605 ("%s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s",
1606 __func__, str_unh, str_nve_pfx);
1607 assert (0);
1608 }
1609
1610 vnc_import_bgp_add_route_mode_resolve_nve_one_bi (bgp, afi, bi, /* VPN bi */
1611 prd, &pb->upfx, /* unicast prefix */
1612 &local_pref,
1613 med, ecom);
1614
1615 if (ecom)
1616 ecommunity_free (&ecom);
1617
1618 #if DEBUG_RHN_LIST
1619 /* debug */
1620 {
1621 char pbuf[BUFSIZ];
1622
1623 prefix2str (prefix, pbuf, BUFSIZ);
1624
1625 zlog_debug ("%s: advancing past RHN Entry (q=%p): with prefix %s",
1626 __func__, cursor, pbuf);
1627 print_rhn_list (__func__, NULL); /* debug */
1628 }
1629 #endif
1630 rc = skiplist_next_value (sl, prefix, (void *) &pb, &cursor);
1631 }
1632 zlog_debug ("%s: done", __func__);
1633 }
1634
1635
1636 void
1637 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve (
1638 struct bgp *bgp,
1639 struct prefix_rd *prd, /* RD */
1640 struct bgp_table *table_rd, /* per-rd VPN route table */
1641 struct prefix *prefix, /* VPN prefix */
1642 struct bgp_info *bi) /* old VPN host route */
1643 {
1644 afi_t afi = family2afi (prefix->family);
1645 struct skiplist *sl = NULL;
1646 struct prefix_bag *pb;
1647 void *cursor;
1648 struct rfapi_cfg *hc = NULL;
1649 int rc;
1650
1651 {
1652 char str_pfx[BUFSIZ];
1653
1654 prefix2str (prefix, str_pfx, BUFSIZ);
1655 str_pfx[BUFSIZ - 1] = 0;
1656
1657 zlog_debug ("%s(bgp=%p, nve prefix=%s)", __func__, bgp, str_pfx);
1658 }
1659
1660 if (afi != AFI_IP && afi != AFI_IP6)
1661 return;
1662
1663 if (!(hc = bgp->rfapi_cfg))
1664 {
1665 zlog_debug ("%s: bgp->rfapi_cfg is NULL, skipping", __func__);
1666 return;
1667 }
1668
1669 /* check vnc redist flag for bgp direct routes */
1670 if (!hc->redist[afi][ZEBRA_ROUTE_BGP_DIRECT])
1671 {
1672 zlog_debug
1673 ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping",
1674 __func__, afi);
1675 return;
1676 }
1677
1678 if (hc->redist_mode != VNC_REDIST_MODE_RESOLVE_NVE)
1679 {
1680 zlog_debug ("%s: not in resolve-nve mode, skipping", __func__);
1681 return;
1682 }
1683
1684 if (bgp && bgp->rfapi)
1685 sl = bgp->rfapi->resolve_nve_nexthop;
1686
1687 if (!sl)
1688 {
1689 zlog_debug ("%s: no RHN entries, skipping", __func__);
1690 return;
1691 }
1692
1693 if (!is_host_prefix (prefix))
1694 {
1695 zlog_debug ("%s: not host route, skip", __func__);
1696 return;
1697 }
1698
1699 /*
1700 * Find all entries with key == CE in the RHN list
1701 */
1702 rc = skiplist_first_value (sl, prefix, (void *) &pb, &cursor);
1703 while (!rc)
1704 {
1705
1706 struct ecommunity *ecom;
1707 struct prefix pfx_unicast_nexthop;
1708
1709 memset (&pfx_unicast_nexthop, 0, sizeof (struct prefix)); /* keep valgrind happy */
1710
1711 if (process_unicast_route (bgp, afi, &pb->upfx, pb->ubi,
1712 &ecom, &pfx_unicast_nexthop))
1713 {
1714
1715 zlog_debug ("%s: process_unicast_route error, skipping", __func__);
1716 continue;
1717 }
1718
1719 /*
1720 * Sanity check
1721 */
1722 if (vnc_prefix_cmp (&pfx_unicast_nexthop, prefix))
1723 {
1724 char str_unh[BUFSIZ];
1725 char str_nve_pfx[BUFSIZ];
1726
1727 prefix2str (&pfx_unicast_nexthop, str_unh, BUFSIZ);
1728 str_unh[BUFSIZ - 1] = 0;
1729
1730 prefix2str (prefix, str_nve_pfx, BUFSIZ);
1731 str_nve_pfx[BUFSIZ - 1] = 0;
1732
1733 zlog_debug
1734 ("%s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s",
1735 __func__, str_unh, str_nve_pfx);
1736 assert (0);
1737 }
1738
1739 vnc_import_bgp_del_route_mode_resolve_nve_one_bi (bgp,
1740 afi,
1741 bi, prd, &pb->upfx);
1742
1743 if (ecom)
1744 ecommunity_free (&ecom);
1745
1746 rc = skiplist_next_value (sl, prefix, (void *) &pb, &cursor);
1747 }
1748 }
1749
1750
1751 /***********************************************************************
1752 * Exterior Routes
1753 ***********************************************************************/
1754
1755 #define DEBUG_IS_USABLE_INTERIOR 1
1756
1757 static int
1758 is_usable_interior_route (struct bgp_info *bi_interior)
1759 {
1760 if (!VALID_INTERIOR_TYPE (bi_interior->type))
1761 {
1762 #if DEBUG_IS_USABLE_INTERIOR
1763 zlog_debug ("%s: NO: type %d is not valid interior type",
1764 __func__, bi_interior->type);
1765 #endif
1766 return 0;
1767 }
1768 if (!CHECK_FLAG (bi_interior->flags, BGP_INFO_VALID))
1769 {
1770 #if DEBUG_IS_USABLE_INTERIOR
1771 zlog_debug ("%s: NO: BGP_INFO_VALID not set", __func__);
1772 #endif
1773 return 0;
1774 }
1775 return 1;
1776 }
1777
1778 /*
1779 * There should be only one of these per prefix at a time.
1780 * This should be called as a result of selection operation
1781 *
1782 * NB should be called espacially for bgp instances that are named,
1783 * because the exterior routes will always come from one of those.
1784 * We filter here on the instance name to make sure we get only the
1785 * right routes.
1786 */
1787 static void
1788 vnc_import_bgp_exterior_add_route_it (
1789 struct bgp *bgp, /* exterior instance, we hope */
1790 struct prefix *prefix,/* unicast prefix */
1791 struct bgp_info *info, /* unicast info */
1792 struct rfapi_import_table *it_only)/* NULL, or limit to this IT */
1793 {
1794 struct rfapi *h;
1795 struct rfapi_cfg *hc;
1796 struct prefix pfx_orig_nexthop;
1797 struct rfapi_import_table *it;
1798 struct bgp *bgp_default = bgp_get_default ();
1799 afi_t afi = family2afi (prefix->family);
1800
1801 h = bgp_default->rfapi;
1802 hc = bgp_default->rfapi_cfg;
1803
1804 zlog_debug ("%s: entry with it=%p", __func__, it_only);
1805
1806 if (!h || !hc)
1807 {
1808 zlog_debug ("%s: rfapi or rfapi_cfg not instantiated, skipping",
1809 __func__);
1810 return;
1811 }
1812 if (!hc->redist_bgp_exterior_view)
1813 {
1814 zlog_debug ("%s: exterior view not set, skipping", __func__);
1815 return;
1816 }
1817 if (bgp != hc->redist_bgp_exterior_view)
1818 {
1819 zlog_debug ("%s: bgp %p != hc->redist_bgp_exterior_view %p, skipping",
1820 __func__, bgp, hc->redist_bgp_exterior_view);
1821 return;
1822 }
1823
1824 if (!hc->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT])
1825 {
1826 zlog_debug ("%s: redist of exterior routes not enabled, skipping",
1827 __func__);
1828 return;
1829 }
1830
1831 if (!info->attr)
1832 {
1833 zlog_debug ("%s: no info, skipping", __func__);
1834 return;
1835 }
1836
1837 /*
1838 * Extract nexthop from exterior route
1839 *
1840 * Incoming prefix is unicast. If v6, it is in multiprotocol area,
1841 * but if v4 it is in attr->nexthop
1842 */
1843 rfapiUnicastNexthop2Prefix (afi, info->attr, &pfx_orig_nexthop);
1844
1845 for (it = h->imports; it; it = it->next)
1846 {
1847 struct route_table *table;
1848 struct route_node *rn;
1849 struct route_node *par;
1850 struct bgp_info *bi_interior;
1851 int have_usable_route;
1852
1853 zlog_debug ("%s: doing it %p", __func__, it);
1854
1855 if (it_only && (it_only != it))
1856 {
1857 zlog_debug ("%s: doesn't match it_only %p", __func__, it_only);
1858 continue;
1859 }
1860
1861 table = it->imported_vpn[afi];
1862
1863 for (rn = route_node_match (table, &pfx_orig_nexthop),
1864 have_usable_route = 0; (!have_usable_route) && rn;)
1865 {
1866
1867 zlog_debug ("%s: it %p trying rn %p", __func__, it, rn);
1868
1869 for (bi_interior = rn->info; bi_interior;
1870 bi_interior = bi_interior->next)
1871 {
1872 struct prefix_rd *prd;
1873 struct attr new_attr;
1874 u_int32_t label = 0;
1875
1876 if (!is_usable_interior_route (bi_interior))
1877 continue;
1878
1879 zlog_debug ("%s: usable: bi_interior %p", __func__,
1880 bi_interior);
1881
1882 /*
1883 * have a legitimate route to exterior's nexthop
1884 * via NVE.
1885 *
1886 * Import unicast route to the import table
1887 */
1888 have_usable_route = 1;
1889
1890 if (bi_interior->extra)
1891 {
1892 prd = &bi_interior->extra->vnc.import.rd;
1893 label = decode_label (bi_interior->extra->tag);
1894 }
1895 else
1896 prd = NULL;
1897
1898 /* use local_pref from unicast route */
1899 memset (&new_attr, 0, sizeof (struct attr));
1900 bgp_attr_dup (&new_attr, bi_interior->attr);
1901 if (info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
1902 {
1903 new_attr.local_pref = info->attr->local_pref;
1904 new_attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
1905 }
1906
1907 rfapiBgpInfoFilteredImportVPN (it, FIF_ACTION_UPDATE, bi_interior->peer, NULL, /* rfd */
1908 prefix,
1909 NULL,
1910 afi,
1911 prd,
1912 &new_attr,
1913 ZEBRA_ROUTE_BGP_DIRECT_EXT,
1914 BGP_ROUTE_REDISTRIBUTE, &label);
1915
1916 bgp_attr_extra_free (&new_attr);
1917 }
1918
1919 if (have_usable_route)
1920 {
1921 /*
1922 * Make monitor
1923 *
1924 * TBD factor this out into its own function
1925 */
1926 struct prefix *pfx_mon = prefix_new ();
1927 if (!RFAPI_MONITOR_EXTERIOR (rn)->source)
1928 {
1929 RFAPI_MONITOR_EXTERIOR (rn)->source =
1930 skiplist_new (0, NULL, (void (*)(void *)) prefix_free);
1931 route_lock_node (rn); /* for skiplist */
1932 }
1933 route_lock_node (rn); /* for skiplist entry */
1934 prefix_copy (pfx_mon, prefix);
1935 if (!skiplist_insert (RFAPI_MONITOR_EXTERIOR (rn)->source,
1936 info, pfx_mon))
1937 {
1938
1939 bgp_info_lock (info);
1940 }
1941 }
1942 par = rn->parent;
1943 if (par)
1944 route_lock_node (par);
1945 route_unlock_node (rn);
1946 rn = par;
1947 }
1948 if (rn)
1949 route_unlock_node (rn);
1950
1951 if (!have_usable_route)
1952 {
1953 struct prefix *pfx_mon = prefix_new ();
1954 prefix_copy (pfx_mon, prefix);
1955 if (!skiplist_insert (it->monitor_exterior_orphans, info, pfx_mon))
1956 {
1957
1958 bgp_info_lock (info);
1959 }
1960 }
1961 }
1962 }
1963
1964 void
1965 vnc_import_bgp_exterior_add_route (
1966 struct bgp *bgp, /* exterior instance, we hope */
1967 struct prefix *prefix,/* unicast prefix */
1968 struct bgp_info *info) /* unicast info */
1969 {
1970 vnc_import_bgp_exterior_add_route_it (bgp, prefix, info, NULL);
1971 }
1972
1973 /*
1974 * There should be only one of these per prefix at a time.
1975 * This should probably be called as a result of selection operation.
1976 *
1977 * NB should be called espacially for bgp instances that are named,
1978 * because the exterior routes will always come from one of those.
1979 * We filter here on the instance name to make sure we get only the
1980 * right routes.
1981 */
1982 void
1983 vnc_import_bgp_exterior_del_route (
1984 struct bgp *bgp,
1985 struct prefix *prefix, /* unicast prefix */
1986 struct bgp_info *info) /* unicast info */
1987 {
1988 struct rfapi *h;
1989 struct rfapi_cfg *hc;
1990 struct rfapi_import_table *it;
1991 struct prefix pfx_orig_nexthop;
1992 afi_t afi = family2afi (prefix->family);
1993 struct bgp *bgp_default = bgp_get_default ();
1994
1995 memset (&pfx_orig_nexthop, 0, sizeof (struct prefix)); /* keep valgrind happy */
1996
1997 h = bgp_default->rfapi;
1998 hc = bgp_default->rfapi_cfg;
1999
2000 if (!h || !hc)
2001 {
2002 zlog_debug ("%s: rfapi or rfapi_cfg not instantiated, skipping",
2003 __func__);
2004 return;
2005 }
2006 if (!hc->redist_bgp_exterior_view)
2007 {
2008 zlog_debug ("%s: exterior view not set, skipping", __func__);
2009 return;
2010 }
2011 if (bgp != hc->redist_bgp_exterior_view)
2012 {
2013 zlog_debug ("%s: bgp %p != hc->redist_bgp_exterior_view %p, skipping",
2014 __func__, bgp, hc->redist_bgp_exterior_view);
2015 return;
2016 }
2017 if (!hc->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT])
2018 {
2019 zlog_debug ("%s: redist of exterior routes no enabled, skipping",
2020 __func__);
2021 return;
2022 }
2023
2024 if (!info->attr)
2025 {
2026 zlog_debug ("%s: no info, skipping", __func__);
2027 return;
2028 }
2029
2030 /*
2031 * Extract nexthop from exterior route
2032 *
2033 * Incoming prefix is unicast. If v6, it is in multiprotocol area,
2034 * but if v4 it is in attr->nexthop
2035 */
2036 rfapiUnicastNexthop2Prefix (afi, info->attr, &pfx_orig_nexthop);
2037
2038 for (it = h->imports; it; it = it->next)
2039 {
2040 struct route_table *table;
2041 struct route_node *rn;
2042 struct route_node *par;
2043 struct bgp_info *bi_interior;
2044 int have_usable_route;
2045
2046 table = it->imported_vpn[afi];
2047
2048 for (rn = route_node_match (table, &pfx_orig_nexthop),
2049 have_usable_route = 0; (!have_usable_route) && rn;)
2050 {
2051
2052 for (bi_interior = rn->info; bi_interior;
2053 bi_interior = bi_interior->next)
2054 {
2055 struct prefix_rd *prd;
2056 u_int32_t label = 0;
2057
2058 if (!is_usable_interior_route (bi_interior))
2059 continue;
2060
2061 /*
2062 * have a legitimate route to exterior's nexthop
2063 * via NVE.
2064 *
2065 * Import unicast route to the import table
2066 */
2067 have_usable_route = 1;
2068
2069 if (bi_interior->extra)
2070 {
2071 prd = &bi_interior->extra->vnc.import.rd;
2072 label = decode_label (bi_interior->extra->tag);
2073 }
2074 else
2075 prd = NULL;
2076
2077 rfapiBgpInfoFilteredImportVPN (it, FIF_ACTION_KILL, bi_interior->peer, NULL, /* rfd */
2078 prefix,
2079 NULL,
2080 afi,
2081 prd,
2082 bi_interior->attr,
2083 ZEBRA_ROUTE_BGP_DIRECT_EXT,
2084 BGP_ROUTE_REDISTRIBUTE, &label);
2085
2086 /*
2087 * Delete monitor
2088 *
2089 * TBD factor this out into its own function
2090 */
2091 {
2092 if (RFAPI_MONITOR_EXTERIOR (rn)->source)
2093 {
2094 if (!skiplist_delete (RFAPI_MONITOR_EXTERIOR (rn)->source,
2095 info, NULL))
2096 {
2097
2098 bgp_info_unlock (info);
2099 route_unlock_node (rn); /* sl entry */
2100 }
2101 if (skiplist_empty (RFAPI_MONITOR_EXTERIOR (rn)->source))
2102 {
2103 skiplist_free (RFAPI_MONITOR_EXTERIOR (rn)->source);
2104 RFAPI_MONITOR_EXTERIOR (rn)->source = NULL;
2105 route_unlock_node (rn); /* skiplist itself */
2106 }
2107 }
2108 }
2109 }
2110 par = rn->parent;
2111 if (par)
2112 route_lock_node (par);
2113 route_unlock_node (rn);
2114 rn = par;
2115 }
2116 if (rn)
2117 route_unlock_node (rn);
2118
2119 if (!have_usable_route)
2120 {
2121 if (!skiplist_delete (it->monitor_exterior_orphans, info, NULL))
2122 {
2123
2124 bgp_info_unlock (info);
2125 }
2126 }
2127 }
2128 }
2129
2130 /*
2131 * This function should be called after a new interior VPN route
2132 * has been added to an import_table.
2133 *
2134 * NB should also be called whenever an existing vpn interior route
2135 * becomes valid (e.g., valid_interior_count is inremented)
2136 */
2137 void
2138 vnc_import_bgp_exterior_add_route_interior (
2139 struct bgp *bgp,
2140 struct rfapi_import_table *it,
2141 struct route_node *rn_interior, /* VPN IT node */
2142 struct bgp_info *bi_interior) /* VPN IT route */
2143 {
2144 afi_t afi = family2afi (rn_interior->p.family);
2145 struct route_node *par;
2146 struct bgp_info *bi_exterior;
2147 struct prefix *pfx_exterior; /* exterior pfx */
2148 void *cursor;
2149 int rc;
2150 struct list *list_adopted;
2151
2152 zlog_debug ("%s: entry", __func__);
2153
2154 if (!is_usable_interior_route (bi_interior))
2155 {
2156 zlog_debug ("%s: not usable interior route, skipping", __func__);
2157 return;
2158 }
2159
2160 if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT])
2161 {
2162 zlog_debug ("%s: redist of exterior routes no enabled, skipping",
2163 __func__);
2164 return;
2165 }
2166
2167 if (it == bgp->rfapi->it_ce)
2168 {
2169 zlog_debug ("%s: import table is it_ce, skipping", __func__);
2170 return;
2171 }
2172
2173 /*debugging */
2174 {
2175 char str_pfx[BUFSIZ];
2176
2177 prefix2str (&rn_interior->p, str_pfx, BUFSIZ);
2178 str_pfx[BUFSIZ - 1] = 0;
2179
2180 zlog_debug ("%s: interior prefix=%s, bi type=%d",
2181 __func__, str_pfx, bi_interior->type);
2182 }
2183
2184 if (RFAPI_HAS_MONITOR_EXTERIOR (rn_interior))
2185 {
2186
2187 int count = 0; /* debugging */
2188
2189 zlog_debug ("%s: has exterior monitor; ext src: %p", __func__,
2190 RFAPI_MONITOR_EXTERIOR (rn_interior)->source);
2191
2192 /*
2193 * There is a monitor here already. Therefore, we do not need
2194 * to do any pulldown. Just construct exterior routes based
2195 * on the new interior route.
2196 */
2197 cursor = NULL;
2198 for (rc = skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior)->source,
2199 (void **) &bi_exterior,
2200 (void **) &pfx_exterior, &cursor); !rc;
2201 rc =
2202 skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior)->source,
2203 (void **) &bi_exterior, (void **) &pfx_exterior,
2204 &cursor))
2205 {
2206
2207 struct prefix_rd *prd;
2208 struct attr new_attr;
2209 u_int32_t label = 0;
2210
2211
2212 ++count; /* debugging */
2213
2214 assert (bi_exterior);
2215 assert (pfx_exterior);
2216
2217 if (bi_interior->extra)
2218 {
2219 prd = &bi_interior->extra->vnc.import.rd;
2220 label = decode_label (bi_interior->extra->tag);
2221 }
2222 else
2223 prd = NULL;
2224
2225 /* use local_pref from unicast route */
2226 memset (&new_attr, 0, sizeof (struct attr));
2227 bgp_attr_dup (&new_attr, bi_interior->attr);
2228 if (bi_exterior &&
2229 (bi_exterior->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)))
2230 {
2231 new_attr.local_pref = bi_exterior->attr->local_pref;
2232 new_attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
2233 }
2234
2235 rfapiBgpInfoFilteredImportVPN (it, FIF_ACTION_UPDATE, bi_interior->peer, NULL, /* rfd */
2236 pfx_exterior,
2237 NULL,
2238 afi,
2239 prd,
2240 &new_attr,
2241 ZEBRA_ROUTE_BGP_DIRECT_EXT,
2242 BGP_ROUTE_REDISTRIBUTE, &label);
2243
2244 bgp_attr_extra_free (&new_attr);
2245 }
2246 zlog_debug
2247 ("%s: finished constructing exteriors based on existing monitors",
2248 __func__);
2249 return;
2250 }
2251
2252 zlog_debug ("%s: no exterior monitor", __func__);
2253
2254 /*
2255 * No monitor at this node. Is this the first valid interior
2256 * route at this node?
2257 */
2258 if (RFAPI_MONITOR_EXTERIOR (rn_interior)->valid_interior_count > 1)
2259 {
2260 zlog_debug
2261 ("%s: new interior route not first valid one, skipping pulldown",
2262 __func__);
2263 return;
2264 }
2265
2266 /*
2267 * Look up the tree for possible pulldown candidates.
2268 * Find nearest parent with an exterior route monitor
2269 */
2270 for (par = rn_interior->parent; par; par = par->parent)
2271 {
2272 if (RFAPI_HAS_MONITOR_EXTERIOR (par))
2273 break;
2274 }
2275
2276 if (par)
2277 {
2278
2279 zlog_debug ("%s: checking parent %p for possible pulldowns",
2280 __func__, par);
2281
2282 /* check monitors at par for possible pulldown */
2283 cursor = NULL;
2284 for (rc = skiplist_next (RFAPI_MONITOR_EXTERIOR (par)->source,
2285 (void **) &bi_exterior,
2286 (void **) &pfx_exterior, &cursor); !rc;
2287 rc =
2288 skiplist_next (RFAPI_MONITOR_EXTERIOR (par)->source,
2289 (void **) &bi_exterior, (void **) &pfx_exterior,
2290 &cursor))
2291 {
2292
2293 struct prefix pfx_nexthop;
2294
2295 memset (&pfx_nexthop, 0, sizeof (struct prefix)); /* keep valgrind happy */
2296
2297 /* check original nexthop for prefix match */
2298 rfapiUnicastNexthop2Prefix (afi, bi_exterior->attr, &pfx_nexthop);
2299
2300 if (prefix_match (&rn_interior->p, &pfx_nexthop))
2301 {
2302
2303 struct bgp_info *bi;
2304 struct prefix_rd *prd;
2305 struct attr new_attr;
2306 u_int32_t label = 0;
2307
2308 /* do pull-down */
2309
2310 /*
2311 * add monitor to longer prefix
2312 */
2313 struct prefix *pfx_mon = prefix_new ();
2314 prefix_copy (pfx_mon, pfx_exterior);
2315 if (!RFAPI_MONITOR_EXTERIOR (rn_interior)->source)
2316 {
2317 RFAPI_MONITOR_EXTERIOR (rn_interior)->source =
2318 skiplist_new (0, NULL, (void (*)(void *)) prefix_free);
2319 route_lock_node (rn_interior);
2320 }
2321 skiplist_insert (RFAPI_MONITOR_EXTERIOR (rn_interior)->source,
2322 bi_exterior, pfx_mon);
2323 route_lock_node (rn_interior);
2324
2325 /*
2326 * Delete constructed exterior routes based on
2327 * parent routes.
2328 */
2329 for (bi = par->info; bi; bi = bi->next)
2330 {
2331
2332 if (bi->extra)
2333 {
2334 prd = &bi->extra->vnc.import.rd;
2335 label = decode_label (bi->extra->tag);
2336 }
2337 else
2338 prd = NULL;
2339
2340 rfapiBgpInfoFilteredImportVPN (it, FIF_ACTION_KILL, bi->peer, NULL, /* rfd */
2341 pfx_exterior,
2342 NULL,
2343 afi,
2344 prd,
2345 bi->attr,
2346 ZEBRA_ROUTE_BGP_DIRECT_EXT,
2347 BGP_ROUTE_REDISTRIBUTE,
2348 &label);
2349 }
2350
2351
2352 /*
2353 * Add constructed exterior routes based on
2354 * the new interior route at longer prefix.
2355 */
2356 if (bi_interior->extra)
2357 {
2358 prd = &bi_interior->extra->vnc.import.rd;
2359 label = decode_label (bi_interior->extra->tag);
2360 }
2361 else
2362 prd = NULL;
2363
2364 /* use local_pref from unicast route */
2365 memset (&new_attr, 0, sizeof (struct attr));
2366 bgp_attr_dup (&new_attr, bi_interior->attr);
2367 if (bi_exterior &&
2368 (bi_exterior->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)))
2369 {
2370 new_attr.local_pref = bi_exterior->attr->local_pref;
2371 new_attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
2372 }
2373
2374 rfapiBgpInfoFilteredImportVPN (it, FIF_ACTION_UPDATE, bi_interior->peer, NULL, /* rfd */
2375 pfx_exterior,
2376 NULL,
2377 afi,
2378 prd,
2379 &new_attr,
2380 ZEBRA_ROUTE_BGP_DIRECT_EXT,
2381 BGP_ROUTE_REDISTRIBUTE, &label);
2382
2383 bgp_attr_extra_free (&new_attr);
2384 }
2385 }
2386
2387 /*
2388 * The only monitors at rn_interior are the ones we added just
2389 * above, so we can use the rn_interior list to identify which
2390 * monitors to delete from the parent.
2391 */
2392 cursor = NULL;
2393 for (rc = skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior)->source,
2394 (void **) &bi_exterior, NULL, &cursor);
2395 !rc;
2396 rc = skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior)->source,
2397 (void **) &bi_exterior, NULL, &cursor))
2398 {
2399
2400
2401 skiplist_delete (RFAPI_MONITOR_EXTERIOR (par)->source,
2402 bi_exterior, NULL);
2403 route_unlock_node (par); /* sl entry */
2404 }
2405 if (skiplist_empty (RFAPI_MONITOR_EXTERIOR (par)->source))
2406 {
2407 skiplist_free (RFAPI_MONITOR_EXTERIOR (par)->source);
2408 RFAPI_MONITOR_EXTERIOR (par)->source = NULL;
2409 route_unlock_node (par); /* sl itself */
2410 }
2411 }
2412
2413 zlog_debug ("%s: checking orphans", __func__);
2414
2415 /*
2416 * See if any orphans can be pulled down to the current node
2417 */
2418 cursor = NULL;
2419 list_adopted = NULL;
2420 for (rc = skiplist_next (it->monitor_exterior_orphans,
2421 (void **) &bi_exterior, (void **) &pfx_exterior,
2422 &cursor); !rc;
2423 rc =
2424 skiplist_next (it->monitor_exterior_orphans, (void **) &bi_exterior,
2425 (void **) &pfx_exterior, &cursor))
2426 {
2427
2428 struct prefix pfx_nexthop;
2429 char buf[BUFSIZ];
2430 afi_t afi_exterior = family2afi (pfx_exterior->family);
2431
2432 prefix2str (pfx_exterior, buf, sizeof (buf));
2433 buf[sizeof (buf) - 1] = 0;
2434 zlog_debug ("%s: checking exterior orphan at prefix %s", __func__, buf);
2435
2436 if (afi_exterior != afi)
2437 {
2438 zlog_debug ("%s: exterior orphan afi %d != interior afi %d, skip",
2439 __func__, afi_exterior, afi);
2440 continue;
2441 }
2442
2443 /* check original nexthop for prefix match */
2444 rfapiUnicastNexthop2Prefix (afi, bi_exterior->attr, &pfx_nexthop);
2445
2446 if (prefix_match (&rn_interior->p, &pfx_nexthop))
2447 {
2448
2449 struct prefix_rd *prd;
2450 struct attr new_attr;
2451 u_int32_t label = 0;
2452
2453 /* do pull-down */
2454
2455 /*
2456 * add monitor to longer prefix
2457 */
2458
2459 struct prefix *pfx_mon = prefix_new ();
2460 prefix_copy (pfx_mon, pfx_exterior);
2461 if (!RFAPI_MONITOR_EXTERIOR (rn_interior)->source)
2462 {
2463 RFAPI_MONITOR_EXTERIOR (rn_interior)->source =
2464 skiplist_new (0, NULL, (void (*)(void *)) prefix_free);
2465 route_lock_node (rn_interior); /* sl */
2466 }
2467 skiplist_insert (RFAPI_MONITOR_EXTERIOR (rn_interior)->source,
2468 bi_exterior, pfx_mon);
2469 route_lock_node (rn_interior); /* sl entry */
2470 if (!list_adopted)
2471 {
2472 list_adopted = list_new ();
2473 }
2474 listnode_add (list_adopted, bi_exterior);
2475
2476 /*
2477 * Add constructed exterior routes based on the
2478 * new interior route at the longer prefix.
2479 */
2480 if (bi_interior->extra)
2481 {
2482 prd = &bi_interior->extra->vnc.import.rd;
2483 label = decode_label (bi_interior->extra->tag);
2484 }
2485 else
2486 prd = NULL;
2487
2488 /* use local_pref from unicast route */
2489 memset (&new_attr, 0, sizeof (struct attr));
2490 bgp_attr_dup (&new_attr, bi_interior->attr);
2491 if (bi_exterior &&
2492 (bi_exterior->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)))
2493 {
2494 new_attr.local_pref = bi_exterior->attr->local_pref;
2495 new_attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
2496 }
2497
2498 rfapiBgpInfoFilteredImportVPN (it, FIF_ACTION_UPDATE, bi_interior->peer, NULL, /* rfd */
2499 pfx_exterior,
2500 NULL,
2501 afi,
2502 prd,
2503 &new_attr,
2504 ZEBRA_ROUTE_BGP_DIRECT_EXT,
2505 BGP_ROUTE_REDISTRIBUTE, &label);
2506
2507 bgp_attr_extra_free (&new_attr);
2508 }
2509 }
2510 if (list_adopted)
2511 {
2512 struct listnode *node;
2513 struct route_node *bi_exterior;
2514
2515 for (ALL_LIST_ELEMENTS_RO (list_adopted, node, bi_exterior))
2516 {
2517 skiplist_delete (it->monitor_exterior_orphans, bi_exterior, NULL);
2518 }
2519 list_delete (list_adopted);
2520 }
2521 }
2522
2523 /*
2524 * This function should be called after an interior VPN route
2525 * has been deleted from an import_table.
2526 * bi_interior must still be valid, but it must already be detached
2527 * from its route node and the route node's valid_interior_count
2528 * must already be decremented.
2529 *
2530 * NB should also be called whenever an existing vpn interior route
2531 * becomes invalid (e.g., valid_interior_count is decremented)
2532 */
2533 void
2534 vnc_import_bgp_exterior_del_route_interior (
2535 struct bgp *bgp,
2536 struct rfapi_import_table *it,
2537 struct route_node *rn_interior, /* VPN IT node */
2538 struct bgp_info *bi_interior) /* VPN IT route */
2539 {
2540 afi_t afi = family2afi (rn_interior->p.family);
2541 struct route_node *par;
2542 struct bgp_info *bi_exterior;
2543 struct prefix *pfx_exterior; /* exterior pfx */
2544 void *cursor;
2545 int rc;
2546
2547 if (!VALID_INTERIOR_TYPE (bi_interior->type))
2548 {
2549 zlog_debug ("%s: type %d not valid interior type, skipping",
2550 __func__, bi_interior->type);
2551 return;
2552 }
2553
2554 if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT])
2555 {
2556 zlog_debug ("%s: redist of exterior routes no enabled, skipping",
2557 __func__);
2558 return;
2559 }
2560
2561 if (it == bgp->rfapi->it_ce)
2562 {
2563 zlog_debug ("%s: it is it_ce, skipping", __func__);
2564 return;
2565 }
2566
2567 /* If no exterior routes depend on this prefix, nothing to do */
2568 if (!RFAPI_HAS_MONITOR_EXTERIOR (rn_interior))
2569 {
2570 zlog_debug ("%s: no exterior monitor, skipping", __func__);
2571 return;
2572 }
2573
2574 /*debugging */
2575 {
2576 char str_pfx[BUFSIZ];
2577
2578 prefix2str (&rn_interior->p, str_pfx, BUFSIZ);
2579 str_pfx[BUFSIZ - 1] = 0;
2580
2581 zlog_debug ("%s: interior prefix=%s, bi type=%d",
2582 __func__, str_pfx, bi_interior->type);
2583 }
2584
2585 /*
2586 * Remove constructed routes based on the deleted interior route
2587 */
2588 cursor = NULL;
2589 for (rc = skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior)->source,
2590 (void **) &bi_exterior, (void **) &pfx_exterior,
2591 &cursor); !rc;
2592 rc =
2593 skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior)->source,
2594 (void **) &bi_exterior, (void **) &pfx_exterior,
2595 &cursor))
2596 {
2597
2598 struct prefix_rd *prd;
2599 u_int32_t label = 0;
2600
2601 if (bi_interior->extra)
2602 {
2603 prd = &bi_interior->extra->vnc.import.rd;
2604 label = decode_label (bi_interior->extra->tag);
2605 }
2606 else
2607 prd = NULL;
2608
2609 rfapiBgpInfoFilteredImportVPN (it, FIF_ACTION_KILL, bi_interior->peer, NULL, /* rfd */
2610 pfx_exterior,
2611 NULL,
2612 afi,
2613 prd,
2614 bi_interior->attr,
2615 ZEBRA_ROUTE_BGP_DIRECT_EXT,
2616 BGP_ROUTE_REDISTRIBUTE, &label);
2617 }
2618
2619 /*
2620 * If there are no remaining valid interior routes at this prefix,
2621 * we need to look up the tree for a possible node to move monitors to
2622 */
2623 if (RFAPI_MONITOR_EXTERIOR (rn_interior)->valid_interior_count)
2624 {
2625 zlog_debug ("%s: interior routes still present, skipping", __func__);
2626 return;
2627 }
2628
2629 /*
2630 * Find nearest parent with at least one valid interior route
2631 * If none is found, par will end up NULL, and we will move
2632 * the monitors to the orphan list for this import table
2633 */
2634 for (par = rn_interior->parent; par; par = par->parent)
2635 {
2636 if (RFAPI_MONITOR_EXTERIOR (par)->valid_interior_count)
2637 break;
2638 }
2639
2640 zlog_debug ("%s: par=%p, ext src: %p", __func__,
2641 par, RFAPI_MONITOR_EXTERIOR (rn_interior)->source);
2642
2643 /* move all monitors */
2644 /*
2645 * We will use and delete every element of the source skiplist
2646 */
2647 while (!skiplist_first (RFAPI_MONITOR_EXTERIOR (rn_interior)->source,
2648 (void **) &bi_exterior, (void **) &pfx_exterior))
2649 {
2650
2651 struct prefix *pfx_mon = prefix_new ();
2652
2653 prefix_copy (pfx_mon, pfx_exterior);
2654
2655 if (par)
2656 {
2657
2658 struct bgp_info *bi;
2659
2660 /*
2661 * Add monitor to parent node
2662 */
2663 if (!RFAPI_MONITOR_EXTERIOR (par)->source)
2664 {
2665 RFAPI_MONITOR_EXTERIOR (par)->source =
2666 skiplist_new (0, NULL, (void (*)(void *)) prefix_free);
2667 route_lock_node (par); /* sl */
2668 }
2669 skiplist_insert (RFAPI_MONITOR_EXTERIOR (par)->source,
2670 bi_exterior, pfx_mon);
2671 route_lock_node (par); /* sl entry */
2672
2673 /* Add constructed exterior routes based on parent */
2674 for (bi = par->info; bi; bi = bi->next)
2675 {
2676
2677 struct prefix_rd *prd;
2678 struct attr new_attr;
2679 u_int32_t label = 0;
2680
2681 if (bi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT)
2682 continue;
2683
2684 if (bi->extra)
2685 {
2686 prd = &bi->extra->vnc.import.rd;
2687 label = decode_label (bi->extra->tag);
2688 }
2689 else
2690 prd = NULL;
2691
2692 /* use local_pref from unicast route */
2693 memset (&new_attr, 0, sizeof (struct attr));
2694 bgp_attr_dup (&new_attr, bi->attr);
2695 if (bi_exterior &&
2696 (bi_exterior->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)))
2697 {
2698 new_attr.local_pref = bi_exterior->attr->local_pref;
2699 new_attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
2700 }
2701
2702 rfapiBgpInfoFilteredImportVPN (it, FIF_ACTION_UPDATE, bi->peer, NULL, /* rfd */
2703 pfx_exterior,
2704 NULL,
2705 afi,
2706 prd,
2707 &new_attr,
2708 ZEBRA_ROUTE_BGP_DIRECT_EXT,
2709 BGP_ROUTE_REDISTRIBUTE, &label);
2710
2711 bgp_attr_extra_free (&new_attr);
2712 }
2713
2714 }
2715 else
2716 {
2717
2718 /*
2719 * No interior route for exterior's nexthop. Save monitor
2720 * in orphan list to await future route.
2721 */
2722 skiplist_insert (it->monitor_exterior_orphans,
2723 bi_exterior, pfx_mon);
2724 }
2725
2726 skiplist_delete_first (RFAPI_MONITOR_EXTERIOR (rn_interior)->source);
2727 route_unlock_node (rn_interior); /* sl entry */
2728 }
2729 if (skiplist_empty (RFAPI_MONITOR_EXTERIOR (rn_interior)->source))
2730 {
2731 skiplist_free (RFAPI_MONITOR_EXTERIOR (rn_interior)->source);
2732 RFAPI_MONITOR_EXTERIOR (rn_interior)->source = NULL;
2733 route_unlock_node (rn_interior); /* sl itself */
2734 }
2735
2736 }
2737
2738 /***********************************************************************
2739 * Generic add/delete unicast routes
2740 ***********************************************************************/
2741
2742 void
2743 vnc_import_bgp_add_route (
2744 struct bgp *bgp,
2745 struct prefix *prefix,
2746 struct bgp_info *info)
2747 {
2748 afi_t afi = family2afi (prefix->family);
2749
2750 {
2751 struct prefix pfx_nexthop;
2752 char buf[BUFSIZ];
2753 char buf_nh[BUFSIZ];
2754
2755 prefix2str (prefix, buf, BUFSIZ);
2756 rfapiUnicastNexthop2Prefix (afi, info->attr, &pfx_nexthop);
2757 prefix2str (&pfx_nexthop, buf_nh, BUFSIZ);
2758
2759 zlog_debug ("%s: pfx %s, nh %s", __func__, buf, buf_nh);
2760 }
2761 #if DEBUG_RHN_LIST
2762 print_rhn_list(__func__, "ENTER ");
2763 #endif
2764 VNC_RHNCK (enter);
2765
2766 if (!afi)
2767 {
2768 zlog_err ("%s: can't get afi of prefix", __func__);
2769 return;
2770 }
2771
2772 if (!bgp->rfapi_cfg)
2773 {
2774 zlog_debug ("%s: bgp->rfapi_cfg is NULL, skipping", __func__);
2775 return;
2776 }
2777
2778 /* check vnc redist flag for bgp direct routes */
2779 if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT])
2780 {
2781 zlog_debug
2782 ("%s: bgp->rfapi_cfg->redist[afi=%d][type=%d=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping",
2783 __func__, afi, ZEBRA_ROUTE_BGP_DIRECT);
2784 return;
2785 }
2786
2787 switch (bgp->rfapi_cfg->redist_mode)
2788 {
2789 case VNC_REDIST_MODE_PLAIN:
2790 vnc_import_bgp_add_route_mode_plain (bgp, prefix, info);
2791 break;
2792
2793 case VNC_REDIST_MODE_RFG:
2794 if (bgp->rfapi_cfg->rfg_redist)
2795 vnc_import_bgp_add_route_mode_nvegroup (bgp, prefix, info,
2796 bgp->rfapi_cfg->rfg_redist);
2797 else
2798 zlog_debug ("%s: mode RFG but no redist RFG", __func__);
2799 break;
2800
2801 case VNC_REDIST_MODE_RESOLVE_NVE:
2802 vnc_import_bgp_add_route_mode_resolve_nve (bgp, prefix, info);
2803 break;
2804 }
2805 #if DEBUG_RHN_LIST
2806 print_rhn_list(__func__, "LEAVE ");
2807 #endif
2808 VNC_RHNCK (leave);
2809 }
2810
2811 /*
2812 * "Withdrawing a Route" import process
2813 */
2814 void
2815 vnc_import_bgp_del_route (
2816 struct bgp *bgp,
2817 struct prefix *prefix,
2818 struct bgp_info *info) /* unicast info */
2819 {
2820 afi_t afi = family2afi (prefix->family);
2821
2822 assert (afi);
2823
2824 {
2825 struct prefix pfx_nexthop;
2826 char buf[BUFSIZ];
2827 char buf_nh[BUFSIZ];
2828
2829 prefix2str (prefix, buf, BUFSIZ);
2830 rfapiUnicastNexthop2Prefix (afi, info->attr, &pfx_nexthop);
2831 prefix2str (&pfx_nexthop, buf_nh, BUFSIZ);
2832
2833 zlog_debug ("%s: pfx %s, nh %s", __func__, buf, buf_nh);
2834 }
2835 #if DEBUG_RHN_LIST
2836 print_rhn_list(__func__, "ENTER ");
2837 #endif
2838 VNC_RHNCK (enter);
2839
2840 if (!bgp->rfapi_cfg)
2841 {
2842 zlog_debug ("%s: bgp->rfapi_cfg is NULL, skipping", __func__);
2843 return;
2844 }
2845
2846 /* check bgp redist flag for vnc direct ("vpn") routes */
2847 if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT])
2848 {
2849 zlog_debug ("%s: bgp redistribution of afi=%d VNC direct routes is off",
2850 __func__, afi);
2851 return;
2852 }
2853
2854 switch (bgp->rfapi_cfg->redist_mode)
2855 {
2856 case VNC_REDIST_MODE_PLAIN:
2857 vnc_import_bgp_del_route_mode_plain (bgp, prefix, info);
2858 break;
2859
2860 case VNC_REDIST_MODE_RFG:
2861 if (bgp->rfapi_cfg->rfg_redist)
2862 vnc_import_bgp_del_route_mode_nvegroup (bgp, prefix, info);
2863 else
2864 zlog_debug ("%s: mode RFG but no redist RFG", __func__);
2865 break;
2866
2867 case VNC_REDIST_MODE_RESOLVE_NVE:
2868 vnc_import_bgp_del_route_mode_resolve_nve (bgp, afi, prefix, info);
2869 break;
2870
2871 }
2872 #if DEBUG_RHN_LIST
2873 print_rhn_list(__func__, "LEAVE ");
2874 #endif
2875 VNC_RHNCK (leave);
2876 }
2877
2878
2879 /***********************************************************************
2880 * Enable/Disable
2881 ***********************************************************************/
2882
2883 void
2884 vnc_import_bgp_redist_enable (struct bgp *bgp, afi_t afi)
2885 {
2886 /* iterate over bgp unicast v4 and v6 routes, call vnc_import_bgp_add_route */
2887
2888 struct bgp_node *rn;
2889
2890 zlog_debug ("%s: entry, afi=%d", __func__, afi);
2891
2892 if (bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT])
2893 {
2894 zlog_debug ("%s: already enabled for afi %d, skipping", __func__, afi);
2895 return;
2896 }
2897 bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT] = 1;
2898
2899 for (rn = bgp_table_top (bgp->rib[afi][SAFI_UNICAST]);
2900 rn; rn = bgp_route_next (rn))
2901 {
2902
2903 struct bgp_info *bi;
2904
2905 for (bi = rn->info; bi; bi = bi->next)
2906 {
2907
2908 if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED))
2909 continue;
2910
2911 vnc_import_bgp_add_route (bgp, &rn->p, bi);
2912 }
2913 }
2914 zlog_debug ("%s: set redist[afi=%d][type=%d=ZEBRA_ROUTE_BGP_DIRECT] return",
2915 __func__, afi, ZEBRA_ROUTE_BGP_DIRECT);
2916 }
2917
2918 void
2919 vnc_import_bgp_exterior_redist_enable (struct bgp *bgp, afi_t afi)
2920 {
2921 struct bgp *bgp_exterior;
2922 struct bgp_node *rn;
2923
2924 bgp_exterior = bgp->rfapi_cfg->redist_bgp_exterior_view;
2925
2926 if (bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT])
2927 {
2928 zlog_debug ("%s: already enabled for afi %d, skipping", __func__, afi);
2929 return;
2930 }
2931 bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT] = 1;
2932
2933 if (!bgp_exterior)
2934 {
2935 zlog_debug ("%s: no exterior view set yet, no routes to import yet",
2936 __func__);
2937 return;
2938 }
2939
2940 for (rn = bgp_table_top (bgp_exterior->rib[afi][SAFI_UNICAST]);
2941 rn; rn = bgp_route_next (rn))
2942 {
2943
2944 struct bgp_info *bi;
2945
2946 for (bi = rn->info; bi; bi = bi->next)
2947 {
2948
2949 if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED))
2950 continue;
2951
2952 vnc_import_bgp_exterior_add_route (bgp_exterior, &rn->p, bi);
2953 }
2954 }
2955 zlog_debug ("%s: set redist[afi=%d][type=%d=ZEBRA_ROUTE_BGP_DIRECT] return",
2956 __func__, afi, ZEBRA_ROUTE_BGP_DIRECT);
2957
2958 }
2959
2960 /*
2961 * This function is for populating a newly-created Import Table
2962 */
2963 void
2964 vnc_import_bgp_exterior_redist_enable_it (
2965 struct bgp *bgp,
2966 afi_t afi,
2967 struct rfapi_import_table *it_only)
2968 {
2969 struct bgp *bgp_exterior;
2970 struct bgp_node *rn;
2971
2972 zlog_debug ("%s: entry", __func__);
2973
2974 bgp_exterior = bgp->rfapi_cfg->redist_bgp_exterior_view;
2975
2976 if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT])
2977 {
2978 zlog_debug ("%s: not enabled for afi %d, skipping", __func__, afi);
2979 return;
2980 }
2981
2982 if (!bgp_exterior)
2983 {
2984 zlog_debug ("%s: no exterior view set yet, no routes to import yet",
2985 __func__);
2986 return;
2987 }
2988
2989 for (rn = bgp_table_top (bgp_exterior->rib[afi][SAFI_UNICAST]);
2990 rn; rn = bgp_route_next (rn))
2991 {
2992
2993 struct bgp_info *bi;
2994
2995 for (bi = rn->info; bi; bi = bi->next)
2996 {
2997
2998 if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED))
2999 continue;
3000
3001 vnc_import_bgp_exterior_add_route_it (bgp_exterior, &rn->p, bi,
3002 it_only);
3003 }
3004 }
3005
3006 }
3007
3008
3009 void
3010 vnc_import_bgp_redist_disable (struct bgp *bgp, afi_t afi)
3011 {
3012 /*
3013 * iterate over vpn routes, find routes of type ZEBRA_ROUTE_BGP_DIRECT,
3014 * delete (call timer expire immediately)
3015 */
3016 struct bgp_node *rn1;
3017 struct bgp_node *rn2;
3018
3019 zlog_debug ("%s: entry", __func__);
3020
3021 if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT])
3022 {
3023 zlog_debug ("%s: already disabled for afi %d, skipping", __func__, afi);
3024 return;
3025 }
3026
3027 /*
3028 * Two-level table for SAFI_MPLS_VPN
3029 * Be careful when changing the things we iterate over
3030 */
3031 for (rn1 = bgp_table_top (bgp->rib[afi][SAFI_MPLS_VPN]);
3032 rn1; rn1 = bgp_route_next (rn1))
3033 {
3034
3035 if (rn1->info)
3036 {
3037 for (rn2 = bgp_table_top (rn1->info);
3038 rn2; rn2 = bgp_route_next (rn2))
3039 {
3040
3041 struct bgp_info *bi;
3042 struct bgp_info *nextbi;
3043
3044 for (bi = rn2->info; bi; bi = nextbi)
3045 {
3046
3047 nextbi = bi->next;
3048
3049 if (bi->type == ZEBRA_ROUTE_BGP_DIRECT)
3050 {
3051
3052 struct rfapi_descriptor *rfd;
3053 vncHDBgpDirect.peer = bi->peer;
3054
3055 rfd = bi->extra->vnc.export.rfapi_handle;
3056
3057 zlog_debug
3058 ("%s: deleting bi=%p, bi->peer=%p, bi->type=%d, bi->sub_type=%d, bi->extra->vnc.export.rfapi_handle=%p [passing rfd=%p]",
3059 __func__, bi, bi->peer, bi->type, bi->sub_type,
3060 (bi->extra ? bi->extra->vnc.
3061 export.rfapi_handle : NULL), rfd);
3062
3063
3064 del_vnc_route (rfd, bi->peer, bgp, SAFI_MPLS_VPN, &rn2->p, (struct prefix_rd *) &rn1->p, bi->type, bi->sub_type, NULL, 1); /* kill */
3065
3066 vncHDBgpDirect.peer = NULL;
3067 }
3068 }
3069 }
3070 }
3071 }
3072 /* Clear RHN list */
3073 if (bgp->rfapi->resolve_nve_nexthop)
3074 {
3075 struct prefix_bag *pb;
3076 struct bgp_info *info;
3077 while (!skiplist_first
3078 (bgp->rfapi->resolve_nve_nexthop, NULL, (void *) &pb))
3079 {
3080 info = pb->ubi;
3081 skiplist_delete_first (bgp->rfapi->resolve_nve_nexthop);
3082 bgp_info_unlock (info);
3083 }
3084 }
3085
3086 bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT] = 0;
3087 zlog_debug ("%s: return", __func__);
3088 }
3089
3090
3091 void
3092 vnc_import_bgp_exterior_redist_disable (struct bgp *bgp, afi_t afi)
3093 {
3094 struct rfapi_cfg *hc = bgp->rfapi_cfg;
3095 struct bgp *bgp_exterior = hc->redist_bgp_exterior_view;
3096
3097 zlog_debug ("%s: entry", __func__);
3098
3099 if (!hc->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT])
3100 {
3101 zlog_debug ("%s: already disabled for afi %d, skipping", __func__, afi);
3102 return;
3103 }
3104
3105 if (!bgp_exterior)
3106 {
3107 zlog_debug ("%s: bgp exterior view not defined, skipping", __func__);
3108 return;
3109 }
3110
3111
3112 {
3113 struct bgp_node *rn;
3114 for (rn = bgp_table_top (bgp_exterior->rib[afi][SAFI_UNICAST]);
3115 rn; rn = bgp_route_next (rn))
3116 {
3117
3118 struct bgp_info *bi;
3119
3120 for (bi = rn->info; bi; bi = bi->next)
3121 {
3122
3123 if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED))
3124 continue;
3125
3126 vnc_import_bgp_exterior_del_route (bgp_exterior, &rn->p, bi);
3127 }
3128 }
3129 #if DEBUG_RHN_LIST
3130 print_rhn_list (__func__, NULL);
3131 #endif
3132 }
3133
3134 bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT] = 0;
3135 zlog_debug ("%s: return", __func__);
3136 }