summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_evpn_vty.c14
-rw-r--r--bgpd/bgp_fsm.c5
-rw-r--r--bgpd/bgp_nht.c21
-rw-r--r--bgpd/bgp_nht.h8
-rw-r--r--bgpd/bgp_packet.c21
-rw-r--r--bgpd/bgp_rpki.c2
-rw-r--r--doc/developer/next-hop-tracking.rst2
-rw-r--r--ospfd/ospf_opaque.c6
-rw-r--r--zebra/sample_plugin.c134
9 files changed, 161 insertions, 52 deletions
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index 55f85eeb83..3bc8345140 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -298,7 +298,7 @@ static void bgp_evpn_show_route_rd_header(struct vty *vty,
if (json)
json_object_string_add(json, "rd", rd_str);
else
- vty_out(vty, "as2 %s\n", rd_str);
+ vty_out(vty, "%s\n", rd_str);
break;
case RD_TYPE_AS4:
@@ -307,7 +307,7 @@ static void bgp_evpn_show_route_rd_header(struct vty *vty,
if (json)
json_object_string_add(json, "rd", rd_str);
else
- vty_out(vty, "as4 %s\n", rd_str);
+ vty_out(vty, "%s\n", rd_str);
break;
case RD_TYPE_IP:
@@ -317,7 +317,7 @@ static void bgp_evpn_show_route_rd_header(struct vty *vty,
if (json)
json_object_string_add(json, "rd", rd_str);
else
- vty_out(vty, "ip %s\n", rd_str);
+ vty_out(vty, "%s\n", rd_str);
break;
default:
@@ -326,7 +326,7 @@ static void bgp_evpn_show_route_rd_header(struct vty *vty,
json_object_string_add(json, "rd", rd_str);
} else {
snprintf(rd_str, len, "Unknown RD type");
- vty_out(vty, "ip %s\n", rd_str);
+ vty_out(vty, "%s\n", rd_str);
}
break;
}
@@ -2619,10 +2619,8 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
prefix_rd2str((struct prefix_rd *)&rd_rn->p, rd_str,
sizeof(rd_str));
- if (json) {
+ if (json)
json_rd = json_object_new_object();
- json_object_string_add(json_rd, "rd", rd_str);
- }
rd_header = 1;
@@ -2659,7 +2657,7 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
/* RD header - per RD. */
if (rd_header) {
bgp_evpn_show_route_rd_header(
- vty, rd_rn, NULL, rd_str,
+ vty, rd_rn, json_rd, rd_str,
RD_ADDRSTRLEN);
rd_header = 0;
}
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index 0be8becbab..2e5b2e115c 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -1359,8 +1359,9 @@ static int bgp_connect_success(struct peer *peer)
flog_err_sys(EC_LIB_SOCKET,
"%s: bgp_getsockname(): failed for peer %s, fd %d",
__FUNCTION__, peer->host, peer->fd);
- bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
- 0); /* internal error */
+ bgp_notify_send(
+ peer, BGP_NOTIFY_FSM_ERR,
+ BGP_NOTIFY_SUBCODE_UNSPECIFIC); /* internal error */
bgp_writes_on(peer);
return -1;
}
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index 915963fad8..6be08efb21 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -65,27 +65,6 @@ static int bgp_isvalid_labeled_nexthop(struct bgp_nexthop_cache *bnc)
|| (bnc && CHECK_FLAG(bnc->flags, BGP_NEXTHOP_LABELED_VALID)));
}
-int bgp_find_nexthop(struct bgp_path_info *path, int connected)
-{
- struct bgp_nexthop_cache *bnc = path->nexthop;
-
- if (!bnc)
- return 0;
-
- /*
- * We are cheating here. Views have no associated underlying
- * ability to detect nexthops. So when we have a view
- * just tell everyone the nexthop is valid
- */
- if (path->peer && path->peer->bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
- return 1;
-
- if (connected && !(CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED)))
- return 0;
-
- return (bgp_isvalid_nexthop(bnc));
-}
-
static void bgp_unlink_nexthop_check(struct bgp_nexthop_cache *bnc)
{
if (LIST_EMPTY(&(bnc->paths)) && !bnc->nht_info) {
diff --git a/bgpd/bgp_nht.h b/bgpd/bgp_nht.h
index 7daae93b25..e39d55567a 100644
--- a/bgpd/bgp_nht.h
+++ b/bgpd/bgp_nht.h
@@ -27,14 +27,6 @@
extern void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id);
/**
- * bgp_find_nexthop() - lookup the nexthop cache table for the bnc object
- * ARGUMENTS:
- * p - path for which the nexthop object is being looked up
- * connected - True if NH MUST be a connected route
- */
-extern int bgp_find_nexthop(struct bgp_path_info *p, int connected);
-
-/**
* bgp_find_or_add_nexthop() - lookup the nexthop cache table for the bnc
* object. If not found, create a new object and register with ZEBRA for
* nexthop notification.
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index c7c1780c21..5296246b31 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -1420,7 +1420,8 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size)
"%s [FSM] Update packet received under status %s",
peer->host,
lookup_msg(bgp_status_msg, peer->status, NULL));
- bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR, 0);
+ bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
+ BGP_NOTIFY_SUBCODE_UNSPECIFIC);
return BGP_Stop;
}
@@ -1792,7 +1793,8 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size)
"%s [Error] Route refresh packet received under status %s",
peer->host,
lookup_msg(bgp_status_msg, peer->status, NULL));
- bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR, 0);
+ bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
+ BGP_NOTIFY_SUBCODE_UNSPECIFIC);
return BGP_Stop;
}
@@ -1827,7 +1829,8 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size)
< 5) {
zlog_info("%s ORF route refresh length error",
peer->host);
- bgp_notify_send(peer, BGP_NOTIFY_CEASE, 0);
+ bgp_notify_send(peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_SUBCODE_UNSPECIFIC);
return BGP_Stop;
}
@@ -2061,7 +2064,8 @@ static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt,
* length. */
if (pnt + 3 > end) {
zlog_info("%s Capability length error", peer->host);
- bgp_notify_send(peer, BGP_NOTIFY_CEASE, 0);
+ bgp_notify_send(peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_SUBCODE_UNSPECIFIC);
return BGP_Stop;
}
action = *pnt;
@@ -2072,7 +2076,8 @@ static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt,
&& action != CAPABILITY_ACTION_UNSET) {
zlog_info("%s Capability Action Value error %d",
peer->host, action);
- bgp_notify_send(peer, BGP_NOTIFY_CEASE, 0);
+ bgp_notify_send(peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_SUBCODE_UNSPECIFIC);
return BGP_Stop;
}
@@ -2084,7 +2089,8 @@ static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt,
/* Capability length check. */
if ((pnt + hdr->length + 3) > end) {
zlog_info("%s Capability length error", peer->host);
- bgp_notify_send(peer, BGP_NOTIFY_CEASE, 0);
+ bgp_notify_send(peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_SUBCODE_UNSPECIFIC);
return BGP_Stop;
}
@@ -2188,7 +2194,8 @@ int bgp_capability_receive(struct peer *peer, bgp_size_t size)
"%s [Error] Dynamic capability packet received under status %s",
peer->host,
lookup_msg(bgp_status_msg, peer->status, NULL));
- bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR, 0);
+ bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
+ BGP_NOTIFY_SUBCODE_UNSPECIFIC);
return BGP_Stop;
}
diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c
index 1267e35097..3b89e50ce4 100644
--- a/bgpd/bgp_rpki.c
+++ b/bgpd/bgp_rpki.c
@@ -406,7 +406,7 @@ static int bgpd_sync_callback(struct thread *thread)
}
}
- prefix_free(prefix);
+ prefix_free(&prefix);
return 0;
}
diff --git a/doc/developer/next-hop-tracking.rst b/doc/developer/next-hop-tracking.rst
index a9af5e749c..99e1d65c2b 100644
--- a/doc/developer/next-hop-tracking.rst
+++ b/doc/developer/next-hop-tracking.rst
@@ -111,8 +111,6 @@ provides the following APIs:
+============================+==================================================+
| bgp_find_or_add_nexthop() | find or add a nexthop in BGP nexthop table |
+----------------------------+--------------------------------------------------+
-| bgp_find_nexthop() | find a nexthop in BGP nexthop table |
-+----------------------------+--------------------------------------------------+
| bgp_parse_nexthop_update() | parse a nexthop update message coming from zebra |
+----------------------------+--------------------------------------------------+
diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c
index 147773ce23..a989b8468c 100644
--- a/ospfd/ospf_opaque.c
+++ b/ospfd/ospf_opaque.c
@@ -430,9 +430,9 @@ void ospf_delete_opaque_functab(uint8_t lsa_type, uint8_t opaque_type)
/* Cleanup internal control information, if it
* still remains. */
if (functab->oipt != NULL) {
+ free_opaque_info_owner(functab->oipt);
free_opaque_info_per_type(
functab->oipt);
- free_opaque_info_owner(functab->oipt);
}
/* Dequeue listnode entry from the list. */
@@ -554,8 +554,8 @@ register_opaque_info_per_type(struct ospf_opaque_functab *functab,
case OSPF_OPAQUE_AS_LSA:
top = ospf_lookup_by_vrf_id(new->vrf_id);
if (new->area != NULL && (top = new->area->ospf) == NULL) {
- free_opaque_info_per_type((void *)oipt);
free_opaque_info_owner(oipt);
+ free_opaque_info_per_type(oipt);
oipt = NULL;
goto out; /* This case may not exist. */
}
@@ -567,8 +567,8 @@ register_opaque_info_per_type(struct ospf_opaque_functab *functab,
EC_OSPF_LSA_UNEXPECTED,
"register_opaque_info_per_type: Unexpected LSA-type(%u)",
new->data->type);
- free_opaque_info_per_type((void *)oipt);
free_opaque_info_owner(oipt);
+ free_opaque_info_per_type(oipt);
oipt = NULL;
goto out; /* This case may not exist. */
}
diff --git a/zebra/sample_plugin.c b/zebra/sample_plugin.c
new file mode 100644
index 0000000000..c96a86cc73
--- /dev/null
+++ b/zebra/sample_plugin.c
@@ -0,0 +1,134 @@
+/*
+ * Sample plugin for the FRR zebra dataplane.
+ *
+ * Copyright (c) 2019 Volta Networks, 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; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * Should be possible to build this plugin using this sort of command:
+ *
+ * gcc -I ~/work/frr/ -I ~/work/frr/lib -I ~/work/frr/zebra \
+ * -g -O0 -o sample_plugin.so -shared -fPIC sample_plugin.c
+ *
+ * where 'frr' is a configured and built frr sandbox.
+ *
+ * Run zebra with '-M /path/to/sample_plugin.so' to load the module.
+ */
+
+#include "config.h" /* Include this explicitly */
+#include "lib/zebra.h"
+#include "lib/libfrr.h"
+#include "zebra/zebra_dplane.h"
+#include "zebra/debug.h"
+
+static const char *plugin_name = "SAMPLE";
+
+static struct zebra_dplane_provider *prov_p;
+
+/*
+ * Startup/init callback, called from the dataplane.
+ */
+static int sample_start(struct zebra_dplane_provider *prov)
+{
+ /* Nothing special to do - we don't allocate anything. */
+ return 0;
+}
+
+
+/*
+ * Shutdown/cleanup callback, called from the dataplane pthread.
+ */
+static int sample_fini(struct zebra_dplane_provider *prov, bool early)
+{
+ /* Nothing special to do. */
+ return 0;
+}
+
+/*
+ * Callback from the dataplane to process incoming work; this runs in the
+ * dplane pthread.
+ */
+static int sample_process(struct zebra_dplane_provider *prov)
+{
+ int counter, limit;
+ struct zebra_dplane_ctx *ctx;
+
+ limit = dplane_provider_get_work_limit(prov_p);
+
+ /* Respect the configured limit on the amount of work to do in
+ * any one call.
+ */
+ for (counter = 0; counter < limit; counter++) {
+ ctx = dplane_provider_dequeue_in_ctx(prov_p);
+ if (!ctx)
+ break;
+
+ /* Just set 'success' status and return to the dataplane */
+ dplane_ctx_set_status(ctx, ZEBRA_DPLANE_REQUEST_SUCCESS);
+ dplane_provider_enqueue_out_ctx(prov_p, ctx);
+ }
+
+ return 0;
+}
+
+/*
+ * Init entry point called during zebra startup. This is registered during
+ * module init.
+ */
+static int init_sample_plugin(struct thread_master *tm)
+{
+ int ret;
+ struct zebra_dplane_provider *prov = NULL;
+
+ /* Note that we don't use or store the thread_master 'tm'. We
+ * don't use the zebra main pthread: our plugin code will run in
+ * the zebra dataplane pthread context.
+ */
+
+ /* Register the plugin with the dataplane infrastructure. We
+ * register to be called before the kernel, and we register
+ * our init, process work, and shutdown callbacks.
+ */
+ ret = dplane_provider_register(plugin_name, DPLANE_PRIO_PRE_KERNEL,
+ DPLANE_PROV_FLAGS_DEFAULT,
+ sample_start,
+ sample_process,
+ sample_fini,
+ NULL,
+ &prov_p);
+
+ if (IS_ZEBRA_DEBUG_DPLANE)
+ zlog_debug("sample plugin register => %d", ret);
+
+ return 0;
+}
+
+/*
+ * Base FRR loadable module info: basic info including module entry-point.
+ */
+static int module_init(void)
+{
+ hook_register(frr_late_init, init_sample_plugin);
+ return 0;
+}
+
+FRR_MODULE_SETUP(
+ .name = "dplane_sample",
+ .version = "0.0.1",
+ .description = "Dataplane Sample Plugin",
+ .init = module_init,
+ )