Fix handling of OFPP_ANY in OpenFlow 1.1 and later.
[sliver-openvswitch.git] / ofproto / ofproto.c
index 0aeb07e..0992fe4 100644 (file)
@@ -1433,6 +1433,30 @@ ofproto_port_dump_done(struct ofproto_port_dump *dump)
     return dump->error == EOF ? 0 : dump->error;
 }
 
+/* Returns the type to pass to netdev_open() when a datapath of type
+ * 'datapath_type' has a port of type 'port_type', for a few special
+ * cases when a netdev type differs from a port type.  For example, when
+ * using the userspace datapath, a port of type "internal" needs to be
+ * opened as "tap".
+ *
+ * Returns either 'type' itself or a string literal, which must not be
+ * freed. */
+const char *
+ofproto_port_open_type(const char *datapath_type, const char *port_type)
+{
+    const struct ofproto_class *class;
+
+    datapath_type = ofproto_normalize_type(datapath_type);
+    class = ofproto_class_find__(datapath_type);
+    if (!class) {
+        return port_type;
+    }
+
+    return (class->port_open_type
+            ? class->port_open_type(datapath_type, port_type)
+            : port_type);
+}
+
 /* Attempts to add 'netdev' as a port on 'ofproto'.  If 'ofp_portp' is
  * non-null and '*ofp_portp' is not OFPP_NONE, attempts to use that as
  * the port's OpenFlow port number.
@@ -1642,7 +1666,8 @@ alloc_ofp_port(struct ofproto *ofproto, const char *netdev_name)
          * flows. */
         while (ofp_port >= ofproto->max_ports) {
             for (ofproto->alloc_port_no++;
-                 ofproto->alloc_port_no < ofproto->max_ports; ) {
+                 ofproto->alloc_port_no < ofproto->max_ports;
+                 ofproto->alloc_port_no++) {
                 if (!bitmap_is_set(ofproto->ofp_port_ids,
                                    ofproto->alloc_port_no)) {
                     ofp_port = ofproto->alloc_port_no;
@@ -2104,7 +2129,7 @@ ofproto_rule_destroy(struct rule *rule)
 bool
 ofproto_rule_has_out_port(const struct rule *rule, uint16_t port)
 {
-    return (port == OFPP_NONE
+    return (port == OFPP_ANY
             || ofpacts_output_to_port(rule->ofpacts, rule->ofpacts_len, port));
 }
 
@@ -2146,7 +2171,7 @@ rule_execute(struct rule *rule, uint16_t in_port, struct ofpbuf *packet)
 
     assert(ofpbuf_headroom(packet) >= sizeof(struct ofp_packet_in));
 
-    flow_extract(packet, 0, NULL, in_port, &flow);
+    flow_extract(packet, 0, 0, NULL, in_port, &flow);
     return rule->ofproto->ofproto_class->rule_execute(rule, &flow, packet);
 }
 
@@ -2335,7 +2360,7 @@ handle_packet_out(struct ofconn *ofconn, const struct ofp_header *oh)
     }
 
     /* Verify actions against packet, then send packet if successful. */
-    flow_extract(payload, 0, NULL, po.in_port, &flow);
+    flow_extract(payload, 0, 0, NULL, po.in_port, &flow);
     error = ofpacts_check(po.ofpacts, po.ofpacts_len, &flow, p->max_ports);
     if (!error) {
         error = p->ofproto_class->packet_out(p, payload, &flow,
@@ -2517,7 +2542,7 @@ handle_port_stats_request(struct ofconn *ofconn,
     }
 
     ofpmp_init(&replies, request);
-    if (port_no != OFPP_NONE) {
+    if (port_no != OFPP_ANY) {
         port = ofproto_get_port(p, port_no);
         if (port) {
             append_port_stat(port, &replies);
@@ -2634,7 +2659,7 @@ next_matching_table(const struct ofproto *ofproto,
  * OpenFlow OFPFC_MODIFY and OFPFC_DELETE requests and puts them on list
  * 'rules'.
  *
- * If 'out_port' is anything other than OFPP_NONE, then only rules that output
+ * If 'out_port' is anything other than OFPP_ANY, then only rules that output
  * to 'out_port' are included.
  *
  * Hidden rules are always omitted.
@@ -2685,7 +2710,7 @@ exit:
  * OpenFlow OFPFC_MODIFY_STRICT and OFPFC_DELETE_STRICT requests and puts them
  * on list 'rules'.
  *
- * If 'out_port' is anything other than OFPP_NONE, then only rules that output
+ * If 'out_port' is anything other than OFPP_ANY, then only rules that output
  * to 'out_port' are included.
  *
  * Hidden rules are always omitted.
@@ -3029,7 +3054,7 @@ handle_queue_stats_request(struct ofconn *ofconn,
         return error;
     }
 
-    if (oqsr.port_no == OFPP_ALL) {
+    if (oqsr.port_no == OFPP_ANY) {
         error = OFPERR_OFPQOFC_BAD_QUEUE;
         HMAP_FOR_EACH (port, hmap_node, &ofproto->ports) {
             if (!handle_queue_stats_for_port(port, oqsr.queue_id, &cbdata)) {
@@ -3302,7 +3327,7 @@ modify_flows_loose(struct ofproto *ofproto, struct ofconn *ofconn,
 
     error = collect_rules_loose(ofproto, fm->table_id, &fm->match,
                                 fm->cookie, fm->cookie_mask,
-                                OFPP_NONE, &rules);
+                                OFPP_ANY, &rules);
     if (error) {
         return error;
     } else if (list_is_empty(&rules)) {
@@ -3327,7 +3352,7 @@ modify_flow_strict(struct ofproto *ofproto, struct ofconn *ofconn,
 
     error = collect_rules_strict(ofproto, fm->table_id, &fm->match,
                                  fm->priority, fm->cookie, fm->cookie_mask,
-                                 OFPP_NONE, &rules);
+                                 OFPP_ANY, &rules);
 
     if (error) {
         return error;