void dpdk_init(const struct smap *ovs_other_config) { static bool enabled = false; if (enabled || !ovs_other_config) { return; } if (smap_get_bool(ovs_other_config, "dpdk-init", false)) { static struct ovsthread_once once_enable = OVSTHREAD_ONCE_INITIALIZER; if (ovsthread_once_start(&once_enable)) { VLOG_INFO("DPDK Enabled - initializing..."); dpdk_init__(ovs_other_config); enabled = true; VLOG_INFO("DPDK Enabled - initialized"); ovsthread_once_done(&once_enable); } } else { static struct ovsthread_once once_disable = OVSTHREAD_ONCE_INITIALIZER; if (ovsthread_once_start(&once_disable)) { VLOG_INFO("DPDK Disabled - Use other_config:dpdk-init to enable"); ovsthread_once_done(&once_disable); } } }
void dpdk_init(const struct smap *ovs_other_config) { static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; if (ovs_other_config && ovsthread_once_start(&once)) { dpdk_init__(ovs_other_config); ovsthread_once_done(&once); } }
void dpdk_init(const struct smap *ovs_other_config) { if (smap_get_bool(ovs_other_config, "dpdk-init", false)) { static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; if (ovsthread_once_start(&once)) { VLOG_ERR("DPDK not supported in this copy of Open vSwitch."); ovsthread_once_done(&once); } } }
/* Returns the type of the 'enum_' member for an ovsdb_base_type whose 'type' * is 'atomic_type'. */ const struct ovsdb_type * ovsdb_base_type_get_enum_type(enum ovsdb_atomic_type atomic_type) { static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; static struct ovsdb_type *types[OVSDB_N_TYPES]; if (ovsthread_once_start(&once)) { enum ovsdb_atomic_type i; for (i = 0; i < OVSDB_N_TYPES; i++) { struct ovsdb_type *type; types[i] = type = xmalloc(sizeof *type); ovsdb_base_type_init(&type->key, i); ovsdb_base_type_init(&type->value, OVSDB_TYPE_VOID); type->n_min = 1; type->n_max = UINT_MAX; } ovsthread_once_done(&once); } return types[atomic_type]; }
static int netdev_windows_init_(void) { int error = 0; static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; if (ovsthread_once_start(&once)) { error = nl_lookup_genl_family(OVS_WIN_NETDEV_FAMILY, &ovs_win_netdev_family); if (error) { VLOG_ERR("Generic Netlink family '%s' does not exist. " "The Open vSwitch kernel module is probably not loaded.", OVS_WIN_NETDEV_FAMILY); } if (!error) { /* XXX: Where to close this socket? */ error = nl_sock_create(NETLINK_GENERIC, &ovs_win_netdev_sock); } ovsthread_once_done(&once); } return error; }
/* Creates a new netlink socket for the given netlink 'protocol' * (NETLINK_ROUTE, NETLINK_GENERIC, ...). Returns 0 and sets '*sockp' to the * new socket if successful, otherwise returns a positive errno value. */ int nl_sock_create(int protocol, struct nl_sock **sockp) { static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; struct nl_sock *sock; struct sockaddr_nl local, remote; socklen_t local_size; int rcvbuf; int retval = 0; if (ovsthread_once_start(&once)) { int save_errno = errno; errno = 0; max_iovs = sysconf(_SC_UIO_MAXIOV); if (max_iovs < _XOPEN_IOV_MAX) { if (max_iovs == -1 && errno) { VLOG_WARN("sysconf(_SC_UIO_MAXIOV): %s", ovs_strerror(errno)); } max_iovs = _XOPEN_IOV_MAX; } else if (max_iovs > MAX_IOVS) { max_iovs = MAX_IOVS; } errno = save_errno; ovsthread_once_done(&once); } *sockp = NULL; sock = xmalloc(sizeof *sock); sock->fd = socket(AF_NETLINK, SOCK_RAW, protocol); if (sock->fd < 0) { VLOG_ERR("fcntl: %s", ovs_strerror(errno)); goto error; } sock->protocol = protocol; sock->next_seq = 1; rcvbuf = 1024 * 1024; if (setsockopt(sock->fd, SOL_SOCKET, SO_RCVBUFFORCE, &rcvbuf, sizeof rcvbuf)) { /* Only root can use SO_RCVBUFFORCE. Everyone else gets EPERM. * Warn only if the failure is therefore unexpected. */ if (errno != EPERM) { VLOG_WARN_RL(&rl, "setting %d-byte socket receive buffer failed " "(%s)", rcvbuf, ovs_strerror(errno)); } } retval = get_socket_rcvbuf(sock->fd); if (retval < 0) { retval = -retval; goto error; } sock->rcvbuf = retval; /* Connect to kernel (pid 0) as remote address. */ memset(&remote, 0, sizeof remote); remote.nl_family = AF_NETLINK; remote.nl_pid = 0; if (connect(sock->fd, (struct sockaddr *) &remote, sizeof remote) < 0) { VLOG_ERR("connect(0): %s", ovs_strerror(errno)); goto error; } /* Obtain pid assigned by kernel. */ local_size = sizeof local; if (getsockname(sock->fd, (struct sockaddr *) &local, &local_size) < 0) { VLOG_ERR("getsockname: %s", ovs_strerror(errno)); goto error; } if (local_size < sizeof local || local.nl_family != AF_NETLINK) { VLOG_ERR("getsockname returned bad Netlink name"); retval = EINVAL; goto error; } sock->pid = local.nl_pid; *sockp = sock; return 0; error: if (retval == 0) { retval = errno; if (retval == 0) { retval = EINVAL; } } if (sock->fd >= 0) { close(sock->fd); } free(sock); return retval; }
/* Returns true if 'ea' is a reserved address, that a bridge must never * forward, false otherwise. * * If you change this function's behavior, please update corresponding * documentation in vswitch.xml at the same time. */ bool eth_addr_is_reserved(const uint8_t ea[ETH_ADDR_LEN]) { struct eth_addr_node { struct hmap_node hmap_node; const uint64_t ea64; }; static struct eth_addr_node nodes[] = { /* STP, IEEE pause frames, and other reserved protocols. */ { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000000ULL }, { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000001ULL }, { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000002ULL }, { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000003ULL }, { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000004ULL }, { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000005ULL }, { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000006ULL }, { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000007ULL }, { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000008ULL }, { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000009ULL }, { HMAP_NODE_NULL_INITIALIZER, 0x0180c200000aULL }, { HMAP_NODE_NULL_INITIALIZER, 0x0180c200000bULL }, { HMAP_NODE_NULL_INITIALIZER, 0x0180c200000cULL }, { HMAP_NODE_NULL_INITIALIZER, 0x0180c200000dULL }, { HMAP_NODE_NULL_INITIALIZER, 0x0180c200000eULL }, { HMAP_NODE_NULL_INITIALIZER, 0x0180c200000fULL }, /* Extreme protocols. */ { HMAP_NODE_NULL_INITIALIZER, 0x00e02b000000ULL }, /* EDP. */ { HMAP_NODE_NULL_INITIALIZER, 0x00e02b000004ULL }, /* EAPS. */ { HMAP_NODE_NULL_INITIALIZER, 0x00e02b000006ULL }, /* EAPS. */ /* Cisco protocols. */ { HMAP_NODE_NULL_INITIALIZER, 0x01000c000000ULL }, /* ISL. */ { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccccULL }, /* PAgP, UDLD, CDP, * DTP, VTP. */ { HMAP_NODE_NULL_INITIALIZER, 0x01000ccccccdULL }, /* PVST+. */ { HMAP_NODE_NULL_INITIALIZER, 0x01000ccdcdcdULL }, /* STP Uplink Fast, * FlexLink. */ /* Cisco CFM. */ { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccc0ULL }, { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccc1ULL }, { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccc2ULL }, { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccc3ULL }, { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccc4ULL }, { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccc5ULL }, { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccc6ULL }, { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccc7ULL }, }; static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; struct eth_addr_node *node; static struct hmap addrs; uint64_t ea64; if (ovsthread_once_start(&once)) { hmap_init(&addrs); for (node = nodes; node < &nodes[ARRAY_SIZE(nodes)]; node++) { hmap_insert(&addrs, &node->hmap_node, hash_2words(node->ea64, node->ea64 >> 32)); } ovsthread_once_done(&once); }
/* Creates a new netlink socket for the given netlink 'protocol' * (NETLINK_ROUTE, NETLINK_GENERIC, ...). Returns 0 and sets '*sockp' to the * new socket if successful, otherwise returns a positive errno value. */ int nl_sock_create(int protocol, struct nl_sock **sockp) { static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; struct nl_sock *sock; #ifndef _WIN32 struct sockaddr_nl local, remote; #endif socklen_t local_size; int rcvbuf; int retval = 0; if (ovsthread_once_start(&once)) { int save_errno = errno; errno = 0; max_iovs = sysconf(_SC_UIO_MAXIOV); if (max_iovs < _XOPEN_IOV_MAX) { if (max_iovs == -1 && errno) { VLOG_WARN("sysconf(_SC_UIO_MAXIOV): %s", ovs_strerror(errno)); } max_iovs = _XOPEN_IOV_MAX; } else if (max_iovs > MAX_IOVS) { max_iovs = MAX_IOVS; } errno = save_errno; ovsthread_once_done(&once); } *sockp = NULL; sock = xmalloc(sizeof *sock); #ifdef _WIN32 sock->handle = CreateFileA("\\\\.\\OpenVSwitchDevice", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); int last_error = GetLastError(); if (sock->handle == INVALID_HANDLE_VALUE) { VLOG_ERR("fcntl: %s", ovs_strerror(last_error)); goto error; } #else sock->fd = socket(AF_NETLINK, SOCK_RAW, protocol); if (sock->fd < 0) { VLOG_ERR("fcntl: %s", ovs_strerror(errno)); goto error; } #endif sock->protocol = protocol; sock->next_seq = 1; rcvbuf = 1024 * 1024; #ifdef _WIN32 sock->rcvbuf = rcvbuf; ovs_mutex_lock(&portid_mutex); sock->pid = portid_next(); set_sock_pid_in_kernel(sock->handle, sock->pid); ovs_mutex_unlock(&portid_mutex); #else if (setsockopt(sock->fd, SOL_SOCKET, SO_RCVBUFFORCE, &rcvbuf, sizeof rcvbuf)) { /* Only root can use SO_RCVBUFFORCE. Everyone else gets EPERM. * Warn only if the failure is therefore unexpected. */ if (errno != EPERM) { VLOG_WARN_RL(&rl, "setting %d-byte socket receive buffer failed " "(%s)", rcvbuf, ovs_strerror(errno)); } } retval = get_socket_rcvbuf(sock->fd); if (retval < 0) { retval = -retval; goto error; } sock->rcvbuf = retval; /* Connect to kernel (pid 0) as remote address. */ memset(&remote, 0, sizeof remote); remote.nl_family = AF_NETLINK; remote.nl_pid = 0; if (connect(sock->fd, (struct sockaddr *) &remote, sizeof remote) < 0) { VLOG_ERR("connect(0): %s", ovs_strerror(errno)); goto error; } /* Obtain pid assigned by kernel. */ local_size = sizeof local; if (getsockname(sock->fd, (struct sockaddr *) &local, &local_size) < 0) { VLOG_ERR("getsockname: %s", ovs_strerror(errno)); goto error; } if (local_size < sizeof local || local.nl_family != AF_NETLINK) { VLOG_ERR("getsockname returned bad Netlink name"); retval = EINVAL; goto error; } sock->pid = local.nl_pid; #endif *sockp = sock; return 0; error: if (retval == 0) { retval = errno; if (retval == 0) { retval = EINVAL; } } #ifdef _WIN32 if (sock->handle != INVALID_HANDLE_VALUE) { CloseHandle(sock->handle); } #else if (sock->fd >= 0) { close(sock->fd); } #endif free(sock); return retval; }