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:
Lou Berger 2016-05-07 14:18:56 -04:00 committed by Donald Sharp
parent 520d2512db
commit 65efcfce42
106 changed files with 44654 additions and 49 deletions

View File

@ -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 \

View File

@ -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

View File

@ -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. */

View File

@ -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. */

View File

@ -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;

View File

@ -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 */

View File

@ -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);
}

View File

@ -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

View File

@ -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,

View File

@ -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);

View File

@ -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")

View File

@ -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 */

View File

@ -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;

View File

@ -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);

View File

@ -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
{

View File

@ -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 */

View File

@ -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 */

View File

@ -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
View 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 */

View File

@ -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. */

View File

@ -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
View 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

View File

@ -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

File diff suppressed because it is too large Load Diff

312
bgpd/rfapi/bgp_rfapi_cfg.h Normal file
View 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

File diff suppressed because it is too large Load Diff

980
bgpd/rfapi/rfapi.h Normal file
View 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
View 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
View 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 */

View 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 */

View 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;
}

View 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);

View 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);
}
}

View 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

File diff suppressed because it is too large Load Diff

283
bgpd/rfapi/rfapi_import.h Normal file
View 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

File diff suppressed because it is too large Load Diff

217
bgpd/rfapi/rfapi_monitor.h Normal file
View 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
View 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;
}

View 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
View 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

File diff suppressed because it is too large Load Diff

154
bgpd/rfapi/rfapi_rib.h Normal file
View 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

File diff suppressed because it is too large Load Diff

223
bgpd/rfapi/rfapi_vty.h Normal file
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

View 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_ */

View 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_ */

View 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;
}

View 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

File diff suppressed because it is too large Load Diff

View 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_ */

View 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

File diff suppressed because it is too large Load Diff

67
bgpd/rfapi/vnc_zebra.h Normal file
View 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 */

View 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)

View 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 */

View 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;
}

View 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 */

View 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 =

View 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);
}

View 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 */

View File

@ -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

View File

@ -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

View File

@ -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

View 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

0
doc/fig-vnc-gw-rr.txt Normal file
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

0
doc/fig-vnc-gw.txt Normal file
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

0
doc/fig-vnc-mesh.txt Normal file
View File

View 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

View 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

View 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

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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 */

View File

@ -240,6 +240,8 @@ afi2str(afi_t afi)
return "IPv6";
case AFI_ETHER:
return "ethernet";
case AFI_MAX:
return "bad-value";
default:
break;
}

View File

@ -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)"

View File

@ -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:

View File

@ -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

View File

@ -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 \

View File

@ -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}
};

View File

@ -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