diff options
author | Ben Pfaff <blp@nicira.com> | 2011-10-12 16:24:54 -0700 |
---|---|---|
committer | Ben Pfaff <blp@nicira.com> | 2011-10-12 16:27:00 -0700 |
commit | 98403001ece61cbf783297c467a06032b200b8d0 (patch) | |
tree | 19123701b08ce6ac93b2a4bf0b4f6fab7042d562 /lib/odp-util.c | |
parent | 69ebca1e35a39d75032f3d8092da563f60673110 (diff) |
datapath: Move Netlink PID for userspace actions from flows to actions.
Commit b063d9f06 "datapath: Use unicast Netlink sockets for upcalls" that
switched from multicast to unicast Netlink for sending upcalls added a
Netlink PID to each kernel flow, used by OVS_ACTION_ATTR_USERSPACE actions
within the flow as target.
This commit drops this per-flow PID in favor of a per-action PID, because
that is more flexible. It does not yet make use of this additional
flexibility, so behavior should not change.
Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Jesse Gross <jesse@nicira.com>
Bug #7559.
Diffstat (limited to 'lib/odp-util.c')
-rw-r--r-- | lib/odp-util.c | 78 |
1 files changed, 56 insertions, 22 deletions
diff --git a/lib/odp-util.c b/lib/odp-util.c index c67e14a9..08378a68 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -39,6 +39,15 @@ * interactions with the datapath. */ +/* Returns one the following for the action with the given OVS_ACTION_ATTR_* + * 'type': + * + * - For an action whose argument has a fixed length, returned that + * nonnegative length in bytes. + * + * - For an action with a variable-length argument, returns -2. + * + * - For an invalid 'type', returns -1. */ int odp_action_len(uint16_t type) { @@ -48,7 +57,7 @@ odp_action_len(uint16_t type) switch ((enum ovs_action_type) type) { case OVS_ACTION_ATTR_OUTPUT: return 4; - case OVS_ACTION_ATTR_USERSPACE: return 8; + case OVS_ACTION_ATTR_USERSPACE: return -2; case OVS_ACTION_ATTR_PUSH_VLAN: return 2; case OVS_ACTION_ATTR_POP_VLAN: return 0; case OVS_ACTION_ATTR_SET_DL_SRC: return ETH_ADDR_LEN; @@ -61,8 +70,8 @@ odp_action_len(uint16_t type) case OVS_ACTION_ATTR_SET_TUNNEL: return 8; case OVS_ACTION_ATTR_SET_PRIORITY: return 4; case OVS_ACTION_ATTR_POP_PRIORITY: return 0; + case OVS_ACTION_ATTR_SAMPLE: return -2; - case OVS_ACTION_ATTR_SAMPLE: case OVS_ACTION_ATTR_UNSPEC: case __OVS_ACTION_ATTR_MAX: return -1; @@ -121,18 +130,57 @@ format_odp_sample_action(struct ds *ds, const struct nlattr *attr) ds_put_format(ds, "))"); } +static void +format_odp_userspace_action(struct ds *ds, const struct nlattr *attr) +{ + static const struct nl_policy ovs_userspace_policy[] = { + [OVS_USERSPACE_ATTR_PID] = { .type = NL_A_U32 }, + [OVS_USERSPACE_ATTR_USERDATA] = { .type = NL_A_U64, .optional = true }, + }; + struct nlattr *a[ARRAY_SIZE(ovs_userspace_policy)]; + + if (!nl_parse_nested(attr, ovs_userspace_policy, a, ARRAY_SIZE(a))) { + ds_put_cstr(ds, "userspace(error)"); + return; + } + + ds_put_format(ds, "userspace(pid=%"PRIu32, + nl_attr_get_u32(a[OVS_USERSPACE_ATTR_PID])); + + if (a[OVS_USERSPACE_ATTR_USERDATA]) { + uint64_t userdata = nl_attr_get_u64(a[OVS_USERSPACE_ATTR_USERDATA]); + struct user_action_cookie cookie; + + memcpy(&cookie, &userdata, sizeof cookie); + + if (cookie.type == USER_ACTION_COOKIE_CONTROLLER) { + ds_put_format(ds, ",controller,length=%"PRIu32, + cookie.data); + } else if (cookie.type == USER_ACTION_COOKIE_SFLOW) { + ds_put_format(ds, ",sFlow,n_output=%"PRIu8"," + "vid=%"PRIu16",pcp=%"PRIu8",ifindex=%"PRIu32, + cookie.n_output, vlan_tci_to_vid(cookie.vlan_tci), + vlan_tci_to_pcp(cookie.vlan_tci), cookie.data); + } else { + ds_put_format(ds, ",userdata=0x%"PRIx64, userdata); + } + } + + ds_put_char(ds, ')'); +} + + void format_odp_action(struct ds *ds, const struct nlattr *a) { const uint8_t *eth; + int expected_len; ovs_be32 ip; - struct user_action_cookie cookie; - uint64_t data; - if (nl_attr_get_size(a) != odp_action_len(nl_attr_type(a)) && - nl_attr_type(a) != OVS_ACTION_ATTR_SAMPLE) { + expected_len = odp_action_len(nl_attr_type(a)); + if (expected_len != -2 && nl_attr_get_size(a) != expected_len) { ds_put_format(ds, "bad length %zu, expected %d for: ", - nl_attr_get_size(a), odp_action_len(nl_attr_type(a))); + nl_attr_get_size(a), expected_len); format_generic_odp_action(ds, a); return; } @@ -142,21 +190,7 @@ format_odp_action(struct ds *ds, const struct nlattr *a) ds_put_format(ds, "%"PRIu16, nl_attr_get_u32(a)); break; case OVS_ACTION_ATTR_USERSPACE: - data = nl_attr_get_u64(a); - memcpy(&cookie, &data, sizeof(cookie)); - - if (cookie.type == USER_ACTION_COOKIE_CONTROLLER) { - ds_put_format(ds, "userspace(controller,length=%"PRIu32")", - cookie.data); - } else if (cookie.type == USER_ACTION_COOKIE_SFLOW) { - ds_put_format(ds, "userspace(sFlow,n_output=%"PRIu8"," - "vid=%"PRIu16",pcp=%"PRIu8",ifindex=%"PRIu32")", - cookie.n_output, vlan_tci_to_vid(cookie.vlan_tci), - vlan_tci_to_pcp(cookie.vlan_tci), cookie.data); - } else { - ds_put_format(ds, "userspace(unknown,data=0x%"PRIx64")", - nl_attr_get_u64(a)); - } + format_odp_userspace_action(ds, a); break; case OVS_ACTION_ATTR_SET_TUNNEL: ds_put_format(ds, "set_tunnel(%#"PRIx64")", |