aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
Diffstat (limited to 'net/core')
-rw-r--r--net/core/flow_dissector.c40
1 files changed, 26 insertions, 14 deletions
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 5f362c1d0332..660c6492fb78 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -34,29 +34,40 @@ static void iph_to_flow_copy_addrs(struct flow_keys *flow, const struct iphdr *i
34 * The function will try to retrieve the ports at offset thoff + poff where poff 34 * The function will try to retrieve the ports at offset thoff + poff where poff
35 * is the protocol port offset returned from proto_ports_offset 35 * is the protocol port offset returned from proto_ports_offset
36 */ 36 */
37__be32 skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto) 37__be32 __skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto,
38 void *data, int hlen)
38{ 39{
39 int poff = proto_ports_offset(ip_proto); 40 int poff = proto_ports_offset(ip_proto);
40 41
42 if (!data) {
43 data = skb->data;
44 hlen = skb_headlen(skb);
45 }
46
41 if (poff >= 0) { 47 if (poff >= 0) {
42 __be32 *ports, _ports; 48 __be32 *ports, _ports;
43 49
44 ports = skb_header_pointer(skb, thoff + poff, 50 ports = __skb_header_pointer(skb, thoff + poff,
45 sizeof(_ports), &_ports); 51 sizeof(_ports), data, hlen, &_ports);
46 if (ports) 52 if (ports)
47 return *ports; 53 return *ports;
48 } 54 }
49 55
50 return 0; 56 return 0;
51} 57}
52EXPORT_SYMBOL(skb_flow_get_ports); 58EXPORT_SYMBOL(__skb_flow_get_ports);
53 59
54bool skb_flow_dissect(const struct sk_buff *skb, struct flow_keys *flow) 60bool __skb_flow_dissect(const struct sk_buff *skb, struct flow_keys *flow, void *data, int hlen)
55{ 61{
56 int nhoff = skb_network_offset(skb); 62 int nhoff = skb_network_offset(skb);
57 u8 ip_proto; 63 u8 ip_proto;
58 __be16 proto = skb->protocol; 64 __be16 proto = skb->protocol;
59 65
66 if (!data) {
67 data = skb->data;
68 hlen = skb_headlen(skb);
69 }
70
60 memset(flow, 0, sizeof(*flow)); 71 memset(flow, 0, sizeof(*flow));
61 72
62again: 73again:
@@ -65,7 +76,7 @@ again:
65 const struct iphdr *iph; 76 const struct iphdr *iph;
66 struct iphdr _iph; 77 struct iphdr _iph;
67ip: 78ip:
68 iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph); 79 iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);
69 if (!iph || iph->ihl < 5) 80 if (!iph || iph->ihl < 5)
70 return false; 81 return false;
71 nhoff += iph->ihl * 4; 82 nhoff += iph->ihl * 4;
@@ -83,7 +94,7 @@ ip:
83 __be32 flow_label; 94 __be32 flow_label;
84 95
85ipv6: 96ipv6:
86 iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph); 97 iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);
87 if (!iph) 98 if (!iph)
88 return false; 99 return false;
89 100
@@ -113,7 +124,7 @@ ipv6:
113 const struct vlan_hdr *vlan; 124 const struct vlan_hdr *vlan;
114 struct vlan_hdr _vlan; 125 struct vlan_hdr _vlan;
115 126
116 vlan = skb_header_pointer(skb, nhoff, sizeof(_vlan), &_vlan); 127 vlan = __skb_header_pointer(skb, nhoff, sizeof(_vlan), data, hlen, &_vlan);
117 if (!vlan) 128 if (!vlan)
118 return false; 129 return false;
119 130
@@ -126,7 +137,7 @@ ipv6:
126 struct pppoe_hdr hdr; 137 struct pppoe_hdr hdr;
127 __be16 proto; 138 __be16 proto;
128 } *hdr, _hdr; 139 } *hdr, _hdr;
129 hdr = skb_header_pointer(skb, nhoff, sizeof(_hdr), &_hdr); 140 hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
130 if (!hdr) 141 if (!hdr)
131 return false; 142 return false;
132 proto = hdr->proto; 143 proto = hdr->proto;
@@ -151,7 +162,7 @@ ipv6:
151 __be16 proto; 162 __be16 proto;
152 } *hdr, _hdr; 163 } *hdr, _hdr;
153 164
154 hdr = skb_header_pointer(skb, nhoff, sizeof(_hdr), &_hdr); 165 hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
155 if (!hdr) 166 if (!hdr)
156 return false; 167 return false;
157 /* 168 /*
@@ -171,8 +182,9 @@ ipv6:
171 const struct ethhdr *eth; 182 const struct ethhdr *eth;
172 struct ethhdr _eth; 183 struct ethhdr _eth;
173 184
174 eth = skb_header_pointer(skb, nhoff, 185 eth = __skb_header_pointer(skb, nhoff,
175 sizeof(_eth), &_eth); 186 sizeof(_eth),
187 data, hlen, &_eth);
176 if (!eth) 188 if (!eth)
177 return false; 189 return false;
178 proto = eth->h_proto; 190 proto = eth->h_proto;
@@ -194,12 +206,12 @@ ipv6:
194 206
195 flow->n_proto = proto; 207 flow->n_proto = proto;
196 flow->ip_proto = ip_proto; 208 flow->ip_proto = ip_proto;
197 flow->ports = skb_flow_get_ports(skb, nhoff, ip_proto); 209 flow->ports = __skb_flow_get_ports(skb, nhoff, ip_proto, data, hlen);
198 flow->thoff = (u16) nhoff; 210 flow->thoff = (u16) nhoff;
199 211
200 return true; 212 return true;
201} 213}
202EXPORT_SYMBOL(skb_flow_dissect); 214EXPORT_SYMBOL(__skb_flow_dissect);
203 215
204static u32 hashrnd __read_mostly; 216static u32 hashrnd __read_mostly;
205static __always_inline void __flow_hash_secret_init(void) 217static __always_inline void __flow_hash_secret_init(void)