diff options
| -rw-r--r-- | bgpd/bgp_vty.c | 54 | ||||
| -rw-r--r-- | bgpd/bgpd.c | 3 | ||||
| -rw-r--r-- | bgpd/bgpd.h | 80 | ||||
| -rw-r--r-- | zebra/kernel_netlink.c | 125 | ||||
| -rw-r--r-- | zebra/kernel_socket.c | 14 | ||||
| -rw-r--r-- | zebra/rt.h | 4 | ||||
| -rw-r--r-- | zebra/zebra_router.c | 6 |
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(); } |
