ofproto-dpif: Differentiate between different miss types in packet in
authorSimon Horman <horms@verge.net.au>
Thu, 13 Mar 2014 06:52:55 +0000 (15:52 +0900)
committerBen Pfaff <blp@nicira.com>
Thu, 20 Mar 2014 22:01:45 +0000 (15:01 -0700)
Replace the generated_by_table_miss field of struct ofproto_packet_in
with a miss_type field.

The generated_by_table_miss field allowed packet-in messages generated
by table-miss rules to be differentiated. This differentiation
is still provided for by miss_type being set to OFPROTO_PACKET_IN_MISS_FLOW.

This patch allows further differentiation by setting miss_type
to OFPROTO_PACKET_IN_MISS_WITHOUT_FLOW if the packet-in message
is generated by a table-miss which is not handled by a table-miss rule.

This is in preparation for OpenFlow 1.3 version-specific
handling of the default action for such misses.

Signed-off-by: Simon Horman <horms@verge.net.au>
Signed-off-by: Ben Pfaff <blp@nicira.com>
ofproto/connmgr.c
ofproto/connmgr.h
ofproto/fail-open.c
ofproto/ofproto-dpif-upcall.c
ofproto/ofproto-dpif-xlate.c
ofproto/ofproto-dpif.c
ofproto/ofproto-dpif.h
ofproto/ofproto-provider.h

