aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Herbert <tom@herbertland.com>2015-09-01 12:24:27 -0400
committerDavid S. Miller <davem@davemloft.net>2015-09-01 18:06:22 -0400
commitcd79a2382aa5dcefa6e21a7c59bb1bb19e53b74d (patch)
treec252b8dd90eddc8d635356e8b394bd455cac51c0
parenta6e544b0a88b53114bfa5a57e21b7be7a8dfc9d0 (diff)
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: Tom Herbert <tom@herbertland.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/bonding/bond_main.c2
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_clsf.c2
-rw-r--r--drivers/net/hyperv/netvsc_drv.c2
-rw-r--r--include/linux/skbuff.h19
-rw-r--r--net/core/flow_dissector.c7
-rw-r--r--net/ethernet/eth.c2
-rw-r--r--net/sched/cls_flow.c2
-rw-r--r--net/sched/cls_flower.c2
-rw-r--r--net/sched/sch_choke.c4
9 files changed, 23 insertions, 19 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 06e2d01f0b4e..771a449d2f56 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3095,7 +3095,7 @@ static bool bond_flow_dissect(struct bonding *bond, struct sk_buff *skb,
3095 int noff, proto = -1; 3095 int noff, proto = -1;
3096 3096
3097 if (bond->params.xmit_policy > BOND_XMIT_POLICY_LAYER23) 3097 if (bond->params.xmit_policy > BOND_XMIT_POLICY_LAYER23)
3098 return skb_flow_dissect_flow_keys(skb, fk); 3098 return skb_flow_dissect_flow_keys(skb, fk, 0);
3099 3099
3100 fk->ports.ports = 0; 3100 fk->ports.ports = 0;
3101 noff = skb_network_offset(skb); 3101 noff = skb_network_offset(skb);
diff --git a/drivers/net/ethernet/cisco/enic/enic_clsf.c b/drivers/net/ethernet/cisco/enic/enic_clsf.c
index d106186f4f4a..3c677ed3c29e 100644
--- a/drivers/net/ethernet/cisco/enic/enic_clsf.c
+++ b/drivers/net/ethernet/cisco/enic/enic_clsf.c
@@ -177,7 +177,7 @@ int enic_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
177 int res, i; 177 int res, i;
178 178
179 enic = netdev_priv(dev); 179 enic = netdev_priv(dev);
180 res = skb_flow_dissect_flow_keys(skb, &keys); 180 res = skb_flow_dissect_flow_keys(skb, &keys, 0);
181 if (!res || keys.basic.n_proto != htons(ETH_P_IP) || 181 if (!res || keys.basic.n_proto != htons(ETH_P_IP) ||
182 (keys.basic.ip_proto != IPPROTO_TCP && 182 (keys.basic.ip_proto != IPPROTO_TCP &&
183 keys.basic.ip_proto != IPPROTO_UDP)) 183 keys.basic.ip_proto != IPPROTO_UDP))
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 2990024b90f9..409b48e1e589 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -239,7 +239,7 @@ static bool netvsc_set_hash(u32 *hash, struct sk_buff *skb)
239 struct flow_keys flow; 239 struct flow_keys flow;
240 int data_len; 240 int data_len;
241 241
242 if (!skb_flow_dissect_flow_keys(skb, &flow) || 242 if (!skb_flow_dissect_flow_keys(skb, &flow, 0) ||
243 !(flow.basic.n_proto == htons(ETH_P_IP) || 243 !(flow.basic.n_proto == htons(ETH_P_IP) ||
244 flow.basic.n_proto == htons(ETH_P_IPV6))) 244 flow.basic.n_proto == htons(ETH_P_IPV6)))
245 return false; 245 return false;
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index bbe41bccfc5f..9e62687c70f3 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -991,31 +991,34 @@ void skb_flow_dissector_init(struct flow_dissector *flow_dissector,
991bool __skb_flow_dissect(const struct sk_buff *skb, 991bool __skb_flow_dissect(const struct sk_buff *skb,
992 struct flow_dissector *flow_dissector, 992 struct flow_dissector *flow_dissector,
993 void *target_container, 993 void *target_container,
994 void *data, __be16 proto, int nhoff, int hlen); 994 void *data, __be16 proto, int nhoff, int hlen,
995 unsigned int flags);
995 996
996static inline bool skb_flow_dissect(const struct sk_buff *skb, 997static inline bool skb_flow_dissect(const struct sk_buff *skb,
997 struct flow_dissector *flow_dissector, 998 struct flow_dissector *flow_dissector,
998 void *target_container) 999 void *target_container, unsigned int flags)
999{ 1000{
1000 return __skb_flow_dissect(skb, flow_dissector, target_container, 1001 return __skb_flow_dissect(skb, flow_dissector, target_container,
1001 NULL, 0, 0, 0); 1002 NULL, 0, 0, 0, flags);
1002} 1003}
1003 1004
1004static inline bool skb_flow_dissect_flow_keys(const struct sk_buff *skb, 1005static inline bool skb_flow_dissect_flow_keys(const struct sk_buff *skb,
1005 struct flow_keys *flow) 1006 struct flow_keys *flow,
1007 unsigned int flags)
1006{ 1008{
1007 memset(flow, 0, sizeof(*flow)); 1009 memset(flow, 0, sizeof(*flow));
1008 return __skb_flow_dissect(skb, &flow_keys_dissector, flow, 1010 return __skb_flow_dissect(skb, &flow_keys_dissector, flow,
1009 NULL, 0, 0, 0); 1011 NULL, 0, 0, 0, flags);
1010} 1012}
1011 1013
1012static inline bool skb_flow_dissect_flow_keys_buf(struct flow_keys *flow, 1014static inline bool skb_flow_dissect_flow_keys_buf(struct flow_keys *flow,
1013 void *data, __be16 proto, 1015 void *data, __be16 proto,
1014 int nhoff, int hlen) 1016 int nhoff, int hlen,
1017 unsigned int flags)
1015{ 1018{
1016 memset(flow, 0, sizeof(*flow)); 1019 memset(flow, 0, sizeof(*flow));
1017 return __skb_flow_dissect(NULL, &flow_keys_buf_dissector, flow, 1020 return __skb_flow_dissect(NULL, &flow_keys_buf_dissector, flow,
1018 data, proto, nhoff, hlen); 1021 data, proto, nhoff, hlen, flags);
1019} 1022}
1020 1023
1021static inline __u32 skb_get_hash(struct sk_buff *skb) 1024static 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 2049
2047 if (skb_transport_header_was_set(skb)) 2050 if (skb_transport_header_was_set(skb))
2048 return; 2051 return;
2049 else if (skb_flow_dissect_flow_keys(skb, &keys)) 2052 else if (skb_flow_dissect_flow_keys(skb, &keys, 0))
2050 skb_set_transport_header(skb, keys.control.thoff); 2053 skb_set_transport_header(skb, keys.control.thoff);
2051 else 2054 else
2052 skb_set_transport_header(skb, offset_hint); 2055 skb_set_transport_header(skb, offset_hint);
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 22f3d768b459..c3d9807cb34e 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -121,7 +121,8 @@ EXPORT_SYMBOL(__skb_flow_get_ports);
121bool __skb_flow_dissect(const struct sk_buff *skb, 121bool __skb_flow_dissect(const struct sk_buff *skb,
122 struct flow_dissector *flow_dissector, 122 struct flow_dissector *flow_dissector,
123 void *target_container, 123 void *target_container,
124 void *data, __be16 proto, int nhoff, int hlen) 124 void *data, __be16 proto, int nhoff, int hlen,
125 unsigned int flags)
125{ 126{
126 struct flow_dissector_key_control *key_control; 127 struct flow_dissector_key_control *key_control;
127 struct flow_dissector_key_basic *key_basic; 128 struct flow_dissector_key_basic *key_basic;
@@ -556,7 +557,7 @@ EXPORT_SYMBOL(flow_hash_from_keys);
556static inline u32 ___skb_get_hash(const struct sk_buff *skb, 557static inline u32 ___skb_get_hash(const struct sk_buff *skb,
557 struct flow_keys *keys, u32 keyval) 558 struct flow_keys *keys, u32 keyval)
558{ 559{
559 if (!skb_flow_dissect_flow_keys(skb, keys)) 560 if (!skb_flow_dissect_flow_keys(skb, keys, 0))
560 return 0; 561 return 0;
561 562
562 return __flow_hash_from_keys(keys, keyval); 563 return __flow_hash_from_keys(keys, keyval);
@@ -726,7 +727,7 @@ u32 skb_get_poff(const struct sk_buff *skb)
726{ 727{
727 struct flow_keys keys; 728 struct flow_keys keys;
728 729
729 if (!skb_flow_dissect_flow_keys(skb, &keys)) 730 if (!skb_flow_dissect_flow_keys(skb, &keys, 0))
730 return 0; 731 return 0;
731 732
732 return __skb_get_poff(skb, skb->data, &keys, skb_headlen(skb)); 733 return __skb_get_poff(skb, skb->data, &keys, skb_headlen(skb));
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index 217127c3a3ef..d850fdc828f9 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -132,7 +132,7 @@ u32 eth_get_headlen(void *data, unsigned int len)
132 132
133 /* parse any remaining L2/L3 headers, check for L4 */ 133 /* parse any remaining L2/L3 headers, check for L4 */
134 if (!skb_flow_dissect_flow_keys_buf(&keys, data, eth->h_proto, 134 if (!skb_flow_dissect_flow_keys_buf(&keys, data, eth->h_proto,
135 sizeof(*eth), len)) 135 sizeof(*eth), len, 0))
136 return max_t(u32, keys.control.thoff, sizeof(*eth)); 136 return max_t(u32, keys.control.thoff, sizeof(*eth));
137 137
138 /* parse for any L4 headers */ 138 /* parse for any L4 headers */
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
index bb2a0f529c1f..536838b657bf 100644
--- a/net/sched/cls_flow.c
+++ b/net/sched/cls_flow.c
@@ -301,7 +301,7 @@ static int flow_classify(struct sk_buff *skb, const struct tcf_proto *tp,
301 301
302 keymask = f->keymask; 302 keymask = f->keymask;
303 if (keymask & FLOW_KEYS_NEEDED) 303 if (keymask & FLOW_KEYS_NEEDED)
304 skb_flow_dissect_flow_keys(skb, &flow_keys); 304 skb_flow_dissect_flow_keys(skb, &flow_keys, 0);
305 305
306 for (n = 0; n < f->nkeys; n++) { 306 for (n = 0; n < f->nkeys; n++) {
307 key = ffs(keymask) - 1; 307 key = ffs(keymask) - 1;
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index 2f3d03f99487..57692947ebbe 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -129,7 +129,7 @@ static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp,
129 * so do it rather here. 129 * so do it rather here.
130 */ 130 */
131 skb_key.basic.n_proto = skb->protocol; 131 skb_key.basic.n_proto = skb->protocol;
132 skb_flow_dissect(skb, &head->dissector, &skb_key); 132 skb_flow_dissect(skb, &head->dissector, &skb_key, 0);
133 133
134 fl_set_masked_key(&skb_mkey, &skb_key, &head->mask); 134 fl_set_masked_key(&skb_mkey, &skb_key, &head->mask);
135 135
diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c
index 665bde07916b..02bfd3d1c4f0 100644
--- a/net/sched/sch_choke.c
+++ b/net/sched/sch_choke.c
@@ -170,13 +170,13 @@ static bool choke_match_flow(struct sk_buff *skb1,
170 170
171 if (!choke_skb_cb(skb1)->keys_valid) { 171 if (!choke_skb_cb(skb1)->keys_valid) {
172 choke_skb_cb(skb1)->keys_valid = 1; 172 choke_skb_cb(skb1)->keys_valid = 1;
173 skb_flow_dissect_flow_keys(skb1, &temp); 173 skb_flow_dissect_flow_keys(skb1, &temp, 0);
174 make_flow_keys_digest(&choke_skb_cb(skb1)->keys, &temp); 174 make_flow_keys_digest(&choke_skb_cb(skb1)->keys, &temp);
175 } 175 }
176 176
177 if (!choke_skb_cb(skb2)->keys_valid) { 177 if (!choke_skb_cb(skb2)->keys_valid) {
178 choke_skb_cb(skb2)->keys_valid = 1; 178 choke_skb_cb(skb2)->keys_valid = 1;
179 skb_flow_dissect_flow_keys(skb2, &temp); 179 skb_flow_dissect_flow_keys(skb2, &temp, 0);
180 make_flow_keys_digest(&choke_skb_cb(skb2)->keys, &temp); 180 make_flow_keys_digest(&choke_skb_cb(skb2)->keys, &temp);
181 } 181 }
182 182