Re: [ovs-dev] [mptcp-dev] MPTCP v0.87 - Release Candidate
Hello, yes this is possible. You just need to make MPTCP create two subflows, e.g., by using the sysctl mptcp_ndiffports [1] or by adding a second IP-address to the interface. Cheers, Christoph [1]: http://multipath-tcp.org/pmwiki.php/Users/ConfigureMPTCP On 23/07/13 - 08:56:56, Vasiliy Tolstov wrote: > Very good. Is that possible to use mptcp with openvswitch in top of it? > For example openvswitch able to aggregate two eth links to bond > interface with lacp : active-passive, but not able to create 802.3ad > aggregation. > > 2013/7/12 Christoph Paasch : > > Hello, > > > > there are two weeks left until the next IETF-meeting - > > thus two weeks left until the new stable MPTCP release - > > two weeks left to test the release-candidate before the "official" release > > :) > > > > The release-candidate is now available in branch mptcp_v0.87 of > > https://github.com/multipath-tcp/mptcp/tree/mptcp_v0.87 . > > > > I encourage everybody to go and try it out, and report any bugs you might > > encounter. > > > > > > This MPTCP-release is based on Linux 3.10. A stable backport will be > > maintained for Linux 3.8 (to be able to use MPTCP with Ubuntu Raring). If > > somebody needs another backport of MPTCP (between 3.6 and 3.10), let us know > > and we will see what can be done. > > > > The new features are mainly on the performance-improvement side: > > - Hardware-offloading > > - Zero-copy support > > - NET_DMA support > > - Proper support for NFS > > - 'ip link set dev [itf] multipath off' now works on existing connections > > > > > > Cheers, > > Christoph > > > > > > MPTCP-developpers Mailing-List > > Visit https://scm.info.ucl.ac.be/trac/mptcp/ to access the source-code of > > MPTCP in the Linux Kernel > > > > To Unsubscribe, visit https://listes-2.sipr.ucl.ac.be/sympa/info/mptcp-dev > > > > > > -- > Vasiliy Tolstov, > e-mail: v.tols...@selfip.ru > jabber: v...@selfip.ru ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [mptcp-dev] MPTCP v0.87 - Release Candidate
2013/7/23 Christoph Paasch : > yes this is possible. You just need to make MPTCP create two subflows, e.g., > by using the sysctl mptcp_ndiffports [1] or by adding a second IP-address to > the interface. Thanks for response. If i don't want to use 2 ip adress and use vSwitch bridge on top of two eth devices with mptcp enable and assign ip to bridge does it can work? -- Vasiliy Tolstov, e-mail: v.tols...@selfip.ru jabber: v...@selfip.ru ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [mptcp-dev] MPTCP v0.87 - Release Candidate
On 23/07/13 - 12:09:12, Vasiliy Tolstov wrote: > 2013/7/23 Christoph Paasch : > > yes this is possible. You just need to make MPTCP create two subflows, e.g., > > by using the sysctl mptcp_ndiffports [1] or by adding a second IP-address to > > the interface. > > > Thanks for response. If i don't want to use 2 ip adress and use > vSwitch bridge on top of two eth devices with mptcp enable and assign > ip to bridge does it can work? I do not know the technical details of bridging with vswitch, but from an MPTCP point-of-view this would work. You just have to set the sysctl ndiffports to 2, so that MPTCP creates two subflows and let the openflow-controller route the subflows accordingly. Cheers, Christoph ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [mptcp-dev] MPTCP v0.87 - Release Candidate
2013/7/23 Christoph Paasch : > I do not know the technical details of bridging with vswitch, but from an > MPTCP point-of-view this would work. > > You just have to set the sysctl ndiffports to 2, so that MPTCP creates two > subflows and let the openflow-controller route the subflows accordingly. Thanks, i'm try and send results. -- Vasiliy Tolstov, e-mail: v.tols...@selfip.ru jabber: v...@selfip.ru ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [mptcp-dev] MPTCP v0.87 - Release Candidate
2013/7/23 Christoph Paasch : > I do not know the technical details of bridging with vswitch, but from an > MPTCP point-of-view this would work. > > You just have to set the sysctl ndiffports to 2, so that MPTCP creates two > subflows and let the openflow-controller route the subflows accordingly. What i need to configure on router side (linux server that act as router and forward packets from mtcp enabled hosts) ? -- Vasiliy Tolstov, e-mail: v.tols...@selfip.ru jabber: v...@selfip.ru ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [mptcp-dev] MPTCP v0.87 - Release Candidate
On 23/07/13 - 13:46:37, Vasiliy Tolstov wrote: > 2013/7/23 Christoph Paasch : > > I do not know the technical details of bridging with vswitch, but from an > > MPTCP point-of-view this would work. > > > > You just have to set the sysctl ndiffports to 2, so that MPTCP creates two > > subflows and let the openflow-controller route the subflows accordingly. > > > What i need to configure on router side (linux server that act as > router and forward packets from mtcp enabled hosts) ? For MPTCP, you don't have to configure anything. MPTCP looks like regular TCP to the middleboxes. Christoph ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [threads 21/23] command-line: Make proctitle changing commands thread-safe.
Looks good to me, thanks, On Thu, Jul 18, 2013 at 4:15 PM, Ben Pfaff wrote: > Signed-off-by: Ben Pfaff > --- > lib/command-line.c |5 + > 1 files changed, 5 insertions(+), 0 deletions(-) > > diff --git a/lib/command-line.c b/lib/command-line.c > index 7800c0b..39b26da 100644 > --- a/lib/command-line.c > +++ b/lib/command-line.c > @@ -97,6 +97,7 @@ run_command(int argc, char *argv[], const struct command > commands[]) > static char *argv_start; /* Start of command-line arguments in > memory. */ > static size_t argv_size; /* Number of bytes of command-line > arguments. */ > static char *saved_proctitle; /* Saved command-line arguments. */ > +static pthread_mutex_t proctitle_mutex = PTHREAD_MUTEX_INITIALIZER; > > /* Prepares the process so that proctitle_set() can later succeed. > * > @@ -154,6 +155,7 @@ proctitle_set(const char *format, ...) > return; > } > > +xpthread_mutex_lock(&proctitle_mutex); > if (!saved_proctitle) { > saved_proctitle = xmemdup(argv_start, argv_size); > } > @@ -172,17 +174,20 @@ proctitle_set(const char *format, ...) > memset(&argv_start[n], '\0', argv_size - n); > } > va_end(args); > +xpthread_mutex_unlock(&proctitle_mutex); > } > > /* Restores the process's original command line, as seen by "ps". */ > void > proctitle_restore(void) > { > +xpthread_mutex_lock(&proctitle_mutex); > if (saved_proctitle) { > memcpy(argv_start, saved_proctitle, argv_size); > free(saved_proctitle); > saved_proctitle = NULL; > } > +xpthread_mutex_unlock(&proctitle_mutex); > } > #else /* !LINUX_DATAPATH*/ > /* Stubs that don't do anything on non-Linux systems. */ > -- > 1.7.2.5 > > ___ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev > ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [threads 23/23] vlog: Mark vlog_module_ptr_* as const.
Looks good to me, Want to ask, the "section" attribute specifies that the pointer is placed in "vlog_modules"" section. And this section is automatically created by compiler, right? Thanks, On Thu, Jul 18, 2013 at 4:15 PM, Ben Pfaff wrote: > This makes them more obviously thread-safe. > > Signed-off-by: Ben Pfaff > --- > lib/vlog.h |4 ++-- > 1 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/lib/vlog.h b/lib/vlog.h > index 9576687..c111ff6 100644 > --- a/lib/vlog.h > +++ b/lib/vlog.h > @@ -88,8 +88,8 @@ struct vlog_module { > #if USE_LINKER_SECTIONS > #define VLOG_DEFINE_MODULE(MODULE) \ > VLOG_DEFINE_MODULE__(MODULE)\ > -extern struct vlog_module *vlog_module_ptr_##MODULE;\ > -struct vlog_module *vlog_module_ptr_##MODULE\ > +extern struct vlog_module *const vlog_module_ptr_##MODULE; \ > +struct vlog_module *const vlog_module_ptr_##MODULE \ > __attribute__((section("vlog_modules"))) = &VLM_##MODULE > #else > #define VLOG_DEFINE_MODULE(MODULE) extern struct vlog_module VLM_##MODULE > -- > 1.7.2.5 > > ___ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev > ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [threads 22/23] fatal-signal: Make thread-safe.
Looks good to me, thanks, On Thu, Jul 18, 2013 at 4:15 PM, Ben Pfaff wrote: > Signed-off-by: Ben Pfaff > --- > lib/fatal-signal.c | 56 > +++ > lib/fatal-signal.h |3 +- > lib/ovs-thread.c |5 > lib/ovs-thread.h |6 + > 4 files changed, 60 insertions(+), 10 deletions(-) > > diff --git a/lib/fatal-signal.c b/lib/fatal-signal.c > index db8d98e..40daf5a 100644 > --- a/lib/fatal-signal.c > +++ b/lib/fatal-signal.c > @@ -23,6 +23,7 @@ > #include > #include > #include > +#include "ovs-thread.h" > #include "poll-loop.h" > #include "shash.h" > #include "sset.h" > @@ -56,20 +57,32 @@ static size_t n_hooks; > static int signal_fds[2]; > static volatile sig_atomic_t stored_sig_nr = SIG_ATOMIC_MAX; > > -static void fatal_signal_init(void); > +static pthread_mutex_t mutex; > + > static void atexit_handler(void); > static void call_hooks(int sig_nr); > > -static void > +/* Initializes the fatal signal handling module. Calling this function is > + * optional, because calling any other function in the module will also > + * initialize it. However, in a multithreaded program, the module must be > + * initialized while the process is still single-threaded. */ > +void > fatal_signal_init(void) > { > static bool inited = false; > > if (!inited) { > +pthread_mutexattr_t attr; > size_t i; > > +assert_single_threaded(); > inited = true; > > +xpthread_mutexattr_init(&attr); > +xpthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); > +xpthread_mutex_init(&mutex, &attr); > +xpthread_mutexattr_destroy(&attr); > + > xpipe_nonblocking(signal_fds); > > for (i = 0; i < ARRAY_SIZE(fatal_signals); i++) { > @@ -86,13 +99,13 @@ fatal_signal_init(void) > } > } > > -/* Registers 'hook_cb' to be called when a process termination signal is > - * raised. If 'run_at_exit' is true, 'hook_cb' is also called during > normal > - * process termination, e.g. when exit() is called or when main() returns. > +/* Registers 'hook_cb' to be called from inside poll_block() following a > fatal > + * signal. 'hook_cb' does not need to be async-signal-safe. In a > + * multithreaded program 'hook_cb' might be called from any thread, with > + * threads other than the one running 'hook_cb' in unknown states. > * > - * 'hook_cb' is not called immediately from the signal handler but rather > the > - * next time the poll loop iterates, so it is freed from the usual > restrictions > - * on signal handler functions. > + * If 'run_at_exit' is true, 'hook_cb' is also called during normal > process > + * termination, e.g. when exit() is called or when main() returns. > * > * If the current process forks, fatal_signal_fork() may be called to > clear the > * parent process's fatal signal hooks, so that 'hook_cb' is only called > when > @@ -106,12 +119,14 @@ fatal_signal_add_hook(void (*hook_cb)(void *aux), > void (*cancel_cb)(void *aux), > { > fatal_signal_init(); > > +xpthread_mutex_lock(&mutex); > ovs_assert(n_hooks < MAX_HOOKS); > hooks[n_hooks].hook_cb = hook_cb; > hooks[n_hooks].cancel_cb = cancel_cb; > hooks[n_hooks].aux = aux; > hooks[n_hooks].run_at_exit = run_at_exit; > n_hooks++; > +xpthread_mutex_unlock(&mutex); > } > > /* Handles fatal signal number 'sig_nr'. > @@ -152,6 +167,8 @@ fatal_signal_run(void) > if (sig_nr != SIG_ATOMIC_MAX) { > char namebuf[SIGNAL_NAME_BUFSIZE]; > > +xpthread_mutex_lock(&mutex); > + > VLOG_WARN("terminating with signal %d (%s)", >(int)sig_nr, signal_name(sig_nr, namebuf, sizeof > namebuf)); > call_hooks(sig_nr); > @@ -160,6 +177,9 @@ fatal_signal_run(void) > * termination status reflects that we were killed by this signal > */ > signal(sig_nr, SIG_DFL); > raise(sig_nr); > + > +xpthread_mutex_unlock(&mutex); > +NOT_REACHED(); > } > } > > @@ -210,12 +230,16 @@ static void do_unlink_files(void); > void > fatal_signal_add_file_to_unlink(const char *file) > { > +fatal_signal_init(); > + > +xpthread_mutex_lock(&mutex); > if (!added_hook) { > added_hook = true; > fatal_signal_add_hook(unlink_files, cancel_files, NULL, true); > } > > sset_add(&files, file); > +xpthread_mutex_unlock(&mutex); > } > > /* Unregisters 'file' from being unlinked when the program terminates via > @@ -223,7 +247,11 @@ fatal_signal_add_file_to_unlink(const char *file) > void > fatal_signal_remove_file_to_unlink(const char *file) > { > +fatal_signal_init(); > + > +xpthread_mutex_lock(&mutex); > sset_find_and_delete(&files, file); > +xpthread_mutex_unlock(&mutex); > } > > /* Like fatal_signal_remove_file_to_unlink(), but also unlinks 'file'. > @@ -231,13 +259,21 @@ fatal_signal_remove_file_to_unlink(const char *file) > int > fatal_sign
[ovs-dev] [PATCH] ovs-ofctl: Add "ofp-parse" command for printing OpenFlow from a file.
Signed-off-by: Ben Pfaff length); +if (length < sizeof *oh) { +ovs_fatal(0, "%s: %zu-byte message is too short for OpenFlow", + filename, length); +} + +tail_len = length - sizeof *oh; +tail = ofpbuf_put_uninit(&b, tail_len); +n = fread(tail, 1, tail_len, file); +if (n < tail_len) { +ovs_fatal(0, "%s: unexpected end of file mid-message", filename); +} + +ofp_print(stdout, b.data, b.size, verbosity + 2); +} +ofpbuf_uninit(&b); + +if (file != stdin) { +fclose(file); +} +} + +static void ofctl_ping(int argc, char *argv[]) { size_t max_payload = 65535 - sizeof(struct ofp_header); @@ -2932,6 +2984,7 @@ static const struct command all_commands[] = { { "mod-port", 3, 3, ofctl_mod_port }, { "get-frags", 1, 1, ofctl_get_frags }, { "set-frags", 2, 2, ofctl_set_frags }, +{ "ofp-parse", 1, 1, ofctl_ofp_parse }, { "probe", 1, 1, ofctl_probe }, { "ping", 1, 2, ofctl_ping }, { "benchmark", 3, 3, ofctl_benchmark }, -- 1.7.2.5 ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH] vlan-splinter: Fix a bug.
On Mon, Jul 22, 2013 at 06:15:49PM -0700, Alex Wang wrote: > When "other-config:enable-vlan-splinters=true" is set, the existing > vlans with ip address must be retained. The bug actually does the > opposite and retains the vlans without ip address. This commit fixes > it. > > Reported-by: Roman Sokolkov > Signed-off-by: Alex Wang Thanks a lot, applied! ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [threads 23/23] vlog: Mark vlog_module_ptr_* as const.
On Tue, Jul 23, 2013 at 08:07:55AM -0700, Alex Wang wrote: > Want to ask, the "section" attribute specifies that the pointer is placed > in "vlog_modules"" section. And this section is automatically created by > compiler, right? Yes. ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH 1/5] ovs-bugtool: Remove duplicate bond/show command.
On Mon, Jul 22, 2013 at 12:17:05PM -0700, Gurucharan Shetty wrote: > ovs-appctl bond/show is being run through the plugin by > calling the script ovs-bugtool-bond-show. > > So remove the redundant code. > > Signed-off-by: Gurucharan Shetty Acked-by: Ben Pfaff ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH 2/5] ovs-bugtool: Separate capability for general network info.
On Mon, Jul 22, 2013 at 12:17:06PM -0700, Gurucharan Shetty wrote: > Current situation is that CAP_NETWORK_STATUS has a max size of 50 MB. > When we have around 100,000 openflow flows, we over-run that size > by just running the "ovs-ofctl dump-flows" command. All the openvswitch > commands run through the plugin scripts in this repo won't have its > data stored in the debug bundle in this case as they are part of > CAP_NETWORK_STATUS too. One option to correct this is to increase > the CAP_NETWORK_STATUS max size to a higher number. But CAP_NETWORK_STATUS > also includes a bunch of general network related information collected > by running commands like ethtool, tc etc. and we probably want to limit > the data collected through those commands. > > With this commit, we create a new capability called CAP_NETWORK_INFO > and collect general network related information through them. For OVS > related information, we continue to use CAP_NETWORK_STATUS, but remove > the maximum size restriction. One rationale to keep OVS related > information in CAP_NETWORK_STATUS is because xen-bugtool probably expects > OVS information in that capability. > > Signed-off-by: Gurucharan Shetty The split seems reasonable. But I am not sure that the names are good, because I'm not sure I know the difference between "info" and "status". Did you try to think of more descriptive names? ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [threads 23/23] vlog: Mark vlog_module_ptr_* as const.
Thanks, patches 21/23-23/23 all looks good to me, On Tue, Jul 23, 2013 at 11:24 AM, Ben Pfaff wrote: > On Tue, Jul 23, 2013 at 08:07:55AM -0700, Alex Wang wrote: > > Want to ask, the "section" attribute specifies that the pointer is placed > > in "vlog_modules"" section. And this section is automatically created by > > compiler, right? > > Yes. > ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [threads 20/23] netdev-vport: Make pid checking in set_tunnel_config() thread-safe
patch 11-20, acked-by: Andy Zhou On Thu, Jul 18, 2013 at 4:15 PM, Ben Pfaff wrote: > Signed-off-by: Ben Pfaff > --- > lib/netdev-vport.c |4 > 1 files changed, 4 insertions(+), 0 deletions(-) > > diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c > index 885bf5e..4214b38 100644 > --- a/lib/netdev-vport.c > +++ b/lib/netdev-vport.c > @@ -413,13 +413,17 @@ set_tunnel_config(struct netdev *dev_, const struct > smap *args) > } > > if (tnl_cfg.ipsec) { > +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; > static pid_t pid = 0; > + > +pthread_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); > } > +pthread_mutex_unlock(&mutex); > > if (pid < 0) { > VLOG_ERR("%s: IPsec requires the ovs-monitor-ipsec daemon", > -- > 1.7.2.5 > > ___ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev > ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH 3/5] ovs-bugtool: Compact the database before collecting.
On Mon, Jul 22, 2013 at 12:17:07PM -0700, Gurucharan Shetty wrote: > Currently the openvswitch database is being collected with > CAP_NETWORK_CONFIG which has a max size of 50 KB. This is > quite low as the database can easily be larger than 50 KB. > > Move database collection to CAP_NETWORK_STATUS which does > not have a max size. Also, compact the database before picking > it up. > > Signed-off-by: Gurucharan Shetty Compacting the database loses tons of information that I often find valuable. I would prefer to compact it only if it's too big to practically include the full version. Also, I think that it would be better to compact only a copy of the database, instead of the version actually in use. ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH 4/5] ovs-bugtool: Add config files to the debug bundle.
On Mon, Jul 22, 2013 at 12:17:08PM -0700, Gurucharan Shetty wrote: > The previously defined config files were never included in > the debug bundle. This will include them. > > Also increase the max size for CAP_NETWORK_CONFIG to 5 MB. > A pre-compressed size of 5 MB does not amount to much after > compression for config files. Aren't these files about 1 kB each though? Acked-by: Ben Pfaff ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH 5/5] ovs-bugtool: Increase max size of CAP_HARDWARE_INFO.
On Mon, Jul 22, 2013 at 12:17:09PM -0700, Gurucharan Shetty wrote: > Current size feels very low when we are collecting o/p of > 'dmidecode' and 'lspci -vv' > > Signed-off-by: Gurucharan Shetty Acked-by: Ben Pfaff ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH 2/5] ovs-bugtool: Separate capability for general network info.
On Tue, Jul 23, 2013 at 11:27 AM, Ben Pfaff wrote: > On Mon, Jul 22, 2013 at 12:17:06PM -0700, Gurucharan Shetty wrote: > > Current situation is that CAP_NETWORK_STATUS has a max size of 50 MB. > > When we have around 100,000 openflow flows, we over-run that size > > by just running the "ovs-ofctl dump-flows" command. All the openvswitch > > commands run through the plugin scripts in this repo won't have its > > data stored in the debug bundle in this case as they are part of > > CAP_NETWORK_STATUS too. One option to correct this is to increase > > the CAP_NETWORK_STATUS max size to a higher number. But > CAP_NETWORK_STATUS > > also includes a bunch of general network related information collected > > by running commands like ethtool, tc etc. and we probably want to limit > > the data collected through those commands. > > > > With this commit, we create a new capability called CAP_NETWORK_INFO > > and collect general network related information through them. For OVS > > related information, we continue to use CAP_NETWORK_STATUS, but remove > > the maximum size restriction. One rationale to keep OVS related > > information in CAP_NETWORK_STATUS is because xen-bugtool probably expects > > OVS information in that capability. > > > > Signed-off-by: Gurucharan Shetty > > The split seems reasonable. But I am not sure that the names are > good, because I'm not sure I know the difference between "info" and > "status". Did you try to think of more descriptive names? > I wanted to keep the openvswitch related commands in a new capability called CAP_OPENVSWITCH_STATUS. But as of now, most of the openvswitch commands are run through plugins and we keep it in a directory called "network-status" and that relates to CAP_NETWORK_STATUS. I could have just renamed the plugin directory to"openvswitch-status" and added a xml file to define the capability. But when xen-bugtool is run it will now have all the openvswitch related information in this new capability that is probably unknown for xenserver users. So to keep that compatibility, I let them remain in CAP_NETWORK_STATUS. For the new CAP_NETWORK_INFO, I thought about CAP_LINUXNET_INFO, but some of these utilities are probably there in other platforms too. But I agree that a new name here can probably be more descriptive. If you have any suggestions, I will use them. Thanks, Guru ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [threads 20/23] netdev-vport: Make pid checking in set_tunnel_config() thread-safe
Thanks, I applied all of these. On Tue, Jul 23, 2013 at 11:28:58AM -0700, Andy Zhou wrote: > patch 11-20, > acked-by: Andy Zhou > > > > On Thu, Jul 18, 2013 at 4:15 PM, Ben Pfaff wrote: > > > Signed-off-by: Ben Pfaff > > --- > > lib/netdev-vport.c |4 > > 1 files changed, 4 insertions(+), 0 deletions(-) > > > > diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c > > index 885bf5e..4214b38 100644 > > --- a/lib/netdev-vport.c > > +++ b/lib/netdev-vport.c > > @@ -413,13 +413,17 @@ set_tunnel_config(struct netdev *dev_, const struct > > smap *args) > > } > > > > if (tnl_cfg.ipsec) { > > +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; > > static pid_t pid = 0; > > + > > +pthread_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); > > } > > +pthread_mutex_unlock(&mutex); > > > > if (pid < 0) { > > VLOG_ERR("%s: IPsec requires the ovs-monitor-ipsec daemon", > > -- > > 1.7.2.5 > > > > ___ > > dev mailing list > > dev@openvswitch.org > > http://openvswitch.org/mailman/listinfo/dev > > ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [threads 23/23] vlog: Mark vlog_module_ptr_* as const.
Thanks, I applied all of these. On Tue, Jul 23, 2013 at 11:28:12AM -0700, Alex Wang wrote: > Thanks, > > patches 21/23-23/23 all looks good to me, > > > On Tue, Jul 23, 2013 at 11:24 AM, Ben Pfaff wrote: > > > On Tue, Jul 23, 2013 at 08:07:55AM -0700, Alex Wang wrote: > > > Want to ask, the "section" attribute specifies that the pointer is placed > > > in "vlog_modules"" section. And this section is automatically created by > > > compiler, right? > > > > Yes. > > ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH 4/5] ovs-bugtool: Add config files to the debug bundle.
On Tue, Jul 23, 2013 at 11:33 AM, Ben Pfaff wrote: > On Mon, Jul 22, 2013 at 12:17:08PM -0700, Gurucharan Shetty wrote: > > The previously defined config files were never included in > > the debug bundle. This will include them. > > > > Also increase the max size for CAP_NETWORK_CONFIG to 5 MB. > > A pre-compressed size of 5 MB does not amount to much after > > compression for config files. > > Aren't these files about 1 kB each though? > True. I mainly increased it for a hypothetical situation of lots of sysconfig network scripts. It is probably never going to reach anywhere close to 5 MB. > > Acked-by: Ben Pfaff > ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH V2 3/3] clang: Fix the alignment warning.
On Mon, Jul 22, 2013 at 03:47:19PM -0700, Alex Wang wrote: > This commit fixes the warning issued by 'clang' when pointer is casted > to one with greater alignment. > > Signed-off-by: Alex Wang Thanks, I applied this. I noticed one place with an unnecessary cast, so I folded this in: diff --git a/lib/netlink.c b/lib/netlink.c index 9ed925b..50444ab 100644 --- a/lib/netlink.c +++ b/lib/netlink.c @@ -711,8 +711,7 @@ nl_policy_parse(const struct ofpbuf *msg, size_t nla_offset, return false; } -NL_ATTR_FOR_EACH (nla, left, - (struct nlattr *) ofpbuf_at(msg, nla_offset, 0), +NL_ATTR_FOR_EACH (nla, left, ofpbuf_at(msg, nla_offset, 0), msg->size - nla_offset) { uint16_t type = nl_attr_type(nla); ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH] ofproto-dpif-xlate: Fix invalid memory read on port removal.
On Mon, Jul 22, 2013 at 12:55:56PM -0700, Ethan Jackson wrote: > Signed-off-by: Ethan Jackson Acked-by: Ben Pfaff ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH V2 3/3] clang: Fix the alignment warning.
Thanks Ben, On Tue, Jul 23, 2013 at 12:34 PM, Ben Pfaff wrote: > On Mon, Jul 22, 2013 at 03:47:19PM -0700, Alex Wang wrote: > > This commit fixes the warning issued by 'clang' when pointer is casted > > to one with greater alignment. > > > > Signed-off-by: Alex Wang > > Thanks, I applied this. > > I noticed one place with an unnecessary cast, so I folded this in: > > diff --git a/lib/netlink.c b/lib/netlink.c > index 9ed925b..50444ab 100644 > --- a/lib/netlink.c > +++ b/lib/netlink.c > @@ -711,8 +711,7 @@ nl_policy_parse(const struct ofpbuf *msg, size_t > nla_offset, > return false; > } > > -NL_ATTR_FOR_EACH (nla, left, > - (struct nlattr *) ofpbuf_at(msg, nla_offset, 0), > +NL_ATTR_FOR_EACH (nla, left, ofpbuf_at(msg, nla_offset, 0), >msg->size - nla_offset) > { > uint16_t type = nl_attr_type(nla); > ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH 2/5] ovs-bugtool: Separate capability for general network info.
On Tue, Jul 23, 2013 at 11:39:38AM -0700, Gurucharan Shetty wrote: > On Tue, Jul 23, 2013 at 11:27 AM, Ben Pfaff wrote: > > > On Mon, Jul 22, 2013 at 12:17:06PM -0700, Gurucharan Shetty wrote: > > > Current situation is that CAP_NETWORK_STATUS has a max size of 50 MB. > > > When we have around 100,000 openflow flows, we over-run that size > > > by just running the "ovs-ofctl dump-flows" command. All the openvswitch > > > commands run through the plugin scripts in this repo won't have its > > > data stored in the debug bundle in this case as they are part of > > > CAP_NETWORK_STATUS too. One option to correct this is to increase > > > the CAP_NETWORK_STATUS max size to a higher number. But > > CAP_NETWORK_STATUS > > > also includes a bunch of general network related information collected > > > by running commands like ethtool, tc etc. and we probably want to limit > > > the data collected through those commands. > > > > > > With this commit, we create a new capability called CAP_NETWORK_INFO > > > and collect general network related information through them. For OVS > > > related information, we continue to use CAP_NETWORK_STATUS, but remove > > > the maximum size restriction. One rationale to keep OVS related > > > information in CAP_NETWORK_STATUS is because xen-bugtool probably expects > > > OVS information in that capability. > > > > > > Signed-off-by: Gurucharan Shetty > > > > The split seems reasonable. But I am not sure that the names are > > good, because I'm not sure I know the difference between "info" and > > "status". Did you try to think of more descriptive names? > > > > I wanted to keep the openvswitch related commands in a new capability > called CAP_OPENVSWITCH_STATUS. But as of now, most of the > openvswitch commands are run through plugins and we keep it in a > directory called "network-status" and that relates to CAP_NETWORK_STATUS. > I could have just renamed the plugin directory to"openvswitch-status" and > added > a xml file to define the capability. But when xen-bugtool is run it will > now have > all the openvswitch related information in this new capability that is > probably unknown > for xenserver users. So to keep that compatibility, I let them remain in > CAP_NETWORK_STATUS. > > For the new CAP_NETWORK_INFO, I thought about CAP_LINUXNET_INFO, but > some of these utilities are probably there in other platforms too. But I > agree that > a new name here can probably be more descriptive. If you have any > suggestions, > I will use them. I'm glad you thought it over. Thanks. I don't have a great name either. Acked-by: Ben Pfaff ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH 4/5] ovs-bugtool: Add config files to the debug bundle.
On Tue, Jul 23, 2013 at 12:29:40PM -0700, Gurucharan Shetty wrote: > On Tue, Jul 23, 2013 at 11:33 AM, Ben Pfaff wrote: > > > On Mon, Jul 22, 2013 at 12:17:08PM -0700, Gurucharan Shetty wrote: > > > The previously defined config files were never included in > > > the debug bundle. This will include them. > > > > > > Also increase the max size for CAP_NETWORK_CONFIG to 5 MB. > > > A pre-compressed size of 5 MB does not amount to much after > > > compression for config files. > > > > Aren't these files about 1 kB each though? > > > True. I mainly increased it for a hypothetical situation of lots of > sysconfig network scripts. > It is probably never going to reach anywhere close to 5 MB. OK. I guess I don't care either way, if you think it makes sense to increase the size then please do. Acked-by: Ben Pfaff ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH 3/5] ovs-bugtool: Compact the database before collecting.
> > Compacting the database loses tons of information that I often find > valuable. +1 ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
[ovs-dev] [PATCH 1/2] Prepare for 1.12.0.
Signed-off-by: Justin Pettit --- NEWS |4 ++-- configure.ac |2 +- debian/changelog | 31 --- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index b46fc43..f422bf8 100644 --- a/NEWS +++ b/NEWS @@ -1,11 +1,11 @@ -post-v1.11.0 +v1.12.0 - xx xxx - - OpenFlow: * Experimental support for OpenFlow 1.1 (in addition to 1.2 and 1.3, which had experimental support in 1.10). * New support for matching outer source and destination IP address of tunneled packets, for tunnel ports configured with the newly - added "remote_ip=flow" and "local_ip=flow" options. +added "remote_ip=flow" and "local_ip=flow" options. - The Interface table in the database has a new "ifindex" column to report the interface's OS-assigned ifindex. - New "check-oftest" Makefile target for running OFTest against Open diff --git a/configure.ac b/configure.ac index 170a852..1e1d24f 100644 --- a/configure.ac +++ b/configure.ac @@ -13,7 +13,7 @@ # limitations under the License. AC_PREREQ(2.64) -AC_INIT(openvswitch, 1.11.90, ovs-b...@openvswitch.org) +AC_INIT(openvswitch, 1.12.0, ovs-b...@openvswitch.org) AC_CONFIG_SRCDIR([datapath/datapath.c]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_AUX_DIR([build-aux]) diff --git a/debian/changelog b/debian/changelog index f601020..d4c7154 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,13 +1,31 @@ -openvswitch (1.11.90-1) unstable; urgency=low +openvswitch (1.12.0-1) unstable; urgency=low [ Open vSwitch team ] * New upstream version - - Nothing yet! Try NEWS... - - -- Open vSwitch team Mon, 29 Apr 2013 14:30:34 -0700 +- OpenFlow: + * Experimental support for OpenFlow 1.1 (in addition to 1.2 and +1.3, which had experimental support in 1.10). + * New support for matching outer source and destination IP address +of tunneled packets, for tunnel ports configured with the newly +added "remote_ip=flow" and "local_ip=flow" options. +- The Interface table in the database has a new "ifindex" column to + report the interface's OS-assigned ifindex. +- New "check-oftest" Makefile target for running OFTest against Open + vSwitch. See README-OFTest for details. +- The flow eviction threshold has been moved to the Open_vSwitch table. +- Database names are now mandatory when specifying ovsdb-server options + through database paths (e.g. Private key option with the database name + should look like "--private-key=db:Open_vSwitch,SSL,private_key"). +- Added ovs-dev.py, a utility script helpful for Open vSwitch developers. + + -- Open vSwitch team Tue, 03 Jul 2013 15:02:34 -0700 openvswitch (1.11.0-1) unstable; urgency=low [ Open vSwitch team ] * New upstream version +- Support for megaflows, which allows wildcarding in the kernel (and + any dpif implementation that supports wildcards). Depending on + the flow table and switch configuration, flow set up rates are + close to the Linux bridge. - The "tutorial" directory contains a new tutorial for some advanced Open vSwitch features. - Stable bond mode has been removed. @@ -20,13 +38,20 @@ openvswitch (1.11.0-1) unstable; urgency=low 1.1 and later are now implemented. * New "stack" extension for use in actions, to push and pop from NXM fields. + * The "load" and "set_field" actions can now modify the "in_port". (This +allows one to enable output to a flow's input port by setting the +in_port to some unused value, such as OFPP_NONE.) - ovs-dpctl: * New debugging commands "add-flow", "mod-flow", "del-flow". +- In dpif-based bridges, cache action translations, which can improve + flow set up performance by 80% with a complicated flow table. - New syslog format, prefixed with "ovs|", to be easier to filter. - RHEL: Removes the default firewall rule that allowed GRE traffic to pass through. Any users that relied on this automatic firewall hole will have to manually configure it. The ovs-ctl(8) manpage documents the "enable-protocol" command that can be used as an alternative. +- New CFM demand mode which uses data traffic to indicate interface + liveness. -- Open vSwitch team Mon, 29 Apr 2013 14:30:34 -0700 -- 1.7.5.4 ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
[ovs-dev] [PATCH 2/2] Prepare for post-1.12.0 (1.12.90).
Signed-off-by: Justin Pettit --- NEWS |4 configure.ac |2 +- debian/changelog |7 +++ 3 files changed, 12 insertions(+), 1 deletions(-) diff --git a/NEWS b/NEWS index f422bf8..3bf4421 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +post-v1.12.0 +- + + v1.12.0 - xx xxx - - OpenFlow: diff --git a/configure.ac b/configure.ac index 1e1d24f..ac847bd 100644 --- a/configure.ac +++ b/configure.ac @@ -13,7 +13,7 @@ # limitations under the License. AC_PREREQ(2.64) -AC_INIT(openvswitch, 1.12.0, ovs-b...@openvswitch.org) +AC_INIT(openvswitch, 1.12.90, ovs-b...@openvswitch.org) AC_CONFIG_SRCDIR([datapath/datapath.c]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_AUX_DIR([build-aux]) diff --git a/debian/changelog b/debian/changelog index d4c7154..09b97f8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +openvswitch (1.12.90-1) unstable; urgency=low + [ Open vSwitch team ] + * New upstream version +- Nothing yet! Try NEWS... + + -- Open vSwitch team Tue, 03 Jul 2013 15:05:34 -0700 + openvswitch (1.12.0-1) unstable; urgency=low [ Open vSwitch team ] * New upstream version -- 1.7.5.4 ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH 2/2] Prepare for post-1.12.0 (1.12.90).
On Tue, Jul 23, 2013 at 03:07:03PM -0700, Justin Pettit wrote: > Signed-off-by: Justin Pettit On both: Acked-by: Ben Pfaff ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
[ovs-dev] [PATCH] clang: Use -Wthread-safety warning flag.
The '-Wthread-safety' warning flag of 'clang' compiler can be useful to the compilation of multi-threading code. This commit enables this flag whenever 'CC=clang'. Signed-off-by: Alex Wang --- configure.ac |1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 170a852..d147e25 100644 --- a/configure.ac +++ b/configure.ac @@ -103,6 +103,7 @@ OVS_ENABLE_OPTION([-Wstrict-prototypes]) OVS_ENABLE_OPTION([-Wold-style-definition]) OVS_ENABLE_OPTION([-Wmissing-prototypes]) OVS_ENABLE_OPTION([-Wmissing-field-initializers]) +OVS_ENABLE_OPTION([-Wthread-safety]) OVS_CONDITIONAL_CC_OPTION([-Wno-unused], [HAVE_WNO_UNUSED]) OVS_CONDITIONAL_CC_OPTION([-Wno-unused-parameter], [HAVE_WNO_UNUSED_PARAMETER]) OVS_ENABLE_WERROR -- 1.7.9.5 ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
[ovs-dev] [PATCH 3/5 v2] ovs-bugtool: Collect database through CAP_NETWORK_STATUS.
Currently the openvswitch database is being collected with CAP_NETWORK_CONFIG which has a max size of 50 KB. This is quite low as the database can easily be larger than 50 KB. Move database collection to CAP_NETWORK_STATUS which does not have a max size. If database size exceeds 10 MB, create a compacted version of it and then collect it. Signed-off-by: Gurucharan Shetty --- utilities/bugtool/ovs-bugtool.in | 36 +++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/utilities/bugtool/ovs-bugtool.in b/utilities/bugtool/ovs-bugtool.in index 854dfa1..d53d6c6 100755 --- a/utilities/bugtool/ovs-bugtool.in +++ b/utilities/bugtool/ovs-bugtool.in @@ -113,6 +113,7 @@ OPENVSWITCH_DEFAULT_SWITCH = '/etc/default/openvswitch-switch' # Debian OPENVSWITCH_SYSCONFIG_SWITCH = '/etc/sysconfig/openvswitch'# RHEL OPENVSWITCH_DEFAULT_CONTROLLER = '/etc/default/openvswitch-controller' OPENVSWITCH_CONF_DB = '@DBDIR@/conf.db' +OPENVSWITCH_COMPACT_DB = '@DBDIR@/bugtool-compact-conf.db' OPENVSWITCH_VSWITCHD_PID = '@RUNDIR@/ovs-vswitchd.pid' VAR_LOG_DIR = '/var/log/' VAR_LOG_CORE_DIR = '/var/log/core' @@ -543,7 +544,6 @@ exclude those logs from the archive. tree_output(CAP_NETWORK_CONFIG, SYSCONFIG_NETWORK_SCRIPTS, ROUTE_RE) file_output(CAP_NETWORK_CONFIG, [SYSCONFIG_NETWORK, RESOLV_CONF, NSSWITCH_CONF, HOSTS]) file_output(CAP_NETWORK_CONFIG, [NTP_CONF, IPTABLES_CONFIG, HOSTS_ALLOW, HOSTS_DENY]) -file_output(CAP_NETWORK_CONFIG, [OPENVSWITCH_CONF_DB]) cmd_output(CAP_NETWORK_INFO, [IFCONFIG, '-a']) cmd_output(CAP_NETWORK_INFO, [ROUTE, '-n']) @@ -575,6 +575,8 @@ exclude those logs from the archive. tree_output(CAP_NETWORK_INFO, PROC_NET_VLAN_DIR) cmd_output(CAP_NETWORK_INFO, [TC, '-s', 'qdisc']) file_output(CAP_NETWORK_INFO, [PROC_NET_SOFTNET_STAT]) + +collect_ovsdb() if os.path.exists(OPENVSWITCH_VSWITCHD_PID): cmd_output(CAP_NETWORK_STATUS, [OVS_DPCTL, 'show', '-s']) for d in dp_list(): @@ -679,6 +681,8 @@ exclude those logs from the archive. for c in caps.keys(): print >>sys.stderr, "%s (%d, %d)" % (c, caps[c][MAX_SIZE], cap_sizes[c]) + +cleanup_ovsdb() return 0 def dump_scsi_hosts(cap): @@ -739,6 +743,36 @@ def dp_list(): return output.getvalue().splitlines() return [] +def collect_ovsdb(): +if not os.path.isfile(OPENVSWITCH_CONF_DB): +return + +max_size = 10*MB + +try: +if os.path.getsize(OPENVSWITCH_CONF_DB) > max_size: +if os.path.isfile(OPENVSWITCH_COMPACT_DB): +os.unlink(OPENVSWITCH_COMPACT_DB) + +output = StringIO.StringIO() +max_time = 5 +procs = [ProcOutput(['ovsdb-tool', 'compact', +OPENVSWITCH_CONF_DB, OPENVSWITCH_COMPACT_DB], +max_time, output)] +run_procs([procs]) +file_output(CAP_NETWORK_STATUS, [OPENVSWITCH_COMPACT_DB]) +else: +file_output(CAP_NETWORK_STATUS, [OPENVSWITCH_CONF_DB]) +except OSError, e: +return + +def cleanup_ovsdb(): +try: +if os.path.isfile(OPENVSWITCH_COMPACT_DB): +os.unlink(OPENVSWITCH_COMPACT_DB) +except: +return + def fd_usage(cap): output = '' fd_dict = {} -- 1.7.9.5 ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH 3/5] ovs-bugtool: Compact the database before collecting.
On Tue, Jul 23, 2013 at 11:31 AM, Ben Pfaff wrote: > On Mon, Jul 22, 2013 at 12:17:07PM -0700, Gurucharan Shetty wrote: > > Currently the openvswitch database is being collected with > > CAP_NETWORK_CONFIG which has a max size of 50 KB. This is > > quite low as the database can easily be larger than 50 KB. > > > > Move database collection to CAP_NETWORK_STATUS which does > > not have a max size. Also, compact the database before picking > > it up. > > > > Signed-off-by: Gurucharan Shetty > > Compacting the database loses tons of information that I often find > valuable. I would prefer to compact it only if it's too big to > practically include the full version. Also, I think that it would be > better to compact only a copy of the database, instead of the version > actually in use. > Okay. I will sent a V2. ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH 2/2] Prepare for post-1.12.0 (1.12.90).
On Jul 23, 2013, at 3:08 PM, Ben Pfaff wrote: > On Tue, Jul 23, 2013 at 03:07:03PM -0700, Justin Pettit wrote: >> Signed-off-by: Justin Pettit > > On both: > Acked-by: Ben Pfaff Thanks. I pushed the changes and created branch "branch-1.12". --Justin ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
[ovs-dev] [dpif 0/5] make dpif library thread-safe
This series makes the dpif library thread-safe. I have not checked yet whether the netdev library, which is not yet thread-safe, screws up this property of the dpif changes yet. Ben Pfaff (5): ovs-thread: Add wrappers for "destroy" functions too. dpif-linux: Make port change notification thread-safe. dpif-linux: Make use of channels thread-safe. dpif-netdev: Make internally thread-safe by introducing a global mutex. dpif: Make dpifs thread-safe, and document it. lib/dpif-linux.c | 277 + lib/dpif-netdev.c | 203 +-- lib/dpif.c| 108 - lib/ovs-thread.c |3 + lib/ovs-thread.h |3 + 5 files changed, 410 insertions(+), 184 deletions(-) -- 1.7.2.5 ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
[ovs-dev] [dpif 1/5] ovs-thread: Add wrappers for "destroy" functions too.
Signed-off-by: Ben Pfaff --- lib/ovs-thread.c |3 +++ lib/ovs-thread.h |3 +++ 2 files changed, 6 insertions(+), 0 deletions(-) diff --git a/lib/ovs-thread.c b/lib/ovs-thread.c index 4776587..91bb3d9 100644 --- a/lib/ovs-thread.c +++ b/lib/ovs-thread.c @@ -73,6 +73,7 @@ static bool multithreaded; } XPTHREAD_FUNC2(pthread_mutex_init, pthread_mutex_t *, pthread_mutexattr_t *); +XPTHREAD_FUNC1(pthread_mutex_destroy, pthread_mutex_t *); XPTHREAD_FUNC1(pthread_mutex_lock, pthread_mutex_t *); XPTHREAD_FUNC1(pthread_mutex_unlock, pthread_mutex_t *); XPTHREAD_TRY_FUNC1(pthread_mutex_trylock, pthread_mutex_t *); @@ -84,6 +85,7 @@ XPTHREAD_FUNC2(pthread_mutexattr_gettype, pthread_mutexattr_t *, int *); XPTHREAD_FUNC2(pthread_rwlock_init, pthread_rwlock_t *, pthread_rwlockattr_t *); +XPTHREAD_FUNC1(pthread_rwlock_destroy, pthread_rwlock_t *); XPTHREAD_FUNC1(pthread_rwlock_rdlock, pthread_rwlock_t *); XPTHREAD_FUNC1(pthread_rwlock_wrlock, pthread_rwlock_t *); XPTHREAD_FUNC1(pthread_rwlock_unlock, pthread_rwlock_t *); @@ -91,6 +93,7 @@ XPTHREAD_TRY_FUNC1(pthread_rwlock_tryrdlock, pthread_rwlock_t *); XPTHREAD_TRY_FUNC1(pthread_rwlock_trywrlock, pthread_rwlock_t *); XPTHREAD_FUNC2(pthread_cond_init, pthread_cond_t *, pthread_condattr_t *); +XPTHREAD_FUNC1(pthread_cond_destroy, pthread_cond_t *); XPTHREAD_FUNC1(pthread_cond_signal, pthread_cond_t *); XPTHREAD_FUNC1(pthread_cond_broadcast, pthread_cond_t *); XPTHREAD_FUNC2(pthread_cond_wait, pthread_cond_t *, pthread_mutex_t *); diff --git a/lib/ovs-thread.h b/lib/ovs-thread.h index b18447d..29a8637 100644 --- a/lib/ovs-thread.h +++ b/lib/ovs-thread.h @@ -58,6 +58,7 @@ * abort on any other error. */ void xpthread_mutex_init(pthread_mutex_t *, pthread_mutexattr_t *); +void xpthread_mutex_destroy(pthread_mutex_t *); void xpthread_mutex_lock(pthread_mutex_t *mutex) OVS_ACQUIRES(mutex); void xpthread_mutex_unlock(pthread_mutex_t *mutex) OVS_RELEASES(mutex); int xpthread_mutex_trylock(pthread_mutex_t *); @@ -68,6 +69,7 @@ void xpthread_mutexattr_settype(pthread_mutexattr_t *, int type); void xpthread_mutexattr_gettype(pthread_mutexattr_t *, int *typep); void xpthread_rwlock_init(pthread_rwlock_t *, pthread_rwlockattr_t *); +void xpthread_rwlock_destroy(pthread_rwlock_t *); void xpthread_rwlock_rdlock(pthread_rwlock_t *rwlock) OVS_ACQUIRES(rwlock); void xpthread_rwlock_wrlock(pthread_rwlock_t *rwlock) OVS_ACQUIRES(rwlock); void xpthread_rwlock_unlock(pthread_rwlock_t *rwlock) OVS_RELEASES(rwlock); @@ -75,6 +77,7 @@ int xpthread_rwlock_tryrdlock(pthread_rwlock_t *); int xpthread_rwlock_trywrlock(pthread_rwlock_t *); void xpthread_cond_init(pthread_cond_t *, pthread_condattr_t *); +void xpthread_cond_destroy(pthread_cond_t *); void xpthread_cond_signal(pthread_cond_t *); void xpthread_cond_broadcast(pthread_cond_t *); void xpthread_cond_wait(pthread_cond_t *, pthread_mutex_t *mutex) -- 1.7.2.5 ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
[ovs-dev] [dpif 2/5] dpif-linux: Make port change notification thread-safe.
Signed-off-by: Ben Pfaff --- lib/dpif-linux.c | 154 ++--- 1 files changed, 76 insertions(+), 78 deletions(-) diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c index c972197..3935eff 100644 --- a/lib/dpif-linux.c +++ b/lib/dpif-linux.c @@ -148,26 +148,26 @@ struct dpif_linux { int event_offset; /* Offset into 'epoll_events'. */ /* Change notification. */ -struct sset changed_ports; /* Ports that have changed. */ -struct nln_notifier *port_notifier; -bool change_error; +struct nl_sock *port_notifier; /* vport multicast group subscriber. */ }; static struct vlog_rate_limit error_rl = VLOG_RATE_LIMIT_INIT(, 5); -/* Generic Netlink family numbers for OVS. */ +/* Generic Netlink family numbers for OVS. + * + * Initialized by dpif_linux_init(). */ static int ovs_datapath_family; static int ovs_vport_family; static int ovs_flow_family; static int ovs_packet_family; -/* Generic Netlink socket. */ -static struct nln *nln = NULL; +/* Generic Netlink multicast groups for OVS. + * + * Initialized by dpif_linux_init(). */ +static unsigned int ovs_vport_mcgroup; static int dpif_linux_init(void); -static void open_dpif(const struct dpif_linux_dp *, struct dpif **); -static bool dpif_linux_nln_parse(struct ofpbuf *, void *); -static void dpif_linux_port_changed(const void *vport, void *dpif); +static int open_dpif(const struct dpif_linux_dp *, struct dpif **); static uint32_t dpif_linux_port_get_pid(const struct dpif *, odp_port_t port_no); @@ -235,27 +235,27 @@ dpif_linux_open(const struct dpif_class *class OVS_UNUSED, const char *name, return error; } -open_dpif(&dp, dpifp); +error = open_dpif(&dp, dpifp); ofpbuf_delete(buf); -return 0; +return error; } -static void +static int open_dpif(const struct dpif_linux_dp *dp, struct dpif **dpifp) { struct dpif_linux *dpif; dpif = xzalloc(sizeof *dpif); -dpif->port_notifier = nln_notifier_create(nln, dpif_linux_port_changed, - dpif); +dpif->port_notifier = NULL; dpif->epoll_fd = -1; dpif_init(&dpif->dpif, &dpif_linux_class, dp->name, dp->dp_ifindex, dp->dp_ifindex); dpif->dp_ifindex = dp->dp_ifindex; -sset_init(&dpif->changed_ports); *dpifp = &dpif->dpif; + +return 0; } static void @@ -374,9 +374,8 @@ dpif_linux_close(struct dpif *dpif_) { struct dpif_linux *dpif = dpif_linux_cast(dpif_); -nln_notifier_destroy(dpif->port_notifier); +nl_sock_destroy(dpif->port_notifier); destroy_channels(dpif); -sset_destroy(&dpif->changed_ports); free(dpif); } @@ -392,22 +391,6 @@ dpif_linux_destroy(struct dpif *dpif_) return dpif_linux_dp_transact(&dp, NULL, NULL); } -static void -dpif_linux_run(struct dpif *dpif_ OVS_UNUSED) -{ -if (nln) { -nln_run(nln); -} -} - -static void -dpif_linux_wait(struct dpif *dpif OVS_UNUSED) -{ -if (nln) { -nln_wait(nln); -} -} - static int dpif_linux_get_stats(const struct dpif *dpif_, struct dpif_dp_stats *stats) { @@ -736,15 +719,61 @@ dpif_linux_port_poll(const struct dpif *dpif_, char **devnamep) { struct dpif_linux *dpif = dpif_linux_cast(dpif_); -if (dpif->change_error) { -dpif->change_error = false; -sset_clear(&dpif->changed_ports); +/* Lazily create the Netlink socket to listen for notifications. */ +if (!dpif->port_notifier) { +struct nl_sock *sock; +int error; + +error = nl_sock_create(NETLINK_GENERIC, &sock); +if (error) { +return error; +} + +error = nl_sock_join_mcgroup(sock, ovs_vport_mcgroup); +if (error) { +nl_sock_destroy(sock); +return error; +} +dpif->port_notifier = sock; + +/* We have no idea of the current state so report that everything + * changed. */ +return ENOBUFS; +} + +for (;;) { +static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); +uint64_t buf_stub[4096 / 8]; +struct ofpbuf buf; +int error; + +ofpbuf_use_stub(&buf, buf_stub, sizeof buf_stub); +error = nl_sock_recv(dpif->port_notifier, &buf, false); +if (!error) { +struct dpif_linux_vport vport; + +error = dpif_linux_vport_from_ofpbuf(&vport, &buf); +if (!error) { +if (vport.dp_ifindex == dpif->dp_ifindex +&& (vport.cmd == OVS_VPORT_CMD_NEW +|| vport.cmd == OVS_VPORT_CMD_DEL +|| vport.cmd == OVS_VPORT_CMD_SET)) { +VLOG_DBG("port_changed: dpif:%s vport:%s cmd:%"PRIu8, + dpif->dpif.full_name, vport.name, vport.cmd); +*devnamep = xstrdup(vport.name); +return 0;
[ovs-dev] [dpif 3/5] dpif-linux: Make use of channels thread-safe.
This seems to be the last remaining thread-unsafe code in dpif-linux. Signed-off-by: Ben Pfaff --- lib/dpif-linux.c | 123 ++ 1 files changed, 96 insertions(+), 27 deletions(-) diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c index 3935eff..a6df339 100644 --- a/lib/dpif-linux.c +++ b/lib/dpif-linux.c @@ -140,6 +140,7 @@ struct dpif_linux { int dp_ifindex; /* Upcall messages. */ +pthread_mutex_t upcall_lock; int uc_array_size; /* Size of 'channels' and 'epoll_events'. */ struct dpif_channel *channels; struct epoll_event *epoll_events; @@ -247,6 +248,7 @@ open_dpif(const struct dpif_linux_dp *dp, struct dpif **dpifp) dpif = xzalloc(sizeof *dpif); dpif->port_notifier = NULL; +xpthread_mutex_init(&dpif->upcall_lock, NULL); dpif->epoll_fd = -1; dpif_init(&dpif->dpif, &dpif_linux_class, dp->name, @@ -276,6 +278,8 @@ destroy_channels(struct dpif_linux *dpif) continue; } +epoll_ctl(dpif->epoll_fd, EPOLL_CTL_DEL, nl_sock_fd(ch->sock), NULL); + /* Turn off upcalls. */ dpif_linux_vport_init(&vport_request); vport_request.cmd = OVS_VPORT_CMD_SET; @@ -295,8 +299,8 @@ destroy_channels(struct dpif_linux *dpif) dpif->epoll_events = NULL; dpif->n_events = dpif->event_offset = 0; -close(dpif->epoll_fd); -dpif->epoll_fd = -1; +/* Don't close dpif->epoll_fd since that would cause other threads that + * call dpif_recv_wait(dpif) to wait on an arbitrary fd or a closed fd. */ } static int @@ -376,6 +380,10 @@ dpif_linux_close(struct dpif *dpif_) nl_sock_destroy(dpif->port_notifier); destroy_channels(dpif); +if (dpif->epoll_fd >= 0) { +close(dpif->epoll_fd); +} +xpthread_mutex_destroy(&dpif->upcall_lock); free(dpif); } @@ -466,8 +474,8 @@ netdev_to_ovs_vport_type(const struct netdev *netdev) } static int -dpif_linux_port_add(struct dpif *dpif_, struct netdev *netdev, -odp_port_t *port_nop) +dpif_linux_port_add__(struct dpif *dpif_, struct netdev *netdev, + odp_port_t *port_nop) { struct dpif_linux *dpif = dpif_linux_cast(dpif_); const struct netdev_tunnel_config *tnl_cfg; @@ -558,7 +566,21 @@ dpif_linux_port_add(struct dpif *dpif_, struct netdev *netdev, } static int -dpif_linux_port_del(struct dpif *dpif_, odp_port_t port_no) +dpif_linux_port_add(struct dpif *dpif_, struct netdev *netdev, +odp_port_t *port_nop) +{ +struct dpif_linux *dpif = dpif_linux_cast(dpif_); +int error; + +xpthread_mutex_lock(&dpif->upcall_lock); +error = dpif_linux_port_add__(dpif_, netdev, port_nop); +xpthread_mutex_unlock(&dpif->upcall_lock); + +return error; +} + +static int +dpif_linux_port_del__(struct dpif *dpif_, odp_port_t port_no) { struct dpif_linux *dpif = dpif_linux_cast(dpif_); struct dpif_linux_vport vport; @@ -576,6 +598,19 @@ dpif_linux_port_del(struct dpif *dpif_, odp_port_t port_no) } static int +dpif_linux_port_del(struct dpif *dpif_, odp_port_t port_no) +{ +struct dpif_linux *dpif = dpif_linux_cast(dpif_); +int error; + +xpthread_mutex_lock(&dpif->upcall_lock); +error = dpif_linux_port_del__(dpif_, port_no); +xpthread_mutex_unlock(&dpif->upcall_lock); + +return error; +} + +static int dpif_linux_port_query__(const struct dpif *dpif, odp_port_t port_no, const char *port_name, struct dpif_port *dpif_port) { @@ -629,17 +664,20 @@ dpif_linux_get_max_ports(const struct dpif *dpif OVS_UNUSED) static uint32_t dpif_linux_port_get_pid(const struct dpif *dpif_, odp_port_t port_no) { -const struct dpif_linux *dpif = dpif_linux_cast(dpif_); +struct dpif_linux *dpif = dpif_linux_cast(dpif_); uint32_t port_idx = odp_to_u32(port_no); +uint32_t pid = 0; -if (dpif->epoll_fd < 0) { -return 0; -} else { +xpthread_mutex_lock(&dpif->upcall_lock); +if (dpif->epoll_fd >= 0) { /* The ODPP_NONE "reserved" port number uses the "ovs-system"'s * channel, since it is not heavily loaded. */ uint32_t idx = port_idx >= dpif->uc_array_size ? 0 : port_idx; -return nl_sock_pid(dpif->channels[idx].sock); +pid = nl_sock_pid(dpif->channels[idx].sock); } +xpthread_mutex_unlock(&dpif->upcall_lock); + +return pid; } static int @@ -1195,7 +1233,7 @@ dpif_linux_operate(struct dpif *dpif, struct dpif_op **ops, size_t n_ops) } static int -dpif_linux_recv_set(struct dpif *dpif_, bool enable) +dpif_linux_recv_set__(struct dpif *dpif_, bool enable) { struct dpif_linux *dpif = dpif_linux_cast(dpif_); @@ -1209,9 +1247,11 @@ dpif_linux_recv_set(struct dpif *dpif_, bool enable) struct dpif_port_dump port_dump; struct dpif_port port; -dpif->epoll_fd = epoll_create(10); if (dpif->epoll_fd < 0) { -retur
[ovs-dev] [dpif 5/5] dpif: Make dpifs thread-safe, and document it.
Signed-off-by: Ben Pfaff --- lib/dpif.c | 108 +-- 1 files changed, 82 insertions(+), 26 deletions(-) diff --git a/lib/dpif.c b/lib/dpif.c index 4878aac..0d8dd9d 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -70,6 +70,9 @@ struct registered_dpif_class { static struct shash dpif_classes = SHASH_INITIALIZER(&dpif_classes); static struct sset dpif_blacklist = SSET_INITIALIZER(&dpif_blacklist); +/* Protects 'dpif_classes', including the refcount, and 'dpif_blacklist'. */ +static pthread_mutex_t dpif_mutex = PTHREAD_MUTEX_INITIALIZER; + /* Rate limit for individual messages going to or from the datapath, output at * DBG level. This is very high because, if these are enabled, it is because * we really need to see them. */ @@ -109,10 +112,8 @@ dp_initialize(void) } } -/* Registers a new datapath provider. After successful registration, new - * datapaths of that type can be opened using dpif_open(). */ -int -dp_register_provider(const struct dpif_class *new_class) +static int +dp_register_provider__(const struct dpif_class *new_class) { struct registered_dpif_class *registered_class; @@ -137,11 +138,25 @@ dp_register_provider(const struct dpif_class *new_class) return 0; } +/* Registers a new datapath provider. After successful registration, new + * datapaths of that type can be opened using dpif_open(). */ +int +dp_register_provider(const struct dpif_class *new_class) +{ +int error; + +xpthread_mutex_lock(&dpif_mutex); +error = dp_register_provider__(new_class); +xpthread_mutex_unlock(&dpif_mutex); + +return error; +} + /* Unregisters a datapath provider. 'type' must have been previously * registered and not currently be in use by any dpifs. After unregistration * new datapaths of that type cannot be opened using dpif_open(). */ -int -dp_unregister_provider(const char *type) +static int +dp_unregister_provider__(const char *type) { struct shash_node *node; struct registered_dpif_class *registered_class; @@ -165,12 +180,31 @@ dp_unregister_provider(const char *type) return 0; } +/* Unregisters a datapath provider. 'type' must have been previously + * registered and not currently be in use by any dpifs. After unregistration + * new datapaths of that type cannot be opened using dpif_open(). */ +int +dp_unregister_provider(const char *type) +{ +int error; + +dp_initialize(); + +xpthread_mutex_lock(&dpif_mutex); +error = dp_unregister_provider__(type); +xpthread_mutex_unlock(&dpif_mutex); + +return error; +} + /* Blacklists a provider. Causes future calls of dp_register_provider() with * a dpif_class which implements 'type' to fail. */ void dp_blacklist_provider(const char *type) { +xpthread_mutex_lock(&dpif_mutex); sset_add(&dpif_blacklist, type); +xpthread_mutex_unlock(&dpif_mutex); } /* Clears 'types' and enumerates the types of all currently registered datapath @@ -183,10 +217,36 @@ dp_enumerate_types(struct sset *types) dp_initialize(); sset_clear(types); +xpthread_mutex_lock(&dpif_mutex); SHASH_FOR_EACH(node, &dpif_classes) { const struct registered_dpif_class *registered_class = node->data; sset_add(types, registered_class->dpif_class->type); } +xpthread_mutex_unlock(&dpif_mutex); +} + +static void +dp_class_unref(struct registered_dpif_class *rc) +{ +xpthread_mutex_lock(&dpif_mutex); +ovs_assert(rc->refcount); +rc->refcount--; +xpthread_mutex_unlock(&dpif_mutex); +} + +static struct registered_dpif_class * +dp_class_lookup(const char *type) +{ +struct registered_dpif_class *rc; + +xpthread_mutex_lock(&dpif_mutex); +rc = shash_find_data(&dpif_classes, type); +if (rc) { +rc->refcount++; +} +xpthread_mutex_unlock(&dpif_mutex); + +return rc; } /* Clears 'names' and enumerates the names of all known created datapaths with @@ -198,14 +258,14 @@ dp_enumerate_types(struct sset *types) int dp_enumerate_names(const char *type, struct sset *names) { -const struct registered_dpif_class *registered_class; +struct registered_dpif_class *registered_class; const struct dpif_class *dpif_class; int error; dp_initialize(); sset_clear(names); -registered_class = shash_find_data(&dpif_classes, type); +registered_class = dp_class_lookup(type); if (!registered_class) { VLOG_WARN("could not enumerate unknown type: %s", type); return EAFNOSUPPORT; @@ -213,11 +273,11 @@ dp_enumerate_names(const char *type, struct sset *names) dpif_class = registered_class->dpif_class; error = dpif_class->enumerate ? dpif_class->enumerate(names) : 0; - if (error) { VLOG_WARN("failed to enumerate %s datapaths: %s", dpif_class->type, ovs_strerror(error)); } +dp_class_unref(registered_class); return error; } @@ -253,8 +313,7 @@ do_open(const
[ovs-dev] [dpif 4/5] dpif-netdev: Make internally thread-safe by introducing a global mutex.
This can be improved later but it is the simple thing to do for now. I marked a couple of races with XXX. I don't have a really good solution for these, but I hope to find one. They may be harmless in practice. Signed-off-by: Ben Pfaff --- lib/dpif-netdev.c | 203 +++-- 1 files changed, 150 insertions(+), 53 deletions(-) diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index d21eb8d..8763e5c 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -139,6 +139,9 @@ struct dpif_netdev { /* All netdev-based datapaths. */ static struct shash dp_netdevs = SHASH_INITIALIZER(&dp_netdevs); +/* Global lock for all data. */ +static pthread_mutex_t dp_netdev_mutex = PTHREAD_MUTEX_INITIALIZER; + static int get_port_by_number(struct dp_netdev *, odp_port_t port_no, struct dp_netdev_port **portp); static int get_port_by_name(struct dp_netdev *, const char *devname, @@ -180,9 +183,12 @@ dpif_netdev_enumerate(struct sset *all_dps) { struct shash_node *node; +xpthread_mutex_lock(&dp_netdev_mutex); SHASH_FOR_EACH(node, &dp_netdevs) { sset_add(all_dps, node->name); } +xpthread_mutex_unlock(&dp_netdev_mutex); + return 0; } @@ -293,28 +299,23 @@ dpif_netdev_open(const struct dpif_class *class, const char *name, bool create, struct dpif **dpifp) { struct dp_netdev *dp; +int error; +xpthread_mutex_lock(&dp_netdev_mutex); dp = shash_find_data(&dp_netdevs, name); if (!dp) { -if (!create) { -return ENODEV; -} else { -int error = create_dp_netdev(name, class, &dp); -if (error) { -return error; -} -ovs_assert(dp != NULL); -} +error = create ? create_dp_netdev(name, class, &dp) : ENODEV; } else { -if (dp->class != class) { -return EINVAL; -} else if (create) { -return EEXIST; -} +error = (dp->class != class ? EINVAL + : create ? EEXIST + : 0); +} +if (!error) { +*dpifp = create_dpif_netdev(dp); } +xpthread_mutex_unlock(&dp_netdev_mutex); -*dpifp = create_dpif_netdev(dp); -return 0; +return error; } static void @@ -351,19 +352,28 @@ static void dpif_netdev_close(struct dpif *dpif) { struct dp_netdev *dp = get_dp_netdev(dpif); + +xpthread_mutex_lock(&dp_netdev_mutex); + ovs_assert(dp->open_cnt > 0); if (--dp->open_cnt == 0 && dp->destroyed) { shash_find_and_delete(&dp_netdevs, dp->name); dp_netdev_free(dp); } free(dpif); + +xpthread_mutex_unlock(&dp_netdev_mutex); } static int dpif_netdev_destroy(struct dpif *dpif) { struct dp_netdev *dp = get_dp_netdev(dpif); + +xpthread_mutex_lock(&dp_netdev_mutex); dp->destroyed = true; +xpthread_mutex_unlock(&dp_netdev_mutex); + return 0; } @@ -371,10 +381,14 @@ static int dpif_netdev_get_stats(const struct dpif *dpif, struct dpif_dp_stats *stats) { struct dp_netdev *dp = get_dp_netdev(dpif); + +xpthread_mutex_lock(&dp_netdev_mutex); stats->n_flows = hmap_count(&dp->flow_table); stats->n_hit = dp->n_hit; stats->n_missed = dp->n_missed; stats->n_lost = dp->n_lost; +xpthread_mutex_unlock(&dp_netdev_mutex); + return 0; } @@ -444,32 +458,44 @@ dpif_netdev_port_add(struct dpif *dpif, struct netdev *netdev, char namebuf[NETDEV_VPORT_NAME_BUFSIZE]; const char *dpif_port; odp_port_t port_no; +int error; +xpthread_mutex_lock(&dp_netdev_mutex); dpif_port = netdev_vport_get_dpif_port(netdev, namebuf, sizeof namebuf); if (*port_nop != ODPP_NONE) { uint32_t port_idx = odp_to_u32(*port_nop); if (port_idx >= MAX_PORTS) { -return EFBIG; +error = EFBIG; } else if (dp->ports[port_idx]) { -return EBUSY; +error = EBUSY; +} else { +error = 0; +port_no = *port_nop; } -port_no = *port_nop; } else { port_no = choose_port(dp, dpif_port); +error = port_no == ODPP_NONE ? EFBIG : 0; } -if (port_no != ODPP_NONE) { +if (!error) { *port_nop = port_no; -return do_add_port(dp, dpif_port, netdev_get_type(netdev), port_no); +error = do_add_port(dp, dpif_port, netdev_get_type(netdev), port_no); } -return EFBIG; +xpthread_mutex_unlock(&dp_netdev_mutex); + +return error; } static int dpif_netdev_port_del(struct dpif *dpif, odp_port_t port_no) { struct dp_netdev *dp = get_dp_netdev(dpif); -return (port_no == ODPP_LOCAL ? - EINVAL : do_del_port(dp, port_no)); +int error; + +xpthread_mutex_lock(&dp_netdev_mutex); +error = port_no == ODPP_LOCAL ? EINVAL : do_del_port(dp, port_no); +xpthread_mutex_unlock(&dp