Commit cd79a238 authored by Tom Herbert's avatar Tom Herbert Committed by David S. Miller

flow_dissector: Add flags argument to skb_flow_dissector functions

The flags argument will allow control of the dissection process (for
instance whether to parse beyond L3).
Signed-off-by: default avatarTom Herbert <tom@herbertland.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a6e544b0
...@@ -3095,7 +3095,7 @@ static bool bond_flow_dissect(struct bonding *bond, struct sk_buff *skb, ...@@ -3095,7 +3095,7 @@ static bool bond_flow_dissect(struct bonding *bond, struct sk_buff *skb,
int noff, proto = -1; int noff, proto = -1;
if (bond->params.xmit_policy > BOND_XMIT_POLICY_LAYER23) if (bond->params.xmit_policy > BOND_XMIT_POLICY_LAYER23)
return skb_flow_dissect_flow_keys(skb, fk); return skb_flow_dissect_flow_keys(skb, fk, 0);
fk->ports.ports = 0; fk->ports.ports = 0;
noff = skb_network_offset(skb); noff = skb_network_offset(skb);
......
...@@ -177,7 +177,7 @@ int enic_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb, ...@@ -177,7 +177,7 @@ int enic_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
int res, i; int res, i;
enic = netdev_priv(dev); enic = netdev_priv(dev);
res = skb_flow_dissect_flow_keys(skb, &keys); res = skb_flow_dissect_flow_keys(skb, &keys, 0);
if (!res || keys.basic.n_proto != htons(ETH_P_IP) || if (!res || keys.basic.n_proto != htons(ETH_P_IP) ||
(keys.basic.ip_proto != IPPROTO_TCP && (keys.basic.ip_proto != IPPROTO_TCP &&
keys.basic.ip_proto != IPPROTO_UDP)) keys.basic.ip_proto != IPPROTO_UDP))
......
...@@ -239,7 +239,7 @@ static bool netvsc_set_hash(u32 *hash, struct sk_buff *skb) ...@@ -239,7 +239,7 @@ static bool netvsc_set_hash(u32 *hash, struct sk_buff *skb)
struct flow_keys flow; struct flow_keys flow;
int data_len; int data_len;
if (!skb_flow_dissect_flow_keys(skb, &flow) || if (!skb_flow_dissect_flow_keys(skb, &flow, 0) ||
!(flow.basic.n_proto == htons(ETH_P_IP) || !(flow.basic.n_proto == htons(ETH_P_IP) ||
flow.basic.n_proto == htons(ETH_P_IPV6))) flow.basic.n_proto == htons(ETH_P_IPV6)))
return false; return false;
......
...@@ -991,31 +991,34 @@ void skb_flow_dissector_init(struct flow_dissector *flow_dissector, ...@@ -991,31 +991,34 @@ void skb_flow_dissector_init(struct flow_dissector *flow_dissector,
bool __skb_flow_dissect(const struct sk_buff *skb, bool __skb_flow_dissect(const struct sk_buff *skb,
struct flow_dissector *flow_dissector, struct flow_dissector *flow_dissector,
void *target_container, void *target_container,
void *data, __be16 proto, int nhoff, int hlen); void *data, __be16 proto, int nhoff, int hlen,
unsigned int flags);
static inline bool skb_flow_dissect(const struct sk_buff *skb, static inline bool skb_flow_dissect(const struct sk_buff *skb,
struct flow_dissector *flow_dissector, struct flow_dissector *flow_dissector,
void *target_container) void *target_container, unsigned int flags)
{ {
return __skb_flow_dissect(skb, flow_dissector, target_container, return __skb_flow_dissect(skb, flow_dissector, target_container,
NULL, 0, 0, 0); NULL, 0, 0, 0, flags);
} }
static inline bool skb_flow_dissect_flow_keys(const struct sk_buff *skb, static inline bool skb_flow_dissect_flow_keys(const struct sk_buff *skb,
struct flow_keys *flow) struct flow_keys *flow,
unsigned int flags)
{ {
memset(flow, 0, sizeof(*flow)); memset(flow, 0, sizeof(*flow));
return __skb_flow_dissect(skb, &flow_keys_dissector, flow, return __skb_flow_dissect(skb, &flow_keys_dissector, flow,
NULL, 0, 0, 0); NULL, 0, 0, 0, flags);
} }
static inline bool skb_flow_dissect_flow_keys_buf(struct flow_keys *flow, static inline bool skb_flow_dissect_flow_keys_buf(struct flow_keys *flow,
void *data, __be16 proto, void *data, __be16 proto,
int nhoff, int hlen) int nhoff, int hlen,
unsigned int flags)
{ {
memset(flow, 0, sizeof(*flow)); memset(flow, 0, sizeof(*flow));
return __skb_flow_dissect(NULL, &flow_keys_buf_dissector, flow, return __skb_flow_dissect(NULL, &flow_keys_buf_dissector, flow,
data, proto, nhoff, hlen); data, proto, nhoff, hlen, flags);
} }
static inline __u32 skb_get_hash(struct sk_buff *skb) static inline __u32 skb_get_hash(struct sk_buff *skb)
...@@ -2046,7 +2049,7 @@ static inline void skb_probe_transport_header(struct sk_buff *skb, ...@@ -2046,7 +2049,7 @@ static inline void skb_probe_transport_header(struct sk_buff *skb,
if (skb_transport_header_was_set(skb)) if (skb_transport_header_was_set(skb))
return; return;
else if (skb_flow_dissect_flow_keys(skb, &keys)) else if (skb_flow_dissect_flow_keys(skb, &keys, 0))
skb_set_transport_header(skb, keys.control.thoff); skb_set_transport_header(skb, keys.control.thoff);
else else
skb_set_transport_header(skb, offset_hint); skb_set_transport_header(skb, offset_hint);
......
...@@ -121,7 +121,8 @@ EXPORT_SYMBOL(__skb_flow_get_ports); ...@@ -121,7 +121,8 @@ EXPORT_SYMBOL(__skb_flow_get_ports);
bool __skb_flow_dissect(const struct sk_buff *skb, bool __skb_flow_dissect(const struct sk_buff *skb,
struct flow_dissector *flow_dissector, struct flow_dissector *flow_dissector,
void *target_container, void *target_container,
void *data, __be16 proto, int nhoff, int hlen) void *data, __be16 proto, int nhoff, int hlen,
unsigned int flags)
{ {
struct flow_dissector_key_control *key_control; struct flow_dissector_key_control *key_control;
struct flow_dissector_key_basic *key_basic; struct flow_dissector_key_basic *key_basic;
...@@ -556,7 +557,7 @@ EXPORT_SYMBOL(flow_hash_from_keys); ...@@ -556,7 +557,7 @@ EXPORT_SYMBOL(flow_hash_from_keys);
static inline u32 ___skb_get_hash(const struct sk_buff *skb, static inline u32 ___skb_get_hash(const struct sk_buff *skb,
struct flow_keys *keys, u32 keyval) struct flow_keys *keys, u32 keyval)
{ {
if (!skb_flow_dissect_flow_keys(skb, keys)) if (!skb_flow_dissect_flow_keys(skb, keys, 0))
return 0; return 0;
return __flow_hash_from_keys(keys, keyval); return __flow_hash_from_keys(keys, keyval);
...@@ -726,7 +727,7 @@ u32 skb_get_poff(const struct sk_buff *skb) ...@@ -726,7 +727,7 @@ u32 skb_get_poff(const struct sk_buff *skb)
{ {
struct flow_keys keys; struct flow_keys keys;
if (!skb_flow_dissect_flow_keys(skb, &keys)) if (!skb_flow_dissect_flow_keys(skb, &keys, 0))
return 0; return 0;
return __skb_get_poff(skb, skb->data, &keys, skb_headlen(skb)); return __skb_get_poff(skb, skb->data, &keys, skb_headlen(skb));
......
...@@ -132,7 +132,7 @@ u32 eth_get_headlen(void *data, unsigned int len) ...@@ -132,7 +132,7 @@ u32 eth_get_headlen(void *data, unsigned int len)
/* parse any remaining L2/L3 headers, check for L4 */ /* parse any remaining L2/L3 headers, check for L4 */
if (!skb_flow_dissect_flow_keys_buf(&keys, data, eth->h_proto, if (!skb_flow_dissect_flow_keys_buf(&keys, data, eth->h_proto,
sizeof(*eth), len)) sizeof(*eth), len, 0))
return max_t(u32, keys.control.thoff, sizeof(*eth)); return max_t(u32, keys.control.thoff, sizeof(*eth));
/* parse for any L4 headers */ /* parse for any L4 headers */
......
...@@ -301,7 +301,7 @@ static int flow_classify(struct sk_buff *skb, const struct tcf_proto *tp, ...@@ -301,7 +301,7 @@ static int flow_classify(struct sk_buff *skb, const struct tcf_proto *tp,
keymask = f->keymask; keymask = f->keymask;
if (keymask & FLOW_KEYS_NEEDED) if (keymask & FLOW_KEYS_NEEDED)
skb_flow_dissect_flow_keys(skb, &flow_keys); skb_flow_dissect_flow_keys(skb, &flow_keys, 0);
for (n = 0; n < f->nkeys; n++) { for (n = 0; n < f->nkeys; n++) {
key = ffs(keymask) - 1; key = ffs(keymask) - 1;
......
...@@ -129,7 +129,7 @@ static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp, ...@@ -129,7 +129,7 @@ static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp,
* so do it rather here. * so do it rather here.
*/ */
skb_key.basic.n_proto = skb->protocol; skb_key.basic.n_proto = skb->protocol;
skb_flow_dissect(skb, &head->dissector, &skb_key); skb_flow_dissect(skb, &head->dissector, &skb_key, 0);
fl_set_masked_key(&skb_mkey, &skb_key, &head->mask); fl_set_masked_key(&skb_mkey, &skb_key, &head->mask);
......
...@@ -170,13 +170,13 @@ static bool choke_match_flow(struct sk_buff *skb1, ...@@ -170,13 +170,13 @@ static bool choke_match_flow(struct sk_buff *skb1,
if (!choke_skb_cb(skb1)->keys_valid) { if (!choke_skb_cb(skb1)->keys_valid) {
choke_skb_cb(skb1)->keys_valid = 1; choke_skb_cb(skb1)->keys_valid = 1;
skb_flow_dissect_flow_keys(skb1, &temp); skb_flow_dissect_flow_keys(skb1, &temp, 0);
make_flow_keys_digest(&choke_skb_cb(skb1)->keys, &temp); make_flow_keys_digest(&choke_skb_cb(skb1)->keys, &temp);
} }
if (!choke_skb_cb(skb2)->keys_valid) { if (!choke_skb_cb(skb2)->keys_valid) {
choke_skb_cb(skb2)->keys_valid = 1; choke_skb_cb(skb2)->keys_valid = 1;
skb_flow_dissect_flow_keys(skb2, &temp); skb_flow_dissect_flow_keys(skb2, &temp, 0);
make_flow_keys_digest(&choke_skb_cb(skb2)->keys, &temp); make_flow_keys_digest(&choke_skb_cb(skb2)->keys, &temp);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment