Merge commit 'origin/citrix'
authorJustin Pettit <jpettit@nicira.com>
Sat, 5 Sep 2009 05:23:29 +0000 (22:23 -0700)
committerJustin Pettit <jpettit@nicira.com>
Sat, 5 Sep 2009 05:23:29 +0000 (22:23 -0700)
datapath/datapath.c
lib/rconn.c
vswitchd/ovs-vswitchd.conf.5.in
xenserver/README
xenserver/automake.mk
xenserver/etc_init.d_vswitch
xenserver/root_vswitch_scripts_sysconfig.template [moved from xenserver/etc_sysconfig_vswitch.example with 55% similarity]
xenserver/vswitch-xen.spec

index 6f96ee4..427391a 100644 (file)
@@ -1107,6 +1107,7 @@ static int do_execute(struct datapath *dp, const struct odp_execute *executep)
        struct odp_flow_key key;
        struct sk_buff *skb;
        struct sw_flow_actions *actions;
+       struct ethhdr *eth;
        int err;
 
        err = -EFAULT;
@@ -1146,6 +1147,17 @@ static int do_execute(struct datapath *dp, const struct odp_execute *executep)
                           execute.length))
                goto error_free_skb;
 
+       skb_reset_mac_header(skb);
+       eth = eth_hdr(skb);
+
+    /* Normally, setting the skb 'protocol' field would be handled by a
+     * call to eth_type_trans(), but it assumes there's a sending
+     * device, which we may not have. */
+       if (ntohs(eth->h_proto) >= 1536)
+               skb->protocol = eth->h_proto;
+       else
+               skb->protocol = htons(ETH_P_802_2);
+
        flow_extract(skb, execute.in_port, &key);
        err = execute_actions(dp, skb, &key, actions->actions,
                              actions->n_actions, GFP_KERNEL);
