secchan: Do not refresh datapath indexes from bridge_get_ifaces().
authorBen Pfaff <blp@nicira.com>
Tue, 26 May 2009 17:36:53 +0000 (10:36 -0700)
committerBen Pfaff <blp@nicira.com>
Tue, 26 May 2009 17:36:53 +0000 (10:36 -0700)
bridge_get_ifaces() called bridge_fetch_dp_ifaces(), which in turn would
set dp_ifidx members of struct iface to -1 if we were racing with a port
being deleted from a datapath.  When this happen it would cause
ODPAT_OUTPUT actions with the port number set to UINT16_MAX to be pushed
to the datapath on OFPP_NORMAL actions, which the datapath would choke
on with EINVAL errors.

Thanks to Justin for pointing out the bad actions being pushed to the
datapath.

vswitchd/bridge.c

index 736e014d4b4cba6b3a32cab52915d3169e413ab1..65be78b021a319a44744d629f8828bcc4db5e036 100644 (file)
@@ -243,8 +243,8 @@ static struct ofhooks bridge_ofhooks;
 \f
 /* Public functions. */
 
-/* xxx Temporary to get around "." delimiter ovs-vswitchd.conf problem in
- * xxx port.c. */
+/* Adds the name of each interface used by a bridge, including local and
+ * internal ports, to 'svec'. */
 void
 bridge_get_ifaces(struct svec *svec) 
 {
@@ -252,7 +252,6 @@ bridge_get_ifaces(struct svec *svec)
     size_t i, j;
 
     LIST_FOR_EACH_SAFE (br, next, struct bridge, node, &all_bridges) {
-        bridge_fetch_dp_ifaces(br);
         for (i = 0; i < br->n_ports; i++) {
             struct port *port = br->ports[i];
 
@@ -1193,7 +1192,13 @@ bridge_get_all_ifaces(const struct bridge *br, struct svec *ifaces)
 }
 
 /* For robustness, in case the administrator moves around datapath ports behind
- * our back, we re-check all the datapath port numbers here. */
+ * our back, we re-check all the datapath port numbers here.
+ *
+ * This function will set the 'dp_ifidx' members of interfaces that have
+ * disappeared to -1, so only call this function from a context where those
+ * 'struct iface's will be removed from the bridge.  Otherwise, the -1
+ * 'dp_ifidx'es will cause trouble later when we try to send them to the
+ * datapath, which doesn't support UINT16_MAX+1 ports. */
 static void
 bridge_fetch_dp_ifaces(struct bridge *br)
 {