summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_vty.c54
-rw-r--r--bgpd/bgpd.c3
-rw-r--r--bgpd/bgpd.h80
-rw-r--r--zebra/kernel_netlink.c125
-rw-r--r--zebra/kernel_socket.c14
-rw-r--r--zebra/rt.h4
-rw-r--r--zebra/zebra_router.c6
7 files changed, 180 insertions, 106 deletions
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 9a1991cd09..afe4c7ae6f 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -803,11 +803,15 @@ struct peer *peer_and_group_lookup_vty(struct vty *vty, const char *peer_str)
return NULL;
}
-int bgp_vty_return(struct vty *vty, int ret)
+int bgp_vty_return(struct vty *vty, enum bgp_create_error_code ret)
{
const char *str = NULL;
switch (ret) {
+ case BGP_SUCCESS:
+ case BGP_CREATED:
+ case BGP_GR_NO_OPERATION:
+ break;
case BGP_ERR_INVALID_VALUE:
str = "Invalid value";
break;
@@ -877,6 +881,36 @@ int bgp_vty_return(struct vty *vty, int ret)
case BGP_ERR_GR_OPERATION_FAILED:
str = "The Graceful Restart Operation failed due to an err.";
break;
+ case BGP_ERR_PEER_GROUP_MEMBER:
+ str = "Peer-group member cannot override remote-as of peer-group.";
+ break;
+ case BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT:
+ str = "Peer-group members must be all internal or all external.";
+ break;
+ case BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND:
+ str = "Range specified cannot be deleted because it is not part of current config.";
+ break;
+ case BGP_ERR_INSTANCE_MISMATCH:
+ str = "Instance specified does not match the current instance.";
+ break;
+ case BGP_ERR_NO_INTERFACE_CONFIG:
+ str = "Interface specified is not being used for interface based peer.";
+ break;
+ case BGP_ERR_SOFT_RECONFIG_UNCONFIGURED:
+ str = "No configuration already specified for soft reconfiguration.";
+ break;
+ case BGP_ERR_AS_MISMATCH:
+ str = "BGP is already running.";
+ break;
+ case BGP_ERR_AF_UNCONFIGURED:
+ str = "AFI/SAFI specified is not currently configured.";
+ break;
+ case BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS:
+ str = "AS specified for local as is the same as the remote as and this is not allowed.";
+ break;
+ case BGP_ERR_INVALID_AS:
+ str = "Confederation AS specified is the same AS as our AS.";
+ break;
}
if (str) {
vty_out(vty, "%% %s\n", str);
@@ -4211,17 +4245,6 @@ static int peer_remote_as_vty(struct vty *vty, const char *peer_str,
ret = peer_remote_as(bgp, &su, NULL, &as, as_type);
}
- /* This peer belongs to peer group. */
- switch (ret) {
- case BGP_ERR_PEER_GROUP_MEMBER:
- vty_out(vty,
- "%% Peer-group member cannot override remote-as of peer-group\n");
- return CMD_WARNING_CONFIG_FAILED;
- case BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT:
- vty_out(vty,
- "%% Peer-group members must be all internal or all external\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
return bgp_vty_return(vty, ret);
}
@@ -4958,13 +4981,6 @@ DEFUN (neighbor_set_peer_group,
ret = peer_group_bind(bgp, &su, peer, group, &as);
- if (ret == BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT) {
- vty_out(vty,
- "%% Peer with AS %u cannot be in this peer-group, members must be all internal or all external\n",
- as);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
return bgp_vty_return(vty, ret);
}
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 567b049c1b..43046f7f18 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -651,9 +651,6 @@ int bgp_confederation_peers_add(struct bgp *bgp, as_t as)
struct peer *peer;
struct listnode *node, *nnode;
- if (!bgp)
- return BGP_ERR_INVALID_BGP;
-
if (bgp->as == as)
return BGP_ERR_INVALID_AS;
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index ff295ffa27..8b93c450e8 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -1919,46 +1919,46 @@ enum bgp_clear_type {
(((S) == OpenSent) || ((S) == OpenConfirm) || ((S) == Established))
/* BGP error codes. */
-#define BGP_SUCCESS 0
-#define BGP_CREATED 1
-#define BGP_ERR_INVALID_VALUE -1
-#define BGP_ERR_INVALID_FLAG -2
-#define BGP_ERR_INVALID_AS -3
-#define BGP_ERR_INVALID_BGP -4
-#define BGP_ERR_PEER_GROUP_MEMBER -5
-#define BGP_ERR_PEER_GROUP_NO_REMOTE_AS -7
-#define BGP_ERR_PEER_GROUP_CANT_CHANGE -8
-#define BGP_ERR_PEER_GROUP_MISMATCH -9
-#define BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT -10
-#define BGP_ERR_AS_MISMATCH -12
-#define BGP_ERR_PEER_FLAG_CONFLICT -13
-#define BGP_ERR_PEER_GROUP_SHUTDOWN -14
-#define BGP_ERR_PEER_FILTER_CONFLICT -15
-#define BGP_ERR_NOT_INTERNAL_PEER -16
-#define BGP_ERR_REMOVE_PRIVATE_AS -17
-#define BGP_ERR_AF_UNCONFIGURED -18
-#define BGP_ERR_SOFT_RECONFIG_UNCONFIGURED -19
-#define BGP_ERR_INSTANCE_MISMATCH -20
-#define BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP -21
-#define BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS -22
-#define BGP_ERR_TCPSIG_FAILED -23
-#define BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK -24
-#define BGP_ERR_NO_IBGP_WITH_TTLHACK -25
-#define BGP_ERR_NO_INTERFACE_CONFIG -26
-#define BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS -27
-#define BGP_ERR_AS_OVERRIDE -28
-#define BGP_ERR_INVALID_DYNAMIC_NEIGHBORS_LIMIT -29
-#define BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_EXISTS -30
-#define BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND -31
-#define BGP_ERR_INVALID_FOR_DYNAMIC_PEER -32
-#define BGP_ERR_MAX -33
-#define BGP_ERR_INVALID_FOR_DIRECT_PEER -34
-#define BGP_ERR_PEER_SAFI_CONFLICT -35
-
-/* BGP GR ERRORS */
-#define BGP_ERR_GR_INVALID_CMD -36
-#define BGP_ERR_GR_OPERATION_FAILED -37
-#define BGP_GR_NO_OPERATION -38
+enum bgp_create_error_code {
+ BGP_SUCCESS = 0,
+ BGP_CREATED = 1,
+ BGP_ERR_INVALID_VALUE = -1,
+ BGP_ERR_INVALID_FLAG = -2,
+ BGP_ERR_INVALID_AS = -3,
+ BGP_ERR_PEER_GROUP_MEMBER = -4,
+ BGP_ERR_PEER_GROUP_NO_REMOTE_AS = -5,
+ BGP_ERR_PEER_GROUP_CANT_CHANGE = -6,
+ BGP_ERR_PEER_GROUP_MISMATCH = -7,
+ BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT = -8,
+ BGP_ERR_AS_MISMATCH = -9,
+ BGP_ERR_PEER_FLAG_CONFLICT = -10,
+ BGP_ERR_PEER_GROUP_SHUTDOWN = -11,
+ BGP_ERR_PEER_FILTER_CONFLICT = -12,
+ BGP_ERR_NOT_INTERNAL_PEER = -13,
+ BGP_ERR_REMOVE_PRIVATE_AS = -14,
+ BGP_ERR_AF_UNCONFIGURED = -15,
+ BGP_ERR_SOFT_RECONFIG_UNCONFIGURED = -16,
+ BGP_ERR_INSTANCE_MISMATCH = -17,
+ BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP = -18,
+ BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS = -19,
+ BGP_ERR_TCPSIG_FAILED = -20,
+ BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK = -21,
+ BGP_ERR_NO_IBGP_WITH_TTLHACK = -22,
+ BGP_ERR_NO_INTERFACE_CONFIG = -23,
+ BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS = -24,
+ BGP_ERR_AS_OVERRIDE = -25,
+ BGP_ERR_INVALID_DYNAMIC_NEIGHBORS_LIMIT = -26,
+ BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_EXISTS = -27,
+ BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND = -28,
+ BGP_ERR_INVALID_FOR_DYNAMIC_PEER = -29,
+ BGP_ERR_INVALID_FOR_DIRECT_PEER = -30,
+ BGP_ERR_PEER_SAFI_CONFLICT = -31,
+
+ /* BGP GR ERRORS */
+ BGP_ERR_GR_INVALID_CMD = -32,
+ BGP_ERR_GR_OPERATION_FAILED = -33,
+ BGP_GR_NO_OPERATION = -34,
+};
/*
* Enumeration of different policy kinds a peer can be configured with.
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c
index ca83a42685..84c15a2a92 100644
--- a/zebra/kernel_netlink.c
+++ b/zebra/kernel_netlink.c
@@ -159,7 +159,17 @@ extern struct zebra_privs_t zserv_privs;
DEFINE_MTYPE_STATIC(ZEBRA, NL_BUF, "Zebra Netlink buffers");
-struct hash *nlsock_hash;
+/* Hashtable and mutex to allow lookup of nlsock structs by socket/fd value.
+ * We have both the main and dplane pthreads using these structs, so we have
+ * to protect the hash with a lock.
+ */
+static struct hash *nlsock_hash;
+pthread_mutex_t nlsock_mutex;
+
+/* Lock and unlock wrappers for nlsock hash */
+#define NLSOCK_LOCK() pthread_mutex_lock(&nlsock_mutex)
+#define NLSOCK_UNLOCK() pthread_mutex_unlock(&nlsock_mutex)
+
size_t nl_batch_tx_bufsize;
char *nl_batch_tx_buf;
@@ -1513,11 +1523,31 @@ void kernel_update_multi(struct dplane_ctx_q *ctx_list)
struct nlsock *kernel_netlink_nlsock_lookup(int sock)
{
- struct nlsock lookup;
+ struct nlsock lookup, *retval;
lookup.sock = sock;
- return hash_lookup(nlsock_hash, &lookup);
+ NLSOCK_LOCK();
+ retval = hash_lookup(nlsock_hash, &lookup);
+ NLSOCK_UNLOCK();
+
+ return retval;
+}
+
+/* Insert nlsock entry into hash */
+static void kernel_netlink_nlsock_insert(struct nlsock *nls)
+{
+ NLSOCK_LOCK();
+ (void)hash_get(nlsock_hash, nls, hash_alloc_intern);
+ NLSOCK_UNLOCK();
+}
+
+/* Remove nlsock entry from hash */
+static void kernel_netlink_nlsock_remove(struct nlsock *nls)
+{
+ NLSOCK_LOCK();
+ (void)hash_release(nlsock_hash, nls);
+ NLSOCK_UNLOCK();
}
static uint32_t kernel_netlink_nlsock_key(const void *arg)
@@ -1547,11 +1577,6 @@ void kernel_init(struct zebra_ns *zns)
int one, ret;
#endif
- if (!nlsock_hash)
- nlsock_hash = hash_create_size(8, kernel_netlink_nlsock_key,
- kernel_netlink_nlsock_hash_equal,
- "Netlink Socket Hash");
-
/*
* Initialize netlink sockets
*
@@ -1584,7 +1609,8 @@ void kernel_init(struct zebra_ns *zns)
zns->netlink.name);
exit(-1);
}
- (void)hash_get(nlsock_hash, &zns->netlink, hash_alloc_intern);
+
+ kernel_netlink_nlsock_insert(&zns->netlink);
snprintf(zns->netlink_cmd.name, sizeof(zns->netlink_cmd.name),
"netlink-cmd (NS %u)", zns->ns_id);
@@ -1594,7 +1620,8 @@ void kernel_init(struct zebra_ns *zns)
zns->netlink_cmd.name);
exit(-1);
}
- (void)hash_get(nlsock_hash, &zns->netlink_cmd, hash_alloc_intern);
+
+ kernel_netlink_nlsock_insert(&zns->netlink_cmd);
/* Outbound socket for dplane programming of the host OS. */
snprintf(zns->netlink_dplane_out.name,
@@ -1606,8 +1633,8 @@ void kernel_init(struct zebra_ns *zns)
zns->netlink_dplane_out.name);
exit(-1);
}
- (void)hash_get(nlsock_hash, &zns->netlink_dplane_out,
- hash_alloc_intern);
+
+ kernel_netlink_nlsock_insert(&zns->netlink_dplane_out);
/* Inbound socket for OS events coming to the dplane. */
snprintf(zns->netlink_dplane_in.name,
@@ -1620,7 +1647,8 @@ void kernel_init(struct zebra_ns *zns)
zns->netlink_dplane_in.name);
exit(-1);
}
- (void)hash_get(nlsock_hash, &zns->netlink_dplane_in, hash_alloc_intern);
+
+ kernel_netlink_nlsock_insert(&zns->netlink_dplane_in);
/*
* SOL_NETLINK is not available on all platforms yet
@@ -1706,47 +1734,56 @@ void kernel_init(struct zebra_ns *zns)
rt_netlink_init();
}
+/* Helper to clean up an nlsock */
+static void kernel_nlsock_fini(struct nlsock *nls)
+{
+ if (nls && nls->sock >= 0) {
+ kernel_netlink_nlsock_remove(nls);
+ close(nls->sock);
+ nls->sock = -1;
+ XFREE(MTYPE_NL_BUF, nls->buf);
+ nls->buflen = 0;
+ }
+}
+
void kernel_terminate(struct zebra_ns *zns, bool complete)
{
thread_cancel(&zns->t_netlink);
- if (zns->netlink.sock >= 0) {
- hash_release(nlsock_hash, &zns->netlink);
- close(zns->netlink.sock);
- zns->netlink.sock = -1;
- XFREE(MTYPE_NL_BUF, zns->netlink.buf);
- zns->netlink.buflen = 0;
- }
+ kernel_nlsock_fini(&zns->netlink);
- if (zns->netlink_cmd.sock >= 0) {
- hash_release(nlsock_hash, &zns->netlink_cmd);
- close(zns->netlink_cmd.sock);
- zns->netlink_cmd.sock = -1;
- XFREE(MTYPE_NL_BUF, zns->netlink_cmd.buf);
- zns->netlink_cmd.buflen = 0;
- }
+ kernel_nlsock_fini(&zns->netlink_cmd);
- if (zns->netlink_dplane_in.sock >= 0) {
- hash_release(nlsock_hash, &zns->netlink_dplane_in);
- close(zns->netlink_dplane_in.sock);
- zns->netlink_dplane_in.sock = -1;
- XFREE(MTYPE_NL_BUF, zns->netlink_dplane_in.buf);
- zns->netlink_dplane_in.buflen = 0;
- }
+ kernel_nlsock_fini(&zns->netlink_dplane_in);
/* During zebra shutdown, we need to leave the dataplane socket
* around until all work is done.
*/
- if (complete) {
- if (zns->netlink_dplane_out.sock >= 0) {
- hash_release(nlsock_hash, &zns->netlink_dplane_out);
- close(zns->netlink_dplane_out.sock);
- zns->netlink_dplane_out.sock = -1;
- XFREE(MTYPE_NL_BUF, zns->netlink_dplane_out.buf);
- zns->netlink_dplane_out.buflen = 0;
- }
+ if (complete)
+ kernel_nlsock_fini(&zns->netlink_dplane_out);
+}
- hash_free(nlsock_hash);
- }
+/*
+ * Global init for platform-/OS-specific things
+ */
+void kernel_router_init(void)
+{
+ /* Init nlsock hash and lock */
+ pthread_mutex_init(&nlsock_mutex, NULL);
+ nlsock_hash = hash_create_size(8, kernel_netlink_nlsock_key,
+ kernel_netlink_nlsock_hash_equal,
+ "Netlink Socket Hash");
+}
+
+/*
+ * Global deinit for platform-/OS-specific things
+ */
+void kernel_router_terminate(void)
+{
+ pthread_mutex_destroy(&nlsock_mutex);
+
+ hash_free(nlsock_hash);
+ nlsock_hash = NULL;
}
+
#endif /* HAVE_NETLINK */
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index 3c9d203a0b..b9228072e5 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -1460,6 +1460,20 @@ void kernel_terminate(struct zebra_ns *zns, bool complete)
}
/*
+ * Global init for platform-/OS-specific things
+ */
+void kernel_router_init(void)
+{
+}
+
+/*
+ * Global deinit for platform-/OS-specific things
+ */
+void kernel_router_terminate(void)
+{
+}
+
+/*
* Called by the dplane pthread to read incoming OS messages and dispatch them.
*/
int kernel_dplane_read(struct zebra_dplane_info *info)
diff --git a/zebra/rt.h b/zebra/rt.h
index 90148d2c0d..5e626928d9 100644
--- a/zebra/rt.h
+++ b/zebra/rt.h
@@ -78,6 +78,10 @@ extern int kernel_interface_set_master(struct interface *master,
extern int mpls_kernel_init(void);
+/* Global init and deinit for platform-/OS-specific things */
+void kernel_router_init(void);
+void kernel_router_terminate(void);
+
extern uint32_t kernel_get_speed(struct interface *ifp, int *error);
extern int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *mroute);
diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c
index 92a3b9424b..6b4a7543cd 100644
--- a/zebra/zebra_router.c
+++ b/zebra/zebra_router.c
@@ -262,6 +262,9 @@ void zebra_router_terminate(void)
#ifdef HAVE_SCRIPTING
zebra_script_destroy();
#endif
+
+ /* OS-specific deinit */
+ kernel_router_terminate();
}
bool zebra_router_notify_on_ack(void)
@@ -307,4 +310,7 @@ void zebra_router_init(bool asic_offload, bool notify_on_ack)
#ifdef HAVE_SCRIPTING
zebra_script_init();
#endif
+
+ /* OS-specific init */
+ kernel_router_init();
}