Merge branch 'cmaster-next' into vtysh-grammar

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>

Conflicts:
	bgpd/bgp_route.c
	bgpd/bgp_routemap.c
	bgpd/bgp_vty.c
	isisd/isis_redist.c
	isisd/isis_routemap.c
	isisd/isis_vty.c
	isisd/isisd.c
	lib/command.c
	lib/distribute.c
	lib/if.c
	lib/keychain.c
	lib/routemap.c
	lib/routemap.h
	ospf6d/ospf6_asbr.c
	ospf6d/ospf6_interface.c
	ospf6d/ospf6_neighbor.c
	ospf6d/ospf6_top.c
	ospf6d/ospf6_zebra.c
	ospf6d/ospf6d.c
	ospfd/ospf_routemap.c
	ospfd/ospf_vty.c
	ripd/rip_routemap.c
	ripngd/ripng_routemap.c
	vtysh/extract.pl.in
	vtysh/vtysh.c
	zebra/interface.c
	zebra/irdp_interface.c
	zebra/rt_netlink.c
	zebra/rtadv.c
	zebra/test_main.c
	zebra/zebra_routemap.c
	zebra/zebra_vty.c
This commit is contained in:
Quentin Young 2016-10-17 23:36:21 +00:00
commit e52702f29d
315 changed files with 78148 additions and 2814 deletions

6
.gitignore vendored
View File

@ -20,6 +20,9 @@ autom4te*.cache
configure.lineno
configure
config.h.in
confdefs.h
conftest
conftest.err
aclocal.m4
Makefile.in
zebra-[0-9.][0-9.][0-9.]*.tar.gz
@ -55,3 +58,6 @@ debian/quagga/
debian/tmp/
*.swp
cscope.*
*.pb.h
*.pb-c.h
*.pb-c.c

View File

@ -1,19 +1,19 @@
## Process this file with automake to produce Makefile.in.
SUBDIRS = lib @ZEBRA@ @BGPD@ @RIPD@ @RIPNGD@ @OSPFD@ @OSPF6D@ \
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 zebra bgpd ripd ripngd ospfd ospf6d \
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 \
vtysh/Makefile.in vtysh/Makefile.am \
tools/rrcheck.pl tools/rrlookup.pl tools/zc.pl \
tools/zebra.el tools/multiple-bgpd.sh \
fpm/fpm.h
tools/zebra.el tools/multiple-bgpd.sh
if HAVE_LATEX

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_builddir@/$(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

@ -44,6 +44,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 "bgpd/rfapi/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 [] =
@ -68,6 +73,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);
@ -257,6 +265,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
}
/*
@ -422,6 +436,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;
}
@ -462,6 +482,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)
@ -471,6 +496,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
}
}
@ -612,6 +642,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)
@ -670,6 +703,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;
@ -940,6 +978,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
}
}
@ -1911,7 +1953,7 @@ bgp_attr_encap(
bgp_size_t total;
struct attr_extra *attre = NULL;
struct bgp_attr_encap_subtlv *stlv_last = NULL;
uint16_t tunneltype;
uint16_t tunneltype = 0;
total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3);
@ -1957,6 +1999,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) {
@ -1988,6 +2036,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;
@ -2301,6 +2359,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;
@ -2570,7 +2631,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(
@ -2604,6 +2667,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);
}
@ -2649,6 +2721,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);
}
@ -3038,6 +3115,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.
@ -103,10 +118,14 @@ struct attr_extra
u_char mp_nexthop_prefer_global;
/* route tag */
u_short tag;
route_tag_t tag;
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

@ -1696,6 +1696,50 @@ DEFUN (show_debugging_bgp,
return CMD_SUCCESS;
}
/* return count of number of debug flags set */
int
bgp_debug_count(void)
{
int ret = 0;
if (BGP_DEBUG (as4, AS4))
ret++;
if (BGP_DEBUG (as4, AS4_SEGMENT))
ret++;
if (BGP_DEBUG (bestpath, BESTPATH))
ret++;
if (BGP_DEBUG (keepalive, KEEPALIVE))
ret++;
if (BGP_DEBUG (neighbor_events, NEIGHBOR_EVENTS))
ret++;
if (BGP_DEBUG (nht, NHT))
ret++;
if (BGP_DEBUG (update_groups, UPDATE_GROUPS))
ret++;
if (BGP_DEBUG (update, UPDATE_PREFIX))
ret++;
if (BGP_DEBUG (update, UPDATE_IN))
ret++;
if (BGP_DEBUG (update, UPDATE_OUT))
ret++;
if (BGP_DEBUG (zebra, ZEBRA))
ret++;
if (BGP_DEBUG (allow_martians, ALLOW_MARTIANS))
ret++;
return ret;
}
static int
bgp_config_write_debug (struct vty *vty)
{

View File

@ -150,4 +150,5 @@ extern int bgp_debug_update(struct peer *peer, struct prefix *p,
extern int bgp_debug_bestpath(struct prefix *p);
extern int bgp_debug_zebra(struct prefix *p);
extern int bgp_debug_count(void);
#endif /* _QUAGGA_BGP_DEBUG_H */

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,50 +45,9 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_vty.h"
#include "bgpd/bgp_encap.h"
static u_int16_t
decode_rd_type (u_char *pnt)
{
u_int16_t v;
v = ((u_int16_t) *pnt++ << 8);
v |= (u_int16_t) *pnt;
return v;
}
static void
decode_rd_as (u_char *pnt, struct rd_as *rd_as)
{
rd_as->as = (u_int16_t) *pnt++ << 8;
rd_as->as |= (u_int16_t) *pnt++;
rd_as->val = ((u_int32_t) *pnt++) << 24;
rd_as->val |= ((u_int32_t) *pnt++) << 16;
rd_as->val |= ((u_int32_t) *pnt++) << 8;
rd_as->val |= (u_int32_t) *pnt;
}
static void
decode_rd_as4 (u_char *pnt, struct rd_as *rd_as)
{
rd_as->as = (u_int32_t) *pnt++ << 24;
rd_as->as |= (u_int32_t) *pnt++ << 16;
rd_as->as |= (u_int32_t) *pnt++ << 8;
rd_as->as |= (u_int32_t) *pnt++;
rd_as->val = ((u_int32_t) *pnt++ << 8);
rd_as->val |= (u_int32_t) *pnt;
}
static void
decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip)
{
memcpy (&rd_ip->ip, pnt, 4);
pnt += 4;
rd_ip->val = ((u_int16_t) *pnt++ << 8);
rd_ip->val |= (u_int16_t) *pnt;
}
#if ENABLE_BGP_VNC
#include "bgpd/rfapi/rfapi_backend.h"
#endif
static void
ecom2prd(struct ecommunity *ecom, struct prefix_rd *prd)
@ -230,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);
}
@ -987,27 +954,4 @@ bgp_encap_init (void)
install_element (VIEW_NODE, &show_bgp_ipv6_encap_neighbor_advertised_routes_cmd);
install_element (VIEW_NODE, &show_bgp_ipv6_encap_rd_neighbor_advertised_routes_cmd);
#endif
install_element (ENABLE_NODE, &show_bgp_ipv4_encap_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv4_encap_rd_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv4_encap_tags_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv4_encap_rd_tags_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv4_encap_neighbor_routes_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv4_encap_rd_neighbor_routes_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv4_encap_neighbor_advertised_routes_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv4_encap_rd_neighbor_advertised_routes_cmd);
#ifdef HAVE_IPV6
install_element (ENABLE_NODE, &show_bgp_ipv6_encap_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv6_encap_rd_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv6_encap_tags_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv6_encap_rd_tags_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv6_encap_neighbor_routes_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv6_encap_rd_neighbor_routes_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv6_encap_neighbor_advertised_routes_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv6_encap_rd_neighbor_advertised_routes_cmd);
#endif
}

View File

@ -410,9 +410,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

@ -702,8 +702,6 @@ bgp_filter_init (void)
install_element (VIEW_NODE, &show_ip_as_path_access_list_cmd);
install_element (VIEW_NODE, &show_ip_as_path_access_list_all_cmd);
install_element (ENABLE_NODE, &show_ip_as_path_access_list_cmd);
install_element (ENABLE_NODE, &show_ip_as_path_access_list_all_cmd);
}
void

View File

@ -689,7 +689,7 @@ bgp_adjust_routeadv (struct peer *peer)
*
* m > MRAI
*/
diff = difftime(nowtime, peer->last_write);
diff = difftime(nowtime, peer->last_update);
if (diff > (double) peer->v_routeadv)
{
BGP_TIMER_OFF(peer->t_routeadv);

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 "bgpd/rfapi/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);
@ -296,6 +302,8 @@ bgp_exit (int status)
if (zlog_default)
closezlog (zlog_default);
if (bgp_debug_count())
log_memstats_stderr ("bgpd");
exit (status);
}

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"
static u_int16_t
#if ENABLE_BGP_VNC
#include "bgpd/rfapi/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,8 +75,19 @@ 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 */
static void
void
decode_rd_as (u_char *pnt, struct rd_as *rd_as)
{
rd_as->as = (u_int16_t) *pnt++ << 8;
@ -70,7 +100,7 @@ decode_rd_as (u_char *pnt, struct rd_as *rd_as)
}
/* type == RD_TYPE_AS4 */
static void
void
decode_rd_as4 (u_char *pnt, struct rd_as *rd_as)
{
rd_as->as = (u_int32_t) *pnt++ << 24;
@ -83,7 +113,7 @@ decode_rd_as4 (u_char *pnt, struct rd_as *rd_as)
}
/* type == RD_TYPE_IP */
static void
void
decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip)
{
memcpy (&rd_ip->ip, pnt, 4);
@ -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 */
static 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)
@ -146,17 +190,17 @@ bgp_nlri_parse_vpn (struct peer *peer, struct attr *attr,
pnt += BGP_ADDPATH_ID_LEN;
}
/* Fetch prefix length. */
prefixlen = *pnt++;
p.family = afi2family (packet->afi);
psize = PSIZE (prefixlen);
if (prefixlen < 88)
{
zlog_err ("prefix length is less than 88: %d", prefixlen);
return -1;
}
/* Fetch prefix length. */
prefixlen = *pnt++;
p.family = afi2family (packet->afi);
psize = PSIZE (prefixlen);
/* sanity check against packet data */
if (prefixlen < VPN_PREFIXLEN_MIN_BYTES*8 || (pnt + psize) > lim)
{
@ -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,22 +255,40 @@ 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);
#if ENABLE_BGP_VNC
rfapiProcessUpdate(peer, NULL, &p, &prd, attr, packet->afi,
SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
&label);
#endif
}
else
{
#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)
return -1;
@ -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;
}
@ -493,6 +574,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;
@ -506,6 +590,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)
{
@ -524,6 +612,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);
}
@ -546,7 +645,7 @@ show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd, u
if (use_json)
{
json_object_object_add(json, "routes", json_routes);
vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
json_object_free(json);
}
return CMD_SUCCESS;
@ -685,6 +784,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;
@ -698,6 +800,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)
{
@ -716,6 +822,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;
@ -753,7 +870,7 @@ bgp_show_mpls_vpn (struct vty *vty, afi_t afi, struct prefix_rd *prd,
if (use_json)
{
json_object_object_add(json, "routes", json_nroute);
vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
json_object_free(json);
}
else
@ -1182,17 +1299,4 @@ bgp_mplsvpn_init (void)
install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv4_vpn_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv4_vpn_rd_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv6_vpn_cmd);
install_element (ENABLE_NODE, &show_bgp_ipv6_vpn_rd_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
}

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,9 +69,27 @@ 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 *);
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

@ -569,16 +569,11 @@ bgp_scan_init (struct bgp *bgp)
void
bgp_scan_vty_init (void)
{
install_element (ENABLE_NODE, &show_ip_bgp_nexthop_cmd);
install_element (VIEW_NODE, &show_ip_bgp_nexthop_cmd);
install_element (VIEW_NODE, &show_ip_bgp_nexthop_detail_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_nexthop_detail_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_instance_nexthop_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_instance_all_nexthop_cmd);
install_element (VIEW_NODE, &show_ip_bgp_instance_nexthop_cmd);
install_element (VIEW_NODE, &show_ip_bgp_instance_all_nexthop_cmd);
install_element (VIEW_NODE, &show_ip_bgp_instance_nexthop_detail_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_instance_nexthop_detail_cmd);
}
void

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

@ -341,6 +341,7 @@ bgp_write (struct thread *thread)
u_char type;
struct stream *s;
int num;
int update_last_write = 0;
unsigned int count = 0;
unsigned int oc = 0;
@ -432,6 +433,7 @@ bgp_write (struct thread *thread)
/* OK we send packet so delete it. */
bgp_packet_delete (peer);
update_last_write = 1;
}
while (++count < peer->bgp->wpkt_quanta &&
(s = bgp_write_packet (peer)) != NULL);
@ -439,8 +441,12 @@ bgp_write (struct thread *thread)
bgp_write_proceed_actions (peer);
done:
/* Update the last write if some updates were written. */
/* Update last_update if UPDATEs were written. */
if (peer->update_out > oc)
peer->last_update = bgp_clock ();
/* If we TXed any flavor of packet update last_write */
if (update_last_write)
peer->last_write = bgp_clock ();
sockopt_cork (peer->fd, 0);

View File

