On Mon, Jun 23, 2014 at 05:34:58PM -0700, Saurabh Shah wrote: > Co-Authored-By: Eitan Eliahu <elia...@vmware.com> > Signed-off-by: Eitan Eliahu <elia...@vmware.com> > Co-Authored-By: Guolin Yang <gy...@vmware.com> > Signed-off-by: Guolin Yang <gy...@vmware.com> > Co-Authored-By: Linda Sun <l...@vmware.com> > Signed-off-by: Linda Sun <l...@vmware.com> > Co-Authored-By: Nithin Raju <nit...@vmware.com> > Signed-off-by: Nithin Raju <nit...@vmware.com> > Signed-off-by: Saurabh Shah <ssaur...@vmware.com>
This is going to be a pretty superficial review, because I don't know Windows well. It's just what I notice as I try to read through the code. I haven't compiled it other than to make sure it doesn't break the GNU/Linux build. It looks like datapath-windows/include/OvsNetlink.h is cut-and-pasted from other OVS header files, especially lib/netlink-protocol.h, lib/netlink.h, and lib/util.h. Is it possible to reduce the amount of code duplication? Either way, the copyright notice in that file should include the original copyright notice years and authors, e.g. * Copyright (c) 2008, 2009, 2010, 2011, 2013 Nicira, Inc. for lib/netlink.h, instead of just saying VMware 2014. dpif-windows.c -------------- A lot of functions shifted around a bit when I asked Emacs to re-indent them. Some code seems to randomly use 3-space indents. This file should #include "dpif-windows.h" just after <config.h>, to ensure that dpif-windows.h is self-contained (it looks to me like it isn't, I don't see any #includes in there that would define enum ovs_vport_type, for example). Some global variables should probably be static: +char *systemType = "system"; +long long int ovs_dp_timestamp_set_time; Please use BUILD_ASSERT(_DECL) from util.h instead of defining ASSERT_ON_COMPILE. Please use the standard offsetof from <stddef.h> instead of defining OFFSET_OF. Is win_error_to_errno() likely to be more broadly useful, e.g. should it be moved to a more global location? (If not, it should be static.) This file uses // comments more than OVS generally does. Lots of log messages log raw error numbers, e.g. in dpif_windows_init_handle(): error = GetLastError(); VLOG_ERR("Failed driver version query: %ws error %d\n", OVS_DEVICE_PATH, error); I guess you can use ovs_last error_to_string() or ovs_format_message() to give the user better diagnostics. Comments should generally begin with a capital letter and end with a period, e.g. /* handle specifically used for receiving packets from the kernel */ -> /* Handle specifically used for receiving packets from the kernel. */ I see a number of lines that would be more readable if broken at 79 characters. The use of __FUNCTION__ in logging in dpif_windows_init_handle() doesn't look too useful to me, since the log message is pretty much unique without it. I suspect that none of the casts in dpif_windows_ioctl__() are actually needed. Also in dpif_windows_ioctl__(): * In order to deal with the situation, we periodicatlly pass down the "periodically" This is a nasty situation. Do you have any leads on why the idea of the current time might drift? /* * There seems to be a skew between the kernel's version of current time and * the userspace's version of current time. The skew was seen to * monotonically increase as well. * * In order to deal with the situation, we periodicatlly pass down the * userspace's version of the timestamp to the kernel, and let the kernel * calculate the delta. The frequency of this is * OVS_DP_TIMESTAMP_SET_TIME_INTVL. */ Also that comment should line up the *s: /* * There seems to be a skew between the kernel's version of current time and * the userspace's version of current time. The skew was seen to * monotonically increase as well. * * In order to deal with the situation, we periodicatlly pass down the * userspace's version of the timestamp to the kernel, and let the kernel * calculate the delta. The frequency of this is * OVS_DP_TIMESTAMP_SET_TIME_INTVL. */ Usually we'd write OVS_NOT_REACHED() here: ovs_assert(FALSE); Stylistically it's rare to see a bare {} block in OVS like the one in the middle of dpif_windows_ioctl__(). Historically we've tended to declare variables at the top of the nearest block. Now the style allows declarations mid-block. I think I'd prefer to see either of those latter two choices here. This: if (!DeviceIoControl(handle, type, (LPVOID)request, (DWORD)request_len, (LPVOID)reply, (DWORD)reply_len, &bytes, NULL)) { should be lined up like this: if (!DeviceIoControl(handle, type, (LPVOID)request, (DWORD)request_len, (LPVOID)reply, (DWORD)reply_len, &bytes, NULL)) { dpif_windows_ioctl__() seems to return a negative errno in some cases, but a positive errno if dpif_windows_init() fails. I think that the latter is probably a mistake, because some callers treat a positive return value as success (e.g. dpif_windows_dump_numbers()). In dpif_windows_ioctl(), this: return dpif_windows_ioctl__(ovs_ctl_device, type, request, request_len, reply, reply_len); should be lined up like this: return dpif_windows_ioctl__(ovs_ctl_device, type, request, request_len, reply, reply_len); In dpif_windows_init_handle(), FILE_READ_ATTRIBUTES | SYNCHRONIZE is commented out in the call to CreateFile. Should these be included? I guess that this comment in dpif_windows_close() should be deleted: // close(dpif->chrdev_fd); In dpif_windows_get_stats(), we don't usually put parentheses around the operand to sizeof when they are not required, like here: memset(stats, 0, sizeof(*stats)); In dpif_windows_port_query__(), we don't normally add parentheses around a "return" expression: return (-retval == ENOENT ? ENODEV : -retval); and the middle line is not indented correctly here: if (port_name && strncmp(port_name, info.name, strlen(port_name))) { return ENODEV; } On that same line of code if (port_name && strncmp(port_name, info.name, strlen(port_name))) { I'm not sure why it uses strncmp(). strncmp() seems to risk accepting a port name that is the requested name plus some trailing prefix (or maybe I've got that backward). Maybe info.name isn't necessarily null-terminated? In that case maybe one should check that strnlen(info.name, sizeof info.name) == strlen(port_name). dpif_windows_port_add() declares 'type' as char * instead of const char * and then needs a cast to char *. Why not just use const char *? This comment in dpif_windows_port_add() is mysterious: /* * we may add uplink support later * when we move away from DVS. */ dpif_windows_port_del() marks its parameters OVS_UNUSED but does use them. In dpif_windows_port_get_pid(), I would write return (port_no != UINT32_MAX) ? port_no : 0; as return port_no != UINT32_MAX ? port_no : 0; The 'event_status' variable declared at file scope should probably be static. It could even be moved inside dpif_windows_poll_datapath() since it appears to be used only inside that function. In dpif_windows_port_poll(), I would write OVS_NOT_REACHED() instead of /* NOT REACHED */ if anything is really needed at all. odp_perfect_flow_key_to_flow() is cut and paste from dpif_netdev_flow_from_nlattrs(). I would break out the common code into odp-util.c. The logging in dpif_windows_flow_del() seems like a debugging stray. FLOW_DUMP_SIZE is only used in dpif_windows_flow_dump_thread_create() so I would probably use an enum there: enum { FLOW_DUMP_SIZE = 4096 }; to keep it nicely scoped. dpif_windows_ovs_flow_key_to_flow() should probably memset 'dst' to all zeros to start out with, to make sure that padding between and after members is zeroed. Then you can omit the other memsets and assignments to 0 within the function. Oh, actually I see that its only caller does the memset. I would move the memset into dpif_windows_ovs_flow_key_to_flow() to make it clearer. odp_flow_key_from_flow(&fstate->key_buf, &flow, NULL, flow.in_port.odp_port, false); should be indented as: odp_flow_key_from_flow(&fstate->key_buf, &flow, NULL, flow.in_port.odp_port, false); It's pretty unusual for dpif_windows_execute() to call malloc() instead of xmalloc(). Any particular reason? I'm not sure why dpif_windows_execute() has a cast to struct dpif_execute *. Why isn't that parameter to dpif_execute_to_packetexecute() const? In dpif_windows_subscribe(), I would write return (retval < 0)? -errno : 0; as return retval < 0 ? -errno : 0; I suspect that the references to erno in dpif_windows_subscribe() should be to retval. jhash.[ch] ---------- I'm not really happy with these changes, let's see if there's a better way. I don't understand why this adds a cast to jhash_bytes(). OvsPub.h -------- The quoted string here appears to have two \\ escapes followed by a \. escape. Does \. mean something special in Windows? #define OVS_DEVICE_PATH TEXT("\\\\\.\\OvsIoctl") I succumbed to "review fatigue" looking at the netdev code, so no comments on that yet. Tomorrow, I'll try to continue my look through, and then I'll shift over to looking at the cloudbase implementation. _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev