[quagga-dev 16456] [PATCH 12/23] bgpd: add autogenerated files

2016-12-02 Thread Philippe Guibert
From: David Lamparter <equi...@diac24.net>

This commit introduces .c and .h files issued from bgp.capnp
scheme file. Generating .c files from this scheme file
requires capnp compiler, and also some custom libraries that,
at the time of this writing are yet under development. So,
practically, in order to be able to compile without having
those custom libraries refreshed, along with capnp compiler,
the generated files are provided.
Consequently, it permits modifying those files. This is what
has been done to manually fix some RD prefix length issues.

Signed-off-by: David Lamparter <equi...@opensourcerouting.org>
Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp.bcapnp.c | 1220 +
 bgpd/bgp.bcapnp.h |   56 +++
 bgpd/bgpd.ndef.hi |   15 +
 bgpd/bgpd.ndef.i  |  791 ++
 4 files changed, 2082 insertions(+)
 create mode 100644 bgpd/bgp.bcapnp.c
 create mode 100644 bgpd/bgp.bcapnp.h
 create mode 100644 bgpd/bgpd.ndef.hi
 create mode 100644 bgpd/bgpd.ndef.i

diff --git a/bgpd/bgp.bcapnp.c b/bgpd/bgp.bcapnp.c
new file mode 100644
index ..83eb3dac3b6e
--- /dev/null
+++ b/bgpd/bgp.bcapnp.c
@@ -0,0 +1,1220 @@
+/*
+ * derived from GPLv2+ sources
+ */
+#include 
+#include "c-capnproto/capn.h"
+#include "bgp.bcapnp.h"
+
+static const capn_text capn_val0 = {0, ""};
+
+
+#include "zebra.h"
+#include "bgpd.h"
+
+afi_t qcapn_AfiSafiKey_get_afi(capn_ptr p)
+{
+capn_resolve();
+return capn_read8(p, 0);
+}
+
+
+safi_t qcapn_AfiSafiKey_get_safi(capn_ptr p)
+{
+capn_resolve();
+return capn_read8(p, 1);
+}
+
+
+capn_ptr qcapn_new_AfiSafiKey(struct capn_segment *s)
+{
+return capn_new_struct(s, 8, 0);
+}
+
+
+afi_t qcapn_AfiKey_get_afi(capn_ptr p)
+{
+capn_resolve();
+return capn_read8(p, 0);
+}
+
+
+capn_ptr qcapn_new_AfiKey(struct capn_segment *s)
+{
+return capn_new_struct(s, 8, 0);
+}
+
+
+
+void qcapn_VRFTableIter_read(struct tbliter_v4 *s, capn_ptr p)
+{
+capn_resolve();
+
+{
+capn_ptr tmp_p = capn_getp(p, 0, 1);
+s->prefix.family = AF_INET;
+s->prefix.prefixlen = capn_read8(tmp_p, 4);
+s->prefix.prefix.s_addr = htonl(capn_read32(tmp_p, 0));
+}
+}
+
+
+
+void qcapn_VRFTableIter_write(const struct tbliter_v4 *s, capn_ptr p)
+{
+capn_resolve();
+
+{
+capn_ptr tempptr = capn_new_struct(p.seg, 8, 0);
+capn_write8(tempptr, 4, s->prefix.prefixlen);
+capn_write32(tempptr, 0, ntohl(s->prefix.prefix.s_addr));
+capn_setp(p, 0, tempptr);
+}
+}
+
+
+
+void qcapn_VRFTableIter_set(struct tbliter_v4 *s, capn_ptr p)
+{
+capn_resolve();
+{
+  /* MISSING: prefix */
+}
+}
+
+
+capn_ptr qcapn_new_VRFTableIter(struct capn_segment *s)
+{
+return capn_new_struct(s, 0, 1);
+}
+
+
+
+void qcapn_BGP_read(struct bgp *s, capn_ptr p)
+{
+capn_resolve();
+s->as = capn_read32(p, 0);
+{ capn_text tp = capn_get_text(p, 0, capn_val0); free(s->name); s->name = 
strdup(tp.str); }
+
+{
+capn_ptr tmp_p = capn_getp(p, 1, 1);
+s->router_id_static.s_addr = htonl(capn_read32(tmp_p, 0));
+}
+{ bool tmp;
+  tmp = !!(capn_read8(p, 4) & (1 << 0));
+  if (tmp) s->flags |=  BGP_FLAG_ALWAYS_COMPARE_MED;
+  else s->flags &= ~BGP_FLAG_ALWAYS_COMPARE_MED;
+}
+{ bool tmp;
+  tmp = !!(capn_read8(p, 4) & (1 << 1));
+  if (tmp) s->flags |=  BGP_FLAG_DETERMINISTIC_MED;
+  else s->flags &= ~BGP_FLAG_DETERMINISTIC_MED;
+}
+{ bool tmp;
+  tmp = !!(capn_read8(p, 4) & (1 << 2));
+  if (tmp) s->flags |=  BGP_FLAG_MED_MISSING_AS_WORST;
+  else s->flags &= ~BGP_FLAG_MED_MISSING_AS_WORST;
+}
+{ bool tmp;
+  tmp = !!(capn_read8(p, 4) & (1 << 3));
+  if (tmp) s->flags |=  BGP_FLAG_MED_CONFED;
+  else s->flags &= ~BGP_FLAG_MED_CONFED;
+}
+{ bool tmp;
+  tmp = !!(capn_read8(p, 4) & (1 << 4));
+  if (tmp) s->flags |=  BGP_FLAG_NO_DEFAULT_IPV4;
+  else s->flags &= ~BGP_FLAG_NO_DEFAULT_IPV4;
+}
+{ bool tmp;
+  tmp = !!(capn_read8(p, 4) & (1 << 5));
+  if (tmp) s->flags |=  BGP_FLAG_NO_CLIENT_TO_CLIENT;
+  else s->flags &= ~BGP_FLAG_NO_CLIENT_TO_CLIENT;
+}
+{ bool tmp;
+  tmp = !!(capn_read8(p, 4) & (1 << 6));
+  if (tmp) s->flags |=  BGP_FLAG_ENFORCE_FIRST_AS;
+  else s->flags &= ~BGP_FLAG_ENFORCE_FIRST_AS;
+}
+{ bool tmp;
+  tmp = !!(capn_read8(p, 4) & (1 << 7));
+  if (tmp) s->flags |=  BGP_FLAG_COMPARE_ROUTER_ID;
+  else s->flags &= ~BGP_FLAG_COMPARE_ROUTER_ID;
+}
+{ bool tmp;
+  tmp = !!(capn_read8(p, 5) & (1 << 0));
+  if (tm

[quagga-dev 16450] [PATCH 17/23] bgpd: support for max_mpath vrf field configuration

2016-12-02 Thread Philippe Guibert
This commit enhances the ability to configure from capnproto the maximum
path field per vrf. The ability to configure multipath for an afi/safi
is also made possible.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp.bcapnp.c | 61 +++
 bgpd/bgp.bcapnp.h |  1 +
 bgpd/bgp.capnp|  1 +
 bgpd/bgpd.ndef.i  | 21 +++
 4 files changed, 80 insertions(+), 4 deletions(-)

diff --git a/bgpd/bgp.bcapnp.c b/bgpd/bgp.bcapnp.c
index 2bf038128cd1..135a54f34dc6 100644
--- a/bgpd/bgp.bcapnp.c
+++ b/bgpd/bgp.bcapnp.c
@@ -415,6 +415,16 @@ void qcapn_BGPAfiSafi_read(struct bgp *s, capn_ptr p, 
afi_t afi, safi_t safi)
   if (tmp) s->af_flags[afi][safi] |=  BGP_CONFIG_DAMPENING;
   else s->af_flags[afi][safi] &= ~BGP_CONFIG_DAMPENING;
 }
+{ bool tmp;
+  tmp = !!(capn_read8(p, 0) & (1 << 1));
+  if (tmp) s->af_flags[afi][safi] |=  BGP_CONFIG_ASPATH_MULTIPATH_RELAX;
+  else s->af_flags[afi][safi] &= ~BGP_CONFIG_ASPATH_MULTIPATH_RELAX;
+}
+{ bool tmp;
+  tmp = !!(capn_read8(p, 0) & (1 << 2));
+  if (tmp) s->af_flags[afi][safi] |=  BGP_CONFIG_MULTIPATH;
+  else s->af_flags[afi][safi] &= ~BGP_CONFIG_MULTIPATH;
+}
 }
 
 
@@ -423,6 +433,8 @@ void qcapn_BGPAfiSafi_write(const struct bgp *s, capn_ptr 
p, afi_t afi, safi_t s
 {
 capn_resolve();
 capn_write1(p, 0, !!(s->af_flags[afi][safi] & BGP_CONFIG_DAMPENING));
+capn_write1(p, 1, !!(s->af_flags[afi][safi] & 
BGP_CONFIG_ASPATH_MULTIPATH_RELAX));
+capn_write1(p, 2, !!(s->af_flags[afi][safi] & BGP_CONFIG_MULTIPATH));
 }
 
 
@@ -435,13 +447,51 @@ void qcapn_BGPAfiSafi_set(struct bgp *s, capn_ptr p, 
afi_t afi, safi_t safi)
   flags = !!(capn_read8(p, 0) & (1 << 0));
   if (flags) bgp_af_flag_set(s, BGP_CONFIG_DAMPENING, afi, safi);
 else bgp_af_flag_unset(s, BGP_CONFIG_DAMPENING, afi, safi);
+  flags = !!(capn_read8(p, 0) & (1 << 1));
+  if (flags)
+  {
+bgp_af_flag_set(s, BGP_CONFIG_ASPATH_MULTIPATH_RELAX, afi, safi);
+  }
+  else
+  {
+bgp_af_flag_unset(s, BGP_CONFIG_ASPATH_MULTIPATH_RELAX, afi, safi);
+  }
+}
+{
+  u_int16_t flags;
+  flags = !!(capn_read8(p, 0) & (1 << 2));
+  if (flags)
+  {
+uint8_t max = capn_read8(p, 3);
+bgp_af_flag_set(s, BGP_CONFIG_MULTIPATH, afi, safi);
+bgp_maximum_paths_set (s, AFI_IP, SAFI_MPLS_VPN,
+   BGP_PEER_EBGP, max);
+bgp_maximum_paths_set (s, AFI_IP, SAFI_MPLS_VPN,
+   BGP_PEER_IBGP, max);
+bgp_maximum_paths_set (s, AFI_IP, SAFI_UNICAST,
+   BGP_PEER_EBGP, max);
+bgp_maximum_paths_set (s, AFI_IP, SAFI_UNICAST,
+   BGP_PEER_IBGP, max);
+  }
+  else
+  {
+bgp_af_flag_unset(s, BGP_CONFIG_MULTIPATH, afi, safi);
+bgp_maximum_paths_unset (s, AFI_IP, SAFI_MPLS_VPN,
+ BGP_PEER_EBGP);
+bgp_maximum_paths_unset (s, AFI_IP, SAFI_MPLS_VPN,
+ BGP_PEER_IBGP);
+bgp_maximum_paths_unset (s, AFI_IP, SAFI_UNICAST,
+ BGP_PEER_EBGP);
+bgp_maximum_paths_unset (s, AFI_IP, SAFI_UNICAST,
+ BGP_PEER_IBGP);
+  }
 }
 }
 
 
 capn_ptr qcapn_new_BGPAfiSafi(struct capn_segment *s)
 {
-return capn_new_struct(s, 8, 0);
+return capn_new_struct(s, 16, 0);
 }
 
 
@@ -936,7 +986,7 @@ void qcapn_BGPVRF_read(struct bgp_vrf *s, capn_ptr p)
 memcpy(>outbound_rd.val, , 8);
 s->outbound_rd.family = AF_UNSPEC;
 s->outbound_rd.prefixlen = 64;
-
+s->max_mpath = capn_read32(p, 8);
 {
 capn_ptr tmp_p = capn_getp(p, 0, 1);
 capn_list64 listptr = { .p = capn_getp(tmp_p, 0, 1) };
@@ -969,7 +1019,7 @@ void qcapn_BGPVRF_write(const struct bgp_vrf *s, capn_ptr 
p)
 memcpy(,&(s->outbound_rd.val), 8);
 capn_resolve();
 capn_write64(p, 0, tmp);
-
+capn_write32(p, 8, s->max_mpath);
 {
 capn_ptr tempptr = capn_new_struct(p.seg, 0, 1);
 size_t size = s->rt_import ? s->rt_import->size : 0;
@@ -997,6 +1047,9 @@ void qcapn_BGPVRF_set(struct bgp_vrf *s, capn_ptr p)
 {
 capn_resolve();
 {
+  s->max_mpath = capn_read32(p, 8);
+}
+{
   /* MISSING: outbound_rd */
 }
 {
@@ -1048,7 +1101,7 @@ struct prefix_rd qcapn_BGPVRF_get_outbound_rd(capn_ptr p)
 
 capn_ptr qcapn_new_BGPVRF(struct capn_segment *s)
 {
-return capn_new_struct(s, 8, 2);
+return capn_new_struct(s, 12, 2);
 }
 
 
diff --git a/bgpd/bgp.bcapnp.h b/bgpd/bgp.bcapnp.h
index 3b8ce361f6b2..eb0cba4a43c7 100644
--- a/bgpd/bgp.bcapnp.h
+++ b/bgpd/bgp.bcapnp.h
@@ -7,6 +7,7 @@
 
 #include "zebra.h

[quagga-dev 16443] [PATCH 07/23] lib: add basic capn config access protocol

2016-12-02 Thread Philippe Guibert
From: David Lamparter <equi...@opensourcerouting.org>

This commit introduces the qzc.capnp schema file. This schema file is
only here for information, despite it is possible to automate c files
generation, from this scheme file.
In addition, qzc framework needs some server API to handle qzc queries
from any qzc client. Among the APIs, there is the possibility to handle
delete/destroy/unset operations. It is also possible to answer to get
operations that request some context to be retrieved. Finally, it is
possible to handle iterations over a table, for example.

Signed-off-by: David Lamparter <equi...@opensourcerouting.org>
Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 lib/.gitignore  |   2 +
 lib/Makefile.am |  10 +-
 lib/memtypes.c  |   1 +
 lib/qzc.c   | 372 
 lib/qzc.capnp   | 148 ++
 lib/qzc.h   |  95 +++
 6 files changed, 626 insertions(+), 2 deletions(-)
 create mode 100644 lib/qzc.c
 create mode 100644 lib/qzc.capnp
 create mode 100644 lib/qzc.h

diff --git a/lib/.gitignore b/lib/.gitignore
index 02aa432ce16d..f30e20b93802 100644
--- a/lib/.gitignore
+++ b/lib/.gitignore
@@ -3,6 +3,8 @@ Makefile.in
 *.o
 *.lo
 *.la
+*.capnp.c
+*.capnp.h
 version.c
 version.h
 gitversion.h
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 7b6c34dcabb5..c286834e 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -36,11 +36,17 @@ noinst_HEADERS = \
plist_int.h
 
 if HAVE_ZEROMQ
-libzebra_la_SOURCES += qzmq.c
-pkginclude_HEADERS += qzmq.h
+libzebra_la_SOURCES += qzmq.c qzc.c
+pkginclude_HEADERS += qzmq.h qzc.h
+endif
+
+if HAVE_CCAPNPROTO
+libzebra_la_SOURCES += qzc.capnp.c
+BUILT_SOURCES += qzc.capnp.c
 endif
 
 EXTRA_DIST = \
+   qzc.capnp \
regex.c regex-gnu.h \
queue.h \
memtypes.awk \
diff --git a/lib/memtypes.c b/lib/memtypes.c
index bfda5eb7b14e..3e43a857322e 100644
--- a/lib/memtypes.c
+++ b/lib/memtypes.c
@@ -75,6 +75,7 @@ struct memory_list memory_list_lib[] =
   { MTYPE_IF_LINK_PARAMS,   "Informational Link Parameters" },
   { MTYPE_LIB_NEXTHOP, "Nexthop"   },
   { MTYPE_ZEROMQ_CB,   "ZEROMQ_CB" },
+  { MTYPE_QZC_SOCK,"QZC"   },
   { -1, NULL },
 };
 
diff --git a/lib/qzc.c b/lib/qzc.c
new file mode 100644
index ..358b7e419eef
--- /dev/null
+++ b/lib/qzc.c
@@ -0,0 +1,372 @@
+/*
+ * Copyright (C) 2015-16  David Lamparter, for NetDEF, Inc.
+ *
+ * This file is part of Quagga
+ *
+ * Quagga 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, or (at your option) any
+ * later version.
+ *
+ * Quagga 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 Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include 
+
+#include "qzmq.h"
+#include "thread.h"
+#include "memory.h"
+#include "hash.h"
+#include "log.h"
+
+#include "qzc.h"
+
+#include "qzc.capnp.h"
+
+static struct qzc_wkn *wkn_first = NULL;
+
+void qzc_wkn_reg(struct qzc_wkn *wkn)
+{
+   wkn->next = wkn_first;
+   wkn_first = wkn;
+}
+
+static struct qzc_wkn *qzc_wkn_find(uint64_t wid)
+{
+   struct qzc_wkn *wkn;
+   for (wkn = wkn_first; wkn; wkn = wkn->next)
+   if (wkn->wid == wid)
+   return wkn;
+   return NULL;
+}
+
+static struct hash *nodes = NULL;
+
+static unsigned int qzc_key (void *data)
+{
+  struct qzc_node *node = data;
+  return (unsigned int)node->nid;
+}
+
+static int qzc_cmp (const void *a, const void *b)
+{
+  const struct qzc_node *na = a, *nb = b;
+  return na->nid == nb->nid;
+}
+
+void qzc_node_reg(struct qzc_node *node, struct qzc_nodetype *type)
+{
+  node->type = type;
+  do
+{
+  node->nid  = (uint64_t)random();
+  node->nid ^= (uint64_t)random() << 32;
+}
+  while (hash_get (nodes, node, hash_alloc_intern) != node);
+}
+
+void qzc_node_unreg(struct qzc_node *node)
+{
+  hash_release (nodes, node);
+}
+
+static struct qzc_node *qzc_node_get(uint64_t id)
+{
+  struct qzc_node dummy = { .nid = id };
+  return hash_lookup (nodes, );
+}
+
+static void qzc_wknresolve (struct QZCRequest *req, struct QZCReply *rep,
+struct capn_segment *cs)
+{
+  struct QZCWKNResolveReq wknreq;
+  struct QZCWKNResolveRep wknrep;
+  memset(, 0, sizeof(wknrep));
+
+  read_QZCWK

[quagga-dev 16454] [PATCH 22/23] bgpd: add a notification message on received bgp notifications

2016-12-02 Thread Philippe Guibert
An handler is added to signify that a remote notification has been
received, meaning that local BGP speaker should be shutdown.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_debug.c | 11 +++
 bgpd/bgp_zmq.c   |  9 +
 bgpd/bgpd.h  | 12 +++-
 3 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c
index ba7972281342..369e27ce4944 100644
--- a/bgpd/bgp_debug.c
+++ b/bgpd/bgp_debug.c
@@ -248,6 +248,17 @@ bgp_notify_print(struct peer *peer, struct bgp_notify 
*bgp_notify,
   const char *subcode_str;
   const char *code_str;
 
+#ifdef HAVE_ZEROMQ
+  if(!strcmp(direct,"received"))
+{
+  struct bgp_event_shut shut = {
+.peer  = peer->remote_id,
+.type  = bgp_notify->code,
+.subtype   = bgp_notify->subcode
+  };
+bgp_notify_shut (peer->bgp, );
+}
+#endif /* HAVE_ZEROMQ */
   subcode_str = "";
   code_str = LOOKUP_DEF (bgp_notify_msg, bgp_notify->code,
  "Unrecognized Error Code");
diff --git a/bgpd/bgp_zmq.c b/bgpd/bgp_zmq.c
index d2e7fb14d40b..66bd27a66126 100644
--- a/bgpd/bgp_zmq.c
+++ b/bgpd/bgp_zmq.c
@@ -102,4 +102,13 @@ bgp_notify_route (struct bgp *bgp, struct bgp_event_vrf 
*update)
 void
 bgp_notify_shut (struct bgp *bgp, struct bgp_event_shut *shut)
 {
+  struct bgp_event_vrf msg;
+
+  /* encapsulate message in bgp_event_vrf structure */
+  memset(, 0, sizeof(struct bgp_event_vrf));
+  msg.announce = BGP_EVENT_SHUT;
+  msg.nexthop.s_addr = shut->peer.s_addr;
+  msg.label = shut->type;
+  msg.prefix.prefix.s_addr = shut->subtype;
+  bgp_notify_send (bgp, );
 }
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index f1de8bbc847b..56e519e02cb5 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -267,11 +267,13 @@ struct bgp_vrf
 
 struct bgp_event_vrf
 {
-  bool announce;
-  struct prefix_rd outbound_rd;
-  struct prefix_ipv4 prefix;
-  struct in_addr nexthop;
-  uint32_t label;
+#define BGP_EVENT_MASK_ANNOUNCE 0x1
+#define BGP_EVENT_SHUT 0x2
+  uint8_t announce;
+  struct prefix_rd outbound_rd; /* dummy for event_shut */
+  struct prefix_ipv4 prefix; /* alias subtype */
+  struct in_addr nexthop; /* alias peer */
+  uint32_t label; /* alias type */
 };
 
 struct bgp_event_shut
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16453] [PATCH 21/23] bgpd: add capnproto support for bgp update-source

2016-12-02 Thread Philippe Guibert
This commit handles the case where an incoming updateSource IP address
is received for setting as bgp update-source IP address.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp.bcapnp.c | 54 +++---
 1 file changed, 51 insertions(+), 3 deletions(-)

diff --git a/bgpd/bgp.bcapnp.c b/bgpd/bgp.bcapnp.c
index 135a54f34dc6..1667033b823f 100644
--- a/bgpd/bgp.bcapnp.c
+++ b/bgpd/bgp.bcapnp.c
@@ -542,7 +542,26 @@ void qcapn_BGPPeer_read(struct peer *s, capn_ptr p)
   else s->flags &= ~PEER_FLAG_DISABLE_CONNECTED_CHECK;
 }
 s->ttl = capn_read32(p, 20);
-/* MISSING: updateSource */
+{
+  const char * update_source = NULL;
+  int len;
+  capn_text tp = capn_get_text(p, 2, capn_val0);
+  update_source = tp.str;
+  len = tp.len;
+  if (update_source && len != 0)
+{
+  union sockunion *su;
+
+  su = sockunion_str2su (update_source);
+  if (su)
+s->update_source = su;
+}
+  else
+{
+  s->update_source = NULL;
+  s->update_if = NULL;
+}
+}
 }
 
 
@@ -565,7 +584,21 @@ void qcapn_BGPPeer_write(const struct peer *s, capn_ptr p)
 capn_write1(p, 53, !!(s->flags & PEER_FLAG_DYNAMIC_CAPABILITY));
 capn_write1(p, 54, !!(s->flags & PEER_FLAG_DISABLE_CONNECTED_CHECK));
 capn_write32(p, 20, s->ttl);
-/* MISSING: updateSource */
+{
+  capn_text tp;
+  char *ptr = malloc(65);
+  if(s->update_source)
+{
+  ptr = (char *)sockunion2str((const union sockunion 
*)s->update_source, ptr, 64);
+  tp.str = ptr;
+  tp.len = strlen(ptr);
+} else
+{
+  tp.str = NULL;
+  tp.len = 0;
+}
+  capn_set_text(p, 2, tp);
+}
 }
 
 
@@ -674,7 +707,22 @@ void qcapn_BGPPeer_set(struct peer *s, capn_ptr p)
   
 }
 {
-  /* MISSING: update_source */
+  const char * update_source = NULL;
+  int len;
+  capn_text tp = capn_get_text(p, 2, capn_val0);
+  update_source = tp.str;
+  len = tp.len;
+  if (update_source && len != 0)
+{
+  union sockunion su;
+  int ret = str2sockunion (update_source, );
+  if (ret == 0)
+peer_update_source_addr_set (s, );
+}
+  else
+{
+  peer_update_source_unset (s);
+}
 }
 }
 
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16452] [PATCH 20/23] bgpd: add vty header under bgpd.h header file

2016-12-02 Thread Philippe Guibert
Because some warnings tell that vty structure is not known, it is
advised to self-content the header so that vty structure is known.
Smooth alternative would have been to declare structure name on top of
bgpd.h.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgpd.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index ba870a025ffb..f1de8bbc847b 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -26,6 +26,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, 
Boston, MA
 #include "bgp_ecommunity.h"
 #include "prefix.h"
 #include "filter.h"
+#include "vty.h"
 #include "qzc.h"
 
 /* Typedef BGP specific types.  */
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16455] [PATCH 23/23] bgpd: set restart_time from capnproto API

2016-12-02 Thread Philippe Guibert
The graceful restart time is configurable by using capnproto API

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp.bcapnp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/bgpd/bgp.bcapnp.c b/bgpd/bgp.bcapnp.c
index 1667033b823f..acdc473a2f7c 100644
--- a/bgpd/bgp.bcapnp.c
+++ b/bgpd/bgp.bcapnp.c
@@ -378,7 +378,7 @@ void qcapn_BGP_set(struct bgp *s, capn_ptr p)
   
 }
 {
-  /* MISSING: restart_time */
+  s->restart_time = capn_read32(p, 24);
 }
 {
   const char * notify_zmq_url;
@@ -390,6 +390,7 @@ void qcapn_BGP_set(struct bgp *s, capn_ptr p)
 s->distance_ibgp = capn_read8(p, 7);
 s->distance_local = capn_read8(p, 8);
 s->stalepath_time = capn_read32(p, 28);
+s->restart_time = capn_read32(p, 24);
 }
 
 
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16438] [PATCH 04/23] *: force the linker to not check for unresolved symbols at link

2016-12-02 Thread Philippe Guibert
This commit bypasses the link check in case a shared library is to be
used in conjunction with one of the quagga daemons. This is the case of
zero ma library that may or not be available on some systems. Adding
-Wl,-unresolved-symbols=ignore-in-shared-libs to the linker flags
permits compiling without having to install zmq.
It also adapts vtysh scripting, as the capnproto and zeromq may be needed,
the compilation flags is added.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/Makefile.am| 2 +-
 isisd/Makefile.am   | 2 +-
 ospf6d/Makefile.am  | 2 +-
 ospfclient/Makefile.am  | 2 +-
 ospfd/Makefile.am   | 2 +-
 pimd/Makefile.am| 2 +-
 ripd/Makefile.am| 2 +-
 ripngd/Makefile.am  | 2 +-
 vtysh/Makefile.am   | 2 +-
 vtysh/extract.pl.in | 2 +-
 watchquagga/Makefile.am | 2 +-
 zebra/Makefile.am   | 2 +-
 12 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/bgpd/Makefile.am b/bgpd/Makefile.am
index fe1be32edb37..d5be054f9555 100644
--- a/bgpd/Makefile.am
+++ b/bgpd/Makefile.am
@@ -4,7 +4,7 @@ AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib 
-I$(top_builddir)/lib
 DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
 INSTALL_SDATA=@INSTALL@ -m 600
 
-AM_CFLAGS = $(WERROR)
+AM_CFLAGS = $(WERROR) -Wl,-unresolved-symbols=ignore-in-shared-libs
 
 noinst_LIBRARIES = libbgp.a
 sbin_PROGRAMS = bgpd
diff --git a/isisd/Makefile.am b/isisd/Makefile.am
index bfe2e947793b..f254cc140b8a 100644
--- a/isisd/Makefile.am
+++ b/isisd/Makefile.am
@@ -6,7 +6,7 @@ DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
 INSTALL_SDATA=@INSTALL@ -m 600
 LIBS = @LIBS@ 
 
-AM_CFLAGS = $(WERROR)
+AM_CFLAGS = $(WERROR) -Wl,-unresolved-symbols=ignore-in-shared-libs
 
 noinst_LIBRARIES = libisis.a
 sbin_PROGRAMS = isisd 
diff --git a/ospf6d/Makefile.am b/ospf6d/Makefile.am
index 75f22572723f..1ce403cf447a 100644
--- a/ospf6d/Makefile.am
+++ b/ospf6d/Makefile.am
@@ -4,7 +4,7 @@ AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib 
-I$(top_builddir)/lib
 DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
 INSTALL_SDATA=@INSTALL@ -m 600
 
-AM_CFLAGS = $(WERROR)
+AM_CFLAGS = $(WERROR) -Wl,-unresolved-symbols=ignore-in-shared-libs
 
 noinst_LIBRARIES = libospf6.a
 sbin_PROGRAMS = ospf6d
diff --git a/ospfclient/Makefile.am b/ospfclient/Makefile.am
index 1fca431a1017..1b04ed1d80ae 100644
--- a/ospfclient/Makefile.am
+++ b/ospfclient/Makefile.am
@@ -1,7 +1,7 @@
 ## Automake.am for OSPF API client
 
 AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
-AM_CFLAGS = $(WERROR)
+AM_CFLAGS = $(WERROR) -Wl,-unresolved-symbols=ignore-in-shared-libs
 
 lib_LTLIBRARIES = libospfapiclient.la
 libospfapiclient_la_LDFLAGS = -version-info 0:0:0
diff --git a/ospfd/Makefile.am b/ospfd/Makefile.am
index f586d73434da..85d8445c6c02 100644
--- a/ospfd/Makefile.am
+++ b/ospfd/Makefile.am
@@ -1,7 +1,7 @@
 ## Process this file with automake to produce Makefile.in.
 
 AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
-AM_CFLAGS = $(WERROR)
+AM_CFLAGS = $(WERROR) 
 DEFS = @DEFS@ $(LOCAL_OPTS) -DSYSCONFDIR=\"$(sysconfdir)/\"
 INSTALL_SDATA=@INSTALL@ -m 600
 
diff --git a/pimd/Makefile.am b/pimd/Makefile.am
index f57c4c254391..a91bd28e480c 100644
--- a/pimd/Makefile.am
+++ b/pimd/Makefile.am
@@ -39,7 +39,7 @@ DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" $(PIM_DEFS)
 INSTALL_SDATA=@INSTALL@ -m 600
 LIBS = @LIBS@
 
-AM_CFLAGS = $(WERROR)
+AM_CFLAGS = $(WERROR) -Wl,-unresolved-symbols=ignore-in-shared-libs
 
 noinst_LIBRARIES = libpim.a
 sbin_PROGRAMS = pimd 
diff --git a/ripd/Makefile.am b/ripd/Makefile.am
index 571a4993dd5a..5fd09d13a7d0 100644
--- a/ripd/Makefile.am
+++ b/ripd/Makefile.am
@@ -4,7 +4,7 @@ AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib 
-I$(top_builddir)/lib
 DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
 INSTALL_SDATA=@INSTALL@ -m 600
 
-AM_CFLAGS = $(WERROR)
+AM_CFLAGS = $(WERROR) -Wl,-unresolved-symbols=ignore-in-shared-libs
 
 noinst_LIBRARIES = librip.a
 sbin_PROGRAMS = ripd
diff --git a/ripngd/Makefile.am b/ripngd/Makefile.am
index df0f7d377ec2..1ed8879a3bd9 100644
--- a/ripngd/Makefile.am
+++ b/ripngd/Makefile.am
@@ -4,7 +4,7 @@ AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib 
-I$(top_builddir)/lib
 DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
 INSTALL_SDATA=@INSTALL@ -m 600
 
-AM_CFLAGS = $(WERROR)
+AM_CFLAGS = $(WERROR) -Wl,-unresolved-symbols=ignore-in-shared-libs
 
 noinst_LIBRARIES = libripng.a
 sbin_PROGRAMS = ripngd
diff --git a/vtysh/Makefile.am b/vtysh/Makefile.am
index e44cd49f597b..8c2476c75fbd 100644
--- a/vtysh/Makefile.am
+++ b/vtysh/Makefile.am
@@ -5,7 +5,7 @@ DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
 
 LIBS = @LIBS@ @CURSES@ @LIBPAM@
 
-AM_CFLAGS = $(WERROR)
+AM_CFLAGS = $(WERROR) -Wl,-unresolved-symbols=ignore-in-shared-libs
 
 bin_PROGRAMS = vtysh
 
diff --git a/vtysh/extract.pl.in b/vtysh/extra

[quagga-dev 16446] [PATCH 10/23] bgpd: enable use of capn/zmq interface

2016-12-02 Thread Philippe Guibert
From: David Lamparter <equi...@opensourcerouting.org>

This commit enables the usage of capn/zmq API on bgp daemon, by
linking and using capn/zmq APIs, through using specific BGP
configuration parameters. It will be possible to receive queries
by using a zmq socket mentioned by -Z parameter.
Also, this commit introduces some new APIs that will be used by
capn/zmq APIs as entry points to manage BGP internals.
Using capn/zmq APIs means sharing data strucures. Those data
structures are defined by schemas, and are mapped on current
BGP structures. In order to be used in BGP daemon, some node
registrations are defined.
This patch introduces also bgp code modifications to
handle peer creation, configure specific bgp fields.

Signed-off-by: David Lamparter <equi...@opensourcerouting.org>
Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/.gitignore  |   5 ++
 bgpd/Makefile.am |   9 ++--
 bgpd/bgp.capnp   | 156 +++
 bgpd/bgp_main.c  |  28 +-
 bgpd/bgpd.c  | 108 ++
 bgpd/bgpd.h  |  11 
 6 files changed, 302 insertions(+), 15 deletions(-)
 create mode 100644 bgpd/bgp.capnp

diff --git a/bgpd/.gitignore b/bgpd/.gitignore
index 105be2299503..863d479f54dd 100644
--- a/bgpd/.gitignore
+++ b/bgpd/.gitignore
@@ -12,6 +12,11 @@ TAGS
 *.la
 *.a
 *.libs
+*.bcapnp
+*.bcapnp.c
+*.bcapnp.h
+*.ndef.i
+*.ndef.hi
 .arch-inventory
 .arch-ids
 *~
diff --git a/bgpd/Makefile.am b/bgpd/Makefile.am
index d5be054f9555..3fcffe62c989 100644
--- a/bgpd/Makefile.am
+++ b/bgpd/Makefile.am
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in.
 
-AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
+AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib 
@CAPN_C_CFLAGS@ @ZEROMQ_CFLAGS@
 DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
 INSTALL_SDATA=@INSTALL@ -m 600
 
@@ -27,13 +27,16 @@ noinst_HEADERS = \
bgp_encap.h bgp_encap_tlv.h bgp_encap_types.h bgp_nht.h
 
 bgpd_SOURCES = bgp_main.c
-bgpd_LDADD = libbgp.a ../lib/libzebra.la @LIBCAP@ @LIBM@
+
+bgpd_LDADD = libbgp.a ../lib/libzebra.la @LIBCAP@ @LIBM@ @ZEROMQ_LIBS@ 
@CAPN_C_LIBS@
 
 bgp_btoa_SOURCES = bgp_btoa.c
-bgp_btoa_LDADD = libbgp.a ../lib/libzebra.la @LIBCAP@ @LIBM@
+bgp_btoa_LDADD = libbgp.a ../lib/libzebra.la @LIBCAP@ @LIBM@ @ZEROMQ_LIBS@ 
@CAPN_C_LIBS@
 
 examplesdir = $(exampledir)
 dist_examples_DATA = bgpd.conf.sample bgpd.conf.sample2
 
 EXTRA_DIST = BGP4-MIB.txt
 
+EXTRA_DIST += bgpd.ndef.i bgpd.ndef.hi bgp.bcapnp.c bgp.bcapnp.h
+libbgp_a_SOURCES += bgp.bcapnp.c
diff --git a/bgpd/bgp.capnp b/bgpd/bgp.capnp
new file mode 100644
index ..2603e6983ad6
--- /dev/null
+++ b/bgpd/bgp.capnp
@@ -0,0 +1,156 @@
+#
+# Copyright (c) 2016  David Lamparter, for NetDEF, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+
+@0xc4c948a17d3b2250;
+
+using import "../capnp/codegen.capnp".Cflag;
+using import "../capnp/codegen.capnp".IPv4;
+
+using import "../capnp/codegen.capnp".ctype;
+using import "../capnp/codegen.capnp".cflag;
+using import "../capnp/codegen.capnp".cheader;
+using import "../capnp/codegen.capnp".cgen;
+using import "../capnp/codegen.capnp".csetter;
+using import "../capnp/codegen.capnp".cgetfield;
+using import "../capnp/codegen.capnp".cgennaked;
+using import "../capnp/codegen.capnp".carraykey;
+using import "../capnp/codegen.capnp".caltname;
+using import "../capnp/codegen.capnp".csetwrite;
+
+struct AfiSafiKey $cgennaked $cgetfield {
+   afi  @0 :UInt8 $ctype("afi_t");
+   safi @1 :UInt8 $ctype("safi_t");
+}
+struct ExtCommunityList {
+   values   @0 :List(UInt64);
+}
+
+struct BGP $ctype("st

[quagga-dev 16451] [PATCH 19/23] bgpd: declare header where FILTER_MAX is defined

2016-12-02 Thread Philippe Guibert
Add include header filter.h file, because bgpd.h defines structures with
FILTER_MAX as define.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgpd.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index ad6a6652784e..ba870a025ffb 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -25,6 +25,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, 
Boston, MA
 #include "sockunion.h"
 #include "bgp_ecommunity.h"
 #include "prefix.h"
+#include "filter.h"
 #include "qzc.h"
 
 /* Typedef BGP specific types.  */
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16448] [PATCH 16/23] bgpd: enable iteration of routes in VRF

2016-12-02 Thread Philippe Guibert
From: David Lamparter <equi...@opensourcerouting.org>

This enhancement to the bgp.capnp scheme files permits bgp daemon
to handle get requests to parse a routing table. It is possible
to retrieve the next element of a table, by reusing the passed
as parameter element, then, the query will response with the
associated next element.

Signed-off-by: David Lamparter <equi...@opensourcerouting.org>
Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp.bcapnp.c | 23 +++---
 bgpd/bgp.bcapnp.h |  6 -
 bgpd/bgp.capnp| 13 ++
 bgpd/bgp_route.c  | 52 +++
 bgpd/bgpd.h   | 10 +++-
 bgpd/bgpd.ndef.i  | 73 +++
 6 files changed, 166 insertions(+), 11 deletions(-)

diff --git a/bgpd/bgp.bcapnp.c b/bgpd/bgp.bcapnp.c
index 0da76f7a492b..2bf038128cd1 100644
--- a/bgpd/bgp.bcapnp.c
+++ b/bgpd/bgp.bcapnp.c
@@ -1109,13 +1109,11 @@ void qcapn_BGPVRFRoute_set(struct bgp_api_route *s, 
capn_ptr p)
 }
 
 
-capn_ptr qcapn_new_BGPVRFRoute(struct capn_segment *s)
+capn_ptr qcapn_new_BGPVRFRoute(struct capn_segment *s, uint8_t extend_by)
 {
-return capn_new_struct(s, 8, 2);
+return capn_new_struct(s, CAPN_BGPVRF_ROUTE_DEF_SIZE + extend_by, 2);
 }
 
-
-
 void qcapn_BGPEventVRFRoute_read(struct bgp_event_vrf *s, capn_ptr p)
 {
 uint64_t tmp;
@@ -1246,3 +1244,20 @@ capn_ptr qcapn_new_BGPEventShut(struct capn_segment *s)
 return capn_new_struct(s, 8, 1);
 }
 
+capn_ptr qcapn_new_BGPVRFInfoIter(struct capn_segment *s)
+{
+return capn_new_struct(s, 8, 0);
+}
+
+void qcapn_BGPVRFInfoIter_write(const unsigned long s, capn_ptr p, int offset)
+{
+capn_resolve();
+capn_write64(p, offset, s);
+}
+
+void qcapn_BGPVRFInfoIter_read(unsigned long *s, capn_ptr p, int offset)
+{
+capn_resolve();
+
+*s = capn_read64(p, offset);
+}
diff --git a/bgpd/bgp.bcapnp.h b/bgpd/bgp.bcapnp.h
index fafaf6cce83a..3b8ce361f6b2 100644
--- a/bgpd/bgp.bcapnp.h
+++ b/bgpd/bgp.bcapnp.h
@@ -43,7 +43,7 @@ capn_ptr qcapn_new_BGPVRF(struct capn_segment *s);
 void qcapn_BGPVRFRoute_read(struct bgp_api_route *s, capn_ptr p);
 void qcapn_BGPVRFRoute_write(const struct bgp_api_route *s, capn_ptr p);
 void qcapn_BGPVRFRoute_set(struct bgp_api_route *s, capn_ptr p);
-capn_ptr qcapn_new_BGPVRFRoute(struct capn_segment *s);
+capn_ptr qcapn_new_BGPVRFRoute(struct capn_segment *s, uint8_t extend_by);
 void qcapn_BGPEventVRFRoute_read(struct bgp_event_vrf *s, capn_ptr p);
 void qcapn_BGPEventVRFRoute_write(const struct bgp_event_vrf *s, capn_ptr p);
 void qcapn_BGPEventVRFRoute_set(struct bgp_event_vrf *s, capn_ptr p);
@@ -52,5 +52,9 @@ void qcapn_BGPEventShut_read(struct bgp_event_shut *s, 
capn_ptr p);
 void qcapn_BGPEventShut_write(const struct bgp_event_shut *s, capn_ptr p);
 void qcapn_BGPEventShut_set(struct bgp_event_shut *s, capn_ptr p);
 capn_ptr qcapn_new_BGPEventShut(struct capn_segment *s);
+capn_ptr qcapn_new_BGPVRFInfoIter(struct capn_segment *s);
+void qcapn_BGPVRFInfoIter_write(const unsigned long s, capn_ptr p, int offset);
+void qcapn_BGPVRFInfoIter_read(unsigned long *s, capn_ptr p, int offset);
 
+#define  CAPN_BGPVRF_ROUTE_DEF_SIZE  8
 #endif /* CAPN_C4C948A17D3B2250 */
diff --git a/bgpd/bgp.capnp b/bgpd/bgp.capnp
index da56ee4d2548..27a917ff62cd 100644
--- a/bgpd/bgp.capnp
+++ b/bgpd/bgp.capnp
@@ -40,6 +40,9 @@ struct AfiSafiKey $cgennaked $cgetfield {
afi  @0 :UInt8 $ctype("afi_t");
safi @1 :UInt8 $ctype("safi_t");
 }
+struct AfiKey $cgennaked $cgetfield {
+   afi  @0 :UInt8 $ctype("afi_t");
+}
 struct ExtCommunityList {
values   @0 :List(UInt64);
 }
@@ -47,6 +50,9 @@ struct PrefixV4 {
addr @0 :UInt32;
prefixlen@1 :UInt8;
 }
+struct VRFTableIter $ctype("struct tbliter_v4") $cgen {
+   prefix   @0 :PrefixV4;
+}
 
 struct BGP $ctype("struct bgp") $cgen
$csetter("bgp_%%_set")
@@ -159,6 +165,13 @@ struct BGPVRF $ctype("struct bgp_vrf") $cgen
rtExport @2 :ExtCommunityList;
 }
 
+struct BGPVRFRoute $ctype("struct bgp_api_route") $cgen
+{
+   prefix   @0 :PrefixV4;
+   nexthop  @1 :IPv4;
+   label@2 :UInt32;
+}
+
 struct BGPEventVRFRoute $ctype("struct bgp_event_vrf") $cgen
 {
announce @0 :Bool;
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index d26e64256985..652c47e6274a 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -1543,6 +1543,58 @@ bgp_process_announce_selected (struct peer *peer, struct 
bgp_info *selected,
   return 0;
 }
 
+bool bgp_api_route_get (struct bgp_api_route *out, struct bgp_node *bn,
+int iter_on_multipath, void **next)
+{
+  struct

[quagga-dev 16441] [PATCH 06/23] lib: capnp files are copied

2016-12-02 Thread Philippe Guibert
This patch integrates c files derived from qzc.capnp scheme
file. This C version is provided an needs to be syncronised with the
associated qzc.capnp file.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 lib/qzc.capnp.c | 466 
 lib/qzc.capnp.h | 251 ++
 2 files changed, 717 insertions(+)
 create mode 100644 lib/qzc.capnp.c
 create mode 100644 lib/qzc.capnp.h

diff --git a/lib/qzc.capnp.c b/lib/qzc.capnp.c
new file mode 100644
index ..e8950bebde5b
--- /dev/null
+++ b/lib/qzc.capnp.c
@@ -0,0 +1,466 @@
+#include "qzc.capnp.h"
+
+QZCNodeInfoReq_ptr new_QZCNodeInfoReq(struct capn_segment *s) {
+   QZCNodeInfoReq_ptr p;
+   p.p = capn_new_struct(s, 8, 0);
+   return p;
+}
+QZCNodeInfoReq_list new_QZCNodeInfoReq_list(struct capn_segment *s, int len) {
+   QZCNodeInfoReq_list p;
+   p.p = capn_new_list(s, len, 8, 0);
+   return p;
+}
+void read_QZCNodeInfoReq(struct QZCNodeInfoReq *s, QZCNodeInfoReq_ptr p) {
+   capn_resolve();
+   s->nid = capn_read64(p.p, 0);
+}
+void write_QZCNodeInfoReq(const struct QZCNodeInfoReq *s, QZCNodeInfoReq_ptr 
p) {
+   capn_resolve();
+   capn_write64(p.p, 0, s->nid);
+}
+void get_QZCNodeInfoReq(struct QZCNodeInfoReq *s, QZCNodeInfoReq_list l, int 
i) {
+   QZCNodeInfoReq_ptr p;
+   p.p = capn_getp(l.p, i, 0);
+   read_QZCNodeInfoReq(s, p);
+}
+void set_QZCNodeInfoReq(const struct QZCNodeInfoReq *s, QZCNodeInfoReq_list l, 
int i) {
+   QZCNodeInfoReq_ptr p;
+   p.p = capn_getp(l.p, i, 0);
+   write_QZCNodeInfoReq(s, p);
+}
+
+QZCNodeInfoRep_ptr new_QZCNodeInfoRep(struct capn_segment *s) {
+   QZCNodeInfoRep_ptr p;
+   p.p = capn_new_struct(s, 16, 0);
+   return p;
+}
+QZCNodeInfoRep_list new_QZCNodeInfoRep_list(struct capn_segment *s, int len) {
+   QZCNodeInfoRep_list p;
+   p.p = capn_new_list(s, len, 16, 0);
+   return p;
+}
+void read_QZCNodeInfoRep(struct QZCNodeInfoRep *s, QZCNodeInfoRep_ptr p) {
+   capn_resolve();
+   s->nid = capn_read64(p.p, 0);
+   s->tid = capn_read64(p.p, 8);
+}
+void write_QZCNodeInfoRep(const struct QZCNodeInfoRep *s, QZCNodeInfoRep_ptr 
p) {
+   capn_resolve();
+   capn_write64(p.p, 0, s->nid);
+   capn_write64(p.p, 8, s->tid);
+}
+void get_QZCNodeInfoRep(struct QZCNodeInfoRep *s, QZCNodeInfoRep_list l, int 
i) {
+   QZCNodeInfoRep_ptr p;
+   p.p = capn_getp(l.p, i, 0);
+   read_QZCNodeInfoRep(s, p);
+}
+void set_QZCNodeInfoRep(const struct QZCNodeInfoRep *s, QZCNodeInfoRep_list l, 
int i) {
+   QZCNodeInfoRep_ptr p;
+   p.p = capn_getp(l.p, i, 0);
+   write_QZCNodeInfoRep(s, p);
+}
+
+QZCWKNResolveReq_ptr new_QZCWKNResolveReq(struct capn_segment *s) {
+   QZCWKNResolveReq_ptr p;
+   p.p = capn_new_struct(s, 8, 0);
+   return p;
+}
+QZCWKNResolveReq_list new_QZCWKNResolveReq_list(struct capn_segment *s, int 
len) {
+   QZCWKNResolveReq_list p;
+   p.p = capn_new_list(s, len, 8, 0);
+   return p;
+}
+void read_QZCWKNResolveReq(struct QZCWKNResolveReq *s, QZCWKNResolveReq_ptr p) 
{
+   capn_resolve();
+   s->wid = capn_read64(p.p, 0);
+}
+void write_QZCWKNResolveReq(const struct QZCWKNResolveReq *s, 
QZCWKNResolveReq_ptr p) {
+   capn_resolve();
+   capn_write64(p.p, 0, s->wid);
+}
+void get_QZCWKNResolveReq(struct QZCWKNResolveReq *s, QZCWKNResolveReq_list l, 
int i) {
+   QZCWKNResolveReq_ptr p;
+   p.p = capn_getp(l.p, i, 0);
+   read_QZCWKNResolveReq(s, p);
+}
+void set_QZCWKNResolveReq(const struct QZCWKNResolveReq *s, 
QZCWKNResolveReq_list l, int i) {
+   QZCWKNResolveReq_ptr p;
+   p.p = capn_getp(l.p, i, 0);
+   write_QZCWKNResolveReq(s, p);
+}
+
+QZCWKNResolveRep_ptr new_QZCWKNResolveRep(struct capn_segment *s) {
+   QZCWKNResolveRep_ptr p;
+   p.p = capn_new_struct(s, 16, 0);
+   return p;
+}
+QZCWKNResolveRep_list new_QZCWKNResolveRep_list(struct capn_segment *s, int 
len) {
+   QZCWKNResolveRep_list p;
+   p.p = capn_new_list(s, len, 16, 0);
+   return p;
+}
+void read_QZCWKNResolveRep(struct QZCWKNResolveRep *s, QZCWKNResolveRep_ptr p) 
{
+   capn_resolve();
+   s->wid = capn_read64(p.p, 0);
+   s->nid = capn_read64(p.p, 8);
+}
+void write_QZCWKNResolveRep(const struct QZCWKNResolveRep *s, 
QZCWKNResolveRep_ptr p) {
+   capn_resolve();
+   capn_write64(p.p, 0, s->wid);
+   capn_write64(p.p, 8, s->nid);
+}
+void get_QZCWKNResolveRep(struct QZCWKNResolveRep *s, QZCWKNResolveRep_list l, 
int i) {
+   QZCWKNResolveRep_ptr p;
+   p.p = capn_getp(l.p, i, 0);
+   read_QZCWKNResolveRep(s, p);
+}
+void set_QZCWKNResolveRep(const struct QZCWKNResolveRep *s, 
QZCWKNResolveRep_list l, int i) {
+   QZCWKNResolveRep_ptr p;
+   p.p = capn_getp(l.p, i, 0);
+   write_QZCWKNResolveRep(s, p);
+}
+
+QZCGetReq_ptr new_QZCGetR

[quagga-dev 16444] [PATCH 13/23] bgpd: sanity checks around capnproto exchange

2016-12-02 Thread Philippe Guibert
This commit contains some modifications on supposed to be generated
files, as the default files may contain some non initialised variables,
it should lead to erratic behaviour on some circumstances.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp.bcapnp.c | 20 
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/bgpd/bgp.bcapnp.c b/bgpd/bgp.bcapnp.c
index 83eb3dac3b6e..c6fd5e67a693 100644
--- a/bgpd/bgp.bcapnp.c
+++ b/bgpd/bgp.bcapnp.c
@@ -530,10 +530,22 @@ void qcapn_BGPPeer_set(struct peer *s, capn_ptr p)
   /* MISSING: host */
 }
 {
-  const char * desc;
-  { capn_text tp = capn_get_text(p, 1, capn_val0); desc = tp.str; }
-  if (desc) { peer_description_set(s, desc); } else { 
peer_description_unset(s); }
-  
+  const char * desc = NULL;
+  {
+capn_text tp = capn_get_text(p, 1, capn_val0);
+if (tp.len)
+  {
+desc = tp.str;
+  }
+if (desc)
+  {
+peer_description_set(s, desc);
+  }
+else
+  {
+peer_description_unset(s);
+  }
+  }
 }
 {
   unsigned port;
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16442] [PATCH 11/23] bgpd: add BGP configuration file with and without debugging

2016-12-02 Thread Philippe Guibert
This commit brings default bgp config files that can be used, in order
to get default debugging setup, or not. There is no configuration
inside.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/Makefile.am   | 2 +-
 bgpd/bgpd.conf.sample3 | 7 +++
 bgpd/bgpd.conf.sample4 | 9 +
 3 files changed, 17 insertions(+), 1 deletion(-)
 create mode 100644 bgpd/bgpd.conf.sample3
 create mode 100644 bgpd/bgpd.conf.sample4

diff --git a/bgpd/Makefile.am b/bgpd/Makefile.am
index 3fcffe62c989..7cb5d8024757 100644
--- a/bgpd/Makefile.am
+++ b/bgpd/Makefile.am
@@ -34,7 +34,7 @@ bgp_btoa_SOURCES = bgp_btoa.c
 bgp_btoa_LDADD = libbgp.a ../lib/libzebra.la @LIBCAP@ @LIBM@ @ZEROMQ_LIBS@ 
@CAPN_C_LIBS@
 
 examplesdir = $(exampledir)
-dist_examples_DATA = bgpd.conf.sample bgpd.conf.sample2
+dist_examples_DATA = bgpd.conf.sample bgpd.conf.sample2 bgpd.conf.sample3 
bgpd.conf.sample4
 
 EXTRA_DIST = BGP4-MIB.txt
 
diff --git a/bgpd/bgpd.conf.sample3 b/bgpd/bgpd.conf.sample3
new file mode 100644
index ..5173c7736863
--- /dev/null
+++ b/bgpd/bgpd.conf.sample3
@@ -0,0 +1,7 @@
+hostname bgpd
+password zebra
+log stdout
+service advanced-vty
+
+line vty
+ exec-timeout 0 0
diff --git a/bgpd/bgpd.conf.sample4 b/bgpd/bgpd.conf.sample4
new file mode 100644
index ..5367e4b2780b
--- /dev/null
+++ b/bgpd/bgpd.conf.sample4
@@ -0,0 +1,9 @@
+hostname bgpd
+password zebra
+service advanced-vty
+log stdout
+line vty
+ exec-timeout 0 0
+debug bgp
+debug bgp updates
+debug bgp events
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16436] [PATCH 03/23] tests: ZeroMQ code

2016-12-02 Thread Philippe Guibert
From: David Lamparter <equi...@opensourcerouting.org>

The test consists in sending a message from a req(uest) to a rep(ly).
The rep will dump the received message and send back an ACK to say it
has well received the message.

To perform the zeromq test on your system, please do the following.
make check
once done, manually run
./tests/test_zmq_event
you will fall on a cli prompt.
perform the following command lines
test# configure
test(config)# log stdout
test(config)# end
test# zmq open rep ipc:///tmp/zeromqtest2
zmq socket 0x1f55ac0
test# zmq open req ipc:///tmp/zeromqtest2
zmq socket 0x1f56940
test# zmq send line

If operation is successfull, a similar message like below should appear:
2016/11/02 08:47:40 NONE: msg: 5(0x7ffddc8eb168) line
2016/11/02 08:47:40 NONE: more data: (0)0
2016/11/02 08:47:40 NONE: REP socket, sending reply
2016/11/02 08:47:40 NONE: msg: 4(0x7ffddc8eb168) ACK
2016/11/02 08:47:40 NONE: more data: (0)0

Signed-off-by: David Lamparter <equi...@opensourcerouting.org>
Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 tests/.gitignore   |   1 +
 tests/Makefile.am  |   8 ++-
 tests/test-zmq-event.c | 181 +
 3 files changed, 189 insertions(+), 1 deletion(-)
 create mode 100644 tests/test-zmq-event.c

diff --git a/tests/.gitignore b/tests/.gitignore
index 3002b27149e1..535375b2bb81 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -38,4 +38,5 @@ teststream
 testnexthopiter
 testcommands
 test-commands-defun.c
+test_zmq_event
 site.exp
diff --git a/tests/Makefile.am b/tests/Makefile.am
index c1194e9090c7..cb907b1b704e 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -16,7 +16,7 @@ EXTRA_DIST = \
testcli.refout
 
 AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib 
-I$(top_srcdir)/lib/c-capnproto
-DEFS = @DEFS@ $(LOCAL_OPTS) -DSYSCONFDIR=\"$(sysconfdir)/\"
+DEFS = @DEFS@ $(LOCAL_OPTS) -DSYSCONFDIR=\"$(sysconfdir)/\" @ZEROMQ_CFLAGS@
 
 if BGPD
 TESTS_BGPD = aspathtest testbgpcap ecommtest testbgpmpattr testbgpmpath
@@ -31,6 +31,10 @@ check_PROGRAMS = testsig testsegv testbuffer testmemory 
heavy heavywq heavythrea
testcli \
$(TESTS_BGPD)
 
+if HAVE_ZEROMQ
+check_PROGRAMS += test_zmq_event
+endif
+
 ../vtysh/vtysh_cmd.c:
$(MAKE) -C ../vtysh vtysh_cmd.c
 
@@ -66,6 +70,7 @@ testnexthopiter_SOURCES = test-nexthop-iter.c prng.c
 testcommands_SOURCES = test-commands-defun.c test-commands.c prng.c
 test_timer_correctness_SOURCES = test-timer-correctness.c prng.c
 test_timer_performance_SOURCES = test-timer-performance.c prng.c
+test_zmq_event_SOURCES = test-zmq-event.c common-cli.c
 
 testcli_LDADD = ../lib/libzebra.la @LIBCAP@
 testsig_LDADD = ../lib/libzebra.la @LIBCAP@
@@ -88,3 +93,4 @@ testnexthopiter_LDADD = ../lib/libzebra.la @LIBCAP@
 testcommands_LDADD = ../lib/libzebra.la @LIBCAP@
 test_timer_correctness_LDADD = ../lib/libzebra.la @LIBCAP@
 test_timer_performance_LDADD = ../lib/libzebra.la @LIBCAP@
+test_zmq_event_LDADD = ../lib/libzebra.la @LIBCAP@ $(ZEROMQ_LIBS)
diff --git a/tests/test-zmq-event.c b/tests/test-zmq-event.c
new file mode 100644
index ..9ebee874cae9
--- /dev/null
+++ b/tests/test-zmq-event.c
@@ -0,0 +1,181 @@
+/*
+ * Test program to verify that scheduled timers are executed in the
+ * correct order.
+ *
+ * Copyright (C) 2013 by Open Source Routing.
+ * Copyright (C) 2013 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2015 by David Lamparter, for NetDEF, Inc.
+ *
+ * This file is part of Quagga
+ *
+ * Quagga 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, or (at your option) any
+ * later version.
+ *
+ * Quagga 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 Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include 
+#include 
+
+#include 
+
+#include "qzmq.h"
+#include "thread.h"
+#include "memory.h"
+#include "pqueue.h"
+#include "prng.h"
+#include "log.h"
+#include "command.h"
+#include "common-cli.h"
+
+static int dummy_req = 0, dummy_rep = 1;
+
+static void callback (void *arg, void *zmqsock, zmq_msg_t *msg)
+{
+  int64_t more = 0;
+  size_t more_size;
+  int ret;
+
+  do
+{
+  void *data = zmq_msg_data (msg);
+  size_t size = zmq_msg_size (msg);
+
+  zlog_info ("msg: %zu(%p) %s", size, data, (const char *)data);
+
+  m

[quagga-dev 16439] [PATCH 08/23] lib: qzc debug log are conditioned with a debug variable

2016-12-02 Thread Philippe Guibert
This variable can be set by compilation, if there is a need to monitor
qzc exchanges.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 lib/qzc.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/lib/qzc.c b/lib/qzc.c
index 358b7e419eef..7425743f8cea 100644
--- a/lib/qzc.c
+++ b/lib/qzc.c
@@ -31,6 +31,8 @@
 
 #include "qzc.capnp.h"
 
+static int qzc_debug = 0;
+
 static struct qzc_wkn *wkn_first = NULL;
 
 void qzc_wkn_reg(struct qzc_wkn *wkn)
@@ -296,7 +298,8 @@ static void qzc_callback (void *arg, void *zmqsock, 
zmq_msg_t *msg)
   capn_free();
   capn_free();
 
-  zlog_info ("QZC request type %d, response type %d, %zd bytes, error=%d", 
req.which, rep.which, rs, rep.error);
+  if(qzc_debug)
+zlog_debug ("QZC request type %d, response type %d, %zd bytes, error=%d", 
req.which, rep.which, rs, rep.error);
   zmq_send (zmqsock, buf, rs, 0);
 
   do
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16437] [PATCH 05/23] tests: update makefile to link with zmq files

2016-12-02 Thread Philippe Guibert
The introduction of ZMQ library has led to automatic linking
with all other daemons and test programs. This modification
is taking into account the link with test programs.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 tests/Makefile.am | 42 +-
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/tests/Makefile.am b/tests/Makefile.am
index cb907b1b704e..65df0479a58e 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -72,25 +72,25 @@ test_timer_correctness_SOURCES = test-timer-correctness.c 
prng.c
 test_timer_performance_SOURCES = test-timer-performance.c prng.c
 test_zmq_event_SOURCES = test-zmq-event.c common-cli.c
 
-testcli_LDADD = ../lib/libzebra.la @LIBCAP@
-testsig_LDADD = ../lib/libzebra.la @LIBCAP@
-testsegv_LDADD = ../lib/libzebra.la @LIBCAP@
-testbuffer_LDADD = ../lib/libzebra.la @LIBCAP@
-testmemory_LDADD = ../lib/libzebra.la @LIBCAP@
-testprivs_LDADD = ../lib/libzebra.la @LIBCAP@
-teststream_LDADD = ../lib/libzebra.la @LIBCAP@
-heavy_LDADD = ../lib/libzebra.la @LIBCAP@ -lm
-heavywq_LDADD = ../lib/libzebra.la @LIBCAP@ -lm
-heavythread_LDADD = ../lib/libzebra.la @LIBCAP@ -lm
-aspathtest_LDADD = ../bgpd/libbgp.a ../lib/libzebra.la @LIBCAP@ -lm
-testbgpcap_LDADD = ../bgpd/libbgp.a ../lib/libzebra.la @LIBCAP@ -lm
-ecommtest_LDADD = ../bgpd/libbgp.a ../lib/libzebra.la @LIBCAP@ -lm
-testbgpmpattr_LDADD = ../bgpd/libbgp.a ../lib/libzebra.la @LIBCAP@ -lm
-testchecksum_LDADD = ../lib/libzebra.la @LIBCAP@ 
-testbgpmpath_LDADD = ../bgpd/libbgp.a ../lib/libzebra.la @LIBCAP@ -lm
-tabletest_LDADD = ../lib/libzebra.la @LIBCAP@ -lm
-testnexthopiter_LDADD = ../lib/libzebra.la @LIBCAP@
-testcommands_LDADD = ../lib/libzebra.la @LIBCAP@
-test_timer_correctness_LDADD = ../lib/libzebra.la @LIBCAP@
-test_timer_performance_LDADD = ../lib/libzebra.la @LIBCAP@
+testcli_LDADD = ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@
+testsig_LDADD = ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@
+testsegv_LDADD = ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@
+testbuffer_LDADD = ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@
+testmemory_LDADD = ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@
+testprivs_LDADD = ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@
+teststream_LDADD = ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@
+heavy_LDADD = ../lib/libzebra.la @LIBCAP@ -lm @ZEROMQ_LIBS@
+heavywq_LDADD = ../lib/libzebra.la @LIBCAP@ -lm @ZEROMQ_LIBS@
+heavythread_LDADD = ../lib/libzebra.la @LIBCAP@ -lm @ZEROMQ_LIBS@
+aspathtest_LDADD = ../bgpd/libbgp.a ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@ 
-lm
+testbgpcap_LDADD = ../bgpd/libbgp.a ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@ 
-lm
+ecommtest_LDADD = ../bgpd/libbgp.a ../lib/libzebra.la @LIBCAP@ -lm 
@ZEROMQ_LIBS@ 
+testbgpmpattr_LDADD = ../bgpd/libbgp.a ../lib/libzebra.la @LIBCAP@ 
@ZEROMQ_LIBS@ -lm
+testchecksum_LDADD = ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@ 
+testbgpmpath_LDADD = ../bgpd/libbgp.a ../lib/libzebra.la @LIBCAP@ 
@ZEROMQ_LIBS@ -lm
+tabletest_LDADD = ../lib/libzebra.la @LIBCAP@ -lm @ZEROMQ_LIBS@
+testnexthopiter_LDADD = ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@
+testcommands_LDADD = ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@
+test_timer_correctness_LDADD = ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@
+test_timer_performance_LDADD = ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@
 test_zmq_event_LDADD = ../lib/libzebra.la @LIBCAP@ $(ZEROMQ_LIBS)
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16433] [PATCH 00/23] Quagga CapnProto API

2016-12-02 Thread Philippe Guibert
Hi all,

This set of patches contains adaptations to BGP daemon, to bring a new API of 
management, based on capnproto protocol.

The API implementation relies on capnproto protocol for data serialisation, 
since it is able to receive and send simple and complex data structures. The 
emission relies on on  an other protocol called zeroMQ, which is a fast data 
exchange mecanism, that is very efficient. The pairing of both technologies 
offers BGP, but also the whole QUAGGA framework, a fast and easy mecanism for 
management, without having to rely on vty. 
Note that capnproto owns its own code generator. Based on a scheme file, it is 
able to generate code so that the application can be hidden of the internal 
complexity of capnproto generated code. As example, it is possible to carry in 
messages some structures like prefixes or ip addresses. As of today, 
unfortunately, there is not yet any publicly available tool that generates c 
code, based on the proposed scheme files available in that patch series ( 
qzc.capnp can with standard c-capnproto compiler, but not bgp.capnp). So 
currently, the code has been hardset, and the scheme file is maintained along 
with the generated source code. More information about capnproto and zeromq on 
respective web sites : http://capnproto.org and http://zeromq.org. 
The API implementation does not limit to capnproto/zeromq protocol, but can 
host a wide variety of other RPC protocols. 

The BGP API implemented currently offers capabilities for configuring the main 
data structures that can be found on BGP: BGP start, BGP instances, BGP peers. 
Basically, with a capnproto interface, one can create, configure, delete the 
whole BGP. This API implementation relies on the BGP VRF extension used in 
conjonction with VPNv4 configuration. By this sentence, the intention is to use 
that API to dynamically provision in BGP networking information about 
MPLS/VXLAN tunnels. As such, it is also possible to configure VRF import 
processing. In addition to configuration, BGP API offers a notification entry 
so that the remote manager can receive notifications from BGP, when an event 
occured. That can be a peer that is being shutdown, or the notification that a 
new entry has been received. BGP API finally permits doing exploitation, since 
an algorithm has been put in place so as to iterate on the list of entries 
contained in VRF RIB tables.

Note also that a build dependency has been added on zeromq and c-capnproto. You 
have to force configuration in order to enable the usage of capnproto with the 
following: --with-ccapnproto --with-zeromq. While zeromq is usually available 
in many distributions ( however a recent version is needed - tested on zeromq 
4.1 - ), it is not the case for ccapnproto. This library is officially 
maintained : https://github.com/opensourcerouting/c-capnproto.

Note also that in order to apply this patch, you will need to get also 
following patches before:
https://lists.quagga.net/pipermail/quagga-dev/2016-October/016266.html
https://lists.quagga.net/pipermail/quagga-dev/2016-December/016504.html
https://lists.quagga.net/pipermail/quagga-dev/2016-October/016349.html
https://lists.quagga.net/pipermail/quagga-dev/2016-October/016375.html
https://lists.quagga.net/pipermail/quagga-dev/2016-October/016382.html


Currently, In order to manage quagga framework by using capnproto, it is needed 
to have an other capnproto implementation able to communicate with the various 
quagga daemons, and using the same capnproto scheme files. 

Cheers,

Philippe


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16440] [PATCH 09/23] bgpd: add capnproto information on doc file related to implementation

2016-12-02 Thread Philippe Guibert
Some information is appended to bgp implementation to explain about
newly added files related to capnproto.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/IMPLEMENTATION.txt | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/bgpd/IMPLEMENTATION.txt b/bgpd/IMPLEMENTATION.txt
index fff360ab9693..b1826108f12e 100644
--- a/bgpd/IMPLEMENTATION.txt
+++ b/bgpd/IMPLEMENTATION.txt
@@ -135,6 +135,9 @@ bgpd.h
   struct bgp_filter: distribute, prefix, aslist, route_maps
   struct peer: neighbor structure (very rich/complex)
   struct bgp_nlri: reference to wire format
+  struct bgp_vrf
+  struct bgp_event_shut, struct bgp_event_vrf
+  struct tbliter_v4, bgp_api_route : shared structures to handle route entries 
with capnprotox
   #define of protocol constants
 attribute type codes
   fsm states/events
@@ -145,6 +148,21 @@ bgpd.c
   configuration
   initialization/termination
 
+bgp_zmq.c
+  handle emission of notifications via capnproto interface
+
+bgp.capnp
+  capnproto schema language file for bgp API.
+  Currently not used to generate c files
+
+bgp.bcapnp.[ch]
+  Handler routines to read/write capnproto structures.
+  Handler routines to set bgp structures.
+
+bgp.ndef.[hi,i]
+  Quagga BGP zeromessagequeues to handle actions on capnproto structures.
+  The actions can be set/get/delete
+
 * DATA STRUCTURE SIZES
 
 Question: How much memory does quagga's bgpd use as a function of
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16434] [PATCH 01/23] configure: add with-zeromq and with-ccapnproto configuration parameter

2016-12-02 Thread Philippe Guibert
Those config parameters permit usage of zeromq library and capnproto
library. Those two config parameters are necessary in order to use
capnproto configuration interface that will be needed by BGP.

Signed-off-by: David Lamparter <equi...@opensourcerouting.org>
Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 configure.ac | 37 -
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index ce1bb7ea713d..6a48c5c544e1 100755
--- a/configure.ac
+++ b/configure.ac
@@ -7,7 +7,7 @@
 ##
 AC_PREREQ(2.60)
 
-AC_INIT(Quagga, 1.1.0, [https://bugzilla.quagga.net])
+AC_INIT(Quagga, 1.1.0-dev, [https://bugzilla.quagga.net])
 CONFIG_ARGS="$*"
 AC_SUBST(CONFIG_ARGS)
 AC_CONFIG_SRCDIR(lib/zebra.h)
@@ -1497,6 +1497,41 @@ AC_CHECK_HEADER([malloc.h],
   )
  ], [], QUAGGA_INCLUDES)
 
+dnl --
+dnl ZeroMQ
+dnl --
+if test "$with_zeromq" != "no"; then
+   AC_SEARCH_LIBS([zmq_msg_init], [zmq], [
+   AC_DEFINE(HAVE_ZEROMQ, 1, [Enable ZeroMQ support])
+   AC_DEFINE(ZEROMQ_CFLAGS, $(ZEROMQ_CFLAGS), [cflags for zeromq])
+   AC_DEFINE(ZEROMQ_LIBS, $(ZEROMQ_LIBS), [ldflags for zeromq])
+   ZEROMQ=true
+   AC_SUBST(ZEROMQ_CFLAGS)
+   AC_SUBST(ZEROMQ_LIBS)
+   ], [
+   AC_MSG_ERROR([configuration specifies --with-zeromq but libzmq was not 
found])
+   ])
+fi
+
+dnl --
+dnl capnproto
+dnl --
+if test "$with_ccapnproto" != "no"; then
+  AC_SEARCH_LIBS([capn_init_malloc], [capn_c], [
+AC_DEFINE(HAVE_CCAPNPROTO, 1, [Enable c-capnproto support])
+AC_DEFINE(CAPN_C_CFLAGS, $(CAPN_C_CFLAGS), [cflags for c-capnproto])
+AC_DEFINE(CAPN_C_LIBS, $(CAPN_C_LIBS), [ldflags for c-capnproto])
+CCAPNPROTO=true
+AC_SUBST(CAPN_C_CFLAGS)
+AC_SUBST(CAPN_C_LIBS)
+  ], [
+   AC_MSG_ERROR([ccapnproto needed but libcapn_c was not found])
+  ])
+fi
+
+AM_CONDITIONAL([HAVE_ZEROMQ], test "x$ZEROMQ" = "xtrue")
+AM_CONDITIONAL([HAVE_CCAPNPROTO], test "x$CCAPNPROTO" = "xtrue")
+
 dnl --
 dnl configure date
 dnl --
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16431] [PATCH 07/23] lib: add basic capn config access protocol

2016-12-02 Thread Philippe Guibert
From: David Lamparter <equi...@opensourcerouting.org>

This commit introduces the qzc.capnp schema file. This schema file is
only here for information, despite it is possible to automate c files
generation, from this scheme file.
In addition, qzc framework needs some server API to handle qzc queries
from any qzc client. Among the APIs, there is the possibility to handle
delete/destroy/unset operations. It is also possible to answer to get
operations that request some context to be retrieved. Finally, it is
possible to handle iterations over a table, for example.

Signed-off-by: David Lamparter <equi...@opensourcerouting.org>
Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 lib/.gitignore  |   2 +
 lib/Makefile.am |  10 +-
 lib/memtypes.c  |   1 +
 lib/qzc.c   | 372 
 lib/qzc.capnp   | 148 ++
 lib/qzc.h   |  95 +++
 6 files changed, 626 insertions(+), 2 deletions(-)
 create mode 100644 lib/qzc.c
 create mode 100644 lib/qzc.capnp
 create mode 100644 lib/qzc.h

diff --git a/lib/.gitignore b/lib/.gitignore
index 02aa432ce16d..f30e20b93802 100644
--- a/lib/.gitignore
+++ b/lib/.gitignore
@@ -3,6 +3,8 @@ Makefile.in
 *.o
 *.lo
 *.la
+*.capnp.c
+*.capnp.h
 version.c
 version.h
 gitversion.h
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 7b6c34dcabb5..c286834e 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -36,11 +36,17 @@ noinst_HEADERS = \
plist_int.h
 
 if HAVE_ZEROMQ
-libzebra_la_SOURCES += qzmq.c
-pkginclude_HEADERS += qzmq.h
+libzebra_la_SOURCES += qzmq.c qzc.c
+pkginclude_HEADERS += qzmq.h qzc.h
+endif
+
+if HAVE_CCAPNPROTO
+libzebra_la_SOURCES += qzc.capnp.c
+BUILT_SOURCES += qzc.capnp.c
 endif
 
 EXTRA_DIST = \
+   qzc.capnp \
regex.c regex-gnu.h \
queue.h \
memtypes.awk \
diff --git a/lib/memtypes.c b/lib/memtypes.c
index bfda5eb7b14e..3e43a857322e 100644
--- a/lib/memtypes.c
+++ b/lib/memtypes.c
@@ -75,6 +75,7 @@ struct memory_list memory_list_lib[] =
   { MTYPE_IF_LINK_PARAMS,   "Informational Link Parameters" },
   { MTYPE_LIB_NEXTHOP, "Nexthop"   },
   { MTYPE_ZEROMQ_CB,   "ZEROMQ_CB" },
+  { MTYPE_QZC_SOCK,"QZC"   },
   { -1, NULL },
 };
 
diff --git a/lib/qzc.c b/lib/qzc.c
new file mode 100644
index ..358b7e419eef
--- /dev/null
+++ b/lib/qzc.c
@@ -0,0 +1,372 @@
+/*
+ * Copyright (C) 2015-16  David Lamparter, for NetDEF, Inc.
+ *
+ * This file is part of Quagga
+ *
+ * Quagga 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, or (at your option) any
+ * later version.
+ *
+ * Quagga 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 Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include 
+
+#include "qzmq.h"
+#include "thread.h"
+#include "memory.h"
+#include "hash.h"
+#include "log.h"
+
+#include "qzc.h"
+
+#include "qzc.capnp.h"
+
+static struct qzc_wkn *wkn_first = NULL;
+
+void qzc_wkn_reg(struct qzc_wkn *wkn)
+{
+   wkn->next = wkn_first;
+   wkn_first = wkn;
+}
+
+static struct qzc_wkn *qzc_wkn_find(uint64_t wid)
+{
+   struct qzc_wkn *wkn;
+   for (wkn = wkn_first; wkn; wkn = wkn->next)
+   if (wkn->wid == wid)
+   return wkn;
+   return NULL;
+}
+
+static struct hash *nodes = NULL;
+
+static unsigned int qzc_key (void *data)
+{
+  struct qzc_node *node = data;
+  return (unsigned int)node->nid;
+}
+
+static int qzc_cmp (const void *a, const void *b)
+{
+  const struct qzc_node *na = a, *nb = b;
+  return na->nid == nb->nid;
+}
+
+void qzc_node_reg(struct qzc_node *node, struct qzc_nodetype *type)
+{
+  node->type = type;
+  do
+{
+  node->nid  = (uint64_t)random();
+  node->nid ^= (uint64_t)random() << 32;
+}
+  while (hash_get (nodes, node, hash_alloc_intern) != node);
+}
+
+void qzc_node_unreg(struct qzc_node *node)
+{
+  hash_release (nodes, node);
+}
+
+static struct qzc_node *qzc_node_get(uint64_t id)
+{
+  struct qzc_node dummy = { .nid = id };
+  return hash_lookup (nodes, );
+}
+
+static void qzc_wknresolve (struct QZCRequest *req, struct QZCReply *rep,
+struct capn_segment *cs)
+{
+  struct QZCWKNResolveReq wknreq;
+  struct QZCWKNResolveRep wknrep;
+  memset(, 0, sizeof(wknrep));
+
+  read_QZCWK

[quagga-dev 16432] [PATCH 10/23] bgpd: enable use of capn/zmq interface

2016-12-02 Thread Philippe Guibert
From: David Lamparter <equi...@opensourcerouting.org>

This commit enables the usage of capn/zmq API on bgp daemon, by
linking and using capn/zmq APIs, through using specific BGP
configuration parameters. It will be possible to receive queries
by using a zmq socket mentioned by -Z parameter.
Also, this commit introduces some new APIs that will be used by
capn/zmq APIs as entry points to manage BGP internals.
Using capn/zmq APIs means sharing data strucures. Those data
structures are defined by schemas, and are mapped on current
BGP structures. In order to be used in BGP daemon, some node
registrations are defined.
This patch introduces also bgp code modifications to
handle peer creation, configure specific bgp fields.

Signed-off-by: David Lamparter <equi...@opensourcerouting.org>
Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/.gitignore  |   5 ++
 bgpd/Makefile.am |   9 ++--
 bgpd/bgp.capnp   | 156 +++
 bgpd/bgp_main.c  |  28 +-
 bgpd/bgpd.c  | 108 ++
 bgpd/bgpd.h  |  11 
 6 files changed, 302 insertions(+), 15 deletions(-)
 create mode 100644 bgpd/bgp.capnp

diff --git a/bgpd/.gitignore b/bgpd/.gitignore
index 105be2299503..863d479f54dd 100644
--- a/bgpd/.gitignore
+++ b/bgpd/.gitignore
@@ -12,6 +12,11 @@ TAGS
 *.la
 *.a
 *.libs
+*.bcapnp
+*.bcapnp.c
+*.bcapnp.h
+*.ndef.i
+*.ndef.hi
 .arch-inventory
 .arch-ids
 *~
diff --git a/bgpd/Makefile.am b/bgpd/Makefile.am
index d5be054f9555..3fcffe62c989 100644
--- a/bgpd/Makefile.am
+++ b/bgpd/Makefile.am
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in.
 
-AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
+AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib 
@CAPN_C_CFLAGS@ @ZEROMQ_CFLAGS@
 DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
 INSTALL_SDATA=@INSTALL@ -m 600
 
@@ -27,13 +27,16 @@ noinst_HEADERS = \
bgp_encap.h bgp_encap_tlv.h bgp_encap_types.h bgp_nht.h
 
 bgpd_SOURCES = bgp_main.c
-bgpd_LDADD = libbgp.a ../lib/libzebra.la @LIBCAP@ @LIBM@
+
+bgpd_LDADD = libbgp.a ../lib/libzebra.la @LIBCAP@ @LIBM@ @ZEROMQ_LIBS@ 
@CAPN_C_LIBS@
 
 bgp_btoa_SOURCES = bgp_btoa.c
-bgp_btoa_LDADD = libbgp.a ../lib/libzebra.la @LIBCAP@ @LIBM@
+bgp_btoa_LDADD = libbgp.a ../lib/libzebra.la @LIBCAP@ @LIBM@ @ZEROMQ_LIBS@ 
@CAPN_C_LIBS@
 
 examplesdir = $(exampledir)
 dist_examples_DATA = bgpd.conf.sample bgpd.conf.sample2
 
 EXTRA_DIST = BGP4-MIB.txt
 
+EXTRA_DIST += bgpd.ndef.i bgpd.ndef.hi bgp.bcapnp.c bgp.bcapnp.h
+libbgp_a_SOURCES += bgp.bcapnp.c
diff --git a/bgpd/bgp.capnp b/bgpd/bgp.capnp
new file mode 100644
index ..2603e6983ad6
--- /dev/null
+++ b/bgpd/bgp.capnp
@@ -0,0 +1,156 @@
+#
+# Copyright (c) 2016  David Lamparter, for NetDEF, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+
+@0xc4c948a17d3b2250;
+
+using import "../capnp/codegen.capnp".Cflag;
+using import "../capnp/codegen.capnp".IPv4;
+
+using import "../capnp/codegen.capnp".ctype;
+using import "../capnp/codegen.capnp".cflag;
+using import "../capnp/codegen.capnp".cheader;
+using import "../capnp/codegen.capnp".cgen;
+using import "../capnp/codegen.capnp".csetter;
+using import "../capnp/codegen.capnp".cgetfield;
+using import "../capnp/codegen.capnp".cgennaked;
+using import "../capnp/codegen.capnp".carraykey;
+using import "../capnp/codegen.capnp".caltname;
+using import "../capnp/codegen.capnp".csetwrite;
+
+struct AfiSafiKey $cgennaked $cgetfield {
+   afi  @0 :UInt8 $ctype("afi_t");
+   safi @1 :UInt8 $ctype("safi_t");
+}
+struct ExtCommunityList {
+   values   @0 :List(UInt64);
+}
+
+struct BGP $ctype("st

[quagga-dev 16430] [PATCH 06/23] lib: capnp files are copied

2016-12-02 Thread Philippe Guibert
This patch integrates c files derived from qzc.capnp scheme
file. This C version is provided an needs to be syncronised with the
associated qzc.capnp file.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 lib/qzc.capnp.c | 466 
 lib/qzc.capnp.h | 251 ++
 2 files changed, 717 insertions(+)
 create mode 100644 lib/qzc.capnp.c
 create mode 100644 lib/qzc.capnp.h

diff --git a/lib/qzc.capnp.c b/lib/qzc.capnp.c
new file mode 100644
index ..e8950bebde5b
--- /dev/null
+++ b/lib/qzc.capnp.c
@@ -0,0 +1,466 @@
+#include "qzc.capnp.h"
+
+QZCNodeInfoReq_ptr new_QZCNodeInfoReq(struct capn_segment *s) {
+   QZCNodeInfoReq_ptr p;
+   p.p = capn_new_struct(s, 8, 0);
+   return p;
+}
+QZCNodeInfoReq_list new_QZCNodeInfoReq_list(struct capn_segment *s, int len) {
+   QZCNodeInfoReq_list p;
+   p.p = capn_new_list(s, len, 8, 0);
+   return p;
+}
+void read_QZCNodeInfoReq(struct QZCNodeInfoReq *s, QZCNodeInfoReq_ptr p) {
+   capn_resolve();
+   s->nid = capn_read64(p.p, 0);
+}
+void write_QZCNodeInfoReq(const struct QZCNodeInfoReq *s, QZCNodeInfoReq_ptr 
p) {
+   capn_resolve();
+   capn_write64(p.p, 0, s->nid);
+}
+void get_QZCNodeInfoReq(struct QZCNodeInfoReq *s, QZCNodeInfoReq_list l, int 
i) {
+   QZCNodeInfoReq_ptr p;
+   p.p = capn_getp(l.p, i, 0);
+   read_QZCNodeInfoReq(s, p);
+}
+void set_QZCNodeInfoReq(const struct QZCNodeInfoReq *s, QZCNodeInfoReq_list l, 
int i) {
+   QZCNodeInfoReq_ptr p;
+   p.p = capn_getp(l.p, i, 0);
+   write_QZCNodeInfoReq(s, p);
+}
+
+QZCNodeInfoRep_ptr new_QZCNodeInfoRep(struct capn_segment *s) {
+   QZCNodeInfoRep_ptr p;
+   p.p = capn_new_struct(s, 16, 0);
+   return p;
+}
+QZCNodeInfoRep_list new_QZCNodeInfoRep_list(struct capn_segment *s, int len) {
+   QZCNodeInfoRep_list p;
+   p.p = capn_new_list(s, len, 16, 0);
+   return p;
+}
+void read_QZCNodeInfoRep(struct QZCNodeInfoRep *s, QZCNodeInfoRep_ptr p) {
+   capn_resolve();
+   s->nid = capn_read64(p.p, 0);
+   s->tid = capn_read64(p.p, 8);
+}
+void write_QZCNodeInfoRep(const struct QZCNodeInfoRep *s, QZCNodeInfoRep_ptr 
p) {
+   capn_resolve();
+   capn_write64(p.p, 0, s->nid);
+   capn_write64(p.p, 8, s->tid);
+}
+void get_QZCNodeInfoRep(struct QZCNodeInfoRep *s, QZCNodeInfoRep_list l, int 
i) {
+   QZCNodeInfoRep_ptr p;
+   p.p = capn_getp(l.p, i, 0);
+   read_QZCNodeInfoRep(s, p);
+}
+void set_QZCNodeInfoRep(const struct QZCNodeInfoRep *s, QZCNodeInfoRep_list l, 
int i) {
+   QZCNodeInfoRep_ptr p;
+   p.p = capn_getp(l.p, i, 0);
+   write_QZCNodeInfoRep(s, p);
+}
+
+QZCWKNResolveReq_ptr new_QZCWKNResolveReq(struct capn_segment *s) {
+   QZCWKNResolveReq_ptr p;
+   p.p = capn_new_struct(s, 8, 0);
+   return p;
+}
+QZCWKNResolveReq_list new_QZCWKNResolveReq_list(struct capn_segment *s, int 
len) {
+   QZCWKNResolveReq_list p;
+   p.p = capn_new_list(s, len, 8, 0);
+   return p;
+}
+void read_QZCWKNResolveReq(struct QZCWKNResolveReq *s, QZCWKNResolveReq_ptr p) 
{
+   capn_resolve();
+   s->wid = capn_read64(p.p, 0);
+}
+void write_QZCWKNResolveReq(const struct QZCWKNResolveReq *s, 
QZCWKNResolveReq_ptr p) {
+   capn_resolve();
+   capn_write64(p.p, 0, s->wid);
+}
+void get_QZCWKNResolveReq(struct QZCWKNResolveReq *s, QZCWKNResolveReq_list l, 
int i) {
+   QZCWKNResolveReq_ptr p;
+   p.p = capn_getp(l.p, i, 0);
+   read_QZCWKNResolveReq(s, p);
+}
+void set_QZCWKNResolveReq(const struct QZCWKNResolveReq *s, 
QZCWKNResolveReq_list l, int i) {
+   QZCWKNResolveReq_ptr p;
+   p.p = capn_getp(l.p, i, 0);
+   write_QZCWKNResolveReq(s, p);
+}
+
+QZCWKNResolveRep_ptr new_QZCWKNResolveRep(struct capn_segment *s) {
+   QZCWKNResolveRep_ptr p;
+   p.p = capn_new_struct(s, 16, 0);
+   return p;
+}
+QZCWKNResolveRep_list new_QZCWKNResolveRep_list(struct capn_segment *s, int 
len) {
+   QZCWKNResolveRep_list p;
+   p.p = capn_new_list(s, len, 16, 0);
+   return p;
+}
+void read_QZCWKNResolveRep(struct QZCWKNResolveRep *s, QZCWKNResolveRep_ptr p) 
{
+   capn_resolve();
+   s->wid = capn_read64(p.p, 0);
+   s->nid = capn_read64(p.p, 8);
+}
+void write_QZCWKNResolveRep(const struct QZCWKNResolveRep *s, 
QZCWKNResolveRep_ptr p) {
+   capn_resolve();
+   capn_write64(p.p, 0, s->wid);
+   capn_write64(p.p, 8, s->nid);
+}
+void get_QZCWKNResolveRep(struct QZCWKNResolveRep *s, QZCWKNResolveRep_list l, 
int i) {
+   QZCWKNResolveRep_ptr p;
+   p.p = capn_getp(l.p, i, 0);
+   read_QZCWKNResolveRep(s, p);
+}
+void set_QZCWKNResolveRep(const struct QZCWKNResolveRep *s, 
QZCWKNResolveRep_list l, int i) {
+   QZCWKNResolveRep_ptr p;
+   p.p = capn_getp(l.p, i, 0);
+   write_QZCWKNResolveRep(s, p);
+}
+
+QZCGetReq_ptr new_QZCGetR

[quagga-dev 16425] [PATCH 03/23] tests: ZeroMQ code

2016-12-02 Thread Philippe Guibert
From: David Lamparter <equi...@opensourcerouting.org>

The test consists in sending a message from a req(uest) to a rep(ly).
The rep will dump the received message and send back an ACK to say it
has well received the message.

To perform the zeromq test on your system, please do the following.
make check
once done, manually run
./tests/test_zmq_event
you will fall on a cli prompt.
perform the following command lines
test# configure
test(config)# log stdout
test(config)# end
test# zmq open rep ipc:///tmp/zeromqtest2
zmq socket 0x1f55ac0
test# zmq open req ipc:///tmp/zeromqtest2
zmq socket 0x1f56940
test# zmq send line

If operation is successfull, a similar message like below should appear:
2016/11/02 08:47:40 NONE: msg: 5(0x7ffddc8eb168) line
2016/11/02 08:47:40 NONE: more data: (0)0
2016/11/02 08:47:40 NONE: REP socket, sending reply
2016/11/02 08:47:40 NONE: msg: 4(0x7ffddc8eb168) ACK
2016/11/02 08:47:40 NONE: more data: (0)0

Signed-off-by: David Lamparter <equi...@opensourcerouting.org>
Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 tests/.gitignore   |   1 +
 tests/Makefile.am  |   8 ++-
 tests/test-zmq-event.c | 181 +
 3 files changed, 189 insertions(+), 1 deletion(-)
 create mode 100644 tests/test-zmq-event.c

diff --git a/tests/.gitignore b/tests/.gitignore
index 3002b27149e1..535375b2bb81 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -38,4 +38,5 @@ teststream
 testnexthopiter
 testcommands
 test-commands-defun.c
+test_zmq_event
 site.exp
diff --git a/tests/Makefile.am b/tests/Makefile.am
index c1194e9090c7..cb907b1b704e 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -16,7 +16,7 @@ EXTRA_DIST = \
testcli.refout
 
 AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib 
-I$(top_srcdir)/lib/c-capnproto
-DEFS = @DEFS@ $(LOCAL_OPTS) -DSYSCONFDIR=\"$(sysconfdir)/\"
+DEFS = @DEFS@ $(LOCAL_OPTS) -DSYSCONFDIR=\"$(sysconfdir)/\" @ZEROMQ_CFLAGS@
 
 if BGPD
 TESTS_BGPD = aspathtest testbgpcap ecommtest testbgpmpattr testbgpmpath
@@ -31,6 +31,10 @@ check_PROGRAMS = testsig testsegv testbuffer testmemory 
heavy heavywq heavythrea
testcli \
$(TESTS_BGPD)
 
+if HAVE_ZEROMQ
+check_PROGRAMS += test_zmq_event
+endif
+
 ../vtysh/vtysh_cmd.c:
$(MAKE) -C ../vtysh vtysh_cmd.c
 
@@ -66,6 +70,7 @@ testnexthopiter_SOURCES = test-nexthop-iter.c prng.c
 testcommands_SOURCES = test-commands-defun.c test-commands.c prng.c
 test_timer_correctness_SOURCES = test-timer-correctness.c prng.c
 test_timer_performance_SOURCES = test-timer-performance.c prng.c
+test_zmq_event_SOURCES = test-zmq-event.c common-cli.c
 
 testcli_LDADD = ../lib/libzebra.la @LIBCAP@
 testsig_LDADD = ../lib/libzebra.la @LIBCAP@
@@ -88,3 +93,4 @@ testnexthopiter_LDADD = ../lib/libzebra.la @LIBCAP@
 testcommands_LDADD = ../lib/libzebra.la @LIBCAP@
 test_timer_correctness_LDADD = ../lib/libzebra.la @LIBCAP@
 test_timer_performance_LDADD = ../lib/libzebra.la @LIBCAP@
+test_zmq_event_LDADD = ../lib/libzebra.la @LIBCAP@ $(ZEROMQ_LIBS)
diff --git a/tests/test-zmq-event.c b/tests/test-zmq-event.c
new file mode 100644
index ..9ebee874cae9
--- /dev/null
+++ b/tests/test-zmq-event.c
@@ -0,0 +1,181 @@
+/*
+ * Test program to verify that scheduled timers are executed in the
+ * correct order.
+ *
+ * Copyright (C) 2013 by Open Source Routing.
+ * Copyright (C) 2013 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2015 by David Lamparter, for NetDEF, Inc.
+ *
+ * This file is part of Quagga
+ *
+ * Quagga 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, or (at your option) any
+ * later version.
+ *
+ * Quagga 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 Quagga; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include 
+#include 
+
+#include 
+
+#include "qzmq.h"
+#include "thread.h"
+#include "memory.h"
+#include "pqueue.h"
+#include "prng.h"
+#include "log.h"
+#include "command.h"
+#include "common-cli.h"
+
+static int dummy_req = 0, dummy_rep = 1;
+
+static void callback (void *arg, void *zmqsock, zmq_msg_t *msg)
+{
+  int64_t more = 0;
+  size_t more_size;
+  int ret;
+
+  do
+{
+  void *data = zmq_msg_data (msg);
+  size_t size = zmq_msg_size (msg);
+
+  zlog_info ("msg: %zu(%p) %s", size, data, (const char *)data);
+
+  m

[quagga-dev 16423] [PATCH 01/23] configure: add with-zeromq and with-ccapnproto configuration parameter

2016-12-02 Thread Philippe Guibert
Those config parameters permit usage of zeromq library and capnproto
library. Those two config parameters are necessary in order to use
capnproto configuration interface that will be needed by BGP.

Signed-off-by: David Lamparter <equi...@opensourcerouting.org>
Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 configure.ac | 37 -
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index ce1bb7ea713d..6a48c5c544e1 100755
--- a/configure.ac
+++ b/configure.ac
@@ -7,7 +7,7 @@
 ##
 AC_PREREQ(2.60)
 
-AC_INIT(Quagga, 1.1.0, [https://bugzilla.quagga.net])
+AC_INIT(Quagga, 1.1.0-dev, [https://bugzilla.quagga.net])
 CONFIG_ARGS="$*"
 AC_SUBST(CONFIG_ARGS)
 AC_CONFIG_SRCDIR(lib/zebra.h)
@@ -1497,6 +1497,41 @@ AC_CHECK_HEADER([malloc.h],
   )
  ], [], QUAGGA_INCLUDES)
 
+dnl --
+dnl ZeroMQ
+dnl --
+if test "$with_zeromq" != "no"; then
+   AC_SEARCH_LIBS([zmq_msg_init], [zmq], [
+   AC_DEFINE(HAVE_ZEROMQ, 1, [Enable ZeroMQ support])
+   AC_DEFINE(ZEROMQ_CFLAGS, $(ZEROMQ_CFLAGS), [cflags for zeromq])
+   AC_DEFINE(ZEROMQ_LIBS, $(ZEROMQ_LIBS), [ldflags for zeromq])
+   ZEROMQ=true
+   AC_SUBST(ZEROMQ_CFLAGS)
+   AC_SUBST(ZEROMQ_LIBS)
+   ], [
+   AC_MSG_ERROR([configuration specifies --with-zeromq but libzmq was not 
found])
+   ])
+fi
+
+dnl --
+dnl capnproto
+dnl --
+if test "$with_ccapnproto" != "no"; then
+  AC_SEARCH_LIBS([capn_init_malloc], [capn_c], [
+AC_DEFINE(HAVE_CCAPNPROTO, 1, [Enable c-capnproto support])
+AC_DEFINE(CAPN_C_CFLAGS, $(CAPN_C_CFLAGS), [cflags for c-capnproto])
+AC_DEFINE(CAPN_C_LIBS, $(CAPN_C_LIBS), [ldflags for c-capnproto])
+CCAPNPROTO=true
+AC_SUBST(CAPN_C_CFLAGS)
+AC_SUBST(CAPN_C_LIBS)
+  ], [
+   AC_MSG_ERROR([ccapnproto needed but libcapn_c was not found])
+  ])
+fi
+
+AM_CONDITIONAL([HAVE_ZEROMQ], test "x$ZEROMQ" = "xtrue")
+AM_CONDITIONAL([HAVE_CCAPNPROTO], test "x$CCAPNPROTO" = "xtrue")
+
 dnl --
 dnl configure date
 dnl --
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16422] [PATCH 00/23] Quagga CapnProto API

2016-12-02 Thread Philippe Guibert
Hi all,

This set of patches contains adaptations to BGP daemon, to bring a new API of 
management, based on capnproto protocol.

The API implementation relies on capnproto protocol for data serialisation, 
since it is able to receive and send simple and complex data structures. The 
emission relies on on  an other protocol called zeroMQ, which is a fast data 
exchange mecanism, that is very efficient. The pairing of both technologies 
offers BGP, but also the whole QUAGGA framework, a fast and easy mecanism for 
management, without having to rely on vty.
Note that capnproto owns its own code generator. Based on a scheme file, it is 
able to generate code so that the application can be hidden of the internal 
complexity of capnproto generated code. As example, it is possible to carry in 
messages some structures like prefixes or ip addresses. As of today, 
unfortunately, there is not yet any publicly available tool that generates c 
code, based on the proposed scheme files available in that patch series ( 
qzc.capnp can with standard c-capnproto compiler, but not bgp.capnp). So 
currently, the code has been hardset, and the scheme file is maintained along 
with the generated source code. More information about capnproto and zeromq on 
respective web sites : http://capnproto.org and http://zeromq.org.
The API implementation does not limit to capnproto/zeromq protocol, but can 
host a wide variety of other RPC protocols. Contributions will be welcomed.

The BGP API implemented currently offers capabilities for configuring the main 
data structures that can be found on BGP: BGP start, BGP instances, BGP peers. 
Basically, with a capnproto interface, one can create, configure, delete the 
whole BGP. This API implementation relies on the BGP VRF extension used in 
conjonction with VPNv4 configuration. By this sentence, the intention is to use 
that API to dynamically provision in BGP networking information about 
MPLS/VXLAN tunnels. As such, it is also possible to configure VRF import 
processing. In addition to configuration, BGP API offers a notification entry 
so that the remote manager can receive notifications from BGP, when an event 
occured. That can be a peer that is being shutdown, or the notification that a 
new entry has been received. BGP API finally permits doing exploitation, since 
an algorithm has been put in place so as to iterate on the list of entries 
contained in VRF RIB tables.

Note also that a build dependency has been added on zeromq and c-capnproto. You 
have to force configuration in order to enable the usage of capnproto with the 
following: --with-ccapnproto --with-zeromq. While zeromq is usually available 
in many distributions ( however a recent version is needed - tested on zeromq 
4.1 - ), it is not the case for ccapnproto. This library is officially 
maintained : https://github.com/opensourcerouting/c-capnproto.

Note also that, to apply that patch, it is necessary to have also those series 
of patches too:
https://lists.quagga.net/pipermail/quagga-dev/2016-December/016504.html
https://lists.quagga.net/pipermail/quagga-dev/2016-October/016266.html
https://lists.quagga.net/pipermail/quagga-dev/2016-October/016349.html
https://lists.quagga.net/pipermail/quagga-dev/2016-October/016375.html
https://lists.quagga.net/pipermail/quagga-dev/2016-October/016382.html

Currently, In order to manage quagga framework by using capnproto, it is needed 
to have an other capnproto implementation able to communicate with the various 
quagga daemons, and using the same capnproto scheme files.

Cheers,

Philippe


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16426] [PATCH 05/23] tests: update makefile to link with zmq files

2016-12-02 Thread Philippe Guibert
The introduction of ZMQ library has led to automatic linking
with all other daemons and test programs. This modification
is taking into account the link with test programs.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 tests/Makefile.am | 42 +-
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/tests/Makefile.am b/tests/Makefile.am
index cb907b1b704e..65df0479a58e 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -72,25 +72,25 @@ test_timer_correctness_SOURCES = test-timer-correctness.c 
prng.c
 test_timer_performance_SOURCES = test-timer-performance.c prng.c
 test_zmq_event_SOURCES = test-zmq-event.c common-cli.c
 
-testcli_LDADD = ../lib/libzebra.la @LIBCAP@
-testsig_LDADD = ../lib/libzebra.la @LIBCAP@
-testsegv_LDADD = ../lib/libzebra.la @LIBCAP@
-testbuffer_LDADD = ../lib/libzebra.la @LIBCAP@
-testmemory_LDADD = ../lib/libzebra.la @LIBCAP@
-testprivs_LDADD = ../lib/libzebra.la @LIBCAP@
-teststream_LDADD = ../lib/libzebra.la @LIBCAP@
-heavy_LDADD = ../lib/libzebra.la @LIBCAP@ -lm
-heavywq_LDADD = ../lib/libzebra.la @LIBCAP@ -lm
-heavythread_LDADD = ../lib/libzebra.la @LIBCAP@ -lm
-aspathtest_LDADD = ../bgpd/libbgp.a ../lib/libzebra.la @LIBCAP@ -lm
-testbgpcap_LDADD = ../bgpd/libbgp.a ../lib/libzebra.la @LIBCAP@ -lm
-ecommtest_LDADD = ../bgpd/libbgp.a ../lib/libzebra.la @LIBCAP@ -lm
-testbgpmpattr_LDADD = ../bgpd/libbgp.a ../lib/libzebra.la @LIBCAP@ -lm
-testchecksum_LDADD = ../lib/libzebra.la @LIBCAP@ 
-testbgpmpath_LDADD = ../bgpd/libbgp.a ../lib/libzebra.la @LIBCAP@ -lm
-tabletest_LDADD = ../lib/libzebra.la @LIBCAP@ -lm
-testnexthopiter_LDADD = ../lib/libzebra.la @LIBCAP@
-testcommands_LDADD = ../lib/libzebra.la @LIBCAP@
-test_timer_correctness_LDADD = ../lib/libzebra.la @LIBCAP@
-test_timer_performance_LDADD = ../lib/libzebra.la @LIBCAP@
+testcli_LDADD = ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@
+testsig_LDADD = ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@
+testsegv_LDADD = ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@
+testbuffer_LDADD = ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@
+testmemory_LDADD = ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@
+testprivs_LDADD = ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@
+teststream_LDADD = ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@
+heavy_LDADD = ../lib/libzebra.la @LIBCAP@ -lm @ZEROMQ_LIBS@
+heavywq_LDADD = ../lib/libzebra.la @LIBCAP@ -lm @ZEROMQ_LIBS@
+heavythread_LDADD = ../lib/libzebra.la @LIBCAP@ -lm @ZEROMQ_LIBS@
+aspathtest_LDADD = ../bgpd/libbgp.a ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@ 
-lm
+testbgpcap_LDADD = ../bgpd/libbgp.a ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@ 
-lm
+ecommtest_LDADD = ../bgpd/libbgp.a ../lib/libzebra.la @LIBCAP@ -lm 
@ZEROMQ_LIBS@ 
+testbgpmpattr_LDADD = ../bgpd/libbgp.a ../lib/libzebra.la @LIBCAP@ 
@ZEROMQ_LIBS@ -lm
+testchecksum_LDADD = ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@ 
+testbgpmpath_LDADD = ../bgpd/libbgp.a ../lib/libzebra.la @LIBCAP@ 
@ZEROMQ_LIBS@ -lm
+tabletest_LDADD = ../lib/libzebra.la @LIBCAP@ -lm @ZEROMQ_LIBS@
+testnexthopiter_LDADD = ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@
+testcommands_LDADD = ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@
+test_timer_correctness_LDADD = ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@
+test_timer_performance_LDADD = ../lib/libzebra.la @LIBCAP@ @ZEROMQ_LIBS@
 test_zmq_event_LDADD = ../lib/libzebra.la @LIBCAP@ $(ZEROMQ_LIBS)
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16429] [PATCH 09/23] bgpd: add capnproto information on doc file related to implementation

2016-12-02 Thread Philippe Guibert
Some information is appended to bgp implementation to explain about
newly added files related to capnproto.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/IMPLEMENTATION.txt | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/bgpd/IMPLEMENTATION.txt b/bgpd/IMPLEMENTATION.txt
index fff360ab9693..b1826108f12e 100644
--- a/bgpd/IMPLEMENTATION.txt
+++ b/bgpd/IMPLEMENTATION.txt
@@ -135,6 +135,9 @@ bgpd.h
   struct bgp_filter: distribute, prefix, aslist, route_maps
   struct peer: neighbor structure (very rich/complex)
   struct bgp_nlri: reference to wire format
+  struct bgp_vrf
+  struct bgp_event_shut, struct bgp_event_vrf
+  struct tbliter_v4, bgp_api_route : shared structures to handle route entries 
with capnprotox
   #define of protocol constants
 attribute type codes
   fsm states/events
@@ -145,6 +148,21 @@ bgpd.c
   configuration
   initialization/termination
 
+bgp_zmq.c
+  handle emission of notifications via capnproto interface
+
+bgp.capnp
+  capnproto schema language file for bgp API.
+  Currently not used to generate c files
+
+bgp.bcapnp.[ch]
+  Handler routines to read/write capnproto structures.
+  Handler routines to set bgp structures.
+
+bgp.ndef.[hi,i]
+  Quagga BGP zeromessagequeues to handle actions on capnproto structures.
+  The actions can be set/get/delete
+
 * DATA STRUCTURE SIZES
 
 Question: How much memory does quagga's bgpd use as a function of
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16428] [PATCH 08/23] lib: qzc debug log are conditioned with a debug variable

2016-12-02 Thread Philippe Guibert
This variable can be set by compilation, if there is a need to monitor
qzc exchanges.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 lib/qzc.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/lib/qzc.c b/lib/qzc.c
index 358b7e419eef..7425743f8cea 100644
--- a/lib/qzc.c
+++ b/lib/qzc.c
@@ -31,6 +31,8 @@
 
 #include "qzc.capnp.h"
 
+static int qzc_debug = 0;
+
 static struct qzc_wkn *wkn_first = NULL;
 
 void qzc_wkn_reg(struct qzc_wkn *wkn)
@@ -296,7 +298,8 @@ static void qzc_callback (void *arg, void *zmqsock, 
zmq_msg_t *msg)
   capn_free();
   capn_free();
 
-  zlog_info ("QZC request type %d, response type %d, %zd bytes, error=%d", 
req.which, rep.which, rs, rep.error);
+  if(qzc_debug)
+zlog_debug ("QZC request type %d, response type %d, %zd bytes, error=%d", 
req.which, rep.which, rs, rep.error);
   zmq_send (zmqsock, buf, rs, 0);
 
   do
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16427] [PATCH 04/23] *: force the linker to not check for unresolved symbols at link

2016-12-02 Thread Philippe Guibert
This commit bypasses the link check in case a shared library is to be
used in conjunction with one of the quagga daemons. This is the case of
zero ma library that may or not be available on some systems. Adding
-Wl,-unresolved-symbols=ignore-in-shared-libs to the linker flags
permits compiling without having to install zmq.
It also adapts vtysh scripting, as the capnproto and zeromq may be needed,
the compilation flags is added.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/Makefile.am| 2 +-
 isisd/Makefile.am   | 2 +-
 ospf6d/Makefile.am  | 2 +-
 ospfclient/Makefile.am  | 2 +-
 ospfd/Makefile.am   | 2 +-
 pimd/Makefile.am| 2 +-
 ripd/Makefile.am| 2 +-
 ripngd/Makefile.am  | 2 +-
 vtysh/Makefile.am   | 2 +-
 vtysh/extract.pl.in | 2 +-
 watchquagga/Makefile.am | 2 +-
 zebra/Makefile.am   | 2 +-
 12 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/bgpd/Makefile.am b/bgpd/Makefile.am
index fe1be32edb37..d5be054f9555 100644
--- a/bgpd/Makefile.am
+++ b/bgpd/Makefile.am
@@ -4,7 +4,7 @@ AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib 
-I$(top_builddir)/lib
 DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
 INSTALL_SDATA=@INSTALL@ -m 600
 
-AM_CFLAGS = $(WERROR)
+AM_CFLAGS = $(WERROR) -Wl,-unresolved-symbols=ignore-in-shared-libs
 
 noinst_LIBRARIES = libbgp.a
 sbin_PROGRAMS = bgpd
diff --git a/isisd/Makefile.am b/isisd/Makefile.am
index bfe2e947793b..f254cc140b8a 100644
--- a/isisd/Makefile.am
+++ b/isisd/Makefile.am
@@ -6,7 +6,7 @@ DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
 INSTALL_SDATA=@INSTALL@ -m 600
 LIBS = @LIBS@ 
 
-AM_CFLAGS = $(WERROR)
+AM_CFLAGS = $(WERROR) -Wl,-unresolved-symbols=ignore-in-shared-libs
 
 noinst_LIBRARIES = libisis.a
 sbin_PROGRAMS = isisd 
diff --git a/ospf6d/Makefile.am b/ospf6d/Makefile.am
index 75f22572723f..1ce403cf447a 100644
--- a/ospf6d/Makefile.am
+++ b/ospf6d/Makefile.am
@@ -4,7 +4,7 @@ AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib 
-I$(top_builddir)/lib
 DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
 INSTALL_SDATA=@INSTALL@ -m 600
 
-AM_CFLAGS = $(WERROR)
+AM_CFLAGS = $(WERROR) -Wl,-unresolved-symbols=ignore-in-shared-libs
 
 noinst_LIBRARIES = libospf6.a
 sbin_PROGRAMS = ospf6d
diff --git a/ospfclient/Makefile.am b/ospfclient/Makefile.am
index 1fca431a1017..1b04ed1d80ae 100644
--- a/ospfclient/Makefile.am
+++ b/ospfclient/Makefile.am
@@ -1,7 +1,7 @@
 ## Automake.am for OSPF API client
 
 AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
-AM_CFLAGS = $(WERROR)
+AM_CFLAGS = $(WERROR) -Wl,-unresolved-symbols=ignore-in-shared-libs
 
 lib_LTLIBRARIES = libospfapiclient.la
 libospfapiclient_la_LDFLAGS = -version-info 0:0:0
diff --git a/ospfd/Makefile.am b/ospfd/Makefile.am
index f586d73434da..85d8445c6c02 100644
--- a/ospfd/Makefile.am
+++ b/ospfd/Makefile.am
@@ -1,7 +1,7 @@
 ## Process this file with automake to produce Makefile.in.
 
 AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
-AM_CFLAGS = $(WERROR)
+AM_CFLAGS = $(WERROR) 
 DEFS = @DEFS@ $(LOCAL_OPTS) -DSYSCONFDIR=\"$(sysconfdir)/\"
 INSTALL_SDATA=@INSTALL@ -m 600
 
diff --git a/pimd/Makefile.am b/pimd/Makefile.am
index f57c4c254391..a91bd28e480c 100644
--- a/pimd/Makefile.am
+++ b/pimd/Makefile.am
@@ -39,7 +39,7 @@ DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" $(PIM_DEFS)
 INSTALL_SDATA=@INSTALL@ -m 600
 LIBS = @LIBS@
 
-AM_CFLAGS = $(WERROR)
+AM_CFLAGS = $(WERROR) -Wl,-unresolved-symbols=ignore-in-shared-libs
 
 noinst_LIBRARIES = libpim.a
 sbin_PROGRAMS = pimd 
diff --git a/ripd/Makefile.am b/ripd/Makefile.am
index 571a4993dd5a..5fd09d13a7d0 100644
--- a/ripd/Makefile.am
+++ b/ripd/Makefile.am
@@ -4,7 +4,7 @@ AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib 
-I$(top_builddir)/lib
 DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
 INSTALL_SDATA=@INSTALL@ -m 600
 
-AM_CFLAGS = $(WERROR)
+AM_CFLAGS = $(WERROR) -Wl,-unresolved-symbols=ignore-in-shared-libs
 
 noinst_LIBRARIES = librip.a
 sbin_PROGRAMS = ripd
diff --git a/ripngd/Makefile.am b/ripngd/Makefile.am
index df0f7d377ec2..1ed8879a3bd9 100644
--- a/ripngd/Makefile.am
+++ b/ripngd/Makefile.am
@@ -4,7 +4,7 @@ AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib 
-I$(top_builddir)/lib
 DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
 INSTALL_SDATA=@INSTALL@ -m 600
 
-AM_CFLAGS = $(WERROR)
+AM_CFLAGS = $(WERROR) -Wl,-unresolved-symbols=ignore-in-shared-libs
 
 noinst_LIBRARIES = libripng.a
 sbin_PROGRAMS = ripngd
diff --git a/vtysh/Makefile.am b/vtysh/Makefile.am
index e44cd49f597b..8c2476c75fbd 100644
--- a/vtysh/Makefile.am
+++ b/vtysh/Makefile.am
@@ -5,7 +5,7 @@ DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
 
 LIBS = @LIBS@ @CURSES@ @LIBPAM@
 
-AM_CFLAGS = $(WERROR)
+AM_CFLAGS = $(WERROR) -Wl,-unresolved-symbols=ignore-in-shared-libs
 
 bin_PROGRAMS = vtysh
 
diff --git a/vtysh/extract.pl.in b/vtysh/extra

[quagga-dev 16424] [PATCH 02/23] lib: ZeroMQ read event

2016-12-02 Thread Philippe Guibert
From: David Lamparter <equi...@opensourcerouting.org>

This commit introduces 2 new files, and introduces the compilation flags
for compiling with zeromq and capnproto dependencies.

Signed-off-by: David Lamparter <equi...@opensourcerouting.org>
Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 lib/Makefile.am |   7 ++-
 lib/memtypes.c  |   1 +
 lib/qzmq.c  | 157 
 lib/qzmq.h  |  55 
 4 files changed, 219 insertions(+), 1 deletion(-)
 create mode 100644 lib/qzmq.c
 create mode 100644 lib/qzmq.h

diff --git a/lib/Makefile.am b/lib/Makefile.am
index be8495f140e4..7b6c34dcabb5 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -1,7 +1,7 @@
 ## Process this file with automake to produce Makefile.in.
 
 AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
-AM_CFLAGS = $(WERROR)
+AM_CFLAGS = $(WERROR) @CAPN_C_CFLAGS@ @ZEROMQ_CFLAGS@
 DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
 
 lib_LTLIBRARIES = libzebra.la
@@ -35,6 +35,11 @@ pkginclude_HEADERS = \
 noinst_HEADERS = \
plist_int.h
 
+if HAVE_ZEROMQ
+libzebra_la_SOURCES += qzmq.c
+pkginclude_HEADERS += qzmq.h
+endif
+
 EXTRA_DIST = \
regex.c regex-gnu.h \
queue.h \
diff --git a/lib/memtypes.c b/lib/memtypes.c
index 75f77a8e13fb..bfda5eb7b14e 100644
--- a/lib/memtypes.c
+++ b/lib/memtypes.c
@@ -74,6 +74,7 @@ struct memory_list memory_list_lib[] =
   { MTYPE_VRF_BITMAP,  "VRF bit-map"   },
   { MTYPE_IF_LINK_PARAMS,   "Informational Link Parameters" },
   { MTYPE_LIB_NEXTHOP, "Nexthop"   },
+  { MTYPE_ZEROMQ_CB,   "ZEROMQ_CB" },
   { -1, NULL },
 };
 
diff --git a/lib/qzmq.c b/lib/qzmq.c
new file mode 100644
index ..ffa086d403a0
--- /dev/null
+++ b/lib/qzmq.c
@@ -0,0 +1,157 @@
+/*
+ * libzebra ZeroMQ bindings
+ * Copyright (C) 2015  David Lamparter, for NetDEF, Inc.
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Quagga 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with Quagga; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include 
+#include 
+
+#include "thread.h"
+#include "memory.h"
+#include "qzmq.h"
+#include "log.h"
+
+/* libzmq's context */
+void *qzmq_context = NULL;
+
+void qzmq_init (void)
+{
+  qzmq_context = zmq_ctx_new ();
+  zmq_ctx_set (qzmq_context, ZMQ_IPV6, 1);
+}
+
+void qzmq_finish (void)
+{
+  zmq_ctx_term (qzmq_context);
+  qzmq_context = NULL;
+}
+
+/* read callback integration */
+struct qzmq_cb {
+  struct thread *thread;
+  void *zmqsock;
+  void *arg;
+
+#if 0
+  void (*cb_buf)(void *arg, void *zmqsock, const uint8_t *buf, size_t len);
+#endif
+  void (*cb_msg)(void *arg, void *zmqsock, zmq_msg_t *msg);
+};
+
+
+static int qzmq_read_msg (struct thread *t)
+{
+  struct qzmq_cb *cb = THREAD_ARG (t);
+  zmq_msg_t msg;
+  int ret;
+  cb->thread = NULL;
+
+  while (1)
+{
+  zmq_pollitem_t polli = { .socket = cb->zmqsock, .events = ZMQ_POLLIN };
+  ret = zmq_poll (, 1, 0);
+
+  if (ret < 0)
+goto out_err;
+  if (!(polli.revents & ZMQ_POLLIN))
+break;
+
+  if (zmq_msg_init ())
+goto out_err;
+  ret = zmq_msg_recv (, cb->zmqsock, ZMQ_NOBLOCK);
+  if (ret < 0)
+{
+  if (errno == EAGAIN)
+break;
+
+  zmq_msg_close ();
+  goto out_err;
+}
+  cb->cb_msg (cb->arg, cb->zmqsock, );
+  zmq_msg_close ();
+}
+
+  cb->thread = funcname_thread_add_read (t->master, qzmq_read_msg, cb,
+t->u.fd, t->funcname, t->schedfrom, t->schedfrom_line);
+  return 0;
+
+out_err:
+  zlog_err ("ZeroMQ error: %s(%d)", strerror (errno), errno);
+  return 0;
+}
+
+#if 0
+static int qzmq_read_buf (struct thread *t)
+{
+  return 0;
+}
+
+struct qzmq_cb *funcname_qzmq_thread_read_buf (
+struct thread_master *master,
+void (*func)(void *arg, void *zmqsock, const uint8_t *buf, size_t len),
+void *arg, void *zmqsock, debugargdef)
+{
+  int fd;
+  size_t fd_len = sizeof (fd);
+  struct qzmq_cb *cb;
+
+  if (zmq_getsockopt (zmqsock, ZMQ_FD, , _len))
+return NULL;
+
+  cb = XCALLOC (MTYPE_ZEROMQ_CB, sizeof (struct qzmq_cb));
+  if

[quagga-dev 16419] [PATCH v3 3/5] bgpd: VRF vty configuration, RIB table creation

2016-12-02 Thread Philippe Guibert
This commit introduces the BGP VRF configuration, and BGP VRF RIB
table.
It includes the ability for a BGP to configure its own route
distinguisher ( aka VRF). New vty commands introduced:

(config-router)# vrf rd 

This structure permits configuring import and export route targets,
which is defined by RFC4360.
(config-router)# vrf rd  exports 
(config-router)# vrf rd  imports 

It brings some improvements.
- for a BGP speaker when emitting BGP updates, the exported route
targets will be mapped to BGP extended communities associated with
the BGP update for the defined Route distinguisher.
This commit does not enhance the support for emitting those BGP
extended communities, but provides the mecanism.
- for a BGP speaker when receiving BGP updaets. Its import route
target will be looked up, in order to match NLRI route distinguisher.
Then, if matching, the entry would be exported to a RIB per VRF table.

As mentioned before, the commit also introduces a BGP VRF RIB table per
Route distinguisher configured. This table aims at receiving BGP NLRI
entries, with matching import and export route targets.
This commit does not take into account the fullfill of this table,
but creates it.

Signed-off-by: David Lamparter <equi...@opensourcerouting.org>
Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_route.c | 192 +++--
 bgpd/bgp_route.h |   4 ++
 bgpd/bgp_table.h |   3 +
 bgpd/bgp_vty.c   | 177 +
 bgpd/bgpd.c  | 199 ++-
 bgpd/bgpd.h  |  57 +---
 lib/memtypes.c   |   2 +
 7 files changed, 620 insertions(+), 14 deletions(-)

diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 4cb6c141bcdc..eb0c9e50094f 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -34,6 +34,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, 
Boston, MA
 #include "plist.h"
 #include "thread.h"
 #include "workqueue.h"
+#include "hash.h"
 
 #include "bgpd/bgpd.h"
 #include "bgpd/bgp_table.h"
@@ -61,6 +62,12 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, 
Boston, MA
 extern const char *bgp_origin_str[];
 extern const char *bgp_origin_long_str[];
 
+static void
+bgp_static_withdraw_safi (struct bgp *bgp, struct prefix *p, afi_t afi,
+  safi_t safi, struct prefix_rd *prd, u_char *tag);
+static void
+bgp_static_free (struct bgp_static *bgp_static);
+
 static struct bgp_node *
 bgp_afi_node_get (struct bgp_table *table, afi_t afi, safi_t safi, struct 
prefix *p,
  struct prefix_rd *prd)
@@ -77,7 +84,11 @@ bgp_afi_node_get (struct bgp_table *table, afi_t afi, safi_t 
safi, struct prefix
   prn = bgp_node_get (table, (struct prefix *) prd);
 
   if (prn->info == NULL)
-   prn->info = bgp_table_init (afi, safi);
+{
+  struct bgp_table *newtab = bgp_table_init (afi, safi);
+  newtab->prd = *prd;
+  prn->info = newtab;
+}
   else
bgp_unlock_node (prn);
   table = prn->info;
@@ -1505,12 +1516,86 @@ bgp_process_announce_selected (struct peer *peer, 
struct bgp_info *selected,
 else
  bgp_adj_out_unset (rn, peer, p, afi, safi);
 break;
+  case BGP_TABLE_VRF:
+/* never called */
+assert (0);
 }
 
   bgp_attr_flush ();
   return 0;
 }
 
+void bgp_vrf_clean_tables (struct bgp_vrf *vrf)
+{
+  afi_t afi;
+  for (afi = AFI_IP; afi < AFI_MAX; afi++)
+{
+  struct bgp_info *ri, *ri_next;
+  struct bgp_node *rn;
+
+  for (rn = bgp_table_top (vrf->rib[afi]); rn; rn = bgp_route_next (rn))
+for (ri = rn->info; ri; ri = ri_next)
+  {
+ri_next = ri->next;
+bgp_info_reap (rn, ri);
+  }
+  bgp_table_finish (>rib[afi]);
+
+  for (rn = bgp_table_top (vrf->route[afi]); rn; rn = bgp_route_next (rn))
+if (rn->info)
+  {
+struct bgp_static *bs = rn->info;
+bgp_static_withdraw_safi (vrf->bgp, >p, afi, SAFI_MPLS_VPN,
+>outbound_rd, NULL);
+bgp_static_free (bs);
+rn->info = NULL;
+bgp_unlock_node (rn);
+  }
+  bgp_table_finish (>route[afi]);
+}
+}
+
+void
+bgp_vrf_apply_new_imports (struct bgp_vrf *vrf, afi_t afi)
+{
+  struct bgp_node *rd_rn, *rn;
+  struct bgp_info *sel;
+  struct bgp_table *table;
+  struct ecommunity *ecom;
+  size_t i, j;
+  bool found;
+
+  if (!vrf->rt_import || vrf->rt_import->size == 0)
+return;
+
+  for (rd_rn = bgp_table_top (vrf->bgp->rib[afi][SAFI_MPLS_VPN]); rd_rn;
+  rd_rn = bgp_route_next (rd_rn))
+if (rd_rn->info != NULL)
+  {
+table = rd_rn->info;
+
+for (rn = bgp_table_top (table); rn; rn = bgp

[quagga-dev 16417] [PATCH v3 1/5] lib: declare BGP_VRF_NODE as vty subnode

2016-12-02 Thread Philippe Guibert
This new node is to be put under router bgp subnode.
On top of this, usual exit and end commands are also taking into account
bgp vrf subnode.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 lib/command.c | 3 +++
 lib/command.h | 1 +
 lib/vty.c | 1 +
 3 files changed, 5 insertions(+)

diff --git a/lib/command.c b/lib/command.c
index ab46fc4a6d11..f0ddc622aaf4 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -2627,6 +2627,7 @@ node_parent ( enum node_type node )
 case BGP_IPV4M_NODE:
 case BGP_IPV6_NODE:
 case BGP_IPV6M_NODE:
+case BGP_VRF_NODE:
   ret = BGP_NODE;
   break;
 case KEYCHAIN_KEY_NODE:
@@ -3002,6 +3003,7 @@ DEFUN (config_exit,
 case BGP_ENCAPV6_NODE:
 case BGP_IPV6_NODE:
 case BGP_IPV6M_NODE:
+case BGP_VRF_NODE:
   vty->node = BGP_NODE;
   break;
 case KEYCHAIN_KEY_NODE:
@@ -3050,6 +3052,7 @@ DEFUN (config_end,
 case BGP_IPV4M_NODE:
 case BGP_IPV6_NODE:
 case BGP_IPV6M_NODE:
+case BGP_VRF_NODE:
 case RMAP_NODE:
 case OSPF_NODE:
 case OSPF6_NODE:
diff --git a/lib/command.h b/lib/command.h
index cc5dd0891630..f2a80b0c5122 100644
--- a/lib/command.h
+++ b/lib/command.h
@@ -90,6 +90,7 @@ enum node_type
   BGP_IPV6M_NODE,  /* BGP IPv6 multicast address family. */
   BGP_ENCAP_NODE,  /* BGP ENCAP SAFI */
   BGP_ENCAPV6_NODE,/* BGP ENCAP SAFI */
+  BGP_VRF_NODE,/* BGP VRF node. */
   OSPF_NODE,   /* OSPF protocol mode */
   OSPF6_NODE,  /* OSPF protocol for IPv6 mode */
   ISIS_NODE,   /* ISIS protocol mode */
diff --git a/lib/vty.c b/lib/vty.c
index 7ba277fd8a88..64fe7cacfe40 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -746,6 +746,7 @@ vty_end_config (struct vty *vty)
 case BGP_IPV4M_NODE:
 case BGP_IPV6_NODE:
 case BGP_IPV6M_NODE:
+case BGP_VRF_NODE:
 case RMAP_NODE:
 case OSPF_NODE:
 case OSPF6_NODE:
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16418] [PATCH v3 2/5] vtysh: vty adaptations for new bgp vrf node

2016-12-02 Thread Philippe Guibert
This commit includes changes related to introduce new subnode under bgp
called vrf <>. This node permits configuring route distinguishers and
route target under the subnode, by using vtysh command tool.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 vtysh/extract.pl.in  |  2 ++
 vtysh/vtysh.c| 42 ++
 vtysh/vtysh_config.c |  6 +-
 3 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/vtysh/extract.pl.in b/vtysh/extract.pl.in
index 924cffe2cb86..54c6f969b690 100755
--- a/vtysh/extract.pl.in
+++ b/vtysh/extract.pl.in
@@ -53,7 +53,9 @@ $ignore{'"address-family ipv4 vrf NAME"'} = "ignore";
 $ignore{'"address-family encap"'} = "ignore";
 $ignore{'"address-family encapv4"'} = "ignore";
 $ignore{'"address-family encapv6"'} = "ignore";
+$ignore{'"vrf WORD"'} = "ignore";
 $ignore{'"exit-address-family"'} = "ignore";
+$ignore{'"exit-bgp-vrf"'} = "ignore";
 $ignore{'"key chain WORD"'} = "ignore";
 $ignore{'"key <0-2147483647>"'} = "ignore";
 $ignore{'"route-map WORD (deny|permit) <1-65535>"'} = "ignore";
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index 2e2203da61d7..e73eb867f3cf 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -302,6 +302,10 @@ vtysh_execute_func (const char *line, int pager)
{
  vtysh_execute("exit-address-family");
}
+  else if ((saved_node == BGP_VRF_NODE) && (tried == 1))
+   {
+ vtysh_execute("exit-bgp-vrf");
+   }
   else if ((saved_node == KEYCHAIN_KEY_NODE) && (tried == 1))
{
  vtysh_execute("exit");
@@ -741,6 +745,13 @@ static struct cmd_node bgp_ipv6m_node =
   "%s(config-router-af)# "
 };
 
+/* VRF node. */
+static struct cmd_node bgp_vrf_node =
+{
+  BGP_VRF_NODE,
+  "%s(bgp-vrf)# "
+};
+
 static struct cmd_node ospf_node =
 {
   OSPF_NODE,
@@ -972,6 +983,18 @@ DEFUNSH (VTYSH_BGPD,
   return CMD_SUCCESS;
 }
 
+DEFUNSH (VTYSH_BGPD,
+ bgp_vrf,
+ bgp_vrf_cmd,
+   "vrf WORD",
+   "BGP VRF\n"
+   "VRF Name\n"
+)
+{
+  vty->node = BGP_VRF_NODE;
+  return CMD_SUCCESS;
+}
+
 DEFUNSH (VTYSH_RIPD,
 key_chain,
 key_chain_cmd,
@@ -1145,6 +1168,7 @@ vtysh_exit (struct vty *vty)
 case BGP_IPV4M_NODE:
 case BGP_IPV6_NODE:
 case BGP_IPV6M_NODE:
+case BGP_VRF_NODE:
   vty->node = BGP_NODE;
   break;
 case KEYCHAIN_KEY_NODE:
@@ -1191,6 +1215,17 @@ DEFUNSH (VTYSH_BGPD,
   return CMD_SUCCESS;
 }
 
+DEFUNSH (VTYSH_BGPD,
+ exit_bgp_vrf,
+ exit_bgp_vrf_cmd,
+ "exit-bgp-vrf",
+ "Exit from BGP vrf configuration mode\n")
+{
+  if (vty->node == BGP_VRF_NODE)
+vty->node = BGP_NODE;
+  return CMD_SUCCESS;
+}
+
 DEFUNSH (VTYSH_ZEBRA,
 vtysh_exit_zebra,
 vtysh_exit_zebra_cmd,
@@ -2428,6 +2463,7 @@ vtysh_init_vty (void)
   install_node (_ipv6_node, NULL);
   install_node (_ipv6m_node, NULL);
 /* #endif */
+  install_node (_vrf_node, NULL);
   install_node (_node, NULL);
 /* #ifdef HAVE_IPV6 */
   install_node (_node, NULL);
@@ -2456,6 +2492,7 @@ vtysh_init_vty (void)
   vtysh_install_default (BGP_IPV4M_NODE);
   vtysh_install_default (BGP_IPV6_NODE);
   vtysh_install_default (BGP_IPV6M_NODE);
+  vtysh_install_default (BGP_VRF_NODE);
   vtysh_install_default (OSPF_NODE);
   vtysh_install_default (RIPNG_NODE);
   vtysh_install_default (OSPF6_NODE);
@@ -2502,6 +2539,8 @@ vtysh_init_vty (void)
   install_element (BGP_IPV6_NODE, _quit_bgpd_cmd);
   install_element (BGP_IPV6M_NODE, _exit_bgpd_cmd);
   install_element (BGP_IPV6M_NODE, _quit_bgpd_cmd);
+  install_element (BGP_VRF_NODE, _exit_bgpd_cmd);
+  install_element (BGP_VRF_NODE, _quit_bgpd_cmd);
   install_element (ISIS_NODE, _exit_isisd_cmd);
   install_element (ISIS_NODE, _quit_isisd_cmd);
   install_element (KEYCHAIN_NODE, _exit_ripd_cmd);
@@ -2530,6 +2569,7 @@ vtysh_init_vty (void)
   install_element (BGP_ENCAPV6_NODE, _end_all_cmd);
   install_element (BGP_IPV6_NODE, _end_all_cmd);
   install_element (BGP_IPV6M_NODE, _end_all_cmd);
+  install_element (BGP_VRF_NODE, _end_all_cmd);
   install_element (ISIS_NODE, _end_all_cmd);
   install_element (KEYCHAIN_NODE, _end_all_cmd);
   install_element (KEYCHAIN_KEY_NODE, _end_all_cmd);
@@ -2567,6 +2607,7 @@ vtysh_init_vty (void)
   install_element (BGP_NODE, _family_ipv6_unicast_cmd);
   install_element (BGP_NODE, _family_ipv6_multicast_cmd);
 #endif
+  install_element (BGP_NODE, _vrf_cmd);
   install_element (BGP_VPNV4_NODE, _address_family_cmd);
   install_element (BGP_VPNV6_NODE, _address_family_cmd);
   install_element (BGP_ENCAP_NODE, _address_family_cmd);
@@ -2575,6 +2616,7 @@ vtysh_init_vty (void)
   ins

[quagga-dev 16420] [PATCH v3 4/5] bgpd: vty adaptations regarding rd and rt configuration

2016-12-02 Thread Philippe Guibert
A new subnode under router bgp command has been created: vrf <>.
This enhancement permits creating a VRF instance specific to VRF.
Then it permits setting specific configuration to vrf entity.
This is the case for route distinguisher, but also route target.
vrf 
 rd 
 no rd 
 rt import 
 rt export 
 rt both 
 no rt import <>
 no rt export <>
 no rt both <>
 exit
no vrf 

Currently, this is necessary to manually set route distinguisher.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_route.c |   3 +
 bgpd/bgp_vty.c   | 252 ++-
 bgpd/bgpd.c  | 126 ++--
 bgpd/bgpd.h  |  14 +++-
 4 files changed, 291 insertions(+), 104 deletions(-)

diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index eb0c9e50094f..c4236fab481b 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -1528,6 +1528,9 @@ bgp_process_announce_selected (struct peer *peer, struct 
bgp_info *selected,
 void bgp_vrf_clean_tables (struct bgp_vrf *vrf)
 {
   afi_t afi;
+
+  if (vrf->rib == NULL || vrf->route == NULL)
+return;
   for (afi = AFI_IP; afi < AFI_MAX; afi++)
 {
   struct bgp_info *ri, *ri_next;
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 63a7b5bfdcf6..4080438b06a0 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -9893,57 +9893,86 @@ bgp_config_write_redistribute (struct vty *vty, struct 
bgp *bgp, afi_t afi,
 
 DEFUN (bgp_vrf,
bgp_vrf_cmd,
-   "vrf rd WORD",
-   "BGP VPN VRF\n"
-   "Route Distinguisher\n"
-   "Route Distinguisher\n"
+   "vrf WORD",
+   "BGP VRF\n"
+   "VRF Name\n"
 )
 {
   struct bgp *bgp = vty->index;
   struct bgp_vrf *vrf;
-  struct prefix_rd prd;
+  if ( (vrf = bgp_vrf_lookup_per_name (bgp, argv[0], 1)) == NULL)
+return CMD_ERR_NO_MATCH;
+  vty->index_sub = vrf;
+  vty->node = BGP_VRF_NODE;
 
-  if (! str2prefix_rd (argv[0], ))
-{
-  vty_out (vty, "%% Invalid RD '%s'%s", argv[0], VTY_NEWLINE);
-  return CMD_WARNING;
-}
+  return CMD_SUCCESS;
+}
+DEFUN (no_bgp_vrf,
+   no_bgp_vrf_cmd,
+   "no vrf WORD",
+   NO_STR
+   "BGP VRF\n"
+   "VRF Name\n"
+)
+{
+  struct bgp *bgp = vty->index;
+  struct bgp_vrf *vrf;
 
-  vrf = bgp_vrf_lookup (bgp, );
-  if (vrf)
+  vrf = bgp_vrf_lookup_per_name (bgp, argv[0], 0);
+  if (! vrf)
 {
-  vty_out (vty, "%% VRF with RD '%s' already exists%s", argv[0], 
VTY_NEWLINE);
+  vty_out (vty, "%% No VRF with name '%s'%s", argv[0], VTY_NEWLINE);
   return CMD_WARNING;
 }
+  bgp_vrf_delete (vrf);
+  return CMD_SUCCESS;
+}
 
-  bgp_vrf_create (bgp, );
+DEFUN (exit_bgp_vrf,
+   exit_bgp_vrf_cmd,
+   "exit-bgp-vrf",
+   "Exit from BGP vrf configuration mode\n")
+{
+  if (vty->node == BGP_VRF_NODE)
+vty->node = BGP_NODE;
   return CMD_SUCCESS;
 }
 
-DEFUN (bgp_vrf_exports,
-   bgp_vrf_exports_cmd,
-   "vrf rd WORD exports .LINE",
-   "BGP VPN VRF\n"
+DEFUN (bgp_vrf_rd,
+   bgp_vrf_rd_cmd,
+   "rd WORD",
"Route Distinguisher\n"
-   "Route Distinguisher\n"
-   "Export RT values\n"
-   "Export RT values\n"
+   "Route Distinguisher Name\n"
 )
 {
   struct bgp *bgp = vty->index;
-  struct bgp_vrf *vrf;
+  struct bgp_vrf *vrf = vty->index_sub;
   struct prefix_rd prd;
-  struct ecommunity *ecom = NULL;
-  int fail = 0, i;
-  char *rts = NULL, *rts_ptr;
 
   if (! str2prefix_rd (argv[0], ))
 {
   vty_out (vty, "%% Invalid RD '%s'%s", argv[0], VTY_NEWLINE);
-  fail++;
+  return CMD_WARNING;
 }
+  bgp_vrf_update_rd (bgp, vrf, );
+  return CMD_SUCCESS;
+}
+
+DEFUN (bgp_vrf_rt_export,
+   bgp_vrf_rt_export_cmd,
+   "rt export .LINE",
+   "Route Target\n"
+   "Export RT values\n"
+   "Export RT values\n"
+)
+{
+  struct bgp_vrf *vrf = vty->index_sub;
+  struct ecommunity *ecom = NULL;
+  int fail = 0, i;
+  char *rts = NULL, *rts_ptr;
+
   /* forge export list */
-  i = 1;
+  i = 0;
   rts = XCALLOC(MTYPE_TMP,2048);
   rts_ptr = rts;
   while(i < argc)
@@ -9963,44 +9992,27 @@ DEFUN (bgp_vrf_exports,
   if (fail)
 return CMD_WARNING;
 
-  vrf = bgp_vrf_lookup (bgp, );
-  if (! vrf)
-{
-  ecommunity_free ();
-  vty_out (vty, "%% No VRF with RD '%s'%s", argv[0], VTY_NEWLINE);
-  return CMD_WARNING;
-}
-
   ecom = ecommunity_intern (ecom);
   bgp_vrf_rt_export_set (vrf, ecom);
   ecommunity_unintern ();
   return CMD_SUCCESS;
 }
 
-DEFUN (bgp_vrf_imports,
-   bgp_vrf_imports_cmd,
-   "vrf rd WORD imports .LINE",
-   "BGP VPN VRF\n"
-   "Route Distinguisher\n"
-  

[quagga-dev 16421] [PATCH v3 5/5] bgpd: vpnv4 af exports extended communities

2016-12-02 Thread Philippe Guibert
If the user preconfigures a vrf with import and export rules, before
creating a new network on vpnv4 address, then BGP update emitted will
contain the exported rts mentioned by the vrf export rule.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_route.c | 11 +++
 bgpd/bgp_route.h |  2 ++
 2 files changed, 13 insertions(+)

diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index c4236fab481b..1d7533c49aad 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -3964,6 +3964,11 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix 
*p,
   attr.med = bgp_static->igpmetric;
   attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
 
+  if (bgp_static->ecomm)
+{
+  bgp_attr_extra_get ()->ecommunity = ecommunity_dup 
(bgp_static->ecomm);
+  attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
+}
   /* Apply route-map. */
   if (bgp_static->rmap.name)
 {
@@ -4264,6 +4269,7 @@ bgp_static_set_safi (safi_t safi, struct vty *vty, const 
char *ip_str,
   struct bgp_node *rn;
   struct bgp_table *table;
   struct bgp_static *bgp_static;
+  struct bgp_vrf *vrf;
   u_char tag[3];
 
   bgp = vty->index;
@@ -4314,6 +4320,11 @@ bgp_static_set_safi (safi_t safi, struct vty *vty, const 
char *ip_str,
   bgp_static->igpmetric = 0;
   bgp_static->igpnexthop.s_addr = 0;
   memcpy(bgp_static->tag, tag, 3);
+  vrf = bgp_vrf_lookup(bgp, );
+  if (vrf)
+{
+  bgp_static->ecomm = vrf->rt_export;
+}
   bgp_static->prd = prd;
 
   if (rmap_str)
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index 25a42e87bd94..642839d6d59f 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -137,6 +137,8 @@ struct bgp_static
   /* Route Distinguisher */
   struct prefix_rd prd;
 
+  struct ecommunity*ecomm;
+
   /* MPLS label.  */
   u_char tag[3];
 };
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16416] [PATCH v3 0/5] BGP VRF Route Distinguisher configuration

2016-12-02 Thread Philippe Guibert
This series of patches introduces the ability for a BGP router,
to configure a route distinguisher and associate import and
export route targets.
This permits for a BGP update to be sent with BGP extended communities
associated to the exported route targets of the RD.
This permits for a BGP update to be received, and to be handled according
to the imported route targets of the RD contained in BGP extended communities.
The V3 version of this patch is rebased with latest from master branch, in
addition to take into account the specificities related to configuring route 
distinguisher and route target within a VRF. For that a vrf subnode under bgp
router node will be created.

Cheers,



___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16390] [PATCH 56/57] bgpd: adj-in-rib table per VRF

2016-10-28 Thread Philippe Guibert
When enabling adj-rib-in for global RIB table, it automatically
stores adj-rib-entries for VRF RIB tables. This commit introduces
a new vty command to dump the adj-rib-in entries per vrf:

show ip bgp vrf  neighbor  received-routes

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_route.c | 197 ++-
 bgpd/bgp_route.h |   3 +
 bgpd/bgpd.c  |  20 +-
 3 files changed, 216 insertions(+), 4 deletions(-)

diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index c6c5ddf26e19..789e219a1178 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -4142,6 +4142,25 @@ bgp_clear_adj_in (struct peer *peer, afi_t afi, safi_t 
safi)
 }
 
 void
+bgp_vrf_clear_adj_in (struct peer *peer, struct bgp_vrf *vrf, afi_t afi)
+{
+  struct bgp_table *table;
+  struct bgp_node *rn;
+  struct bgp_adj_in *ain;
+
+  table = vrf->rib[afi];
+
+  for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
+for (ain = rn->adj_in; ain ; ain = ain->next)
+  if (ain->peer == peer)
+   {
+  bgp_adj_in_remove (rn, ain);
+  bgp_unlock_node (rn);
+  break;
+   }
+}
+
+void
 bgp_clear_stale_route (struct peer *peer, afi_t afi, safi_t safi)
 {
   struct bgp_node *rn;
@@ -8034,6 +8053,121 @@ bgp_show_table (struct vty *vty, struct bgp_table 
*table, struct in_addr *router
   return CMD_SUCCESS;
 }
 
+#define BGP_SHOW_SCODE_HEADER "Status codes: s suppressed, d damped, "\
+ "h history, * valid, > best, = multipath,%s"\
+   "  i internal, r RIB-failure, S Stale, R Removed%s"
+#define BGP_SHOW_OCODE_HEADER "Origin codes: i - IGP, e - EGP, ? - 
incomplete%s%s"
+#define BGP_SHOW_HEADER "   Network  Next HopMetric LocPrf 
Weight Path%s"
+int
+show_adj_route_vrf (struct vty *vty, struct peer *peer, struct bgp_vrf *vrf, 
int in)
+{
+  struct bgp_table *table;
+  struct bgp *bgp;
+  char buf[RD_ADDRSTRLEN];
+  char *ptr;
+  struct bgp_node *rn;
+  unsigned long output_count;
+  safi_t safi;
+  int rd_header = 1;
+  int header1 = 1;
+  int header2 = 1;
+  struct bgp_adj_in *ain;
+  struct bgp_adj_out *adj;
+
+  /* This is first entry point, so reset total line. */
+  output_count = 0;
+
+  bgp = bgp_get_default ();
+  if (bgp == NULL)
+{
+  vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+  return CMD_WARNING;
+}
+  table = vrf->rib[AFI_IP];
+
+  safi = table->type == BGP_TABLE_VRF ? SAFI_INTERNAL_EVPN : SAFI_UNICAST;
+  /* Start processing of routes. */
+  for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
+if (rn->info != NULL)
+  {
+if (in)
+  {
+for (ain = rn->adj_in; ain; ain = ain->next)
+  if (ain->peer == peer)
+{
+  if (header1)
+{
+  vty_out (vty, "BGP table version is 0, local router ID 
is %s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE);
+  vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, 
VTY_NEWLINE);
+  vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, 
VTY_NEWLINE);
+  header1 = 0;
+}
+  if (header2)
+{
+  vty_out (vty, BGP_SHOW_HEADER, VTY_NEWLINE);
+  header2 = 0;
+}
+  if (rd_header)
+{
+  ptr = prefix_rd2str (&(vrf->outbound_rd), buf, 
RD_ADDRSTRLEN);
+  vty_out (vty, "Route Distinguisher: ");
+  if(ptr)
+vty_out (vty, "%s", buf);
+  else
+vty_out (vty, "");
+  vty_out (vty, "%s", VTY_NEWLINE);
+  rd_header = 0;
+}
+  if (ain->attr)
+{
+  route_vty_out_tmp (vty, >p, ain->attr, safi);
+  output_count++;
+}
+}
+  }
+else
+  {
+for (adj = rn->adj_out; adj; adj = adj->next)
+  if (adj->peer == peer)
+{
+  if (header1)
+{
+  vty_out (vty, "BGP table version is 0, local router ID 
is %s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE);
+  vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, 
VTY_NEWLINE);
+  vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, 
VTY_NEWLINE);
+  header1 = 0;
+}
+  if (rd_header)
+{
+  ptr = prefix_rd2str ((struct

[quagga-dev 16386] [PATCH 54/57] bgpd: VRF table exportation filters labels according to layer type

2016-10-28 Thread Philippe Guibert
From: Julien Courtat <julien.cour...@6wind.com>

>From draft-ietf-bess-evpn-inter-subnet-forwarding-01#section-5.1.1,
Label-1 and Label-2 is not exported systematically. Actually, Label-1
refers to MAC-VRF and is exported to LAYER_2 VRF. Label-2 will act the
same with IP-VRF and is exported to LAYER_3 VRF.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_route.c | 78 +++-
 1 file changed, 55 insertions(+), 23 deletions(-)

diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 6673749c7dde..9a8619dda841 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -1737,6 +1737,58 @@ bgp_vrf_update (struct bgp_vrf *vrf, afi_t afi, struct 
bgp_node *rn,
 }
 }
 
+/* when exporting bgp_info structure to out VRF RIB,
+ * some information are copied :
+ * other info is filtered : labels
+ */
+static void bgp_vrf_copy_bgp_info(struct bgp_vrf *vrf, struct bgp_node *rn,
+  safi_t safi, struct bgp_info *select, struct 
bgp_info *target)
+{
+  if(!target->extra)
+target->extra = bgp_info_extra_new();
+  if(select->attr)
+{
+  if(target->attr)
+bgp_attr_unintern(>attr);
+  target->attr = bgp_attr_intern (select->attr);
+  if(select->attr->extra)
+{
+  if(select->attr->extra->ecommunity)
+{
+  if(!target->attr->extra)
+bgp_attr_extra_get(target->attr);
+  /* MAC-VRF does not export RouterMac
+   * however, because ecom is shared among all bgp infos
+   * this option is not stripped;
+   * This should be the place to strip the ecomm
+   */
+  overlay_index_dup(target->attr, 
&(select->attr->extra->evpn_overlay));
+}
+}
+}
+  /* copy label information */
+  if(select->extra)
+{
+  uint32_t l3label = 0, l2label = 0;
+
+  bgp_vrf_update_labels (vrf, rn, select, , );
+  if(safi == SAFI_INTERNAL_EVPN)
+{
+  target->extra->nlabels = 1;
+  if(vrf->ltype == BGP_LAYER_TYPE_3)
+target->extra->labels[0] = (l3label << 4) | 1;
+  else
+target->extra->labels[0] = (l2label << 4) | 1;
+}
+  else
+{
+  target->extra->nlabels = select->extra->nlabels;
+  memcpy (target->extra->labels, select->extra->labels,
+  select->extra->nlabels * sizeof(select->extra->labels[0]));
+}
+}
+}
+
 /* updates selected bgp_info structure to bgp vrf rib table
  * most of the cases, processing consists in adding or removing entries in RIB 
tables
  * on some cases, there is an update request. then it is necessary to have 
both old and new ri
@@ -1798,7 +1850,6 @@ bgp_vrf_process_one (struct bgp_vrf *vrf, afi_t afi, 
safi_t safi, struct bgp_nod
   /* check entry not already present */
   for (iter = vrf_rn->info; iter; iter = iter->next)
 {
-  /* coming from same peer */
   if(iter->peer->remote_id.s_addr == select->peer->remote_id.s_addr)
 {
   bgp_info_delete(vrf_rn, iter);
@@ -1842,24 +1893,7 @@ bgp_vrf_process_one (struct bgp_vrf *vrf, afi_t afi, 
safi_t safi, struct bgp_nod
 {
   /* update labels labels */
   /* update attr part / containing next hop */
-  if(select->extra)
-{
-  iter->extra->nlabels = select->extra->nlabels;
-  memcpy (iter->extra->labels, select->extra->labels,
-  select->extra->nlabels * 
sizeof(select->extra->labels[0]));
-}
-  if(select->attr)
-{
-  if(iter->attr)
-bgp_attr_unintern(>attr);
-  iter->attr = bgp_attr_intern (select->attr);
-  if(select->attr->extra && 
select->attr->extra->ecommunity)
-{
-  bgp_attr_extra_get(iter->attr);
-  iter->attr->extra->ecommunity = 
-ecommunity_dup(select->attr->extra->ecommunity);
-}
-}
+  bgp_vrf_copy_bgp_info(vrf, rn, safi, select, iter);
   /* if changes, update, and permit resending
  information */
   bgp_info_set_flag (rn, iter, BGP_INFO_ATTR_CHANGED);
@@ -1870,16 +1904,14 @@ bgp_vrf_process_one (struct bgp_vrf *vrf, afi_t afi, 
safi_t safi, struct bgp_nod
   /* silently add new entry to rn */
   if(!iter)
 {
-  iter 

[quagga-dev 16387] [PATCH 53/57] bgpd: evpn import processing

2016-10-28 Thread Philippe Guibert
Enhancement of EVPN bgp information exportation to VRF RIBs.
Currently, only IPv4 unicast VRF RIBs are filled in, according from
EVPN information coming from Prefix route advertisements.
Labels are processed differently according to the VRF layer type.
In addition to this, routermac will not be displayed if VRF layer type
is layer2
In addition to this, a log event is displayed to give information on
MAC/IP and RT5 information.

Signed-off-by: Julien Courtat 
---
 bgpd/bgp_route.c | 110 ++-
 bgpd/bgp_route.h |   1 +
 2 files changed, 109 insertions(+), 2 deletions(-)

diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 191e889634d7..6673749c7dde 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -85,6 +85,17 @@ static struct bgp_info *
 info_make (int type, int sub_type, struct peer *peer, struct attr *attr,
   struct bgp_node *rn);
 
+static void
+overlay_index_dup(struct attr *attr, struct overlay_index *src)
+{
+  if(!src)
+return;
+  if(!attr->extra)
+bgp_attr_extra_get(attr);
+  memcpy(&(attr->extra->evpn_overlay), src, sizeof(struct overlay_index));
+  return;
+}
+
 static struct bgp_node *
 bgp_afi_node_get (struct bgp_table *table, afi_t afi, safi_t safi, struct 
prefix *p,
  struct prefix_rd *prd)
@@ -1583,6 +1594,43 @@ void bgp_vrf_clean_tables (struct bgp_vrf *vrf)
 }
 }
 
+/* from draft-ietf-bess-evpn-inter-subnet-forwarding-01,
+ * for EVPN, MAC/IP advertisement should be filtered
+ * Label-1 = MPLS Label or VNID corresponding to MAC-VRF
+ * Label-2 = MPLS Label or VNID corresponding to IP-VRF
+ */
+static void bgp_vrf_update_labels (struct bgp_vrf *vrf, struct bgp_node *rn,
+   struct bgp_info *selected, uint32_t 
*l3label, uint32_t *l2label)
+{
+  if (selected->extra->nlabels)
+{
+  if (rn->p.family == AF_L2VPN)
+{
+  if(vrf->ltype == BGP_LAYER_TYPE_3)
+{
+  /* either select belongs to vrf table => only 1 label 
+   * or it is part of global rib => 2 labels 
+   */
+  if(rn->table && bgp_node_table (rn) && bgp_node_table (rn)->type 
== BGP_TABLE_VRF)
+*l3label = selected->extra->labels[0] >> 4;
+  else
+*l3label = selected->extra->labels[1] >> 4;
+  *l2label = 0;
+}
+  else
+{
+  *l2label = selected->extra->labels[0] >> 4;
+  *l3label = 0;
+}
+}
+  else
+{
+  *l3label = selected->extra->labels[0] >> 4;
+  *l2label = 0;
+}
+}
+}
+
 /* messages sent to ODL to signify that an entry
  * has been selected, or unselected
  */
@@ -1590,6 +1638,9 @@ void
 bgp_vrf_update (struct bgp_vrf *vrf, afi_t afi, struct bgp_node *rn,
 struct bgp_info *selected, uint8_t announce)
 {
+  char *esi = NULL, *mac_router = NULL;
+  uint32_t ethtag = 0, l3label = 0, l2label = 0;
+
   if(!vrf || (rn && bgp_node_table (rn)->type != BGP_TABLE_VRF))
 return;
   if (announce == true)
@@ -1611,7 +1662,7 @@ bgp_vrf_update (struct bgp_vrf *vrf, afi_t afi, struct 
bgp_node *rn,
 }
   if (BGP_DEBUG (events, EVENTS))
 {
-  char vrf_rd_str[RD_ADDRSTRLEN], rd_str[RD_ADDRSTRLEN], 
pfx_str[INET6_BUFSIZ];
+  char vrf_rd_str[RD_ADDRSTRLEN], rd_str[RD_ADDRSTRLEN], 
pfx_str[PREFIX_STRLEN];
   char label_str[BUFSIZ] = "", nh_str[BUFSIZ] = "";
 
   prefix_rd2str(>outbound_rd, vrf_rd_str, sizeof(vrf_rd_str));
@@ -1634,6 +1685,55 @@ bgp_vrf_update (struct bgp_vrf *vrf, afi_t afi, struct 
bgp_node *rn,
   else
 zlog_debug ("vrf[%s] %s: prefix withdrawn nh %s label %s",
 vrf_rd_str, pfx_str, nh_str, label_str);
+
+  if(CHECK_FLAG (selected->flags, BGP_INFO_ORIGIN_EVPN))
+{
+  esi = esi2str(&(selected->attr->extra->evpn_overlay.eth_s_id));
+  if (rn->p.family == AF_L2VPN)
+{
+  ethtag = rn->p.u.prefix_macip.eth_tag_id;
+}
+  else
+ethtag = selected->attr->extra->eth_t_id;
+
+  if(selected->extra)
+bgp_vrf_update_labels (vrf, rn, selected, , );
+  
+  if(selected->attr && selected->attr->extra && 
selected->attr->extra->ecommunity)
+{
+  /* only router mac is filled in for VRF RIB layer 3 */
+  if(vrf->ltype == BGP_LAYER_TYPE_3)
+{
+  /* import routermac */
+  struct ecommunity_val *routermac = ecommunity_lookup 
(selected->attr->extra->ecommunity, 
+
ECOMMUNITY_ENCODE_EVPN,
+
ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
+  if(routermac)
+mac_router = ecom_mac2str(routermac->val);
+  else 

[quagga-dev 16389] [PATCH 57/57] bgpd: VRF adj rib in update

2016-10-28 Thread Philippe Guibert
This commit appends or withdraw entries in ADJ-RIB-IN entries of VRF
RIB tables.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_route.c | 45 +
 1 file changed, 33 insertions(+), 12 deletions(-)

diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 789e219a1178..674dbced9a6c 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -1800,10 +1800,13 @@ bgp_vrf_process_one (struct bgp_vrf *vrf, afi_t afi, 
safi_t safi, struct bgp_nod
   struct bgp_node *vrf_rn;
   struct bgp_info *iter = NULL;
   struct prefix_rd *prd;
-  char pfx_str[INET6_BUFSIZ];
+  char pfx_str[PREFIX_STRLEN];
+  afi_t afi_int;
 
   if(afi == AFI_INTERNAL_L2VPN)
-afi = AFI_IP; /* XXX should be set to appropriate AFI : AF_INET or 
AF_INET6 */
+afi_int = AFI_IP; /* XXX should be set to appropriate AFI : AF_INET or 
AF_INET6 */
+  else
+afi_int = afi;
   prd = _node_table (rn)->prd;
   if (BGP_DEBUG (events, EVENTS))
 {
@@ -1815,9 +1818,9 @@ bgp_vrf_process_one (struct bgp_vrf *vrf, afi_t afi, 
safi_t safi, struct bgp_nod
   prefix2str(>p, pfx_str, sizeof(pfx_str));
   if(select && select->attr && select->attr->extra)
 {
-  if (afi == AFI_IP)
+  if (afi_int == AFI_IP)
 strcpy (nh_str, inet_ntoa 
(select->attr->extra->mp_nexthop_global_in));
-  else if (afi == AFI_IP6)
+  else if (afi_int == AFI_IP6)
 inet_ntop (AF_INET6, >attr->extra->mp_nexthop_global, 
nh_str, BUFSIZ);
 }
   else if(select)
@@ -1835,11 +1838,11 @@ bgp_vrf_process_one (struct bgp_vrf *vrf, afi_t afi, 
safi_t safi, struct bgp_nod
   /* check if global RIB plans for destroying initial entry
* if yes, then suppress it
*/
-  if(!vrf || !vrf->rib[afi] || !select)
+  if(!vrf || !vrf->rib[afi_int] || !select)
 {
   return;
 }
-  vrf_rn = bgp_node_get (vrf->rib[afi], >p);
+  vrf_rn = bgp_node_get (vrf->rib[afi_int], >p);
   if(!vrf_rn)
 {
   return;
@@ -1852,6 +1855,15 @@ bgp_vrf_process_one (struct bgp_vrf *vrf, afi_t afi, 
safi_t safi, struct bgp_nod
 {
   if(iter->peer->remote_id.s_addr == select->peer->remote_id.s_addr)
 {
+  if (CHECK_FLAG (iter->peer->af_flags[afi][safi], 
PEER_FLAG_SOFT_RECONFIG)
+  && iter->peer != iter->peer->bgp->peer_self)
+if (!bgp_adj_in_unset (vrf_rn, iter->peer))
+  {
+prefix2str(_rn->p, pfx_str, sizeof(pfx_str));
+if (BGP_DEBUG (update, UPDATE_IN))
+  zlog (iter->peer->log, LOG_DEBUG, "%s withdrawing route 
%s "
+"not in adj-in", iter->peer->host, pfx_str);
+  }
   bgp_info_delete(vrf_rn, iter);
   prefix2str(_rn->p, pfx_str, sizeof(pfx_str));
   if (BGP_DEBUG (events, EVENTS))
@@ -1859,9 +1871,9 @@ bgp_vrf_process_one (struct bgp_vrf *vrf, afi_t afi, 
safi_t safi, struct bgp_nod
   char nh_str[BUFSIZ] = "";
   if(iter->attr && iter->attr->extra)
 {
-  if (afi == AFI_IP)
+  if (afi_int == AFI_IP)
 strcpy (nh_str, inet_ntoa 
(iter->attr->extra->mp_nexthop_global_in));
-  else if (afi == AFI_IP6)
+  else if (afi_int == AFI_IP6)
 inet_ntop (AF_INET6, 
>attr->extra->mp_nexthop_global, nh_str, BUFSIZ);
 }
   else
@@ -1872,7 +1884,7 @@ bgp_vrf_process_one (struct bgp_vrf *vrf, afi_t afi, 
safi_t safi, struct bgp_nod
   zlog_debug ("%s: processing entry (for removal) from %s [ nh 
%s]", 
   pfx_str, iter->peer->host, nh_str);
 }
-  bgp_process (iter->peer->bgp, vrf_rn, afi, SAFI_UNICAST);
+  bgp_process (iter->peer->bgp, vrf_rn, afi_int, SAFI_UNICAST);
   break;
 }
 }
@@ -1927,9 +1939,9 @@ bgp_vrf_process_one (struct bgp_vrf *vrf, afi_t afi, 
safi_t safi, struct bgp_nod
   prefix2str(>p, pfx_str, sizeof(pfx_str));
   if(iter->attr && iter->attr->extra)
 {
-  if (afi == AFI_IP)
+  if (afi_int == AFI_IP)
 strcpy (nh_str, inet_ntoa 
(iter->attr->extra->mp_nexthop_global_in));
-  else if (afi == AFI_IP6)
+  else if (afi_int == AFI_IP6)
 inet_ntop (AF_INET6, >attr->extra->mp_nexthop_global, 
nh_str, BUFSIZ);
 }
   else
@@ -1942,7 +1954,16 @@ bgp_vrf_process_one (struct bgp_vrf *vrf, afi_t afi, 
safi_t safi, st

[quagga-dev 16388] [PATCH 55/57] bgpd: show ip bgp vrf enhancements.

2016-10-28 Thread Philippe Guibert
add vty command : show ipv6 bgp vrf [route]
This command permits to dump IPv6 entries in VRF RIB filled by export RT 
facility.
Type 1 route distinguishers are now supported by command show ip bgp vrf


Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_route.c | 41 -
 1 file changed, 36 insertions(+), 5 deletions(-)

diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 9a8619dda841..c6c5ddf26e19 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -8069,7 +8069,7 @@ bgp_show_vrf (struct vty *vty, const char *vrf_name, 
afi_t afi,
   vty_out (vty, "%% No default BGP instance%s", VTY_NEWLINE);
   return CMD_WARNING;
 }
-  if (! str2prefix_rd (vrf_name, ))
+  if (! prefix_str2rd (vrf_name, ))
 {
   vty_out (vty, "%% Invalid RD '%s'%s", vrf_name, VTY_NEWLINE);
   return CMD_WARNING;
@@ -8363,11 +8363,25 @@ DEFUN (show_ip_bgp_vrf,
"show ip bgp vrf WORD",
SHOW_STR
IP_STR
-   BGP_STR)
+   BGP_STR
+   "VRF\n"
+   "Route Distinguisher\n")
 {
   return bgp_show_vrf (vty, argv[0], AFI_IP, bgp_show_type_normal, NULL);
 }
 
+DEFUN (show_ipv6_bgp_vrf,
+   show_ipv6_bgp_vrf_cmd,
+   "show ipv6 bgp vrf WORD",
+   SHOW_STR
+   IPV6_STR
+   BGP_STR
+   "VRF\n"
+   "Route Distinguisher\n")
+{
+  return bgp_show_vrf (vty, argv[0], AFI_IP6, bgp_show_type_normal, NULL);
+}
+
 DEFUN (show_ip_bgp_ipv4,
show_ip_bgp_ipv4_cmd,
"show ip bgp ipv4 (unicast|multicast)",
@@ -8438,14 +8452,28 @@ DEFUN (show_bgp_ipv4_safi_route_pathtype,
 
 DEFUN (show_ip_bgp_vrf_route,
show_ip_bgp_vrf_route_cmd,
-   "show ip bgp vrf WORD (ipv4|ipv6) (A.B.C.D|X:X::X:X)",
+   "show ip bgp vrf WORD (A.B.C.D)",
SHOW_STR
IP_STR
BGP_STR
"VRF\n"
-   "Route Distinguisher\n")
+   "Route Distinguisher\n"
+   "IPv4 Address")
+{
+  return bgp_show_vrf_route (vty, argv[0], argv[2], AFI_IP, 0);
+}
+
+DEFUN (show_ipv6_bgp_vrf_route,
+   show_ipv6_bgp_vrf_route_cmd,
+   "show ipv6 bgp vrf WORD X:X::X:X",
+   SHOW_STR
+   IPV6_STR
+   BGP_STR
+   "VRF\n"
+   "Route Distinguisher\n"
+   "IPv6 Address")
 {
-  afi_t afi = (strncmp (argv[1], "ipv6", 4) == 0) ? AFI_IP6 : AFI_IP;
+  afi_t afi = AFI_IP6;
   return bgp_show_vrf_route (vty, argv[0], argv[2], afi, 0);
 }
 
@@ -18238,11 +18266,13 @@ bgp_route_init (void)
   /* old style commands */
   install_element (VIEW_NODE, _ip_bgp_cmd);
   install_element (VIEW_NODE, _ip_bgp_vrf_cmd);
+  install_element (VIEW_NODE, _ipv6_bgp_vrf_cmd);
   install_element (VIEW_NODE, _ip_bgp_ipv4_cmd);
   install_element (VIEW_NODE, _ip_bgp_route_cmd);
   install_element (VIEW_NODE, _ip_bgp_route_pathtype_cmd);
   install_element (VIEW_NODE, _bgp_ipv4_safi_route_pathtype_cmd);
   install_element (VIEW_NODE, _ip_bgp_vrf_route_cmd);
+  install_element (VIEW_NODE, _ipv6_bgp_vrf_route_cmd);
   install_element (VIEW_NODE, _ip_bgp_ipv4_route_cmd);
   install_element (VIEW_NODE, _ip_bgp_vpnv4_all_route_cmd);
   install_element (VIEW_NODE, _bgp_l2vpn_evpn_all_route_cmd);
@@ -18337,6 +18367,7 @@ bgp_route_init (void)
   install_element (RESTRICTED_NODE, _ip_bgp_route_pathtype_cmd);
   install_element (RESTRICTED_NODE, _bgp_ipv4_safi_route_pathtype_cmd);
   install_element (RESTRICTED_NODE, _ip_bgp_vrf_route_cmd);
+  install_element (RESTRICTED_NODE, _ipv6_bgp_vrf_route_cmd);
   install_element (RESTRICTED_NODE, _ip_bgp_ipv4_route_cmd);
   install_element (RESTRICTED_NODE, _ip_bgp_vpnv4_all_route_cmd);
   install_element (RESTRICTED_NODE, _bgp_l2vpn_evpn_all_route_cmd);
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16384] [PATCH 52/57] bgpd: add VRF field layer type

2016-10-28 Thread Philippe Guibert
From: Julien Courtat 

On VRF creation, an additionnal parameter layer type can be provided to
distinguish between layer 2 and layer 3 vrf. layer 2 is used by EVPN
when dealing with MAC/IP route advertisement. layer 3 is used by any
other route L3VPN or EVPN route advertisement.

Signed-off-by: Julien Courtat 
---
 bgpd/bgp_vty.c | 20 ++--
 bgpd/bgpd.c| 13 ++---
 bgpd/bgpd.h| 11 ++-
 3 files changed, 38 insertions(+), 6 deletions(-)

diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index ea00149ba0a1..a0d37d1a9d69 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -9947,15 +9947,17 @@ bgp_config_write_redistribute (struct vty *vty, struct 
bgp *bgp, afi_t afi,
 
 DEFUN (bgp_vrf,
bgp_vrf_cmd,
-   "vrf rd WORD",
+   "vrf rd WORD [LAYER]",
"BGP VPN VRF\n"
"Route Distinguisher\n"
"Route Distinguisher\n"
+   "Layer type: layer_2 or layer_3\n"
 )
 {
   struct bgp *bgp = vty->index;
   struct bgp_vrf *vrf;
   struct prefix_rd prd;
+  bgp_layer_type_t ltype = BGP_LAYER_TYPE_3;
 
   if (! str2prefix_rd (argv[0], ))
 {
@@ -9963,6 +9965,20 @@ DEFUN (bgp_vrf,
   return CMD_WARNING;
 }
 
+  if (argc == 2)
+{
+  if (!strncmp(argv[1], "layer_2", 7))
+ltype = BGP_LAYER_TYPE_2;
+  else
+if (!strncmp(argv[1], "layer_3", 7))
+  ltype = BGP_LAYER_TYPE_3;
+else
+  {
+vty_out (vty, "%% VRF with layer type '%s' not supported%s", 
argv[1], VTY_NEWLINE);
+return CMD_WARNING;
+  }
+}
+
   vrf = bgp_vrf_lookup (bgp, );
   if (vrf)
 {
@@ -9970,7 +9986,7 @@ DEFUN (bgp_vrf,
   return CMD_WARNING;
 }
 
-  bgp_vrf_create (bgp, );
+  bgp_vrf_create (bgp, ltype, );
   return CMD_SUCCESS;
 }
 
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 2833b6e8751f..82d077c03876 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -2123,7 +2123,7 @@ bgp_vrf_lookup (struct bgp *bgp, struct prefix_rd 
*outbound_rd)
 }
 
 struct bgp_vrf *
-bgp_vrf_create (struct bgp *bgp, struct prefix_rd *outbound_rd)
+bgp_vrf_create (struct bgp *bgp, bgp_layer_type_t ltype, struct prefix_rd 
*outbound_rd)
 {
   struct bgp_vrf *vrf;
   afi_t afi;
@@ -2132,8 +2132,13 @@ bgp_vrf_create (struct bgp *bgp, struct prefix_rd 
*outbound_rd)
 return NULL;
 
   vrf->bgp = bgp;
+  vrf->ltype = ltype;
   vrf->outbound_rd = *outbound_rd;
-  vrf->max_mpath = bgp->maxpaths[AFI_IP][SAFI_MPLS_VPN].maxpaths_ibgp;
+
+  if (ltype == BGP_LAYER_TYPE_2)
+vrf->max_mpath = 
bgp->maxpaths[AFI_INTERNAL_L2VPN][SAFI_INTERNAL_EVPN].maxpaths_ibgp;
+  else
+vrf->max_mpath = bgp->maxpaths[AFI_IP][SAFI_MPLS_VPN].maxpaths_ibgp;
 
   for (afi = AFI_IP; afi < AFI_MAX; afi++)
 {
@@ -5818,7 +5823,9 @@ bgp_config_write (struct vty *vty)
 for (ALL_LIST_ELEMENTS_RO(bgp->vrfs, node, vrf))
   {
 str_p = prefix_rd2str(&(vrf->outbound_rd), rdstr, RD_ADDRSTRLEN);
-vty_out(vty, " vrf rd %s%s", str_p == NULL?"":str_p, 
VTY_NEWLINE);
+vty_out(vty, " vrf rd %s%s%s", str_p == NULL?"":str_p,
+  vrf->ltype == BGP_LAYER_TYPE_2 ? " 
layer_2": "",
+  VTY_NEWLINE);
 if(vrf->rt_import)
   {
 str2_p = ecommunity_ecom2str (vrf->rt_import,
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 505c1389a087..15a4aaaf16d8 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -208,10 +208,19 @@ struct bgp_rt_sub
   struct list *vrfs;
 };
 
+typedef enum
+{
+  BGP_LAYER_TYPE_2 = 1,
+  BGP_LAYER_TYPE_3 = 2,
+} bgp_layer_type_t;
+
 struct bgp_vrf
 {
   struct bgp *bgp;
 
+  /* TYPE2 for EVPN MAC/IP routes, TYPE3 for others */
+  bgp_layer_type_t ltype;
+
   /* RD used for route advertisements */
   struct prefix_rd outbound_rd;
 
@@ -1040,7 +1049,7 @@ extern int peer_ttl_security_hops_set (struct peer *, 
int);
 extern int peer_ttl_security_hops_unset (struct peer *);
 
 extern void bgp_scan_finish (void);
-extern struct bgp_vrf *bgp_vrf_create (struct bgp *bgp, struct prefix_rd 
*outbound_rd);
+extern struct bgp_vrf *bgp_vrf_create (struct bgp *bgp, bgp_layer_type_t 
ltype, struct prefix_rd *outbound_rd);
 extern struct bgp_vrf *bgp_vrf_lookup (struct bgp *bgp, struct prefix_rd 
*outbound_rd);
 extern struct bgp_vrf *bgp_vrf_lookup_per_rn (struct bgp *bgp, int afi, struct 
bgp_node *vrf_rn);
 extern void bgp_vrf_delete (struct bgp_vrf *vrf);
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16377] [PATCH 44/57] bgpd: MAC/IP advertisements have next hop attribute

2016-10-28 Thread Philippe Guibert
When sending an EVPN MAC/IP attribute, the nexthop attribute is also
appended.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_attr.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 2b57d687800c..eb13e1762b1d 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -2860,13 +2860,15 @@ bgp_packet_attribute (struct bgp *bgp, struct peer 
*peer,
   send_as4_path = 1; /* we'll do this later, at the correct place */
   
   /* Nexthop attribute. */
-  if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP) && afi == AFI_IP &&
-safi ==  SAFI_UNICAST)   /* only write NH attr for unicast safi */
+  if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP) && 
+  ((afi == AFI_IP && safi ==  SAFI_UNICAST) ||  /* only write NH attr for 
unicast safi */
+   (safi ==  SAFI_MPLS_VPN) ||  /* only write NH attr for unicast safi */
+   (afi == AFI_INTERNAL_L2VPN && safi == SAFI_INTERNAL_EVPN)))
 {
   stream_putc (s, BGP_ATTR_FLAG_TRANS);
   stream_putc (s, BGP_ATTR_NEXT_HOP);
   stream_putc (s, 4);
-  if (safi == SAFI_MPLS_VPN)
+  if ( (safi == SAFI_MPLS_VPN)  || ( safi == SAFI_INTERNAL_EVPN))
{
  if (attr->nexthop.s_addr == 0)
stream_put_ipv4 (s, peer->nexthop.v4.s_addr);
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16382] [PATCH 51/57] bgpd: avoid sending duplicated nlri attributed in bgp

2016-10-28 Thread Philippe Guibert
When configuring MPLS or EVPN entries, the NLRI is duplicated.
Which is not wished.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_attr.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index eb13e1762b1d..d9c54e938467 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -2784,7 +2784,9 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
   /* Remember current pointer. */
   cp = stream_get_endp (s);
 
-  if (p && !(afi == AFI_IP && safi == SAFI_UNICAST))
+  if (p && !(afi == AFI_IP && safi == SAFI_UNICAST) &&
+  !(afi == AFI_IP && safi == SAFI_MPLS_VPN) &&
+  !(afi == AFI_INTERNAL_L2VPN && safi == SAFI_INTERNAL_EVPN))
 {
   size_t mpattrlen_pos = 0;
   mpattrlen_pos = bgp_packet_mpattr_start(s, afi, safi, attr);
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16365] [PATCH 31/57] bgpd: evpn vty show commands are moved under show bgp l2vpn

2016-10-28 Thread Philippe Guibert
All current vty show commands related to evpn are moved from
show bgp evpn node to show bgp l2vpn evpn node. Only two
commands are kept: show bgp evpn rd <> [overlay] has been duplicated.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_evpn.c | 105 +---
 1 file changed, 62 insertions(+), 43 deletions(-)

diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index 61335eaaa1ca..b8945daeffc2 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -394,12 +394,12 @@ bgp_show_ethernet_vpn (struct vty *vty, struct prefix_rd 
*prd, enum bgp_show_typ
   return CMD_SUCCESS;
 }
 
-DEFUN (show_bgp_evpn_all,
-   show_bgp_evpn_all_cmd,
-   "show bgp evpn all",
+DEFUN (show_bgp_l2vpn_evpn_all,
+   show_bgp_l2vpn_evpn_all_cmd,
+   "show bgp l2vpn evpn all",
SHOW_STR
-   IP_STR
BGP_STR
+   "Display L2VPN AFI information\n"
"Display EVPN NLRI specific information\n"
"Display information about all EVPN NLRIs\n")
 {
@@ -411,7 +411,6 @@ DEFUN (show_bgp_evpn_rd,
show_bgp_evpn_rd_cmd,
"show bgp evpn rd ASN:nn_or_IP-address:nn",
SHOW_STR
-   IP_STR
BGP_STR
"Display EVPN NLRI specific information\n"
"Display information for a route distinguisher\n"
@@ -430,12 +429,21 @@ DEFUN (show_bgp_evpn_rd,
 SHOW_DISPLAY_STANDARD);
 }
 
-DEFUN (show_bgp_evpn_all_tags,
-   show_bgp_evpn_all_tags_cmd,
-   "show bgp evpn all tags",
+ALIAS (show_bgp_evpn_rd,
+   show_bgp_l2vpn_evpn_rd_cmd,
+   "show bgp l2vpn evpn rd ASN:nn_or_IP-address:nn",
SHOW_STR
-   IP_STR
BGP_STR
+   "Display L2VPN AFI information\n"
+   "Display information for a route distinguisher\n"
+   "VPN Route Distinguisher\n")
+
+DEFUN (show_bgp_l2vpn_evpn_all_tags,
+   show_bgp_l2vpn_evpn_all_tags_cmd,
+   "show bgp l2vpn evpn all tags",
+   SHOW_STR
+   BGP_STR
+   "Display L2VPN AFI information\n"
"Display EVPN NLRI specific information\n"
"Display information about all EVPN NLRIs\n"
"Display BGP tags for prefixes\n")
@@ -444,12 +452,12 @@ DEFUN (show_bgp_evpn_all_tags,
 SHOW_DISPLAY_TAGS);
 }
 
-DEFUN (show_bgp_evpn_rd_tags,
-   show_bgp_evpn_rd_tags_cmd,
-   "show bgp evpn rd ASN:nn_or_IP-address:nn tags",
+DEFUN (show_bgp_l2vpn_evpn_rd_tags,
+   show_bgp_l2vpn_evpn_rd_tags_cmd,
+   "show bgp l2vpn evpn rd ASN:nn_or_IP-address:nn tags",
SHOW_STR
-   IP_STR
BGP_STR
+   "Display L2VPN AFI information\n"
"Display EVPN NLRI specific information\n"
"Display information for a route distinguisher\n"
"VPN Route Distinguisher\n"
@@ -468,12 +476,12 @@ DEFUN (show_bgp_evpn_rd_tags,
 SHOW_DISPLAY_TAGS);
 }
 
-DEFUN (show_bgp_evpn_all_overlay,
-   show_bgp_evpn_all_overlay_cmd,
-   "show bgp evpn all overlay",
+DEFUN (show_bgp_l2vpn_evpn_all_overlay,
+   show_bgp_l2vpn_evpn_all_overlay_cmd,
+   "show bgp l2vpn evpn all overlay",
SHOW_STR
-   IP_STR
BGP_STR
+   "Display L2VPN AFI information\n"
"Display EVPN NLRI specific information\n"
"Display information about all EVPN NLRIs\n"
"Display BGP tags for prefixes\n")
@@ -486,12 +494,11 @@ DEFUN (show_bgp_evpn_rd_overlay,
show_bgp_evpn_rd_overlay_cmd,
"show bgp evpn rd ASN:nn_or_IP-address:nn overlay",
SHOW_STR
-   IP_STR
BGP_STR
"Display EVPN NLRI specific information\n"
"Display information for a route distinguisher\n"
"VPN Route Distinguisher\n"
-   "Display BGP tags for prefixes\n")
+   "Display BGP Overlay information\n")
 {
   int ret;
   struct prefix_rd prd;
@@ -506,12 +513,22 @@ DEFUN (show_bgp_evpn_rd_overlay,
 SHOW_DISPLAY_OVERLAY);
 }
 
-DEFUN (show_bgp_evpn_all_neighbor_routes,
-   show_bgp_evpn_all_neighbor_routes_cmd,
-   "show bgp evpn all neighbors A.B.C.D routes",
+ALIAS (show_bgp_evpn_rd_overlay,
+   show_bgp_l2vpn_evpn_rd_overlay_cmd,
+   "show bgp l2vpn evpn rd ASN:nn_or_IP-address:nn overlay",
+   SHOW_STR
+   BGP_STR
+   "Display L2VPN AFI information\n"
+   "Display EVPN NLRI specific information\n"
+   "Display information for a route distinguisher\n"
+   "Display BGP Overlay information\n")
+
+DEFUN (show_bgp_l2vpn_evpn_all_neighbor_routes,
+ 

[quagga-dev 16380] [PATCH 46/57] bgpd: mpath debug displays l2vpn prefix

2016-10-28 Thread Philippe Guibert
The introduction of L2VPN prefix in EVPN makes that the inner IP prefix
must be retrieved to display correct information.

Signed-off-by: Julien Courtat 
---
 bgpd/bgp_mpath.c | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c
index b47cdad95909..f9ecefd08d85 100644
--- a/bgpd/bgp_mpath.c
+++ b/bgpd/bgp_mpath.c
@@ -441,10 +441,22 @@ bgp_info_mpath_sprint_nh(afi_t afi, struct bgp_node *rn, 
struct bgp_info *mpath,
 {
   if(mpath->attr && mpath->attr->extra)
 {
+  if ( afi == AFI_INTERNAL_L2VPN)
+{
+  struct prefix *p = >p;
+  if (p->family == AF_INET)
+strcpy (nh_str, inet_ntoa 
(mpath->attr->extra->mp_nexthop_global_in));
+  else if (p->family == AF_INET6)
+inet_ntop (AF_INET6, >attr->extra->mp_nexthop_global, 
nh_str, BUFSIZ);
+  else if (rn->p.family == AF_L2VPN)
+strcpy (nh_str, inet_ntoa 
(mpath->attr->extra->mp_nexthop_global_in));
+}
   if (afi == AFI_IP)
 strcpy (nh_str, inet_ntoa (mpath->attr->extra->mp_nexthop_global_in));
   else if (afi == AFI_IP6)
 inet_ntop (AF_INET6, >attr->extra->mp_nexthop_global, nh_str, 
BUFSIZ);
+  else if (rn->p.family == AF_L2VPN)
+strcpy (nh_str, inet_ntoa (mpath->attr->extra->mp_nexthop_global_in));
 }
   else if(mpath->attr)
 {
@@ -474,7 +486,7 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info 
*new_best,
   struct listnode *mp_node, *mp_next_node;
   struct bgp_info *cur_mpath, *new_mpath, *next_mpath, *prev_mpath;
   int mpath_changed, debug;
-  char pfx_buf[INET6_ADDRSTRLEN], nh_buf[2][INET6_ADDRSTRLEN];
+  char pfx_buf[PREFIX_STRLEN], nh_buf[2][INET_ADDRSTRLEN];
   struct bgp_maxpaths_cfg *mpath_cfg = NULL;
   struct prefix_rd *prd = NULL;
   struct bgp_vrf *vrf = NULL;
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16373] [PATCH 40/57] lib: afi_ether structure packing fix

2016-10-28 Thread Philippe Guibert
'packed' keyword had no effect on packing the afi_ethernet structure.
The attribute keyword has been eppended in order to take into account
the packed feature.

Signed-off-by: Julien Courtat 
---
 lib/prefix.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/prefix.h b/lib/prefix.h
index 2cf0b20b00ca..0075cce43de3 100644
--- a/lib/prefix.h
+++ b/lib/prefix.h
@@ -44,7 +44,7 @@
  */
 struct ethaddr {
 u_char octet[ETHER_ADDR_LEN];
-} __packed;
+} __attribute__ ((packed));
 
 
 /*
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16368] [PATCH 37/57] bgpd: introduction of vxlan tunnel attribute

2016-10-28 Thread Philippe Guibert
As per draft-ietf-idr-tunnel-encaps-02, section 3.2.1, BGP Encap
attribute supports vxlan tunnel type. A new tunnel attribute has been
appended to subtlv list, describing the vxlan network identifier to
be used for the routing information of the BGP update message.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_attr.c|  5 +++--
 bgpd/bgp_encap_tlv.c   | 22 ++
 bgpd/bgp_encap_types.h |  7 ++-
 bgpd/bgp_route.c   |  9 +
 4 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 5c5bafa8af81..f53fb14c759d 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -3058,8 +3058,9 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
   stream_put_ipv4 (s, attr->extra->aggregator_addr.s_addr);
 }
 
-  if ((afi == AFI_IP || afi == AFI_IP6) &&
-  (safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN))
+  if (((afi == AFI_IP || afi == AFI_IP6) &&
+   (safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN)) ||
+  (afi == AFI_INTERNAL_L2VPN && safi == SAFI_INTERNAL_EVPN))
 {
/* Tunnel Encap attribute */
bgp_packet_mpattr_tea(bgp, peer, s, attr, BGP_ATTR_ENCAP);
diff --git a/bgpd/bgp_encap_tlv.c b/bgpd/bgp_encap_tlv.c
index 347b4b3ce72c..0814b811d031 100644
--- a/bgpd/bgp_encap_tlv.c
+++ b/bgpd/bgp_encap_tlv.c
@@ -390,8 +390,30 @@ bgp_encap_type_vxlan_to_tlv(
 struct attr*attr)
 {
 struct attr_extra  *extra = bgp_attr_extra_get(attr);
+struct bgp_attr_encap_subtlv   *tlv;
+uint32_t vnid;
 
 extra->encap_tunneltype = BGP_ENCAP_TYPE_VXLAN;
+
+if(bet == NULL ||!bet->vnid)
+  return;
+if(extra->encap_subtlvs)
+  XFREE(MTYPE_ENCAP_TLV, extra->encap_subtlvs);
+tlv = XCALLOC (MTYPE_ENCAP_TLV, sizeof(struct bgp_attr_encap_subtlv)-1+12);
+tlv->type = 1; /* encapsulation type */
+tlv->length = 12;
+if(bet->vnid)
+  {
+vnid = htonl(bet->vnid | VXLAN_ENCAP_MASK_VNID_VALID);
+memcpy(>value, , 4);
+  }
+if(bet->mac_address)
+  {
+char *ptr = (char *)>value + 4;
+memcpy( ptr, bet->mac_address, 6);
+  }
+extra->encap_subtlvs = tlv;
+return;
 }
 
 void
diff --git a/bgpd/bgp_encap_types.h b/bgpd/bgp_encap_types.h
index 603ff9d2d624..0e999ccde833 100644
--- a/bgpd/bgp_encap_types.h
+++ b/bgpd/bgp_encap_types.h
@@ -167,10 +167,15 @@ struct 
bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode {
 struct bgp_tea_subtlv_remote_endpoint   st_endpoint;/* optional */
 };
 
+#define VXLAN_ENCAP_MASK_VNID_VALID 0x8000
+#define VXLAN_ENCAP_MASK_MAC_VALID  0x4000
+
 struct bgp_encap_type_vxlan {
 uint32_t   valid_subtlvs;
 struct bgp_tea_subtlv_remote_endpoint   st_endpoint;/* optional */
-/* No subtlvs defined in spec? */
+/* draft-ietf-idr-tunnel-encaps-02 */
+uint32_tvnid; /* does not include V 
and M bit */
+uint8_t *mac_address;   /* optional */
 };
 
 struct bgp_encap_type_nvgre {
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index af191f64a472..d1e1c6d19643 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -57,9 +57,12 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, 
Boston, MA
 #include "bgpd/bgp_vty.h"
 #include "bgpd/bgp_mpath.h"
 #include "bgpd/bgp_nht.h"
+#include "bgpd/bgp_encap_types.h"
+#include "bgpd/bgp_encap_tlv.h"
 #include "bgpd/bgp_evpn.h"
 #include "bgpd/bgp_attr_evpn.h"
 
+
 /* Extern from bgp_dump.c */
 extern const char *bgp_origin_str[];
 extern const char *bgp_origin_long_str[];
@@ -4750,6 +4753,12 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix 
*p,
 }
   if(afi == AFI_INTERNAL_L2VPN)
 {
+  struct bgp_encap_type_vxlan bet;
+
+  memset(, 0, sizeof(struct bgp_encap_type_vxlan));
+  if(bgp_static->eth_t_id)
+bet.vnid = bgp_static->eth_t_id;
+  bgp_encap_type_vxlan_to_tlv(, );
   if (bgp_static->igpnexthop.s_addr)
 {
   union gw_addr add;
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16371] [PATCH 39/57] bgpd: fix compilation warning due to AFI_ETHER

2016-10-28 Thread Philippe Guibert
This commits avoids keeping a warning of compilation.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_open.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c
index 75c840ef4958..ce1fea16971e 100644
--- a/bgpd/bgp_open.c
+++ b/bgpd/bgp_open.c
@@ -136,6 +136,8 @@ bgp_afi_safi_valid_indices (afi_t *afi, safi_t *safi)
 {
   switch (*afi)
 {
+case AFI_ETHER:
+  break;
 case AFI_IP:
 case AFI_IP6:
   switch (*safi)
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16369] [PATCH 35/57] bgpd: support for router mac extended community

2016-10-28 Thread Philippe Guibert
As per draft-ietf-bess-evpn-inter-subnet-forwarding-01, chapter 6.1,
a new extended community called router's MAC Extended Community is
provided. This community is appended to extended community list.
Note that a show API has been changed in order to be able to not
display (or not) this new type.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_clist.c  |  4 ++--
 bgpd/bgp_ecommunity.c | 61 ++-
 bgpd/bgp_ecommunity.h |  5 -
 bgpd/bgpd.c   |  8 +--
 4 files changed, 67 insertions(+), 11 deletions(-)

diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c
index bb06028b0ca7..697fcef285ec 100644
--- a/bgpd/bgp_clist.c
+++ b/bgpd/bgp_clist.c
@@ -807,14 +807,14 @@ extcommunity_list_set (struct community_list_handler *ch,
 }
 
   if (ecom)
-ecom->str = ecommunity_ecom2str (ecom, ECOMMUNITY_FORMAT_DISPLAY);
+ecom->str = ecommunity_ecom2str (ecom, ECOMMUNITY_FORMAT_DISPLAY, 0);
 
   entry = community_entry_new ();
   entry->direct = direct;
   entry->style = style;
   entry->any = (str ? 0 : 1);
   if (ecom)
-entry->config = ecommunity_ecom2str (ecom, 
ECOMMUNITY_FORMAT_COMMUNITY_LIST);
+entry->config = ecommunity_ecom2str (ecom, 
ECOMMUNITY_FORMAT_COMMUNITY_LIST, 0);
   else if (regex)
 entry->config = XSTRDUP (MTYPE_COMMUNITY_LIST_CONFIG, str);
   else
diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c
index 5d69b42c310f..79b7af075e9f 100644
--- a/bgpd/bgp_ecommunity.c
+++ b/bgpd/bgp_ecommunity.c
@@ -58,7 +58,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;
@@ -166,7 +166,7 @@ char *
 ecommunity_str (struct ecommunity *ecom)
 {
   if (! ecom->str)
-ecom->str = ecommunity_ecom2str (ecom, ECOMMUNITY_FORMAT_DISPLAY);
+ecom->str = ecommunity_ecom2str (ecom, ECOMMUNITY_FORMAT_DISPLAY, 0);
   return ecom->str;
 }
 
@@ -204,7 +204,7 @@ ecommunity_intern (struct ecommunity *ecom)
   find->refcnt++;
 
   if (! find->str)
-find->str = ecommunity_ecom2str (find, ECOMMUNITY_FORMAT_DISPLAY);
+find->str = ecommunity_ecom2str (find, ECOMMUNITY_FORMAT_DISPLAY, 0);
 
   return find;
 }
@@ -585,9 +585,12 @@ ecommunity_str2com (const char *str, int type, int 
keyword_included)
ECOMMUNITY_FORMAT_ROUTE_MAP
ECOMMUNITY_FORMAT_COMMUNITY_LIST
ECOMMUNITY_FORMAT_DISPLAY
+
+   Filter is added to display only ECOMMUNITY_ROUTE_TARGET in some cases. 
+   0 value displays all
 */
 char *
-ecommunity_ecom2str (struct ecommunity *ecom, int format)
+ecommunity_ecom2str (struct ecommunity *ecom, int format, int filter)
 {
   int i;
   u_int8_t *pnt;
@@ -652,6 +655,11 @@ ecommunity_ecom2str (struct ecommunity *ecom, int format)
   break;
 
 case ECOMMUNITY_ENCODE_OPAQUE:
+  if(filter == ECOMMUNITY_ROUTE_TARGET)
+{
+  first = 0;
+  continue;
+}
   if (*pnt == ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP)
 {
   uint16_t tunneltype;
@@ -662,8 +670,32 @@ ecommunity_ecom2str (struct ecommunity *ecom, int format)
   first = 0;
   continue;
 }
-/* fall through */
-
+  len = sprintf (str_buf + str_pnt, "?");
+  str_pnt += len;
+  first = 0;
+  continue;
+case ECOMMUNITY_ENCODE_EVPN:
+  if(filter == ECOMMUNITY_ROUTE_TARGET)
+{
+  first = 0;
+  continue;
+}
+  if (*pnt == ECOMMUNITY_SITE_ORIGIN)
+{
+  char macaddr[6];
+  pnt++;
+  memcpy(, pnt, 6);
+  len = sprintf(str_buf + str_pnt, 
"EVPN:%02x:%02x:%02x:%02x:%02x:%02x",
+macaddr[0], macaddr[1], macaddr[2],
+macaddr[3], macaddr[4], macaddr[5]);
+  str_pnt += len;
+  first = 0;
+  continue;
+}
+  len = sprintf (str_buf + str_pnt, "?");
+  str_pnt += len;
+  first = 0;
+  continue;
 default:
   len = sprintf (str_buf + str_pnt, "?");
   str_pnt += len;
@@ -774,3 +806,20 @@ ecommunity_match (const struct ecommunity *ecom1,
 return 0;
 }
 
+/* return first occurence of type */
+extern struct ecommunity_val *ecommunity_lookup (const struct ecommunity 
*ecom, uint8_t type)
+{
+  u_int8_t *p;
+  int c;
+  struct ecommunity_val *ecom_val;
+
+  /* If the value already exists in the structure return 0.  */
+  c = 0;
+  for (p = ecom->val; c < ecom->size; p += ECOMMUNITY_SIZE, c++)
+{
+  ecom_val = (struct ecommunity_val *)p;
+ 

[quagga-dev 16366] [PATCH 33/57] bgpd: enhance network command for evpn route type 5

2016-10-28 Thread Philippe Guibert
A new vty command available under evpn address family. This command
takes following format:

(af-evpn)# network A.B.C.D/M rd ASN:nn_or_IP-address:nn ethtag WORD
 label WORD esi WORD gwip A.B.C.D routermac WORD

Among new parameters, ethtag stands for the ethernet tag indentifier.
ESI stands for the ethernet segment identifier, and must be entered in
following format: 00:11:22:33:44:55:66:77:88:99.
gwip stands for the gateway IP address contained in RT5 message.
RouterMAc is the gateway mac address sent as extended community
attribute.
The no form of above command is also available.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_encap.c   |   4 +-
 bgpd/bgp_evpn.c|  48 +++
 bgpd/bgp_mplsvpn.c |   6 +--
 bgpd/bgp_route.c   | 113 +
 bgpd/bgp_route.h   |   6 ++-
 5 files changed, 162 insertions(+), 15 deletions(-)

diff --git a/bgpd/bgp_encap.c b/bgpd/bgp_encap.c
index 48817e05da88..3fe0d8c9f817 100644
--- a/bgpd/bgp_encap.c
+++ b/bgpd/bgp_encap.c
@@ -211,7 +211,7 @@ DEFUN (encap_network,
"BGP tag\n"
"tag value\n")
 {
-  return bgp_static_set_safi (SAFI_ENCAP, vty, argv[0], argv[1], argv[2], 
NULL);
+  return bgp_static_set_safi (SAFI_ENCAP, vty, argv[0], argv[1], argv[2], 
NULL, NULL, NULL, NULL, NULL);
 }
 
 /* For testing purpose, static route of ENCAP. */
@@ -226,7 +226,7 @@ DEFUN (no_encap_network,
"BGP tag\n"
"tag value\n")
 {
-  return bgp_static_unset_safi (SAFI_ENCAP, vty, argv[0], argv[1], argv[2]);
+  return bgp_static_unset_safi (SAFI_ENCAP, vty, argv[0], argv[1], argv[2], 
NULL, NULL, NULL);
 }
 
 static int
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index b8945daeffc2..7828caa02fea 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -673,6 +673,52 @@ DEFUN (show_bgp_l2vpn_evpn_rd_neighbor_advertised_routes,
   return show_adj_route_evpn (vty, peer, );
 }
 
+/* For testing purpose, static route of MPLS-VPN. */
+DEFUN (evpnrt5_network,
+   evpnrt5_network_cmd,
+   "network A.B.C.D/M rd ASN:nn_or_IP-address:nn ethtag WORD label WORD 
esi WORD gwip A.B.C.D routermac WORD",
+   "Specify a network to announce via BGP\n"
+   "IP prefix /, e.g., 35.0.0.0/8\n"
+   "Specify Route Distinguisher\n"
+   "VPN Route Distinguisher\n"
+   "Ethernet Tag\n"
+   "Ethernet Tag Value\n"
+   "BGP label\n"
+   "label value\n"
+   "Ethernet Segment Identifier\n"
+   "ESI value ( 00:11:22:33:44:55:66:77:88:99 format) \n"
+   "Gateway IP\n"
+   "Gateway IP ( A.B.C.D )\n"
+   "Router Mac Ext Comm\n"
+   "Router Mac address Value ( aa:bb:cc:dd:ee:ff format)\n")
+{
+  return bgp_static_set_safi (SAFI_INTERNAL_EVPN, vty, argv[0], argv[1], 
argv[3], NULL, 
+  argv[4], argv[5], argv[2], argv[6]);
+}
+
+/* For testing purpose, static route of MPLS-VPN. */
+DEFUN (no_evpnrt5_network,
+   no_evpnrt5_network_cmd,
+   "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn ethtag WORD label WORD 
esi WORD gwip A.B.C.D",
+   NO_STR
+   "Specify a network to announce via BGP\n"
+   "IP prefix /, e.g., 35.0.0.0/8\n"
+   "Specify Route Distinguisher\n"
+   "VPN Route Distinguisher\n"
+   "Ethernet Tag\n"
+   "Ethernet Tag Value\n"
+   "BGP label\n"
+   "label value\n"
+   "Ethernet Segment Identifier\n"
+   "ESI value ( 00:11:22:33:44:55:66:77:88:99 format) \n"
+   "Gateway IP\n"
+   "Gateway IP ( A.B.C.D )\n")
+{
+  return bgp_static_unset_safi (SAFI_INTERNAL_EVPN, vty, argv[0], argv[1], 
argv[3], 
+argv[4], argv[5], argv[2]);
+}
+
+
 void
 bgp_ethernetvpn_init (void)
 {
@@ -688,4 +734,6 @@ bgp_ethernetvpn_init (void)
   install_element (VIEW_NODE, _bgp_l2vpn_evpn_rd_neighbor_routes_cmd);
   install_element (VIEW_NODE, 
_bgp_l2vpn_evpn_all_neighbor_advertised_routes_cmd);
   install_element (VIEW_NODE, 
_bgp_l2vpn_evpn_rd_neighbor_advertised_routes_cmd);
+  install_element (BGP_EVPN_NODE, _evpnrt5_network_cmd);
+  install_element (BGP_EVPN_NODE, _network_cmd);
 }
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index 09a20a1c18b7..2385bfade3b9 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -407,7 +407,7 @@ DEFUN (vpnv4_network,
"BGP tag\n"
"tag value\n")
 {
-  return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2], 
NULL);
+  return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2], 
NULL, NULL, NULL, NULL, NULL);
 }
 
 DEFUN (vpnv4_network_route_map,
@@ -422,7 +422,7 @@ DEFUN (vpnv4_network_rout

[quagga-dev 16370] [PATCH 38/57] bgpd: handling router mac extended community

2016-10-28 Thread Philippe Guibert
For each received routermac extended community, the mac address is
copied into routermac extended community context. For each emission,
a check is done against routermac extended community, if L2VPN is
enabled. If enabled, the extended community is appended.

Signed-off-by: Philippe Gubiert 
---
 bgpd/bgp_ecommunity.c |  2 +-
 bgpd/bgp_route.c  | 11 +++
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c
index 79b7af075e9f..de3bce41783c 100644
--- a/bgpd/bgp_ecommunity.c
+++ b/bgpd/bgp_ecommunity.c
@@ -204,7 +204,7 @@ ecommunity_intern (struct ecommunity *ecom)
   find->refcnt++;
 
   if (! find->str)
-find->str = ecommunity_ecom2str (find, ECOMMUNITY_FORMAT_DISPLAY, 0);
+find->str = ecommunity_ecom2str (find, ECOMMUNITY_FORMAT_DISPLAY, 
ECOMMUNITY_ROUTE_TARGET);
 
   return find;
 }
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index d1e1c6d19643..467c83c72750 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -4255,6 +4255,8 @@ bgp_static_free (struct bgp_static *bgp_static)
 free (bgp_static->rmap.name);
   if(bgp_static->eth_s_id)
 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
+  if(bgp_static->router_mac)
+XFREE(MTYPE_ATTR, bgp_static->router_mac);
   XFREE (MTYPE_BGP_STATIC, bgp_static);
 }
 
@@ -4759,6 +4761,15 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix 
*p,
   if(bgp_static->eth_t_id)
 bet.vnid = bgp_static->eth_t_id;
   bgp_encap_type_vxlan_to_tlv(, );
+ if(bgp_static->router_mac)
+{
+  struct ecommunity_val routermac;
+  memset(, 0, sizeof(struct ecommunity_val));
+  routermac.val[0] = ECOMMUNITY_ENCODE_EVPN;
+  routermac.val[1] = ECOMMUNITY_SITE_ORIGIN;
+  memcpy([2], bgp_static->router_mac, MAC_LEN);
+  ecommunity_add_val(bgp_attr_extra_get 
()->ecommunity,);
+}
   if (bgp_static->igpnexthop.s_addr)
 {
   union gw_addr add;
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16358] [PATCH 27/57] bgpd: route type 5 internal structures plus processing

2016-10-28 Thread Philippe Guibert
The commit introduces the changes to be done to carry route type 5 EVPN
information in bgp extra attribute information. The commit also handles
the update processing for route type 5 information.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_attr.c  |  16 -
 bgpd/bgp_attr.h  |  14 +
 bgpd/bgp_route.c | 173 ++-
 bgpd/bgp_route.h |   5 ++
 4 files changed, 205 insertions(+), 3 deletions(-)

diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 8741c4af3441..c7564ae49fb8 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -311,6 +311,18 @@ encap_same(struct bgp_attr_encap_subtlv *h1, struct 
bgp_attr_encap_subtlv *h2)
 return 1;
 }
 
+static bool
+overlay_index_same(const struct attr_extra *ae1, const struct attr_extra *ae2)
+{
+  if(!ae1 && ae2)
+return false;
+  if(!ae2 && ae1)
+return false;
+  if(!ae1 && !ae2)
+return false;
+  return !memcmp(&(ae1->evpn_overlay), &(ae2->evpn_overlay), sizeof(struct 
overlay_index));
+}
+
 /* Unknown transit attribute. */
 static struct hash *transit_hash;
 
@@ -551,7 +563,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)
-  && IPV4_ADDR_SAME (>originator_id, >originator_id))
+  && IPV4_ADDR_SAME (>originator_id, >originator_id)
+  && ae1->eth_t_id == ae2->eth_t_id
+  && overlay_index_same(ae1, ae2))
 return 1;
   else if (ae1 || ae2)
 return 0;
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index 3bd7aface174..64a7464177df 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -21,6 +21,8 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, 
Boston, MA
 #ifndef _QUAGGA_BGP_ATTR_H
 #define _QUAGGA_BGP_ATTR_H
 
+#include "bgp_attr_evpn.h"
+
 /* Simple bit mapping. */
 #define BITMAP_NBBY 8
 
@@ -54,6 +56,13 @@ struct bgp_attr_encap_subtlv {
 uint8_tvalue[1];   /* will be extended */
 };
 
+/* Overlay Index Info */
+struct overlay_index
+{
+  struct eth_segment_id eth_s_id;
+  union gw_addr gw_ip;
+};
+
 /* Additional/uncommon BGP attributes.
  * lazily allocated as and when a struct attr
  * requires it.
@@ -95,6 +104,11 @@ struct attr_extra
 
   /* route tag */
   route_tag_t tag;
+
+  /* EVPN */
+  uint32_t eth_t_id;
+  struct overlay_index evpn_overlay;
+  short use_gw;
 };
 
 /* BGP core attribute structure. */
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 32577c299f6a..3c8ebcab8676 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -57,6 +57,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, 
Boston, MA
 #include "bgpd/bgp_vty.h"
 #include "bgpd/bgp_mpath.h"
 #include "bgpd/bgp_nht.h"
+#include "bgpd/bgp_evpn.h"
 
 /* Extern from bgp_dump.c */
 extern const char *bgp_origin_str[];
@@ -2526,6 +2527,86 @@ info_make (int type, int sub_type, struct peer *peer, 
struct attr *attr,
   return new;
 }
 
+static void
+overlay_index_update(struct attr *attr, struct eth_segment_id *eth_s_id, union 
gw_addr *gw_ip)
+{
+  struct attr_extra *extra;
+
+  if(!attr)
+return;
+  extra = bgp_attr_extra_get(attr);
+
+  if(eth_s_id == NULL)
+{
+  memset(&(extra->evpn_overlay.eth_s_id),0, sizeof(struct eth_segment_id));
+}
+  else
+{
+  memcpy(&(extra->evpn_overlay.eth_s_id), eth_s_id, sizeof(struct 
eth_segment_id));
+}
+  if(gw_ip == NULL)
+{
+  memset(&(extra->evpn_overlay.gw_ip), 0, sizeof(union gw_addr));
+}
+  else
+{
+  memcpy(&(extra->evpn_overlay.gw_ip),gw_ip, sizeof(union gw_addr));
+}
+}
+
+static bool
+eth_tag_id_equal(afi_t afi, struct bgp_info *info, uint32_t *eth_t_id)
+{
+  uint32_t local_eth_t_id;
+
+  if(afi != AFI_INTERNAL_L2VPN)
+return true;
+  if (!info->attr || !info->attr->extra) {
+local_eth_t_id = 0;
+if(eth_t_id == NULL)
+  return true;
+  } else {
+local_eth_t_id = info->attr->extra->eth_t_id;
+  }
+  if(eth_t_id && (local_eth_t_id == *eth_t_id))
+return true;
+  if (local_eth_t_id == 0)
+return true;
+  return false;
+}
+
+static bool
+overlay_index_equal(afi_t afi, struct bgp_info *info, struct eth_segment_id 
*eth_s_id, union gw_addr *gw_ip)
+{
+  struct eth_segment_id *info_eth_s_id, *info_eth_s_id_remote;
+  union gw_addr *info_gw_ip, *info_gw_ip_remote;
+  char temp[16];
+
+  if(afi != AFI_INTERNAL_L2VPN)
+return true;
+  if (!info->attr || !info->attr->extra) {
+memset(, 0, 16);
+info_eth_s_id = (struct eth_segment_id *)
+info_gw_ip = (union gw_addr *)
+if(eth_s_id == NULL && gw_ip == NULL)
+  return true;
+  }

[quagga-dev 16363] [PATCH 30/57] bgpd: enhance EPVN vty show commands

2016-10-28 Thread Philippe Guibert
This patch introduces show show bgp evpn commands to dump
NLRI entries configured or received on BGP, related to EVPN
route type 5. New command introduced is the following:

show bgp evpn [all | rd  ] [overlay]

This command displays gw ip field of the RT-5 message in the
nexthop field of the show command.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_evpn.c  | 495 +++
 bgpd/bgp_evpn.h  |   1 +
 bgpd/bgp_route.c |  91 ++
 bgpd/bgp_route.h |   1 +
 bgpd/bgpd.c  |   1 +
 5 files changed, 589 insertions(+)

diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index 1d537fa7eab8..61335eaaa1ca 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -175,3 +175,498 @@ bgp_nlri_parse_evpn (struct peer *peer, struct attr *attr,
 
   return 0;
 }
+
+static int
+show_adj_route_evpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd)
+{
+  struct bgp *bgp;
+  struct bgp_table *table;
+  struct bgp_node *rn;
+  struct bgp_node *rm;
+  struct attr *attr;
+  int rd_header;
+  int header = 1;
+  char v4_header[] = "   Network  Next HopMetric LocPrf 
Weight Path%s";
+
+  bgp = bgp_get_default ();
+  if (bgp == NULL)
+{
+  vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+  return CMD_WARNING;
+}
+
+  for (rn = bgp_table_top (bgp->rib[AFI_INTERNAL_L2VPN][SAFI_INTERNAL_EVPN]); 
rn;
+   rn = bgp_route_next (rn))
+{
+  if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
+continue;
+
+  if ((table = rn->info) != NULL)
+{
+  rd_header = 1;
+
+  for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
+if ((attr = rm->info) != NULL)
+  {
+if (header)
+  {
+vty_out (vty, "BGP table version is 0, local router ID is 
%s%s",
+ inet_ntoa (bgp->router_id), VTY_NEWLINE);
+vty_out (vty, "Status codes: s suppressed, d damped, h 
history, * valid, > best, i - internal%s",
+ VTY_NEWLINE);
+vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - 
incomplete%s%s",
+ VTY_NEWLINE, VTY_NEWLINE);
+vty_out (vty, v4_header, VTY_NEWLINE);
+header = 0;
+  }
+
+if (rd_header)
+  {
+u_int16_t type;
+struct rd_as rd_as;
+struct rd_ip rd_ip;
+u_char *pnt;
+
+pnt = rn->p.u.val;
+
+/* Decode RD type. */
+type = decode_rd_type (pnt);
+/* Decode RD value. */
+if (type == RD_TYPE_AS)
+  decode_rd_as (pnt + 2, _as);
+else if (type == RD_TYPE_AS4)
+  decode_rd_as4 (pnt + 2, _as);
+else if (type == RD_TYPE_IP)
+  decode_rd_ip (pnt + 2, _ip);
+
+vty_out (vty, "Route Distinguisher: ");
+
+if (type == RD_TYPE_AS)
+  vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
+else if (type == RD_TYPE_AS4)
+  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);
+
+vty_out (vty, "%s", VTY_NEWLINE);
+rd_header = 0;
+  }
+route_vty_out_tmp (vty, >p, attr, SAFI_MPLS_VPN);
+  }
+}
+}
+  return CMD_SUCCESS;
+}
+
+enum bgp_show_type
+{
+  bgp_show_type_normal,
+  bgp_show_type_regexp,
+  bgp_show_type_prefix_list,
+  bgp_show_type_filter_list,
+  bgp_show_type_neighbor,
+  bgp_show_type_cidr_only,
+  bgp_show_type_prefix_longer,
+  bgp_show_type_community_all,
+  bgp_show_type_community,
+  bgp_show_type_community_exact,
+  bgp_show_type_community_list,
+  bgp_show_type_community_list_exact
+};
+
+#define SHOW_DISPLAY_STANDARD 0
+#define SHOW_DISPLAY_TAGS 1
+#define SHOW_DISPLAY_OVERLAY 2
+
+static int
+bgp_show_ethernet_vpn (struct vty *vty, struct prefix_rd *prd, enum 
bgp_show_type type,
+  void *output_arg, int option)
+{
+  afi_t afi = AFI_INTERNAL_L2VPN;
+  struct bgp *bgp;
+  struct bgp_table *table;
+  struct bgp_node *rn;
+  struct bgp_node *rm;
+  struct bgp_info *ri;
+  int rd_header;
+  int header = 1;
+  char v4_header[] = "   Network  Next HopMetric LocPrf 
Weight Path%s";
+  char v4_header_tag[] = "   Network  Next Hop  In tag/Out tag%s";
+  char v4_header_overlay[] = "   Network  Next Hop  

[quagga-dev 16362] [PATCH 29/57] bgpd: evpn RT-5 bgp update carries nexthop attribute

2016-10-28 Thread Philippe Guibert
This patch appends nexthop attribute to EVPN message, in addition
to appending gateway IP in RT-5 NLRI itself. In reception, if
both informations are stored, then the GW IP information will
supersede the NLRI nexthop attribute.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_attr.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 5d333c2edbe2..5c5bafa8af81 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -2491,6 +2491,20 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, 
safi_t safi,
break;
   }
   break;
+case AFI_INTERNAL_L2VPN:
+  switch (safi)
+  {
+  case SAFI_INTERNAL_EVPN:
+  /* XXX assumption : NH as MPLSVPN, and IPv4 */
+ stream_putc (s, 12);
+ stream_putl (s, 0);   /* RD = 0, per RFC */
+ stream_putl (s, 0);
+ stream_put (s, >extra->mp_nexthop_global_in, 4);
+ break;
+break;
+  default:
+break;
+  }
 default:
   break;
 }
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16359] [PATCH 26/57] bgpd: handling EVPN Route Type 5 NLRI message

2016-10-28 Thread Philippe Guibert
This patch introduces code to receive a NLRI message with route type
5, as defined in draft-ietf-bess-evpn-prefix-advertisement-02. It
It increases the number of parameters to extract from the NLRI and
to store into bgp extra information structure. Those parameters are
the ESI (ethernet segment identifier), the gateway IP Address (which
acts like nexthop attribute but is contained inside the NLRI itself)
and the ethernet tag identifier ( that acts for the VXLan Identifier)

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/Makefile.am |   4 +-
 bgpd/bgp_attr_evpn.c |   1 +
 bgpd/bgp_attr_evpn.h |   7 ++
 bgpd/bgp_encap.c |   4 +-
 bgpd/bgp_evpn.c  | 177 +++
 bgpd/bgp_evpn.h  |  36 +++
 bgpd/bgp_mplsvpn.c   |   4 +-
 bgpd/bgp_packet.c|   4 ++
 bgpd/bgp_route.c |  26 +---
 bgpd/bgp_route.h |  11 +++-
 bgpd/bgpd.c  |   1 +
 11 files changed, 257 insertions(+), 18 deletions(-)
 create mode 100644 bgpd/bgp_evpn.c
 create mode 100644 bgpd/bgp_evpn.h

diff --git a/bgpd/Makefile.am b/bgpd/Makefile.am
index a2ebe2dcd8cc..da1146c69880 100644
--- a/bgpd/Makefile.am
+++ b/bgpd/Makefile.am
@@ -16,7 +16,7 @@ libbgp_a_SOURCES = \
bgp_packet.c bgp_network.c bgp_filter.c bgp_regex.c bgp_clist.c \
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_encap.c bgp_encap_tlv.c bgp_nht.c bgp_attr_evpn.c
+   bgp_encap.c bgp_encap_tlv.c bgp_nht.c bgp_attr_evpn.c bgp_evpn.c
 
 noinst_HEADERS = \
bgp_aspath.h bgp_attr.h bgp_community.h bgp_debug.h bgp_fsm.h \
@@ -25,7 +25,7 @@ noinst_HEADERS = \
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_encap.h bgp_encap_tlv.h bgp_encap_types.h bgp_nht.h \
-   bgp_attr_evpn.h
+   bgp_attr_evpn.h bgp_evpn.h
 
 bgpd_SOURCES = bgp_main.c
 bgpd_LDADD = libbgp.a ../lib/libzebra.la @LIBCAP@ @LIBM@
diff --git a/bgpd/bgp_attr_evpn.c b/bgpd/bgp_attr_evpn.c
index 9a092a11ff21..66751342ec7b 100644
--- a/bgpd/bgp_attr_evpn.c
+++ b/bgpd/bgp_attr_evpn.c
@@ -21,6 +21,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, 
Boston, MA
 #include 
 
 #include "command.h"
+#include "filter.h"
 #include "prefix.h"
 #include "log.h"
 #include "memory.h"
diff --git a/bgpd/bgp_attr_evpn.h b/bgpd/bgp_attr_evpn.h
index 1f5e579a0f00..d50a6f66758a 100644
--- a/bgpd/bgp_attr_evpn.h
+++ b/bgpd/bgp_attr_evpn.h
@@ -48,6 +48,13 @@ union gw_addr {
 #endif /* HAVE_IPV6 */
 };
 
+struct bgp_route_evpn
+{
+  uint32_t eth_t_id;
+  struct eth_segment_id eth_s_id;
+  union gw_addr gw_ip;
+};
+
 extern int str2esi (const char *str, struct eth_segment_id *id);
 extern int str2mac (const char *str, char *mac);
 extern char *esi2str (struct eth_segment_id *id);
diff --git a/bgpd/bgp_encap.c b/bgpd/bgp_encap.c
index 2cf55131c9d5..48817e05da88 100644
--- a/bgpd/bgp_encap.c
+++ b/bgpd/bgp_encap.c
@@ -183,10 +183,10 @@ bgp_nlri_parse_encap(
 
   if (attr) {
bgp_update (peer, , attr, afi, SAFI_ENCAP,
-   ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, , NULL, 0, 0);
+   ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, , NULL, 0, 0, NULL);
   } else {
bgp_withdraw (peer, , attr, afi, SAFI_ENCAP,
- ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, , NULL, 0);
+ ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, , NULL, 0, NULL);
   }
 }
 
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
new file mode 100644
index ..1d537fa7eab8
--- /dev/null
+++ b/bgpd/bgp_evpn.c
@@ -0,0 +1,177 @@
+/* Ethernet-VPN Packet and vty Processing File
+   Copyright (C) 2016 6WIND
+
+This file is part of GNU Quagga
+
+GNU Zebra 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, or (at your option) any
+later version.
+
+GNU Zebra 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 GNU Zebra; see the file COPYING.  If not, write to the Free
+Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
+
+#include 
+
+#include "command.h"
+#include "filter.h"
+#include "prefix.h"
+#include "log.h"
+#include "memory.h"
+#include "stream.h"
+
+#include "bgpd/bgp_attr_evpn.h"
+#include "bgpd/bgpd.h"
+#include "bgpd/bgp_table.h"
+#include "bgpd/bgp_route.h"
+#include "bgpd/bgp_attr.h"
+#include "bgp

[quagga-dev 16360] [PATCH 28/57] bgpd: evpn NLRI route type 5 forging

2016-10-28 Thread Philippe Guibert
This patch introduces the ability to make route type 5 message
when EVPN is enabled. Picked up paramters are collected from the
bgp extra attribute structure and are the ESI, the ethernet tag
information. In addition to this, nexthop attribute is collected too.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_attr.c   | 71 +++
 bgpd/bgp_attr.h   |  4 ++--
 bgpd/bgp_packet.c | 11 +
 3 files changed, 76 insertions(+), 10 deletions(-)

diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index c7564ae49fb8..5d333c2edbe2 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -41,6 +41,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, 
Boston, MA
 #include "bgpd/bgp_ecommunity.h"
 #include "table.h"
 #include "bgp_encap_types.h"
+#include "bgp_evpn.h"
 
 /* Attribute strings for logging. */
 static const struct message attr_str [] = 
@@ -2499,10 +2500,68 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, 
safi_t safi,
   return sizep;
 }
 
+static void
+bgp_packet_mpattr_route_type_5 (struct stream *s,
+struct prefix *p, struct prefix_rd *prd,
+uint32_t *labels, size_t nlabels, struct attr 
*attr)
+{
+  int len;
+  char temp[16];
+
+  memset(, 0, 16);
+  if(p->family == AF_INET)
+len = 8; /* ipv4 */
+  else if (p->family == AF_INET6)
+len = 32; /* ipv6 */
+  else
+len = 8; /* XXX */
+  stream_putc (s, EVPN_IP_PREFIX);
+  stream_putc (s, 8 /* RD */ + 10 /* ESI */  + 4 /* EthTag */ + 1 + len + 3 /* 
label */);
+  stream_put (s, prd->val, 8);
+  if(attr && attr->extra)
+stream_put (s, &(attr->extra->evpn_overlay.eth_s_id), 10);
+  else
+stream_put (s, , 10);
+  if(attr && attr->extra)
+stream_putl (s, attr->extra->eth_t_id);
+  else
+stream_putl (s, 0);
+  stream_putc (s, p->prefixlen);
+  if(p->family == AF_INET)
+stream_put_ipv4(s, p->u.prefix4.s_addr);
+  else if (p->family == AF_INET6)
+stream_put(s, >u.prefix, 16);
+  if(attr && attr->extra)
+{
+  //CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)
+  if(p->family == AF_INET)
+{
+  if (attr->extra->use_gw)
+stream_put_ipv4(s, attr->extra->evpn_overlay.gw_ip.ipv4.s_addr);
+  else
+stream_put_ipv4(s, attr->extra->mp_nexthop_global_in.s_addr);
+}
+  else if (p->family == AF_INET6)
+stream_put(s, &(attr->extra->evpn_overlay.gw_ip.ipv6), 16);
+}
+  else
+{
+  if(p->family == AF_INET)
+stream_put_ipv4(s, 0);
+  else if (p->family == AF_INET6)
+stream_put(s, , 16);
+}
+  if(labels)
+stream_put3 (s, labels[0]);
+  else
+stream_put3 (s, 0);
+  return;
+}
+
 void
 bgp_packet_mpattr_prefix (struct stream *s, afi_t afi, safi_t safi,
  struct prefix *p, struct prefix_rd *prd,
- uint32_t *labels, size_t nlabels)
+ uint32_t *labels, size_t nlabels, struct attr *attr)
 {
   if (safi == SAFI_MPLS_VPN)
 {
@@ -2523,6 +2582,10 @@ bgp_packet_mpattr_prefix (struct stream *s, afi_t afi, 
safi_t safi,
   stream_put (s, prd->val, 8);
   stream_put (s, >u.prefix, PSIZE (p->prefixlen));
 }
+  else if ((safi == SAFI_INTERNAL_EVPN))
+{
+  bgp_packet_mpattr_route_type_5(s, p, prd, labels, nlabels, attr);
+}
   else
 stream_put_prefix (s, p);
 }
@@ -2655,7 +2718,7 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
 {
   size_t mpattrlen_pos = 0;
   mpattrlen_pos = bgp_packet_mpattr_start(s, afi, safi, attr);
-  bgp_packet_mpattr_prefix(s, afi, safi, p, prd, labels, nlabels);
+  bgp_packet_mpattr_prefix(s, afi, safi, p, prd, labels, nlabels, attr);
   bgp_packet_mpattr_end(s, mpattrlen_pos);
 }
 
@@ -3024,9 +3087,9 @@ bgp_packet_mpunreach_start (struct stream *s, afi_t afi, 
safi_t safi)
 void
 bgp_packet_mpunreach_prefix (struct stream *s, struct prefix *p,
 afi_t afi, safi_t safi, struct prefix_rd *prd,
-uint32_t *labels, size_t nlabels)
+uint32_t *labels, size_t nlabels, struct attr 
*attr)
 {
-  bgp_packet_mpattr_prefix (s, afi, safi, p, prd, labels, nlabels);
+  bgp_packet_mpattr_prefix (s, afi, safi, p, prd, labels, nlabels, attr);
 }
 
 void
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index 64a7464177df..30fa98a41074 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -234,7 +234,7 @@ extern size_t bgp_packet_mpattr_start(struct stream *s, 
afi_t afi, safi_t safi,
  struct attr *attr);
 extern void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi,
 struct prefix *p, s

[quagga-dev 16345] [PATCH 13/57] bgpd: apply multipath algorithm to VRF

2016-10-28 Thread Philippe Guibert
This commit checks for the maximum path per VRF before running the
multipath algorithm. This makes it possible to limit the number of
paths for a specific VRF, and not for an other one.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_mpath.c | 34 +-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c
index dc99591bf8ad..f117d2dbed8d 100644
--- a/bgpd/bgp_mpath.c
+++ b/bgpd/bgp_mpath.c
@@ -38,6 +38,7 @@
 #include "bgpd/bgp_aspath.h"
 #include "bgpd/bgp_community.h"
 #include "bgpd/bgp_ecommunity.h"
+#include "bgpd/bgp_mplsvpn.h"
 #include "bgpd/bgp_mpath.h"
 
 bool
@@ -335,9 +336,13 @@ bgp_info_mpath_enqueue (struct bgp_info *prev_info, struct 
bgp_info *binfo)
 void
 bgp_info_mpath_dequeue (struct bgp_info *binfo)
 {
-  struct bgp_info_mpath *mpath = binfo->mpath;
+  struct bgp_info_mpath *mpath;
+  if (!binfo)
+return;
+  mpath = binfo->mpath;
   if (!mpath)
 return;
+
   if (mpath->mp_prev)
 mpath->mp_prev->mp_next = mpath->mp_next;
   if (mpath->mp_next)
@@ -471,6 +476,8 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info 
*new_best,
   int mpath_changed, debug;
   char pfx_buf[INET6_ADDRSTRLEN], nh_buf[2][INET6_ADDRSTRLEN];
   struct bgp_maxpaths_cfg *mpath_cfg = NULL;
+  struct prefix_rd *prd = NULL;
+  struct bgp_vrf *vrf = NULL;
 
   mpath_changed = 0;
   maxpaths = BGP_DEFAULT_MAXPATHS;
@@ -494,6 +501,31 @@ bgp_info_mpath_update (struct bgp_node *rn, struct 
bgp_info *new_best,
   maxpaths = (new_best->peer->sort == BGP_PEER_IBGP) ?
 mpath_cfg->maxpaths_ibgp : mpath_cfg->maxpaths_ebgp;
 }
+  if (safi == SAFI_MPLS_VPN)
+{
+  prd = _node_table (rn)->prd;
+  if (new_best)
+vrf = bgp_vrf_lookup(new_best->peer->bgp, prd);
+  else if (old_best)
+vrf = bgp_vrf_lookup(old_best->peer->bgp, prd);
+}
+  else if(bgp_node_table (rn)->type == BGP_TABLE_VRF)
+{
+  if (new_best)
+vrf = bgp_vrf_lookup_per_rn(new_best->peer->bgp, afi, rn);
+  else if (old_best)
+vrf = bgp_vrf_lookup_per_rn(old_best->peer->bgp, afi, rn);
+}
+  if (vrf)
+{
+  maxpaths = vrf->max_mpath;
+  if(debug && vrf)
+{
+  char vrf_rd_str[RD_ADDRSTRLEN];
+  prefix_rd2str(>outbound_rd, vrf_rd_str, sizeof(vrf_rd_str));
+  zlog_debug ("vrf[%s] : mpath. max detected : %d", vrf_rd_str, 
maxpaths);
+}
+}
 
   if (old_best)
 {
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16356] [PATCH 22/57] tests: update safi_valid_indices API

2016-10-28 Thread Philippe Guibert
There has been a change in API safi_valid_indices.
This modification is updating the call API.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 tests/bgp_capability_test.c | 13 +++--
 tests/bgp_mp_attr_test.c|  9 +
 2 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/tests/bgp_capability_test.c b/tests/bgp_capability_test.c
index a3813518b6a1..5f3d13aabc8d 100644
--- a/tests/bgp_capability_test.c
+++ b/tests/bgp_capability_test.c
@@ -584,21 +584,22 @@ parse_test (struct peer *peer, struct test_segment *t, 
int type)
   if (!ret && t->validate_afi)
 {
   safi_t safi = t->safi;
-  
-  if (bgp_afi_safi_valid_indices (t->afi, ) != t->afi_valid)
+  afi_t afi = t->afi;
+
+  if (bgp_afi_safi_valid_indices (, ) != t->afi_valid)
 failed++;
   
   printf ("MP: %u/%u (%u): recv %u, nego %u\n",
   t->afi, t->safi, safi,
-  peer->afc_recv[t->afi][safi],
-  peer->afc_nego[t->afi][safi]);
+  peer->afc_recv[afi][safi],
+  peer->afc_nego[afi][safi]);
 
   if (t->afi_valid == VALID_AFI)
 {
 
-  if (!peer->afc_recv[t->afi][safi])
+  if (!peer->afc_recv[afi][safi])
 failed++;
-  if (!peer->afc_nego[t->afi][safi])
+  if (!peer->afc_nego[afi][safi])
 failed++;
 }
 }
diff --git a/tests/bgp_mp_attr_test.c b/tests/bgp_mp_attr_test.c
index 7d6d8293c298..0f0813c01067 100644
--- a/tests/bgp_mp_attr_test.c
+++ b/tests/bgp_mp_attr_test.c
@@ -709,14 +709,15 @@ handle_result (struct peer *peer, struct test_segment *t,
   if (!parse_ret)
 {
   safi_t safi = t->safi;
-  
-  if (bgp_afi_safi_valid_indices (t->afi, ) != t->afi_valid)
+  afi_t afi = t->afi;
+
+  if (bgp_afi_safi_valid_indices ( , ) != t->afi_valid)
 failed++;
   
   printf ("MP: %u/%u (%u): recv %u, nego %u\n",
   t->afi, t->safi, safi,
-  peer->afc_recv[t->afi][safi],
-  peer->afc_nego[t->afi][safi]);
+  peer->afc_recv[afi][safi],
+  peer->afc_nego[afi][safi]);
 }
   
   printf ("mp attr parsed?: %s\n", parse_ret ? "no" : "yes");
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16333] [PATCH 00/57] Ethernet VPN RFC Patch

2016-10-28 Thread Philippe Guibert
As explained in a previous mail addressed to quagga-dev, Tue, Oct 25,
2016 at 2:46 PM, the proposed implementation covers the following:
- EVPN route type 2 aka MAC/IP advertisement
- EVPN route type 5 aka Prefix IP advertisement.
It is possible to statically set abovementioned messages.

It also covers BGP extended community attributes:
- Router MAC extended community
- BGP encapsulation attribute for VXLAN
- Tunnel Encapsulation attribute VXLAN

It also covers VRF import processing.
By using exported RT set from BGP extended communities, EVPN
information is added in ADJ-RIB-IN per VRF per neighbor table. Some
associated vty show commands are available.

More information is given in this previous email.
The below description details how the sets of patches are organised.

Regards,

Philippe


Not all the patches are dealing with EVPN.
Some older patches not in quagga-1.1.0 have been added as dependencies.
This permits CI to be able to take the patches, compile and run testing.

- EVPN route redistribution depends of the following change :

* BGP multiple label support *
[quagga-dev,16250,v2,2/2] bgpd: vpnv4 af exports extended communities
[quagga-dev,16249,v2,1/2] bgpd: VRF vty configuration, RIB table creation
[quagga-dev,16246,v4,3/3] tests: enhance bgpd testing with label value
[quagga-dev,16247,v4,2/3] bgpd: multiple label stack support
[quagga-dev,16244,v4,1/3] lib: 3byte stream foo

- EVPN VRF import processing depends of the following 2 series of patches:

* VRF Route Distinguisher Configuration *
[quagga-dev,16250,v2,2/2] bgpd: vpnv4 af exports extended communities
[quagga-dev,16249,v2,1/2] bgpd: VRF vty configuration, RIB table creation

* VRF import processing + VRF multipath *
[quagga-dev,16282,v2,10/10] bgpd: avoid looping when unselecting a list of mpath
entries.
[quagga-dev,16281,v2,09/10] bgpd: sanity check against accessing invalid table
pointer.
[quagga-dev,16280,v2,08/10] bgpd: apply multipath algorithm to VRF
[quagga-dev,16279,v2,07/10] bgpd: factorise mpath debug routine
[quagga-dev,16280,v2,06/10] bgpd: vty command for vrf maximum path configuration
[quagga-dev,16279,v2,05/10] bgpd: VRF RIB log updates enhancement
[quagga-dev,16278,v2,04/10] bgpd: VRF import processing
[quagga-dev,16277,v2,03/10] bgpd: detect if bgp_info is multipath entry
[quagga-dev,16276,v2,02/10] bgpd: BGP VRF processing handling
[quagga-dev,16276,v2,01/10] tests: fix BGP VRF interactions

Among the remaining 40 commits, one can divide the EVPN changes in the following
series of patches
* Core Support for Ethernet VPN*
[PATCH 16/57] => [PATCH 25/57]
* EVPN Route Type 5 support*
[PATCH 26/57] => [PATCH 34/57]
* BGP extended communities extension: router mac and vxlan support*
[PATCH 35/57] => [PATCH 38/57]
* EVPN Route Type 2 support*
[PATCH 39/57] => [PATCH 46/57]
* VRF Import Processing
[PATCH 47/57] => [PATCH 57/57]





___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16344] [PATCH 09/57] bgpd: VRF import processing

2016-10-28 Thread Philippe Guibert
From: Christian Franke <ch...@opensourcerouting.org>

This enhancement permits to export received or locally set route
entries for MPLS VPN, to the appropriate VRF. By introducing the
RFC4360 and BGP extended communities, some export route target are
received on BGP update, or some import route target are set on a
local route entry. It results from exporting the current route
information to the appropriate VRF RIB entry.
This commit is relying on BGP VRF processing, and supports VRF
RIB election as for standard RIBs. This makes it reusable, even
for multipath feature.

Signed-off-by: Christian Franke <ch...@opensourcerouting.org>
Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_route.c | 384 +--
 1 file changed, 376 insertions(+), 8 deletions(-)

diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 615cd375bb78..5b70478870d2 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -62,6 +62,10 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, 
Boston, MA
 extern const char *bgp_origin_str[];
 extern const char *bgp_origin_long_str[];
 
+#define ROUTE_INFO_TO_UPDATE 2
+#define ROUTE_INFO_TO_REMOVE 1
+#define ROUTE_INFO_TO_ADD0
+
 static void
 bgp_static_withdraw_safi (struct bgp *bgp, struct prefix *p, afi_t afi,
   safi_t safi, struct prefix_rd *prd,
@@ -69,6 +73,13 @@ bgp_static_withdraw_safi (struct bgp *bgp, struct prefix *p, 
afi_t afi,
 static void
 bgp_static_free (struct bgp_static *bgp_static);
 
+static void
+bgp_vrf_apply_new_imports_internal (struct bgp_vrf *vrf, afi_t afi, safi_t 
safi);
+
+static struct bgp_info *
+info_make (int type, int sub_type, struct peer *peer, struct attr *attr,
+  struct bgp_node *rn);
+
 static struct bgp_node *
 bgp_afi_node_get (struct bgp_table *table, afi_t afi, safi_t safi, struct 
prefix *p,
  struct prefix_rd *prd)
@@ -1525,6 +1536,12 @@ bgp_process_announce_selected (struct peer *peer, struct 
bgp_info *selected,
   return 0;
 }
 
+
+static bool rd_same (const struct prefix_rd *a, const struct prefix_rd *b)
+{
+  return !memcmp(>val, >val, sizeof(a->val));
+}
+
 void bgp_vrf_clean_tables (struct bgp_vrf *vrf)
 {
   afi_t afi;
@@ -1555,20 +1572,325 @@ void bgp_vrf_clean_tables (struct bgp_vrf *vrf)
 }
 }
 
+/* updates selected bgp_info structure to bgp vrf rib table
+ * most of the cases, processing consists in adding or removing entries in RIB 
tables
+ * on some cases, there is an update request. then it is necessary to have 
both old and new ri
+ */
+static void
+bgp_vrf_process_one (struct bgp_vrf *vrf, afi_t afi, safi_t safi, struct 
bgp_node *rn,
+ struct bgp_info *select, int action)
+{
+  struct bgp_node *vrf_rn;
+  struct bgp_info *iter = NULL;
+  struct prefix_rd *prd;
+  char pfx_str[INET6_BUFSIZ];
+
+  prd = _node_table (rn)->prd;
+  if (BGP_DEBUG (events, EVENTS))
+{
+  char vrf_rd_str[RD_ADDRSTRLEN], rd_str[RD_ADDRSTRLEN];
+  char nh_str[BUFSIZ] = "";
+
+  prefix_rd2str(>outbound_rd, vrf_rd_str, sizeof(vrf_rd_str));
+  prefix_rd2str(prd, rd_str, sizeof(rd_str));
+  prefix2str(>p, pfx_str, sizeof(pfx_str));
+  if(select && select->attr && select->attr->extra)
+{
+  if (afi == AFI_IP)
+strcpy (nh_str, inet_ntoa 
(select->attr->extra->mp_nexthop_global_in));
+  else if (afi == AFI_IP6)
+inet_ntop (AF_INET6, >attr->extra->mp_nexthop_global, 
nh_str, BUFSIZ);
+}
+  else if(select)
+{
+  inet_ntop (AF_INET, >attr->nexthop,
+ nh_str, sizeof (nh_str));
+}
+  zlog_debug ("vrf[%s] %s: [%s] [nh %s] %s ", vrf_rd_str, pfx_str, rd_str, 
nh_str,
+action == ROUTE_INFO_TO_REMOVE? "withdrawing" : "updating");
+}  
+  /* add a new entry if necessary
+   * if already present, do nothing. 
+   * use the loop to parse old entry also */
+
+  /* check if global RIB plans for destroying initial entry
+   * if yes, then suppress it
+   */
+  if(!vrf || !vrf->rib[afi] || !select)
+{
+  return;
+}
+  vrf_rn = bgp_node_get (vrf->rib[afi], >p);
+  if(!vrf_rn)
+{
+  return;
+}
+  if ( (action == ROUTE_INFO_TO_REMOVE) &&
+   (CHECK_FLAG (select->flags, BGP_INFO_REMOVED)))
+{
+  /* check entry not already present */
+  for (iter = vrf_rn->info; iter; iter = iter->next)
+{
+  /* coming from same peer */
+  if(iter->peer->remote_id.s_addr == select->peer->remote_id.s_addr)
+{
+  bgp_info_delete(vrf_rn, iter);
+  prefix2str(_rn->p, pfx_str, sizeof(pfx_str));
+  if (BGP_DEBUG (events, EVENTS))
+{
+  char nh_str[BUFSIZ] = "";
+ 

[quagga-dev 16342] [PATCH 11/57] bgpd: vty command for vrf maximum path configuration

2016-10-28 Thread Philippe Guibert
From: Julien Courtat 

Enhancement of new vty command to configure the maximum number of
multipath entries that are possible within a VRF RIB table.

The following command is available:
- vrf rd  maximum-path <1-64>
- no vrf rd  maximum-path <1-64>

Vrfs with a maximum-path of 1 don't display such info in show
running-config.

Signed-off-by: Julien Courtat 
---
 bgpd/bgp_mpath.h |  2 ++
 bgpd/bgp_vty.c   | 76 
 bgpd/bgpd.c  |  5 
 bgpd/bgpd.h  |  3 +++
 4 files changed, 86 insertions(+)

diff --git a/bgpd/bgp_mpath.h b/bgpd/bgp_mpath.h
index 2b3eaf51901f..3fcdf5a0f9ab 100644
--- a/bgpd/bgp_mpath.h
+++ b/bgpd/bgp_mpath.h
@@ -51,6 +51,8 @@ struct bgp_info_mpath
 /* Functions to support maximum-paths configuration */
 extern int bgp_maximum_paths_set (struct bgp *, afi_t, safi_t, int, u_int16_t);
 extern int bgp_maximum_paths_unset (struct bgp *, afi_t, safi_t, int);
+extern int bgp_maxpaths_default_set (struct bgp *, u_int32_t);
+extern int bgp_maxpaths_default_unset (struct bgp *);
 bool bgp_mpath_is_configured_sort (struct bgp *, bgp_peer_sort_t, afi_t, 
safi_t);
 bool bgp_mpath_is_configured (struct bgp *, afi_t, safi_t);
 
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 63a7b5bfdcf6..5fbec0f1a85b 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -10034,6 +10034,50 @@ DEFUN (bgp_vrf_imports,
   return CMD_SUCCESS;
 }
 
+DEFUN (bgp_vrf_maximum_path,
+   bgp_vrf_maximum_path_cmd,
+   "vrf rd WORD maximum-path [1-64]",
+   "BGP VPN VRF\n"
+   "Route Distinguisher\n"
+   "Route Distinguisher\n"
+   "Maximum number of multipath routes\n"
+   "Maximum number of multipath routes\n"
+)
+{
+  struct bgp *bgp = vty->index;
+  struct bgp_vrf *vrf;
+  struct prefix_rd prd;
+  int max_mpath;
+
+  if (! str2prefix_rd (argv[0], ))
+{
+  vty_out (vty, "%% Invalid RD '%s'%s", argv[0], VTY_NEWLINE);
+  return CMD_WARNING;
+}
+
+  max_mpath = atoi(argv[1]);
+
+  /* some values for maximum path aren't acceptable */
+  if (1 > max_mpath || max_mpath > 64)
+{
+  vty_out (vty, "%% Invalid maximum multipath '%d'%s", max_mpath, 
VTY_NEWLINE);
+  return CMD_WARNING;
+}
+
+  /* look for VRF */
+  vrf = bgp_vrf_lookup (bgp, );
+  if (! vrf)
+{
+  vty_out (vty, "%% No VRF with RD '%s'%s", argv[0], VTY_NEWLINE);
+  return CMD_WARNING;
+}
+
+  /* update max_mpath field in struct bgp_vrf */
+  vrf->max_mpath = max_mpath;
+
+  return CMD_SUCCESS;
+}
+
 DEFUN (no_bgp_vrf,
no_bgp_vrf_cmd,
"no vrf rd WORD",
@@ -10063,6 +10107,36 @@ DEFUN (no_bgp_vrf,
   return CMD_SUCCESS;
 }
 
+DEFUN (no_bgp_vrf_maximum_path,
+   no_bgp_vrf_maximum_path_cmd,
+   "no vrf rd WORD maximum-path",
+   NO_STR
+   "BGP VPN VRF\n"
+   "Route Distinguisher\n"
+   "Route Distinguisher\n"
+)
+{
+  struct bgp *bgp = vty->index;
+  struct bgp_vrf *vrf;
+  struct prefix_rd prd;
+
+  if (! str2prefix_rd (argv[0], ))
+{
+  vty_out (vty, "%% Invalid RD '%s'%s", argv[0], VTY_NEWLINE);
+  return CMD_WARNING;
+}
+
+  vrf = bgp_vrf_lookup (bgp, );
+  if (! vrf)
+{
+  vty_out (vty, "%% No VRF with RD '%s'%s", argv[0], VTY_NEWLINE);
+  return CMD_WARNING;
+}
+  /* reset maximum mpath to default value */
+  vrf->max_mpath = BGP_DEFAULT_MAXPATHS;
+
+  return CMD_SUCCESS;
+}
 /* BGP node structure. */
 static struct cmd_node bgp_node =
 {
@@ -10157,7 +10231,9 @@ bgp_vty_init (void)
   install_element (BGP_NODE, _vrf_cmd);
   install_element (BGP_NODE, _vrf_exports_cmd);
   install_element (BGP_NODE, _vrf_imports_cmd);
+  install_element (BGP_NODE, _vrf_maximum_path_cmd);
   install_element (BGP_NODE, _bgp_vrf_cmd);
+  install_element (BGP_NODE, _bgp_vrf_maximum_path_cmd);
 
   /* "bgp multiple-instance" commands. */
   install_element (CONFIG_NODE, _multiple_instance_cmd);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index a0fe4de390fb..9e091dd2e04b 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -2129,6 +2129,7 @@ bgp_vrf_create (struct bgp *bgp, struct prefix_rd 
*outbound_rd)
 
   vrf->bgp = bgp;
   vrf->outbound_rd = *outbound_rd;
+  vrf->max_mpath = bgp->maxpaths[AFI_IP][SAFI_MPLS_VPN].maxpaths_ibgp;
 
   for (afi = AFI_IP; afi < AFI_MAX; afi++)
 {
@@ -5826,6 +5827,10 @@ bgp_config_write (struct vty *vty)
 XFREE (MTYPE_ECOMMUNITY_STR, str2_p);
   }
   }
+if (vrf->max_mpath != BGP_DEFAULT_MAXPATHS)
+  vty_out(vty,
+  " vrf rd %s maximum-path %d%s", str_p == 
NULL?"":str_p,
+  vrf->max_mpath, VTY_NEWLINE);
   }
   }
   /* maximum-paths */
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index acf59c5aaf04..505c1389a087 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -225,6 +225,9 @@ struct bgp_vrf
   /* Static route configuration.  */
   struct bgp_table *route[AFI_MAX];
 
+  /* maximum multipath 

[quagga-dev 16346] [PATCH 14/57] bgpd: sanity check against accessing invalid table pointer.

2016-10-28 Thread Philippe Guibert
This sanity check has been discovered when running bgp mpath_tests
that are available in tests folder.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_mpath.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c
index f117d2dbed8d..46d813984741 100644
--- a/bgpd/bgp_mpath.c
+++ b/bgpd/bgp_mpath.c
@@ -509,7 +509,7 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info 
*new_best,
   else if (old_best)
 vrf = bgp_vrf_lookup(old_best->peer->bgp, prd);
 }
-  else if(bgp_node_table (rn)->type == BGP_TABLE_VRF)
+  else if(rn->table && bgp_node_table (rn) && bgp_node_table (rn)->type == 
BGP_TABLE_VRF)
 {
   if (new_best)
 vrf = bgp_vrf_lookup_per_rn(new_best->peer->bgp, afi, rn);
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16339] [PATCH 05/57] bgpd: multiple label stack support

2016-10-28 Thread Philippe Guibert
From: David Lamparter <equi...@opensourcerouting.org>

Support for multiple label support handling in NLRI messages.
Ability to receive and sent BGP updates with NLRI containing multiple
labels. The commit follows label encoding rules, contained in RFC3107.

Signed-off-by: David Lamparter <equi...@opensourcerouting.org>
Signed-off-by: Christian Franke <ch...@opensourcerouting.org>
Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_attr.c|  28 +++---
 bgpd/bgp_attr.h|   6 +--
 bgpd/bgp_encap.c   |   4 +-
 bgpd/bgp_mplsvpn.c | 148 
 bgpd/bgp_mplsvpn.h |   4 +-
 bgpd/bgp_packet.c  |  29 +++
 bgpd/bgp_route.c   | 149 +++--
 bgpd/bgp_route.h   |  15 --
 8 files changed, 248 insertions(+), 135 deletions(-)

diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 6aab50af4cfb..b46e7a30e3f7 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -2481,13 +2481,24 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, 
safi_t safi,
 void
 bgp_packet_mpattr_prefix (struct stream *s, afi_t afi, safi_t safi,
  struct prefix *p, struct prefix_rd *prd,
- u_char *tag)
+ uint32_t *labels, size_t nlabels)
 {
   if (safi == SAFI_MPLS_VPN)
 {
-  /* Tag, RD, Prefix write. */
-  stream_putc (s, p->prefixlen + 88);
-  stream_put (s, tag, 3);
+  if (nlabels != 0)
+{
+  size_t i;
+  /* Tag, RD, Prefix write. */
+  stream_putc (s, p->prefixlen + 8 * (8 + 3 * nlabels));
+  for (i = 0; i < nlabels; i++)
+stream_put3 (s, labels[i]);
+}
+  else
+{
+  /* Withdraw, put bottom of stack as only label */
+  stream_putc (s, p->prefixlen + 8 * (8 + 3));
+  stream_put3 (s, 0x1);
+}
   stream_put (s, prd->val, 8);
   stream_put (s, >u.prefix, PSIZE (p->prefixlen));
 }
@@ -2603,7 +2614,8 @@ bgp_size_t
 bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
  struct stream *s, struct attr *attr,
  struct prefix *p, afi_t afi, safi_t safi,
- struct peer *from, struct prefix_rd *prd, u_char *tag)
+ struct peer *from, struct prefix_rd *prd,
+ uint32_t *labels, size_t nlabels)
 {
   size_t cp;
   size_t aspath_sizep;
@@ -2622,7 +2634,7 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
 {
   size_t mpattrlen_pos = 0;
   mpattrlen_pos = bgp_packet_mpattr_start(s, afi, safi, attr);
-  bgp_packet_mpattr_prefix(s, afi, safi, p, prd, tag);
+  bgp_packet_mpattr_prefix(s, afi, safi, p, prd, labels, nlabels);
   bgp_packet_mpattr_end(s, mpattrlen_pos);
 }
 
@@ -2983,9 +2995,9 @@ bgp_packet_mpunreach_start (struct stream *s, afi_t afi, 
safi_t safi)
 void
 bgp_packet_mpunreach_prefix (struct stream *s, struct prefix *p,
 afi_t afi, safi_t safi, struct prefix_rd *prd,
-u_char *tag)
+uint32_t *labels, size_t nlabels)
 {
-  bgp_packet_mpattr_prefix (s, afi, safi, p, prd, tag);
+  bgp_packet_mpattr_prefix (s, afi, safi, p, prd, labels, nlabels);
 }
 
 void
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index 8457f4022437..3bd7aface174 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -173,7 +173,7 @@ extern bgp_size_t bgp_packet_attribute (struct bgp *bgp, 
struct peer *,
struct stream *, struct attr *,
struct prefix *, afi_t, safi_t,
struct peer *, struct prefix_rd *,
-   u_char *);
+   uint32_t *labels, size_t nlabels);
 extern void bgp_dump_routes_attr (struct stream *, struct attr *,
  struct prefix *);
 extern int attrhash_cmp (const void *, const void *);
@@ -220,7 +220,7 @@ extern size_t bgp_packet_mpattr_start(struct stream *s, 
afi_t afi, safi_t safi,
  struct attr *attr);
 extern void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi,
 struct prefix *p, struct prefix_rd *prd,
-u_char *tag);
+uint32_t *labels, size_t nlabels);
 extern size_t bgp_packet_mpattr_prefix_size(afi_t afi, safi_t safi,
 struct prefix *p);
 extern void bgp_packet_mpattr_end(struct stream *s, size_t sizep);
@@ -229,7 +229,7 @@ extern size_t bgp_packet_mpunreach_start (struct stream *s, 
afi_t afi,
  safi_t safi);
 extern void bgp_packet_mpunreach_prefix (struct stream *s, struct prefix *p,
  

[quagga-dev 16353] [PATCH 20/57] bgpd: basic vty support for EVPN

2016-10-28 Thread Philippe Guibert
Introduction of EVPN address-family node that is reachable under
BGP node, like follow: address-family evpn. Under that node, only
some commands are available for configuring a neighbor or setting
some basic settings like attribute unchanged behaviour. Currently,
no vty command is available for setting NLRI entries for EVPN.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_vty.c | 54 ++
 lib/command.c  |  3 +++
 lib/command.h  |  1 +
 lib/vty.c  |  1 +
 vtysh/vtysh.c  | 28 +++-
 5 files changed, 86 insertions(+), 1 deletion(-)

diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 1720fafe9d0a..6b40bf41b663 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -64,6 +64,9 @@ bgp_node_afi (struct vty *vty)
 case BGP_ENCAPV6_NODE:
   afi = AFI_IP6;
   break;
+case BGP_EVPN_NODE:
+  afi = AFI_INTERNAL_L2VPN;
+  break;
 default:
   afi = AFI_IP;
   break;
@@ -91,6 +94,9 @@ bgp_node_safi (struct vty *vty)
 case BGP_IPV6M_NODE:
   safi = SAFI_MULTICAST;
   break;
+case BGP_EVPN_NODE:
+  safi = SAFI_INTERNAL_EVPN;
+  break;
 default:
   safi = SAFI_UNICAST;
   break;
@@ -4496,6 +4502,16 @@ DEFUN (address_family_encapv6,
   return CMD_SUCCESS;
 }
 
+DEFUN (address_family_evpn,
+   address_family_evpn_cmd,
+   "address-family evpn",
+   "Enter Address Family command mode\n"
+   "Address family\n")
+{
+  vty->node = BGP_EVPN_NODE;
+  return CMD_SUCCESS;
+}
+
 DEFUN (exit_address_family,
exit_address_family_cmd,
"exit-address-family",
@@ -4503,6 +4519,7 @@ DEFUN (exit_address_family,
 {
   /* should match list in command.c:config_exit */
   if (vty->node == BGP_IPV4_NODE
+  || vty->node == BGP_EVPN_NODE
   || vty->node == BGP_ENCAP_NODE
   || vty->node == BGP_ENCAPV6_NODE
   || vty->node == BGP_IPV4M_NODE
@@ -10203,6 +10220,13 @@ static struct cmd_node bgp_encapv6_node =
   1
 };
 
+static struct cmd_node bgp_evpn_node =
+{
+  BGP_EVPN_NODE,
+  "%s(config-router-evpn)# ",
+  1
+};
+
 static void community_list_vty (void);
 
 void
@@ -10218,6 +10242,7 @@ bgp_vty_init (void)
   install_node (_vpnv6_node, NULL);
   install_node (_encap_node, NULL);
   install_node (_encapv6_node, NULL);
+  install_node (_evpn_node, NULL);
 
   /* Install default VTY commands to new nodes.  */
   install_default (BGP_NODE);
@@ -10229,6 +10254,7 @@ bgp_vty_init (void)
   install_default (BGP_VPNV6_NODE);
   install_default (BGP_ENCAP_NODE);
   install_default (BGP_ENCAPV6_NODE);
+  install_default (BGP_EVPN_NODE);
   
   install_element (BGP_NODE, _vrf_cmd);
   install_element (BGP_NODE, _vrf_exports_cmd);
@@ -10410,6 +10436,7 @@ bgp_vty_init (void)
   install_element (BGP_VPNV6_NODE, _activate_cmd);
   install_element (BGP_ENCAP_NODE, _activate_cmd);
   install_element (BGP_ENCAPV6_NODE, _activate_cmd);
+  install_element (BGP_EVPN_NODE, _activate_cmd);
 
   /* "no neighbor activate" commands. */
   install_element (BGP_NODE, _neighbor_activate_cmd);
@@ -10421,6 +10448,7 @@ bgp_vty_init (void)
   install_element (BGP_VPNV6_NODE, _neighbor_activate_cmd);
   install_element (BGP_ENCAP_NODE, _neighbor_activate_cmd);
   install_element (BGP_ENCAPV6_NODE, _neighbor_activate_cmd);
+  install_element (BGP_EVPN_NODE, _neighbor_activate_cmd);
 
   /* "neighbor peer-group set" commands. */
   install_element (BGP_NODE, _set_peer_group_cmd);
@@ -10667,6 +10695,29 @@ bgp_vty_init (void)
   install_element (BGP_ENCAPV6_NODE, _neighbor_attr_unchanged9_cmd);
   install_element (BGP_ENCAPV6_NODE, _neighbor_attr_unchanged10_cmd);
 
+  install_element (BGP_EVPN_NODE, _attr_unchanged_cmd);
+  install_element (BGP_EVPN_NODE, _attr_unchanged1_cmd);
+  install_element (BGP_EVPN_NODE, _attr_unchanged2_cmd);
+  install_element (BGP_EVPN_NODE, _attr_unchanged3_cmd);
+  install_element (BGP_EVPN_NODE, _attr_unchanged4_cmd);
+  install_element (BGP_EVPN_NODE, _attr_unchanged5_cmd);
+  install_element (BGP_EVPN_NODE, _attr_unchanged6_cmd);
+  install_element (BGP_EVPN_NODE, _attr_unchanged7_cmd);
+  install_element (BGP_EVPN_NODE, _attr_unchanged8_cmd);
+  install_element (BGP_EVPN_NODE, _attr_unchanged9_cmd);
+  install_element (BGP_EVPN_NODE, _attr_unchanged10_cmd);
+  install_element (BGP_EVPN_NODE, _neighbor_attr_unchanged_cmd);
+  install_element (BGP_EVPN_NODE, _neighbor_attr_unchanged1_cmd);
+  install_element (BGP_EVPN_NODE, _neighbor_attr_unchanged2_cmd);
+  install_element (BGP_EVPN_NODE, _neighbor_attr_unchanged3_cmd);
+  install_element (BGP_EVPN_NODE, _neighbor_attr_unchanged4_cmd);
+  install_element (BGP_EVPN_NODE, _neighbor_attr_unchanged5_cmd);
+  install_element (BGP_EVPN_NODE, _neighbor_attr_unchanged6_cmd);
+  install_element (BGP_EVPN_NODE, _neighbor_attr_unchanged7_cmd);
+  install_element (BGP_EVPN_NODE, _neighbor_attr_unchange

[quagga-dev 16337] [PATCH 02/57] bgpd: vpnv4 af exports extended communities

2016-10-28 Thread Philippe Guibert
If the user preconfigures a vrf with import and export rules, before
creating a new network on vpnv4 address, then BGP update emitted will
contain the exported rts mentioned by the vrf export rule.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_route.c | 11 +++
 bgpd/bgp_route.h |  2 ++
 2 files changed, 13 insertions(+)

diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index eb0c9e50094f..01d3ef008cdb 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -3961,6 +3961,11 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix 
*p,
   attr.med = bgp_static->igpmetric;
   attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
 
+  if (bgp_static->ecomm)
+{
+  bgp_attr_extra_get ()->ecommunity = ecommunity_dup 
(bgp_static->ecomm);
+  attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
+}
   /* Apply route-map. */
   if (bgp_static->rmap.name)
 {
@@ -4261,6 +4266,7 @@ bgp_static_set_safi (safi_t safi, struct vty *vty, const 
char *ip_str,
   struct bgp_node *rn;
   struct bgp_table *table;
   struct bgp_static *bgp_static;
+  struct bgp_vrf *vrf;
   u_char tag[3];
 
   bgp = vty->index;
@@ -4311,6 +4317,11 @@ bgp_static_set_safi (safi_t safi, struct vty *vty, const 
char *ip_str,
   bgp_static->igpmetric = 0;
   bgp_static->igpnexthop.s_addr = 0;
   memcpy(bgp_static->tag, tag, 3);
+  vrf = bgp_vrf_lookup(bgp, );
+  if (vrf)
+{
+  bgp_static->ecomm = vrf->rt_export;
+}
   bgp_static->prd = prd;
 
   if (rmap_str)
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index 25a42e87bd94..642839d6d59f 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -137,6 +137,8 @@ struct bgp_static
   /* Route Distinguisher */
   struct prefix_rd prd;
 
+  struct ecommunity*ecomm;
+
   /* MPLS label.  */
   u_char tag[3];
 };
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16349] [PATCH 19/57] vtysh: add support of address-family evpn

2016-10-28 Thread Philippe Guibert
From: Julien Courtat 

Update extract.pl ignore list to prevent from installing
address_family_evpn_cmd twice and have "Ambiguous command" return by
vtysh when trying to configure address-family evpn.

Signed-off-by: Julien Courtat 
---
 vtysh/extract.pl.in | 1 +
 1 file changed, 1 insertion(+)

diff --git a/vtysh/extract.pl.in b/vtysh/extract.pl.in
index 924cffe2cb86..e7f37c83a454 100755
--- a/vtysh/extract.pl.in
+++ b/vtysh/extract.pl.in
@@ -53,6 +53,7 @@ $ignore{'"address-family ipv4 vrf NAME"'} = "ignore";
 $ignore{'"address-family encap"'} = "ignore";
 $ignore{'"address-family encapv4"'} = "ignore";
 $ignore{'"address-family encapv6"'} = "ignore";
+$ignore{'"address-family evpn"'} = "ignore";
 $ignore{'"exit-address-family"'} = "ignore";
 $ignore{'"key chain WORD"'} = "ignore";
 $ignore{'"key <0-2147483647>"'} = "ignore";
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16336] [PATCH 03/57] tests: enhance bgpd testing with label value

2016-10-28 Thread Philippe Guibert
bgp NLRI has a specific format for label, terminating with bottom
of stack bit. This value is updated in all BGP attribute tests. A
specific test has been added to check for a list of labels contained
in a single NLRI.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 tests/bgp_mp_attr_test.c   | 87 ++
 tests/bgpd.tests/testbgpmpattr.exp |  2 +
 2 files changed, 71 insertions(+), 18 deletions(-)

diff --git a/tests/bgp_mp_attr_test.c b/tests/bgp_mp_attr_test.c
index 3b1bf1452cf8..7d6d8293c298 100644
--- a/tests/bgp_mp_attr_test.c
+++ b/tests/bgp_mp_attr_test.c
@@ -322,13 +322,13 @@ static struct test_segment {
   /* Nexthop */192, 168,   0,  1, 
   /* SNPA (defunct, MBZ) */0x0,
   /* NLRI tuples */88 + 16,
-  0, 1, 2,   /* tag */
+  0, 1, 1,   /* tag */
   /* rd, 8 octets */
 0, 0, /* RD_TYPE_AS */
 0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
   10, 1,/* 10.1/16 */
 88 + 17,
-  0xff, 0, 0,   /* tag */
+  2, 43, 1,   /* tag */
   /* rd, 8 octets */
 0, 0, /* RD_TYPE_IP */
 192, 168, 0, 1, /* IPv4 */
@@ -365,13 +365,13 @@ static struct test_segment {
   /* Nexthop */192, 168,   0,  1, 
   /* SNPA (defunct, MBZ) */0x0,
   /* NLRI tuples */88 + 1,
-  0, 1, 2,   /* tag */
+  0, 2, 1,   /* tag with BOS bit set */
   /* rd, 8 octets */
 0, 0, /* RD_TYPE_AS */
 0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
   10, 1,/* 10.1/16 */
 88 + 17,
-  0xff, 0, 0,   /* tag */
+  3, 4, 1,   /* tag with BOS bit set */
   /* rd, 8 octets */
 0, 0, /* RD_TYPE_IP */
 192, 168, 0, 1, /* IPv4 */
@@ -391,13 +391,13 @@ static struct test_segment {
   /* Nexthop */192, 168,   0,  1, 
   /* SNPA (defunct, MBZ) */0x0,
   /* NLRI tuples */88 + 32,
-  0, 1, 2,   /* tag */
+  0, 2, 1,   /* tag  with BOS bit */
   /* rd, 8 octets */
 0, 0, /* RD_TYPE_AS */
 0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
   10, 1,/* 10.1/16 */
 88 + 17,
-  0xff, 0, 0,   /* tag */
+  3, 4, 1,   /* tag with BOS bit set */
   /* rd, 8 octets */
 0, 0, /* RD_TYPE_IP */
 192, 168, 0, 1, /* IPv4 */
@@ -417,13 +417,13 @@ static struct test_segment {
   /* Nexthop */192, 168,   0,  1, 
   /* SNPA (defunct, MBZ) */0x0,
   /* NLRI tuples */88 + 16,
-  0, 1, 2,   /* tag */
+  0, 2, 1,   /* tag  with BOS bit */
   /* rd, 8 octets */
 0, 0, /* RD_TYPE_AS */
 0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
   10, 1,/* 10.1/16 */
 88 + 17,
-  0xff, 0, 0,   /* tag */
+  3, 4, 1,   /* tag with BOS bit set */
   /* rd, 8 octets */
 0, 0, /* RD_TYPE_IP */
 192, 168, 0, 1, /* IPv4 */
@@ -444,13 +444,13 @@ static struct test_segment {
   /* Nexthop */192, 168,   0,  1, 
   /* SNPA (defunct, MBZ) */0x0,
   /* NLRI tuples */88 + 16,
-  0, 1, 2,   /* tag */
+  0, 2, 1,   /* tag  with BOS bit */
   /* rd, 8 octets */
 0, 0, /* RD_TYPE_AS */
 0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
   10, 1,/* 10.1/16 */
 88 + 2,
-  0xff, 0, 0,   

[quagga-dev 16351] [PATCH 17/57] bgpd: basic support for EVPN

2016-10-28 Thread Philippe Guibert
To handle BGP NLRI EVPN messages, bgp is modified to handle AFI_L2VPN
and SAFI_EVPN values.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_attr.c   | 25 ++-
 bgpd/bgp_open.c   | 29 ++-
 bgpd/bgp_packet.c | 28 --
 bgpd/bgp_route.c  | 60 ++-
 bgpd/bgp_vty.c|  2 ++
 bgpd/bgpd.c   | 20 +++
 6 files changed, 130 insertions(+), 34 deletions(-)

diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index b46e7a30e3f7..8741c4af3441 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -2396,9 +2396,16 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, 
safi_t safi,
   sizep = stream_get_endp (s);
   stream_putw (s, 0);  /* Marker: Attribute length. */
 
-  stream_putw (s, afi);
-  stream_putc (s, (safi == SAFI_MPLS_VPN) ? SAFI_MPLS_LABELED_VPN : safi);
-
+  if(afi == AFI_INTERNAL_L2VPN)
+stream_putw (s, AFI_L2VPN);
+  else
+stream_putw (s, afi);
+  if(safi == SAFI_MPLS_VPN)
+stream_putc (s, SAFI_MPLS_LABELED_VPN);
+  else if(safi == SAFI_INTERNAL_EVPN)
+stream_putc (s, SAFI_EVPN);
+  else
+stream_putc (s, safi);
   /* Nexthop */
   switch (afi)
 {
@@ -2987,8 +2994,16 @@ bgp_packet_mpunreach_start (struct stream *s, afi_t afi, 
safi_t safi)
   attrlen_pnt = stream_get_endp (s);
   stream_putw (s, 0);  /* Length of this attribute. */
 
-  stream_putw (s, afi);
-  stream_putc (s, (safi == SAFI_MPLS_VPN) ? SAFI_MPLS_LABELED_VPN : safi);
+  if(afi == AFI_INTERNAL_L2VPN)
+stream_putw (s, AFI_L2VPN);
+  else
+stream_putw (s, afi);
+  if(safi == SAFI_MPLS_VPN)
+stream_putc (s, SAFI_MPLS_LABELED_VPN);
+  else if(safi == SAFI_INTERNAL_EVPN)
+stream_putc (s, SAFI_EVPN);
+  else
+stream_putc (s, safi);
   return attrlen_pnt;
 }
 
diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c
index 7b8b6577e078..5ce838b899dc 100644
--- a/bgpd/bgp_open.c
+++ b/bgpd/bgp_open.c
@@ -82,6 +82,9 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer)
case AFI_IP6:
  vty_out (vty, "AFI IPv6, ");
  break;
+   case AFI_L2VPN:
+ vty_out (vty, "AFI L2VPN, ");
+ break;
default:
  vty_out (vty, "AFI Unknown %d, ", ntohs (mpc.afi));
  break;
@@ -100,6 +103,9 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer)
case SAFI_ENCAP:
  vty_out (vty, "SAFI ENCAP");
  break;
+   case SAFI_EVPN:
+ vty_out (vty, "SAFI EVPN");
+ break;
default:
  vty_out (vty, "SAFI Unknown %d ", mpc.safi);
  break;
@@ -143,6 +149,12 @@ bgp_afi_safi_valid_indices (afi_t afi, safi_t *safi)
case SAFI_ENCAP:
  return 1;
}
+case AFI_INTERNAL_L2VPN:
+  switch (*safi)
+   {
+case SAFI_INTERNAL_EVPN:
+  return 1;
+}
   break;
 }
 
@@ -849,7 +861,8 @@ bgp_open_option_parse (struct peer *peer, u_char length, 
int *mp_capability)
  && ! peer->afc_nego[AFI_IP6][SAFI_UNICAST]
  && ! peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
  && ! peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]
- && ! peer->afc_nego[AFI_IP6][SAFI_ENCAP])
+ && ! peer->afc_nego[AFI_IP6][SAFI_ENCAP]
+ && ! peer->afc_nego[AFI_INTERNAL_L2VPN][SAFI_INTERNAL_EVPN])
{
  plog_err (peer->log, "%s [Error] Configured AFI/SAFIs do not "
"overlap with received MP capabilities",
@@ -884,6 +897,8 @@ bgp_open_capability_orf (struct stream *s, struct peer 
*peer,
 
   if (safi == SAFI_MPLS_VPN)
 safi = SAFI_MPLS_LABELED_VPN;
+  else if (safi == SAFI_INTERNAL_EVPN)
+safi = SAFI_EVPN;
 
   stream_putc (s, BGP_OPEN_OPT_CAP);
   capp = stream_get_endp (s);   /* Set Capability Len Pointer */
@@ -1054,6 +1069,18 @@ bgp_open_capability (struct stream *s, struct peer *peer)
   stream_putc (s, 0);
   stream_putc (s, SAFI_ENCAP);
 }
+  /* IPv6 ENCAP. */
+  if (peer->afc[AFI_INTERNAL_L2VPN][SAFI_INTERNAL_EVPN])
+{
+  peer->afc_adv[AFI_INTERNAL_L2VPN][SAFI_INTERNAL_EVPN] = 1;
+  stream_putc (s, BGP_OPEN_OPT_CAP);
+  stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
+  stream_putc (s, CAPABILITY_CODE_MP);
+  stream_putc (s, CAPABILITY_CODE_MP_LEN);
+  stream_putw (s, AFI_L2VPN);
+  stream_putc (s, 0);
+  stream_putc (s, SAFI_EVPN);
+}
 
   /* Route refresh. */
   SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 8e315d1dbc80..db569b876424 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -650,7 +650,8 @@ bgp_write_packet (struct peer *peer)
  CHECK_F

[quagga-dev 16341] [PATCH 10/57] bgpd: VRF RIB log updates enhancement

2016-10-28 Thread Philippe Guibert
On adding/removing/updating NLRI entries into VRF RIB tables, a BGP
event is fired. Note that only selected entries, and entries that are
part of multipath entries, and where one of the multipath entry is
selected.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_route.c | 105 +--
 bgpd/bgp_route.h |   2 ++
 bgpd/bgpd.c  |  16 +
 bgpd/bgpd.h  |   3 ++
 4 files changed, 124 insertions(+), 2 deletions(-)

diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 5b70478870d2..e83f292162ba 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -1572,6 +1572,60 @@ void bgp_vrf_clean_tables (struct bgp_vrf *vrf)
 }
 }
 
+/* messages sent to ODL to signify that an entry
+ * has been selected, or unselected
+ */
+void
+bgp_vrf_update (struct bgp_vrf *vrf, afi_t afi, struct bgp_node *rn,
+struct bgp_info *selected, uint8_t announce)
+{
+  if(!vrf || (rn && bgp_node_table (rn)->type != BGP_TABLE_VRF))
+return;
+  if (announce == true)
+{
+  if(CHECK_FLAG (selected->flags, BGP_INFO_UPDATE_SENT))
+return;
+  SET_FLAG (selected->flags, BGP_INFO_UPDATE_SENT);
+  UNSET_FLAG (selected->flags, BGP_INFO_WITHDRAW_SENT);
+}
+  else
+{
+  /* if not already sent, do nothing */
+  if(!CHECK_FLAG (selected->flags, BGP_INFO_UPDATE_SENT))
+return;
+  if(CHECK_FLAG (selected->flags, BGP_INFO_WITHDRAW_SENT))
+return;
+  SET_FLAG (selected->flags, BGP_INFO_WITHDRAW_SENT);
+  UNSET_FLAG (selected->flags, BGP_INFO_UPDATE_SENT);
+}
+  if (BGP_DEBUG (events, EVENTS))
+{
+  char vrf_rd_str[RD_ADDRSTRLEN], rd_str[RD_ADDRSTRLEN], 
pfx_str[INET6_BUFSIZ];
+  char label_str[BUFSIZ] = "", nh_str[BUFSIZ] = "";
+
+  prefix_rd2str(>outbound_rd, vrf_rd_str, sizeof(vrf_rd_str));
+  prefix_rd2str(>extra->vrf_rd, rd_str, sizeof(rd_str));
+  prefix2str(>p, pfx_str, sizeof(pfx_str));
+  labels2str(label_str, sizeof(label_str),
+  selected->extra->labels, selected->extra->nlabels);
+
+  if (selected->attr && selected->attr->extra)
+{
+  if (afi == AFI_IP)
+strcpy (nh_str, inet_ntoa 
(selected->attr->extra->mp_nexthop_global_in));
+  else if (afi == AFI_IP6)
+inet_ntop (AF_INET6, >attr->extra->mp_nexthop_global, 
nh_str, BUFSIZ);
+}
+
+  if (announce)
+zlog_debug ("vrf[%s] %s: prefix updated, best RD %s labels %s nexthop 
%s",
+   vrf_rd_str, pfx_str, rd_str, label_str, nh_str);
+  else
+zlog_debug ("vrf[%s] %s: prefix withdrawn nh %s label %s",
+vrf_rd_str, pfx_str, nh_str, label_str);
+}
+}
+
 /* updates selected bgp_info structure to bgp vrf rib table
  * most of the cases, processing consists in adding or removing entries in RIB 
tables
  * on some cases, there is an update request. then it is necessary to have 
both old and new ri
@@ -2098,9 +2152,13 @@ bgp_process_vrf_main (struct work_queue *wq, void *data)
   struct bgp_node *rn = pq->rn;
   afi_t afi = pq->afi;
   safi_t safi = pq->safi;
-  struct bgp_info *new_select;
+  struct bgp_info *new_select, *ri;
   struct bgp_info *old_select;
   struct bgp_info_pair old_and_new;
+  struct bgp_vrf *vrf = NULL;
+
+  if(rn)
+vrf = bgp_vrf_lookup_per_rn(bgp, afi, rn);
 
   /* Best path selection. */
   bgp_best_selection (bgp, rn, _and_new, afi, safi);
@@ -2117,6 +2175,13 @@ bgp_process_vrf_main (struct work_queue *wq, void *data)
 {
   UNSET_FLAG (old_select->flags, BGP_INFO_MULTIPATH_CHG);
   SET_FLAG (old_select->flags, BGP_INFO_MULTIPATH);
+  for(ri = rn->info; ri; ri = ri->next)
+{
+  if(ri == old_select)
+continue;
+  if(!bgp_is_mpath_entry(ri, new_select))
+bgp_vrf_update(vrf, afi, rn, ri, false);
+}
 }
   /* no zebra announce */
  UNSET_FLAG (old_select->flags, BGP_INFO_MULTIPATH_CHG);
@@ -2138,18 +2203,53 @@ bgp_process_vrf_main (struct work_queue *wq, void *data)
 {
   if( CHECK_FLAG (old_select->flags, BGP_INFO_SELECTED))
 {
-  if(bgp_is_mpath_entry(old_select, new_select))
+  if(!bgp_is_mpath_entry(old_select, new_select))
+{
+  bgp_vrf_update(vrf, afi, rn, old_select, false);
+}
+  else
 {
   UNSET_FLAG (old_select->flags, BGP_INFO_MULTIPATH_CHG);
   SET_FLAG (old_select->flags, BGP_INFO_MULTIPATH);
 }
 }
+  /* withdraw mp entries which could have been removed
+   * and that a update has previously been sent
+   */
+  for(r

[quagga-dev 16347] [PATCH 15/57] bgpd: avoid looping when unselecting a list of mpath entries

2016-10-28 Thread Philippe Guibert
sometimes, when electing best route algorithm, a static route
may be injected, thus causing all old multipath entries to be
removed from multipath list. As a loop is removing each mpath
entry from mpath list, it is necessary to update the pointer.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_mpath.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c
index 46d813984741..b47cdad95909 100644
--- a/bgpd/bgp_mpath.c
+++ b/bgpd/bgp_mpath.c
@@ -615,6 +615,7 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info 
*new_best,
   sockunion2str (cur_mpath->peer->su_remote,
  nh_buf[1], sizeof (nh_buf[1])));
 }
+  mp_node = mp_next_node;
   cur_mpath = next_mpath;
 }
   else
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16334] [PATCH 01/57] bgpd: VRF vty configuration, RIB table creation

2016-10-28 Thread Philippe Guibert
This commit introduces the BGP VRF configuration, and BGP VRF RIB
table.
It includes the ability for a BGP to configure its own route
distinguisher ( aka VRF). New vty commands introduced:

(config-router)# vrf rd 

This structure permits configuring import and export route targets,
which is defined by RFC4360.
(config-router)# vrf rd  exports 
(config-router)# vrf rd  imports 

It brings some improvements.
- for a BGP speaker when emitting BGP updates, the exported route
targets will be mapped to BGP extended communities associated with
the BGP update for the defined Route distinguisher.
This commit does not enhance the support for emitting those BGP
extended communities, but provides the mecanism.
- for a BGP speaker when receiving BGP updaets. Its import route
target will be looked up, in order to match NLRI route distinguisher.
Then, if matching, the entry would be exported to a RIB per VRF table.

As mentioned before, the commit also introduces a BGP VRF RIB table per
Route distinguisher configured. This table aims at receiving BGP NLRI
entries, with matching import and export route targets.
This commit does not take into account the fullfill of this table,
but creates it.

Signed-off-by: David Lamparter <equi...@opensourcerouting.org>
Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_route.c | 192 +++--
 bgpd/bgp_route.h |   4 ++
 bgpd/bgp_table.h |   3 +
 bgpd/bgp_vty.c   | 177 +
 bgpd/bgpd.c  | 199 ++-
 bgpd/bgpd.h  |  58 +---
 lib/memtypes.c   |   2 +
 7 files changed, 621 insertions(+), 14 deletions(-)

diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 4cb6c141bcdc..eb0c9e50094f 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -34,6 +34,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, 
Boston, MA
 #include "plist.h"
 #include "thread.h"
 #include "workqueue.h"
+#include "hash.h"
 
 #include "bgpd/bgpd.h"
 #include "bgpd/bgp_table.h"
@@ -61,6 +62,12 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, 
Boston, MA
 extern const char *bgp_origin_str[];
 extern const char *bgp_origin_long_str[];
 
+static void
+bgp_static_withdraw_safi (struct bgp *bgp, struct prefix *p, afi_t afi,
+  safi_t safi, struct prefix_rd *prd, u_char *tag);
+static void
+bgp_static_free (struct bgp_static *bgp_static);
+
 static struct bgp_node *
 bgp_afi_node_get (struct bgp_table *table, afi_t afi, safi_t safi, struct 
prefix *p,
  struct prefix_rd *prd)
@@ -77,7 +84,11 @@ bgp_afi_node_get (struct bgp_table *table, afi_t afi, safi_t 
safi, struct prefix
   prn = bgp_node_get (table, (struct prefix *) prd);
 
   if (prn->info == NULL)
-   prn->info = bgp_table_init (afi, safi);
+{
+  struct bgp_table *newtab = bgp_table_init (afi, safi);
+  newtab->prd = *prd;
+  prn->info = newtab;
+}
   else
bgp_unlock_node (prn);
   table = prn->info;
@@ -1505,12 +1516,86 @@ bgp_process_announce_selected (struct peer *peer, 
struct bgp_info *selected,
 else
  bgp_adj_out_unset (rn, peer, p, afi, safi);
 break;
+  case BGP_TABLE_VRF:
+/* never called */
+assert (0);
 }
 
   bgp_attr_flush ();
   return 0;
 }
 
+void bgp_vrf_clean_tables (struct bgp_vrf *vrf)
+{
+  afi_t afi;
+  for (afi = AFI_IP; afi < AFI_MAX; afi++)
+{
+  struct bgp_info *ri, *ri_next;
+  struct bgp_node *rn;
+
+  for (rn = bgp_table_top (vrf->rib[afi]); rn; rn = bgp_route_next (rn))
+for (ri = rn->info; ri; ri = ri_next)
+  {
+ri_next = ri->next;
+bgp_info_reap (rn, ri);
+  }
+  bgp_table_finish (>rib[afi]);
+
+  for (rn = bgp_table_top (vrf->route[afi]); rn; rn = bgp_route_next (rn))
+if (rn->info)
+  {
+struct bgp_static *bs = rn->info;
+bgp_static_withdraw_safi (vrf->bgp, >p, afi, SAFI_MPLS_VPN,
+>outbound_rd, NULL);
+bgp_static_free (bs);
+rn->info = NULL;
+bgp_unlock_node (rn);
+  }
+  bgp_table_finish (>route[afi]);
+}
+}
+
+void
+bgp_vrf_apply_new_imports (struct bgp_vrf *vrf, afi_t afi)
+{
+  struct bgp_node *rd_rn, *rn;
+  struct bgp_info *sel;
+  struct bgp_table *table;
+  struct ecommunity *ecom;
+  size_t i, j;
+  bool found;
+
+  if (!vrf->rt_import || vrf->rt_import->size == 0)
+return;
+
+  for (rd_rn = bgp_table_top (vrf->bgp->rib[afi][SAFI_MPLS_VPN]); rd_rn;
+  rd_rn = bgp_route_next (rd_rn))
+if (rd_rn->info != NULL)
+  {
+table = rd_rn->info;
+
+for (rn = bgp_table_top (table); rn; rn = bgp

[quagga-dev 16335] [PATCH 04/57] lib: 3byte stream foo

2016-10-28 Thread Philippe Guibert
From: David Lamparter <equi...@opensourcerouting.org>

API enhancement to be able to write and read 3 byte series in
stream structures.

Signed-off-by: David Lamparter <equi...@opensourcerouting.org>
Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 lib/stream.c | 77 
 lib/stream.h |  4 
 2 files changed, 81 insertions(+)

diff --git a/lib/stream.c b/lib/stream.c
index b50992d6a9c2..0296d981c86e 100644
--- a/lib/stream.c
+++ b/lib/stream.c
@@ -379,6 +379,47 @@ stream_getw_from (struct stream *s, size_t from)
   return w;
 }
 
+/* Get next 3-byte from the stream. */
+u_int32_t
+stream_get3_from (struct stream *s, size_t from)
+{
+  u_int32_t l;
+
+  STREAM_VERIFY_SANE(s);
+  
+  if (!GETP_VALID (s, from + 3))
+{
+  STREAM_BOUND_WARN (s, "get 3byte");
+  return 0;
+}
+  
+  l  = s->data[from++] << 16;
+  l |= s->data[from++] << 8;
+  l |= s->data[from];
+  
+  return l;
+}
+
+u_int32_t
+stream_get3 (struct stream *s)
+{
+  u_int32_t l;
+
+  STREAM_VERIFY_SANE(s);
+  
+  if (STREAM_READABLE (s) < 3)
+{
+  STREAM_BOUND_WARN (s, "get 3byte");
+  return 0;
+}
+  
+  l  = s->data[s->getp++] << 16;
+  l |= s->data[s->getp++] << 8;
+  l |= s->data[s->getp++];
+  
+  return l;
+}
+
 /* Get next long word from the stream. */
 u_int32_t
 stream_getl_from (struct stream *s, size_t from)
@@ -589,6 +630,25 @@ stream_putw (struct stream *s, u_int16_t w)
 
 /* Put long word to the stream. */
 int
+stream_put3 (struct stream *s, u_int32_t l)
+{
+  STREAM_VERIFY_SANE (s);
+
+  if (STREAM_WRITEABLE (s) < 3)
+{
+  STREAM_BOUND_WARN (s, "put");
+  return 0;
+}
+  
+  s->data[s->endp++] = (u_char)(l >> 16);
+  s->data[s->endp++] = (u_char)(l >>  8);
+  s->data[s->endp++] = (u_char)l;
+
+  return 3;
+}
+
+/* Put long word to the stream. */
+int
 stream_putl (struct stream *s, u_int32_t l)
 {
   STREAM_VERIFY_SANE (s);
@@ -696,6 +756,23 @@ stream_putw_at (struct stream *s, size_t putp, u_int16_t w)
 }
 
 int
+stream_put3_at (struct stream *s, size_t putp, u_int32_t l)
+{
+  STREAM_VERIFY_SANE(s);
+  
+  if (!PUT_AT_VALID (s, putp + 3))
+{
+  STREAM_BOUND_WARN (s, "put");
+  return 0;
+}
+  s->data[putp] = (u_char)(l >> 16);
+  s->data[putp + 1] = (u_char)(l >>  8);
+  s->data[putp + 2] = (u_char)l;
+  
+  return 3;
+}
+
+int
 stream_putl_at (struct stream *s, size_t putp, u_int32_t l)
 {
   STREAM_VERIFY_SANE(s);
diff --git a/lib/stream.h b/lib/stream.h
index 06b0ee12cf26..70d0a2fffcb9 100644
--- a/lib/stream.h
+++ b/lib/stream.h
@@ -167,6 +167,8 @@ extern int stream_putc (struct stream *, u_char);
 extern int stream_putc_at (struct stream *, size_t, u_char);
 extern int stream_putw (struct stream *, u_int16_t);
 extern int stream_putw_at (struct stream *, size_t, u_int16_t);
+extern int stream_put3 (struct stream *, u_int32_t);
+extern int stream_put3_at (struct stream *, size_t, u_int32_t);
 extern int stream_putl (struct stream *, u_int32_t);
 extern int stream_putl_at (struct stream *, size_t, u_int32_t);
 extern int stream_putq (struct stream *, uint64_t);
@@ -180,6 +182,8 @@ extern u_char stream_getc (struct stream *);
 extern u_char stream_getc_from (struct stream *, size_t);
 extern u_int16_t stream_getw (struct stream *);
 extern u_int16_t stream_getw_from (struct stream *, size_t);
+extern u_int32_t stream_get3 (struct stream *);
+extern u_int32_t stream_get3_from (struct stream *, size_t);
 extern u_int32_t stream_getl (struct stream *);
 extern u_int32_t stream_getl_from (struct stream *, size_t);
 extern uint64_t stream_getq (struct stream *);
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16354] [PATCH 18/57] bgpd: bgp open graceful restart capability fix with mpls

2016-10-28 Thread Philippe Guibert
If vpnv4 capability has to be sent, then the correct safi parameter
is sent instead of internal value.
In case BGP open graceful restart capability is applied to EVPN, then
the flags to be set are modified to be official afi and safi parameters,
and not internal value.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_open.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c
index 5ce838b899dc..4e5ef30ccf2d 100644
--- a/bgpd/bgp_open.c
+++ b/bgpd/bgp_open.c
@@ -1149,8 +1149,16 @@ bgp_open_capability (struct stream *s, struct peer *peer)
 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
   if (peer->afc[afi][safi])
 {
-  stream_putw (s, afi);
-  stream_putc (s, safi);
+  if(afi == AFI_INTERNAL_L2VPN)
+stream_putw (s, AFI_L2VPN);
+  else
+stream_putw (s, afi);
+  if(safi == SAFI_MPLS_VPN)
+stream_putc (s, SAFI_MPLS_LABELED_VPN);
+  else if(safi == SAFI_INTERNAL_EVPN)
+stream_putc (s, SAFI_EVPN );
+  else
+stream_putc (s, safi);
   stream_putc (s, 0); //Forwarding is not retained as of now.
 }
 }
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16338] [PATCH 07/57] bgpd: BGP VRF processing handling

2016-10-28 Thread Philippe Guibert
NLRI entries received from MP-BGP peer exchange are exported in VRF RIB
tables. This commit introduces the BGP VRF processing handler that can
be used for further processing into VRF RIB tables: best selection
algorithm, multipath.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_main.c  |  5 
 bgpd/bgp_route.c | 91 +---
 bgpd/bgp_route.h |  3 ++
 bgpd/bgpd.c  |  5 
 bgpd/bgpd.h  |  1 +
 5 files changed, 95 insertions(+), 10 deletions(-)

diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
index af9c03052020..51a2770a5ead 100644
--- a/bgpd/bgp_main.c
+++ b/bgpd/bgp_main.c
@@ -258,6 +258,11 @@ bgp_exit (int status)
   work_queue_free (bm->process_rsclient_queue);
   bm->process_rsclient_queue = NULL;
 }
+  if (bm->process_vrf_queue)
+{
+ work_queue_free (bm->process_vrf_queue);
+ bm->process_vrf_queue = NULL;
+}
   
   /* reverse bgp_master_init */
   for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, socket))
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 3aa421ea400a..615cd375bb78 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -1338,7 +1338,6 @@ bgp_best_selection (struct bgp *bgp, struct bgp_node *rn,
   
   bgp_mp_list_init (_list);
   do_mpath = bgp_mpath_is_configured (bgp, afi, safi);
-
   /* bgp deterministic-med */
   new_select = NULL;
   if (bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED))
@@ -1707,7 +1706,7 @@ bgp_process_main (struct work_queue *wq, void *data)
   UNSET_FLAG(rn->flags, BGP_NODE_USER_CLEAR);
 
   if (old_select)
-bgp_info_unset_flag (rn, old_select, BGP_INFO_SELECTED);
+  bgp_info_unset_flag (rn, old_select, BGP_INFO_SELECTED);
   if (new_select)
 {
   bgp_info_set_flag (rn, new_select, BGP_INFO_SELECTED);
@@ -1715,7 +1714,6 @@ bgp_process_main (struct work_queue *wq, void *data)
   UNSET_FLAG (new_select->flags, BGP_INFO_MULTIPATH_CHG);
 }
 
-
   /* Check each BGP peer. */
   for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
 {
@@ -1748,6 +1746,65 @@ bgp_process_main (struct work_queue *wq, void *data)
   return WQ_SUCCESS;
 }
 
+/* processing done for BGP VRF tables */
+static wq_item_status
+bgp_process_vrf_main (struct work_queue *wq, void *data)
+{
+  struct bgp_process_queue *pq = data;
+  struct bgp *bgp = pq->bgp;
+  struct bgp_node *rn = pq->rn;
+  afi_t afi = pq->afi;
+  safi_t safi = pq->safi;
+  struct bgp_info *new_select;
+  struct bgp_info *old_select;
+  struct bgp_info_pair old_and_new;
+
+  /* Best path selection. */
+  bgp_best_selection (bgp, rn, _and_new, afi, safi);
+  old_select = old_and_new.old;
+  new_select = old_and_new.new;
+
+  /* Nothing to do. */
+  if (old_select && old_select == new_select)
+{
+  if (! CHECK_FLAG (old_select->flags, BGP_INFO_ATTR_CHANGED))
+{
+  /* no zebra announce */
+ UNSET_FLAG (old_select->flags, BGP_INFO_MULTIPATH_CHG);
+  UNSET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
+  return WQ_SUCCESS;
+}
+}
+  if (old_select && new_select)
+{
+  if(!CHECK_FLAG (new_select->flags, BGP_INFO_MULTIPATH_CHG) &&
+ !CHECK_FLAG (new_select->flags, BGP_INFO_ATTR_CHANGED))
+{
+  UNSET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
+  return WQ_SUCCESS;
+}
+}
+
+  if (old_select)
+{
+  bgp_info_unset_flag (rn, old_select, BGP_INFO_SELECTED);
+}
+  if (new_select)
+{
+  bgp_info_set_flag (rn, new_select, BGP_INFO_SELECTED);
+  bgp_info_unset_flag (rn, new_select, BGP_INFO_ATTR_CHANGED);
+  UNSET_FLAG (new_select->flags, BGP_INFO_MULTIPATH_CHG);
+}
+
+  /* Reap old select bgp_info, if it has been removed */
+  if (old_select && CHECK_FLAG (old_select->flags, BGP_INFO_REMOVED))
+bgp_info_reap (rn, old_select);
+
+  UNSET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
+  return WQ_SUCCESS;
+  /* no announce */
+}
+
 static void
 bgp_processq_del (struct work_queue *wq, void *data)
 {
@@ -1767,8 +1824,10 @@ bgp_process_queue_init (void)
 = work_queue_new (bm->master, "process_main_queue");
   bm->process_rsclient_queue
 = work_queue_new (bm->master, "process_rsclient_queue");
+  bm->process_vrf_queue
+= work_queue_new (bm->master, "process_vrf_queue");
   
-  if ( !(bm->process_main_queue && bm->process_rsclient_queue) )
+  if ( !(bm->process_main_queue && bm->process_rsclient_queue && 
bm->process_vrf_queue) )
 {
   zlog_err ("%s: Failed to allocate work queue", __func__);
   exit (1);
@@ -1783,6 +1842,12 @@ bgp_process_queue_init (void)
   bm->process_rsclient_queue->spec.del_item_data = _processq_del;
   bm->process_rsclient_queue->spec.max_retries = 0;
   bm->process_rsclient_queue->spec.hol

[quagga-dev 16352] [PATCH 21/57] bgpd: safi_valid_indices ability to return internal afi identifier

2016-10-28 Thread Philippe Guibert
Because afi numbers can reach high values, a conversion is necessary
to return associate afi internal identifier. The safi_valid_indices
API has been changed for that.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_open.c   | 22 +++---
 bgpd/bgp_open.h   |  2 +-
 bgpd/bgp_packet.c |  6 +++---
 3 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c
index 4e5ef30ccf2d..75c840ef4958 100644
--- a/bgpd/bgp_open.c
+++ b/bgpd/bgp_open.c
@@ -132,9 +132,9 @@ bgp_capability_mp_data (struct stream *s, struct 
capability_mp_data *mpc)
 }
 
 int
-bgp_afi_safi_valid_indices (afi_t afi, safi_t *safi)
+bgp_afi_safi_valid_indices (afi_t *afi, safi_t *safi)
 {
-  switch (afi)
+  switch (*afi)
 {
 case AFI_IP:
 case AFI_IP6:
@@ -149,6 +149,15 @@ bgp_afi_safi_valid_indices (afi_t afi, safi_t *safi)
case SAFI_ENCAP:
  return 1;
}
+case AFI_L2VPN:
+  *afi = AFI_INTERNAL_L2VPN;
+  switch (*safi)
+   {
+case SAFI_EVPN:
+ *safi = SAFI_INTERNAL_EVPN;
+  return 1;
+}
+  break;
 case AFI_INTERNAL_L2VPN:
   switch (*safi)
{
@@ -157,8 +166,7 @@ bgp_afi_safi_valid_indices (afi_t afi, safi_t *safi)
 }
   break;
 }
-
-  zlog_debug ("unknown afi/safi (%u/%u)", afi, *safi);
+  zlog_debug ("unknown afi/safi (%u/%u)", *afi, *safi);
 
   return 0;
 }
@@ -176,7 +184,7 @@ bgp_capability_mp (struct peer *peer, struct 
capability_header *hdr)
 zlog_debug ("%s OPEN has MP_EXT CAP for afi/safi: %u/%u",
peer->host, mpc.afi, mpc.safi);
   
-  if (!bgp_afi_safi_valid_indices (mpc.afi, ))
+  if (!bgp_afi_safi_valid_indices (, ))
 return -1;

   /* Now safi remapped, and afi/safi are valid array indices */
@@ -238,7 +246,7 @@ bgp_capability_orf_entry (struct peer *peer, struct 
capability_header *hdr)
peer->host, entry.mpc.afi, entry.mpc.safi);
 
   /* Check AFI and SAFI. */
-  if (!bgp_afi_safi_valid_indices (entry.mpc.afi, ))
+  if (!bgp_afi_safi_valid_indices (, ))
 {
   zlog_info ("%s Addr-family %d/%d not supported."
  " Ignoring the ORF capability",
@@ -381,7 +389,7 @@ bgp_capability_restart (struct peer *peer, struct 
capability_header *caphdr)
   safi_t safi = stream_getc (s);
   u_char flag = stream_getc (s);
   
-  if (!bgp_afi_safi_valid_indices (afi, ))
+  if (!bgp_afi_safi_valid_indices (, ))
 {
   if (BGP_DEBUG (normal, NORMAL))
 zlog_debug ("%s Addr-family %d/%d(afi/safi) not supported."
diff --git a/bgpd/bgp_open.h b/bgpd/bgp_open.h
index 62333754b04f..1d30d30e8f68 100644
--- a/bgpd/bgp_open.h
+++ b/bgpd/bgp_open.h
@@ -107,6 +107,6 @@ extern int bgp_open_option_parse (struct peer *, u_char, 
int *);
 extern void bgp_open_capability (struct stream *, struct peer *);
 extern void bgp_capability_vty_out (struct vty *, struct peer *);
 extern as_t peek_for_as4_capability (struct peer *, u_char);
-extern int bgp_afi_safi_valid_indices (afi_t, safi_t *);
+extern int bgp_afi_safi_valid_indices (afi_t *, safi_t *);
 
 #endif /* _QUAGGA_BGP_OPEN_H */
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index db569b876424..22998c4aabdc 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -1846,7 +1846,7 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
* Note2: This will also remap the wire code-point for VPN safi to the
* internal safi_t point, as needs be.
*/
-  if (!bgp_afi_safi_valid_indices (nlris[i].afi, [i].safi))
+  if (!bgp_afi_safi_valid_indices ([i].afi, [i].safi))
 {
   plog_info (peer->log,
  "%s [Info] UPDATE with unsupported AFI/SAFI %u/%u",
@@ -1917,7 +1917,7 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
*/
   else if (attr.flag == BGP_ATTR_MP_UNREACH_NLRI
&& nlris[NLRI_MP_WITHDRAW].length == 0
-   && bgp_afi_safi_valid_indices (nlris[NLRI_MP_WITHDRAW].afi,
+   && bgp_afi_safi_valid_indices ([NLRI_MP_WITHDRAW].afi,
   [NLRI_MP_WITHDRAW].safi))
 {
   afi = nlris[NLRI_MP_WITHDRAW].afi;
@@ -2321,7 +2321,7 @@ bgp_capability_msg_parse (struct peer *peer, u_char *pnt, 
bgp_size_t length)
   if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
continue;
   
-  if (!bgp_afi_safi_valid_indices (afi, ))
+  if (!bgp_afi_safi_valid_indices (, ))
 {
   if (BGP_DEBUG (normal, NORMAL))
 zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid "
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16343] [PATCH 08/57] bgpd: detect if bgp_info is multipath entry

2016-10-28 Thread Philippe Guibert
Enhance a function that permits knowing if two entries belong to the
same multipath group.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_mpath.c | 15 +++
 bgpd/bgp_mpath.h |  1 +
 2 files changed, 16 insertions(+)

diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c
index 6465aad1d99a..87f3e1eab461 100644
--- a/bgpd/bgp_mpath.c
+++ b/bgpd/bgp_mpath.c
@@ -781,3 +781,18 @@ bgp_info_mpath_aggregate_update (struct bgp_info *new_best,
   else
 bgp_attr_unintern (_attr);
 }
+
+/* returns 1 if ri is part of the mpath list from new_select */
+int bgp_is_mpath_entry(struct bgp_info *ri, struct bgp_info *curr)
+{
+  struct bgp_info *mpinfo;
+
+  /* not a multipath entry */
+  if(!curr || !curr->mpath)
+return 0;
+  for (mpinfo = bgp_info_mpath_first (curr); mpinfo;
+   mpinfo = bgp_info_mpath_next (mpinfo))
+if(mpinfo == ri)
+  return 1;
+  return 0;
+}
diff --git a/bgpd/bgp_mpath.h b/bgpd/bgp_mpath.h
index 2a84d5e1e21b..2b3eaf51901f 100644
--- a/bgpd/bgp_mpath.h
+++ b/bgpd/bgp_mpath.h
@@ -78,5 +78,6 @@ extern struct bgp_info *bgp_info_mpath_next (struct bgp_info 
*);
 /* Accessors for multipath information */
 extern u_int32_t bgp_info_mpath_count (struct bgp_info *);
 extern struct attr *bgp_info_mpath_attr (struct bgp_info *);
+extern int bgp_is_mpath_entry(struct bgp_info *ri, struct bgp_info *curr);
 
 #endif /* _QUAGGA_BGP_MPATH_H */
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16340] [PATCH 06/57] tests: fix BGP VRF interactions

2016-10-28 Thread Philippe Guibert
From: David Lamparter <equi...@opensourcerouting.org>

Signed-off-by: David Lamparter <equi...@opensourcerouting.org>
Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 tests/Makefile.am  |  2 +-
 tests/bgp_mpath_test.c | 15 +++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/tests/Makefile.am b/tests/Makefile.am
index 16c9e4c3db5d..c1194e9090c7 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -15,7 +15,7 @@ EXTRA_DIST = \
testcli.in \
testcli.refout
 
-AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
+AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib 
-I$(top_srcdir)/lib/c-capnproto
 DEFS = @DEFS@ $(LOCAL_OPTS) -DSYSCONFDIR=\"$(sysconfdir)/\"
 
 if BGPD
diff --git a/tests/bgp_mpath_test.c b/tests/bgp_mpath_test.c
index 174d299870ca..bb3e3e89daba 100644
--- a/tests/bgp_mpath_test.c
+++ b/tests/bgp_mpath_test.c
@@ -27,6 +27,7 @@
 #include "stream.h"
 #include "privs.h"
 #include "linklist.h"
+#include "hash.h"
 #include "memory.h"
 #include "zclient.h"
 #include "filter.h"
@@ -83,6 +84,17 @@ struct zebra_privs_t bgpd_privs =
 
 static int tty = 0;
 
+static unsigned int
+hash_make_dummy (void *arg)
+{
+  return 0;
+}
+static int
+hash_cmp_dummy (const void *a, const void *b)
+{
+  return 0;
+}
+
 /* Create fake bgp instance */
 static struct bgp *
 bgp_create_fake (as_t *as, const char *name)
@@ -107,6 +119,9 @@ bgp_create_fake (as_t *as, const char *name)
   bgp->rsclient = list_new ();
   //bgp->rsclient->cmp = (int (*)(void*, void*)) peer_cmp;
 
+  bgp->vrfs = list_new ();
+  bgp->rt_subscribers = hash_create (hash_make_dummy, hash_cmp_dummy);
+
   for (afi = AFI_IP; afi < AFI_MAX; afi++)
 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
   {
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16332] EVPN RFC Patch

2016-10-25 Thread Philippe Guibert
Hi all,

This thread is a starting point to discuss about Ethernet VPN
implementation in Quagga BGP daemon. Currently, the RFC7432 is not
supported in quagga 1.1.0.

This email is a preparatory work to open discussion.
It is also a preparatory work to propose the following EVPN implementation.

Best Regards,

Philippe

*Overview*
This implementation is a response for the following use case.
On the datacenter, there are openflow switches. Behind those openflow
switches, one can find hosts/VMs, as well as gateway nodes which can
host a number of IP addresses.
There is also a Data-Center Gateway (DC-GW) behind which one can find
the same kind of host/VMS and gateway nodes. Those VMs can be on the
same Data Center, or be in a remote Data Center.
The goal is to implement a Layer 2 network across the hosts/VMs such
that we can establish a L2 connectivity between the hosts behind DC-GW
and the hosts behind OF switches.

Quagga BGP daemon is in charge of sending (and receiving) signaling
information to (from) DC-GW, by using EVPN BGP implementation. It acts
on behalf on SDN controller of the Data Center. EVPN has been
implemented in the ability to establish vxlan tunnels within a data
center.

This work relies on some IETF documents.
- rfc7432
- draft-ietf-bess-evpn-inter-subnet-forwarding-01
- draft-ietf-idr-tunnel-encaps-02
- draft-ietf-bess-evpn-prefix-advertisement-02
- draft-ietf-bess-evpn-overlay-05

*EVPN feature proposed*

Currently, the proposed implementation covers the following:
- EVPN route type 2 aka MAC/IP advertisement
- EVPN route type 5 aka Prefix IP advertisement.
It is possible to statically set abovementioned messages.

It also covers BGP extended community attributes:
- Router MAC extended community
- BGP encapsulation attribute for VXLAN
- Tunnel Encapsulation attribute VXLAN

It also covers VRF import processing.
By using exported RT set from BGP extended communities, EVPN
information is added in ADJ-RIB-IN per VRF per neighbor table. Some
associated vty show commands are available.

*EVPN changes proposed*
The changes occur in lib/ and bgpd folder.
The following is impacted:

- bgpd folder and lib/zebra.h. Two new defines are appended: AFI_L2VPN
(25) and SAFI_EVPN (70). In order to minimize RIB table sizing, 2 new
defines: AFI_INTENRNAL_L2VPN and SAFI_INTERNAL_EVPN values are chosen.
afi_safi_valid_indices() routine will be changed to take into account.
BGP core code is updated so as to take into account relevant changes
regarding to the new parameters.

- bgpd: support for overlay index information
Route type 5 messages carry overlay index information, which can
either be Ethernet Segment Identifier ( ESI) or gateway IP ( GWIP).
This information is carried in extra attr information. Some APIs are
designed in order to manipulate overlay index: update/add/remove/dup.
Extract structures implement the above.

   struct eth_segment_id
   {
 u_char val[ESI_LEN];
   };

   #define MAC_LEN 6

   union gw_addr {
 struct in_addr ipv4;
   #ifdef HAVE_IPV6
 struct in6_addr ipv6;
   #endif /* HAVE_IPV6 */
   };

  /* Overlay Index Info */
  struct overlay_index
  {
struct eth_segment_id eth_s_id;
union gw_addr gw_ip;
  };


- prefix.[ch] : prefix extension to support MAC/IP prefixes. Extract
below indicates what the prefix looks like now:

struct macipaddr {
  u_int32_t eth_tag_id;
  u_int8_t mac_len;
  struct ethaddr mac;
  u_int8_t ip_len;
  union
  {
 struct in_addr in4; /* AF_INET */
  #ifdef HAVE_IPV6
struct in6_addr in6;/* AF_INET6 */
  #endif /* HAVE_IPV6 */
  } ip __attribute__ ((packed));
};

- EVPN processing in reception and in emission. Modifications mainly
done in bgp_attr.[ch] and bgp_evpn.[ch]. BGP EVPN format is translated
into internal structures and vice-versa. bgp_update() routine is
adapted and uses an extra parameter ( struct bgp_route_evpn), as
indicated below.

   struct bgp_route_evpn
   {
  uint32_t eth_t_id;
  struct eth_segment_id eth_s_id;
  union gw_addr gw_ip;
   };

   int bgp_update (struct peer *peer, struct prefix *p, struct attr *attr,
   afi_t afi, safi_t safi, int type, int sub_type,
   struct prefix_rd *prd, uint32_t *labels, size_t nlabels,
   int soft_reconfig, struct bgp_route_evpn* evpn);

- EVPN extra information.

As indicated in above features, BGP router target extended community
and BGP vxlan encapsulation attribute are handled. For that,
bgp_ecommunity.[ch] file is modified.

Also, MAC/IP contains 2 label fields, one for layer 2, one for layer
3. This label is mapped to the current label list. The following is
chosen. First label entry is layer2. Second is for layer3.

- EVPN configuration
Currently, an internal API is used and is not yet mapped on vty.
This API is relying on an internal structure named bgp_api_route.
This is the configuration structure.

struct bgp_api_route
{
  struct prefix prefix;
  

[quagga-dev 16331] Re: [PATCH v2 1/2] bgpd: VRF vty configuration, RIB table creation

2016-10-24 Thread Philippe Guibert
On Fri, Oct 21, 2016 at 8:21 PM, Lou Berger  wrote:

Hello Lou,

Thanks for your detailed response,
I agree to configure the RD , and the RT set per VRF.
However, I tried to make a counter proposal about the way to configure it.
You will find it below.
Your comments are welcome.

Best Regards,

Philippe

>>  About the concepts you are talking about, I agree with you.
>> Regarding design issue, I think there is a misunderstanding because I
>> link RD with RTs, within a VRF.
>> Whereas you point the following:
>> - associate RD with VPN flows
> Not sure what you mean here.

About linking RD with RTs, this is not correct. You are right.
In previous mail, you underlined the way to associate RD with VPN flows.
So I was thinking about configuring RD per VPN flows.
This is why I used that sentence "associate RD with VPN flows".

> I don't understand what "VPN" means to you or in the config model.  BGP
> LxVPNs have VRFs and Route Distribution semantics.  Together these
> semantics can be combined to support LxVPNs.


> how about
> vrf 
> rd ...
> rt (import|export|both) ...
> network  [rd ...]
>
In proposed patchwork, vrf is under bgp router subnode.
I think, your proposal refers to reuse vrf command under configuration
mode. Right ?
If that is it, yes. Adaptation is possible.
Or you probably think of keeping the VRF command under bgp router node ?

For RD and RT set dissociation, yes too.
For network command, I don't see the need to move network command
under vrf subnode, whereas there is yet some network commands under
various bgp vpnvx subnodes.
What about keeping network command under address family subnode ?

>> One reason is that this work is pure signalling, there is no dataplane
>> interaction.
>
> As is always the the case for BGP ;-)

Sorry, I am diving one more time into quagga code :-).
The implementation I did does not take into account zebra <-> bgpd
communication, and FIB updates.
That is what I insisted on when I say the work is "pure signalling".

>> Do you see other points to discuss ?
>>
>
> Well, we need to ensure that route distribution happens properly for all
> cases (including RR).  See below for more specific comments.

I noticed a problem , using RR with VPNv4.
Actually, this does not work with VPNv4. No BGP updates messages
received from RR.

 Most of the modifications have been done around what is called the
 "VRF structure".
>
> This is good and aligned with the suggestion to move config to be per VRF.

ok


 The RD is mapped to that "VRF structure", but the RT also. This is a
 one-to-one mapping.
 That "VRF structure" has a RIB table where RT imports are processed.

>
> I think a mapping of VRF to RT set is right.  Having a default RD for
> VRF export is also good.
>
 I mean, on the design point of view, I don't make a difference between
 a RD and a RT.
>
> I think this is a mistake.  RD is about route (re)distribution
> selection.  RT is about topology and VRF control.

yes.

 I just have to ensure that the incoming structure is available to
 import appropriate entries.
 in order to import a RT entry, I have to create a RT mapped to an
 other "VRF structure".

 If the RT is not mapped to that "VRF structure", then the RIB
 associated to that RT is not present.
 Then the import in the RIB RT will not be possible.
>
> We have parallel code doing the same in RFAPI.
0
I am looking at the RFAPI :  imported_vpn table seems to be the one
that is similar to the VRF table.
I try to find out a solution in order to permit both code live together.
I mean, I code redundancy ( not code duplication) can be possible, no?


 To illustrate, a quick example shows that routerA sends a NLRI entry to
 routerB.

 routerA> rd 200:111 import 100:111 export 100:111 300:111
 routerA> network 10.10.10.0/24 rd 200:111
 routerB> rd 100:111 import 100:111 export 100:111

> is this all under a vpn/vrf config parameter or at the top (bgp) level?
>

see answer above.
currently:
- vrf rd command is under bgp router sub node.
- network is under vpnv4 address family subnode

 RouterB will import NLRI entry to RT 100:111
>
   This is possible because RouterB has the line rd100:111 ... created.
>
> hopefully you really mean because RouterB has the line import 100:111
>

 RouterB will not import NLRI entry to RT 300:111, since there is no
 underlying structure.
>
> all good here.
>
>
> Is this a valid entry
> routerA> network 10.10.10.0/24 rd 123:111
>
> assuming the config structure is under "... vpn ..."
> what rt's would be in the update?

If the config structure was under vpn, I think this entry would not be valid.



 About "VRF structure", My intention is not to interfere about current
 VRF implementation in Quagga.
 From the configuration point of view, it is easy to find in literature
 cisco configuration where VRF
 and RD configuration maps 

[quagga-dev 16329] Re: [PATCH v2 1/2] bgpd: VRF vty configuration, RIB table creation

2016-10-20 Thread Philippe Guibert
On Wed, Oct 19, 2016 at 2:22 PM, Lou Berger <lber...@labn.net> wrote:

Hello Lou,

> I think either we're talking past each other are have some other
> major disconnect.

Let me reassure you. If both of us speak not at the same time design and
concepts,this may be problematic :-)
 About the concepts you are talking about, I agree with you.
Regarding design issue, I think there is a misunderstanding because I
link RD with RTs, within a VRF.
Whereas you point the following:
- associate RD with VPN flows
- associate RT set with VRF

The design currently is not aware of the underlying VRF it works on.
One reason is that this work is pure signalling, there is no dataplane
interaction.

I think it should be possible, to adapt the configuration. For
instance,  for a VPN network route,
to know which VRF it uses, and consequently, which RT set.

Before going further, can I ask you if we share the same point of view
about this patchwork issue ?
Do you see other points to discuss ?

Best Regards,

Philippe

> Per BGP LxVPNs, we really should distinguish between VRFs and (vpn)
> route distribution.
>
> WRT VRFs:
>
> The contents of a VRF imported from BGP is determined by one or more
> (import) RTs. RDs are ignored at this point.
>
> An outgoing VPN route is exported to BGP with one or more (export) RTs.
> One configured RD is typically used on outgoing routes exported from a
> VRF (note not VPN) , but multiple routes (identified by different RDs)
> may exist across a single VPN (as identified by an RT set).
>
> WRT Route distribution:
>
> Ignoring RT/community filtering, which currently isn't in the code, BGP
> route distribution basically ignores RTs and uses standard route
> selection based on NRLI route which includes the RD+prefix.  This means
> that different RDs can not only be used to segregate prefixes that exist
> within a VPN (and are identified with disjoint sets of RTs) they can
> also be use to support multi-path routes within a VPN (and are
> identified with same/overlapping sets of RTs).  BTW RRs only care about
> this part.
>
> So keying a VPN/VRF off an RD just seems wrong, particularly for the
> import case where RD is ignored.
>
> Lou
>
> On 10/19/2016 3:59 AM, Philippe Guibert wrote:
>> On Tue, Oct 18, 2016 at 3:56 PM, Lou Berger <lber...@labn.net> wrote:
>>
>> Hello Lou,
>>
>> Please read below my comments.
>> Consecutive to your feedback, I think there are some improvements to bring,
>> mainly about configuration and structure naming.
>>
>>> It looks like RD is your key to a VRF, is this right?
>>> This doesn't match the semantics of BGP VPNs, where RDs are independent
>>> of VRF.  (RT set is really the critical thing.)
>> Most of the modifications have been done around what is called the
>> "VRF structure".
>>
>> The RD is mapped to that "VRF structure", but the RT also. This is a
>> one-to-one mapping.
>> That "VRF structure" has a RIB table where RT imports are processed.
>>
>> I mean, on the design point of view, I don't make a difference between
>> a RD and a RT.
>> I just have to ensure that the incoming structure is available to
>> import appropriate entries.
>> in order to import a RT entry, I have to create a RT mapped to an
>> other "VRF structure".
>>
>> If the RT is not mapped to that "VRF structure", then the RIB
>> associated to that RT is not present.
>> Then the import in the RIB RT will not be possible.
>>
>> To illustrate, a quick example shows that routerA sends a NLRI entry to 
>> routerB.
>>
>> routerA> rd 200:111 import 100:111 export 100:111 300:111
>> routerA> network 10.10.10.0/24 rd 200:111
>> routerB> rd 100:111 import 100:111 export 100:111
>>
>> RouterB will import NLRI entry to RT 100:111
>>   This is possible because RouterB has the line rd100:111 ... created.
>>
>> RouterB will not import NLRI entry to RT 300:111, since there is no
>> underlying structure.
>>
>> About "VRF structure", My intention is not to interfere about current
>> VRF implementation in Quagga.
>> From the configuration point of view, it is easy to find in literature
>> cisco configuration where VRF
>> and RD configuration maps together.
>> Could you be more specific about the reason to dissociate RD from VRF ?
>>
>> One modification improvement would consist in :
>> - That "VRF structure" could be renamed to "RT/RD structure"
>> - some show commands would be impacted. Instead of dumping VRF RIB
>> table, one would dump RT/RD RIB table
>> - the commit logs would be rewor

[quagga-dev 16309] Re: [PATCH v2 1/2] bgpd: VRF vty configuration, RIB table creation

2016-10-19 Thread Philippe Guibert
On Tue, Oct 18, 2016 at 3:56 PM, Lou Berger <lber...@labn.net> wrote:

Hello Lou,

Please read below my comments.
Consecutive to your feedback, I think there are some improvements to bring,
mainly about configuration and structure naming.

> It looks like RD is your key to a VRF, is this right?
> This doesn't match the semantics of BGP VPNs, where RDs are independent
> of VRF.  (RT set is really the critical thing.)

Most of the modifications have been done around what is called the
"VRF structure".

The RD is mapped to that "VRF structure", but the RT also. This is a
one-to-one mapping.
That "VRF structure" has a RIB table where RT imports are processed.

I mean, on the design point of view, I don't make a difference between
a RD and a RT.
I just have to ensure that the incoming structure is available to
import appropriate entries.
in order to import a RT entry, I have to create a RT mapped to an
other "VRF structure".

If the RT is not mapped to that "VRF structure", then the RIB
associated to that RT is not present.
Then the import in the RIB RT will not be possible.

To illustrate, a quick example shows that routerA sends a NLRI entry to routerB.

routerA> rd 200:111 import 100:111 export 100:111 300:111
routerA> network 10.10.10.0/24 rd 200:111
routerB> rd 100:111 import 100:111 export 100:111

RouterB will import NLRI entry to RT 100:111
  This is possible because RouterB has the line rd100:111 ... created.

RouterB will not import NLRI entry to RT 300:111, since there is no
underlying structure.

About "VRF structure", My intention is not to interfere about current
VRF implementation in Quagga.
>From the configuration point of view, it is easy to find in literature
cisco configuration where VRF
and RD configuration maps together.
Could you be more specific about the reason to dissociate RD from VRF ?

One modification improvement would consist in :
- That "VRF structure" could be renamed to "RT/RD structure"
- some show commands would be impacted. Instead of dumping VRF RIB
table, one would dump RT/RD RIB table
- the commit logs would be reworked

> The main implication of
> this is that multipath/ECMP isn't (at least easily)  supported.
> Also,
> best path selection on import routes will be wrong if keyed based on RD

Multipath feature impacts both global RIB, and RIB per RT.

As before, let me illustrate this with a 3 router setup topology.
router A) and router B) send 2 NLRI ECMP entries to router C)

routerA> rd 200:111 import 100:111 export 100:111
routerA> network 10.10.10.0/24 rd 200:111 

routerB> rd 200:111 import 100:111 export 100:111
routerB> network 10.10.10.0/24 rd 200:111 

routerC> rd 100:111 import 100:111 export 100:111

When receiving a NLRI entry from routerB), and routerA), bgp_update()
will append the entry in the global RIB, according to RD field.

routerC> show bgp ipv4 vpn
Route Distinguisher : 200:111
*> 10.10.10.0/24 
=> 10.10.10.0/24 

Then, the import processing is storing the same 2 entries in RT RIB.
routerC> show ip bgp rd 100:111
Route Distinguisher : 100:111
*> 10.10.10.0/24 
=> 10.10.10.0/24 

By playing with configuration, it is possible to have multipath
entries in the global RIB, but not in the RD RIB.

> and I'm not sure what's being done on route reflectors.

There may be some missing elements on implementation.
Only the global RIB entries injected by remote peer would be
transmitted, including the export RT information originated by routerA
and routerB.

> I really think that BGP VRFs cannot / must not be keyed based on RDs.
> If this is just the config interface, then changing this should be
> pretty straight forward.

RT RIBS are keyed based on RTs
global RIBS entries are keyed based on RDs.
About config interface, It would be possible to change configuration:
instead of "vrf rd", one could have "rd <>".

> PS I think an update to bgpd.texi is needed for this patch

of course, this is something that can be done.

Best Regards,

Philippe

> On 10/11/2016 4:17 AM, Philippe Guibert wrote:
>> This commit introduces the BGP VRF configuration, and BGP VRF RIB
>> table.
>> It includes the ability for a BGP to configure its own route
>> distinguisher ( aka VRF). New vty commands introduced:
>>
>> (config-router)# vrf rd 
>>
>> This structure permits configuring import and export route targets,
>> which is defined by RFC4360.
>> (config-router)# vrf rd  exports 
>> (config-router)# vrf rd  imports 
>>
>> It brings some improvements.
>> - for a BGP speaker when emitting BGP updates, the exported route
>> targets will be mapped to BGP extended communities associated with
>> the BGP update for the defined Route distinguisher.
>> This commit does not enhance th

[quagga-dev 16281] [PATCH v2 09/10] bgpd: sanity check against accessing invalid table pointer.

2016-10-12 Thread Philippe Guibert
This sanity check has been discovered when running bgp mpath_tests
that are available in tests folder.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_mpath.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c
index f117d2dbed8d..46d813984741 100644
--- a/bgpd/bgp_mpath.c
+++ b/bgpd/bgp_mpath.c
@@ -509,7 +509,7 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info 
*new_best,
   else if (old_best)
 vrf = bgp_vrf_lookup(old_best->peer->bgp, prd);
 }
-  else if(bgp_node_table (rn)->type == BGP_TABLE_VRF)
+  else if(rn->table && bgp_node_table (rn) && bgp_node_table (rn)->type == 
BGP_TABLE_VRF)
 {
   if (new_best)
 vrf = bgp_vrf_lookup_per_rn(new_best->peer->bgp, afi, rn);
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16280] [PATCH v2 08/10] bgpd: apply multipath algorithm to VRF

2016-10-12 Thread Philippe Guibert
This commit checks for the maximum path per VRF before running the
multipath algorithm. This makes it possible to limit the number of
paths for a specific VRF, and not for an other one.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_mpath.c | 34 +-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c
index dc99591bf8ad..f117d2dbed8d 100644
--- a/bgpd/bgp_mpath.c
+++ b/bgpd/bgp_mpath.c
@@ -38,6 +38,7 @@
 #include "bgpd/bgp_aspath.h"
 #include "bgpd/bgp_community.h"
 #include "bgpd/bgp_ecommunity.h"
+#include "bgpd/bgp_mplsvpn.h"
 #include "bgpd/bgp_mpath.h"
 
 bool
@@ -335,9 +336,13 @@ bgp_info_mpath_enqueue (struct bgp_info *prev_info, struct 
bgp_info *binfo)
 void
 bgp_info_mpath_dequeue (struct bgp_info *binfo)
 {
-  struct bgp_info_mpath *mpath = binfo->mpath;
+  struct bgp_info_mpath *mpath;
+  if (!binfo)
+return;
+  mpath = binfo->mpath;
   if (!mpath)
 return;
+
   if (mpath->mp_prev)
 mpath->mp_prev->mp_next = mpath->mp_next;
   if (mpath->mp_next)
@@ -471,6 +476,8 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info 
*new_best,
   int mpath_changed, debug;
   char pfx_buf[INET6_ADDRSTRLEN], nh_buf[2][INET6_ADDRSTRLEN];
   struct bgp_maxpaths_cfg *mpath_cfg = NULL;
+  struct prefix_rd *prd = NULL;
+  struct bgp_vrf *vrf = NULL;
 
   mpath_changed = 0;
   maxpaths = BGP_DEFAULT_MAXPATHS;
@@ -494,6 +501,31 @@ bgp_info_mpath_update (struct bgp_node *rn, struct 
bgp_info *new_best,
   maxpaths = (new_best->peer->sort == BGP_PEER_IBGP) ?
 mpath_cfg->maxpaths_ibgp : mpath_cfg->maxpaths_ebgp;
 }
+  if (safi == SAFI_MPLS_VPN)
+{
+  prd = _node_table (rn)->prd;
+  if (new_best)
+vrf = bgp_vrf_lookup(new_best->peer->bgp, prd);
+  else if (old_best)
+vrf = bgp_vrf_lookup(old_best->peer->bgp, prd);
+}
+  else if(bgp_node_table (rn)->type == BGP_TABLE_VRF)
+{
+  if (new_best)
+vrf = bgp_vrf_lookup_per_rn(new_best->peer->bgp, afi, rn);
+  else if (old_best)
+vrf = bgp_vrf_lookup_per_rn(old_best->peer->bgp, afi, rn);
+}
+  if (vrf)
+{
+  maxpaths = vrf->max_mpath;
+  if(debug && vrf)
+{
+  char vrf_rd_str[RD_ADDRSTRLEN];
+  prefix_rd2str(>outbound_rd, vrf_rd_str, sizeof(vrf_rd_str));
+  zlog_debug ("vrf[%s] : mpath. max detected : %d", vrf_rd_str, 
maxpaths);
+}
+}
 
   if (old_best)
 {
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16279] [PATCH v2 05/10] bgpd: VRF RIB log updates enhancement

2016-10-12 Thread Philippe Guibert
On adding/removing/updating NLRI entries into VRF RIB tables, a BGP
event is fired. Note that only selected entries, and entries that are
part of multipath entries, and where one of the multipath entry is
selected.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_route.c | 105 +--
 bgpd/bgp_route.h |   2 ++
 bgpd/bgpd.c  |  16 +
 bgpd/bgpd.h  |   3 ++
 4 files changed, 124 insertions(+), 2 deletions(-)

diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 5744a3a2c27e..5eb195467c98 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -1572,6 +1572,60 @@ void bgp_vrf_clean_tables (struct bgp_vrf *vrf)
 }
 }
 
+/* messages sent to ODL to signify that an entry
+ * has been selected, or unselected
+ */
+void
+bgp_vrf_update (struct bgp_vrf *vrf, afi_t afi, struct bgp_node *rn,
+struct bgp_info *selected, uint8_t announce)
+{
+  if(!vrf || (rn && bgp_node_table (rn)->type != BGP_TABLE_VRF))
+return;
+  if (announce == true)
+{
+  if(CHECK_FLAG (selected->flags, BGP_INFO_UPDATE_SENT))
+return;
+  SET_FLAG (selected->flags, BGP_INFO_UPDATE_SENT);
+  UNSET_FLAG (selected->flags, BGP_INFO_WITHDRAW_SENT);
+}
+  else
+{
+  /* if not already sent, do nothing */
+  if(!CHECK_FLAG (selected->flags, BGP_INFO_UPDATE_SENT))
+return;
+  if(CHECK_FLAG (selected->flags, BGP_INFO_WITHDRAW_SENT))
+return;
+  SET_FLAG (selected->flags, BGP_INFO_WITHDRAW_SENT);
+  UNSET_FLAG (selected->flags, BGP_INFO_UPDATE_SENT);
+}
+  if (BGP_DEBUG (events, EVENTS))
+{
+  char vrf_rd_str[RD_ADDRSTRLEN], rd_str[RD_ADDRSTRLEN], 
pfx_str[INET6_BUFSIZ];
+  char label_str[BUFSIZ] = "", nh_str[BUFSIZ] = "";
+
+  prefix_rd2str(>outbound_rd, vrf_rd_str, sizeof(vrf_rd_str));
+  prefix_rd2str(>extra->vrf_rd, rd_str, sizeof(rd_str));
+  prefix2str(>p, pfx_str, sizeof(pfx_str));
+  labels2str(label_str, sizeof(label_str),
+  selected->extra->labels, selected->extra->nlabels);
+
+  if (selected->attr && selected->attr->extra)
+{
+  if (afi == AFI_IP)
+strcpy (nh_str, inet_ntoa 
(selected->attr->extra->mp_nexthop_global_in));
+  else if (afi == AFI_IP6)
+inet_ntop (AF_INET6, >attr->extra->mp_nexthop_global, 
nh_str, BUFSIZ);
+}
+
+  if (announce)
+zlog_debug ("vrf[%s] %s: prefix updated, best RD %s labels %s nexthop 
%s",
+   vrf_rd_str, pfx_str, rd_str, label_str, nh_str);
+  else
+zlog_debug ("vrf[%s] %s: prefix withdrawn nh %s label %s",
+vrf_rd_str, pfx_str, nh_str, label_str);
+}
+}
+
 /* updates selected bgp_info structure to bgp vrf rib table
  * most of the cases, processing consists in adding or removing entries in RIB 
tables
  * on some cases, there is an update request. then it is necessary to have 
both old and new ri
@@ -2098,9 +2152,13 @@ bgp_process_vrf_main (struct work_queue *wq, void *data)
   struct bgp_node *rn = pq->rn;
   afi_t afi = pq->afi;
   safi_t safi = pq->safi;
-  struct bgp_info *new_select;
+  struct bgp_info *new_select, *ri;
   struct bgp_info *old_select;
   struct bgp_info_pair old_and_new;
+  struct bgp_vrf *vrf = NULL;
+
+  if(rn)
+vrf = bgp_vrf_lookup_per_rn(bgp, afi, rn);
 
   /* Best path selection. */
   bgp_best_selection (bgp, rn, _and_new, afi, safi);
@@ -2117,6 +2175,13 @@ bgp_process_vrf_main (struct work_queue *wq, void *data)
 {
   UNSET_FLAG (old_select->flags, BGP_INFO_MULTIPATH_CHG);
   SET_FLAG (old_select->flags, BGP_INFO_MULTIPATH);
+  for(ri = rn->info; ri; ri = ri->next)
+{
+  if(ri == old_select)
+continue;
+  if(!bgp_is_mpath_entry(ri, new_select))
+bgp_vrf_update(vrf, afi, rn, ri, false);
+}
 }
   /* no zebra announce */
  UNSET_FLAG (old_select->flags, BGP_INFO_MULTIPATH_CHG);
@@ -2138,18 +2203,53 @@ bgp_process_vrf_main (struct work_queue *wq, void *data)
 {
   if( CHECK_FLAG (old_select->flags, BGP_INFO_SELECTED))
 {
-  if(bgp_is_mpath_entry(old_select, new_select))
+  if(!bgp_is_mpath_entry(old_select, new_select))
+{
+  bgp_vrf_update(vrf, afi, rn, old_select, false);
+}
+  else
 {
   UNSET_FLAG (old_select->flags, BGP_INFO_MULTIPATH_CHG);
   SET_FLAG (old_select->flags, BGP_INFO_MULTIPATH);
 }
 }
+  /* withdraw mp entries which could have been removed
+   * and that a update has previously been sent
+   */
+  for(r

[quagga-dev 16276] [PATCH v2 01/10] tests: fix BGP VRF interactions

2016-10-12 Thread Philippe Guibert
From: David Lamparter <equi...@opensourcerouting.org>

Signed-off-by: David Lamparter <equi...@opensourcerouting.org>
Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 tests/Makefile.am  |  2 +-
 tests/bgp_mpath_test.c | 15 +++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/tests/Makefile.am b/tests/Makefile.am
index 16c9e4c3db5d..c1194e9090c7 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -15,7 +15,7 @@ EXTRA_DIST = \
testcli.in \
testcli.refout
 
-AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
+AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib 
-I$(top_srcdir)/lib/c-capnproto
 DEFS = @DEFS@ $(LOCAL_OPTS) -DSYSCONFDIR=\"$(sysconfdir)/\"
 
 if BGPD
diff --git a/tests/bgp_mpath_test.c b/tests/bgp_mpath_test.c
index 174d299870ca..bb3e3e89daba 100644
--- a/tests/bgp_mpath_test.c
+++ b/tests/bgp_mpath_test.c
@@ -27,6 +27,7 @@
 #include "stream.h"
 #include "privs.h"
 #include "linklist.h"
+#include "hash.h"
 #include "memory.h"
 #include "zclient.h"
 #include "filter.h"
@@ -83,6 +84,17 @@ struct zebra_privs_t bgpd_privs =
 
 static int tty = 0;
 
+static unsigned int
+hash_make_dummy (void *arg)
+{
+  return 0;
+}
+static int
+hash_cmp_dummy (const void *a, const void *b)
+{
+  return 0;
+}
+
 /* Create fake bgp instance */
 static struct bgp *
 bgp_create_fake (as_t *as, const char *name)
@@ -107,6 +119,9 @@ bgp_create_fake (as_t *as, const char *name)
   bgp->rsclient = list_new ();
   //bgp->rsclient->cmp = (int (*)(void*, void*)) peer_cmp;
 
+  bgp->vrfs = list_new ();
+  bgp->rt_subscribers = hash_create (hash_make_dummy, hash_cmp_dummy);
+
   for (afi = AFI_IP; afi < AFI_MAX; afi++)
 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
   {
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16278] [PATCH v2 04/10] bgpd: VRF import processing

2016-10-12 Thread Philippe Guibert
From: Christian Franke <ch...@opensourcerouting.org>

This enhancement permits to export received or locally set route
entries for MPLS VPN, to the appropriate VRF. By introducing the
RFC4360 and BGP extended communities, some export route target are
received on BGP update, or some import route target are set on a
local route entry. It results from exporting the current route
information to the appropriate VRF RIB entry.
This commit is relying on BGP VRF processing, and supports VRF
RIB election as for standard RIBs. This makes it reusable, even
for multipath feature.

Signed-off-by: Christian Franke <ch...@opensourcerouting.org>
Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_route.c | 384 +--
 1 file changed, 376 insertions(+), 8 deletions(-)

diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 1a0ea222322e..5744a3a2c27e 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -62,6 +62,10 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, 
Boston, MA
 extern const char *bgp_origin_str[];
 extern const char *bgp_origin_long_str[];
 
+#define ROUTE_INFO_TO_UPDATE 2
+#define ROUTE_INFO_TO_REMOVE 1
+#define ROUTE_INFO_TO_ADD0
+
 static void
 bgp_static_withdraw_safi (struct bgp *bgp, struct prefix *p, afi_t afi,
   safi_t safi, struct prefix_rd *prd,
@@ -69,6 +73,13 @@ bgp_static_withdraw_safi (struct bgp *bgp, struct prefix *p, 
afi_t afi,
 static void
 bgp_static_free (struct bgp_static *bgp_static);
 
+static void
+bgp_vrf_apply_new_imports_internal (struct bgp_vrf *vrf, afi_t afi, safi_t 
safi);
+
+static struct bgp_info *
+info_make (int type, int sub_type, struct peer *peer, struct attr *attr,
+  struct bgp_node *rn);
+
 static struct bgp_node *
 bgp_afi_node_get (struct bgp_table *table, afi_t afi, safi_t safi, struct 
prefix *p,
  struct prefix_rd *prd)
@@ -1525,6 +1536,12 @@ bgp_process_announce_selected (struct peer *peer, struct 
bgp_info *selected,
   return 0;
 }
 
+
+static bool rd_same (const struct prefix_rd *a, const struct prefix_rd *b)
+{
+  return !memcmp(>val, >val, sizeof(a->val));
+}
+
 void bgp_vrf_clean_tables (struct bgp_vrf *vrf)
 {
   afi_t afi;
@@ -1555,20 +1572,325 @@ void bgp_vrf_clean_tables (struct bgp_vrf *vrf)
 }
 }
 
+/* updates selected bgp_info structure to bgp vrf rib table
+ * most of the cases, processing consists in adding or removing entries in RIB 
tables
+ * on some cases, there is an update request. then it is necessary to have 
both old and new ri
+ */
+static void
+bgp_vrf_process_one (struct bgp_vrf *vrf, afi_t afi, safi_t safi, struct 
bgp_node *rn,
+ struct bgp_info *select, int action)
+{
+  struct bgp_node *vrf_rn;
+  struct bgp_info *iter = NULL;
+  struct prefix_rd *prd;
+  char pfx_str[INET6_BUFSIZ];
+
+  prd = _node_table (rn)->prd;
+  if (BGP_DEBUG (events, EVENTS))
+{
+  char vrf_rd_str[RD_ADDRSTRLEN], rd_str[RD_ADDRSTRLEN];
+  char nh_str[BUFSIZ] = "";
+
+  prefix_rd2str(>outbound_rd, vrf_rd_str, sizeof(vrf_rd_str));
+  prefix_rd2str(prd, rd_str, sizeof(rd_str));
+  prefix2str(>p, pfx_str, sizeof(pfx_str));
+  if(select && select->attr && select->attr->extra)
+{
+  if (afi == AFI_IP)
+strcpy (nh_str, inet_ntoa 
(select->attr->extra->mp_nexthop_global_in));
+  else if (afi == AFI_IP6)
+inet_ntop (AF_INET6, >attr->extra->mp_nexthop_global, 
nh_str, BUFSIZ);
+}
+  else if(select)
+{
+  inet_ntop (AF_INET, >attr->nexthop,
+ nh_str, sizeof (nh_str));
+}
+  zlog_debug ("vrf[%s] %s: [%s] [nh %s] %s ", vrf_rd_str, pfx_str, rd_str, 
nh_str,
+action == ROUTE_INFO_TO_REMOVE? "withdrawing" : "updating");
+}  
+  /* add a new entry if necessary
+   * if already present, do nothing. 
+   * use the loop to parse old entry also */
+
+  /* check if global RIB plans for destroying initial entry
+   * if yes, then suppress it
+   */
+  if(!vrf || !vrf->rib[afi] || !select)
+{
+  return;
+}
+  vrf_rn = bgp_node_get (vrf->rib[afi], >p);
+  if(!vrf_rn)
+{
+  return;
+}
+  if ( (action == ROUTE_INFO_TO_REMOVE) &&
+   (CHECK_FLAG (select->flags, BGP_INFO_REMOVED)))
+{
+  /* check entry not already present */
+  for (iter = vrf_rn->info; iter; iter = iter->next)
+{
+  /* coming from same peer */
+  if(iter->peer->remote_id.s_addr == select->peer->remote_id.s_addr)
+{
+  bgp_info_delete(vrf_rn, iter);
+  prefix2str(_rn->p, pfx_str, sizeof(pfx_str));
+  if (BGP_DEBUG (events, EVENTS))
+{
+  char nh_str[BUFSIZ] = "";
+ 

[quagga-dev 16276] [PATCH v2 02/10] bgpd: BGP VRF processing handling

2016-10-12 Thread Philippe Guibert
NLRI entries received from MP-BGP peer exchange are exported in VRF RIB
tables. This commit introduces the BGP VRF processing handler that can
be used for further processing into VRF RIB tables: best selection
algorithm, multipath.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_main.c  |  5 
 bgpd/bgp_route.c | 91 +---
 bgpd/bgp_route.h |  3 ++
 bgpd/bgpd.c  |  5 
 bgpd/bgpd.h  |  1 +
 5 files changed, 95 insertions(+), 10 deletions(-)

diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
index af9c03052020..51a2770a5ead 100644
--- a/bgpd/bgp_main.c
+++ b/bgpd/bgp_main.c
@@ -258,6 +258,11 @@ bgp_exit (int status)
   work_queue_free (bm->process_rsclient_queue);
   bm->process_rsclient_queue = NULL;
 }
+  if (bm->process_vrf_queue)
+{
+ work_queue_free (bm->process_vrf_queue);
+ bm->process_vrf_queue = NULL;
+}
   
   /* reverse bgp_master_init */
   for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, socket))
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 99637b6dba51..1a0ea222322e 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -1338,7 +1338,6 @@ bgp_best_selection (struct bgp *bgp, struct bgp_node *rn,
   
   bgp_mp_list_init (_list);
   do_mpath = bgp_mpath_is_configured (bgp, afi, safi);
-
   /* bgp deterministic-med */
   new_select = NULL;
   if (bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED))
@@ -1707,7 +1706,7 @@ bgp_process_main (struct work_queue *wq, void *data)
   UNSET_FLAG(rn->flags, BGP_NODE_USER_CLEAR);
 
   if (old_select)
-bgp_info_unset_flag (rn, old_select, BGP_INFO_SELECTED);
+  bgp_info_unset_flag (rn, old_select, BGP_INFO_SELECTED);
   if (new_select)
 {
   bgp_info_set_flag (rn, new_select, BGP_INFO_SELECTED);
@@ -1715,7 +1714,6 @@ bgp_process_main (struct work_queue *wq, void *data)
   UNSET_FLAG (new_select->flags, BGP_INFO_MULTIPATH_CHG);
 }
 
-
   /* Check each BGP peer. */
   for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
 {
@@ -1748,6 +1746,65 @@ bgp_process_main (struct work_queue *wq, void *data)
   return WQ_SUCCESS;
 }
 
+/* processing done for BGP VRF tables */
+static wq_item_status
+bgp_process_vrf_main (struct work_queue *wq, void *data)
+{
+  struct bgp_process_queue *pq = data;
+  struct bgp *bgp = pq->bgp;
+  struct bgp_node *rn = pq->rn;
+  afi_t afi = pq->afi;
+  safi_t safi = pq->safi;
+  struct bgp_info *new_select;
+  struct bgp_info *old_select;
+  struct bgp_info_pair old_and_new;
+
+  /* Best path selection. */
+  bgp_best_selection (bgp, rn, _and_new, afi, safi);
+  old_select = old_and_new.old;
+  new_select = old_and_new.new;
+
+  /* Nothing to do. */
+  if (old_select && old_select == new_select)
+{
+  if (! CHECK_FLAG (old_select->flags, BGP_INFO_ATTR_CHANGED))
+{
+  /* no zebra announce */
+ UNSET_FLAG (old_select->flags, BGP_INFO_MULTIPATH_CHG);
+  UNSET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
+  return WQ_SUCCESS;
+}
+}
+  if (old_select && new_select)
+{
+  if(!CHECK_FLAG (new_select->flags, BGP_INFO_MULTIPATH_CHG) &&
+ !CHECK_FLAG (new_select->flags, BGP_INFO_ATTR_CHANGED))
+{
+  UNSET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
+  return WQ_SUCCESS;
+}
+}
+
+  if (old_select)
+{
+  bgp_info_unset_flag (rn, old_select, BGP_INFO_SELECTED);
+}
+  if (new_select)
+{
+  bgp_info_set_flag (rn, new_select, BGP_INFO_SELECTED);
+  bgp_info_unset_flag (rn, new_select, BGP_INFO_ATTR_CHANGED);
+  UNSET_FLAG (new_select->flags, BGP_INFO_MULTIPATH_CHG);
+}
+
+  /* Reap old select bgp_info, if it has been removed */
+  if (old_select && CHECK_FLAG (old_select->flags, BGP_INFO_REMOVED))
+bgp_info_reap (rn, old_select);
+
+  UNSET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
+  return WQ_SUCCESS;
+  /* no announce */
+}
+
 static void
 bgp_processq_del (struct work_queue *wq, void *data)
 {
@@ -1767,8 +1824,10 @@ bgp_process_queue_init (void)
 = work_queue_new (bm->master, "process_main_queue");
   bm->process_rsclient_queue
 = work_queue_new (bm->master, "process_rsclient_queue");
+  bm->process_vrf_queue
+= work_queue_new (bm->master, "process_vrf_queue");
   
-  if ( !(bm->process_main_queue && bm->process_rsclient_queue) )
+  if ( !(bm->process_main_queue && bm->process_rsclient_queue && 
bm->process_vrf_queue) )
 {
   zlog_err ("%s: Failed to allocate work queue", __func__);
   exit (1);
@@ -1783,6 +1842,12 @@ bgp_process_queue_init (void)
   bm->process_rsclient_queue->spec.del_item_data = _processq_del;
   bm->process_rsclient_queue->spec.max_retries = 0;
   bm->process_rsclient_queue->spec.hol

[quagga-dev 16277] [PATCH v2 03/10] bgpd: detect if bgp_info is multipath entry

2016-10-12 Thread Philippe Guibert
Enhance a function that permits knowing if two entries belong to the
same multipath group.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_mpath.c | 15 +++
 bgpd/bgp_mpath.h |  1 +
 2 files changed, 16 insertions(+)

diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c
index 6465aad1d99a..87f3e1eab461 100644
--- a/bgpd/bgp_mpath.c
+++ b/bgpd/bgp_mpath.c
@@ -781,3 +781,18 @@ bgp_info_mpath_aggregate_update (struct bgp_info *new_best,
   else
 bgp_attr_unintern (_attr);
 }
+
+/* returns 1 if ri is part of the mpath list from new_select */
+int bgp_is_mpath_entry(struct bgp_info *ri, struct bgp_info *curr)
+{
+  struct bgp_info *mpinfo;
+
+  /* not a multipath entry */
+  if(!curr || !curr->mpath)
+return 0;
+  for (mpinfo = bgp_info_mpath_first (curr); mpinfo;
+   mpinfo = bgp_info_mpath_next (mpinfo))
+if(mpinfo == ri)
+  return 1;
+  return 0;
+}
diff --git a/bgpd/bgp_mpath.h b/bgpd/bgp_mpath.h
index 2a84d5e1e21b..2b3eaf51901f 100644
--- a/bgpd/bgp_mpath.h
+++ b/bgpd/bgp_mpath.h
@@ -78,5 +78,6 @@ extern struct bgp_info *bgp_info_mpath_next (struct bgp_info 
*);
 /* Accessors for multipath information */
 extern u_int32_t bgp_info_mpath_count (struct bgp_info *);
 extern struct attr *bgp_info_mpath_attr (struct bgp_info *);
+extern int bgp_is_mpath_entry(struct bgp_info *ri, struct bgp_info *curr);
 
 #endif /* _QUAGGA_BGP_MPATH_H */
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16274] [PATCH v1 09/10] *: enhance memtype and memgroup generation across lib and daemons

2016-10-12 Thread Philippe Guibert
This commit introduces a bash script called from Makefile from each
lib/daemon. Upon call, this script takes as input a txt file
describing the various memory group and type that need to be defined,
initialised and declared. The output of this script is 2 .c and .h
files used for compilation within lib/and or daemons and describing
the memory group and memory types.
Note that this generator tool takes into account global memory
declarations, but not static memory group and types defined inside
specific .c files.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 .gitignore  |   2 +
 bgpd/Makefile.am|   9 ++-
 bgpd/bgp_memory.c   | 168 
 bgpd/bgp_memory.h   |  97 
 bgpd/bgp_memory.txt |  66 +++
 isisd/Makefile.am   |   7 ++
 isisd/isis_memory.c |  72 -
 isisd/isis_memory.h |  51 ---
 isisd/isis_memory.txt   |  21 ++
 lib/Makefile.am |   6 +-
 lib/lib_memory.c| 149 --
 lib/lib_memory.h|  96 ---
 lib/lib_memory.txt  |  64 ++
 memory_gen.sh   | 154 
 ospf6d/Makefile.am  |   7 ++
 ospf6d/ospf6_memory.c   |  67 ---
 ospf6d/ospf6_memory.h   |  48 --
 ospf6d/ospf6_memory.txt |  18 ++
 ospfd/Makefile.am   |   8 ++-
 ospfd/ospf_memory.c |  88 -
 ospfd/ospf_memory.h |  57 
 ospfd/ospf_memory.txt   |  28 
 pimd/Makefile.am|   7 ++
 pimd/pim_memory.c   |  58 -
 pimd/pim_memory.h   |  44 -
 pimd/pim_memory.txt |  14 
 ripd/Makefile.am|   8 ++-
 ripd/rip_memory.c   |  48 --
 ripd/rip_memory.h   |  39 ---
 ripd/rip_memory.txt |   9 +++
 ripngd/Makefile.am  |   6 ++
 ripngd/ripng_memory.c   |  48 --
 ripngd/ripng_memory.h   |  39 ---
 ripngd/ripng_memory.txt |   9 +++
 zebra/Makefile.am   |   8 ++-
 zebra/zebra_memory.c|  54 
 zebra/zebra_memory.h|  42 
 zebra/zebra_memory.txt  |  13 
 38 files changed, 459 insertions(+), 1270 deletions(-)
 delete mode 100644 bgpd/bgp_memory.c
 delete mode 100644 bgpd/bgp_memory.h
 create mode 100644 bgpd/bgp_memory.txt
 delete mode 100644 isisd/isis_memory.c
 delete mode 100644 isisd/isis_memory.h
 create mode 100644 isisd/isis_memory.txt
 delete mode 100644 lib/lib_memory.c
 delete mode 100644 lib/lib_memory.h
 create mode 100644 lib/lib_memory.txt
 create mode 100644 memory_gen.sh
 delete mode 100644 ospf6d/ospf6_memory.c
 delete mode 100644 ospf6d/ospf6_memory.h
 create mode 100644 ospf6d/ospf6_memory.txt
 delete mode 100644 ospfd/ospf_memory.c
 delete mode 100644 ospfd/ospf_memory.h
 create mode 100644 ospfd/ospf_memory.txt
 delete mode 100644 pimd/pim_memory.c
 delete mode 100644 pimd/pim_memory.h
 create mode 100644 pimd/pim_memory.txt
 delete mode 100644 ripd/rip_memory.c
 delete mode 100644 ripd/rip_memory.h
 create mode 100644 ripd/rip_memory.txt
 delete mode 100644 ripngd/ripng_memory.c
 delete mode 100644 ripngd/ripng_memory.h
 create mode 100644 ripngd/ripng_memory.txt
 delete mode 100644 zebra/zebra_memory.c
 delete mode 100644 zebra/zebra_memory.h
 create mode 100644 zebra/zebra_memory.txt

diff --git a/.gitignore b/.gitignore
index e8de252370de..1562581ee692 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,3 +38,5 @@ build
 m4/*.m4
 !m4/ax_sys_weak_alias.m4
 cscope.*
+*/*_memory.c
+*/*_memory.h
diff --git a/bgpd/Makefile.am b/bgpd/Makefile.am
index 608d018140e2..8e42395f0094 100644
--- a/bgpd/Makefile.am
+++ b/bgpd/Makefile.am
@@ -28,7 +28,14 @@ noinst_HEADERS = \
bgp_advertise.h bgp_snmp.h bgp_vty.h bgp_mpath.h \
bgp_encap.h bgp_encap_tlv.h bgp_encap_types.h
 
+
+bgp_memory.h: $(srcdir)/bgp_memory.txt $(srcdir)/../memory_gen.sh
+   (bash $(srcdir)/../memory_gen.sh bgp)
+
 bgpd_SOURCES = bgp_main.c
+
+BUILT_SOURCES = bgp_memory.h bgp_memory.c
+
 bgpd_LDADD = libbgp.a ../lib/libzebra.la @LIBCAP@ @LIBM@
 
 bgp_btoa_SOURCES = bgp_btoa.c
@@ -37,5 +44,5 @@ bgp_btoa_LDADD = libbgp.a ../lib/libzebra.la @LIBCAP@ @LIBM@
 examplesdir = $(exampledir)
 dist_examples_DATA = bgpd.conf.sample bgpd.conf.sample2
 
-EXTRA_DIST = BGP4-MIB.txt
+EXTRA_DIST = BGP4-MIB.txt bgp_memory.txt ../memory_gen.sh
 
diff --git a/bgpd/bgp_memory.c b/bgpd/bgp_memory.c
deleted file mode 100644
index 1c0ec1e6b360..
--- a/bgpd/bgp_memory.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/* bgpd memory type definitions
- *
- * Copyright (C) 2015  David Lamparter
- *
- * This file is part of Quagga.
- *
- * Quagga 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, or (a

[quagga-dev 16273] [PATCH v1 05/10] *: split & distribute memtypes

2016-10-12 Thread Philippe Guibert
From: David Lamparter <equi...@opensourcerouting.org>

This is a rather large mechanical commit that splits up the memory types
defined in lib/memtypes.c and distributes them into *_memory.[ch] files
in the individual daemons.
The zebra change is slightly annoying because there is no nice place to
put the #include "zebra_memory.h" statement.

Signed-off-by: David Lamparter <equi...@opensourcerouting.org>
Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/Makefile.am |   2 +
 bgpd/bgp_community.c |   1 +
 bgpd/bgp_memory.c|  97 
 bgpd/bgp_memory.h|  94 +++
 bgpd/bgpd.h  |   1 +
 isisd/Makefile.am|   2 +
 isisd/dict.c |   1 +
 isisd/isis_memory.c  |  45 +++
 isisd/isis_memory.h  |  46 
 isisd/isisd.h|   1 +
 lib/memtypes.c   | 190 ---
 ospf6d/Makefile.am   |   2 +
 ospf6d/ospf6_memory.c|  44 +++
 ospf6d/ospf6_memory.h|  45 +++
 ospf6d/ospf6d.h  |   2 +
 ospfd/Makefile.am|   6 +-
 ospfd/ospf_memory.c  |  54 ++
 ospfd/ospf_memory.h  |  55 ++
 ospfd/ospfd.h|   2 +
 pimd/Makefile.am |   2 +
 pimd/pim_memory.c|  40 ++
 pimd/pim_memory.h|  41 ++
 pimd/pimd.h  |   1 +
 ripd/Makefile.am |   2 +
 ripd/rip_memory.c|  35 +
 ripd/rip_memory.h|  36 +
 ripd/ripd.h  |   2 +
 ripngd/Makefile.am   |   2 +
 ripngd/ripng_memory.c|  35 +
 ripngd/ripng_memory.h|  36 +
 ripngd/ripngd.h  |   2 +
 vtysh/vtysh.h|   3 +
 vtysh/vtysh_config.c |   4 +
 zebra/Makefile.am|   6 +-
 zebra/connected.c|   1 +
 zebra/if_ioctl.c |   1 +
 zebra/if_ioctl_solaris.c |   1 +
 zebra/if_sysctl.c|   1 +
 zebra/interface.c|   1 +
 zebra/irdp_interface.c   |   1 +
 zebra/irdp_main.c|   1 +
 zebra/irdp_packet.c  |   1 +
 zebra/kernel_socket.c|   1 +
 zebra/main.c |   1 +
 zebra/router-id.c|   1 +
 zebra/rt_netlink.c   |   1 +
 zebra/rtadv.c|   1 +
 zebra/rtread_sysctl.c|   1 +
 zebra/test_main.c|   1 +
 zebra/zebra_memory.c |  38 ++
 zebra/zebra_memory.h |  39 ++
 zebra/zebra_rib.c|   1 +
 zebra/zebra_routemap.c   |   1 +
 zebra/zebra_vty.c|   1 +
 zebra/zserv.c|   1 +
 55 files changed, 840 insertions(+), 193 deletions(-)
 create mode 100644 bgpd/bgp_memory.c
 create mode 100644 bgpd/bgp_memory.h
 create mode 100644 isisd/isis_memory.c
 create mode 100644 isisd/isis_memory.h
 create mode 100644 ospf6d/ospf6_memory.c
 create mode 100644 ospf6d/ospf6_memory.h
 create mode 100644 ospfd/ospf_memory.c
 create mode 100644 ospfd/ospf_memory.h
 create mode 100644 pimd/pim_memory.c
 create mode 100644 pimd/pim_memory.h
 create mode 100644 ripd/rip_memory.c
 create mode 100644 ripd/rip_memory.h
 create mode 100644 ripngd/ripng_memory.c
 create mode 100644 ripngd/ripng_memory.h
 create mode 100644 zebra/zebra_memory.c
 create mode 100644 zebra/zebra_memory.h

diff --git a/bgpd/Makefile.am b/bgpd/Makefile.am
index d2775f39d277..608d018140e2 100644
--- a/bgpd/Makefile.am
+++ b/bgpd/Makefile.am
@@ -11,6 +11,7 @@ sbin_PROGRAMS = bgpd
 bin_PROGRAMS = bgp_btoa
 
 libbgp_a_SOURCES = \
+   bgp_memory.c \
bgpd.c bgp_fsm.c bgp_aspath.c bgp_community.c bgp_attr.c \
bgp_debug.c bgp_route.c bgp_zebra.c bgp_open.c bgp_routemap.c \
bgp_packet.c bgp_network.c bgp_filter.c bgp_regex.c bgp_clist.c \
@@ -19,6 +20,7 @@ libbgp_a_SOURCES = \
bgp_encap.c bgp_encap_tlv.c
 
 noinst_HEADERS = \
+   bgp_memory.h \
bgp_aspath.h bgp_attr.h bgp_community.h bgp_debug.h bgp_fsm.h \
bgp_network.h bgp_open.h bgp_packet.h bgp_regex.h bgp_route.h \
bgpd.h bgp_filter.h bgp_clist.h bgp_dump.h bgp_zebra.h \
diff --git a/bgpd/bgp_community.c b/bgpd/bgp_community.c
index f1997bd9ce3e..0d272c4c7896 100644
--- a/bgpd/bgp_community.c
+++ b/bgpd/bgp_community.c
@@ -23,6 +23,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, 
Boston, MA
 #include "hash.h"
 #include "memory.h"
 
+#include "bgpd/bgp_memory.h"
 #include "bgpd/bgp_community.h"
 
 /* Hash of community attribute. */
diff --git a/bgpd/bgp_memory.c b/bgpd/bgp_memory.c
new file mode 100644
index ..3c2b08796713
--- /dev/null
+++ b/bgpd/bgp_memory.c
@@ -0,0 +1,97 @@
+/* bgpd memory type definitions
+ *
+ * Copyright (C) 2015  David Lamparter
+ *
+ * This file is part of Quagga.
+ *
+ * Quagga 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, or (at your opti

[quagga-dev 16272] [PATCH v1 07/10] *: declare and init mgroup and mtype for all lib/daemons

2016-10-12 Thread Philippe Guibert
This commit centralises the memory group and memory types declarations
into one single place for each daemon/library. In this case, files
affected are /_memory.[ch].
In order to be used, the memory groups and memory types have to be
manually initialised. This is why the daemons are initialising their
own memory types and groups. In addition to this, as all daemons require
usage of lib library, then the daemons also initialise the lib memory
types and group entries.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_main.c   |   2 +
 bgpd/bgp_memory.c |  71 
 bgpd/bgp_memory.h |   3 +
 isisd/isis_main.c |   2 +
 isisd/isis_memory.c   |  25 +
 isisd/isis_memory.h   |   3 +
 lib/Makefile.am   |  10 +---
 lib/buffer.c  |   2 +-
 lib/command.c |   2 +-
 lib/distribute.c  |   2 +-
 lib/filter.c  |   2 +-
 lib/hash.c|   2 +-
 lib/if.c  |   2 +-
 lib/if_rmap.c |   2 +-
 lib/keychain.c|   2 +-
 lib/lib_memory.c  | 149 ++
 lib/lib_memory.h  |  96 
 lib/linklist.c|   2 +-
 lib/log.c |   2 +-
 lib/memory.h  |   2 -
 lib/memtypes.c|  80 ---
 lib/plist.c   |   2 +-
 lib/pqueue.c  |   2 +-
 lib/prefix.c  |   2 +-
 lib/privs.c   |   2 +-
 lib/routemap.c|   2 +-
 lib/sockunion.c   |   2 +-
 lib/stream.c  |   2 +-
 lib/table.c   |   2 +-
 lib/thread.c  |   2 +-
 lib/vector.c  |   2 +-
 lib/vrf.c |   2 +-
 lib/vty.c |   2 +-
 lib/workqueue.c   |   2 +-
 lib/zclient.c |   2 +-
 ospf6d/ospf6_main.c   |   2 +
 ospf6d/ospf6_memory.c |  23 
 ospf6d/ospf6_memory.h |   3 +
 ospfd/ospf_main.c |   2 +
 ospfd/ospf_memory.c   |  34 
 ospfd/ospf_memory.h   |   2 +
 pimd/pim_main.c   |   2 +
 pimd/pim_memory.c |  18 ++
 pimd/pim_memory.h |   3 +
 ripd/rip_main.c   |   2 +
 ripd/rip_memory.c |  13 +
 ripd/rip_memory.h |   3 +
 ripngd/ripng_main.c   |   2 +
 ripngd/ripng_memory.c |  13 +
 ripngd/ripng_memory.h |   3 +
 vtysh/vtysh.c |   1 +
 vtysh/vtysh_main.c|   1 +
 vtysh/vtysh_user.c|   1 +
 zebra/main.c  |   2 +
 zebra/zebra_memory.c  |  16 ++
 zebra/zebra_memory.h  |   3 +
 56 files changed, 527 insertions(+), 113 deletions(-)
 create mode 100644 lib/lib_memory.c
 create mode 100644 lib/lib_memory.h
 delete mode 100644 lib/memtypes.c

diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
index 25669a0cb08f..e1bc4c6151d2 100644
--- a/bgpd/bgp_main.c
+++ b/bgpd/bgp_main.c
@@ -354,6 +354,8 @@ main (int argc, char **argv)
   /* Preserve name of myself. */
   progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
 
+  bgp_memory_init();
+
   zlog_default = openzlog (progname, ZLOG_BGP,
   LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
 
diff --git a/bgpd/bgp_memory.c b/bgpd/bgp_memory.c
index 3c2b08796713..1c0ec1e6b360 100644
--- a/bgpd/bgp_memory.c
+++ b/bgpd/bgp_memory.c
@@ -95,3 +95,74 @@ DEFINE_MTYPE(BGPD, BGP_AGGREGATE,"BGP aggregate")
 DEFINE_MTYPE(BGPD, BGP_ADDR,   "BGP own address")
 DEFINE_MTYPE(BGPD, ENCAP_TLV,  "ENCAP TLV")
 
+void bgp_memory_init(void)
+{
+  lib_memory_init();
+
+  INIT_MGROUP(BGPD);
+  INIT_MTYPE(BGP);
+  INIT_MTYPE(BGP_LISTENER);
+  INIT_MTYPE(BGP_PEER);
+  INIT_MTYPE(BGP_PEER_HOST);
+  INIT_MTYPE(PEER_GROUP);
+  INIT_MTYPE(PEER_DESC);
+  INIT_MTYPE(PEER_PASSWORD);
+  INIT_MTYPE(ATTR);
+  INIT_MTYPE(ATTR_EXTRA);
+  INIT_MTYPE(AS_PATH);
+  INIT_MTYPE(AS_SEG);
+  INIT_MTYPE(AS_SEG_DATA);
+  INIT_MTYPE(AS_STR);
+
+  INIT_MTYPE(BGP_TABLE);
+  INIT_MTYPE(BGP_NODE);
+  INIT_MTYPE(BGP_ROUTE);
+  INIT_MTYPE(BGP_ROUTE_EXTRA);
+  INIT_MTYPE(BGP_CONN);
+  INIT_MTYPE(BGP_STATIC);
+  INIT_MTYPE(BGP_ADVERTISE_ATTR);
+  INIT_MTYPE(BGP_ADVERTISE);
+  INIT_MTYPE(BGP_SYNCHRONISE);
+  INIT_MTYPE(BGP_ADJ_IN);
+  INIT_MTYPE(BGP_ADJ_OUT);
+  INIT_MTYPE(BGP_MPATH_INFO);
+
+  INIT_MTYPE(AS_LIST);
+  INIT_MTYPE(AS_FILTER);
+  INIT_MTYPE(AS_FILTER_STR);
+
+  INIT_MTYPE(COMMUNITY);
+  INIT_MTYPE(COMMUNITY_VAL);
+  INIT_MTYPE(COMMUNITY_STR);
+
+  INIT_MTYPE(ECOMMUNITY);
+  INIT_MTYPE(ECOMMUNITY_VAL);
+  INIT_MTYPE(ECOMMUNITY_STR);
+
+  INIT_MTYPE(COMMUNITY_LIST);
+  INIT_MTYPE(COMMUNITY_LIST_NAME);
+  INIT_MTYPE(COMMUNITY_LIST_ENTRY);
+  INIT_MTYPE(COMMUNITY_LIST_CONFIG);
+  INIT_MTYPE(COMMUNITY_LIST_HANDLER);
+
+  INIT_MTYPE(CLUSTER);
+  INIT_MTYPE(CLUSTER_VAL);
+
+  INIT_MTYPE(BGP_PROCESS_QUEUE);
+  INIT_MTYPE(BGP_CLEAR_NODE_QUEUE);
+
+  INIT_MTYPE(TRANSIT);
+  INIT_MTYPE(TRANSIT_VAL);
+
+  INIT_MTYPE(BGP_DISTANCE);
+  INIT_MTYPE(BGP_NEXTHOP_CACHE);
+  INIT_MTYPE(BGP_CONFED_LIST);
+  INIT_MTYPE(PEER_UPDATE_SOURCE);
+  INIT_MTYPE(BGP_DAMP_INFO);
+  INIT_MTYPE(BGP_D

[quagga-dev 16273] [PATCH v1 10/10] lib: clean/restore memory debugging functions

2016-10-12 Thread Philippe Guibert
This adapts the dump-at-exit handler and removes the old leftover code.

(Note the text in log_memtype_stderr was actually incorrect as the only
caller in bgpd cleans up configuration before calling it, i.e. any
remaining allocations are missing-cleanup bugs.)

Signed-off-by: David Lamparter <equi...@opensourcerouting.org>
Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 lib/memory.c | 35 ++
 lib/memory.h |  1 +
 lib/memory_vty.c | 89 +---
 lib/memory_vty.h |  1 -
 4 files changed, 37 insertions(+), 89 deletions(-)

diff --git a/lib/memory.c b/lib/memory.c
index c30d41dda4e9..8f21a3bf35ab 100644
--- a/lib/memory.c
+++ b/lib/memory.c
@@ -100,3 +100,38 @@ int qmem_walk (qmem_walk_fn *func, void *arg)
}
return 0;
 }
+
+struct exit_dump_args
+{
+  const char *prefix;
+  int error;
+};
+
+static int
+qmem_exit_walker (void *arg, struct memgroup *mg, struct memtype *mt)
+{
+  struct exit_dump_args *eda = arg;
+  
+  if (!mt)
+{
+  fprintf (stderr, "%s: showing active allocations in memory group %s\n",
+   eda->prefix, mg->name);
+}
+  else if (mt->n_alloc)
+{
+  char size[32];
+  eda->error++;
+  snprintf (size, sizeof (size), "%10zu", mt->size);
+  fprintf (stderr, "%s:  %-30s: %6zu * %s\n",
+   eda->prefix, mt->name, mt->n_alloc,
+   mt->size == SIZE_VAR ? "(variably sized)" : size);
+}
+  return 0;
+}
+
+void
+log_memstats_stderr (const char *prefix)
+{
+  struct exit_dump_args eda = { .prefix = prefix, .error = 0 };
+  qmem_walk (qmem_exit_walker, );
+}
diff --git a/lib/memory.h b/lib/memory.h
index 602afff2e2c4..3eea4bd736b3 100644
--- a/lib/memory.h
+++ b/lib/memory.h
@@ -141,6 +141,7 @@ static inline size_t mtype_stats_alloc(struct memtype *mt)
  * last value from qmem_walk_fn. */
 typedef int qmem_walk_fn (void *arg, struct memgroup *mg, struct memtype *mt);
 extern int qmem_walk (qmem_walk_fn *func, void *arg);
+extern void log_memstats_stderr (const char *);
 
 extern void memory_oom (size_t size, const char *name);
 
diff --git a/lib/memory_vty.c b/lib/memory_vty.c
index 814ced8607c0..010fe9e664c1 100644
--- a/lib/memory_vty.c
+++ b/lib/memory_vty.c
@@ -35,80 +35,6 @@
 #include "vty.h"
 #include "command.h"
 
-void
-log_memstats_stderr (const char *prefix)
-{
-#if 0
-  struct mlist *ml;
-  struct memory_list *m;
-  int i;
-  int j = 0;
-
-  for (ml = mlists; ml->list; ml++)
-{
-  i = 0;
-
-  for (m = ml->list; m->index >= 0; m++)
-if (m->index && mstat[m->index].alloc)
-  {
-if (!i)
-  fprintf (stderr,
-   "%s: memstats: Current memory utilization in module 
%s:\n",
-   prefix,
-   ml->name);
-fprintf (stderr,
- "%s: memstats:  %-30s: %10ld%s\n",
- prefix,
- m->format,
- mstat[m->index].alloc,
- mstat[m->index].alloc < 0 ? " (REPORT THIS BUG!)" : "");
-i = j = 1;
-  }
-}
-
-  if (j)
-fprintf (stderr,
- "%s: memstats: NOTE: If configuration exists, utilization may be "
- "expected.\n",
- prefix);
-  else
-fprintf (stderr,
- "%s: memstats: No remaining tracked memory utilization.\n",
- prefix);
-#endif
-}
-
-#if 0
-static void
-show_separator(struct vty *vty)
-{
-  vty_out (vty, "-\r\n");
-}
-
-static int
-show_memory_vty (struct vty *vty, struct memory_list *list)
-{
-  struct memory_list *m;
-  int needsep = 0;
-
-  for (m = list; m->index >= 0; m++)
-if (m->index == 0)
-  {
-   if (needsep)
- {
-   show_separator (vty);
-   needsep = 0;
- }
-  }
-else if (mstat[m->index].alloc)
-  {
-   vty_out (vty, "%-30s: %10ld\r\n", m->format, mstat[m->index].alloc);
-   needsep = 1;
-  }
-  return needsep;
-}
-#endif
-
 #ifdef HAVE_MALLINFO
 static int
 show_memory_mallinfo (struct vty *vty)
@@ -174,23 +100,10 @@ DEFUN (show_memory,
"Show running system information\n"
"Memory statistics\n")
 {
-  int needsep = 0;
-  
 #ifdef HAVE_MALLINFO
-  needsep = show_memory_mallinfo (vty);
+  show_memory_mallinfo (vty);
 #endif /* HAVE_MALLINFO */
 
-  (void) needsep;
-#if 0
-  struct mlist *ml;
-  for (ml = mlists; ml->list; ml++)
-{
-  if (needsep)
-   show_separator (vty);
-  needsep = show_memory_vty (vty, ml->list);
-}
-#endif
-
   qmem_walk(qmem_walker, vty);
   return CMD_SUCCESS;
 }
diff --git a/lib/memory_vty.h b/lib/memory

[quagga-dev 16271] [PATCH v1 06/10] *: stop (re|ab)using lib/ MTYPEs

2016-10-12 Thread Philippe Guibert
From: David Lamparter <equi...@opensourcerouting.org>

bgpd, ospf6d, isisd and some tests were reusing MTYPEs defined in the
library for its own use.  This is bad practice and will break with the
later commit making the library's MTYPEs static.

Signed-off-by: David Lamparter <equi...@opensourcerouting.org>
Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_nexthop.c   |  8 +---
 isisd/isis_memory.c  |  2 ++
 isisd/isis_memory.h  |  2 ++
 isisd/isis_redist.c  | 14 +++---
 ospf6d/ospf6_interface.c | 10 ++
 tests/heavy-wq.c | 14 +-
 tests/test-memory.c  | 49 +---
 7 files changed, 57 insertions(+), 42 deletions(-)

diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c
index 24068141c1d5..364d6e924e68 100644
--- a/bgpd/bgp_nexthop.c
+++ b/bgpd/bgp_nexthop.c
@@ -42,6 +42,8 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, 
Boston, MA
 #include "zebra/rib.h"
 #include "zebra/zserv.h"   /* For ZEBRA_SERV_PATH. */
 
+DEFINE_MTYPE_STATIC(BGPD, BGP_NEXTHOP, "BGP nexthop")
+
 struct bgp_nexthop_cache *zlookup_query (struct in_addr);
 struct bgp_nexthop_cache *zlookup_query_ipv6 (struct in6_addr *);
 
@@ -92,7 +94,7 @@ bnc_nexthop_free (struct bgp_nexthop_cache *bnc)
   for (nexthop = bnc->nexthop; nexthop; nexthop = next)
 {
   next = nexthop->next;
-  XFREE (MTYPE_NEXTHOP, nexthop);
+  XFREE (MTYPE_BGP_NEXTHOP, nexthop);
 }
 }
 
@@ -819,7 +821,7 @@ zlookup_read (void)
 
   for (i = 0; i < nexthop_num; i++)
{
- nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
+ nexthop = XCALLOC (MTYPE_BGP_NEXTHOP, sizeof (struct nexthop));
  nexthop->type = stream_getc (s);
  switch (nexthop->type)
{
@@ -922,7 +924,7 @@ zlookup_read_ipv6 (void)
 
   for (i = 0; i < nexthop_num; i++)
{
- nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
+ nexthop = XCALLOC (MTYPE_BGP_NEXTHOP, sizeof (struct nexthop));
  nexthop->type = stream_getc (s);
  switch (nexthop->type)
{
diff --git a/isisd/isis_memory.c b/isisd/isis_memory.c
index 9bc506e3a325..5c5fee76bb6c 100644
--- a/isisd/isis_memory.c
+++ b/isisd/isis_memory.c
@@ -43,3 +43,5 @@ DEFINE_MTYPE(ISISD, ISIS_NEXTHOP,   "ISIS nexthop")
 DEFINE_MTYPE(ISISD, ISIS_NEXTHOP6,  "ISIS nexthop6")
 DEFINE_MTYPE(ISISD, ISIS_DICT,  "ISIS dictionary")
 DEFINE_MTYPE(ISISD, ISIS_DICT_NODE, "ISIS dictionary node")
+DEFINE_MTYPE(ISISD, ISIS_EXT_ROUTE, "ISIS redistributed route")
+DEFINE_MTYPE(ISISD, ISIS_EXT_INFO,  "ISIS redistributed route info")
diff --git a/isisd/isis_memory.h b/isisd/isis_memory.h
index 40bb88a842d4..6ebce1fc614a 100644
--- a/isisd/isis_memory.h
+++ b/isisd/isis_memory.h
@@ -42,5 +42,7 @@ DECLARE_MTYPE(ISIS_NEXTHOP)
 DECLARE_MTYPE(ISIS_NEXTHOP6)
 DECLARE_MTYPE(ISIS_DICT)
 DECLARE_MTYPE(ISIS_DICT_NODE)
+DECLARE_MTYPE(ISIS_EXT_ROUTE)
+DECLARE_MTYPE(ISIS_EXT_INFO)
 
 #endif /* _QUAGGA_ISIS_MEMORY_H */
diff --git a/isisd/isis_redist.c b/isisd/isis_redist.c
index 690ae4720c86..d4a6675d4d62 100644
--- a/isisd/isis_redist.c
+++ b/isisd/isis_redist.c
@@ -24,7 +24,7 @@
 #include "if.h"
 #include "linklist.h"
 #include "memory.h"
-#include "memtypes.h"
+#include "isis_memory.h"
 #include "prefix.h"
 #include "routemap.h"
 #include "stream.h"
@@ -95,7 +95,7 @@ isis_redist_route_node_create(route_table_delegate_t 
*delegate,
   struct route_table *table)
 {
   struct route_node *node;
-  node = XCALLOC(MTYPE_ROUTE_NODE, sizeof(*node));
+  node = XCALLOC(MTYPE_ISIS_EXT_ROUTE, sizeof(*node));
   return node;
 }
 
@@ -105,8 +105,8 @@ isis_redist_route_node_destroy(route_table_delegate_t 
*delegate,
struct route_node *node)
 {
   if (node->info)
-XFREE(MTYPE_ISIS, node->info);
-  XFREE (MTYPE_ROUTE_NODE, node);
+XFREE(MTYPE_ISIS_EXT_INFO, node->info);
+  XFREE (MTYPE_ISIS_EXT_ROUTE, node);
 }
 
 static route_table_delegate_t isis_redist_rt_delegate = {
@@ -143,7 +143,7 @@ isis_redist_install(struct isis_area *area, int level,
 }
   else
 {
-  er_node->info = XMALLOC(MTYPE_ISIS, sizeof(*info));
+  er_node->info = XMALLOC(MTYPE_ISIS_EXT_INFO, sizeof(*info));
 }
 
   memcpy(er_node->info, info, sizeof(*info));
@@ -243,7 +243,7 @@ isis_redist_ensure_default(struct isis *isis, int family)
   return;
 }
 
-  ei_node->info = XCALLOC(MTYPE_ISIS, sizeof(struct isis_ext_info));
+  ei_node->info = XCALLOC(MTYPE_ISIS_EXT_INFO, sizeof(struct isis_ext_info));
 
   info = ei_node->info;
   info->origin = DEFAULT_ROUTE;
@@ -281,7 +281,7 @@ isis_redist_add(int type, st

[quagga-dev 16269] [PATCH v1 02/10] lib: add new extensible memory-type handling

2016-10-12 Thread Philippe Guibert
From: David Lamparter <equi...@opensourcerouting.org>

This rewrites Quagga's memory per-type allocation counting, without
using a fixed global list of types.  Instead, source files can declare
memory types which get handled through constructor functions called by
the dynamic linker during startup.

Signed-off-by: David Lamparter <equi...@opensourcerouting.org>
Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 lib/Makefile.am  |   1 +
 lib/log.c|   8 +++
 lib/memory.c | 102 +++
 lib/memory.h | 159 ++-
 lib/memory_vty.c |  19 +++
 lib/memory_vty.h |   2 -
 6 files changed, 288 insertions(+), 3 deletions(-)
 create mode 100644 lib/memory.c

diff --git a/lib/Makefile.am b/lib/Makefile.am
index e1e79caebc41..d67c4e72fd3b 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -14,6 +14,7 @@ libzebra_la_SOURCES = \
filter.c routemap.c distribute.c stream.c str.c log.c plist.c \
zclient.c sockopt.c smux.c agentx.c snmp.c md5.c if_rmap.c keychain.c 
privs.c \
sigevent.c pqueue.c jhash.c memtypes.c workqueue.c vrf.c \
+   memory.c \
memory_vty.c
 
 BUILT_SOURCES = memtypes.h route_types.h gitversion.h
diff --git a/lib/log.c b/lib/log.c
index 0914bf8405b6..41de03a8e3ed 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -669,6 +669,14 @@ _zlog_assert_failed (const char *assertion, const char 
*file,
   abort();
 }
 
+void
+memory_oom (size_t size, const char *name)
+{
+   zlog_err("out of memory: failed to allocate %zu bytes for %s"
+"object", size, name);
+   zlog_backtrace(LOG_ERR);
+   abort();
+}
 
 /* Open log stream */
 struct zlog *
diff --git a/lib/memory.c b/lib/memory.c
new file mode 100644
index ..c30d41dda4e9
--- /dev/null
+++ b/lib/memory.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2015-16  David Lamparter
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include 
+
+#include 
+
+#include "memory.h"
+
+static struct memgroup *mg_first = NULL;
+struct memgroup **mg_insert = _first;
+
+static inline void mt_count_alloc(struct memtype *mt, size_t size)
+{
+   mt->n_alloc++;
+
+   if (mt->size == 0)
+   mt->size = size;
+   else if (mt->size != size)
+   mt->size = SIZE_VAR;
+}
+
+static inline void mt_count_free(struct memtype *mt)
+{
+   mt->n_alloc--;
+}
+
+static inline void *mt_checkalloc(struct memtype *mt, void *ptr, size_t size)
+{
+   if (__builtin_expect(ptr == NULL, 0)) {
+   memory_oom(size, mt->name);
+   return NULL;
+   }
+   mt_count_alloc (mt, size);
+   return ptr;
+}
+
+void *qmalloc (struct memtype *mt, size_t size)
+{
+   return mt_checkalloc(mt, malloc (size), size);
+}
+
+void *qcalloc (struct memtype *mt, size_t size)
+{
+   return mt_checkalloc(mt, calloc (size, 1), size);
+}
+
+void *qrealloc (struct memtype *mt, void *ptr, size_t size)
+{
+   if (ptr)
+   mt_count_free (mt);
+   return mt_checkalloc(mt,
+   ptr ? realloc(ptr, size) : malloc(size),
+   size);
+}
+
+void *qstrdup (struct memtype *mt, const char *str)
+{
+   return mt_checkalloc(mt, strdup (str), strlen (str) + 1);
+}
+
+void qfree (struct memtype *mt, void *ptr)
+{
+   if (ptr)
+   mt_count_free (mt);
+   free (ptr);
+}
+
+int qmem_walk (qmem_walk_fn *func, void *arg)
+{
+   struct memgroup *mg;
+   struct memtype *mt;
+   int rv;
+
+   for (mg = mg_first; mg; mg = mg->next) {
+   if ((rv = func (arg, mg, NULL)))
+   return rv;
+   for (mt = mg->types; mt; mt = mt->next)
+   if ((rv = func (arg, mg, mt)))
+   return rv;
+   }
+  

[quagga-dev 16272] [PATCH v1 08/10] *: static mgroup and mtypes are locally declared and initialised

2016-10-12 Thread Philippe Guibert
On some specific cases, the user may wish not to export its memory
type and group. The user can then declare and initialises this
memory type, provided that he ensures also the initialisation. The
goal of that commit is initialising in quagga the static mtypes.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_nexthop.c  | 2 ++
 ospf6d/ospf6_interface.c| 2 ++
 ospfclient/ospf_apiclient.c | 2 ++
 ospfd/ospf_opaque.c | 9 +
 ospfd/ospf_te.c | 8 
 tests/heavy-wq.c| 3 +++
 tests/test-memory.c | 2 ++
 vtysh/vtysh_config.c| 4 
 8 files changed, 32 insertions(+)

diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c
index 364d6e924e68..117083cbd3b0 100644
--- a/bgpd/bgp_nexthop.c
+++ b/bgpd/bgp_nexthop.c
@@ -1393,6 +1393,8 @@ bgp_config_write_scan_time (struct vty *vty)
 void
 bgp_scan_init (void)
 {
+  INIT_MTYPE(BGP_NEXTHOP);
+
   zlookup = zclient_new (bm->master);
   zlookup->sock = -1;
   zlookup->t_connect = thread_add_event (bm->master, zlookup_connect, zlookup, 
0);
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c
index d03ae76d5e94..32c1b7271a4c 100644
--- a/ospf6d/ospf6_interface.c
+++ b/ospf6d/ospf6_interface.c
@@ -1865,6 +1865,8 @@ static struct cmd_node interface_node =
 void
 ospf6_interface_init (void)
 {
+  INIT_MTYPE(CFG_PLIST_NAME);
+
   /* Install interface node. */
   install_node (_node, config_write_ospf6_interface);
 
diff --git a/ospfclient/ospf_apiclient.c b/ospfclient/ospf_apiclient.c
index 453e05ce2ebb..799d63f0c203 100644
--- a/ospfclient/ospf_apiclient.c
+++ b/ospfclient/ospf_apiclient.c
@@ -99,6 +99,8 @@ ospf_apiclient_connect (char *host, int syncport)
   int ret;
   int on = 1;
 
+  INIT_MTYPE(OSPF_APICLIENT);
+
   /* There are two connections between the client and the server.
  First the client opens a connection for synchronous requests/replies 
  to the server. The server will accept this connection and
diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c
index fa7b2de8f432..2c2971b47d24 100644
--- a/ospfd/ospf_opaque.c
+++ b/ospfd/ospf_opaque.c
@@ -69,6 +69,7 @@ void ospf_apiserver_term (void);
 int ospf_apiserver_enable;
 #endif /* SUPPORT_OSPF_API */
 
+static void ospf_opaque_memory_init ();
 static void ospf_opaque_register_vty (void);
 static void ospf_opaque_funclist_init (void);
 static void ospf_opaque_funclist_term (void);
@@ -77,9 +78,17 @@ static void free_opaque_info_per_id (void *val);
 static int ospf_opaque_lsa_install_hook (struct ospf_lsa *lsa);
 static int ospf_opaque_lsa_delete_hook (struct ospf_lsa *lsa);
 
+static void ospf_opaque_memory_init(void)
+{
+  INIT_MTYPE(OSPF_OPAQUE_FUNCTAB);
+  INIT_MTYPE(OPAQUE_INFO_PER_TYPE);
+  INIT_MTYPE(OPAQUE_INFO_PER_ID); 
+}
+
 void
 ospf_opaque_init (void)
 {
+  ospf_opaque_memory_init ();
   ospf_opaque_register_vty ();
   ospf_opaque_funclist_init ();
 
diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c
index 04496ef21ce2..a02715e1bf0c 100644
--- a/ospfd/ospf_te.c
+++ b/ospfd/ospf_te.c
@@ -119,6 +119,7 @@ enum sched_opcode {
  * Followings are initialize/terminate functions for MPLS-TE handling.
  **/
 
+static void ospf_mpls_te_memory_init(void);
 static int ospf_mpls_te_new_if (struct interface *ifp);
 static int ospf_mpls_te_del_if (struct interface *ifp);
 static void ospf_mpls_te_ism_change (struct ospf_interface *oi, int 
old_status);
@@ -133,11 +134,18 @@ static void ospf_mpls_te_lsa_schedule (struct 
mpls_te_link *lp, enum sched_opcod
 static void del_mpls_te_link (void *val);
 static void ospf_mpls_te_register_vty (void);
 
+static void ospf_mpls_te_memory_init(void)
+{
+  INIT_MTYPE(OSPF_MPLS_TE_LINKPARAMS);
+}
+
 int
 ospf_mpls_te_init (void)
 {
   int rc;
 
+  ospf_mpls_te_memory_init();
+
   rc = ospf_register_opaque_functab (
 OSPF_OPAQUE_AREA_LSA,
 OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA,
diff --git a/tests/heavy-wq.c b/tests/heavy-wq.c
index 2d15dc37bdeb..fc836150da7c 100644
--- a/tests/heavy-wq.c
+++ b/tests/heavy-wq.c
@@ -179,6 +179,9 @@ heavy_wq_init ()
 void
 test_init()
 {
+  INIT_MTYPE(WQ_NODE);
+  INIT_MTYPE(WQ_NODE_STR);
+
   install_element (VIEW_NODE, _foo_cmd);
   heavy_wq_init();
 }
diff --git a/tests/test-memory.c b/tests/test-memory.c
index 6849b9dcebef..da623f885a70 100644
--- a/tests/test-memory.c
+++ b/tests/test-memory.c
@@ -51,6 +51,8 @@ main(int argc, char **argv)
   void *a[10];
   int i;
 
+  INIT_MTYPE(TEST);
+
   printf ("malloc x, malloc x, free, malloc x, free free\n\n");
   /* simple case, test cache */
   for (i = 0; i < TIMES; i++)
diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c
index f19fe0b86bc5..1866f376d027 100644
--- a/vtysh/vtysh_config.c
+++ b/vtysh/vtysh_config.c
@@ -438,6 +438,10 @@ vtysh_config_write ()
 void
 vtysh_config_init ()
 {
+  INIT_MGROUP(MVTYSH);
+  INIT_MTYPE(VTYSH_CONFIG);

[quagga-dev 16266] [PATCH v1 00/10] VRF Import Processing + VRF Multipath

2016-10-12 Thread Philippe Guibert
This series of patch is the following of VRF and VRF RIB tables
introduction in BGP.
It enhances the import processing algorithm: it reuses the export route
target extended community, as well as the local import route target
configured per VRF, to append/remove NLRI entries from VPNv4 into VRF
RIB entries.
The received NLRI entries are stored in VRF RIB entries, then BGP best
selection algorithm applies to select the best path.
This patch also includes a new vty command to set the multipath per VRF.
This makes then the selection algorithm more robust.
All those multipath and selected entries are notified in a log
message.

This series of patch should be used in conjunction with the following 5 patches.

[quagga-dev,16244,v4,1/3] lib: 3byte stream foo
[quagga-dev,16247,v4,2/3] bgpd: multiple label stack support
[quagga-dev,16246,v4,3/3] tests: enhance bgpd testing with label value

[quagga-dev,16249,v2,1/2] bgpd: VRF vty configuration, RIB table creation
[quagga-dev,16250,v2,2/2] bgpd: vpnv4 af exports extended communities


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16268] [PATCH v1 03/10] lib: remove constructor reference

2016-10-12 Thread Philippe Guibert
because some compilers do not use this feature, it is provided an
API that forces the user to call its mem group and memtypes init.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 lib/memory.h | 24 ++--
 1 file changed, 2 insertions(+), 22 deletions(-)

diff --git a/lib/memory.h b/lib/memory.h
index 0c4a1ef56ccc..86971ccd5e90 100644
--- a/lib/memory.h
+++ b/lib/memory.h
@@ -41,27 +41,9 @@ struct memgroup {
const char *name;
 };
 
-#if defined(__clang__)
-# if __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 5)
-#  define _RET_NONNULL  , returns_nonnull
-# endif
-# define _CONSTRUCTOR(x) constructor(x)
-#elif defined(__GNUC__)
-# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)
-#  define _RET_NONNULL  , returns_nonnull
-# endif
-# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
-#  define _CONSTRUCTOR(x) constructor(x)
-#  define _ALLOC_SIZE(x)  alloc_size(x)
-# endif
-#endif
-
 #ifndef _RET_NONNULL
 # define _RET_NONNULL
 #endif
-#ifndef _CONSTRUCTOR
-# define _CONSTRUCTOR(x) constructor
-#endif
 #ifndef _ALLOC_SIZE
 # define _ALLOC_SIZE(x)
 #endif
@@ -100,12 +82,11 @@ struct memgroup {
.types = NULL, .next = NULL, .insert = NULL, \
}; \
static void _mginit_##mname (void) \
- __attribute__ ((_CONSTRUCTOR (1000))); \
-   static void _mginit_##mname (void) \
{   extern struct memgroup **mg_insert; \
*mg_insert = &_mg_##mname; \
mg_insert =  &_mg_##mname.next; }
 
+#define INIT_MGROUP(mname) _mginit_##mname ()
 
 #define DECLARE_MTYPE(name) \
extern struct memtype _mt_##name; \
@@ -118,8 +99,6 @@ struct memgroup {
.next = NULL, .n_alloc = 0, .size = 0, \
}; \
static void _mtinit_##mname (void) \
- __attribute__ ((_CONSTRUCTOR (1001))); \
-   static void _mtinit_##mname (void) \
{   if (_mg_##group.insert == NULL) \
_mg_##group.insert = &_mg_##group.types; \
*_mg_##group.insert = &_mt_##mname; \
@@ -131,6 +110,7 @@ struct memgroup {
DEFINE_MTYPE_ATTR(group, name, static, desc) \
static struct memtype * const MTYPE_ ## name = &_mt_##name;
 
+#define INIT_MTYPE(mname) _mtinit_##mname ()
 
 extern void *qmalloc (struct memtype *mt, size_t size)
__attribute__ ((malloc, _ALLOC_SIZE(2), nonnull (1) _RET_NONNULL));
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


[quagga-dev 16262] [PATCH 1/2] bgpd: eliminate RD related duplicate code in bgp_encap.c decode_rd_... apis are declared global in bgp_mplsvpn.c

2016-10-12 Thread Philippe Guibert
From: Lou Berger 

---
 bgpd/bgp_encap.c   | 45 -
 bgpd/bgp_mplsvpn.c |  8 
 bgpd/bgp_mplsvpn.h |  5 +
 3 files changed, 9 insertions(+), 49 deletions(-)

diff --git a/bgpd/bgp_encap.c b/bgpd/bgp_encap.c
index edd9d7675811..8361d3f55a49 100644
--- a/bgpd/bgp_encap.c
+++ b/bgpd/bgp_encap.c
@@ -45,51 +45,6 @@ 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 (_ip->ip, pnt, 4);
-  pnt += 4;
-  
-  rd_ip->val = ((u_int16_t) *pnt++ << 8);
-  rd_ip->val |= (u_int16_t) *pnt;
-}
-
 static void
 ecom2prd(struct ecommunity *ecom, struct prefix_rd *prd)
 {
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index 047105d79130..392a239f19c8 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -35,7 +35,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, 
Boston, MA
 #include "bgpd/bgp_mplsvpn.h"
 #include "bgpd/bgp_packet.h"
 
-static u_int16_t
+u_int16_t
 decode_rd_type (u_char *pnt)
 {
   u_int16_t v;
@@ -57,7 +57,7 @@ decode_label (u_char *pnt)
 }
 
 /* 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 +70,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 +83,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 (_ip->ip, pnt, 4);
diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h
index 3299b9cb9a04..3fbbd335405b 100644
--- a/bgpd/bgp_mplsvpn.h
+++ b/bgpd/bgp_mplsvpn.h
@@ -41,9 +41,14 @@ struct rd_ip
   u_int16_t val;
 };
 
+extern u_int16_t decode_rd_type (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 *);
 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);
-- 
2.1.4


___
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev


  1   2   >