From 32260212a0687b6d14544a93a17363683bf41ea5 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Thu, 13 Mar 2014 15:52:55 +0900 Subject: [PATCH] ofproto-dpif: Differentiate between different miss types in packet in 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 Signed-off-by: Ben Pfaff --- ofproto/connmgr.c | 3 ++- ofproto/connmgr.h | 25 ++++++++++++++++++++----- 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, 56 insertions(+), 10 deletions(-) diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c index 0058309b4..9bc189793 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 3c9216ffb..c4cfd8337 100644 --- a/ofproto/connmgr.h +++ b/ofproto/connmgr.h @@ -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. */ diff --git a/ofproto/fail-open.c b/ofproto/fail-open.c index 9ac80b6d1..467cafaf5 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 56e6d24dc..0048943e9 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -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); } } diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 9d7c75251..9b6ce104e 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -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); } diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index cb3014224..8ce439d9f 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -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; +} /* Linux VLAN device support (e.g. "eth0.10" for VLAN 10.) * diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h index 5409ce7f0..06fde3fbe 100644 --- a/ofproto/ofproto-dpif.h +++ b/ofproto/ofproto-dpif.h @@ -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 *); diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h index 28223fea7..dd10f3a2e 100644 --- a/ofproto/ofproto-provider.h +++ b/ofproto/ofproto-provider.h @@ -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". * -- 2.43.0