mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-28 21:06:50 +00:00
bgpd: add L3/L2VPN Virtual Network Control feature
This feature adds an L3 & L2 VPN application that makes use of the VPN and Encap SAFIs. This code is currently used to support IETF NVO3 style operation. In NVO3 terminology it provides the Network Virtualization Authority (NVA) and the ability to import/export IP prefixes and MAC addresses from Network Virtualization Edges (NVEs). The code supports per-NVE tables. The NVE-NVA protocol used to communicate routing and Ethernet / Layer 2 (L2) forwarding information between NVAs and NVEs is referred to as the Remote Forwarder Protocol (RFP). OpenFlow is an example RFP. For general background on NVO3 and RFP concepts see [1]. For information on Openflow see [2]. RFPs are integrated with BGP via the RF API contained in the new "rfapi" BGP sub-directory. Currently, only a simple example RFP is included in Quagga. Developers may use this example as a starting point to integrate Quagga with an RFP of their choosing, e.g., OpenFlow. The RFAPI code also supports the ability import/export of routing information between VNC and customer edge routers (CEs) operating within a virtual network. Import/export may take place between BGP views or to the default zebera VRF. BGP, with IP VPNs and Tunnel Encapsulation, is used to distribute VPN information between NVAs. BGP based IP VPN support is defined in RFC4364, BGP/MPLS IP Virtual Private Networks (VPNs), and RFC4659, BGP-MPLS IP Virtual Private Network (VPN) Extension for IPv6 VPN . Use of both the Encapsulation Subsequent Address Family Identifier (SAFI) and the Tunnel Encapsulation Attribute, RFC5512, The BGP Encapsulation Subsequent Address Family Identifier (SAFI) and the BGP Tunnel Encapsulation Attribute, are supported. MAC address distribution does not follow any standard BGB encoding, although it was inspired by the early IETF EVPN concepts. The feature is conditionally compiled and disabled by default. Use the --enable-bgp-vnc configure option to enable. The majority of this code was authored by G. Paul Ziemba <paulz@labn.net>. [1] http://tools.ietf.org/html/draft-ietf-nvo3-nve-nva-cp-req [2] https://www.opennetworking.org/sdn-resources/technical-library Now includes changes needed to merge with cmaster-next.
This commit is contained in:
parent
520d2512db
commit
65efcfce42
@ -1,12 +1,13 @@
|
||||
## Process this file with automake to produce Makefile.in.
|
||||
|
||||
SUBDIRS = lib qpb fpm @ZEBRA@ @BGPD@ @RIPD@ @RIPNGD@ @OSPFD@ @OSPF6D@ @LDPD@ \
|
||||
SUBDIRS = lib qpb fpm @ZEBRA@ @LIBRFP@ @RFPTEST@ \
|
||||
@BGPD@ @RIPD@ @RIPNGD@ @OSPFD@ @OSPF6D@ @LDPD@ \
|
||||
@ISISD@ @PIMD@ @WATCHQUAGGA@ @VTYSH@ @OSPFCLIENT@ @DOC@ m4 @pkgsrcdir@ \
|
||||
redhat @SOLARIS@ tests tools cumulus
|
||||
|
||||
DIST_SUBDIRS = lib qpb fpm zebra bgpd ripd ripngd ospfd ospf6d ldpd \
|
||||
isisd watchquagga vtysh ospfclient doc m4 pkgsrc redhat tests \
|
||||
solaris pimd tools cumulus
|
||||
solaris pimd @LIBRFP@ @RFPTEST@ tools cumulus
|
||||
|
||||
EXTRA_DIST = aclocal.m4 SERVICES TODO REPORTING-BUGS INSTALL.quagga.txt \
|
||||
update-autotools \
|
||||
|
@ -1,6 +1,64 @@
|
||||
## Process this file with automake to produce Makefile.in.
|
||||
AUTOMAKE_OPTIONS = subdir-objects
|
||||
|
||||
AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
|
||||
if ENABLE_BGP_VNC
|
||||
#o file to keep linker happy
|
||||
BGP_VNC_RFP_LIB=rfapi/rfapi_descriptor_rfp_utils.o @top_srcdir@/$(LIBRFP)/librfp.a
|
||||
BGP_VNC_RFP_INC=-I@top_srcdir@/$(RFPINC)
|
||||
BGP_VNC_RFP_HD=\
|
||||
@top_srcdir@/$(RFPINC)/rfp.h
|
||||
BGP_VNC_RFP_LD_FLAGS_FILE=@top_srcdir@/$(LIBRFP)/rfp_ld_flags
|
||||
BGP_VNC_RFP_LD_FLAGS=`if [ -e "$(BGP_VNC_RFP_LD_FLAGS_FILE)" ] ; then cat "$(BGP_VNC_RFP_LD_FLAGS_FILE)" ; fi `
|
||||
|
||||
#BGP_VNC_RFAPI_SRCDIR=rfapi
|
||||
BGP_VNC_RFAPI_SRCDIR=
|
||||
BGP_VNC_RFAPI_INC=-Irfapi
|
||||
BGP_VNC_RFAPI_SRC=rfapi/bgp_rfapi_cfg.c \
|
||||
rfapi/rfapi_import.c \
|
||||
rfapi/rfapi.c \
|
||||
rfapi/rfapi_ap.c \
|
||||
rfapi/rfapi_descriptor_rfp_utils.c \
|
||||
rfapi/rfapi_encap_tlv.c \
|
||||
rfapi/rfapi_nve_addr.c \
|
||||
rfapi/rfapi_monitor.c \
|
||||
rfapi/rfapi_rib.c \
|
||||
rfapi/rfapi_vty.c \
|
||||
rfapi/vnc_debug.c \
|
||||
rfapi/vnc_export_bgp.c \
|
||||
rfapi/vnc_export_table.c \
|
||||
rfapi/vnc_import_bgp.c \
|
||||
rfapi/vnc_zebra.c
|
||||
BGP_VNC_RFAPI_HD=rfapi/bgp_rfapi_cfg.h \
|
||||
rfapi/rfapi_import.h \
|
||||
rfapi/rfapi.h \
|
||||
rfapi/rfapi_ap.h \
|
||||
rfapi/rfapi_backend.h \
|
||||
rfapi/rfapi_descriptor_rfp_utils.h \
|
||||
rfapi/rfapi_encap_tlv.h \
|
||||
rfapi/rfapi_nve_addr.h \
|
||||
rfapi/rfapi_monitor.h \
|
||||
rfapi/rfapi_private.h \
|
||||
rfapi/rfapi_rib.h \
|
||||
rfapi/rfapi_vty.h \
|
||||
rfapi/vnc_debug.h \
|
||||
rfapi/vnc_export_bgp.h \
|
||||
rfapi/vnc_export_table.h \
|
||||
rfapi/vnc_import_bgp.h \
|
||||
rfapi/vnc_zebra.h \
|
||||
bgp_vnc_types.h $(BGP_VNC_RFP_HD)
|
||||
|
||||
else
|
||||
BGP_VNC_RFAPI_INC=
|
||||
BGP_VNC_RFAPI_SRC=
|
||||
BGP_VNC_RFAPI_HD=
|
||||
BGP_VNC_RFP_LIB=
|
||||
BGP_VNC_RFP_INC=
|
||||
BGP_VNC_RFP_HD=
|
||||
BGP_VNC_RFP_LD_FLAGS=
|
||||
endif
|
||||
|
||||
AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib \
|
||||
$(BGP_VNC_RFAPI_INC) $(BGP_VNC_RFP_INC)
|
||||
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
|
||||
INSTALL_SDATA=@INSTALL@ -m 600
|
||||
|
||||
@ -18,7 +76,7 @@ libbgp_a_SOURCES = \
|
||||
bgp_dump.c bgp_snmp.c bgp_ecommunity.c bgp_mplsvpn.c bgp_nexthop.c \
|
||||
bgp_damp.c bgp_table.c bgp_advertise.c bgp_vty.c bgp_mpath.c \
|
||||
bgp_nht.c bgp_updgrp.c bgp_updgrp_packet.c bgp_updgrp_adv.c bgp_bfd.c \
|
||||
bgp_encap.c bgp_encap_tlv.c
|
||||
bgp_encap.c bgp_encap_tlv.c $(BGP_VNC_RFAPI_SRC)
|
||||
|
||||
noinst_HEADERS = \
|
||||
bgp_memory.h \
|
||||
@ -27,16 +85,20 @@ noinst_HEADERS = \
|
||||
bgpd.h bgp_filter.h bgp_clist.h bgp_dump.h bgp_zebra.h \
|
||||
bgp_ecommunity.h bgp_mplsvpn.h bgp_nexthop.h bgp_damp.h bgp_table.h \
|
||||
bgp_advertise.h bgp_snmp.h bgp_vty.h bgp_mpath.h bgp_nht.h \
|
||||
bgp_updgrp.h bgp_bfd.h bgp_encap.h bgp_encap_tlv.h bgp_encap_types.h
|
||||
bgp_updgrp.h bgp_bfd.h bgp_encap.h bgp_encap_tlv.h bgp_encap_types.h \
|
||||
$(BGP_VNC_RFAPI_HD)
|
||||
|
||||
bgpd_SOURCES = bgp_main.c
|
||||
bgpd_LDADD = libbgp.a ../lib/libzebra.la @LIBCAP@ @LIBM@
|
||||
bgpd_LDADD = libbgp.a $(BGP_VNC_RFP_LIB) ../lib/libzebra.la @LIBCAP@ @LIBM@
|
||||
bgpd_LDFLAGS = $(BGP_VNC_RFP_LD_FLAGS)
|
||||
|
||||
bgp_btoa_SOURCES = bgp_btoa.c
|
||||
bgp_btoa_LDADD = libbgp.a ../lib/libzebra.la @LIBCAP@ @LIBM@
|
||||
bgp_btoa_LDADD = libbgp.a $(BGP_VNC_RFP_LIB) ../lib/libzebra.la @LIBCAP@ @LIBM@
|
||||
bgp_btoa_LDFLAGS = $(BGP_VNC_RFP_LD_FLAGS)
|
||||
|
||||
examplesdir = $(exampledir)
|
||||
dist_examples_DATA = bgpd.conf.sample bgpd.conf.sample2
|
||||
dist_examples_DATA = bgpd.conf.sample bgpd.conf.sample2 \
|
||||
bgpd.conf.vnc.sample
|
||||
|
||||
EXTRA_DIST = BGP4-MIB.txt
|
||||
|
||||
|
@ -43,6 +43,11 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "bgpd/bgp_ecommunity.h"
|
||||
#include "bgpd/bgp_updgrp.h"
|
||||
#include "bgpd/bgp_encap_types.h"
|
||||
#if ENABLE_BGP_VNC
|
||||
# include "bgp_rfapi_cfg.h"
|
||||
# include "bgp_encap_types.h"
|
||||
# include "bgp_vnc_types.h"
|
||||
#endif
|
||||
|
||||
/* Attribute strings for logging. */
|
||||
static const struct message attr_str [] =
|
||||
@ -67,6 +72,9 @@ static const struct message attr_str [] =
|
||||
{ BGP_ATTR_AS4_AGGREGATOR, "AS4_AGGREGATOR" },
|
||||
{ BGP_ATTR_AS_PATHLIMIT, "AS_PATHLIMIT" },
|
||||
{ BGP_ATTR_ENCAP, "ENCAP" },
|
||||
#if ENABLE_BGP_VNC
|
||||
{ BGP_ATTR_VNC, "VNC" },
|
||||
#endif
|
||||
};
|
||||
static const int attr_str_max = array_size(attr_str);
|
||||
|
||||
@ -256,6 +264,12 @@ bgp_attr_flush_encap(struct attr *attr)
|
||||
encap_free(attr->extra->encap_subtlvs);
|
||||
attr->extra->encap_subtlvs = NULL;
|
||||
}
|
||||
#if ENABLE_BGP_VNC
|
||||
if (attr->extra->vnc_subtlvs) {
|
||||
encap_free(attr->extra->vnc_subtlvs);
|
||||
attr->extra->vnc_subtlvs = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -421,6 +435,12 @@ bgp_attr_extra_free (struct attr *attr)
|
||||
encap_free(attr->extra->encap_subtlvs);
|
||||
attr->extra->encap_subtlvs = NULL;
|
||||
}
|
||||
#if ENABLE_BGP_VNC
|
||||
if (attr->extra->vnc_subtlvs) {
|
||||
encap_free(attr->extra->vnc_subtlvs);
|
||||
attr->extra->vnc_subtlvs = NULL;
|
||||
}
|
||||
#endif
|
||||
XFREE (MTYPE_ATTR_EXTRA, attr->extra);
|
||||
attr->extra = NULL;
|
||||
}
|
||||
@ -461,6 +481,11 @@ bgp_attr_dup (struct attr *new, struct attr *orig)
|
||||
if (orig->extra->encap_subtlvs) {
|
||||
new->extra->encap_subtlvs = encap_tlv_dup(orig->extra->encap_subtlvs);
|
||||
}
|
||||
#if ENABLE_BGP_VNC
|
||||
if (orig->extra->vnc_subtlvs) {
|
||||
new->extra->vnc_subtlvs = encap_tlv_dup(orig->extra->vnc_subtlvs);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (orig->extra)
|
||||
@ -470,6 +495,11 @@ bgp_attr_dup (struct attr *new, struct attr *orig)
|
||||
if (orig->extra->encap_subtlvs) {
|
||||
new->extra->encap_subtlvs = encap_tlv_dup(orig->extra->encap_subtlvs);
|
||||
}
|
||||
#if ENABLE_BGP_VNC
|
||||
if (orig->extra->vnc_subtlvs) {
|
||||
new->extra->vnc_subtlvs = encap_tlv_dup(orig->extra->vnc_subtlvs);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -611,6 +641,9 @@ attrhash_cmp (const void *p1, const void *p2)
|
||||
&& ae1->transit == ae2->transit
|
||||
&& (ae1->encap_tunneltype == ae2->encap_tunneltype)
|
||||
&& encap_same(ae1->encap_subtlvs, ae2->encap_subtlvs)
|
||||
#if ENABLE_BGP_VNC
|
||||
&& encap_same(ae1->vnc_subtlvs, ae2->vnc_subtlvs)
|
||||
#endif
|
||||
&& IPV4_ADDR_SAME (&ae1->originator_id, &ae2->originator_id))
|
||||
return 1;
|
||||
else if (ae1 || ae2)
|
||||
@ -669,6 +702,11 @@ bgp_attr_hash_alloc (void *p)
|
||||
if (attr->extra->encap_subtlvs) {
|
||||
attr->extra->encap_subtlvs = encap_tlv_dup(attr->extra->encap_subtlvs);
|
||||
}
|
||||
#if ENABLE_BGP_VNC
|
||||
if (attr->extra->vnc_subtlvs) {
|
||||
attr->extra->vnc_subtlvs = encap_tlv_dup(attr->extra->vnc_subtlvs);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
attr->refcnt = 0;
|
||||
return attr;
|
||||
@ -939,6 +977,10 @@ bgp_attr_flush (struct attr *attr)
|
||||
transit_free (attre->transit);
|
||||
encap_free(attre->encap_subtlvs);
|
||||
attre->encap_subtlvs = NULL;
|
||||
#if ENABLE_BGP_VNC
|
||||
encap_free(attre->vnc_subtlvs);
|
||||
attre->vnc_subtlvs = NULL;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -1956,6 +1998,12 @@ bgp_attr_encap(
|
||||
subtype = stream_getc (BGP_INPUT (peer));
|
||||
sublength = stream_getc (BGP_INPUT (peer));
|
||||
length -= 2;
|
||||
#if ENABLE_BGP_VNC
|
||||
} else {
|
||||
subtype = stream_getw (BGP_INPUT (peer));
|
||||
sublength = stream_getw (BGP_INPUT (peer));
|
||||
length -= 4;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (sublength > length) {
|
||||
@ -1987,6 +2035,16 @@ bgp_attr_encap(
|
||||
} else {
|
||||
attre->encap_subtlvs = tlv;
|
||||
}
|
||||
#if ENABLE_BGP_VNC
|
||||
} else {
|
||||
for (stlv_last = attre->vnc_subtlvs; stlv_last && stlv_last->next;
|
||||
stlv_last = stlv_last->next);
|
||||
if (stlv_last) {
|
||||
stlv_last->next = tlv;
|
||||
} else {
|
||||
attre->vnc_subtlvs = tlv;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
stlv_last->next = tlv;
|
||||
@ -2300,6 +2358,9 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
|
||||
case BGP_ATTR_EXT_COMMUNITIES:
|
||||
ret = bgp_attr_ext_communities (&attr_args);
|
||||
break;
|
||||
#if ENABLE_BGP_VNC
|
||||
case BGP_ATTR_VNC:
|
||||
#endif
|
||||
case BGP_ATTR_ENCAP:
|
||||
ret = bgp_attr_encap (type, peer, length, attr, flag, startp);
|
||||
break;
|
||||
@ -2569,7 +2630,9 @@ bgp_packet_mpattr_prefix_size (afi_t afi, safi_t safi, struct prefix *p)
|
||||
}
|
||||
|
||||
/*
|
||||
* Encodes the tunnel encapsulation attribute
|
||||
* Encodes the tunnel encapsulation attribute,
|
||||
* and with ENABLE_BGP_VNC the VNC attribute which uses
|
||||
* almost the same TLV format
|
||||
*/
|
||||
static void
|
||||
bgp_packet_mpattr_tea(
|
||||
@ -2603,6 +2666,15 @@ bgp_packet_mpattr_tea(
|
||||
attrhdrlen = 1 + 1; /* subTLV T + L */
|
||||
break;
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
case BGP_ATTR_VNC:
|
||||
attrname = "VNC";
|
||||
subtlvs = attr->extra->vnc_subtlvs;
|
||||
attrlenfield = 0; /* no outer T + L */
|
||||
attrhdrlen = 2 + 2; /* subTLV T + L */
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
@ -2648,6 +2720,11 @@ bgp_packet_mpattr_tea(
|
||||
if (attrtype == BGP_ATTR_ENCAP) {
|
||||
stream_putc (s, st->type);
|
||||
stream_putc (s, st->length);
|
||||
#if ENABLE_BGP_VNC
|
||||
} else {
|
||||
stream_putw (s, st->type);
|
||||
stream_putw (s, st->length);
|
||||
#endif
|
||||
}
|
||||
stream_put (s, st->value, st->length);
|
||||
}
|
||||
@ -3037,6 +3114,11 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
|
||||
{
|
||||
/* Tunnel Encap attribute */
|
||||
bgp_packet_mpattr_tea(bgp, peer, s, attr, BGP_ATTR_ENCAP);
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
/* VNC attribute */
|
||||
bgp_packet_mpattr_tea(bgp, peer, s, attr, BGP_ATTR_VNC);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Unknown transit attribute. */
|
||||
|
@ -63,6 +63,21 @@ struct bgp_attr_encap_subtlv {
|
||||
uint8_t value[1]; /* will be extended */
|
||||
};
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
/*
|
||||
* old rfp<->rfapi representation
|
||||
*/
|
||||
struct bgp_tea_options {
|
||||
struct bgp_tea_options *next;
|
||||
uint8_t options_count;
|
||||
uint16_t options_length; /* each TLV may be 256 in length */
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
void *value; /* pointer to data */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* Additional/uncommon BGP attributes.
|
||||
* lazily allocated as and when a struct attr
|
||||
* requires it.
|
||||
@ -107,6 +122,10 @@ struct attr_extra
|
||||
|
||||
uint16_t encap_tunneltype; /* grr */
|
||||
struct bgp_attr_encap_subtlv *encap_subtlvs; /* rfc5512 */
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
struct bgp_attr_encap_subtlv *vnc_subtlvs; /* VNC-specific */
|
||||
#endif
|
||||
};
|
||||
|
||||
/* BGP core attribute structure. */
|
||||
|
@ -35,7 +35,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
static struct hash *ecomhash;
|
||||
|
||||
/* Allocate a new ecommunities. */
|
||||
static struct ecommunity *
|
||||
struct ecommunity *
|
||||
ecommunity_new (void)
|
||||
{
|
||||
return (struct ecommunity *) XCALLOC (MTYPE_ECOMMUNITY,
|
||||
@ -59,7 +59,7 @@ ecommunity_free (struct ecommunity **ecom)
|
||||
structure, we don't add the value. Newly added value is sorted by
|
||||
numerical order. When the value is added to the structure return 1
|
||||
else return 0. */
|
||||
static int
|
||||
int
|
||||
ecommunity_add_val (struct ecommunity *ecom, struct ecommunity_val *eval)
|
||||
{
|
||||
u_int8_t *p;
|
||||
|
@ -85,4 +85,7 @@ extern char *ecommunity_ecom2str (struct ecommunity *, int);
|
||||
extern int ecommunity_match (const struct ecommunity *, const struct ecommunity *);
|
||||
extern char *ecommunity_str (struct ecommunity *);
|
||||
|
||||
/* for vpn */
|
||||
extern struct ecommunity *ecommunity_new (void);
|
||||
extern int ecommunity_add_val (struct ecommunity *, struct ecommunity_val *);
|
||||
#endif /* _QUAGGA_BGP_ECOMMUNITY_H */
|
||||
|
@ -45,6 +45,10 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "bgpd/bgp_vty.h"
|
||||
#include "bgpd/bgp_encap.h"
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
#include "rfapi_backend.h"
|
||||
#endif
|
||||
|
||||
static void
|
||||
ecom2prd(struct ecommunity *ecom, struct prefix_rd *prd)
|
||||
{
|
||||
@ -185,7 +189,15 @@ bgp_nlri_parse_encap(
|
||||
if (!withdraw) {
|
||||
bgp_update (peer, &p, 0, attr, afi, SAFI_ENCAP,
|
||||
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, NULL, 0);
|
||||
#if ENABLE_BGP_VNC
|
||||
rfapiProcessUpdate(peer, NULL, &p, &prd, attr, afi, SAFI_ENCAP,
|
||||
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL);
|
||||
#endif
|
||||
} else {
|
||||
#if ENABLE_BGP_VNC
|
||||
rfapiProcessWithdraw(peer, NULL, &p, &prd, attr, afi, SAFI_ENCAP,
|
||||
ZEBRA_ROUTE_BGP, 0);
|
||||
#endif
|
||||
bgp_withdraw (peer, &p, 0, attr, afi, SAFI_ENCAP,
|
||||
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, NULL);
|
||||
}
|
||||
|
@ -409,9 +409,7 @@ bgp_encap_type_mpls_to_tlv(
|
||||
struct bgp_encap_type_mpls *bet, /* input structure */
|
||||
struct attr *attr)
|
||||
{
|
||||
struct attr_extra *extra = bgp_attr_extra_get(attr);
|
||||
|
||||
extra->encap_tunneltype = BGP_ENCAP_TYPE_MPLS;
|
||||
return; /* no encap attribute for MPLS */
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -32,7 +32,7 @@ typedef enum {
|
||||
BGP_ENCAP_TYPE_IP_IN_IP=7,
|
||||
BGP_ENCAP_TYPE_VXLAN=8,
|
||||
BGP_ENCAP_TYPE_NVGRE=9,
|
||||
BGP_ENCAP_TYPE_MPLS=10,
|
||||
BGP_ENCAP_TYPE_MPLS=10, /* NOTE: Encap SAFI&Attribute not used */
|
||||
BGP_ENCAP_TYPE_MPLS_IN_GRE=11,
|
||||
BGP_ENCAP_TYPE_VXLAN_GPE=12,
|
||||
BGP_ENCAP_TYPE_MPLS_IN_UDP=13,
|
||||
|
@ -54,6 +54,10 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "bgpd/bgp_filter.h"
|
||||
#include "bgpd/bgp_zebra.h"
|
||||
|
||||
#ifdef ENABLE_BGP_VNC
|
||||
#include "rfapi_backend.h"
|
||||
#endif
|
||||
|
||||
/* bgpd options, we use GNU getopt library. */
|
||||
static const struct option longopts[] =
|
||||
{
|
||||
@ -282,7 +286,9 @@ bgp_exit (int status)
|
||||
bgp_vrf_terminate ();
|
||||
cmd_terminate ();
|
||||
vty_terminate ();
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
vnc_zebra_destroy();
|
||||
#endif
|
||||
bgp_zebra_destroy();
|
||||
if (bgp_nexthop_buf)
|
||||
stream_free (bgp_nexthop_buf);
|
||||
|
@ -108,3 +108,6 @@ DEFINE_MTYPE(BGPD, BGP_REDIST, "BGP redistribution")
|
||||
DEFINE_MTYPE(BGPD, BGP_FILTER_NAME, "BGP Filter Information")
|
||||
DEFINE_MTYPE(BGPD, BGP_DUMP_STR, "BGP Dump String Information")
|
||||
DEFINE_MTYPE(BGPD, ENCAP_TLV, "ENCAP TLV")
|
||||
|
||||
DEFINE_MTYPE(BGPD, BGP_TEA_OPTIONS, "BGP TEA Options")
|
||||
DEFINE_MTYPE(BGPD, BGP_TEA_OPTIONS_VALUE, "BGP TEA Options Value")
|
||||
|
@ -105,4 +105,7 @@ DECLARE_MTYPE(BGP_FILTER_NAME)
|
||||
DECLARE_MTYPE(BGP_DUMP_STR)
|
||||
DECLARE_MTYPE(ENCAP_TLV)
|
||||
|
||||
DECLARE_MTYPE(BGP_TEA_OPTIONS)
|
||||
DECLARE_MTYPE(BGP_TEA_OPTIONS_VALUE)
|
||||
|
||||
#endif /* _QUAGGA_BGP_MEMORY_H */
|
||||
|
@ -35,16 +35,35 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "bgpd/bgp_attr.h"
|
||||
#include "bgpd/bgp_mplsvpn.h"
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
#include "rfapi_backend.h"
|
||||
#endif
|
||||
|
||||
u_int16_t
|
||||
decode_rd_type (u_char *pnt)
|
||||
{
|
||||
u_int16_t v;
|
||||
|
||||
v = ((u_int16_t) *pnt++ << 8);
|
||||
#if ENABLE_BGP_VNC
|
||||
/*
|
||||
* VNC L2 stores LHI in lower byte, so omit it
|
||||
*/
|
||||
if (v != RD_TYPE_VNC_ETH)
|
||||
v |= (u_int16_t) *pnt;
|
||||
#else /* duplicate code for clarity */
|
||||
v |= (u_int16_t) *pnt;
|
||||
#endif
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
void
|
||||
encode_rd_type (u_int16_t v, u_char *pnt)
|
||||
{
|
||||
*((u_int16_t *)pnt) = htons(v);
|
||||
}
|
||||
|
||||
u_int32_t
|
||||
decode_label (u_char *pnt)
|
||||
{
|
||||
@ -56,6 +75,17 @@ decode_label (u_char *pnt)
|
||||
return l;
|
||||
}
|
||||
|
||||
void
|
||||
encode_label(u_int32_t label,
|
||||
u_char *pnt)
|
||||
{
|
||||
if (pnt == NULL)
|
||||
return;
|
||||
*pnt++ = (label>>12) & 0xff;
|
||||
*pnt++ = (label>>4) & 0xff;
|
||||
*pnt++ = ((label<<4)+1) & 0xff; /* S=1 */
|
||||
}
|
||||
|
||||
/* type == RD_TYPE_AS */
|
||||
void
|
||||
decode_rd_as (u_char *pnt, struct rd_as *rd_as)
|
||||
@ -93,6 +123,17 @@ decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip)
|
||||
rd_ip->val |= (u_int16_t) *pnt;
|
||||
}
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
/* type == RD_TYPE_VNC_ETH */
|
||||
void
|
||||
decode_rd_vnc_eth (u_char *pnt, struct rd_vnc_eth *rd_vnc_eth)
|
||||
{
|
||||
rd_vnc_eth->type = RD_TYPE_VNC_ETH;
|
||||
rd_vnc_eth->local_nve_id = pnt[1];
|
||||
memcpy (rd_vnc_eth->macaddr.octet, pnt + 2, ETHER_ADDR_LEN);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
bgp_nlri_parse_vpn (struct peer *peer, struct attr *attr,
|
||||
struct bgp_nlri *packet)
|
||||
@ -111,6 +152,9 @@ bgp_nlri_parse_vpn (struct peer *peer, struct attr *attr,
|
||||
safi_t safi;
|
||||
int addpath_encoded;
|
||||
u_int32_t addpath_id;
|
||||
#if ENABLE_BGP_VNC
|
||||
u_int32_t label = 0;
|
||||
#endif
|
||||
|
||||
/* Check peer status. */
|
||||
if (peer->status != Established)
|
||||
@ -184,6 +228,10 @@ bgp_nlri_parse_vpn (struct peer *peer, struct attr *attr,
|
||||
|
||||
}
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
label = decode_label (pnt);
|
||||
#endif
|
||||
|
||||
/* Copyr label to prefix. */
|
||||
tagpnt = pnt;
|
||||
|
||||
@ -207,21 +255,39 @@ bgp_nlri_parse_vpn (struct peer *peer, struct attr *attr,
|
||||
decode_rd_ip (pnt + 5, &rd_ip);
|
||||
break;
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
case RD_TYPE_VNC_ETH:
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
zlog_err ("Unknown RD type %d", type);
|
||||
break; /* just report */
|
||||
}
|
||||
|
||||
p.prefixlen = prefixlen - VPN_PREFIXLEN_MIN_BYTES*8;
|
||||
p.prefixlen = prefixlen - VPN_PREFIXLEN_MIN_BYTES*8;/* exclude label & RD */
|
||||
memcpy (&p.u.prefix, pnt + VPN_PREFIXLEN_MIN_BYTES,
|
||||
psize - VPN_PREFIXLEN_MIN_BYTES);
|
||||
|
||||
if (attr)
|
||||
bgp_update (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN,
|
||||
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0);
|
||||
{
|
||||
bgp_update (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN,
|
||||
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0);
|
||||
#if ENABLE_BGP_VNC
|
||||
rfapiProcessUpdate(peer, NULL, &p, &prd, attr, packet->afi,
|
||||
SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
|
||||
&label);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
bgp_withdraw (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN,
|
||||
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt);
|
||||
{
|
||||
#if ENABLE_BGP_VNC
|
||||
rfapiProcessWithdraw(peer, NULL, &p, &prd, attr, packet->afi,
|
||||
SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP, 0);
|
||||
#endif
|
||||
bgp_withdraw (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN,
|
||||
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt);
|
||||
}
|
||||
}
|
||||
/* Packet length consistency check. */
|
||||
if (pnt != lim)
|
||||
@ -346,6 +412,21 @@ prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
|
||||
snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
|
||||
return buf;
|
||||
}
|
||||
#if ENABLE_BGP_VNC
|
||||
else if (type == RD_TYPE_VNC_ETH)
|
||||
{
|
||||
snprintf(buf, size, "LHI:%d, %02x:%02x:%02x:%02x:%02x:%02x",
|
||||
*(pnt+1), /* LHI */
|
||||
*(pnt+2), /* MAC[0] */
|
||||
*(pnt+3),
|
||||
*(pnt+4),
|
||||
*(pnt+5),
|
||||
*(pnt+6),
|
||||
*(pnt+7));
|
||||
|
||||
return buf;
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -483,6 +564,9 @@ show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd, u
|
||||
u_int16_t type;
|
||||
struct rd_as rd_as;
|
||||
struct rd_ip rd_ip = {0};
|
||||
#if ENABLE_BGP_VNC
|
||||
struct rd_vnc_eth rd_vnc_eth;
|
||||
#endif
|
||||
u_char *pnt;
|
||||
|
||||
pnt = rn->p.u.val;
|
||||
@ -496,6 +580,10 @@ show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd, u
|
||||
decode_rd_as4 (pnt + 2, &rd_as);
|
||||
else if (type == RD_TYPE_IP)
|
||||
decode_rd_ip (pnt + 2, &rd_ip);
|
||||
#if ENABLE_BGP_VNC
|
||||
else if (type == RD_TYPE_VNC_ETH)
|
||||
decode_rd_vnc_eth (pnt, &rd_vnc_eth);
|
||||
#endif
|
||||
|
||||
if (use_json)
|
||||
{
|
||||
@ -514,6 +602,17 @@ show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd, u
|
||||
vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
|
||||
else if (type == RD_TYPE_IP)
|
||||
vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
|
||||
#if ENABLE_BGP_VNC
|
||||
else if (type == RD_TYPE_VNC_ETH)
|
||||
vty_out (vty, "%u:%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
rd_vnc_eth.local_nve_id,
|
||||
rd_vnc_eth.macaddr.octet[0],
|
||||
rd_vnc_eth.macaddr.octet[1],
|
||||
rd_vnc_eth.macaddr.octet[2],
|
||||
rd_vnc_eth.macaddr.octet[3],
|
||||
rd_vnc_eth.macaddr.octet[4],
|
||||
rd_vnc_eth.macaddr.octet[5]);
|
||||
#endif
|
||||
|
||||
vty_out (vty, "%s", VTY_NEWLINE);
|
||||
}
|
||||
@ -675,6 +774,9 @@ bgp_show_mpls_vpn (struct vty *vty, afi_t afi, struct prefix_rd *prd,
|
||||
u_int16_t type;
|
||||
struct rd_as rd_as;
|
||||
struct rd_ip rd_ip = {0};
|
||||
#if ENABLE_BGP_VNC
|
||||
struct rd_vnc_eth rd_vnc_eth;
|
||||
#endif
|
||||
u_char *pnt;
|
||||
|
||||
pnt = rn->p.u.val;
|
||||
@ -688,6 +790,10 @@ bgp_show_mpls_vpn (struct vty *vty, afi_t afi, struct prefix_rd *prd,
|
||||
decode_rd_as4 (pnt + 2, &rd_as);
|
||||
else if (type == RD_TYPE_IP)
|
||||
decode_rd_ip (pnt + 2, &rd_ip);
|
||||
#if ENABLE_BGP_VNC
|
||||
else if (type == RD_TYPE_VNC_ETH)
|
||||
decode_rd_vnc_eth (pnt, &rd_vnc_eth);
|
||||
#endif
|
||||
|
||||
if (use_json)
|
||||
{
|
||||
@ -706,6 +812,17 @@ bgp_show_mpls_vpn (struct vty *vty, afi_t afi, struct prefix_rd *prd,
|
||||
vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
|
||||
else if (type == RD_TYPE_IP)
|
||||
vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
|
||||
#if ENABLE_BGP_VNC
|
||||
else if (type == RD_TYPE_VNC_ETH)
|
||||
vty_out (vty, "%u:%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
rd_vnc_eth.local_nve_id,
|
||||
rd_vnc_eth.macaddr.octet[0],
|
||||
rd_vnc_eth.macaddr.octet[1],
|
||||
rd_vnc_eth.macaddr.octet[2],
|
||||
rd_vnc_eth.macaddr.octet[3],
|
||||
rd_vnc_eth.macaddr.octet[4],
|
||||
rd_vnc_eth.macaddr.octet[5]);
|
||||
#endif
|
||||
vty_out (vty, "%s", VTY_NEWLINE);
|
||||
}
|
||||
rd_header = 0;
|
||||
|
@ -24,9 +24,37 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
#define RD_TYPE_AS 0
|
||||
#define RD_TYPE_IP 1
|
||||
#define RD_TYPE_AS4 2
|
||||
#if ENABLE_BGP_VNC
|
||||
#define RD_TYPE_VNC_ETH 0xff00 /* VNC L2VPN */
|
||||
#endif
|
||||
|
||||
#define RD_ADDRSTRLEN 28
|
||||
|
||||
typedef enum {
|
||||
MPLS_LABEL_IPV4_EXPLICIT_NULL = 0, /* [RFC3032] */
|
||||
MPLS_LABEL_ROUTER_ALERT = 1, /* [RFC3032] */
|
||||
MPLS_LABEL_IPV6_EXPLICIT_NULL = 2, /* [RFC3032] */
|
||||
MPLS_LABEL_IMPLICIT_NULL = 3, /* [RFC3032] */
|
||||
MPLS_LABEL_UNASSIGNED4 = 4,
|
||||
MPLS_LABEL_UNASSIGNED5 = 5,
|
||||
MPLS_LABEL_UNASSIGNED6 = 6,
|
||||
MPLS_LABEL_ELI = 7, /* Entropy Indicator [RFC6790] */
|
||||
MPLS_LABEL_UNASSIGNED8 = 8,
|
||||
MPLS_LABEL_UNASSIGNED9 = 9,
|
||||
MPLS_LABEL_UNASSIGNED10 = 10,
|
||||
MPLS_LABEL_UNASSIGNED11 = 11,
|
||||
MPLS_LABEL_GAL = 13, /* [RFC5586] */
|
||||
MPLS_LABEL_OAM_ALERT = 14, /* [RFC3429] */
|
||||
MPLS_LABEL_EXTENSION = 15 /* [RFC7274] */
|
||||
} mpls_special_label_t;
|
||||
|
||||
#define MPLS_LABEL_IS_SPECIAL(label) \
|
||||
((label) <= MPLS_LABEL_EXTENSION)
|
||||
#define MPLS_LABEL_IS_NULL(label) \
|
||||
((label) == MPLS_LABEL_IPV4_EXPLICIT_NULL || \
|
||||
(label) == MPLS_LABEL_IPV6_EXPLICIT_NULL || \
|
||||
(label) == MPLS_LABEL_IMPLICIT_NULL)
|
||||
|
||||
struct rd_as
|
||||
{
|
||||
u_int16_t type;
|
||||
@ -41,7 +69,17 @@ struct rd_ip
|
||||
u_int16_t val;
|
||||
};
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
struct rd_vnc_eth
|
||||
{
|
||||
u_int16_t type;
|
||||
uint8_t local_nve_id;
|
||||
struct ethaddr macaddr;
|
||||
};
|
||||
#endif
|
||||
|
||||
extern u_int16_t decode_rd_type (u_char *);
|
||||
extern void encode_rd_type (u_int16_t, u_char *);
|
||||
extern void bgp_mplsvpn_init (void);
|
||||
extern int bgp_nlri_parse_vpn (struct peer *, struct attr *, struct bgp_nlri *);
|
||||
extern u_int32_t decode_label (u_char *);
|
||||
@ -49,6 +87,9 @@ extern void encode_label(u_int32_t, u_char *);
|
||||
extern void decode_rd_as (u_char *, struct rd_as *);
|
||||
extern void decode_rd_as4 (u_char *, struct rd_as *);
|
||||
extern void decode_rd_ip (u_char *, struct rd_ip *);
|
||||
#if ENABLE_BGP_VNC
|
||||
extern void decode_vnc_eth (u_char *, struct rd_vnc_eth *);
|
||||
#endif
|
||||
extern int str2prefix_rd (const char *, struct prefix_rd *);
|
||||
extern int str2tag (const char *, u_char *);
|
||||
extern char *prefix_rd2str (struct prefix_rd *, char *, size_t);
|
||||
|
@ -34,6 +34,8 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
AF_UNSPEC)) \
|
||||
)
|
||||
|
||||
#define BGP_MP_NEXTHOP_FAMILY NEXTHOP_FAMILY
|
||||
|
||||
/* BGP nexthop cache value structure. */
|
||||
struct bgp_nexthop_cache
|
||||
{
|
||||
|
294
bgpd/bgp_route.c
294
bgpd/bgp_route.c
@ -62,6 +62,12 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "bgpd/bgp_updgrp.h"
|
||||
#include "bgpd/bgp_vty.h"
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
#include "rfapi_backend.h"
|
||||
#include "vnc_import_bgp.h"
|
||||
#include "vnc_export_bgp.h"
|
||||
#endif
|
||||
|
||||
/* Extern from bgp_dump.c */
|
||||
extern const char *bgp_origin_str[];
|
||||
extern const char *bgp_origin_long_str[];
|
||||
@ -132,6 +138,13 @@ bgp_info_extra_get (struct bgp_info *ri)
|
||||
return ri->extra;
|
||||
}
|
||||
|
||||
/* Allocate new bgp info structure. */
|
||||
struct bgp_info *
|
||||
bgp_info_new (void)
|
||||
{
|
||||
return XCALLOC (MTYPE_BGP_ROUTE, sizeof (struct bgp_info));
|
||||
}
|
||||
|
||||
/* Free bgp route information. */
|
||||
static void
|
||||
bgp_info_free (struct bgp_info *binfo)
|
||||
@ -228,7 +241,7 @@ bgp_info_delete (struct bgp_node *rn, struct bgp_info *ri)
|
||||
/* undo the effects of a previous call to bgp_info_delete; typically
|
||||
called when a route is deleted and then quickly re-added before the
|
||||
deletion has been processed */
|
||||
static void
|
||||
void
|
||||
bgp_info_restore (struct bgp_node *rn, struct bgp_info *ri)
|
||||
{
|
||||
bgp_info_unset_flag (rn, ri, BGP_INFO_REMOVED);
|
||||
@ -332,7 +345,7 @@ bgp_info_path_with_addpath_rx_str (struct bgp_info *ri, char *buf)
|
||||
static int
|
||||
bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist,
|
||||
int *paths_eq, struct bgp_maxpaths_cfg *mpath_cfg, int debug,
|
||||
char *pfx_buf)
|
||||
const char *pfx_buf)
|
||||
{
|
||||
struct attr *newattr, *existattr;
|
||||
struct attr_extra *newattre, *existattre;
|
||||
@ -847,6 +860,31 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
|
||||
* is preferred, or 0 if they are the same (usually will only occur if
|
||||
* multipath is enabled
|
||||
* This version is compatible with */
|
||||
int
|
||||
bgp_info_cmp_compatible (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist,
|
||||
afi_t afi, safi_t safi)
|
||||
{
|
||||
int paths_eq;
|
||||
struct bgp_maxpaths_cfg mpath_cfg;
|
||||
int ret;
|
||||
ret = bgp_info_cmp (bgp, new, exist, &paths_eq, &mpath_cfg, 0, __func__);
|
||||
|
||||
if (paths_eq)
|
||||
ret = 0;
|
||||
else
|
||||
{
|
||||
if (ret == 1)
|
||||
ret = -1;
|
||||
else
|
||||
ret = 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static enum filter_type
|
||||
bgp_input_filter (struct peer *peer, struct prefix *p, struct attr *attr,
|
||||
afi_t afi, safi_t safi)
|
||||
@ -1159,6 +1197,7 @@ subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
|
||||
int reflect;
|
||||
afi_t afi;
|
||||
safi_t safi;
|
||||
int samepeer_safe = 0; /* for synthetic mplsvpns routes */
|
||||
|
||||
if (DISABLE_BGP_ANNOUNCE)
|
||||
return 0;
|
||||
@ -1175,6 +1214,22 @@ subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
|
||||
bgp = SUBGRP_INST(subgrp);
|
||||
riattr = bgp_info_mpath_count (ri) ? bgp_info_mpath_attr (ri) : ri->attr;
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN) &&
|
||||
((ri->type == ZEBRA_ROUTE_BGP_DIRECT) ||
|
||||
(ri->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
|
||||
|
||||
/*
|
||||
* direct and direct_ext type routes originate internally even
|
||||
* though they can have peer pointers that reference other systems
|
||||
*/
|
||||
char buf[BUFSIZ];
|
||||
prefix2str(p, buf, BUFSIZ);
|
||||
zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe", __func__, buf);
|
||||
samepeer_safe = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* With addpath we may be asked to TX all kinds of paths so make sure
|
||||
* ri is valid */
|
||||
if (!CHECK_FLAG (ri->flags, BGP_INFO_VALID) ||
|
||||
@ -1311,7 +1366,7 @@ subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
|
||||
reflect = 0;
|
||||
|
||||
/* IBGP reflection check. */
|
||||
if (reflect)
|
||||
if (reflect && !samepeer_safe)
|
||||
{
|
||||
/* A route from a Client peer. */
|
||||
if (CHECK_FLAG (from->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
|
||||
@ -1869,8 +1924,13 @@ bgp_process_main (struct work_queue *wq, void *data)
|
||||
!bgp->addpath_tx_used[afi][safi])
|
||||
{
|
||||
if (bgp_zebra_has_route_changed (rn, old_select))
|
||||
bgp_zebra_announce (p, old_select, bgp, afi, safi);
|
||||
|
||||
{
|
||||
#if ENABLE_BGP_VNC
|
||||
vnc_import_bgp_add_route(bgp, p, old_select);
|
||||
vnc_import_bgp_exterior_add_route(bgp, p, old_select);
|
||||
#endif
|
||||
bgp_zebra_announce (p, old_select, bgp, afi, safi);
|
||||
}
|
||||
UNSET_FLAG (old_select->flags, BGP_INFO_MULTIPATH_CHG);
|
||||
bgp_zebra_clear_route_change_flags (rn);
|
||||
UNSET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
|
||||
@ -1903,6 +1963,21 @@ bgp_process_main (struct work_queue *wq, void *data)
|
||||
UNSET_FLAG (new_select->flags, BGP_INFO_MULTIPATH_CHG);
|
||||
}
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
|
||||
if (old_select != new_select) {
|
||||
if (old_select) {
|
||||
vnc_import_bgp_exterior_del_route(bgp, p, old_select);
|
||||
vnc_import_bgp_del_route(bgp, p, old_select);
|
||||
}
|
||||
if (new_select) {
|
||||
vnc_import_bgp_exterior_add_route(bgp, p, new_select);
|
||||
vnc_import_bgp_add_route(bgp, p, new_select);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
group_announce_route(bgp, afi, safi, rn, new_select);
|
||||
|
||||
/* FIB update. */
|
||||
@ -2136,7 +2211,7 @@ bgp_rib_remove (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer,
|
||||
|
||||
static void
|
||||
bgp_rib_withdraw (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer,
|
||||
afi_t afi, safi_t safi)
|
||||
afi_t afi, safi_t safi, struct prefix_rd *prd)
|
||||
{
|
||||
int status = BGP_DAMP_NONE;
|
||||
|
||||
@ -2151,7 +2226,33 @@ bgp_rib_withdraw (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer,
|
||||
bgp_aggregate_decrement (peer->bgp, &rn->p, ri, afi, safi);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
if (safi == SAFI_MPLS_VPN) {
|
||||
struct bgp_node *prn = NULL;
|
||||
struct bgp_table *table = NULL;
|
||||
|
||||
prn = bgp_node_get(peer->bgp->rib[afi][safi], (struct prefix *) prd);
|
||||
if (prn->info) {
|
||||
table = (struct bgp_table *)(prn->info);
|
||||
|
||||
vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
|
||||
peer->bgp,
|
||||
prd,
|
||||
table,
|
||||
&rn->p,
|
||||
ri);
|
||||
}
|
||||
bgp_unlock_node(prn);
|
||||
}
|
||||
if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
|
||||
if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)) {
|
||||
|
||||
vnc_import_bgp_del_route(peer->bgp, &rn->p, ri);
|
||||
vnc_import_bgp_exterior_del_route(peer->bgp, &rn->p, ri);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
bgp_rib_remove (rn, ri, peer, afi, safi);
|
||||
}
|
||||
|
||||
@ -2254,6 +2355,9 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
|
||||
char buf[SU_ADDRSTRLEN];
|
||||
char buf2[30];
|
||||
int connected = 0;
|
||||
#if ENABLE_BGP_VNC
|
||||
int vnc_implicit_withdraw = 0;
|
||||
#endif
|
||||
|
||||
bgp = peer->bgp;
|
||||
rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
|
||||
@ -2443,6 +2547,35 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
|
||||
if (! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
|
||||
bgp_damp_withdraw (ri, rn, afi, safi, 1);
|
||||
}
|
||||
#if ENABLE_BGP_VNC
|
||||
if (safi == SAFI_MPLS_VPN) {
|
||||
struct bgp_node *prn = NULL;
|
||||
struct bgp_table *table = NULL;
|
||||
|
||||
prn = bgp_node_get(bgp->rib[afi][safi], (struct prefix *) prd);
|
||||
if (prn->info) {
|
||||
table = (struct bgp_table *)(prn->info);
|
||||
|
||||
vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
|
||||
bgp,
|
||||
prd,
|
||||
table,
|
||||
p,
|
||||
ri);
|
||||
}
|
||||
bgp_unlock_node(prn);
|
||||
}
|
||||
if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
|
||||
if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)) {
|
||||
/*
|
||||
* Implicit withdraw case.
|
||||
*/
|
||||
++vnc_implicit_withdraw;
|
||||
vnc_import_bgp_del_route(bgp, p, ri);
|
||||
vnc_import_bgp_exterior_del_route(bgp, p, ri);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Update to new attribute. */
|
||||
bgp_attr_unintern (&ri->attr);
|
||||
@ -2452,6 +2585,25 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
|
||||
if (safi == SAFI_MPLS_VPN)
|
||||
memcpy ((bgp_info_extra_get (ri))->tag, tag, 3);
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST))
|
||||
{
|
||||
if (vnc_implicit_withdraw)
|
||||
{
|
||||
/*
|
||||
* Add back the route with its new attributes (e.g., nexthop).
|
||||
* The route is still selected, until the route selection
|
||||
* queued by bgp_process actually runs. We have to make this
|
||||
* update to the VNC side immediately to avoid racing against
|
||||
* configuration changes (e.g., route-map changes) which
|
||||
* trigger re-importation of the entire RIB.
|
||||
*/
|
||||
vnc_import_bgp_add_route(bgp, p, ri);
|
||||
vnc_import_bgp_exterior_add_route(bgp, p, ri);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Update bgp route dampening information. */
|
||||
if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
|
||||
&& peer->sort == BGP_PEER_EBGP)
|
||||
@ -2491,6 +2643,28 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
|
||||
else
|
||||
bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
if (safi == SAFI_MPLS_VPN)
|
||||
{
|
||||
struct bgp_node *prn = NULL;
|
||||
struct bgp_table *table = NULL;
|
||||
|
||||
prn = bgp_node_get(bgp->rib[afi][safi], (struct prefix *) prd);
|
||||
if (prn->info)
|
||||
{
|
||||
table = (struct bgp_table *)(prn->info);
|
||||
|
||||
vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
|
||||
bgp,
|
||||
prd,
|
||||
table,
|
||||
p,
|
||||
ri);
|
||||
}
|
||||
bgp_unlock_node(prn);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Process change. */
|
||||
bgp_aggregate_increment (bgp, p, ri, afi, safi);
|
||||
|
||||
@ -2561,6 +2735,28 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
|
||||
/* route_node_get lock */
|
||||
bgp_unlock_node (rn);
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
if (safi == SAFI_MPLS_VPN)
|
||||
{
|
||||
struct bgp_node *prn = NULL;
|
||||
struct bgp_table *table = NULL;
|
||||
|
||||
prn = bgp_node_get(bgp->rib[afi][safi], (struct prefix *) prd);
|
||||
if (prn->info)
|
||||
{
|
||||
table = (struct bgp_table *)(prn->info);
|
||||
|
||||
vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
|
||||
bgp,
|
||||
prd,
|
||||
table,
|
||||
p,
|
||||
new);
|
||||
}
|
||||
bgp_unlock_node(prn);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If maximum prefix count is configured and current prefix
|
||||
count exeed it. */
|
||||
if (bgp_maximum_prefix_overflow (peer, afi, safi, 0))
|
||||
@ -2653,7 +2849,7 @@ bgp_withdraw (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
|
||||
|
||||
/* Withdraw specified route from routing table. */
|
||||
if (ri && ! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
|
||||
bgp_rib_withdraw (rn, ri, peer, afi, safi);
|
||||
bgp_rib_withdraw (rn, ri, peer, afi, safi, prd);
|
||||
else if (bgp_debug_update(peer, p, NULL, 1))
|
||||
zlog_debug ("%s Can't find the route %s/%d", peer->host,
|
||||
inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
|
||||
@ -3047,6 +3243,10 @@ bgp_clear_route_all (struct peer *peer)
|
||||
for (afi = AFI_IP; afi < AFI_MAX; afi++)
|
||||
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
|
||||
bgp_clear_route (peer, afi, safi);
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
rfapiProcessPeerDown(peer);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@ -3117,7 +3317,13 @@ bgp_cleanup_table(struct bgp_table *table, safi_t safi)
|
||||
&& ri->type == ZEBRA_ROUTE_BGP
|
||||
&& (ri->sub_type == BGP_ROUTE_NORMAL ||
|
||||
ri->sub_type == BGP_ROUTE_AGGREGATE))
|
||||
bgp_zebra_withdraw (&rn->p, ri, safi);
|
||||
{
|
||||
#if ENABLE_BGP_VNC
|
||||
if (table->owner && table->owner->bgp)
|
||||
vnc_import_bgp_del_route(table->owner->bgp, &rn->p, ri);
|
||||
#endif
|
||||
bgp_zebra_withdraw (&rn->p, ri, safi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3417,6 +3623,9 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p,
|
||||
struct attr attr;
|
||||
struct attr *attr_new;
|
||||
int ret;
|
||||
#if ENABLE_BGP_VNC
|
||||
int vnc_implicit_withdraw = 0;
|
||||
#endif
|
||||
|
||||
assert (bgp_static);
|
||||
if (!bgp_static)
|
||||
@ -3489,9 +3698,34 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p,
|
||||
bgp_info_restore(rn, ri);
|
||||
else
|
||||
bgp_aggregate_decrement (bgp, p, ri, afi, safi);
|
||||
#if ENABLE_BGP_VNC
|
||||
if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST))
|
||||
{
|
||||
if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED))
|
||||
{
|
||||
/*
|
||||
* Implicit withdraw case.
|
||||
* We have to do this before ri is changed
|
||||
*/
|
||||
++vnc_implicit_withdraw;
|
||||
vnc_import_bgp_del_route(bgp, p, ri);
|
||||
vnc_import_bgp_exterior_del_route(bgp, p, ri);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
bgp_attr_unintern (&ri->attr);
|
||||
ri->attr = attr_new;
|
||||
ri->uptime = bgp_clock ();
|
||||
#if ENABLE_BGP_VNC
|
||||
if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST))
|
||||
{
|
||||
if (vnc_implicit_withdraw)
|
||||
{
|
||||
vnc_import_bgp_add_route(bgp, p, ri);
|
||||
vnc_import_bgp_exterior_add_route(bgp, p, ri);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Nexthop reachability check. */
|
||||
if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
|
||||
@ -3637,6 +3871,18 @@ bgp_static_withdraw_safi (struct bgp *bgp, struct prefix *p, afi_t afi,
|
||||
/* Withdraw static BGP route from routing table. */
|
||||
if (ri)
|
||||
{
|
||||
#if ENABLE_BGP_VNC
|
||||
rfapiProcessWithdraw(
|
||||
ri->peer,
|
||||
NULL,
|
||||
p,
|
||||
prd,
|
||||
ri->attr,
|
||||
afi,
|
||||
safi,
|
||||
ri->type,
|
||||
1); /* Kill, since it is an administrative change */
|
||||
#endif
|
||||
bgp_aggregate_decrement (bgp, p, ri, afi, safi);
|
||||
bgp_info_delete (rn, ri);
|
||||
bgp_process (bgp, rn, afi, safi);
|
||||
@ -3655,6 +3901,9 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix *p,
|
||||
struct attr *attr_new;
|
||||
struct attr attr = { 0 };
|
||||
struct bgp_info *ri;
|
||||
#if ENABLE_BGP_VNC
|
||||
u_int32_t label = 0;
|
||||
#endif
|
||||
|
||||
assert (bgp_static);
|
||||
|
||||
@ -3731,10 +3980,19 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix *p,
|
||||
bgp_attr_unintern (&ri->attr);
|
||||
ri->attr = attr_new;
|
||||
ri->uptime = bgp_clock ();
|
||||
#if ENABLE_BGP_VNC
|
||||
if (ri->extra)
|
||||
label = decode_label (ri->extra->tag);
|
||||
#endif
|
||||
|
||||
/* Process change. */
|
||||
bgp_aggregate_increment (bgp, p, ri, afi, safi);
|
||||
bgp_process (bgp, rn, afi, safi);
|
||||
#if ENABLE_BGP_VNC
|
||||
rfapiProcessUpdate(ri->peer, NULL, p, &bgp_static->prd,
|
||||
ri->attr, afi, safi,
|
||||
ri->type, ri->sub_type, &label);
|
||||
#endif
|
||||
bgp_unlock_node (rn);
|
||||
aspath_unintern (&attr.aspath);
|
||||
bgp_attr_extra_free (&attr);
|
||||
@ -3749,6 +4007,9 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix *p,
|
||||
SET_FLAG (new->flags, BGP_INFO_VALID);
|
||||
new->extra = bgp_info_extra_new();
|
||||
memcpy (new->extra->tag, bgp_static->tag, 3);
|
||||
#if ENABLE_BGP_VNC
|
||||
label = decode_label (bgp_static->tag);
|
||||
#endif
|
||||
|
||||
/* Aggregate address increment. */
|
||||
bgp_aggregate_increment (bgp, p, new, afi, safi);
|
||||
@ -3762,6 +4023,12 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix *p,
|
||||
/* Process change. */
|
||||
bgp_process (bgp, rn, afi, safi);
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd,
|
||||
new->attr, afi, safi,
|
||||
new->type, new->sub_type, &label);
|
||||
#endif
|
||||
|
||||
/* Unintern original. */
|
||||
aspath_unintern (&attr.aspath);
|
||||
bgp_attr_extra_free (&attr);
|
||||
@ -6107,7 +6374,14 @@ route_vty_out (struct vty *vty, struct prefix *p,
|
||||
json_object_array_add(json_paths, json_path);
|
||||
}
|
||||
else
|
||||
vty_out (vty, "%s", VTY_NEWLINE);
|
||||
{
|
||||
vty_out (vty, "%s", VTY_NEWLINE);
|
||||
#if ENABLE_BGP_VNC
|
||||
/* prints an additional line, indented, with VNC info, if present */
|
||||
if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP) || (safi == SAFI_UNICAST))
|
||||
rfapi_vty_out_vncinfo(vty, p, binfo, safi);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* called from terminal list command */
|
||||
|
@ -49,6 +49,30 @@ struct bgp_info_extra
|
||||
|
||||
/* MPLS label. */
|
||||
u_char tag[3];
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
union {
|
||||
|
||||
struct {
|
||||
void *rfapi_handle; /* export: NVE advertising this route */
|
||||
struct list *local_nexthops; /* optional, for static routes */
|
||||
} export;
|
||||
|
||||
struct {
|
||||
void *timer;
|
||||
void *hme; /* encap monitor, if this is a VPN route */
|
||||
struct prefix_rd rd; /* import: route's route-distinguisher */
|
||||
u_char un_family; /* family of cached un address, 0 if unset */
|
||||
union {
|
||||
struct in_addr addr4;
|
||||
struct in6_addr addr6;
|
||||
} un; /* cached un address */
|
||||
time_t create_time;
|
||||
struct prefix aux_prefix; /* AFI_ETHER: the IP addr, if family set */
|
||||
} import;
|
||||
|
||||
} vnc;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct bgp_info
|
||||
@ -111,6 +135,9 @@ struct bgp_info
|
||||
#define BGP_ROUTE_STATIC 1
|
||||
#define BGP_ROUTE_AGGREGATE 2
|
||||
#define BGP_ROUTE_REDISTRIBUTE 3
|
||||
#ifdef ENABLE_BGP_VNC
|
||||
# define BGP_ROUTE_RFP 4
|
||||
#endif
|
||||
|
||||
u_short instance;
|
||||
|
||||
@ -309,4 +336,14 @@ extern int subgroup_announce_check(struct bgp_info *ri,
|
||||
extern void bgp_peer_clear_node_queue_drain_immediate (struct peer *peer);
|
||||
extern void bgp_process_queues_drain_immediate (void);
|
||||
|
||||
/* for encap/vpn */
|
||||
extern struct bgp_node *
|
||||
bgp_afi_node_get (struct bgp_table *, afi_t , safi_t , struct prefix *,
|
||||
struct prefix_rd *);
|
||||
extern struct bgp_info *bgp_info_new (void);
|
||||
extern void bgp_info_restore (struct bgp_node *, struct bgp_info *);
|
||||
|
||||
extern int bgp_info_cmp_compatible (struct bgp *, struct bgp_info *,
|
||||
struct bgp_info *, afi_t, safi_t );
|
||||
|
||||
#endif /* _QUAGGA_BGP_ROUTE_H */
|
||||
|
@ -58,6 +58,9 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "bgpd/bgp_vty.h"
|
||||
#include "bgpd/bgp_debug.h"
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
# include "bgp_rfapi_cfg.h"
|
||||
#endif
|
||||
|
||||
/* Memo of route-map commands.
|
||||
|
||||
@ -2924,6 +2927,10 @@ bgp_route_map_process_update_cb (char *rmap_name)
|
||||
for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
|
||||
bgp_route_map_process_update(bgp, rmap_name, 1);
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
zlog_debug("%s: calling vnc_routemap_update", __func__);
|
||||
vnc_routemap_update(bgp, __func__);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2960,6 +2967,10 @@ bgp_route_map_mark_update (const char *rmap_name)
|
||||
{
|
||||
for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
|
||||
bgp_route_map_process_update(bgp, rmap_name, 0);
|
||||
#if ENABLE_BGP_VNC
|
||||
zlog_debug("%s: calling vnc_routemap_update", __func__);
|
||||
vnc_routemap_update(bgp, __func__);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
41
bgpd/bgp_vnc_types.h
Normal file
41
bgpd/bgp_vnc_types.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2015-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_BGP_VNC_TYPES_H
|
||||
#define _QUAGGA_BGP_VNC_TYPES_H
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
typedef enum {
|
||||
BGP_VNC_SUBTLV_TYPE_LIFETIME=1,
|
||||
BGP_VNC_SUBTLV_TYPE_RFPOPTION=2, /* deprecated */
|
||||
} bgp_vnc_subtlv_types;
|
||||
|
||||
/*
|
||||
* VNC Attribute subtlvs
|
||||
*/
|
||||
struct bgp_vnc_subtlv_lifetime {
|
||||
uint32_t lifetime;
|
||||
};
|
||||
|
||||
struct bgp_vnc_subtlv_unaddr {
|
||||
struct prefix un_address; /* IPv4 or IPv6; pfx length ignored */
|
||||
};
|
||||
|
||||
#endif /* ENABLE_BGP_VNC */
|
||||
#endif /* _QUAGGA_BGP_VNC_TYPES_H */
|
@ -46,6 +46,10 @@ Boston, MA 02111-1307, USA. */
|
||||
#include "bgpd/bgp_nexthop.h"
|
||||
#include "bgpd/bgp_nht.h"
|
||||
#include "bgpd/bgp_bfd.h"
|
||||
#if ENABLE_BGP_VNC
|
||||
# include "rfapi_backend.h"
|
||||
# include "vnc_export_bgp.h"
|
||||
#endif
|
||||
|
||||
/* All information about zebra. */
|
||||
struct zclient *zclient = NULL;
|
||||
@ -1806,6 +1810,13 @@ bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type, u_short instance)
|
||||
if (vrf_bitmap_check (zclient->redist[afi][type], bgp->vrf_id))
|
||||
return CMD_WARNING;
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
if (bgp->vrf_id == VRF_DEFAULT &&
|
||||
type == ZEBRA_ROUTE_VNC_DIRECT) {
|
||||
vnc_export_bgp_enable(bgp, afi); /* only enables if mode bits cfg'd */
|
||||
}
|
||||
#endif
|
||||
|
||||
vrf_bitmap_set (zclient->redist[afi][type], bgp->vrf_id);
|
||||
}
|
||||
|
||||
@ -1933,6 +1944,13 @@ bgp_redistribute_unreg (struct bgp *bgp, afi_t afi, int type, u_short instance)
|
||||
vrf_bitmap_unset (zclient->redist[afi][type], bgp->vrf_id);
|
||||
}
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
if (bgp->vrf_id == VRF_DEFAULT &&
|
||||
type == ZEBRA_ROUTE_VNC_DIRECT) {
|
||||
vnc_export_bgp_disable(bgp, afi);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (bgp_install_info_to_zebra (bgp))
|
||||
{
|
||||
/* Send distribute delete message to zebra. */
|
||||
|
33
bgpd/bgpd.c
33
bgpd/bgpd.c
@ -63,6 +63,10 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "bgpd/bgp_damp.h"
|
||||
#include "bgpd/bgp_mplsvpn.h"
|
||||
#include "bgpd/bgp_encap.h"
|
||||
#if ENABLE_BGP_VNC
|
||||
#include "bgp_rfapi_cfg.h"
|
||||
#include "rfapi_backend.h"
|
||||
#endif
|
||||
#include "bgpd/bgp_advertise.h"
|
||||
#include "bgpd/bgp_network.h"
|
||||
#include "bgpd/bgp_vty.h"
|
||||
@ -1127,7 +1131,7 @@ peer_unlock_with_caller (const char *name, struct peer *peer)
|
||||
}
|
||||
|
||||
/* Allocate new peer object, implicitely locked. */
|
||||
static struct peer *
|
||||
struct peer *
|
||||
peer_new (struct bgp *bgp)
|
||||
{
|
||||
afi_t afi;
|
||||
@ -2885,6 +2889,12 @@ bgp_create (as_t *as, const char *name, enum bgp_instance_type inst_type)
|
||||
|
||||
bgp->as = *as;
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
bgp->rfapi = bgp_rfapi_new(bgp);
|
||||
assert(bgp->rfapi);
|
||||
assert(bgp->rfapi_cfg);
|
||||
#endif /* ENABLE_BGP_VNC */
|
||||
|
||||
if (name)
|
||||
{
|
||||
bgp->name = XSTRDUP(MTYPE_BGP, name);
|
||||
@ -3165,6 +3175,11 @@ bgp_delete (struct bgp *bgp)
|
||||
|
||||
/* TODO - Other memory may need to be freed - e.g., NHT */
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
rfapi_delete(bgp);
|
||||
bgp_cleanup_routes(); /* rfapi cleanup can create route entries! */
|
||||
#endif
|
||||
|
||||
/* Remove visibility via the master list - there may however still be
|
||||
* routes to be processed still referencing the struct bgp.
|
||||
*/
|
||||
@ -5233,6 +5248,9 @@ peer_distribute_update (struct access_list *access)
|
||||
}
|
||||
}
|
||||
}
|
||||
#if ENABLE_BGP_VNC
|
||||
vnc_prefix_list_update(bgp);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -7337,6 +7355,12 @@ bgp_config_write (struct vty *vty)
|
||||
/* ENCAPv6 configuration. */
|
||||
write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_ENCAP);
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
write += bgp_rfapi_cfg_write(vty, bgp);
|
||||
#endif
|
||||
|
||||
vty_out (vty, " exit%s", VTY_NEWLINE);
|
||||
|
||||
write++;
|
||||
}
|
||||
return write;
|
||||
@ -7407,6 +7431,10 @@ bgp_init (void)
|
||||
/* Init zebra. */
|
||||
bgp_zebra_init(bm->master);
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
vnc_zebra_init (bm->master);
|
||||
#endif
|
||||
|
||||
/* BGP VTY commands installation. */
|
||||
bgp_vty_init ();
|
||||
|
||||
@ -7419,6 +7447,9 @@ bgp_init (void)
|
||||
bgp_scan_vty_init();
|
||||
bgp_mplsvpn_init ();
|
||||
bgp_encap_init ();
|
||||
#if ENABLE_BGP_VNC
|
||||
rfapi_init ();
|
||||
#endif
|
||||
|
||||
/* Access list initialize. */
|
||||
access_list_init ();
|
||||
|
89
bgpd/bgpd.conf.vnc.sample
Normal file
89
bgpd/bgpd.conf.vnc.sample
Normal file
@ -0,0 +1,89 @@
|
||||
hostname H192.1.1.1
|
||||
password zebra
|
||||
#enable password zebra
|
||||
log stdout notifications
|
||||
log monitor notifications
|
||||
#debug bgp
|
||||
|
||||
line vty
|
||||
exec-timeout 1000
|
||||
exit
|
||||
|
||||
|
||||
router bgp 64512
|
||||
|
||||
# Must set a router-id if no zebra (default 0.0.0.0)
|
||||
bgp router-id 192.1.1.1
|
||||
|
||||
neighbor 192.1.1.2 remote-as 64512
|
||||
neighbor 192.1.1.2 description H192.1.1.2
|
||||
neighbor 192.1.1.2 update-source 192.1.1.1
|
||||
neighbor 192.1.1.2 advertisement-interval 1
|
||||
no neighbor 192.1.1.2 activate
|
||||
|
||||
neighbor 192.1.1.3 remote-as 64512
|
||||
neighbor 192.1.1.3 description H192.1.1.3
|
||||
neighbor 192.1.1.3 update-source 192.1.1.1
|
||||
neighbor 192.1.1.3 advertisement-interval 1
|
||||
no neighbor 192.1.1.3 activate
|
||||
|
||||
address-family vpnv4
|
||||
neighbor 192.1.1.2 activate
|
||||
neighbor 192.1.1.3 activate
|
||||
exit-address-family
|
||||
|
||||
address-family vpnv6
|
||||
neighbor 192.1.1.2 activate
|
||||
neighbor 192.1.1.3 activate
|
||||
exit-address-family
|
||||
|
||||
vnc defaults
|
||||
rd auto:vn:5226
|
||||
response-lifetime 45
|
||||
rt both 1000:1 1000:2
|
||||
exit-vnc
|
||||
|
||||
vnc nve-group group1
|
||||
prefix vn 172.16.0.0/16
|
||||
exit-vnc
|
||||
|
||||
vnc nve-group red
|
||||
prefix vn 10.0.0.0/8
|
||||
rd auto:vn:10
|
||||
rt both 1000:10
|
||||
exit-vnc
|
||||
|
||||
vnc nve-group blue
|
||||
prefix vn 20.0.0.0/8
|
||||
rd auto:vn:20
|
||||
rt both 1000:20
|
||||
exit-vnc
|
||||
|
||||
vnc nve-group green
|
||||
prefix vn 30.0.0.0/8
|
||||
rd auto:vn:20
|
||||
rt both 1000:30
|
||||
exit-vnc
|
||||
|
||||
vnc nve-group rfc4291v6c
|
||||
prefix vn ::ac10:0/112
|
||||
rd auto:vn:5227
|
||||
rt both 2000:1
|
||||
exit-vnc
|
||||
|
||||
vnc nve-group rfc4291v6m
|
||||
prefix vn ::ffff:ac10:0/112
|
||||
rd auto:vn:5528
|
||||
rt both 3000:1
|
||||
exit-vnc
|
||||
|
||||
vnc nve-group rfc6052v6
|
||||
prefix vn 64:ff9b::ac10:0/112
|
||||
rd auto:vn:5529
|
||||
rt both 4000:1
|
||||
exit-vnc
|
||||
|
||||
exit
|
||||
|
||||
|
||||
|
18
bgpd/bgpd.h
18
bgpd/bgpd.h
@ -351,6 +351,11 @@ struct bgp
|
||||
|
||||
u_int32_t addpath_tx_id;
|
||||
int addpath_tx_used[AFI_MAX][SAFI_MAX];
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
struct rfapi_cfg *rfapi_cfg;
|
||||
struct rfapi *rfapi;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define BGP_ROUTE_ADV_HOLD(bgp) (bgp->main_peers_update_hold)
|
||||
@ -417,6 +422,8 @@ struct bgp_rd
|
||||
#define RMAP_OUT 1
|
||||
#define RMAP_MAX 2
|
||||
|
||||
#include "filter.h"
|
||||
|
||||
/* BGP filter structure. */
|
||||
struct bgp_filter
|
||||
{
|
||||
@ -657,6 +664,9 @@ struct peer
|
||||
#define PEER_FLAG_DYNAMIC_NEIGHBOR (1 << 12) /* dynamic neighbor */
|
||||
#define PEER_FLAG_CAPABILITY_ENHE (1 << 13) /* Extended next-hop (rfc 5549)*/
|
||||
#define PEER_FLAG_IFPEER_V6ONLY (1 << 14) /* if-based peer is v6 only */
|
||||
#if ENABLE_BGP_VNC
|
||||
#define PEER_FLAG_IS_RFAPI_HD (1 << 15) /* attached to rfapi HD */
|
||||
#endif
|
||||
|
||||
/* NSF mode (graceful restart) */
|
||||
u_char nsf[AFI_MAX][SAFI_MAX];
|
||||
@ -940,6 +950,9 @@ struct bgp_nlri
|
||||
#define BGP_ATTR_AS4_AGGREGATOR 18
|
||||
#define BGP_ATTR_AS_PATHLIMIT 21
|
||||
#define BGP_ATTR_ENCAP 23
|
||||
#if ENABLE_BGP_VNC
|
||||
#define BGP_ATTR_VNC 255
|
||||
#endif
|
||||
|
||||
/* BGP update origin. */
|
||||
#define BGP_ORIGIN_IGP 0
|
||||
@ -1054,6 +1067,7 @@ struct bgp_nlri
|
||||
|
||||
/* RFC4364 */
|
||||
#define SAFI_MPLS_LABELED_VPN 128
|
||||
#define BGP_SAFI_VPN 128
|
||||
|
||||
/* BGP uptime string length. */
|
||||
#define BGP_UPTIME_LEN 25
|
||||
@ -1506,4 +1520,8 @@ bgp_vrf_unlink (struct bgp *bgp, struct vrf *vrf)
|
||||
}
|
||||
|
||||
extern void bgp_update_redist_vrf_bitmaps (struct bgp*, vrf_id_t);
|
||||
|
||||
/* For benefit of rfapi */
|
||||
extern struct peer * peer_new (struct bgp *bgp);
|
||||
|
||||
#endif /* _QUAGGA_BGPD_H */
|
||||
|
4706
bgpd/rfapi/bgp_rfapi_cfg.c
Normal file
4706
bgpd/rfapi/bgp_rfapi_cfg.c
Normal file
File diff suppressed because it is too large
Load Diff
312
bgpd/rfapi/bgp_rfapi_cfg.h
Normal file
312
bgpd/rfapi/bgp_rfapi_cfg.h
Normal file
@ -0,0 +1,312 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_BGP_RFAPI_CFG_H
|
||||
#define _QUAGGA_BGP_RFAPI_CFG_H
|
||||
|
||||
#include "table.h"
|
||||
#include "routemap.h"
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
#include "rfapi.h"
|
||||
|
||||
struct rfapi_l2_group_cfg
|
||||
{
|
||||
char *name;
|
||||
uint32_t logical_net_id;
|
||||
struct list *labels; /* list of uint32_t */
|
||||
struct ecommunity *rt_import_list;
|
||||
struct ecommunity *rt_export_list;
|
||||
void *rfp_cfg; /* rfp owned group config */
|
||||
};
|
||||
|
||||
struct rfapi_nve_group_cfg
|
||||
{
|
||||
struct route_node *vn_node; /* backref */
|
||||
struct route_node *un_node; /* backref */
|
||||
|
||||
char *name;
|
||||
struct prefix vn_prefix;
|
||||
struct prefix un_prefix;
|
||||
|
||||
struct prefix_rd rd;
|
||||
uint8_t l2rd; /* 0 = VN addr LSB */
|
||||
uint32_t response_lifetime;
|
||||
uint32_t flags;
|
||||
#define RFAPI_RFG_RESPONSE_LIFETIME 0x1
|
||||
#define RFAPI_RFG_L2RD 0x02
|
||||
struct ecommunity *rt_import_list;
|
||||
struct ecommunity *rt_export_list;
|
||||
struct rfapi_import_table *rfapi_import_table;
|
||||
|
||||
void *rfp_cfg; /* rfp owned group config */
|
||||
/*
|
||||
* List of NVE descriptors that are assigned to this NVE group
|
||||
*
|
||||
* Currently (Mar 2010) this list is used only by the route
|
||||
* export code to generate per-NVE nexthops for each route.
|
||||
*
|
||||
* The nve descriptors listed here have pointers back to
|
||||
* this nve group config structure to enable them to delete
|
||||
* their own list entries when they are closed. Consequently,
|
||||
* if an instance of this nve group config structure is deleted,
|
||||
* we must first set the nve descriptor references to it to NULL.
|
||||
*/
|
||||
struct list *nves;
|
||||
|
||||
/*
|
||||
* Route filtering
|
||||
*
|
||||
* Prefix lists are segregated by afi (part of the base plist code)
|
||||
* Route-maps are not segregated
|
||||
*/
|
||||
char *plist_export_bgp_name[AFI_MAX];
|
||||
struct prefix_list *plist_export_bgp[AFI_MAX];
|
||||
|
||||
char *plist_export_zebra_name[AFI_MAX];
|
||||
struct prefix_list *plist_export_zebra[AFI_MAX];
|
||||
|
||||
char *plist_redist_name[ZEBRA_ROUTE_MAX][AFI_MAX];
|
||||
struct prefix_list *plist_redist[ZEBRA_ROUTE_MAX][AFI_MAX];
|
||||
|
||||
char *routemap_export_bgp_name;
|
||||
struct route_map *routemap_export_bgp;
|
||||
|
||||
char *routemap_export_zebra_name;
|
||||
struct route_map *routemap_export_zebra;
|
||||
|
||||
char *routemap_redist_name[ZEBRA_ROUTE_MAX];
|
||||
struct route_map *routemap_redist[ZEBRA_ROUTE_MAX];
|
||||
};
|
||||
|
||||
struct rfapi_rfg_name
|
||||
{
|
||||
struct rfapi_nve_group_cfg *rfg;
|
||||
char *name;
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
VNC_REDIST_MODE_PLAIN = 0, /* 0 = default */
|
||||
VNC_REDIST_MODE_RFG,
|
||||
VNC_REDIST_MODE_RESOLVE_NVE
|
||||
} vnc_redist_mode_t;
|
||||
|
||||
struct rfapi_cfg
|
||||
{
|
||||
struct prefix_rd default_rd;
|
||||
uint8_t default_l2rd;
|
||||
struct ecommunity *default_rt_import_list;
|
||||
struct ecommunity *default_rt_export_list;
|
||||
uint32_t default_response_lifetime;
|
||||
#define BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT 3600
|
||||
void *default_rfp_cfg; /* rfp owned group config */
|
||||
|
||||
struct list *l2_groups; /* rfapi_l2_group_cfg list */
|
||||
/* three views into the same collection of rfapi_nve_group_cfg */
|
||||
struct list *nve_groups_sequential;
|
||||
struct route_table nve_groups_vn[AFI_MAX];
|
||||
struct route_table nve_groups_un[AFI_MAX];
|
||||
|
||||
/*
|
||||
* For Single VRF export to ordinary routing protocols. This is
|
||||
* the nve-group that the ordinary protocols belong to. We use it
|
||||
* to set the RD when sending unicast Zebra routes to VNC
|
||||
*/
|
||||
uint8_t redist[AFI_MAX][ZEBRA_ROUTE_MAX];
|
||||
uint32_t redist_lifetime;
|
||||
vnc_redist_mode_t redist_mode;
|
||||
|
||||
/*
|
||||
* view name of BGP unicast instance that holds
|
||||
* exterior routes
|
||||
*/
|
||||
char *redist_bgp_exterior_view_name;
|
||||
struct bgp *redist_bgp_exterior_view;
|
||||
|
||||
/*
|
||||
* nve group for redistribution of routes from zebra to VNC
|
||||
* (which is probably not useful for production networks)
|
||||
*/
|
||||
char *rfg_redist_name;
|
||||
struct rfapi_nve_group_cfg *rfg_redist;
|
||||
|
||||
/*
|
||||
* List of NVE groups on whose behalf we will export VNC
|
||||
* routes to zebra. ((NB: it's actually a list of <struct rfapi_rfg_name>)
|
||||
* This list is used when BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS is
|
||||
* BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP
|
||||
*/
|
||||
struct list *rfg_export_zebra_l;
|
||||
|
||||
/*
|
||||
* List of NVE groups on whose behalf we will export VNC
|
||||
* routes directly to the bgp unicast RIB. (NB: it's actually
|
||||
* a list of <struct rfapi_rfg_name>)
|
||||
* This list is used when BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS is
|
||||
* BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP
|
||||
*/
|
||||
struct list *rfg_export_direct_bgp_l;
|
||||
|
||||
/*
|
||||
* Exported Route filtering
|
||||
*
|
||||
* Prefix lists are segregated by afi (part of the base plist code)
|
||||
* Route-maps are not segregated
|
||||
*/
|
||||
char *plist_export_bgp_name[AFI_MAX];
|
||||
struct prefix_list *plist_export_bgp[AFI_MAX];
|
||||
|
||||
char *plist_export_zebra_name[AFI_MAX];
|
||||
struct prefix_list *plist_export_zebra[AFI_MAX];
|
||||
|
||||
char *routemap_export_bgp_name;
|
||||
struct route_map *routemap_export_bgp;
|
||||
|
||||
char *routemap_export_zebra_name;
|
||||
struct route_map *routemap_export_zebra;
|
||||
|
||||
/*
|
||||
* Redistributed route filtering (routes from other
|
||||
* protocols into VNC)
|
||||
*/
|
||||
char *plist_redist_name[ZEBRA_ROUTE_MAX][AFI_MAX];
|
||||
struct prefix_list *plist_redist[ZEBRA_ROUTE_MAX][AFI_MAX];
|
||||
|
||||
char *routemap_redist_name[ZEBRA_ROUTE_MAX];
|
||||
struct route_map *routemap_redist[ZEBRA_ROUTE_MAX];
|
||||
|
||||
/*
|
||||
* For importing bgp unicast routes to VNC, we encode the CE
|
||||
* (route nexthop) in a Route Origin extended community. The
|
||||
* local part (16-bit) is user-configurable.
|
||||
*/
|
||||
uint16_t resolve_nve_roo_local_admin;
|
||||
#define BGP_VNC_CONFIG_RESOLVE_NVE_ROO_LOCAL_ADMIN_DEFAULT 5226
|
||||
|
||||
uint32_t flags;
|
||||
#define BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP 0x00000001
|
||||
#define BGP_VNC_CONFIG_CALLBACK_DISABLE 0x00000002
|
||||
#define BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE 0x00000004
|
||||
|
||||
#define BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS 0x000000f0
|
||||
#define BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS 0x00000f00
|
||||
|
||||
#define BGP_VNC_CONFIG_EXPORT_BGP_MODE_NONE 0x00000000
|
||||
#define BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP 0x00000010
|
||||
#define BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH 0x00000020 /* registerd nve */
|
||||
#define BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE 0x00000040
|
||||
|
||||
#define BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_NONE 0x00000000
|
||||
#define BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP 0x00000100
|
||||
#define BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH 0x00000200
|
||||
|
||||
#define BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP 0x00001000
|
||||
#define BGP_VNC_CONFIG_L2RD 0x00002000
|
||||
|
||||
/* Use new NVE RIB to filter callback routes */
|
||||
/* Filter querying NVE's registrations from responses */
|
||||
/* Default to updated-responses off */
|
||||
/* Default to removal-responses off */
|
||||
#define BGP_VNC_CONFIG_FLAGS_DEFAULT \
|
||||
(BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP |\
|
||||
BGP_VNC_CONFIG_CALLBACK_DISABLE |\
|
||||
BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE)
|
||||
|
||||
struct rfapi_rfp_cfg rfp_cfg; /* rfp related configuration */
|
||||
};
|
||||
|
||||
#define VNC_EXPORT_ZEBRA_GRP_ENABLED(hc) \
|
||||
(((hc)->flags & BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS) == \
|
||||
BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP)
|
||||
|
||||
#define VNC_EXPORT_ZEBRA_RH_ENABLED(hc) \
|
||||
(((hc)->flags & BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS) == \
|
||||
BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH)
|
||||
|
||||
#define VNC_EXPORT_BGP_GRP_ENABLED(hc) \
|
||||
(((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) == \
|
||||
BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP)
|
||||
|
||||
#define VNC_EXPORT_BGP_RH_ENABLED(hc) \
|
||||
(((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) == \
|
||||
BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH)
|
||||
|
||||
#define VNC_EXPORT_BGP_CE_ENABLED(hc) \
|
||||
(((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) == \
|
||||
BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE)
|
||||
|
||||
|
||||
void
|
||||
bgp_rfapi_cfg_init (void);
|
||||
|
||||
struct rfapi_cfg *
|
||||
bgp_rfapi_cfg_new (struct rfapi_rfp_cfg *cfg);
|
||||
|
||||
void
|
||||
bgp_rfapi_cfg_destroy (struct bgp *bgp, struct rfapi_cfg *h);
|
||||
|
||||
int
|
||||
bgp_rfapi_cfg_write (struct vty *vty, struct bgp *bgp);
|
||||
|
||||
extern int
|
||||
bgp_rfapi_is_vnc_configured (struct bgp *bgp);
|
||||
|
||||
extern void
|
||||
nve_group_to_nve_list (
|
||||
struct rfapi_nve_group_cfg *rfg,
|
||||
struct list **nves,
|
||||
uint8_t family); /* AF_INET, AF_INET6 */
|
||||
|
||||
struct rfapi_nve_group_cfg *
|
||||
bgp_rfapi_cfg_match_group (
|
||||
struct rfapi_cfg *hc,
|
||||
struct prefix *vn,
|
||||
struct prefix *un);
|
||||
|
||||
extern void
|
||||
vnc_prefix_list_update (struct bgp *bgp);
|
||||
|
||||
extern void
|
||||
vnc_routemap_update (struct bgp *bgp, const char *unused);
|
||||
|
||||
extern void
|
||||
bgp_rfapi_show_summary (struct bgp *bgp, struct vty *vty);
|
||||
|
||||
extern struct rfapi_cfg *
|
||||
bgp_rfapi_get_config (struct bgp *bgp);
|
||||
|
||||
extern struct ecommunity *
|
||||
bgp_rfapi_get_ecommunity_by_lni_label (
|
||||
struct bgp *bgp,
|
||||
uint32_t is_import,
|
||||
uint32_t logical_net_id,
|
||||
uint32_t label); /* note, 20bit label! */
|
||||
|
||||
extern struct list *
|
||||
bgp_rfapi_get_labellist_by_lni_label (
|
||||
struct bgp *bgp,
|
||||
uint32_t logical_net_id,
|
||||
uint32_t label); /* note, 20bit label! */
|
||||
|
||||
#endif /* ENABLE_BGP_VNC */
|
||||
|
||||
#endif /* _QUAGGA_BGP_RFAPI_CFG_H */
|
4412
bgpd/rfapi/rfapi.c
Normal file
4412
bgpd/rfapi/rfapi.c
Normal file
File diff suppressed because it is too large
Load Diff
980
bgpd/rfapi/rfapi.h
Normal file
980
bgpd/rfapi/rfapi.h
Normal file
@ -0,0 +1,980 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_BGP_RFAPI_H
|
||||
#define _QUAGGA_BGP_RFAPI_H
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
|
||||
#include <stdint.h>
|
||||
#include <netinet/in.h>
|
||||
#include <zebra.h>
|
||||
#include "vty.h"
|
||||
#include "prefix.h"
|
||||
#include "../bgpd.h"
|
||||
#include "../bgp_encap_types.h"
|
||||
|
||||
/* probably ought to have a field-specific define in config.h */
|
||||
# ifndef s6_addr32 /* for solaris/bsd */
|
||||
# ifdef SOLARIS_IPV6
|
||||
# define s6_addr32 _S6_un._S6_u32
|
||||
# else
|
||||
# define s6_addr32 __u6_addr.__u6_addr32
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#define RFAPI_V4_ADDR 0x04
|
||||
#define RFAPI_V6_ADDR 0x06
|
||||
#define RFAPI_SHOW_STR "VNC information\n"
|
||||
|
||||
struct rfapi_ip_addr
|
||||
{
|
||||
uint8_t addr_family; /* AF_INET | AF_INET6 */
|
||||
union
|
||||
{
|
||||
struct in_addr v4; /* in network order */
|
||||
struct in6_addr v6; /* in network order */
|
||||
} addr;
|
||||
};
|
||||
|
||||
struct rfapi_ip_prefix
|
||||
{
|
||||
uint8_t length;
|
||||
uint8_t cost; /* bgp local pref = 255 - cost */
|
||||
struct rfapi_ip_addr prefix;
|
||||
};
|
||||
|
||||
struct rfapi_nexthop
|
||||
{
|
||||
struct prefix addr;
|
||||
uint8_t cost;
|
||||
};
|
||||
|
||||
struct rfapi_next_hop_entry
|
||||
{
|
||||
struct rfapi_next_hop_entry *next;
|
||||
struct rfapi_ip_prefix prefix;
|
||||
uint32_t lifetime;
|
||||
struct rfapi_ip_addr un_address;
|
||||
struct rfapi_ip_addr vn_address;
|
||||
struct rfapi_vn_option *vn_options;
|
||||
struct rfapi_un_option *un_options;
|
||||
};
|
||||
|
||||
#define RFAPI_REMOVE_RESPONSE_LIFETIME 0
|
||||
#define RFAPI_INFINITE_LIFETIME 0xFFFFFFFF
|
||||
|
||||
struct rfapi_l2address_option
|
||||
{
|
||||
struct ethaddr macaddr; /* use 0 to assign label to IP prefix */
|
||||
uint32_t label; /* 20bit label in low bits, no TC, S, or TTL */
|
||||
uint32_t logical_net_id; /* ~= EVPN Ethernet Segment Id,
|
||||
must not be zero for mac regis. */
|
||||
uint8_t local_nve_id;
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RFAPI_UN_OPTION_TYPE_PROVISIONAL, /* internal use only */
|
||||
RFAPI_UN_OPTION_TYPE_TUNNELTYPE,
|
||||
} rfapi_un_option_type;
|
||||
|
||||
struct rfapi_tunneltype_option
|
||||
{
|
||||
bgp_encap_types type;
|
||||
union
|
||||
{
|
||||
struct bgp_encap_type_reserved reserved;
|
||||
struct bgp_encap_type_l2tpv3_over_ip l2tpv3_ip;
|
||||
struct bgp_encap_type_gre gre;
|
||||
struct bgp_encap_type_transmit_tunnel_endpoint transmit_tunnel_endpoint;
|
||||
struct bgp_encap_type_ipsec_in_tunnel_mode ipsec_tunnel;
|
||||
struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode ip_ipsec;
|
||||
struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode mpls_ipsec;
|
||||
struct bgp_encap_type_ip_in_ip ip_ip;
|
||||
struct bgp_encap_type_vxlan vxlan;
|
||||
struct bgp_encap_type_nvgre nvgre;
|
||||
struct bgp_encap_type_mpls mpls;
|
||||
struct bgp_encap_type_mpls_in_gre mpls_gre;
|
||||
struct bgp_encap_type_vxlan_gpe vxlan_gpe;
|
||||
struct bgp_encap_type_mpls_in_udp mpls_udp;
|
||||
struct bgp_encap_type_pbb pbb;
|
||||
} bgpinfo;
|
||||
};
|
||||
|
||||
struct rfapi_un_option
|
||||
{
|
||||
struct rfapi_un_option *next;
|
||||
rfapi_un_option_type type;
|
||||
union
|
||||
{
|
||||
struct rfapi_tunneltype_option tunnel;
|
||||
} v;
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RFAPI_VN_OPTION_TYPE_L2ADDR = 3, /* Layer 2 address, 3 for legacy compatibility */
|
||||
RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP, /* for static routes */
|
||||
RFAPI_VN_OPTION_TYPE_INTERNAL_RD, /* internal use only */
|
||||
} rfapi_vn_option_type;
|
||||
|
||||
struct rfapi_vn_option
|
||||
{
|
||||
struct rfapi_vn_option *next;
|
||||
|
||||
rfapi_vn_option_type type;
|
||||
|
||||
union
|
||||
{
|
||||
struct rfapi_l2address_option l2addr;
|
||||
|
||||
/*
|
||||
* If this option is present, the next hop is local to the
|
||||
* client NVE (i.e., not via a tunnel).
|
||||
*/
|
||||
struct rfapi_nexthop local_nexthop;
|
||||
|
||||
/*
|
||||
* For rfapi internal use only
|
||||
*/
|
||||
struct prefix_rd internal_rd;
|
||||
} v;
|
||||
};
|
||||
|
||||
struct rfapi_l2address_option_match
|
||||
{
|
||||
struct rfapi_l2address_option o;
|
||||
uint32_t flags;
|
||||
|
||||
#define RFAPI_L2O_MACADDR 0x00000001
|
||||
#define RFAPI_L2O_LABEL 0x00000002
|
||||
#define RFAPI_L2O_LNI 0x00000004
|
||||
#define RFAPI_L2O_LHI 0x00000008
|
||||
};
|
||||
|
||||
#define VNC_CONFIG_STR "VNC/RFP related configuration\n"
|
||||
|
||||
typedef void *rfapi_handle;
|
||||
|
||||
/***********************************************************************
|
||||
* RFP Callbacks
|
||||
***********************************************************************/
|
||||
/*------------------------------------------
|
||||
* rfapi_response_cb_t (callback typedef)
|
||||
*
|
||||
* Callbacks of this type are used to provide asynchronous
|
||||
* route updates from RFAPI to the RFP client.
|
||||
*
|
||||
* response_cb
|
||||
* called to notify the rfp client that a next hop list
|
||||
* that has previously been provided in response to an
|
||||
* rfapi_query call has been updated. Deleted routes are indicated
|
||||
* with lifetime==RFAPI_REMOVE_RESPONSE_LIFETIME.
|
||||
*
|
||||
* By default, the routes an NVE receives via this callback include
|
||||
* its own routes (that it has registered). However, these may be
|
||||
* filtered out if the global BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP
|
||||
* flag is set.
|
||||
*
|
||||
* local_cb
|
||||
* called to notify the rfp client that a local route
|
||||
* has been added or deleted. Deleted routes are indicated
|
||||
* with lifetime==RFAPI_REMOVE_RESPONSE_LIFETIME.
|
||||
*
|
||||
* input:
|
||||
* next_hops a list of possible next hops.
|
||||
* This is a linked list allocated within the
|
||||
* rfapi. The response_cb callback function is responsible
|
||||
* for freeing this memory via rfapi_free_next_hop_list()
|
||||
* in order to avoid memory leaks.
|
||||
*
|
||||
* userdata value (cookie) originally specified in call to
|
||||
* rfapi_open()
|
||||
*
|
||||
*------------------------------------------*/
|
||||
typedef void (rfapi_response_cb_t) (struct rfapi_next_hop_entry * next_hops,
|
||||
void *userdata);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_nve_close_cb_t (callback typedef)
|
||||
*
|
||||
* Callbacks of this type are used to provide asynchronous
|
||||
* notification that an rfapi_handle was invalidated
|
||||
*
|
||||
* input:
|
||||
* pHandle Firmerly valid rfapi_handle returned to
|
||||
* client via rfapi_open().
|
||||
*
|
||||
* reason EIDRM handle administratively closed (clear nve ...)
|
||||
* ESTALE handle invalidated by configuration change
|
||||
*
|
||||
*------------------------------------------*/
|
||||
typedef void (rfapi_nve_close_cb_t) (rfapi_handle pHandle, int reason);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfp_cfg_write_cb_t (callback typedef)
|
||||
*
|
||||
* This callback is used to generate output for any config parameters
|
||||
* that may supported by RFP via RFP defined vty commands at the bgp
|
||||
* level. See loglevel as an example.
|
||||
*
|
||||
* input:
|
||||
* vty -- quagga vty context
|
||||
* rfp_start_val -- value returned by rfp_start
|
||||
*
|
||||
* output:
|
||||
* to vty, rfp related configuration
|
||||
*
|
||||
* return value:
|
||||
* lines written
|
||||
--------------------------------------------*/
|
||||
typedef int (rfp_cfg_write_cb_t) (struct vty * vty, void *rfp_start_val);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfp_cfg_group_write_cb_t (callback typedef)
|
||||
*
|
||||
* This callback is used to generate output for any config parameters
|
||||
* that may supported by RFP via RFP defined vty commands at the
|
||||
* L2 or NVE level. See loglevel as an example.
|
||||
*
|
||||
* input:
|
||||
* vty quagga vty context
|
||||
* rfp_start_val value returned by rfp_start
|
||||
* type group type
|
||||
* name group name
|
||||
* rfp_cfg_group Pointer to configuration structure
|
||||
*
|
||||
* output:
|
||||
* to vty, rfp related configuration
|
||||
*
|
||||
* return value:
|
||||
* lines written
|
||||
--------------------------------------------*/
|
||||
typedef enum
|
||||
{
|
||||
RFAPI_RFP_CFG_GROUP_DEFAULT,
|
||||
RFAPI_RFP_CFG_GROUP_NVE,
|
||||
RFAPI_RFP_CFG_GROUP_L2
|
||||
} rfapi_rfp_cfg_group_type;
|
||||
|
||||
typedef int (rfp_cfg_group_write_cb_t) (struct vty * vty,
|
||||
void *rfp_start_val,
|
||||
rfapi_rfp_cfg_group_type type,
|
||||
const char *name,
|
||||
void *rfp_cfg_group);
|
||||
|
||||
/***********************************************************************
|
||||
* Configuration related defines and structures
|
||||
***********************************************************************/
|
||||
|
||||
struct rfapi_rfp_cb_methods
|
||||
{
|
||||
rfp_cfg_write_cb_t *cfg_cb; /* show top level config */
|
||||
rfp_cfg_group_write_cb_t *cfg_group_cb; /* show group level config */
|
||||
rfapi_response_cb_t *response_cb; /* unsolicited responses */
|
||||
rfapi_response_cb_t *local_cb; /* local route add/delete */
|
||||
rfapi_nve_close_cb_t *close_cb; /* handle closed */
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* If a route with infinite lifetime is withdrawn, this is
|
||||
* how long (in seconds) to wait before expiring it (because
|
||||
* RFAPI_LIFETIME_MULTIPLIER_PCT * infinity is too long to wait)
|
||||
*/
|
||||
#define RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY (60*120)
|
||||
|
||||
/*
|
||||
* the factor that should be applied to a prefix's <lifetime> value
|
||||
* before using it to expire a withdrawn prefix, expressed as a percent.
|
||||
* Thus, a value of 100 means to use the exact value of <lifetime>,
|
||||
* a value of 200 means to use twice the value of <lifetime>, etc.
|
||||
*/
|
||||
#define RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR 150
|
||||
|
||||
/*
|
||||
* This is used by rfapi to determine if RFP is using/supports
|
||||
* a partial (i.e., cache) or full table download approach for
|
||||
* mapping information. When full table download approach is
|
||||
* used all information is passed to RFP after an initial
|
||||
* rfapi_query. When partial table download is used, only
|
||||
* information matching a query is passed.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
RFAPI_RFP_DOWNLOAD_PARTIAL = 0,
|
||||
RFAPI_RFP_DOWNLOAD_FULL
|
||||
} rfapi_rfp_download_type;
|
||||
|
||||
#define RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL 1
|
||||
|
||||
struct rfapi_rfp_cfg
|
||||
{
|
||||
/* partial or full table download */
|
||||
rfapi_rfp_download_type download_type; /* default=partial */
|
||||
/*
|
||||
* When full-table-download is enabled, this is the minimum
|
||||
* number of seconds between times a non-queried prefix will
|
||||
* be updated to a particular NVE.
|
||||
* default: RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL
|
||||
*/
|
||||
uint32_t ftd_advertisement_interval;
|
||||
/*
|
||||
* percentage of registration lifetime to continue to use information
|
||||
* post soft-state refresh timeout
|
||||
default: RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR
|
||||
*/
|
||||
uint32_t holddown_factor;
|
||||
/* Control generation of updated RFP responses */
|
||||
uint8_t use_updated_response; /* default=0/no */
|
||||
/* when use_updated_response, also generate remove responses */
|
||||
uint8_t use_removes; /* default=0/no */
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* Process related functions -- MUST be provided by the RFAPI user <<===
|
||||
***********************************************************************/
|
||||
|
||||
/*------------------------------------------
|
||||
* rfp_start
|
||||
*
|
||||
* This function will start the RFP code
|
||||
*
|
||||
* input:
|
||||
* master quagga thread_master to tie into bgpd threads
|
||||
*
|
||||
* output:
|
||||
* cfgp Pointer to rfapi_rfp_cfg (null = use defaults),
|
||||
* copied by caller, updated via rfp_set_configuration
|
||||
* cbmp Pointer to rfapi_rfp_cb_methods, may be null
|
||||
* copied by caller, updated via rfapi_rfp_set_cb_methods
|
||||
* return value:
|
||||
* rfp_start_val rfp returned value passed on rfp_stop and other rfapi calls
|
||||
--------------------------------------------*/
|
||||
extern void *
|
||||
rfp_start (
|
||||
struct thread_master *master,
|
||||
struct rfapi_rfp_cfg **cfgp,
|
||||
struct rfapi_rfp_cb_methods **cbmp);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfp_stop
|
||||
*
|
||||
* This function is called on shutdown to trigger RFP cleanup
|
||||
*
|
||||
* input:
|
||||
* rfp_start_val
|
||||
*
|
||||
* output:
|
||||
* none
|
||||
*
|
||||
* return value:
|
||||
--------------------------------------------*/
|
||||
extern void
|
||||
rfp_stop (void *rfp_start_val);
|
||||
|
||||
/***********************************************************************
|
||||
* RFP processing behavior configuration
|
||||
***********************************************************************/
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_rfp_set_configuration
|
||||
*
|
||||
* This is used to change rfapi's processing behavior based on
|
||||
* RFP requirements.
|
||||
*
|
||||
* input:
|
||||
* rfp_start_val value returned by rfp_start
|
||||
* rfapi_rfp_cfg Pointer to configuration structure
|
||||
*
|
||||
* output:
|
||||
* none
|
||||
*
|
||||
* return value:
|
||||
* 0 Success
|
||||
* ENXIO Unabled to locate configured BGP/VNC
|
||||
--------------------------------------------*/
|
||||
extern int
|
||||
rfapi_rfp_set_configuration (
|
||||
void *rfp_start_val,
|
||||
struct rfapi_rfp_cfg *rfp_cfg);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_rfp_set_cb_methods
|
||||
*
|
||||
* Change registered callback functions for asynchronous notifications
|
||||
* from RFAPI to the RFP client.
|
||||
*
|
||||
* input:
|
||||
* rfp_start_val value by rfp_start
|
||||
* methods Pointer to struct rfapi_rfp_cb_methods containing
|
||||
* pointers to callback methods as described above
|
||||
*
|
||||
* return value:
|
||||
* 0 Success
|
||||
* ENXIO BGP or VNC not configured
|
||||
*------------------------------------------*/
|
||||
extern int
|
||||
rfapi_rfp_set_cb_methods (
|
||||
void *rfp_start_val,
|
||||
struct rfapi_rfp_cb_methods *methods);
|
||||
|
||||
/***********************************************************************
|
||||
* RFP group specific configuration
|
||||
***********************************************************************/
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_rfp_init_group_config_ptr_vty
|
||||
*
|
||||
* This is used to init or return a previously init'ed group specific
|
||||
* configuration pointer. Group is identified by vty context.
|
||||
* NOTE: size is ignored when a previously init'ed value is returned.
|
||||
* RFAPI frees rfp_cfg_group when group is deleted during reconfig,
|
||||
* bgp restart or shutdown.
|
||||
*
|
||||
* input:
|
||||
* rfp_start_val value returned by rfp_start
|
||||
* type group type
|
||||
* vty quagga vty context
|
||||
* size number of bytes to allocation
|
||||
*
|
||||
* output:
|
||||
* none
|
||||
*
|
||||
* return value:
|
||||
* rfp_cfg_group NULL or Pointer to configuration structure
|
||||
--------------------------------------------*/
|
||||
extern void *
|
||||
rfapi_rfp_init_group_config_ptr_vty (
|
||||
void *rfp_start_val,
|
||||
rfapi_rfp_cfg_group_type type,
|
||||
struct vty *vty,
|
||||
uint32_t size);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_rfp_get_group_config_ptr_vty
|
||||
*
|
||||
* This is used to get group specific configuration pointer.
|
||||
* Group is identified by type and vty context.
|
||||
* RFAPI frees rfp_cfg_group when group is deleted during reconfig,
|
||||
* bgp restart or shutdown.
|
||||
*
|
||||
* input:
|
||||
* rfp_start_val value returned by rfp_start
|
||||
* type group type
|
||||
* vty quagga vty context
|
||||
*
|
||||
* output:
|
||||
* none
|
||||
*
|
||||
* return value:
|
||||
* rfp_cfg_group Pointer to configuration structure
|
||||
--------------------------------------------*/
|
||||
extern void *
|
||||
rfapi_rfp_get_group_config_ptr_vty (
|
||||
void *rfp_start_val,
|
||||
rfapi_rfp_cfg_group_type type,
|
||||
struct vty *vty);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfp_group_config_search_cb_t (callback typedef)
|
||||
*
|
||||
* This callback is used to called from within a
|
||||
* rfapi_rfp_get_group_config_ptr to check if the rfp_cfg_group
|
||||
* matches the search criteria
|
||||
*
|
||||
* input:
|
||||
* criteria RFAPI caller provided serach criteria
|
||||
* rfp_cfg_group Pointer to configuration structure | NULL
|
||||
*
|
||||
* output:
|
||||
*
|
||||
* return value:
|
||||
* 0 Match/Success
|
||||
* ENOENT No matching
|
||||
--------------------------------------------*/
|
||||
typedef int (rfp_group_config_search_cb_t) (void *criteria,
|
||||
void *rfp_cfg_group);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_rfp_get_group_config_ptr_name
|
||||
*
|
||||
* This is used to get group specific configuration pointer.
|
||||
* Group is identified by type and name context.
|
||||
* RFAPI frees rfp_cfg_group when group is deleted during reconfig,
|
||||
* bgp restart or shutdown.
|
||||
*
|
||||
* input:
|
||||
* rfp_start_val value returned by rfp_start
|
||||
* type group type
|
||||
* name group name
|
||||
* criteria RFAPI caller provided serach criteria
|
||||
* search_cb optional rfp_group_config_search_cb_t
|
||||
*
|
||||
* output:
|
||||
* none
|
||||
*
|
||||
* return value:
|
||||
* rfp_cfg_group Pointer to configuration structure
|
||||
--------------------------------------------*/
|
||||
extern void *
|
||||
rfapi_rfp_get_group_config_ptr_name (
|
||||
void *rfp_start_val,
|
||||
rfapi_rfp_cfg_group_type type,
|
||||
const char *name,
|
||||
void *criteria,
|
||||
rfp_group_config_search_cb_t *search_cb);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_rfp_get_l2_group_config_ptr_lni
|
||||
*
|
||||
* This is used to get group specific configuration pointer.
|
||||
* Group is identified by type and logical network identifier.
|
||||
* RFAPI frees rfp_cfg_group when group is deleted during reconfig,
|
||||
* bgp restart or shutdown.
|
||||
*
|
||||
* input:
|
||||
* rfp_start_val value returned by rfp_start
|
||||
* logical_net_id group logical network identifier
|
||||
* criteria RFAPI caller provided serach criteria
|
||||
* search_cb optional rfp_group_config_search_cb_t
|
||||
*
|
||||
* output:
|
||||
* none
|
||||
*
|
||||
* return value:
|
||||
* rfp_cfg_group Pointer to configuration structure
|
||||
--------------------------------------------*/
|
||||
extern void *
|
||||
rfapi_rfp_get_l2_group_config_ptr_lni (
|
||||
void *rfp_start_val,
|
||||
uint32_t logical_net_id,
|
||||
void *criteria,
|
||||
rfp_group_config_search_cb_t *search_cb);
|
||||
|
||||
/***********************************************************************
|
||||
* NVE Sessions
|
||||
***********************************************************************/
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_open
|
||||
*
|
||||
* This function initializes a NVE record and associates it with
|
||||
* the specified VN and underlay network addresses
|
||||
*
|
||||
* input:
|
||||
* rfp_start_val value returned by rfp_start
|
||||
* vn NVE virtual network address
|
||||
*
|
||||
* un NVE underlay network address
|
||||
*
|
||||
* default_options Default options to use on registrations.
|
||||
* For now only tunnel type is supported.
|
||||
* May be overridden per-prefix in rfapi_register().
|
||||
* Caller owns (rfapi_open() does not free)
|
||||
*
|
||||
* response_cb Pointer to next hop list update callback function or
|
||||
* NULL when no callbacks are desired.
|
||||
*
|
||||
* userdata Passed to subsequent response_cb invocations.
|
||||
*
|
||||
* output:
|
||||
* response_lifetime The length of time that responses sent to this
|
||||
* NVE are valid.
|
||||
*
|
||||
* pHandle pointer to location to store rfapi handle. The
|
||||
* handle must be passed on subsequent rfapi_ calls.
|
||||
*
|
||||
*
|
||||
* return value:
|
||||
* 0 Success
|
||||
* EEXIST NVE with this {vn,un} already open
|
||||
* ENOENT No matching nve group config
|
||||
* ENOMSG Matched nve group config was incomplete
|
||||
* ENXIO BGP or VNC not configured
|
||||
* EAFNOSUPPORT Matched nve group specifies auto-assignment of RD,
|
||||
* but underlay network address is not IPv4
|
||||
* EDEADLK Called from within a callback procedure
|
||||
*------------------------------------------*/
|
||||
extern int
|
||||
rfapi_open (
|
||||
void *rfp_start_val,
|
||||
struct rfapi_ip_addr *vn,
|
||||
struct rfapi_ip_addr *un,
|
||||
struct rfapi_un_option *default_options,
|
||||
uint32_t *response_lifetime,
|
||||
void *userdata,
|
||||
rfapi_handle *pHandle);
|
||||
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_close
|
||||
*
|
||||
* Shut down NVE session and release associated data. Calling
|
||||
* from within a rfapi callback procedure is permitted (the close
|
||||
* will be completed asynchronously after the callback finishes).
|
||||
*
|
||||
* input:
|
||||
* rfd: rfapi descriptor returned by rfapi_open
|
||||
*
|
||||
* output:
|
||||
*
|
||||
* return value:
|
||||
* 0 Success
|
||||
* EBADF invalid handle
|
||||
* ENXIO BGP or VNC not configured
|
||||
*------------------------------------------*/
|
||||
extern int
|
||||
rfapi_close (rfapi_handle rfd);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_check
|
||||
*
|
||||
* Test rfapi descriptor
|
||||
*
|
||||
* input:
|
||||
* rfd: rfapi descriptor returned by rfapi_open
|
||||
*
|
||||
* output:
|
||||
*
|
||||
* return value:
|
||||
* 0 Success: handle is valid and usable
|
||||
* EINVAL null argument
|
||||
* ESTALE formerly valid handle invalidated by config, needs close
|
||||
* EBADF invalid handle
|
||||
* ENXIO BGP or VNC not configured
|
||||
* EAFNOSUPPORT Internal addressing error
|
||||
*------------------------------------------*/
|
||||
extern int
|
||||
rfapi_check (rfapi_handle rfd);
|
||||
|
||||
/***********************************************************************
|
||||
* NVE Routes
|
||||
***********************************************************************/
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_query
|
||||
*
|
||||
* This function queries the RIB for a
|
||||
* particular route. Note that this call may result in subsequent
|
||||
* callbacks to response_cb. Response callbacks can be cancelled
|
||||
* by calling rfapi_query_done. A duplicate query using the same target
|
||||
* will result in only one callback per change in next_hops. (i.e.,
|
||||
* cancel/replace the prior query results.)
|
||||
*
|
||||
* input:
|
||||
* rfd: rfapi descriptor returned by rfapi_open
|
||||
* target: the destination address
|
||||
* l2o ptr to L2 Options struct, NULL if not present in query
|
||||
*
|
||||
* output:
|
||||
* ppNextHopEntry pointer to a location to store a pointer
|
||||
* to the returned list of nexthops. It is the
|
||||
* caller's responsibility to free this list
|
||||
* via rfapi_free_next_hop_list().
|
||||
*
|
||||
*
|
||||
* return value:
|
||||
* 0 Success
|
||||
* EBADF invalid handle
|
||||
* ENOENT no valid route
|
||||
* ENXIO BGP or VNC not configured
|
||||
* ESTALE descriptor is no longer usable; should be closed
|
||||
* EDEADLK Called from within a callback procedure
|
||||
--------------------------------------------*/
|
||||
extern int
|
||||
rfapi_query (
|
||||
rfapi_handle rfd,
|
||||
struct rfapi_ip_addr *target,
|
||||
struct rfapi_l2address_option *l2o,
|
||||
struct rfapi_next_hop_entry **ppNextHopEntry);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_query_done
|
||||
*
|
||||
* Notifies the rfapi that the user is no longer interested
|
||||
* in the specified target.
|
||||
*
|
||||
* input:
|
||||
* rfd: rfapi descriptor returned by rfapi_open
|
||||
* target: the destination address
|
||||
*
|
||||
* output:
|
||||
*
|
||||
* return value:
|
||||
* 0 Success
|
||||
* EBADF invalid handle
|
||||
* ENOENT no match found for target
|
||||
* ENXIO BGP or VNC not configured
|
||||
* ESTALE descriptor is no longer usable; should be closed
|
||||
* EDEADLK Called from within a callback procedure
|
||||
--------------------------------------------*/
|
||||
extern int
|
||||
rfapi_query_done (rfapi_handle rfd, struct rfapi_ip_addr *target);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_query_done_all
|
||||
*
|
||||
* Notifies the rfapi that the user is no longer interested
|
||||
* in any target.
|
||||
*
|
||||
* input:
|
||||
* rfd: rfapi descriptor returned by rfapi_open
|
||||
*
|
||||
* output:
|
||||
* count: number of queries cleared
|
||||
*
|
||||
* return value:
|
||||
* 0 Success
|
||||
* EBADF invalid handle
|
||||
* ENXIO BGP or VNC not configured
|
||||
* ESTALE descriptor is no longer usable; should be closed
|
||||
* EDEADLK Called from within a callback procedure
|
||||
--------------------------------------------*/
|
||||
extern int
|
||||
rfapi_query_done_all (rfapi_handle rfd, int *count);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_register
|
||||
*
|
||||
* Requests that reachability to the indicated prefix via this NVE
|
||||
* be advertised by BGP. If <unregister> is non-zero, then the previously-
|
||||
* advertised prefix should be withdrawn.
|
||||
*
|
||||
* (This function should NOT be called if the rfapi_open() function
|
||||
* returns NULL)
|
||||
*
|
||||
* input:
|
||||
* rfd: rfapi descriptor returned by rfapi_open
|
||||
* prefix: A prefix to be registered or deregistered
|
||||
* lifetime Prefix lifetime in seconds, host byte order
|
||||
* options_un underlay netowrk options, may include tunnel-type
|
||||
* Caller owns (rfapi_register() does not free).
|
||||
* options_vn virtual network options, may include layer 2 address
|
||||
* option and local-nexthop option
|
||||
* Caller owns (rfapi_register() does not free).
|
||||
*
|
||||
* action: RFAPI_REGISTER_ADD add the route
|
||||
* RFAPI_REGISTER_WITHDRAW withdraw route
|
||||
* RFAPI_REGISTER_KILL withdraw without holddown
|
||||
*
|
||||
* return value:
|
||||
* 0 Success
|
||||
* EBADF invalid handle
|
||||
* ENXIO BGP or VNC not configured
|
||||
* ESTALE descriptor is no longer usable; should be closed
|
||||
* EDEADLK Called from within a callback procedure
|
||||
--------------------------------------------*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RFAPI_REGISTER_ADD,
|
||||
RFAPI_REGISTER_WITHDRAW,
|
||||
RFAPI_REGISTER_KILL
|
||||
} rfapi_register_action;
|
||||
|
||||
extern int
|
||||
rfapi_register (
|
||||
rfapi_handle rfd,
|
||||
struct rfapi_ip_prefix *prefix,
|
||||
uint32_t lifetime,
|
||||
struct rfapi_un_option *options_un,
|
||||
struct rfapi_vn_option *options_vn,
|
||||
rfapi_register_action action);
|
||||
|
||||
/***********************************************************************
|
||||
* Helper / Utility functions
|
||||
***********************************************************************/
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_get_vn_addr
|
||||
*
|
||||
* Get the virtual network address used by an NVE based on it's RFD
|
||||
*
|
||||
* input:
|
||||
* rfd: rfapi descriptor returned by rfapi_open or rfapi_create_generic
|
||||
*
|
||||
* output:
|
||||
*
|
||||
* return value:
|
||||
* vn NVE virtual network address
|
||||
*------------------------------------------*/
|
||||
extern struct rfapi_ip_addr *
|
||||
rfapi_get_vn_addr (void *);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_get_un_addr
|
||||
*
|
||||
* Get the underlay network address used by an NVE based on it's RFD
|
||||
*
|
||||
* input:
|
||||
* rfd: rfapi descriptor returned by rfapi_open or rfapi_create_generic
|
||||
*
|
||||
* output:
|
||||
*
|
||||
* return value:
|
||||
* un NVE underlay network address
|
||||
*------------------------------------------*/
|
||||
extern struct rfapi_ip_addr *
|
||||
rfapi_get_un_addr (void *);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_error_str
|
||||
*
|
||||
* Returns a string describing the rfapi error code.
|
||||
*
|
||||
* input:
|
||||
*
|
||||
* code Error code returned by rfapi function
|
||||
*
|
||||
* returns:
|
||||
*
|
||||
* const char * String
|
||||
*------------------------------------------*/
|
||||
extern const char *
|
||||
rfapi_error_str (int code);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_get_rfp_start_val
|
||||
*
|
||||
* Returns value passed to rfapi on rfp_start
|
||||
*
|
||||
* input:
|
||||
* void * bgp structure
|
||||
*
|
||||
* returns:
|
||||
* void *
|
||||
*------------------------------------------*/
|
||||
extern void *
|
||||
rfapi_get_rfp_start_val (void *bgpv);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_compare_rfds
|
||||
*
|
||||
* Compare two generic rfapi descriptors.
|
||||
*
|
||||
* input:
|
||||
* rfd1: rfapi descriptor returned by rfapi_open or rfapi_create_generic
|
||||
* rfd2: rfapi descriptor returned by rfapi_open or rfapi_create_generic
|
||||
*
|
||||
* output:
|
||||
*
|
||||
* return value:
|
||||
* 0 Mismatch
|
||||
* 1 Match
|
||||
*------------------------------------------*/
|
||||
extern int
|
||||
rfapi_compare_rfds (void *rfd1, void *rfd2);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_free_next_hop_list
|
||||
*
|
||||
* Frees a next_hop_list returned by a rfapi_query invocation
|
||||
*
|
||||
* input:
|
||||
* list: a pointer to a response list (as a
|
||||
* struct rfapi_next_hop_entry) to free.
|
||||
*
|
||||
* output:
|
||||
*
|
||||
* return value: None
|
||||
--------------------------------------------*/
|
||||
extern void
|
||||
rfapi_free_next_hop_list (struct rfapi_next_hop_entry *list);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_get_response_lifetime_default
|
||||
*
|
||||
* Returns the default lifetime for a response.
|
||||
* rfp_start_val value returned by rfp_start or
|
||||
* NULL (=use default instance)
|
||||
*
|
||||
* input:
|
||||
* None
|
||||
*
|
||||
* output:
|
||||
*
|
||||
* return value: The bgp instance default lifetime for a response.
|
||||
--------------------------------------------*/
|
||||
extern int
|
||||
rfapi_get_response_lifetime_default (void *rfp_start_val);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_is_vnc_configured
|
||||
*
|
||||
* Returns if VNC (BGP VPN messaging /VPN & encap SAFIs) are configured
|
||||
*
|
||||
* input:
|
||||
* rfp_start_val value returned by rfp_start or
|
||||
* NULL (=use default instance)
|
||||
*
|
||||
* output:
|
||||
*
|
||||
* return value: If VNC is configured for the bgpd instance
|
||||
* 0 Success
|
||||
* ENXIO VNC not configured
|
||||
--------------------------------------------*/
|
||||
extern int
|
||||
rfapi_is_vnc_configured (void *rfp_start_val);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_bgp_lookup_by_rfp
|
||||
*
|
||||
* Find bgp instance pointer based on value returned by rfp_start
|
||||
*
|
||||
* input:
|
||||
* rfp_start_val value returned by rfp_startor
|
||||
* NULL (=get default instance)
|
||||
*
|
||||
* output:
|
||||
* none
|
||||
*
|
||||
* return value:
|
||||
* bgp bgp instance pointer
|
||||
* NULL = not found
|
||||
*
|
||||
--------------------------------------------*/
|
||||
extern struct bgp *
|
||||
rfapi_bgp_lookup_by_rfp (void *rfp_start_val);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_get_rfp_start_val_by_bgp
|
||||
*
|
||||
* Find bgp instance pointer based on value returned by rfp_start
|
||||
*
|
||||
* input:
|
||||
* bgp bgp instance pointer
|
||||
*
|
||||
* output:
|
||||
* none
|
||||
*
|
||||
* return value:
|
||||
* rfp_start_val
|
||||
* NULL = not found
|
||||
*
|
||||
--------------------------------------------*/
|
||||
extern void *
|
||||
rfapi_get_rfp_start_val_by_bgp (struct bgp *bgp);
|
||||
|
||||
#endif /* ENABLE_BGP_VNC */
|
||||
|
||||
#endif /* _QUAGGA_BGP_RFAPI_H */
|
629
bgpd/rfapi/rfapi_ap.c
Normal file
629
bgpd/rfapi/rfapi_ap.c
Normal file
@ -0,0 +1,629 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "zebra.h"
|
||||
#include "prefix.h"
|
||||
#include "table.h"
|
||||
#include "vty.h"
|
||||
#include "memory.h"
|
||||
#include "routemap.h"
|
||||
#include "log.h"
|
||||
#include "linklist.h"
|
||||
#include "command.h"
|
||||
#include "stream.h"
|
||||
|
||||
#include "bgpd.h"
|
||||
#include "bgp_ecommunity.h"
|
||||
#include "bgp_attr.h"
|
||||
#include "bgp_mplsvpn.h"
|
||||
|
||||
#include "bgp_rfapi_cfg.h"
|
||||
#include "rfapi.h"
|
||||
#include "rfapi_backend.h"
|
||||
|
||||
#include "bgp_route.h"
|
||||
#include "bgp_aspath.h"
|
||||
#include "bgp_advertise.h"
|
||||
|
||||
#include "rfapi_import.h"
|
||||
#include "rfapi_private.h"
|
||||
#include "rfapi_monitor.h"
|
||||
#include "rfapi_vty.h"
|
||||
#include "vnc_export_bgp.h"
|
||||
#include "vnc_export_bgp_p.h"
|
||||
#include "vnc_zebra.h"
|
||||
#include "vnc_import_bgp.h"
|
||||
#include "rfapi_rib.h"
|
||||
|
||||
#include "rfapi_ap.h"
|
||||
|
||||
/*
|
||||
* Per-NVE Advertised prefixes
|
||||
*
|
||||
* We maintain a list of prefixes advertised by each NVE.
|
||||
* There are two indices: by prefix and by lifetime.
|
||||
*
|
||||
* BY-PREFIX skiplist
|
||||
*
|
||||
* key: ptr to struct prefix (when storing, point to prefix that
|
||||
* is part of rfapi_adb).
|
||||
*
|
||||
* value: ptr to struct rfapi_adb
|
||||
*
|
||||
* BY-LIFETIME skiplist
|
||||
*
|
||||
* key: ptr to struct rfapi_adb
|
||||
* value: ptr to struct rfapi_adb
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Skiplist sort function that sorts first according to lifetime
|
||||
* and then according to adb pointer value. The adb pointer
|
||||
* is used to spread out the sort for adbs with the same lifetime
|
||||
* and thereby make the skip list operations more efficient.
|
||||
*/
|
||||
static int
|
||||
sl_adb_lifetime_cmp (void *adb1, void *adb2)
|
||||
{
|
||||
struct rfapi_adb *a1 = adb1;
|
||||
struct rfapi_adb *a2 = adb2;
|
||||
|
||||
if (a1->lifetime < a2->lifetime)
|
||||
return -1;
|
||||
if (a1->lifetime > a2->lifetime)
|
||||
return 1;
|
||||
|
||||
if (a1 < a2)
|
||||
return -1;
|
||||
if (a1 > a2)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
rfapiApInit (struct rfapi_advertised_prefixes *ap)
|
||||
{
|
||||
ap->ipN_by_prefix = skiplist_new (0, vnc_prefix_cmp, NULL);
|
||||
ap->ip0_by_ether = skiplist_new (0, vnc_prefix_cmp, NULL);
|
||||
ap->by_lifetime = skiplist_new (0, sl_adb_lifetime_cmp, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
rfapiApRelease (struct rfapi_advertised_prefixes *ap)
|
||||
{
|
||||
struct rfapi_adb *adb;
|
||||
|
||||
/* Free ADBs and lifetime items */
|
||||
while (0 == skiplist_first (ap->by_lifetime, NULL, (void **) &adb))
|
||||
{
|
||||
rfapiAdbFree (adb);
|
||||
skiplist_delete_first (ap->by_lifetime);
|
||||
}
|
||||
|
||||
while (0 == skiplist_delete_first (ap->ipN_by_prefix));
|
||||
while (0 == skiplist_delete_first (ap->ip0_by_ether));
|
||||
|
||||
/* Free lists */
|
||||
skiplist_free (ap->ipN_by_prefix);
|
||||
skiplist_free (ap->ip0_by_ether);
|
||||
skiplist_free (ap->by_lifetime);
|
||||
|
||||
ap->ipN_by_prefix = NULL;
|
||||
ap->ip0_by_ether = NULL;
|
||||
ap->by_lifetime = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
rfapiApCount (struct rfapi_descriptor *rfd)
|
||||
{
|
||||
if (!rfd->advertised.by_lifetime)
|
||||
return 0;
|
||||
|
||||
return skiplist_count (rfd->advertised.by_lifetime);
|
||||
}
|
||||
|
||||
int
|
||||
rfapiApCountAll (struct bgp *bgp)
|
||||
{
|
||||
struct rfapi *h;
|
||||
struct listnode *node;
|
||||
struct rfapi_descriptor *rfd;
|
||||
int total = 0;
|
||||
|
||||
h = bgp->rfapi;
|
||||
if (h)
|
||||
{
|
||||
for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd))
|
||||
{
|
||||
total += rfapiApCount (rfd);
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
rfapiApReadvertiseAll (struct bgp *bgp, struct rfapi_descriptor *rfd)
|
||||
{
|
||||
struct rfapi_adb *adb;
|
||||
void *cursor;
|
||||
int rc;
|
||||
|
||||
for (rc =
|
||||
skiplist_next (rfd->advertised.by_lifetime, NULL, (void **) &adb,
|
||||
&cursor); rc == 0;
|
||||
rc =
|
||||
skiplist_next (rfd->advertised.by_lifetime, NULL, (void **) &adb,
|
||||
&cursor))
|
||||
{
|
||||
|
||||
struct prefix_rd prd;
|
||||
uint32_t local_pref = rfp_cost_to_localpref (adb->cost);
|
||||
|
||||
prd = rfd->rd;
|
||||
prd.family = AF_UNSPEC;
|
||||
prd.prefixlen = 64;
|
||||
|
||||
/*
|
||||
* TBD this is not quite right. When pfx_ip is 0/32 or 0/128,
|
||||
* we need to substitute the VN address as the prefix
|
||||
*/
|
||||
add_vnc_route (rfd, bgp, SAFI_MPLS_VPN, &adb->prefix_ip, &prd, /* RD to use (0 for ENCAP) */
|
||||
&rfd->vn_addr, /* nexthop */
|
||||
&local_pref, &adb->lifetime, NULL, NULL, /* struct rfapi_un_option */
|
||||
NULL, /* struct rfapi_vn_option */
|
||||
rfd->rt_export_list, NULL, /* med */
|
||||
NULL, ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rfapiApWithdrawAll (struct bgp *bgp, struct rfapi_descriptor *rfd)
|
||||
{
|
||||
struct rfapi_adb *adb;
|
||||
void *cursor;
|
||||
int rc;
|
||||
|
||||
|
||||
cursor = NULL;
|
||||
for (rc =
|
||||
skiplist_next (rfd->advertised.by_lifetime, NULL, (void **) &adb,
|
||||
&cursor); rc == 0;
|
||||
rc =
|
||||
skiplist_next (rfd->advertised.by_lifetime, NULL, (void **) &adb,
|
||||
&cursor))
|
||||
{
|
||||
|
||||
struct prefix pfx_vn_buf;
|
||||
struct prefix *pfx_ip;
|
||||
|
||||
if (!(RFAPI_0_PREFIX (&adb->prefix_ip) &&
|
||||
RFAPI_HOST_PREFIX (&adb->prefix_ip)))
|
||||
{
|
||||
|
||||
pfx_ip = &adb->prefix_ip;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
pfx_ip = NULL;
|
||||
|
||||
/*
|
||||
* 0/32 or 0/128 => mac advertisement
|
||||
*/
|
||||
if (rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx_vn_buf))
|
||||
{
|
||||
/*
|
||||
* Bad: it means we can't delete the route
|
||||
*/
|
||||
zlog_debug ("%s: BAD: handle has bad vn_addr: skipping",
|
||||
__func__);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
del_vnc_route (rfd, rfd->peer, bgp, SAFI_MPLS_VPN, pfx_ip ? pfx_ip : &pfx_vn_buf, &adb->prd, /* RD to use (0 for ENCAP) */
|
||||
ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* returns nonzero if tunnel readvertisement is needed, 0 otherwise
|
||||
*/
|
||||
static int
|
||||
rfapiApAdjustLifetimeStats (
|
||||
struct rfapi_descriptor *rfd,
|
||||
uint32_t *old_lifetime, /* set if removing/replacing */
|
||||
uint32_t *new_lifetime) /* set if replacing/adding */
|
||||
{
|
||||
int advertise = 0;
|
||||
int find_max = 0;
|
||||
int find_min = 0;
|
||||
|
||||
zlog_debug ("%s: rfd=%p, pOldLife=%p, pNewLife=%p",
|
||||
__func__, rfd, old_lifetime, new_lifetime);
|
||||
if (old_lifetime)
|
||||
zlog_debug ("%s: OldLife=%d", __func__, *old_lifetime);
|
||||
if (new_lifetime)
|
||||
zlog_debug ("%s: NewLife=%d", __func__, *new_lifetime);
|
||||
|
||||
if (new_lifetime)
|
||||
{
|
||||
/*
|
||||
* Adding new lifetime
|
||||
*/
|
||||
if (old_lifetime)
|
||||
{
|
||||
/*
|
||||
* replacing existing lifetime
|
||||
*/
|
||||
|
||||
|
||||
/* old and new are same */
|
||||
if (*old_lifetime == *new_lifetime)
|
||||
return 0;
|
||||
|
||||
if (*old_lifetime == rfd->min_prefix_lifetime)
|
||||
{
|
||||
find_min = 1;
|
||||
}
|
||||
if (*old_lifetime == rfd->max_prefix_lifetime)
|
||||
{
|
||||
find_max = 1;
|
||||
}
|
||||
|
||||
/* no need to search if new value is at or equals min|max */
|
||||
if (*new_lifetime <= rfd->min_prefix_lifetime)
|
||||
{
|
||||
rfd->min_prefix_lifetime = *new_lifetime;
|
||||
find_min = 0;
|
||||
}
|
||||
if (*new_lifetime >= rfd->max_prefix_lifetime)
|
||||
{
|
||||
rfd->max_prefix_lifetime = *new_lifetime;
|
||||
advertise = 1;
|
||||
find_max = 0;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Just adding new lifetime
|
||||
*/
|
||||
if (*new_lifetime < rfd->min_prefix_lifetime)
|
||||
{
|
||||
rfd->min_prefix_lifetime = *new_lifetime;
|
||||
}
|
||||
if (*new_lifetime > rfd->max_prefix_lifetime)
|
||||
{
|
||||
advertise = 1;
|
||||
rfd->max_prefix_lifetime = *new_lifetime;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Deleting
|
||||
*/
|
||||
|
||||
/*
|
||||
* See if the max prefix lifetime for this NVE has decreased.
|
||||
* The easy optimization: track min & max; walk the table only
|
||||
* if they are different.
|
||||
* The general optimization: index the advertised_prefixes
|
||||
* table by lifetime.
|
||||
*
|
||||
* Note: for a given nve_descriptor, only one of the
|
||||
* advertised_prefixes[] tables will be used: viz., the
|
||||
* address family that matches the VN address.
|
||||
*
|
||||
*/
|
||||
if (rfd->max_prefix_lifetime == rfd->min_prefix_lifetime)
|
||||
{
|
||||
|
||||
/*
|
||||
* Common case: all lifetimes are the same. Only
|
||||
* thing we need to do here is check if there are
|
||||
* no exported routes left. In that case, reinitialize
|
||||
* the max and min values.
|
||||
*/
|
||||
if (!rfapiApCount (rfd))
|
||||
{
|
||||
rfd->max_prefix_lifetime = 0;
|
||||
rfd->min_prefix_lifetime = UINT32_MAX;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (old_lifetime)
|
||||
{
|
||||
if (*old_lifetime == rfd->min_prefix_lifetime)
|
||||
{
|
||||
find_min = 1;
|
||||
}
|
||||
if (*old_lifetime == rfd->max_prefix_lifetime)
|
||||
{
|
||||
find_max = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (find_min || find_max)
|
||||
{
|
||||
uint32_t min = UINT32_MAX;
|
||||
uint32_t max = 0;
|
||||
|
||||
struct rfapi_adb *adb_min;
|
||||
struct rfapi_adb *adb_max;
|
||||
|
||||
if (!skiplist_first
|
||||
(rfd->advertised.by_lifetime, (void **) &adb_min, NULL)
|
||||
&& !skiplist_last (rfd->advertised.by_lifetime, (void **) &adb_max,
|
||||
NULL))
|
||||
{
|
||||
|
||||
/*
|
||||
* This should always work
|
||||
*/
|
||||
min = adb_min->lifetime;
|
||||
max = adb_max->lifetime;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
void *cursor;
|
||||
struct prefix *prefix;
|
||||
struct rfapi_adb *adb;
|
||||
int rc;
|
||||
|
||||
zlog_debug ("%s: walking to find new min/max", __func__);
|
||||
|
||||
cursor = NULL;
|
||||
for (rc = skiplist_next (rfd->advertised.ipN_by_prefix,
|
||||
(void **) &prefix, (void **) &adb,
|
||||
&cursor); !rc;
|
||||
rc =
|
||||
skiplist_next (rfd->advertised.ipN_by_prefix,
|
||||
(void **) &prefix, (void **) &adb, &cursor))
|
||||
{
|
||||
|
||||
uint32_t lt = adb->lifetime;
|
||||
|
||||
if (lt > max)
|
||||
max = lt;
|
||||
if (lt < min)
|
||||
min = lt;
|
||||
}
|
||||
cursor = NULL;
|
||||
for (rc = skiplist_next (rfd->advertised.ip0_by_ether,
|
||||
(void **) &prefix, (void **) &adb,
|
||||
&cursor); !rc;
|
||||
rc =
|
||||
skiplist_next (rfd->advertised.ip0_by_ether, (void **) &prefix,
|
||||
(void **) &adb, &cursor))
|
||||
{
|
||||
|
||||
uint32_t lt = adb->lifetime;
|
||||
|
||||
if (lt > max)
|
||||
max = lt;
|
||||
if (lt < min)
|
||||
min = lt;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* trigger tunnel route update
|
||||
* but only if we found a VPN route and it had
|
||||
* a lifetime greater than 0
|
||||
*/
|
||||
if (max && rfd->max_prefix_lifetime != max)
|
||||
advertise = 1;
|
||||
rfd->max_prefix_lifetime = max;
|
||||
rfd->min_prefix_lifetime = min;
|
||||
}
|
||||
|
||||
zlog_debug ("%s: returning advertise=%d, min=%d, max=%d",
|
||||
__func__, advertise, rfd->min_prefix_lifetime,
|
||||
rfd->max_prefix_lifetime);
|
||||
|
||||
return (advertise != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return Value
|
||||
*
|
||||
* 0 No need to advertise tunnel route
|
||||
* non-0 advertise tunnel route
|
||||
*/
|
||||
int
|
||||
rfapiApAdd (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_descriptor *rfd,
|
||||
struct prefix *pfx_ip,
|
||||
struct prefix *pfx_eth,
|
||||
struct prefix_rd *prd,
|
||||
uint32_t lifetime,
|
||||
uint8_t cost,
|
||||
struct rfapi_l2address_option *l2o) /* other options TBD */
|
||||
{
|
||||
int rc;
|
||||
struct rfapi_adb *adb;
|
||||
uint32_t old_lifetime = 0;
|
||||
int use_ip0 = 0;
|
||||
|
||||
if (RFAPI_0_PREFIX (pfx_ip) && RFAPI_HOST_PREFIX (pfx_ip))
|
||||
{
|
||||
use_ip0 = 1;
|
||||
assert (pfx_eth);
|
||||
|
||||
rc =
|
||||
skiplist_search (rfd->advertised.ip0_by_ether, pfx_eth,
|
||||
(void **) &adb);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* find prefix in advertised prefixes list */
|
||||
rc =
|
||||
skiplist_search (rfd->advertised.ipN_by_prefix, pfx_ip,
|
||||
(void **) &adb);
|
||||
}
|
||||
|
||||
|
||||
if (rc)
|
||||
{
|
||||
/* Not found */
|
||||
adb = XCALLOC (MTYPE_RFAPI_ADB, sizeof (struct rfapi_adb));
|
||||
assert (adb);
|
||||
adb->lifetime = lifetime;
|
||||
adb->prefix_ip = *pfx_ip;
|
||||
if (pfx_eth)
|
||||
adb->prefix_eth = *pfx_eth;
|
||||
|
||||
if (use_ip0)
|
||||
{
|
||||
assert (pfx_eth);
|
||||
skiplist_insert (rfd->advertised.ip0_by_ether, &adb->prefix_eth,
|
||||
adb);
|
||||
}
|
||||
else
|
||||
{
|
||||
skiplist_insert (rfd->advertised.ipN_by_prefix, &adb->prefix_ip,
|
||||
adb);
|
||||
}
|
||||
|
||||
skiplist_insert (rfd->advertised.by_lifetime, adb, adb);
|
||||
}
|
||||
else
|
||||
{
|
||||
old_lifetime = adb->lifetime;
|
||||
if (old_lifetime != lifetime)
|
||||
{
|
||||
assert (!skiplist_delete (rfd->advertised.by_lifetime, adb, NULL));
|
||||
adb->lifetime = lifetime;
|
||||
assert (!skiplist_insert (rfd->advertised.by_lifetime, adb, adb));
|
||||
}
|
||||
|
||||
if (!use_ip0 && pfx_eth && prefix_cmp (&adb->prefix_eth, pfx_eth))
|
||||
{
|
||||
/* mac address changed */
|
||||
adb->prefix_eth = *pfx_eth;
|
||||
}
|
||||
}
|
||||
adb->cost = cost;
|
||||
if (l2o)
|
||||
adb->l2o = *l2o;
|
||||
else
|
||||
memset (&adb->l2o, 0, sizeof (struct rfapi_l2address_option));
|
||||
adb->prd = *prd;
|
||||
|
||||
if (rfapiApAdjustLifetimeStats
|
||||
(rfd, (rc ? NULL : &old_lifetime), &lifetime))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* After this function returns successfully, caller should call
|
||||
* rfapiAdjustLifetimeStats() and possibly rfapiTunnelRouteAnnounce()
|
||||
*/
|
||||
int
|
||||
rfapiApDelete (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_descriptor *rfd,
|
||||
struct prefix *pfx_ip,
|
||||
struct prefix *pfx_eth,
|
||||
int *advertise_tunnel) /* out */
|
||||
{
|
||||
int rc;
|
||||
struct rfapi_adb *adb;
|
||||
uint32_t old_lifetime;
|
||||
int use_ip0 = 0;
|
||||
|
||||
if (advertise_tunnel)
|
||||
*advertise_tunnel = 0;
|
||||
|
||||
/* find prefix in advertised prefixes list */
|
||||
if (RFAPI_0_PREFIX (pfx_ip) && RFAPI_HOST_PREFIX (pfx_ip))
|
||||
{
|
||||
use_ip0 = 1;
|
||||
assert (pfx_eth);
|
||||
|
||||
rc =
|
||||
skiplist_search (rfd->advertised.ip0_by_ether, pfx_eth,
|
||||
(void **) &adb);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* find prefix in advertised prefixes list */
|
||||
rc =
|
||||
skiplist_search (rfd->advertised.ipN_by_prefix, pfx_ip,
|
||||
(void **) &adb);
|
||||
}
|
||||
|
||||
if (rc)
|
||||
{
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
old_lifetime = adb->lifetime;
|
||||
|
||||
if (use_ip0)
|
||||
{
|
||||
rc = skiplist_delete (rfd->advertised.ip0_by_ether, pfx_eth, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = skiplist_delete (rfd->advertised.ipN_by_prefix, pfx_ip, NULL);
|
||||
}
|
||||
assert (!rc);
|
||||
|
||||
rc = skiplist_delete (rfd->advertised.by_lifetime, adb, NULL);
|
||||
assert (!rc);
|
||||
|
||||
rfapiAdbFree (adb);
|
||||
|
||||
if (rfapiApAdjustLifetimeStats (rfd, &old_lifetime, NULL))
|
||||
{
|
||||
if (advertise_tunnel)
|
||||
*advertise_tunnel = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
99
bgpd/rfapi/rfapi_ap.h
Normal file
99
bgpd/rfapi/rfapi_ap.h
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
#ifndef _QUAGGA_BGP_RFAPI_AP_H
|
||||
#define _QUAGGA_BGP_RFAPI_AP_H
|
||||
|
||||
/* TBD delete some of these #includes */
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "zebra.h"
|
||||
#include "prefix.h"
|
||||
#include "table.h"
|
||||
#include "vty.h"
|
||||
#include "memory.h"
|
||||
#include "routemap.h"
|
||||
#include "log.h"
|
||||
#include "linklist.h"
|
||||
#include "command.h"
|
||||
#include "stream.h"
|
||||
|
||||
#include "bgpd.h"
|
||||
|
||||
#include "bgp_rfapi_cfg.h"
|
||||
#include "rfapi.h"
|
||||
#include "rfapi_backend.h"
|
||||
|
||||
#include "bgp_route.h"
|
||||
#include "bgp_aspath.h"
|
||||
#include "bgp_advertise.h"
|
||||
|
||||
#include "rfapi_import.h"
|
||||
#include "rfapi_private.h"
|
||||
#include "rfapi_monitor.h"
|
||||
#include "rfapi_vty.h"
|
||||
#include "vnc_export_bgp.h"
|
||||
#include "vnc_export_bgp_p.h"
|
||||
#include "vnc_zebra.h"
|
||||
#include "vnc_import_bgp.h"
|
||||
#include "rfapi_rib.h"
|
||||
|
||||
|
||||
extern void
|
||||
rfapiApInit (struct rfapi_advertised_prefixes *ap);
|
||||
|
||||
extern void
|
||||
rfapiApRelease (struct rfapi_advertised_prefixes *ap);
|
||||
|
||||
extern int
|
||||
rfapiApCount (struct rfapi_descriptor *rfd);
|
||||
|
||||
|
||||
extern int
|
||||
rfapiApCountAll (struct bgp *bgp);
|
||||
|
||||
extern void
|
||||
rfapiApReadvertiseAll (struct bgp *bgp, struct rfapi_descriptor *rfd);
|
||||
|
||||
extern void
|
||||
rfapiApWithdrawAll (struct bgp *bgp, struct rfapi_descriptor *rfd);
|
||||
|
||||
extern int
|
||||
rfapiApAdd (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_descriptor *rfd,
|
||||
struct prefix *pfx_ip,
|
||||
struct prefix *pfx_eth,
|
||||
struct prefix_rd *prd,
|
||||
uint32_t lifetime,
|
||||
uint8_t cost,
|
||||
struct rfapi_l2address_option *l2o); /* other options TBD */
|
||||
|
||||
extern int
|
||||
rfapiApDelete (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_descriptor *rfd,
|
||||
struct prefix *pfx_ip,
|
||||
struct prefix *pfx_eth,
|
||||
int *advertise_tunnel); /* out */
|
||||
|
||||
|
||||
#endif /* _QUAGGA_BGP_RFAPI_AP_H */
|
92
bgpd/rfapi/rfapi_backend.h
Normal file
92
bgpd/rfapi/rfapi_backend.h
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_BGP_RFAPI_BACKEND_H
|
||||
#define _QUAGGA_BGP_RFAPI_BACKEND_H
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
|
||||
#include "bgp_route.h"
|
||||
#include "bgp_nexthop.h"
|
||||
|
||||
extern void rfapi_init (void);
|
||||
extern void vnc_zebra_init (struct thread_master *master);
|
||||
extern void vnc_zebra_destroy (void);
|
||||
|
||||
extern void rfapi_delete (struct bgp *);
|
||||
|
||||
struct rfapi *bgp_rfapi_new (struct bgp *bgp);
|
||||
void bgp_rfapi_destroy (struct bgp *bgp, struct rfapi *h);
|
||||
|
||||
struct rfapi_import_table *rfapiImportTableRefAdd (struct bgp *bgp,
|
||||
struct ecommunity
|
||||
*rt_import_list);
|
||||
|
||||
void
|
||||
rfapiImportTableRefDelByIt (struct bgp *bgp,
|
||||
struct rfapi_import_table *it_target);
|
||||
|
||||
|
||||
extern void
|
||||
rfapiProcessUpdate (struct peer *peer,
|
||||
void *rfd,
|
||||
struct prefix *p,
|
||||
struct prefix_rd *prd,
|
||||
struct attr *attr,
|
||||
afi_t afi,
|
||||
safi_t safi,
|
||||
u_char type, u_char sub_type, uint32_t * label);
|
||||
|
||||
|
||||
extern void
|
||||
rfapiProcessWithdraw (struct peer *peer,
|
||||
void *rfd,
|
||||
struct prefix *p,
|
||||
struct prefix_rd *prd,
|
||||
struct attr *attr,
|
||||
afi_t afi, safi_t safi, u_char type, int kill);
|
||||
|
||||
extern void rfapiProcessPeerDown (struct peer *peer);
|
||||
|
||||
extern void
|
||||
vnc_zebra_announce (struct prefix *p,
|
||||
struct bgp_info *new_select, struct bgp *bgp);
|
||||
|
||||
extern void
|
||||
vnc_zebra_withdraw (struct prefix *p, struct bgp_info *old_select);
|
||||
|
||||
|
||||
extern void
|
||||
rfapi_vty_out_vncinfo (struct vty *vty,
|
||||
struct prefix *p, struct bgp_info *bi, safi_t safi);
|
||||
|
||||
|
||||
extern void vnc_direct_bgp_vpn_enable (struct bgp *bgp, afi_t afi);
|
||||
|
||||
extern void vnc_direct_bgp_vpn_disable (struct bgp *bgp, afi_t afi);
|
||||
|
||||
extern void vnc_direct_bgp_rh_vpn_enable (struct bgp *bgp, afi_t afi);
|
||||
|
||||
extern void vnc_direct_bgp_rh_vpn_disable (struct bgp *bgp, afi_t afi);
|
||||
|
||||
#endif /* ENABLE_BGP_VNC */
|
||||
|
||||
#endif /* _QUAGGA_BGP_RFAPI_BACKEND_H */
|
131
bgpd/rfapi/rfapi_descriptor_rfp_utils.c
Normal file
131
bgpd/rfapi/rfapi_descriptor_rfp_utils.c
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "zebra.h"
|
||||
#include "prefix.h"
|
||||
#include "table.h"
|
||||
#include "vty.h"
|
||||
#include "memory.h"
|
||||
#include "log.h"
|
||||
|
||||
#include "bgpd.h"
|
||||
|
||||
#include "rfapi.h"
|
||||
#include "rfapi_private.h"
|
||||
#include "rfapi_descriptor_rfp_utils.h"
|
||||
|
||||
|
||||
void *
|
||||
rfapi_create_generic (struct rfapi_ip_addr *vn, struct rfapi_ip_addr *un)
|
||||
{
|
||||
struct rfapi_descriptor *rfd;
|
||||
rfd = XCALLOC (MTYPE_RFAPI_DESC, sizeof (struct rfapi_descriptor));
|
||||
zlog_debug ("%s: rfd=%p", __func__, rfd);
|
||||
rfd->vn_addr = *vn;
|
||||
rfd->un_addr = *un;
|
||||
return (void *) rfd;
|
||||
}
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_free_generic
|
||||
*
|
||||
* Compare two generic rfapi descriptors.
|
||||
*
|
||||
* input:
|
||||
* grfd: rfapi descriptor returned by rfapi_open or rfapi_create_generic
|
||||
*
|
||||
* output:
|
||||
*
|
||||
* return value:
|
||||
*
|
||||
*------------------------------------------*/
|
||||
void
|
||||
rfapi_free_generic (void *grfd)
|
||||
{
|
||||
struct rfapi_descriptor *rfd;
|
||||
rfd = (struct rfapi_descriptor *) grfd;
|
||||
XFREE (MTYPE_RFAPI_DESC, rfd);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_compare_rfds
|
||||
*
|
||||
* Compare two generic rfapi descriptors.
|
||||
*
|
||||
* input:
|
||||
* rfd1: rfapi descriptor returned by rfapi_open or rfapi_create_generic
|
||||
* rfd2: rfapi descriptor returned by rfapi_open or rfapi_create_generic
|
||||
*
|
||||
* output:
|
||||
*
|
||||
* return value:
|
||||
* 0 Mismatch
|
||||
* 1 Match
|
||||
*------------------------------------------*/
|
||||
int
|
||||
rfapi_compare_rfds (void *rfd1, void *rfd2)
|
||||
{
|
||||
struct rfapi_descriptor *rrfd1, *rrfd2;
|
||||
int match = 0;
|
||||
|
||||
rrfd1 = (struct rfapi_descriptor *) rfd1;
|
||||
rrfd2 = (struct rfapi_descriptor *) rfd2;
|
||||
|
||||
if (rrfd1->vn_addr.addr_family == rrfd2->vn_addr.addr_family)
|
||||
{
|
||||
if (rrfd1->vn_addr.addr_family == AF_INET)
|
||||
match = IPV4_ADDR_SAME (&(rrfd1->vn_addr.addr.v4),
|
||||
&(rrfd2->vn_addr.addr.v4));
|
||||
else
|
||||
match = IPV6_ADDR_SAME (&(rrfd1->vn_addr.addr.v6),
|
||||
&(rrfd2->vn_addr.addr.v6));
|
||||
}
|
||||
|
||||
/*
|
||||
* If the VN addresses don't match in all forms,
|
||||
* give up.
|
||||
*/
|
||||
if (!match)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* do the process again for the UN addresses.
|
||||
*/
|
||||
match = 0;
|
||||
if (rrfd1->un_addr.addr_family == rrfd2->un_addr.addr_family)
|
||||
{
|
||||
/* VN addresses match
|
||||
* UN address families match
|
||||
* now check the actual UN addresses
|
||||
*/
|
||||
if (rrfd1->un_addr.addr_family == AF_INET)
|
||||
match = IPV4_ADDR_SAME (&(rrfd1->un_addr.addr.v4),
|
||||
&(rrfd2->un_addr.addr.v4));
|
||||
else
|
||||
match = IPV6_ADDR_SAME (&(rrfd1->un_addr.addr.v6),
|
||||
&(rrfd2->un_addr.addr.v6));
|
||||
}
|
||||
return match;
|
||||
}
|
39
bgpd/rfapi/rfapi_descriptor_rfp_utils.h
Normal file
39
bgpd/rfapi/rfapi_descriptor_rfp_utils.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
extern void *rfapi_create_generic (struct rfapi_ip_addr *vn,
|
||||
struct rfapi_ip_addr *un);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_free_generic
|
||||
*
|
||||
* Compare two generic rfapi descriptors.
|
||||
*
|
||||
* input:
|
||||
* grfd: rfapi descriptor returned by rfapi_open or rfapi_create_generic
|
||||
*
|
||||
* output:
|
||||
*
|
||||
* return value:
|
||||
*
|
||||
*------------------------------------------*/
|
||||
extern void rfapi_free_generic (void *grfd);
|
812
bgpd/rfapi/rfapi_encap_tlv.c
Normal file
812
bgpd/rfapi/rfapi_encap_tlv.c
Normal file
@ -0,0 +1,812 @@
|
||||
/*
|
||||
* Copyright 2015-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <zebra.h>
|
||||
|
||||
#include <memory.h>
|
||||
#include <prefix.h>
|
||||
#include <table.h>
|
||||
#include <vty.h>
|
||||
|
||||
#include "bgpd.h"
|
||||
#include "bgp_attr.h"
|
||||
|
||||
#include "bgp_encap_types.h"
|
||||
#include "bgp_encap_tlv.h"
|
||||
|
||||
#include "rfapi.h"
|
||||
#include "rfapi_encap_tlv.h"
|
||||
#include "rfapi_private.h"
|
||||
#include "rfapi_monitor.h"
|
||||
#include "rfapi_vty.h"
|
||||
#include "bgp_rfapi_cfg.h"
|
||||
|
||||
static void
|
||||
rfapi_add_endpoint_address_to_subtlv (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_ip_addr *ea,
|
||||
struct bgp_tea_subtlv_remote_endpoint *subtlv)
|
||||
{
|
||||
subtlv->family = ea->addr_family;
|
||||
if (subtlv->family == AF_INET)
|
||||
subtlv->ip_address.v4 = ea->addr.v4;
|
||||
else
|
||||
subtlv->ip_address.v6 = ea->addr.v6;
|
||||
subtlv->as4 = htonl (bgp->as);
|
||||
}
|
||||
|
||||
bgp_encap_types
|
||||
rfapi_tunneltype_option_to_tlv (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_ip_addr *ea,
|
||||
struct rfapi_tunneltype_option *tto,
|
||||
struct attr *attr,
|
||||
int always_add)
|
||||
{
|
||||
|
||||
#define _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(ttype) \
|
||||
if ((always_add || (bgp->rfapi_cfg && \
|
||||
!CHECK_FLAG(bgp->rfapi_cfg->flags, \
|
||||
BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP))) && \
|
||||
ea && !CHECK_SUBTLV_FLAG(&tto->bgpinfo.ttype, \
|
||||
BGP_TEA_SUBTLV_REMOTE_ENDPOINT)) { \
|
||||
rfapi_add_endpoint_address_to_subtlv(bgp, ea, \
|
||||
&tto->bgpinfo.ttype.st_endpoint); \
|
||||
SET_SUBTLV_FLAG(&tto->bgpinfo.ttype, BGP_TEA_SUBTLV_REMOTE_ENDPOINT); \
|
||||
}
|
||||
|
||||
struct rfapi_tunneltype_option dto;
|
||||
if (tto == NULL)
|
||||
{ /* create default type */
|
||||
tto = &dto;
|
||||
memset (tto, 0, sizeof (dto));
|
||||
tto->type = RFAPI_BGP_ENCAP_TYPE_DEFAULT;
|
||||
}
|
||||
switch (tto->type)
|
||||
{
|
||||
case BGP_ENCAP_TYPE_L2TPV3_OVER_IP:
|
||||
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (l2tpv3_ip);
|
||||
bgp_encap_type_l2tpv3overip_to_tlv (&tto->bgpinfo.l2tpv3_ip, attr);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_GRE:
|
||||
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (gre);
|
||||
bgp_encap_type_gre_to_tlv (&tto->bgpinfo.gre, attr);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT:
|
||||
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (transmit_tunnel_endpoint);
|
||||
bgp_encap_type_transmit_tunnel_endpoint (&tto->bgpinfo.transmit_tunnel_endpoint,
|
||||
attr);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE:
|
||||
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (ipsec_tunnel);
|
||||
bgp_encap_type_ipsec_in_tunnel_mode_to_tlv (&tto->bgpinfo.ipsec_tunnel,
|
||||
attr);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE:
|
||||
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (ip_ipsec);
|
||||
bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode_to_tlv
|
||||
(&tto->bgpinfo.ip_ipsec, attr);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE:
|
||||
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (mpls_ipsec);
|
||||
bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode_to_tlv
|
||||
(&tto->bgpinfo.mpls_ipsec, attr);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_IP_IN_IP:
|
||||
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (ip_ip);
|
||||
bgp_encap_type_ip_in_ip_to_tlv (&tto->bgpinfo.ip_ip, attr);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_VXLAN:
|
||||
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (vxlan);
|
||||
bgp_encap_type_vxlan_to_tlv (&tto->bgpinfo.vxlan, attr);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_NVGRE:
|
||||
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (nvgre);
|
||||
bgp_encap_type_nvgre_to_tlv (&tto->bgpinfo.nvgre, attr);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_MPLS:
|
||||
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (mpls);
|
||||
bgp_encap_type_mpls_to_tlv (&tto->bgpinfo.mpls, attr);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_MPLS_IN_GRE:
|
||||
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (mpls_gre);
|
||||
bgp_encap_type_mpls_in_gre_to_tlv (&tto->bgpinfo.mpls_gre, attr);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_VXLAN_GPE:
|
||||
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (vxlan_gpe);
|
||||
bgp_encap_type_vxlan_gpe_to_tlv (&tto->bgpinfo.vxlan_gpe, attr);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_MPLS_IN_UDP:
|
||||
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (mpls_udp);
|
||||
bgp_encap_type_mpls_in_udp_to_tlv (&tto->bgpinfo.mpls_udp, attr);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_PBB:
|
||||
_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (pbb);
|
||||
bgp_encap_type_pbb_to_tlv (&tto->bgpinfo.pbb, attr);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert (0);
|
||||
}
|
||||
return tto->type;
|
||||
}
|
||||
|
||||
struct rfapi_un_option *
|
||||
rfapi_encap_tlv_to_un_option (struct attr *attr)
|
||||
{
|
||||
struct attr_extra *attre = attr->extra;
|
||||
struct rfapi_un_option *uo = NULL;
|
||||
struct rfapi_tunneltype_option *tto;
|
||||
int rc;
|
||||
struct bgp_attr_encap_subtlv *stlv;
|
||||
|
||||
if (!attre)
|
||||
return NULL;
|
||||
|
||||
/* no tunnel encap attr stored */
|
||||
if (!attre->encap_tunneltype)
|
||||
return NULL;
|
||||
|
||||
stlv = attre->encap_subtlvs;
|
||||
|
||||
uo = XCALLOC (MTYPE_RFAPI_UN_OPTION, sizeof (struct rfapi_un_option));
|
||||
assert (uo);
|
||||
uo->type = RFAPI_UN_OPTION_TYPE_TUNNELTYPE;
|
||||
uo->v.tunnel.type = attre->encap_tunneltype;
|
||||
tto = &uo->v.tunnel;
|
||||
|
||||
switch (attre->encap_tunneltype)
|
||||
{
|
||||
case BGP_ENCAP_TYPE_L2TPV3_OVER_IP:
|
||||
rc = tlv_to_bgp_encap_type_l2tpv3overip (stlv, &tto->bgpinfo.l2tpv3_ip);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_GRE:
|
||||
rc = tlv_to_bgp_encap_type_gre (stlv, &tto->bgpinfo.gre);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT:
|
||||
rc = tlv_to_bgp_encap_type_transmit_tunnel_endpoint (stlv,
|
||||
&tto->bgpinfo.transmit_tunnel_endpoint);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE:
|
||||
rc = tlv_to_bgp_encap_type_ipsec_in_tunnel_mode (stlv,
|
||||
&tto->bgpinfo.ipsec_tunnel);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE:
|
||||
rc =
|
||||
tlv_to_bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode (stlv,
|
||||
&tto->bgpinfo.ip_ipsec);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE:
|
||||
rc =
|
||||
tlv_to_bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode
|
||||
(stlv, &tto->bgpinfo.mpls_ipsec);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_IP_IN_IP:
|
||||
rc = tlv_to_bgp_encap_type_ip_in_ip (stlv, &tto->bgpinfo.ip_ip);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_VXLAN:
|
||||
rc = tlv_to_bgp_encap_type_vxlan (stlv, &tto->bgpinfo.vxlan);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_NVGRE:
|
||||
rc = tlv_to_bgp_encap_type_nvgre (stlv, &tto->bgpinfo.nvgre);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_MPLS:
|
||||
rc = tlv_to_bgp_encap_type_mpls (stlv, &tto->bgpinfo.mpls);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_MPLS_IN_GRE:
|
||||
rc = tlv_to_bgp_encap_type_mpls_in_gre (stlv, &tto->bgpinfo.mpls_gre);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_VXLAN_GPE:
|
||||
rc = tlv_to_bgp_encap_type_vxlan_gpe (stlv, &tto->bgpinfo.vxlan_gpe);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_MPLS_IN_UDP:
|
||||
rc = tlv_to_bgp_encap_type_mpls_in_udp (stlv, &tto->bgpinfo.mpls_udp);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_PBB:
|
||||
rc = tlv_to_bgp_encap_type_pbb (stlv, &tto->bgpinfo.pbb);
|
||||
break;
|
||||
|
||||
default:
|
||||
zlog_debug ("%s: unknown tunnel type %d",
|
||||
__func__, attre->encap_tunneltype);
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
if (rc)
|
||||
{
|
||||
XFREE (MTYPE_RFAPI_UN_OPTION, uo);
|
||||
uo = NULL;
|
||||
}
|
||||
return uo;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* SUBTLV PRINT
|
||||
***********************************************************************/
|
||||
|
||||
static void
|
||||
subtlv_print_encap_l2tpv3_over_ip (
|
||||
void *stream,
|
||||
int column_offset,
|
||||
struct bgp_tea_subtlv_encap_l2tpv3_over_ip *st)
|
||||
{
|
||||
int (*fp) (void *, const char *, ...);
|
||||
struct vty *vty;
|
||||
void *out;
|
||||
const char *vty_newline;
|
||||
|
||||
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||
return;
|
||||
if (!st)
|
||||
return;
|
||||
|
||||
fp (out, "%*s%s%s", column_offset, "", "SubTLV: Encap(L2TPv3 over IP)",
|
||||
vty_newline);
|
||||
fp (out, "%*s SessionID: %d%s", column_offset, "", st->sessionid,
|
||||
vty_newline);
|
||||
fp (out, "%*s Cookie: (length %d)%s", column_offset, "", st->cookie_length,
|
||||
vty_newline);
|
||||
}
|
||||
|
||||
static void
|
||||
subtlv_print_encap_gre (
|
||||
void *stream,
|
||||
int column_offset,
|
||||
struct bgp_tea_subtlv_encap_gre_key *st)
|
||||
{
|
||||
int (*fp) (void *, const char *, ...);
|
||||
struct vty *vty;
|
||||
void *out;
|
||||
const char *vty_newline;
|
||||
|
||||
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||
return;
|
||||
if (!st)
|
||||
return;
|
||||
|
||||
fp (out, "%*s%s%s", column_offset, "", "SubTLV: Encap(GRE)", vty_newline);
|
||||
fp (out, "%*s GRE key: %d (0x%x)%s", column_offset, "", st->gre_key,
|
||||
st->gre_key, vty_newline);
|
||||
}
|
||||
|
||||
static void
|
||||
subtlv_print_encap_pbb (
|
||||
void *stream,
|
||||
int column_offset,
|
||||
struct bgp_tea_subtlv_encap_pbb *st)
|
||||
{
|
||||
int (*fp) (void *, const char *, ...);
|
||||
struct vty *vty;
|
||||
void *out;
|
||||
const char *vty_newline;
|
||||
|
||||
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||
return;
|
||||
if (!st)
|
||||
return;
|
||||
|
||||
fp (out, "%*s%s%s", column_offset, "", "SubTLV: Encap(PBB)", vty_newline);
|
||||
if (st->flag_isid)
|
||||
{
|
||||
fp (out, "%*s ISID: %d (0x%x)%s", column_offset, "", st->isid,
|
||||
st->isid, vty_newline);
|
||||
}
|
||||
if (st->flag_vid)
|
||||
{
|
||||
fp (out, "%*s VID: %d (0x%x)%s", column_offset, "", st->vid, st->vid,
|
||||
vty_newline);
|
||||
}
|
||||
fp (out, "%*s MACADDR %02x:%02x:%02x:%02x:%02x:%02x%s",
|
||||
column_offset, "",
|
||||
st->macaddr[0],
|
||||
st->macaddr[1],
|
||||
st->macaddr[2],
|
||||
st->macaddr[3], st->macaddr[4], st->macaddr[5], vty_newline);
|
||||
}
|
||||
|
||||
static void
|
||||
subtlv_print_proto_type (
|
||||
void *stream,
|
||||
int column_offset,
|
||||
struct bgp_tea_subtlv_proto_type *st)
|
||||
{
|
||||
int (*fp) (void *, const char *, ...);
|
||||
struct vty *vty;
|
||||
void *out;
|
||||
const char *vty_newline;
|
||||
|
||||
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||
return;
|
||||
if (!st)
|
||||
return;
|
||||
|
||||
fp (out, "%*s%s%s", column_offset, "", "SubTLV: Encap(Proto Type)",
|
||||
vty_newline);
|
||||
fp (out, "%*s Proto %d (0x%x)%s", column_offset, "", st->proto, st->proto,
|
||||
vty_newline);
|
||||
}
|
||||
|
||||
static void
|
||||
subtlv_print_color (
|
||||
void *stream,
|
||||
int column_offset,
|
||||
struct bgp_tea_subtlv_color *st)
|
||||
{
|
||||
int (*fp) (void *, const char *, ...);
|
||||
struct vty *vty;
|
||||
void *out;
|
||||
const char *vty_newline;
|
||||
|
||||
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||
return;
|
||||
if (!st)
|
||||
return;
|
||||
|
||||
fp (out, "%*s%s%s", column_offset, "", "SubTLV: Color", vty_newline);
|
||||
fp (out, "%*s Color: %d (0x%x)", column_offset, "", st->color, st->color,
|
||||
vty_newline);
|
||||
}
|
||||
|
||||
static void
|
||||
subtlv_print_ipsec_ta (
|
||||
void *stream,
|
||||
int column_offset,
|
||||
struct bgp_tea_subtlv_ipsec_ta *st)
|
||||
{
|
||||
int (*fp) (void *, const char *, ...);
|
||||
struct vty *vty;
|
||||
void *out;
|
||||
const char *vty_newline;
|
||||
|
||||
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||
return;
|
||||
if (!st)
|
||||
return;
|
||||
|
||||
fp (out, "%*s%s%s", column_offset, "", "SubTLV: IPSEC TA", vty_newline);
|
||||
fp (out, "%*s Authenticator Type: %d (0x%x)", column_offset, "",
|
||||
st->authenticator_type, st->authenticator_type, vty_newline);
|
||||
fp (out, "%*s Authenticator: (length %d)", column_offset, "",
|
||||
st->authenticator_length, vty_newline);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* TLV PRINT
|
||||
***********************************************************************/
|
||||
|
||||
static void
|
||||
print_encap_type_l2tpv3overip (
|
||||
void *stream,
|
||||
int column_offset,
|
||||
struct bgp_encap_type_l2tpv3_over_ip *bet)
|
||||
{
|
||||
const char *type = "L2TPv3 over IP";
|
||||
int (*fp) (void *, const char *, ...);
|
||||
struct vty *vty;
|
||||
void *out;
|
||||
const char *vty_newline;
|
||||
|
||||
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||
return;
|
||||
if (!bet)
|
||||
return;
|
||||
|
||||
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
|
||||
|
||||
subtlv_print_encap_l2tpv3_over_ip (stream, column_offset + 2,
|
||||
&bet->st_encap);
|
||||
subtlv_print_proto_type (stream, column_offset + 2, &bet->st_proto);
|
||||
subtlv_print_color (stream, column_offset + 2, &bet->st_color);
|
||||
}
|
||||
|
||||
static void
|
||||
print_encap_type_gre (
|
||||
void *stream,
|
||||
int column_offset,
|
||||
struct bgp_encap_type_gre *bet)
|
||||
{
|
||||
const char *type = "GRE";
|
||||
int (*fp) (void *, const char *, ...);
|
||||
struct vty *vty;
|
||||
void *out;
|
||||
const char *vty_newline;
|
||||
|
||||
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||
return;
|
||||
if (!bet)
|
||||
return;
|
||||
|
||||
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
|
||||
|
||||
subtlv_print_encap_gre (stream, column_offset + 2, &bet->st_encap);
|
||||
subtlv_print_proto_type (stream, column_offset + 2, &bet->st_proto);
|
||||
subtlv_print_color (stream, column_offset + 2, &bet->st_color);
|
||||
}
|
||||
|
||||
static void
|
||||
print_encap_type_ip_in_ip (
|
||||
void *stream,
|
||||
int column_offset,
|
||||
struct bgp_encap_type_ip_in_ip *bet)
|
||||
{
|
||||
const char *type = "IP in IP";
|
||||
int (*fp) (void *, const char *, ...);
|
||||
struct vty *vty;
|
||||
void *out;
|
||||
const char *vty_newline;
|
||||
|
||||
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||
return;
|
||||
if (!bet)
|
||||
return;
|
||||
|
||||
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
|
||||
|
||||
subtlv_print_proto_type (stream, column_offset + 2, &bet->st_proto);
|
||||
subtlv_print_color (stream, column_offset + 2, &bet->st_color);
|
||||
}
|
||||
|
||||
static void
|
||||
print_encap_type_transmit_tunnel_endpoint (
|
||||
void *stream,
|
||||
int column_offset,
|
||||
struct bgp_encap_type_transmit_tunnel_endpoint *bet)
|
||||
{
|
||||
const char *type = "Transmit Tunnel Endpoint";
|
||||
int (*fp) (void *, const char *, ...);
|
||||
struct vty *vty;
|
||||
void *out;
|
||||
const char *vty_newline;
|
||||
|
||||
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||
return;
|
||||
if (!bet)
|
||||
return;
|
||||
|
||||
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
|
||||
|
||||
/* no subtlvs for this type */
|
||||
}
|
||||
|
||||
static void
|
||||
print_encap_type_ipsec_in_tunnel_mode (
|
||||
void *stream,
|
||||
int column_offset,
|
||||
struct bgp_encap_type_ipsec_in_tunnel_mode *bet)
|
||||
{
|
||||
const char *type = "IPSEC in Tunnel mode";
|
||||
int (*fp) (void *, const char *, ...);
|
||||
struct vty *vty;
|
||||
void *out;
|
||||
const char *vty_newline;
|
||||
|
||||
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||
return;
|
||||
if (!bet)
|
||||
return;
|
||||
|
||||
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
|
||||
subtlv_print_ipsec_ta (stream, column_offset + 2, &bet->st_ipsec_ta);
|
||||
}
|
||||
|
||||
static void
|
||||
print_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode (
|
||||
void *stream,
|
||||
int column_offset,
|
||||
struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode *bet)
|
||||
{
|
||||
const char *type = "IP in IP Tunnel with IPSEC transport mode";
|
||||
int (*fp) (void *, const char *, ...);
|
||||
struct vty *vty;
|
||||
void *out;
|
||||
const char *vty_newline;
|
||||
|
||||
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||
return;
|
||||
if (!bet)
|
||||
return;
|
||||
|
||||
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
|
||||
|
||||
subtlv_print_ipsec_ta (stream, column_offset + 2, &bet->st_ipsec_ta);
|
||||
}
|
||||
|
||||
static void
|
||||
print_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode (
|
||||
void *stream,
|
||||
int column_offset,
|
||||
struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode *bet)
|
||||
{
|
||||
const char *type = "MPLS in IP Tunnel with IPSEC transport mode";
|
||||
int (*fp) (void *, const char *, ...);
|
||||
struct vty *vty;
|
||||
void *out;
|
||||
const char *vty_newline;
|
||||
|
||||
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||
return;
|
||||
if (!bet)
|
||||
return;
|
||||
|
||||
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
|
||||
|
||||
subtlv_print_ipsec_ta (stream, column_offset + 2, &bet->st_ipsec_ta);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_encap_type_pbb (
|
||||
void *stream,
|
||||
int column_offset,
|
||||
struct bgp_encap_type_pbb *bet)
|
||||
{
|
||||
const char *type = "PBB";
|
||||
int (*fp) (void *, const char *, ...);
|
||||
struct vty *vty;
|
||||
void *out;
|
||||
const char *vty_newline;
|
||||
|
||||
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||
return;
|
||||
if (!bet)
|
||||
return;
|
||||
|
||||
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
|
||||
|
||||
subtlv_print_encap_pbb (stream, column_offset + 2, &bet->st_encap);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_encap_type_vxlan (
|
||||
void *stream,
|
||||
int column_offset,
|
||||
struct bgp_encap_type_vxlan *bet)
|
||||
{
|
||||
const char *type = "VXLAN";
|
||||
int (*fp) (void *, const char *, ...);
|
||||
struct vty *vty;
|
||||
void *out;
|
||||
const char *vty_newline;
|
||||
|
||||
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||
return;
|
||||
if (!bet)
|
||||
return;
|
||||
|
||||
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
|
||||
|
||||
/* no subtlvs for this type */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_encap_type_nvgre (
|
||||
void *stream,
|
||||
int column_offset,
|
||||
struct bgp_encap_type_nvgre *bet)
|
||||
{
|
||||
const char *type = "NVGRE";
|
||||
int (*fp) (void *, const char *, ...);
|
||||
struct vty *vty;
|
||||
void *out;
|
||||
const char *vty_newline;
|
||||
|
||||
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||
return;
|
||||
if (!bet)
|
||||
return;
|
||||
|
||||
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
|
||||
|
||||
/* no subtlvs for this type */
|
||||
}
|
||||
|
||||
static void
|
||||
print_encap_type_mpls (
|
||||
void *stream,
|
||||
int column_offset,
|
||||
struct bgp_encap_type_mpls *bet)
|
||||
{
|
||||
const char *type = "MPLS";
|
||||
int (*fp) (void *, const char *, ...);
|
||||
struct vty *vty;
|
||||
void *out;
|
||||
const char *vty_newline;
|
||||
|
||||
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||
return;
|
||||
if (!bet)
|
||||
return;
|
||||
|
||||
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
|
||||
|
||||
/* no subtlvs for this type */
|
||||
}
|
||||
|
||||
static void
|
||||
print_encap_type_mpls_in_gre (
|
||||
void *stream,
|
||||
int column_offset,
|
||||
struct bgp_encap_type_mpls_in_gre *bet)
|
||||
{
|
||||
const char *type = "MPLS in GRE";
|
||||
int (*fp) (void *, const char *, ...);
|
||||
struct vty *vty;
|
||||
void *out;
|
||||
const char *vty_newline;
|
||||
|
||||
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||
return;
|
||||
if (!bet)
|
||||
return;
|
||||
|
||||
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
|
||||
|
||||
/* no subtlvs for this type */
|
||||
}
|
||||
|
||||
static void
|
||||
print_encap_type_vxlan_gpe (
|
||||
void *stream,
|
||||
int column_offset,
|
||||
struct bgp_encap_type_vxlan_gpe *bet)
|
||||
{
|
||||
const char *type = "VXLAN GPE";
|
||||
int (*fp) (void *, const char *, ...);
|
||||
struct vty *vty;
|
||||
void *out;
|
||||
const char *vty_newline;
|
||||
|
||||
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||
return;
|
||||
if (!bet)
|
||||
return;
|
||||
|
||||
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
|
||||
|
||||
/* no subtlvs for this type */
|
||||
}
|
||||
|
||||
static void
|
||||
print_encap_type_mpls_in_udp (
|
||||
void *stream,
|
||||
int column_offset,
|
||||
struct bgp_encap_type_mpls_in_udp *bet)
|
||||
{
|
||||
const char *type = "MPLS in UDP";
|
||||
int (*fp) (void *, const char *, ...);
|
||||
struct vty *vty;
|
||||
void *out;
|
||||
const char *vty_newline;
|
||||
|
||||
if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||
return;
|
||||
if (!bet)
|
||||
return;
|
||||
|
||||
fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
|
||||
|
||||
/* no subtlvs for this type */
|
||||
}
|
||||
|
||||
void
|
||||
rfapi_print_tunneltype_option (
|
||||
void *stream,
|
||||
int column_offset,
|
||||
struct rfapi_tunneltype_option *tto)
|
||||
{
|
||||
switch (tto->type)
|
||||
{
|
||||
case BGP_ENCAP_TYPE_L2TPV3_OVER_IP:
|
||||
print_encap_type_l2tpv3overip (stream, column_offset,
|
||||
&tto->bgpinfo.l2tpv3_ip);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_GRE:
|
||||
print_encap_type_gre (stream, column_offset, &tto->bgpinfo.gre);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT:
|
||||
print_encap_type_transmit_tunnel_endpoint (stream, column_offset,
|
||||
&tto->bgpinfo.transmit_tunnel_endpoint);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE:
|
||||
print_encap_type_ipsec_in_tunnel_mode (stream, column_offset,
|
||||
&tto->bgpinfo.ipsec_tunnel);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE:
|
||||
print_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode (stream,
|
||||
column_offset,
|
||||
&tto->bgpinfo.ip_ipsec);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE:
|
||||
print_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode (stream,
|
||||
column_offset,
|
||||
&tto->bgpinfo.mpls_ipsec);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_IP_IN_IP:
|
||||
print_encap_type_ip_in_ip (stream, column_offset, &tto->bgpinfo.ip_ip);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_VXLAN:
|
||||
print_encap_type_vxlan (stream, column_offset, &tto->bgpinfo.vxlan);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_NVGRE:
|
||||
print_encap_type_nvgre (stream, column_offset, &tto->bgpinfo.nvgre);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_MPLS:
|
||||
print_encap_type_mpls (stream, column_offset, &tto->bgpinfo.mpls);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_MPLS_IN_GRE:
|
||||
print_encap_type_mpls_in_gre (stream, column_offset,
|
||||
&tto->bgpinfo.mpls_gre);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_VXLAN_GPE:
|
||||
print_encap_type_vxlan_gpe (stream, column_offset,
|
||||
&tto->bgpinfo.vxlan_gpe);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_MPLS_IN_UDP:
|
||||
print_encap_type_mpls_in_udp (stream, column_offset,
|
||||
&tto->bgpinfo.mpls_udp);
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_TYPE_PBB:
|
||||
print_encap_type_pbb (stream, column_offset, &tto->bgpinfo.pbb);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert (0);
|
||||
}
|
||||
}
|
43
bgpd/rfapi/rfapi_encap_tlv.h
Normal file
43
bgpd/rfapi/rfapi_encap_tlv.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2015-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_BGP_RFAPI_ENCAP_TLV_H
|
||||
#define _QUAGGA_BGP_RFAPI_ENCAP_TLV_H
|
||||
|
||||
#define RFAPI_BGP_ENCAP_TYPE_DEFAULT BGP_ENCAP_TYPE_IP_IN_IP
|
||||
|
||||
extern bgp_encap_types
|
||||
rfapi_tunneltype_option_to_tlv (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_ip_addr *ea,
|
||||
struct rfapi_tunneltype_option *tto,
|
||||
struct attr *attr,
|
||||
int always_add);
|
||||
|
||||
extern struct rfapi_un_option *
|
||||
rfapi_encap_tlv_to_un_option (struct attr *attr);
|
||||
|
||||
extern void
|
||||
rfapi_print_tunneltype_option (
|
||||
void *stream,
|
||||
int column_offset,
|
||||
struct rfapi_tunneltype_option *tto);
|
||||
|
||||
|
||||
#endif /* _QUAGGA_BGP_RFAPI_ENCAP_TLV_H */
|
5154
bgpd/rfapi/rfapi_import.c
Normal file
5154
bgpd/rfapi/rfapi_import.c
Normal file
File diff suppressed because it is too large
Load Diff
283
bgpd/rfapi/rfapi_import.h
Normal file
283
bgpd/rfapi/rfapi_import.h
Normal file
@ -0,0 +1,283 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* File: rfapi_import.h
|
||||
* Purpose: Handle import of routes from BGP to RFAPI
|
||||
*/
|
||||
|
||||
#ifndef QUAGGA_HGP_RFAPI_IMPORT_H
|
||||
#define QUAGGA_HGP_RFAPI_IMPORT_H
|
||||
|
||||
#include "thread.h"
|
||||
|
||||
/*
|
||||
* These are per-rt-import-list
|
||||
*
|
||||
* routes are not segregated by RD - the RD is stored in bgp_info_extra
|
||||
* and is needed to determine if two prefixes are the same.
|
||||
*/
|
||||
struct rfapi_import_table
|
||||
{
|
||||
struct rfapi_import_table *next;
|
||||
struct ecommunity *rt_import_list; /* copied from nve grp */
|
||||
int refcount; /* nve grps and nves */
|
||||
uint32_t l2_logical_net_id; /* L2 only: EVPN Eth Seg Id */
|
||||
struct route_table *imported_vpn[AFI_MAX];
|
||||
struct rfapi_monitor_vpn *vpn0_queries[AFI_MAX];
|
||||
struct rfapi_monitor_eth *eth0_queries;
|
||||
struct route_table *imported_encap[AFI_MAX];
|
||||
struct skiplist *monitor_exterior_orphans;
|
||||
int local_count[AFI_MAX];
|
||||
int remote_count[AFI_MAX];
|
||||
int holddown_count[AFI_MAX];
|
||||
int imported_count[AFI_MAX];
|
||||
};
|
||||
|
||||
#define RFAPI_LOCAL_BI(bi) \
|
||||
(((bi)->type == ZEBRA_ROUTE_BGP) && ((bi)->sub_type == BGP_ROUTE_RFP))
|
||||
|
||||
#define RFAPI_DIRECT_IMPORT_BI(bi) \
|
||||
(((bi)->type == ZEBRA_ROUTE_BGP_DIRECT) || ((bi)->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))
|
||||
|
||||
#define RFAPI_UPDATE_ITABLE_COUNT(bi, itable, afi, cnt) \
|
||||
if (RFAPI_LOCAL_BI(bi)) { \
|
||||
(itable)->local_count[(afi)] += (cnt); \
|
||||
} else { \
|
||||
if (RFAPI_DIRECT_IMPORT_BI(bi)) \
|
||||
(itable)->imported_count[(afi)] += (cnt); \
|
||||
else \
|
||||
(itable)->remote_count[(afi)] += (cnt); \
|
||||
}
|
||||
|
||||
extern uint8_t
|
||||
rfapiRfpCost (struct attr *attr);
|
||||
|
||||
extern void
|
||||
rfapiDebugBacktrace (void);
|
||||
|
||||
extern void
|
||||
rfapiCheckRouteCount (void);
|
||||
|
||||
/*
|
||||
* Print BI in an Import Table
|
||||
*/
|
||||
extern void
|
||||
rfapiPrintBi (void *stream, struct bgp_info *bi);
|
||||
|
||||
extern void
|
||||
rfapiShowImportTable (
|
||||
void *stream,
|
||||
const char *label,
|
||||
struct route_table *rt,
|
||||
int isvpn);
|
||||
|
||||
|
||||
extern void
|
||||
rfapiImportTableRefDelByIt (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_import_table *it_target);
|
||||
|
||||
|
||||
/*
|
||||
* Construct an rfapi nexthop list based on the routes attached to
|
||||
* the specified node.
|
||||
*
|
||||
* If there are any routes that do NOT have BGP_INFO_REMOVED set,
|
||||
* return those only. If there are ONLY routes with BGP_INFO_REMOVED,
|
||||
* then return those, and also include all the non-removed routes from the
|
||||
* next less-specific node (i.e., this node's parent) at the end.
|
||||
*/
|
||||
extern struct rfapi_next_hop_entry *
|
||||
rfapiRouteNode2NextHopList (
|
||||
struct route_node *rn,
|
||||
uint32_t lifetime, /* put into nexthop entries */
|
||||
struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */
|
||||
struct route_table *rfd_rib_table, /* preload this NVE rib table */
|
||||
struct prefix *pfx_target_original); /* query target */
|
||||
|
||||
extern struct rfapi_next_hop_entry *
|
||||
rfapiRouteTable2NextHopList (
|
||||
struct route_table *rt,
|
||||
uint32_t lifetime, /* put into nexthop entries */
|
||||
struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */
|
||||
struct route_table *rfd_rib_table, /* preload this NVE rib table */
|
||||
struct prefix *pfx_target_original); /* query target */
|
||||
|
||||
extern struct rfapi_next_hop_entry *
|
||||
rfapiEthRouteTable2NextHopList (
|
||||
uint32_t logical_net_id,
|
||||
struct rfapi_ip_prefix *rprefix,
|
||||
uint32_t lifetime, /* put into nexthop entries */
|
||||
struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */
|
||||
struct route_table *rib_route_table,/* preload NVE rib node */
|
||||
struct prefix *pfx_target_original); /* query target */
|
||||
|
||||
extern int
|
||||
rfapiEcommunitiesIntersect (struct ecommunity *e1, struct ecommunity *e2);
|
||||
|
||||
extern void
|
||||
rfapiCheckRefcount (struct route_node *rn, safi_t safi, int lockoffset);
|
||||
|
||||
extern int
|
||||
rfapiHasNonRemovedRoutes (struct route_node *rn);
|
||||
|
||||
extern int
|
||||
rfapiProcessDeferredClose (struct thread *t);
|
||||
|
||||
extern int
|
||||
rfapiGetUnAddrOfVpnBi (struct bgp_info *bi, struct prefix *p);
|
||||
|
||||
extern void
|
||||
rfapiNexthop2Prefix (struct attr *attr, struct prefix *p);
|
||||
|
||||
extern void
|
||||
rfapiUnicastNexthop2Prefix (
|
||||
afi_t afi,
|
||||
struct attr *attr,
|
||||
struct prefix *p);
|
||||
|
||||
/* Filtered Import Function actions */
|
||||
#define FIF_ACTION_UPDATE 0
|
||||
#define FIF_ACTION_WITHDRAW 1
|
||||
#define FIF_ACTION_KILL 2
|
||||
|
||||
extern void
|
||||
rfapiBgpInfoFilteredImportVPN (
|
||||
struct rfapi_import_table *import_table,
|
||||
int action,
|
||||
struct peer *peer,
|
||||
void *rfd, /* set for looped back routes */
|
||||
struct prefix *p,
|
||||
struct prefix *aux_prefix, /* AFI_ETHER: optional IP */
|
||||
afi_t afi,
|
||||
struct prefix_rd *prd,
|
||||
struct attr *attr, /* part of bgp_info */
|
||||
u_char type, /* part of bgp_info */
|
||||
u_char sub_type, /* part of bgp_info */
|
||||
uint32_t *label); /* part of bgp_info */
|
||||
|
||||
extern struct rfapi_next_hop_entry *
|
||||
rfapiEthRouteNode2NextHopList (
|
||||
struct route_node *rn,
|
||||
struct rfapi_ip_prefix *rprefix,
|
||||
uint32_t lifetime, /* put into nexthop entries */
|
||||
struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */
|
||||
struct route_table *rib_route_table,/* preload NVE rib table */
|
||||
struct prefix *pfx_target_original); /* query target */
|
||||
|
||||
extern struct rfapi_import_table *
|
||||
rfapiMacImportTableGetNoAlloc (
|
||||
struct bgp *bgp,
|
||||
uint32_t lni);
|
||||
|
||||
extern struct rfapi_import_table *
|
||||
rfapiMacImportTableGet (
|
||||
struct bgp *bgp,
|
||||
uint32_t lni);
|
||||
|
||||
extern int
|
||||
rfapiGetL2o (
|
||||
struct attr *attr,
|
||||
struct rfapi_l2address_option *l2o);
|
||||
|
||||
extern int rfapiEcommunityGetLNI (
|
||||
struct ecommunity *ecom,
|
||||
uint32_t *lni);
|
||||
|
||||
|
||||
/* enable for debugging; disable for performance */
|
||||
#if 0
|
||||
#define RFAPI_CHECK_REFCOUNT(rn, safi, lo) rfapiCheckRefcount((rn),(safi),(lo))
|
||||
#else
|
||||
#define RFAPI_CHECK_REFCOUNT(rn, safi, lo) {}
|
||||
#endif
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapiDeleteRemotePrefixes
|
||||
*
|
||||
* UI helper: For use by the "clear vnc prefixes" command
|
||||
*
|
||||
* input:
|
||||
* un if set, tunnel must match this prefix
|
||||
* vn if set, nexthop prefix must match this prefix
|
||||
* p if set, prefix must match this prefix
|
||||
*
|
||||
* output
|
||||
* pARcount number of active routes deleted
|
||||
* pAHcount number of active nves deleted
|
||||
* pHRcount number of holddown routes deleted
|
||||
* pHHcount number of holddown nves deleted
|
||||
*
|
||||
* return value:
|
||||
* void
|
||||
--------------------------------------------*/
|
||||
extern void
|
||||
rfapiDeleteRemotePrefixes (
|
||||
struct prefix *un,
|
||||
struct prefix *vn,
|
||||
struct prefix *p,
|
||||
int delete_active,
|
||||
int delete_holddown,
|
||||
uint32_t *pARcount, /* active routes */
|
||||
uint32_t *pAHcount, /* active nves */
|
||||
uint32_t *pHRcount, /* holddown routes */
|
||||
uint32_t *pHHcount); /* holddown nves */
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapiCountAllItRoutes
|
||||
*
|
||||
* UI helper: count VRF routes from BGP side
|
||||
*
|
||||
* input:
|
||||
*
|
||||
* output
|
||||
* pARcount count of active routes
|
||||
* pHRcount count of holddown routes
|
||||
* pIRcount count of holddown routes
|
||||
*
|
||||
* return value:
|
||||
* void
|
||||
--------------------------------------------*/
|
||||
extern void
|
||||
rfapiCountAllItRoutes (
|
||||
int *pALRcount, /* active local routes */
|
||||
int *pARRcount, /* active remote routes */
|
||||
int *pHRcount, /* holddown routes */
|
||||
int *pIRcount); /* direct imported routes */
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapiGetHolddownFromLifetime
|
||||
*
|
||||
* calculate holddown value based on lifetime
|
||||
*
|
||||
* input:
|
||||
* lifetime lifetime
|
||||
*
|
||||
* return value:
|
||||
* Holddown value based on lifetime, holddown_factor,
|
||||
* and RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY
|
||||
*
|
||||
--------------------------------------------*/
|
||||
extern uint32_t
|
||||
rfapiGetHolddownFromLifetime (uint32_t lifetime);
|
||||
|
||||
#endif /* QUAGGA_HGP_RFAPI_IMPORT_H */
|
1701
bgpd/rfapi/rfapi_monitor.c
Normal file
1701
bgpd/rfapi/rfapi_monitor.c
Normal file
File diff suppressed because it is too large
Load Diff
217
bgpd/rfapi/rfapi_monitor.h
Normal file
217
bgpd/rfapi/rfapi_monitor.h
Normal file
@ -0,0 +1,217 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QUAGGA_HGP_RFAPI_MONITOR_H
|
||||
#define QUAGGA_HGP_RFAPI_MONITOR_H
|
||||
|
||||
#include "zebra.h"
|
||||
#include "prefix.h"
|
||||
#include "table.h"
|
||||
|
||||
/*
|
||||
* These get attached to the nodes in an import table (using "aggregate" ptr)
|
||||
* to indicate which nves are interested in a prefix/target
|
||||
*/
|
||||
struct rfapi_monitor_vpn
|
||||
{
|
||||
struct rfapi_monitor_vpn *next; /* chain from struct route_node */
|
||||
struct rfapi_descriptor *rfd; /* which NVE requested the route */
|
||||
struct prefix p; /* constant: pfx in original request */
|
||||
struct route_node *node; /* node we're currently attached to */
|
||||
uint32_t flags;
|
||||
#define RFAPI_MON_FLAG_NEEDCALLBACK 0x00000001 /* deferred callback */
|
||||
|
||||
//int dcount; /* debugging counter */
|
||||
void *timer;
|
||||
};
|
||||
|
||||
struct rfapi_monitor_encap
|
||||
{
|
||||
struct rfapi_monitor_encap *next;
|
||||
struct rfapi_monitor_encap *prev;
|
||||
struct route_node *node; /* VPN node */
|
||||
struct bgp_info *bi; /* VPN bi */
|
||||
struct route_node *rn; /* parent node */
|
||||
};
|
||||
|
||||
struct rfapi_monitor_eth
|
||||
{
|
||||
struct rfapi_monitor_eth *next; /* for use in vpn0_queries list */
|
||||
struct rfapi_descriptor *rfd; /* which NVE requested the route */
|
||||
struct ethaddr macaddr;
|
||||
uint32_t logical_net_id;
|
||||
void *timer;
|
||||
};
|
||||
|
||||
/*
|
||||
* This is referenced by the "aggregate" field of a route node
|
||||
* in an RFAPI import table.
|
||||
*
|
||||
* node lock/unlock:
|
||||
* - one lock increment for this structure itself
|
||||
* - one lock per chained struct rfapi_monitor_vpn
|
||||
* - one lock for the mon_eth skiplist itself
|
||||
* - one lock per mon_eth skiplist entry
|
||||
* - one lock for the ext skiplist itself
|
||||
* - one lock for each ext skiplist entry
|
||||
* remember to free skiplist when freeing rfapi_it_extra
|
||||
* - one lock per chained struct rfapi_monitor_encap
|
||||
*
|
||||
*/
|
||||
struct rfapi_it_extra
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
struct rfapi_monitor_vpn *v;
|
||||
struct skiplist *idx_rd; /* RD index */
|
||||
struct skiplist *mon_eth; /* ether queries */
|
||||
struct
|
||||
{
|
||||
/* routes with UN addrs, either cached encap or Encap TLV */
|
||||
int valid_interior_count;
|
||||
|
||||
/* unicast exterior routes, key=bi, val=allocated prefix */
|
||||
struct skiplist *source;
|
||||
} e;
|
||||
} vpn;
|
||||
struct
|
||||
{
|
||||
struct rfapi_monitor_encap *e;
|
||||
} encap;
|
||||
} u;
|
||||
};
|
||||
|
||||
#define RFAPI_IT_EXTRA_GET(rn) ((struct rfapi_it_extra *)( \
|
||||
(rn)->aggregate? (rn)->aggregate: \
|
||||
(route_lock_node(rn), (rn)->aggregate = \
|
||||
XCALLOC(MTYPE_RFAPI_IT_EXTRA,sizeof(struct rfapi_it_extra)))))
|
||||
|
||||
#define RFAPI_RDINDEX(rn) \
|
||||
((rn)->aggregate ? RFAPI_IT_EXTRA_GET(rn)->u.vpn.idx_rd : NULL)
|
||||
|
||||
#define RFAPI_RDINDEX_W_ALLOC(rn) (RFAPI_IT_EXTRA_GET(rn)->u.vpn.idx_rd)
|
||||
|
||||
#define RFAPI_MONITOR_ETH(rn) \
|
||||
((rn)->aggregate ? RFAPI_IT_EXTRA_GET(rn)->u.vpn.mon_eth : NULL)
|
||||
|
||||
#define RFAPI_MONITOR_ETH_W_ALLOC(rn) (RFAPI_IT_EXTRA_GET(rn)->u.vpn.mon_eth)
|
||||
|
||||
#define RFAPI_MONITOR_VPN(rn) \
|
||||
((rn)->aggregate ? RFAPI_IT_EXTRA_GET(rn)->u.vpn.v : NULL)
|
||||
|
||||
#define RFAPI_MONITOR_VPN_W_ALLOC(rn) (RFAPI_IT_EXTRA_GET(rn)->u.vpn.v)
|
||||
|
||||
#define RFAPI_MONITOR_ENCAP(rn) \
|
||||
((rn)->aggregate ? RFAPI_IT_EXTRA_GET(rn)->u.encap.e : NULL)
|
||||
|
||||
#define RFAPI_MONITOR_ENCAP_W_ALLOC(rn) (RFAPI_IT_EXTRA_GET(rn)->u.encap.e)
|
||||
|
||||
#define RFAPI_MONITOR_EXTERIOR(rn) (&(RFAPI_IT_EXTRA_GET(rn)->u.vpn.e))
|
||||
|
||||
#define RFAPI_HAS_MONITOR_EXTERIOR(rn) (rn && rn->aggregate && \
|
||||
((struct rfapi_it_extra *)(rn->aggregate))->u.vpn.e.source && \
|
||||
!skiplist_first(((struct rfapi_it_extra *)(rn->aggregate))-> \
|
||||
u.vpn.e.source, NULL, NULL))
|
||||
|
||||
extern void
|
||||
rfapiMonitorLoopCheck (struct rfapi_monitor_vpn *mchain);
|
||||
|
||||
extern void
|
||||
rfapiMonitorCleanCheck (struct bgp *bgp);
|
||||
|
||||
extern void
|
||||
rfapiMonitorCheckAttachAllowed (void);
|
||||
|
||||
extern void
|
||||
rfapiMonitorExtraFlush (safi_t safi, struct route_node *rn);
|
||||
|
||||
extern struct route_node *
|
||||
rfapiMonitorGetAttachNode (struct rfapi_descriptor *rfd, struct prefix *p);
|
||||
|
||||
extern void
|
||||
rfapiMonitorAttachImportHd (struct rfapi_descriptor *rfd);
|
||||
|
||||
extern struct route_node *
|
||||
rfapiMonitorAdd (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_descriptor *rfd,
|
||||
struct prefix *p);
|
||||
|
||||
extern void
|
||||
rfapiMonitorDetachImportHd (struct rfapi_descriptor *rfd);
|
||||
|
||||
extern void
|
||||
rfapiMonitorDel (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_descriptor *rfd,
|
||||
struct prefix *p);
|
||||
|
||||
extern int
|
||||
rfapiMonitorDelHd (struct rfapi_descriptor *rfd);
|
||||
|
||||
extern void
|
||||
rfapiMonitorCallbacksOff (struct bgp *bgp);
|
||||
|
||||
extern void
|
||||
rfapiMonitorCallbacksOn (struct bgp *bgp);
|
||||
|
||||
extern void
|
||||
rfapiMonitorResponseRemovalOff (struct bgp *bgp);
|
||||
|
||||
extern void
|
||||
rfapiMonitorResponseRemovalOn (struct bgp *bgp);
|
||||
|
||||
extern void
|
||||
rfapiMonitorExtraPrune (safi_t safi, struct route_node *rn);
|
||||
|
||||
extern void
|
||||
rfapiMonitorTimersRestart (struct rfapi_descriptor *rfd, struct prefix *p);
|
||||
|
||||
extern void
|
||||
rfapiMonitorItNodeChanged (
|
||||
struct rfapi_import_table *import_table,
|
||||
struct route_node *it_node,
|
||||
struct rfapi_monitor_vpn *monitor_list);
|
||||
|
||||
extern void
|
||||
rfapiMonitorMovedUp (
|
||||
struct rfapi_import_table *import_table,
|
||||
struct route_node *old_node,
|
||||
struct route_node *new_node,
|
||||
struct rfapi_monitor_vpn *monitor_list);
|
||||
|
||||
extern struct route_node *
|
||||
rfapiMonitorEthAdd (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_descriptor *rfd,
|
||||
struct ethaddr *macaddr,
|
||||
uint32_t logical_net_id);
|
||||
|
||||
extern void
|
||||
rfapiMonitorEthDel (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_descriptor *rfd,
|
||||
struct ethaddr *macaddr,
|
||||
uint32_t logical_net_id);
|
||||
|
||||
#endif /* QUAGGA_HGP_RFAPI_MONITOR_H */
|
175
bgpd/rfapi/rfapi_nve_addr.c
Normal file
175
bgpd/rfapi/rfapi_nve_addr.c
Normal file
@ -0,0 +1,175 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "zebra.h"
|
||||
#include "prefix.h"
|
||||
#include "table.h"
|
||||
#include "vty.h"
|
||||
#include "memory.h"
|
||||
#include "skiplist.h"
|
||||
|
||||
|
||||
#include "bgpd.h"
|
||||
|
||||
#include "bgp_rfapi_cfg.h"
|
||||
#include "rfapi.h"
|
||||
#include "rfapi_backend.h"
|
||||
|
||||
#include "rfapi_import.h"
|
||||
#include "rfapi_private.h"
|
||||
#include "rfapi_nve_addr.h"
|
||||
#include "rfapi_vty.h"
|
||||
|
||||
#define DEBUG_NVE_ADDR 0
|
||||
|
||||
void rfapiNveAddr2Str (struct rfapi_nve_addr *, char *, int);
|
||||
|
||||
|
||||
#if DEBUG_NVE_ADDR
|
||||
static void
|
||||
logdifferent (const char *tag,
|
||||
struct rfapi_nve_addr *a, struct rfapi_nve_addr *b)
|
||||
{
|
||||
char a_str[BUFSIZ];
|
||||
char b_str[BUFSIZ];
|
||||
|
||||
rfapiNveAddr2Str (a, a_str, BUFSIZ);
|
||||
rfapiNveAddr2Str (b, b_str, BUFSIZ);
|
||||
zlog_debug ("%s: [%s] [%s]", tag, a_str, b_str);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int
|
||||
rfapi_nve_addr_cmp (void *k1, void *k2)
|
||||
{
|
||||
struct rfapi_nve_addr *a = (struct rfapi_nve_addr *) k1;
|
||||
struct rfapi_nve_addr *b = (struct rfapi_nve_addr *) k2;
|
||||
int ret = 0;
|
||||
|
||||
if (!a || !b)
|
||||
{
|
||||
#if DEBUG_NVE_ADDR
|
||||
zlog_debug ("%s: missing address a=%p b=%p", __func__, a, b);
|
||||
#endif
|
||||
return (a - b);
|
||||
}
|
||||
if (a->un.addr_family != b->un.addr_family)
|
||||
{
|
||||
#if DEBUG_NVE_ADDR
|
||||
zlog_debug ("diff: UN addr fam a->un.af=%d, b->un.af=%d",
|
||||
a->un.addr_family, b->un.addr_family);
|
||||
#endif
|
||||
return (a->un.addr_family - b->un.addr_family);
|
||||
}
|
||||
if (a->un.addr_family == AF_INET)
|
||||
{
|
||||
ret = IPV4_ADDR_CMP (&a->un.addr.v4, &b->un.addr.v4);
|
||||
if (ret != 0)
|
||||
{
|
||||
#if DEBUG_NVE_ADDR
|
||||
logdifferent ("diff: UN addr", a, b);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else if (a->un.addr_family == AF_INET6)
|
||||
{
|
||||
ret = IPV6_ADDR_CMP (&a->un.addr.v6, &b->un.addr.v6);
|
||||
if (ret == 0)
|
||||
{
|
||||
#if DEBUG_NVE_ADDR
|
||||
logdifferent ("diff: UN addr", a, b);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert (0);
|
||||
}
|
||||
if (a->vn.addr_family != b->vn.addr_family)
|
||||
{
|
||||
#if DEBUG_NVE_ADDR
|
||||
zlog_debug ("diff: pT addr fam a->vn.af=%d, b->vn.af=%d",
|
||||
a->vn.addr_family, b->vn.addr_family);
|
||||
#endif
|
||||
return (a->vn.addr_family - b->vn.addr_family);
|
||||
}
|
||||
if (a->vn.addr_family == AF_INET)
|
||||
{
|
||||
ret = IPV4_ADDR_CMP (&a->vn.addr.v4, &b->vn.addr.v4);
|
||||
if (ret != 0)
|
||||
{
|
||||
#if DEBUG_NVE_ADDR
|
||||
logdifferent ("diff: VN addr", a, b);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else if (a->vn.addr_family == AF_INET6)
|
||||
{
|
||||
ret = IPV6_ADDR_CMP (&a->vn.addr.v6, &b->vn.addr.v6);
|
||||
if (ret == 0)
|
||||
{
|
||||
#if DEBUG_NVE_ADDR
|
||||
logdifferent ("diff: VN addr", a, b);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert (0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
rfapiNveAddr2Str (struct rfapi_nve_addr *na, char *buf, int bufsize)
|
||||
{
|
||||
char *p = buf;
|
||||
int r;
|
||||
|
||||
#define REMAIN (bufsize - (p-buf))
|
||||
#define INCP {p += (r > REMAIN)? REMAIN: r;}
|
||||
|
||||
if (bufsize < 1)
|
||||
return;
|
||||
|
||||
r = snprintf (p, REMAIN, "VN=");
|
||||
INCP;
|
||||
|
||||
if (!rfapiRfapiIpAddr2Str (&na->vn, p, REMAIN))
|
||||
goto done;
|
||||
|
||||
buf[bufsize - 1] = 0;
|
||||
p = buf + strlen (buf);
|
||||
|
||||
r = snprintf (p, REMAIN, ", UN=");
|
||||
INCP;
|
||||
|
||||
rfapiRfapiIpAddr2Str (&na->un, p, REMAIN);
|
||||
|
||||
done:
|
||||
buf[bufsize - 1] = 0;
|
||||
}
|
43
bgpd/rfapi/rfapi_nve_addr.h
Normal file
43
bgpd/rfapi/rfapi_nve_addr.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_BGP_RFAPI_NVE_ADDR_H
|
||||
#define _QUAGGA_BGP_RFAPI_NVE_ADDR_H
|
||||
|
||||
#include "rfapi.h"
|
||||
|
||||
struct rfapi_nve_addr
|
||||
{
|
||||
struct rfapi_ip_addr vn;
|
||||
struct rfapi_ip_addr un;
|
||||
void *info;
|
||||
};
|
||||
|
||||
|
||||
extern int
|
||||
rfapi_nve_addr_cmp (void *k1, void *k2);
|
||||
|
||||
extern void
|
||||
rfapiNveAddr2Str (struct rfapi_nve_addr *na, char *buf, int bufsize);
|
||||
|
||||
|
||||
|
||||
#endif /* _QUAGGA_BGP_RFAPI_NVE_ADDR_H */
|
455
bgpd/rfapi/rfapi_private.h
Normal file
455
bgpd/rfapi/rfapi_private.h
Normal file
@ -0,0 +1,455 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Internal definitions for RFAPI. Not for use by other code
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_BGP_RFAPI_PRIVATE_H
|
||||
#define _QUAGGA_BGP_RFAPI_PRIVATE_H
|
||||
|
||||
#include "linklist.h"
|
||||
#include "skiplist.h"
|
||||
#include "workqueue.h"
|
||||
|
||||
#include "bgp_attr.h"
|
||||
|
||||
#include "rfapi.h"
|
||||
|
||||
/*
|
||||
* RFAPI Advertisement Data Block
|
||||
*
|
||||
* Holds NVE prefix advertisement information
|
||||
*/
|
||||
struct rfapi_adb
|
||||
{
|
||||
struct prefix prefix_ip;
|
||||
struct prefix prefix_eth; /* now redundant with l2o */
|
||||
struct prefix_rd prd;
|
||||
uint32_t lifetime;
|
||||
uint8_t cost;
|
||||
struct rfapi_l2address_option l2o;
|
||||
};
|
||||
|
||||
/*
|
||||
* Lists of rfapi_adb. Each rfapi_adb is referenced twice:
|
||||
*
|
||||
* 1. each is referenced in by_lifetime
|
||||
* 2. each is referenced by exactly one of: ipN_by_prefix, ip0_by_ether
|
||||
*/
|
||||
struct rfapi_advertised_prefixes
|
||||
{
|
||||
struct skiplist *ipN_by_prefix; /* all except 0/32, 0/128 */
|
||||
struct skiplist *ip0_by_ether; /* ip prefix 0/32, 0/128 */
|
||||
struct skiplist *by_lifetime; /* all */
|
||||
};
|
||||
|
||||
|
||||
struct rfapi_descriptor
|
||||
{
|
||||
struct route_node *un_node; /* backref to un table */
|
||||
|
||||
struct rfapi_descriptor *next; /* next vn_addr */
|
||||
|
||||
/* supplied by client */
|
||||
struct bgp *bgp; /* from rfp_start_val */
|
||||
struct rfapi_ip_addr vn_addr;
|
||||
struct rfapi_ip_addr un_addr;
|
||||
rfapi_response_cb_t *response_cb; /* override per-bgp response_cb */
|
||||
void *cookie; /* for callbacks */
|
||||
struct rfapi_tunneltype_option default_tunneltype_option;
|
||||
|
||||
/* supplied by matched configuration */
|
||||
struct prefix_rd rd;
|
||||
struct ecommunity *rt_export_list;
|
||||
uint32_t response_lifetime;
|
||||
|
||||
/* list of prefixes currently being advertised by this nve */
|
||||
struct rfapi_advertised_prefixes advertised;
|
||||
|
||||
time_t open_time;
|
||||
|
||||
uint32_t max_prefix_lifetime;
|
||||
uint32_t min_prefix_lifetime;
|
||||
|
||||
/* reference to this nve's import table */
|
||||
struct rfapi_import_table *import_table;
|
||||
|
||||
uint32_t monitor_count;
|
||||
struct route_table *mon; /* rfapi_monitors */
|
||||
struct skiplist *mon_eth; /* ethernet monitors */
|
||||
|
||||
/*
|
||||
* rib RIB as seen by NVE
|
||||
* rib_pending RIB containing nodes with updated info chains
|
||||
* rsp_times last time we sent response containing pfx
|
||||
*/
|
||||
uint32_t rib_prefix_count; /* pfxes with routes */
|
||||
struct route_table *rib[AFI_MAX];
|
||||
struct route_table *rib_pending[AFI_MAX];
|
||||
struct work_queue *updated_responses_queue;
|
||||
struct route_table *rsp_times[AFI_MAX];
|
||||
|
||||
uint32_t rsp_counter; /* dedup initial rsp */
|
||||
time_t rsp_time; /* dedup initial rsp */
|
||||
time_t ftd_last_allowed_time; /* FTD filter */
|
||||
|
||||
unsigned int stat_count_nh_reachable;
|
||||
unsigned int stat_count_nh_removal;
|
||||
|
||||
/*
|
||||
* points to the original nve group structure that matched
|
||||
* when this nve_descriptor was created. We use this pointer
|
||||
* in rfapi_close() to find the nve group structure and
|
||||
* delete its reference back to us.
|
||||
*
|
||||
* If the nve group structure is deleted (via configuration
|
||||
* change) while this nve_descriptor exists, this rfg pointer
|
||||
* will be set to NULL.
|
||||
*/
|
||||
struct rfapi_nve_group_cfg *rfg;
|
||||
|
||||
/*
|
||||
* This ~7kB structure is here to permit multiple routes for
|
||||
* a prefix to be injected to BGP. There are at least two
|
||||
* situations where such conditions obtain:
|
||||
*
|
||||
* When an VNC route is exported to BGP on behalf of the set of
|
||||
* NVEs that belong to the export NVE group, it is replicated
|
||||
* so that there is one route per NVE (and the route's nexthop
|
||||
* is the NVE's VN address).
|
||||
*
|
||||
* Each of these routes being injected to BGP must have a distinct
|
||||
* peer pointer (otherwise, if they have the same peer pointer, each
|
||||
* route will be considered an implicit waithdraw of the previous
|
||||
* route injected from that peer, and the new route will replace
|
||||
* rather than augment the old one(s)).
|
||||
*/
|
||||
struct peer *peer;
|
||||
|
||||
uint32_t flags;
|
||||
#define RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP 0x00000001
|
||||
#define RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP6 0x00000002
|
||||
#define RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_ETHER 0x00000004
|
||||
#define RFAPI_HD_FLAG_PROVISIONAL 0x00000008
|
||||
#define RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY 0x00000010
|
||||
};
|
||||
|
||||
#define RFAPI_QUEUED_FLAG(afi) ( \
|
||||
((afi) == AFI_IP)? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP: \
|
||||
(((afi) == AFI_IP6)? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP6: \
|
||||
(((afi) == AFI_ETHER)? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_ETHER: \
|
||||
(assert(0), 0) )))
|
||||
|
||||
|
||||
struct rfapi_global_stats
|
||||
{
|
||||
time_t last_reset;
|
||||
unsigned int max_descriptors;
|
||||
|
||||
unsigned int count_unknown_nves;
|
||||
|
||||
unsigned int count_queries;
|
||||
unsigned int count_queries_failed;
|
||||
|
||||
unsigned int max_responses; /* semantics? */
|
||||
|
||||
unsigned int count_registrations;
|
||||
unsigned int count_registrations_failed;
|
||||
|
||||
unsigned int count_updated_response_updates;
|
||||
unsigned int count_updated_response_deletes;
|
||||
};
|
||||
|
||||
/*
|
||||
* There is one of these per BGP instance.
|
||||
*
|
||||
* Radix tree is indexed by un address; follow chain and
|
||||
* check vn address to get exact match.
|
||||
*/
|
||||
struct rfapi
|
||||
{
|
||||
struct route_table un[AFI_MAX];
|
||||
struct rfapi_import_table *imports; /* IPv4, IPv6 */
|
||||
struct list descriptors;/* debug & resolve-nve imports */
|
||||
|
||||
struct rfapi_global_stats stat;
|
||||
|
||||
/*
|
||||
* callbacks into RFP, set at startup time (bgp_rfapi_new() gets
|
||||
* values from rfp_start()) or via rfapi_rfp_set_cb_methods()
|
||||
* (otherwise NULL). Note that the response_cb method can also
|
||||
* be overridden per-rfd (currently used only for debug/test scenarios)
|
||||
*/
|
||||
struct rfapi_rfp_cb_methods rfp_methods;
|
||||
|
||||
/*
|
||||
* Import tables for Ethernet over IPSEC
|
||||
*
|
||||
* The skiplist keys are LNIs. Values are pointers
|
||||
* to struct rfapi_import_table.
|
||||
*/
|
||||
struct skiplist *import_mac; /* L2 */
|
||||
|
||||
/*
|
||||
* when exporting plain routes ("registered-nve" mode) to
|
||||
* bgp unicast or zebra, we need to keep track of information
|
||||
* related to expiring the routes according to the VNC lifetime
|
||||
*/
|
||||
struct route_table *rt_export_bgp[AFI_MAX];
|
||||
struct route_table *rt_export_zebra[AFI_MAX];
|
||||
|
||||
/*
|
||||
* For VNC->BGP unicast exports in CE mode, we need a
|
||||
* routing table that collects all of the VPN routes
|
||||
* in a single tree. The VPN rib is split up according
|
||||
* to RD first, so we can't use that. This is an import
|
||||
* table that matches all RTs.
|
||||
*/
|
||||
struct rfapi_import_table *it_ce;
|
||||
|
||||
/*
|
||||
* when importing bgp-direct routes in resolve-nve mode,
|
||||
* this list maps unicast route nexthops to their bgp_infos
|
||||
* in the unicast table
|
||||
*/
|
||||
struct skiplist *resolve_nve_nexthop;
|
||||
|
||||
/*
|
||||
* Descriptors for which rfapi_close() was called during a callback.
|
||||
* They will be closed after the callback finishes.
|
||||
*/
|
||||
struct work_queue *deferred_close_q;
|
||||
|
||||
/*
|
||||
* For "show vnc responses"
|
||||
*/
|
||||
uint32_t response_immediate_count;
|
||||
uint32_t response_updated_count;
|
||||
uint32_t monitor_count;
|
||||
|
||||
uint32_t rib_prefix_count_total;
|
||||
uint32_t rib_prefix_count_total_max;
|
||||
|
||||
uint32_t flags;
|
||||
#define RFAPI_INCALLBACK 0x00000001
|
||||
void *rfp; /* from rfp_start */
|
||||
};
|
||||
|
||||
#define RFAPI_RIB_PREFIX_COUNT_INCR(rfd, rfapi) do { \
|
||||
++(rfd)->rib_prefix_count; \
|
||||
++(rfapi)->rib_prefix_count_total; \
|
||||
if ((rfapi)->rib_prefix_count_total > (rfapi)->rib_prefix_count_total_max) \
|
||||
++(rfapi)->rib_prefix_count_total_max; \
|
||||
} while (0)
|
||||
|
||||
#define RFAPI_RIB_PREFIX_COUNT_DECR(rfd, rfapi) do { \
|
||||
--(rfd)->rib_prefix_count; \
|
||||
--(rfapi)->rib_prefix_count_total; \
|
||||
} while (0)
|
||||
|
||||
#define RFAPI_0_PREFIX(prefix) ( \
|
||||
(((prefix)->family == AF_INET)? (prefix)->u.prefix4.s_addr == 0: \
|
||||
(((prefix)->family == AF_INET6)? \
|
||||
(IN6_IS_ADDR_UNSPECIFIED(&(prefix)->u.prefix6)) : 0)) \
|
||||
)
|
||||
|
||||
#define RFAPI_0_ETHERADDR(ea) ( \
|
||||
((ea)->octet[0] | (ea)->octet[1] | (ea)->octet[2] | \
|
||||
(ea)->octet[3] | (ea)->octet[4] | (ea)->octet[5]) == 0)
|
||||
|
||||
#define RFAPI_HOST_PREFIX(prefix) ( \
|
||||
((prefix)->family == AF_INET)? ((prefix)->prefixlen == 32): \
|
||||
(((prefix)->family == AF_INET6)? ((prefix)->prefixlen == 128): 0) )
|
||||
|
||||
extern void
|
||||
rfapiQprefix2Rprefix (
|
||||
struct prefix *qprefix,
|
||||
struct rfapi_ip_prefix *rprefix);
|
||||
|
||||
extern int
|
||||
rfapi_find_rfd (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_ip_addr *vn_addr,
|
||||
struct rfapi_ip_addr *un_addr,
|
||||
struct rfapi_descriptor **rfd);
|
||||
|
||||
extern void
|
||||
add_vnc_route (
|
||||
struct rfapi_descriptor *rfd, /* cookie + UN addr for VPN */
|
||||
struct bgp *bgp,
|
||||
int safi,
|
||||
struct prefix *p,
|
||||
struct prefix_rd *prd,
|
||||
struct rfapi_ip_addr *nexthop,
|
||||
uint32_t *local_pref, /* host byte order */
|
||||
uint32_t *lifetime, /* host byte order */
|
||||
struct bgp_tea_options *rfp_options,
|
||||
struct rfapi_un_option *options_un,
|
||||
struct rfapi_vn_option *options_vn,
|
||||
struct ecommunity *rt_export_list,
|
||||
uint32_t *med,
|
||||
uint32_t *label,
|
||||
uint8_t type,
|
||||
uint8_t sub_type,
|
||||
int flags);
|
||||
#define RFAPI_AHR_NO_TUNNEL_SUBTLV 0x00000001
|
||||
#define RFAPI_AHR_RFPOPT_IS_VNCTLV 0x00000002 /* hack! */
|
||||
#if 0 /* unused? */
|
||||
# define RFAPI_AHR_SET_PFX_TO_NEXTHOP 0x00000004
|
||||
#endif
|
||||
|
||||
extern void
|
||||
del_vnc_route (
|
||||
struct rfapi_descriptor *rfd,
|
||||
struct peer *peer,
|
||||
struct bgp *bgp,
|
||||
safi_t safi,
|
||||
struct prefix *p,
|
||||
struct prefix_rd *prd,
|
||||
uint8_t type,
|
||||
uint8_t sub_type,
|
||||
struct rfapi_nexthop *lnh,
|
||||
int kill);
|
||||
|
||||
extern int
|
||||
rfapiCliGetPrefixAddr (struct vty *vty, const char *str, struct prefix *p);
|
||||
|
||||
extern int
|
||||
rfapiGetVncLifetime (struct attr *attr, uint32_t * lifetime);
|
||||
|
||||
extern int
|
||||
rfapiGetTunnelType (struct attr *attr, bgp_encap_types *type);
|
||||
|
||||
extern int
|
||||
rfapiGetVncTunnelUnAddr (struct attr *attr, struct prefix *p);
|
||||
|
||||
extern int
|
||||
rfapi_reopen (struct rfapi_descriptor *rfd, struct bgp *bgp);
|
||||
|
||||
extern void
|
||||
vnc_import_bgp_add_rfp_host_route_mode_resolve_nve (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_descriptor *rfd,
|
||||
struct prefix *prefix);
|
||||
|
||||
extern void
|
||||
vnc_import_bgp_del_rfp_host_route_mode_resolve_nve (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_descriptor *rfd,
|
||||
struct prefix *prefix);
|
||||
|
||||
extern void
|
||||
rfapiFreeBgpTeaOptionChain (struct bgp_tea_options *p);
|
||||
|
||||
extern struct rfapi_vn_option *
|
||||
rfapiVnOptionsDup (struct rfapi_vn_option *orig);
|
||||
|
||||
extern struct rfapi_un_option *
|
||||
rfapiUnOptionsDup (struct rfapi_un_option *orig);
|
||||
|
||||
extern struct bgp_tea_options *
|
||||
rfapiOptionsDup (struct bgp_tea_options *orig);
|
||||
|
||||
extern int
|
||||
rfapi_ip_addr_cmp (struct rfapi_ip_addr *a1, struct rfapi_ip_addr *a2);
|
||||
|
||||
extern uint32_t
|
||||
rfp_cost_to_localpref (uint8_t cost);
|
||||
|
||||
extern int
|
||||
rfapi_set_autord_from_vn (struct prefix_rd *rd, struct rfapi_ip_addr *vn);
|
||||
|
||||
extern void
|
||||
rfapiAdbFree (struct rfapi_adb *adb);
|
||||
|
||||
extern struct rfapi_nexthop *
|
||||
rfapi_nexthop_new (struct rfapi_nexthop *copyme);
|
||||
|
||||
extern void
|
||||
rfapi_nexthop_free (void *goner);
|
||||
|
||||
extern struct rfapi_vn_option *
|
||||
rfapi_vn_options_dup (struct rfapi_vn_option *existing);
|
||||
|
||||
extern void
|
||||
rfapi_un_options_free (struct rfapi_un_option *goner);
|
||||
|
||||
extern void
|
||||
rfapi_vn_options_free (struct rfapi_vn_option *goner);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_extract_l2o
|
||||
*
|
||||
* Find Layer 2 options in an option chain
|
||||
*
|
||||
* input:
|
||||
* pHop option chain
|
||||
*
|
||||
* output:
|
||||
* l2o layer 2 options extracted
|
||||
*
|
||||
* return value:
|
||||
* 0 OK
|
||||
* 1 no options found
|
||||
*
|
||||
--------------------------------------------*/
|
||||
extern int
|
||||
rfapi_extract_l2o (
|
||||
struct bgp_tea_options *pHop, /* chain of options */
|
||||
struct rfapi_l2address_option *l2o); /* return extracted value */
|
||||
|
||||
/*
|
||||
* compaitibility to old quagga_time call
|
||||
* time_t value in terms of stabilised absolute time.
|
||||
* replacement for POSIX time()
|
||||
*/
|
||||
extern time_t rfapi_time (time_t *t);
|
||||
|
||||
DECLARE_MGROUP(RFAPI)
|
||||
DECLARE_MTYPE(RFAPI_CFG)
|
||||
DECLARE_MTYPE(RFAPI_GROUP_CFG)
|
||||
DECLARE_MTYPE(RFAPI_L2_CFG)
|
||||
DECLARE_MTYPE(RFAPI_RFP_GROUP_CFG)
|
||||
DECLARE_MTYPE(RFAPI)
|
||||
DECLARE_MTYPE(RFAPI_DESC)
|
||||
DECLARE_MTYPE(RFAPI_IMPORTTABLE)
|
||||
DECLARE_MTYPE(RFAPI_MONITOR)
|
||||
DECLARE_MTYPE(RFAPI_MONITOR_ENCAP)
|
||||
DECLARE_MTYPE(RFAPI_NEXTHOP)
|
||||
DECLARE_MTYPE(RFAPI_VN_OPTION)
|
||||
DECLARE_MTYPE(RFAPI_UN_OPTION)
|
||||
DECLARE_MTYPE(RFAPI_WITHDRAW)
|
||||
DECLARE_MTYPE(RFAPI_RFG_NAME)
|
||||
DECLARE_MTYPE(RFAPI_ADB)
|
||||
DECLARE_MTYPE(RFAPI_ETI)
|
||||
DECLARE_MTYPE(RFAPI_NVE_ADDR)
|
||||
DECLARE_MTYPE(RFAPI_PREFIX_BAG)
|
||||
DECLARE_MTYPE(RFAPI_IT_EXTRA)
|
||||
DECLARE_MTYPE(RFAPI_INFO)
|
||||
DECLARE_MTYPE(RFAPI_ADDR)
|
||||
DECLARE_MTYPE(RFAPI_UPDATED_RESPONSE_QUEUE)
|
||||
DECLARE_MTYPE(RFAPI_RECENT_DELETE)
|
||||
DECLARE_MTYPE(RFAPI_L2ADDR_OPT)
|
||||
DECLARE_MTYPE(RFAPI_AP)
|
||||
DECLARE_MTYPE(RFAPI_MONITOR_ETH)
|
||||
|
||||
#endif /* _QUAGGA_BGP_RFAPI_PRIVATE_H */
|
2535
bgpd/rfapi/rfapi_rib.c
Normal file
2535
bgpd/rfapi/rfapi_rib.c
Normal file
File diff suppressed because it is too large
Load Diff
154
bgpd/rfapi/rfapi_rib.h
Normal file
154
bgpd/rfapi/rfapi_rib.h
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* File: rfapi_rib.h
|
||||
* Purpose: per-nve rib
|
||||
*/
|
||||
|
||||
#ifndef QUAGGA_HGP_RFAPI_RIB_H
|
||||
#define QUAGGA_HGP_RFAPI_RIB_H
|
||||
|
||||
/*
|
||||
* Key for indexing RIB and Pending RIB skiplists. For L3 RIBs,
|
||||
* the VN address is sufficient because it represents the actual next hop.
|
||||
*
|
||||
* For L2 RIBs, it is possible to have multiple routes to a given L2
|
||||
* prefix via a given VN address, but each route having a unique aux_prefix.
|
||||
*/
|
||||
struct rfapi_rib_key
|
||||
{
|
||||
struct prefix vn;
|
||||
struct prefix_rd rd;
|
||||
|
||||
/*
|
||||
* for L2 routes: optional IP addr
|
||||
* .family == 0 means "none"
|
||||
*/
|
||||
struct prefix aux_prefix;
|
||||
};
|
||||
|
||||
struct rfapi_info
|
||||
{
|
||||
struct rfapi_rib_key rk; /* NVE VN addr + aux addr */
|
||||
struct prefix un;
|
||||
uint8_t cost;
|
||||
uint32_t lifetime;
|
||||
time_t last_sent_time;
|
||||
uint32_t rsp_counter; /* dedup initial responses */
|
||||
struct bgp_tea_options *tea_options;
|
||||
struct rfapi_un_option *un_options;
|
||||
struct rfapi_vn_option *vn_options;
|
||||
void *timer;
|
||||
};
|
||||
|
||||
/*
|
||||
* Work item for updated responses queue
|
||||
*/
|
||||
struct rfapi_updated_responses_queue
|
||||
{
|
||||
struct rfapi_descriptor *rfd;
|
||||
afi_t afi;
|
||||
};
|
||||
|
||||
|
||||
extern void
|
||||
rfapiRibClear (struct rfapi_descriptor *rfd);
|
||||
|
||||
extern void
|
||||
rfapiRibFree (struct rfapi_descriptor *rfd);
|
||||
|
||||
extern void
|
||||
rfapiRibUpdatePendingNode (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_descriptor *rfd,
|
||||
struct rfapi_import_table *it,
|
||||
struct route_node *it_node,
|
||||
uint32_t lifetime);
|
||||
|
||||
extern void
|
||||
rfapiRibUpdatePendingNodeSubtree (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_descriptor *rfd,
|
||||
struct rfapi_import_table *it,
|
||||
struct route_node *it_node,
|
||||
struct route_node *omit_subtree,
|
||||
uint32_t lifetime);
|
||||
|
||||
extern int
|
||||
rfapiRibPreloadBi(
|
||||
struct route_node *rfd_rib_node,
|
||||
struct prefix *pfx_vn,
|
||||
struct prefix *pfx_un,
|
||||
uint32_t lifetime,
|
||||
struct bgp_info *bi);
|
||||
|
||||
extern struct rfapi_next_hop_entry *
|
||||
rfapiRibPreload (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_descriptor *rfd,
|
||||
struct rfapi_next_hop_entry *response,
|
||||
int use_eth_resolution);
|
||||
|
||||
extern void
|
||||
rfapiRibPendingDeleteRoute (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_import_table *it,
|
||||
afi_t afi,
|
||||
struct route_node *it_node);
|
||||
|
||||
extern void
|
||||
rfapiRibShowResponsesSummary (void *stream);
|
||||
|
||||
extern void
|
||||
rfapiRibShowResponsesSummaryClear (void);
|
||||
|
||||
extern void
|
||||
rfapiRibShowResponses (
|
||||
void *stream,
|
||||
struct prefix *pfx_match,
|
||||
int show_removed);
|
||||
|
||||
extern int
|
||||
rfapiRibFTDFilterRecentPrefix(
|
||||
struct rfapi_descriptor *rfd,
|
||||
struct route_node *it_rn, /* import table node */
|
||||
struct prefix *pfx_target_original); /* query target */
|
||||
|
||||
extern void
|
||||
rfapiFreeRfapiUnOptionChain (struct rfapi_un_option *p);
|
||||
|
||||
extern void
|
||||
rfapiFreeRfapiVnOptionChain (struct rfapi_vn_option *p);
|
||||
|
||||
extern void
|
||||
rfapiRibCheckCounts (
|
||||
int checkstats, /* validate rfd & global counts */
|
||||
unsigned int offset); /* number of ri's held separately */
|
||||
|
||||
/* enable for debugging; disable for performance */
|
||||
#if 0
|
||||
#define RFAPI_RIB_CHECK_COUNTS(checkstats, offset) rfapiRibCheckCounts(checkstats, offset)
|
||||
#else
|
||||
#define RFAPI_RIB_CHECK_COUNTS(checkstats, offset)
|
||||
#endif
|
||||
|
||||
#endif /* QUAGGA_HGP_RFAPI_RIB_H */
|
5025
bgpd/rfapi/rfapi_vty.c
Normal file
5025
bgpd/rfapi/rfapi_vty.c
Normal file
File diff suppressed because it is too large
Load Diff
223
bgpd/rfapi/rfapi_vty.h
Normal file
223
bgpd/rfapi/rfapi_vty.h
Normal file
@ -0,0 +1,223 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef RFAPI_VTY_H
|
||||
#define RFAPI_VTY_H
|
||||
|
||||
#include "vty.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SHOW_NVE_SUMMARY_ACTIVE_NVES,
|
||||
SHOW_NVE_SUMMARY_UNKNOWN_NVES, /* legacy */
|
||||
SHOW_NVE_SUMMARY_REGISTERED,
|
||||
SHOW_NVE_SUMMARY_QUERIES,
|
||||
SHOW_NVE_SUMMARY_RESPONSES,
|
||||
SHOW_NVE_SUMMARY_MAX
|
||||
} show_nve_summary_t;
|
||||
|
||||
#define VNC_SHOW_STR "VNC information\n"
|
||||
|
||||
extern char *
|
||||
rfapiFormatSeconds (uint32_t seconds, char *buf, size_t len);
|
||||
|
||||
extern char *
|
||||
rfapiFormatAge (time_t age, char *buf, size_t len);
|
||||
|
||||
extern void
|
||||
rfapiRprefixApplyMask (struct rfapi_ip_prefix *rprefix);
|
||||
|
||||
extern int
|
||||
rfapiQprefix2Raddr (struct prefix *qprefix, struct rfapi_ip_addr *raddr);
|
||||
|
||||
extern void
|
||||
rfapiQprefix2Rprefix (struct prefix *qprefix,
|
||||
struct rfapi_ip_prefix *rprefix);
|
||||
|
||||
extern int
|
||||
rfapiRprefix2Qprefix (struct rfapi_ip_prefix *rprefix,
|
||||
struct prefix *qprefix);
|
||||
|
||||
extern int
|
||||
rfapiRaddr2Qprefix (struct rfapi_ip_addr *hia, struct prefix *pfx);
|
||||
|
||||
extern int
|
||||
rfapiRprefixSame (struct rfapi_ip_prefix *hp1, struct rfapi_ip_prefix *hp2);
|
||||
|
||||
extern void
|
||||
rfapiL2o2Qprefix (struct rfapi_l2address_option *l2o, struct prefix *pfx);
|
||||
|
||||
extern int
|
||||
rfapiStr2EthAddr (const char *str, struct ethaddr *ea);
|
||||
|
||||
extern const char *
|
||||
rfapi_ntop (
|
||||
int af,
|
||||
const void *src,
|
||||
char *buf,
|
||||
socklen_t size);
|
||||
|
||||
extern int
|
||||
rfapiDebugPrintf (void *dummy, const char *format, ...);
|
||||
|
||||
extern int
|
||||
rfapiStream2Vty (
|
||||
void *stream, /* input */
|
||||
int (**fp) (void *, const char *, ...), /* output */
|
||||
struct vty **vty, /* output */
|
||||
void **outstream, /* output */
|
||||
const char **vty_newline); /* output */
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapiRfapiIpAddr2Str
|
||||
*
|
||||
* UI helper: generate string from rfapi_ip_addr
|
||||
*
|
||||
* input:
|
||||
* a IP v4/v6 address
|
||||
*
|
||||
* output
|
||||
* buf put string here
|
||||
* bufsize max space to write
|
||||
*
|
||||
* return value:
|
||||
* NULL conversion failed
|
||||
* non-NULL pointer to buf
|
||||
--------------------------------------------*/
|
||||
extern const char *
|
||||
rfapiRfapiIpAddr2Str (struct rfapi_ip_addr *a, char *buf, int bufsize);
|
||||
|
||||
extern void
|
||||
rfapiPrintRfapiIpAddr (void *stream, struct rfapi_ip_addr *a);
|
||||
|
||||
extern void
|
||||
rfapiPrintRfapiIpPrefix (void *stream, struct rfapi_ip_prefix *p);
|
||||
|
||||
void
|
||||
rfapiPrintRd (struct vty *vty, struct prefix_rd *prd);
|
||||
|
||||
extern void
|
||||
rfapiPrintAdvertisedInfo (
|
||||
struct vty *vty,
|
||||
struct rfapi_descriptor *rfd,
|
||||
safi_t safi,
|
||||
struct prefix *p);
|
||||
|
||||
extern void
|
||||
rfapiPrintDescriptor (struct vty *vty, struct rfapi_descriptor *rfd);
|
||||
|
||||
extern void
|
||||
rfapiPrintMatchingDescriptors (struct vty *vty,
|
||||
struct prefix *vn_prefix,
|
||||
struct prefix *un_prefix);
|
||||
|
||||
extern void
|
||||
rfapiPrintAttrPtrs (void *stream, struct attr *attr);
|
||||
|
||||
/*
|
||||
* Parse an address and put into a struct prefix
|
||||
*/
|
||||
extern int
|
||||
rfapiCliGetPrefixAddr (struct vty *vty, const char *str, struct prefix *p);
|
||||
|
||||
extern int
|
||||
rfapiCliGetRfapiIpAddr (
|
||||
struct vty *vty,
|
||||
const char *str,
|
||||
struct rfapi_ip_addr *hai);
|
||||
|
||||
extern void
|
||||
rfapiPrintNhl (void *stream, struct rfapi_next_hop_entry *next_hops);
|
||||
|
||||
extern char *
|
||||
rfapiMonitorVpn2Str (
|
||||
struct rfapi_monitor_vpn *m,
|
||||
char *buf,
|
||||
int size);
|
||||
|
||||
extern const char *
|
||||
rfapiRfapiIpPrefix2Str (
|
||||
struct rfapi_ip_prefix *p,
|
||||
char *buf,
|
||||
int bufsize);
|
||||
|
||||
extern void
|
||||
rfapiShowItNode (void *stream, struct route_node *rn);
|
||||
|
||||
extern char *
|
||||
rfapiEthAddr2Str (
|
||||
const struct ethaddr *ea,
|
||||
char *buf,
|
||||
int bufsize);
|
||||
|
||||
/* install vty commands */
|
||||
extern void
|
||||
rfapi_vty_init (void);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapiShowRemoteRegistrations
|
||||
*
|
||||
* UI helper: produces the "remote" portion of the output
|
||||
* of "show vnc registrations".
|
||||
*
|
||||
* input:
|
||||
* stream pointer to output stream
|
||||
* prefix_only pointer to prefix. If non-NULL, print only registrations
|
||||
* matching the specified prefix
|
||||
* show_expiring if non-zero, show expiring registrations
|
||||
* show_local if non-zero, show local registrations
|
||||
* show_imported if non-zero, show imported registrations
|
||||
*
|
||||
* return value:
|
||||
* 0 nothing printed
|
||||
* >0 something printed
|
||||
--------------------------------------------*/
|
||||
extern int
|
||||
rfapiShowRemoteRegistrations (
|
||||
void *stream,
|
||||
struct prefix *prefix_only,
|
||||
int show_expiring,
|
||||
int show_local,
|
||||
int show_remote,
|
||||
int show_imported);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_monitor_count
|
||||
*
|
||||
* UI helper: count number of active monitors
|
||||
*
|
||||
* input:
|
||||
* handle rfapi handle (NULL to count across
|
||||
* all open handles)
|
||||
*
|
||||
* output
|
||||
*
|
||||
* return value:
|
||||
* count of monitors
|
||||
--------------------------------------------*/
|
||||
extern uint32_t
|
||||
rfapi_monitor_count (rfapi_handle);
|
||||
|
||||
extern int
|
||||
rfapiShowVncQueries (void *stream, struct prefix *pfx_match);
|
||||
|
||||
|
||||
#endif
|
230
bgpd/rfapi/vnc_debug.c
Normal file
230
bgpd/rfapi/vnc_debug.c
Normal file
@ -0,0 +1,230 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <zebra.h>
|
||||
|
||||
#include <lib/version.h>
|
||||
#include "prefix.h"
|
||||
#include "linklist.h"
|
||||
#include "stream.h"
|
||||
#include "command.h"
|
||||
#include "str.h"
|
||||
#include "log.h"
|
||||
#include "vnc_debug.h"
|
||||
|
||||
/*
|
||||
* debug state storage
|
||||
*/
|
||||
unsigned long conf_vnc_debug;
|
||||
unsigned long term_vnc_debug;
|
||||
|
||||
struct vnc_debug {
|
||||
unsigned long bit;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct vnc_debug vncdebug[] =
|
||||
{
|
||||
{VNC_DEBUG_RFAPI_QUERY, "rfapi-query"},
|
||||
{VNC_DEBUG_IMPORT_BI_ATTACH, "import-bi-attach"},
|
||||
{VNC_DEBUG_IMPORT_DEL_REMOTE, "import-del-remote"},
|
||||
{VNC_DEBUG_EXPORT_BGP_GETCE, "export-bgp-getce"},
|
||||
{VNC_DEBUG_EXPORT_BGP_DIRECT_ADD, "export-bgp-direct-add"},
|
||||
{VNC_DEBUG_IMPORT_BGP_ADD_ROUTE, "import-bgp-add-route"},
|
||||
};
|
||||
|
||||
#define VNC_STR "VNC information\n"
|
||||
|
||||
/***********************************************************************
|
||||
* debug bgp vnc <foo>
|
||||
***********************************************************************/
|
||||
DEFUN (debug_bgp_vnc,
|
||||
debug_bgp_vnc_cmd,
|
||||
"debug bgp vnc (rfapi-query|import-bi-attach|import-del-remote)",
|
||||
DEBUG_STR
|
||||
BGP_STR
|
||||
VNC_STR
|
||||
"rfapi query handling\n"
|
||||
"import BI atachment\n"
|
||||
"import delete remote routes\n")
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i)
|
||||
{
|
||||
if (!strcmp(argv[0], vncdebug[i].name))
|
||||
{
|
||||
if (vty->node == CONFIG_NODE)
|
||||
{
|
||||
conf_vnc_debug |= vncdebug[i].bit;
|
||||
term_vnc_debug |= vncdebug[i].bit;
|
||||
}
|
||||
else
|
||||
{
|
||||
term_vnc_debug |= vncdebug[i].bit;
|
||||
vty_out (vty, "BGP vnc %s debugging is on%s",
|
||||
vncdebug[i].name, VTY_NEWLINE);
|
||||
}
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
}
|
||||
vty_out (vty, "Unknown debug flag: %s%s", argv[0], VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
DEFUN (no_debug_bgp_vnc,
|
||||
no_debug_bgp_vnc_cmd,
|
||||
"no debug bgp vnc (rfapi-query|import-bi-attach|import-del-remote)",
|
||||
NO_STR
|
||||
DEBUG_STR
|
||||
BGP_STR
|
||||
VNC_STR
|
||||
"rfapi query handling\n"
|
||||
"import BI atachment\n"
|
||||
"import delete remote routes\n")
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i)
|
||||
{
|
||||
if (!strcmp(argv[0], vncdebug[i].name))
|
||||
{
|
||||
if (vty->node == CONFIG_NODE)
|
||||
{
|
||||
conf_vnc_debug &= ~vncdebug[i].bit;
|
||||
term_vnc_debug &= ~vncdebug[i].bit;
|
||||
}
|
||||
else
|
||||
{
|
||||
term_vnc_debug &= ~vncdebug[i].bit;
|
||||
vty_out (vty, "BGP vnc %s debugging is off%s",
|
||||
vncdebug[i].name, VTY_NEWLINE);
|
||||
}
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
}
|
||||
vty_out (vty, "Unknown debug flag: %s%s", argv[0], VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
ALIAS (no_debug_bgp_vnc,
|
||||
undebug_bgp_vnc_cmd,
|
||||
"undebug bgp vnc (rfapi-query|import-bi-attach|import-del-remote)",
|
||||
UNDEBUG_STR
|
||||
BGP_STR
|
||||
VNC_STR
|
||||
"rfapi query handling\n"
|
||||
"import BI atachment\n"
|
||||
"import delete remote routes\n")
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* no debug bgp vnc all
|
||||
***********************************************************************/
|
||||
|
||||
DEFUN (no_debug_bgp_vnc_all,
|
||||
no_debug_bgp_vnc_all_cmd,
|
||||
"no debug all bgp vnc",
|
||||
NO_STR
|
||||
DEBUG_STR
|
||||
"Disable all VNC debugging\n"
|
||||
BGP_STR
|
||||
VNC_STR)
|
||||
{
|
||||
term_vnc_debug = 0;
|
||||
vty_out (vty, "All possible VNC debugging has been turned off%s", VTY_NEWLINE);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
ALIAS (no_debug_bgp_vnc_all,
|
||||
undebug_bgp_vnc_all_cmd,
|
||||
"undebug all bgp vnc",
|
||||
UNDEBUG_STR
|
||||
"Disable all VNC debugging\n"
|
||||
BGP_STR
|
||||
VNC_STR)
|
||||
|
||||
/***********************************************************************
|
||||
* show/save
|
||||
***********************************************************************/
|
||||
|
||||
DEFUN (show_debugging_bgp_vnc,
|
||||
show_debugging_bgp_vnc_cmd,
|
||||
"show debugging bgp vnc",
|
||||
SHOW_STR
|
||||
DEBUG_STR
|
||||
BGP_STR
|
||||
VNC_STR)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
vty_out (vty, "BGP VNC debugging status:%s", VTY_NEWLINE);
|
||||
|
||||
for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i)
|
||||
{
|
||||
if (term_vnc_debug & vncdebug[i].bit)
|
||||
{
|
||||
vty_out (vty, " BGP VNC %s debugging is on%s",
|
||||
vncdebug[i].name, VTY_NEWLINE);
|
||||
}
|
||||
}
|
||||
vty_out (vty, "%s", VTY_NEWLINE);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
bgp_vnc_config_write_debug (struct vty *vty)
|
||||
{
|
||||
int write = 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i)
|
||||
{
|
||||
if (conf_vnc_debug & vncdebug[i].bit)
|
||||
{
|
||||
vty_out (vty, "debug bgp vnc %s%s", vncdebug[i].name, VTY_NEWLINE);
|
||||
write++;
|
||||
}
|
||||
}
|
||||
return write;
|
||||
}
|
||||
|
||||
static struct cmd_node debug_node =
|
||||
{
|
||||
DEBUG_VNC_NODE,
|
||||
"",
|
||||
1
|
||||
};
|
||||
|
||||
void
|
||||
vnc_debug_init (void)
|
||||
{
|
||||
install_node (&debug_node, bgp_vnc_config_write_debug);
|
||||
install_element (ENABLE_NODE, &show_debugging_bgp_vnc_cmd);
|
||||
|
||||
install_element (ENABLE_NODE, &debug_bgp_vnc_cmd);
|
||||
install_element (CONFIG_NODE, &debug_bgp_vnc_cmd);
|
||||
install_element (ENABLE_NODE, &no_debug_bgp_vnc_cmd);
|
||||
install_element (ENABLE_NODE, &undebug_bgp_vnc_cmd);
|
||||
|
||||
install_element (ENABLE_NODE, &no_debug_bgp_vnc_all_cmd);
|
||||
install_element (ENABLE_NODE, &undebug_bgp_vnc_all_cmd);
|
||||
}
|
49
bgpd/rfapi/vnc_debug.h
Normal file
49
bgpd/rfapi/vnc_debug.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_BGP_VNC_DEBUG_H
|
||||
#define _QUAGGA_BGP_VNC_DEBUG_H
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
|
||||
/*
|
||||
* debug state storage
|
||||
*/
|
||||
extern unsigned long conf_vnc_debug;
|
||||
extern unsigned long term_vnc_debug;
|
||||
|
||||
/*
|
||||
* debug flag bits
|
||||
*/
|
||||
#define VNC_DEBUG_RFAPI_QUERY 0x00000001
|
||||
#define VNC_DEBUG_IMPORT_BI_ATTACH 0x00000002
|
||||
#define VNC_DEBUG_IMPORT_DEL_REMOTE 0x00000004
|
||||
#define VNC_DEBUG_EXPORT_BGP_GETCE 0x00000008
|
||||
#define VNC_DEBUG_EXPORT_BGP_DIRECT_ADD 0x00000010
|
||||
#define VNC_DEBUG_IMPORT_BGP_ADD_ROUTE 0x00000020
|
||||
|
||||
#define VNC_DEBUG(bit) (term_vnc_debug & (VNC_DEBUG_ ## bit))
|
||||
|
||||
extern void
|
||||
vnc_debug_init (void);
|
||||
|
||||
#endif /* ENABLE_BGP_VNC */
|
||||
|
||||
#endif /* _QUAGGA_BGP_VNC_DEBUG_H */
|
2177
bgpd/rfapi/vnc_export_bgp.c
Normal file
2177
bgpd/rfapi/vnc_export_bgp.c
Normal file
File diff suppressed because it is too large
Load Diff
42
bgpd/rfapi/vnc_export_bgp.h
Normal file
42
bgpd/rfapi/vnc_export_bgp.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_RFAPI_VNC_EXPORT_BGP_H_
|
||||
#define _QUAGGA_RFAPI_VNC_EXPORT_BGP_H_
|
||||
|
||||
#include "zebra.h"
|
||||
#include "prefix.h"
|
||||
|
||||
#include "bgpd.h"
|
||||
#include "bgp_route.h"
|
||||
|
||||
|
||||
extern void vnc_direct_bgp_rh_reexport (struct bgp *bgp, afi_t afi);
|
||||
|
||||
extern void vnc_export_bgp_prechange (struct bgp *bgp);
|
||||
|
||||
extern void vnc_export_bgp_postchange (struct bgp *bgp);
|
||||
|
||||
extern void vnc_export_bgp_enable (struct bgp *bgp, afi_t afi);
|
||||
|
||||
extern void vnc_export_bgp_disable (struct bgp *bgp, afi_t afi);
|
||||
|
||||
#endif /* _QUAGGA_RFAPI_VNC_EXPORT_BGP_H_ */
|
95
bgpd/rfapi/vnc_export_bgp_p.h
Normal file
95
bgpd/rfapi/vnc_export_bgp_p.h
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_RFAPI_VNC_EXPORT_BGP_P_H_
|
||||
#define _QUAGGA_RFAPI_VNC_EXPORT_BGP_P_H_
|
||||
|
||||
#include "zebra.h"
|
||||
#include "prefix.h"
|
||||
|
||||
#include "bgpd.h"
|
||||
#include "bgp_route.h"
|
||||
|
||||
#include "rfapi_private.h"
|
||||
|
||||
extern void
|
||||
vnc_direct_bgp_add_route_ce (
|
||||
struct bgp *bgp,
|
||||
struct route_node *rn,
|
||||
struct bgp_info *bi);
|
||||
|
||||
extern void
|
||||
vnc_direct_bgp_del_route_ce (
|
||||
struct bgp *bgp,
|
||||
struct route_node *rn,
|
||||
struct bgp_info *bi);
|
||||
|
||||
extern void
|
||||
vnc_direct_bgp_add_prefix (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_import_table *import_table,
|
||||
struct route_node *rn);
|
||||
|
||||
extern void
|
||||
vnc_direct_bgp_del_prefix (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_import_table *import_table,
|
||||
struct route_node *rn);
|
||||
|
||||
extern void
|
||||
vnc_direct_bgp_add_nve (struct bgp *bgp, struct rfapi_descriptor *rfd);
|
||||
|
||||
extern void
|
||||
vnc_direct_bgp_del_nve (struct bgp *bgp, struct rfapi_descriptor *rfd);
|
||||
|
||||
extern void
|
||||
vnc_direct_bgp_add_group (struct bgp *bgp, struct rfapi_nve_group_cfg *rfg);
|
||||
|
||||
extern void
|
||||
vnc_direct_bgp_del_group (struct bgp *bgp, struct rfapi_nve_group_cfg *rfg);
|
||||
|
||||
extern void
|
||||
vnc_direct_bgp_reexport_group_afi (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_nve_group_cfg *rfg,
|
||||
afi_t afi);
|
||||
|
||||
|
||||
extern void
|
||||
vnc_direct_bgp_rh_add_route (
|
||||
struct bgp *bgp,
|
||||
afi_t afi,
|
||||
struct prefix *prefix,
|
||||
struct peer *peer,
|
||||
struct attr *attr);
|
||||
|
||||
|
||||
extern void
|
||||
vnc_direct_bgp_rh_del_route (
|
||||
struct bgp *bgp,
|
||||
afi_t afi,
|
||||
struct prefix *prefix,
|
||||
struct peer *peer);
|
||||
|
||||
extern void
|
||||
vnc_direct_bgp_reexport (struct bgp *bgp, afi_t afi);
|
||||
|
||||
#endif /* _QUAGGA_RFAPI_VNC_EXPORT_BGP_P_H_ */
|
214
bgpd/rfapi/vnc_export_table.c
Normal file
214
bgpd/rfapi/vnc_export_table.c
Normal file
@ -0,0 +1,214 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "zebra.h"
|
||||
#include "prefix.h"
|
||||
#include "table.h"
|
||||
#include "memory.h"
|
||||
#include "vty.h"
|
||||
|
||||
#include "bgpd.h"
|
||||
#include "bgp_route.h"
|
||||
|
||||
#include "vnc_export_table.h"
|
||||
#include "rfapi_private.h"
|
||||
#include "rfapi_import.h"
|
||||
|
||||
struct route_node *
|
||||
vnc_etn_get (struct bgp *bgp, vnc_export_type_t type, struct prefix *p)
|
||||
{
|
||||
struct route_table *t = NULL;
|
||||
struct route_node *rn = NULL;
|
||||
afi_t afi;
|
||||
|
||||
if (!bgp || !bgp->rfapi)
|
||||
return NULL;
|
||||
|
||||
afi = family2afi (p->family);
|
||||
assert (afi == AFI_IP || afi == AFI_IP6);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case EXPORT_TYPE_BGP:
|
||||
if (!bgp->rfapi->rt_export_bgp[afi])
|
||||
bgp->rfapi->rt_export_bgp[afi] = route_table_init ();
|
||||
t = bgp->rfapi->rt_export_bgp[afi];
|
||||
break;
|
||||
|
||||
case EXPORT_TYPE_ZEBRA:
|
||||
if (!bgp->rfapi->rt_export_zebra[afi])
|
||||
bgp->rfapi->rt_export_zebra[afi] = route_table_init ();
|
||||
t = bgp->rfapi->rt_export_zebra[afi];
|
||||
break;
|
||||
}
|
||||
|
||||
if (t)
|
||||
rn = route_node_get (t, p);
|
||||
return rn;
|
||||
}
|
||||
|
||||
struct route_node *
|
||||
vnc_etn_lookup (struct bgp *bgp, vnc_export_type_t type, struct prefix *p)
|
||||
{
|
||||
struct route_table *t = NULL;
|
||||
struct route_node *rn = NULL;
|
||||
afi_t afi;
|
||||
|
||||
if (!bgp || !bgp->rfapi)
|
||||
return NULL;
|
||||
|
||||
afi = family2afi (p->family);
|
||||
assert (afi == AFI_IP || afi == AFI_IP6);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case EXPORT_TYPE_BGP:
|
||||
if (!bgp->rfapi->rt_export_bgp[afi])
|
||||
bgp->rfapi->rt_export_bgp[afi] = route_table_init ();
|
||||
t = bgp->rfapi->rt_export_bgp[afi];
|
||||
break;
|
||||
|
||||
case EXPORT_TYPE_ZEBRA:
|
||||
if (!bgp->rfapi->rt_export_zebra[afi])
|
||||
bgp->rfapi->rt_export_zebra[afi] = route_table_init ();
|
||||
t = bgp->rfapi->rt_export_zebra[afi];
|
||||
break;
|
||||
}
|
||||
|
||||
if (t)
|
||||
rn = route_node_lookup (t, p);
|
||||
return rn;
|
||||
}
|
||||
|
||||
struct vnc_export_info *
|
||||
vnc_eti_get (
|
||||
struct bgp *bgp,
|
||||
vnc_export_type_t etype,
|
||||
struct prefix *p,
|
||||
struct peer *peer,
|
||||
uint8_t type,
|
||||
uint8_t subtype)
|
||||
{
|
||||
struct route_node *etn;
|
||||
struct vnc_export_info *eti;
|
||||
|
||||
etn = vnc_etn_get (bgp, etype, p);
|
||||
assert (etn);
|
||||
|
||||
for (eti = etn->info; eti; eti = eti->next)
|
||||
{
|
||||
if (peer == eti->peer && type == eti->type && subtype == eti->subtype)
|
||||
{
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (eti)
|
||||
{
|
||||
route_unlock_node (etn);
|
||||
}
|
||||
else
|
||||
{
|
||||
eti = XCALLOC (MTYPE_RFAPI_ETI, sizeof (struct vnc_export_info));
|
||||
assert (eti);
|
||||
eti->node = etn;
|
||||
eti->peer = peer;
|
||||
peer_lock (peer);
|
||||
eti->type = type;
|
||||
eti->subtype = subtype;
|
||||
eti->next = etn->info;
|
||||
etn->info = eti;
|
||||
}
|
||||
|
||||
return eti;
|
||||
}
|
||||
|
||||
void
|
||||
vnc_eti_delete (struct vnc_export_info *goner)
|
||||
{
|
||||
struct route_node *etn;
|
||||
struct vnc_export_info *eti;
|
||||
struct vnc_export_info *eti_prev = NULL;
|
||||
|
||||
etn = goner->node;
|
||||
|
||||
for (eti = etn->info; eti; eti_prev = eti, eti = eti->next)
|
||||
{
|
||||
if (eti == goner)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!eti)
|
||||
{
|
||||
zlog_debug ("%s: COULDN'T FIND ETI", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (eti_prev)
|
||||
{
|
||||
eti_prev->next = goner->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
etn->info = goner->next;
|
||||
}
|
||||
|
||||
peer_unlock (eti->peer);
|
||||
goner->node = NULL;
|
||||
XFREE (MTYPE_RFAPI_ETI, goner);
|
||||
|
||||
route_unlock_node (etn);
|
||||
}
|
||||
|
||||
struct vnc_export_info *
|
||||
vnc_eti_checktimer (
|
||||
struct bgp *bgp,
|
||||
vnc_export_type_t etype,
|
||||
struct prefix *p,
|
||||
struct peer *peer,
|
||||
uint8_t type,
|
||||
uint8_t subtype)
|
||||
{
|
||||
struct route_node *etn;
|
||||
struct vnc_export_info *eti;
|
||||
|
||||
etn = vnc_etn_lookup (bgp, etype, p);
|
||||
if (!etn)
|
||||
return NULL;
|
||||
|
||||
for (eti = etn->info; eti; eti = eti->next)
|
||||
{
|
||||
if (peer == eti->peer && type == eti->type && subtype == eti->subtype)
|
||||
{
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
route_unlock_node (etn);
|
||||
|
||||
if (eti && eti->timer)
|
||||
return eti;
|
||||
|
||||
return NULL;
|
||||
}
|
85
bgpd/rfapi/vnc_export_table.h
Normal file
85
bgpd/rfapi/vnc_export_table.h
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_VNC_VNC_EXPORT_TABLE_H_
|
||||
#define _QUAGGA_VNC_VNC_EXPORT_TABLE_H_
|
||||
|
||||
#include "table.h"
|
||||
#include "thread.h"
|
||||
#include "vty.h"
|
||||
|
||||
#include "bgpd.h"
|
||||
|
||||
#define VNC_EXPORT_TYPE_BGP 1
|
||||
#define VNC_EXPORT_TYPE_ZEBRA 2
|
||||
|
||||
typedef enum vnc_export_type
|
||||
{
|
||||
EXPORT_TYPE_BGP,
|
||||
EXPORT_TYPE_ZEBRA
|
||||
} vnc_export_type_t;
|
||||
|
||||
struct vnc_export_info
|
||||
{
|
||||
struct vnc_export_info *next;
|
||||
struct route_node *node;
|
||||
struct peer *peer;
|
||||
u_char type;
|
||||
u_char subtype;
|
||||
uint32_t lifetime;
|
||||
struct thread *timer;
|
||||
};
|
||||
|
||||
extern struct route_node *
|
||||
vnc_etn_get (
|
||||
struct bgp *bgp,
|
||||
vnc_export_type_t type,
|
||||
struct prefix *p);
|
||||
|
||||
extern struct route_node *
|
||||
vnc_etn_lookup (
|
||||
struct bgp *bgp,
|
||||
vnc_export_type_t type,
|
||||
struct prefix *p);
|
||||
|
||||
extern struct vnc_export_info *
|
||||
vnc_eti_get (
|
||||
struct bgp *bgp,
|
||||
vnc_export_type_t etype,
|
||||
struct prefix *p,
|
||||
struct peer *peer,
|
||||
uint8_t type,
|
||||
uint8_t subtype);
|
||||
|
||||
extern void
|
||||
vnc_eti_delete (struct vnc_export_info *goner);
|
||||
|
||||
extern struct vnc_export_info *
|
||||
vnc_eti_checktimer (
|
||||
struct bgp *bgp,
|
||||
vnc_export_type_t etype,
|
||||
struct prefix *p,
|
||||
struct peer *peer,
|
||||
uint8_t type,
|
||||
uint8_t subtype);
|
||||
|
||||
|
||||
#endif /* _QUAGGA_VNC_VNC_EXPORT_TABLE_H_ */
|
3165
bgpd/rfapi/vnc_import_bgp.c
Normal file
3165
bgpd/rfapi/vnc_import_bgp.c
Normal file
File diff suppressed because it is too large
Load Diff
93
bgpd/rfapi/vnc_import_bgp.h
Normal file
93
bgpd/rfapi/vnc_import_bgp.h
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_RFAPI_VNC_IMPORT_BGP_H_
|
||||
#define _QUAGGA_RFAPI_VNC_IMPORT_BGP_H_
|
||||
|
||||
#include "zebra.h"
|
||||
#include "prefix.h"
|
||||
|
||||
#include "bgpd.h"
|
||||
#include "bgp_route.h"
|
||||
|
||||
#define VALID_INTERIOR_TYPE(type) \
|
||||
(((type) == ZEBRA_ROUTE_BGP) || ((type) == ZEBRA_ROUTE_BGP_DIRECT))
|
||||
|
||||
extern uint32_t
|
||||
calc_local_pref (struct attr *attr, struct peer *peer);
|
||||
|
||||
extern int
|
||||
vnc_prefix_cmp (void *pfx1, void *pfx2);
|
||||
|
||||
extern void
|
||||
vnc_import_bgp_add_route (
|
||||
struct bgp *bgp,
|
||||
struct prefix *prefix,
|
||||
struct bgp_info *info);
|
||||
|
||||
extern void
|
||||
vnc_import_bgp_del_route (
|
||||
struct bgp *bgp,
|
||||
struct prefix *prefix,
|
||||
struct bgp_info *info);
|
||||
|
||||
extern void
|
||||
vnc_import_bgp_redist_enable (struct bgp *bgp, afi_t afi);
|
||||
|
||||
extern void
|
||||
vnc_import_bgp_redist_disable (struct bgp *bgp, afi_t afi);
|
||||
|
||||
extern void
|
||||
vnc_import_bgp_exterior_redist_enable (struct bgp *bgp, afi_t afi);
|
||||
|
||||
extern void
|
||||
vnc_import_bgp_exterior_redist_disable (struct bgp *bgp, afi_t afi);
|
||||
|
||||
|
||||
extern void
|
||||
vnc_import_bgp_exterior_add_route (
|
||||
struct bgp *bgp, /* exterior instance, we hope */
|
||||
struct prefix *prefix,/* unicast prefix */
|
||||
struct bgp_info *info); /* unicast info */
|
||||
|
||||
extern void
|
||||
vnc_import_bgp_exterior_del_route (
|
||||
struct bgp *bgp,
|
||||
struct prefix *prefix,/* unicast prefix */
|
||||
struct bgp_info *info); /* unicast info */
|
||||
|
||||
extern void
|
||||
vnc_import_bgp_add_vnc_host_route_mode_resolve_nve (
|
||||
struct bgp *bgp,
|
||||
struct prefix_rd *prd, /* RD */
|
||||
struct bgp_table *table_rd, /* per-rd VPN route table */
|
||||
struct prefix *prefix, /* VPN prefix */
|
||||
struct bgp_info *bi); /* new VPN host route */
|
||||
|
||||
extern void
|
||||
vnc_import_bgp_del_vnc_host_route_mode_resolve_nve (
|
||||
struct bgp *bgp,
|
||||
struct prefix_rd *prd, /* RD */
|
||||
struct bgp_table *table_rd, /* per-rd VPN route table */
|
||||
struct prefix *prefix, /* VPN prefix */
|
||||
struct bgp_info *bi); /* old VPN host route */
|
||||
|
||||
#endif /* _QUAGGA_RFAPI_VNC_IMPORT_BGP_H_ */
|
51
bgpd/rfapi/vnc_import_bgp_p.h
Normal file
51
bgpd/rfapi/vnc_import_bgp_p.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_RFAPI_VNC_IMPORT_BGP_P_H_
|
||||
#define _QUAGGA_RFAPI_VNC_IMPORT_BGP_P_H_
|
||||
|
||||
#include "zebra.h"
|
||||
#include "prefix.h"
|
||||
|
||||
#include "bgpd.h"
|
||||
#include "bgp_route.h"
|
||||
|
||||
extern void
|
||||
vnc_import_bgp_exterior_add_route_interior (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_import_table *it,
|
||||
struct route_node *rn_interior, /* VPN IT node */
|
||||
struct bgp_info *bi_interior); /* VPN IT route */
|
||||
|
||||
extern void
|
||||
vnc_import_bgp_exterior_del_route_interior (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_import_table *it,
|
||||
struct route_node *rn_interior, /* VPN IT node */
|
||||
struct bgp_info *bi_interior); /* VPN IT route */
|
||||
|
||||
extern void
|
||||
vnc_import_bgp_exterior_redist_enable_it (
|
||||
struct bgp *bgp,
|
||||
afi_t afi,
|
||||
struct rfapi_import_table *it_only);
|
||||
|
||||
#endif /* _QUAGGA_RFAPI_VNC_IMPORT_BGP_P_H_ */
|
1121
bgpd/rfapi/vnc_zebra.c
Normal file
1121
bgpd/rfapi/vnc_zebra.c
Normal file
File diff suppressed because it is too large
Load Diff
67
bgpd/rfapi/vnc_zebra.h
Normal file
67
bgpd/rfapi/vnc_zebra.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* File: vnc_zebra.h
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_BGP_VNC_ZEBRA_H
|
||||
#define _QUAGGA_BGP_VNC_ZEBRA_H
|
||||
|
||||
#include "zebra.h"
|
||||
|
||||
extern void
|
||||
vnc_zebra_add_prefix (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_import_table *import_table,
|
||||
struct route_node *rn);
|
||||
|
||||
extern void
|
||||
vnc_zebra_del_prefix (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_import_table *import_table,
|
||||
struct route_node *rn);
|
||||
|
||||
extern void
|
||||
vnc_zebra_add_nve (struct bgp *bgp, struct rfapi_descriptor *rfd);
|
||||
|
||||
extern void
|
||||
vnc_zebra_del_nve (struct bgp *bgp, struct rfapi_descriptor *rfd);
|
||||
|
||||
extern void
|
||||
vnc_zebra_add_group (struct bgp *bgp, struct rfapi_nve_group_cfg *rfg);
|
||||
|
||||
extern void
|
||||
vnc_zebra_del_group (struct bgp *bgp, struct rfapi_nve_group_cfg *rfg);
|
||||
|
||||
extern void
|
||||
vnc_zebra_reexport_group_afi (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_nve_group_cfg *rfg,
|
||||
afi_t afi);
|
||||
|
||||
extern int
|
||||
vnc_redistribute_set (struct bgp *bgp, afi_t afi, int type);
|
||||
|
||||
extern int
|
||||
vnc_redistribute_unset (struct bgp *bgp, afi_t afi, int type);
|
||||
|
||||
#endif /* _QUAGGA_BGP_VNC_ZEBRA_H */
|
40
bgpd/rfp-example/librfp/Makefile.am
Normal file
40
bgpd/rfp-example/librfp/Makefile.am
Normal file
@ -0,0 +1,40 @@
|
||||
#
|
||||
# This file has been modified by LabN Consulting, L.L.C.
|
||||
#
|
||||
#
|
||||
## Process this file with automake to produce Makefile.in.
|
||||
|
||||
if ENABLE_BGP_VNC
|
||||
BGP_VNC_RFAPI_INC=-I$(top_srcdir)/bgpd/rfapi
|
||||
BGP_VNC_RFP_LIBDIR=.
|
||||
BGP_VNC_RFP_INCDIR=$(BGP_VNC_RFP_LIBDIR)
|
||||
BGP_VNC_RFP_LIB=librfp.a
|
||||
BGP_VNC_RFP_INC=-I$(BGP_VNC_RFP_INCDIR)
|
||||
|
||||
librfp_a_SOURCES = \
|
||||
rfp_example.c
|
||||
|
||||
librfp_a_INCLUDES = \
|
||||
rfp.h \
|
||||
rfp_internal.h
|
||||
|
||||
else
|
||||
BGP_VNC_RFAPI_INC=
|
||||
BGP_VNC_RFAPI_SRC=
|
||||
BGP_VNC_RFP_LIB=
|
||||
BGP_VNC_RFP_INC=
|
||||
endif
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib \
|
||||
-I$(top_builddir) -I$(top_builddir)/lib \
|
||||
$(BGP_VNC_RFAPI_INC) $(BGP_VNC_RFP_INC)
|
||||
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
|
||||
INSTALL_SDATA=@INSTALL@ -m 600
|
||||
|
||||
AM_CFLAGS = $(PICFLAGS)
|
||||
AM_LDFLAGS = $(PILDFLAGS)
|
||||
|
||||
noinst_LIBRARIES = $(BGP_VNC_RFP_LIB)
|
||||
|
||||
noinst_HEADERS = \
|
||||
$(librfp_a_INCLUDES)
|
31
bgpd/rfp-example/librfp/rfp.h
Normal file
31
bgpd/rfp-example/librfp/rfp.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2015-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Sample header file */
|
||||
#ifndef _RFP_H
|
||||
#define _RFP_H
|
||||
|
||||
#include "rfapi.h"
|
||||
extern int bgp_rfp_cfg_write (void *vty, void *bgp);
|
||||
/* TO BE REMOVED */
|
||||
void rfp_clear_vnc_nve_all (void);
|
||||
|
||||
#endif /* _RFP_H */
|
286
bgpd/rfp-example/librfp/rfp_example.c
Normal file
286
bgpd/rfp-example/librfp/rfp_example.c
Normal file
@ -0,0 +1,286 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2015-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/* stub rfp */
|
||||
#include "rfp_internal.h"
|
||||
#include "rfapi.h"
|
||||
#include "command.h"
|
||||
|
||||
struct rfp_instance_t
|
||||
{
|
||||
struct rfapi_rfp_cfg rfapi_config;
|
||||
struct rfapi_rfp_cb_methods rfapi_callbacks;
|
||||
struct thread_master *master;
|
||||
uint32_t config_var;
|
||||
};
|
||||
|
||||
struct rfp_instance_t global_rfi; /* dynamically allocate in full implementation */
|
||||
|
||||
/***********************************************************************
|
||||
* Sample VTY / internal function
|
||||
**********************************************************************/
|
||||
#define RFP_SHOW_STR "RFP information\n"
|
||||
DEFUN (rfp_example_config_value,
|
||||
rfp_example_config_value_cmd,
|
||||
"rfp example-config-value VALUE",
|
||||
RFP_SHOW_STR "Example value to be configured\n")
|
||||
{
|
||||
uint32_t value = 0;
|
||||
struct rfp_instance_t *rfi = NULL;
|
||||
rfi = rfapi_get_rfp_start_val (vty->index); /* index=bgp for BGP_NODE */
|
||||
assert (rfi != NULL);
|
||||
|
||||
VTY_GET_INTEGER ("Example value", value, argv[0]);
|
||||
if (rfi)
|
||||
rfi->config_var = value;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
rfp_vty_install ()
|
||||
{
|
||||
static int installed = 0;
|
||||
if (installed) /* do this only once */
|
||||
return;
|
||||
installed = 1;
|
||||
/* example of new cli command */
|
||||
install_element (BGP_NODE, &rfp_example_config_value_cmd);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RFAPI Callbacks
|
||||
**********************************************************************/
|
||||
|
||||
/*------------------------------------------
|
||||
* rfp_response_cb
|
||||
*
|
||||
* Callbacks of this type are used to provide asynchronous
|
||||
* route updates from RFAPI to the RFP client.
|
||||
*
|
||||
* response_cb
|
||||
* called to notify the rfp client that a next hop list
|
||||
* that has previously been provided in response to an
|
||||
* rfapi_query call has been updated. Deleted routes are indicated
|
||||
* with lifetime==RFAPI_REMOVE_RESPONSE_LIFETIME.
|
||||
*
|
||||
* By default, the routes an NVE receives via this callback include
|
||||
* its own routes (that it has registered). However, these may be
|
||||
* filtered out if the global BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP
|
||||
* flag is set.
|
||||
*
|
||||
* input:
|
||||
* next_hops a list of possible next hops.
|
||||
* This is a linked list allocated within the
|
||||
* rfapi. The response_cb callback function is responsible
|
||||
* for freeing this memory via rfapi_free_next_hop_list()
|
||||
* in order to avoid memory leaks.
|
||||
*
|
||||
* userdata value (cookie) originally specified in call to
|
||||
* rfapi_open()
|
||||
*
|
||||
*------------------------------------------*/
|
||||
static void
|
||||
rfp_response_cb (struct rfapi_next_hop_entry *next_hops, void *userdata)
|
||||
{
|
||||
/*
|
||||
* Identify NVE based on userdata, which is a value passed
|
||||
* to RFAPI in the rfapi_open call
|
||||
*/
|
||||
|
||||
/* process list of next_hops */
|
||||
|
||||
/* free next hops */
|
||||
rfapi_free_next_hop_list (next_hops);
|
||||
return;
|
||||
}
|
||||
|
||||
/*------------------------------------------
|
||||
* rfp_local_cb
|
||||
*
|
||||
* Callbacks of this type are used to provide asynchronous
|
||||
* route updates from RFAPI to the RFP client.
|
||||
*
|
||||
* local_cb
|
||||
* called to notify the rfp client that a local route
|
||||
* has been added or deleted. Deleted routes are indicated
|
||||
* with lifetime==RFAPI_REMOVE_RESPONSE_LIFETIME.
|
||||
*
|
||||
* input:
|
||||
* next_hops a list of possible next hops.
|
||||
* This is a linked list allocated within the
|
||||
* rfapi. The local_cb callback function is responsible
|
||||
* for freeing this memory via rfapi_free_next_hop_list()
|
||||
* in order to avoid memory leaks.
|
||||
*
|
||||
* userdata value (cookie) originally specified in call to
|
||||
* rfapi_open()
|
||||
*
|
||||
*------------------------------------------*/
|
||||
static void
|
||||
rfp_local_cb (struct rfapi_next_hop_entry *next_hops, void *userdata)
|
||||
{
|
||||
/*
|
||||
* Identify NVE based on userdata, which is a value passed
|
||||
* to RFAPI in the rfapi_open call
|
||||
*/
|
||||
|
||||
/* process list of local next_hops */
|
||||
|
||||
/* free next hops */
|
||||
rfapi_free_next_hop_list (next_hops);
|
||||
return;
|
||||
}
|
||||
|
||||
/*------------------------------------------
|
||||
* rfp_close_cb
|
||||
*
|
||||
* Callbacks used to provide asynchronous
|
||||
* notification that an rfapi_handle was invalidated
|
||||
*
|
||||
* input:
|
||||
* pHandle Firmerly valid rfapi_handle returned to
|
||||
* client via rfapi_open().
|
||||
*
|
||||
* reason EIDRM handle administratively closed (clear nve ...)
|
||||
* ESTALE handle invalidated by configuration change
|
||||
*
|
||||
*------------------------------------------*/
|
||||
static void
|
||||
rfp_close_cb (rfapi_handle pHandle, int reason)
|
||||
{
|
||||
/* close / invalidate NVE with the pHandle returned by the rfapi_open call */
|
||||
return;
|
||||
}
|
||||
|
||||
/*------------------------------------------
|
||||
* rfp_cfg_write_cb
|
||||
*
|
||||
* This callback is used to generate output for any config parameters
|
||||
* that may supported by RFP via RFP defined vty commands at the bgp
|
||||
* level. See loglevel as an example.
|
||||
*
|
||||
* input:
|
||||
* vty -- quagga vty context
|
||||
* rfp_start_val -- value returned by rfp_start
|
||||
*
|
||||
* output:
|
||||
* to vty, rfp related configuration
|
||||
*
|
||||
* return value:
|
||||
* lines written
|
||||
--------------------------------------------*/
|
||||
static int
|
||||
rfp_cfg_write_cb (struct vty *vty, void *rfp_start_val)
|
||||
{
|
||||
struct rfp_instance_t *rfi = rfp_start_val;
|
||||
int write = 0;
|
||||
assert (rfp_start_val != NULL);
|
||||
if (rfi->config_var != 0)
|
||||
{
|
||||
vty_out (vty, " rfp example-config-value %u", rfi->config_var);
|
||||
vty_out (vty, "%s", VTY_NEWLINE);
|
||||
write++;
|
||||
}
|
||||
|
||||
return write;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RFAPI required functions
|
||||
**********************************************************************/
|
||||
|
||||
/*------------------------------------------
|
||||
* rfp_start
|
||||
*
|
||||
* This function will start the RFP code
|
||||
*
|
||||
* input:
|
||||
* master quagga thread_master to tie into bgpd threads
|
||||
*
|
||||
* output:
|
||||
* cfgp Pointer to rfapi_rfp_cfg (null = use defaults),
|
||||
* copied by caller, updated via rfp_set_configuration
|
||||
* cbmp Pointer to rfapi_rfp_cb_methods, may be null
|
||||
* copied by caller, updated via rfapi_rfp_set_cb_methods
|
||||
*
|
||||
* return value:
|
||||
* rfp_start_val rfp returned value passed on rfp_stop and rfp_cfg_write
|
||||
*
|
||||
--------------------------------------------*/
|
||||
void *
|
||||
rfp_start (struct thread_master *master,
|
||||
struct rfapi_rfp_cfg **cfgp, struct rfapi_rfp_cb_methods **cbmp)
|
||||
{
|
||||
memset (&global_rfi, 0, sizeof (struct rfp_instance_t));
|
||||
global_rfi.master = master; /* for BGPD threads */
|
||||
|
||||
/* initilize struct rfapi_rfp_cfg, see rfapi.h */
|
||||
global_rfi.rfapi_config.download_type = RFAPI_RFP_DOWNLOAD_FULL; /* default=partial */
|
||||
global_rfi.rfapi_config.ftd_advertisement_interval =
|
||||
RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL;
|
||||
global_rfi.rfapi_config.holddown_factor = 0; /* default: RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR */
|
||||
global_rfi.rfapi_config.use_updated_response = 1; /* 0=no */
|
||||
global_rfi.rfapi_config.use_removes = 1; /* 0=no */
|
||||
|
||||
|
||||
/* initilize structrfapi_rfp_cb_methods , see rfapi.h */
|
||||
global_rfi.rfapi_callbacks.cfg_cb = rfp_cfg_write_cb;
|
||||
/* no group config */
|
||||
global_rfi.rfapi_callbacks.response_cb = rfp_response_cb;
|
||||
global_rfi.rfapi_callbacks.local_cb = rfp_local_cb;
|
||||
global_rfi.rfapi_callbacks.close_cb = rfp_close_cb;
|
||||
|
||||
if (cfgp != NULL)
|
||||
*cfgp = &global_rfi.rfapi_config;
|
||||
if (cbmp != NULL)
|
||||
*cbmp = &global_rfi.rfapi_callbacks;
|
||||
|
||||
rfp_vty_install ();
|
||||
|
||||
return &global_rfi;
|
||||
}
|
||||
|
||||
/*------------------------------------------
|
||||
* rfp_stop
|
||||
*
|
||||
* This function is called on shutdown to trigger RFP cleanup
|
||||
*
|
||||
* input:
|
||||
* none
|
||||
*
|
||||
* output:
|
||||
* none
|
||||
*
|
||||
* return value:
|
||||
* rfp_start_val
|
||||
--------------------------------------------*/
|
||||
void
|
||||
rfp_stop (void *rfp_start_val)
|
||||
{
|
||||
assert (rfp_start_val != NULL);
|
||||
}
|
||||
|
||||
/* TO BE REMOVED */
|
||||
void
|
||||
rfp_clear_vnc_nve_all (void)
|
||||
{
|
||||
return;
|
||||
}
|
29
bgpd/rfp-example/librfp/rfp_internal.h
Normal file
29
bgpd/rfp-example/librfp/rfp_internal.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2015-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Sample header file */
|
||||
#ifndef _RFP_INTERNAL_H
|
||||
#define _RFP_INTERNAL_H
|
||||
#include <zebra.h>
|
||||
#include "rfp.h"
|
||||
#include "rfapi.h"
|
||||
|
||||
#endif /* _RFP_INTERNAL_H */
|
52
bgpd/rfp-example/rfptest/Makefile.am
Normal file
52
bgpd/rfp-example/rfptest/Makefile.am
Normal file
@ -0,0 +1,52 @@
|
||||
#
|
||||
# This file has been modified by LabN Consulting, L.L.C.
|
||||
#
|
||||
#
|
||||
## Process this file with automake to produce Makefile.in.
|
||||
|
||||
if ENABLE_BGP_VNC
|
||||
BGP_VNC_RFAPI_INC=-I$(top_srcdir)/bgpd/rfapi
|
||||
BGP_VNC_RFP_LIBDIR=../librfp
|
||||
BGP_VNC_RFP_INCDIR=$(BGP_VNC_RFP_LIBDIR)
|
||||
BGP_VNC_RFP_LIB=$(BGP_VNC_RFP_LIBDIR)/librfp.a
|
||||
BGP_VNC_RFP_INC=-I$(BGP_VNC_RFP_INCDIR)
|
||||
|
||||
rfptest_SOURCES = \
|
||||
rfptest.c
|
||||
|
||||
rfptest_INCLUDES = \
|
||||
rfptest.h
|
||||
|
||||
|
||||
RFPTEST_BIN = rfptest
|
||||
|
||||
else
|
||||
BGP_VNC_RFAPI_INC=
|
||||
BGP_VNC_RFAPI_SRC=
|
||||
BGP_VNC_RFP_LIB=
|
||||
BGP_VNC_RFP_INC=
|
||||
RFPTEST_BIN=
|
||||
endif
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib \
|
||||
-I$(top_builddir) -I$(top_builddir)/lib \
|
||||
$(BGP_VNC_RFAPI_INC) $(BGP_VNC_RFP_INC)
|
||||
|
||||
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
|
||||
INSTALL_SDATA=@INSTALL@ -m 600
|
||||
|
||||
|
||||
AM_CFLAGS = $(PICFLAGS)
|
||||
AM_LDFLAGS = $(PILDFLAGS)
|
||||
|
||||
|
||||
noinst_HEADERS = \
|
||||
$(rfptest_INCLUDES)
|
||||
|
||||
noinst_LIBRARIES =
|
||||
sbin_PROGRAMS = $(RFPTEST_BIN)
|
||||
|
||||
examplesdir = $(exampledir)
|
||||
|
||||
rfptest_LDADD = $(top_builddir)/lib/libzebra.la $(BGP_VNC_RFP_LIB)
|
||||
dist_examples_DATA =
|
32
bgpd/rfp-example/rfptest/rfptest.c
Normal file
32
bgpd/rfp-example/rfptest/rfptest.c
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2015-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* dummy test program */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "rfptest.h"
|
||||
int
|
||||
main ()
|
||||
{
|
||||
printf ("Your test code goes here.\n");
|
||||
exit (1);
|
||||
}
|
26
bgpd/rfp-example/rfptest/rfptest.h
Normal file
26
bgpd/rfp-example/rfptest/rfptest.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2015-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Sample header file */
|
||||
#ifndef _RFPTEST_H
|
||||
#define _RFPTEST_H
|
||||
|
||||
#endif /* _RFPTEST_H */
|
38
configure.ac
38
configure.ac
@ -258,6 +258,10 @@ AC_ARG_ENABLE(pimd,
|
||||
AS_HELP_STRING([--disable-pimd], [do not build pimd]))
|
||||
AC_ARG_ENABLE(bgp-announce,
|
||||
AS_HELP_STRING([--disable-bgp-announce,], [turn off BGP route announcement]))
|
||||
AC_ARG_ENABLE(bgp-vnc,
|
||||
AS_HELP_STRING([--enable-bgp-vnc],[turn on BGP VNC support]))
|
||||
AC_ARG_WITH(rfp-path,
|
||||
AS_HELP_STRING([--with-rfp-path[=DIR]],[path to replaced stub RFP used with BGP VNC]))
|
||||
AC_ARG_ENABLE(snmp,
|
||||
AS_HELP_STRING([--enable-snmp=ARG], [enable SNMP support (smux or agentx)]))
|
||||
AC_ARG_WITH(libpam,
|
||||
@ -1362,8 +1366,32 @@ else
|
||||
AC_DEFINE(DISABLE_BGP_ANNOUNCE,0,Disable BGP installation to zebra)
|
||||
fi
|
||||
|
||||
if test "${with_rfp_path}" = "yes" || test x"${with_rfp_path}" = x""; then
|
||||
with_rfp_path="bgpd/rfp-example"
|
||||
fi
|
||||
if test "${with_rfp_path}" != "no"; then
|
||||
VNC_RFP_PATH="${with_rfp_path}"
|
||||
AC_SUBST(VNC_RFP_PATH)
|
||||
fi
|
||||
|
||||
if test "${enable_bgp_vnc}" = "yes";then
|
||||
AC_DEFINE(ENABLE_BGP_VNC,1,Enable BGP VNC support)
|
||||
RFPTEST="${with_rfp_path}/rfptest"
|
||||
LIBRFP="${with_rfp_path}/librfp"
|
||||
RFPINC="${with_rfp_path}/librfp"
|
||||
else
|
||||
RFPTEST=
|
||||
LIBRFP=
|
||||
RFPINC="bgpd/rfp-example/librfp"
|
||||
fi
|
||||
# set
|
||||
AM_CONDITIONAL([ENABLE_BGP_VNC], [test x${enable_bgp_vnc} = xyes])
|
||||
|
||||
AC_SUBST(DOC)
|
||||
AC_SUBST(ZEBRA)
|
||||
AC_SUBST(RFPTEST)
|
||||
AC_SUBST(LIBRFP)
|
||||
AC_SUBST(RFPINC)
|
||||
AC_SUBST(BGPD)
|
||||
AC_SUBST(RIPD)
|
||||
AC_SUBST(RIPNGD)
|
||||
@ -1744,9 +1772,19 @@ AC_CONFIG_FILES([Makefile lib/Makefile qpb/Makefile zebra/Makefile ripd/Makefile
|
||||
isisd/topology/Makefile
|
||||
pkgsrc/bgpd.sh pkgsrc/ospf6d.sh pkgsrc/ospfd.sh
|
||||
pkgsrc/ripd.sh pkgsrc/ripngd.sh pkgsrc/zebra.sh])
|
||||
|
||||
if test "${enable_bgp_vnc}" = "yes"; then
|
||||
if test "${with_rfp_path}" = "bgpd/rfp-example" ; then
|
||||
AC_CONFIG_FILES([bgpd/rfp-example/rfptest/Makefile bgpd/rfp-example/librfp/Makefile])
|
||||
else
|
||||
AC_CONFIG_FILES([${with_rfp_path}/rfptest/Makefile ${with_rfp_path}/librfp/Makefile])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_CONFIG_FILES([solaris/Makefile])
|
||||
|
||||
AC_CONFIG_FILES([vtysh/extract.pl],[chmod +x vtysh/extract.pl])
|
||||
|
||||
## Hack, but working solution to avoid rebuilding of quagga.info.
|
||||
## It's already in CVS until texinfo 4.7 is more common.
|
||||
AC_OUTPUT
|
||||
|
@ -19,13 +19,24 @@ PNGTOEPS = convert -antialias -contrast -despeckle
|
||||
PNGTOPDF = $(PNGTOEPS)
|
||||
EPSTOPDF = epstopdf
|
||||
|
||||
VNCFIGURES_PNG =
|
||||
VNCFIGURES_DIA = -vnc-mesh -vnc-quagga-route-reflector \
|
||||
-vnc-commercial-route-reflector -vnc-redundant-route-reflectors \
|
||||
-vnc-gw -vnc-gw-rr
|
||||
|
||||
# TODO: A target that creates an empty text file for each member of
|
||||
# VNCFIGURES_TXT
|
||||
VNCFIGURES_TXT = $(VNCFIGURES:%.png=%.txt)
|
||||
|
||||
# The figure sources
|
||||
figures_names_parts = -normal-processing -rs-processing \
|
||||
_topologies_full _topologies_rs
|
||||
_topologies_full _topologies_rs \
|
||||
$(VNCFIGURES_DIA)
|
||||
|
||||
figures_sources = $(figures_names_parts:%=fig%.dia)
|
||||
figures_png = $(figures_names_parts:%=fig%.png)
|
||||
figures_pdf = $(figures_names_parts:%=fig%.pdf)
|
||||
figures_eps = $(figures_names_parts:%=fig%.eps)
|
||||
figures_png = $(figures_names_parts:%=fig%.png) $(VNCFIGURES_PNG)
|
||||
figures_pdf = $(figures_names_parts:%=fig%.pdf) $(VNCFIGURES_PNG:%.png=%.pdf)
|
||||
figures_eps = $(figures_names_parts:%=fig%.eps) $(VNCFIGURES_PNG:%.png=%.eps)
|
||||
figures_txt = $(figures_names_parts:%=fig%.txt)
|
||||
|
||||
# rather twisted logic because we have to build PDFs of the EPS figures for
|
||||
@ -47,6 +58,7 @@ quagga.pdf: $(info_TEXINFOS) $(figures_pdf) $(quagga_TEXINFOS)
|
||||
$(TEXI2PDF) -o "$@" $< || true
|
||||
|
||||
quagga_TEXINFOS = appendix.texi basic.texi bgpd.texi isisd.texi filter.texi \
|
||||
vnc.texi \
|
||||
install.texi ipv6.texi kernel.texi main.texi ospf6d.texi ospfd.texi \
|
||||
overview.texi protocol.texi ripd.texi ripngd.texi routemap.texi \
|
||||
snmp.texi vtysh.texi routeserver.texi defines.texi $(figures_png) \
|
||||
@ -120,3 +132,11 @@ EXTRA_DIST = BGP-TypeCode draft-zebra-00.ms draft-zebra-00.txt \
|
||||
|
||||
draft-zebra-00.txt: draft-zebra-00.ms
|
||||
groff -T ascii -ms $< > $@
|
||||
|
||||
# Ensure that all of the figures are copied into the html directory
|
||||
html-local: $(HTMLS)
|
||||
if test -d $(HTMLS) ; then \
|
||||
cp -p $(figures_png) $(HTMLS) ; \
|
||||
else \
|
||||
echo "$(HTMLS) is not a directory. Make it so, the rerun make."; \
|
||||
fi
|
||||
|
@ -581,6 +581,10 @@ Redistribute RIP route to BGP process.
|
||||
Redistribute OSPF route to BGP process.
|
||||
@end deffn
|
||||
|
||||
@deffn {BGP} {redistribute vpn} {}
|
||||
Redistribute VNC routes to BGP process.
|
||||
@end deffn
|
||||
|
||||
@deffn {BGP} {update-delay @var{max-delay}} {}
|
||||
@deffnx {BGP} {update-delay @var{max-delay} @var{establish-wait}} {}
|
||||
This feature is used to enable read-only mode on BGP process restart or when
|
||||
|
794
doc/fig-vnc-commercial-route-reflector.dia
Normal file
794
doc/fig-vnc-commercial-route-reflector.dia
Normal file
@ -0,0 +1,794 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<dia:diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">
|
||||
<dia:diagramdata>
|
||||
<dia:attribute name="background">
|
||||
<dia:color val="#ffffff"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pagebreak">
|
||||
<dia:color val="#000099"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="paper">
|
||||
<dia:composite type="paper">
|
||||
<dia:attribute name="name">
|
||||
<dia:string>#Letter#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="tmargin">
|
||||
<dia:real val="2.5399999618530273"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="bmargin">
|
||||
<dia:real val="2.5399999618530273"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="lmargin">
|
||||
<dia:real val="2.5399999618530273"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="rmargin">
|
||||
<dia:real val="2.5399999618530273"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="is_portrait">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="scaling">
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="fitto">
|
||||
<dia:boolean val="false"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="grid">
|
||||
<dia:composite type="grid">
|
||||
<dia:attribute name="width_x">
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="width_y">
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="visible_x">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="visible_y">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:composite type="color"/>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#d8e5e5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="guides">
|
||||
<dia:composite type="guides">
|
||||
<dia:attribute name="hguides"/>
|
||||
<dia:attribute name="vguides"/>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
</dia:diagramdata>
|
||||
<dia:layer name="Background" visible="true" active="true">
|
||||
<dia:object type="Standard - Box" version="0" id="O0">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,39.145"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="57.1801,39.095;64.0901,42.445"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="57.2301,39.145"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O1">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,34.2475"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="57.1801,34.1975;64.0901,37.5475"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="57.2301,34.2475"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O2">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,29.35"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="57.1801,29.3;64.0901,32.65"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="57.2301,29.35"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O3">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="2.1126,39.295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.0626,39.245;8.9726,42.595"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="2.1126,39.295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O4">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="2.1126,34.3975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.0626,34.3475;8.9726,37.6975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="2.1126,34.3975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O5">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="2.1126,29.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.0626,29.45;8.9726,32.8"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="2.1126,29.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O6">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="22.5347,32.178"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="22.4642,23.359;30.091,32.2485"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="22.5347,32.178"/>
|
||||
<dia:point val="30.0205,23.4295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O7">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="43.1205,32.4705"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="36.8099,23.3599;43.1901,32.5401"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="43.1205,32.4705"/>
|
||||
<dia:point val="36.8795,23.4295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O8">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="16.5501,5.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="16.5501,4.905;16.5501,5.6525"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>##</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="16.5501,5.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="0"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O9">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="5.5176,31.125"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="3.29385,30.5113;7.76004,32.1149"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 4
|
||||
VN 172.16.4.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="5.5176,31.125"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O5" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O10">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="5.5176,36.0225"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.88385,35.4088;8.17004,37.0124"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 5
|
||||
VN 172.16.130.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="5.5176,36.0225"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O4" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O11">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="5.5176,40.92"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.8826,40.3063;8.17129,41.9099"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 6
|
||||
VN 172.16.132.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="5.5176,40.92"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O3" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O12">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="60.6351,30.975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="58.4101,30.3613;62.8788,31.9649"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 7
|
||||
VN 172.16.6.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="60.6351,30.975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O2" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O13">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="60.6351,35.8725"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="58.4101,35.2588;62.8788,36.8624"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 8
|
||||
VN 172.16.8.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="60.6351,35.8725"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O1" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O14">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="60.6351,40.77"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="58.0026,40.1563;63.2863,41.7599"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 9
|
||||
VN 172.16.134.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="60.6351,40.77"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O0" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O15">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="8.9226,31.125"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="8.86406,31.0665;15.979,32.529"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="8.9226,31.125"/>
|
||||
<dia:point val="15.9205,32.4705"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O5" connection="4"/>
|
||||
<dia:connection handle="1" to="O24" connection="0"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O16">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="8.9226,36.0225"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="8.87151,35.8489;14.5511,36.0736"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="8.9226,36.0225"/>
|
||||
<dia:point val="14.5,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O4" connection="4"/>
|
||||
<dia:connection handle="1" to="O24" connection="3"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O17">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="8.9226,40.92"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="8.86276,39.2697;15.9803,40.9798"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="8.9226,40.92"/>
|
||||
<dia:point val="15.9205,39.3295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O3" connection="4"/>
|
||||
<dia:connection handle="1" to="O24" connection="5"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O18">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,30.975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="49.9204,30.9159;57.2892,32.5296"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="57.2301,30.975"/>
|
||||
<dia:point val="49.9795,32.4705"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O2" connection="3"/>
|
||||
<dia:connection handle="1" to="O22" connection="2"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O19">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,35.8725"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="51.3498,35.8223;57.2803,35.9502"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="57.2301,35.8725"/>
|
||||
<dia:point val="51.4,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O1" connection="3"/>
|
||||
<dia:connection handle="1" to="O22" connection="4"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O20">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,40.77"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="50.9399,37.8657;57.2963,40.8362"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="57.2301,40.77"/>
|
||||
<dia:point val="51.0061,37.9319"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O0" connection="3"/>
|
||||
<dia:connection handle="1" to="O22" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O21">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="34.8,20.45"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="34.8,19.855;34.8,20.6025"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>##</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="34.8,20.45"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="0"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:group>
|
||||
<dia:object type="Standard - Ellipse" version="0" id="O22">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="41.7,31.05"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="41.65,31;51.45,40.8"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="41.7,31.05"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="aspect">
|
||||
<dia:enum val="2"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O23">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="46.55,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="44.2012,35.305;48.8987,36.8525"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVA 3
|
||||
192.168.1.102#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="46.55,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O22" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
</dia:group>
|
||||
<dia:group>
|
||||
<dia:object type="Standard - Ellipse" version="0" id="O24">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="14.5,31.05"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="14.45,31;24.25,40.8"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="14.5,31.05"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="9.7000007629394531"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="9.7000007629394531"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="aspect">
|
||||
<dia:enum val="2"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O25">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="19.35,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="17.0013,35.305;21.6988,36.8525"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVA 2
|
||||
192.168.1.101#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="19.35,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O24" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
</dia:group>
|
||||
<dia:group>
|
||||
<dia:object type="Standard - Ellipse" version="0" id="O26">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="28.6,15.15"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="28.55,15.1;38.35,24.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="28.6,15.15"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="aspect">
|
||||
<dia:enum val="2"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O27">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="33.45,19.7"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="30.9863,19.105;35.9138,21.4525"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#Commercial Router
|
||||
Route Reflector
|
||||
192.168.1.104#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="33.45,19.7"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
</dia:group>
|
||||
</dia:layer>
|
||||
</dia:diagram>
|
BIN
doc/fig-vnc-commercial-route-reflector.png
Normal file
BIN
doc/fig-vnc-commercial-route-reflector.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 50 KiB |
0
doc/fig-vnc-commercial-route-reflector.txt
Normal file
0
doc/fig-vnc-commercial-route-reflector.txt
Normal file
1155
doc/fig-vnc-gw-rr.dia
Normal file
1155
doc/fig-vnc-gw-rr.dia
Normal file
File diff suppressed because it is too large
Load Diff
BIN
doc/fig-vnc-gw-rr.png
Normal file
BIN
doc/fig-vnc-gw-rr.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 78 KiB |
0
doc/fig-vnc-gw-rr.txt
Normal file
0
doc/fig-vnc-gw-rr.txt
Normal file
1058
doc/fig-vnc-gw.dia
Normal file
1058
doc/fig-vnc-gw.dia
Normal file
File diff suppressed because it is too large
Load Diff
BIN
doc/fig-vnc-gw.png
Normal file
BIN
doc/fig-vnc-gw.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 66 KiB |
0
doc/fig-vnc-gw.txt
Normal file
0
doc/fig-vnc-gw.txt
Normal file
1071
doc/fig-vnc-mesh.dia
Normal file
1071
doc/fig-vnc-mesh.dia
Normal file
File diff suppressed because it is too large
Load Diff
BIN
doc/fig-vnc-mesh.png
Normal file
BIN
doc/fig-vnc-mesh.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 60 KiB |
0
doc/fig-vnc-mesh.txt
Normal file
0
doc/fig-vnc-mesh.txt
Normal file
763
doc/fig-vnc-quagga-route-reflector.dia
Normal file
763
doc/fig-vnc-quagga-route-reflector.dia
Normal file
@ -0,0 +1,763 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<dia:diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">
|
||||
<dia:diagramdata>
|
||||
<dia:attribute name="background">
|
||||
<dia:color val="#ffffff"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pagebreak">
|
||||
<dia:color val="#000099"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="paper">
|
||||
<dia:composite type="paper">
|
||||
<dia:attribute name="name">
|
||||
<dia:string>#Letter#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="tmargin">
|
||||
<dia:real val="2.5399999618530273"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="bmargin">
|
||||
<dia:real val="2.5399999618530273"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="lmargin">
|
||||
<dia:real val="2.5399999618530273"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="rmargin">
|
||||
<dia:real val="2.5399999618530273"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="is_portrait">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="scaling">
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="fitto">
|
||||
<dia:boolean val="false"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="grid">
|
||||
<dia:composite type="grid">
|
||||
<dia:attribute name="width_x">
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="width_y">
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="visible_x">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="visible_y">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:composite type="color"/>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#d8e5e5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="guides">
|
||||
<dia:composite type="guides">
|
||||
<dia:attribute name="hguides"/>
|
||||
<dia:attribute name="vguides"/>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
</dia:diagramdata>
|
||||
<dia:layer name="Background" visible="true" active="true">
|
||||
<dia:object type="Standard - Box" version="0" id="O0">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,39.145"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="57.1801,39.095;64.0901,42.445"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="57.2301,39.145"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O1">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,34.2475"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="57.1801,34.1975;64.0901,37.5475"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="57.2301,34.2475"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O2">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,29.35"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="57.1801,29.3;64.0901,32.65"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="57.2301,29.35"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O3">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="2.1126,39.295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.0626,39.245;8.9726,42.595"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="2.1126,39.295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O4">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="2.1126,34.3975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.0626,34.3475;8.9726,37.6975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="2.1126,34.3975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O5">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="2.1126,29.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.0626,29.45;8.9726,32.8"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="2.1126,29.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O6">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="22.5347,32.178"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="22.4642,23.359;30.091,32.2485"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="22.5347,32.178"/>
|
||||
<dia:point val="30.0205,23.4295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O7">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="43.1205,32.4705"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="36.8099,23.3599;43.1901,32.5401"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="43.1205,32.4705"/>
|
||||
<dia:point val="36.8795,23.4295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O8">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="16.5501,5.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="16.5501,4.905;16.5501,5.6525"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>##</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="16.5501,5.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="0"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O9">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="5.5176,31.125"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="3.29385,30.5113;7.76004,32.1149"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 4
|
||||
VN 172.16.4.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="5.5176,31.125"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O5" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O10">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="5.5176,36.0225"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.88385,35.4088;8.17004,37.0124"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 5
|
||||
VN 172.16.130.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="5.5176,36.0225"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O4" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O11">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="5.5176,40.92"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.8826,40.3063;8.17129,41.9099"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 6
|
||||
VN 172.16.132.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="5.5176,40.92"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O3" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O12">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="60.6351,30.975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="58.4101,30.3613;62.8788,31.9649"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 7
|
||||
VN 172.16.6.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="60.6351,30.975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O2" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O13">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="60.6351,35.8725"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="58.4101,35.2588;62.8788,36.8624"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 8
|
||||
VN 172.16.8.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="60.6351,35.8725"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O1" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O14">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="60.6351,40.77"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="58.0026,40.1563;63.2863,41.7599"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 9
|
||||
VN 172.16.134.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="60.6351,40.77"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O0" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O15">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="8.9226,31.125"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="8.86406,31.0665;15.979,32.529"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="8.9226,31.125"/>
|
||||
<dia:point val="15.9205,32.4705"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O5" connection="4"/>
|
||||
<dia:connection handle="1" to="O23" connection="0"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O16">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="8.9226,36.0225"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="8.87151,35.8489;14.5511,36.0736"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="8.9226,36.0225"/>
|
||||
<dia:point val="14.5,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O4" connection="4"/>
|
||||
<dia:connection handle="1" to="O23" connection="3"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O17">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="8.9226,40.92"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="8.86276,39.2697;15.9803,40.9798"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="8.9226,40.92"/>
|
||||
<dia:point val="15.9205,39.3295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O3" connection="4"/>
|
||||
<dia:connection handle="1" to="O23" connection="5"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O18">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,30.975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="49.9204,30.9159;57.2892,32.5296"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="57.2301,30.975"/>
|
||||
<dia:point val="49.9795,32.4705"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O2" connection="3"/>
|
||||
<dia:connection handle="1" to="O25" connection="2"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O19">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,35.8725"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="51.3498,35.8223;57.2803,35.9502"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="57.2301,35.8725"/>
|
||||
<dia:point val="51.4,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O1" connection="3"/>
|
||||
<dia:connection handle="1" to="O25" connection="4"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O20">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,40.77"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="50.9399,37.8657;57.2963,40.8362"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="57.2301,40.77"/>
|
||||
<dia:point val="51.0061,37.9319"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O0" connection="3"/>
|
||||
<dia:connection handle="1" to="O25" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:group>
|
||||
<dia:object type="Standard - Ellipse" version="0" id="O21">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="28.6,15.15"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="28.55,15.1;38.35,24.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="28.6,15.15"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="aspect">
|
||||
<dia:enum val="2"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O22">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="33.45,20"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="29.9225,19.405;36.9775,20.9525"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#BGP Route Reflector 1
|
||||
192.168.1.100#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="33.45,20"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O21" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
</dia:group>
|
||||
<dia:group>
|
||||
<dia:object type="Standard - Ellipse" version="0" id="O23">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="14.5,31.05"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="14.45,31;24.25,40.8"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="14.5,31.05"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="9.7000007629394531"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="9.7000007629394531"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="aspect">
|
||||
<dia:enum val="2"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O24">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="19.35,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="17.0013,35.305;21.6988,36.8525"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVA 2
|
||||
192.168.1.101#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="19.35,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O23" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
</dia:group>
|
||||
<dia:group>
|
||||
<dia:object type="Standard - Ellipse" version="0" id="O25">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="41.7,31.05"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="41.65,31;51.45,40.8"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="41.7,31.05"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="aspect">
|
||||
<dia:enum val="2"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O26">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="46.55,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="44.2012,35.305;48.8987,36.8525"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVA 3
|
||||
192.168.1.102#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="46.55,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O25" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
</dia:group>
|
||||
</dia:layer>
|
||||
</dia:diagram>
|
BIN
doc/fig-vnc-quagga-route-reflector.png
Normal file
BIN
doc/fig-vnc-quagga-route-reflector.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 49 KiB |
0
doc/fig-vnc-quagga-route-reflector.txt
Normal file
0
doc/fig-vnc-quagga-route-reflector.txt
Normal file
871
doc/fig-vnc-redundant-route-reflectors.dia
Normal file
871
doc/fig-vnc-redundant-route-reflectors.dia
Normal file
@ -0,0 +1,871 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<dia:diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">
|
||||
<dia:diagramdata>
|
||||
<dia:attribute name="background">
|
||||
<dia:color val="#ffffff"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pagebreak">
|
||||
<dia:color val="#000099"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="paper">
|
||||
<dia:composite type="paper">
|
||||
<dia:attribute name="name">
|
||||
<dia:string>#Letter#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="tmargin">
|
||||
<dia:real val="2.5399999618530273"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="bmargin">
|
||||
<dia:real val="2.5399999618530273"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="lmargin">
|
||||
<dia:real val="2.5399999618530273"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="rmargin">
|
||||
<dia:real val="2.5399999618530273"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="is_portrait">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="scaling">
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="fitto">
|
||||
<dia:boolean val="false"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="grid">
|
||||
<dia:composite type="grid">
|
||||
<dia:attribute name="width_x">
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="width_y">
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="visible_x">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="visible_y">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:composite type="color"/>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#d8e5e5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="guides">
|
||||
<dia:composite type="guides">
|
||||
<dia:attribute name="hguides"/>
|
||||
<dia:attribute name="vguides"/>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
</dia:diagramdata>
|
||||
<dia:layer name="Background" visible="true" active="true">
|
||||
<dia:object type="Standard - Box" version="0" id="O0">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,39.145"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="57.1801,39.095;64.0901,42.445"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="57.2301,39.145"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O1">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,34.2475"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="57.1801,34.1975;64.0901,37.5475"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="57.2301,34.2475"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O2">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,29.35"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="57.1801,29.3;64.0901,32.65"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="57.2301,29.35"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O3">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="2.1126,39.295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.0626,39.245;8.9726,42.595"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="2.1126,39.295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O4">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="2.1126,34.3975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.0626,34.3475;8.9726,37.6975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="2.1126,34.3975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O5">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="2.1126,29.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.0626,29.45;8.9726,32.8"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="2.1126,29.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O6">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="22.5347,32.178"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="22.4648,17.4572;42.6316,32.2479"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="22.5347,32.178"/>
|
||||
<dia:point val="42.5617,17.5271"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="1" to="O26" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O7">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="43.1205,32.4705"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="22.6348,17.9948;43.1902,32.5402"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="43.1205,32.4705"/>
|
||||
<dia:point val="22.7045,18.0645"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="1" to="O24" connection="7"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O8">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="16.5501,5.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="16.5501,4.905;16.5501,5.6525"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>##</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="16.5501,5.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="0"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O9">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="5.5176,31.125"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="3.29385,30.5113;7.76004,32.1149"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 4
|
||||
VN 172.16.4.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="5.5176,31.125"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O5" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O10">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="5.5176,36.0225"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.88385,35.4088;8.17004,37.0124"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 5
|
||||
VN 172.16.130.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="5.5176,36.0225"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O4" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O11">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="5.5176,40.92"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.8826,40.3063;8.17129,41.9099"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 6
|
||||
VN 172.16.132.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="5.5176,40.92"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O3" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O12">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="60.6351,30.975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="58.4101,30.3613;62.8788,31.9649"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 7
|
||||
VN 172.16.6.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="60.6351,30.975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O2" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O13">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="60.6351,35.8725"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="58.4101,35.2588;62.8788,36.8624"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 8
|
||||
VN 172.16.8.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="60.6351,35.8725"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O1" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O14">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="60.6351,40.77"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="58.0026,40.1563;63.2863,41.7599"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 9
|
||||
VN 172.16.134.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="60.6351,40.77"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O0" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O15">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="8.9226,31.125"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="8.86398,31.0664;15.9041,32.5291"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="8.9226,31.125"/>
|
||||
<dia:point val="15.8455,32.4705"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O5" connection="4"/>
|
||||
<dia:connection handle="1" to="O28" connection="0"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O16">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="8.9226,36.0225"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="8.8715,35.8489;14.4761,36.0736"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="8.9226,36.0225"/>
|
||||
<dia:point val="14.425,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O4" connection="4"/>
|
||||
<dia:connection handle="1" to="O28" connection="3"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O17">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="8.9226,40.92"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="8.86267,39.2696;15.9054,40.9799"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="8.9226,40.92"/>
|
||||
<dia:point val="15.8455,39.3295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O3" connection="4"/>
|
||||
<dia:connection handle="1" to="O28" connection="5"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O18">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,30.975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="49.8855,30.916;57.2891,32.5295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="57.2301,30.975"/>
|
||||
<dia:point val="49.9445,32.4705"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O2" connection="3"/>
|
||||
<dia:connection handle="1" to="O30" connection="2"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O19">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,35.8725"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="51.3148,35.8223;57.2803,35.9502"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="57.2301,35.8725"/>
|
||||
<dia:point val="51.365,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O1" connection="3"/>
|
||||
<dia:connection handle="1" to="O30" connection="4"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O20">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,40.77"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="50.9097,37.8613;57.2963,40.8362"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="57.2301,40.77"/>
|
||||
<dia:point val="50.9759,37.9275"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O0" connection="3"/>
|
||||
<dia:connection handle="1" to="O30" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O21">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="24.25,15.05"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="24.1999,14.9999;41.6501,15.1501"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="24.25,15.05"/>
|
||||
<dia:point val="41.6,15.1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O22">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="19.1,31"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="18.9998,19.5998;19.1502,31.0502"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="19.1,31"/>
|
||||
<dia:point val="19.05,19.65"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O23">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="46.4,19.6"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="46.35,19.55;46.45,30.95"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="46.4,19.6"/>
|
||||
<dia:point val="46.4,30.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:group>
|
||||
<dia:object type="Standard - Ellipse" version="0" id="O24">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="14.425,9.785"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="14.375,9.735;24.175,19.535"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="14.425,9.785"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="aspect">
|
||||
<dia:enum val="2"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O25">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="19.275,14.635"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="15.7475,14.04;22.8025,15.5875"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#BGP Route Reflector 1
|
||||
192.168.1.100#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="19.275,14.635"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O24" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
</dia:group>
|
||||
<dia:group>
|
||||
<dia:object type="Standard - Ellipse" version="0" id="O26">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="41.665,9.785"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="41.615,9.735;51.415,19.535"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="41.665,9.785"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="aspect">
|
||||
<dia:enum val="2"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O27">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="46.565,14.285"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="44.1013,13.69;49.0288,16.0375"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#Commercial Router
|
||||
Route Reflector
|
||||
192.168.1.104#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="46.565,14.285"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
</dia:group>
|
||||
<dia:group>
|
||||
<dia:object type="Standard - Ellipse" version="0" id="O28">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="14.425,31.05"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="14.375,31;24.175,40.8"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="14.425,31.05"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="9.7000007629394531"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="9.7000007629394531"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="aspect">
|
||||
<dia:enum val="2"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O29">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="19.275,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="16.9262,35.305;21.6238,36.8525"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVA 2
|
||||
192.168.1.101#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="19.275,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O28" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
</dia:group>
|
||||
<dia:group>
|
||||
<dia:object type="Standard - Ellipse" version="0" id="O30">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="41.665,31.05"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="41.615,31;51.415,40.8"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="41.665,31.05"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="aspect">
|
||||
<dia:enum val="2"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O31">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="46.515,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="44.1662,35.305;48.8637,36.8525"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVA 3
|
||||
192.168.1.102#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="46.515,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O30" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
</dia:group>
|
||||
</dia:layer>
|
||||
</dia:diagram>
|
BIN
doc/fig-vnc-redundant-route-reflectors.png
Normal file
BIN
doc/fig-vnc-redundant-route-reflectors.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 74 KiB |
0
doc/fig-vnc-redundant-route-reflectors.txt
Normal file
0
doc/fig-vnc-redundant-route-reflectors.txt
Normal file
@ -580,6 +580,10 @@ redistributed into OSPF (@pxref{OSPF redistribute}).
|
||||
@deffnx {OSPF Command} {no distance ospf} {}
|
||||
@end deffn
|
||||
|
||||
@deffn {Command} {router zebra} {}
|
||||
@deffnx {Command} {no router zebra} {}
|
||||
@end deffn
|
||||
|
||||
@node Showing OSPF information
|
||||
@section Showing OSPF information
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
|
||||
@c Set variables - sourced from defines.texi
|
||||
@include defines.texi
|
||||
|
||||
@c %**start of header
|
||||
@setfilename quagga.info
|
||||
@c Set variables - sourced from defines.texi
|
||||
@ -28,6 +31,7 @@ Permission is granted to copy and distribute translations of this manual
|
||||
into another language, under the above conditions for modified versions,
|
||||
except that this permission notice may be stated in a translation
|
||||
approved by Kunihiro Ishiguro.
|
||||
|
||||
@end quotation
|
||||
@end copying
|
||||
|
||||
@ -66,7 +70,7 @@ Version @value{VERSION}.
|
||||
|
||||
@ifnottex
|
||||
@node Top
|
||||
@top Quagga
|
||||
@top Quagga -- With Virtual Network Control
|
||||
|
||||
@uref{http://www.quagga.net,,Quagga} is an advanced routing software package
|
||||
that provides a suite of TCP/IP based routing protocols. This is the Manual
|
||||
@ -88,6 +92,7 @@ for @value{PACKAGE_STRING}. @uref{http://www.quagga.net,,Quagga} is a fork of
|
||||
* ISIS::
|
||||
* BGP::
|
||||
* Configuring Quagga as a Route Server::
|
||||
* VNC and VNC-GW::
|
||||
* VTY shell::
|
||||
* Filtering::
|
||||
* Route Map::
|
||||
@ -113,6 +118,7 @@ for @value{PACKAGE_STRING}. @uref{http://www.quagga.net,,Quagga} is a fork of
|
||||
@include isisd.texi
|
||||
@include bgpd.texi
|
||||
@include routeserver.texi
|
||||
@include vnc.texi
|
||||
@include vtysh.texi
|
||||
@include filter.texi
|
||||
@include routemap.texi
|
||||
|
@ -167,7 +167,7 @@ Set the BGP nexthop address.
|
||||
@end deffn
|
||||
|
||||
@deffn {Route-map Command} {set local-preference @var{local_pref}} {}
|
||||
Set the BGP local preference.
|
||||
Set the BGP local preference to @var{local_pref}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Route-map Command} {set weight @var{weight}} {}
|
||||
|
1584
doc/vnc.texi
Normal file
1584
doc/vnc.texi
Normal file
File diff suppressed because it is too large
Load Diff
@ -2538,6 +2538,9 @@ node_parent ( enum node_type node )
|
||||
case BGP_VPNV6_NODE:
|
||||
case BGP_ENCAP_NODE:
|
||||
case BGP_ENCAPV6_NODE:
|
||||
case BGP_VNC_DEFAULTS_NODE:
|
||||
case BGP_VNC_NVE_GROUP_NODE:
|
||||
case BGP_VNC_L2_GROUP_NODE:
|
||||
case BGP_IPV4_NODE:
|
||||
case BGP_IPV4M_NODE:
|
||||
case BGP_IPV6_NODE:
|
||||
@ -2949,6 +2952,9 @@ DEFUN (config_exit,
|
||||
case BGP_VPNV6_NODE:
|
||||
case BGP_ENCAP_NODE:
|
||||
case BGP_ENCAPV6_NODE:
|
||||
case BGP_VNC_DEFAULTS_NODE:
|
||||
case BGP_VNC_NVE_GROUP_NODE:
|
||||
case BGP_VNC_L2_GROUP_NODE:
|
||||
case BGP_IPV6_NODE:
|
||||
case BGP_IPV6M_NODE:
|
||||
vty->node = BGP_NODE;
|
||||
@ -3007,6 +3013,9 @@ DEFUN (config_end,
|
||||
case BGP_NODE:
|
||||
case BGP_ENCAP_NODE:
|
||||
case BGP_ENCAPV6_NODE:
|
||||
case BGP_VNC_DEFAULTS_NODE:
|
||||
case BGP_VNC_NVE_GROUP_NODE:
|
||||
case BGP_VNC_L2_GROUP_NODE:
|
||||
case BGP_VPNV4_NODE:
|
||||
case BGP_VPNV6_NODE:
|
||||
case BGP_IPV4_NODE:
|
||||
@ -3630,6 +3639,7 @@ DEFUN (config_logmsg,
|
||||
zlog(NULL, level, "%s", ((message = argv_concat(argv, argc, 1)) ? message : ""));
|
||||
if (message)
|
||||
XFREE(MTYPE_TMP, message);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,7 @@ enum node_type
|
||||
SERVICE_NODE, /* Service node. */
|
||||
DEBUG_NODE, /* Debug node. */
|
||||
VRF_DEBUG_NODE, /* Vrf Debug node. */
|
||||
DEBUG_VNC_NODE, /* Debug VNC node. */
|
||||
AAA_NODE, /* AAA node. */
|
||||
KEYCHAIN_NODE, /* Key-chain node. */
|
||||
KEYCHAIN_KEY_NODE, /* Key-chain key node. */
|
||||
@ -96,6 +97,10 @@ enum node_type
|
||||
BGP_IPV6M_NODE, /* BGP IPv6 multicast address family. */
|
||||
BGP_ENCAP_NODE, /* BGP ENCAP SAFI */
|
||||
BGP_ENCAPV6_NODE, /* BGP ENCAP SAFI */
|
||||
BGP_VNC_DEFAULTS_NODE, /* BGP VNC nve defaults */
|
||||
BGP_VNC_NVE_GROUP_NODE, /* BGP VNC nve group */
|
||||
BGP_VNC_L2_GROUP_NODE, /* BGP VNC L2 group */
|
||||
RFP_DEFAULTS_NODE, /* RFP defaults node */
|
||||
OSPF_NODE, /* OSPF protocol mode */
|
||||
OSPF6_NODE, /* OSPF protocol for IPv6 mode */
|
||||
LDP_NODE, /* LDP protocol mode */
|
||||
|
52
lib/log.c
52
lib/log.c
@ -55,6 +55,7 @@ const char *zlog_proto_names[] =
|
||||
"ISIS",
|
||||
"PIM",
|
||||
"MASC",
|
||||
"RFP",
|
||||
NULL,
|
||||
};
|
||||
|
||||
@ -258,6 +259,44 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args)
|
||||
errno = original_errno;
|
||||
}
|
||||
|
||||
int
|
||||
vzlog_test (struct zlog *zl, int priority)
|
||||
{
|
||||
/* If zlog is not specified, use default one. */
|
||||
if (zl == NULL)
|
||||
zl = zlog_default;
|
||||
|
||||
/* When zlog_default is also NULL, use stderr for logging. */
|
||||
if (zl == NULL)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Syslog output */
|
||||
if (priority <= zl->maxlvl[ZLOG_DEST_SYSLOG])
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* File output. */
|
||||
if ((priority <= zl->maxlvl[ZLOG_DEST_FILE]) && zl->fp)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* stdout output. */
|
||||
if (priority <= zl->maxlvl[ZLOG_DEST_STDOUT])
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Terminal monitor. */
|
||||
if (priority <= zl->maxlvl[ZLOG_DEST_MONITOR])
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
str_append(char *dst, int len, const char *src)
|
||||
{
|
||||
@ -680,6 +719,7 @@ _zlog_assert_failed (const char *assertion, const char *file,
|
||||
assertion,file,line,(function ? function : "?"));
|
||||
zlog_backtrace(LOG_CRIT);
|
||||
zlog_thread_info(LOG_CRIT);
|
||||
log_memstats_stderr ("log");
|
||||
abort();
|
||||
}
|
||||
|
||||
@ -941,6 +981,10 @@ static const struct zebra_desc_table command_types[] = {
|
||||
DESC_ENTRY (ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB),
|
||||
DESC_ENTRY (ZEBRA_MPLS_LABELS_ADD),
|
||||
DESC_ENTRY (ZEBRA_MPLS_LABELS_DELETE),
|
||||
DESC_ENTRY (ZEBRA_IPV4_NEXTHOP_ADD),
|
||||
DESC_ENTRY (ZEBRA_IPV4_NEXTHOP_DELETE),
|
||||
DESC_ENTRY (ZEBRA_IPV6_NEXTHOP_ADD),
|
||||
DESC_ENTRY (ZEBRA_IPV6_NEXTHOP_DELETE),
|
||||
};
|
||||
#undef DESC_ENTRY
|
||||
|
||||
@ -1029,6 +1073,10 @@ proto_redistnum(int afi, const char *s)
|
||||
return ZEBRA_ROUTE_BGP;
|
||||
else if (strncmp (s, "ta", 2) == 0)
|
||||
return ZEBRA_ROUTE_TABLE;
|
||||
else if (strncmp (s, "v", 1) == 0)
|
||||
return ZEBRA_ROUTE_VNC;
|
||||
else if (strncmp (s, "vd", 1) == 0)
|
||||
return ZEBRA_ROUTE_VNC_DIRECT;
|
||||
}
|
||||
if (afi == AFI_IP6)
|
||||
{
|
||||
@ -1048,6 +1096,10 @@ proto_redistnum(int afi, const char *s)
|
||||
return ZEBRA_ROUTE_BGP;
|
||||
else if (strncmp (s, "ta", 2) == 0)
|
||||
return ZEBRA_ROUTE_TABLE;
|
||||
else if (strncmp (s, "v", 1) == 0)
|
||||
return ZEBRA_ROUTE_VNC;
|
||||
else if (strncmp (s, "vd", 1) == 0)
|
||||
return ZEBRA_ROUTE_VNC_DIRECT;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ typedef enum
|
||||
ZLOG_OSPF6,
|
||||
ZLOG_LDP,
|
||||
ZLOG_ISIS,
|
||||
ZLOG_RFP,
|
||||
ZLOG_PIM,
|
||||
ZLOG_MASC
|
||||
} zlog_proto_t;
|
||||
@ -184,6 +185,10 @@ extern size_t quagga_timestamp(int timestamp_precision /* # subsecond digits */,
|
||||
|
||||
extern void zlog_hexdump(const void *mem, unsigned int len);
|
||||
|
||||
|
||||
extern int
|
||||
vzlog_test (struct zlog *zl, int priority);
|
||||
|
||||
/* structure useful for avoiding repeated rendering of the same timestamp */
|
||||
struct timestamp_control {
|
||||
size_t len; /* length of rendered timestamp */
|
||||
|
@ -240,6 +240,8 @@ afi2str(afi_t afi)
|
||||
return "IPv6";
|
||||
case AFI_ETHER:
|
||||
return "ethernet";
|
||||
case AFI_MAX:
|
||||
return "bad-value";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -61,6 +61,16 @@ ZEBRA_ROUTE_HSLS, hsls, hslsd, 'H', 0, 0, "HSLS"
|
||||
ZEBRA_ROUTE_OLSR, olsr, olsrd, 'o', 0, 0, "OLSR"
|
||||
ZEBRA_ROUTE_TABLE, table, zebra, 'T', 1, 1, "Table"
|
||||
ZEBRA_ROUTE_LDP, ldp, ldpd, 'L', 0, 0, "LDP"
|
||||
#vnc when sent to zebra
|
||||
ZEBRA_ROUTE_VNC, vnc, NULL, 'v', 1, 1, "VNC"
|
||||
# vnc when sent to bgp
|
||||
ZEBRA_ROUTE_VNC_DIRECT, vpn, NULL, 'V', 1, 1, "VPN"
|
||||
# vnc when sent to bgp (remote next hop?)
|
||||
ZEBRA_ROUTE_VNC_DIRECT_RH, vpn-rh, NULL, 'V', 0, 0, "VPN"
|
||||
# bgp unicast -> vnc
|
||||
ZEBRA_ROUTE_BGP_DIRECT, bgp-direct, NULL, 'b', 0, 0, "BGP-Direct"
|
||||
# bgp unicast -> vnc
|
||||
ZEBRA_ROUTE_BGP_DIRECT_EXT, bgp-direct-to-nve-groups, NULL, 'e', 0, 0, "BGP2VNC"
|
||||
|
||||
## help strings
|
||||
ZEBRA_ROUTE_SYSTEM, "Reserved route type, for internal use only"
|
||||
@ -75,6 +85,8 @@ ZEBRA_ROUTE_ISIS, "Intermediate System to Intermediate System (IS-IS)"
|
||||
ZEBRA_ROUTE_BGP, "Border Gateway Protocol (BGP)"
|
||||
ZEBRA_ROUTE_PIM, "Protocol Independent Multicast (PIM)"
|
||||
ZEBRA_ROUTE_HSLS, "Hazy-Sighted Link State Protocol (HSLS)"
|
||||
ZEBRA_ROUTE_VNC, "Virtual Network Control (VNC)"
|
||||
ZEBRA_ROUTE_OLSR, "Optimised Link State Routing (OLSR)"
|
||||
ZEBRA_ROUTE_TABLE, "Non-main Kernel Routing Table"
|
||||
ZEBRA_ROUTE_LDP, "Label Distribution Protocol (LDP)"
|
||||
ZEBRA_ROUTE_VNC_DIRECT, "VPN routes(VPN)"
|
||||
|
@ -747,6 +747,9 @@ vty_end_config (struct vty *vty)
|
||||
case BGP_VPNV6_NODE:
|
||||
case BGP_ENCAP_NODE:
|
||||
case BGP_ENCAPV6_NODE:
|
||||
case BGP_VNC_DEFAULTS_NODE:
|
||||
case BGP_VNC_NVE_GROUP_NODE:
|
||||
case BGP_VNC_L2_GROUP_NODE:
|
||||
case BGP_IPV4_NODE:
|
||||
case BGP_IPV4M_NODE:
|
||||
case BGP_IPV6_NODE:
|
||||
|
@ -427,6 +427,10 @@ typedef enum {
|
||||
ZEBRA_INTERFACE_LINK_PARAMS,
|
||||
ZEBRA_MPLS_LABELS_ADD,
|
||||
ZEBRA_MPLS_LABELS_DELETE,
|
||||
ZEBRA_IPV4_NEXTHOP_ADD,
|
||||
ZEBRA_IPV4_NEXTHOP_DELETE,
|
||||
ZEBRA_IPV6_NEXTHOP_ADD,
|
||||
ZEBRA_IPV6_NEXTHOP_DELETE,
|
||||
} zebra_message_types_t;
|
||||
|
||||
/* Marker value used in new Zserv, in the byte location corresponding
|
||||
|
@ -24,6 +24,7 @@
|
||||
%{!?vty_group: %global vty_group quaggavty }
|
||||
%{!?with_fpm: %global with_fpm 0 }
|
||||
%{!?with_watchquagga: %global with_watchquagga 1 }
|
||||
%{!?with_bgp_vnc: %global with_bgp_vnc 0 }
|
||||
|
||||
# path defines
|
||||
%define _sysconfdir /etc/quagga
|
||||
@ -235,6 +236,11 @@ developing OSPF-API and quagga applications.
|
||||
--enable-watchquagga \
|
||||
%else
|
||||
--disable-watchquagga \
|
||||
%endif
|
||||
%if %{with_bgp_vnc}
|
||||
--enable-bgp-vnc \
|
||||
%else
|
||||
--disable-bgp-vnc \
|
||||
%endif
|
||||
--enable-gcc-rdynamic \
|
||||
--enable-isisd=yes \
|
||||
|
@ -248,6 +248,7 @@ static struct {
|
||||
{ZEBRA_ROUTE_STATIC, 1, "static"},
|
||||
{ZEBRA_ROUTE_OSPF, 1, "ospf"},
|
||||
{ZEBRA_ROUTE_BGP, 2, "bgp"},
|
||||
{ZEBRA_ROUTE_VNC, 1, "vnc"},
|
||||
{0, 0, NULL}
|
||||
};
|
||||
|
||||
|
@ -255,6 +255,7 @@ static struct {
|
||||
{ZEBRA_ROUTE_STATIC, 1, "static"},
|
||||
{ZEBRA_ROUTE_OSPF6, 1, "ospf6"},
|
||||
{ZEBRA_ROUTE_BGP, 2, "bgp"},
|
||||
{ZEBRA_ROUTE_VNC, 1, "vnc"},
|
||||
{0, 0, NULL}
|
||||
};
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user