Mailing List Archive

[PATCH 15/23] bgpd: pubsub route updates
From: David Lamparter <equinox@opensourcerouting.org>

This commit brings necessary changes in order to send a notification
through capnproto.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
---
bgpd/Makefile.am | 4 +++
bgpd/bgp.capnp | 22 ++++++++++++
bgpd/bgp_route.c | 22 ++++++++++++
bgpd/bgp_zmq.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
bgpd/bgpd.c | 4 +++
bgpd/bgpd.h | 24 +++++++++++++
lib/memtypes.c | 1 +
7 files changed, 182 insertions(+)
create mode 100644 bgpd/bgp_zmq.c

diff --git a/bgpd/Makefile.am b/bgpd/Makefile.am
index 7cb5d8024757..1304edddeccb 100644
--- a/bgpd/Makefile.am
+++ b/bgpd/Makefile.am
@@ -26,6 +26,10 @@ 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_nht.h

+if HAVE_ZEROMQ
+libbgp_a_SOURCES += bgp_zmq.c
+endif
+
bgpd_SOURCES = bgp_main.c

bgpd_LDADD = libbgp.a ../lib/libzebra.la @LIBCAP@ @LIBM@ @ZEROMQ_LIBS@ @CAPN_C_LIBS@
diff --git a/bgpd/bgp.capnp b/bgpd/bgp.capnp
index 2603e6983ad6..da56ee4d2548 100644
--- a/bgpd/bgp.capnp
+++ b/bgpd/bgp.capnp
@@ -43,6 +43,10 @@ struct AfiSafiKey $cgennaked $cgetfield {
struct ExtCommunityList {
values @0 :List(UInt64);
}
+struct PrefixV4 {
+ addr @0 :UInt32;
+ prefixlen @1 :UInt8;
+}

struct BGP $ctype("struct bgp") $cgen
$csetter("bgp_%%_set")
@@ -80,6 +84,8 @@ struct BGP $ctype("struct bgp") $cgen

restartTime @25 :UInt32;
stalepathTime @26 :UInt32 $csetwrite;
+
+ notifyZMQUrl @27 :Text;
}

struct BGPAfiSafi $ctype("struct bgp") $cgen $carraykey("AfiSafiKey") {
@@ -153,4 +159,20 @@ struct BGPVRF $ctype("struct bgp_vrf") $cgen
rtExport @2 :ExtCommunityList;
}

