From: David Lamparter <equi...@opensourcerouting.org> This commit brings necessary changes in order to send a notification through capnproto.
Signed-off-by: David Lamparter <equi...@opensourcerouting.org> Signed-off-by: Philippe Guibert <philippe.guib...@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