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 <ho...@verge.net.au> -- v2 * First post --- ofproto/connmgr.c | 3 ++- ofproto/connmgr.h | 11 ++++++++++- ofproto/fail-open.c | 2 +- ofproto/ofproto-dpif-upcall.c | 2 +- ofproto/ofproto-dpif-xlate.c | 18 ++++++++++++++++-- ofproto/ofproto-dpif.c | 14 ++++++++++++++ ofproto/ofproto-dpif.h | 1 + ofproto/ofproto-provider.h | 1 + 8 files changed, 46 insertions(+), 6 deletions(-) diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c index 033ab7d..fc3b84c 100644 --- a/ofproto/connmgr.c +++ b/ofproto/connmgr.c @@ -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 diff --git a/ofproto/connmgr.h b/ofproto/connmgr.h index 3c9216f..90b5856 100644 --- a/ofproto/connmgr.h +++ b/ofproto/connmgr.h @@ -62,6 +62,15 @@ enum ofconn_async_msg_type { OAM_N_TYPES }; +enum ofproto_packet_in_miss_type { + OFPROTO_PACKET_IN_NO_MISS, /* Not a miss */ + OFPROTO_PACKET_IN_MISS_FLOW, /* Miss handled by a table-miss flow + * See OF1.3.3 section 5.4 */ + OFPROTO_PACKET_IN_MISS_WITHOUT_FLOW, + /* Miss was not handled by a table-miss + * flow */ +}; + /* A packet_in, with extra members to assist in queuing and routing it. */ struct ofproto_packet_in { struct ofputil_packet_in up; @@ -72,7 +81,7 @@ struct ofproto_packet_in { /* 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. */ diff --git a/ofproto/fail-open.c b/ofproto/fail-open.c index 9ac80b6..467cafa 100644 --- a/ofproto/fail-open.c +++ b/ofproto/fail-open.c @@ -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); diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index 0d5b251..035fc3f 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -1238,7 +1238,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); } } diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index d93e5ca..32baa22 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -2136,8 +2136,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); } diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index e5f5131..063bc23 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -3028,6 +3028,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) @@ -4346,6 +4352,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; +} /* Linux VLAN device support (e.g. "eth0.10" for VLAN 10.) * diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h index c09aee6..5df0130 100644 --- a/ofproto/ofproto-dpif.h +++ b/ofproto/ofproto-dpif.h @@ -98,6 +98,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 *); diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h index d116451..363931a 100644 --- a/ofproto/ofproto-provider.h +++ b/ofproto/ofproto-provider.h @@ -419,6 +419,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". * -- 1.8.5.2 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev