X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fodp-util.c;h=8fa3359493b11523fb43a729e06bf45c2e727210;hb=fe13b0e71752a5eb30b21e7a09d2f9370bc02387;hp=490d35eb252a06dc283082b4ba7942e4035d99f0;hpb=deedf7e78b249383d6f7b385f9d04e08e33d0e3f;p=openvswitch diff --git a/lib/odp-util.c b/lib/odp-util.c index 490d35eb..8fa33594 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010, 2011 Nicira Networks. + * Copyright (c) 2009, 2010, 2011, 2012 Nicira Networks. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -189,9 +189,7 @@ format_odp_userspace_action(struct ds *ds, const struct nlattr *attr) 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) { + 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), @@ -280,10 +278,16 @@ format_odp_actions(struct ds *ds, const struct nlattr *actions, format_odp_action(ds, a); } if (left) { + int i; + if (left == actions_len) { ds_put_cstr(ds, ""); } - ds_put_format(ds, ",***%u leftover bytes***", left); + ds_put_format(ds, ",***%u leftover bytes*** (", left); + for (i = 0; i < left; i++) { + ds_put_format(ds, "%02x", ((const uint8_t *) a)[i]); + } + ds_put_char(ds, ')'); } } else { ds_put_cstr(ds, "drop"); @@ -328,7 +332,6 @@ parse_odp_action(const char *s, const struct shash *port_names, { unsigned long long int pid; - unsigned long long int length; unsigned long long int ifindex; char userdata_s[32]; int n_output; @@ -338,16 +341,6 @@ parse_odp_action(const char *s, const struct shash *port_names, if (sscanf(s, "userspace(pid=%lli)%n", &pid, &n) > 0 && n > 0) { odp_put_userspace_action(pid, NULL, actions); return n; - } else if (sscanf(s, "userspace(pid=%lli,controller,length=%lli)%n", - &pid, &length, &n) > 0 && n > 0) { - struct user_action_cookie cookie; - - cookie.type = USER_ACTION_COOKIE_CONTROLLER; - cookie.n_output = 0; - cookie.vlan_tci = htons(0); - cookie.data = length; - odp_put_userspace_action(pid, &cookie, actions); - return n; } else if (sscanf(s, "userspace(pid=%lli,sFlow,n_output=%i,vid=%i," "pcp=%i,ifindex=%lli)%n", &pid, &n_output, &vid, &pcp, &ifindex, &n) > 0 && n > 0) { @@ -740,10 +733,16 @@ odp_flow_key_format(const struct nlattr *key, size_t key_len, struct ds *ds) format_odp_key_attr(a, ds); } if (left) { + int i; + if (left == key_len) { ds_put_cstr(ds, ""); } - ds_put_format(ds, ",***%u leftover bytes***", left); + ds_put_format(ds, ",***%u leftover bytes*** (", left); + for (i = 0; i < left; i++) { + ds_put_format(ds, "%02x", ((const uint8_t *) a)[i]); + } + ds_put_char(ds, ')'); } } else { ds_put_cstr(ds, ""); @@ -1149,11 +1148,11 @@ odp_flow_key_from_string(const char *s, const struct shash *port_names, } static uint8_t -ovs_to_odp_frag(uint8_t ovs_frag) +ovs_to_odp_frag(uint8_t nw_frag) { - return (ovs_frag & FLOW_NW_FRAG_LATER ? OVS_FRAG_TYPE_LATER - : ovs_frag & FLOW_NW_FRAG_ANY ? OVS_FRAG_TYPE_FIRST - : OVS_FRAG_TYPE_NONE); + return (nw_frag == 0 ? OVS_FRAG_TYPE_NONE + : nw_frag == FLOW_NW_FRAG_ANY ? OVS_FRAG_TYPE_FIRST + : OVS_FRAG_TYPE_LATER); } /* Appends a representation of 'flow' as OVS_KEY_ATTR_* attributes to 'buf'. */ @@ -1700,6 +1699,24 @@ odp_flow_key_to_flow(const struct nlattr *key, size_t key_len, expected_attrs, flow, key, key_len); } +/* Returns 'fitness' as a string, for use in debug messages. */ +const char * +odp_key_fitness_to_string(enum odp_key_fitness fitness) +{ + switch (fitness) { + case ODP_FIT_PERFECT: + return "OK"; + case ODP_FIT_TOO_MUCH: + return "too_much"; + case ODP_FIT_TOO_LITTLE: + return "too_little"; + case ODP_FIT_ERROR: + return "error"; + default: + return ""; + } +} + /* Appends an OVS_ACTION_ATTR_USERSPACE action to 'odp_actions' that specifies * Netlink PID 'pid'. If 'cookie' is nonnull, adds a userdata attribute whose * contents contains 'cookie' and returns the offset within 'odp_actions' of @@ -1791,16 +1808,11 @@ commit_vlan_action(const struct flow *flow, struct flow *base, } static void -commit_set_nw_action(const struct flow *flow, struct flow *base, +commit_set_ipv4_action(const struct flow *flow, struct flow *base, struct ofpbuf *odp_actions) { struct ovs_key_ipv4 ipv4_key; - if (base->dl_type != htons(ETH_TYPE_IP) || - !base->nw_src || !base->nw_dst) { - return; - } - if (base->nw_src == flow->nw_src && base->nw_dst == flow->nw_dst && base->nw_tos == flow->nw_tos && @@ -1814,14 +1826,58 @@ commit_set_nw_action(const struct flow *flow, struct flow *base, ipv4_key.ipv4_tos = base->nw_tos = flow->nw_tos; ipv4_key.ipv4_ttl = base->nw_ttl = flow->nw_ttl; ipv4_key.ipv4_proto = base->nw_proto; - ipv4_key.ipv4_frag = (base->nw_frag == 0 ? OVS_FRAG_TYPE_NONE - : base->nw_frag == FLOW_NW_FRAG_ANY - ? OVS_FRAG_TYPE_FIRST : OVS_FRAG_TYPE_LATER); + ipv4_key.ipv4_frag = ovs_to_odp_frag(base->nw_frag); commit_set_action(odp_actions, OVS_KEY_ATTR_IPV4, &ipv4_key, sizeof(ipv4_key)); } +static void +commit_set_ipv6_action(const struct flow *flow, struct flow *base, + struct ofpbuf *odp_actions) +{ + struct ovs_key_ipv6 ipv6_key; + + if (ipv6_addr_equals(&base->ipv6_src, &flow->ipv6_src) && + ipv6_addr_equals(&base->ipv6_dst, &flow->ipv6_dst) && + base->ipv6_label == flow->ipv6_label && + base->nw_tos == flow->nw_tos && + base->nw_ttl == flow->nw_ttl && + base->nw_frag == flow->nw_frag) { + return; + } + + base->ipv6_src = flow->ipv6_src; + memcpy(&ipv6_key.ipv6_src, &base->ipv6_src, sizeof(ipv6_key.ipv6_src)); + base->ipv6_dst = flow->ipv6_dst; + memcpy(&ipv6_key.ipv6_dst, &base->ipv6_dst, sizeof(ipv6_key.ipv6_dst)); + + ipv6_key.ipv6_label = base->ipv6_label = flow->ipv6_label; + ipv6_key.ipv6_tclass = base->nw_tos = flow->nw_tos; + ipv6_key.ipv6_hlimit = base->nw_ttl = flow->nw_ttl; + ipv6_key.ipv6_proto = base->nw_proto; + ipv6_key.ipv6_frag = ovs_to_odp_frag(base->nw_frag); + + commit_set_action(odp_actions, OVS_KEY_ATTR_IPV6, + &ipv6_key, sizeof(ipv6_key)); +} + +static void +commit_set_nw_action(const struct flow *flow, struct flow *base, + struct ofpbuf *odp_actions) +{ + /* Check if flow really have an IP header. */ + if (!flow->nw_proto) { + return; + } + + if (base->dl_type == htons(ETH_TYPE_IP)) { + commit_set_ipv4_action(flow, base, odp_actions); + } else if (base->dl_type == htons(ETH_TYPE_IPV6)) { + commit_set_ipv6_action(flow, base, odp_actions); + } +} + static void commit_set_port_action(const struct flow *flow, struct flow *base, struct ofpbuf *odp_actions)