-static struct shash pltap_netdevs = SHASH_INITIALIZER(&pltap_netdevs);
+/* Protects 'pltap_netdevs' */
+static struct ovs_mutex pltap_netdevs_mutex = OVS_MUTEX_INITIALIZER;
+static struct shash pltap_netdevs OVS_GUARDED_BY(pltap_netdevs_mutex)
+ = SHASH_INITIALIZER(&pltap_netdevs);
-static void netdev_pltap_update_seq(struct netdev_pltap *);
-static int get_flags(struct netdev_pltap *dev, enum netdev_flags *flags);
+static void netdev_pltap_update_seq(struct netdev_pltap *)
+ OVS_REQUIRES(dev->mutex);
+static int get_flags(struct netdev_pltap *dev, enum netdev_flags *flags)
+ OVS_REQUIRES(dev->mutex);
return CONTAINER_OF(rx, struct netdev_rx_pltap, up);
}
static void sync_needed(struct netdev_pltap *dev)
return CONTAINER_OF(rx, struct netdev_rx_pltap, up);
}
static void sync_needed(struct netdev_pltap *dev)
{
if (dev->sync_flags_needed)
return;
dev->sync_flags_needed = true;
list_insert(&sync_list, &dev->sync_list);
{
if (dev->sync_flags_needed)
return;
dev->sync_flags_needed = true;
list_insert(&sync_list, &dev->sync_list);
netdev->real_name = xzalloc(IFNAMSIZ + 1);
memset(&netdev->local_addr, 0, sizeof(netdev->local_addr));
netdev->valid_local_ip = false;
netdev->valid_local_netmask = false;
netdev->flags = 0;
netdev->sync_flags_needed = false;
netdev->real_name = xzalloc(IFNAMSIZ + 1);
memset(&netdev->local_addr, 0, sizeof(netdev->local_addr));
netdev->valid_local_ip = false;
netdev->valid_local_netmask = false;
netdev->flags = 0;
netdev->sync_flags_needed = false;
- VLOG_WARN("tun_alloc(IFF_TAP, %s) failed: %s", name, ovs_strerror(error));
- goto cleanup;
+ VLOG_WARN("tun_alloc(IFF_TAP, %s) failed: %s",
+ netdev_get_name(netdev_), ovs_strerror(error));
+ return error;
}
VLOG_DBG("real_name = %s", netdev->real_name);
/* Make non-blocking. */
error = set_nonblocking(netdev->fd);
if (error) {
}
VLOG_DBG("real_name = %s", netdev->real_name);
/* Make non-blocking. */
error = set_nonblocking(netdev->fd);
if (error) {
- netdev_init(&netdev->up, name, &netdev_pltap_class);
- shash_add(&pltap_netdevs, name, netdev);
- *netdevp = &netdev->up;
+ ovs_mutex_lock(&pltap_netdevs_mutex);
+ shash_add(&pltap_netdevs, netdev_get_name(netdev_), netdev);
+ ovs_mutex_unlock(&pltap_netdevs_mutex);
shash_find_and_delete(&pltap_netdevs,
netdev_get_name(netdev_));
shash_find_and_delete(&pltap_netdevs,
netdev_get_name(netdev_));
-static int netdev_pltap_up(struct netdev_pltap *dev);
+static int netdev_pltap_up(struct netdev_pltap *dev) OVS_REQUIRES(dev->mutex);
+
+static struct netdev_rx *
+netdev_pltap_rx_alloc(void)
+{
+ struct netdev_rx_pltap *rx = xzalloc(sizeof *rx);
+ return &rx->up;
+}
if (netdev->valid_local_ip)
smap_add_format(args, "local_ip", IP_FMT,
IP_ARGS(netdev->local_addr.sin_addr.s_addr));
if (netdev->valid_local_netmask)
smap_add_format(args, "local_netmask", "%"PRIu32,
ntohs(netdev->local_netmask));
if (netdev->valid_local_ip)
smap_add_format(args, "local_ip", IP_FMT,
IP_ARGS(netdev->local_addr.sin_addr.s_addr));
if (netdev->valid_local_netmask)
smap_add_format(args, "local_netmask", "%"PRIu32,
ntohs(netdev->local_netmask));
VLOG_DBG("pltap_set_config(%s)", netdev_get_name(dev_));
SMAP_FOR_EACH(node, args) {
VLOG_DBG("arg: %s->%s", node->name, (char*)node->data);
VLOG_DBG("pltap_set_config(%s)", netdev_get_name(dev_));
SMAP_FOR_EACH(node, args) {
VLOG_DBG("arg: %s->%s", node->name, (char*)node->data);
retval = writev(dev->fd, iov, 2);
if (retval >= 0) {
if (retval != size + 4) {
retval = writev(dev->fd, iov, 2);
if (retval >= 0) {
if (retval != size + 4) {
// XXX from netdev-linux.c
static int
get_etheraddr(struct netdev_pltap *dev, uint8_t ea[ETH_ADDR_LEN])
// XXX from netdev-linux.c
static int
get_etheraddr(struct netdev_pltap *dev, uint8_t ea[ETH_ADDR_LEN])
error = af_inet_ifreq_ioctl(dev->real_name, &ifr,
SIOCGIFHWADDR, "SIOCGIFHWADDR");
if (error) {
error = af_inet_ifreq_ioctl(dev->real_name, &ifr,
SIOCGIFHWADDR, "SIOCGIFHWADDR");
if (error) {
}
hwaddr_family = ifr.ifr_hwaddr.sa_family;
if (hwaddr_family != AF_UNSPEC && hwaddr_family != ARPHRD_ETHER) {
}
hwaddr_family = ifr.ifr_hwaddr.sa_family;
if (hwaddr_family != AF_UNSPEC && hwaddr_family != ARPHRD_ETHER) {
- if (dev->fd < 0)
- return EAGAIN;
- return get_etheraddr(dev, mac);
+ int error = 0;
+
+ ovs_mutex_lock(&dev->mutex);
+ if (dev->fd < 0) {
+ error = EAGAIN;
+ goto out;
+ }
+ error = get_etheraddr(dev, mac);
+
+out:
+ ovs_mutex_unlock(&dev->mutex);
+ return error;
- return netdev_pltap_cast(netdev)->change_seq;
+ struct netdev_pltap *dev =
+ netdev_pltap_cast(netdev);
+ unsigned int change_seq;
+
+ ovs_mutex_lock(&dev->mutex);
+ change_seq = dev->change_seq;
+ ovs_mutex_unlock(&dev->mutex);
+
+ return change_seq;
pltap_dev = shash_find_data(&pltap_netdevs, argv[1]);
if (!pltap_dev) {
unixctl_command_reply_error(conn, "no such pltap netdev");
pltap_dev = shash_find_data(&pltap_netdevs, argv[1]);
if (!pltap_dev) {
unixctl_command_reply_error(conn, "no such pltap netdev");
unixctl_command_register("netdev-pltap/get-tapname", "port",
1, 1, netdev_pltap_get_real_name, NULL);
return 0;
unixctl_command_register("netdev-pltap/get-tapname", "port",
1, 1, netdev_pltap_get_real_name, NULL);
return 0;
LIST_FOR_EACH_SAFE(iter, next, sync_list, &sync_list) {
netdev_pltap_sync_flags(iter);
}
LIST_FOR_EACH_SAFE(iter, next, sync_list, &sync_list) {
netdev_pltap_sync_flags(iter);
}
netdev_pltap_send,
netdev_pltap_send_wait,
netdev_pltap_set_etheraddr,
netdev_pltap_get_etheraddr,
netdev_pltap_send,
netdev_pltap_send_wait,
netdev_pltap_set_etheraddr,
netdev_pltap_get_etheraddr,
- NULL, /* dump_queues */
+ NULL, /* queue_dump_start */
+ NULL, /* queue_dump_next */
+ NULL, /* queue_dump_done */
- netdev_pltap_change_seq
-};
-
-static const struct netdev_rx_class netdev_rx_pltap_class = {
- netdev_rx_pltap_destroy,
- netdev_rx_pltap_recv,
- netdev_rx_pltap_wait,
- netdev_rx_pltap_drain,
+ netdev_pltap_change_seq,