git://git.onelab.eu
/
sliver-openvswitch.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
ofproto-dpif: Use sequence number to wake up main thread for
[sliver-openvswitch.git]
/
lib
/
netdev-vport.c
diff --git
a/lib/netdev-vport.c
b/lib/netdev-vport.c
index
ac3da63
..
9e92a88
100644
(file)
--- a/
lib/netdev-vport.c
+++ b/
lib/netdev-vport.c
@@
-48,7
+48,10
@@
VLOG_DEFINE_THIS_MODULE(netdev_vport);
struct netdev_vport {
struct netdev up;
struct netdev_vport {
struct netdev up;
- unsigned int change_seq;
+
+ /* Protects all members below. */
+ struct ovs_mutex mutex;
+
uint8_t etheraddr[ETH_ADDR_LEN];
struct netdev_stats stats;
uint8_t etheraddr[ETH_ADDR_LEN];
struct netdev_stats stats;
@@
-65,9
+68,8
@@
struct vport_class {
};
static int netdev_vport_construct(struct netdev *);
};
static int netdev_vport_construct(struct netdev *);
-static int get_patch_config(const struct netdev *, struct smap *args);
+static int get_patch_config(const struct netdev *
netdev
, struct smap *args);
static int get_tunnel_config(const struct netdev *, struct smap *args);
static int get_tunnel_config(const struct netdev *, struct smap *args);
-static void netdev_vport_poll_notify(struct netdev_vport *);
static bool
is_vport_class(const struct netdev_class *class)
static bool
is_vport_class(const struct netdev_class *class)
@@
-103,6
+105,14
@@
netdev_vport_is_patch(const struct netdev *netdev)
return class->get_config == get_patch_config;
}
return class->get_config == get_patch_config;
}
+bool
+netdev_vport_is_layer3(const struct netdev *dev)
+{
+ const char *type = netdev_get_type(dev);
+
+ return (!strcmp("lisp", type));
+}
+
static bool
netdev_vport_needs_dst_port(const struct netdev *dev)
{
static bool
netdev_vport_needs_dst_port(const struct netdev *dev)
{
@@
-166,7
+176,7
@@
netdev_vport_construct(struct netdev *netdev_)
{
struct netdev_vport *netdev = netdev_vport_cast(netdev_);
{
struct netdev_vport *netdev = netdev_vport_cast(netdev_);
-
netdev->change_seq = 1
;
+
ovs_mutex_init(&netdev->mutex)
;
eth_addr_random(netdev->etheraddr);
route_table_register();
eth_addr_random(netdev->etheraddr);
route_table_register();
@@
-181,6
+191,7
@@
netdev_vport_destruct(struct netdev *netdev_)
route_table_unregister();
free(netdev->peer);
route_table_unregister();
free(netdev->peer);
+ ovs_mutex_destroy(&netdev->mutex);
}
static void
}
static void
@@
-195,26
+206,39
@@
netdev_vport_set_etheraddr(struct netdev *netdev_,
const uint8_t mac[ETH_ADDR_LEN])
{
struct netdev_vport *netdev = netdev_vport_cast(netdev_);
const uint8_t mac[ETH_ADDR_LEN])
{
struct netdev_vport *netdev = netdev_vport_cast(netdev_);
+
+ ovs_mutex_lock(&netdev->mutex);
memcpy(netdev->etheraddr, mac, ETH_ADDR_LEN);
memcpy(netdev->etheraddr, mac, ETH_ADDR_LEN);
- netdev_vport_poll_notify(netdev);
+ ovs_mutex_unlock(&netdev->mutex);
+ netdev_change_seq_changed(netdev_);
+
return 0;
}
static int
return 0;
}
static int
-netdev_vport_get_etheraddr(const struct netdev *netdev,
+netdev_vport_get_etheraddr(const struct netdev *netdev
_
,
uint8_t mac[ETH_ADDR_LEN])
{
uint8_t mac[ETH_ADDR_LEN])
{
- memcpy(mac, netdev_vport_cast(netdev)->etheraddr, ETH_ADDR_LEN);
+ struct netdev_vport *netdev = netdev_vport_cast(netdev_);
+
+ ovs_mutex_lock(&netdev->mutex);
+ memcpy(mac, netdev->etheraddr, ETH_ADDR_LEN);
+ ovs_mutex_unlock(&netdev->mutex);
+
return 0;
}
static int
return 0;
}
static int
-tunnel_get_status(const struct netdev *netdev, struct smap *smap)
+tunnel_get_status(const struct netdev *netdev
_
, struct smap *smap)
{
{
+ struct netdev_vport *netdev = netdev_vport_cast(netdev_);
char iface[IFNAMSIZ];
ovs_be32 route;
char iface[IFNAMSIZ];
ovs_be32 route;
- route = netdev_vport_cast(netdev)->tnl_cfg.ip_dst;
+ ovs_mutex_lock(&netdev->mutex);
+ route = netdev->tnl_cfg.ip_dst;
+ ovs_mutex_unlock(&netdev->mutex);
+
if (route_table_get_name(route, iface)) {
struct netdev *egress_netdev;
if (route_table_get_name(route, iface)) {
struct netdev *egress_netdev;
@@
-244,12
+268,6
@@
netdev_vport_update_flags(struct netdev *netdev OVS_UNUSED,
return 0;
}
return 0;
}
-static unsigned int
-netdev_vport_change_seq(const struct netdev *netdev)
-{
- return netdev_vport_cast(netdev)->change_seq;
-}
-
static void
netdev_vport_run(void)
{
static void
netdev_vport_run(void)
{
@@
-262,17
+280,6
@@
netdev_vport_wait(void)
route_table_wait();
}
\f
route_table_wait();
}
\f
-/* Helper functions. */
-
-static void
-netdev_vport_poll_notify(struct netdev_vport *ndv)
-{
- ndv->change_seq++;
- if (!ndv->change_seq) {
- ndv->change_seq++;
- }
-}
-
\f
/* Code specific to tunnel types. */
static ovs_be64
/* Code specific to tunnel types. */
static ovs_be64
@@
-424,6
+431,7
@@
set_tunnel_config(struct netdev *dev_, const struct smap *args)
static struct ovs_mutex mutex = OVS_MUTEX_INITIALIZER;
static pid_t pid = 0;
static struct ovs_mutex mutex = OVS_MUTEX_INITIALIZER;
static pid_t pid = 0;
+#ifndef _WIN32
ovs_mutex_lock(&mutex);
if (pid <= 0) {
char *file_name = xasprintf("%s/%s", ovs_rundir(),
ovs_mutex_lock(&mutex);
if (pid <= 0) {
char *file_name = xasprintf("%s/%s", ovs_rundir(),
@@
-432,6
+440,7
@@
set_tunnel_config(struct netdev *dev_, const struct smap *args)
free(file_name);
}
ovs_mutex_unlock(&mutex);
free(file_name);
}
ovs_mutex_unlock(&mutex);
+#endif
if (pid < 0) {
VLOG_ERR("%s: IPsec requires the ovs-monitor-ipsec daemon",
if (pid < 0) {
VLOG_ERR("%s: IPsec requires the ovs-monitor-ipsec daemon",
@@
-473,8
+482,10
@@
set_tunnel_config(struct netdev *dev_, const struct smap *args)
&tnl_cfg.out_key_present,
&tnl_cfg.out_key_flow);
&tnl_cfg.out_key_present,
&tnl_cfg.out_key_flow);
+ ovs_mutex_lock(&dev->mutex);
dev->tnl_cfg = tnl_cfg;
dev->tnl_cfg = tnl_cfg;
- netdev_vport_poll_notify(dev);
+ netdev_change_seq_changed(dev_);
+ ovs_mutex_unlock(&dev->mutex);
return 0;
}
return 0;
}
@@
-482,56
+493,60
@@
set_tunnel_config(struct netdev *dev_, const struct smap *args)
static int
get_tunnel_config(const struct netdev *dev, struct smap *args)
{
static int
get_tunnel_config(const struct netdev *dev, struct smap *args)
{
- const struct netdev_tunnel_config *tnl_cfg =
- &netdev_vport_cast(dev)->tnl_cfg;
+ struct netdev_vport *netdev = netdev_vport_cast(dev);
+ struct netdev_tunnel_config tnl_cfg;
+
+ ovs_mutex_lock(&netdev->mutex);
+ tnl_cfg = netdev->tnl_cfg;
+ ovs_mutex_unlock(&netdev->mutex);
- if (tnl_cfg
->
ip_dst) {
- smap_add_format(args, "remote_ip", IP_FMT, IP_ARGS(tnl_cfg
->
ip_dst));
- } else if (tnl_cfg
->
ip_dst_flow) {
+ if (tnl_cfg
.
ip_dst) {
+ smap_add_format(args, "remote_ip", IP_FMT, IP_ARGS(tnl_cfg
.
ip_dst));
+ } else if (tnl_cfg
.
ip_dst_flow) {
smap_add(args, "remote_ip", "flow");
}
smap_add(args, "remote_ip", "flow");
}
- if (tnl_cfg
->
ip_src) {
- smap_add_format(args, "local_ip", IP_FMT, IP_ARGS(tnl_cfg
->
ip_src));
- } else if (tnl_cfg
->
ip_src_flow) {
+ if (tnl_cfg
.
ip_src) {
+ smap_add_format(args, "local_ip", IP_FMT, IP_ARGS(tnl_cfg
.
ip_src));
+ } else if (tnl_cfg
.
ip_src_flow) {
smap_add(args, "local_ip", "flow");
}
smap_add(args, "local_ip", "flow");
}
- if (tnl_cfg
->in_key_flow && tnl_cfg->
out_key_flow) {
+ if (tnl_cfg
.in_key_flow && tnl_cfg.
out_key_flow) {
smap_add(args, "key", "flow");
smap_add(args, "key", "flow");
- } else if (tnl_cfg
->in_key_present && tnl_cfg->
out_key_present
- && tnl_cfg
->in_key == tnl_cfg->
out_key) {
- smap_add_format(args, "key", "%"PRIu64, ntohll(tnl_cfg
->
in_key));
+ } else if (tnl_cfg
.in_key_present && tnl_cfg.
out_key_present
+ && tnl_cfg
.in_key == tnl_cfg.
out_key) {
+ smap_add_format(args, "key", "%"PRIu64, ntohll(tnl_cfg
.
in_key));
} else {
} else {
- if (tnl_cfg
->
in_key_flow) {
+ if (tnl_cfg
.
in_key_flow) {
smap_add(args, "in_key", "flow");
smap_add(args, "in_key", "flow");
- } else if (tnl_cfg
->
in_key_present) {
+ } else if (tnl_cfg
.
in_key_present) {
smap_add_format(args, "in_key", "%"PRIu64,
smap_add_format(args, "in_key", "%"PRIu64,
- ntohll(tnl_cfg
->
in_key));
+ ntohll(tnl_cfg
.
in_key));
}
}
- if (tnl_cfg
->
out_key_flow) {
+ if (tnl_cfg
.
out_key_flow) {
smap_add(args, "out_key", "flow");
smap_add(args, "out_key", "flow");
- } else if (tnl_cfg
->
out_key_present) {
+ } else if (tnl_cfg
.
out_key_present) {
smap_add_format(args, "out_key", "%"PRIu64,
smap_add_format(args, "out_key", "%"PRIu64,
- ntohll(tnl_cfg
->
out_key));
+ ntohll(tnl_cfg
.
out_key));
}
}
}
}
- if (tnl_cfg
->
ttl_inherit) {
+ if (tnl_cfg
.
ttl_inherit) {
smap_add(args, "ttl", "inherit");
smap_add(args, "ttl", "inherit");
- } else if (tnl_cfg
->
ttl != DEFAULT_TTL) {
- smap_add_format(args, "ttl", "%"PRIu8, tnl_cfg
->
ttl);
+ } else if (tnl_cfg
.
ttl != DEFAULT_TTL) {
+ smap_add_format(args, "ttl", "%"PRIu8, tnl_cfg
.
ttl);
}
}
- if (tnl_cfg
->
tos_inherit) {
+ if (tnl_cfg
.
tos_inherit) {
smap_add(args, "tos", "inherit");
smap_add(args, "tos", "inherit");
- } else if (tnl_cfg
->
tos) {
- smap_add_format(args, "tos", "0x%x", tnl_cfg
->
tos);
+ } else if (tnl_cfg
.
tos) {
+ smap_add_format(args, "tos", "0x%x", tnl_cfg
.
tos);
}
}
- if (tnl_cfg
->
dst_port) {
- uint16_t dst_port = ntohs(tnl_cfg
->
dst_port);
+ if (tnl_cfg
.
dst_port) {
+ uint16_t dst_port = ntohs(tnl_cfg
.
dst_port);
const char *type = netdev_get_type(dev);
if ((!strcmp("vxlan", type) && dst_port != VXLAN_DST_PORT) ||
const char *type = netdev_get_type(dev);
if ((!strcmp("vxlan", type) && dst_port != VXLAN_DST_PORT) ||
@@
-540,11
+555,11
@@
get_tunnel_config(const struct netdev *dev, struct smap *args)
}
}
}
}
- if (tnl_cfg
->
csum) {
+ if (tnl_cfg
.
csum) {
smap_add(args, "csum", "true");
}
smap_add(args, "csum", "true");
}
- if (!tnl_cfg
->
dont_fragment) {
+ if (!tnl_cfg
.
dont_fragment) {
smap_add(args, "df_default", "false");
}
smap_add(args, "df_default", "false");
}
@@
-553,22
+568,39
@@
get_tunnel_config(const struct netdev *dev, struct smap *args)
\f
/* Code specific to patch ports. */
\f
/* Code specific to patch ports. */
-const char *
-netdev_vport_patch_peer(const struct netdev *netdev)
+/* If 'netdev' is a patch port, returns the name of its peer as a malloc()'d
+ * string that the caller must free.
+ *
+ * If 'netdev' is not a patch port, returns NULL. */
+char *
+netdev_vport_patch_peer(const struct netdev *netdev_)
{
{
- return (netdev_vport_is_patch(netdev)
- ? netdev_vport_cast(netdev)->peer
- : NULL);
+ char *peer = NULL;
+
+ if (netdev_vport_is_patch(netdev_)) {
+ struct netdev_vport *netdev = netdev_vport_cast(netdev_);
+
+ ovs_mutex_lock(&netdev->mutex);
+ if (netdev->peer) {
+ peer = xstrdup(netdev->peer);
+ }
+ ovs_mutex_unlock(&netdev->mutex);
+ }
+
+ return peer;
}
void
netdev_vport_inc_rx(const struct netdev *netdev,
}
void
netdev_vport_inc_rx(const struct netdev *netdev,
-
const struct dpif_flow_stats *stats)
+ const struct dpif_flow_stats *stats)
{
if (is_vport_class(netdev_get_class(netdev))) {
struct netdev_vport *dev = netdev_vport_cast(netdev);
{
if (is_vport_class(netdev_get_class(netdev))) {
struct netdev_vport *dev = netdev_vport_cast(netdev);
+
+ ovs_mutex_lock(&dev->mutex);
dev->stats.rx_packets += stats->n_packets;
dev->stats.rx_bytes += stats->n_bytes;
dev->stats.rx_packets += stats->n_packets;
dev->stats.rx_bytes += stats->n_bytes;
+ ovs_mutex_unlock(&dev->mutex);
}
}
}
}
@@
-578,8
+610,11
@@
netdev_vport_inc_tx(const struct netdev *netdev,
{
if (is_vport_class(netdev_get_class(netdev))) {
struct netdev_vport *dev = netdev_vport_cast(netdev);
{
if (is_vport_class(netdev_get_class(netdev))) {
struct netdev_vport *dev = netdev_vport_cast(netdev);
+
+ ovs_mutex_lock(&dev->mutex);
dev->stats.tx_packets += stats->n_packets;
dev->stats.tx_bytes += stats->n_bytes;
dev->stats.tx_packets += stats->n_packets;
dev->stats.tx_bytes += stats->n_bytes;
+ ovs_mutex_unlock(&dev->mutex);
}
}
}
}
@@
-588,9
+623,12
@@
get_patch_config(const struct netdev *dev_, struct smap *args)
{
struct netdev_vport *dev = netdev_vport_cast(dev_);
{
struct netdev_vport *dev = netdev_vport_cast(dev_);
+ ovs_mutex_lock(&dev->mutex);
if (dev->peer) {
smap_add(args, "peer", dev->peer);
}
if (dev->peer) {
smap_add(args, "peer", dev->peer);
}
+ ovs_mutex_unlock(&dev->mutex);
+
return 0;
}
return 0;
}
@@
-617,9
+655,12
@@
set_patch_config(struct netdev *dev_, const struct smap *args)
return EINVAL;
}
return EINVAL;
}
+ ovs_mutex_lock(&dev->mutex);
free(dev->peer);
dev->peer = xstrdup(peer);
free(dev->peer);
dev->peer = xstrdup(peer);
- netdev_vport_poll_notify(dev);
+ netdev_change_seq_changed(dev_);
+ ovs_mutex_unlock(&dev->mutex);
+
return 0;
}
return 0;
}
@@
-627,7
+668,11
@@
static int
get_stats(const struct netdev *netdev, struct netdev_stats *stats)
{
struct netdev_vport *dev = netdev_vport_cast(netdev);
get_stats(const struct netdev *netdev, struct netdev_stats *stats)
{
struct netdev_vport *dev = netdev_vport_cast(netdev);
- memcpy(stats, &dev->stats, sizeof *stats);
+
+ ovs_mutex_lock(&dev->mutex);
+ *stats = dev->stats;
+ ovs_mutex_unlock(&dev->mutex);
+
return 0;
}
\f
return 0;
}
\f
@@
-671,7
+716,9
@@
get_stats(const struct netdev *netdev, struct netdev_stats *stats)
NULL, /* set_queue */ \
NULL, /* delete_queue */ \
NULL, /* get_queue_stats */ \
NULL, /* set_queue */ \
NULL, /* delete_queue */ \
NULL, /* get_queue_stats */ \
- NULL, /* dump_queues */ \
+ NULL, /* queue_dump_start */ \
+ NULL, /* queue_dump_next */ \
+ NULL, /* queue_dump_done */ \
NULL, /* dump_queue_stats */ \
\
NULL, /* get_in4 */ \
NULL, /* dump_queue_stats */ \
\
NULL, /* get_in4 */ \
@@
-684,8
+731,6
@@
get_stats(const struct netdev *netdev, struct netdev_stats *stats)
\
netdev_vport_update_flags, \
\
\
netdev_vport_update_flags, \
\
- netdev_vport_change_seq, \
- \
NULL, /* rx_alloc */ \
NULL, /* rx_construct */ \
NULL, /* rx_destruct */ \
NULL, /* rx_alloc */ \
NULL, /* rx_construct */ \
NULL, /* rx_destruct */ \
@@
-712,15
+757,15
@@
netdev_vport_tunnel_register(void)
TUNNEL_CLASS("vxlan", "vxlan_system"),
TUNNEL_CLASS("lisp", "lisp_system")
};
TUNNEL_CLASS("vxlan", "vxlan_system"),
TUNNEL_CLASS("lisp", "lisp_system")
};
- static
bool inited
;
+ static
struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER
;
- int i;
+ if (ovsthread_once_start(&once)) {
+ int i;
- if (!inited) {
- inited = true;
for (i = 0; i < ARRAY_SIZE(vport_classes); i++) {
netdev_register_provider(&vport_classes[i].netdev_class);
}
for (i = 0; i < ARRAY_SIZE(vport_classes); i++) {
netdev_register_provider(&vport_classes[i].netdev_class);
}
+ ovsthread_once_done(&once);
}
}
}
}