3 * Copyright 2009-2016, LabN Consulting, L.L.C.
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.
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.
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.
23 * File: vnc_import_bgp.c
24 * Purpose: Import routes from BGP unicast directly (not via zebra)
27 #include "lib/zebra.h"
28 #include "lib/prefix.h"
29 #include "lib/table.h"
32 #include "lib/memory.h"
33 #include "lib/linklist.h"
34 #include "lib/plist.h"
35 #include "lib/routemap.h"
37 #include "bgpd/bgpd.h"
38 #include "bgpd/bgp_ecommunity.h"
39 #include "bgpd/bgp_attr.h"
40 #include "bgpd/bgp_route.h"
41 #include "bgpd/bgp_mplsvpn.h" /* for RD_TYPE_IP */
43 #include "bgpd/rfapi/vnc_export_bgp.h"
44 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
45 #include "bgpd/rfapi/rfapi.h"
46 #include "bgpd/rfapi/rfapi_import.h"
47 #include "bgpd/rfapi/rfapi_private.h"
48 #include "bgpd/rfapi/rfapi_monitor.h"
49 #include "bgpd/rfapi/rfapi_vty.h"
50 #include "bgpd/rfapi/vnc_import_bgp.h"
51 #include "bgpd/rfapi/vnc_import_bgp_p.h"
52 #include "bgpd/rfapi/vnc_debug.h"
54 #define ENABLE_VNC_RHNCK
56 #define DEBUG_RHN_LIST 0
58 static struct rfapi_descriptor vncHDBgpDirect
; /* dummy nve descriptor */
59 static struct rfapi_descriptor vncHDResolveNve
; /* dummy nve descriptor */
62 * For routes from another AS:
65 * LOCAL_PREF = 255 - MIN(255, MED)
67 * LOCAL_PREF = default_local_pref
69 * For routes from the same AS:
71 * LOCAL_PREF unchanged
74 calc_local_pref (struct attr
*attr
, struct peer
*peer
)
76 uint32_t local_pref
= 0;
82 return peer
->bgp
->default_local_pref
;
84 return bgp_get_default ()->default_local_pref
;
87 if (peer
&& (peer
->as
!= peer
->bgp
->as
))
89 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
97 local_pref
= 255 - attr
->med
;
102 local_pref
= peer
->bgp
->default_local_pref
;
107 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
109 local_pref
= attr
->local_pref
;
113 if (peer
&& peer
->bgp
)
115 local_pref
= peer
->bgp
->default_local_pref
;
124 is_host_prefix (struct prefix
*p
)
129 return (p
->prefixlen
== 32);
131 return (p
->prefixlen
== 128);
136 /***********************************************************************
138 ***********************************************************************/
142 struct prefix hpfx
; /* ce address = unicast nexthop */
143 struct prefix upfx
; /* unicast prefix */
144 struct bgp_info
*ubi
; /* unicast route */
147 static const u_char maskbit
[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0,
148 0xf8, 0xfc, 0xfe, 0xff
152 vnc_prefix_cmp (void *pfx1
, void *pfx2
)
158 struct prefix
*p1
= pfx1
;
159 struct prefix
*p2
= pfx2
;
161 if (p1
->family
< p2
->family
)
163 if (p1
->family
> p2
->family
)
166 if (p1
->prefixlen
< p2
->prefixlen
)
168 if (p1
->prefixlen
> p2
->prefixlen
)
171 offset
= p1
->prefixlen
/ 8;
172 shift
= p1
->prefixlen
% 8;
173 if (shift
== 0 && offset
)
174 { /* catch aligned case */
179 /* Set both prefix's head pointer. */
180 const u_char
*pp1
= (const u_char
*) &p1
->u
.prefix
;
181 const u_char
*pp2
= (const u_char
*) &p2
->u
.prefix
;
193 mask
= maskbit
[shift
];
194 if ((*pp1
& mask
) < (*pp2
& mask
))
196 if ((*pp1
& mask
) > (*pp2
& mask
))
203 prefix_bag_free (void *pb
)
205 XFREE (MTYPE_RFAPI_PREFIX_BAG
, pb
);
210 print_rhn_list (const char *tag1
, const char *tag2
)
214 struct skiplistnode
*p
;
215 struct prefix_bag
*pb
;
218 bgp
= bgp_get_default ();
222 sl
= bgp
->frapi
->resolve_nve_nexthop
;
225 vnc_zlog_debug_verbose ("%s: %s: RHN List is empty", (tag1
? tag1
: ""),
230 vnc_zlog_debug_verbose ("%s: %s: RHN list:", (tag1
? tag1
: ""), (tag2
? tag2
: ""));
232 /* XXX uses secret knowledge of skiplist structure */
233 for (p
= sl
->header
->forward
[0]; p
; p
= p
->forward
[0])
241 prefix2str (p
->key
, kbuf
, BUFSIZ
);
242 prefix2str (&pb
->hpfx
, hbuf
, BUFSIZ
);
243 prefix2str (&pb
->upfx
, ubuf
, BUFSIZ
);
245 vnc_zlog_debug_verbose ("RHN Entry %d (q=%p): kpfx=%s, upfx=%s, hpfx=%s, ubi=%p",
246 ++count
, p
, kbuf
, ubuf
, hbuf
, pb
->ubi
);
251 #ifdef ENABLE_VNC_RHNCK
253 vnc_rhnck (char *tag
)
257 struct skiplistnode
*p
;
259 bgp
= bgp_get_default ();
262 sl
= bgp
->rfapi
->resolve_nve_nexthop
;
267 /* XXX uses secret knowledge of skiplist structure */
268 for (p
= sl
->header
->forward
[0]; p
; p
= p
->forward
[0])
270 struct prefix_bag
*pb
;
273 struct prefix pfx_orig_nexthop
;
275 memset (&pfx_orig_nexthop
, 0, sizeof (struct prefix
)); /* keep valgrind happy */
280 afi
= family2afi (pb
->upfx
.family
);
282 rfapiUnicastNexthop2Prefix (afi
, pb
->ubi
->attr
, &pfx_orig_nexthop
);
284 /* pb->hpfx, pb->ubi nexthop, pkey should all reflect the same pfx */
285 assert (!vnc_prefix_cmp (&pb
->hpfx
, pkey
));
286 if (vnc_prefix_cmp (&pb
->hpfx
, &pfx_orig_nexthop
))
288 char str_onh
[BUFSIZ
];
289 char str_nve_pfx
[BUFSIZ
];
291 prefix2str (&pfx_orig_nexthop
, str_onh
, BUFSIZ
);
292 str_onh
[BUFSIZ
- 1] = 0;
294 prefix2str (&pb
->hpfx
, str_nve_pfx
, BUFSIZ
);
295 str_nve_pfx
[BUFSIZ
- 1] = 0;
297 vnc_zlog_debug_verbose
298 ("%s: %s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s",
299 __func__
, tag
, str_onh
, str_nve_pfx
);
303 vnc_zlog_debug_verbose ("%s: vnc_rhnck OK", tag
);
306 #define VNC_RHNCK(n) do {char buf[BUFSIZ];sprintf(buf,"%s: %s", __func__, #n);vnc_rhnck(buf);} while (0)
314 /***********************************************************************
315 * Add/Delete Unicast Route
316 ***********************************************************************/
319 * "Adding a Route" import process
323 * extract and package information from the BGP unicast route.
324 * Return code 0 means OK, non-0 means drop.
326 * If return code is 0, caller MUST release ecom
329 process_unicast_route (
330 struct bgp
*bgp
, /* in */
332 struct prefix
*prefix
, /* in */
333 struct bgp_info
*info
, /* in */
334 struct ecommunity
**ecom
, /* OUT */
335 struct prefix
*unicast_nexthop
) /* OUT */
337 struct rfapi_cfg
*hc
= bgp
->rfapi_cfg
;
338 struct peer
*peer
= info
->peer
;
339 struct attr
*attr
= info
->attr
;
341 struct route_map
*rmap
= NULL
;
342 struct prefix pfx_orig_nexthop
;
344 memset (&pfx_orig_nexthop
, 0, sizeof (struct prefix
)); /* keep valgrind happy */
349 if (hc
->plist_redist
[ZEBRA_ROUTE_BGP_DIRECT
][afi
])
351 vnc_zlog_debug_verbose ("%s: HC prefix list is set, checking", __func__
);
352 if (prefix_list_apply
353 (hc
->plist_redist
[ZEBRA_ROUTE_BGP_DIRECT
][afi
],
354 prefix
) == PREFIX_DENY
)
356 vnc_zlog_debug_verbose ("%s: prefix list returns DENY, blocking route",
360 vnc_zlog_debug_verbose ("%s: prefix list returns PASS, allowing route", __func__
);
363 /* apply routemap, if any, later */
364 rmap
= hc
->routemap_redist
[ZEBRA_ROUTE_BGP_DIRECT
];
367 * Extract original nexthop, which we expect to be a NVE connected router
368 * Note that this is the nexthop before any possible application of policy
371 * Incoming prefix is unicast. If v6, it is in multiprotocol area,
372 * but if v4 it is in attr->nexthop
374 rfapiUnicastNexthop2Prefix (afi
, attr
, &pfx_orig_nexthop
);
378 * This code is here because it allocates an interned attr which
379 * must be freed before we return. It's easier to put it after
380 * all of the possible returns above.
382 memset (&hattr
, 0, sizeof (struct attr
));
383 bgp_attr_dup (&hattr
, attr
); /* hattr becomes a ghost attr */
387 struct bgp_info info
;
388 route_map_result_t ret
;
390 memset (&info
, 0, sizeof (info
));
393 ret
= route_map_apply (rmap
, prefix
, RMAP_BGP
, &info
);
394 if (ret
== RMAP_DENYMATCH
)
396 bgp_attr_flush (&hattr
);
397 bgp_attr_extra_free (&hattr
);
398 vnc_zlog_debug_verbose ("%s: route map \"%s\" says DENY, returning", __func__
,
405 * Get the (possibly altered by policy) unicast nexthop
406 * for later lookup in the Import Table by caller
408 rfapiUnicastNexthop2Prefix (afi
, &hattr
, unicast_nexthop
);
410 if (hattr
.extra
&& hattr
.extra
->ecommunity
)
411 *ecom
= ecommunity_dup (hattr
.extra
->ecommunity
);
413 *ecom
= ecommunity_new ();
416 * Done with hattr, clean up
418 bgp_attr_flush (&hattr
);
419 bgp_attr_extra_free (&hattr
);
422 * Add EC that carries original NH of iBGP route (2 bytes = magic
423 * value indicating it came from an VNC gateway; default 5226, but
424 * must be user configurable). Note that this is the nexthop before
425 * any application of policy.
428 struct ecommunity_val vnc_gateway_magic
;
431 /* Using route origin extended community type */
432 memset (&vnc_gateway_magic
, 0, sizeof (vnc_gateway_magic
));
433 vnc_gateway_magic
.val
[0] = 0x01;
434 vnc_gateway_magic
.val
[1] = 0x03;
436 /* Only works for IPv4 nexthops */
437 if (prefix
->family
== AF_INET
)
439 memcpy (vnc_gateway_magic
.val
+ 2, &unicast_nexthop
->u
.prefix4
, 4);
441 localadmin
= htons (hc
->resolve_nve_roo_local_admin
);
442 memcpy (vnc_gateway_magic
.val
+ 6, (char *) &localadmin
, 2);
444 ecommunity_add_val (*ecom
, &vnc_gateway_magic
);
452 vnc_import_bgp_add_route_mode_resolve_nve_one_bi (
455 struct bgp_info
*bi
, /* VPN bi */
456 struct prefix_rd
*prd
, /* RD */
457 struct prefix
*prefix
, /* unicast route prefix */
458 uint32_t *local_pref
,/* NULL = no local_pref */
459 uint32_t *med
, /* NULL = no med */
460 struct ecommunity
*ecom
) /* generated ecoms */
463 struct prefix nexthop
;
464 struct rfapi_ip_addr nexthop_h
;
467 struct bgp_attr_encap_subtlv
*encaptlvs
;
470 struct rfapi_un_option optary
[3];
471 struct rfapi_un_option
*opt
= NULL
;
474 vnc_zlog_debug_verbose ("%s: entry", __func__
);
476 if (bi
->type
!= ZEBRA_ROUTE_BGP
&& bi
->type
!= ZEBRA_ROUTE_BGP_DIRECT
)
481 if (bi
->sub_type
!= BGP_ROUTE_NORMAL
&&
482 bi
->sub_type
!= BGP_ROUTE_STATIC
&& bi
->sub_type
!= BGP_ROUTE_RFP
)
487 if (CHECK_FLAG (bi
->flags
, BGP_INFO_REMOVED
))
490 vncHDResolveNve
.peer
= bi
->peer
;
491 if (!rfapiGetVncTunnelUnAddr (bi
->attr
, &un
))
493 if (rfapiQprefix2Raddr (&un
, &vncHDResolveNve
.un_addr
))
498 memset (&vncHDResolveNve
.un_addr
, 0, sizeof (vncHDResolveNve
.un_addr
));
501 /* Use nexthop of VPN route as nexthop of constructed route */
502 rfapiNexthop2Prefix (bi
->attr
, &nexthop
);
503 rfapiQprefix2Raddr (&nexthop
, &nexthop_h
);
505 if (rfapiGetVncLifetime (bi
->attr
, &lifetime
))
511 plifetime
= &lifetime
;
514 if (bi
->attr
&& bi
->attr
->extra
)
516 encaptlvs
= bi
->attr
->extra
->vnc_subtlvs
;
517 if (bi
->attr
->extra
->encap_tunneltype
!= BGP_ENCAP_TYPE_RESERVED
&&
518 bi
->attr
->extra
->encap_tunneltype
!= BGP_ENCAP_TYPE_MPLS
)
521 opt
->next
= &optary
[cur_opt
];
522 opt
= &optary
[cur_opt
++];
523 memset (opt
, 0, sizeof (struct rfapi_un_option
));
524 opt
->type
= RFAPI_UN_OPTION_TYPE_TUNNELTYPE
;
525 opt
->v
.tunnel
.type
= bi
->attr
->extra
->encap_tunneltype
;
526 /* TBD parse bi->attr->extra->encap_subtlvs */
534 struct ecommunity
*new_ecom
= ecommunity_dup (ecom
);
536 if (bi
->attr
&& bi
->attr
->extra
&& bi
->attr
->extra
->ecommunity
)
537 ecommunity_merge (new_ecom
, bi
->attr
->extra
->ecommunity
);
540 label
= decode_label (bi
->extra
->tag
);
546 prefix
, /* unicast route prefix */
548 &nexthop_h
, /* new nexthop */
551 (struct bgp_tea_options
*) encaptlvs
, /* RFP options */
555 med
, /* NULL => don't set med */
556 (label
?&label
:NULL
), /* NULL= default */
557 ZEBRA_ROUTE_BGP_DIRECT
,
558 BGP_ROUTE_REDISTRIBUTE
,
559 RFAPI_AHR_RFPOPT_IS_VNCTLV
); /* flags */
561 ecommunity_free (&new_ecom
);
566 vnc_import_bgp_add_route_mode_resolve_nve_one_rd (
567 struct prefix_rd
*prd
, /* RD */
568 struct bgp_table
*table_rd
, /* per-rd VPN route table */
571 struct prefix
*prefix
, /* unicast prefix */
572 struct ecommunity
*ecom
, /* generated ecoms */
573 uint32_t *local_pref
, /* NULL = no local_pref */
574 uint32_t *med
, /* NULL = no med */
575 struct prefix
*ubi_nexthop
) /* unicast nexthop */
586 prefix2str (ubi_nexthop
, str_nh
, BUFSIZ
);
587 str_nh
[BUFSIZ
- 1] = 0;
589 vnc_zlog_debug_verbose ("%s: ubi_nexthop=%s", __func__
, str_nh
);
593 bn
= bgp_node_lookup (table_rd
, ubi_nexthop
);
596 vnc_zlog_debug_verbose ("%s: no match in RD's table for ubi_nexthop", __func__
);
600 /* Iterate over bgp_info items at this node */
601 for (bi
= bn
->info
; bi
; bi
= bi
->next
)
604 vnc_import_bgp_add_route_mode_resolve_nve_one_bi (bgp
, afi
, bi
, /* VPN bi */
611 bgp_unlock_node (bn
);
615 vnc_import_bgp_add_route_mode_resolve_nve (
617 struct prefix
*prefix
,/* unicast prefix */
618 struct bgp_info
*info
) /* unicast info */
620 afi_t afi
= family2afi (prefix
->family
);
621 struct rfapi_cfg
*hc
= NULL
;
623 struct prefix pfx_unicast_nexthop
= { 0 }; /* happy valgrind */
625 struct ecommunity
*ecom
= NULL
;
627 uint32_t *med
= NULL
;
629 struct prefix_bag
*pb
;
630 struct bgp_node
*bnp
; /* prd table node */
634 char str_pfx
[BUFSIZ
];
638 prefix2str (prefix
, str_pfx
, BUFSIZ
);
639 str_pfx
[BUFSIZ
- 1] = 0;
642 rfapiUnicastNexthop2Prefix (afi
, info
->attr
, &nh
);
645 prefix2str (&nh
, str_nh
, BUFSIZ
);
646 str_nh
[BUFSIZ
- 1] = 0;
654 vnc_zlog_debug_verbose ("%s(bgp=%p, unicast prefix=%s, unicast nh=%s)",
655 __func__
, bgp
, str_pfx
, str_nh
);
658 if (info
->type
!= ZEBRA_ROUTE_BGP
)
660 vnc_zlog_debug_verbose ("%s: unicast type %d=\"%s\" is not %d=%s, skipping",
661 __func__
, info
->type
, zebra_route_string (info
->type
),
662 ZEBRA_ROUTE_BGP
, "ZEBRA_ROUTE_BGP");
672 zlog_err ("%s: can't get afi of prefix", __func__
);
676 if (!(hc
= bgp
->rfapi_cfg
))
678 vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
682 /* check vnc redist flag for bgp direct routes */
683 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
685 vnc_zlog_debug_verbose
686 ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping",
692 if (process_unicast_route (bgp
, afi
, prefix
, info
,
693 &ecom
, &pfx_unicast_nexthop
))
696 vnc_zlog_debug_verbose ("%s: process_unicast_route error, skipping", __func__
);
700 local_pref
= calc_local_pref (info
->attr
, info
->peer
);
702 (info
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
)))
705 med
= &info
->attr
->med
;
710 * At this point, we have allocated:
712 * ecom ecommunity ptr, union of unicast and ROO parts (no NVE part)
716 * pfx_unicast_nexthop nexthop of uncast route
719 if (!bgp
->rfapi
->resolve_nve_nexthop
)
721 bgp
->rfapi
->resolve_nve_nexthop
=
722 skiplist_new (SKIPLIST_FLAG_ALLOW_DUPLICATES
, vnc_prefix_cmp
,
726 pb
= XCALLOC (MTYPE_RFAPI_PREFIX_BAG
, sizeof (struct prefix_bag
));
727 pb
->hpfx
= pfx_unicast_nexthop
;
731 bgp_info_lock (info
); /* skiplist refers to it */
732 skiplist_insert (bgp
->rfapi
->resolve_nve_nexthop
, &pb
->hpfx
, pb
);
735 * Iterate over RDs in VPN RIB. For each RD, look up unicast nexthop
736 * (exact match, /32). If an exact match is found, call add_vnc_route.
739 for (bnp
= bgp_table_top (bgp
->rib
[afi
][SAFI_MPLS_VPN
]); bnp
;
740 bnp
= bgp_route_next (bnp
))
743 struct bgp_table
*table
;
745 table
= (struct bgp_table
*) (bnp
->info
);
750 vnc_import_bgp_add_route_mode_resolve_nve_one_rd ((struct prefix_rd
*)
754 &pfx_unicast_nexthop
);
760 ecommunity_free (&ecom
);
762 vnc_zlog_debug_verbose ("%s: done", __func__
);
767 vnc_import_bgp_add_route_mode_plain (struct bgp
*bgp
,
768 struct prefix
*prefix
,
769 struct bgp_info
*info
)
771 afi_t afi
= family2afi (prefix
->family
);
772 struct peer
*peer
= info
->peer
;
773 struct attr
*attr
= info
->attr
;
775 struct rfapi_cfg
*hc
= NULL
;
776 struct attr
*iattr
= NULL
;
778 struct rfapi_ip_addr vnaddr
;
779 struct prefix vn_pfx_space
;
780 struct prefix
*vn_pfx
= NULL
;
782 struct ecommunity
*ecom
= NULL
;
783 struct prefix_rd prd
;
784 struct route_map
*rmap
= NULL
;
786 uint32_t *med
= NULL
;
792 prefix2str (prefix
, buf
, BUFSIZ
);
794 vnc_zlog_debug_verbose ("%s(prefix=%s) entry", __func__
, buf
);
799 zlog_err ("%s: can't get afi of prefix", __func__
);
803 if (!(hc
= bgp
->rfapi_cfg
))
805 vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
809 /* check vnc redist flag for bgp direct routes */
810 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
812 vnc_zlog_debug_verbose
813 ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping",
819 * mode "plain" specific code
822 vnc_zlog_debug_verbose ("%s: NOT using redist RFG", __func__
);
827 if (hc
->plist_redist
[ZEBRA_ROUTE_BGP_DIRECT
][afi
])
829 vnc_zlog_debug_verbose ("%s: HC prefix list is set, checking", __func__
);
830 if (prefix_list_apply
831 (hc
->plist_redist
[ZEBRA_ROUTE_BGP_DIRECT
][afi
],
832 prefix
) == PREFIX_DENY
)
834 vnc_zlog_debug_verbose ("%s: prefix list returns DENY, blocking route",
838 vnc_zlog_debug_verbose ("%s: prefix list returns PASS, allowing route", __func__
);
841 /* apply routemap, if any, later */
842 rmap
= hc
->routemap_redist
[ZEBRA_ROUTE_BGP_DIRECT
];
845 * Incoming prefix is unicast. If v6, it is in multiprotocol area,
846 * but if v4 it is in attr->nexthop
848 rfapiUnicastNexthop2Prefix (afi
, attr
, &vn_pfx_space
);
849 vn_pfx
= &vn_pfx_space
;
852 ahr_flags
|= RFAPI_AHR_NO_TUNNEL_SUBTLV
;
855 if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE
))
860 prefix2str (vn_pfx
, buf
, BUFSIZ
);
862 vnc_zlog_debug_any ("%s vn_pfx=%s", __func__
, buf
);
868 if (rfapiQprefix2Raddr (vn_pfx
, &vnaddr
))
870 vnc_zlog_debug_verbose ("%s: redist VN invalid, skipping", __func__
);
876 * This code is here because it allocates an interned attr which
877 * must be freed before we return. It's easier to put it after
878 * all of the possible returns above.
880 memset (&hattr
, 0, sizeof (struct attr
));
881 bgp_attr_dup (&hattr
, attr
); /* hattr becomes a ghost attr */
885 struct bgp_info info
;
886 route_map_result_t ret
;
888 memset (&info
, 0, sizeof (info
));
891 ret
= route_map_apply (rmap
, prefix
, RMAP_BGP
, &info
);
892 if (ret
== RMAP_DENYMATCH
)
894 bgp_attr_flush (&hattr
);
895 bgp_attr_extra_free (&hattr
);
896 vnc_zlog_debug_verbose ("%s: route map \"%s\" says DENY, returning", __func__
,
902 iattr
= bgp_attr_intern (&hattr
);
903 bgp_attr_flush (&hattr
);
904 bgp_attr_extra_free (&hattr
);
906 /* Now iattr is an allocated interned attr */
909 * Mode "plain" specific code
911 * Sets RD in dummy HD
915 if (vnaddr
.addr_family
!= AF_INET
)
917 vnc_zlog_debug_verbose
918 ("%s: can't auto-assign RD, VN AF (%d) is not IPv4, skipping",
919 __func__
, vnaddr
.addr_family
);
922 bgp_attr_unintern (&iattr
);
926 memset (&prd
, 0, sizeof (prd
));
927 rfapi_set_autord_from_vn (&prd
, &vnaddr
);
929 if (iattr
&& iattr
->extra
&& iattr
->extra
->ecommunity
)
930 ecom
= ecommunity_dup (iattr
->extra
->ecommunity
);
934 local_pref
= calc_local_pref (iattr
, peer
);
936 if (iattr
&& (iattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
)))
941 if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE
))
946 rfapiRfapiIpAddr2Str (&vnaddr
, buf
, BUFSIZ
);
948 vnc_zlog_debug_any ("%s: setting vnaddr to %s", __func__
, buf
);
951 vncHDBgpDirect
.peer
= peer
;
952 add_vnc_route (&vncHDBgpDirect
, bgp
, SAFI_MPLS_VPN
, prefix
, &prd
, &vnaddr
, &local_pref
, &(bgp
->rfapi_cfg
->redist_lifetime
), NULL
, /* RFP options */
953 NULL
, NULL
, ecom
, med
, /* med */
954 NULL
, /* label: default */
955 ZEBRA_ROUTE_BGP_DIRECT
, BGP_ROUTE_REDISTRIBUTE
, ahr_flags
);
956 vncHDBgpDirect
.peer
= NULL
;
959 ecommunity_free (&ecom
);
963 vnc_import_bgp_add_route_mode_nvegroup (struct bgp
*bgp
,
964 struct prefix
*prefix
,
965 struct bgp_info
*info
,
966 struct rfapi_nve_group_cfg
*rfg
)
968 afi_t afi
= family2afi (prefix
->family
);
969 struct peer
*peer
= info
->peer
;
970 struct attr
*attr
= info
->attr
;
972 struct rfapi_cfg
*hc
= NULL
;
973 struct attr
*iattr
= NULL
;
975 struct rfapi_ip_addr vnaddr
;
976 struct prefix
*vn_pfx
= NULL
;
978 struct ecommunity
*ecom
= NULL
;
979 struct prefix_rd prd
;
980 struct route_map
*rmap
= NULL
;
987 prefix2str (prefix
, buf
, BUFSIZ
);
989 vnc_zlog_debug_verbose ("%s(prefix=%s) entry", __func__
, buf
);
996 zlog_err ("%s: can't get afi of prefix", __func__
);
1000 if (!(hc
= bgp
->rfapi_cfg
))
1002 vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
1006 /* check vnc redist flag for bgp direct routes */
1007 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
1009 vnc_zlog_debug_verbose
1010 ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping",
1021 struct rfapi_ip_prefix pfx_un
;
1023 vnc_zlog_debug_verbose ("%s: using redist RFG", __func__
);
1026 * RFG prefix list check
1028 if (rfg
->plist_redist
[ZEBRA_ROUTE_BGP_DIRECT
][afi
])
1030 vnc_zlog_debug_verbose ("%s: RFG prefix list is set, checking", __func__
);
1031 if (prefix_list_apply
1032 (rfg
->plist_redist
[ZEBRA_ROUTE_BGP_DIRECT
][afi
],
1033 prefix
) == PREFIX_DENY
)
1035 vnc_zlog_debug_verbose ("%s: prefix list returns DENY, blocking route",
1039 vnc_zlog_debug_verbose ("%s: prefix list returns PASS, allowing route", __func__
);
1042 /* apply routemap, if any, later */
1043 rmap
= rfg
->routemap_redist
[ZEBRA_ROUTE_BGP_DIRECT
];
1046 * export nve group's VN addr prefix must be a /32 which
1047 * will yield the VN addr to use
1049 vn_pfx
= &rfg
->vn_prefix
;
1054 if (!is_host_prefix (&rfg
->un_prefix
))
1056 /* NB prefixlen==0 means it has not been configured */
1057 vnc_zlog_debug_verbose ("%s: redist RFG UN pfx not host pfx (plen=%d), skipping",
1058 __func__
, rfg
->un_prefix
.prefixlen
);
1062 rfapiQprefix2Rprefix (&rfg
->un_prefix
, &pfx_un
);
1064 vncHDBgpDirect
.un_addr
= pfx_un
.prefix
;
1067 if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE
))
1072 prefix2str (vn_pfx
, buf
, BUFSIZ
);
1073 buf
[BUFSIZ
- 1] = 0;
1074 vnc_zlog_debug_any ("%s vn_pfx=%s", __func__
, buf
);
1078 * Compute VN address
1080 if (rfapiQprefix2Raddr (vn_pfx
, &vnaddr
))
1082 vnc_zlog_debug_verbose ("%s: redist VN invalid, skipping", __func__
);
1087 * route map handling
1088 * This code is here because it allocates an interned attr which
1089 * must be freed before we return. It's easier to put it after
1090 * all of the possible returns above.
1092 memset (&hattr
, 0, sizeof (struct attr
));
1093 bgp_attr_dup (&hattr
, attr
); /* hattr becomes a ghost attr */
1097 struct bgp_info info
;
1098 route_map_result_t ret
;
1100 memset (&info
, 0, sizeof (info
));
1103 ret
= route_map_apply (rmap
, prefix
, RMAP_BGP
, &info
);
1104 if (ret
== RMAP_DENYMATCH
)
1106 bgp_attr_flush (&hattr
);
1107 bgp_attr_extra_free (&hattr
);
1108 vnc_zlog_debug_verbose ("%s: route map \"%s\" says DENY, returning", __func__
,
1114 iattr
= bgp_attr_intern (&hattr
);
1115 bgp_attr_flush (&hattr
);
1116 bgp_attr_extra_free (&hattr
);
1118 /* Now iattr is an allocated interned attr */
1123 * Sets RD in dummy HD
1128 memset (&prd
, 0, sizeof (prd
));
1130 prd
.family
= AF_UNSPEC
;
1133 if (rfg
->rd
.family
== AF_UNIX
)
1135 rfapi_set_autord_from_vn (&prd
, &vnaddr
);
1138 if (rfg
->rt_export_list
)
1139 ecom
= ecommunity_dup (bgp
->rfapi_cfg
->rfg_redist
->rt_export_list
);
1141 ecom
= ecommunity_new ();
1143 if (iattr
&& iattr
->extra
&& iattr
->extra
->ecommunity
)
1144 ecom
= ecommunity_merge (ecom
, iattr
->extra
->ecommunity
);
1147 local_pref
= calc_local_pref (iattr
, peer
);
1149 if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE
))
1154 rfapiRfapiIpAddr2Str (&vnaddr
, buf
, BUFSIZ
);
1155 buf
[BUFSIZ
- 1] = 0;
1156 vnc_zlog_debug_any ("%s: setting vnaddr to %s", __func__
, buf
);
1159 vncHDBgpDirect
.peer
= peer
;
1168 &(bgp
->rfapi_cfg
->redist_lifetime
),
1169 NULL
, /* RFP options */
1174 NULL
, /* label: default */
1175 ZEBRA_ROUTE_BGP_DIRECT
,
1176 BGP_ROUTE_REDISTRIBUTE
,
1178 vncHDBgpDirect
.peer
= NULL
;
1181 ecommunity_free (&ecom
);
1185 vnc_import_bgp_del_route_mode_plain (struct bgp
*bgp
,
1186 struct prefix
*prefix
,
1187 struct bgp_info
*info
)
1189 struct prefix_rd prd
;
1190 afi_t afi
= family2afi (prefix
->family
);
1191 struct prefix
*vn_pfx
= NULL
;
1192 struct rfapi_ip_addr vnaddr
;
1193 struct prefix vn_pfx_space
;
1199 * Compute VN address
1202 if (info
&& info
->attr
)
1204 rfapiUnicastNexthop2Prefix (afi
, info
->attr
, &vn_pfx_space
);
1208 vnc_zlog_debug_verbose ("%s: no attr, can't delete route", __func__
);
1211 vn_pfx
= &vn_pfx_space
;
1213 vnaddr
.addr_family
= vn_pfx
->family
;
1214 switch (vn_pfx
->family
)
1217 if (vn_pfx
->prefixlen
!= 32)
1219 vnc_zlog_debug_verbose ("%s: redist VN plen (%d) != 32, skipping",
1220 __func__
, vn_pfx
->prefixlen
);
1223 vnaddr
.addr
.v4
= vn_pfx
->u
.prefix4
;
1227 if (vn_pfx
->prefixlen
!= 128)
1229 vnc_zlog_debug_verbose ("%s: redist VN plen (%d) != 128, skipping",
1230 __func__
, vn_pfx
->prefixlen
);
1233 vnaddr
.addr
.v6
= vn_pfx
->u
.prefix6
;
1237 vnc_zlog_debug_verbose ("%s: no redist RFG VN host pfx configured, skipping",
1243 memset (&prd
, 0, sizeof (prd
));
1244 if (rfapi_set_autord_from_vn (&prd
, &vnaddr
))
1246 vnc_zlog_debug_verbose ("%s: can't auto-assign RD, skipping", __func__
);
1250 vncHDBgpDirect
.peer
= info
->peer
;
1251 vnc_zlog_debug_verbose ("%s: setting peer to %p", __func__
, vncHDBgpDirect
.peer
);
1252 del_vnc_route (&vncHDBgpDirect
,
1258 ZEBRA_ROUTE_BGP_DIRECT
, BGP_ROUTE_REDISTRIBUTE
, NULL
, 1);
1260 vncHDBgpDirect
.peer
= NULL
;
1264 vnc_import_bgp_del_route_mode_nvegroup (struct bgp
*bgp
,
1265 struct prefix
*prefix
,
1266 struct bgp_info
*info
)
1268 struct prefix_rd prd
;
1269 afi_t afi
= family2afi (prefix
->family
);
1270 struct rfapi_nve_group_cfg
*rfg
= NULL
;
1271 struct prefix
*vn_pfx
= NULL
;
1272 struct rfapi_ip_addr vnaddr
;
1277 assert ((rfg
= bgp
->rfapi_cfg
->rfg_redist
));
1280 * Compute VN address
1284 * export nve group's VN addr prefix must be a /32 which
1285 * will yield the VN addr to use
1287 vn_pfx
= &rfg
->vn_prefix
;
1290 vnaddr
.addr_family
= vn_pfx
->family
;
1291 switch (vn_pfx
->family
)
1294 if (vn_pfx
->prefixlen
!= 32)
1296 vnc_zlog_debug_verbose ("%s: redist VN plen (%d) != 32, skipping",
1297 __func__
, vn_pfx
->prefixlen
);
1300 vnaddr
.addr
.v4
= vn_pfx
->u
.prefix4
;
1304 if (vn_pfx
->prefixlen
!= 128)
1306 vnc_zlog_debug_verbose ("%s: redist VN plen (%d) != 128, skipping",
1307 __func__
, vn_pfx
->prefixlen
);
1310 vnaddr
.addr
.v6
= vn_pfx
->u
.prefix6
;
1314 vnc_zlog_debug_verbose ("%s: no redist RFG VN host pfx configured, skipping",
1319 memset (&prd
, 0, sizeof (prd
));
1321 prd
.family
= AF_UNSPEC
;
1324 if (rfg
->rd
.family
== AF_UNIX
)
1326 /* means "auto" with VN addr */
1327 if (rfapi_set_autord_from_vn (&prd
, &vnaddr
))
1329 vnc_zlog_debug_verbose ("%s: can't auto-assign RD, skipping", __func__
);
1335 vncHDBgpDirect
.peer
= info
->peer
;
1336 vnc_zlog_debug_verbose ("%s: setting peer to %p", __func__
, vncHDBgpDirect
.peer
);
1337 del_vnc_route (&vncHDBgpDirect
,
1343 ZEBRA_ROUTE_BGP_DIRECT
, BGP_ROUTE_REDISTRIBUTE
, NULL
, 1);
1345 vncHDBgpDirect
.peer
= NULL
;
1349 vnc_import_bgp_del_route_mode_resolve_nve_one_bi (
1352 struct bgp_info
*bi
, /* VPN bi */
1353 struct prefix_rd
*prd
, /* RD */
1354 struct prefix
*prefix
)/* unicast route prefix */
1358 if (bi
->type
!= ZEBRA_ROUTE_BGP
&& bi
->type
!= ZEBRA_ROUTE_BGP_DIRECT
)
1363 if (bi
->sub_type
!= BGP_ROUTE_NORMAL
&&
1364 bi
->sub_type
!= BGP_ROUTE_STATIC
&& bi
->sub_type
!= BGP_ROUTE_RFP
)
1369 if (CHECK_FLAG (bi
->flags
, BGP_INFO_REMOVED
))
1372 vncHDResolveNve
.peer
= bi
->peer
;
1373 if (!rfapiGetVncTunnelUnAddr (bi
->attr
, &un
))
1375 if (rfapiQprefix2Raddr (&un
, &vncHDResolveNve
.un_addr
))
1380 memset (&vncHDResolveNve
.un_addr
, 0, sizeof (vncHDResolveNve
.un_addr
));
1383 del_vnc_route (&vncHDResolveNve
, vncHDResolveNve
.peer
, bgp
, SAFI_MPLS_VPN
, prefix
, /* unicast route prefix */
1384 prd
, ZEBRA_ROUTE_BGP_DIRECT
, BGP_ROUTE_REDISTRIBUTE
, NULL
, 0); /* flags */
1389 vnc_import_bgp_del_route_mode_resolve_nve_one_rd (
1390 struct prefix_rd
*prd
,
1391 struct bgp_table
*table_rd
, /* per-rd VPN route table */
1394 struct prefix
*prefix
, /* unicast prefix */
1395 struct prefix
*ubi_nexthop
) /* unicast bi's nexthop */
1397 struct bgp_node
*bn
;
1398 struct bgp_info
*bi
;
1404 char str_nh
[BUFSIZ
];
1406 prefix2str (ubi_nexthop
, str_nh
, BUFSIZ
);
1407 str_nh
[BUFSIZ
- 1] = 0;
1409 vnc_zlog_debug_verbose ("%s: ubi_nexthop=%s", __func__
, str_nh
);
1414 bn
= bgp_node_lookup (table_rd
, ubi_nexthop
);
1417 vnc_zlog_debug_verbose ("%s: no match in RD's table for ubi_nexthop", __func__
);
1421 /* Iterate over bgp_info items at this node */
1422 for (bi
= bn
->info
; bi
; bi
= bi
->next
)
1425 vnc_import_bgp_del_route_mode_resolve_nve_one_bi (bgp
, afi
, bi
, /* VPN bi */
1427 prefix
); /* unicast route prefix */
1430 bgp_unlock_node (bn
);
1434 vnc_import_bgp_del_route_mode_resolve_nve (struct bgp
*bgp
,
1436 struct prefix
*prefix
,
1437 struct bgp_info
*info
)
1439 struct ecommunity
*ecom
= NULL
;
1440 struct prefix pfx_unicast_nexthop
= { 0 }; /* happy valgrind */
1442 //struct listnode *hnode;
1443 //struct rfapi_descriptor *rfd;
1444 struct prefix_bag
*pb
;
1446 struct skiplist
*sl
= bgp
->rfapi
->resolve_nve_nexthop
;
1448 struct bgp_node
*bnp
; /* prd table node */
1452 vnc_zlog_debug_verbose ("%s: no RHN entries, skipping", __func__
);
1456 if (info
->type
!= ZEBRA_ROUTE_BGP
)
1458 vnc_zlog_debug_verbose ("%s: unicast type %d=\"%s\" is not %d=%s, skipping",
1459 __func__
, info
->type
, zebra_route_string (info
->type
),
1460 ZEBRA_ROUTE_BGP
, "ZEBRA_ROUTE_BGP");
1464 if (process_unicast_route (bgp
, afi
, prefix
, info
,
1465 &ecom
, &pfx_unicast_nexthop
))
1468 vnc_zlog_debug_verbose ("%s: process_unicast_route error, skipping", __func__
);
1472 rc
= skiplist_first_value (sl
, &pfx_unicast_nexthop
, (void *) &pb
, &cursor
);
1475 if (pb
->ubi
== info
)
1477 skiplist_delete (sl
, &pfx_unicast_nexthop
, pb
);
1478 bgp_info_unlock (info
);
1482 skiplist_next_value (sl
, &pfx_unicast_nexthop
, (void *) &pb
, &cursor
);
1486 * Iterate over RDs in VPN RIB. For each RD, look up unicast nexthop
1487 * (exact match, /32). If an exact match is found, call add_vnc_route.
1490 for (bnp
= bgp_table_top (bgp
->rib
[afi
][SAFI_MPLS_VPN
]); bnp
;
1491 bnp
= bgp_route_next (bnp
))
1494 struct bgp_table
*table
;
1496 table
= (struct bgp_table
*) (bnp
->info
);
1501 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? */
1505 ecommunity_free (&ecom
);
1511 /***********************************************************************
1512 * Add/Delete CE->NVE routes
1513 ***********************************************************************/
1516 * Should be called whan a bi is added to VPN RIB. This function
1517 * will check if it is a host route and return immediately if not.
1520 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve (
1522 struct prefix_rd
*prd
, /* RD */
1523 struct bgp_table
*table_rd
, /* per-rd VPN route table */
1524 struct prefix
*prefix
, /* VPN prefix */
1525 struct bgp_info
*bi
) /* new VPN host route */
1527 afi_t afi
= family2afi (prefix
->family
);
1528 struct skiplist
*sl
= NULL
;
1530 struct prefix_bag
*pb
;
1532 struct rfapi_cfg
*hc
= NULL
;
1534 vnc_zlog_debug_verbose ("%s: entry", __func__
);
1536 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
1538 vnc_zlog_debug_verbose ("%s: bad afi %d, skipping", __func__
, afi
);
1542 if (!(hc
= bgp
->rfapi_cfg
))
1544 vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
1548 /* check vnc redist flag for bgp direct routes */
1549 if (!hc
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
1551 vnc_zlog_debug_verbose
1552 ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping",
1557 if (hc
->redist_mode
!= VNC_REDIST_MODE_RESOLVE_NVE
)
1559 vnc_zlog_debug_verbose ("%s: not in resolve-nve mode, skipping", __func__
);
1563 if (bgp
&& bgp
->rfapi
)
1564 sl
= bgp
->rfapi
->resolve_nve_nexthop
;
1568 vnc_zlog_debug_verbose ("%s: no resolve_nve_nexthop skiplist, skipping", __func__
);
1572 if (!is_host_prefix (prefix
))
1574 vnc_zlog_debug_verbose ("%s: not host prefix, skipping", __func__
);
1578 rc
= skiplist_first_value (sl
, prefix
, (void *) &pb
, &cursor
);
1581 struct ecommunity
*ecom
;
1582 struct prefix pfx_unicast_nexthop
;
1583 uint32_t *med
= NULL
;
1584 uint32_t local_pref
;
1586 memset (&pfx_unicast_nexthop
, 0, sizeof (struct prefix
)); /* keep valgrind happy */
1588 if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE
))
1593 prefix2str (&pb
->hpfx
, hbuf
, BUFSIZ
);
1594 prefix2str (&pb
->upfx
, ubuf
, BUFSIZ
);
1597 ("%s: examining RHN Entry (q=%p): upfx=%s, hpfx=%s, ubi=%p",
1598 __func__
, cursor
, ubuf
, hbuf
, pb
->ubi
);
1601 if (process_unicast_route (bgp
, afi
, &pb
->upfx
, pb
->ubi
,
1602 &ecom
, &pfx_unicast_nexthop
))
1605 vnc_zlog_debug_verbose ("%s: process_unicast_route error, skipping", __func__
);
1608 local_pref
= calc_local_pref (pb
->ubi
->attr
, pb
->ubi
->peer
);
1610 if (pb
->ubi
->attr
&&
1611 (pb
->ubi
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
)))
1614 med
= &pb
->ubi
->attr
->med
;
1620 if (vnc_prefix_cmp (&pfx_unicast_nexthop
, prefix
))
1622 char str_unh
[BUFSIZ
];
1623 char str_nve_pfx
[BUFSIZ
];
1625 prefix2str (&pfx_unicast_nexthop
, str_unh
, BUFSIZ
);
1626 str_unh
[BUFSIZ
- 1] = 0;
1628 prefix2str (prefix
, str_nve_pfx
, BUFSIZ
);
1629 str_nve_pfx
[BUFSIZ
- 1] = 0;
1631 vnc_zlog_debug_verbose
1632 ("%s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s",
1633 __func__
, str_unh
, str_nve_pfx
);
1637 vnc_import_bgp_add_route_mode_resolve_nve_one_bi (bgp
, afi
, bi
, /* VPN bi */
1638 prd
, &pb
->upfx
, /* unicast prefix */
1643 ecommunity_free (&ecom
);
1650 prefix2str (prefix
, pbuf
, BUFSIZ
);
1652 vnc_zlog_debug_verbose ("%s: advancing past RHN Entry (q=%p): with prefix %s",
1653 __func__
, cursor
, pbuf
);
1654 print_rhn_list (__func__
, NULL
); /* debug */
1657 rc
= skiplist_next_value (sl
, prefix
, (void *) &pb
, &cursor
);
1659 vnc_zlog_debug_verbose ("%s: done", __func__
);
1664 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve (
1666 struct prefix_rd
*prd
, /* RD */
1667 struct bgp_table
*table_rd
, /* per-rd VPN route table */
1668 struct prefix
*prefix
, /* VPN prefix */
1669 struct bgp_info
*bi
) /* old VPN host route */
1671 afi_t afi
= family2afi (prefix
->family
);
1672 struct skiplist
*sl
= NULL
;
1673 struct prefix_bag
*pb
;
1675 struct rfapi_cfg
*hc
= NULL
;
1679 char str_pfx
[BUFSIZ
];
1681 prefix2str (prefix
, str_pfx
, BUFSIZ
);
1682 str_pfx
[BUFSIZ
- 1] = 0;
1684 vnc_zlog_debug_verbose ("%s(bgp=%p, nve prefix=%s)", __func__
, bgp
, str_pfx
);
1687 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
1690 if (!(hc
= bgp
->rfapi_cfg
))
1692 vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
1696 /* check vnc redist flag for bgp direct routes */
1697 if (!hc
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
1699 vnc_zlog_debug_verbose
1700 ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping",
1705 if (hc
->redist_mode
!= VNC_REDIST_MODE_RESOLVE_NVE
)
1707 vnc_zlog_debug_verbose ("%s: not in resolve-nve mode, skipping", __func__
);
1711 if (bgp
&& bgp
->rfapi
)
1712 sl
= bgp
->rfapi
->resolve_nve_nexthop
;
1716 vnc_zlog_debug_verbose ("%s: no RHN entries, skipping", __func__
);
1720 if (!is_host_prefix (prefix
))
1722 vnc_zlog_debug_verbose ("%s: not host route, skip", __func__
);
1727 * Find all entries with key == CE in the RHN list
1729 rc
= skiplist_first_value (sl
, prefix
, (void *) &pb
, &cursor
);
1733 struct ecommunity
*ecom
;
1734 struct prefix pfx_unicast_nexthop
;
1736 memset (&pfx_unicast_nexthop
, 0, sizeof (struct prefix
)); /* keep valgrind happy */
1738 if (process_unicast_route (bgp
, afi
, &pb
->upfx
, pb
->ubi
,
1739 &ecom
, &pfx_unicast_nexthop
))
1742 vnc_zlog_debug_verbose ("%s: process_unicast_route error, skipping", __func__
);
1749 if (vnc_prefix_cmp (&pfx_unicast_nexthop
, prefix
))
1751 char str_unh
[BUFSIZ
];
1752 char str_nve_pfx
[BUFSIZ
];
1754 prefix2str (&pfx_unicast_nexthop
, str_unh
, BUFSIZ
);
1755 str_unh
[BUFSIZ
- 1] = 0;
1757 prefix2str (prefix
, str_nve_pfx
, BUFSIZ
);
1758 str_nve_pfx
[BUFSIZ
- 1] = 0;
1760 vnc_zlog_debug_verbose
1761 ("%s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s",
1762 __func__
, str_unh
, str_nve_pfx
);
1766 vnc_import_bgp_del_route_mode_resolve_nve_one_bi (bgp
,
1768 bi
, prd
, &pb
->upfx
);
1771 ecommunity_free (&ecom
);
1773 rc
= skiplist_next_value (sl
, prefix
, (void *) &pb
, &cursor
);
1778 /***********************************************************************
1780 ***********************************************************************/
1782 #define DEBUG_IS_USABLE_INTERIOR 1
1785 is_usable_interior_route (struct bgp_info
*bi_interior
)
1787 if (!VALID_INTERIOR_TYPE (bi_interior
->type
))
1789 #if DEBUG_IS_USABLE_INTERIOR
1790 vnc_zlog_debug_verbose ("%s: NO: type %d is not valid interior type",
1791 __func__
, bi_interior
->type
);
1795 if (!CHECK_FLAG (bi_interior
->flags
, BGP_INFO_VALID
))
1797 #if DEBUG_IS_USABLE_INTERIOR
1798 vnc_zlog_debug_verbose ("%s: NO: BGP_INFO_VALID not set", __func__
);
1806 * There should be only one of these per prefix at a time.
1807 * This should be called as a result of selection operation
1809 * NB should be called espacially for bgp instances that are named,
1810 * because the exterior routes will always come from one of those.
1811 * We filter here on the instance name to make sure we get only the
1815 vnc_import_bgp_exterior_add_route_it (
1816 struct bgp
*bgp
, /* exterior instance, we hope */
1817 struct prefix
*prefix
,/* unicast prefix */
1818 struct bgp_info
*info
, /* unicast info */
1819 struct rfapi_import_table
*it_only
)/* NULL, or limit to this IT */
1822 struct rfapi_cfg
*hc
;
1823 struct prefix pfx_orig_nexthop
;
1824 struct rfapi_import_table
*it
;
1825 struct bgp
*bgp_default
= bgp_get_default ();
1826 afi_t afi
= family2afi (prefix
->family
);
1831 h
= bgp_default
->rfapi
;
1832 hc
= bgp_default
->rfapi_cfg
;
1834 vnc_zlog_debug_verbose ("%s: entry with it=%p", __func__
, it_only
);
1838 vnc_zlog_debug_verbose ("%s: rfapi or rfapi_cfg not instantiated, skipping",
1842 if (!hc
->redist_bgp_exterior_view
)
1844 vnc_zlog_debug_verbose ("%s: exterior view not set, skipping", __func__
);
1847 if (bgp
!= hc
->redist_bgp_exterior_view
)
1849 vnc_zlog_debug_verbose ("%s: bgp %p != hc->redist_bgp_exterior_view %p, skipping",
1850 __func__
, bgp
, hc
->redist_bgp_exterior_view
);
1854 if (!hc
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
])
1856 vnc_zlog_debug_verbose ("%s: redist of exterior routes not enabled, skipping",
1863 vnc_zlog_debug_verbose ("%s: no info, skipping", __func__
);
1868 * Extract nexthop from exterior route
1870 * Incoming prefix is unicast. If v6, it is in multiprotocol area,
1871 * but if v4 it is in attr->nexthop
1873 rfapiUnicastNexthop2Prefix (afi
, info
->attr
, &pfx_orig_nexthop
);
1875 for (it
= h
->imports
; it
; it
= it
->next
)
1877 struct route_table
*table
;
1878 struct route_node
*rn
;
1879 struct route_node
*par
;
1880 struct bgp_info
*bi_interior
;
1881 int have_usable_route
;
1883 vnc_zlog_debug_verbose ("%s: doing it %p", __func__
, it
);
1885 if (it_only
&& (it_only
!= it
))
1887 vnc_zlog_debug_verbose ("%s: doesn't match it_only %p", __func__
, it_only
);
1891 table
= it
->imported_vpn
[afi
];
1893 for (rn
= route_node_match (table
, &pfx_orig_nexthop
),
1894 have_usable_route
= 0; (!have_usable_route
) && rn
;)
1897 vnc_zlog_debug_verbose ("%s: it %p trying rn %p", __func__
, it
, rn
);
1899 for (bi_interior
= rn
->info
; bi_interior
;
1900 bi_interior
= bi_interior
->next
)
1902 struct prefix_rd
*prd
;
1903 struct attr new_attr
;
1904 u_int32_t label
= 0;
1906 if (!is_usable_interior_route (bi_interior
))
1909 vnc_zlog_debug_verbose ("%s: usable: bi_interior %p", __func__
,
1913 * have a legitimate route to exterior's nexthop
1916 * Import unicast route to the import table
1918 have_usable_route
= 1;
1920 if (bi_interior
->extra
)
1922 prd
= &bi_interior
->extra
->vnc
.import
.rd
;
1923 label
= decode_label (bi_interior
->extra
->tag
);
1928 /* use local_pref from unicast route */
1929 memset (&new_attr
, 0, sizeof (struct attr
));
1930 bgp_attr_dup (&new_attr
, bi_interior
->attr
);
1931 if (info
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
1933 new_attr
.local_pref
= info
->attr
->local_pref
;
1934 new_attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
1937 rfapiBgpInfoFilteredImportVPN (it
, FIF_ACTION_UPDATE
, bi_interior
->peer
, NULL
, /* rfd */
1943 ZEBRA_ROUTE_BGP_DIRECT_EXT
,
1944 BGP_ROUTE_REDISTRIBUTE
, &label
);
1946 bgp_attr_extra_free (&new_attr
);
1949 if (have_usable_route
)
1954 * TBD factor this out into its own function
1956 struct prefix
*pfx_mon
= prefix_new ();
1957 if (!RFAPI_MONITOR_EXTERIOR (rn
)->source
)
1959 RFAPI_MONITOR_EXTERIOR (rn
)->source
=
1960 skiplist_new (0, NULL
, (void (*)(void *)) prefix_free
);
1961 route_lock_node (rn
); /* for skiplist */
1963 route_lock_node (rn
); /* for skiplist entry */
1964 prefix_copy (pfx_mon
, prefix
);
1965 if (!skiplist_insert (RFAPI_MONITOR_EXTERIOR (rn
)->source
,
1969 bgp_info_lock (info
);
1974 route_lock_node (par
);
1975 route_unlock_node (rn
);
1979 route_unlock_node (rn
);
1981 if (!have_usable_route
)
1983 struct prefix
*pfx_mon
= prefix_new ();
1984 prefix_copy (pfx_mon
, prefix
);
1985 if (!skiplist_insert (it
->monitor_exterior_orphans
, info
, pfx_mon
))
1988 bgp_info_lock (info
);
1995 vnc_import_bgp_exterior_add_route (
1996 struct bgp
*bgp
, /* exterior instance, we hope */
1997 struct prefix
*prefix
,/* unicast prefix */
1998 struct bgp_info
*info
) /* unicast info */
2000 vnc_import_bgp_exterior_add_route_it (bgp
, prefix
, info
, NULL
);
2004 * There should be only one of these per prefix at a time.
2005 * This should probably be called as a result of selection operation.
2007 * NB should be called espacially for bgp instances that are named,
2008 * because the exterior routes will always come from one of those.
2009 * We filter here on the instance name to make sure we get only the
2013 vnc_import_bgp_exterior_del_route (
2015 struct prefix
*prefix
, /* unicast prefix */
2016 struct bgp_info
*info
) /* unicast info */
2019 struct rfapi_cfg
*hc
;
2020 struct rfapi_import_table
*it
;
2021 struct prefix pfx_orig_nexthop
;
2022 afi_t afi
= family2afi (prefix
->family
);
2023 struct bgp
*bgp_default
= bgp_get_default ();
2028 memset (&pfx_orig_nexthop
, 0, sizeof (struct prefix
)); /* keep valgrind happy */
2030 h
= bgp_default
->rfapi
;
2031 hc
= bgp_default
->rfapi_cfg
;
2035 vnc_zlog_debug_verbose ("%s: rfapi or rfapi_cfg not instantiated, skipping",
2039 if (!hc
->redist_bgp_exterior_view
)
2041 vnc_zlog_debug_verbose ("%s: exterior view not set, skipping", __func__
);
2044 if (bgp
!= hc
->redist_bgp_exterior_view
)
2046 vnc_zlog_debug_verbose ("%s: bgp %p != hc->redist_bgp_exterior_view %p, skipping",
2047 __func__
, bgp
, hc
->redist_bgp_exterior_view
);
2050 if (!hc
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
])
2052 vnc_zlog_debug_verbose ("%s: redist of exterior routes no enabled, skipping",
2059 vnc_zlog_debug_verbose ("%s: no info, skipping", __func__
);
2064 * Extract nexthop from exterior route
2066 * Incoming prefix is unicast. If v6, it is in multiprotocol area,
2067 * but if v4 it is in attr->nexthop
2069 rfapiUnicastNexthop2Prefix (afi
, info
->attr
, &pfx_orig_nexthop
);
2071 for (it
= h
->imports
; it
; it
= it
->next
)
2073 struct route_table
*table
;
2074 struct route_node
*rn
;
2075 struct route_node
*par
;
2076 struct bgp_info
*bi_interior
;
2077 int have_usable_route
;
2079 table
= it
->imported_vpn
[afi
];
2081 for (rn
= route_node_match (table
, &pfx_orig_nexthop
),
2082 have_usable_route
= 0; (!have_usable_route
) && rn
;)
2085 for (bi_interior
= rn
->info
; bi_interior
;
2086 bi_interior
= bi_interior
->next
)
2088 struct prefix_rd
*prd
;
2089 u_int32_t label
= 0;
2091 if (!is_usable_interior_route (bi_interior
))
2095 * have a legitimate route to exterior's nexthop
2098 * Import unicast route to the import table
2100 have_usable_route
= 1;
2102 if (bi_interior
->extra
)
2104 prd
= &bi_interior
->extra
->vnc
.import
.rd
;
2105 label
= decode_label (bi_interior
->extra
->tag
);
2110 rfapiBgpInfoFilteredImportVPN (it
, FIF_ACTION_KILL
, bi_interior
->peer
, NULL
, /* rfd */
2116 ZEBRA_ROUTE_BGP_DIRECT_EXT
,
2117 BGP_ROUTE_REDISTRIBUTE
, &label
);
2122 * TBD factor this out into its own function
2125 if (RFAPI_MONITOR_EXTERIOR (rn
)->source
)
2127 if (!skiplist_delete (RFAPI_MONITOR_EXTERIOR (rn
)->source
,
2131 bgp_info_unlock (info
);
2132 route_unlock_node (rn
); /* sl entry */
2134 if (skiplist_empty (RFAPI_MONITOR_EXTERIOR (rn
)->source
))
2136 skiplist_free (RFAPI_MONITOR_EXTERIOR (rn
)->source
);
2137 RFAPI_MONITOR_EXTERIOR (rn
)->source
= NULL
;
2138 route_unlock_node (rn
); /* skiplist itself */
2145 route_lock_node (par
);
2146 route_unlock_node (rn
);
2150 route_unlock_node (rn
);
2152 if (!have_usable_route
)
2154 if (!skiplist_delete (it
->monitor_exterior_orphans
, info
, NULL
))
2157 bgp_info_unlock (info
);
2164 * This function should be called after a new interior VPN route
2165 * has been added to an import_table.
2167 * NB should also be called whenever an existing vpn interior route
2168 * becomes valid (e.g., valid_interior_count is inremented)
2171 vnc_import_bgp_exterior_add_route_interior (
2173 struct rfapi_import_table
*it
,
2174 struct route_node
*rn_interior
, /* VPN IT node */
2175 struct bgp_info
*bi_interior
) /* VPN IT route */
2177 afi_t afi
= family2afi (rn_interior
->p
.family
);
2178 struct route_node
*par
;
2179 struct bgp_info
*bi_exterior
;
2180 struct prefix
*pfx_exterior
; /* exterior pfx */
2183 struct list
*list_adopted
;
2185 vnc_zlog_debug_verbose ("%s: entry", __func__
);
2187 if (!is_usable_interior_route (bi_interior
))
2189 vnc_zlog_debug_verbose ("%s: not usable interior route, skipping", __func__
);
2193 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
])
2195 vnc_zlog_debug_verbose ("%s: redist of exterior routes no enabled, skipping",
2200 if (it
== bgp
->rfapi
->it_ce
)
2202 vnc_zlog_debug_verbose ("%s: import table is it_ce, skipping", __func__
);
2208 char str_pfx
[BUFSIZ
];
2210 prefix2str (&rn_interior
->p
, str_pfx
, BUFSIZ
);
2211 str_pfx
[BUFSIZ
- 1] = 0;
2213 vnc_zlog_debug_verbose ("%s: interior prefix=%s, bi type=%d",
2214 __func__
, str_pfx
, bi_interior
->type
);
2217 if (RFAPI_HAS_MONITOR_EXTERIOR (rn_interior
))
2220 int count
= 0; /* debugging */
2222 vnc_zlog_debug_verbose ("%s: has exterior monitor; ext src: %p", __func__
,
2223 RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
);
2226 * There is a monitor here already. Therefore, we do not need
2227 * to do any pulldown. Just construct exterior routes based
2228 * on the new interior route.
2231 for (rc
= skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2232 (void **) &bi_exterior
,
2233 (void **) &pfx_exterior
, &cursor
); !rc
;
2235 skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2236 (void **) &bi_exterior
, (void **) &pfx_exterior
,
2240 struct prefix_rd
*prd
;
2241 struct attr new_attr
;
2242 u_int32_t label
= 0;
2245 ++count
; /* debugging */
2247 assert (bi_exterior
);
2248 assert (pfx_exterior
);
2250 if (bi_interior
->extra
)
2252 prd
= &bi_interior
->extra
->vnc
.import
.rd
;
2253 label
= decode_label (bi_interior
->extra
->tag
);
2258 /* use local_pref from unicast route */
2259 memset (&new_attr
, 0, sizeof (struct attr
));
2260 bgp_attr_dup (&new_attr
, bi_interior
->attr
);
2262 (bi_exterior
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
)))
2264 new_attr
.local_pref
= bi_exterior
->attr
->local_pref
;
2265 new_attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
2268 rfapiBgpInfoFilteredImportVPN (it
, FIF_ACTION_UPDATE
, bi_interior
->peer
, NULL
, /* rfd */
2274 ZEBRA_ROUTE_BGP_DIRECT_EXT
,
2275 BGP_ROUTE_REDISTRIBUTE
, &label
);
2277 bgp_attr_extra_free (&new_attr
);
2279 vnc_zlog_debug_verbose
2280 ("%s: finished constructing exteriors based on existing monitors",
2285 vnc_zlog_debug_verbose ("%s: no exterior monitor", __func__
);
2288 * No monitor at this node. Is this the first valid interior
2289 * route at this node?
2291 if (RFAPI_MONITOR_EXTERIOR (rn_interior
)->valid_interior_count
> 1)
2293 vnc_zlog_debug_verbose
2294 ("%s: new interior route not first valid one, skipping pulldown",
2300 * Look up the tree for possible pulldown candidates.
2301 * Find nearest parent with an exterior route monitor
2303 for (par
= rn_interior
->parent
; par
; par
= par
->parent
)
2305 if (RFAPI_HAS_MONITOR_EXTERIOR (par
))
2312 vnc_zlog_debug_verbose ("%s: checking parent %p for possible pulldowns",
2315 /* check monitors at par for possible pulldown */
2317 for (rc
= skiplist_next (RFAPI_MONITOR_EXTERIOR (par
)->source
,
2318 (void **) &bi_exterior
,
2319 (void **) &pfx_exterior
, &cursor
); !rc
;
2321 skiplist_next (RFAPI_MONITOR_EXTERIOR (par
)->source
,
2322 (void **) &bi_exterior
, (void **) &pfx_exterior
,
2326 struct prefix pfx_nexthop
;
2328 memset (&pfx_nexthop
, 0, sizeof (struct prefix
)); /* keep valgrind happy */
2330 /* check original nexthop for prefix match */
2331 rfapiUnicastNexthop2Prefix (afi
, bi_exterior
->attr
, &pfx_nexthop
);
2333 if (prefix_match (&rn_interior
->p
, &pfx_nexthop
))
2336 struct bgp_info
*bi
;
2337 struct prefix_rd
*prd
;
2338 struct attr new_attr
;
2339 u_int32_t label
= 0;
2344 * add monitor to longer prefix
2346 struct prefix
*pfx_mon
= prefix_new ();
2347 prefix_copy (pfx_mon
, pfx_exterior
);
2348 if (!RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
)
2350 RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
=
2351 skiplist_new (0, NULL
, (void (*)(void *)) prefix_free
);
2352 route_lock_node (rn_interior
);
2354 skiplist_insert (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2355 bi_exterior
, pfx_mon
);
2356 route_lock_node (rn_interior
);
2359 * Delete constructed exterior routes based on
2362 for (bi
= par
->info
; bi
; bi
= bi
->next
)
2367 prd
= &bi
->extra
->vnc
.import
.rd
;
2368 label
= decode_label (bi
->extra
->tag
);
2373 rfapiBgpInfoFilteredImportVPN (it
, FIF_ACTION_KILL
, bi
->peer
, NULL
, /* rfd */
2379 ZEBRA_ROUTE_BGP_DIRECT_EXT
,
2380 BGP_ROUTE_REDISTRIBUTE
,
2386 * Add constructed exterior routes based on
2387 * the new interior route at longer prefix.
2389 if (bi_interior
->extra
)
2391 prd
= &bi_interior
->extra
->vnc
.import
.rd
;
2392 label
= decode_label (bi_interior
->extra
->tag
);
2397 /* use local_pref from unicast route */
2398 memset (&new_attr
, 0, sizeof (struct attr
));
2399 bgp_attr_dup (&new_attr
, bi_interior
->attr
);
2401 (bi_exterior
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
)))
2403 new_attr
.local_pref
= bi_exterior
->attr
->local_pref
;
2404 new_attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
2407 rfapiBgpInfoFilteredImportVPN (it
, FIF_ACTION_UPDATE
, bi_interior
->peer
, NULL
, /* rfd */
2413 ZEBRA_ROUTE_BGP_DIRECT_EXT
,
2414 BGP_ROUTE_REDISTRIBUTE
, &label
);
2416 bgp_attr_extra_free (&new_attr
);
2421 * The only monitors at rn_interior are the ones we added just
2422 * above, so we can use the rn_interior list to identify which
2423 * monitors to delete from the parent.
2426 for (rc
= skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2427 (void **) &bi_exterior
, NULL
, &cursor
);
2429 rc
= skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2430 (void **) &bi_exterior
, NULL
, &cursor
))
2434 skiplist_delete (RFAPI_MONITOR_EXTERIOR (par
)->source
,
2436 route_unlock_node (par
); /* sl entry */
2438 if (skiplist_empty (RFAPI_MONITOR_EXTERIOR (par
)->source
))
2440 skiplist_free (RFAPI_MONITOR_EXTERIOR (par
)->source
);
2441 RFAPI_MONITOR_EXTERIOR (par
)->source
= NULL
;
2442 route_unlock_node (par
); /* sl itself */
2446 vnc_zlog_debug_verbose ("%s: checking orphans", __func__
);
2449 * See if any orphans can be pulled down to the current node
2452 list_adopted
= NULL
;
2453 for (rc
= skiplist_next (it
->monitor_exterior_orphans
,
2454 (void **) &bi_exterior
, (void **) &pfx_exterior
,
2457 skiplist_next (it
->monitor_exterior_orphans
, (void **) &bi_exterior
,
2458 (void **) &pfx_exterior
, &cursor
))
2461 struct prefix pfx_nexthop
;
2463 afi_t afi_exterior
= family2afi (pfx_exterior
->family
);
2465 prefix2str (pfx_exterior
, buf
, sizeof (buf
));
2466 buf
[sizeof (buf
) - 1] = 0;
2467 vnc_zlog_debug_verbose ("%s: checking exterior orphan at prefix %s", __func__
, buf
);
2469 if (afi_exterior
!= afi
)
2471 vnc_zlog_debug_verbose ("%s: exterior orphan afi %d != interior afi %d, skip",
2472 __func__
, afi_exterior
, afi
);
2476 /* check original nexthop for prefix match */
2477 rfapiUnicastNexthop2Prefix (afi
, bi_exterior
->attr
, &pfx_nexthop
);
2479 if (prefix_match (&rn_interior
->p
, &pfx_nexthop
))
2482 struct prefix_rd
*prd
;
2483 struct attr new_attr
;
2484 u_int32_t label
= 0;
2489 * add monitor to longer prefix
2492 struct prefix
*pfx_mon
= prefix_new ();
2493 prefix_copy (pfx_mon
, pfx_exterior
);
2494 if (!RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
)
2496 RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
=
2497 skiplist_new (0, NULL
, (void (*)(void *)) prefix_free
);
2498 route_lock_node (rn_interior
); /* sl */
2500 skiplist_insert (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2501 bi_exterior
, pfx_mon
);
2502 route_lock_node (rn_interior
); /* sl entry */
2505 list_adopted
= list_new ();
2507 listnode_add (list_adopted
, bi_exterior
);
2510 * Add constructed exterior routes based on the
2511 * new interior route at the longer prefix.
2513 if (bi_interior
->extra
)
2515 prd
= &bi_interior
->extra
->vnc
.import
.rd
;
2516 label
= decode_label (bi_interior
->extra
->tag
);
2521 /* use local_pref from unicast route */
2522 memset (&new_attr
, 0, sizeof (struct attr
));
2523 bgp_attr_dup (&new_attr
, bi_interior
->attr
);
2525 (bi_exterior
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
)))
2527 new_attr
.local_pref
= bi_exterior
->attr
->local_pref
;
2528 new_attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
2531 rfapiBgpInfoFilteredImportVPN (it
, FIF_ACTION_UPDATE
, bi_interior
->peer
, NULL
, /* rfd */
2537 ZEBRA_ROUTE_BGP_DIRECT_EXT
,
2538 BGP_ROUTE_REDISTRIBUTE
, &label
);
2540 bgp_attr_extra_free (&new_attr
);
2545 struct listnode
*node
;
2546 struct route_node
*bi_exterior
;
2548 for (ALL_LIST_ELEMENTS_RO (list_adopted
, node
, bi_exterior
))
2550 skiplist_delete (it
->monitor_exterior_orphans
, bi_exterior
, NULL
);
2552 list_delete (list_adopted
);
2557 * This function should be called after an interior VPN route
2558 * has been deleted from an import_table.
2559 * bi_interior must still be valid, but it must already be detached
2560 * from its route node and the route node's valid_interior_count
2561 * must already be decremented.
2563 * NB should also be called whenever an existing vpn interior route
2564 * becomes invalid (e.g., valid_interior_count is decremented)
2567 vnc_import_bgp_exterior_del_route_interior (
2569 struct rfapi_import_table
*it
,
2570 struct route_node
*rn_interior
, /* VPN IT node */
2571 struct bgp_info
*bi_interior
) /* VPN IT route */
2573 afi_t afi
= family2afi (rn_interior
->p
.family
);
2574 struct route_node
*par
;
2575 struct bgp_info
*bi_exterior
;
2576 struct prefix
*pfx_exterior
; /* exterior pfx */
2580 if (!VALID_INTERIOR_TYPE (bi_interior
->type
))
2582 vnc_zlog_debug_verbose ("%s: type %d not valid interior type, skipping",
2583 __func__
, bi_interior
->type
);
2587 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
])
2589 vnc_zlog_debug_verbose ("%s: redist of exterior routes no enabled, skipping",
2594 if (it
== bgp
->rfapi
->it_ce
)
2596 vnc_zlog_debug_verbose ("%s: it is it_ce, skipping", __func__
);
2600 /* If no exterior routes depend on this prefix, nothing to do */
2601 if (!RFAPI_HAS_MONITOR_EXTERIOR (rn_interior
))
2603 vnc_zlog_debug_verbose ("%s: no exterior monitor, skipping", __func__
);
2609 char str_pfx
[BUFSIZ
];
2611 prefix2str (&rn_interior
->p
, str_pfx
, BUFSIZ
);
2612 str_pfx
[BUFSIZ
- 1] = 0;
2614 vnc_zlog_debug_verbose ("%s: interior prefix=%s, bi type=%d",
2615 __func__
, str_pfx
, bi_interior
->type
);
2619 * Remove constructed routes based on the deleted interior route
2622 for (rc
= skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2623 (void **) &bi_exterior
, (void **) &pfx_exterior
,
2626 skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2627 (void **) &bi_exterior
, (void **) &pfx_exterior
,
2631 struct prefix_rd
*prd
;
2632 u_int32_t label
= 0;
2634 if (bi_interior
->extra
)
2636 prd
= &bi_interior
->extra
->vnc
.import
.rd
;
2637 label
= decode_label (bi_interior
->extra
->tag
);
2642 rfapiBgpInfoFilteredImportVPN (it
, FIF_ACTION_KILL
, bi_interior
->peer
, NULL
, /* rfd */
2648 ZEBRA_ROUTE_BGP_DIRECT_EXT
,
2649 BGP_ROUTE_REDISTRIBUTE
, &label
);
2653 * If there are no remaining valid interior routes at this prefix,
2654 * we need to look up the tree for a possible node to move monitors to
2656 if (RFAPI_MONITOR_EXTERIOR (rn_interior
)->valid_interior_count
)
2658 vnc_zlog_debug_verbose ("%s: interior routes still present, skipping", __func__
);
2663 * Find nearest parent with at least one valid interior route
2664 * If none is found, par will end up NULL, and we will move
2665 * the monitors to the orphan list for this import table
2667 for (par
= rn_interior
->parent
; par
; par
= par
->parent
)
2669 if (RFAPI_MONITOR_EXTERIOR (par
)->valid_interior_count
)
2673 vnc_zlog_debug_verbose ("%s: par=%p, ext src: %p", __func__
,
2674 par
, RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
);
2676 /* move all monitors */
2678 * We will use and delete every element of the source skiplist
2680 while (!skiplist_first (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2681 (void **) &bi_exterior
, (void **) &pfx_exterior
))
2684 struct prefix
*pfx_mon
= prefix_new ();
2686 prefix_copy (pfx_mon
, pfx_exterior
);
2691 struct bgp_info
*bi
;
2694 * Add monitor to parent node
2696 if (!RFAPI_MONITOR_EXTERIOR (par
)->source
)
2698 RFAPI_MONITOR_EXTERIOR (par
)->source
=
2699 skiplist_new (0, NULL
, (void (*)(void *)) prefix_free
);
2700 route_lock_node (par
); /* sl */
2702 skiplist_insert (RFAPI_MONITOR_EXTERIOR (par
)->source
,
2703 bi_exterior
, pfx_mon
);
2704 route_lock_node (par
); /* sl entry */
2706 /* Add constructed exterior routes based on parent */
2707 for (bi
= par
->info
; bi
; bi
= bi
->next
)
2710 struct prefix_rd
*prd
;
2711 struct attr new_attr
;
2712 u_int32_t label
= 0;
2714 if (bi
->type
== ZEBRA_ROUTE_BGP_DIRECT_EXT
)
2719 prd
= &bi
->extra
->vnc
.import
.rd
;
2720 label
= decode_label (bi
->extra
->tag
);
2725 /* use local_pref from unicast route */
2726 memset (&new_attr
, 0, sizeof (struct attr
));
2727 bgp_attr_dup (&new_attr
, bi
->attr
);
2729 (bi_exterior
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
)))
2731 new_attr
.local_pref
= bi_exterior
->attr
->local_pref
;
2732 new_attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
2735 rfapiBgpInfoFilteredImportVPN (it
, FIF_ACTION_UPDATE
, bi
->peer
, NULL
, /* rfd */
2741 ZEBRA_ROUTE_BGP_DIRECT_EXT
,
2742 BGP_ROUTE_REDISTRIBUTE
, &label
);
2744 bgp_attr_extra_free (&new_attr
);
2752 * No interior route for exterior's nexthop. Save monitor
2753 * in orphan list to await future route.
2755 skiplist_insert (it
->monitor_exterior_orphans
,
2756 bi_exterior
, pfx_mon
);
2759 skiplist_delete_first (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
);
2760 route_unlock_node (rn_interior
); /* sl entry */
2762 if (skiplist_empty (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
))
2764 skiplist_free (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
);
2765 RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
= NULL
;
2766 route_unlock_node (rn_interior
); /* sl itself */
2771 /***********************************************************************
2772 * Generic add/delete unicast routes
2773 ***********************************************************************/
2776 vnc_import_bgp_add_route (
2778 struct prefix
*prefix
,
2779 struct bgp_info
*info
)
2781 afi_t afi
= family2afi (prefix
->family
);
2784 struct prefix pfx_nexthop
;
2786 char buf_nh
[BUFSIZ
];
2788 prefix2str (prefix
, buf
, BUFSIZ
);
2789 rfapiUnicastNexthop2Prefix (afi
, info
->attr
, &pfx_nexthop
);
2790 prefix2str (&pfx_nexthop
, buf_nh
, BUFSIZ
);
2792 vnc_zlog_debug_verbose ("%s: pfx %s, nh %s", __func__
, buf
, buf_nh
);
2795 print_rhn_list(__func__
, "ENTER ");
2801 zlog_err ("%s: can't get afi of prefix", __func__
);
2805 if (!bgp
->rfapi_cfg
)
2807 vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
2811 /* check vnc redist flag for bgp direct routes */
2812 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
2814 vnc_zlog_debug_verbose
2815 ("%s: bgp->rfapi_cfg->redist[afi=%d][type=%d=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping",
2816 __func__
, afi
, ZEBRA_ROUTE_BGP_DIRECT
);
2820 switch (bgp
->rfapi_cfg
->redist_mode
)
2822 case VNC_REDIST_MODE_PLAIN
:
2823 vnc_import_bgp_add_route_mode_plain (bgp
, prefix
, info
);
2826 case VNC_REDIST_MODE_RFG
:
2827 if (bgp
->rfapi_cfg
->rfg_redist
)
2828 vnc_import_bgp_add_route_mode_nvegroup (bgp
, prefix
, info
,
2829 bgp
->rfapi_cfg
->rfg_redist
);
2831 vnc_zlog_debug_verbose ("%s: mode RFG but no redist RFG", __func__
);
2834 case VNC_REDIST_MODE_RESOLVE_NVE
:
2835 vnc_import_bgp_add_route_mode_resolve_nve (bgp
, prefix
, info
);
2839 print_rhn_list(__func__
, "LEAVE ");
2845 * "Withdrawing a Route" import process
2848 vnc_import_bgp_del_route (
2850 struct prefix
*prefix
,
2851 struct bgp_info
*info
) /* unicast info */
2853 afi_t afi
= family2afi (prefix
->family
);
2858 struct prefix pfx_nexthop
;
2860 char buf_nh
[BUFSIZ
];
2862 prefix2str (prefix
, buf
, BUFSIZ
);
2863 rfapiUnicastNexthop2Prefix (afi
, info
->attr
, &pfx_nexthop
);
2864 prefix2str (&pfx_nexthop
, buf_nh
, BUFSIZ
);
2866 vnc_zlog_debug_verbose ("%s: pfx %s, nh %s", __func__
, buf
, buf_nh
);
2869 print_rhn_list(__func__
, "ENTER ");
2873 if (!bgp
->rfapi_cfg
)
2875 vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
2879 /* check bgp redist flag for vnc direct ("vpn") routes */
2880 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
2882 vnc_zlog_debug_verbose ("%s: bgp redistribution of afi=%d VNC direct routes is off",
2887 switch (bgp
->rfapi_cfg
->redist_mode
)
2889 case VNC_REDIST_MODE_PLAIN
:
2890 vnc_import_bgp_del_route_mode_plain (bgp
, prefix
, info
);
2893 case VNC_REDIST_MODE_RFG
:
2894 if (bgp
->rfapi_cfg
->rfg_redist
)
2895 vnc_import_bgp_del_route_mode_nvegroup (bgp
, prefix
, info
);
2897 vnc_zlog_debug_verbose ("%s: mode RFG but no redist RFG", __func__
);
2900 case VNC_REDIST_MODE_RESOLVE_NVE
:
2901 vnc_import_bgp_del_route_mode_resolve_nve (bgp
, afi
, prefix
, info
);
2906 print_rhn_list(__func__
, "LEAVE ");
2912 /***********************************************************************
2914 ***********************************************************************/
2917 vnc_import_bgp_redist_enable (struct bgp
*bgp
, afi_t afi
)
2919 /* iterate over bgp unicast v4 and v6 routes, call vnc_import_bgp_add_route */
2921 struct bgp_node
*rn
;
2923 vnc_zlog_debug_verbose ("%s: entry, afi=%d", __func__
, afi
);
2925 if (bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
2927 vnc_zlog_debug_verbose ("%s: already enabled for afi %d, skipping", __func__
, afi
);
2930 bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
] = 1;
2932 for (rn
= bgp_table_top (bgp
->rib
[afi
][SAFI_UNICAST
]);
2933 rn
; rn
= bgp_route_next (rn
))
2936 struct bgp_info
*bi
;
2938 for (bi
= rn
->info
; bi
; bi
= bi
->next
)
2941 if (CHECK_FLAG (bi
->flags
, BGP_INFO_REMOVED
))
2944 vnc_import_bgp_add_route (bgp
, &rn
->p
, bi
);
2947 vnc_zlog_debug_verbose ("%s: set redist[afi=%d][type=%d=ZEBRA_ROUTE_BGP_DIRECT] return",
2948 __func__
, afi
, ZEBRA_ROUTE_BGP_DIRECT
);
2952 vnc_import_bgp_exterior_redist_enable (struct bgp
*bgp
, afi_t afi
)
2954 struct bgp
*bgp_exterior
;
2955 struct bgp_node
*rn
;
2957 bgp_exterior
= bgp
->rfapi_cfg
->redist_bgp_exterior_view
;
2959 if (bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
])
2961 vnc_zlog_debug_verbose ("%s: already enabled for afi %d, skipping", __func__
, afi
);
2964 bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
] = 1;
2968 vnc_zlog_debug_verbose ("%s: no exterior view set yet, no routes to import yet",
2973 for (rn
= bgp_table_top (bgp_exterior
->rib
[afi
][SAFI_UNICAST
]);
2974 rn
; rn
= bgp_route_next (rn
))
2977 struct bgp_info
*bi
;
2979 for (bi
= rn
->info
; bi
; bi
= bi
->next
)
2982 if (CHECK_FLAG (bi
->flags
, BGP_INFO_REMOVED
))
2985 vnc_import_bgp_exterior_add_route (bgp_exterior
, &rn
->p
, bi
);
2988 vnc_zlog_debug_verbose ("%s: set redist[afi=%d][type=%d=ZEBRA_ROUTE_BGP_DIRECT] return",
2989 __func__
, afi
, ZEBRA_ROUTE_BGP_DIRECT
);
2994 * This function is for populating a newly-created Import Table
2997 vnc_import_bgp_exterior_redist_enable_it (
3000 struct rfapi_import_table
*it_only
)
3002 struct bgp
*bgp_exterior
;
3003 struct bgp_node
*rn
;
3005 vnc_zlog_debug_verbose ("%s: entry", __func__
);
3007 bgp_exterior
= bgp
->rfapi_cfg
->redist_bgp_exterior_view
;
3009 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
])
3011 vnc_zlog_debug_verbose ("%s: not enabled for afi %d, skipping", __func__
, afi
);
3017 vnc_zlog_debug_verbose ("%s: no exterior view set yet, no routes to import yet",
3022 for (rn
= bgp_table_top (bgp_exterior
->rib
[afi
][SAFI_UNICAST
]);
3023 rn
; rn
= bgp_route_next (rn
))
3026 struct bgp_info
*bi
;
3028 for (bi
= rn
->info
; bi
; bi
= bi
->next
)
3031 if (CHECK_FLAG (bi
->flags
, BGP_INFO_REMOVED
))
3034 vnc_import_bgp_exterior_add_route_it (bgp_exterior
, &rn
->p
, bi
,
3043 vnc_import_bgp_redist_disable (struct bgp
*bgp
, afi_t afi
)
3046 * iterate over vpn routes, find routes of type ZEBRA_ROUTE_BGP_DIRECT,
3047 * delete (call timer expire immediately)
3049 struct bgp_node
*rn1
;
3050 struct bgp_node
*rn2
;
3052 vnc_zlog_debug_verbose ("%s: entry", __func__
);
3054 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
3056 vnc_zlog_debug_verbose ("%s: already disabled for afi %d, skipping", __func__
, afi
);
3061 * Two-level table for SAFI_MPLS_VPN
3062 * Be careful when changing the things we iterate over
3064 for (rn1
= bgp_table_top (bgp
->rib
[afi
][SAFI_MPLS_VPN
]);
3065 rn1
; rn1
= bgp_route_next (rn1
))
3070 for (rn2
= bgp_table_top (rn1
->info
);
3071 rn2
; rn2
= bgp_route_next (rn2
))
3074 struct bgp_info
*bi
;
3075 struct bgp_info
*nextbi
;
3077 for (bi
= rn2
->info
; bi
; bi
= nextbi
)
3082 if (bi
->type
== ZEBRA_ROUTE_BGP_DIRECT
)
3085 struct rfapi_descriptor
*rfd
;
3086 vncHDBgpDirect
.peer
= bi
->peer
;
3088 rfd
= bi
->extra
->vnc
.export
.rfapi_handle
;
3090 vnc_zlog_debug_verbose
3091 ("%s: deleting bi=%p, bi->peer=%p, bi->type=%d, bi->sub_type=%d, bi->extra->vnc.export.rfapi_handle=%p [passing rfd=%p]",
3092 __func__
, bi
, bi
->peer
, bi
->type
, bi
->sub_type
,
3093 (bi
->extra
? bi
->extra
->vnc
.
3094 export
.rfapi_handle
: NULL
), rfd
);
3097 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 */
3099 vncHDBgpDirect
.peer
= NULL
;
3105 /* Clear RHN list */
3106 if (bgp
->rfapi
->resolve_nve_nexthop
)
3108 struct prefix_bag
*pb
;
3109 struct bgp_info
*info
;
3110 while (!skiplist_first
3111 (bgp
->rfapi
->resolve_nve_nexthop
, NULL
, (void *) &pb
))
3114 skiplist_delete_first (bgp
->rfapi
->resolve_nve_nexthop
);
3115 bgp_info_unlock (info
);
3119 bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
] = 0;
3120 vnc_zlog_debug_verbose ("%s: return", __func__
);
3125 vnc_import_bgp_exterior_redist_disable (struct bgp
*bgp
, afi_t afi
)
3127 struct rfapi_cfg
*hc
= bgp
->rfapi_cfg
;
3128 struct bgp
*bgp_exterior
= hc
->redist_bgp_exterior_view
;
3130 vnc_zlog_debug_verbose ("%s: entry", __func__
);
3132 if (!hc
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
])
3134 vnc_zlog_debug_verbose ("%s: already disabled for afi %d, skipping", __func__
, afi
);
3140 vnc_zlog_debug_verbose ("%s: bgp exterior view not defined, skipping", __func__
);
3146 struct bgp_node
*rn
;
3147 for (rn
= bgp_table_top (bgp_exterior
->rib
[afi
][SAFI_UNICAST
]);
3148 rn
; rn
= bgp_route_next (rn
))
3151 struct bgp_info
*bi
;
3153 for (bi
= rn
->info
; bi
; bi
= bi
->next
)
3156 if (CHECK_FLAG (bi
->flags
, BGP_INFO_REMOVED
))
3159 vnc_import_bgp_exterior_del_route (bgp_exterior
, &rn
->p
, bi
);
3163 print_rhn_list (__func__
, NULL
);
3167 bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
] = 0;
3168 vnc_zlog_debug_verbose ("%s: return", __func__
);