datapath: add skb mark matching and set action
[openvswitch] / ofproto / ofproto.c
index 1f34bbaeda98aaf6c92bb0e32abec33b10998f1a..dabb590d3e55027219feb9fca6275291d91e9ffc 100644 (file)
@@ -518,9 +518,10 @@ ofproto_set_datapath_id(struct ofproto *p, uint64_t datapath_id)
 void
 ofproto_set_controllers(struct ofproto *p,
                         const struct ofproto_controller *controllers,
-                        size_t n_controllers)
+                        size_t n_controllers, uint32_t allowed_versions)
 {
-    connmgr_set_controllers(p->connmgr, controllers, n_controllers);
+    connmgr_set_controllers(p->connmgr, controllers, n_controllers,
+                            allowed_versions);
 }
 
 void
@@ -1432,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.
@@ -1641,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;
@@ -2145,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);
 }
 
@@ -2334,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,