diff options
| author | Harout Hedeshian <harouth@codeaurora.org> | 2014-06-16 09:26:42 -0600 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-22 11:09:37 -0700 |
| commit | 1afe1dec58534a2efd806e79ef1915d711d19a10 (patch) | |
| tree | d04ce1cf4a173939158a4c919cd49833c31aa1ea | |
| parent | 7d052379ef29c8e49be215e249fdd6558ff116bb (diff) | |
net: core: add MAP support to RPS flow dissector
More efficiently utilize multiple cores when using MAP encoded frames.
RPS flow dissector now appropriately decodes IPv4 and IPv6 frames with
MAP headers prepended.
CRs-Fixed: 681280
Change-Id: Ia4dde47fcc0f3436dcaa71a5160c0a59fe7ed53a
Signed-off-by: Harout Hedeshian <harouth@codeaurora.org>
[subashab@codeaurora.org: resolve trivial merge conflicts]
Signed-off-by: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
| -rw-r--r-- | include/uapi/linux/net_map.h | 3 | ||||
| -rw-r--r-- | net/core/flow_dissector.c | 35 |
2 files changed, 38 insertions, 0 deletions
diff --git a/include/uapi/linux/net_map.h b/include/uapi/linux/net_map.h index 879a854cb1da..544cf03b9a5e 100644 --- a/include/uapi/linux/net_map.h +++ b/include/uapi/linux/net_map.h @@ -23,5 +23,8 @@ struct rmnet_map_header_s { #define RMNET_MAP_GET_LENGTH(Y) (ntohs( \ ((struct rmnet_map_header_s *)Y->data)->pkt_len)) +#define RMNET_IP_VER_MASK 0xF0 +#define RMNET_IPV4 0x40 +#define RMNET_IPV6 0x60 #endif /* _NET_MAP_H_ */ diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index d79699c9d1b9..b32fe21ba2e6 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c @@ -18,6 +18,7 @@ #include <linux/mpls.h> #include <net/flow_dissector.h> #include <scsi/fc/fc_fcoe.h> +#include <linux/net_map.h> static bool dissector_uses_key(const struct flow_dissector *flow_dissector, enum flow_dissector_key_id key_id) @@ -335,6 +336,40 @@ mpls: goto out_good; } + case __constant_htons(ETH_P_MAP): { + struct { + struct rmnet_map_header_s map; + uint8_t proto; + } *map, _map; + unsigned int maplen; + + map = skb_header_pointer(skb, nhoff, sizeof(_map), &_map); + if (!map) + return false; + + /* Is MAP command? */ + if (map->map.cd_bit) + return false; + + /* Is aggregated frame? */ + maplen = ntohs(map->map.pkt_len); + maplen += map->map.pad_len; + maplen += sizeof(struct rmnet_map_header_s); + if (maplen < skb->len) + return false; + + nhoff += sizeof(struct rmnet_map_header_s); + switch (map->proto & RMNET_IP_VER_MASK) { + case RMNET_IPV4: + proto = htons(ETH_P_IP); + goto ip; + case RMNET_IPV6: + proto = htons(ETH_P_IPV6); + goto ipv6; + default: + return false; + } + } case htons(ETH_P_FCOE): key_control->thoff = (u16)(nhoff + FCOE_HEADER_LEN); /* fall through */ |
