aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ip_gre.c
diff options
context:
space:
mode:
authorPravin B Shelar <pshelar@nicira.com>2013-06-17 20:49:38 -0400
committerDavid S. Miller <davem@davemloft.net>2013-06-19 21:07:40 -0400
commitbda7bb46343647f68591366731295a0f3eea59ed (patch)
tree99fa502fe0439a7776227238bfc3a5b0d4dbe7b3 /net/ipv4/ip_gre.c
parent20fd4d1f04da07d09192ad8ad366a70d5125bfaf (diff)
gre: Allow multiple protocol listener for gre protocol.
Currently there is only one user is allowed to register for gre protocol. Following patch adds de-multiplexer. So that multiple modules can listen on gre protocol e.g. kernel gre devices and ovs. Signed-off-by: Pravin B Shelar <pshelar@nicira.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/ip_gre.c')
-rw-r--r--net/ipv4/ip_gre.c173
1 files changed, 26 insertions, 147 deletions
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index a982657d05e7..19863a81cea1 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -121,103 +121,8 @@ static int ipgre_tunnel_init(struct net_device *dev);
121static int ipgre_net_id __read_mostly; 121static int ipgre_net_id __read_mostly;
122static int gre_tap_net_id __read_mostly; 122static int gre_tap_net_id __read_mostly;
123 123
124static __sum16 check_checksum(struct sk_buff *skb) 124static int ipgre_err(struct sk_buff *skb, u32 info,
125{ 125 const struct tnl_ptk_info *tpi)
126 __sum16 csum = 0;
127
128 switch (skb->ip_summed) {
129 case CHECKSUM_COMPLETE:
130 csum = csum_fold(skb->csum);
131
132 if (!csum)
133 break;
134 /* Fall through. */
135
136 case CHECKSUM_NONE:
137 skb->csum = 0;
138 csum = __skb_checksum_complete(skb);
139 skb->ip_summed = CHECKSUM_COMPLETE;
140 break;
141 }
142
143 return csum;
144}
145
146static int ip_gre_calc_hlen(__be16 o_flags)
147{
148 int addend = 4;
149
150 if (o_flags&TUNNEL_CSUM)
151 addend += 4;
152 if (o_flags&TUNNEL_KEY)
153 addend += 4;
154 if (o_flags&TUNNEL_SEQ)
155 addend += 4;
156 return addend;
157}
158
159static int parse_gre_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
160 bool *csum_err, int *hdr_len)
161{
162 unsigned int ip_hlen = ip_hdrlen(skb);
163 const struct gre_base_hdr *greh;
164 __be32 *options;
165
166 if (unlikely(!pskb_may_pull(skb, sizeof(struct gre_base_hdr))))
167 return -EINVAL;
168
169 greh = (struct gre_base_hdr *)(skb_network_header(skb) + ip_hlen);
170 if (unlikely(greh->flags & (GRE_VERSION | GRE_ROUTING)))
171 return -EINVAL;
172
173 tpi->flags = gre_flags_to_tnl_flags(greh->flags);
174 *hdr_len = ip_gre_calc_hlen(tpi->flags);
175
176 if (!pskb_may_pull(skb, *hdr_len))
177 return -EINVAL;
178
179 greh = (struct gre_base_hdr *)(skb_network_header(skb) + ip_hlen);
180
181 tpi->proto = greh->protocol;
182
183 options = (__be32 *)(greh + 1);
184 if (greh->flags & GRE_CSUM) {
185 if (check_checksum(skb)) {
186 *csum_err = true;
187 return -EINVAL;
188 }
189 options++;
190 }
191
192 if (greh->flags & GRE_KEY) {
193 tpi->key = *options;
194 options++;
195 } else
196 tpi->key = 0;
197
198 if (unlikely(greh->flags & GRE_SEQ)) {
199 tpi->seq = *options;
200 options++;
201 } else
202 tpi->seq = 0;
203
204 /* WCCP version 1 and 2 protocol decoding.
205 * - Change protocol to IP
206 * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header
207 */
208 if (greh->flags == 0 && tpi->proto == htons(ETH_P_WCCP)) {
209 tpi->proto = htons(ETH_P_IP);
210 if ((*(u8 *)options & 0xF0) != 0x40) {
211 *hdr_len += 4;
212 if (!pskb_may_pull(skb, *hdr_len))
213 return -EINVAL;
214 }
215 }
216
217 return 0;
218}
219
220static void ipgre_err(struct sk_buff *skb, u32 info)
221{ 126{
222 127
223 /* All the routers (except for Linux) return only 128 /* All the routers (except for Linux) return only
@@ -239,26 +144,18 @@ static void ipgre_err(struct sk_buff *skb, u32 info)
239 const int type = icmp_hdr(skb)->type; 144 const int type = icmp_hdr(skb)->type;
240 const int code = icmp_hdr(skb)->code; 145 const int code = icmp_hdr(skb)->code;
241 struct ip_tunnel *t; 146 struct ip_tunnel *t;
242 struct tnl_ptk_info tpi;
243 int hdr_len;
244 bool csum_err = false;
245
246 if (parse_gre_header(skb, &tpi, &csum_err, &hdr_len)) {
247 if (!csum_err) /* ignore csum errors. */
248 return;
249 }
250 147
251 switch (type) { 148 switch (type) {
252 default: 149 default:
253 case ICMP_PARAMETERPROB: 150 case ICMP_PARAMETERPROB:
254 return; 151 return PACKET_RCVD;
255 152
256 case ICMP_DEST_UNREACH: 153 case ICMP_DEST_UNREACH:
257 switch (code) { 154 switch (code) {
258 case ICMP_SR_FAILED: 155 case ICMP_SR_FAILED:
259 case ICMP_PORT_UNREACH: 156 case ICMP_PORT_UNREACH:
260 /* Impossible event. */ 157 /* Impossible event. */
261 return; 158 return PACKET_RCVD;
262 default: 159 default:
263 /* All others are translated to HOST_UNREACH. 160 /* All others are translated to HOST_UNREACH.
264 rfc2003 contains "deep thoughts" about NET_UNREACH, 161 rfc2003 contains "deep thoughts" about NET_UNREACH,
@@ -269,79 +166,61 @@ static void ipgre_err(struct sk_buff *skb, u32 info)
269 break; 166 break;
270 case ICMP_TIME_EXCEEDED: 167 case ICMP_TIME_EXCEEDED:
271 if (code != ICMP_EXC_TTL) 168 if (code != ICMP_EXC_TTL)
272 return; 169 return PACKET_RCVD;
273 break; 170 break;
274 171
275 case ICMP_REDIRECT: 172 case ICMP_REDIRECT:
276 break; 173 break;
277 } 174 }
278 175
279 if (tpi.proto == htons(ETH_P_TEB)) 176 if (tpi->proto == htons(ETH_P_TEB))
280 itn = net_generic(net, gre_tap_net_id); 177 itn = net_generic(net, gre_tap_net_id);
281 else 178 else
282 itn = net_generic(net, ipgre_net_id); 179 itn = net_generic(net, ipgre_net_id);
283 180
284 iph = (const struct iphdr *)skb->data; 181 iph = (const struct iphdr *)skb->data;
285 t = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi.flags, 182 t = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags,
286 iph->daddr, iph->saddr, tpi.key); 183 iph->daddr, iph->saddr, tpi->key);
287 184
288 if (t == NULL) 185 if (t == NULL)
289 return; 186 return PACKET_REJECT;
290 187
291 if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
292 ipv4_update_pmtu(skb, dev_net(skb->dev), info,
293 t->parms.link, 0, IPPROTO_GRE, 0);
294 return;
295 }
296 if (type == ICMP_REDIRECT) {
297 ipv4_redirect(skb, dev_net(skb->dev), t->parms.link, 0,
298 IPPROTO_GRE, 0);
299 return;
300 }
301 if (t->parms.iph.daddr == 0 || 188 if (t->parms.iph.daddr == 0 ||
302 ipv4_is_multicast(t->parms.iph.daddr)) 189 ipv4_is_multicast(t->parms.iph.daddr))
303 return; 190 return PACKET_RCVD;
304 191
305 if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED) 192 if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
306 return; 193 return PACKET_RCVD;
307 194
308 if (time_before(jiffies, t->err_time + IPTUNNEL_ERR_TIMEO)) 195 if (time_before(jiffies, t->err_time + IPTUNNEL_ERR_TIMEO))
309 t->err_count++; 196 t->err_count++;
310 else 197 else
311 t->err_count = 1; 198 t->err_count = 1;
312 t->err_time = jiffies; 199 t->err_time = jiffies;
200 return PACKET_RCVD;
313} 201}
314 202
315static int ipgre_rcv(struct sk_buff *skb) 203static int ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi)
316{ 204{
317 struct net *net = dev_net(skb->dev); 205 struct net *net = dev_net(skb->dev);
318 struct ip_tunnel_net *itn; 206 struct ip_tunnel_net *itn;
319 const struct iphdr *iph; 207 const struct iphdr *iph;
320 struct ip_tunnel *tunnel; 208 struct ip_tunnel *tunnel;
321 struct tnl_ptk_info tpi;
322 int hdr_len;
323 bool csum_err = false;
324
325 if (parse_gre_header(skb, &tpi, &csum_err, &hdr_len) < 0)
326 goto drop;
327 209
328 if (tpi.proto == htons(ETH_P_TEB)) 210 if (tpi->proto == htons(ETH_P_TEB))
329 itn = net_generic(net, gre_tap_net_id); 211 itn = net_generic(net, gre_tap_net_id);
330 else 212 else
331 itn = net_generic(net, ipgre_net_id); 213 itn = net_generic(net, ipgre_net_id);
332 214
333 iph = ip_hdr(skb); 215 iph = ip_hdr(skb);
334 tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi.flags, 216 tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags,
335 iph->saddr, iph->daddr, tpi.key); 217 iph->saddr, iph->daddr, tpi->key);
336 218
337 if (tunnel) { 219 if (tunnel) {
338 ip_tunnel_rcv(tunnel, skb, &tpi, log_ecn_error); 220 ip_tunnel_rcv(tunnel, skb, tpi, log_ecn_error);
339 return 0; 221 return PACKET_RCVD;
340 } 222 }
341 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); 223 return PACKET_REJECT;
342drop:
343 kfree_skb(skb);
344 return 0;
345} 224}
346 225
347static struct sk_buff *handle_offloads(struct ip_tunnel *tunnel, struct sk_buff *skb) 226static struct sk_buff *handle_offloads(struct ip_tunnel *tunnel, struct sk_buff *skb)
@@ -708,9 +587,10 @@ static int ipgre_tunnel_init(struct net_device *dev)
708 return ip_tunnel_init(dev); 587 return ip_tunnel_init(dev);
709} 588}
710 589
711static const struct gre_protocol ipgre_protocol = { 590static struct gre_cisco_protocol ipgre_protocol = {
712 .handler = ipgre_rcv, 591 .handler = ipgre_rcv,
713 .err_handler = ipgre_err, 592 .err_handler = ipgre_err,
593 .priority = 0,
714}; 594};
715 595
716static int __net_init ipgre_init_net(struct net *net) 596static int __net_init ipgre_init_net(struct net *net)
@@ -978,7 +858,7 @@ static int __init ipgre_init(void)
978 if (err < 0) 858 if (err < 0)
979 goto pnet_tap_faied; 859 goto pnet_tap_faied;
980 860
981 err = gre_add_protocol(&ipgre_protocol, GREPROTO_CISCO); 861 err = gre_cisco_register(&ipgre_protocol);
982 if (err < 0) { 862 if (err < 0) {
983 pr_info("%s: can't add protocol\n", __func__); 863 pr_info("%s: can't add protocol\n", __func__);
984 goto add_proto_failed; 864 goto add_proto_failed;
@@ -997,7 +877,7 @@ static int __init ipgre_init(void)
997tap_ops_failed: 877tap_ops_failed:
998 rtnl_link_unregister(&ipgre_link_ops); 878 rtnl_link_unregister(&ipgre_link_ops);
999rtnl_link_failed: 879rtnl_link_failed:
1000 gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO); 880 gre_cisco_unregister(&ipgre_protocol);
1001add_proto_failed: 881add_proto_failed:
1002 unregister_pernet_device(&ipgre_tap_net_ops); 882 unregister_pernet_device(&ipgre_tap_net_ops);
1003pnet_tap_faied: 883pnet_tap_faied:
@@ -1009,8 +889,7 @@ static void __exit ipgre_fini(void)
1009{ 889{
1010 rtnl_link_unregister(&ipgre_tap_ops); 890 rtnl_link_unregister(&ipgre_tap_ops);
1011 rtnl_link_unregister(&ipgre_link_ops); 891 rtnl_link_unregister(&ipgre_link_ops);
1012 if (gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO) < 0) 892 gre_cisco_unregister(&ipgre_protocol);
1013 pr_info("%s: can't remove protocol\n", __func__);
1014 unregister_pernet_device(&ipgre_tap_net_ops); 893 unregister_pernet_device(&ipgre_tap_net_ops);
1015 unregister_pernet_device(&ipgre_net_ops); 894 unregister_pernet_device(&ipgre_net_ops);
1016} 895}