+struct BGPEventVRFRoute $ctype("struct bgp_event_vrf") $cgen
+{
+ announce @0 :Bool;
+ outboundRd @1 :UInt64;
+ prefix @2 :PrefixV4;
+ nexthop @3 :IPv4;
+ label @4 :UInt32;
+}
+
+struct BGPEventShut $ctype("struct bgp_event_shut") $cgen
+{
+ peer @0 :IPv4;
+ type @1 :UInt8;
+ subtype @2 :UInt8;
+}
+
# vim: set noet ts=8 nowrap tw=0:
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 07aa5a259f32..d26e64256985 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -1590,8 +1590,22 @@ void
bgp_vrf_update (struct bgp_vrf *vrf, afi_t afi, struct bgp_node *rn,
struct bgp_info *selected, uint8_t announce)
{
+ struct bgp_event_vrf event = {
+ .announce = announce,
+ .outbound_rd = vrf->outbound_rd,
+ .prefix.family = rn->p.family,
+ .prefix.prefixlen = rn->p.prefixlen,
+ .prefix.prefix = rn->p.u.prefix4,
+ };
+
if(!vrf || (rn && bgp_node_table (rn)->type != BGP_TABLE_VRF))
return;
+
+ if (selected->extra->nlabels)
+ event.label = selected->extra->labels[0] >> 4;
+ else
+ event.label = 0;
+
if (announce == true)
{
if(CHECK_FLAG (selected->flags, BGP_INFO_UPDATE_SENT))
@@ -1635,6 +1649,14 @@ bgp_vrf_update (struct bgp_vrf *vrf, afi_t afi, struct bgp_node *rn,
zlog_debug ("vrf[%s] %s: prefix withdrawn nh %s label %s",
vrf_rd_str, pfx_str, nh_str, label_str);
}
+ if (afi == AFI_IP)
+ {
+ if (selected->attr && selected->attr->extra)
+ event.nexthop = selected->attr->extra->mp_nexthop_global_in;
+#ifdef HAVE_ZEROMQ
+ bgp_notify_route (vrf->bgp, &event);
+#endif /* HAVE_ZEROMQ */
+ }
}

int
diff --git a/bgpd/bgp_zmq.c b/bgpd/bgp_zmq.c
new file mode 100644
index 000000000000..d2e7fb14d40b
--- /dev/null
+++ b/bgpd/bgp_zmq.c
@@ -0,0 +1,105 @@
+/*
+ * bgpd ZeroMQ/Cap'n'Proto event update feed
+ * Copyright (C) 2016 David Lamparter, for NetDEF, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <zebra.h>
+#include <zmq.h>
+#include "memory.h"
+
+#include "prefix.h"
+#include "memory.h"
+#include "log.h"
+#include "qzmq.h"
+#include "bgp.bcapnp.h"
+
+#include "bgpd.h"
+
+void
+bgp_notify_cleanup (struct bgp *bgp)
+{
+ if (bgp->notify_zmq_url)
+ XFREE (MTYPE_ZMQ_NOTIFY, bgp->notify_zmq_url);
+ if (bgp->notify_zmq)
+ zmq_close (bgp->notify_zmq);
+}
+
+int
+bgp_notify_zmq_url_set (struct bgp *bgp, const char *url)
+{
+ if (bgp->notify_zmq_url)
+ {
+ if (url && !strcmp (url, bgp->notify_zmq_url))
+ return 0;
+
+ XFREE (MTYPE_ZMQ_NOTIFY, bgp->notify_zmq_url);
+ bgp->notify_zmq_url = NULL;
+ }
+ if (bgp->notify_zmq)
+ {
+ zmq_close (bgp->notify_zmq);
+ bgp->notify_zmq = NULL;
+ }
+
+ if (!url || !*url)
+ return 0;
+
+ bgp->notify_zmq_url = XSTRDUP (MTYPE_ZMQ_NOTIFY, url);
+ bgp->notify_zmq = zmq_socket (qzmq_context, ZMQ_PUB);
+ if (!bgp->notify_zmq)
+ {
+ zlog_err ("failed to open ZeroMQ PUB socket: %s (%d)",
+ strerror (errno), errno);
+ return -1;
+ }
+ if (zmq_bind (bgp->notify_zmq, bgp->notify_zmq_url))
+ {
+ zlog_err ("ZeroMQ event PUB bind failed: %s (%d)",
+ strerror (errno), errno);
+ zmq_close (bgp->notify_zmq);
+ return -1;
+ }
+ return 0;
+}
+
+static void
+bgp_notify_send (struct bgp *bgp, struct bgp_event_vrf *update)
+{
+ struct capn rc;
+ capn_init_malloc(&rc);
+ struct capn_segment *cs = capn_root(&rc).seg;
+ capn_ptr p = qcapn_new_BGPEventVRFRoute (cs);
+ qcapn_BGPEventVRFRoute_write (update, p);
+ capn_setp(capn_root(&rc), 0, p);
+
+ uint8_t buf[4096];
+ ssize_t rs = capn_write_mem(&rc, buf, sizeof(buf), 0);
+ capn_free(&rc);
+
+ zmq_send (bgp->notify_zmq, buf, rs, 0);
+}
+
+void
+bgp_notify_route (struct bgp *bgp, struct bgp_event_vrf *update)
+{
+ bgp_notify_send (bgp, update);
+}
+
+void
+bgp_notify_shut (struct bgp *bgp, struct bgp_event_shut *shut)
+{
+}
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 337a5d0386a0..567cdd0af7b5 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -2557,6 +2557,10 @@ bgp_delete (struct bgp *bgp)

SET_FLAG(bgp->flags, BGP_FLAG_DELETING);

+#ifdef HAVE_ZEROMQ
+ bgp_notify_cleanup (bgp);
+#endif /* HAVE_ZEROMQ */
+
THREAD_OFF (bgp->t_startup);
QZC_NODE_UNREG(bgp)

diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 09f9c6a1c551..dfc2a4e97ef2 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -205,6 +205,10 @@ struct bgp

struct hash *rt_subscribers;

+ /* outbound update feeds */
+ char *notify_zmq_url;
+ void *notify_zmq;
+
QZC_NODE
};

@@ -259,6 +263,21 @@ struct bgp_vrf
QZC_NODE
};

+struct bgp_event_vrf
+{
+ bool announce;
+ struct prefix_rd outbound_rd;
+ struct prefix_ipv4 prefix;
+ struct in_addr nexthop;
+ uint32_t label;
+};
+
+struct bgp_event_shut
+{
+ struct in_addr peer;
+ uint8_t type, subtype;
+};
+
struct bgp_api_route
{
struct prefix_ipv4 prefix;
@@ -987,6 +1006,11 @@ extern int bgp_timers_unset (struct bgp *);
extern int bgp_default_local_preference_set (struct bgp *, u_int32_t);
extern int bgp_default_local_preference_unset (struct bgp *);

+extern int bgp_notify_zmq_url_set (struct bgp *, const char *url);
+extern void bgp_notify_route (struct bgp *, struct bgp_event_vrf *update);
+extern void bgp_notify_shut (struct bgp *, struct bgp_event_shut *shut);
+extern void bgp_notify_cleanup (struct bgp *);
+
extern int peer_rsclient_active (struct peer *);

extern int peer_remote_as (struct bgp *, union sockunion *, as_t *, afi_t, safi_t);
diff --git a/lib/memtypes.c b/lib/memtypes.c
index 3e43a857322e..f3605d5aabc5 100644
--- a/lib/memtypes.c
+++ b/lib/memtypes.c
@@ -161,6 +161,7 @@ struct memory_list memory_list_bgp[] =
{ MTYPE_ENCAP_TLV, "ENCAP TLV", },
{ MTYPE_BGP_VRF, "BGP VRF", },
{ MTYPE_BGP_RT_SUB, "BGP RT SUB", },
+ { MTYPE_ZMQ_NOTIFY, "ZMQ notify", },
{ -1, NULL }
};

--
2.1.4


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