mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-08 11:18:43 +00:00
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:
commit
e52702f29d
6
.gitignore
vendored
6
.gitignore
vendored
@ -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
|
||||
|
10
Makefile.am
10
Makefile.am
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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. */
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 */
|
||||
|
@ -35,7 +35,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
static struct hash *ecomhash;
|
||||
|
||||
/* Allocate a new ecommunities. */
|
||||
static struct ecommunity *
|
||||
struct ecommunity *
|
||||
ecommunity_new (void)
|
||||
{
|
||||
return (struct ecommunity *) XCALLOC (MTYPE_ECOMMUNITY,
|
||||
@ -59,7 +59,7 @@ ecommunity_free (struct ecommunity **ecom)
|
||||
structure, we don't add the value. Newly added value is sorted by
|
||||
numerical order. When the value is added to the structure return 1
|
||||
else return 0. */
|
||||
static int
|
||||
int
|
||||
ecommunity_add_val (struct ecommunity *ecom, struct ecommunity_val *eval)
|
||||
{
|
||||
u_int8_t *p;
|
||||
|
@ -85,4 +85,7 @@ extern char *ecommunity_ecom2str (struct ecommunity *, int);
|
||||
extern int ecommunity_match (const struct ecommunity *, const struct ecommunity *);
|
||||
extern char *ecommunity_str (struct ecommunity *);
|
||||
|
||||
/* for vpn */
|
||||
extern struct ecommunity *ecommunity_new (void);
|
||||
extern int ecommunity_add_val (struct ecommunity *, struct ecommunity_val *);
|
||||
#endif /* _QUAGGA_BGP_ECOMMUNITY_H */
|
||||
|
@ -45,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
|
||||
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -108,3 +108,6 @@ DEFINE_MTYPE(BGPD, BGP_REDIST, "BGP redistribution")
|
||||
DEFINE_MTYPE(BGPD, BGP_FILTER_NAME, "BGP Filter Information")
|
||||
DEFINE_MTYPE(BGPD, BGP_DUMP_STR, "BGP Dump String Information")
|
||||
DEFINE_MTYPE(BGPD, ENCAP_TLV, "ENCAP TLV")
|
||||
|
||||
DEFINE_MTYPE(BGPD, BGP_TEA_OPTIONS, "BGP TEA Options")
|
||||
DEFINE_MTYPE(BGPD, BGP_TEA_OPTIONS_VALUE, "BGP TEA Options Value")
|
||||
|
@ -105,4 +105,7 @@ DECLARE_MTYPE(BGP_FILTER_NAME)
|
||||
DECLARE_MTYPE(BGP_DUMP_STR)
|
||||
DECLARE_MTYPE(ENCAP_TLV)
|
||||
|
||||
DECLARE_MTYPE(BGP_TEA_OPTIONS)
|
||||
DECLARE_MTYPE(BGP_TEA_OPTIONS_VALUE)
|
||||
|
||||
#endif /* _QUAGGA_BGP_MEMORY_H */
|
||||
|
@ -35,16 +35,35 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "bgpd/bgp_attr.h"
|
||||
#include "bgpd/bgp_mplsvpn.h"
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
|
331
bgpd/bgp_route.c
331
bgpd/bgp_route.c
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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.
|
||||
|
||||
@ -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,
|
||||
};
|
||||
|
||||
|
||||
@ -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,
|
||||
};
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3777,7 +3721,6 @@ DEFUN (no_set_aggregator_as,
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
DEFUN (match_ipv6_next_hop,
|
||||
match_ipv6_next_hop_cmd,
|
||||
|
@ -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
41
bgpd/bgp_vnc_types.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2015-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_BGP_VNC_TYPES_H
|
||||
#define _QUAGGA_BGP_VNC_TYPES_H
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
typedef enum {
|
||||
BGP_VNC_SUBTLV_TYPE_LIFETIME=1,
|
||||
BGP_VNC_SUBTLV_TYPE_RFPOPTION=2, /* deprecated */
|
||||
} bgp_vnc_subtlv_types;
|
||||
|
||||
/*
|
||||
* VNC Attribute subtlvs
|
||||
*/
|
||||
struct bgp_vnc_subtlv_lifetime {
|
||||
uint32_t lifetime;
|
||||
};
|
||||
|
||||
struct bgp_vnc_subtlv_unaddr {
|
||||
struct prefix un_address; /* IPv4 or IPv6; pfx length ignored */
|
||||
};
|
||||
|
||||
#endif /* ENABLE_BGP_VNC */
|
||||
#endif /* _QUAGGA_BGP_VNC_TYPES_H */
|
122
bgpd/bgp_vty.c
122
bgpd/bgp_vty.c
@ -4553,6 +4553,7 @@ DEFUN (no_neighbor_port,
|
||||
/* neighbor weight. */
|
||||
static int
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
@ -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);
|
||||
@ -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);
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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
|
||||
@ -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,18 +11083,12 @@ 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 ();
|
||||
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
196
bgpd/bgpd.c
196
bgpd/bgpd.c
@ -63,6 +63,10 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "bgpd/bgp_damp.h"
|
||||
#include "bgpd/bgp_mplsvpn.h"
|
||||
#include "bgpd/bgp_encap.h"
|
||||
#if ENABLE_BGP_VNC
|
||||
#include "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
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UNSET_FLAG (peer->config, PEER_CONFIG_WEIGHT);
|
||||
|
||||
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
|
||||
return 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);
|
||||
}
|
||||
|
||||
/* 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
89
bgpd/bgpd.conf.vnc.sample
Normal file
@ -0,0 +1,89 @@
|
||||
hostname H192.1.1.1
|
||||
password zebra
|
||||
#enable password zebra
|
||||
log stdout notifications
|
||||
log monitor notifications
|
||||
#debug bgp
|
||||
|
||||
line vty
|
||||
exec-timeout 1000
|
||||
exit
|
||||
|
||||
|
||||
router bgp 64512
|
||||
|
||||
# Must set a router-id if no zebra (default 0.0.0.0)
|
||||
bgp router-id 192.1.1.1
|
||||
|
||||
neighbor 192.1.1.2 remote-as 64512
|
||||
neighbor 192.1.1.2 description H192.1.1.2
|
||||
neighbor 192.1.1.2 update-source 192.1.1.1
|
||||
neighbor 192.1.1.2 advertisement-interval 1
|
||||
no neighbor 192.1.1.2 activate
|
||||
|
||||
neighbor 192.1.1.3 remote-as 64512
|
||||
neighbor 192.1.1.3 description H192.1.1.3
|
||||
neighbor 192.1.1.3 update-source 192.1.1.1
|
||||
neighbor 192.1.1.3 advertisement-interval 1
|
||||
no neighbor 192.1.1.3 activate
|
||||
|
||||
address-family vpnv4
|
||||
neighbor 192.1.1.2 activate
|
||||
neighbor 192.1.1.3 activate
|
||||
exit-address-family
|
||||
|
||||
address-family vpnv6
|
||||
neighbor 192.1.1.2 activate
|
||||
neighbor 192.1.1.3 activate
|
||||
exit-address-family
|
||||
|
||||
vnc defaults
|
||||
rd auto:vn:5226
|
||||
response-lifetime 45
|
||||
rt both 1000:1 1000:2
|
||||
exit-vnc
|
||||
|
||||
vnc nve-group group1
|
||||
prefix vn 172.16.0.0/16
|
||||
exit-vnc
|
||||
|
||||
vnc nve-group red
|
||||
prefix vn 10.0.0.0/8
|
||||
rd auto:vn:10
|
||||
rt both 1000:10
|
||||
exit-vnc
|
||||
|
||||
vnc nve-group blue
|
||||
prefix vn 20.0.0.0/8
|
||||
rd auto:vn:20
|
||||
rt both 1000:20
|
||||
exit-vnc
|
||||
|
||||
vnc nve-group green
|
||||
prefix vn 30.0.0.0/8
|
||||
rd auto:vn:20
|
||||
rt both 1000:30
|
||||
exit-vnc
|
||||
|
||||
vnc nve-group rfc4291v6c
|
||||
prefix vn ::ac10:0/112
|
||||
rd auto:vn:5227
|
||||
rt both 2000:1
|
||||
exit-vnc
|
||||
|
||||
vnc nve-group rfc4291v6m
|
||||
prefix vn ::ffff:ac10:0/112
|
||||
rd auto:vn:5528
|
||||
rt both 3000:1
|
||||
exit-vnc
|
||||
|
||||
vnc nve-group rfc6052v6
|
||||
prefix vn 64:ff9b::ac10:0/112
|
||||
rd auto:vn:5529
|
||||
rt both 4000:1
|
||||
exit-vnc
|
||||
|
||||
exit
|
||||
|
||||
|
||||
|
37
bgpd/bgpd.h
37
bgpd/bgpd.h
@ -351,6 +351,11 @@ struct bgp
|
||||
|
||||
u_int32_t addpath_tx_id;
|
||||
int addpath_tx_used[AFI_MAX][SAFI_MAX];
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
struct rfapi_cfg *rfapi_cfg;
|
||||
struct rfapi *rfapi;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define BGP_ROUTE_ADV_HOLD(bgp) (bgp->main_peers_update_hold)
|
||||
@ -417,6 +422,8 @@ struct bgp_rd
|
||||
#define RMAP_OUT 1
|
||||
#define RMAP_MAX 2
|
||||
|
||||
#include "filter.h"
|
||||
|
||||
/* BGP filter structure. */
|
||||
struct bgp_filter
|
||||
{
|
||||
@ -657,6 +664,9 @@ struct peer
|
||||
#define PEER_FLAG_DYNAMIC_NEIGHBOR (1 << 12) /* dynamic neighbor */
|
||||
#define PEER_FLAG_CAPABILITY_ENHE (1 << 13) /* Extended next-hop (rfc 5549)*/
|
||||
#define PEER_FLAG_IFPEER_V6ONLY (1 << 14) /* if-based peer is v6 only */
|
||||
#if ENABLE_BGP_VNC
|
||||
#define PEER_FLAG_IS_RFAPI_HD (1 << 15) /* attached to rfapi HD */
|
||||
#endif
|
||||
|
||||
/* NSF mode (graceful restart) */
|
||||
u_char nsf[AFI_MAX][SAFI_MAX];
|
||||
@ -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
1
bgpd/rfapi/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
.dirstamp
|
4643
bgpd/rfapi/bgp_rfapi_cfg.c
Normal file
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
318
bgpd/rfapi/bgp_rfapi_cfg.h
Normal 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
4386
bgpd/rfapi/rfapi.c
Normal file
File diff suppressed because it is too large
Load Diff
980
bgpd/rfapi/rfapi.h
Normal file
980
bgpd/rfapi/rfapi.h
Normal file
@ -0,0 +1,980 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_BGP_RFAPI_H
|
||||
#define _QUAGGA_BGP_RFAPI_H
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
|
||||
#include <stdint.h>
|
||||
#include <netinet/in.h>
|
||||
#include "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
629
bgpd/rfapi/rfapi_ap.c
Normal file
@ -0,0 +1,629 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "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
99
bgpd/rfapi/rfapi_ap.h
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
#ifndef _QUAGGA_BGP_RFAPI_AP_H
|
||||
#define _QUAGGA_BGP_RFAPI_AP_H
|
||||
|
||||
/* TBD delete some of these #includes */
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "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 */
|
92
bgpd/rfapi/rfapi_backend.h
Normal file
92
bgpd/rfapi/rfapi_backend.h
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_BGP_RFAPI_BACKEND_H
|
||||
#define _QUAGGA_BGP_RFAPI_BACKEND_H
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
|
||||
#include "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 */
|
131
bgpd/rfapi/rfapi_descriptor_rfp_utils.c
Normal file
131
bgpd/rfapi/rfapi_descriptor_rfp_utils.c
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "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;
|
||||
}
|
39
bgpd/rfapi/rfapi_descriptor_rfp_utils.h
Normal file
39
bgpd/rfapi/rfapi_descriptor_rfp_utils.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
extern void *rfapi_create_generic (struct rfapi_ip_addr *vn,
|
||||
struct rfapi_ip_addr *un);
|
||||
|
||||
/*------------------------------------------
|
||||
* rfapi_free_generic
|
||||
*
|
||||
* Compare two generic rfapi descriptors.
|
||||
*
|
||||
* input:
|
||||
* grfd: rfapi descriptor returned by rfapi_open or rfapi_create_generic
|
||||
*
|
||||
* output:
|
||||
*
|
||||
* return value:
|
||||
*
|
||||
*------------------------------------------*/
|
||||
extern void rfapi_free_generic (void *grfd);
|
812
bgpd/rfapi/rfapi_encap_tlv.c
Normal file
812
bgpd/rfapi/rfapi_encap_tlv.c
Normal file
@ -0,0 +1,812 @@
|
||||
/*
|
||||
* Copyright 2015-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "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);
|
||||
}
|
||||
}
|
43
bgpd/rfapi/rfapi_encap_tlv.h
Normal file
43
bgpd/rfapi/rfapi_encap_tlv.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2015-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_BGP_RFAPI_ENCAP_TLV_H
|
||||
#define _QUAGGA_BGP_RFAPI_ENCAP_TLV_H
|
||||
|
||||
#define RFAPI_BGP_ENCAP_TYPE_DEFAULT BGP_ENCAP_TYPE_IP_IN_IP
|
||||
|
||||
extern bgp_encap_types
|
||||
rfapi_tunneltype_option_to_tlv (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_ip_addr *ea,
|
||||
struct rfapi_tunneltype_option *tto,
|
||||
struct attr *attr,
|
||||
int always_add);
|
||||
|
||||
extern struct rfapi_un_option *
|
||||
rfapi_encap_tlv_to_un_option (struct attr *attr);
|
||||
|
||||
extern void
|
||||
rfapi_print_tunneltype_option (
|
||||
void *stream,
|
||||
int column_offset,
|
||||
struct rfapi_tunneltype_option *tto);
|
||||
|
||||
|
||||
#endif /* _QUAGGA_BGP_RFAPI_ENCAP_TLV_H */
|
5150
bgpd/rfapi/rfapi_import.c
Normal file
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
283
bgpd/rfapi/rfapi_import.h
Normal file
@ -0,0 +1,283 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* File: rfapi_import.h
|
||||
* Purpose: Handle import of routes from BGP to RFAPI
|
||||
*/
|
||||
|
||||
#ifndef QUAGGA_HGP_RFAPI_IMPORT_H
|
||||
#define QUAGGA_HGP_RFAPI_IMPORT_H
|
||||
|
||||
#include "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
1701
bgpd/rfapi/rfapi_monitor.c
Normal file
File diff suppressed because it is too large
Load Diff
217
bgpd/rfapi/rfapi_monitor.h
Normal file
217
bgpd/rfapi/rfapi_monitor.h
Normal file
@ -0,0 +1,217 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QUAGGA_HGP_RFAPI_MONITOR_H
|
||||
#define QUAGGA_HGP_RFAPI_MONITOR_H
|
||||
|
||||
#include "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
175
bgpd/rfapi/rfapi_nve_addr.c
Normal file
@ -0,0 +1,175 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "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;
|
||||
}
|
43
bgpd/rfapi/rfapi_nve_addr.h
Normal file
43
bgpd/rfapi/rfapi_nve_addr.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_BGP_RFAPI_NVE_ADDR_H
|
||||
#define _QUAGGA_BGP_RFAPI_NVE_ADDR_H
|
||||
|
||||
#include "rfapi.h"
|
||||
|
||||
struct rfapi_nve_addr
|
||||
{
|
||||
struct rfapi_ip_addr vn;
|
||||
struct rfapi_ip_addr un;
|
||||
void *info;
|
||||
};
|
||||
|
||||
|
||||
extern int
|
||||
rfapi_nve_addr_cmp (void *k1, void *k2);
|
||||
|
||||
extern void
|
||||
rfapiNveAddr2Str (struct rfapi_nve_addr *na, char *buf, int bufsize);
|
||||
|
||||
|
||||
|
||||
#endif /* _QUAGGA_BGP_RFAPI_NVE_ADDR_H */
|
455
bgpd/rfapi/rfapi_private.h
Normal file
455
bgpd/rfapi/rfapi_private.h
Normal file
@ -0,0 +1,455 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Internal definitions for RFAPI. Not for use by other code
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_BGP_RFAPI_PRIVATE_H
|
||||
#define _QUAGGA_BGP_RFAPI_PRIVATE_H
|
||||
|
||||
#include "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
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
154
bgpd/rfapi/rfapi_rib.h
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* File: rfapi_rib.h
|
||||
* Purpose: per-nve rib
|
||||
*/
|
||||
|
||||
#ifndef QUAGGA_HGP_RFAPI_RIB_H
|
||||
#define QUAGGA_HGP_RFAPI_RIB_H
|
||||
|
||||
/*
|
||||
* Key for indexing RIB and Pending RIB skiplists. For L3 RIBs,
|
||||
* the VN address is sufficient because it represents the actual next hop.
|
||||
*
|
||||
* For L2 RIBs, it is possible to have multiple routes to a given L2
|
||||
* prefix via a given VN address, but each route having a unique aux_prefix.
|
||||
*/
|
||||
struct rfapi_rib_key
|
||||
{
|
||||
struct prefix vn;
|
||||
struct prefix_rd rd;
|
||||
|
||||
/*
|
||||
* for L2 routes: optional IP addr
|
||||
* .family == 0 means "none"
|
||||
*/
|
||||
struct prefix aux_prefix;
|
||||
};
|
||||
|
||||
struct rfapi_info
|
||||
{
|
||||
struct rfapi_rib_key rk; /* NVE VN addr + aux addr */
|
||||
struct prefix un;
|
||||
uint8_t cost;
|
||||
uint32_t lifetime;
|
||||
time_t last_sent_time;
|
||||
uint32_t rsp_counter; /* dedup initial responses */
|
||||
struct bgp_tea_options *tea_options;
|
||||
struct rfapi_un_option *un_options;
|
||||
struct rfapi_vn_option *vn_options;
|
||||
void *timer;
|
||||
};
|
||||
|
||||
/*
|
||||
* Work item for updated responses queue
|
||||
*/
|
||||
struct rfapi_updated_responses_queue
|
||||
{
|
||||
struct rfapi_descriptor *rfd;
|
||||
afi_t afi;
|
||||
};
|
||||
|
||||
|
||||
extern void
|
||||
rfapiRibClear (struct rfapi_descriptor *rfd);
|
||||
|
||||
extern void
|
||||
rfapiRibFree (struct rfapi_descriptor *rfd);
|
||||
|
||||
extern void
|
||||
rfapiRibUpdatePendingNode (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_descriptor *rfd,
|
||||
struct rfapi_import_table *it,
|
||||
struct route_node *it_node,
|
||||
uint32_t lifetime);
|
||||
|
||||
extern void
|
||||
rfapiRibUpdatePendingNodeSubtree (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_descriptor *rfd,
|
||||
struct rfapi_import_table *it,
|
||||
struct route_node *it_node,
|
||||
struct route_node *omit_subtree,
|
||||
uint32_t lifetime);
|
||||
|
||||
extern int
|
||||
rfapiRibPreloadBi(
|
||||
struct route_node *rfd_rib_node,
|
||||
struct prefix *pfx_vn,
|
||||
struct prefix *pfx_un,
|
||||
uint32_t lifetime,
|
||||
struct bgp_info *bi);
|
||||
|
||||
extern struct rfapi_next_hop_entry *
|
||||
rfapiRibPreload (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_descriptor *rfd,
|
||||
struct rfapi_next_hop_entry *response,
|
||||
int use_eth_resolution);
|
||||
|
||||
extern void
|
||||
rfapiRibPendingDeleteRoute (
|
||||
struct bgp *bgp,
|
||||
struct rfapi_import_table *it,
|
||||
afi_t afi,
|
||||
struct route_node *it_node);
|
||||
|
||||
extern void
|
||||
rfapiRibShowResponsesSummary (void *stream);
|
||||
|
||||
extern void
|
||||
rfapiRibShowResponsesSummaryClear (void);
|
||||
|
||||
extern void
|
||||
rfapiRibShowResponses (
|
||||
void *stream,
|
||||
struct prefix *pfx_match,
|
||||
int show_removed);
|
||||
|
||||
extern int
|
||||
rfapiRibFTDFilterRecentPrefix(
|
||||
struct rfapi_descriptor *rfd,
|
||||
struct route_node *it_rn, /* import table node */
|
||||
struct prefix *pfx_target_original); /* query target */
|
||||
|
||||
extern void
|
||||
rfapiFreeRfapiUnOptionChain (struct rfapi_un_option *p);
|
||||
|
||||
extern void
|
||||
rfapiFreeRfapiVnOptionChain (struct rfapi_vn_option *p);
|
||||
|
||||
extern void
|
||||
rfapiRibCheckCounts (
|
||||
int checkstats, /* validate rfd & global counts */
|
||||
unsigned int offset); /* number of ri's held separately */
|
||||
|
||||
/* enable for debugging; disable for performance */
|
||||
#if 0
|
||||
#define RFAPI_RIB_CHECK_COUNTS(checkstats, offset) rfapiRibCheckCounts(checkstats, offset)
|
||||
#else
|
||||
#define RFAPI_RIB_CHECK_COUNTS(checkstats, offset)
|
||||
#endif
|
||||
|
||||
#endif /* QUAGGA_HGP_RFAPI_RIB_H */
|
5016
bgpd/rfapi/rfapi_vty.c
Normal file
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
223
bgpd/rfapi/rfapi_vty.h
Normal file
@ -0,0 +1,223 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef RFAPI_VTY_H
|
||||
#define RFAPI_VTY_H
|
||||
|
||||
#include "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
230
bgpd/rfapi/vnc_debug.c
Normal file
@ -0,0 +1,230 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "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
49
bgpd/rfapi/vnc_debug.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_BGP_VNC_DEBUG_H
|
||||
#define _QUAGGA_BGP_VNC_DEBUG_H
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
|
||||
/*
|
||||
* debug state storage
|
||||
*/
|
||||
extern unsigned long conf_vnc_debug;
|
||||
extern unsigned long term_vnc_debug;
|
||||
|
||||
/*
|
||||
* debug flag bits
|
||||
*/
|
||||
#define VNC_DEBUG_RFAPI_QUERY 0x00000001
|
||||
#define VNC_DEBUG_IMPORT_BI_ATTACH 0x00000002
|
||||
#define VNC_DEBUG_IMPORT_DEL_REMOTE 0x00000004
|
||||
#define VNC_DEBUG_EXPORT_BGP_GETCE 0x00000008
|
||||
#define VNC_DEBUG_EXPORT_BGP_DIRECT_ADD 0x00000010
|
||||
#define VNC_DEBUG_IMPORT_BGP_ADD_ROUTE 0x00000020
|
||||
|
||||
#define VNC_DEBUG(bit) (term_vnc_debug & (VNC_DEBUG_ ## bit))
|
||||
|
||||
extern void
|
||||
vnc_debug_init (void);
|
||||
|
||||
#endif /* ENABLE_BGP_VNC */
|
||||
|
||||
#endif /* _QUAGGA_BGP_VNC_DEBUG_H */
|
2177
bgpd/rfapi/vnc_export_bgp.c
Normal file
2177
bgpd/rfapi/vnc_export_bgp.c
Normal file
File diff suppressed because it is too large
Load Diff
42
bgpd/rfapi/vnc_export_bgp.h
Normal file
42
bgpd/rfapi/vnc_export_bgp.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_RFAPI_VNC_EXPORT_BGP_H_
|
||||
#define _QUAGGA_RFAPI_VNC_EXPORT_BGP_H_
|
||||
|
||||
#include "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_ */
|
95
bgpd/rfapi/vnc_export_bgp_p.h
Normal file
95
bgpd/rfapi/vnc_export_bgp_p.h
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_RFAPI_VNC_EXPORT_BGP_P_H_
|
||||
#define _QUAGGA_RFAPI_VNC_EXPORT_BGP_P_H_
|
||||
|
||||
#include "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_ */
|
214
bgpd/rfapi/vnc_export_table.c
Normal file
214
bgpd/rfapi/vnc_export_table.c
Normal file
@ -0,0 +1,214 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "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;
|
||||
}
|
85
bgpd/rfapi/vnc_export_table.h
Normal file
85
bgpd/rfapi/vnc_export_table.h
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_VNC_VNC_EXPORT_TABLE_H_
|
||||
#define _QUAGGA_VNC_VNC_EXPORT_TABLE_H_
|
||||
|
||||
#include "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
3136
bgpd/rfapi/vnc_import_bgp.c
Normal file
File diff suppressed because it is too large
Load Diff
93
bgpd/rfapi/vnc_import_bgp.h
Normal file
93
bgpd/rfapi/vnc_import_bgp.h
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_RFAPI_VNC_IMPORT_BGP_H_
|
||||
#define _QUAGGA_RFAPI_VNC_IMPORT_BGP_H_
|
||||
|
||||
#include "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_ */
|
51
bgpd/rfapi/vnc_import_bgp_p.h
Normal file
51
bgpd/rfapi/vnc_import_bgp_p.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_RFAPI_VNC_IMPORT_BGP_P_H_
|
||||
#define _QUAGGA_RFAPI_VNC_IMPORT_BGP_P_H_
|
||||
|
||||
#include "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
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
67
bgpd/rfapi/vnc_zebra.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2009-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* File: vnc_zebra.h
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_BGP_VNC_ZEBRA_H
|
||||
#define _QUAGGA_BGP_VNC_ZEBRA_H
|
||||
|
||||
#include "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 */
|
40
bgpd/rfp-example/librfp/Makefile.am
Normal file
40
bgpd/rfp-example/librfp/Makefile.am
Normal file
@ -0,0 +1,40 @@
|
||||
#
|
||||
# This file has been modified by LabN Consulting, L.L.C.
|
||||
#
|
||||
#
|
||||
## Process this file with automake to produce Makefile.in.
|
||||
|
||||
if ENABLE_BGP_VNC
|
||||
BGP_VNC_RFAPI_INC=-I$(top_srcdir)/bgpd/rfapi
|
||||
BGP_VNC_RFP_LIBDIR=.
|
||||
BGP_VNC_RFP_INCDIR=$(BGP_VNC_RFP_LIBDIR)
|
||||
BGP_VNC_RFP_LIB=librfp.a
|
||||
BGP_VNC_RFP_INC=-I$(BGP_VNC_RFP_INCDIR)
|
||||
|
||||
librfp_a_SOURCES = \
|
||||
rfp_example.c
|
||||
|
||||
librfp_a_INCLUDES = \
|
||||
rfp.h \
|
||||
rfp_internal.h
|
||||
|
||||
else
|
||||
BGP_VNC_RFAPI_INC=
|
||||
BGP_VNC_RFAPI_SRC=
|
||||
BGP_VNC_RFP_LIB=
|
||||
BGP_VNC_RFP_INC=
|
||||
endif
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib \
|
||||
-I$(top_builddir) -I$(top_builddir)/lib \
|
||||
$(BGP_VNC_RFAPI_INC) $(BGP_VNC_RFP_INC)
|
||||
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
|
||||
INSTALL_SDATA=@INSTALL@ -m 600
|
||||
|
||||
AM_CFLAGS = $(PICFLAGS)
|
||||
AM_LDFLAGS = $(PILDFLAGS)
|
||||
|
||||
noinst_LIBRARIES = $(BGP_VNC_RFP_LIB)
|
||||
|
||||
noinst_HEADERS = \
|
||||
$(librfp_a_INCLUDES)
|
31
bgpd/rfp-example/librfp/rfp.h
Normal file
31
bgpd/rfp-example/librfp/rfp.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2015-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Sample header file */
|
||||
#ifndef _RFP_H
|
||||
#define _RFP_H
|
||||
|
||||
#include "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 */
|
286
bgpd/rfp-example/librfp/rfp_example.c
Normal file
286
bgpd/rfp-example/librfp/rfp_example.c
Normal file
@ -0,0 +1,286 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2015-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/* stub rfp */
|
||||
#include "rfp_internal.h"
|
||||
#include "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;
|
||||
}
|
29
bgpd/rfp-example/librfp/rfp_internal.h
Normal file
29
bgpd/rfp-example/librfp/rfp_internal.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2015-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Sample header file */
|
||||
#ifndef _RFP_INTERNAL_H
|
||||
#define _RFP_INTERNAL_H
|
||||
#include "lib/zebra.h"
|
||||
#include "rfp.h"
|
||||
#include "bgpd/rfapi/rfapi.h"
|
||||
|
||||
#endif /* _RFP_INTERNAL_H */
|
52
bgpd/rfp-example/rfptest/Makefile.am
Normal file
52
bgpd/rfp-example/rfptest/Makefile.am
Normal file
@ -0,0 +1,52 @@
|
||||
#
|
||||
# This file has been modified by LabN Consulting, L.L.C.
|
||||
#
|
||||
#
|
||||
## Process this file with automake to produce Makefile.in.
|
||||
|
||||
if ENABLE_BGP_VNC
|
||||
BGP_VNC_RFAPI_INC=-I$(top_srcdir)/bgpd/rfapi
|
||||
BGP_VNC_RFP_LIBDIR=../librfp
|
||||
BGP_VNC_RFP_INCDIR=$(BGP_VNC_RFP_LIBDIR)
|
||||
BGP_VNC_RFP_LIB=$(BGP_VNC_RFP_LIBDIR)/librfp.a
|
||||
BGP_VNC_RFP_INC=-I$(BGP_VNC_RFP_INCDIR)
|
||||
|
||||
rfptest_SOURCES = \
|
||||
rfptest.c
|
||||
|
||||
rfptest_INCLUDES = \
|
||||
rfptest.h
|
||||
|
||||
|
||||
RFPTEST_BIN = rfptest
|
||||
|
||||
else
|
||||
BGP_VNC_RFAPI_INC=
|
||||
BGP_VNC_RFAPI_SRC=
|
||||
BGP_VNC_RFP_LIB=
|
||||
BGP_VNC_RFP_INC=
|
||||
RFPTEST_BIN=
|
||||
endif
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib \
|
||||
-I$(top_builddir) -I$(top_builddir)/lib \
|
||||
$(BGP_VNC_RFAPI_INC) $(BGP_VNC_RFP_INC)
|
||||
|
||||
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
|
||||
INSTALL_SDATA=@INSTALL@ -m 600
|
||||
|
||||
|
||||
AM_CFLAGS = $(PICFLAGS)
|
||||
AM_LDFLAGS = $(PILDFLAGS)
|
||||
|
||||
|
||||
noinst_HEADERS = \
|
||||
$(rfptest_INCLUDES)
|
||||
|
||||
noinst_LIBRARIES =
|
||||
sbin_PROGRAMS = $(RFPTEST_BIN)
|
||||
|
||||
examplesdir = $(exampledir)
|
||||
|
||||
rfptest_LDADD = $(top_builddir)/lib/libzebra.la $(BGP_VNC_RFP_LIB)
|
||||
dist_examples_DATA =
|
32
bgpd/rfp-example/rfptest/rfptest.c
Normal file
32
bgpd/rfp-example/rfptest/rfptest.c
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2015-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* dummy test program */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "rfptest.h"
|
||||
int
|
||||
main ()
|
||||
{
|
||||
printf ("Your test code goes here.\n");
|
||||
exit (1);
|
||||
}
|
26
bgpd/rfp-example/rfptest/rfptest.h
Normal file
26
bgpd/rfp-example/rfptest/rfptest.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2015-2016, LabN Consulting, L.L.C.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Sample header file */
|
||||
#ifndef _RFPTEST_H
|
||||
#define _RFPTEST_H
|
||||
|
||||
#endif /* _RFPTEST_H */
|
41
common.am
Normal file
41
common.am
Normal 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)
|
163
configure.ac
163
configure.ac
@ -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
6
debian/changelog
vendored
@ -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
3
debian/rules
vendored
@ -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:
|
||||
|
@ -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
|
||||
|
@ -581,6 +581,10 @@ Redistribute RIP route to BGP process.
|
||||
Redistribute OSPF route to BGP process.
|
||||
@end deffn
|
||||
|
||||
@deffn {BGP} {redistribute vpn} {}
|
||||
Redistribute VNC routes to BGP process.
|
||||
@end deffn
|
||||
|
||||
@deffn {BGP} {update-delay @var{max-delay}} {}
|
||||
@deffnx {BGP} {update-delay @var{max-delay} @var{establish-wait}} {}
|
||||
This feature is used to enable read-only mode on BGP process restart or when
|
||||
|
794
doc/fig-vnc-commercial-route-reflector.dia
Normal file
794
doc/fig-vnc-commercial-route-reflector.dia
Normal file
@ -0,0 +1,794 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<dia:diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">
|
||||
<dia:diagramdata>
|
||||
<dia:attribute name="background">
|
||||
<dia:color val="#ffffff"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pagebreak">
|
||||
<dia:color val="#000099"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="paper">
|
||||
<dia:composite type="paper">
|
||||
<dia:attribute name="name">
|
||||
<dia:string>#Letter#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="tmargin">
|
||||
<dia:real val="2.5399999618530273"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="bmargin">
|
||||
<dia:real val="2.5399999618530273"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="lmargin">
|
||||
<dia:real val="2.5399999618530273"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="rmargin">
|
||||
<dia:real val="2.5399999618530273"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="is_portrait">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="scaling">
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="fitto">
|
||||
<dia:boolean val="false"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="grid">
|
||||
<dia:composite type="grid">
|
||||
<dia:attribute name="width_x">
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="width_y">
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="visible_x">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="visible_y">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:composite type="color"/>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#d8e5e5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="guides">
|
||||
<dia:composite type="guides">
|
||||
<dia:attribute name="hguides"/>
|
||||
<dia:attribute name="vguides"/>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
</dia:diagramdata>
|
||||
<dia:layer name="Background" visible="true" active="true">
|
||||
<dia:object type="Standard - Box" version="0" id="O0">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,39.145"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="57.1801,39.095;64.0901,42.445"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="57.2301,39.145"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O1">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,34.2475"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="57.1801,34.1975;64.0901,37.5475"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="57.2301,34.2475"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O2">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,29.35"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="57.1801,29.3;64.0901,32.65"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="57.2301,29.35"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O3">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="2.1126,39.295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.0626,39.245;8.9726,42.595"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="2.1126,39.295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O4">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="2.1126,34.3975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.0626,34.3475;8.9726,37.6975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="2.1126,34.3975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O5">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="2.1126,29.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.0626,29.45;8.9726,32.8"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="2.1126,29.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O6">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="22.5347,32.178"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="22.4642,23.359;30.091,32.2485"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="22.5347,32.178"/>
|
||||
<dia:point val="30.0205,23.4295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O7">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="43.1205,32.4705"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="36.8099,23.3599;43.1901,32.5401"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="43.1205,32.4705"/>
|
||||
<dia:point val="36.8795,23.4295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O8">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="16.5501,5.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="16.5501,4.905;16.5501,5.6525"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>##</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="16.5501,5.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="0"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O9">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="5.5176,31.125"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="3.29385,30.5113;7.76004,32.1149"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 4
|
||||
VN 172.16.4.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="5.5176,31.125"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O5" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O10">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="5.5176,36.0225"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.88385,35.4088;8.17004,37.0124"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 5
|
||||
VN 172.16.130.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="5.5176,36.0225"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O4" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O11">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="5.5176,40.92"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.8826,40.3063;8.17129,41.9099"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 6
|
||||
VN 172.16.132.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="5.5176,40.92"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O3" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O12">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="60.6351,30.975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="58.4101,30.3613;62.8788,31.9649"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 7
|
||||
VN 172.16.6.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="60.6351,30.975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O2" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O13">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="60.6351,35.8725"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="58.4101,35.2588;62.8788,36.8624"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 8
|
||||
VN 172.16.8.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="60.6351,35.8725"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O1" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O14">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="60.6351,40.77"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="58.0026,40.1563;63.2863,41.7599"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 9
|
||||
VN 172.16.134.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="60.6351,40.77"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O0" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O15">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="8.9226,31.125"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="8.86406,31.0665;15.979,32.529"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="8.9226,31.125"/>
|
||||
<dia:point val="15.9205,32.4705"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O5" connection="4"/>
|
||||
<dia:connection handle="1" to="O24" connection="0"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O16">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="8.9226,36.0225"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="8.87151,35.8489;14.5511,36.0736"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="8.9226,36.0225"/>
|
||||
<dia:point val="14.5,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O4" connection="4"/>
|
||||
<dia:connection handle="1" to="O24" connection="3"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O17">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="8.9226,40.92"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="8.86276,39.2697;15.9803,40.9798"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="8.9226,40.92"/>
|
||||
<dia:point val="15.9205,39.3295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O3" connection="4"/>
|
||||
<dia:connection handle="1" to="O24" connection="5"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O18">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,30.975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="49.9204,30.9159;57.2892,32.5296"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="57.2301,30.975"/>
|
||||
<dia:point val="49.9795,32.4705"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O2" connection="3"/>
|
||||
<dia:connection handle="1" to="O22" connection="2"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O19">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,35.8725"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="51.3498,35.8223;57.2803,35.9502"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="57.2301,35.8725"/>
|
||||
<dia:point val="51.4,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O1" connection="3"/>
|
||||
<dia:connection handle="1" to="O22" connection="4"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O20">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,40.77"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="50.9399,37.8657;57.2963,40.8362"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="57.2301,40.77"/>
|
||||
<dia:point val="51.0061,37.9319"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O0" connection="3"/>
|
||||
<dia:connection handle="1" to="O22" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O21">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="34.8,20.45"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="34.8,19.855;34.8,20.6025"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>##</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="34.8,20.45"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="0"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:group>
|
||||
<dia:object type="Standard - Ellipse" version="0" id="O22">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="41.7,31.05"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="41.65,31;51.45,40.8"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="41.7,31.05"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="aspect">
|
||||
<dia:enum val="2"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O23">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="46.55,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="44.2012,35.305;48.8987,36.8525"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVA 3
|
||||
192.168.1.102#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="46.55,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O22" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
</dia:group>
|
||||
<dia:group>
|
||||
<dia:object type="Standard - Ellipse" version="0" id="O24">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="14.5,31.05"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="14.45,31;24.25,40.8"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="14.5,31.05"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="9.7000007629394531"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="9.7000007629394531"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="aspect">
|
||||
<dia:enum val="2"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O25">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="19.35,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="17.0013,35.305;21.6988,36.8525"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVA 2
|
||||
192.168.1.101#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="19.35,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O24" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
</dia:group>
|
||||
<dia:group>
|
||||
<dia:object type="Standard - Ellipse" version="0" id="O26">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="28.6,15.15"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="28.55,15.1;38.35,24.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="28.6,15.15"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="aspect">
|
||||
<dia:enum val="2"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O27">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="33.45,19.7"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="30.9863,19.105;35.9138,21.4525"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#Commercial Router
|
||||
Route Reflector
|
||||
192.168.1.104#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="33.45,19.7"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
</dia:group>
|
||||
</dia:layer>
|
||||
</dia:diagram>
|
BIN
doc/fig-vnc-commercial-route-reflector.png
Normal file
BIN
doc/fig-vnc-commercial-route-reflector.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 50 KiB |
0
doc/fig-vnc-commercial-route-reflector.txt
Normal file
0
doc/fig-vnc-commercial-route-reflector.txt
Normal file
1155
doc/fig-vnc-gw-rr.dia
Normal file
1155
doc/fig-vnc-gw-rr.dia
Normal file
File diff suppressed because it is too large
Load Diff
BIN
doc/fig-vnc-gw-rr.png
Normal file
BIN
doc/fig-vnc-gw-rr.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 78 KiB |
0
doc/fig-vnc-gw-rr.txt
Normal file
0
doc/fig-vnc-gw-rr.txt
Normal file
1058
doc/fig-vnc-gw.dia
Normal file
1058
doc/fig-vnc-gw.dia
Normal file
File diff suppressed because it is too large
Load Diff
BIN
doc/fig-vnc-gw.png
Normal file
BIN
doc/fig-vnc-gw.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 66 KiB |
0
doc/fig-vnc-gw.txt
Normal file
0
doc/fig-vnc-gw.txt
Normal file
1071
doc/fig-vnc-mesh.dia
Normal file
1071
doc/fig-vnc-mesh.dia
Normal file
File diff suppressed because it is too large
Load Diff
BIN
doc/fig-vnc-mesh.png
Normal file
BIN
doc/fig-vnc-mesh.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 60 KiB |
0
doc/fig-vnc-mesh.txt
Normal file
0
doc/fig-vnc-mesh.txt
Normal file
763
doc/fig-vnc-quagga-route-reflector.dia
Normal file
763
doc/fig-vnc-quagga-route-reflector.dia
Normal file
@ -0,0 +1,763 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<dia:diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">
|
||||
<dia:diagramdata>
|
||||
<dia:attribute name="background">
|
||||
<dia:color val="#ffffff"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pagebreak">
|
||||
<dia:color val="#000099"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="paper">
|
||||
<dia:composite type="paper">
|
||||
<dia:attribute name="name">
|
||||
<dia:string>#Letter#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="tmargin">
|
||||
<dia:real val="2.5399999618530273"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="bmargin">
|
||||
<dia:real val="2.5399999618530273"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="lmargin">
|
||||
<dia:real val="2.5399999618530273"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="rmargin">
|
||||
<dia:real val="2.5399999618530273"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="is_portrait">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="scaling">
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="fitto">
|
||||
<dia:boolean val="false"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="grid">
|
||||
<dia:composite type="grid">
|
||||
<dia:attribute name="width_x">
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="width_y">
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="visible_x">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="visible_y">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:composite type="color"/>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#d8e5e5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="guides">
|
||||
<dia:composite type="guides">
|
||||
<dia:attribute name="hguides"/>
|
||||
<dia:attribute name="vguides"/>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
</dia:diagramdata>
|
||||
<dia:layer name="Background" visible="true" active="true">
|
||||
<dia:object type="Standard - Box" version="0" id="O0">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,39.145"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="57.1801,39.095;64.0901,42.445"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="57.2301,39.145"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O1">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,34.2475"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="57.1801,34.1975;64.0901,37.5475"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="57.2301,34.2475"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O2">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,29.35"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="57.1801,29.3;64.0901,32.65"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="57.2301,29.35"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O3">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="2.1126,39.295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.0626,39.245;8.9726,42.595"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="2.1126,39.295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O4">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="2.1126,34.3975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.0626,34.3475;8.9726,37.6975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="2.1126,34.3975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O5">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="2.1126,29.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.0626,29.45;8.9726,32.8"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="2.1126,29.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O6">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="22.5347,32.178"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="22.4642,23.359;30.091,32.2485"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="22.5347,32.178"/>
|
||||
<dia:point val="30.0205,23.4295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O7">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="43.1205,32.4705"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="36.8099,23.3599;43.1901,32.5401"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="43.1205,32.4705"/>
|
||||
<dia:point val="36.8795,23.4295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O8">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="16.5501,5.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="16.5501,4.905;16.5501,5.6525"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>##</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="16.5501,5.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="0"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O9">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="5.5176,31.125"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="3.29385,30.5113;7.76004,32.1149"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 4
|
||||
VN 172.16.4.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="5.5176,31.125"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O5" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O10">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="5.5176,36.0225"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.88385,35.4088;8.17004,37.0124"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 5
|
||||
VN 172.16.130.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="5.5176,36.0225"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O4" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O11">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="5.5176,40.92"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.8826,40.3063;8.17129,41.9099"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 6
|
||||
VN 172.16.132.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="5.5176,40.92"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O3" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O12">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="60.6351,30.975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="58.4101,30.3613;62.8788,31.9649"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 7
|
||||
VN 172.16.6.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="60.6351,30.975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O2" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O13">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="60.6351,35.8725"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="58.4101,35.2588;62.8788,36.8624"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 8
|
||||
VN 172.16.8.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="60.6351,35.8725"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O1" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O14">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="60.6351,40.77"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="58.0026,40.1563;63.2863,41.7599"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 9
|
||||
VN 172.16.134.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="60.6351,40.77"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O0" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O15">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="8.9226,31.125"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="8.86406,31.0665;15.979,32.529"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="8.9226,31.125"/>
|
||||
<dia:point val="15.9205,32.4705"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O5" connection="4"/>
|
||||
<dia:connection handle="1" to="O23" connection="0"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O16">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="8.9226,36.0225"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="8.87151,35.8489;14.5511,36.0736"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="8.9226,36.0225"/>
|
||||
<dia:point val="14.5,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O4" connection="4"/>
|
||||
<dia:connection handle="1" to="O23" connection="3"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O17">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="8.9226,40.92"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="8.86276,39.2697;15.9803,40.9798"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="8.9226,40.92"/>
|
||||
<dia:point val="15.9205,39.3295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O3" connection="4"/>
|
||||
<dia:connection handle="1" to="O23" connection="5"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O18">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,30.975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="49.9204,30.9159;57.2892,32.5296"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="57.2301,30.975"/>
|
||||
<dia:point val="49.9795,32.4705"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O2" connection="3"/>
|
||||
<dia:connection handle="1" to="O25" connection="2"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O19">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,35.8725"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="51.3498,35.8223;57.2803,35.9502"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="57.2301,35.8725"/>
|
||||
<dia:point val="51.4,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O1" connection="3"/>
|
||||
<dia:connection handle="1" to="O25" connection="4"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O20">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,40.77"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="50.9399,37.8657;57.2963,40.8362"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="57.2301,40.77"/>
|
||||
<dia:point val="51.0061,37.9319"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O0" connection="3"/>
|
||||
<dia:connection handle="1" to="O25" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:group>
|
||||
<dia:object type="Standard - Ellipse" version="0" id="O21">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="28.6,15.15"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="28.55,15.1;38.35,24.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="28.6,15.15"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="aspect">
|
||||
<dia:enum val="2"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O22">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="33.45,20"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="29.9225,19.405;36.9775,20.9525"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#BGP Route Reflector 1
|
||||
192.168.1.100#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="33.45,20"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O21" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
</dia:group>
|
||||
<dia:group>
|
||||
<dia:object type="Standard - Ellipse" version="0" id="O23">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="14.5,31.05"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="14.45,31;24.25,40.8"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="14.5,31.05"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="9.7000007629394531"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="9.7000007629394531"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="aspect">
|
||||
<dia:enum val="2"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O24">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="19.35,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="17.0013,35.305;21.6988,36.8525"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVA 2
|
||||
192.168.1.101#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="19.35,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O23" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
</dia:group>
|
||||
<dia:group>
|
||||
<dia:object type="Standard - Ellipse" version="0" id="O25">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="41.7,31.05"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="41.65,31;51.45,40.8"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="41.7,31.05"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="aspect">
|
||||
<dia:enum val="2"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O26">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="46.55,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="44.2012,35.305;48.8987,36.8525"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVA 3
|
||||
192.168.1.102#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="46.55,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O25" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
</dia:group>
|
||||
</dia:layer>
|
||||
</dia:diagram>
|
BIN
doc/fig-vnc-quagga-route-reflector.png
Normal file
BIN
doc/fig-vnc-quagga-route-reflector.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 49 KiB |
0
doc/fig-vnc-quagga-route-reflector.txt
Normal file
0
doc/fig-vnc-quagga-route-reflector.txt
Normal file
871
doc/fig-vnc-redundant-route-reflectors.dia
Normal file
871
doc/fig-vnc-redundant-route-reflectors.dia
Normal file
@ -0,0 +1,871 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<dia:diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">
|
||||
<dia:diagramdata>
|
||||
<dia:attribute name="background">
|
||||
<dia:color val="#ffffff"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pagebreak">
|
||||
<dia:color val="#000099"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="paper">
|
||||
<dia:composite type="paper">
|
||||
<dia:attribute name="name">
|
||||
<dia:string>#Letter#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="tmargin">
|
||||
<dia:real val="2.5399999618530273"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="bmargin">
|
||||
<dia:real val="2.5399999618530273"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="lmargin">
|
||||
<dia:real val="2.5399999618530273"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="rmargin">
|
||||
<dia:real val="2.5399999618530273"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="is_portrait">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="scaling">
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="fitto">
|
||||
<dia:boolean val="false"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="grid">
|
||||
<dia:composite type="grid">
|
||||
<dia:attribute name="width_x">
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="width_y">
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="visible_x">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="visible_y">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:composite type="color"/>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#d8e5e5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="guides">
|
||||
<dia:composite type="guides">
|
||||
<dia:attribute name="hguides"/>
|
||||
<dia:attribute name="vguides"/>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
</dia:diagramdata>
|
||||
<dia:layer name="Background" visible="true" active="true">
|
||||
<dia:object type="Standard - Box" version="0" id="O0">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,39.145"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="57.1801,39.095;64.0901,42.445"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="57.2301,39.145"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O1">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,34.2475"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="57.1801,34.1975;64.0901,37.5475"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="57.2301,34.2475"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O2">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,29.35"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="57.1801,29.3;64.0901,32.65"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="57.2301,29.35"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O3">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="2.1126,39.295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.0626,39.245;8.9726,42.595"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="2.1126,39.295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O4">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="2.1126,34.3975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.0626,34.3475;8.9726,37.6975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="2.1126,34.3975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O5">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="2.1126,29.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.0626,29.45;8.9726,32.8"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="2.1126,29.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="6.8100000000000023"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.2500000000000018"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O6">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="22.5347,32.178"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="22.4648,17.4572;42.6316,32.2479"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="22.5347,32.178"/>
|
||||
<dia:point val="42.5617,17.5271"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="1" to="O26" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O7">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="43.1205,32.4705"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="22.6348,17.9948;43.1902,32.5402"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="43.1205,32.4705"/>
|
||||
<dia:point val="22.7045,18.0645"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="1" to="O24" connection="7"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O8">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="16.5501,5.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="16.5501,4.905;16.5501,5.6525"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>##</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="16.5501,5.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="0"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O9">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="5.5176,31.125"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="3.29385,30.5113;7.76004,32.1149"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 4
|
||||
VN 172.16.4.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="5.5176,31.125"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O5" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O10">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="5.5176,36.0225"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.88385,35.4088;8.17004,37.0124"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 5
|
||||
VN 172.16.130.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="5.5176,36.0225"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O4" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O11">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="5.5176,40.92"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="2.8826,40.3063;8.17129,41.9099"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 6
|
||||
VN 172.16.132.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="5.5176,40.92"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O3" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O12">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="60.6351,30.975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="58.4101,30.3613;62.8788,31.9649"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 7
|
||||
VN 172.16.6.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="60.6351,30.975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O2" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O13">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="60.6351,35.8725"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="58.4101,35.2588;62.8788,36.8624"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 8
|
||||
VN 172.16.8.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="60.6351,35.8725"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O1" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O14">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="60.6351,40.77"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="58.0026,40.1563;63.2863,41.7599"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVE 9
|
||||
VN 172.16.134.1#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="60.6351,40.77"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O0" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O15">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="8.9226,31.125"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="8.86398,31.0664;15.9041,32.5291"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="8.9226,31.125"/>
|
||||
<dia:point val="15.8455,32.4705"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O5" connection="4"/>
|
||||
<dia:connection handle="1" to="O28" connection="0"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O16">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="8.9226,36.0225"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="8.8715,35.8489;14.4761,36.0736"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="8.9226,36.0225"/>
|
||||
<dia:point val="14.425,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O4" connection="4"/>
|
||||
<dia:connection handle="1" to="O28" connection="3"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O17">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="8.9226,40.92"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="8.86267,39.2696;15.9054,40.9799"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="8.9226,40.92"/>
|
||||
<dia:point val="15.8455,39.3295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O3" connection="4"/>
|
||||
<dia:connection handle="1" to="O28" connection="5"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O18">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,30.975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="49.8855,30.916;57.2891,32.5295"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="57.2301,30.975"/>
|
||||
<dia:point val="49.9445,32.4705"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O2" connection="3"/>
|
||||
<dia:connection handle="1" to="O30" connection="2"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O19">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,35.8725"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="51.3148,35.8223;57.2803,35.9502"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="57.2301,35.8725"/>
|
||||
<dia:point val="51.365,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O1" connection="3"/>
|
||||
<dia:connection handle="1" to="O30" connection="4"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O20">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="57.2301,40.77"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="50.9097,37.8613;57.2963,40.8362"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="57.2301,40.77"/>
|
||||
<dia:point val="50.9759,37.9275"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O0" connection="3"/>
|
||||
<dia:connection handle="1" to="O30" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O21">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="24.25,15.05"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="24.1999,14.9999;41.6501,15.1501"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="24.25,15.05"/>
|
||||
<dia:point val="41.6,15.1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O22">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="19.1,31"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="18.9998,19.5998;19.1502,31.0502"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="19.1,31"/>
|
||||
<dia:point val="19.05,19.65"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O23">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="46.4,19.6"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="46.35,19.55;46.45,30.95"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="46.4,19.6"/>
|
||||
<dia:point val="46.4,30.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:group>
|
||||
<dia:object type="Standard - Ellipse" version="0" id="O24">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="14.425,9.785"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="14.375,9.735;24.175,19.535"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="14.425,9.785"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="aspect">
|
||||
<dia:enum val="2"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O25">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="19.275,14.635"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="15.7475,14.04;22.8025,15.5875"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#BGP Route Reflector 1
|
||||
192.168.1.100#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="19.275,14.635"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O24" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
</dia:group>
|
||||
<dia:group>
|
||||
<dia:object type="Standard - Ellipse" version="0" id="O26">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="41.665,9.785"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="41.615,9.735;51.415,19.535"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="41.665,9.785"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="aspect">
|
||||
<dia:enum val="2"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O27">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="46.565,14.285"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="44.1013,13.69;49.0288,16.0375"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#Commercial Router
|
||||
Route Reflector
|
||||
192.168.1.104#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="46.565,14.285"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
</dia:group>
|
||||
<dia:group>
|
||||
<dia:object type="Standard - Ellipse" version="0" id="O28">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="14.425,31.05"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="14.375,31;24.175,40.8"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="14.425,31.05"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="9.7000007629394531"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="9.7000007629394531"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="aspect">
|
||||
<dia:enum val="2"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O29">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="19.275,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="16.9262,35.305;21.6238,36.8525"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVA 2
|
||||
192.168.1.101#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="19.275,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O28" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
</dia:group>
|
||||
<dia:group>
|
||||
<dia:object type="Standard - Ellipse" version="0" id="O30">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="41.665,31.05"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="41.615,31;51.415,40.8"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="41.665,31.05"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="9.7000026702880859"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="aspect">
|
||||
<dia:enum val="2"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O31">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="46.515,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="44.1662,35.305;48.8637,36.8525"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#NVA 3
|
||||
192.168.1.102#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="46.515,35.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O30" connection="8"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
</dia:group>
|
||||
</dia:layer>
|
||||
</dia:diagram>
|
BIN
doc/fig-vnc-redundant-route-reflectors.png
Normal file
BIN
doc/fig-vnc-redundant-route-reflectors.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 74 KiB |
0
doc/fig-vnc-redundant-route-reflectors.txt
Normal file
0
doc/fig-vnc-redundant-route-reflectors.txt
Normal file
681
doc/ldpd-basic-test-setup.md
Normal file
681
doc/ldpd-basic-test-setup.md
Normal 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
109
doc/ldpd.8
Normal 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
Loading…
Reference in New Issue
Block a user