vswitchd: Bubble no-flood configuration up to bridge
authorEthan Jackson <ethan@nicira.com>
Wed, 13 Oct 2010 22:12:12 +0000 (22:12 +0000)
committerEthan Jackson <ethan@nicira.com>
Thu, 14 Oct 2010 18:18:23 +0000 (18:18 +0000)
When bridge.c decides to flood a packet as the result of a "normal"
flow action, it now checks whether each port is configured to
receive flood packets.

Bug #3741

ofproto/ofproto.c
ofproto/ofproto.h
vswitchd/bridge.c

index 5e99fcab188390d276a5e9a80407118b20609aa6..bb2bf5a4ae2873c3447d5b949c4334f28336af14 100644 (file)
@@ -1277,6 +1277,15 @@ ofproto_port_del(struct ofproto *ofproto, uint16_t odp_port)
     return error;
 }
 
+/* Checks if 'ofproto' thinks 'odp_port' should be included in floods.  Returns
+ * true if 'odp_port' exists and should be included, false otherwise. */
+bool
+ofproto_port_is_floodable(struct ofproto *ofproto, uint16_t odp_port)
+{
+    struct ofport *ofport = get_port(ofproto, odp_port);
+    return ofport && !(ofport->opp.config & OFPPC_NO_FLOOD);
+}
+
 int
 ofproto_send_packet(struct ofproto *p, const struct flow *flow,
                     const union ofp_action *actions, size_t n_actions,
index 0c403e903329fc0457a98166cc7bc6779d693463..362ea264bad6f6b61fc383390d5cf972f03cab11 100644 (file)
@@ -95,6 +95,7 @@ void ofproto_wait(struct ofproto *);
 bool ofproto_is_alive(const struct ofproto *);
 
 int ofproto_port_del(struct ofproto *, uint16_t odp_port);
+bool ofproto_port_is_floodable(struct ofproto *, uint16_t odp_port);
 
 /* Configuration. */
 void ofproto_set_datapath_id(struct ofproto *, uint64_t datapath_id);
index 74ac87efa1d85c81b98778c4a1a3699c09719fab..4a7f90bfa6b9aa3b12ac5ffcbb30a7e56f13f72b 100644 (file)
@@ -2203,6 +2203,20 @@ port_includes_vlan(const struct port *port, uint16_t vlan)
     return vlan == port->vlan || port_trunks_vlan(port, vlan);
 }
 
+static bool
+port_is_floodable(const struct port *port)
+{
+    int i;
+
+    for (i = 0; i < port->n_ifaces; i++) {
+        if (!ofproto_port_is_floodable(port->bridge->ofproto,
+                                       port->ifaces[i]->dp_ifidx)) {
+            return false;
+        }
+    }
+    return true;
+}
+
 static size_t
 compose_dsts(const struct bridge *br, const struct flow *flow, uint16_t vlan,
              const struct port *in_port, const struct port *out_port,
@@ -2217,7 +2231,9 @@ compose_dsts(const struct bridge *br, const struct flow *flow, uint16_t vlan,
         /* XXX even better, define each VLAN as a datapath port group */
         for (i = 0; i < br->n_ports; i++) {
             struct port *port = br->ports[i];
-            if (port != in_port && port_includes_vlan(port, vlan)
+            if (port != in_port
+                && port_is_floodable(port)
+                && port_includes_vlan(port, vlan)
                 && !port->is_mirror_output_port
                 && set_dst(dst, flow, in_port, port, tags)) {
                 mirrors |= port->dst_mirrors;