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
)
213 struct skiplistnode
*p
;
214 struct prefix_bag
*pb
;
217 bgp
= bgp_get_default ();
221 sl
= bgp
->frapi
->resolve_nve_nexthop
;
224 vnc_zlog_debug_verbose ("%s: %s: RHN List is empty", (tag1
? tag1
: ""),
229 vnc_zlog_debug_verbose ("%s: %s: RHN list:", (tag1
? tag1
: ""), (tag2
? tag2
: ""));
231 /* XXX uses secret knowledge of skiplist structure */
232 for (p
= sl
->header
->forward
[0]; p
; p
= p
->forward
[0])
240 prefix2str (p
->key
, kbuf
, BUFSIZ
);
241 prefix2str (&pb
->hpfx
, hbuf
, BUFSIZ
);
242 prefix2str (&pb
->upfx
, ubuf
, BUFSIZ
);
244 vnc_zlog_debug_verbose ("RHN Entry %d (q=%p): kpfx=%s, upfx=%s, hpfx=%s, ubi=%p",
245 ++count
, p
, kbuf
, ubuf
, hbuf
, pb
->ubi
);
250 #ifdef ENABLE_VNC_RHNCK
252 vnc_rhnck (char *tag
)
256 struct skiplistnode
*p
;
258 bgp
= bgp_get_default ();
261 sl
= bgp
->rfapi
->resolve_nve_nexthop
;
266 /* XXX uses secret knowledge of skiplist structure */
267 for (p
= sl
->header
->forward
[0]; p
; p
= p
->forward
[0])
269 struct prefix_bag
*pb
;
272 struct prefix pfx_orig_nexthop
;
274 memset (&pfx_orig_nexthop
, 0, sizeof (struct prefix
)); /* keep valgrind happy */
279 afi
= family2afi (pb
->upfx
.family
);
281 rfapiUnicastNexthop2Prefix (afi
, pb
->ubi
->attr
, &pfx_orig_nexthop
);
283 /* pb->hpfx, pb->ubi nexthop, pkey should all reflect the same pfx */
284 assert (!vnc_prefix_cmp (&pb
->hpfx
, pkey
));
285 if (vnc_prefix_cmp (&pb
->hpfx
, &pfx_orig_nexthop
))
287 char str_onh
[BUFSIZ
];
288 char str_nve_pfx
[BUFSIZ
];
290 prefix2str (&pfx_orig_nexthop
, str_onh
, BUFSIZ
);
291 str_onh
[BUFSIZ
- 1] = 0;
293 prefix2str (&pb
->hpfx
, str_nve_pfx
, BUFSIZ
);
294 str_nve_pfx
[BUFSIZ
- 1] = 0;
296 vnc_zlog_debug_verbose
297 ("%s: %s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s",
298 __func__
, tag
, str_onh
, str_nve_pfx
);
302 vnc_zlog_debug_verbose ("%s: vnc_rhnck OK", tag
);
305 #define VNC_RHNCK(n) do {char buf[BUFSIZ];sprintf(buf,"%s: %s", __func__, #n);vnc_rhnck(buf);} while (0)
313 /***********************************************************************
314 * Add/Delete Unicast Route
315 ***********************************************************************/
318 * "Adding a Route" import process
322 * extract and package information from the BGP unicast route.
323 * Return code 0 means OK, non-0 means drop.
325 * If return code is 0, caller MUST release ecom
328 process_unicast_route (
329 struct bgp
*bgp
, /* in */
331 struct prefix
*prefix
, /* in */
332 struct bgp_info
*info
, /* in */
333 struct ecommunity
**ecom
, /* OUT */
334 struct prefix
*unicast_nexthop
) /* OUT */
336 struct rfapi_cfg
*hc
= bgp
->rfapi_cfg
;
337 struct peer
*peer
= info
->peer
;
338 struct attr
*attr
= info
->attr
;
340 struct route_map
*rmap
= NULL
;
341 struct prefix pfx_orig_nexthop
;
343 memset (&pfx_orig_nexthop
, 0, sizeof (struct prefix
)); /* keep valgrind happy */
348 if (hc
->plist_redist
[ZEBRA_ROUTE_BGP_DIRECT
][afi
])
350 vnc_zlog_debug_verbose ("%s: HC prefix list is set, checking", __func__
);
351 if (prefix_list_apply
352 (hc
->plist_redist
[ZEBRA_ROUTE_BGP_DIRECT
][afi
],
353 prefix
) == PREFIX_DENY
)
355 vnc_zlog_debug_verbose ("%s: prefix list returns DENY, blocking route",
359 vnc_zlog_debug_verbose ("%s: prefix list returns PASS, allowing route", __func__
);
362 /* apply routemap, if any, later */
363 rmap
= hc
->routemap_redist
[ZEBRA_ROUTE_BGP_DIRECT
];
366 * Extract original nexthop, which we expect to be a NVE connected router
367 * Note that this is the nexthop before any possible application of policy
370 * Incoming prefix is unicast. If v6, it is in multiprotocol area,
371 * but if v4 it is in attr->nexthop
373 rfapiUnicastNexthop2Prefix (afi
, attr
, &pfx_orig_nexthop
);
377 * This code is here because it allocates an interned attr which
378 * must be freed before we return. It's easier to put it after
379 * all of the possible returns above.
381 memset (&hattr
, 0, sizeof (struct attr
));
382 bgp_attr_dup (&hattr
, attr
); /* hattr becomes a ghost attr */
386 struct bgp_info info
;
387 route_map_result_t ret
;
389 memset (&info
, 0, sizeof (info
));
392 ret
= route_map_apply (rmap
, prefix
, RMAP_BGP
, &info
);
393 if (ret
== RMAP_DENYMATCH
)
395 bgp_attr_flush (&hattr
);
396 bgp_attr_extra_free (&hattr
);
397 vnc_zlog_debug_verbose ("%s: route map \"%s\" says DENY, returning", __func__
,
404 * Get the (possibly altered by policy) unicast nexthop
405 * for later lookup in the Import Table by caller
407 rfapiUnicastNexthop2Prefix (afi
, &hattr
, unicast_nexthop
);
409 if (hattr
.extra
&& hattr
.extra
->ecommunity
)
410 *ecom
= ecommunity_dup (hattr
.extra
->ecommunity
);
412 *ecom
= ecommunity_new ();
415 * Done with hattr, clean up
417 bgp_attr_flush (&hattr
);
418 bgp_attr_extra_free (&hattr
);
421 * Add EC that carries original NH of iBGP route (2 bytes = magic
422 * value indicating it came from an VNC gateway; default 5226, but
423 * must be user configurable). Note that this is the nexthop before
424 * any application of policy.
427 struct ecommunity_val vnc_gateway_magic
;
430 /* Using route origin extended community type */
431 memset (&vnc_gateway_magic
, 0, sizeof (vnc_gateway_magic
));
432 vnc_gateway_magic
.val
[0] = 0x01;
433 vnc_gateway_magic
.val
[1] = 0x03;
435 /* Only works for IPv4 nexthops */
436 if (prefix
->family
== AF_INET
)
438 memcpy (vnc_gateway_magic
.val
+ 2, &unicast_nexthop
->u
.prefix4
, 4);
440 localadmin
= htons (hc
->resolve_nve_roo_local_admin
);
441 memcpy (vnc_gateway_magic
.val
+ 6, (char *) &localadmin
, 2);
443 ecommunity_add_val (*ecom
, &vnc_gateway_magic
);
451 vnc_import_bgp_add_route_mode_resolve_nve_one_bi (
454 struct bgp_info
*bi
, /* VPN bi */
455 struct prefix_rd
*prd
, /* RD */
456 struct prefix
*prefix
, /* unicast route prefix */
457 uint32_t *local_pref
,/* NULL = no local_pref */
458 uint32_t *med
, /* NULL = no med */
459 struct ecommunity
*ecom
) /* generated ecoms */
462 struct prefix nexthop
;
463 struct rfapi_ip_addr nexthop_h
;
466 struct bgp_attr_encap_subtlv
*encaptlvs
;
469 struct rfapi_un_option optary
[3];
470 struct rfapi_un_option
*opt
= NULL
;
473 vnc_zlog_debug_verbose ("%s: entry", __func__
);
475 if (bi
->type
!= ZEBRA_ROUTE_BGP
&& bi
->type
!= ZEBRA_ROUTE_BGP_DIRECT
)
480 if (bi
->sub_type
!= BGP_ROUTE_NORMAL
&&
481 bi
->sub_type
!= BGP_ROUTE_STATIC
&& bi
->sub_type
!= BGP_ROUTE_RFP
)
486 if (CHECK_FLAG (bi
->flags
, BGP_INFO_REMOVED
))
489 vncHDResolveNve
.peer
= bi
->peer
;
490 if (!rfapiGetVncTunnelUnAddr (bi
->attr
, &un
))
492 if (rfapiQprefix2Raddr (&un
, &vncHDResolveNve
.un_addr
))
497 memset (&vncHDResolveNve
.un_addr
, 0, sizeof (vncHDResolveNve
.un_addr
));
500 /* Use nexthop of VPN route as nexthop of constructed route */
501 rfapiNexthop2Prefix (bi
->attr
, &nexthop
);
502 rfapiQprefix2Raddr (&nexthop
, &nexthop_h
);
504 if (rfapiGetVncLifetime (bi
->attr
, &lifetime
))
510 plifetime
= &lifetime
;
513 if (bi
->attr
&& bi
->attr
->extra
)
515 encaptlvs
= bi
->attr
->extra
->vnc_subtlvs
;
516 if (bi
->attr
->extra
->encap_tunneltype
!= BGP_ENCAP_TYPE_MPLS
)
519 opt
->next
= &optary
[cur_opt
];
520 opt
= &optary
[cur_opt
++];
521 memset (opt
, 0, sizeof (struct rfapi_un_option
));
522 opt
->type
= RFAPI_UN_OPTION_TYPE_TUNNELTYPE
;
523 opt
->v
.tunnel
.type
= bi
->attr
->extra
->encap_tunneltype
;
524 /* TBD parse bi->attr->extra->encap_subtlvs */
532 struct ecommunity
*new_ecom
= ecommunity_dup (ecom
);
534 if (bi
->attr
&& bi
->attr
->extra
&& bi
->attr
->extra
->ecommunity
)
535 ecommunity_merge (new_ecom
, bi
->attr
->extra
->ecommunity
);
538 label
= decode_label (bi
->extra
->tag
);
544 prefix
, /* unicast route prefix */
546 &nexthop_h
, /* new nexthop */
549 (struct bgp_tea_options
*) encaptlvs
, /* RFP options */
553 med
, /* NULL => don't set med */
554 (label
?&label
:NULL
), /* NULL= default */
555 ZEBRA_ROUTE_BGP_DIRECT
,
556 BGP_ROUTE_REDISTRIBUTE
,
557 RFAPI_AHR_RFPOPT_IS_VNCTLV
); /* flags */
559 ecommunity_free (&new_ecom
);
564 vnc_import_bgp_add_route_mode_resolve_nve_one_rd (
565 struct prefix_rd
*prd
, /* RD */
566 struct bgp_table
*table_rd
, /* per-rd VPN route table */
569 struct prefix
*prefix
, /* unicast prefix */
570 struct ecommunity
*ecom
, /* generated ecoms */
571 uint32_t *local_pref
, /* NULL = no local_pref */
572 uint32_t *med
, /* NULL = no med */
573 struct prefix
*ubi_nexthop
) /* unicast nexthop */
584 prefix2str (ubi_nexthop
, str_nh
, BUFSIZ
);
585 str_nh
[BUFSIZ
- 1] = 0;
587 vnc_zlog_debug_verbose ("%s: ubi_nexthop=%s", __func__
, str_nh
);
591 bn
= bgp_node_lookup (table_rd
, ubi_nexthop
);
594 vnc_zlog_debug_verbose ("%s: no match in RD's table for ubi_nexthop", __func__
);
598 /* Iterate over bgp_info items at this node */
599 for (bi
= bn
->info
; bi
; bi
= bi
->next
)
602 vnc_import_bgp_add_route_mode_resolve_nve_one_bi (bgp
, afi
, bi
, /* VPN bi */
609 bgp_unlock_node (bn
);
613 vnc_import_bgp_add_route_mode_resolve_nve (
615 struct prefix
*prefix
,/* unicast prefix */
616 struct bgp_info
*info
) /* unicast info */
618 afi_t afi
= family2afi (prefix
->family
);
619 struct rfapi_cfg
*hc
= NULL
;
621 struct prefix pfx_unicast_nexthop
= { 0 }; /* happy valgrind */
623 struct ecommunity
*ecom
= NULL
;
625 uint32_t *med
= NULL
;
627 struct prefix_bag
*pb
;
628 struct bgp_node
*bnp
; /* prd table node */
632 char str_pfx
[BUFSIZ
];
636 prefix2str (prefix
, str_pfx
, BUFSIZ
);
637 str_pfx
[BUFSIZ
- 1] = 0;
640 rfapiUnicastNexthop2Prefix (afi
, info
->attr
, &nh
);
643 prefix2str (&nh
, str_nh
, BUFSIZ
);
644 str_nh
[BUFSIZ
- 1] = 0;
652 vnc_zlog_debug_verbose ("%s(bgp=%p, unicast prefix=%s, unicast nh=%s)",
653 __func__
, bgp
, str_pfx
, str_nh
);
656 if (info
->type
!= ZEBRA_ROUTE_BGP
)
658 vnc_zlog_debug_verbose ("%s: unicast type %d=\"%s\" is not %d=%s, skipping",
659 __func__
, info
->type
, zebra_route_string (info
->type
),
660 ZEBRA_ROUTE_BGP
, "ZEBRA_ROUTE_BGP");
670 zlog_err ("%s: can't get afi of prefix", __func__
);
674 if (!(hc
= bgp
->rfapi_cfg
))
676 vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
680 /* check vnc redist flag for bgp direct routes */
681 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
683 vnc_zlog_debug_verbose
684 ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping",
690 if (process_unicast_route (bgp
, afi
, prefix
, info
,
691 &ecom
, &pfx_unicast_nexthop
))
694 vnc_zlog_debug_verbose ("%s: process_unicast_route error, skipping", __func__
);
698 local_pref
= calc_local_pref (info
->attr
, info
->peer
);
700 (info
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
)))
703 med
= &info
->attr
->med
;
708 * At this point, we have allocated:
710 * ecom ecommunity ptr, union of unicast and ROO parts (no NVE part)
714 * pfx_unicast_nexthop nexthop of uncast route
717 if (!bgp
->rfapi
->resolve_nve_nexthop
)
719 bgp
->rfapi
->resolve_nve_nexthop
=
720 skiplist_new (SKIPLIST_FLAG_ALLOW_DUPLICATES
, vnc_prefix_cmp
,
724 pb
= XCALLOC (MTYPE_RFAPI_PREFIX_BAG
, sizeof (struct prefix_bag
));
725 pb
->hpfx
= pfx_unicast_nexthop
;
729 bgp_info_lock (info
); /* skiplist refers to it */
730 skiplist_insert (bgp
->rfapi
->resolve_nve_nexthop
, &pb
->hpfx
, pb
);
733 * Iterate over RDs in VPN RIB. For each RD, look up unicast nexthop
734 * (exact match, /32). If an exact match is found, call add_vnc_route.
737 for (bnp
= bgp_table_top (bgp
->rib
[afi
][SAFI_MPLS_VPN
]); bnp
;
738 bnp
= bgp_route_next (bnp
))
741 struct bgp_table
*table
;
743 table
= (struct bgp_table
*) (bnp
->info
);
748 vnc_import_bgp_add_route_mode_resolve_nve_one_rd ((struct prefix_rd
*)
752 &pfx_unicast_nexthop
);
758 ecommunity_free (&ecom
);
760 vnc_zlog_debug_verbose ("%s: done", __func__
);
765 vnc_import_bgp_add_route_mode_plain (struct bgp
*bgp
,
766 struct prefix
*prefix
,
767 struct bgp_info
*info
)
769 afi_t afi
= family2afi (prefix
->family
);
770 struct peer
*peer
= info
->peer
;
771 struct attr
*attr
= info
->attr
;
773 struct rfapi_cfg
*hc
= NULL
;
774 struct attr
*iattr
= NULL
;
776 struct rfapi_ip_addr vnaddr
;
777 struct prefix vn_pfx_space
;
778 struct prefix
*vn_pfx
= NULL
;
780 struct ecommunity
*ecom
= NULL
;
781 struct prefix_rd prd
;
782 struct route_map
*rmap
= NULL
;
784 uint32_t *med
= NULL
;
790 prefix2str (prefix
, buf
, BUFSIZ
);
792 vnc_zlog_debug_verbose ("%s(prefix=%s) entry", __func__
, buf
);
797 zlog_err ("%s: can't get afi of prefix", __func__
);
801 if (!(hc
= bgp
->rfapi_cfg
))
803 vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
807 /* check vnc redist flag for bgp direct routes */
808 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
810 vnc_zlog_debug_verbose
811 ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping",
817 * mode "plain" specific code
820 vnc_zlog_debug_verbose ("%s: NOT using redist RFG", __func__
);
825 if (hc
->plist_redist
[ZEBRA_ROUTE_BGP_DIRECT
][afi
])
827 vnc_zlog_debug_verbose ("%s: HC prefix list is set, checking", __func__
);
828 if (prefix_list_apply
829 (hc
->plist_redist
[ZEBRA_ROUTE_BGP_DIRECT
][afi
],
830 prefix
) == PREFIX_DENY
)
832 vnc_zlog_debug_verbose ("%s: prefix list returns DENY, blocking route",
836 vnc_zlog_debug_verbose ("%s: prefix list returns PASS, allowing route", __func__
);
839 /* apply routemap, if any, later */
840 rmap
= hc
->routemap_redist
[ZEBRA_ROUTE_BGP_DIRECT
];
843 * Incoming prefix is unicast. If v6, it is in multiprotocol area,
844 * but if v4 it is in attr->nexthop
846 rfapiUnicastNexthop2Prefix (afi
, attr
, &vn_pfx_space
);
847 vn_pfx
= &vn_pfx_space
;
850 ahr_flags
|= RFAPI_AHR_NO_TUNNEL_SUBTLV
;
853 if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE
))
858 prefix2str (vn_pfx
, buf
, BUFSIZ
);
860 vnc_zlog_debug_any ("%s vn_pfx=%s", __func__
, buf
);
866 if (rfapiQprefix2Raddr (vn_pfx
, &vnaddr
))
868 vnc_zlog_debug_verbose ("%s: redist VN invalid, skipping", __func__
);
874 * This code is here because it allocates an interned attr which
875 * must be freed before we return. It's easier to put it after
876 * all of the possible returns above.
878 memset (&hattr
, 0, sizeof (struct attr
));
879 bgp_attr_dup (&hattr
, attr
); /* hattr becomes a ghost attr */
883 struct bgp_info info
;
884 route_map_result_t ret
;
886 memset (&info
, 0, sizeof (info
));
889 ret
= route_map_apply (rmap
, prefix
, RMAP_BGP
, &info
);
890 if (ret
== RMAP_DENYMATCH
)
892 bgp_attr_flush (&hattr
);
893 bgp_attr_extra_free (&hattr
);
894 vnc_zlog_debug_verbose ("%s: route map \"%s\" says DENY, returning", __func__
,
900 iattr
= bgp_attr_intern (&hattr
);
901 bgp_attr_flush (&hattr
);
902 bgp_attr_extra_free (&hattr
);
904 /* Now iattr is an allocated interned attr */
907 * Mode "plain" specific code
909 * Sets RD in dummy HD
913 if (vnaddr
.addr_family
!= AF_INET
)
915 vnc_zlog_debug_verbose
916 ("%s: can't auto-assign RD, VN AF (%d) is not IPv4, skipping",
917 __func__
, vnaddr
.addr_family
);
920 bgp_attr_unintern (&iattr
);
924 memset (&prd
, 0, sizeof (prd
));
925 rfapi_set_autord_from_vn (&prd
, &vnaddr
);
927 if (iattr
&& iattr
->extra
&& iattr
->extra
->ecommunity
)
928 ecom
= ecommunity_dup (iattr
->extra
->ecommunity
);
932 local_pref
= calc_local_pref (iattr
, peer
);
934 if (iattr
&& (iattr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
)))
939 if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE
))
944 rfapiRfapiIpAddr2Str (&vnaddr
, buf
, BUFSIZ
);
946 vnc_zlog_debug_any ("%s: setting vnaddr to %s", __func__
, buf
);
949 vncHDBgpDirect
.peer
= peer
;
950 add_vnc_route (&vncHDBgpDirect
, bgp
, SAFI_MPLS_VPN
, prefix
, &prd
, &vnaddr
, &local_pref
, &(bgp
->rfapi_cfg
->redist_lifetime
), NULL
, /* RFP options */
951 NULL
, NULL
, ecom
, med
, /* med */
952 NULL
, /* label: default */
953 ZEBRA_ROUTE_BGP_DIRECT
, BGP_ROUTE_REDISTRIBUTE
, ahr_flags
);
954 vncHDBgpDirect
.peer
= NULL
;
957 ecommunity_free (&ecom
);
961 vnc_import_bgp_add_route_mode_nvegroup (struct bgp
*bgp
,
962 struct prefix
*prefix
,
963 struct bgp_info
*info
,
964 struct rfapi_nve_group_cfg
*rfg
)
966 afi_t afi
= family2afi (prefix
->family
);
967 struct peer
*peer
= info
->peer
;
968 struct attr
*attr
= info
->attr
;
970 struct rfapi_cfg
*hc
= NULL
;
971 struct attr
*iattr
= NULL
;
973 struct rfapi_ip_addr vnaddr
;
974 struct prefix
*vn_pfx
= NULL
;
976 struct ecommunity
*ecom
= NULL
;
977 struct prefix_rd prd
;
978 struct route_map
*rmap
= NULL
;
985 prefix2str (prefix
, buf
, BUFSIZ
);
987 vnc_zlog_debug_verbose ("%s(prefix=%s) entry", __func__
, buf
);
994 zlog_err ("%s: can't get afi of prefix", __func__
);
998 if (!(hc
= bgp
->rfapi_cfg
))
1000 vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
1004 /* check vnc redist flag for bgp direct routes */
1005 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
1007 vnc_zlog_debug_verbose
1008 ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping",
1019 struct rfapi_ip_prefix pfx_un
;
1021 vnc_zlog_debug_verbose ("%s: using redist RFG", __func__
);
1024 * RFG prefix list check
1026 if (rfg
->plist_redist
[ZEBRA_ROUTE_BGP_DIRECT
][afi
])
1028 vnc_zlog_debug_verbose ("%s: RFG prefix list is set, checking", __func__
);
1029 if (prefix_list_apply
1030 (rfg
->plist_redist
[ZEBRA_ROUTE_BGP_DIRECT
][afi
],
1031 prefix
) == PREFIX_DENY
)
1033 vnc_zlog_debug_verbose ("%s: prefix list returns DENY, blocking route",
1037 vnc_zlog_debug_verbose ("%s: prefix list returns PASS, allowing route", __func__
);
1040 /* apply routemap, if any, later */
1041 rmap
= rfg
->routemap_redist
[ZEBRA_ROUTE_BGP_DIRECT
];
1044 * export nve group's VN addr prefix must be a /32 which
1045 * will yield the VN addr to use
1047 vn_pfx
= &rfg
->vn_prefix
;
1052 if (!is_host_prefix (&rfg
->un_prefix
))
1054 /* NB prefixlen==0 means it has not been configured */
1055 vnc_zlog_debug_verbose ("%s: redist RFG UN pfx not host pfx (plen=%d), skipping",
1056 __func__
, rfg
->un_prefix
.prefixlen
);
1060 rfapiQprefix2Rprefix (&rfg
->un_prefix
, &pfx_un
);
1062 vncHDBgpDirect
.un_addr
= pfx_un
.prefix
;
1065 if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE
))
1070 prefix2str (vn_pfx
, buf
, BUFSIZ
);
1071 buf
[BUFSIZ
- 1] = 0;
1072 vnc_zlog_debug_any ("%s vn_pfx=%s", __func__
, buf
);
1076 * Compute VN address
1078 if (rfapiQprefix2Raddr (vn_pfx
, &vnaddr
))
1080 vnc_zlog_debug_verbose ("%s: redist VN invalid, skipping", __func__
);
1085 * route map handling
1086 * This code is here because it allocates an interned attr which
1087 * must be freed before we return. It's easier to put it after
1088 * all of the possible returns above.
1090 memset (&hattr
, 0, sizeof (struct attr
));
1091 bgp_attr_dup (&hattr
, attr
); /* hattr becomes a ghost attr */
1095 struct bgp_info info
;
1096 route_map_result_t ret
;
1098 memset (&info
, 0, sizeof (info
));
1101 ret
= route_map_apply (rmap
, prefix
, RMAP_BGP
, &info
);
1102 if (ret
== RMAP_DENYMATCH
)
1104 bgp_attr_flush (&hattr
);
1105 bgp_attr_extra_free (&hattr
);
1106 vnc_zlog_debug_verbose ("%s: route map \"%s\" says DENY, returning", __func__
,
1112 iattr
= bgp_attr_intern (&hattr
);
1113 bgp_attr_flush (&hattr
);
1114 bgp_attr_extra_free (&hattr
);
1116 /* Now iattr is an allocated interned attr */
1121 * Sets RD in dummy HD
1126 memset (&prd
, 0, sizeof (prd
));
1128 prd
.family
= AF_UNSPEC
;
1131 if (rfg
->rd
.family
== AF_UNIX
)
1133 rfapi_set_autord_from_vn (&prd
, &vnaddr
);
1136 if (rfg
->rt_export_list
)
1137 ecom
= ecommunity_dup (bgp
->rfapi_cfg
->rfg_redist
->rt_export_list
);
1139 ecom
= ecommunity_new ();
1141 if (iattr
&& iattr
->extra
&& iattr
->extra
->ecommunity
)
1142 ecom
= ecommunity_merge (ecom
, iattr
->extra
->ecommunity
);
1145 local_pref
= calc_local_pref (iattr
, peer
);
1147 if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE
))
1152 rfapiRfapiIpAddr2Str (&vnaddr
, buf
, BUFSIZ
);
1153 buf
[BUFSIZ
- 1] = 0;
1154 vnc_zlog_debug_any ("%s: setting vnaddr to %s", __func__
, buf
);
1157 vncHDBgpDirect
.peer
= peer
;
1166 &(bgp
->rfapi_cfg
->redist_lifetime
),
1167 NULL
, /* RFP options */
1172 NULL
, /* label: default */
1173 ZEBRA_ROUTE_BGP_DIRECT
,
1174 BGP_ROUTE_REDISTRIBUTE
,
1176 vncHDBgpDirect
.peer
= NULL
;
1179 ecommunity_free (&ecom
);
1183 vnc_import_bgp_del_route_mode_plain (struct bgp
*bgp
,
1184 struct prefix
*prefix
,
1185 struct bgp_info
*info
)
1187 struct prefix_rd prd
;
1188 afi_t afi
= family2afi (prefix
->family
);
1189 struct prefix
*vn_pfx
= NULL
;
1190 struct rfapi_ip_addr vnaddr
;
1191 struct prefix vn_pfx_space
;
1197 * Compute VN address
1200 if (info
&& info
->attr
)
1202 rfapiUnicastNexthop2Prefix (afi
, info
->attr
, &vn_pfx_space
);
1206 vnc_zlog_debug_verbose ("%s: no attr, can't delete route", __func__
);
1209 vn_pfx
= &vn_pfx_space
;
1211 vnaddr
.addr_family
= vn_pfx
->family
;
1212 switch (vn_pfx
->family
)
1215 if (vn_pfx
->prefixlen
!= 32)
1217 vnc_zlog_debug_verbose ("%s: redist VN plen (%d) != 32, skipping",
1218 __func__
, vn_pfx
->prefixlen
);
1221 vnaddr
.addr
.v4
= vn_pfx
->u
.prefix4
;
1225 if (vn_pfx
->prefixlen
!= 128)
1227 vnc_zlog_debug_verbose ("%s: redist VN plen (%d) != 128, skipping",
1228 __func__
, vn_pfx
->prefixlen
);
1231 vnaddr
.addr
.v6
= vn_pfx
->u
.prefix6
;
1235 vnc_zlog_debug_verbose ("%s: no redist RFG VN host pfx configured, skipping",
1241 memset (&prd
, 0, sizeof (prd
));
1242 if (rfapi_set_autord_from_vn (&prd
, &vnaddr
))
1244 vnc_zlog_debug_verbose ("%s: can't auto-assign RD, skipping", __func__
);
1248 vncHDBgpDirect
.peer
= info
->peer
;
1249 vnc_zlog_debug_verbose ("%s: setting peer to %p", __func__
, vncHDBgpDirect
.peer
);
1250 del_vnc_route (&vncHDBgpDirect
,
1256 ZEBRA_ROUTE_BGP_DIRECT
, BGP_ROUTE_REDISTRIBUTE
, NULL
, 1);
1258 vncHDBgpDirect
.peer
= NULL
;
1262 vnc_import_bgp_del_route_mode_nvegroup (struct bgp
*bgp
,
1263 struct prefix
*prefix
,
1264 struct bgp_info
*info
)
1266 struct prefix_rd prd
;
1267 afi_t afi
= family2afi (prefix
->family
);
1268 struct rfapi_nve_group_cfg
*rfg
= NULL
;
1269 struct prefix
*vn_pfx
= NULL
;
1270 struct rfapi_ip_addr vnaddr
;
1275 assert ((rfg
= bgp
->rfapi_cfg
->rfg_redist
));
1278 * Compute VN address
1282 * export nve group's VN addr prefix must be a /32 which
1283 * will yield the VN addr to use
1285 vn_pfx
= &rfg
->vn_prefix
;
1288 vnaddr
.addr_family
= vn_pfx
->family
;
1289 switch (vn_pfx
->family
)
1292 if (vn_pfx
->prefixlen
!= 32)
1294 vnc_zlog_debug_verbose ("%s: redist VN plen (%d) != 32, skipping",
1295 __func__
, vn_pfx
->prefixlen
);
1298 vnaddr
.addr
.v4
= vn_pfx
->u
.prefix4
;
1302 if (vn_pfx
->prefixlen
!= 128)
1304 vnc_zlog_debug_verbose ("%s: redist VN plen (%d) != 128, skipping",
1305 __func__
, vn_pfx
->prefixlen
);
1308 vnaddr
.addr
.v6
= vn_pfx
->u
.prefix6
;
1312 vnc_zlog_debug_verbose ("%s: no redist RFG VN host pfx configured, skipping",
1317 memset (&prd
, 0, sizeof (prd
));
1319 prd
.family
= AF_UNSPEC
;
1322 if (rfg
->rd
.family
== AF_UNIX
)
1324 /* means "auto" with VN addr */
1325 if (rfapi_set_autord_from_vn (&prd
, &vnaddr
))
1327 vnc_zlog_debug_verbose ("%s: can't auto-assign RD, skipping", __func__
);
1333 vncHDBgpDirect
.peer
= info
->peer
;
1334 vnc_zlog_debug_verbose ("%s: setting peer to %p", __func__
, vncHDBgpDirect
.peer
);
1335 del_vnc_route (&vncHDBgpDirect
,
1341 ZEBRA_ROUTE_BGP_DIRECT
, BGP_ROUTE_REDISTRIBUTE
, NULL
, 1);
1343 vncHDBgpDirect
.peer
= NULL
;
1347 vnc_import_bgp_del_route_mode_resolve_nve_one_bi (
1350 struct bgp_info
*bi
, /* VPN bi */
1351 struct prefix_rd
*prd
, /* RD */
1352 struct prefix
*prefix
)/* unicast route prefix */
1356 if (bi
->type
!= ZEBRA_ROUTE_BGP
&& bi
->type
!= ZEBRA_ROUTE_BGP_DIRECT
)
1361 if (bi
->sub_type
!= BGP_ROUTE_NORMAL
&&
1362 bi
->sub_type
!= BGP_ROUTE_STATIC
&& bi
->sub_type
!= BGP_ROUTE_RFP
)
1367 if (CHECK_FLAG (bi
->flags
, BGP_INFO_REMOVED
))
1370 vncHDResolveNve
.peer
= bi
->peer
;
1371 if (!rfapiGetVncTunnelUnAddr (bi
->attr
, &un
))
1373 if (rfapiQprefix2Raddr (&un
, &vncHDResolveNve
.un_addr
))
1378 memset (&vncHDResolveNve
.un_addr
, 0, sizeof (vncHDResolveNve
.un_addr
));
1381 del_vnc_route (&vncHDResolveNve
, vncHDResolveNve
.peer
, bgp
, SAFI_MPLS_VPN
, prefix
, /* unicast route prefix */
1382 prd
, ZEBRA_ROUTE_BGP_DIRECT
, BGP_ROUTE_REDISTRIBUTE
, NULL
, 0); /* flags */
1387 vnc_import_bgp_del_route_mode_resolve_nve_one_rd (
1388 struct prefix_rd
*prd
,
1389 struct bgp_table
*table_rd
, /* per-rd VPN route table */
1392 struct prefix
*prefix
, /* unicast prefix */
1393 struct prefix
*ubi_nexthop
) /* unicast bi's nexthop */
1395 struct bgp_node
*bn
;
1396 struct bgp_info
*bi
;
1402 char str_nh
[BUFSIZ
];
1404 prefix2str (ubi_nexthop
, str_nh
, BUFSIZ
);
1405 str_nh
[BUFSIZ
- 1] = 0;
1407 vnc_zlog_debug_verbose ("%s: ubi_nexthop=%s", __func__
, str_nh
);
1412 bn
= bgp_node_lookup (table_rd
, ubi_nexthop
);
1415 vnc_zlog_debug_verbose ("%s: no match in RD's table for ubi_nexthop", __func__
);
1419 /* Iterate over bgp_info items at this node */
1420 for (bi
= bn
->info
; bi
; bi
= bi
->next
)
1423 vnc_import_bgp_del_route_mode_resolve_nve_one_bi (bgp
, afi
, bi
, /* VPN bi */
1425 prefix
); /* unicast route prefix */
1428 bgp_unlock_node (bn
);
1432 vnc_import_bgp_del_route_mode_resolve_nve (struct bgp
*bgp
,
1434 struct prefix
*prefix
,
1435 struct bgp_info
*info
)
1437 struct ecommunity
*ecom
= NULL
;
1438 struct prefix pfx_unicast_nexthop
= { 0 }; /* happy valgrind */
1440 //struct listnode *hnode;
1441 //struct rfapi_descriptor *rfd;
1442 struct prefix_bag
*pb
;
1444 struct skiplist
*sl
= bgp
->rfapi
->resolve_nve_nexthop
;
1446 struct bgp_node
*bnp
; /* prd table node */
1450 vnc_zlog_debug_verbose ("%s: no RHN entries, skipping", __func__
);
1454 if (info
->type
!= ZEBRA_ROUTE_BGP
)
1456 vnc_zlog_debug_verbose ("%s: unicast type %d=\"%s\" is not %d=%s, skipping",
1457 __func__
, info
->type
, zebra_route_string (info
->type
),
1458 ZEBRA_ROUTE_BGP
, "ZEBRA_ROUTE_BGP");
1462 if (process_unicast_route (bgp
, afi
, prefix
, info
,
1463 &ecom
, &pfx_unicast_nexthop
))
1466 vnc_zlog_debug_verbose ("%s: process_unicast_route error, skipping", __func__
);
1470 rc
= skiplist_first_value (sl
, &pfx_unicast_nexthop
, (void *) &pb
, &cursor
);
1473 if (pb
->ubi
== info
)
1475 skiplist_delete (sl
, &pfx_unicast_nexthop
, pb
);
1476 bgp_info_unlock (info
);
1480 skiplist_next_value (sl
, &pfx_unicast_nexthop
, (void *) &pb
, &cursor
);
1484 * Iterate over RDs in VPN RIB. For each RD, look up unicast nexthop
1485 * (exact match, /32). If an exact match is found, call add_vnc_route.
1488 for (bnp
= bgp_table_top (bgp
->rib
[afi
][SAFI_MPLS_VPN
]); bnp
;
1489 bnp
= bgp_route_next (bnp
))
1492 struct bgp_table
*table
;
1494 table
= (struct bgp_table
*) (bnp
->info
);
1499 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? */
1503 ecommunity_free (&ecom
);
1509 /***********************************************************************
1510 * Add/Delete CE->NVE routes
1511 ***********************************************************************/
1514 * Should be called whan a bi is added to VPN RIB. This function
1515 * will check if it is a host route and return immediately if not.
1518 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve (
1520 struct prefix_rd
*prd
, /* RD */
1521 struct bgp_table
*table_rd
, /* per-rd VPN route table */
1522 struct prefix
*prefix
, /* VPN prefix */
1523 struct bgp_info
*bi
) /* new VPN host route */
1525 afi_t afi
= family2afi (prefix
->family
);
1526 struct skiplist
*sl
= NULL
;
1528 struct prefix_bag
*pb
;
1530 struct rfapi_cfg
*hc
= NULL
;
1532 vnc_zlog_debug_verbose ("%s: entry", __func__
);
1534 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
1536 vnc_zlog_debug_verbose ("%s: bad afi %d, skipping", __func__
, afi
);
1540 if (!(hc
= bgp
->rfapi_cfg
))
1542 vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
1546 /* check vnc redist flag for bgp direct routes */
1547 if (!hc
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
1549 vnc_zlog_debug_verbose
1550 ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping",
1555 if (hc
->redist_mode
!= VNC_REDIST_MODE_RESOLVE_NVE
)
1557 vnc_zlog_debug_verbose ("%s: not in resolve-nve mode, skipping", __func__
);
1561 if (bgp
&& bgp
->rfapi
)
1562 sl
= bgp
->rfapi
->resolve_nve_nexthop
;
1566 vnc_zlog_debug_verbose ("%s: no resolve_nve_nexthop skiplist, skipping", __func__
);
1570 if (!is_host_prefix (prefix
))
1572 vnc_zlog_debug_verbose ("%s: not host prefix, skipping", __func__
);
1576 rc
= skiplist_first_value (sl
, prefix
, (void *) &pb
, &cursor
);
1579 struct ecommunity
*ecom
;
1580 struct prefix pfx_unicast_nexthop
;
1581 uint32_t *med
= NULL
;
1582 uint32_t local_pref
;
1584 memset (&pfx_unicast_nexthop
, 0, sizeof (struct prefix
)); /* keep valgrind happy */
1586 if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE
))
1591 prefix2str (&pb
->hpfx
, hbuf
, BUFSIZ
);
1592 prefix2str (&pb
->upfx
, ubuf
, BUFSIZ
);
1595 ("%s: examining RHN Entry (q=%p): upfx=%s, hpfx=%s, ubi=%p",
1596 __func__
, cursor
, ubuf
, hbuf
, pb
->ubi
);
1599 if (process_unicast_route (bgp
, afi
, &pb
->upfx
, pb
->ubi
,
1600 &ecom
, &pfx_unicast_nexthop
))
1603 vnc_zlog_debug_verbose ("%s: process_unicast_route error, skipping", __func__
);
1606 local_pref
= calc_local_pref (pb
->ubi
->attr
, pb
->ubi
->peer
);
1608 if (pb
->ubi
->attr
&&
1609 (pb
->ubi
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
)))
1612 med
= &pb
->ubi
->attr
->med
;
1618 if (vnc_prefix_cmp (&pfx_unicast_nexthop
, prefix
))
1620 char str_unh
[BUFSIZ
];
1621 char str_nve_pfx
[BUFSIZ
];
1623 prefix2str (&pfx_unicast_nexthop
, str_unh
, BUFSIZ
);
1624 str_unh
[BUFSIZ
- 1] = 0;
1626 prefix2str (prefix
, str_nve_pfx
, BUFSIZ
);
1627 str_nve_pfx
[BUFSIZ
- 1] = 0;
1629 vnc_zlog_debug_verbose
1630 ("%s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s",
1631 __func__
, str_unh
, str_nve_pfx
);
1635 vnc_import_bgp_add_route_mode_resolve_nve_one_bi (bgp
, afi
, bi
, /* VPN bi */
1636 prd
, &pb
->upfx
, /* unicast prefix */
1641 ecommunity_free (&ecom
);
1648 prefix2str (prefix
, pbuf
, BUFSIZ
);
1650 vnc_zlog_debug_verbose ("%s: advancing past RHN Entry (q=%p): with prefix %s",
1651 __func__
, cursor
, pbuf
);
1652 print_rhn_list (__func__
, NULL
); /* debug */
1655 rc
= skiplist_next_value (sl
, prefix
, (void *) &pb
, &cursor
);
1657 vnc_zlog_debug_verbose ("%s: done", __func__
);
1662 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve (
1664 struct prefix_rd
*prd
, /* RD */
1665 struct bgp_table
*table_rd
, /* per-rd VPN route table */
1666 struct prefix
*prefix
, /* VPN prefix */
1667 struct bgp_info
*bi
) /* old VPN host route */
1669 afi_t afi
= family2afi (prefix
->family
);
1670 struct skiplist
*sl
= NULL
;
1671 struct prefix_bag
*pb
;
1673 struct rfapi_cfg
*hc
= NULL
;
1677 char str_pfx
[BUFSIZ
];
1679 prefix2str (prefix
, str_pfx
, BUFSIZ
);
1680 str_pfx
[BUFSIZ
- 1] = 0;
1682 vnc_zlog_debug_verbose ("%s(bgp=%p, nve prefix=%s)", __func__
, bgp
, str_pfx
);
1685 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
)
1688 if (!(hc
= bgp
->rfapi_cfg
))
1690 vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
1694 /* check vnc redist flag for bgp direct routes */
1695 if (!hc
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
1697 vnc_zlog_debug_verbose
1698 ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping",
1703 if (hc
->redist_mode
!= VNC_REDIST_MODE_RESOLVE_NVE
)
1705 vnc_zlog_debug_verbose ("%s: not in resolve-nve mode, skipping", __func__
);
1709 if (bgp
&& bgp
->rfapi
)
1710 sl
= bgp
->rfapi
->resolve_nve_nexthop
;
1714 vnc_zlog_debug_verbose ("%s: no RHN entries, skipping", __func__
);
1718 if (!is_host_prefix (prefix
))
1720 vnc_zlog_debug_verbose ("%s: not host route, skip", __func__
);
1725 * Find all entries with key == CE in the RHN list
1727 rc
= skiplist_first_value (sl
, prefix
, (void *) &pb
, &cursor
);
1731 struct ecommunity
*ecom
;
1732 struct prefix pfx_unicast_nexthop
;
1734 memset (&pfx_unicast_nexthop
, 0, sizeof (struct prefix
)); /* keep valgrind happy */
1736 if (process_unicast_route (bgp
, afi
, &pb
->upfx
, pb
->ubi
,
1737 &ecom
, &pfx_unicast_nexthop
))
1740 vnc_zlog_debug_verbose ("%s: process_unicast_route error, skipping", __func__
);
1747 if (vnc_prefix_cmp (&pfx_unicast_nexthop
, prefix
))
1749 char str_unh
[BUFSIZ
];
1750 char str_nve_pfx
[BUFSIZ
];
1752 prefix2str (&pfx_unicast_nexthop
, str_unh
, BUFSIZ
);
1753 str_unh
[BUFSIZ
- 1] = 0;
1755 prefix2str (prefix
, str_nve_pfx
, BUFSIZ
);
1756 str_nve_pfx
[BUFSIZ
- 1] = 0;
1758 vnc_zlog_debug_verbose
1759 ("%s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s",
1760 __func__
, str_unh
, str_nve_pfx
);
1764 vnc_import_bgp_del_route_mode_resolve_nve_one_bi (bgp
,
1766 bi
, prd
, &pb
->upfx
);
1769 ecommunity_free (&ecom
);
1771 rc
= skiplist_next_value (sl
, prefix
, (void *) &pb
, &cursor
);
1776 /***********************************************************************
1778 ***********************************************************************/
1780 #define DEBUG_IS_USABLE_INTERIOR 1
1783 is_usable_interior_route (struct bgp_info
*bi_interior
)
1785 if (!VALID_INTERIOR_TYPE (bi_interior
->type
))
1787 #if DEBUG_IS_USABLE_INTERIOR
1788 vnc_zlog_debug_verbose ("%s: NO: type %d is not valid interior type",
1789 __func__
, bi_interior
->type
);
1793 if (!CHECK_FLAG (bi_interior
->flags
, BGP_INFO_VALID
))
1795 #if DEBUG_IS_USABLE_INTERIOR
1796 vnc_zlog_debug_verbose ("%s: NO: BGP_INFO_VALID not set", __func__
);
1804 * There should be only one of these per prefix at a time.
1805 * This should be called as a result of selection operation
1807 * NB should be called espacially for bgp instances that are named,
1808 * because the exterior routes will always come from one of those.
1809 * We filter here on the instance name to make sure we get only the
1813 vnc_import_bgp_exterior_add_route_it (
1814 struct bgp
*bgp
, /* exterior instance, we hope */
1815 struct prefix
*prefix
,/* unicast prefix */
1816 struct bgp_info
*info
, /* unicast info */
1817 struct rfapi_import_table
*it_only
)/* NULL, or limit to this IT */
1820 struct rfapi_cfg
*hc
;
1821 struct prefix pfx_orig_nexthop
;
1822 struct rfapi_import_table
*it
;
1823 struct bgp
*bgp_default
= bgp_get_default ();
1824 afi_t afi
= family2afi (prefix
->family
);
1829 h
= bgp_default
->rfapi
;
1830 hc
= bgp_default
->rfapi_cfg
;
1832 vnc_zlog_debug_verbose ("%s: entry with it=%p", __func__
, it_only
);
1836 vnc_zlog_debug_verbose ("%s: rfapi or rfapi_cfg not instantiated, skipping",
1840 if (!hc
->redist_bgp_exterior_view
)
1842 vnc_zlog_debug_verbose ("%s: exterior view not set, skipping", __func__
);
1845 if (bgp
!= hc
->redist_bgp_exterior_view
)
1847 vnc_zlog_debug_verbose ("%s: bgp %p != hc->redist_bgp_exterior_view %p, skipping",
1848 __func__
, bgp
, hc
->redist_bgp_exterior_view
);
1852 if (!hc
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
])
1854 vnc_zlog_debug_verbose ("%s: redist of exterior routes not enabled, skipping",
1861 vnc_zlog_debug_verbose ("%s: no info, skipping", __func__
);
1866 * Extract nexthop from exterior route
1868 * Incoming prefix is unicast. If v6, it is in multiprotocol area,
1869 * but if v4 it is in attr->nexthop
1871 rfapiUnicastNexthop2Prefix (afi
, info
->attr
, &pfx_orig_nexthop
);
1873 for (it
= h
->imports
; it
; it
= it
->next
)
1875 struct route_table
*table
;
1876 struct route_node
*rn
;
1877 struct route_node
*par
;
1878 struct bgp_info
*bi_interior
;
1879 int have_usable_route
;
1881 vnc_zlog_debug_verbose ("%s: doing it %p", __func__
, it
);
1883 if (it_only
&& (it_only
!= it
))
1885 vnc_zlog_debug_verbose ("%s: doesn't match it_only %p", __func__
, it_only
);
1889 table
= it
->imported_vpn
[afi
];
1891 for (rn
= route_node_match (table
, &pfx_orig_nexthop
),
1892 have_usable_route
= 0; (!have_usable_route
) && rn
;)
1895 vnc_zlog_debug_verbose ("%s: it %p trying rn %p", __func__
, it
, rn
);
1897 for (bi_interior
= rn
->info
; bi_interior
;
1898 bi_interior
= bi_interior
->next
)
1900 struct prefix_rd
*prd
;
1901 struct attr new_attr
;
1902 u_int32_t label
= 0;
1904 if (!is_usable_interior_route (bi_interior
))
1907 vnc_zlog_debug_verbose ("%s: usable: bi_interior %p", __func__
,
1911 * have a legitimate route to exterior's nexthop
1914 * Import unicast route to the import table
1916 have_usable_route
= 1;
1918 if (bi_interior
->extra
)
1920 prd
= &bi_interior
->extra
->vnc
.import
.rd
;
1921 label
= decode_label (bi_interior
->extra
->tag
);
1926 /* use local_pref from unicast route */
1927 memset (&new_attr
, 0, sizeof (struct attr
));
1928 bgp_attr_dup (&new_attr
, bi_interior
->attr
);
1929 if (info
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
1931 new_attr
.local_pref
= info
->attr
->local_pref
;
1932 new_attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
1935 rfapiBgpInfoFilteredImportVPN (it
, FIF_ACTION_UPDATE
, bi_interior
->peer
, NULL
, /* rfd */
1941 ZEBRA_ROUTE_BGP_DIRECT_EXT
,
1942 BGP_ROUTE_REDISTRIBUTE
, &label
);
1944 bgp_attr_extra_free (&new_attr
);
1947 if (have_usable_route
)
1952 * TBD factor this out into its own function
1954 struct prefix
*pfx_mon
= prefix_new ();
1955 if (!RFAPI_MONITOR_EXTERIOR (rn
)->source
)
1957 RFAPI_MONITOR_EXTERIOR (rn
)->source
=
1958 skiplist_new (0, NULL
, (void (*)(void *)) prefix_free
);
1959 route_lock_node (rn
); /* for skiplist */
1961 route_lock_node (rn
); /* for skiplist entry */
1962 prefix_copy (pfx_mon
, prefix
);
1963 if (!skiplist_insert (RFAPI_MONITOR_EXTERIOR (rn
)->source
,
1967 bgp_info_lock (info
);
1972 route_lock_node (par
);
1973 route_unlock_node (rn
);
1977 route_unlock_node (rn
);
1979 if (!have_usable_route
)
1981 struct prefix
*pfx_mon
= prefix_new ();
1982 prefix_copy (pfx_mon
, prefix
);
1983 if (!skiplist_insert (it
->monitor_exterior_orphans
, info
, pfx_mon
))
1986 bgp_info_lock (info
);
1993 vnc_import_bgp_exterior_add_route (
1994 struct bgp
*bgp
, /* exterior instance, we hope */
1995 struct prefix
*prefix
,/* unicast prefix */
1996 struct bgp_info
*info
) /* unicast info */
1998 vnc_import_bgp_exterior_add_route_it (bgp
, prefix
, info
, NULL
);
2002 * There should be only one of these per prefix at a time.
2003 * This should probably be called as a result of selection operation.
2005 * NB should be called espacially for bgp instances that are named,
2006 * because the exterior routes will always come from one of those.
2007 * We filter here on the instance name to make sure we get only the
2011 vnc_import_bgp_exterior_del_route (
2013 struct prefix
*prefix
, /* unicast prefix */
2014 struct bgp_info
*info
) /* unicast info */
2017 struct rfapi_cfg
*hc
;
2018 struct rfapi_import_table
*it
;
2019 struct prefix pfx_orig_nexthop
;
2020 afi_t afi
= family2afi (prefix
->family
);
2021 struct bgp
*bgp_default
= bgp_get_default ();
2026 memset (&pfx_orig_nexthop
, 0, sizeof (struct prefix
)); /* keep valgrind happy */
2028 h
= bgp_default
->rfapi
;
2029 hc
= bgp_default
->rfapi_cfg
;
2033 vnc_zlog_debug_verbose ("%s: rfapi or rfapi_cfg not instantiated, skipping",
2037 if (!hc
->redist_bgp_exterior_view
)
2039 vnc_zlog_debug_verbose ("%s: exterior view not set, skipping", __func__
);
2042 if (bgp
!= hc
->redist_bgp_exterior_view
)
2044 vnc_zlog_debug_verbose ("%s: bgp %p != hc->redist_bgp_exterior_view %p, skipping",
2045 __func__
, bgp
, hc
->redist_bgp_exterior_view
);
2048 if (!hc
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
])
2050 vnc_zlog_debug_verbose ("%s: redist of exterior routes no enabled, skipping",
2057 vnc_zlog_debug_verbose ("%s: no info, skipping", __func__
);
2062 * Extract nexthop from exterior route
2064 * Incoming prefix is unicast. If v6, it is in multiprotocol area,
2065 * but if v4 it is in attr->nexthop
2067 rfapiUnicastNexthop2Prefix (afi
, info
->attr
, &pfx_orig_nexthop
);
2069 for (it
= h
->imports
; it
; it
= it
->next
)
2071 struct route_table
*table
;
2072 struct route_node
*rn
;
2073 struct route_node
*par
;
2074 struct bgp_info
*bi_interior
;
2075 int have_usable_route
;
2077 table
= it
->imported_vpn
[afi
];
2079 for (rn
= route_node_match (table
, &pfx_orig_nexthop
),
2080 have_usable_route
= 0; (!have_usable_route
) && rn
;)
2083 for (bi_interior
= rn
->info
; bi_interior
;
2084 bi_interior
= bi_interior
->next
)
2086 struct prefix_rd
*prd
;
2087 u_int32_t label
= 0;
2089 if (!is_usable_interior_route (bi_interior
))
2093 * have a legitimate route to exterior's nexthop
2096 * Import unicast route to the import table
2098 have_usable_route
= 1;
2100 if (bi_interior
->extra
)
2102 prd
= &bi_interior
->extra
->vnc
.import
.rd
;
2103 label
= decode_label (bi_interior
->extra
->tag
);
2108 rfapiBgpInfoFilteredImportVPN (it
, FIF_ACTION_KILL
, bi_interior
->peer
, NULL
, /* rfd */
2114 ZEBRA_ROUTE_BGP_DIRECT_EXT
,
2115 BGP_ROUTE_REDISTRIBUTE
, &label
);
2120 * TBD factor this out into its own function
2123 if (RFAPI_MONITOR_EXTERIOR (rn
)->source
)
2125 if (!skiplist_delete (RFAPI_MONITOR_EXTERIOR (rn
)->source
,
2129 bgp_info_unlock (info
);
2130 route_unlock_node (rn
); /* sl entry */
2132 if (skiplist_empty (RFAPI_MONITOR_EXTERIOR (rn
)->source
))
2134 skiplist_free (RFAPI_MONITOR_EXTERIOR (rn
)->source
);
2135 RFAPI_MONITOR_EXTERIOR (rn
)->source
= NULL
;
2136 route_unlock_node (rn
); /* skiplist itself */
2143 route_lock_node (par
);
2144 route_unlock_node (rn
);
2148 route_unlock_node (rn
);
2150 if (!have_usable_route
)
2152 if (!skiplist_delete (it
->monitor_exterior_orphans
, info
, NULL
))
2155 bgp_info_unlock (info
);
2162 * This function should be called after a new interior VPN route
2163 * has been added to an import_table.
2165 * NB should also be called whenever an existing vpn interior route
2166 * becomes valid (e.g., valid_interior_count is inremented)
2169 vnc_import_bgp_exterior_add_route_interior (
2171 struct rfapi_import_table
*it
,
2172 struct route_node
*rn_interior
, /* VPN IT node */
2173 struct bgp_info
*bi_interior
) /* VPN IT route */
2175 afi_t afi
= family2afi (rn_interior
->p
.family
);
2176 struct route_node
*par
;
2177 struct bgp_info
*bi_exterior
;
2178 struct prefix
*pfx_exterior
; /* exterior pfx */
2181 struct list
*list_adopted
;
2183 vnc_zlog_debug_verbose ("%s: entry", __func__
);
2185 if (!is_usable_interior_route (bi_interior
))
2187 vnc_zlog_debug_verbose ("%s: not usable interior route, skipping", __func__
);
2191 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
])
2193 vnc_zlog_debug_verbose ("%s: redist of exterior routes no enabled, skipping",
2198 if (it
== bgp
->rfapi
->it_ce
)
2200 vnc_zlog_debug_verbose ("%s: import table is it_ce, skipping", __func__
);
2206 char str_pfx
[BUFSIZ
];
2208 prefix2str (&rn_interior
->p
, str_pfx
, BUFSIZ
);
2209 str_pfx
[BUFSIZ
- 1] = 0;
2211 vnc_zlog_debug_verbose ("%s: interior prefix=%s, bi type=%d",
2212 __func__
, str_pfx
, bi_interior
->type
);
2215 if (RFAPI_HAS_MONITOR_EXTERIOR (rn_interior
))
2218 int count
= 0; /* debugging */
2220 vnc_zlog_debug_verbose ("%s: has exterior monitor; ext src: %p", __func__
,
2221 RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
);
2224 * There is a monitor here already. Therefore, we do not need
2225 * to do any pulldown. Just construct exterior routes based
2226 * on the new interior route.
2229 for (rc
= skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2230 (void **) &bi_exterior
,
2231 (void **) &pfx_exterior
, &cursor
); !rc
;
2233 skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2234 (void **) &bi_exterior
, (void **) &pfx_exterior
,
2238 struct prefix_rd
*prd
;
2239 struct attr new_attr
;
2240 u_int32_t label
= 0;
2243 ++count
; /* debugging */
2245 assert (bi_exterior
);
2246 assert (pfx_exterior
);
2248 if (bi_interior
->extra
)
2250 prd
= &bi_interior
->extra
->vnc
.import
.rd
;
2251 label
= decode_label (bi_interior
->extra
->tag
);
2256 /* use local_pref from unicast route */
2257 memset (&new_attr
, 0, sizeof (struct attr
));
2258 bgp_attr_dup (&new_attr
, bi_interior
->attr
);
2260 (bi_exterior
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
)))
2262 new_attr
.local_pref
= bi_exterior
->attr
->local_pref
;
2263 new_attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
2266 rfapiBgpInfoFilteredImportVPN (it
, FIF_ACTION_UPDATE
, bi_interior
->peer
, NULL
, /* rfd */
2272 ZEBRA_ROUTE_BGP_DIRECT_EXT
,
2273 BGP_ROUTE_REDISTRIBUTE
, &label
);
2275 bgp_attr_extra_free (&new_attr
);
2277 vnc_zlog_debug_verbose
2278 ("%s: finished constructing exteriors based on existing monitors",
2283 vnc_zlog_debug_verbose ("%s: no exterior monitor", __func__
);
2286 * No monitor at this node. Is this the first valid interior
2287 * route at this node?
2289 if (RFAPI_MONITOR_EXTERIOR (rn_interior
)->valid_interior_count
> 1)
2291 vnc_zlog_debug_verbose
2292 ("%s: new interior route not first valid one, skipping pulldown",
2298 * Look up the tree for possible pulldown candidates.
2299 * Find nearest parent with an exterior route monitor
2301 for (par
= rn_interior
->parent
; par
; par
= par
->parent
)
2303 if (RFAPI_HAS_MONITOR_EXTERIOR (par
))
2310 vnc_zlog_debug_verbose ("%s: checking parent %p for possible pulldowns",
2313 /* check monitors at par for possible pulldown */
2315 for (rc
= skiplist_next (RFAPI_MONITOR_EXTERIOR (par
)->source
,
2316 (void **) &bi_exterior
,
2317 (void **) &pfx_exterior
, &cursor
); !rc
;
2319 skiplist_next (RFAPI_MONITOR_EXTERIOR (par
)->source
,
2320 (void **) &bi_exterior
, (void **) &pfx_exterior
,
2324 struct prefix pfx_nexthop
;
2326 memset (&pfx_nexthop
, 0, sizeof (struct prefix
)); /* keep valgrind happy */
2328 /* check original nexthop for prefix match */
2329 rfapiUnicastNexthop2Prefix (afi
, bi_exterior
->attr
, &pfx_nexthop
);
2331 if (prefix_match (&rn_interior
->p
, &pfx_nexthop
))
2334 struct bgp_info
*bi
;
2335 struct prefix_rd
*prd
;
2336 struct attr new_attr
;
2337 u_int32_t label
= 0;
2342 * add monitor to longer prefix
2344 struct prefix
*pfx_mon
= prefix_new ();
2345 prefix_copy (pfx_mon
, pfx_exterior
);
2346 if (!RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
)
2348 RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
=
2349 skiplist_new (0, NULL
, (void (*)(void *)) prefix_free
);
2350 route_lock_node (rn_interior
);
2352 skiplist_insert (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2353 bi_exterior
, pfx_mon
);
2354 route_lock_node (rn_interior
);
2357 * Delete constructed exterior routes based on
2360 for (bi
= par
->info
; bi
; bi
= bi
->next
)
2365 prd
= &bi
->extra
->vnc
.import
.rd
;
2366 label
= decode_label (bi
->extra
->tag
);
2371 rfapiBgpInfoFilteredImportVPN (it
, FIF_ACTION_KILL
, bi
->peer
, NULL
, /* rfd */
2377 ZEBRA_ROUTE_BGP_DIRECT_EXT
,
2378 BGP_ROUTE_REDISTRIBUTE
,
2384 * Add constructed exterior routes based on
2385 * the new interior route at longer prefix.
2387 if (bi_interior
->extra
)
2389 prd
= &bi_interior
->extra
->vnc
.import
.rd
;
2390 label
= decode_label (bi_interior
->extra
->tag
);
2395 /* use local_pref from unicast route */
2396 memset (&new_attr
, 0, sizeof (struct attr
));
2397 bgp_attr_dup (&new_attr
, bi_interior
->attr
);
2399 (bi_exterior
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
)))
2401 new_attr
.local_pref
= bi_exterior
->attr
->local_pref
;
2402 new_attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
2405 rfapiBgpInfoFilteredImportVPN (it
, FIF_ACTION_UPDATE
, bi_interior
->peer
, NULL
, /* rfd */
2411 ZEBRA_ROUTE_BGP_DIRECT_EXT
,
2412 BGP_ROUTE_REDISTRIBUTE
, &label
);
2414 bgp_attr_extra_free (&new_attr
);
2419 * The only monitors at rn_interior are the ones we added just
2420 * above, so we can use the rn_interior list to identify which
2421 * monitors to delete from the parent.
2424 for (rc
= skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2425 (void **) &bi_exterior
, NULL
, &cursor
);
2427 rc
= skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2428 (void **) &bi_exterior
, NULL
, &cursor
))
2432 skiplist_delete (RFAPI_MONITOR_EXTERIOR (par
)->source
,
2434 route_unlock_node (par
); /* sl entry */
2436 if (skiplist_empty (RFAPI_MONITOR_EXTERIOR (par
)->source
))
2438 skiplist_free (RFAPI_MONITOR_EXTERIOR (par
)->source
);
2439 RFAPI_MONITOR_EXTERIOR (par
)->source
= NULL
;
2440 route_unlock_node (par
); /* sl itself */
2444 vnc_zlog_debug_verbose ("%s: checking orphans", __func__
);
2447 * See if any orphans can be pulled down to the current node
2450 list_adopted
= NULL
;
2451 for (rc
= skiplist_next (it
->monitor_exterior_orphans
,
2452 (void **) &bi_exterior
, (void **) &pfx_exterior
,
2455 skiplist_next (it
->monitor_exterior_orphans
, (void **) &bi_exterior
,
2456 (void **) &pfx_exterior
, &cursor
))
2459 struct prefix pfx_nexthop
;
2461 afi_t afi_exterior
= family2afi (pfx_exterior
->family
);
2463 prefix2str (pfx_exterior
, buf
, sizeof (buf
));
2464 buf
[sizeof (buf
) - 1] = 0;
2465 vnc_zlog_debug_verbose ("%s: checking exterior orphan at prefix %s", __func__
, buf
);
2467 if (afi_exterior
!= afi
)
2469 vnc_zlog_debug_verbose ("%s: exterior orphan afi %d != interior afi %d, skip",
2470 __func__
, afi_exterior
, afi
);
2474 /* check original nexthop for prefix match */
2475 rfapiUnicastNexthop2Prefix (afi
, bi_exterior
->attr
, &pfx_nexthop
);
2477 if (prefix_match (&rn_interior
->p
, &pfx_nexthop
))
2480 struct prefix_rd
*prd
;
2481 struct attr new_attr
;
2482 u_int32_t label
= 0;
2487 * add monitor to longer prefix
2490 struct prefix
*pfx_mon
= prefix_new ();
2491 prefix_copy (pfx_mon
, pfx_exterior
);
2492 if (!RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
)
2494 RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
=
2495 skiplist_new (0, NULL
, (void (*)(void *)) prefix_free
);
2496 route_lock_node (rn_interior
); /* sl */
2498 skiplist_insert (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2499 bi_exterior
, pfx_mon
);
2500 route_lock_node (rn_interior
); /* sl entry */
2503 list_adopted
= list_new ();
2505 listnode_add (list_adopted
, bi_exterior
);
2508 * Add constructed exterior routes based on the
2509 * new interior route at the longer prefix.
2511 if (bi_interior
->extra
)
2513 prd
= &bi_interior
->extra
->vnc
.import
.rd
;
2514 label
= decode_label (bi_interior
->extra
->tag
);
2519 /* use local_pref from unicast route */
2520 memset (&new_attr
, 0, sizeof (struct attr
));
2521 bgp_attr_dup (&new_attr
, bi_interior
->attr
);
2523 (bi_exterior
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
)))
2525 new_attr
.local_pref
= bi_exterior
->attr
->local_pref
;
2526 new_attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
2529 rfapiBgpInfoFilteredImportVPN (it
, FIF_ACTION_UPDATE
, bi_interior
->peer
, NULL
, /* rfd */
2535 ZEBRA_ROUTE_BGP_DIRECT_EXT
,
2536 BGP_ROUTE_REDISTRIBUTE
, &label
);
2538 bgp_attr_extra_free (&new_attr
);
2543 struct listnode
*node
;
2544 struct route_node
*bi_exterior
;
2546 for (ALL_LIST_ELEMENTS_RO (list_adopted
, node
, bi_exterior
))
2548 skiplist_delete (it
->monitor_exterior_orphans
, bi_exterior
, NULL
);
2550 list_delete (list_adopted
);
2555 * This function should be called after an interior VPN route
2556 * has been deleted from an import_table.
2557 * bi_interior must still be valid, but it must already be detached
2558 * from its route node and the route node's valid_interior_count
2559 * must already be decremented.
2561 * NB should also be called whenever an existing vpn interior route
2562 * becomes invalid (e.g., valid_interior_count is decremented)
2565 vnc_import_bgp_exterior_del_route_interior (
2567 struct rfapi_import_table
*it
,
2568 struct route_node
*rn_interior
, /* VPN IT node */
2569 struct bgp_info
*bi_interior
) /* VPN IT route */
2571 afi_t afi
= family2afi (rn_interior
->p
.family
);
2572 struct route_node
*par
;
2573 struct bgp_info
*bi_exterior
;
2574 struct prefix
*pfx_exterior
; /* exterior pfx */
2578 if (!VALID_INTERIOR_TYPE (bi_interior
->type
))
2580 vnc_zlog_debug_verbose ("%s: type %d not valid interior type, skipping",
2581 __func__
, bi_interior
->type
);
2585 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
])
2587 vnc_zlog_debug_verbose ("%s: redist of exterior routes no enabled, skipping",
2592 if (it
== bgp
->rfapi
->it_ce
)
2594 vnc_zlog_debug_verbose ("%s: it is it_ce, skipping", __func__
);
2598 /* If no exterior routes depend on this prefix, nothing to do */
2599 if (!RFAPI_HAS_MONITOR_EXTERIOR (rn_interior
))
2601 vnc_zlog_debug_verbose ("%s: no exterior monitor, skipping", __func__
);
2607 char str_pfx
[BUFSIZ
];
2609 prefix2str (&rn_interior
->p
, str_pfx
, BUFSIZ
);
2610 str_pfx
[BUFSIZ
- 1] = 0;
2612 vnc_zlog_debug_verbose ("%s: interior prefix=%s, bi type=%d",
2613 __func__
, str_pfx
, bi_interior
->type
);
2617 * Remove constructed routes based on the deleted interior route
2620 for (rc
= skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2621 (void **) &bi_exterior
, (void **) &pfx_exterior
,
2624 skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2625 (void **) &bi_exterior
, (void **) &pfx_exterior
,
2629 struct prefix_rd
*prd
;
2630 u_int32_t label
= 0;
2632 if (bi_interior
->extra
)
2634 prd
= &bi_interior
->extra
->vnc
.import
.rd
;
2635 label
= decode_label (bi_interior
->extra
->tag
);
2640 rfapiBgpInfoFilteredImportVPN (it
, FIF_ACTION_KILL
, bi_interior
->peer
, NULL
, /* rfd */
2646 ZEBRA_ROUTE_BGP_DIRECT_EXT
,
2647 BGP_ROUTE_REDISTRIBUTE
, &label
);
2651 * If there are no remaining valid interior routes at this prefix,
2652 * we need to look up the tree for a possible node to move monitors to
2654 if (RFAPI_MONITOR_EXTERIOR (rn_interior
)->valid_interior_count
)
2656 vnc_zlog_debug_verbose ("%s: interior routes still present, skipping", __func__
);
2661 * Find nearest parent with at least one valid interior route
2662 * If none is found, par will end up NULL, and we will move
2663 * the monitors to the orphan list for this import table
2665 for (par
= rn_interior
->parent
; par
; par
= par
->parent
)
2667 if (RFAPI_MONITOR_EXTERIOR (par
)->valid_interior_count
)
2671 vnc_zlog_debug_verbose ("%s: par=%p, ext src: %p", __func__
,
2672 par
, RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
);
2674 /* move all monitors */
2676 * We will use and delete every element of the source skiplist
2678 while (!skiplist_first (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
,
2679 (void **) &bi_exterior
, (void **) &pfx_exterior
))
2682 struct prefix
*pfx_mon
= prefix_new ();
2684 prefix_copy (pfx_mon
, pfx_exterior
);
2689 struct bgp_info
*bi
;
2692 * Add monitor to parent node
2694 if (!RFAPI_MONITOR_EXTERIOR (par
)->source
)
2696 RFAPI_MONITOR_EXTERIOR (par
)->source
=
2697 skiplist_new (0, NULL
, (void (*)(void *)) prefix_free
);
2698 route_lock_node (par
); /* sl */
2700 skiplist_insert (RFAPI_MONITOR_EXTERIOR (par
)->source
,
2701 bi_exterior
, pfx_mon
);
2702 route_lock_node (par
); /* sl entry */
2704 /* Add constructed exterior routes based on parent */
2705 for (bi
= par
->info
; bi
; bi
= bi
->next
)
2708 struct prefix_rd
*prd
;
2709 struct attr new_attr
;
2710 u_int32_t label
= 0;
2712 if (bi
->type
== ZEBRA_ROUTE_BGP_DIRECT_EXT
)
2717 prd
= &bi
->extra
->vnc
.import
.rd
;
2718 label
= decode_label (bi
->extra
->tag
);
2723 /* use local_pref from unicast route */
2724 memset (&new_attr
, 0, sizeof (struct attr
));
2725 bgp_attr_dup (&new_attr
, bi
->attr
);
2727 (bi_exterior
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
)))
2729 new_attr
.local_pref
= bi_exterior
->attr
->local_pref
;
2730 new_attr
.flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
2733 rfapiBgpInfoFilteredImportVPN (it
, FIF_ACTION_UPDATE
, bi
->peer
, NULL
, /* rfd */
2739 ZEBRA_ROUTE_BGP_DIRECT_EXT
,
2740 BGP_ROUTE_REDISTRIBUTE
, &label
);
2742 bgp_attr_extra_free (&new_attr
);
2750 * No interior route for exterior's nexthop. Save monitor
2751 * in orphan list to await future route.
2753 skiplist_insert (it
->monitor_exterior_orphans
,
2754 bi_exterior
, pfx_mon
);
2757 skiplist_delete_first (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
);
2758 route_unlock_node (rn_interior
); /* sl entry */
2760 if (skiplist_empty (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
))
2762 skiplist_free (RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
);
2763 RFAPI_MONITOR_EXTERIOR (rn_interior
)->source
= NULL
;
2764 route_unlock_node (rn_interior
); /* sl itself */
2769 /***********************************************************************
2770 * Generic add/delete unicast routes
2771 ***********************************************************************/
2774 vnc_import_bgp_add_route (
2776 struct prefix
*prefix
,
2777 struct bgp_info
*info
)
2779 afi_t afi
= family2afi (prefix
->family
);
2782 struct prefix pfx_nexthop
;
2784 char buf_nh
[BUFSIZ
];
2786 prefix2str (prefix
, buf
, BUFSIZ
);
2787 rfapiUnicastNexthop2Prefix (afi
, info
->attr
, &pfx_nexthop
);
2788 prefix2str (&pfx_nexthop
, buf_nh
, BUFSIZ
);
2790 vnc_zlog_debug_verbose ("%s: pfx %s, nh %s", __func__
, buf
, buf_nh
);
2793 print_rhn_list(__func__
, "ENTER ");
2799 zlog_err ("%s: can't get afi of prefix", __func__
);
2803 if (!bgp
->rfapi_cfg
)
2805 vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
2809 /* check vnc redist flag for bgp direct routes */
2810 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
2812 vnc_zlog_debug_verbose
2813 ("%s: bgp->rfapi_cfg->redist[afi=%d][type=%d=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping",
2814 __func__
, afi
, ZEBRA_ROUTE_BGP_DIRECT
);
2818 switch (bgp
->rfapi_cfg
->redist_mode
)
2820 case VNC_REDIST_MODE_PLAIN
:
2821 vnc_import_bgp_add_route_mode_plain (bgp
, prefix
, info
);
2824 case VNC_REDIST_MODE_RFG
:
2825 if (bgp
->rfapi_cfg
->rfg_redist
)
2826 vnc_import_bgp_add_route_mode_nvegroup (bgp
, prefix
, info
,
2827 bgp
->rfapi_cfg
->rfg_redist
);
2829 vnc_zlog_debug_verbose ("%s: mode RFG but no redist RFG", __func__
);
2832 case VNC_REDIST_MODE_RESOLVE_NVE
:
2833 vnc_import_bgp_add_route_mode_resolve_nve (bgp
, prefix
, info
);
2837 print_rhn_list(__func__
, "LEAVE ");
2843 * "Withdrawing a Route" import process
2846 vnc_import_bgp_del_route (
2848 struct prefix
*prefix
,
2849 struct bgp_info
*info
) /* unicast info */
2851 afi_t afi
= family2afi (prefix
->family
);
2856 struct prefix pfx_nexthop
;
2858 char buf_nh
[BUFSIZ
];
2860 prefix2str (prefix
, buf
, BUFSIZ
);
2861 rfapiUnicastNexthop2Prefix (afi
, info
->attr
, &pfx_nexthop
);
2862 prefix2str (&pfx_nexthop
, buf_nh
, BUFSIZ
);
2864 vnc_zlog_debug_verbose ("%s: pfx %s, nh %s", __func__
, buf
, buf_nh
);
2867 print_rhn_list(__func__
, "ENTER ");
2871 if (!bgp
->rfapi_cfg
)
2873 vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
2877 /* check bgp redist flag for vnc direct ("vpn") routes */
2878 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
2880 vnc_zlog_debug_verbose ("%s: bgp redistribution of afi=%d VNC direct routes is off",
2885 switch (bgp
->rfapi_cfg
->redist_mode
)
2887 case VNC_REDIST_MODE_PLAIN
:
2888 vnc_import_bgp_del_route_mode_plain (bgp
, prefix
, info
);
2891 case VNC_REDIST_MODE_RFG
:
2892 if (bgp
->rfapi_cfg
->rfg_redist
)
2893 vnc_import_bgp_del_route_mode_nvegroup (bgp
, prefix
, info
);
2895 vnc_zlog_debug_verbose ("%s: mode RFG but no redist RFG", __func__
);
2898 case VNC_REDIST_MODE_RESOLVE_NVE
:
2899 vnc_import_bgp_del_route_mode_resolve_nve (bgp
, afi
, prefix
, info
);
2904 print_rhn_list(__func__
, "LEAVE ");
2910 /***********************************************************************
2912 ***********************************************************************/
2915 vnc_import_bgp_redist_enable (struct bgp
*bgp
, afi_t afi
)
2917 /* iterate over bgp unicast v4 and v6 routes, call vnc_import_bgp_add_route */
2919 struct bgp_node
*rn
;
2921 vnc_zlog_debug_verbose ("%s: entry, afi=%d", __func__
, afi
);
2923 if (bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
2925 vnc_zlog_debug_verbose ("%s: already enabled for afi %d, skipping", __func__
, afi
);
2928 bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
] = 1;
2930 for (rn
= bgp_table_top (bgp
->rib
[afi
][SAFI_UNICAST
]);
2931 rn
; rn
= bgp_route_next (rn
))
2934 struct bgp_info
*bi
;
2936 for (bi
= rn
->info
; bi
; bi
= bi
->next
)
2939 if (CHECK_FLAG (bi
->flags
, BGP_INFO_REMOVED
))
2942 vnc_import_bgp_add_route (bgp
, &rn
->p
, bi
);
2945 vnc_zlog_debug_verbose ("%s: set redist[afi=%d][type=%d=ZEBRA_ROUTE_BGP_DIRECT] return",
2946 __func__
, afi
, ZEBRA_ROUTE_BGP_DIRECT
);
2950 vnc_import_bgp_exterior_redist_enable (struct bgp
*bgp
, afi_t afi
)
2952 struct bgp
*bgp_exterior
;
2953 struct bgp_node
*rn
;
2955 bgp_exterior
= bgp
->rfapi_cfg
->redist_bgp_exterior_view
;
2957 if (bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
])
2959 vnc_zlog_debug_verbose ("%s: already enabled for afi %d, skipping", __func__
, afi
);
2962 bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
] = 1;
2966 vnc_zlog_debug_verbose ("%s: no exterior view set yet, no routes to import yet",
2971 for (rn
= bgp_table_top (bgp_exterior
->rib
[afi
][SAFI_UNICAST
]);
2972 rn
; rn
= bgp_route_next (rn
))
2975 struct bgp_info
*bi
;
2977 for (bi
= rn
->info
; bi
; bi
= bi
->next
)
2980 if (CHECK_FLAG (bi
->flags
, BGP_INFO_REMOVED
))
2983 vnc_import_bgp_exterior_add_route (bgp_exterior
, &rn
->p
, bi
);
2986 vnc_zlog_debug_verbose ("%s: set redist[afi=%d][type=%d=ZEBRA_ROUTE_BGP_DIRECT] return",
2987 __func__
, afi
, ZEBRA_ROUTE_BGP_DIRECT
);
2992 * This function is for populating a newly-created Import Table
2995 vnc_import_bgp_exterior_redist_enable_it (
2998 struct rfapi_import_table
*it_only
)
3000 struct bgp
*bgp_exterior
;
3001 struct bgp_node
*rn
;
3003 vnc_zlog_debug_verbose ("%s: entry", __func__
);
3005 bgp_exterior
= bgp
->rfapi_cfg
->redist_bgp_exterior_view
;
3007 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
])
3009 vnc_zlog_debug_verbose ("%s: not enabled for afi %d, skipping", __func__
, afi
);
3015 vnc_zlog_debug_verbose ("%s: no exterior view set yet, no routes to import yet",
3020 for (rn
= bgp_table_top (bgp_exterior
->rib
[afi
][SAFI_UNICAST
]);
3021 rn
; rn
= bgp_route_next (rn
))
3024 struct bgp_info
*bi
;
3026 for (bi
= rn
->info
; bi
; bi
= bi
->next
)
3029 if (CHECK_FLAG (bi
->flags
, BGP_INFO_REMOVED
))
3032 vnc_import_bgp_exterior_add_route_it (bgp_exterior
, &rn
->p
, bi
,
3041 vnc_import_bgp_redist_disable (struct bgp
*bgp
, afi_t afi
)
3044 * iterate over vpn routes, find routes of type ZEBRA_ROUTE_BGP_DIRECT,
3045 * delete (call timer expire immediately)
3047 struct bgp_node
*rn1
;
3048 struct bgp_node
*rn2
;
3050 vnc_zlog_debug_verbose ("%s: entry", __func__
);
3052 if (!bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
])
3054 vnc_zlog_debug_verbose ("%s: already disabled for afi %d, skipping", __func__
, afi
);
3059 * Two-level table for SAFI_MPLS_VPN
3060 * Be careful when changing the things we iterate over
3062 for (rn1
= bgp_table_top (bgp
->rib
[afi
][SAFI_MPLS_VPN
]);
3063 rn1
; rn1
= bgp_route_next (rn1
))
3068 for (rn2
= bgp_table_top (rn1
->info
);
3069 rn2
; rn2
= bgp_route_next (rn2
))
3072 struct bgp_info
*bi
;
3073 struct bgp_info
*nextbi
;
3075 for (bi
= rn2
->info
; bi
; bi
= nextbi
)
3080 if (bi
->type
== ZEBRA_ROUTE_BGP_DIRECT
)
3083 struct rfapi_descriptor
*rfd
;
3084 vncHDBgpDirect
.peer
= bi
->peer
;
3086 rfd
= bi
->extra
->vnc
.export
.rfapi_handle
;
3088 vnc_zlog_debug_verbose
3089 ("%s: deleting bi=%p, bi->peer=%p, bi->type=%d, bi->sub_type=%d, bi->extra->vnc.export.rfapi_handle=%p [passing rfd=%p]",
3090 __func__
, bi
, bi
->peer
, bi
->type
, bi
->sub_type
,
3091 (bi
->extra
? bi
->extra
->vnc
.
3092 export
.rfapi_handle
: NULL
), rfd
);
3095 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 */
3097 vncHDBgpDirect
.peer
= NULL
;
3103 /* Clear RHN list */
3104 if (bgp
->rfapi
->resolve_nve_nexthop
)
3106 struct prefix_bag
*pb
;
3107 struct bgp_info
*info
;
3108 while (!skiplist_first
3109 (bgp
->rfapi
->resolve_nve_nexthop
, NULL
, (void *) &pb
))
3112 skiplist_delete_first (bgp
->rfapi
->resolve_nve_nexthop
);
3113 bgp_info_unlock (info
);
3117 bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT
] = 0;
3118 vnc_zlog_debug_verbose ("%s: return", __func__
);
3123 vnc_import_bgp_exterior_redist_disable (struct bgp
*bgp
, afi_t afi
)
3125 struct rfapi_cfg
*hc
= bgp
->rfapi_cfg
;
3126 struct bgp
*bgp_exterior
= hc
->redist_bgp_exterior_view
;
3128 vnc_zlog_debug_verbose ("%s: entry", __func__
);
3130 if (!hc
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
])
3132 vnc_zlog_debug_verbose ("%s: already disabled for afi %d, skipping", __func__
, afi
);
3138 vnc_zlog_debug_verbose ("%s: bgp exterior view not defined, skipping", __func__
);
3144 struct bgp_node
*rn
;
3145 for (rn
= bgp_table_top (bgp_exterior
->rib
[afi
][SAFI_UNICAST
]);
3146 rn
; rn
= bgp_route_next (rn
))
3149 struct bgp_info
*bi
;
3151 for (bi
= rn
->info
; bi
; bi
= bi
->next
)
3154 if (CHECK_FLAG (bi
->flags
, BGP_INFO_REMOVED
))
3157 vnc_import_bgp_exterior_del_route (bgp_exterior
, &rn
->p
, bi
);
3161 print_rhn_list (__func__
, NULL
);
3165 bgp
->rfapi_cfg
->redist
[afi
][ZEBRA_ROUTE_BGP_DIRECT_EXT
] = 0;
3166 vnc_zlog_debug_verbose ("%s: return", __func__
);