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
Prepare for post-2.2.0 (2.2.90).
[sliver-openvswitch.git]
/
lib
/
netdev-vport.c
diff --git
a/lib/netdev-vport.c
b/lib/netdev-vport.c
index
38fc996
..
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;
@@
-64,16
+67,14
@@
struct vport_class {
struct netdev_class netdev_class;
};
struct netdev_class netdev_class;
};
-static int netdev_vport_create(const struct netdev_class *, const char *,
- struct netdev **);
-static int get_patch_config(const struct netdev *, struct smap *args);
+static int netdev_vport_construct(struct netdev *);
+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)
{
- return class->c
reate == netdev_vport_create
;
+ return class->c
onstruct == netdev_vport_construct
;
}
static const struct vport_class *
}
static const struct vport_class *
@@
-104,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)
{
@@
-121,14
+130,12
@@
netdev_vport_class_get_dpif_port(const struct netdev_class *class)
}
const char *
}
const char *
-netdev_vport_get_dpif_port(const struct netdev *netdev)
+netdev_vport_get_dpif_port(const struct netdev *netdev,
+ char namebuf[], size_t bufsize)
{
{
- const char *dpif_port;
-
if (netdev_vport_needs_dst_port(netdev)) {
const struct netdev_vport *vport = netdev_vport_cast(netdev);
const char *type = netdev_get_type(netdev);
if (netdev_vport_needs_dst_port(netdev)) {
const struct netdev_vport *vport = netdev_vport_cast(netdev);
const char *type = netdev_get_type(netdev);
- static char dpif_port_combined[IFNAMSIZ];
/*
* Note: IFNAMSIZ is 16 bytes long. The maximum length of a VXLAN
/*
* Note: IFNAMSIZ is 16 bytes long. The maximum length of a VXLAN
@@
-136,42
+143,61
@@
netdev_vport_get_dpif_port(const struct netdev *netdev)
* assert here on the size of strlen(type) in case that changes
* in the future.
*/
* assert here on the size of strlen(type) in case that changes
* in the future.
*/
+ BUILD_ASSERT(NETDEV_VPORT_NAME_BUFSIZE >= IFNAMSIZ);
ovs_assert(strlen(type) + 10 < IFNAMSIZ);
ovs_assert(strlen(type) + 10 < IFNAMSIZ);
- snprintf(
dpif_port_combined, IFNAMSIZ
, "%s_sys_%d", type,
+ snprintf(
namebuf, bufsize
, "%s_sys_%d", type,
ntohs(vport->tnl_cfg.dst_port));
ntohs(vport->tnl_cfg.dst_port));
- return
dpif_port_combined
;
+ return
namebuf
;
} else {
const struct netdev_class *class = netdev_get_class(netdev);
} else {
const struct netdev_class *class = netdev_get_class(netdev);
- dpif_port = netdev_vport_class_get_dpif_port(class);
+ const char *dpif_port = netdev_vport_class_get_dpif_port(class);
+ return dpif_port ? dpif_port : netdev_get_name(netdev);
}
}
+}
+
+char *
+netdev_vport_get_dpif_port_strdup(const struct netdev *netdev)
+{
+ char namebuf[NETDEV_VPORT_NAME_BUFSIZE];
+
+ return xstrdup(netdev_vport_get_dpif_port(netdev, namebuf,
+ sizeof namebuf));
+}
- return dpif_port ? dpif_port : netdev_get_name(netdev);
+static struct netdev *
+netdev_vport_alloc(void)
+{
+ struct netdev_vport *netdev = xzalloc(sizeof *netdev);
+ return &netdev->up;
}
static int
}
static int
-netdev_vport_create(const struct netdev_class *netdev_class, const char *name,
- struct netdev **netdevp)
+netdev_vport_construct(struct netdev *netdev_)
{
{
- struct netdev_vport *
dev
;
+ struct netdev_vport *
netdev = netdev_vport_cast(netdev_)
;
- dev = xzalloc(sizeof *dev);
- netdev_init(&dev->up, name, netdev_class);
- dev->change_seq = 1;
- eth_addr_random(dev->etheraddr);
+ ovs_mutex_init(&netdev->mutex);
+ eth_addr_random(netdev->etheraddr);
- *netdevp = &dev->up;
route_table_register();
return 0;
}
static void
route_table_register();
return 0;
}
static void
-netdev_vport_destr
oy
(struct netdev *netdev_)
+netdev_vport_destr
uct
(struct netdev *netdev_)
{
struct netdev_vport *netdev = netdev_vport_cast(netdev_);
route_table_unregister();
free(netdev->peer);
{
struct netdev_vport *netdev = netdev_vport_cast(netdev_);
route_table_unregister();
free(netdev->peer);
+ ovs_mutex_destroy(&netdev->mutex);
+}
+
+static void
+netdev_vport_dealloc(struct netdev *netdev_)
+{
+ struct netdev_vport *netdev = netdev_vport_cast(netdev_);
free(netdev);
}
free(netdev);
}
@@
-180,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)
{
{
- static char iface[IFNAMSIZ];
+ struct netdev_vport *netdev = netdev_vport_cast(netdev_);
+ char iface[IFNAMSIZ];
ovs_be32 route;
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;
@@
-229,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)
{
@@
-247,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
@@
-406,13
+428,19
@@
set_tunnel_config(struct netdev *dev_, const struct smap *args)
}
if (tnl_cfg.ipsec) {
}
if (tnl_cfg.ipsec) {
+ static struct ovs_mutex mutex = OVS_MUTEX_INITIALIZER;
static pid_t pid = 0;
static pid_t pid = 0;
+
+#ifndef _WIN32
+ ovs_mutex_lock(&mutex);
if (pid <= 0) {
char *file_name = xasprintf("%s/%s", ovs_rundir(),
"ovs-monitor-ipsec.pid");
pid = read_pidfile(file_name);
free(file_name);
}
if (pid <= 0) {
char *file_name = xasprintf("%s/%s", ovs_rundir(),
"ovs-monitor-ipsec.pid");
pid = read_pidfile(file_name);
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",
@@
-454,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;
}
@@
-463,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) ||
@@
-521,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");
}
@@
-534,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);
}
}
}
}
@@
-559,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);
}
}
}
}
@@
-569,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;
}
@@
-598,8
+655,11
@@
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_change_seq_changed(dev_);
+ ovs_mutex_unlock(&dev->mutex);
return 0;
}
return 0;
}
@@
-608,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
@@
-618,14
+682,14
@@
get_stats(const struct netdev *netdev, struct netdev_stats *stats)
netdev_vport_run, \
netdev_vport_wait, \
\
netdev_vport_run, \
netdev_vport_wait, \
\
- netdev_vport_create, \
- netdev_vport_destroy, \
+ netdev_vport_alloc, \
+ netdev_vport_construct, \
+ netdev_vport_destruct, \
+ netdev_vport_dealloc, \
GET_CONFIG, \
SET_CONFIG, \
GET_TUNNEL_CONFIG, \
\
GET_CONFIG, \
SET_CONFIG, \
GET_TUNNEL_CONFIG, \
\
- NULL, /* rx_open */ \
- \
NULL, /* send */ \
NULL, /* send_wait */ \
\
NULL, /* send */ \
NULL, /* send_wait */ \
\
@@
-652,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 */ \
@@
-665,7
+731,13
@@
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_dealloc */ \
+ NULL, /* rx_recv */ \
+ NULL, /* rx_wait */ \
+ NULL, /* rx_drain */
#define TUNNEL_CLASS(NAME, DPIF_PORT) \
{ DPIF_PORT, \
#define TUNNEL_CLASS(NAME, DPIF_PORT) \
{ DPIF_PORT, \
@@
-685,11
+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 struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
- int i;
+ if (ovsthread_once_start(&once)) {
+ int i;
- 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);
}
}
}
}