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_mplsvpn.h" /* for RD_TYPE_IP */
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"
53 #define ENABLE_VNC_RHNCK
55 #define DEBUG_RHN_LIST 0
57 static struct rfapi_descriptor vncHDBgpDirect
; /* dummy nve descriptor */
58 static struct rfapi_descriptor vncHDResolveNve
; /* dummy nve descriptor */
61 * For routes from another AS:
64 * LOCAL_PREF = 255 - MIN(255, MED)
66 * LOCAL_PREF = default_local_pref
68 * For routes from the same AS:
70 * LOCAL_PREF unchanged
73 calc_local_pref (struct attr
*attr
, struct peer
*peer
)
75 uint32_t local_pref
= 0;
81 return peer
->bgp
->default_local_pref
;
83 return bgp_get_default ()->default_local_pref
;
86 if (peer
&& (peer
->as
!= peer
->bgp
->as
))
88 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
96 local_pref
= 255 - attr
->med
;
101 local_pref
= peer
->bgp
->default_local_pref
;
106 if (attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
108 local_pref
= attr
->local_pref
;
112 if (peer
&& peer
->bgp
)
114 local_pref
= peer
->bgp
->default_local_pref
;
123 is_host_prefix (struct prefix
*p
)
128 return (p
->prefixlen
== 32);
130 return (p
->prefixlen
== 128);
135 /***********************************************************************
137 ***********************************************************************/
141 struct prefix hpfx
; /* ce address = unicast nexthop */
142 struct prefix upfx
; /* unicast prefix */
143 struct bgp_info
*ubi
; /* unicast route */
146 static const u_char maskbit
[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0,
147 0xf8, 0xfc, 0xfe, 0xff
151 vnc_prefix_cmp (void *pfx1
, void *pfx2
)
157 struct prefix
*p1
= pfx1
;
158 struct prefix
*p2
= pfx2
;
160 if (p1
->family
< p2
->family
)
162 if (p1
->family
> p2
->family
)
165 if (p1
->prefixlen
< p2
->prefixlen
)
167 if (p1
->prefixlen
> p2
->prefixlen
)
170 offset
= p1
->prefixlen
/ 8;
171 shift
= p1
->prefixlen
% 8;
172 if (shift
== 0 && offset
)
173 { /* catch aligned case */
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
;
192 mask
= maskbit
[shift
];
193 if ((*pp1
& mask
) < (*pp2
& mask
))
195 if ((*pp1
& mask
) > (*pp2
& mask
))
202 prefix_bag_free (void *pb
)
204 XFREE (MTYPE_RFAPI_PREFIX_BAG
, pb
);
209 print_rhn_list (const char *tag1
, const char *tag2
)
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
;
219 zlog_debug ("%s: %s: RHN List is empty", (tag1
? tag1
: ""),
224 zlog_debug ("%s: %s: RHN list:", (tag1
? tag1
: ""), (tag2
? tag2
: ""));
226 /* XXX uses secret knowledge of skiplist structure */
227 for (p
= sl
->header
->forward
[0]; p
; p
= p
->forward
[0])
235 prefix2str (p
->key
, kbuf
, BUFSIZ
);
236 prefix2str (&pb
->hpfx
, hbuf
, BUFSIZ
);
237 prefix2str (&pb
->upfx
, ubuf
, BUFSIZ
);
239 zlog_debug ("RHN Entry %d (q=%p): kpfx=%s, upfx=%s, hpfx=%s, ubi=%p",
240 ++count
, p
, kbuf
, ubuf
, hbuf
, pb
->ubi
);
245 #ifdef ENABLE_VNC_RHNCK
247 vnc_rhnck (char *tag
)
251 struct skiplistnode
*p
;
253 bgp
= bgp_get_default ();
254 sl
= bgp
->rfapi
->resolve_nve_nexthop
;
259 /* XXX uses secret knowledge of skiplist structure */
260 for (p
= sl
->header
->forward
[0]; p
; p
= p
->forward
[0])
262 struct prefix_bag
*pb
;
265 struct prefix pfx_orig_nexthop
;
267 memset (&pfx_orig_nexthop
, 0, sizeof (struct prefix
)); /* keep valgrind happy */
272 afi
= family2afi (pb
->upfx
.family
);
274 rfapiUnicastNexthop2Prefix (afi
, pb
->ubi
->attr
, &pfx_orig_nexthop
);
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
))
280 char str_onh
[BUFSIZ
];
281 char str_nve_pfx
[BUFSIZ
];
283 prefix2str (&pfx_orig_nexthop
, str_onh
, BUFSIZ
);
284 str_onh
[BUFSIZ
- 1] = 0;
286 prefix2str (&pb
->hpfx
, str_nve_pfx
, BUFSIZ
);
287 str_nve_pfx
[BUFSIZ
- 1] = 0;
290 ("%s: %s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s",
291 __func__
, tag
, str_onh
, str_nve_pfx
);
295 zlog_debug ("%s: vnc_rhnck OK", tag
);
298 #define VNC_RHNCK(n) do {char buf[BUFSIZ];sprintf(buf,"%s: %s", __func__, #n);vnc_rhnck(buf);} while (0)
306 /***********************************************************************
307 * Add/Delete Unicast Route
308 ***********************************************************************/
311 * "Adding a Route" import process
315 * extract and package information from the BGP unicast route.
316 * Return code 0 means OK, non-0 means drop.
318 * If return code is 0, caller MUST release ecom
321 process_unicast_route (
322 struct bgp
*bgp
, /* in */
324 struct prefix
*prefix
, /* in */
325 struct bgp_info
*info
, /* in */
326 struct ecommunity
**ecom
, /* OUT */
327 struct prefix
*unicast_nexthop
) /* OUT */
329 struct rfapi_cfg
*hc
= bgp
->rfapi_cfg
;
330 struct peer
*peer
= info
->peer
;
331 struct attr
*attr
= info
->attr
;
333 struct route_map
*rmap
= NULL
;
334 struct prefix pfx_orig_nexthop
;
336 memset (&pfx_orig_nexthop
, 0, sizeof (struct prefix
)); /* keep valgrind happy */
341 if (hc
->plist_redist
[ZEBRA_ROUTE_BGP_DIRECT
][afi
])
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
)
348 zlog_debug ("%s: prefix list returns DENY, blocking route",
352 zlog_debug ("%s: prefix list returns PASS, allowing route", __func__
);
355 /* apply routemap, if any, later */
356 rmap
= hc
->routemap_redist
[ZEBRA_ROUTE_BGP_DIRECT
];
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
363 * Incoming prefix is unicast. If v6, it is in multiprotocol area,
364 * but if v4 it is in attr->nexthop
366 rfapiUnicastNexthop2Prefix (afi
, attr
, &pfx_orig_nexthop
);
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.
374 memset (&hattr
, 0, sizeof (struct attr
));
375 bgp_attr_dup (&hattr
, attr
); /* hattr becomes a ghost attr */
379 struct bgp_info info
;
380 route_map_result_t ret
;
382 memset (&info
, 0, sizeof (info
));
385 ret
= route_map_apply (rmap
, prefix
, RMAP_BGP
, &info
);
386 if (ret
== RMAP_DENYMATCH
)
388 bgp_attr_flush (&hattr
);
389 bgp_attr_extra_free (&hattr
);
390 zlog_debug ("%s: route map \"%s\" says DENY, returning", __func__
,
397 * Get the (possibly altered by policy) unicast nexthop
398 * for later lookup in the Import Table by caller
400 rfapiUnicastNexthop2Prefix (afi
, &hattr
, unicast_nexthop
);
402 if (hattr
.extra
&& hattr
.extra
->ecommunity
)
403 *ecom
= ecommunity_dup (hattr
.extra
->ecommunity
);
405 *ecom
= ecommunity_new ();
408 * Done with hattr, clean up
410 bgp_attr_flush (&hattr
);
411 bgp_attr_extra_free (&hattr
);
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.
420 struct ecommunity_val vnc_gateway_magic
;
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;
428 /* Only works for IPv4 nexthops */
429 if (prefix
->family
== AF_INET
)
431 memcpy (vnc_gateway_magic
.val
+ 2, &unicast_nexthop
->u
.prefix4
, 4);
433 localadmin
= htons (hc
->resolve_nve_roo_local_admin
);
434 memcpy (vnc_gateway_magic
.val
+ 6, (char *) &localadmin
, 2);
436 ecommunity_add_val (*ecom
, &vnc_gateway_magic
);
444 vnc_import_bgp_add_route_mode_resolve_nve_one_bi (
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 */
455 struct prefix nexthop
;
456 struct rfapi_ip_addr nexthop_h
;
459 struct bgp_attr_encap_subtlv
*encaptlvs
;
461 zlog_debug ("%s: entry", __func__
);
463 if (bi
->type
!= ZEBRA_ROUTE_BGP
&& bi
->type
!= ZEBRA_ROUTE_BGP_DIRECT
)
468 if (bi
->sub_type
!= BGP_ROUTE_NORMAL
&&
469 bi
->sub_type
!= BGP_ROUTE_STATIC
&& bi
->sub_type
!= BGP_ROUTE_RFP
)
474 if (CHECK_FLAG (bi
->flags
, BGP_INFO_REMOVED
))
477 vncHDResolveNve
.peer
= bi
->peer
;
478 if (!rfapiGetVncTunnelUnAddr (bi
->attr
, &un
))
480 if (rfapiQprefix2Raddr (&un
, &vncHDResolveNve
.un_addr
))
485 memset (&vncHDResolveNve
.un_addr
, 0, sizeof (vncHDResolveNve
.un_addr
));
488 /* Use nexthop of VPN route as nexthop of constructed route */
489 rfapiNexthop2Prefix (bi
->attr
, &nexthop
);
490 rfapiQprefix2Raddr (&nexthop
, &nexthop_h
);
492 if (rfapiGetVncLifetime (bi
->attr
, &lifetime
))
498 plifetime
= &lifetime
;
501 if (bi
->attr
&& bi
->attr
->extra
)
503 encaptlvs
= bi
->attr
->extra
->vnc_subtlvs
;
510 struct ecommunity
*new_ecom
= ecommunity_dup (ecom
);
512 if (bi
->attr
&& bi
->attr
->extra
&& bi
->attr
->extra
->ecommunity
)
513 ecommunity_merge (new_ecom
, bi
->attr
->extra
->ecommunity
);
519 prefix
, /* unicast route prefix */
521 &nexthop_h
, /* new nexthop */
524 (struct bgp_tea_options
*) encaptlvs
, /* RFP options */
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 */
534 ecommunity_free (&new_ecom
);
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 */
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 */
559 prefix2str (ubi_nexthop
, str_nh
, BUFSIZ
);
560 str_nh
[BUFSIZ
- 1] = 0;
562 zlog_debug ("%s: ubi_nexthop=%s", __func__
, str_nh
);
566 bn
= bgp_node_lookup (table_rd
, ubi_nexthop
);
569 zlog_debug ("%s: no match in RD's table for ubi_nexthop", __func__
);
573 /* Iterate over bgp_info items at this node */
574 for (bi
= bn
->info
; bi
; bi
= bi
->next
)
577 vnc_import_bgp_add_route_mode_resolve_nve_one_bi (bgp
, afi
, bi
, /* VPN bi */
584 bgp_unlock_node (bn
);
588 vnc_import_bgp_add_route_mode_resolve_nve (
590 struct prefix
*prefix
,/* unicast prefix */
591 struct bgp_info
*info
) /* unicast info */
593 afi_t afi
= family2afi (prefix
->family
);
594 struct rfapi_cfg
*hc
= NULL
;
596 struct prefix pfx_unicast_nexthop
= { 0 }; /* happy valgrind */
598 struct ecommunity
*ecom
= NULL
;
600 uint32_t *med
= NULL
;
602 struct prefix_bag
*pb
;
603 struct bgp_node
*bnp
; /* prd table node */
607 char str_pfx
[BUFSIZ
];
611 prefix2str (prefix
, str_pfx
, BUFSIZ
);
612 str_pfx
[BUFSIZ
- 1] = 0;
615 rfapiUnicastNexthop2Prefix (afi
, info
->attr
, &nh
);
618 prefix2str (&nh
, str_nh
, BUFSIZ
);
619 str_nh
[BUFSIZ
- 1] = 0;
627 zlog_debug ("%s(bgp=%p, unicast prefix=%s, unicast nh=%s)",
628 __func__
, bgp
, str_pfx
, str_nh
);
631 if (info
->type
!= ZEBRA_ROUTE_BGP
)
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");
645 zlog_err ("%s: can't get afi of prefix", __func__
);
649 if (!(hc
= bgp
->rfapi_cfg
))
651 zlog_debug ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
655 /* check vnc redist flag for bgp direct routes */
656 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
659 ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping",
665 if (process_unicast_route (bgp
, afi
, prefix
, info
,
666 &ecom
, &pfx_unicast_nexthop
))
669 zlog_debug ("%s: process_unicast_route error, skipping", __func__
);
673 local_pref
= calc_local_pref (info
->attr
, info
->peer
);
675 (info
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
)))
678 med
= &info
->attr
->med
;
683 * At this point, we have allocated:
685 * ecom ecommunity ptr, union of unicast and ROO parts (no NVE part)
689 * pfx_unicast_nexthop nexthop of uncast route
692 if (!bgp
->rfapi
->resolve_nve_nexthop
)
694 bgp
->rfapi
->resolve_nve_nexthop
=
695 skiplist_new (SKIPLIST_FLAG_ALLOW_DUPLICATES
, vnc_prefix_cmp
,
699 pb
= XCALLOC (MTYPE_RFAPI_PREFIX_BAG
, sizeof (struct prefix_bag
));
700 pb
->hpfx
= pfx_unicast_nexthop
;
704 bgp_info_lock (info
); /* skiplist refers to it */
705 skiplist_insert (bgp
->rfapi
->resolve_nve_nexthop
, &pb
->hpfx
, pb
);
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.
712 for (bnp
= bgp_table_top (bgp
->rib
[afi
][SAFI_MPLS_VPN
]); bnp
;
713 bnp
= bgp_route_next (bnp
))
716 struct bgp_table
*table
;
718 table
= (struct bgp_table
*) (bnp
->info
);
723 vnc_import_bgp_add_route_mode_resolve_nve_one_rd ((struct prefix_rd
*)
727 &pfx_unicast_nexthop
);
733 ecommunity_free (&ecom
);
735 zlog_debug ("%s: done", __func__
);
740 vnc_import_bgp_add_route_mode_plain (struct bgp
*bgp
,
741 struct prefix
*prefix
,
742 struct bgp_info
*info
)
744 afi_t afi
= family2afi (prefix
->family
);
745 struct peer
*peer
= info
->peer
;
746 struct attr
*attr
= info
->attr
;
748 struct rfapi_cfg
*hc
= NULL
;
749 struct attr
*iattr
= NULL
;
751 struct rfapi_ip_addr vnaddr
;
752 struct prefix vn_pfx_space
;
753 struct prefix
*vn_pfx
= NULL
;
755 struct ecommunity
*ecom
= NULL
;
756 struct prefix_rd prd
;
757 struct route_map
*rmap
= NULL
;
759 uint32_t *med
= NULL
;
765 prefix2str (prefix
, buf
, BUFSIZ
);
767 zlog_debug ("%s(prefix=%s) entry", __func__
, buf
);
772 zlog_err ("%s: can't get afi of prefix", __func__
);
776 if (!(hc
= bgp
->rfapi_cfg
))
778 zlog_debug ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
782 /* check vnc redist flag for bgp direct routes */
783 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
786 ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping",
792 * mode "plain" specific code
795 zlog_debug ("%s: NOT using redist RFG", __func__
);
800 if (hc
->plist_redist
[ZEBRA_ROUTE_BGP_DIRECT
][afi
])
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
)
807 zlog_debug ("%s: prefix list returns DENY, blocking route",
811 zlog_debug ("%s: prefix list returns PASS, allowing route", __func__
);
814 /* apply routemap, if any, later */
815 rmap
= hc
->routemap_redist
[ZEBRA_ROUTE_BGP_DIRECT
];
818 * Incoming prefix is unicast. If v6, it is in multiprotocol area,
819 * but if v4 it is in attr->nexthop
821 rfapiUnicastNexthop2Prefix (afi
, attr
, &vn_pfx_space
);
822 vn_pfx
= &vn_pfx_space
;
825 ahr_flags
|= RFAPI_AHR_NO_TUNNEL_SUBTLV
;
828 if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE
))
833 prefix2str (vn_pfx
, buf
, BUFSIZ
);
835 zlog_debug ("%s vn_pfx=%s", __func__
, buf
);
841 if (rfapiQprefix2Raddr (vn_pfx
, &vnaddr
))
843 zlog_debug ("%s: redist VN invalid, skipping", __func__
);
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.
853 memset (&hattr
, 0, sizeof (struct attr
));
854 bgp_attr_dup (&hattr
, attr
); /* hattr becomes a ghost attr */
858 struct bgp_info info
;
859 route_map_result_t ret
;
861 memset (&info
, 0, sizeof (info
));
864 ret
= route_map_apply (rmap
, prefix
, RMAP_BGP
, &info
);
865 if (ret
== RMAP_DENYMATCH
)
867 bgp_attr_flush (&hattr
);
868 bgp_attr_extra_free (&hattr
);
869 zlog_debug ("%s: route map \"%s\" says DENY, returning", __func__
,
875 iattr
= bgp_attr_intern (&hattr
);
876 bgp_attr_flush (&hattr
);
877 bgp_attr_extra_free (&hattr
);
879 /* Now iattr is an allocated interned attr */
882 * Mode "plain" specific code
884 * Sets RD in dummy HD
888 if (vnaddr
.addr_family
!= AF_INET
)
891 ("%s: can't auto-assign RD, VN AF (%d) is not IPv4, skipping",
892 __func__
, vnaddr
.addr_family
);
895 bgp_attr_unintern (&iattr
);
899 memset (&prd
, 0, sizeof (prd
));
900 rfapi_set_autord_from_vn (&prd
, &vnaddr
);
902 if (iattr
&& iattr
->extra
&& iattr
->extra
->ecommunity
)
903 ecom
= ecommunity_dup (iattr
->extra
->ecommunity
);
907 local_pref
= calc_local_pref (iattr
, peer
);
909 if (iattr
&& (iattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
)))
914 if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE
))
919 rfapiRfapiIpAddr2Str (&vnaddr
, buf
, BUFSIZ
);
921 zlog_debug ("%s: setting vnaddr to %s", __func__
, buf
);
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
;
932 ecommunity_free (&ecom
);
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
)
941 afi_t afi
= family2afi (prefix
->family
);
942 struct peer
*peer
= info
->peer
;
943 struct attr
*attr
= info
->attr
;
945 struct rfapi_cfg
*hc
= NULL
;
946 struct attr
*iattr
= NULL
;
948 struct rfapi_ip_addr vnaddr
;
949 struct prefix
*vn_pfx
= NULL
;
951 struct ecommunity
*ecom
= NULL
;
952 struct prefix_rd prd
;
953 struct route_map
*rmap
= NULL
;
960 prefix2str (prefix
, buf
, BUFSIZ
);
962 zlog_debug ("%s(prefix=%s) entry", __func__
, buf
);
969 zlog_err ("%s: can't get afi of prefix", __func__
);
973 if (!(hc
= bgp
->rfapi_cfg
))
975 zlog_debug ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
979 /* check vnc redist flag for bgp direct routes */
980 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
983 ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping",
994 struct rfapi_ip_prefix pfx_un
;
996 zlog_debug ("%s: using redist RFG", __func__
);
999 * RFG prefix list check
1001 if (rfg
->plist_redist
[ZEBRA_ROUTE_BGP_DIRECT
][afi
])
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
)
1008 zlog_debug ("%s: prefix list returns DENY, blocking route",
1012 zlog_debug ("%s: prefix list returns PASS, allowing route", __func__
);
1015 /* apply routemap, if any, later */
1016 rmap
= rfg
->routemap_redist
[ZEBRA_ROUTE_BGP_DIRECT
];
1019 * export nve group's VN addr prefix must be a /32 which
1020 * will yield the VN addr to use
1022 vn_pfx
= &rfg
->vn_prefix
;
1027 if (!is_host_prefix (&rfg
->un_prefix
))
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
);
1035 rfapiQprefix2Rprefix (&rfg
->un_prefix
, &pfx_un
);
1037 vncHDBgpDirect
.un_addr
= pfx_un
.prefix
;
1040 if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE
))
1045 prefix2str (vn_pfx
, buf
, BUFSIZ
);
1046 buf
[BUFSIZ
- 1] = 0;
1047 zlog_debug ("%s vn_pfx=%s", __func__
, buf
);
1051 * Compute VN address
1053 if (rfapiQprefix2Raddr (vn_pfx
, &vnaddr
))
1055 zlog_debug ("%s: redist VN invalid, skipping", __func__
);
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.
1065 memset (&hattr
, 0, sizeof (struct attr
));
1066 bgp_attr_dup (&hattr
, attr
); /* hattr becomes a ghost attr */
1070 struct bgp_info info
;
1071 route_map_result_t ret
;
1073 memset (&info
, 0, sizeof (info
));
1076 ret
= route_map_apply (rmap
, prefix
, RMAP_BGP
, &info
);
1077 if (ret
== RMAP_DENYMATCH
)
1079 bgp_attr_flush (&hattr
);
1080 bgp_attr_extra_free (&hattr
);
1081 zlog_debug ("%s: route map \"%s\" says DENY, returning", __func__
,
1087 iattr
= bgp_attr_intern (&hattr
);
1088 bgp_attr_flush (&hattr
);
1089 bgp_attr_extra_free (&hattr
);
1091 /* Now iattr is an allocated interned attr */
1096 * Sets RD in dummy HD
1101 memset (&prd
, 0, sizeof (prd
));
1103 prd
.family
= AF_UNSPEC
;
1106 if (rfg
->rd
.family
== AF_UNIX
)
1108 rfapi_set_autord_from_vn (&prd
, &vnaddr
);
1111 if (rfg
->rt_export_list
)
1112 ecom
= ecommunity_dup (bgp
->rfapi_cfg
->rfg_redist
->rt_export_list
);
1114 ecom
= ecommunity_new ();
1116 if (iattr
&& iattr
->extra
&& iattr
->extra
->ecommunity
)
1117 ecom
= ecommunity_merge (ecom
, iattr
->extra
->ecommunity
);
1120 local_pref
= calc_local_pref (iattr
, peer
);
1122 if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE
))
1127 rfapiRfapiIpAddr2Str (&vnaddr
, buf
, BUFSIZ
);
1128 buf
[BUFSIZ
- 1] = 0;
1129 zlog_debug ("%s: setting vnaddr to %s", __func__
, buf
);
1132 vncHDBgpDirect
.peer
= peer
;
1141 &(bgp
->rfapi_cfg
->redist_lifetime
),
1142 NULL
, /* RFP options */
1147 NULL
, /* label: default */
1148 ZEBRA_ROUTE_BGP_DIRECT
,
1149 BGP_ROUTE_REDISTRIBUTE
,
1151 vncHDBgpDirect
.peer
= NULL
;
1154 ecommunity_free (&ecom
);
1158 vnc_import_bgp_del_route_mode_plain (struct bgp
*bgp
,
1159 struct prefix
*prefix
,
1160 struct bgp_info
*info
)
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
;
1172 * Compute VN address
1175 if (info
&& info
->attr
)
1177 rfapiUnicastNexthop2Prefix (afi
, info
->attr
, &vn_pfx_space
);
1181 zlog_debug ("%s: no attr, can't delete route", __func__
);
1184 vn_pfx
= &vn_pfx_space
;
1186 vnaddr
.addr_family
= vn_pfx
->family
;
1187 switch (vn_pfx
->family
)
1190 if (vn_pfx
->prefixlen
!= 32)
1192 zlog_debug ("%s: redist VN plen (%d) != 32, skipping",
1193 __func__
, vn_pfx
->prefixlen
);
1196 vnaddr
.addr
.v4
= vn_pfx
->u
.prefix4
;
1200 if (vn_pfx
->prefixlen
!= 128)
1202 zlog_debug ("%s: redist VN plen (%d) != 128, skipping",
1203 __func__
, vn_pfx
->prefixlen
);
1206 vnaddr
.addr
.v6
= vn_pfx
->u
.prefix6
;
1210 zlog_debug ("%s: no redist RFG VN host pfx configured, skipping",
1216 memset (&prd
, 0, sizeof (prd
));
1217 if (rfapi_set_autord_from_vn (&prd
, &vnaddr
))
1219 zlog_debug ("%s: can't auto-assign RD, skipping", __func__
);
1223 vncHDBgpDirect
.peer
= info
->peer
;
1224 zlog_debug ("%s: setting peer to %p", __func__
, vncHDBgpDirect
.peer
);
1225 del_vnc_route (&vncHDBgpDirect
,
1231 ZEBRA_ROUTE_BGP_DIRECT
, BGP_ROUTE_REDISTRIBUTE
, NULL
, 1);
1233 vncHDBgpDirect
.peer
= NULL
;
1237 vnc_import_bgp_del_route_mode_nvegroup (struct bgp
*bgp
,
1238 struct prefix
*prefix
,
1239 struct bgp_info
*info
)
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
;
1250 assert ((rfg
= bgp
->rfapi_cfg
->rfg_redist
));
1253 * Compute VN address
1257 * export nve group's VN addr prefix must be a /32 which
1258 * will yield the VN addr to use
1260 vn_pfx
= &rfg
->vn_prefix
;
1263 vnaddr
.addr_family
= vn_pfx
->family
;
1264 switch (vn_pfx
->family
)
1267 if (vn_pfx
->prefixlen
!= 32)
1269 zlog_debug ("%s: redist VN plen (%d) != 32, skipping",
1270 __func__
, vn_pfx
->prefixlen
);
1273 vnaddr
.addr
.v4
= vn_pfx
->u
.prefix4
;
1277 if (vn_pfx
->prefixlen
!= 128)
1279 zlog_debug ("%s: redist VN plen (%d) != 128, skipping",
1280 __func__
, vn_pfx
->prefixlen
);
1283 vnaddr
.addr
.v6
= vn_pfx
->u
.prefix6
;
1287 zlog_debug ("%s: no redist RFG VN host pfx configured, skipping",
1292 memset (&prd
, 0, sizeof (prd
));
1294 prd
.family
= AF_UNSPEC
;
1297 if (rfg
->rd
.family
== AF_UNIX
)
1299 /* means "auto" with VN addr */
1300 if (rfapi_set_autord_from_vn (&prd
, &vnaddr
))
1302 zlog_debug ("%s: can't auto-assign RD, skipping", __func__
);
1308 vncHDBgpDirect
.peer
= info
->peer
;
1309 zlog_debug ("%s: setting peer to %p", __func__
, vncHDBgpDirect
.peer
);
1310 del_vnc_route (&vncHDBgpDirect
,
1316 ZEBRA_ROUTE_BGP_DIRECT
, BGP_ROUTE_REDISTRIBUTE
, NULL
, 1);
1318 vncHDBgpDirect
.peer
= NULL
;
1322 vnc_import_bgp_del_route_mode_resolve_nve_one_bi (
1325 struct bgp_info
*bi
, /* VPN bi */
1326 struct prefix_rd
*prd
, /* RD */
1327 struct prefix
*prefix
)/* unicast route prefix */
1331 if (bi
->type
!= ZEBRA_ROUTE_BGP
&& bi
->type
!= ZEBRA_ROUTE_BGP_DIRECT
)
1336 if (bi
->sub_type
!= BGP_ROUTE_NORMAL
&&
1337 bi
->sub_type
!= BGP_ROUTE_STATIC
&& bi
->sub_type
!= BGP_ROUTE_RFP
)
1342 if (CHECK_FLAG (bi
->flags
, BGP_INFO_REMOVED
))
1345 vncHDResolveNve
.peer
= bi
->peer
;
1346 if (!rfapiGetVncTunnelUnAddr (bi
->attr
, &un
))
1348 if (rfapiQprefix2Raddr (&un
, &vncHDResolveNve
.un_addr
))
1353 memset (&vncHDResolveNve
.un_addr
, 0, sizeof (vncHDResolveNve
.un_addr
));
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 */
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 */
1367 struct prefix
*prefix
, /* unicast prefix */
1368 struct prefix
*ubi_nexthop
) /* unicast bi's nexthop */
1370 struct bgp_node
*bn
;
1371 struct bgp_info
*bi
;
1377 char str_nh
[BUFSIZ
];
1379 prefix2str (ubi_nexthop
, str_nh
, BUFSIZ
);
1380 str_nh
[BUFSIZ
- 1] = 0;
1382 zlog_debug ("%s: ubi_nexthop=%s", __func__
, str_nh
);
1387 bn
= bgp_node_lookup (table_rd
, ubi_nexthop
);
1390 zlog_debug ("%s: no match in RD's table for ubi_nexthop", __func__
);
1394 /* Iterate over bgp_info items at this node */
1395 for (bi
= bn
->info
; bi
; bi
= bi
->next
)
1398 vnc_import_bgp_del_route_mode_resolve_nve_one_bi (bgp
, afi
, bi
, /* VPN bi */
1400 prefix
); /* unicast route prefix */
1403 bgp_unlock_node (bn
);
1407 vnc_import_bgp_del_route_mode_resolve_nve (struct bgp
*bgp
,
1409 struct prefix
*prefix
,
1410 struct bgp_info
*info
)
1412 struct ecommunity
*ecom
= NULL
;
1413 struct prefix pfx_unicast_nexthop
= { 0 }; /* happy valgrind */
1415 //struct listnode *hnode;
1416 //struct rfapi_descriptor *rfd;
1417 struct prefix_bag
*pb
;
1419 struct skiplist
*sl
= bgp
->rfapi
->resolve_nve_nexthop
;
1421 struct bgp_node
*bnp
; /* prd table node */
1425 zlog_debug ("%s: no RHN entries, skipping", __func__
);
1429 if (info
->type
!= ZEBRA_ROUTE_BGP
)
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");
1437 if (process_unicast_route (bgp
, afi
, prefix
, info
,
1438 &ecom
, &pfx_unicast_nexthop
))
1441 zlog_debug ("%s: process_unicast_route error, skipping", __func__
);
1445 rc
= skiplist_first_value (sl
, &pfx_unicast_nexthop
, (void *) &pb
, &cursor
);
1448 if (pb
->ubi
== info
)
1450 skiplist_delete (sl
, &pfx_unicast_nexthop
, pb
);
1451 bgp_info_unlock (info
);
1455 skiplist_next_value (sl
, &pfx_unicast_nexthop
, (void *) &pb
, &cursor
);
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.
1463 for (bnp
= bgp_table_top (bgp
->rib
[afi
][SAFI_MPLS_VPN
]); bnp
;
1464 bnp
= bgp_route_next (bnp
))
1467 struct bgp_table
*table
;
1469 table
= (struct bgp_table
*) (bnp
->info
);
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? */
1478 ecommunity_free (&ecom
);
1484 /***********************************************************************
1485 * Add/Delete CE->NVE routes
1486 ***********************************************************************/
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.
1493 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve (
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 */
1500 afi_t afi
= family2afi (prefix
->family
);
1501 struct skiplist
*sl
= NULL
;
1503 struct prefix_bag
*pb
;
1505 struct rfapi_cfg
*hc
= NULL
;
1507 zlog_debug ("%s: entry", __func__
);
1509 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
1511 zlog_debug ("%s: bad afi %d, skipping", __func__
, afi
);
1515 if (!(hc
= bgp
->rfapi_cfg
))
1517 zlog_debug ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
1521 /* check vnc redist flag for bgp direct routes */
1522 if (!hc
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
1525 ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping",
1530 if (hc
->redist_mode
!= VNC_REDIST_MODE_RESOLVE_NVE
)
1532 zlog_debug ("%s: not in resolve-nve mode, skipping", __func__
);
1536 if (bgp
&& bgp
->rfapi
)
1537 sl
= bgp
->rfapi
->resolve_nve_nexthop
;
1541 zlog_debug ("%s: no resolve_nve_nexthop skiplist, skipping", __func__
);
1545 if (!is_host_prefix (prefix
))
1547 zlog_debug ("%s: not host prefix, skipping", __func__
);
1551 rc
= skiplist_first_value (sl
, prefix
, (void *) &pb
, &cursor
);
1554 struct ecommunity
*ecom
;
1555 struct prefix pfx_unicast_nexthop
;
1556 uint32_t *med
= NULL
;
1557 uint32_t local_pref
;
1559 memset (&pfx_unicast_nexthop
, 0, sizeof (struct prefix
)); /* keep valgrind happy */
1561 if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE
))
1566 prefix2str (&pb
->hpfx
, hbuf
, BUFSIZ
);
1567 prefix2str (&pb
->upfx
, ubuf
, BUFSIZ
);
1570 ("%s: examining RHN Entry (q=%p): upfx=%s, hpfx=%s, ubi=%p",
1571 __func__
, cursor
, ubuf
, hbuf
, pb
->ubi
);
1574 if (process_unicast_route (bgp
, afi
, &pb
->upfx
, pb
->ubi
,
1575 &ecom
, &pfx_unicast_nexthop
))
1578 zlog_debug ("%s: process_unicast_route error, skipping", __func__
);
1581 local_pref
= calc_local_pref (pb
->ubi
->attr
, pb
->ubi
->peer
);
1583 if (pb
->ubi
->attr
&&
1584 (pb
->ubi
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
)))
1587 med
= &pb
->ubi
->attr
->med
;
1593 if (vnc_prefix_cmp (&pfx_unicast_nexthop
, prefix
))
1595 char str_unh
[BUFSIZ
];
1596 char str_nve_pfx
[BUFSIZ
];
1598 prefix2str (&pfx_unicast_nexthop
, str_unh
, BUFSIZ
);
1599 str_unh
[BUFSIZ
- 1] = 0;
1601 prefix2str (prefix
, str_nve_pfx
, BUFSIZ
);
1602 str_nve_pfx
[BUFSIZ
- 1] = 0;
1605 ("%s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s",
1606 __func__
, str_unh
, str_nve_pfx
);
1610 vnc_import_bgp_add_route_mode_resolve_nve_one_bi (bgp
, afi
, bi
, /* VPN bi */
1611 prd
, &pb
->upfx
, /* unicast prefix */
1616 ecommunity_free (&ecom
);
1623 prefix2str (prefix
, pbuf
, BUFSIZ
);
1625 zlog_debug ("%s: advancing past RHN Entry (q=%p): with prefix %s",
1626 __func__
, cursor
, pbuf
);
1627 print_rhn_list (__func__
, NULL
); /* debug */
1630 rc
= skiplist_next_value (sl
, prefix
, (void *) &pb
, &cursor
);
1632 zlog_debug ("%s: done", __func__
);
1637 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve (
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 */
1644 afi_t afi
= family2afi (prefix
->family
);
1645 struct skiplist
*sl
= NULL
;
1646 struct prefix_bag
*pb
;
1648 struct rfapi_cfg
*hc
= NULL
;
1652 char str_pfx
[BUFSIZ
];
1654 prefix2str (prefix
, str_pfx
, BUFSIZ
);
1655 str_pfx
[BUFSIZ
- 1] = 0;
1657 zlog_debug ("%s(bgp=%p, nve prefix=%s)", __func__
, bgp
, str_pfx
);
1660 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
1663 if (!(hc
= bgp
->rfapi_cfg
))
1665 zlog_debug ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
1669 /* check vnc redist flag for bgp direct routes */
1670 if (!hc
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
1673 ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping",
1678 if (hc
->redist_mode
!= VNC_REDIST_MODE_RESOLVE_NVE
)
1680 zlog_debug ("%s: not in resolve-nve mode, skipping", __func__
);
1684 if (bgp
&& bgp
->rfapi
)
1685 sl
= bgp
->rfapi
->resolve_nve_nexthop
;
1689 zlog_debug ("%s: no RHN entries, skipping", __func__
);
1693 if (!is_host_prefix (prefix
))
1695 zlog_debug ("%s: not host route, skip", __func__
);
1700 * Find all entries with key == CE in the RHN list
1702 rc
= skiplist_first_value (sl
, prefix
, (void *) &pb
, &cursor
);
1706 struct ecommunity
*ecom
;
1707 struct prefix pfx_unicast_nexthop
;
1709 memset (&pfx_unicast_nexthop
, 0, sizeof (struct prefix
)); /* keep valgrind happy */
1711 if (process_unicast_route (bgp
, afi
, &pb
->upfx
, pb
->ubi
,
1712 &ecom
, &pfx_unicast_nexthop
))
1715 zlog_debug ("%s: process_unicast_route error, skipping", __func__
);
1722 if (vnc_prefix_cmp (&pfx_unicast_nexthop
, prefix
))
1724 char str_unh
[BUFSIZ
];
1725 char str_nve_pfx
[BUFSIZ
];
1727 prefix2str (&pfx_unicast_nexthop
, str_unh
, BUFSIZ
);
1728 str_unh
[BUFSIZ
- 1] = 0;
1730 prefix2str (prefix
, str_nve_pfx
, BUFSIZ
);
1731 str_nve_pfx
[BUFSIZ
- 1] = 0;
1734 ("%s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s",
1735 __func__
, str_unh
, str_nve_pfx
);
1739 vnc_import_bgp_del_route_mode_resolve_nve_one_bi (bgp
,
1741 bi
, prd
, &pb
->upfx
);
1744 ecommunity_free (&ecom
);
1746 rc
= skiplist_next_value (sl
, prefix
, (void *) &pb
, &cursor
);
1751 /***********************************************************************
1753 ***********************************************************************/
1755 #define DEBUG_IS_USABLE_INTERIOR 1
1758 is_usable_interior_route (struct bgp_info
*bi_interior
)
1760 if (!VALID_INTERIOR_TYPE (bi_interior
->type
))
1762 #if DEBUG_IS_USABLE_INTERIOR
1763 zlog_debug ("%s: NO: type %d is not valid interior type",
1764 __func__
, bi_interior
->type
);
1768 if (!CHECK_FLAG (bi_interior
->flags
, BGP_INFO_VALID
))
1770 #if DEBUG_IS_USABLE_INTERIOR
1771 zlog_debug ("%s: NO: BGP_INFO_VALID not set", __func__
);
1779 * There should be only one of these per prefix at a time.
1780 * This should be called as a result of selection operation
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
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 */
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
);
1801 h
= bgp_default
->rfapi
;
1802 hc
= bgp_default
->rfapi_cfg
;
1804 zlog_debug ("%s: entry with it=%p", __func__
, it_only
);
1808 zlog_debug ("%s: rfapi or rfapi_cfg not instantiated, skipping",
1812 if (!hc
->redist_bgp_exterior_view
)
1814 zlog_debug ("%s: exterior view not set, skipping", __func__
);
1817 if (bgp
!= hc
->redist_bgp_exterior_view
)
1819 zlog_debug ("%s: bgp %p != hc->redist_bgp_exterior_view %p, skipping",
1820 __func__
, bgp
, hc
->redist_bgp_exterior_view
);
1824 if (!hc
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
])
1826 zlog_debug ("%s: redist of exterior routes not enabled, skipping",
1833 zlog_debug ("%s: no info, skipping", __func__
);
1838 * Extract nexthop from exterior route
1840 * Incoming prefix is unicast. If v6, it is in multiprotocol area,
1841 * but if v4 it is in attr->nexthop
1843 rfapiUnicastNexthop2Prefix (afi
, info
->attr
, &pfx_orig_nexthop
);
1845 for (it
= h
->imports
; it
; it
= it
->next
)
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
;
1853 zlog_debug ("%s: doing it %p", __func__
, it
);
1855 if (it_only
&& (it_only
!= it
))
1857 zlog_debug ("%s: doesn't match it_only %p", __func__
, it_only
);
1861 table
= it
->imported_vpn
[afi
];
1863 for (rn
= route_node_match (table
, &pfx_orig_nexthop
),
1864 have_usable_route
= 0; (!have_usable_route
) && rn
;)
1867 zlog_debug ("%s: it %p trying rn %p", __func__
, it
, rn
);
1869 for (bi_interior
= rn
->info
; bi_interior
;
1870 bi_interior
= bi_interior
->next
)
1872 struct prefix_rd
*prd
;
1873 struct attr new_attr
;
1874 u_int32_t label
= 0;
1876 if (!is_usable_interior_route (bi_interior
))
1879 zlog_debug ("%s: usable: bi_interior %p", __func__
,
1883 * have a legitimate route to exterior's nexthop
1886 * Import unicast route to the import table
1888 have_usable_route
= 1;
1890 if (bi_interior
->extra
)
1892 prd
= &bi_interior
->extra
->vnc
.import
.rd
;
1893 label
= decode_label (bi_interior
->extra
->tag
);
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
))
1903 new_attr
.local_pref
= info
->attr
->local_pref
;
1904 new_attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
1907 rfapiBgpInfoFilteredImportVPN (it
, FIF_ACTION_UPDATE
, bi_interior
->peer
, NULL
, /* rfd */
1913 ZEBRA_ROUTE_BGP_DIRECT_EXT
,
1914 BGP_ROUTE_REDISTRIBUTE
, &label
);
1916 bgp_attr_extra_free (&new_attr
);
1919 if (have_usable_route
)
1924 * TBD factor this out into its own function
1926 struct prefix
*pfx_mon
= prefix_new ();
1927 if (!RFAPI_MONITOR_EXTERIOR (rn
)->source
)
1929 RFAPI_MONITOR_EXTERIOR (rn
)->source
=
1930 skiplist_new (0, NULL
, (void (*)(void *)) prefix_free
);
1931 route_lock_node (rn
); /* for skiplist */
1933 route_lock_node (rn
); /* for skiplist entry */
1934 prefix_copy (pfx_mon
, prefix
);
1935 if (!skiplist_insert (RFAPI_MONITOR_EXTERIOR (rn
)->source
,
1939 bgp_info_lock (info
);
1944 route_lock_node (par
);
1945 route_unlock_node (rn
);
1949 route_unlock_node (rn
);
1951 if (!have_usable_route
)
1953 struct prefix
*pfx_mon
= prefix_new ();
1954 prefix_copy (pfx_mon
, prefix
);
1955 if (!skiplist_insert (it
->monitor_exterior_orphans
, info
, pfx_mon
))
1958 bgp_info_lock (info
);
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 */
1970 vnc_import_bgp_exterior_add_route_it (bgp
, prefix
, info
, NULL
);
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.
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
1983 vnc_import_bgp_exterior_del_route (
1985 struct prefix
*prefix
, /* unicast prefix */
1986 struct bgp_info
*info
) /* unicast info */
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 ();
1995 memset (&pfx_orig_nexthop
, 0, sizeof (struct prefix
)); /* keep valgrind happy */
1997 h
= bgp_default
->rfapi
;
1998 hc
= bgp_default
->rfapi_cfg
;
2002 zlog_debug ("%s: rfapi or rfapi_cfg not instantiated, skipping",
2006 if (!hc
->redist_bgp_exterior_view
)
2008 zlog_debug ("%s: exterior view not set, skipping", __func__
);
2011 if (bgp
!= hc
->redist_bgp_exterior_view
)
2013 zlog_debug ("%s: bgp %p != hc->redist_bgp_exterior_view %p, skipping",
2014 __func__
, bgp
, hc
->redist_bgp_exterior_view
);
2017 if (!hc
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
])
2019 zlog_debug ("%s: redist of exterior routes no enabled, skipping",
2026 zlog_debug ("%s: no info, skipping", __func__
);
2031 * Extract nexthop from exterior route
2033 * Incoming prefix is unicast. If v6, it is in multiprotocol area,
2034 * but if v4 it is in attr->nexthop
2036 rfapiUnicastNexthop2Prefix (afi
, info
->attr
, &pfx_orig_nexthop
);
2038 for (it
= h
->imports
; it
; it
= it
->next
)
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
;
2046 table
= it
->imported_vpn
[afi
];
2048 for (rn
= route_node_match (table
, &pfx_orig_nexthop
),
2049 have_usable_route
= 0; (!have_usable_route
) && rn
;)
2052 for (bi_interior
= rn
->info
; bi_interior
;
2053 bi_interior
= bi_interior
->next
)
2055 struct prefix_rd
*prd
;
2056 u_int32_t label
= 0;
2058 if (!is_usable_interior_route (bi_interior
))
2062 * have a legitimate route to exterior's nexthop
2065 * Import unicast route to the import table
2067 have_usable_route
= 1;
2069 if (bi_interior
->extra
)
2071 prd
= &bi_interior
->extra
->vnc
.import
.rd
;
2072 label
= decode_label (bi_interior
->extra
->tag
);
2077 rfapiBgpInfoFilteredImportVPN (it
, FIF_ACTION_KILL
, bi_interior
->peer
, NULL
, /* rfd */
2083 ZEBRA_ROUTE_BGP_DIRECT_EXT
,
2084 BGP_ROUTE_REDISTRIBUTE
, &label
);
2089 * TBD factor this out into its own function
2092 if (RFAPI_MONITOR_EXTERIOR (rn
)->source
)
2094 if (!skiplist_delete (RFAPI_MONITOR_EXTERIOR (rn
)->source
,
2098 bgp_info_unlock (info
);
2099 route_unlock_node (rn
); /* sl entry */
2101 if (skiplist_empty (RFAPI_MONITOR_EXTERIOR (rn
)->source
))
2103 skiplist_free (RFAPI_MONITOR_EXTERIOR (rn
)->source
);
2104 RFAPI_MONITOR_EXTERIOR (rn
)->source
= NULL
;
2105 route_unlock_node (rn
); /* skiplist itself */
2112 route_lock_node (par
);
2113 route_unlock_node (rn
);
2117 route_unlock_node (rn
);
2119 if (!have_usable_route
)
2121 if (!skiplist_delete (it
->monitor_exterior_orphans
, info
, NULL
))
2124 bgp_info_unlock (info
);
2131 * This function should be called after a new interior VPN route
2132 * has been added to an import_table.
2134 * NB should also be called whenever an existing vpn interior route
2135 * becomes valid (e.g., valid_interior_count is inremented)
2138 vnc_import_bgp_exterior_add_route_interior (
2140 struct rfapi_import_table
*it
,
2141 struct route_node
*rn_interior
, /* VPN IT node */
2142 struct bgp_info
*bi_interior
) /* VPN IT route */
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 */
2150 struct list
*list_adopted
;
2152 zlog_debug ("%s: entry", __func__
);
2154 if (!is_usable_interior_route (bi_interior
))
2156 zlog_debug ("%s: not usable interior route, skipping", __func__
);
2160 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
])
2162 zlog_debug ("%s: redist of exterior routes no enabled, skipping",
2167 if (it
== bgp
->rfapi
->it_ce
)
2169 zlog_debug ("%s: import table is it_ce, skipping", __func__
);
2175 char str_pfx
[BUFSIZ
];
2177 prefix2str (&rn_interior
->p
, str_pfx
, BUFSIZ
);
2178 str_pfx
[BUFSIZ
- 1] = 0;
2180 zlog_debug ("%s: interior prefix=%s, bi type=%d",
2181 __func__
, str_pfx
, bi_interior
->type
);
2184 if (RFAPI_HAS_MONITOR_EXTERIOR (rn_interior
))
2187 int count
= 0; /* debugging */
2189 zlog_debug ("%s: has exterior monitor; ext src: %p", __func__
,
2190 RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
);
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.
2198 for (rc
= skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2199 (void **) &bi_exterior
,
2200 (void **) &pfx_exterior
, &cursor
); !rc
;
2202 skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2203 (void **) &bi_exterior
, (void **) &pfx_exterior
,
2207 struct prefix_rd
*prd
;
2208 struct attr new_attr
;
2209 u_int32_t label
= 0;
2212 ++count
; /* debugging */
2214 assert (bi_exterior
);
2215 assert (pfx_exterior
);
2217 if (bi_interior
->extra
)
2219 prd
= &bi_interior
->extra
->vnc
.import
.rd
;
2220 label
= decode_label (bi_interior
->extra
->tag
);
2225 /* use local_pref from unicast route */
2226 memset (&new_attr
, 0, sizeof (struct attr
));
2227 bgp_attr_dup (&new_attr
, bi_interior
->attr
);
2229 (bi_exterior
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
)))
2231 new_attr
.local_pref
= bi_exterior
->attr
->local_pref
;
2232 new_attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
2235 rfapiBgpInfoFilteredImportVPN (it
, FIF_ACTION_UPDATE
, bi_interior
->peer
, NULL
, /* rfd */
2241 ZEBRA_ROUTE_BGP_DIRECT_EXT
,
2242 BGP_ROUTE_REDISTRIBUTE
, &label
);
2244 bgp_attr_extra_free (&new_attr
);
2247 ("%s: finished constructing exteriors based on existing monitors",
2252 zlog_debug ("%s: no exterior monitor", __func__
);
2255 * No monitor at this node. Is this the first valid interior
2256 * route at this node?
2258 if (RFAPI_MONITOR_EXTERIOR (rn_interior
)->valid_interior_count
> 1)
2261 ("%s: new interior route not first valid one, skipping pulldown",
2267 * Look up the tree for possible pulldown candidates.
2268 * Find nearest parent with an exterior route monitor
2270 for (par
= rn_interior
->parent
; par
; par
= par
->parent
)
2272 if (RFAPI_HAS_MONITOR_EXTERIOR (par
))
2279 zlog_debug ("%s: checking parent %p for possible pulldowns",
2282 /* check monitors at par for possible pulldown */
2284 for (rc
= skiplist_next (RFAPI_MONITOR_EXTERIOR (par
)->source
,
2285 (void **) &bi_exterior
,
2286 (void **) &pfx_exterior
, &cursor
); !rc
;
2288 skiplist_next (RFAPI_MONITOR_EXTERIOR (par
)->source
,
2289 (void **) &bi_exterior
, (void **) &pfx_exterior
,
2293 struct prefix pfx_nexthop
;
2295 memset (&pfx_nexthop
, 0, sizeof (struct prefix
)); /* keep valgrind happy */
2297 /* check original nexthop for prefix match */
2298 rfapiUnicastNexthop2Prefix (afi
, bi_exterior
->attr
, &pfx_nexthop
);
2300 if (prefix_match (&rn_interior
->p
, &pfx_nexthop
))
2303 struct bgp_info
*bi
;
2304 struct prefix_rd
*prd
;
2305 struct attr new_attr
;
2306 u_int32_t label
= 0;
2311 * add monitor to longer prefix
2313 struct prefix
*pfx_mon
= prefix_new ();
2314 prefix_copy (pfx_mon
, pfx_exterior
);
2315 if (!RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
)
2317 RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
=
2318 skiplist_new (0, NULL
, (void (*)(void *)) prefix_free
);
2319 route_lock_node (rn_interior
);
2321 skiplist_insert (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2322 bi_exterior
, pfx_mon
);
2323 route_lock_node (rn_interior
);
2326 * Delete constructed exterior routes based on
2329 for (bi
= par
->info
; bi
; bi
= bi
->next
)
2334 prd
= &bi
->extra
->vnc
.import
.rd
;
2335 label
= decode_label (bi
->extra
->tag
);
2340 rfapiBgpInfoFilteredImportVPN (it
, FIF_ACTION_KILL
, bi
->peer
, NULL
, /* rfd */
2346 ZEBRA_ROUTE_BGP_DIRECT_EXT
,
2347 BGP_ROUTE_REDISTRIBUTE
,
2353 * Add constructed exterior routes based on
2354 * the new interior route at longer prefix.
2356 if (bi_interior
->extra
)
2358 prd
= &bi_interior
->extra
->vnc
.import
.rd
;
2359 label
= decode_label (bi_interior
->extra
->tag
);
2364 /* use local_pref from unicast route */
2365 memset (&new_attr
, 0, sizeof (struct attr
));
2366 bgp_attr_dup (&new_attr
, bi_interior
->attr
);
2368 (bi_exterior
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
)))
2370 new_attr
.local_pref
= bi_exterior
->attr
->local_pref
;
2371 new_attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
2374 rfapiBgpInfoFilteredImportVPN (it
, FIF_ACTION_UPDATE
, bi_interior
->peer
, NULL
, /* rfd */
2380 ZEBRA_ROUTE_BGP_DIRECT_EXT
,
2381 BGP_ROUTE_REDISTRIBUTE
, &label
);
2383 bgp_attr_extra_free (&new_attr
);
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.
2393 for (rc
= skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2394 (void **) &bi_exterior
, NULL
, &cursor
);
2396 rc
= skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2397 (void **) &bi_exterior
, NULL
, &cursor
))
2401 skiplist_delete (RFAPI_MONITOR_EXTERIOR (par
)->source
,
2403 route_unlock_node (par
); /* sl entry */
2405 if (skiplist_empty (RFAPI_MONITOR_EXTERIOR (par
)->source
))
2407 skiplist_free (RFAPI_MONITOR_EXTERIOR (par
)->source
);
2408 RFAPI_MONITOR_EXTERIOR (par
)->source
= NULL
;
2409 route_unlock_node (par
); /* sl itself */
2413 zlog_debug ("%s: checking orphans", __func__
);
2416 * See if any orphans can be pulled down to the current node
2419 list_adopted
= NULL
;
2420 for (rc
= skiplist_next (it
->monitor_exterior_orphans
,
2421 (void **) &bi_exterior
, (void **) &pfx_exterior
,
2424 skiplist_next (it
->monitor_exterior_orphans
, (void **) &bi_exterior
,
2425 (void **) &pfx_exterior
, &cursor
))
2428 struct prefix pfx_nexthop
;
2430 afi_t afi_exterior
= family2afi (pfx_exterior
->family
);
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
);
2436 if (afi_exterior
!= afi
)
2438 zlog_debug ("%s: exterior orphan afi %d != interior afi %d, skip",
2439 __func__
, afi_exterior
, afi
);
2443 /* check original nexthop for prefix match */
2444 rfapiUnicastNexthop2Prefix (afi
, bi_exterior
->attr
, &pfx_nexthop
);
2446 if (prefix_match (&rn_interior
->p
, &pfx_nexthop
))
2449 struct prefix_rd
*prd
;
2450 struct attr new_attr
;
2451 u_int32_t label
= 0;
2456 * add monitor to longer prefix
2459 struct prefix
*pfx_mon
= prefix_new ();
2460 prefix_copy (pfx_mon
, pfx_exterior
);
2461 if (!RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
)
2463 RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
=
2464 skiplist_new (0, NULL
, (void (*)(void *)) prefix_free
);
2465 route_lock_node (rn_interior
); /* sl */
2467 skiplist_insert (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2468 bi_exterior
, pfx_mon
);
2469 route_lock_node (rn_interior
); /* sl entry */
2472 list_adopted
= list_new ();
2474 listnode_add (list_adopted
, bi_exterior
);
2477 * Add constructed exterior routes based on the
2478 * new interior route at the longer prefix.
2480 if (bi_interior
->extra
)
2482 prd
= &bi_interior
->extra
->vnc
.import
.rd
;
2483 label
= decode_label (bi_interior
->extra
->tag
);
2488 /* use local_pref from unicast route */
2489 memset (&new_attr
, 0, sizeof (struct attr
));
2490 bgp_attr_dup (&new_attr
, bi_interior
->attr
);
2492 (bi_exterior
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
)))
2494 new_attr
.local_pref
= bi_exterior
->attr
->local_pref
;
2495 new_attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
2498 rfapiBgpInfoFilteredImportVPN (it
, FIF_ACTION_UPDATE
, bi_interior
->peer
, NULL
, /* rfd */
2504 ZEBRA_ROUTE_BGP_DIRECT_EXT
,
2505 BGP_ROUTE_REDISTRIBUTE
, &label
);
2507 bgp_attr_extra_free (&new_attr
);
2512 struct listnode
*node
;
2513 struct route_node
*bi_exterior
;
2515 for (ALL_LIST_ELEMENTS_RO (list_adopted
, node
, bi_exterior
))
2517 skiplist_delete (it
->monitor_exterior_orphans
, bi_exterior
, NULL
);
2519 list_delete (list_adopted
);
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.
2530 * NB should also be called whenever an existing vpn interior route
2531 * becomes invalid (e.g., valid_interior_count is decremented)
2534 vnc_import_bgp_exterior_del_route_interior (
2536 struct rfapi_import_table
*it
,
2537 struct route_node
*rn_interior
, /* VPN IT node */
2538 struct bgp_info
*bi_interior
) /* VPN IT route */
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 */
2547 if (!VALID_INTERIOR_TYPE (bi_interior
->type
))
2549 zlog_debug ("%s: type %d not valid interior type, skipping",
2550 __func__
, bi_interior
->type
);
2554 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
])
2556 zlog_debug ("%s: redist of exterior routes no enabled, skipping",
2561 if (it
== bgp
->rfapi
->it_ce
)
2563 zlog_debug ("%s: it is it_ce, skipping", __func__
);
2567 /* If no exterior routes depend on this prefix, nothing to do */
2568 if (!RFAPI_HAS_MONITOR_EXTERIOR (rn_interior
))
2570 zlog_debug ("%s: no exterior monitor, skipping", __func__
);
2576 char str_pfx
[BUFSIZ
];
2578 prefix2str (&rn_interior
->p
, str_pfx
, BUFSIZ
);
2579 str_pfx
[BUFSIZ
- 1] = 0;
2581 zlog_debug ("%s: interior prefix=%s, bi type=%d",
2582 __func__
, str_pfx
, bi_interior
->type
);
2586 * Remove constructed routes based on the deleted interior route
2589 for (rc
= skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2590 (void **) &bi_exterior
, (void **) &pfx_exterior
,
2593 skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2594 (void **) &bi_exterior
, (void **) &pfx_exterior
,
2598 struct prefix_rd
*prd
;
2599 u_int32_t label
= 0;
2601 if (bi_interior
->extra
)
2603 prd
= &bi_interior
->extra
->vnc
.import
.rd
;
2604 label
= decode_label (bi_interior
->extra
->tag
);
2609 rfapiBgpInfoFilteredImportVPN (it
, FIF_ACTION_KILL
, bi_interior
->peer
, NULL
, /* rfd */
2615 ZEBRA_ROUTE_BGP_DIRECT_EXT
,
2616 BGP_ROUTE_REDISTRIBUTE
, &label
);
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
2623 if (RFAPI_MONITOR_EXTERIOR (rn_interior
)->valid_interior_count
)
2625 zlog_debug ("%s: interior routes still present, skipping", __func__
);
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
2634 for (par
= rn_interior
->parent
; par
; par
= par
->parent
)
2636 if (RFAPI_MONITOR_EXTERIOR (par
)->valid_interior_count
)
2640 zlog_debug ("%s: par=%p, ext src: %p", __func__
,
2641 par
, RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
);
2643 /* move all monitors */
2645 * We will use and delete every element of the source skiplist
2647 while (!skiplist_first (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2648 (void **) &bi_exterior
, (void **) &pfx_exterior
))
2651 struct prefix
*pfx_mon
= prefix_new ();
2653 prefix_copy (pfx_mon
, pfx_exterior
);
2658 struct bgp_info
*bi
;
2661 * Add monitor to parent node
2663 if (!RFAPI_MONITOR_EXTERIOR (par
)->source
)
2665 RFAPI_MONITOR_EXTERIOR (par
)->source
=
2666 skiplist_new (0, NULL
, (void (*)(void *)) prefix_free
);
2667 route_lock_node (par
); /* sl */
2669 skiplist_insert (RFAPI_MONITOR_EXTERIOR (par
)->source
,
2670 bi_exterior
, pfx_mon
);
2671 route_lock_node (par
); /* sl entry */
2673 /* Add constructed exterior routes based on parent */
2674 for (bi
= par
->info
; bi
; bi
= bi
->next
)
2677 struct prefix_rd
*prd
;
2678 struct attr new_attr
;
2679 u_int32_t label
= 0;
2681 if (bi
->type
== ZEBRA_ROUTE_BGP_DIRECT_EXT
)
2686 prd
= &bi
->extra
->vnc
.import
.rd
;
2687 label
= decode_label (bi
->extra
->tag
);
2692 /* use local_pref from unicast route */
2693 memset (&new_attr
, 0, sizeof (struct attr
));
2694 bgp_attr_dup (&new_attr
, bi
->attr
);
2696 (bi_exterior
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
)))
2698 new_attr
.local_pref
= bi_exterior
->attr
->local_pref
;
2699 new_attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
2702 rfapiBgpInfoFilteredImportVPN (it
, FIF_ACTION_UPDATE
, bi
->peer
, NULL
, /* rfd */
2708 ZEBRA_ROUTE_BGP_DIRECT_EXT
,
2709 BGP_ROUTE_REDISTRIBUTE
, &label
);
2711 bgp_attr_extra_free (&new_attr
);
2719 * No interior route for exterior's nexthop. Save monitor
2720 * in orphan list to await future route.
2722 skiplist_insert (it
->monitor_exterior_orphans
,
2723 bi_exterior
, pfx_mon
);
2726 skiplist_delete_first (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
);
2727 route_unlock_node (rn_interior
); /* sl entry */
2729 if (skiplist_empty (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
))
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 */
2738 /***********************************************************************
2739 * Generic add/delete unicast routes
2740 ***********************************************************************/
2743 vnc_import_bgp_add_route (
2745 struct prefix
*prefix
,
2746 struct bgp_info
*info
)
2748 afi_t afi
= family2afi (prefix
->family
);
2751 struct prefix pfx_nexthop
;
2753 char buf_nh
[BUFSIZ
];
2755 prefix2str (prefix
, buf
, BUFSIZ
);
2756 rfapiUnicastNexthop2Prefix (afi
, info
->attr
, &pfx_nexthop
);
2757 prefix2str (&pfx_nexthop
, buf_nh
, BUFSIZ
);
2759 zlog_debug ("%s: pfx %s, nh %s", __func__
, buf
, buf_nh
);
2762 print_rhn_list(__func__
, "ENTER ");
2768 zlog_err ("%s: can't get afi of prefix", __func__
);
2772 if (!bgp
->rfapi_cfg
)
2774 zlog_debug ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
2778 /* check vnc redist flag for bgp direct routes */
2779 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
2782 ("%s: bgp->rfapi_cfg->redist[afi=%d][type=%d=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping",
2783 __func__
, afi
, ZEBRA_ROUTE_BGP_DIRECT
);
2787 switch (bgp
->rfapi_cfg
->redist_mode
)
2789 case VNC_REDIST_MODE_PLAIN
:
2790 vnc_import_bgp_add_route_mode_plain (bgp
, prefix
, info
);
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
);
2798 zlog_debug ("%s: mode RFG but no redist RFG", __func__
);
2801 case VNC_REDIST_MODE_RESOLVE_NVE
:
2802 vnc_import_bgp_add_route_mode_resolve_nve (bgp
, prefix
, info
);
2806 print_rhn_list(__func__
, "LEAVE ");
2812 * "Withdrawing a Route" import process
2815 vnc_import_bgp_del_route (
2817 struct prefix
*prefix
,
2818 struct bgp_info
*info
) /* unicast info */
2820 afi_t afi
= family2afi (prefix
->family
);
2825 struct prefix pfx_nexthop
;
2827 char buf_nh
[BUFSIZ
];
2829 prefix2str (prefix
, buf
, BUFSIZ
);
2830 rfapiUnicastNexthop2Prefix (afi
, info
->attr
, &pfx_nexthop
);
2831 prefix2str (&pfx_nexthop
, buf_nh
, BUFSIZ
);
2833 zlog_debug ("%s: pfx %s, nh %s", __func__
, buf
, buf_nh
);
2836 print_rhn_list(__func__
, "ENTER ");
2840 if (!bgp
->rfapi_cfg
)
2842 zlog_debug ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
2846 /* check bgp redist flag for vnc direct ("vpn") routes */
2847 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
2849 zlog_debug ("%s: bgp redistribution of afi=%d VNC direct routes is off",
2854 switch (bgp
->rfapi_cfg
->redist_mode
)
2856 case VNC_REDIST_MODE_PLAIN
:
2857 vnc_import_bgp_del_route_mode_plain (bgp
, prefix
, info
);
2860 case VNC_REDIST_MODE_RFG
:
2861 if (bgp
->rfapi_cfg
->rfg_redist
)
2862 vnc_import_bgp_del_route_mode_nvegroup (bgp
, prefix
, info
);
2864 zlog_debug ("%s: mode RFG but no redist RFG", __func__
);
2867 case VNC_REDIST_MODE_RESOLVE_NVE
:
2868 vnc_import_bgp_del_route_mode_resolve_nve (bgp
, afi
, prefix
, info
);
2873 print_rhn_list(__func__
, "LEAVE ");
2879 /***********************************************************************
2881 ***********************************************************************/
2884 vnc_import_bgp_redist_enable (struct bgp
*bgp
, afi_t afi
)
2886 /* iterate over bgp unicast v4 and v6 routes, call vnc_import_bgp_add_route */
2888 struct bgp_node
*rn
;
2890 zlog_debug ("%s: entry, afi=%d", __func__
, afi
);
2892 if (bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
2894 zlog_debug ("%s: already enabled for afi %d, skipping", __func__
, afi
);
2897 bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
] = 1;
2899 for (rn
= bgp_table_top (bgp
->rib
[afi
][SAFI_UNICAST
]);
2900 rn
; rn
= bgp_route_next (rn
))
2903 struct bgp_info
*bi
;
2905 for (bi
= rn
->info
; bi
; bi
= bi
->next
)
2908 if (CHECK_FLAG (bi
->flags
, BGP_INFO_REMOVED
))
2911 vnc_import_bgp_add_route (bgp
, &rn
->p
, bi
);
2914 zlog_debug ("%s: set redist[afi=%d][type=%d=ZEBRA_ROUTE_BGP_DIRECT] return",
2915 __func__
, afi
, ZEBRA_ROUTE_BGP_DIRECT
);
2919 vnc_import_bgp_exterior_redist_enable (struct bgp
*bgp
, afi_t afi
)
2921 struct bgp
*bgp_exterior
;
2922 struct bgp_node
*rn
;
2924 bgp_exterior
= bgp
->rfapi_cfg
->redist_bgp_exterior_view
;
2926 if (bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
])
2928 zlog_debug ("%s: already enabled for afi %d, skipping", __func__
, afi
);
2931 bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
] = 1;
2935 zlog_debug ("%s: no exterior view set yet, no routes to import yet",
2940 for (rn
= bgp_table_top (bgp_exterior
->rib
[afi
][SAFI_UNICAST
]);
2941 rn
; rn
= bgp_route_next (rn
))
2944 struct bgp_info
*bi
;
2946 for (bi
= rn
->info
; bi
; bi
= bi
->next
)
2949 if (CHECK_FLAG (bi
->flags
, BGP_INFO_REMOVED
))
2952 vnc_import_bgp_exterior_add_route (bgp_exterior
, &rn
->p
, bi
);
2955 zlog_debug ("%s: set redist[afi=%d][type=%d=ZEBRA_ROUTE_BGP_DIRECT] return",
2956 __func__
, afi
, ZEBRA_ROUTE_BGP_DIRECT
);
2961 * This function is for populating a newly-created Import Table
2964 vnc_import_bgp_exterior_redist_enable_it (
2967 struct rfapi_import_table
*it_only
)
2969 struct bgp
*bgp_exterior
;
2970 struct bgp_node
*rn
;
2972 zlog_debug ("%s: entry", __func__
);
2974 bgp_exterior
= bgp
->rfapi_cfg
->redist_bgp_exterior_view
;
2976 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
])
2978 zlog_debug ("%s: not enabled for afi %d, skipping", __func__
, afi
);
2984 zlog_debug ("%s: no exterior view set yet, no routes to import yet",
2989 for (rn
= bgp_table_top (bgp_exterior
->rib
[afi
][SAFI_UNICAST
]);
2990 rn
; rn
= bgp_route_next (rn
))
2993 struct bgp_info
*bi
;
2995 for (bi
= rn
->info
; bi
; bi
= bi
->next
)
2998 if (CHECK_FLAG (bi
->flags
, BGP_INFO_REMOVED
))
3001 vnc_import_bgp_exterior_add_route_it (bgp_exterior
, &rn
->p
, bi
,
3010 vnc_import_bgp_redist_disable (struct bgp
*bgp
, afi_t afi
)
3013 * iterate over vpn routes, find routes of type ZEBRA_ROUTE_BGP_DIRECT,
3014 * delete (call timer expire immediately)
3016 struct bgp_node
*rn1
;
3017 struct bgp_node
*rn2
;
3019 zlog_debug ("%s: entry", __func__
);
3021 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
3023 zlog_debug ("%s: already disabled for afi %d, skipping", __func__
, afi
);
3028 * Two-level table for SAFI_MPLS_VPN
3029 * Be careful when changing the things we iterate over
3031 for (rn1
= bgp_table_top (bgp
->rib
[afi
][SAFI_MPLS_VPN
]);
3032 rn1
; rn1
= bgp_route_next (rn1
))
3037 for (rn2
= bgp_table_top (rn1
->info
);
3038 rn2
; rn2
= bgp_route_next (rn2
))
3041 struct bgp_info
*bi
;
3042 struct bgp_info
*nextbi
;
3044 for (bi
= rn2
->info
; bi
; bi
= nextbi
)
3049 if (bi
->type
== ZEBRA_ROUTE_BGP_DIRECT
)
3052 struct rfapi_descriptor
*rfd
;
3053 vncHDBgpDirect
.peer
= bi
->peer
;
3055 rfd
= bi
->extra
->vnc
.export
.rfapi_handle
;
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
);
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 */
3066 vncHDBgpDirect
.peer
= NULL
;
3072 /* Clear RHN list */
3073 if (bgp
->rfapi
->resolve_nve_nexthop
)
3075 struct prefix_bag
*pb
;
3076 struct bgp_info
*info
;
3077 while (!skiplist_first
3078 (bgp
->rfapi
->resolve_nve_nexthop
, NULL
, (void *) &pb
))
3081 skiplist_delete_first (bgp
->rfapi
->resolve_nve_nexthop
);
3082 bgp_info_unlock (info
);
3086 bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
] = 0;
3087 zlog_debug ("%s: return", __func__
);
3092 vnc_import_bgp_exterior_redist_disable (struct bgp
*bgp
, afi_t afi
)
3094 struct rfapi_cfg
*hc
= bgp
->rfapi_cfg
;
3095 struct bgp
*bgp_exterior
= hc
->redist_bgp_exterior_view
;
3097 zlog_debug ("%s: entry", __func__
);
3099 if (!hc
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
])
3101 zlog_debug ("%s: already disabled for afi %d, skipping", __func__
, afi
);
3107 zlog_debug ("%s: bgp exterior view not defined, skipping", __func__
);
3113 struct bgp_node
*rn
;
3114 for (rn
= bgp_table_top (bgp_exterior
->rib
[afi
][SAFI_UNICAST
]);
3115 rn
; rn
= bgp_route_next (rn
))
3118 struct bgp_info
*bi
;
3120 for (bi
= rn
->info
; bi
; bi
= bi
->next
)
3123 if (CHECK_FLAG (bi
->flags
, BGP_INFO_REMOVED
))
3126 vnc_import_bgp_exterior_del_route (bgp_exterior
, &rn
->p
, bi
);
3130 print_rhn_list (__func__
, NULL
);
3134 bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
] = 0;
3135 zlog_debug ("%s: return", __func__
);