index 4c6c9e9..a27e432 100644 (file)
@@ -111,6 +111,18 @@ struct rconn {
      * a response. */
     int probe_interval;         /* Secs of inactivity before sending probe. */
 
+    /* When we create a vconn we obtain these values, to save them past the end
+     * of the vconn's lifetime.  Otherwise, in-band control will only allow
+     * traffic when a vconn is actually open, but it is nice to allow ARP to
+     * complete even between connection attempts, and it is also polite to
+     * allow traffic from other switches to go through to the controller
+     * whether or not we are connected.
+     *
+     * We don't cache the local port, because that changes from one connection
+     * attempt to the next. */
+    uint32_t local_ip, remote_ip;
+    uint16_t remote_port;
+
     /* Messages sent or received are copied to the monitor connections. */
 #define MAX_MONITORS 8
     struct vconn *monitors[8];
@@ -121,6 +133,7 @@ static unsigned int elapsed_in_this_state(const struct rconn *);
 static unsigned int timeout(const struct rconn *);
 static bool timed_out(const struct rconn *);
 static void state_transition(struct rconn *, enum state);
+static void set_vconn_name(struct rconn *, const char *name);
 static int try_send(struct rconn *);
 static int reconnect(struct rconn *);
 static void disconnect(struct rconn *, int error);
@@ -236,8 +249,7 @@ int
 rconn_connect(struct rconn *rc, const char *name)
 {
     rconn_disconnect(rc);
-    free(rc->name);
-    rc->name = xstrdup(name);
+    set_vconn_name(rc, name);
     rc->reliable = true;
     return reconnect(rc);
 }
@@ -248,8 +260,7 @@ rconn_connect_unreliably(struct rconn *rc,
 {
     assert(vconn != NULL);
     rconn_disconnect(rc);
-    free(rc->name);
-    rc->name = xstrdup(name);
+    set_vconn_name(rc, name);
     rc->reliable = false;
     rc->vconn = vconn;
     rc->last_connected = time_now();
@@ -273,8 +284,7 @@ rconn_disconnect(struct rconn *rc)
             vconn_close(rc->vconn);
             rc->vconn = NULL;
         }
-        free(rc->name);
-        rc->name = xstrdup("void");
+        set_vconn_name(rc, "void");
         rc->reliable = false;
 
         rc->backoff = 0;
@@ -323,6 +333,9 @@ reconnect(struct rconn *rc)
     rc->n_attempted_connections++;
     retval = vconn_open(rc->name, OFP_VERSION, &rc->vconn);
     if (!retval) {
+        rc->remote_ip = vconn_get_remote_ip(rc->vconn);
+        rc->local_ip = vconn_get_local_ip(rc->vconn);
+        rc->remote_port = vconn_get_remote_port(rc->vconn);
         rc->backoff_deadline = time_now() + rc->backoff;
         state_transition(rc, S_CONNECTING);
     } else {
@@ -635,20 +648,20 @@ rconn_failure_duration(const struct rconn *rconn)
     return rconn_is_connected(rconn) ? 0 : time_now() - rconn->last_admitted;
 }
 
-/* Returns the IP address of the peer, or 0 if the peer is not connected over
- * an IP-based protocol or if its IP address is not known. */
+/* Returns the IP address of the peer, or 0 if the peer's IP address is not
+ * known. */
 uint32_t
 rconn_get_remote_ip(const struct rconn *rconn) 
 {
-    return rconn->vconn ? vconn_get_remote_ip(rconn->vconn) : 0;
+    return rconn->remote_ip;
 }
 
-/* Returns the transport port of the peer, or 0 if the peer does not 
- * contain a port or if the port is not known. */
+/* Returns the transport port of the peer, or 0 if the peer's port is not
+ * known. */
 uint16_t
 rconn_get_remote_port(const struct rconn *rconn) 
 {
-    return rconn->vconn ? vconn_get_remote_port(rconn->vconn) : 0;
+    return rconn->remote_port;
 }
 
 /* Returns the IP address used to connect to the peer, or 0 if the
@@ -657,7 +670,7 @@ rconn_get_remote_port(const struct rconn *rconn)
 uint32_t
 rconn_get_local_ip(const struct rconn *rconn) 
 {
-    return rconn->vconn ? vconn_get_local_ip(rconn->vconn) : 0;
+    return rconn->local_ip;
 }
 
 /* Returns the transport port used to connect to the peer, or 0 if the
@@ -805,6 +818,19 @@ rconn_packet_counter_dec(struct rconn_packet_counter *c)
     }
 }
 \f
+/* Set the name of the remote vconn to 'name' and clear out the cached IP
+ * address and port information, since changing the name also likely changes
+ * these values. */
+static void
+set_vconn_name(struct rconn *rc, const char *name)
+{
+    free(rc->name);
+    rc->name = xstrdup(name);
+    rc->local_ip = 0;
+    rc->remote_ip = 0;
+    rc->remote_port = 0;
+}
+
 /* Tries to send a packet from 'rc''s send buffer.  Returns 0 if successful,
  * otherwise a positive errno value. */
 static int
index 0dbf94d..af3ff27 100644 (file)
@@ -266,6 +266,22 @@ a trunk port, the frame's VLAN tag will be set to \fIvid\fR, replacing
 any existing tag; when it is sent out an implicit VLAN port, the frame
 will not be tagged.  This type of mirroring may be referred to as
 RSPAN.
+.IP
+Please note that mirroring to a VLAN can disrupt a network that
+contains unmanaged switches.  Consider an unmanaged physical switch
+with two ports: port 1, connected to an end host, and port 2,
+connected to an Open vSwitch configured to mirror received packets
+into VLAN 123 on port 2.  Suppose that the end host sends a packet on
+port 1 that the physical switch forwards to port 2.  The Open vSwitch
+forwards this packet to its destination and then reflects it back on
+port 2 in VLAN 123.  This reflected packet causes the unmanaged
+physical switch to replace the MAC learning table entry, which
+correctly pointed to port 1, with one that incorrectly points to port
+2.  Afterward, the physical switch will direct packets destined for
+the end host to the Open vSwitch on port 2, instead of to the end host
+on port 1, disrupting connectivity.  If mirroring to a VLAN is desired
+in this scenario, then the physical switch must be replaced by one
+that learns Ethernet addresses on a per-VLAN basis.
 .ST "Example"
 The following \fBovs\-vswitchd\fR configuration copies all frames received
 on \fBeth1\fR or \fBeth2\fR to \fBeth3\fR.
index b940e3f..276cd6c 100644 (file)
@@ -30,10 +30,6 @@ files are:
         vswitch-related shell functions for the administrator's
         convenience.
 
-    etc_sysconfig_vswitch.example
-
-        Example configuration options for vswitch.
-
     etc_xapi.d_plugins_vswitch-cfg-update
 
         xapi plugin script to update the cache of configuration items
@@ -54,6 +50,11 @@ files are:
         needed by the controller.  This is called by the "vif" script,
         which is run when virtual interfaces are added and removed.
 
+    root_vswitch_scripts_sysconfig.template
+
+        Template for vswitch's /etc/sysconfig/vswitch configuration
+        file.
+
     usr_lib_xsconsole_plugins-base_XSFeatureVSwitch.py
 
         xsconsole plugin to configure the pool-wide configuration keys
index ceebb9d..deb79bc 100644 (file)
@@ -11,10 +11,10 @@ EXTRA_DIST += \
        xenserver/etc_init.d_vswitch-xapi-update \
        xenserver/etc_logrotate.d_vswitch \
        xenserver/etc_profile.d_vswitch.sh \
-       xenserver/etc_sysconfig_vswitch.example \
        xenserver/etc_xapi.d_plugins_vswitch-cfg-update \
        xenserver/etc_xensource_scripts_vif \
        xenserver/opt_xensource_libexec_interface-reconfigure \
+       xenserver/root_vswitch_scripts_sysconfig.template \
        xenserver/root_vswitch_scripts_dump-vif-details \
        xenserver/usr_lib_xsconsole_plugins-base_XSFeatureVSwitch.py \
        xenserver/usr_sbin_brctl \
index abd594e..ee858fd 100755 (executable)
@@ -286,6 +286,11 @@ function start {
     # ovs-vswitchd needs a few per bridge
     ulimit -n 4096
 
+    if [ ! -e "$VSWITCHD_CONF" ]; then
+        warning "$VSWITCHD_CONF does not exist"
+        action "Creating empty $VSWITCHD_CONF" touch "$VSWITCHD_CONF"
+    fi
+
     start_vswitchd
     start_brcompatd
     reload_vswitchd  # ensures ovs-vswitchd has fully read config file.
similarity index 55%
rename from xenserver/etc_sysconfig_vswitch.example
rename to xenserver/root_vswitch_scripts_sysconfig.template
index ea8efe1..4bc4b19 100644 (file)
 # VSWITCHD_LOGFILE: File to send the FILE_LOGLEVEL log messages to.
 # VSWITCHD_LOGFILE=/var/log/ovs-vswitchd.log
 
+# VSWITCHD_MEMLEAK_LOGFILE: File for logging memory leak data.
+#     Enabling this option will slow ovs-vswitchd significantly.  Do not
+#     enable it except to debug a suspected memory leak.  Use the
+#     ovs-parse-leaks utility included with Open vSwitch to parse the
+#     log file.  For best results, you also need debug symbols.
+# VSWITCHD_MEMLEAK_LOGFILE=""
+
 # VSWITCHD_FILE_LOGLEVEL: Log level at which to log into the
 #     VSWITCHD_LOG file.  If this is null or not set the logfile will
 #     not be created and nothing will be sent to it.  This is the
 #     emergency and warning level messages only.
 # VSWITCHD_SYSLOG_LOGLEVEL="WARN"
 
+# VSWITCHD_STRACE_LOG: File for logging strace output.
+#     If this is set to a nonempty string, then ovs-vswitchd will run
+#     under strace, whose output will be logged to the specified file.
+#     Enabling this option will slow ovs-vswitchd significantly.
+#     VSWITCHD_STRACE_LOG and VSWITCHD_VALGRIND_LOG are mutually exclusive.
+# VSWITCHD_STRACE_LOG=""
+
+# VSWITCHD_STRACE_OPT: Options to pass to strace.
+#     This option's value is honored only when VSWITCHD_STRACE_LOG is
+#     set to a nonempty string.
+# VSWITCHD_STRACE_OPT=""
+
+# VSWITCHD_VALGRIND_LOG: File for logging valgrind output.
+#     If this is set to a nonempty string, then ovs-vswitchd will run
+#     under valgrind, whose output will be logged to the specified file.
+#     Enabling this option will slow ovs-vswitchd by 100X or more.
+#     valgrind is not installed by default on XenServer systems; you must
+#     install it by hand to usefully enable this option.
+#     VSWITCHD_STRACE_LOG and VSWITCHD_VALGRIND_LOG are mutually exclusive.
+# VSWITCHD_VALGRIND_LOG=""
+
+# VSWITCHD_VALGRIND_OPT: Options to pass to valgrind.
+#     This option's value is honored only when VSWITCHD_VALGRIND_LOG is
+#     set to a nonempty string.
+# VSWITCHD_VALGRIND_OPT=""
+
 # BRCOMPATD_PIDFILE: File in which to store the pid of the running
 #     ovs-brcompatd (the Linux bridge compatibility daemon for ovs-vswitchd).
 #     If this is the empty string, ovs-brcompatd will not be started and
 #     this is null or not set the default is to log to syslog
 #     emergency and warning level messages only.
 # BRCOMPATD_SYSLOG_LOGLEVEL="WARN"
+
+# BRCOMPATD_MEMLEAK_LOGFILE: File for logging memory leak data.
+#     Enabling this option will slow ovs-brcompatd significantly.  Do not
+#     enable it except to debug a suspected memory leak.  Use the
+#     ovs-parse-leaks utility included with Open vSwitch to parse the
+#     log file.  For best results, you also need debug symbols.
+# BRCOMPATD_MEMLEAK_LOGFILE=""
+
+# BRCOMPATD_STRACE_LOG: File for logging strace output.
+#     If this is set to a nonempty string, then ovs-brcompatd will run
+#     under strace, whose output will be logged to the specified file.
+#     Enabling this option will slow brcompatd significantly.
+#     BRCOMPATD_STRACE_LOG and BRCOMPATD_VALGRIND_LOG are mutually exclusive.
+# BRCOMPATD_STRACE_LOG=""
+
+# BRCOMPATD_STRACE_OPT: Options to pass to strace.
+#     This option's value is honored only when BRCOMPATD_STRACE_LOG is
+#     set to a nonempty string.
+# BRCOMPATD_STRACE_OPT=""
+
+# BRCOMPATD_VALGRIND_LOG: File for logging valgrind output.
+#     If this is set to a nonempty string, then ovs-brcompatd will run
+#     under valgrind, whose output will be logged to the specified file.
+#     Enabling this option will slow brcompatd by 100X or more.
+#     valgrind is not installed by default on XenServer systems; you must
+#     install it by hand to usefully enable this option.
+#     BRCOMPATD_STRACE_LOG and BRCOMPATD_VALGRIND_LOG are mutually exclusive.
+# BRCOMPATD_VALGRIND_LOG=""
+
+# BRCOMPATD_VALGRIND_OPT: Options to pass to valgrind.
+#     This option's value is honored only when BRCOMPATD_VALGRIND_LOG is
+#     set to a nonempty string.
+# BRCOMPATD_VALGRIND_OPT=""
index 576c6e6..58f578c 100644 (file)
@@ -51,8 +51,6 @@ install -m 755 xenserver/etc_init.d_vswitch \
 install -m 755 xenserver/etc_init.d_vswitch-xapi-update \
          $RPM_BUILD_ROOT/etc/init.d/vswitch-xapi-update
 install -d -m 755 $RPM_BUILD_ROOT/etc/sysconfig
-install -m 755 xenserver/etc_sysconfig_vswitch.example \
-         $RPM_BUILD_ROOT/etc/sysconfig/vswitch.example
 install -d -m 755 $RPM_BUILD_ROOT/etc/logrotate.d
 install -m 755 xenserver/etc_logrotate.d_vswitch \
          $RPM_BUILD_ROOT/etc/logrotate.d/vswitch
@@ -73,6 +71,8 @@ install -m 755 xenserver/usr_sbin_xen-bugtool \
              $RPM_BUILD_ROOT%{_prefix}/scripts/xen-bugtool
 install -m 755 xenserver/usr_sbin_brctl \
              $RPM_BUILD_ROOT%{_prefix}/scripts/brctl
+install -m 755 xenserver/root_vswitch_scripts_sysconfig.template \
+         $RPM_BUILD_ROOT/root/vswitch/scripts/sysconfig.template
 install -m 644 \
         xenserver/usr_lib_xsconsole_plugins-base_XSFeatureVSwitch.py \
                $RPM_BUILD_ROOT%{_prefix}/scripts/XSFeatureVSwitch.py
@@ -208,6 +208,21 @@ fi
 # Ensure ovs-vswitchd.conf exists
 touch /etc/ovs-vswitchd.conf
 
+# Create default or update existing /etc/sysconfig/vswitch.
+SYSCONFIG=/etc/sysconfig/vswitch
+TEMPLATE=/root/vswitch/scripts/sysconfig.template
+if [ ! -e $SYSCONFIG ]; then
+    cp $TEMPLATE $SYSCONFIG
+else
+    for var in $(awk -F'[ :]' '/^# [_A-Z0-9]+:/{print $2}' $TEMPLATE)
+    do
+        if ! grep $var $SYSCONFIG >/dev/null 2>&1; then
+            echo >> $SYSCONFIG
+            sed -n "/$var:/,/$var=/p" $TEMPLATE >> $SYSCONFIG
+        fi
+    done
+fi
+
 # Replace XenServer files by our versions.
 mkdir -p %{_prefix}/xs-original \
     || printf "Could not create script backup directory.\n"
@@ -308,7 +323,6 @@ fi
 /etc/init.d/vswitch
 /etc/init.d/vswitch-xapi-update
 /etc/xapi.d/plugins/vswitch-cfg-update
-/etc/sysconfig/vswitch.example
 /etc/logrotate.d/vswitch
 /etc/profile.d/vswitch.sh
 /root/vswitch/kernel_modules/brcompat_mod.ko
@@ -319,6 +333,7 @@ fi
 /root/vswitch/scripts/xen-bugtool
 /root/vswitch/scripts/XSFeatureVSwitch.py
 /root/vswitch/scripts/brctl
+/root/vswitch/scripts/sysconfig.template
 # Following two files are generated automatically by rpm.  We don't
 # really need them and they won't be used on the XenServer, but there
 # isn't an obvious place to get rid of them since they are generated