X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fodp-util.c;h=7f5158fe90f32764823d2411d7891d29de016376;hb=5621afff91b24a9b79b9eab0965dcd888ef810e8;hp=9657595084de2bafd3da8d4df5eefc4f291b5686;hpb=d9065a90b6b955aa38586c952e8804ca7a22547e;p=openvswitch diff --git a/lib/odp-util.c b/lib/odp-util.c index 96575950..7f5158fe 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -62,6 +62,7 @@ odp_action_len(uint16_t type) case OVS_ACTION_ATTR_SET_PRIORITY: return 4; case OVS_ACTION_ATTR_POP_PRIORITY: return 0; + case OVS_ACTION_ATTR_SAMPLE: case OVS_ACTION_ATTR_UNSPEC: case __OVS_ACTION_ATTR_MAX: return -1; @@ -89,13 +90,47 @@ format_generic_odp_action(struct ds *ds, const struct nlattr *a) } } +static void +format_odp_sample_action(struct ds *ds, const struct nlattr *attr) +{ + static const struct nl_policy ovs_sample_policy[] = { + [OVS_SAMPLE_ATTR_PROBABILITY] = { .type = NL_A_U32 }, + [OVS_SAMPLE_ATTR_ACTIONS] = { .type = NL_A_NESTED } + }; + struct nlattr *a[ARRAY_SIZE(ovs_sample_policy)]; + double percentage; + const struct nlattr *nla_acts; + int len; + + ds_put_cstr(ds, "sample"); + + if (!nl_parse_nested(attr, ovs_sample_policy, a, ARRAY_SIZE(a))) { + ds_put_cstr(ds, "(error)"); + return; + } + + percentage = (100.0 * nl_attr_get_u32(a[OVS_SAMPLE_ATTR_PROBABILITY])) / + UINT32_MAX; + + ds_put_format(ds, "(sample=%.1f%%,", percentage); + + ds_put_cstr(ds, "actions("); + nla_acts = nl_attr_get(a[OVS_SAMPLE_ATTR_ACTIONS]); + len = nl_attr_get_size(a[OVS_SAMPLE_ATTR_ACTIONS]); + format_odp_actions(ds, nla_acts, len); + ds_put_format(ds, "))"); +} + void format_odp_action(struct ds *ds, const struct nlattr *a) { const uint8_t *eth; ovs_be32 ip; + struct user_action_cookie cookie; + uint64_t data; - if (nl_attr_get_size(a) != odp_action_len(nl_attr_type(a))) { + if (nl_attr_get_size(a) != odp_action_len(nl_attr_type(a)) && + nl_attr_type(a) != OVS_ACTION_ATTR_SAMPLE) { ds_put_format(ds, "bad length %zu, expected %d for: ", nl_attr_get_size(a), odp_action_len(nl_attr_type(a))); format_generic_odp_action(ds, a); @@ -107,7 +142,21 @@ 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: - ds_put_format(ds, "userspace(%"PRIu64")", nl_attr_get_u64(a)); + 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)); + } break; case OVS_ACTION_ATTR_SET_TUNNEL: ds_put_format(ds, "set_tunnel(%#"PRIx64")", @@ -152,6 +201,9 @@ format_odp_action(struct ds *ds, const struct nlattr *a) case OVS_ACTION_ATTR_POP_PRIORITY: ds_put_cstr(ds, "pop_priority"); break; + case OVS_ACTION_ATTR_SAMPLE: + format_odp_sample_action(ds, a); + break; default: format_generic_odp_action(ds, a); break; @@ -989,10 +1041,6 @@ odp_flow_key_to_flow(const struct nlattr *key, size_t key_len, break; default: - if (type == OVS_KEY_ATTR_UNSPEC - || prev_type == OVS_KEY_ATTR_UNSPEC) { - return EINVAL; - } return EINVAL; }