summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJustin Pettit <jpettit@ovn.org>2017-07-05 15:17:52 -0700
committerJustin Pettit <jpettit@ovn.org>2018-01-10 16:42:00 -0800
commitd39ec23de38464ee35b3098b9f6c5f06d5191015 (patch)
tree2f9d5eb33373d01dcd6d8c84107a7a588bd9e8b9 /lib
parentfcb9579be3c7717744e63a343a86a0dbcf0d3d78 (diff)
downloadopenvswitch-d39ec23de38464ee35b3098b9f6c5f06d5191015.tar.gz
ofproto-dpif: Don't slow-path controller actions.
Controller actions have become more commonly used for purposes other than just making forwarding decisions (e.g., packet logging). A packet that needs to be copied to the controller and forwarded would always be sent to ovs-vswitchd to be handled, which could negatively affect performance and cause heavier CPU utilization in ovs-vswitchd. This commit changes the behavior so that OpenFlow controller actions become userspace datapath actions while continuing to let packet forwarding and manipulation continue to be handled by the datapath directly. This patch still slow-paths controller actions with the "pause" flag set. A future patch will stop slow-pathing these pause actions as well. Signed-off-by: Justin Pettit <jpettit@ovn.org> Acked-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/odp-util.c54
-rw-r--r--lib/odp-util.h16
2 files changed, 61 insertions, 9 deletions
diff --git a/lib/odp-util.c b/lib/odp-util.c
index a2a8d615f..1b4b847e1 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -478,6 +478,21 @@ format_odp_userspace_action(struct ds *ds, const struct nlattr *attr,
odp_portno_name_format(portno_names,
cookie.ipfix.output_odp_port, ds);
ds_put_char(ds, ')');
+ } else if (cookie.type == USER_ACTION_COOKIE_CONTROLLER) {
+ ds_put_format(ds, ",controller(reason=%"PRIu16
+ ",dont_send=%"PRIu8
+ ",recirc_id=%"PRIu32
+ ",rule_cookie=%#"PRIx64
+ ",controller_id=%"PRIu16
+ ",max_len=%"PRIu16,
+ cookie.controller.reason,
+ cookie.controller.dont_send ? 1 : 0,
+ cookie.controller.recirc_id,
+ ntohll(get_32aligned_be64(
+ &cookie.controller.rule_cookie)),
+ cookie.controller.controller_id,
+ cookie.controller.max_len);
+ ds_put_char(ds, ')');
} else {
userdata_unspec = true;
}
@@ -1128,6 +1143,15 @@ parse_odp_userspace_action(const char *s, struct ofpbuf *actions)
uint32_t collector_set_id;
uint32_t obs_domain_id;
uint32_t obs_point_id;
+
+ /* USER_ACTION_COOKIE_CONTROLLER. */
+ uint8_t dont_send;
+ uint16_t reason;
+ uint32_t recirc_id;
+ ovs_be64 rule_cookie;
+ uint16_t controller_id;
+ uint16_t max_len;
+
int vid, pcp;
int n1 = -1;
if (ovs_scan(&s[n], ",sFlow(vid=%i,"
@@ -1201,8 +1225,26 @@ parse_odp_userspace_action(const char *s, struct ofpbuf *actions)
cookie.ofp_in_port = OFPP_NONE;
cookie.ofproto_uuid = UUID_ZERO;
cookie.ipfix.output_odp_port = u32_to_odp(output);
- } else if (ovs_scan(&s[n], ",userdata(%n",
- &n1)) {
+ } else if (ovs_scan(&s[n], ",controller(reason=%"SCNu16
+ ",dont_send=%"SCNu8
+ ",recirc_id=%"SCNu32
+ ",rule_cookie=%"SCNx64
+ ",controller_id=%"SCNu16
+ ",max_len=%"SCNu16")%n",
+ &reason, &dont_send, &recirc_id, &rule_cookie,
+ &controller_id, &max_len, &n1)) {
+ n += n1;
+ cookie.type = USER_ACTION_COOKIE_CONTROLLER;
+ cookie.ofp_in_port = OFPP_NONE;
+ cookie.ofproto_uuid = UUID_ZERO;
+ cookie.controller.dont_send = dont_send ? true : false;
+ cookie.controller.reason = reason;
+ cookie.controller.recirc_id = recirc_id;
+ put_32aligned_be64(&cookie.controller.rule_cookie,
+ htonll(rule_cookie));
+ cookie.controller.controller_id = controller_id;
+ cookie.controller.max_len = max_len;
+ } else if (ovs_scan(&s[n], ",userdata(%n", &n1)) {
char *end;
n += n1;
@@ -3266,7 +3308,7 @@ format_odp_tun_attr(const struct nlattr *attr, const struct nlattr *mask_attr,
case OVS_TUNNEL_KEY_ATTR_ID:
format_be64(ds, "tun_id", nl_attr_get_be64(a),
ma ? nl_attr_get(ma) : NULL, verbose);
- flags |= FLOW_TNL_F_KEY;
+ flags |= FLOW_TNL_F_KEY;
if (ma) {
mask_flags |= FLOW_TNL_F_KEY;
}
@@ -3302,10 +3344,10 @@ format_odp_tun_attr(const struct nlattr *attr, const struct nlattr *mask_attr,
ma ? nl_attr_get(ma) : NULL, verbose);
break;
case OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT:
- flags |= FLOW_TNL_F_DONT_FRAGMENT;
+ flags |= FLOW_TNL_F_DONT_FRAGMENT;
break;
case OVS_TUNNEL_KEY_ATTR_CSUM:
- flags |= FLOW_TNL_F_CSUM;
+ flags |= FLOW_TNL_F_CSUM;
break;
case OVS_TUNNEL_KEY_ATTR_TP_SRC:
format_be16(ds, "tp_src", nl_attr_get_be16(a),
@@ -3316,7 +3358,7 @@ format_odp_tun_attr(const struct nlattr *attr, const struct nlattr *mask_attr,
ma ? nl_attr_get(ma) : NULL, verbose);
break;
case OVS_TUNNEL_KEY_ATTR_OAM:
- flags |= FLOW_TNL_F_OAM;
+ flags |= FLOW_TNL_F_OAM;
break;
case OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS:
ds_put_cstr(ds, "vxlan(");
diff --git a/lib/odp-util.h b/lib/odp-util.h
index 2a4b3d138..981dcd8f2 100644
--- a/lib/odp-util.h
+++ b/lib/odp-util.h
@@ -42,9 +42,8 @@ struct pkt_metadata;
SPR(SLOW_BFD, "bfd", "Consists of BFD packets") \
SPR(SLOW_LACP, "lacp", "Consists of LACP packets") \
SPR(SLOW_STP, "stp", "Consists of STP packets") \
- SPR(SLOW_LLDP, "lldp", "Consists of LLDP packets") \
- SPR(SLOW_CONTROLLER, "controller", \
- "Sends \"packet-in\" messages to the OpenFlow controller") \
+ SPR(SLOW_LLDP, "lldp", "Consists of LLDP packets") \
+ SPR(SLOW_PAUSE, "pause", "Controller action with pause") \
SPR(SLOW_ACTION, "action", \
"Uses action(s) not supported by datapath")
@@ -298,6 +297,7 @@ enum user_action_cookie_type {
USER_ACTION_COOKIE_SLOW_PATH, /* Userspace must process this flow. */
USER_ACTION_COOKIE_FLOW_SAMPLE, /* Packet for per-flow sampling. */
USER_ACTION_COOKIE_IPFIX, /* Packet for per-bridge IPFIX sampling. */
+ USER_ACTION_COOKIE_CONTROLLER, /* Forward packet to controller. */
};
/* user_action_cookie is passed as argument to OVS_ACTION_ATTR_USERSPACE. */
@@ -333,6 +333,16 @@ struct user_action_cookie {
/* USER_ACTION_COOKIE_IPFIX. */
odp_port_t output_odp_port; /* The output odp port. */
} ipfix;
+
+ struct {
+ /* USER_ACTION_COOKIE_CONTROLLER. */
+ bool dont_send; /* Don't send the packet to controller. */
+ uint16_t reason;
+ uint32_t recirc_id;
+ ovs_32aligned_be64 rule_cookie;
+ uint16_t controller_id;
+ uint16_t max_len;
+ } controller;
};
};
BUILD_ASSERT_DECL(sizeof(struct user_action_cookie) == 48);