@ -61,6 +61,12 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_nht.h"
#include "bgpd/bgp_updgrp.h"
#if ENABLE_BGP_VNC
#include "bgpd/rfapi/rfapi_backend.h"
#include "bgpd/rfapi/vnc_import_bgp.h"
#include "bgpd/rfapi/vnc_export_bgp.h"
#endif
/* Extern from bgp_dump.c */
extern const char *bgp_origin_str[];
extern const char *bgp_origin_long_str[];
@ -131,6 +137,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)
@ -227,7 +240,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);
@ -331,7 +344,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;
@ -846,6 +859,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)
@ -979,8 +1017,8 @@ bgp_input_modifier (struct peer *peer, struct prefix *p, struct attr *attr,
filter = &peer->filter[afi][safi];
/* Apply default weight value. */
if (peer->weight)
(bgp_attr_extra_get (attr))->weight = peer->weight;
if (peer->weight[afi][safi])
(bgp_attr_extra_get (attr))->weight = peer->weight[afi][safi];
if (rmap_name)
{
@ -1036,8 +1074,8 @@ bgp_output_modifier (struct peer *peer, struct prefix *p, struct attr *attr,
filter = &peer->filter[afi][safi];
/* Apply default weight value. */
if (peer->weight)
(bgp_attr_extra_get (attr))->weight = peer->weight;
if (peer->weight[afi][safi])
(bgp_attr_extra_get (attr))->weight = peer->weight[afi][safi];
if (rmap_name)
{
@ -1158,6 +1196,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;
@ -1174,6 +1213,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) ||
@ -1310,7 +1365,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))
@ -1868,8 +1923,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))
{
#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);
@ -1902,6 +1962,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. */
@ -2135,7 +2210,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,6 +2226,32 @@ bgp_rib_withdraw (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer,
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);
}
@ -2253,6 +2354,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);
@ -2442,6 +2546,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);
@ -2451,6 +2584,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)
@ -2490,6 +2642,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);
@ -2560,6 +2734,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))
@ -2652,7 +2848,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),
@ -3046,6 +3242,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
@ -3116,9 +3316,15 @@ 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))
{
#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);
}
}
}
/* Delete all kernel routes. */
void
@ -3416,6 +3622,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)
@ -3488,9 +3697,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))
@ -3636,6 +3870,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);
@ -3654,6 +3900,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);
@ -3730,10 +3979,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);
@ -3748,6 +4006,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);
@ -3761,6 +4022,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);
@ -5404,7 +5671,7 @@ DEFUN (no_ipv6_aggregate_address_summary_only,
void
bgp_redistribute_add (struct bgp *bgp, struct prefix *p, const struct in_addr *nexthop,
const struct in6_addr *nexthop6, unsigned int ifindex,
u_int32_t metric, u_char type, u_short instance, u_short tag)
u_int32_t metric, u_char type, u_short instance, route_tag_t tag)
{
struct bgp_info *new;
struct bgp_info *bi;
@ -5773,7 +6040,7 @@ route_vty_out (struct vty *vty, struct prefix *p,
vty_out(vty, "?");
}
/* IPv4 Next Hop */
else if (p->family == AF_INET || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
{
if (json_paths)
{
@ -5958,7 +6225,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);
#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 */
@ -6762,7 +7036,7 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
if (json_paths)
json_object_int_add(json_path, "tag", attr->extra->tag);
else
vty_out (vty, ", tag %d", attr->extra->tag);
vty_out (vty, ", tag %"ROUTE_TAG_PRI, attr->extra->tag);
}
if (! CHECK_FLAG (binfo->flags, BGP_INFO_VALID))
@ -7159,6 +7433,7 @@ bgp_show_table (struct vty *vty, struct bgp_table *table,
int header = 1;
int display;
unsigned long output_count;
unsigned long total_count;
struct prefix *p;
char buf[BUFSIZ];
char buf2[BUFSIZ];
@ -7177,6 +7452,7 @@ bgp_show_table (struct vty *vty, struct bgp_table *table,
/* This is first entry point, so reset total line. */
output_count = 0;
total_count = 0;
/* Start processing of routes. */
for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
@ -7191,6 +7467,7 @@ bgp_show_table (struct vty *vty, struct bgp_table *table,
for (ri = rn->info; ri; ri = ri->next)
{
total_count++;
if (type == bgp_show_type_flap_statistics
|| type == bgp_show_type_flap_neighbor
|| type == bgp_show_type_dampend_paths
@ -7350,6 +7627,9 @@ bgp_show_table (struct vty *vty, struct bgp_table *table,
if (use_json)
{
/* This can produce a LOT of text so do not use
* JSON_C_TO_STRING_PRETTY here
*/
json_object_object_add(json, "routes", json_routes);
vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
json_object_free(json);
@ -7360,11 +7640,11 @@ bgp_show_table (struct vty *vty, struct bgp_table *table,
if (output_count == 0)
{
if (type == bgp_show_type_normal)
vty_out (vty, "No BGP network exists%s", VTY_NEWLINE);
vty_out (vty, "No BGP prefixes displayed, %ld exist%s", total_count, VTY_NEWLINE);
}
else
vty_out (vty, "%sTotal number of prefixes %ld%s",
VTY_NEWLINE, output_count, VTY_NEWLINE);
vty_out (vty, "%sDisplayed %ld out of %ld total prefixes%s",
VTY_NEWLINE, output_count, total_count, VTY_NEWLINE);
}
return CMD_SUCCESS;
@ -7680,7 +7960,7 @@ bgp_show_route_in_table (struct vty *vty, struct bgp *bgp,
if (display)
json_object_object_add(json, "paths", json_paths);
vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
json_object_free(json);
}
else
@ -10258,17 +10538,16 @@ bgp_route_init (void)
install_element (VIEW_NODE, &show_ip_bgp_ipv4_dampening_parameters_cmd);
/* Restricted node: VIEW_NODE - (set of dangerous commands) */
install_element (RESTRICTED_NODE, &show_ip_bgp_route_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_instance_all_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_ipv4_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_route_cmd);
install_element (VIEW_NODE, &show_ip_bgp_instance_all_cmd);
install_element (VIEW_NODE, &show_ip_bgp_ipv4_cmd);
install_element (VIEW_NODE, &show_ip_bgp_route_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_instance_neighbor_advertised_route_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_neighbor_routes_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_neighbor_received_prefix_filter_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_dampening_params_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_ipv4_dampening_parameters_cmd);
install_element (VIEW_NODE, &show_ip_bgp_instance_neighbor_advertised_route_cmd);
install_element (VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
install_element (VIEW_NODE, &show_ip_bgp_neighbor_received_prefix_filter_cmd);
install_element (VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
install_element (VIEW_NODE, &show_ip_bgp_ipv4_dampening_parameters_cmd);
/* BGP dampening clear commands */
install_element (ENABLE_NODE, &clear_ip_bgp_dampening_cmd);

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;
@ -244,7 +271,7 @@ extern int bgp_maximum_prefix_overflow (struct peer *, afi_t, safi_t, int);
extern void bgp_redistribute_add (struct bgp *, struct prefix *, const struct in_addr *,
const struct in6_addr *, unsigned int ifindex,
u_int32_t, u_char, u_short, u_short);
u_int32_t, u_char, u_short, route_tag_t);
extern void bgp_redistribute_delete (struct bgp *, struct prefix *, u_char, u_short);
extern void bgp_redistribute_withdraw (struct bgp *, afi_t, int, u_short);
@ -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

@ -59,6 +59,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 "bgpd/rfapi/bgp_rfapi_cfg.h"
#endif
/* Memo of route-map commands.
@ -108,7 +111,7 @@ o Local extensions
set ipv6 next-hop local : Done
set as-path exclude : Done
*/
*/
/* generic value manipulation to be shared in multiple rules */
@ -330,7 +333,7 @@ struct route_map_rule_cmd route_match_peer_cmd =
/* Match function should return 1 if match is success else return
zero. */
static route_map_result_t
route_match_ip_address (void *rule, struct prefix *prefix,
route_match_ip_address (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct access_list *alist;
@ -341,7 +344,7 @@ route_match_ip_address (void *rule, struct prefix *prefix,
alist = access_list_lookup (AFI_IP, (char *) rule);
if (alist == NULL)
return RMAP_NOMATCH;
return (access_list_apply (alist, prefix) == FILTER_DENY ?
RMAP_NOMATCH : RMAP_MATCH);
}
@ -376,7 +379,7 @@ struct route_map_rule_cmd route_match_ip_address_cmd =
/* Match function return 1 if match is success else return zero. */
static route_map_result_t
route_match_ip_next_hop (void *rule, struct prefix *prefix,
route_match_ip_next_hop (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct access_list *alist;
@ -428,7 +431,7 @@ struct route_map_rule_cmd route_match_ip_next_hop_cmd =
/* Match function return 1 if match is success else return zero. */
static route_map_result_t
route_match_ip_route_source (void *rule, struct prefix *prefix,
route_match_ip_route_source (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct access_list *alist;
@ -485,7 +488,7 @@ struct route_map_rule_cmd route_match_ip_route_source_cmd =
/* `match ip address prefix-list PREFIX_LIST' */
static route_map_result_t
route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct prefix_list *plist;
@ -495,7 +498,7 @@ route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
plist = prefix_list_lookup (AFI_IP, (char *) rule);
if (plist == NULL)
return RMAP_NOMATCH;
return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
RMAP_NOMATCH : RMAP_MATCH);
}
@ -692,7 +695,7 @@ struct route_map_rule_cmd route_match_local_pref_cmd =
/* Match function return 1 if match is success else return zero. */
static route_map_result_t
route_match_metric (void *rule, struct prefix *prefix,
route_match_metric (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct rmap_value *rv;
@ -720,10 +723,10 @@ struct route_map_rule_cmd route_match_metric_cmd =
/* Match function for as-path match. I assume given object is */
static route_map_result_t
route_match_aspath (void *rule, struct prefix *prefix,
route_match_aspath (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct as_list *as_list;
struct bgp_info *bgp_info;
@ -756,7 +759,7 @@ route_match_aspath_free (void *rule)
}
/* Route map commands for aspath matching. */
struct route_map_rule_cmd route_match_aspath_cmd =
struct route_map_rule_cmd route_match_aspath_cmd =
{
"as-path",
route_match_aspath,
@ -773,14 +776,14 @@ struct rmap_community
/* Match function for community match. */
static route_map_result_t
route_match_community (void *rule, struct prefix *prefix,
route_match_community (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct community_list *list;
struct bgp_info *bgp_info;
struct rmap_community *rcom;
if (type == RMAP_BGP)
if (type == RMAP_BGP)
{
bgp_info = object;
rcom = rule;
@ -835,12 +838,12 @@ route_match_community_free (void *rule)
{
struct rmap_community *rcom = rule;
XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
}
/* Route map commands for community matching. */
struct route_map_rule_cmd route_match_community_cmd =
struct route_map_rule_cmd route_match_community_cmd =
{
"community",
route_match_community,
@ -850,19 +853,19 @@ struct route_map_rule_cmd route_match_community_cmd =
/* Match function for extcommunity match. */
static route_map_result_t
route_match_ecommunity (void *rule, struct prefix *prefix,
route_match_ecommunity (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct community_list *list;
struct bgp_info *bgp_info;
if (type == RMAP_BGP)
if (type == RMAP_BGP)
{
bgp_info = object;
if (!bgp_info->attr->extra)
return RMAP_NOMATCH;
list = community_list_lookup (bgp_clist, (char *) rule,
EXTCOMMUNITY_LIST_MASTER);
if (! list)
@ -889,7 +892,7 @@ route_match_ecommunity_free (void *rule)
}
/* Route map commands for community matching. */
struct route_map_rule_cmd route_match_ecommunity_cmd =
struct route_map_rule_cmd route_match_ecommunity_cmd =
{
"extcommunity",
route_match_ecommunity,
@ -902,7 +905,7 @@ struct route_map_rule_cmd route_match_ecommunity_cmd =
/* `match origin' */
static route_map_result_t
route_match_origin (void *rule, struct prefix *prefix,
route_match_origin (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
u_char *origin;
@ -912,7 +915,7 @@ route_match_origin (void *rule, struct prefix *prefix,
{
origin = rule;
bgp_info = object;
if (bgp_info->attr->origin == *origin)
return RMAP_MATCH;
}
@ -1068,7 +1071,7 @@ static route_map_result_t
route_match_tag (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
u_short *tag;
route_tag_t *tag;
struct bgp_info *bgp_info;
if (type == RMAP_BGP)
@ -1086,46 +1089,13 @@ route_match_tag (void *rule, struct prefix *prefix,
}
/* Route map `match tag' match statement. `arg' is TAG value */
static void *
route_match_tag_compile (const char *arg)
{
u_short *tag;
u_short tmp;
/* tag value shoud be integer. */
if (! all_digit (arg))
return NULL;
tmp = atoi(arg);
if (tmp < 1)
return NULL;
tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short));
if (!tag)
return tag;
*tag = tmp;
return tag;
}
/* Free route map's compiled 'match tag' value. */
static void
route_match_tag_free (void *rule)
{
XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
}
/* Route map commands for tag matching. */
struct route_map_rule_cmd route_match_tag_cmd =
static struct route_map_rule_cmd route_match_tag_cmd =
{
"tag",
route_match_tag,
route_match_tag_compile,
route_match_tag_free,
route_map_rule_tag_compile,
route_map_rule_tag_free,
};
@ -1159,7 +1129,7 @@ route_set_ip_nexthop (void *rule, struct prefix *prefix,
{
if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
&& peer->su_remote
&& peer->su_remote
&& sockunion_family (peer->su_remote) == AF_INET)
{
bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_remote);
@ -1233,7 +1203,7 @@ route_set_ip_nexthop_free (void *rule)
if (rins->address)
XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
}
@ -1262,8 +1232,8 @@ route_set_local_pref (void *rule, struct prefix *prefix,
/* Fetch routemap's rule information. */
rv = rule;
bgp_info = object;
/* Set local preference value. */
/* Set local preference value. */
if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
locpref = bgp_info->attr->local_pref;
@ -1275,7 +1245,7 @@ route_set_local_pref (void *rule, struct prefix *prefix,
}
/* Set local preference rule structure. */
struct route_map_rule_cmd route_set_local_pref_cmd =
struct route_map_rule_cmd route_set_local_pref_cmd =
{
"local-preference",
route_set_local_pref,
@ -1299,8 +1269,8 @@ route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
/* Fetch routemap's rule information. */
rv = rule;
bgp_info = object;
/* Set weight value. */
/* Set weight value. */
weight = route_value_adjust(rv, 0, bgp_info->peer);
if (weight)
(bgp_attr_extra_get (bgp_info->attr))->weight = weight;
@ -1312,7 +1282,7 @@ route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
}
/* Set local preference rule structure. */
struct route_map_rule_cmd route_set_weight_cmd =
struct route_map_rule_cmd route_set_weight_cmd =
{
"weight",
route_set_weight,
@ -1324,7 +1294,7 @@ struct route_map_rule_cmd route_set_weight_cmd =
/* Set metric to attribute. */
static route_map_result_t
route_set_metric (void *rule, struct prefix *prefix,
route_set_metric (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct rmap_value *rv;
@ -1347,7 +1317,7 @@ route_set_metric (void *rule, struct prefix *prefix,
}
/* Set metric rule structure. */
struct route_map_rule_cmd route_set_metric_cmd =
struct route_map_rule_cmd route_set_metric_cmd =
{
"metric",
route_set_metric,
@ -1368,7 +1338,7 @@ route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t
if (type == RMAP_BGP)
{
binfo = object;
if (binfo->attr->aspath->refcnt)
new = aspath_dup (binfo->attr->aspath);
else
@ -1412,7 +1382,7 @@ route_set_aspath_prepend_free (void *rule)
/* Set as-path prepend rule structure. */
struct route_map_rule_cmd route_set_aspath_prepend_cmd =
struct route_map_rule_cmd route_set_aspath_prepend_cmd =
{
"as-path prepend",
route_set_aspath_prepend,
@ -1446,7 +1416,7 @@ route_set_aspath_exclude (void *rule, struct prefix *dummy, route_map_object_t t
}
/* Set ASn exlude rule structure. */
struct route_map_rule_cmd route_set_aspath_exclude_cmd =
struct route_map_rule_cmd route_set_aspath_exclude_cmd =
{
"as-path exclude",
route_set_aspath_exclude,
@ -1473,7 +1443,7 @@ route_set_community (void *rule, struct prefix *prefix,
struct community *new = NULL;
struct community *old;
struct community *merge;
if (type == RMAP_BGP)
{
rcs = rule;
@ -1496,8 +1466,8 @@ route_set_community (void *rule, struct prefix *prefix,
if (rcs->additive && old)
{
merge = community_merge (community_dup (old), rcs->com);
/* HACK: if the old community is not intern'd,
/* HACK: if the old community is not intern'd,
* we should free it here, or all reference to it may be lost.
* Really need to cleanup attribute caching sometime.
*/
@ -1508,7 +1478,7 @@ route_set_community (void *rule, struct prefix *prefix,
}
else
new = community_dup (rcs->com);
/* will be interned by caller if required */
attr->community = new;
@ -1527,7 +1497,7 @@ route_set_community_compile (const char *arg)
char *sp;
int additive = 0;
int none = 0;
if (strcmp (arg, "none") == 0)
none = 1;
else
@ -1549,12 +1519,12 @@ route_set_community_compile (const char *arg)
if (! com)
return NULL;
}
rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
rcs->com = com;
rcs->additive = additive;
rcs->none = none;
return rcs;
}
@ -1570,7 +1540,7 @@ route_set_community_free (void *rule)
}
/* Set community rule structure. */
struct route_map_rule_cmd route_set_community_cmd =
struct route_map_rule_cmd route_set_community_cmd =
{
"community",
route_set_community,
@ -1683,10 +1653,10 @@ route_set_ecommunity (void *rule, struct prefix *prefix,
{
ecom = rule;
bgp_info = object;
if (! ecom)
return RMAP_OKAY;
/* We assume additive for Extended Community. */
old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
@ -1731,7 +1701,7 @@ route_set_ecommunity_free (void *rule)
}
/* Set community rule structure. */
struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
{
"extcommunity rt",
route_set_ecommunity,
@ -1750,12 +1720,12 @@ route_set_ecommunity_soo_compile (const char *arg)
ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
if (! ecom)
return NULL;
return ecommunity_intern (ecom);
}
/* Set community rule structure. */
struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
{
"extcommunity soo",
route_set_ecommunity,
@ -1776,7 +1746,7 @@ route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, vo
{
origin = rule;
bgp_info = object;
bgp_info->attr->origin = *origin;
}
@ -1809,7 +1779,7 @@ route_set_origin_free (void *rule)
}
/* Set origin rule structure. */
struct route_map_rule_cmd route_set_origin_cmd =
struct route_map_rule_cmd route_set_origin_cmd =
{
"origin",
route_set_origin,
@ -1850,7 +1820,7 @@ route_set_atomic_aggregate_free (void *rule)
}
/* Set atomic aggregate rule structure. */
struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
{
"atomic-aggregate",
route_set_atomic_aggregate,
@ -1866,7 +1836,7 @@ struct aggregator
};
static route_map_result_t
route_set_aggregator_as (void *rule, struct prefix *prefix,
route_set_aggregator_as (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct bgp_info *bgp_info;
@ -1878,7 +1848,7 @@ route_set_aggregator_as (void *rule, struct prefix *prefix,
bgp_info = object;
aggregator = rule;
ae = bgp_attr_extra_get (bgp_info->attr);
ae->aggregator_as = aggregator->as;
ae->aggregator_addr = aggregator->address;
bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
@ -1909,7 +1879,7 @@ route_set_aggregator_as_free (void *rule)
XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
}
struct route_map_rule_cmd route_set_aggregator_as_cmd =
struct route_map_rule_cmd route_set_aggregator_as_cmd =
{
"aggregator as",
route_set_aggregator_as,
@ -1922,7 +1892,7 @@ static route_map_result_t
route_set_tag (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
u_short *tag;
route_tag_t *tag;
struct bgp_info *bgp_info;
struct attr_extra *ae;
@ -1940,47 +1910,13 @@ route_set_tag (void *rule, struct prefix *prefix,
return RMAP_OKAY;
}
/* Route map `tag' compile function. Given string is converted to u_short. */
static void *
route_set_tag_compile (const char *arg)
{
u_short *tag;
u_short tmp;
/* tag value shoud be integer. */
if (! all_digit (arg))
return NULL;
tmp = atoi(arg);
if (tmp < 1)
return NULL;
tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short));
if (!tag)
return tag;
*tag = tmp;
return tag;
}
/* Free route map's tag value. */
static void
route_set_tag_free (void *rule)
{
XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
}
/* Route map commands for tag set. */
struct route_map_rule_cmd route_set_tag_cmd =
static struct route_map_rule_cmd route_set_tag_cmd =
{
"tag",
route_set_tag,
route_set_tag_compile,
route_set_tag_free,
route_map_rule_tag_compile,
route_map_rule_tag_free,
};
@ -1988,7 +1924,7 @@ struct route_map_rule_cmd route_set_tag_cmd =
/* `match ipv6 address IP_ACCESS_LIST' */
static route_map_result_t
route_match_ipv6_address (void *rule, struct prefix *prefix,
route_match_ipv6_address (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct access_list *alist;
@ -1998,7 +1934,7 @@ route_match_ipv6_address (void *rule, struct prefix *prefix,
alist = access_list_lookup (AFI_IP6, (char *) rule);
if (alist == NULL)
return RMAP_NOMATCH;
return (access_list_apply (alist, prefix) == FILTER_DENY ?
RMAP_NOMATCH : RMAP_MATCH);
}
@ -2029,7 +1965,7 @@ struct route_map_rule_cmd route_match_ipv6_address_cmd =
/* `match ipv6 next-hop IP_ADDRESS' */
static route_map_result_t
route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct in6_addr *addr = rule;
@ -2038,10 +1974,10 @@ route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
if (type == RMAP_BGP)
{
bgp_info = object;
if (!bgp_info->attr->extra)
return RMAP_NOMATCH;
if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, addr))
return RMAP_MATCH;
@ -2090,7 +2026,7 @@ struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
/* `match ipv6 address prefix-list PREFIX_LIST' */
static route_map_result_t
route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct prefix_list *plist;
@ -2100,7 +2036,7 @@ route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
plist = prefix_list_lookup (AFI_IP6, (char *) rule);
if (plist == NULL)
return RMAP_NOMATCH;
return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
RMAP_NOMATCH : RMAP_MATCH);
}
@ -2131,7 +2067,7 @@ struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
/* Set nexthop to object. ojbect must be pointer to struct attr. */
static route_map_result_t
route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct in6_addr *address;
@ -2142,8 +2078,8 @@ route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
/* Fetch routemap's rule information. */
address = rule;
bgp_info = object;
/* Set next hop value. */
/* Set next hop value. */
(bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
/* Set nexthop length. */
@ -2259,7 +2195,7 @@ struct route_map_rule_cmd route_set_ipv6_nexthop_prefer_global_cmd =
/* Set nexthop to object. ojbect must be pointer to struct attr. */
static route_map_result_t
route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct in6_addr *address;
@ -2270,10 +2206,10 @@ route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
/* Fetch routemap's rule information. */
address = rule;
bgp_info = object;
/* Set next hop value. */
/* Set next hop value. */
(bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
/* Set nexthop length. */
if (bgp_info->attr->extra->mp_nexthop_len != BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
bgp_info->attr->extra->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
@ -2418,7 +2354,7 @@ struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd =
/* `set vpnv4 nexthop A.B.C.D' */
static route_map_result_t
route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct in_addr *address;
@ -2429,8 +2365,8 @@ route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
/* Fetch routemap's rule information. */
address = rule;
bgp_info = object;
/* Set next hop value. */
/* Set next hop value. */
(bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
(bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_len = 4;
}
@ -2481,11 +2417,11 @@ route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t t
struct in_addr *address;
struct bgp_info *bgp_info;
if (type == RMAP_BGP)
if (type == RMAP_BGP)
{
address = rule;
bgp_info = object;
bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
(bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
}
@ -2521,7 +2457,7 @@ route_set_originator_id_free (void *rule)
}
/* Set originator-id rule structure. */
struct route_map_rule_cmd route_set_originator_id_cmd =
struct route_map_rule_cmd route_set_originator_id_cmd =
{
"originator-id",
route_set_originator_id,
@ -2879,6 +2815,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;
}
@ -2915,6 +2855,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
}
}
}
@ -3718,7 +3662,7 @@ DEFUN (set_aggregator_as,
int ret;
struct in_addr address;
char *argstr;
ret = inet_aton (argv[idx_ipv4]->arg, &address);
if (ret == 0)
{
@ -3757,7 +3701,7 @@ DEFUN (no_set_aggregator_as,
if (argc <= idx_asn)
return generic_set_delete (vty, vty->index, "aggregator as", NULL);
ret = inet_aton (argv[idx_ip]->arg, &address);
if (ret == 0)
{
@ -3777,7 +3721,6 @@ DEFUN (no_set_aggregator_as,
return ret;
}
#ifdef HAVE_IPV6
DEFUN (match_ipv6_next_hop,
match_ipv6_next_hop_cmd,

View File

@ -140,7 +140,6 @@ conf_copy (struct peer *dst, struct peer *src, afi_t afi, safi_t safi)
dst->bgp = src->bgp;
dst->sort = src->sort;
dst->as = src->as;
dst->weight = src->weight;
dst->v_routeadv = src->v_routeadv;
dst->flags = src->flags;
dst->af_flags[afi][safi] = src->af_flags[afi][safi];

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

@ -702,9 +702,9 @@ DEFUN (router_bgp,
{
name = argv[idx_vrf]->arg;
if (!strcmp(argv[idx_view_vrf]->text, "vrf"))
if (!strcmp(argv[idx_view_vrf]->text, "vrf"))
inst_type = BGP_INSTANCE_TYPE_VRF;
else if (!strcmp(argv[idx_view_vrf]->text, "view"))
else if (!strcmp(argv[idx_view_vrf]->text, "view"))
inst_type = BGP_INSTANCE_TYPE_VIEW;
}
@ -1999,7 +1999,7 @@ DEFUN (bgp_bestpath_med,
{
int idx_med_knob = 3;
struct bgp *bgp;
bgp = vty->index;
if (strncmp (argv[idx_med_knob]->arg, "confed", 1) == 0)
@ -2024,7 +2024,7 @@ DEFUN (bgp_bestpath_med2,
"Compare MED among confederation paths\n")
{
struct bgp *bgp;
bgp = vty->index;
bgp_flag_set (bgp, BGP_FLAG_MED_CONFED);
bgp_flag_set (bgp, BGP_FLAG_MED_MISSING_AS_WORST);
@ -2048,7 +2048,7 @@ DEFUN (no_bgp_bestpath_med,
struct bgp *bgp;
bgp = vty->index;
if (strncmp (argv[idx_med_knob]->arg, "confed", 1) == 0)
bgp_flag_unset (bgp, BGP_FLAG_MED_CONFED);
else
@ -2070,7 +2070,7 @@ DEFUN (no_bgp_bestpath_med2,
"Treat missing MED as the least preferred one\n")
{
struct bgp *bgp;
bgp = vty->index;
bgp_flag_unset (bgp, BGP_FLAG_MED_CONFED);
bgp_flag_unset (bgp, BGP_FLAG_MED_MISSING_AS_WORST);
@ -2571,7 +2571,7 @@ DEFUN (no_bgp_disable_connected_route_check,
static int
peer_remote_as_vty (struct vty *vty, const char *peer_str,
peer_remote_as_vty (struct vty *vty, const char *peer_str,
const char *as_str, afi_t afi, safi_t safi)
{
int ret;
@ -3318,7 +3318,7 @@ DEFUN (no_neighbor_set_peer_group,
}
static int
peer_flag_modify_vty (struct vty *vty, const char *ip_str,
peer_flag_modify_vty (struct vty *vty, const char *ip_str,
u_int16_t flag, int set)
{
int ret;
@ -4101,7 +4101,7 @@ DEFUN (neighbor_attr_unchanged4,
DEFUN (no_neighbor_attr_unchanged,
no_neighbor_attr_unchanged_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> attribute-unchanged [as-path] [next-hop] [med]",
NO_STR
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"BGP attribute is propagated unchanged to this neighbor\n"
@ -4223,7 +4223,7 @@ DEFUN (no_neighbor_attr_unchanged4,
/* EBGP multihop configuration. */
static int
peer_ebgp_multihop_set_vty (struct vty *vty, const char *ip_str,
peer_ebgp_multihop_set_vty (struct vty *vty, const char *ip_str,
const char *ttl_str)
{
struct peer *peer;
@ -4245,7 +4245,7 @@ peer_ebgp_multihop_set_vty (struct vty *vty, const char *ip_str,
}
static int
peer_ebgp_multihop_unset_vty (struct vty *vty, const char *ip_str)
peer_ebgp_multihop_unset_vty (struct vty *vty, const char *ip_str)
{
struct peer *peer;
@ -4371,7 +4371,7 @@ DEFUN (no_neighbor_description,
/* Neighbor update-source. */
static int
peer_update_source_vty (struct vty *vty, const char *peer_str,
peer_update_source_vty (struct vty *vty, const char *peer_str,
const char *source_str)
{
struct peer *peer;
@ -4431,8 +4431,8 @@ DEFUN (no_neighbor_update_source,
}
static int
peer_default_originate_set_vty (struct vty *vty, const char *peer_str,
afi_t afi, safi_t safi,
peer_default_originate_set_vty (struct vty *vty, const char *peer_str,
afi_t afi, safi_t safi,
const char *rmap, int set)
{
int ret;
@ -4496,7 +4496,7 @@ DEFUN (no_neighbor_default_originate,
/* Set neighbor's BGP port. */
static int
peer_port_vty (struct vty *vty, const char *ip_str, int afi,
peer_port_vty (struct vty *vty, const char *ip_str, int afi,
const char *port_str)
{
struct peer *peer;
@ -4508,7 +4508,7 @@ peer_port_vty (struct vty *vty, const char *ip_str, int afi,
return CMD_WARNING;
if (! port_str)
{
{
sp = getservbyname ("bgp", "tcp");
port = (sp == NULL) ? BGP_PORT_DEFAULT : ntohs (sp->s_port);
}
@ -4552,7 +4552,8 @@ DEFUN (no_neighbor_port,
/* neighbor weight. */
static int
peer_weight_set_vty (struct vty *vty, const char *ip_str,
peer_weight_set_vty (struct vty *vty, const char *ip_str,
afi_t afi, safi_t safi,
const char *weight_str)
{
int ret;
@ -4565,12 +4566,13 @@ peer_weight_set_vty (struct vty *vty, const char *ip_str,
VTY_GET_INTEGER_RANGE("weight", weight, weight_str, 0, 65535);
ret = peer_weight_set (peer, weight);
ret = peer_weight_set (peer, afi, safi, weight);
return bgp_vty_return (vty, ret);
}
static int
peer_weight_unset_vty (struct vty *vty, const char *ip_str)
peer_weight_unset_vty (struct vty *vty, const char *ip_str,
afi_t afi, safi_t safi)
{
int ret;
struct peer *peer;
@ -4579,7 +4581,7 @@ peer_weight_unset_vty (struct vty *vty, const char *ip_str)
if (! peer)
return CMD_WARNING;
ret = peer_weight_unset (peer);
ret = peer_weight_unset (peer, afi, safi);
return bgp_vty_return (vty, ret);
}
@ -4593,7 +4595,11 @@ DEFUN (neighbor_weight,
{
int idx_peer = 1;
int idx_number = 3;
return peer_weight_set_vty (vty, argv[idx_peer]->arg, argv[idx_number]->arg);
return peer_weight_set_vty (vty,
argv[idx_peer]->arg,
bgp_node_afi (vty),
bgp_node_safi (vty),
argv[idx_number]->arg);
}
DEFUN (no_neighbor_weight,
@ -4606,7 +4612,7 @@ DEFUN (no_neighbor_weight,
"default weight\n")
{
int idx_peer = 2;
return peer_weight_unset_vty (vty, argv[idx_peer]->arg);
return peer_weight_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty), bgp_node_safi (vty));
}
@ -4658,7 +4664,7 @@ DEFUN (no_neighbor_strict_capability,
}
static int
peer_timers_set_vty (struct vty *vty, const char *ip_str,
peer_timers_set_vty (struct vty *vty, const char *ip_str,
const char *keep_str, const char *hold_str)
{
int ret;
@ -4724,7 +4730,7 @@ DEFUN (no_neighbor_timers,
static int
peer_timers_connect_set_vty (struct vty *vty, const char *ip_str,
peer_timers_connect_set_vty (struct vty *vty, const char *ip_str,
const char *time_str)
{
int ret;
@ -4787,8 +4793,8 @@ DEFUN (no_neighbor_timers_connect,
static int
peer_advertise_interval_vty (struct vty *vty, const char *ip_str,
const char *time_str, int set)
peer_advertise_interval_vty (struct vty *vty, const char *ip_str,
const char *time_str, int set)
{
int ret;
struct peer *peer;
@ -4928,7 +4934,7 @@ DEFUN (no_neighbor_interface,
/* Set distribute list to the peer. */
static int
peer_distribute_set_vty (struct vty *vty, const char *ip_str,
peer_distribute_set_vty (struct vty *vty, const char *ip_str,
afi_t afi, safi_t safi,
const char *name_str, const char *direct_str)
{
@ -5015,7 +5021,7 @@ DEFUN (no_neighbor_distribute_list,
/* Set prefix list to the peer. */
static int
peer_prefix_list_set_vty (struct vty *vty, const char *ip_str, afi_t afi,
safi_t safi, const char *name_str,
safi_t safi, const char *name_str,
const char *direct_str)
{
int ret;
@ -5048,7 +5054,7 @@ peer_prefix_list_unset_vty (struct vty *vty, const char *ip_str, afi_t afi,
peer = peer_and_group_lookup_vty (vty, ip_str);
if (! peer)
return CMD_WARNING;
/* Check filter direction. */
if (strncmp (direct_str, "i", 1) == 0)
direct = FILTER_IN;
@ -5095,7 +5101,7 @@ DEFUN (no_neighbor_prefix_list,
}
static int
peer_aslist_set_vty (struct vty *vty, const char *ip_str,
peer_aslist_set_vty (struct vty *vty, const char *ip_str,
afi_t afi, safi_t safi,
const char *name_str, const char *direct_str)
{
@ -5119,7 +5125,7 @@ peer_aslist_set_vty (struct vty *vty, const char *ip_str,
}
static int
peer_aslist_unset_vty (struct vty *vty, const char *ip_str,
peer_aslist_unset_vty (struct vty *vty, const char *ip_str,
afi_t afi, safi_t safi,
const char *direct_str)
{
@ -5178,7 +5184,7 @@ DEFUN (no_neighbor_filter_list,
/* Set route-map to the peer. */
static int
peer_route_map_set_vty (struct vty *vty, const char *ip_str,
peer_route_map_set_vty (struct vty *vty, const char *ip_str,
afi_t afi, safi_t safi,
const char *name_str, const char *direct_str)
{
@ -5322,7 +5328,7 @@ DEFUN (no_neighbor_unsuppress_map,
static int
peer_maximum_prefix_set_vty (struct vty *vty, const char *ip_str, afi_t afi,
safi_t safi, const char *num_str,
safi_t safi, const char *num_str,
const char *threshold_str, int warning,
const char *restart_str)
{
@ -5489,7 +5495,7 @@ DEFUN (no_neighbor_maximum_prefix,
return peer_maximum_prefix_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty),
bgp_node_safi (vty));
}
/* "neighbor allowas-in" */
DEFUN (neighbor_allowas_in,
@ -5559,7 +5565,7 @@ DEFUN (neighbor_ttl_security,
peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg);
if (! peer)
return CMD_WARNING;
VTY_GET_INTEGER_RANGE ("", gtsm_hops, argv[idx_number]->arg, 1, 254);
/*
@ -6170,7 +6176,7 @@ DEFUN (show_bgp_views,
vty_out (vty, "BGP Multiple Instance is not enabled%s", VTY_NEWLINE);
return CMD_WARNING;
}
vty_out (vty, "Defined BGP views:%s", VTY_NEWLINE);
for (ALL_LIST_ELEMENTS_RO(inst, node, bgp))
{
@ -6181,7 +6187,7 @@ DEFUN (show_bgp_views,
bgp->name ? bgp->name : "(null)",
bgp->as, VTY_NEWLINE);
}
return CMD_SUCCESS;
}
@ -6280,7 +6286,7 @@ DEFUN (show_bgp_vrfs,
json_object_int_add(json, "totalVrfs", count);
vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
json_object_free(json);
}
else
@ -6302,14 +6308,14 @@ DEFUN (show_bgp_memory,
{
char memstrbuf[MTYPE_MEMSTR_LEN];
unsigned long count;
/* RIB related usage stats */
count = mtype_stats_alloc (MTYPE_BGP_NODE);
vty_out (vty, "%ld RIB nodes, using %s of memory%s", count,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
count * sizeof (struct bgp_node)),
VTY_NEWLINE);
count = mtype_stats_alloc (MTYPE_BGP_ROUTE);
vty_out (vty, "%ld BGP routes, using %s of memory%s", count,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
@ -6320,7 +6326,7 @@ DEFUN (show_bgp_memory,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
count * sizeof (struct bgp_info_extra)),
VTY_NEWLINE);
if ((count = mtype_stats_alloc (MTYPE_BGP_STATIC)))
vty_out (vty, "%ld Static routes, using %s of memory%s", count,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
@ -6332,7 +6338,7 @@ DEFUN (show_bgp_memory,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
count * sizeof (struct bpacket)),
VTY_NEWLINE);
/* Adj-In/Out */
if ((count = mtype_stats_alloc (MTYPE_BGP_ADJ_IN)))
vty_out (vty, "%ld Adj-In entries, using %s of memory%s", count,
@ -6344,7 +6350,7 @@ DEFUN (show_bgp_memory,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
count * sizeof (struct bgp_adj_out)),
VTY_NEWLINE);
if ((count = mtype_stats_alloc (MTYPE_BGP_NEXTHOP_CACHE)))
vty_out (vty, "%ld Nexthop cache entries, using %s of memory%s", count,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
@ -6359,32 +6365,32 @@ DEFUN (show_bgp_memory,
/* Attributes */
count = attr_count();
vty_out (vty, "%ld BGP attributes, using %s of memory%s", count,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
count * sizeof(struct attr)),
vty_out (vty, "%ld BGP attributes, using %s of memory%s", count,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
count * sizeof(struct attr)),
VTY_NEWLINE);
if ((count = mtype_stats_alloc (MTYPE_ATTR_EXTRA)))
vty_out (vty, "%ld BGP extra attributes, using %s of memory%s", count,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
count * sizeof(struct attr_extra)),
vty_out (vty, "%ld BGP extra attributes, using %s of memory%s", count,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
count * sizeof(struct attr_extra)),
VTY_NEWLINE);
if ((count = attr_unknown_count()))
vty_out (vty, "%ld unknown attributes%s", count, VTY_NEWLINE);
/* AS_PATH attributes */
count = aspath_count ();
vty_out (vty, "%ld BGP AS-PATH entries, using %s of memory%s", count,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
count * sizeof (struct aspath)),
VTY_NEWLINE);
count = mtype_stats_alloc (MTYPE_AS_SEG);
vty_out (vty, "%ld BGP AS-PATH segments, using %s of memory%s", count,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
count * sizeof (struct assegment)),
VTY_NEWLINE);
/* Other attributes */
if ((count = community_count ()))
vty_out (vty, "%ld BGP community entries, using %s of memory%s", count,
@ -6396,26 +6402,26 @@ DEFUN (show_bgp_memory,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
count * sizeof (struct ecommunity)),
VTY_NEWLINE);
if ((count = mtype_stats_alloc (MTYPE_CLUSTER)))
vty_out (vty, "%ld Cluster lists, using %s of memory%s", count,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
count * sizeof (struct cluster_list)),
VTY_NEWLINE);
/* Peer related usage */
count = mtype_stats_alloc (MTYPE_BGP_PEER);
vty_out (vty, "%ld peers, using %s of memory%s", count,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
count * sizeof (struct peer)),
VTY_NEWLINE);
if ((count = mtype_stats_alloc (MTYPE_PEER_GROUP)))
vty_out (vty, "%ld peer groups, using %s of memory%s", count,
mtype_memstr (memstrbuf, sizeof (memstrbuf),
count * sizeof (struct peer_group)),
VTY_NEWLINE);
/* Other */
if ((count = mtype_stats_alloc (MTYPE_HASH)))
vty_out (vty, "%ld hash tables, using %s of memory%s", count,
@ -6614,7 +6620,7 @@ bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi,
vty_out (vty, "%s%s", header, VTY_NEWLINE);
}
}
count++;
if (use_json)
@ -6724,7 +6730,7 @@ bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi,
json_object_int_add(json, "totalPeers", count);
json_object_int_add(json, "dynamicPeers", dn_count);
vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
json_object_free(json);
}
else
@ -6976,8 +6982,6 @@ bgp_show_peer_afi (struct vty *vty, struct peer *p, afi_t afi, safi_t safi,
{
json_addr = json_object_new_object();
json_af = json_object_new_object();
json_prefA = json_object_new_object();
json_prefB = json_object_new_object();
filter = &p->filter[afi][safi];
if (peer_group_active(p))
@ -6997,6 +7001,7 @@ bgp_show_peer_afi (struct vty *vty, struct peer *p, afi_t afi, safi_t safi,
|| CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV))
{
json_object_int_add(json_af, "orfType", ORF_TYPE_PREFIX);
json_prefA = json_object_new_object();
bgp_show_peer_afi_orf_cap (vty, p, afi, safi,
PEER_CAP_ORF_PREFIX_SM_ADV,
PEER_CAP_ORF_PREFIX_RM_ADV,
@ -7011,6 +7016,7 @@ bgp_show_peer_afi (struct vty *vty, struct peer *p, afi_t afi, safi_t safi,
|| CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV))
{
json_object_int_add(json_af, "orfOldType", ORF_TYPE_PREFIX_OLD);
json_prefB = json_object_new_object();
bgp_show_peer_afi_orf_cap (vty, p, afi, safi,
PEER_CAP_ORF_PREFIX_SM_ADV,
PEER_CAP_ORF_PREFIX_RM_ADV,
@ -7026,6 +7032,8 @@ bgp_show_peer_afi (struct vty *vty, struct peer *p, afi_t afi, safi_t safi,
|| CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV)
|| CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV))
json_object_object_add(json_addr, "afDependentCap", json_af);
else
json_object_free(json_af);
sprintf (orf_pfx_name, "%s.%d.%d", p->host, afi, safi);
orf_pfx_count = prefix_bgp_show_prefix_list (NULL, afi, orf_pfx_name, use_json);
@ -7633,7 +7641,7 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
if (CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION)
&& bgp_confederation_peers_check (bgp, p->as))
vty_out (vty, " Neighbor under common administration%s", VTY_NEWLINE);
/* Status. */
vty_out (vty, " BGP state = %s", LOOKUP (bgp_status_msg, p->status));
@ -7665,7 +7673,7 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
}
}
/* Capability. */
if (p->status == Established)
if (p->status == Established)
{
if (p->cap
|| p->afc_adv[AFI_IP][SAFI_UNICAST]
@ -7748,6 +7756,8 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV) ||
CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_RCV))
json_object_object_add(json_add, print_store, json_sub);
else
json_object_free(json_sub);
}
json_object_object_add(json_cap, "addPath", json_add);
@ -7772,7 +7782,6 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
json_object *json_nxt = NULL;
const char *print_store;
json_nxt = json_object_new_object();
if (CHECK_FLAG (p->cap, PEER_CAP_ENHE_ADV) && CHECK_FLAG (p->cap, PEER_CAP_ENHE_RCV))
json_object_string_add(json_cap, "extendedNexthop", "advertisedAndReceived");
@ -7783,6 +7792,8 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
if (CHECK_FLAG (p->cap, PEER_CAP_ENHE_RCV))
{
json_nxt = json_object_new_object();
for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
{
if (CHECK_FLAG (p->af_cap[AFI_IP][safi], PEER_CAP_ENHE_AF_RCV))
@ -7880,7 +7891,10 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
}
}
if (! restart_af_count)
{
json_object_string_add(json_cap, "addressFamiliesByPeer", "none");
json_object_free(json_restart);
}
else
json_object_object_add(json_cap, "addressFamiliesByPeer", json_restart);
}
@ -8154,7 +8168,7 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
if (p->t_gr_restart)
vty_out (vty, " The remaining time of restart timer is %ld%s",
thread_timer_remain_second (p->t_gr_restart), VTY_NEWLINE);
if (p->t_gr_stale)
vty_out (vty, " The remaining time of stalepath timer is %ld%s",
thread_timer_remain_second (p->t_gr_stale), VTY_NEWLINE);
@ -8215,11 +8229,6 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
else if (p->update_source)
json_object_string_add(json_neigh, "updateSource", sockunion2str (p->update_source, buf1, SU_ADDRSTRLEN));
}
/* Default weight */
if (CHECK_FLAG (p->config, PEER_CONFIG_WEIGHT))
json_object_int_add(json_neigh, "defaultWeight", p->weight);
}
else
{
@ -8238,10 +8247,6 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
vty_out (vty, "%s", VTY_NEWLINE);
}
/* Default weight */
if (CHECK_FLAG (p->config, PEER_CONFIG_WEIGHT))
vty_out (vty, " Default weight %d%s", p->weight, VTY_NEWLINE);
vty_out (vty, "%s", VTY_NEWLINE);
}
@ -8414,7 +8419,7 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
ntohs (p->su_local->sin.sin_port),
VTY_NEWLINE);
}
/* Remote address. */
if (p->su_remote)
{
@ -8582,7 +8587,7 @@ bgp_show_neighbor (struct vty *vty, struct bgp *bgp, enum show_type type,
if (use_json)
{
vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
json_object_free(json);
}
else
@ -8674,7 +8679,7 @@ bgp_show_neighbor_vty (struct vty *vty, const char *name,
if (use_json)
{
json_object_boolean_true_add(json, "bgpNoSuchInstance");
vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
json_object_free(json);
}
else
@ -8817,7 +8822,7 @@ DEFUN (show_ip_bgp_community_info,
{
vty_out (vty, "Address Refcnt Community%s", VTY_NEWLINE);
hash_iterate (community_hash (),
hash_iterate (community_hash (),
(void (*) (struct hash_backet *, void *))
community_show_all_iterator,
vty);
@ -10062,7 +10067,7 @@ bgp_vty_init (void)
install_default (BGP_VPNV6_NODE);
install_default (BGP_ENCAP_NODE);
install_default (BGP_ENCAPV6_NODE);
/* "bgp multiple-instance" commands. */
install_element (CONFIG_NODE, &bgp_multiple_instance_cmd);
install_element (CONFIG_NODE, &no_bgp_multiple_instance_cmd);
@ -10155,7 +10160,7 @@ bgp_vty_init (void)
/* "bgp always-compare-med" commands */
install_element (BGP_NODE, &bgp_always_compare_med_cmd);
install_element (BGP_NODE, &no_bgp_always_compare_med_cmd);
/* "bgp deterministic-med" commands */
install_element (BGP_NODE, &bgp_deterministic_med_cmd);
install_element (BGP_NODE, &no_bgp_deterministic_med_cmd);
@ -10167,7 +10172,7 @@ bgp_vty_init (void)
install_element (BGP_NODE, &no_bgp_graceful_restart_stalepath_time_cmd);
install_element (BGP_NODE, &bgp_graceful_restart_restart_time_cmd);
install_element (BGP_NODE, &no_bgp_graceful_restart_restart_time_cmd);
/* "bgp fast-external-failover" commands */
install_element (BGP_NODE, &bgp_fast_external_failover_cmd);
install_element (BGP_NODE, &no_bgp_fast_external_failover_cmd);
@ -10205,7 +10210,7 @@ bgp_vty_init (void)
/* "no bgp default ipv4-unicast" commands. */
install_element (BGP_NODE, &no_bgp_default_ipv4_unicast_cmd);
install_element (BGP_NODE, &bgp_default_ipv4_unicast_cmd);
/* "bgp network import-check" commands. */
install_element (BGP_NODE, &bgp_network_import_check_cmd);
install_element (BGP_NODE, &bgp_network_import_check_exact_cmd);
@ -10311,7 +10316,7 @@ bgp_vty_init (void)
install_element (BGP_VPNV6_NODE, &no_neighbor_set_peer_group_cmd);
install_element (BGP_ENCAP_NODE, &no_neighbor_set_peer_group_cmd);
install_element (BGP_ENCAPV6_NODE, &no_neighbor_set_peer_group_cmd);
/* "neighbor softreconfiguration inbound" commands.*/
install_element (BGP_NODE, &neighbor_soft_reconfiguration_cmd);
install_element (BGP_NODE, &no_neighbor_soft_reconfiguration_cmd);
@ -10729,6 +10734,23 @@ bgp_vty_init (void)
install_element (BGP_NODE, &neighbor_weight_cmd);
install_element (BGP_NODE, &no_neighbor_weight_cmd);
install_element (BGP_IPV4_NODE, &neighbor_weight_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_weight_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_weight_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_weight_cmd);
install_element (BGP_IPV6_NODE, &neighbor_weight_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_weight_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_weight_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_weight_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_weight_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_weight_cmd);
install_element (BGP_VPNV6_NODE, &neighbor_weight_cmd);
install_element (BGP_VPNV6_NODE, &no_neighbor_weight_cmd);
install_element (BGP_ENCAP_NODE, &neighbor_weight_cmd);
install_element (BGP_ENCAP_NODE, &no_neighbor_weight_cmd);
install_element (BGP_ENCAPV6_NODE, &neighbor_weight_cmd);
install_element (BGP_ENCAPV6_NODE, &no_neighbor_weight_cmd);
/* "neighbor override-capability" commands. */
install_element (BGP_NODE, &neighbor_override_capability_cmd);
install_element (BGP_NODE, &no_neighbor_override_capability_cmd);
@ -10988,60 +11010,38 @@ bgp_vty_init (void)
install_element (VIEW_NODE, &show_bgp_updgrps_adj_s_cmd);
install_element (VIEW_NODE, &show_bgp_instance_updgrps_adj_s_cmd);
install_element (VIEW_NODE, &show_bgp_updgrps_afi_adj_s_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_summary_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_updgrps_cmd);
install_element (RESTRICTED_NODE, &show_bgp_instance_all_ipv6_updgrps_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_updgrps_adj_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_instance_updgrps_adj_cmd);
install_element (RESTRICTED_NODE, &show_bgp_updgrps_adj_cmd);
install_element (RESTRICTED_NODE, &show_bgp_instance_updgrps_adj_cmd);
install_element (RESTRICTED_NODE, &show_bgp_updgrps_afi_adj_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_updgrps_adj_s_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_instance_updgrps_adj_s_cmd);
install_element (RESTRICTED_NODE, &show_bgp_updgrps_adj_s_cmd);
install_element (RESTRICTED_NODE, &show_bgp_instance_updgrps_adj_s_cmd);
install_element (RESTRICTED_NODE, &show_bgp_updgrps_afi_adj_s_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_summary_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_updgrps_cmd);
install_element (ENABLE_NODE, &show_bgp_instance_all_ipv6_updgrps_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_updgrps_adj_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_instance_updgrps_adj_cmd);
install_element (ENABLE_NODE, &show_bgp_updgrps_adj_cmd);
install_element (ENABLE_NODE, &show_bgp_instance_updgrps_adj_cmd);
install_element (ENABLE_NODE, &show_bgp_updgrps_afi_adj_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_updgrps_adj_s_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_instance_updgrps_adj_s_cmd);
install_element (ENABLE_NODE, &show_bgp_updgrps_adj_s_cmd);
install_element (ENABLE_NODE, &show_bgp_instance_updgrps_adj_s_cmd);
install_element (ENABLE_NODE, &show_bgp_updgrps_afi_adj_s_cmd);
install_element (VIEW_NODE, &show_ip_bgp_summary_cmd);
install_element (VIEW_NODE, &show_ip_bgp_updgrps_cmd);
install_element (VIEW_NODE, &show_bgp_instance_all_ipv6_updgrps_cmd);
install_element (VIEW_NODE, &show_ip_bgp_updgrps_adj_cmd);
install_element (VIEW_NODE, &show_ip_bgp_instance_updgrps_adj_cmd);
install_element (VIEW_NODE, &show_bgp_updgrps_adj_cmd);
install_element (VIEW_NODE, &show_bgp_instance_updgrps_adj_cmd);
install_element (VIEW_NODE, &show_bgp_updgrps_afi_adj_cmd);
install_element (VIEW_NODE, &show_ip_bgp_updgrps_adj_s_cmd);
install_element (VIEW_NODE, &show_ip_bgp_instance_updgrps_adj_s_cmd);
install_element (VIEW_NODE, &show_bgp_updgrps_adj_s_cmd);
install_element (VIEW_NODE, &show_bgp_instance_updgrps_adj_s_cmd);
install_element (VIEW_NODE, &show_bgp_updgrps_afi_adj_s_cmd);
/* "show ip bgp neighbors" commands. */
install_element (VIEW_NODE, &show_ip_bgp_neighbors_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_neighbors_cmd);
/* "show ip bgp peer-group" commands. */
install_element (VIEW_NODE, &show_ip_bgp_peer_groups_cmd);
install_element (VIEW_NODE, &show_ip_bgp_instance_peer_groups_cmd);
install_element (VIEW_NODE, &show_ip_bgp_peer_group_cmd);
install_element (VIEW_NODE, &show_ip_bgp_instance_peer_group_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_peer_groups_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_instance_peer_groups_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_peer_group_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_instance_peer_group_cmd);
/* "show ip bgp paths" commands. */
install_element (VIEW_NODE, &show_ip_bgp_paths_cmd);
install_element (VIEW_NODE, &show_ip_bgp_ipv4_paths_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_paths_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_ipv4_paths_cmd);
/* "show ip bgp community" commands. */
install_element (VIEW_NODE, &show_ip_bgp_community_info_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_community_info_cmd);
/* "show ip bgp attribute-info" commands. */
install_element (VIEW_NODE, &show_ip_bgp_attr_info_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_attr_info_cmd);
/* "redistribute" commands. */
install_element (BGP_NODE, &bgp_redistribute_ipv4_cmd);
@ -11083,19 +11083,13 @@ bgp_vty_init (void)
/* "show bgp memory" commands. */
install_element (VIEW_NODE, &show_bgp_memory_cmd);
install_element (RESTRICTED_NODE, &show_bgp_memory_cmd);
install_element (ENABLE_NODE, &show_bgp_memory_cmd);
/* "show bgp views" commands. */
install_element (VIEW_NODE, &show_bgp_views_cmd);
install_element (RESTRICTED_NODE, &show_bgp_views_cmd);
install_element (ENABLE_NODE, &show_bgp_views_cmd);
/* "show bgp vrfs" commands. */
install_element (VIEW_NODE, &show_bgp_vrfs_cmd);
install_element (RESTRICTED_NODE, &show_bgp_vrfs_cmd);
install_element (ENABLE_NODE, &show_bgp_vrfs_cmd);
/* Community-list. */
community_list_vty ();
}
@ -11219,7 +11213,7 @@ community_list_unset_vty (struct vty *vty, int argc, struct cmd_token **argv,
if (argc > 1)
{
// Check the list direct.
// Check the list direct.
if (strncmp (argv[1], "p", 1) == 0)
direct = COMMUNITY_PERMIT;
else if (strncmp (argv[1], "d", 1) == 0)
@ -11396,7 +11390,7 @@ DEFUN (show_ip_community_list_arg,
}
static int
extcommunity_list_set_vty (struct vty *vty, int argc, struct cmd_token **argv,
extcommunity_list_set_vty (struct vty *vty, int argc, struct cmd_token **argv,
int style)
{
/* CHECK ME dwalton finish this
@ -11416,7 +11410,7 @@ extcommunity_list_set_vty (struct vty *vty, int argc, struct cmd_token **argv,
return CMD_WARNING;
}
// All digit name check.
// All digit name check.
if (reject_all_digit_name && all_digit (argv[0]))
{
vty_out (vty, "%% Community name cannot have all digits%s", VTY_NEWLINE);
@ -11431,7 +11425,7 @@ extcommunity_list_set_vty (struct vty *vty, int argc, struct cmd_token **argv,
ret = extcommunity_list_set (bgp_clist, argv[0], str, direct, style);
// Free temporary community list string allocated by argv_concat().
// Free temporary community list string allocated by argv_concat().
if (str)
XFREE (MTYPE_TMP, str);
@ -11726,8 +11720,6 @@ community_list_vty (void)
install_element (CONFIG_NODE, &no_ip_community_list_expanded_all_cmd);
install_element (VIEW_NODE, &show_ip_community_list_cmd);
install_element (VIEW_NODE, &show_ip_community_list_arg_cmd);
install_element (ENABLE_NODE, &show_ip_community_list_cmd);
install_element (ENABLE_NODE, &show_ip_community_list_arg_cmd);
/* Extcommunity-list. */
install_element (CONFIG_NODE, &ip_extcommunity_list_standard_cmd);
@ -11736,6 +11728,4 @@ community_list_vty (void)
install_element (CONFIG_NODE, &no_ip_extcommunity_list_expanded_all_cmd);
install_element (VIEW_NODE, &show_ip_extcommunity_list_cmd);
install_element (VIEW_NODE, &show_ip_extcommunity_list_arg_cmd);
install_element (ENABLE_NODE, &show_ip_extcommunity_list_cmd);
install_element (ENABLE_NODE, &show_ip_extcommunity_list_arg_cmd);
}

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 "bgpd/rfapi/rfapi_backend.h"
# include "bgpd/rfapi/vnc_export_bgp.h"
#endif
/* All information about zebra. */
struct zclient *zclient = NULL;
@ -601,13 +605,13 @@ zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length,
/* Type, flags, message. */
api.type = stream_getc (s);
api.instance = stream_getw (s);
api.flags = stream_getc (s);
api.flags = stream_getl (s);
api.message = stream_getc (s);
/* IPv4 prefix. */
memset (&p, 0, sizeof (struct prefix_ipv4));
p.family = AF_INET;
p.prefixlen = stream_getc (s);
p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, stream_getc (s));
stream_get (&p.prefix, s, PSIZE (p.prefixlen));
/* Nexthop, ifindex, distance, metric. */
@ -636,7 +640,7 @@ zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length,
api.metric = 0;
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
api.tag = stream_getw (s);
api.tag = stream_getl (s);
else
api.tag = 0;
@ -645,7 +649,7 @@ zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length,
if (bgp_debug_zebra((struct prefix *)&p))
{
char buf[2][INET_ADDRSTRLEN];
zlog_debug("Rx IPv4 route add VRF %u %s[%d] %s/%d nexthop %s metric %u tag %d",
zlog_debug("Rx IPv4 route add VRF %u %s[%d] %s/%d nexthop %s metric %u tag %"ROUTE_TAG_PRI,
vrf_id,
zebra_route_string(api.type), api.instance,
inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
@ -677,7 +681,7 @@ zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length,
{
char buf[2][INET_ADDRSTRLEN];
zlog_debug("Rx IPv4 route delete VRF %u %s[%d] %s/%d "
"nexthop %s metric %u tag %d",
"nexthop %s metric %u tag %"ROUTE_TAG_PRI,
vrf_id,
zebra_route_string(api.type), api.instance,
inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
@ -716,13 +720,13 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length,
/* Type, flags, message. */
api.type = stream_getc (s);
api.instance = stream_getw (s);
api.flags = stream_getc (s);
api.flags = stream_getl (s);
api.message = stream_getc (s);
/* IPv6 prefix. */
memset (&p, 0, sizeof (struct prefix_ipv6));
p.family = AF_INET6;
p.prefixlen = stream_getc (s);
p.prefixlen = MIN(IPV6_MAX_PREFIXLEN, stream_getc (s));
stream_get (&p.prefix, s, PSIZE (p.prefixlen));
/* Nexthop, ifindex, distance, metric. */
@ -753,7 +757,7 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length,
api.metric = 0;
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
api.tag = stream_getw (s);
api.tag = stream_getl (s);
else
api.tag = 0;
@ -766,7 +770,7 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length,
if (bgp_debug_zebra((struct prefix *)&p))
{
char buf[2][INET6_ADDRSTRLEN];
zlog_debug("Rx IPv6 route add VRF %u %s[%d] %s/%d nexthop %s metric %u tag %d",
zlog_debug("Rx IPv6 route add VRF %u %s[%d] %s/%d nexthop %s metric %u tag %"ROUTE_TAG_PRI,
vrf_id,
zebra_route_string(api.type), api.instance,
inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
@ -797,7 +801,7 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length,
{
char buf[2][INET6_ADDRSTRLEN];
zlog_debug("Rx IPv6 route delete VRF %u %s[%d] %s/%d "
"nexthop %s metric %u tag %d",
"nexthop %s metric %u tag %"ROUTE_TAG_PRI,
vrf_id,
zebra_route_string(api.type), api.instance,
inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
@ -1199,7 +1203,7 @@ void
bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
afi_t afi, safi_t safi)
{
int flags;
u_int32_t flags;
u_char distance;
struct peer *peer;
struct bgp_info *mpinfo;
@ -1207,7 +1211,7 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
u_int32_t nhcount, metric;
struct bgp_info local_info;
struct bgp_info *info_cp = &local_info;
u_short tag;
route_tag_t tag;
/* Don't try to install if we're not connected to Zebra or Zebra doesn't
* know of this instance.
@ -1372,7 +1376,7 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
if (bgp_debug_zebra(p))
{
int i;
zlog_debug("Tx IPv4 route %s VRF %u %s/%d metric %u tag %d"
zlog_debug("Tx IPv4 route %s VRF %u %s/%d metric %u tag %"ROUTE_TAG_PRI
" count %d", (valid_nh_count ? "add":"delete"),
bgp->vrf_id,
inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
@ -1553,7 +1557,7 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
if (bgp_debug_zebra(p))
{
int i;
zlog_debug("Tx IPv4 route %s VRF %u %s/%d metric %u tag %d",
zlog_debug("Tx IPv4 route %s VRF %u %s/%d metric %u tag %"ROUTE_TAG_PRI,
valid_nh_count ? "add" : "delete", bgp->vrf_id,
inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
p->prefixlen, api.metric, api.tag);
@ -1575,7 +1579,7 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
if (bgp_debug_zebra(p))
{
int i;
zlog_debug("Tx IPv6 route %s VRF %u %s/%d metric %u tag %d",
zlog_debug("Tx IPv6 route %s VRF %u %s/%d metric %u tag %"ROUTE_TAG_PRI,
valid_nh_count ? "add" : "delete", bgp->vrf_id,
inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
p->prefixlen, api.metric, api.tag);
@ -1620,7 +1624,7 @@ bgp_zebra_announce_table (struct bgp *bgp, afi_t afi, safi_t safi)
void
bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
{
int flags;
u_int32_t flags;
struct peer *peer;
peer = info->peer;
@ -1679,7 +1683,7 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
if (bgp_debug_zebra(p))
{
char buf[2][INET_ADDRSTRLEN];
zlog_debug("Tx IPv4 route delete VRF %u %s/%d metric %u tag %d",
zlog_debug("Tx IPv4 route delete VRF %u %s/%d metric %u tag %"ROUTE_TAG_PRI,
peer->bgp->vrf_id,
inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
p->prefixlen, api.metric, api.tag);
@ -1719,7 +1723,7 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
if (bgp_debug_zebra(p))
{
char buf[2][INET6_ADDRSTRLEN];
zlog_debug("Tx IPv6 route delete VRF %u %s/%d metric %u tag %d",
zlog_debug("Tx IPv6 route delete VRF %u %s/%d metric %u tag %"ROUTE_TAG_PRI,
peer->bgp->vrf_id,
inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
p->prefixlen, api.metric, api.tag);
@ -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. */
@ -2103,14 +2121,10 @@ bgp_zebra_init (struct thread_master *master)
zclient->interface_nbr_address_add = bgp_interface_nbr_address_add;
zclient->interface_nbr_address_delete = bgp_interface_nbr_address_delete;
zclient->interface_vrf_update = bgp_interface_vrf_update;
zclient->ipv4_route_add = zebra_read_ipv4;
zclient->ipv4_route_delete = zebra_read_ipv4;
zclient->redistribute_route_ipv4_add = zebra_read_ipv4;
zclient->redistribute_route_ipv4_del = zebra_read_ipv4;
zclient->interface_up = bgp_interface_up;
zclient->interface_down = bgp_interface_down;
zclient->ipv6_route_add = zebra_read_ipv6;
zclient->ipv6_route_delete = zebra_read_ipv6;
zclient->redistribute_route_ipv6_add = zebra_read_ipv6;
zclient->redistribute_route_ipv6_del = zebra_read_ipv6;
zclient->nexthop_update = bgp_read_nexthop_update;

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 "bgpd/rfapi/bgp_rfapi_cfg.h"
#include "bgpd/rfapi/rfapi_backend.h"
#endif
#include "bgpd/bgp_advertise.h"
#include "bgpd/bgp_network.h"
#include "bgpd/bgp_vty.h"
@ -886,7 +890,6 @@ peer_global_config_reset (struct peer *peer)
int v6only;
peer->weight = 0;
peer->change_local_as = 0;
peer->ttl = (peer_sort (peer) == BGP_PEER_IBGP ? MAXTTL : 1);
if (peer->update_source)
@ -1127,7 +1130,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;
@ -1153,7 +1156,6 @@ peer_new (struct bgp *bgp)
peer->bgp = bgp;
peer = peer_lock (peer); /* initial reference */
bgp_lock (bgp);
peer->weight = 0;
peer->password = NULL;
/* Set default flags. */
@ -1249,6 +1251,7 @@ peer_xfer_config (struct peer *peer_dst, struct peer *peer_src)
peer_dst->afc[afi][safi] = peer_src->afc[afi][safi];
peer_dst->af_flags[afi][safi] = peer_src->af_flags[afi][safi];
peer_dst->allowas_in[afi][safi] = peer_src->allowas_in[afi][safi];
peer_dst->weight[afi][safi] = peer_src->weight[afi][safi];
}
for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++)
@ -2195,9 +2198,6 @@ peer_group2peer_config_copy (struct peer_group *group, struct peer *peer)
/* GTSM hops */
peer->gtsm_hops = conf->gtsm_hops;
/* Weight */
peer->weight = conf->weight;
/* this flag is per-neighbor and so has to be preserved */
v6only = CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY);
@ -2287,6 +2287,9 @@ peer_group2peer_config_copy_af (struct peer_group *group, struct peer *peer,
/* allowas-in */
peer->allowas_in[afi][safi] = conf->allowas_in[afi][safi];
/* weight */
peer->weight[afi][safi] = conf->weight[afi][safi];
/* default-originate route-map */
if (conf->default_rmap[afi][safi].name)
{
@ -2885,6 +2888,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 +3174,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.
*/
@ -3663,6 +3677,7 @@ static const struct peer_flag_action peer_af_flag_action_list[] =
{ PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE,1, peer_change_reset_out },
{ PEER_FLAG_ADDPATH_TX_ALL_PATHS, 1, peer_change_reset },
{ PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS, 1, peer_change_reset },
{ PEER_FLAG_WEIGHT, 0, peer_change_reset_in },
{ 0, 0, 0 }
};
@ -4498,15 +4513,47 @@ peer_port_unset (struct peer *peer)
return 0;
}
/*
* Helper function that is called after the name of the policy
* being used by a peer has changed (AF specific). Automatically
* initiates inbound or outbound processing as needed.
*/
static void
peer_on_policy_change (struct peer *peer, afi_t afi, safi_t safi, int outbound)
{
if (outbound)
{
update_group_adjust_peer (peer_af_find (peer, afi, safi));
if (peer->status == Established)
bgp_announce_route(peer, afi, safi);
}
else
{
if (peer->status != Established)
return;
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
bgp_soft_reconfig_in (peer, afi, safi);
else if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV)
|| CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
bgp_route_refresh_send (peer, afi, safi, 0, 0, 0);
}
}
/* neighbor weight. */
int
peer_weight_set (struct peer *peer, u_int16_t weight)
peer_weight_set (struct peer *peer, afi_t afi, safi_t safi, u_int16_t weight)
{
struct peer_group *group;
struct listnode *node, *nnode;
SET_FLAG (peer->config, PEER_CONFIG_WEIGHT);
peer->weight = weight;
if (peer->weight[afi][safi] != weight)
{
peer->weight[afi][safi] = weight;
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_WEIGHT);
peer_on_policy_change (peer, afi, safi, 0);
}
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
return 0;
@ -4515,35 +4562,71 @@ peer_weight_set (struct peer *peer, u_int16_t weight)
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
{
peer->weight = group->conf->weight;
if (peer->weight[afi][safi] != weight)
{
peer->weight[afi][safi] = weight;
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_WEIGHT);
peer_on_policy_change (peer, afi, safi, 0);
}
return 1;
}
return 0;
}
int
peer_weight_unset (struct peer *peer)
peer_weight_unset (struct peer *peer, afi_t afi, safi_t safi)
{
struct peer_group *group;
struct listnode *node, *nnode;
/* Set default weight. */
/* not the peer-group itself but a peer in a peer-group */
if (peer_group_active (peer))
peer->weight = peer->group->conf->weight;
{
group = peer->group;
/* inherit weight from the peer-group */
if (CHECK_FLAG (group->conf->af_flags[afi][safi], PEER_FLAG_WEIGHT))
{
peer->weight[afi][safi] = group->conf->weight[afi][safi];
peer_af_flag_set (peer, afi, safi, PEER_FLAG_WEIGHT);
peer_on_policy_change (peer, afi, safi, 0);
}
else
{
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_WEIGHT))
{
peer->weight[afi][safi] = 0;
peer_af_flag_unset (peer, afi, safi, PEER_FLAG_WEIGHT);
peer_on_policy_change (peer, afi, safi, 0);
}
}
}
else
peer->weight = 0;
UNSET_FLAG (peer->config, PEER_CONFIG_WEIGHT);
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
return 0;
{
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_WEIGHT))
{
peer->weight[afi][safi] = 0;
peer_af_flag_unset (peer, afi, safi, PEER_FLAG_WEIGHT);
peer_on_policy_change (peer, afi, safi, 0);
}
/* peer-group member updates. */
group = peer->group;
if (group)
{
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
{
peer->weight = 0;
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_WEIGHT))
{
peer->weight[afi][safi] = 0;
peer_af_flag_unset (peer, afi, safi, PEER_FLAG_WEIGHT);
peer_on_policy_change (peer, afi, safi, 0);
}
}
}
return 1;
}
return 0;
}
int
@ -4773,7 +4856,7 @@ peer_allowas_in_set (struct peer *peer, afi_t afi, safi_t safi, int allow_num)
{
peer->allowas_in[afi][safi] = allow_num;
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN);
peer_change_action (peer, afi, safi, peer_change_reset_in);
peer_on_policy_change (peer, afi, safi, 0);
}
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
@ -4786,7 +4869,7 @@ peer_allowas_in_set (struct peer *peer, afi_t afi, safi_t safi, int allow_num)
{
peer->allowas_in[afi][safi] = allow_num;
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN);
peer_change_action (peer, afi, safi, peer_change_reset_in);
peer_on_policy_change (peer, afi, safi, 0);
}
}
@ -4803,6 +4886,7 @@ peer_allowas_in_unset (struct peer *peer, afi_t afi, safi_t safi)
{
peer->allowas_in[afi][safi] = 0;
peer_af_flag_unset (peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
peer_on_policy_change (peer, afi, safi, 0);
}
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
@ -4815,6 +4899,7 @@ peer_allowas_in_unset (struct peer *peer, afi_t afi, safi_t safi)
{
peer->allowas_in[afi][safi] = 0;
peer_af_flag_unset (peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
peer_on_policy_change (peer, afi, safi, 0);
}
}
return 0;
@ -5049,33 +5134,6 @@ peer_password_unset (struct peer *peer)
return 0;
}
/*
* Helper function that is called after the name of the policy
* being used by a peer has changed (AF specific). Automatically
* initiates inbound or outbound processing as needed.
*/
static void
peer_on_policy_change (struct peer *peer, afi_t afi, safi_t safi, int outbound)
{
if (outbound)
{
update_group_adjust_peer (peer_af_find (peer, afi, safi));
if (peer->status == Established)
bgp_announce_route(peer, afi, safi);
}
else
{
if (peer->status != Established)
return;
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
bgp_soft_reconfig_in (peer, afi, safi);
else if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV)
|| CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
bgp_route_refresh_send (peer, afi, safi, 0, 0, 0);
}
}
/* Set distribute list to the peer. */
int
@ -5233,6 +5291,9 @@ peer_distribute_update (struct access_list *access)
}
}
}
#if ENABLE_BGP_VNC
vnc_prefix_list_update(bgp);
#endif
}
}
@ -6605,16 +6666,6 @@ bgp_config_write_peer_global (struct vty *vty, struct bgp *bgp,
peer->connect, VTY_NEWLINE);
}
/* weight */
if (CHECK_FLAG (peer->config, PEER_CONFIG_WEIGHT))
{
if (! peer_group_active (peer) || g_peer->weight != peer->weight)
{
vty_out (vty, " neighbor %s weight %d%s", addr, peer->weight,
VTY_NEWLINE);
}
}
/* capability dynamic */
if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
{
@ -6977,6 +7028,20 @@ bgp_config_write_peer_af (struct vty *vty, struct bgp *bgp,
}
}
/* weight */
if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_WEIGHT))
if (! peer_group_active (peer)
|| ! peer_af_flag_check (g_peer, afi, safi, PEER_FLAG_WEIGHT)
|| peer->weight[afi][safi] != g_peer->weight[afi][safi])
{
if (peer->weight[afi][safi])
{
afi_header_vty_out (vty, afi, safi, write,
" neighbor %s weight %d%s",
addr, peer->weight[afi][safi], VTY_NEWLINE);
}
}
/* Filter. */
bgp_config_write_filter (vty, peer, afi, safi, write);
@ -7337,6 +7402,10 @@ 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
write++;
}
return write;
@ -7407,6 +7476,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 +7492,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];
@ -687,6 +697,7 @@ struct peer
#define PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE (1 << 21) /* remove-private-as all replace-as */
#define PEER_FLAG_ADDPATH_TX_ALL_PATHS (1 << 22) /* addpath-tx-all-paths */
#define PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS (1 << 23) /* addpath-tx-bestpath-per-AS */
#define PEER_FLAG_WEIGHT (1 << 24) /* weight */
/* MD5 password */
char *password;
@ -719,12 +730,10 @@ struct peer
/* Default attribute value for the peer. */
u_int32_t config;
#define PEER_CONFIG_WEIGHT (1 << 0) /* Default weight. */
#define PEER_CONFIG_TIMER (1 << 1) /* keepalive & holdtime */
#define PEER_CONFIG_CONNECT (1 << 2) /* connect */
#define PEER_CONFIG_ROUTEADV (1 << 3) /* route advertise */
#define PEER_CONFIG_TIMER (1 << 0) /* keepalive & holdtime */
#define PEER_CONFIG_CONNECT (1 << 1) /* connect */
#define PEER_CONFIG_ROUTEADV (1 << 2) /* route advertise */
u_int32_t weight;
u_int32_t holdtime;
u_int32_t keepalive;
u_int32_t connect;
@ -779,7 +788,8 @@ struct peer
/* Syncronization list and time. */
struct bgp_synchronize *sync[AFI_MAX][SAFI_MAX];
time_t synctime;
time_t last_write; /* timestamp when the last UPDATE msg was written */
time_t last_write; /* timestamp when the last msg was written */
time_t last_update; /* timestamp when the last UPDATE msg was written */
/* Send prefix count. */
unsigned long scount[AFI_MAX][SAFI_MAX];
@ -817,6 +827,9 @@ struct peer
/* allowas-in. */
char allowas_in[AFI_MAX][SAFI_MAX];
/* weight */
unsigned long weight[AFI_MAX][SAFI_MAX];
/* peer reset cause */
char last_reset;
#define PEER_DOWN_RID_CHANGE 1 /* bgp router-id command */
@ -940,6 +953,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 +1070,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
@ -1277,8 +1294,8 @@ extern int peer_default_originate_unset (struct peer *, afi_t, safi_t);
extern int peer_port_set (struct peer *, u_int16_t);
extern int peer_port_unset (struct peer *);
extern int peer_weight_set (struct peer *, u_int16_t);
extern int peer_weight_unset (struct peer *);
extern int peer_weight_set (struct peer *, afi_t, safi_t, u_int16_t);
extern int peer_weight_unset (struct peer *, afi_t, safi_t);
extern int peer_timers_set (struct peer *, u_int32_t keepalive, u_int32_t holdtime);
extern int peer_timers_unset (struct peer *);
@ -1506,4 +1523,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 */

1
bgpd/rfapi/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.dirstamp

4643
bgpd/rfapi/bgp_rfapi_cfg.c Normal file

File diff suppressed because it is too large Load Diff

318
bgpd/rfapi/bgp_rfapi_cfg.h Normal file
View File

@ -0,0 +1,318 @@
/*
*
* 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 "lib/table.h"
#include "lib/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 */
QOBJ_FIELDS
};
DECLARE_QOBJ_TYPE(rfapi_l2_group_cfg)
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];
QOBJ_FIELDS
};
DECLARE_QOBJ_TYPE(rfapi_nve_group_cfg)
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 */

4386
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 "lib/zebra.h"
#include "lib/vty.h"
#include "lib/prefix.h"
#include "bgpd/bgpd.h"
#include "bgpd/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 "lib/zebra.h"
#include "lib/prefix.h"
#include "lib/table.h"
#include "lib/vty.h"
#include "lib/memory.h"
#include "lib/routemap.h"
#include "lib/log.h"
#include "lib/linklist.h"
#include "lib/command.h"
#include "lib/stream.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_ecommunity.h"
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_mplsvpn.h"
#include "bgpd/rfapi/bgp_rfapi_cfg.h"
#include "bgpd/rfapi/rfapi.h"
#include "bgpd/rfapi/rfapi_backend.h"
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_aspath.h"
#include "bgpd/bgp_advertise.h"
#include "bgpd/rfapi/rfapi_import.h"
#include "bgpd/rfapi/rfapi_private.h"
#include "bgpd/rfapi/rfapi_monitor.h"
#include "bgpd/rfapi/rfapi_vty.h"
#include "bgpd/rfapi/vnc_export_bgp.h"
#include "bgpd/rfapi/vnc_export_bgp_p.h"
#include "bgpd/rfapi/vnc_zebra.h"
#include "bgpd/rfapi/vnc_import_bgp.h"
#include "bgpd/rfapi/rfapi_rib.h"
#include "bgpd/rfapi/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 "lib/zebra.h"
#include "lib/prefix.h"
#include "lib/table.h"
#include "lib/vty.h"
#include "lib/memory.h"
#include "lib/routemap.h"
#include "lib/log.h"
#include "lib/linklist.h"
#include "lib/command.h"
#include "lib/stream.h"
#include "bgpd/bgpd.h"
#include "bgp_rfapi_cfg.h"
#include "rfapi.h"
#include "rfapi_backend.h"
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_aspath.h"
#include "bgpd/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 "bgpd/bgp_route.h"
#include "bgpd/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 "lib/zebra.h"
#include "lib/prefix.h"
#include "lib/table.h"
#include "lib/vty.h"
#include "lib/memory.h"
#include "lib/log.h"
#include "bgpd/bgpd.h"
#include "bgpd/rfapi/rfapi.h"
#include "bgpd/rfapi/rfapi_private.h"
#include "bgpd/rfapi/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 "lib/zebra.h"
#include "lib/memory.h"
#include "lib/prefix.h"
#include "lib/table.h"
#include "lib/vty.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_encap_types.h"
#include "bgpd/bgp_encap_tlv.h"
#include "bgpd/rfapi/rfapi.h"
#include "bgpd/rfapi/rfapi_encap_tlv.h"
#include "bgpd/rfapi/rfapi_private.h"
#include "bgpd/rfapi/rfapi_monitor.h"
#include "bgpd/rfapi/rfapi_vty.h"
#include "bgpd/rfapi/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 */

5150
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 "lib/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 "lib/zebra.h"
#include "lib/prefix.h"
#include "lib/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 "lib/zebra.h"
#include "lib/prefix.h"
#include "lib/table.h"
#include "lib/vty.h"
#include "lib/memory.h"
#include "lib/skiplist.h"
#include "bgpd/bgpd.h"
#include "bgpd/rfapi/bgp_rfapi_cfg.h"
#include "bgpd/rfapi/rfapi.h"
#include "bgpd/rfapi/rfapi_backend.h"
#include "bgpd/rfapi/rfapi_import.h"
#include "bgpd/rfapi/rfapi_private.h"
#include "bgpd/rfapi/rfapi_nve_addr.h"
#include "bgpd/rfapi/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 "lib/linklist.h"
#include "lib/skiplist.h"
#include "lib/workqueue.h"
#include "bgpd/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 */

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

5016
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 "lib/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 "lib/zebra.h"
#include <lib/version.h>
#include "lib/prefix.h"
#include "lib/linklist.h"
#include "lib/stream.h"
#include "lib/command.h"
#include "lib/str.h"
#include "lib/log.h"
#include "bgpd/rfapi/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 "lib/zebra.h"
#include "lib/prefix.h"
#include "bgpd/bgpd.h"
#include "bgpd/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 "lib/zebra.h"
#include "lib/prefix.h"
#include "bgpd/bgpd.h"
#include "bgpd/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 "lib/zebra.h"
#include "lib/prefix.h"
#include "lib/table.h"
#include "lib/memory.h"
#include "lib/vty.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_route.h"
#include "bgpd/rfapi/vnc_export_table.h"
#include "bgpd/rfapi/rfapi_private.h"
#include "bgpd/rfapi/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 "lib/table.h"
#include "lib/thread.h"
#include "lib/vty.h"
#include "bgpd/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_ */

3136
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 "lib/zebra.h"
#include "lib/prefix.h"
#include "bgpd/bgpd.h"
#include "bgpd/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 "lib/zebra.h"
#include "lib/prefix.h"
#include "bgpd/bgpd.h"
#include "bgpd/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_ */

1117
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 "lib/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 "bgpd/rfapi/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 "bgpd/rfapi/rfapi.h"
#include "lib/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 "lib/zebra.h"
#include "rfp.h"
#include "bgpd/rfapi/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 */

41
common.am Normal file
View File

@ -0,0 +1,41 @@
#
# Automake fragment intended to be shared by Makefile.am files in the
# tree.
#
if HAVE_PROTOBUF
# Uncomment to use an non-system version of libprotobuf-c.
#
# Q_PROTOBUF_C_CLIENT_INCLUDES = -I$(top_srcdir)/third-party/protobuf-c/src
# Q_PROTOBUF_C_CLIENT_LDOPTS = $(top_builddir)/third-party/protobuf-c/src/libprotobuf-c.la
Q_PROTOBUF_C_CLIENT_INCLUDES=
Q_PROTOBUF_C_CLIENT_LDOPTS=-lprotobuf-c
Q_PROTOC=protoc
Q_PROTOC_C=protoc-c
Q_PROTOBUF_CFILES = $(filter %.pb-c.c,$(SOURCES))
Q_PROTOBUF_SRCS = $(Q_PROTOBUF_CFILES) $(Q_PROTOBUF_HFILES)
# Rules
%.pb.h: %.proto
$(Q_PROTOC) $(PROTOBUF_INCLUDES) --cpp_out=$(top_srcdir) $(top_srcdir)/$(PROTOBUF_PACKAGE)/$^
%.pb-c.c %.pb-c.h: %.proto
$(Q_PROTOC_C) $(PROTOBUF_INCLUDES) --c_out=$(top_srcdir) $(top_srcdir)/$(PROTOBUF_PACKAGE)/$^
#
# Information about how to link to various libraries.
#
Q_QUAGGA_PB_CLIENT_LDOPTS = $(top_srcdir)/qpb/libquagga_pb.la $(Q_PROTOBUF_C_CLIENT_LDOPTS)
Q_FPM_PB_CLIENT_LDOPTS = $(top_srcdir)/fpm/libfpm_pb.la $(Q_QUAGGA_PB_CLIENT_LDOPTS)
endif # HAVE_PROTOBUF
Q_CLEANFILES = $(Q_PROTOBUF_SRCS)
Q_BUILT_SRCS = $(Q_PROTOBUF_SRCS)

View File

@ -7,7 +7,7 @@
##
AC_PREREQ(2.60)
AC_INIT(Quagga, 0.99.24+cl3u3, [https://bugzilla.quagga.net])
AC_INIT(Quagga, 0.99.24+cl3u4, [https://bugzilla.quagga.net])
CONFIG_ARGS="$*"
AC_SUBST(CONFIG_ARGS)
AC_CONFIG_SRCDIR(lib/zebra.h)
@ -20,7 +20,9 @@ AC_CANONICAL_BUILD()
AC_CANONICAL_HOST()
AC_CANONICAL_TARGET()
AM_INIT_AUTOMAKE(1.6)
# Disable portability warnings -- our automake code (in particular
# common.am) uses some constructs specific to gmake.
AM_INIT_AUTOMAKE([1.6 -Wno-portability])
m4_ifndef([AM_SILENT_RULES], [m4_define([AM_SILENT_RULES],[])])
AM_SILENT_RULES([yes])
AC_CONFIG_HEADERS(config.h)
@ -246,6 +248,8 @@ AC_ARG_ENABLE(ospfd,
AS_HELP_STRING([--disable-ospfd], [do not build ospfd]))
AC_ARG_ENABLE(ospf6d,
AS_HELP_STRING([--disable-ospf6d], [do not build ospf6d]))
AC_ARG_ENABLE(ldpd,
AS_HELP_STRING([--enable-ldpd], [build ldpd]))
AC_ARG_ENABLE(watchquagga,
AS_HELP_STRING([--disable-watchquagga], [do not build watchquagga]))
AC_ARG_ENABLE(isisd,
@ -254,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([--disable-bgp-vnc],[turn off 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,
@ -313,6 +321,8 @@ AC_ARG_ENABLE(cumulus,
AS_HELP_STRING([--enable-cumulus], [enable Cumulus Switch Special Extensions]))
AC_ARG_ENABLE(rr-semantics,
AS_HELP_STRING([--disable-rr-semantics], [disable the v6 Route Replace semantics]))
AC_ARG_ENABLE([protobuf],
AS_HELP_STRING([--enable-protobuf], [Enable experimental protobuf support]))
AC_CHECK_HEADERS(json-c/json.h)
AC_CHECK_LIB(json-c, json_object_get, LIBS="$LIBS -ljson-c")
@ -323,6 +333,9 @@ if test $ac_cv_lib_json_c_json_object_get = no; then
fi
fi
AC_ARG_ENABLE([dev_build],
AS_HELP_STRING([--enable-dev-build], [build for development]))
if test x"${enable_gcc_rdynamic}" != x"no" ; then
if test x"${enable_gcc_rdynamic}" = x"yes" -o x"$COMPILER" = x"GCC"; then
LDFLAGS="${LDFLAGS} -rdynamic"
@ -358,6 +371,26 @@ if test "${enable_poll}" = "yes" ; then
AC_DEFINE(HAVE_POLL,,Compile systemd support in)
fi
dnl ----------
dnl MPLS check
dnl ----------
AC_MSG_CHECKING(whether this OS has MPLS stack)
case "$host" in
*-linux*)
MPLS_METHOD="zebra_mpls_netlink.o"
AC_MSG_RESULT(Linux MPLS)
;;
*-openbsd*)
MPLS_METHOD="zebra_mpls_openbsd.o"
AC_MSG_RESULT(OpenBSD MPLS)
;;
*)
MPLS_METHOD="zebra_mpls_null.o"
AC_MSG_RESULT(Unsupported kernel)
;;
esac
AC_SUBST(MPLS_METHOD)
if test "${enable_cumulus}" = "yes" ; then
AC_DEFINE(HAVE_CUMULUS,,Compile Special Cumulus Code in)
fi
@ -370,6 +403,53 @@ if test "${enable_fpm}" = "yes"; then
AC_DEFINE(HAVE_FPM,,Forwarding Plane Manager support)
fi
if test "x${enable_dev_build}" = "xyes"; then
AC_DEFINE(DEV_BUILD,,Build for development)
fi
AM_CONDITIONAL([DEV_BUILD], [test "x$enable_dev_build" = "xyes"])
#
# Logic for protobuf support.
#
if test "$enable_protobuf" = "yes"; then
have_protobuf=yes
# Check for protoc-c
AC_CHECK_PROG([PROTOC_C], [protoc-c], [protoc-c], [/bin/false])
if test "x$PROTOC_C" = "x/bin/false"; then
have_protobuf=no
else
found_protobuf_c=no
PKG_CHECK_MODULES([PROTOBUF_C], libprotobuf-c >= 0.14,
[found_protobuf_c=yes],
[AC_MSG_RESULT([pkg-config did not find libprotobuf-c])])
if test "x$found_protobuf_c" = "xyes"; then
LDFLAGS="$LDFLAGS $PROTOBUF_C_LIBS"
CFLAGS="$CFLAGS $PROTOBUF_C_CFLAGS"
else
AC_CHECK_HEADER([google/protobuf-c/protobuf-c.h], [],
[have_protobuf=no; AC_MSG_RESULT([Couldn't find google/protobuf-c.h])])
fi
fi
fi
# Fail if the user explicity enabled protobuf support and we couldn't
# find the compiler or libraries.
if test "x$have_protobuf" = "xno" && test "x$enable_protobuf" = "xyes"; then
AC_MSG_ERROR([Protobuf enabled explicitly but can't find libraries/tools])
fi
if test "x$have_protobuf" = "xyes"; then
AC_DEFINE(HAVE_PROTOBUF,, protobuf)
fi
AM_CONDITIONAL([HAVE_PROTOBUF], [test "x$have_protobuf" = "xyes"])
#
# End of logic for protobuf support.
#
if test "${enable_tcp_zebra}" = "yes"; then
AC_DEFINE(HAVE_TCP_ZEBRA,,Use TCP for zebra communication)
fi
@ -838,7 +918,7 @@ AC_CHECK_FUNCS([dup2 ftruncate getcwd gethostbyname getpagesize gettimeofday \
strtol strtoul strlcat strlcpy \
daemon snprintf vsnprintf \
if_nametoindex if_indextoname getifaddrs \
uname fcntl getgrouplist])
uname fcntl getgrouplist pledge])
AC_CHECK_HEADER([asm-generic/unistd.h],
[AC_CHECK_DECL(__NR_setns,
@ -1231,6 +1311,13 @@ else
fi
AM_CONDITIONAL(OSPFD, test "x$OSPFD" = "xospfd")
if test "${enable_ldpd}" = "yes";then
LDPD="ldpd"
else
LDPD=""
fi
AM_CONDITIONAL(LDPD, test "x$LDPD" = "xldpd")
if test "${enable_watchquagga}" = "no";then
WATCHQUAGGA=""
else
@ -1279,13 +1366,38 @@ 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}" != "no";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} != xno])
AC_SUBST(DOC)
AC_SUBST(ZEBRA)
AC_SUBST(RFPTEST)
AC_SUBST(LIBRFP)
AC_SUBST(RFPINC)
AC_SUBST(BGPD)
AC_SUBST(RIPD)
AC_SUBST(RIPNGD)
AC_SUBST(OSPFD)
AC_SUBST(OSPF6D)
AC_SUBST(LDPD)
AC_SUBST(WATCHQUAGGA)
AC_SUBST(ISISD)
AC_SUBST(PIMD)
@ -1432,6 +1544,32 @@ AC_TRY_COMPILE([#include <netinet/in.h>], [
AC_MSG_RESULT(no)
])
dnl ----------------------
dnl checking for SO_BINDANY
dnl ----------------------
AC_MSG_CHECKING(for SO_BINDANY)
AC_TRY_COMPILE([#include <sys/socket.h>], [
int opt = SO_BINDANY;
], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_SO_BINDANY, 1, [Have SO_BINDANY])
], [
AC_MSG_RESULT(no)
])
dnl ----------------------
dnl checking for IP_FREEBIND
dnl ----------------------
AC_MSG_CHECKING(for IP_FREEBIND)
AC_TRY_COMPILE([#include <netinet/in.h>], [
int opt = IP_FREEBIND;
], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_IP_FREEBIND, 1, [Have IP_FREEBIND])
], [
AC_MSG_RESULT(no)
])
dnl --------------------------------------
dnl checking for getrusage struct and call
dnl --------------------------------------
@ -1591,6 +1729,8 @@ AC_DEFINE_UNQUOTED(PATH_RIPNGD_PID, "$quagga_statedir/ripngd.pid",ripngd PID)
AC_DEFINE_UNQUOTED(PATH_BGPD_PID, "$quagga_statedir/bgpd.pid",bgpd PID)
AC_DEFINE_UNQUOTED(PATH_OSPFD_PID, "$quagga_statedir/ospfd.pid",ospfd PID)
AC_DEFINE_UNQUOTED(PATH_OSPF6D_PID, "$quagga_statedir/ospf6d.pid",ospf6d PID)
AC_DEFINE_UNQUOTED(PATH_LDPD_PID, "$quagga_statedir/ldpd.pid",ldpd PID)
AC_DEFINE_UNQUOTED(LDPD_SOCKET, "$quagga_statedir/ldpd.sock",ldpd control socket)
AC_DEFINE_UNQUOTED(PATH_ISISD_PID, "$quagga_statedir/isisd.pid",isisd PID)
AC_DEFINE_UNQUOTED(PATH_PIMD_PID, "$quagga_statedir/pimd.pid",pimd PID)
AC_DEFINE_UNQUOTED(PATH_WATCHQUAGGA_PID, "$quagga_statedir/watchquagga.pid",watchquagga PID)
@ -1601,6 +1741,7 @@ AC_DEFINE_UNQUOTED(RIPNG_VTYSH_PATH, "$quagga_statedir/ripngd.vty",ripng vty soc
AC_DEFINE_UNQUOTED(BGP_VTYSH_PATH, "$quagga_statedir/bgpd.vty",bgpd vty socket)
AC_DEFINE_UNQUOTED(OSPF_VTYSH_PATH, "$quagga_statedir/ospfd.vty",ospfd vty socket)
AC_DEFINE_UNQUOTED(OSPF6_VTYSH_PATH, "$quagga_statedir/ospf6d.vty",ospf6d vty socket)
AC_DEFINE_UNQUOTED(LDP_VTYSH_PATH, "$quagga_statedir/ldpd.vty",ldpd vty socket)
AC_DEFINE_UNQUOTED(ISIS_VTYSH_PATH, "$quagga_statedir/isisd.vty",isisd vty socket)
AC_DEFINE_UNQUOTED(PIM_VTYSH_PATH, "$quagga_statedir/pimd.vty",pimd vty socket)
AC_DEFINE_UNQUOTED(DAEMON_VTY_DIR, "$quagga_statedir",daemon vty directory)
@ -1624,9 +1765,9 @@ AC_CACHE_VAL(ac_cv_htonl_works,
)
AC_MSG_RESULT($ac_cv_htonl_works)
AC_CONFIG_FILES([Makefile lib/Makefile zebra/Makefile ripd/Makefile
AC_CONFIG_FILES([Makefile lib/Makefile qpb/Makefile zebra/Makefile ripd/Makefile
ripngd/Makefile bgpd/Makefile ospfd/Makefile watchquagga/Makefile
ospf6d/Makefile isisd/Makefile vtysh/Makefile
ospf6d/Makefile ldpd/Makefile isisd/Makefile vtysh/Makefile
doc/Makefile ospfclient/Makefile tests/Makefile m4/Makefile
pimd/Makefile
tests/bgpd.tests/Makefile
@ -1635,15 +1776,26 @@ AC_CONFIG_FILES([Makefile lib/Makefile zebra/Makefile ripd/Makefile
tools/Makefile
cumulus/Makefile
pkgsrc/Makefile
fpm/Makefile
redhat/quagga.spec
lib/version.h
doc/defines.texi
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}" != "no"; 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
@ -1666,6 +1818,7 @@ group to run as : ${enable_group}
group for vty sockets : ${enable_vty_group}
config file mask : ${enable_configfile_mask}
log file mask : ${enable_logfile_mask}
zebra protobuf enabled : ${have_protobuf:-no}
The above user and group must have read/write access to the state file
directory and to the config files in the config file directory."

6
debian/changelog vendored
View File

@ -1,3 +1,9 @@
quagga (0.99.24+cl3u4) RELEASED; urgency=medium
* Closes: CM-12687 - Buffer overflow in zebra RA code
-- dev-support <dev-support@cumulusnetworks.com> Wed, 31 Aug 2016 12:36:10 -0400
quagga (0.99.24+cl3u3) RELEASED; urgency=medium
* New Enabled: Merge up-to 0.99.24 code from upstream

3
debian/rules vendored
View File

@ -54,7 +54,8 @@ override_dh_auto_configure:
--enable-poll=yes \
--enable-cumulus=yes \
--enable-pimd=no \
--enable-dependency-tracking; \
--enable-dependency-tracking \
--enable-bgp-vnc=no; \
fi
override_dh_auto_build:

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
@ -46,7 +57,8 @@ info_TEXINFOS = quagga.texi
quagga.pdf: $(info_TEXINFOS) $(figures_pdf) $(quagga_TEXINFOS)
$(TEXI2PDF) -o "$@" $< || true
quagga_TEXINFOS = appendix.texi basic.texi bgpd.texi filter.texi \
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) \
@ -87,6 +99,10 @@ if OSPFD
man_MANS += ospfd.8
endif
if LDPD
man_MANS += ldpd.8
endif
if RIPD
man_MANS += ripd.8
endif
@ -108,7 +124,7 @@ man_MANS += zebra.8
endif
EXTRA_DIST = BGP-TypeCode draft-zebra-00.ms draft-zebra-00.txt \
bgpd.8 isisd.8 ospf6d.8 ospfclient.8 ospfd.8 ripd.8 \
bgpd.8 isisd.8 ospf6d.8 ospfclient.8 ospfd.8 ldpd.8 ripd.8 \
ripngd.8 pimd.8 vtysh.1 watchquagga.8 zebra.8 quagga.1 \
mpls/ChangeLog.opaque.txt mpls/cli_summary.txt \
mpls/opaque_lsa.txt mpls/ospfd.conf \
@ -116,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

@ -0,0 +1,681 @@
## Topology
The goal of this test is to verify that the all the basic functionality
of ldpd is working as expected, be it running on Linux or OpenBSD. In
addition to that, more advanced features are also tested, like LDP
sessions over IPv6, MD5 authentication and pseudowire signaling.
In the topology below there are 3 PE routers, 3 CE routers and one P
router (not attached to any consumer site).
All routers have IPv4 addresses and OSPF is used as the IGP. The
three routers from the bottom of the picture, P, PE2 and PE3, are also
configured for IPv6 (dual-stack) and static IPv6 routes are used to
provide connectivity among them.
The three CEs share the same VPLS membership. LDP is used to set up the
LSPs among the PEs and to signal the pseudowires. MD5 authentication is
used to protect all LDP sessions.
```
CE1 172.16.1.1/24
+
|
+---+---+
| PE1 |
| IOS XE|
| |
+---+---+
|
| 10.0.1.0/24
|
+---+---+
| P |
+------+ IOS XR+------+
| | | |
| +-------+ |
10.0.2.0/24 | | 10.0.3.0/24
2001:db8:2::/64 | | 2001:db8:3::/64
| |
+---+---+ +---+---+
| PE2 | | PE3 |
|OpenBSD+-------------+ Linux |
| | | |
+---+---+ 10.0.4.0/24 +---+---+
| 2001:db8:4::/64 |
+ +
172.16.1.2/24 CE2 CE3 172.16.1.3/24
```
## Configuration
#### Linux
1 - Enable IPv4/v6 forwarding:
```
# sysctl -w net.ipv4.ip_forward=1
# sysctl -w net.ipv6.conf.all.forwarding=1
```
2 - Enable MPLS forwarding:
```
# modprobe mpls-router
# modprobe mpls-iptunnel
# echo 100000 > /proc/sys/net/mpls/platform_labels
# echo 1 > /proc/sys/net/mpls/conf/eth1/input
# echo 1 > /proc/sys/net/mpls/conf/eth2/input
```
3 - Set up the interfaces:
```
# ip link add name lo1 type dummy
# ip link set dev lo1 up
# ip addr add 4.4.4.4/32 dev lo1
# ip -6 addr add 4:4:4::4/128 dev lo1
# ip link set dev eth1 up
# ip addr add 10.0.4.4/24 dev eth1
# ip -6 addr add 2001:db8:4::4/64 dev eth1
# ip link set dev eth2 up
# ip addr add 10.0.3.4/24 dev eth2
# ip -6 addr add 2001:db8:3::4/64 dev eth2
```
4 - Set up the bridge and pseudowire interfaces:
```
# ip link add type bridge
# ip link set dev bridge0 up
# ip link set dev eth0 up
# ip link set dev eth0 master bridge0
# ip link add name mpw0 type dummy
# ip link set dev mpw0 up
# ip link set dev mpw0 master bridge0
# ip link add name mpw1 type dummy
# ip link set dev mpw1 up
# ip link set dev mpw1 master bridge0
```
> NOTE: MPLS support in the Linux kernel is very recent and it still
doesn't support pseudowire interfaces. We are using here dummy interfaces
just to show how the VPLS configuration should look like in the future.
5 - Add static IPv6 routes for the remote loopbacks:
```
# ip -6 route add 2:2:2::2/128 via 2001:db8:3::2
# ip -6 route add 3:3:3::3/128 via 2001:db8:4::3
```
6 - Edit /etc/quagga/ospfd.conf:
```
router ospf
network 4.4.4.4/32 area 0.0.0.0
network 10.0.3.4/24 area 0.0.0.0
network 10.0.4.4/24 area 0.0.0.0
!
```
7 - Edit /etc/quagga/ldpd.conf:
```
debug mpls ldp messages recv
debug mpls ldp messages sent
debug mpls ldp zebra
!
mpls ldp
router-id 4.4.4.4
dual-stack cisco-interop
neighbor 1.1.1.1 password opensourcerouting
neighbor 2.2.2.2 password opensourcerouting
neighbor 3.3.3.3 password opensourcerouting
!
address-family ipv4
discovery transport-address 4.4.4.4
label local advertise explicit-null
!
interface eth2
!
interface eth1
!
!
address-family ipv6
discovery transport-address 4:4:4::4
ttl-security disable
!
interface eth2
!
interface eth1
!
!
!
l2vpn ENG type vpls
bridge br0
member interface eth0
!
member pseudowire mpw0
neighbor lsr-id 1.1.1.1
pw-id 100
!
member pseudowire mpw1
neighbor lsr-id 3.3.3.3
neighbor address 3:3:3::3
pw-id 100
!
!
```
> NOTE: We have to disable ttl-security under the ipv6 address-family
in order to interoperate with the IOS-XR router. GTSM is mandatory for
LDPv6 but the IOS-XR implementation is not RFC compliant in this regard.
8 - Run zebra, ospfd and ldpd.
#### OpenBSD
1 - Enable IPv4/v6 forwarding:
```
# sysctl net.inet.ip.forwarding=1
# sysctl net.inet6.ip6.forwarding=1
```
2 - Enable MPLS forwarding:
```
# ifconfig em2 10.0.2.3/24 mpls
# ifconfig em3 10.0.4.3/24 mpls
```
3 - Set up the interfaces:
```
# ifconfig lo1 alias 3.3.3.3 netmask 255.255.255.255
# ifconfig lo1 inet6 3:3:3::3/128
# ifconfig em2 inet6 2001:db8:2::3/64
# ifconfig em3 inet6 2001:db8:4::3/64
```
4 - Set up the bridge and pseudowire interfaces:
```
# ifconfig bridge0 create
# ifconfig bridge0 up
# ifconfig em1 up
# ifconfig bridge0 add em1
# ifconfig mpw0 create
# ifconfig mpw0 up
# ifconfig bridge0 add mpw0
# ifconfig mpw1 create
# ifconfig mpw1 up
# ifconfig bridge0 add mpw1
```
5 - Add static IPv6 routes for the remote loopbacks:
```
# route -n add 4:4:4::4/128 2001:db8:4::4
# route -n add 2:2:2::2/128 2001:db8:2::2
```
6 - Edit /etc/quagga/ospfd.conf:
```
router ospf
network 10.0.2.3/24 area 0
network 10.0.4.3/24 area 0
network 3.3.3.3/32 area 0
!
```
7 - Edit /etc/quagga/ldpd.conf:
```
debug mpls ldp messages recv
debug mpls ldp messages sent
debug mpls ldp zebra
!
mpls ldp
router-id 3.3.3.3
dual-stack cisco-interop
neighbor 1.1.1.1 password opensourcerouting
neighbor 2.2.2.2 password opensourcerouting
neighbor 4.4.4.4 password opensourcerouting
!
address-family ipv4
discovery transport-address 3.3.3.3
label local advertise explicit-null
!
interface em3
!
interface em2
!
!
address-family ipv6
discovery transport-address 3:3:3::3
ttl-security disable
!
interface em3
!
interface em2
!
!
!
l2vpn ENG type vpls
bridge br0
member interface em1
!
member pseudowire mpw0
neighbor lsr-id 1.1.1.1
pw-id 100
!
member pseudowire mpw1
neighbor lsr-id 4.4.4.4
neighbor address 4:4:4::4
pw-id 100
!
!
```
8 - Run zebra, ospfd and ldpd.
#### Cisco routers
CE1 (IOS):
```
interface FastEthernet0/0
ip address 172.16.1.1 255.255.255.0
!
!
```
CE2 (IOS):
```
interface FastEthernet0/0
ip address 172.16.1.2 255.255.255.0
!
!
```
CE3 (IOS):
```
interface FastEthernet0/0
ip address 172.16.1.3 255.255.255.0
!
!
```
PE1 - IOS-XE (1):
```
mpls ldp neighbor 2.2.2.2 password opensourcerouting
mpls ldp neighbor 3.3.3.3 password opensourcerouting
mpls ldp neighbor 4.4.4.4 password opensourcerouting
!
l2vpn vfi context VFI
vpn id 1
member pseudowire2
member pseudowire1
!
bridge-domain 1
member GigabitEthernet1 service-instance 1
member vfi VFI
!
interface Loopback1
ip address 1.1.1.1 255.255.255.255
!
interface pseudowire1
encapsulation mpls
neighbor 3.3.3.3 100
!
interface pseudowire2
encapsulation mpls
neighbor 4.4.4.4 100
!
interface GigabitEthernet3
ip address 10.0.1.1 255.255.255.0
mpls ip
!
router ospf 1
network 0.0.0.0 255.255.255.255 area 0
!
```
P - IOS-XR (2):
```
interface Loopback1
ipv4 address 2.2.2.2 255.255.255.255
ipv6 address 2:2:2::2/128
!
interface GigabitEthernet0/0/0/0
ipv4 address 10.0.1.2 255.255.255.0
!
interface GigabitEthernet0/0/0/1
ipv4 address 10.0.2.2 255.255.255.0
ipv6 address 2001:db8:2::2/64
ipv6 enable
!
interface GigabitEthernet0/0/0/2
ipv4 address 10.0.3.2 255.255.255.0
ipv6 address 2001:db8:3::2/64
ipv6 enable
!
router static
address-family ipv6 unicast
3:3:3::3/128 2001:db8:2::3
4:4:4::4/128 2001:db8:3::4
!
!
router ospf 1
router-id 2.2.2.2
address-family ipv4 unicast
area 0
interface Loopback1
!
interface GigabitEthernet0/0/0/0
!
interface GigabitEthernet0/0/0/1
!
interface GigabitEthernet0/0/0/2
!
!
!
mpls ldp
router-id 2.2.2.2
neighbor
1.1.1.1:0 password clear opensourcerouting
3.3.3.3:0 password clear opensourcerouting
4.4.4.4:0 password clear opensourcerouting
!
address-family ipv4
!
address-family ipv6
discovery transport-address 2:2:2::2
!
interface GigabitEthernet0/0/0/0
address-family ipv4
!
!
interface GigabitEthernet0/0/0/1
address-family ipv4
!
address-family ipv6
!
!
interface GigabitEthernet0/0/0/2
address-family ipv4
!
address-family ipv6
!
!
!
```
## Verification - Control Plane
Using the CLI on the Linux box, the goal is to ensure that everything
is working as expected.
First, verify that all the required adjacencies and neighborships sessions
were established:
```
linux# show mpls ldp discovery
Local LDP Identifier: 4.4.4.4:0
Discovery Sources:
Interfaces:
eth1: xmit/recv
LDP Id: 3.3.3.3:0, Transport address: 3.3.3.3
Hold time: 15 sec
LDP Id: 3.3.3.3:0, Transport address: 3:3:3::3
Hold time: 15 sec
eth2: xmit/recv
LDP Id: 2.2.2.2:0, Transport address: 2.2.2.2
Hold time: 15 sec
LDP Id: 2.2.2.2:0, Transport address: 2:2:2::2
Hold time: 15 sec
Targeted Hellos:
4.4.4.4 -> 1.1.1.1: xmit/recv
LDP Id: 1.1.1.1:0, Transport address: 1.1.1.1
Hold time: 45 sec
4:4:4::4 -> 3:3:3::3: xmit/recv
LDP Id: 3.3.3.3:0, Transport address: 3:3:3::3
Hold time: 45 sec
linux# show mpls ldp neighbor
Peer LDP Identifier: 1.1.1.1:0
TCP connection: 4.4.4.4:40921 - 1.1.1.1:646
Session Holdtime: 180 sec
State: OPERATIONAL; Downstream-Unsolicited
Up time: 00:06:02
LDP Discovery Sources:
IPv4:
Targeted Hello: 1.1.1.1
Peer LDP Identifier: 2.2.2.2:0
TCP connection: 4:4:4::4:52286 - 2:2:2::2:646
Session Holdtime: 180 sec
State: OPERATIONAL; Downstream-Unsolicited
Up time: 00:06:02
LDP Discovery Sources:
IPv4:
Interface: eth2
IPv6:
Interface: eth2
Peer LDP Identifier: 3.3.3.3:0
TCP connection: 4:4:4::4:60575 - 3:3:3::3:646
Session Holdtime: 180 sec
State: OPERATIONAL; Downstream-Unsolicited
Up time: 00:05:57
LDP Discovery Sources:
IPv4:
Interface: eth1
IPv6:
Targeted Hello: 3:3:3::3
Interface: eth1
```
Note that the neighborships with the P and PE2 routers were established
over IPv6, since this is the default behavior for dual-stack LSRs, as
specified in RFC 7552. If desired, the **dual-stack transport-connection
prefer ipv4** command can be used to establish these sessions over IPv4
(the command should be applied an all routers).
Now, verify that there's a remote label for each PE address:
```
linux# show mpls ldp binding
1.1.1.1/32
Local binding: label: 20
Remote bindings:
Peer Label
----------------- ---------
1.1.1.1 imp-null
2.2.2.2 24000
3.3.3.3 20
2.2.2.2/32
Local binding: label: 21
Remote bindings:
Peer Label
----------------- ---------
1.1.1.1 18
2.2.2.2 imp-null
3.3.3.3 21
3.3.3.3/32
Local binding: label: 22
Remote bindings:
Peer Label
----------------- ---------
1.1.1.1 21
2.2.2.2 24003
3.3.3.3 imp-null
4.4.4.4/32
Local binding: label: imp-null
Remote bindings:
Peer Label
----------------- ---------
1.1.1.1 22
2.2.2.2 24001
3.3.3.3 22
10.0.1.0/24
Local binding: label: 23
Remote bindings:
Peer Label
----------------- ---------
1.1.1.1 imp-null
2.2.2.2 imp-null
3.3.3.3 23
10.0.2.0/24
Local binding: label: 24
Remote bindings:
Peer Label
----------------- ---------
1.1.1.1 20
2.2.2.2 imp-null
3.3.3.3 imp-null
10.0.3.0/24
Local binding: label: imp-null
Remote bindings:
Peer Label
----------------- ---------
1.1.1.1 19
2.2.2.2 imp-null
3.3.3.3 24
10.0.4.0/24
Local binding: label: imp-null
Remote bindings:
Peer Label
----------------- ---------
1.1.1.1 23
2.2.2.2 24002
3.3.3.3 imp-null
2:2:2::2/128
Local binding: label: 18
Remote bindings:
Peer Label
----------------- ---------
2.2.2.2 imp-null
3.3.3.3 18
3:3:3::3/128
Local binding: label: 19
Remote bindings:
Peer Label
----------------- ---------
2.2.2.2 24007
4:4:4::4/128
Local binding: label: imp-null
Remote bindings:
Peer Label
----------------- ---------
2.2.2.2 24006
3.3.3.3 19
2001:db8:2::/64
Local binding: label: -
Remote bindings:
Peer Label
----------------- ---------
2.2.2.2 imp-null
3.3.3.3 imp-null
2001:db8:3::/64
Local binding: label: imp-null
Remote bindings:
Peer Label
----------------- ---------
2.2.2.2 imp-null
2001:db8:4::/64
Local binding: label: imp-null
Remote bindings:
Peer Label
----------------- ---------
3.3.3.3 imp-null
```
Check if the pseudowires are up:
```
linux# show l2vpn atom vc
Interface Peer ID VC ID Name Status
--------- --------------- ---------- ---------------- ----------
mpw1 3.3.3.3 100 ENG UP
mpw0 1.1.1.1 100 ENG UP
```
Check the label bindings of the pseudowires:
```
linux# show l2vpn atom binding
Destination Address: 1.1.1.1, VC ID: 100
Local Label: 25
Cbit: 1, VC Type: Ethernet, GroupID: 0
MTU: 1500
Remote Label: 16
Cbit: 1, VC Type: Ethernet, GroupID: 0
MTU: 1500
Destination Address: 3.3.3.3, VC ID: 100
Local Label: 26
Cbit: 1, VC Type: Ethernet, GroupID: 0
MTU: 1500
Remote Label: 26
Cbit: 1, VC Type: Ethernet, GroupID: 0
MTU: 1500
```
## Verification - Data Plane
Verify that all the exchanged label mappings were installed in zebra:
```
linux# show mpls table
Inbound Outbound
Label Type Nexthop Label
-------- ------- --------------- --------
17 LDP 2001:db8:3::2 3
19 LDP 2001:db8:3::2 24005
20 LDP 10.0.3.2 24000
21 LDP 10.0.3.2 3
22 LDP 10.0.3.2 24001
23 LDP 10.0.3.2 3
24 LDP 10.0.3.2 3
25 LDP 10.0.3.2 3
linux# show ip route ldp
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, P - PIM, A - Babel, L - LDP,
> - selected route, * - FIB route
L>* 1.1.1.1/32 [0/0] via 10.0.3.2, eth2 label 24000
L>* 3.3.3.3/32 [0/0] via 10.0.3.2, eth2 label 24001
```
Verify that all the exchanged label mappings were installed in the kernel:
```
$ ip -M ro
17 via inet6 2001:db8:3::2 dev eth2 proto zebra
19 as to 24005 via inet6 2001:db8:3::2 dev eth2 proto zebra
20 as to 24000 via inet 10.0.3.2 dev eth2 proto zebra
21 via inet 10.0.3.2 dev eth2 proto zebra
22 as to 24001 via inet 10.0.3.2 dev eth2 proto zebra
23 via inet 10.0.3.2 dev eth2 proto zebra
24 via inet 10.0.3.2 dev eth2 proto zebra
25 via inet 10.0.3.2 dev eth2 proto zebra
$
$ ip route | grep mpls
1.1.1.1 encap mpls 24000 via 10.0.3.2 dev eth2 proto zebra metric 20
3.3.3.3 encap mpls 24001 via 10.0.3.2 dev eth2 proto zebra metric 20
```
Now ping PE1's loopback using lo1's address as a source address:
```
$ ping -c 5 -I 4.4.4.4 1.1.1.1
PING 1.1.1.1 (1.1.1.1) from 4.4.4.4 : 56(84) bytes of data.
64 bytes from 1.1.1.1: icmp_seq=1 ttl=253 time=3.02 ms
64 bytes from 1.1.1.1: icmp_seq=2 ttl=253 time=3.13 ms
64 bytes from 1.1.1.1: icmp_seq=3 ttl=253 time=3.19 ms
64 bytes from 1.1.1.1: icmp_seq=4 ttl=253 time=3.07 ms
64 bytes from 1.1.1.1: icmp_seq=5 ttl=253 time=3.27 ms
--- 1.1.1.1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4005ms
rtt min/avg/max/mdev = 3.022/3.140/3.278/0.096 ms
```
Verify that the ICMP echo request packets are leaving with the MPLS
label advertised by the P router. Also, verify that the ICMP echo reply
packets are arriving with an explicit-null MPLS label:
```
# tcpdump -n -i eth2 mpls and icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth2, link-type EN10MB (Ethernet), capture size 262144 bytes
10:01:40.758771 MPLS (label 24000, exp 0, [S], ttl 64) IP 4.4.4.4 > 1.1.1.1: ICMP echo request, id 13370, seq 1, length 64
10:01:40.761777 MPLS (label 0, exp 0, [S], ttl 254) IP 1.1.1.1 > 4.4.4.4: ICMP echo reply, id 13370, seq 1, length 64
10:01:41.760343 MPLS (label 24000, exp 0, [S], ttl 64) IP 4.4.4.4 > 1.1.1.1: ICMP echo request, id 13370, seq 2, length 64
10:01:41.763448 MPLS (label 0, exp 0, [S], ttl 254) IP 1.1.1.1 > 4.4.4.4: ICMP echo reply, id 13370, seq 2, length 64
10:01:42.761758 MPLS (label 24000, exp 0, [S], ttl 64) IP 4.4.4.4 > 1.1.1.1: ICMP echo request, id 13370, seq 3, length 64
10:01:42.764924 MPLS (label 0, exp 0, [S], ttl 254) IP 1.1.1.1 > 4.4.4.4: ICMP echo reply, id 13370, seq 3, length 64
10:01:43.763193 MPLS (label 24000, exp 0, [S], ttl 64) IP 4.4.4.4 > 1.1.1.1: ICMP echo request, id 13370, seq 4, length 64
10:01:43.766237 MPLS (label 0, exp 0, [S], ttl 254) IP 1.1.1.1 > 4.4.4.4: ICMP echo reply, id 13370, seq 4, length 64
10:01:44.764552 MPLS (label 24000, exp 0, [S], ttl 64) IP 4.4.4.4 > 1.1.1.1: ICMP echo request, id 13370, seq 5, length 64
10:01:44.767803 MPLS (label 0, exp 0, [S], ttl 254) IP 1.1.1.1 > 4.4.4.4: ICMP echo reply, id 13370, seq 5, length 64
```

109
doc/ldpd.8 Normal file
View File

@ -0,0 +1,109 @@
.TH LDPD 8 "29 March 2016" "Quagga LDP daemon" "Version 1.0.20160309"
.SH NAME
ldpd \- an LDP engine for use with Quagga routing software.
.SH SYNOPSIS
.B ldpd
[
.B \-dhv
] [
.B \-f
.I config-file
] [
.B \-i
.I pid-file
] [
.B \-P
.I port-number
] [
.B \-A
.I vty-address
] [
.B \-u
.I user
] [
.B \-g
.I group
]
.SH DESCRIPTION
.B ldpd
is a component that works with the
.B Quagga
routing engine.
.SH OPTIONS
Options available for the
.B ldpd
command:
.TP
\fB\-d\fR, \fB\-\-daemon\fR
Runs in daemon mode, forking and exiting from tty.
.TP
\fB\-f\fR, \fB\-\-config-file \fR\fIconfig-file\fR
Specifies the config file to use for startup. If not specified this
option will likely default to \fB\fI/usr/local/etc/ldpd.conf\fR.
.TP
\fB\-g\fR, \fB\-\-group \fR\fIgroup\fR
Specify the group to run as. Default is \fIquagga\fR.
.TP
\fB\-h\fR, \fB\-\-help\fR
A brief message.
.TP
\fB\-i\fR, \fB\-\-pid_file \fR\fIpid-file\fR
When ldpd starts its process identifier is written to
\fB\fIpid-file\fR. The init system uses the recorded PID to stop or
restart ldpd. The likely default is \fB\fI/var/run/ldpd.pid\fR.
.TP
\fB\-P\fR, \fB\-\-vty_port \fR\fIport-number\fR
Specify the port that the ldpd VTY will listen on. This defaults to
2612, as specified in \fB\fI/etc/services\fR.
.TP
\fB\-A\fR, \fB\-\-vty_addr \fR\fIvty-address\fR
Specify the address that the ldpd VTY will listen on. Default is all
interfaces.
.TP
\fB\-u\fR, \fB\-\-user \fR\fIuser\fR
Specify the user to run as. Default is \fIquagga\fR.
.TP
\fB\-v\fR, \fB\-\-version\fR
Print the version and exit.
.SH FILES
.TP
.BI /usr/local/sbin/ldpd
The default location of the
.B ldpd
binary.
.TP
.BI /usr/local/etc/ldpd.conf
The default location of the
.B ldpd
config file.
.TP
.BI $(PWD)/ldpd.log
If the
.B ldpd
process is config'd to output logs to a file, then you will find this
file in the directory where you started \fBldpd\fR.
.SH WARNING
This man page is intended to be a quick reference for command line
options. The definitive document is the Info file \fBQuagga\fR.
.SH DIAGNOSTICS
The ldpd process may log to standard output, to a VTY, to a log
file, or through syslog to the system logs. \fBldpd\fR supports many
debugging options, see the Info file, or the source for details.
.SH "SEE ALSO"
.BR bgpd (8),
.BR ripd (8),
.BR ripngd (8),
.BR ospfd (8),
.BR ospf6d (8),
.BR isisd (8),
.BR zebra (8),
.BR vtysh (1)
.SH BUGS
.B ldpd
eats bugs for breakfast. If you have food for the maintainers try
.BI http://bugzilla.quagga.net
.SH AUTHORS
See
.BI http://www.quagga.net
or the Info file for an accurate list of authors.

Some files were not shown because too many files have changed in this diff Show More