index 0058309..9bc1897 100644 (file)
@@ -1534,7 +1534,8 @@ connmgr_send_flow_removed(struct connmgr *mgr,
 static enum ofp_packet_in_reason
 wire_reason(struct ofconn *ofconn, const struct ofproto_packet_in *pin)
 {
-    if (pin->generated_by_table_miss && pin->up.reason == OFPR_ACTION) {
+    if (pin->miss_type == OFPROTO_PACKET_IN_MISS_FLOW
+        && pin->up.reason == OFPR_ACTION) {
         enum ofputil_protocol protocol = ofconn_get_protocol(ofconn);
 
         if (protocol != OFPUTIL_P_NONE
index 3c9216f..c4cfd83 100644 (file)
@@ -62,17 +62,32 @@ enum ofconn_async_msg_type {
     OAM_N_TYPES
 };
 
+enum ofproto_packet_in_miss_type {
+    /* Not generated by a flow miss or table-miss flow. */
+    OFPROTO_PACKET_IN_NO_MISS,
+
+    /* The packet_in was generated directly by a table-miss flow, that is, a
+     * flow with priority 0 that wildcards all fields.  See OF1.3.3 section
+     * 5.4.
+     *
+     * (Our interpretation of "directly" is "not via groups".  Packet_ins
+     * generated by table-miss flows via groups use
+     * OFPROTO_PACKET_IN_NO_MISS.) */
+    OFPROTO_PACKET_IN_MISS_FLOW,
+
+    /* The packet-in was generated directly by a table-miss, but not a
+     * table-miss flow.  That is, it was generated by the OpenFlow 1.0, 1.1, or
+     * 1.2 table-miss behavior. */
+    OFPROTO_PACKET_IN_MISS_WITHOUT_FLOW,
+};
+
 /* A packet_in, with extra members to assist in queuing and routing it. */
 struct ofproto_packet_in {
     struct ofputil_packet_in up;
     struct list list_node;      /* For queuing. */
     uint16_t controller_id;     /* Controller ID to send to. */
     int send_len;               /* Length that the action requested sending. */
-
-    /* True if the packet_in was generated directly by a table-miss flow, that
-     * is, a flow with priority 0 that wildcards all fields.  (Our
-     * interpretation of "directly" is "not via groups".) */
-    bool generated_by_table_miss;
+    enum ofproto_packet_in_miss_type miss_type;
 };
 
 /* Basics. */
index 9ac80b6..467cafa 100644 (file)
@@ -130,7 +130,7 @@ send_bogus_packet_ins(struct fail_open *fo)
     pin.up.reason = OFPR_NO_MATCH;
     pin.up.fmd.in_port = OFPP_LOCAL;
     pin.send_len = b.size;
-    pin.generated_by_table_miss = false;
+    pin.miss_type = OFPROTO_PACKET_IN_NO_MISS;
     connmgr_send_packet_in(fo->connmgr, &pin);
 
     ofpbuf_uninit(&b);
index 56e6d24..0048943 100644 (file)
@@ -1261,7 +1261,7 @@ handle_upcalls(struct handler *handler, struct list *upcalls)
             pin->up.cookie = OVS_BE64_MAX;
             flow_get_metadata(&miss->flow, &pin->up.fmd);
             pin->send_len = 0; /* Not used for flow table misses. */
-            pin->generated_by_table_miss = false;
+            pin->miss_type = OFPROTO_PACKET_IN_NO_MISS;
             ofproto_dpif_send_packet_in(miss->ofproto, pin);
         }
     }
index 9d7c752..9b6ce10 100644 (file)
@@ -2151,8 +2151,22 @@ execute_controller_action(struct xlate_ctx *ctx, int len,
 
     pin->controller_id = controller_id;
     pin->send_len = len;
-    pin->generated_by_table_miss = (ctx->rule
-                                    && rule_dpif_is_table_miss(ctx->rule));
+    /* If a rule is a table-miss rule then this is
+     * a table-miss handled by a table-miss rule.
+     *
+     * Else, if rule is internal and has a controller action,
+     * the later being implied by the rule being processed here,
+     * then this is a table-miss handled without a table-miss rule.
+     *
+     * Otherwise this is not a table-miss. */
+    pin->miss_type = OFPROTO_PACKET_IN_NO_MISS;
+    if (ctx->rule) {
+        if (rule_dpif_is_table_miss(ctx->rule)) {
+            pin->miss_type = OFPROTO_PACKET_IN_MISS_FLOW;
+        } else if (rule_dpif_is_internal(ctx->rule)) {
+            pin->miss_type = OFPROTO_PACKET_IN_MISS_WITHOUT_FLOW;
+        }
+    }
     ofproto_dpif_send_packet_in(ctx->xbridge->ofproto, pin);
     ofpbuf_delete(packet);
 }
index cb30142..8ce439d 100644 (file)
@@ -3034,6 +3034,12 @@ rule_dpif_is_table_miss(const struct rule_dpif *rule)
     return rule_is_table_miss(&rule->up);
 }
 
+bool
+rule_dpif_is_internal(const struct rule_dpif *rule)
+{
+    return rule_is_internal(&rule->up);
+}
+
 ovs_be64
 rule_dpif_get_flow_cookie(const struct rule_dpif *rule)
     OVS_REQUIRES(rule->up.mutex)
@@ -4332,6 +4338,14 @@ ofproto_dpif_unixctl_init(void)
     unixctl_command_register("dpif/dump-flows", "[-m] bridge", 1, 2,
                              ofproto_unixctl_dpif_dump_flows, NULL);
 }
+
+
+/* Returns true if 'rule' is an internal rule, false otherwise. */
+bool
+rule_is_internal(const struct rule *rule)
+{
+    return rule->table_id == TBL_INTERNAL;
+}
 \f
 /* Linux VLAN device support (e.g. "eth0.10" for VLAN 10.)
  *
index 5409ce7..06fde3f 100644 (file)
@@ -94,6 +94,7 @@ void rule_dpif_credit_stats(struct rule_dpif *rule ,
 
 bool rule_dpif_is_fail_open(const struct rule_dpif *);
 bool rule_dpif_is_table_miss(const struct rule_dpif *);
+bool rule_dpif_is_internal(const struct rule_dpif *);
 
 struct rule_actions *rule_dpif_get_actions(const struct rule_dpif *);
 
index 28223fe..dd10f3a 100644 (file)
@@ -421,6 +421,7 @@ rule_is_table_miss(const struct rule *rule)
 {
     return rule->cr.priority == 0 && cls_rule_is_catchall(&rule->cr);
 }
+bool rule_is_internal(const struct rule *);
 
 /* A set of actions within a "struct rule".
  *