diff options
Diffstat (limited to 'net/ipv4/ip_gre.c')
-rw-r--r-- | net/ipv4/ip_gre.c | 487 |
1 files changed, 439 insertions, 48 deletions
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 2a61158ea722..85c487b8572b 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/inetdevice.h> | 27 | #include <linux/inetdevice.h> |
28 | #include <linux/igmp.h> | 28 | #include <linux/igmp.h> |
29 | #include <linux/netfilter_ipv4.h> | 29 | #include <linux/netfilter_ipv4.h> |
30 | #include <linux/etherdevice.h> | ||
30 | #include <linux/if_ether.h> | 31 | #include <linux/if_ether.h> |
31 | 32 | ||
32 | #include <net/sock.h> | 33 | #include <net/sock.h> |
@@ -41,6 +42,7 @@ | |||
41 | #include <net/xfrm.h> | 42 | #include <net/xfrm.h> |
42 | #include <net/net_namespace.h> | 43 | #include <net/net_namespace.h> |
43 | #include <net/netns/generic.h> | 44 | #include <net/netns/generic.h> |
45 | #include <net/rtnetlink.h> | ||
44 | 46 | ||
45 | #ifdef CONFIG_IPV6 | 47 | #ifdef CONFIG_IPV6 |
46 | #include <net/ipv6.h> | 48 | #include <net/ipv6.h> |
@@ -117,8 +119,10 @@ | |||
117 | Alexey Kuznetsov. | 119 | Alexey Kuznetsov. |
118 | */ | 120 | */ |
119 | 121 | ||
122 | static struct rtnl_link_ops ipgre_link_ops __read_mostly; | ||
120 | static int ipgre_tunnel_init(struct net_device *dev); | 123 | static int ipgre_tunnel_init(struct net_device *dev); |
121 | static void ipgre_tunnel_setup(struct net_device *dev); | 124 | static void ipgre_tunnel_setup(struct net_device *dev); |
125 | static int ipgre_tunnel_bind_dev(struct net_device *dev); | ||
122 | 126 | ||
123 | /* Fallback tunnel: no source, no destination, no key, no options */ | 127 | /* Fallback tunnel: no source, no destination, no key, no options */ |
124 | 128 | ||
@@ -163,38 +167,64 @@ static DEFINE_RWLOCK(ipgre_lock); | |||
163 | /* Given src, dst and key, find appropriate for input tunnel. */ | 167 | /* Given src, dst and key, find appropriate for input tunnel. */ |
164 | 168 | ||
165 | static struct ip_tunnel * ipgre_tunnel_lookup(struct net *net, | 169 | static struct ip_tunnel * ipgre_tunnel_lookup(struct net *net, |
166 | __be32 remote, __be32 local, __be32 key) | 170 | __be32 remote, __be32 local, |
171 | __be32 key, __be16 gre_proto) | ||
167 | { | 172 | { |
168 | unsigned h0 = HASH(remote); | 173 | unsigned h0 = HASH(remote); |
169 | unsigned h1 = HASH(key); | 174 | unsigned h1 = HASH(key); |
170 | struct ip_tunnel *t; | 175 | struct ip_tunnel *t; |
176 | struct ip_tunnel *t2 = NULL; | ||
171 | struct ipgre_net *ign = net_generic(net, ipgre_net_id); | 177 | struct ipgre_net *ign = net_generic(net, ipgre_net_id); |
178 | int dev_type = (gre_proto == htons(ETH_P_TEB)) ? | ||
179 | ARPHRD_ETHER : ARPHRD_IPGRE; | ||
172 | 180 | ||
173 | for (t = ign->tunnels_r_l[h0^h1]; t; t = t->next) { | 181 | for (t = ign->tunnels_r_l[h0^h1]; t; t = t->next) { |
174 | if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) { | 182 | if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) { |
175 | if (t->parms.i_key == key && (t->dev->flags&IFF_UP)) | 183 | if (t->parms.i_key == key && t->dev->flags & IFF_UP) { |
176 | return t; | 184 | if (t->dev->type == dev_type) |
185 | return t; | ||
186 | if (t->dev->type == ARPHRD_IPGRE && !t2) | ||
187 | t2 = t; | ||
188 | } | ||
177 | } | 189 | } |
178 | } | 190 | } |
191 | |||
179 | for (t = ign->tunnels_r[h0^h1]; t; t = t->next) { | 192 | for (t = ign->tunnels_r[h0^h1]; t; t = t->next) { |
180 | if (remote == t->parms.iph.daddr) { | 193 | if (remote == t->parms.iph.daddr) { |
181 | if (t->parms.i_key == key && (t->dev->flags&IFF_UP)) | 194 | if (t->parms.i_key == key && t->dev->flags & IFF_UP) { |
182 | return t; | 195 | if (t->dev->type == dev_type) |
196 | return t; | ||
197 | if (t->dev->type == ARPHRD_IPGRE && !t2) | ||
198 | t2 = t; | ||
199 | } | ||
183 | } | 200 | } |
184 | } | 201 | } |
202 | |||
185 | for (t = ign->tunnels_l[h1]; t; t = t->next) { | 203 | for (t = ign->tunnels_l[h1]; t; t = t->next) { |
186 | if (local == t->parms.iph.saddr || | 204 | if (local == t->parms.iph.saddr || |
187 | (local == t->parms.iph.daddr && | 205 | (local == t->parms.iph.daddr && |
188 | ipv4_is_multicast(local))) { | 206 | ipv4_is_multicast(local))) { |
189 | if (t->parms.i_key == key && (t->dev->flags&IFF_UP)) | 207 | if (t->parms.i_key == key && t->dev->flags & IFF_UP) { |
190 | return t; | 208 | if (t->dev->type == dev_type) |
209 | return t; | ||
210 | if (t->dev->type == ARPHRD_IPGRE && !t2) | ||
211 | t2 = t; | ||
212 | } | ||
191 | } | 213 | } |
192 | } | 214 | } |
215 | |||
193 | for (t = ign->tunnels_wc[h1]; t; t = t->next) { | 216 | for (t = ign->tunnels_wc[h1]; t; t = t->next) { |
194 | if (t->parms.i_key == key && (t->dev->flags&IFF_UP)) | 217 | if (t->parms.i_key == key && t->dev->flags & IFF_UP) { |
195 | return t; | 218 | if (t->dev->type == dev_type) |
219 | return t; | ||
220 | if (t->dev->type == ARPHRD_IPGRE && !t2) | ||
221 | t2 = t; | ||
222 | } | ||
196 | } | 223 | } |
197 | 224 | ||
225 | if (t2) | ||
226 | return t2; | ||
227 | |||
198 | if (ign->fb_tunnel_dev->flags&IFF_UP) | 228 | if (ign->fb_tunnel_dev->flags&IFF_UP) |
199 | return netdev_priv(ign->fb_tunnel_dev); | 229 | return netdev_priv(ign->fb_tunnel_dev); |
200 | return NULL; | 230 | return NULL; |
@@ -249,25 +279,37 @@ static void ipgre_tunnel_unlink(struct ipgre_net *ign, struct ip_tunnel *t) | |||
249 | } | 279 | } |
250 | } | 280 | } |
251 | 281 | ||
252 | static struct ip_tunnel * ipgre_tunnel_locate(struct net *net, | 282 | static struct ip_tunnel *ipgre_tunnel_find(struct net *net, |
253 | struct ip_tunnel_parm *parms, int create) | 283 | struct ip_tunnel_parm *parms, |
284 | int type) | ||
254 | { | 285 | { |
255 | __be32 remote = parms->iph.daddr; | 286 | __be32 remote = parms->iph.daddr; |
256 | __be32 local = parms->iph.saddr; | 287 | __be32 local = parms->iph.saddr; |
257 | __be32 key = parms->i_key; | 288 | __be32 key = parms->i_key; |
258 | struct ip_tunnel *t, **tp, *nt; | 289 | struct ip_tunnel *t, **tp; |
290 | struct ipgre_net *ign = net_generic(net, ipgre_net_id); | ||
291 | |||
292 | for (tp = __ipgre_bucket(ign, parms); (t = *tp) != NULL; tp = &t->next) | ||
293 | if (local == t->parms.iph.saddr && | ||
294 | remote == t->parms.iph.daddr && | ||
295 | key == t->parms.i_key && | ||
296 | type == t->dev->type) | ||
297 | break; | ||
298 | |||
299 | return t; | ||
300 | } | ||
301 | |||
302 | static struct ip_tunnel * ipgre_tunnel_locate(struct net *net, | ||
303 | struct ip_tunnel_parm *parms, int create) | ||
304 | { | ||
305 | struct ip_tunnel *t, *nt; | ||
259 | struct net_device *dev; | 306 | struct net_device *dev; |
260 | char name[IFNAMSIZ]; | 307 | char name[IFNAMSIZ]; |
261 | struct ipgre_net *ign = net_generic(net, ipgre_net_id); | 308 | struct ipgre_net *ign = net_generic(net, ipgre_net_id); |
262 | 309 | ||
263 | for (tp = __ipgre_bucket(ign, parms); (t = *tp) != NULL; tp = &t->next) { | 310 | t = ipgre_tunnel_find(net, parms, ARPHRD_IPGRE); |
264 | if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) { | 311 | if (t || !create) |
265 | if (key == t->parms.i_key) | 312 | return t; |
266 | return t; | ||
267 | } | ||
268 | } | ||
269 | if (!create) | ||
270 | return NULL; | ||
271 | 313 | ||
272 | if (parms->name[0]) | 314 | if (parms->name[0]) |
273 | strlcpy(name, parms->name, IFNAMSIZ); | 315 | strlcpy(name, parms->name, IFNAMSIZ); |
@@ -285,9 +327,11 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct net *net, | |||
285 | goto failed_free; | 327 | goto failed_free; |
286 | } | 328 | } |
287 | 329 | ||
288 | dev->init = ipgre_tunnel_init; | ||
289 | nt = netdev_priv(dev); | 330 | nt = netdev_priv(dev); |
290 | nt->parms = *parms; | 331 | nt->parms = *parms; |
332 | dev->rtnl_link_ops = &ipgre_link_ops; | ||
333 | |||
334 | dev->mtu = ipgre_tunnel_bind_dev(dev); | ||
291 | 335 | ||
292 | if (register_netdevice(dev) < 0) | 336 | if (register_netdevice(dev) < 0) |
293 | goto failed_free; | 337 | goto failed_free; |
@@ -380,8 +424,9 @@ static void ipgre_err(struct sk_buff *skb, u32 info) | |||
380 | 424 | ||
381 | read_lock(&ipgre_lock); | 425 | read_lock(&ipgre_lock); |
382 | t = ipgre_tunnel_lookup(dev_net(skb->dev), iph->daddr, iph->saddr, | 426 | t = ipgre_tunnel_lookup(dev_net(skb->dev), iph->daddr, iph->saddr, |
383 | (flags&GRE_KEY) ? | 427 | flags & GRE_KEY ? |
384 | *(((__be32*)p) + (grehlen>>2) - 1) : 0); | 428 | *(((__be32 *)p) + (grehlen / 4) - 1) : 0, |
429 | p[1]); | ||
385 | if (t == NULL || t->parms.iph.daddr == 0 || | 430 | if (t == NULL || t->parms.iph.daddr == 0 || |
386 | ipv4_is_multicast(t->parms.iph.daddr)) | 431 | ipv4_is_multicast(t->parms.iph.daddr)) |
387 | goto out; | 432 | goto out; |
@@ -431,6 +476,8 @@ static int ipgre_rcv(struct sk_buff *skb) | |||
431 | u32 seqno = 0; | 476 | u32 seqno = 0; |
432 | struct ip_tunnel *tunnel; | 477 | struct ip_tunnel *tunnel; |
433 | int offset = 4; | 478 | int offset = 4; |
479 | __be16 gre_proto; | ||
480 | unsigned int len; | ||
434 | 481 | ||
435 | if (!pskb_may_pull(skb, 16)) | 482 | if (!pskb_may_pull(skb, 16)) |
436 | goto drop_nolock; | 483 | goto drop_nolock; |
@@ -470,20 +517,22 @@ static int ipgre_rcv(struct sk_buff *skb) | |||
470 | } | 517 | } |
471 | } | 518 | } |
472 | 519 | ||
520 | gre_proto = *(__be16 *)(h + 2); | ||
521 | |||
473 | read_lock(&ipgre_lock); | 522 | read_lock(&ipgre_lock); |
474 | if ((tunnel = ipgre_tunnel_lookup(dev_net(skb->dev), | 523 | if ((tunnel = ipgre_tunnel_lookup(dev_net(skb->dev), |
475 | iph->saddr, iph->daddr, key)) != NULL) { | 524 | iph->saddr, iph->daddr, key, |
525 | gre_proto))) { | ||
476 | struct net_device_stats *stats = &tunnel->dev->stats; | 526 | struct net_device_stats *stats = &tunnel->dev->stats; |
477 | 527 | ||
478 | secpath_reset(skb); | 528 | secpath_reset(skb); |
479 | 529 | ||
480 | skb->protocol = *(__be16*)(h + 2); | 530 | skb->protocol = gre_proto; |
481 | /* WCCP version 1 and 2 protocol decoding. | 531 | /* WCCP version 1 and 2 protocol decoding. |
482 | * - Change protocol to IP | 532 | * - Change protocol to IP |
483 | * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header | 533 | * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header |
484 | */ | 534 | */ |
485 | if (flags == 0 && | 535 | if (flags == 0 && gre_proto == htons(ETH_P_WCCP)) { |
486 | skb->protocol == htons(ETH_P_WCCP)) { | ||
487 | skb->protocol = htons(ETH_P_IP); | 536 | skb->protocol = htons(ETH_P_IP); |
488 | if ((*(h + offset) & 0xF0) != 0x40) | 537 | if ((*(h + offset) & 0xF0) != 0x40) |
489 | offset += 4; | 538 | offset += 4; |
@@ -491,7 +540,6 @@ static int ipgre_rcv(struct sk_buff *skb) | |||
491 | 540 | ||
492 | skb->mac_header = skb->network_header; | 541 | skb->mac_header = skb->network_header; |
493 | __pskb_pull(skb, offset); | 542 | __pskb_pull(skb, offset); |
494 | skb_reset_network_header(skb); | ||
495 | skb_postpull_rcsum(skb, skb_transport_header(skb), offset); | 543 | skb_postpull_rcsum(skb, skb_transport_header(skb), offset); |
496 | skb->pkt_type = PACKET_HOST; | 544 | skb->pkt_type = PACKET_HOST; |
497 | #ifdef CONFIG_NET_IPGRE_BROADCAST | 545 | #ifdef CONFIG_NET_IPGRE_BROADCAST |
@@ -519,13 +567,32 @@ static int ipgre_rcv(struct sk_buff *skb) | |||
519 | } | 567 | } |
520 | tunnel->i_seqno = seqno + 1; | 568 | tunnel->i_seqno = seqno + 1; |
521 | } | 569 | } |
570 | |||
571 | len = skb->len; | ||
572 | |||
573 | /* Warning: All skb pointers will be invalidated! */ | ||
574 | if (tunnel->dev->type == ARPHRD_ETHER) { | ||
575 | if (!pskb_may_pull(skb, ETH_HLEN)) { | ||
576 | stats->rx_length_errors++; | ||
577 | stats->rx_errors++; | ||
578 | goto drop; | ||
579 | } | ||
580 | |||
581 | iph = ip_hdr(skb); | ||
582 | skb->protocol = eth_type_trans(skb, tunnel->dev); | ||
583 | skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN); | ||
584 | } | ||
585 | |||
522 | stats->rx_packets++; | 586 | stats->rx_packets++; |
523 | stats->rx_bytes += skb->len; | 587 | stats->rx_bytes += len; |
524 | skb->dev = tunnel->dev; | 588 | skb->dev = tunnel->dev; |
525 | dst_release(skb->dst); | 589 | dst_release(skb->dst); |
526 | skb->dst = NULL; | 590 | skb->dst = NULL; |
527 | nf_reset(skb); | 591 | nf_reset(skb); |
592 | |||
593 | skb_reset_network_header(skb); | ||
528 | ipgre_ecn_decapsulate(iph, skb); | 594 | ipgre_ecn_decapsulate(iph, skb); |
595 | |||
529 | netif_rx(skb); | 596 | netif_rx(skb); |
530 | read_unlock(&ipgre_lock); | 597 | read_unlock(&ipgre_lock); |
531 | return(0); | 598 | return(0); |
@@ -560,7 +627,10 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
560 | goto tx_error; | 627 | goto tx_error; |
561 | } | 628 | } |
562 | 629 | ||
563 | if (dev->header_ops) { | 630 | if (dev->type == ARPHRD_ETHER) |
631 | IPCB(skb)->flags = 0; | ||
632 | |||
633 | if (dev->header_ops && dev->type == ARPHRD_IPGRE) { | ||
564 | gre_hlen = 0; | 634 | gre_hlen = 0; |
565 | tiph = (struct iphdr*)skb->data; | 635 | tiph = (struct iphdr*)skb->data; |
566 | } else { | 636 | } else { |
@@ -637,7 +707,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
637 | 707 | ||
638 | df = tiph->frag_off; | 708 | df = tiph->frag_off; |
639 | if (df) | 709 | if (df) |
640 | mtu = dst_mtu(&rt->u.dst) - tunnel->hlen; | 710 | mtu = dst_mtu(&rt->u.dst) - dev->hard_header_len - tunnel->hlen; |
641 | else | 711 | else |
642 | mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu; | 712 | mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu; |
643 | 713 | ||
@@ -703,7 +773,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
703 | old_iph = ip_hdr(skb); | 773 | old_iph = ip_hdr(skb); |
704 | } | 774 | } |
705 | 775 | ||
706 | skb->transport_header = skb->network_header; | 776 | skb_reset_transport_header(skb); |
707 | skb_push(skb, gre_hlen); | 777 | skb_push(skb, gre_hlen); |
708 | skb_reset_network_header(skb); | 778 | skb_reset_network_header(skb); |
709 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); | 779 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); |
@@ -736,8 +806,9 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
736 | iph->ttl = dst_metric(&rt->u.dst, RTAX_HOPLIMIT); | 806 | iph->ttl = dst_metric(&rt->u.dst, RTAX_HOPLIMIT); |
737 | } | 807 | } |
738 | 808 | ||
739 | ((__be16*)(iph+1))[0] = tunnel->parms.o_flags; | 809 | ((__be16 *)(iph + 1))[0] = tunnel->parms.o_flags; |
740 | ((__be16*)(iph+1))[1] = skb->protocol; | 810 | ((__be16 *)(iph + 1))[1] = (dev->type == ARPHRD_ETHER) ? |
811 | htons(ETH_P_TEB) : skb->protocol; | ||
741 | 812 | ||
742 | if (tunnel->parms.o_flags&(GRE_KEY|GRE_CSUM|GRE_SEQ)) { | 813 | if (tunnel->parms.o_flags&(GRE_KEY|GRE_CSUM|GRE_SEQ)) { |
743 | __be32 *ptr = (__be32*)(((u8*)iph) + tunnel->hlen - 4); | 814 | __be32 *ptr = (__be32*)(((u8*)iph) + tunnel->hlen - 4); |
@@ -773,7 +844,7 @@ tx_error: | |||
773 | return 0; | 844 | return 0; |
774 | } | 845 | } |
775 | 846 | ||
776 | static void ipgre_tunnel_bind_dev(struct net_device *dev) | 847 | static int ipgre_tunnel_bind_dev(struct net_device *dev) |
777 | { | 848 | { |
778 | struct net_device *tdev = NULL; | 849 | struct net_device *tdev = NULL; |
779 | struct ip_tunnel *tunnel; | 850 | struct ip_tunnel *tunnel; |
@@ -785,7 +856,7 @@ static void ipgre_tunnel_bind_dev(struct net_device *dev) | |||
785 | tunnel = netdev_priv(dev); | 856 | tunnel = netdev_priv(dev); |
786 | iph = &tunnel->parms.iph; | 857 | iph = &tunnel->parms.iph; |
787 | 858 | ||
788 | /* Guess output device to choose reasonable mtu and hard_header_len */ | 859 | /* Guess output device to choose reasonable mtu and needed_headroom */ |
789 | 860 | ||
790 | if (iph->daddr) { | 861 | if (iph->daddr) { |
791 | struct flowi fl = { .oif = tunnel->parms.link, | 862 | struct flowi fl = { .oif = tunnel->parms.link, |
@@ -799,14 +870,16 @@ static void ipgre_tunnel_bind_dev(struct net_device *dev) | |||
799 | tdev = rt->u.dst.dev; | 870 | tdev = rt->u.dst.dev; |
800 | ip_rt_put(rt); | 871 | ip_rt_put(rt); |
801 | } | 872 | } |
802 | dev->flags |= IFF_POINTOPOINT; | 873 | |
874 | if (dev->type != ARPHRD_ETHER) | ||
875 | dev->flags |= IFF_POINTOPOINT; | ||
803 | } | 876 | } |
804 | 877 | ||
805 | if (!tdev && tunnel->parms.link) | 878 | if (!tdev && tunnel->parms.link) |
806 | tdev = __dev_get_by_index(dev_net(dev), tunnel->parms.link); | 879 | tdev = __dev_get_by_index(dev_net(dev), tunnel->parms.link); |
807 | 880 | ||
808 | if (tdev) { | 881 | if (tdev) { |
809 | hlen = tdev->hard_header_len; | 882 | hlen = tdev->hard_header_len + tdev->needed_headroom; |
810 | mtu = tdev->mtu; | 883 | mtu = tdev->mtu; |
811 | } | 884 | } |
812 | dev->iflink = tunnel->parms.link; | 885 | dev->iflink = tunnel->parms.link; |
@@ -820,10 +893,15 @@ static void ipgre_tunnel_bind_dev(struct net_device *dev) | |||
820 | if (tunnel->parms.o_flags&GRE_SEQ) | 893 | if (tunnel->parms.o_flags&GRE_SEQ) |
821 | addend += 4; | 894 | addend += 4; |
822 | } | 895 | } |
823 | dev->hard_header_len = hlen + addend; | 896 | dev->needed_headroom = addend + hlen; |
824 | dev->mtu = mtu - addend; | 897 | mtu -= dev->hard_header_len - addend; |
898 | |||
899 | if (mtu < 68) | ||
900 | mtu = 68; | ||
901 | |||
825 | tunnel->hlen = addend; | 902 | tunnel->hlen = addend; |
826 | 903 | ||
904 | return mtu; | ||
827 | } | 905 | } |
828 | 906 | ||
829 | static int | 907 | static int |
@@ -917,7 +995,7 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
917 | t->parms.iph.frag_off = p.iph.frag_off; | 995 | t->parms.iph.frag_off = p.iph.frag_off; |
918 | if (t->parms.link != p.link) { | 996 | if (t->parms.link != p.link) { |
919 | t->parms.link = p.link; | 997 | t->parms.link = p.link; |
920 | ipgre_tunnel_bind_dev(dev); | 998 | dev->mtu = ipgre_tunnel_bind_dev(dev); |
921 | netdev_state_change(dev); | 999 | netdev_state_change(dev); |
922 | } | 1000 | } |
923 | } | 1001 | } |
@@ -959,7 +1037,8 @@ done: | |||
959 | static int ipgre_tunnel_change_mtu(struct net_device *dev, int new_mtu) | 1037 | static int ipgre_tunnel_change_mtu(struct net_device *dev, int new_mtu) |
960 | { | 1038 | { |
961 | struct ip_tunnel *tunnel = netdev_priv(dev); | 1039 | struct ip_tunnel *tunnel = netdev_priv(dev); |
962 | if (new_mtu < 68 || new_mtu > 0xFFF8 - tunnel->hlen) | 1040 | if (new_mtu < 68 || |
1041 | new_mtu > 0xFFF8 - dev->hard_header_len - tunnel->hlen) | ||
963 | return -EINVAL; | 1042 | return -EINVAL; |
964 | dev->mtu = new_mtu; | 1043 | dev->mtu = new_mtu; |
965 | return 0; | 1044 | return 0; |
@@ -1078,6 +1157,7 @@ static int ipgre_close(struct net_device *dev) | |||
1078 | 1157 | ||
1079 | static void ipgre_tunnel_setup(struct net_device *dev) | 1158 | static void ipgre_tunnel_setup(struct net_device *dev) |
1080 | { | 1159 | { |
1160 | dev->init = ipgre_tunnel_init; | ||
1081 | dev->uninit = ipgre_tunnel_uninit; | 1161 | dev->uninit = ipgre_tunnel_uninit; |
1082 | dev->destructor = free_netdev; | 1162 | dev->destructor = free_netdev; |
1083 | dev->hard_start_xmit = ipgre_tunnel_xmit; | 1163 | dev->hard_start_xmit = ipgre_tunnel_xmit; |
@@ -1085,7 +1165,7 @@ static void ipgre_tunnel_setup(struct net_device *dev) | |||
1085 | dev->change_mtu = ipgre_tunnel_change_mtu; | 1165 | dev->change_mtu = ipgre_tunnel_change_mtu; |
1086 | 1166 | ||
1087 | dev->type = ARPHRD_IPGRE; | 1167 | dev->type = ARPHRD_IPGRE; |
1088 | dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr) + 4; | 1168 | dev->needed_headroom = LL_MAX_HEADER + sizeof(struct iphdr) + 4; |
1089 | dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr) - 4; | 1169 | dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr) - 4; |
1090 | dev->flags = IFF_NOARP; | 1170 | dev->flags = IFF_NOARP; |
1091 | dev->iflink = 0; | 1171 | dev->iflink = 0; |
@@ -1107,8 +1187,6 @@ static int ipgre_tunnel_init(struct net_device *dev) | |||
1107 | memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4); | 1187 | memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4); |
1108 | memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); | 1188 | memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); |
1109 | 1189 | ||
1110 | ipgre_tunnel_bind_dev(dev); | ||
1111 | |||
1112 | if (iph->daddr) { | 1190 | if (iph->daddr) { |
1113 | #ifdef CONFIG_NET_IPGRE_BROADCAST | 1191 | #ifdef CONFIG_NET_IPGRE_BROADCAST |
1114 | if (ipv4_is_multicast(iph->daddr)) { | 1192 | if (ipv4_is_multicast(iph->daddr)) { |
@@ -1189,6 +1267,7 @@ static int ipgre_init_net(struct net *net) | |||
1189 | 1267 | ||
1190 | ign->fb_tunnel_dev->init = ipgre_fb_tunnel_init; | 1268 | ign->fb_tunnel_dev->init = ipgre_fb_tunnel_init; |
1191 | dev_net_set(ign->fb_tunnel_dev, net); | 1269 | dev_net_set(ign->fb_tunnel_dev, net); |
1270 | ign->fb_tunnel_dev->rtnl_link_ops = &ipgre_link_ops; | ||
1192 | 1271 | ||
1193 | if ((err = register_netdev(ign->fb_tunnel_dev))) | 1272 | if ((err = register_netdev(ign->fb_tunnel_dev))) |
1194 | goto err_reg_dev; | 1273 | goto err_reg_dev; |
@@ -1221,6 +1300,298 @@ static struct pernet_operations ipgre_net_ops = { | |||
1221 | .exit = ipgre_exit_net, | 1300 | .exit = ipgre_exit_net, |
1222 | }; | 1301 | }; |
1223 | 1302 | ||
1303 | static int ipgre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[]) | ||
1304 | { | ||
1305 | __be16 flags; | ||
1306 | |||
1307 | if (!data) | ||
1308 | return 0; | ||
1309 | |||
1310 | flags = 0; | ||
1311 | if (data[IFLA_GRE_IFLAGS]) | ||
1312 | flags |= nla_get_be16(data[IFLA_GRE_IFLAGS]); | ||
1313 | if (data[IFLA_GRE_OFLAGS]) | ||
1314 | flags |= nla_get_be16(data[IFLA_GRE_OFLAGS]); | ||
1315 | if (flags & (GRE_VERSION|GRE_ROUTING)) | ||
1316 | return -EINVAL; | ||
1317 | |||
1318 | return 0; | ||
1319 | } | ||
1320 | |||
1321 | static int ipgre_tap_validate(struct nlattr *tb[], struct nlattr *data[]) | ||
1322 | { | ||
1323 | __be32 daddr; | ||
1324 | |||
1325 | if (tb[IFLA_ADDRESS]) { | ||
1326 | if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) | ||
1327 | return -EINVAL; | ||
1328 | if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) | ||
1329 | return -EADDRNOTAVAIL; | ||
1330 | } | ||
1331 | |||
1332 | if (!data) | ||
1333 | goto out; | ||
1334 | |||
1335 | if (data[IFLA_GRE_REMOTE]) { | ||
1336 | memcpy(&daddr, nla_data(data[IFLA_GRE_REMOTE]), 4); | ||
1337 | if (!daddr) | ||
1338 | return -EINVAL; | ||
1339 | } | ||
1340 | |||
1341 | out: | ||
1342 | return ipgre_tunnel_validate(tb, data); | ||
1343 | } | ||
1344 | |||
1345 | static void ipgre_netlink_parms(struct nlattr *data[], | ||
1346 | struct ip_tunnel_parm *parms) | ||
1347 | { | ||
1348 | memset(parms, 0, sizeof(*parms)); | ||
1349 | |||
1350 | parms->iph.protocol = IPPROTO_GRE; | ||
1351 | |||
1352 | if (!data) | ||
1353 | return; | ||
1354 | |||
1355 | if (data[IFLA_GRE_LINK]) | ||
1356 | parms->link = nla_get_u32(data[IFLA_GRE_LINK]); | ||
1357 | |||
1358 | if (data[IFLA_GRE_IFLAGS]) | ||
1359 | parms->i_flags = nla_get_be16(data[IFLA_GRE_IFLAGS]); | ||
1360 | |||
1361 | if (data[IFLA_GRE_OFLAGS]) | ||
1362 | parms->o_flags = nla_get_be16(data[IFLA_GRE_OFLAGS]); | ||
1363 | |||
1364 | if (data[IFLA_GRE_IKEY]) | ||
1365 | parms->i_key = nla_get_be32(data[IFLA_GRE_IKEY]); | ||
1366 | |||
1367 | if (data[IFLA_GRE_OKEY]) | ||
1368 | parms->o_key = nla_get_be32(data[IFLA_GRE_OKEY]); | ||
1369 | |||
1370 | if (data[IFLA_GRE_LOCAL]) | ||
1371 | parms->iph.saddr = nla_get_be32(data[IFLA_GRE_LOCAL]); | ||
1372 | |||
1373 | if (data[IFLA_GRE_REMOTE]) | ||
1374 | parms->iph.daddr = nla_get_be32(data[IFLA_GRE_REMOTE]); | ||
1375 | |||
1376 | if (data[IFLA_GRE_TTL]) | ||
1377 | parms->iph.ttl = nla_get_u8(data[IFLA_GRE_TTL]); | ||
1378 | |||
1379 | if (data[IFLA_GRE_TOS]) | ||
1380 | parms->iph.tos = nla_get_u8(data[IFLA_GRE_TOS]); | ||
1381 | |||
1382 | if (!data[IFLA_GRE_PMTUDISC] || nla_get_u8(data[IFLA_GRE_PMTUDISC])) | ||
1383 | parms->iph.frag_off = htons(IP_DF); | ||
1384 | } | ||
1385 | |||
1386 | static int ipgre_tap_init(struct net_device *dev) | ||
1387 | { | ||
1388 | struct ip_tunnel *tunnel; | ||
1389 | |||
1390 | tunnel = netdev_priv(dev); | ||
1391 | |||
1392 | tunnel->dev = dev; | ||
1393 | strcpy(tunnel->parms.name, dev->name); | ||
1394 | |||
1395 | ipgre_tunnel_bind_dev(dev); | ||
1396 | |||
1397 | return 0; | ||
1398 | } | ||
1399 | |||
1400 | static void ipgre_tap_setup(struct net_device *dev) | ||
1401 | { | ||
1402 | |||
1403 | ether_setup(dev); | ||
1404 | |||
1405 | dev->init = ipgre_tap_init; | ||
1406 | dev->uninit = ipgre_tunnel_uninit; | ||
1407 | dev->destructor = free_netdev; | ||
1408 | dev->hard_start_xmit = ipgre_tunnel_xmit; | ||
1409 | dev->change_mtu = ipgre_tunnel_change_mtu; | ||
1410 | |||
1411 | dev->iflink = 0; | ||
1412 | dev->features |= NETIF_F_NETNS_LOCAL; | ||
1413 | } | ||
1414 | |||
1415 | static int ipgre_newlink(struct net_device *dev, struct nlattr *tb[], | ||
1416 | struct nlattr *data[]) | ||
1417 | { | ||
1418 | struct ip_tunnel *nt; | ||
1419 | struct net *net = dev_net(dev); | ||
1420 | struct ipgre_net *ign = net_generic(net, ipgre_net_id); | ||
1421 | int mtu; | ||
1422 | int err; | ||
1423 | |||
1424 | nt = netdev_priv(dev); | ||
1425 | ipgre_netlink_parms(data, &nt->parms); | ||
1426 | |||
1427 | if (ipgre_tunnel_find(net, &nt->parms, dev->type)) | ||
1428 | return -EEXIST; | ||
1429 | |||
1430 | if (dev->type == ARPHRD_ETHER && !tb[IFLA_ADDRESS]) | ||
1431 | random_ether_addr(dev->dev_addr); | ||
1432 | |||
1433 | mtu = ipgre_tunnel_bind_dev(dev); | ||
1434 | if (!tb[IFLA_MTU]) | ||
1435 | dev->mtu = mtu; | ||
1436 | |||
1437 | err = register_netdevice(dev); | ||
1438 | if (err) | ||
1439 | goto out; | ||
1440 | |||
1441 | dev_hold(dev); | ||
1442 | ipgre_tunnel_link(ign, nt); | ||
1443 | |||
1444 | out: | ||
1445 | return err; | ||
1446 | } | ||
1447 | |||
1448 | static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[], | ||
1449 | struct nlattr *data[]) | ||
1450 | { | ||
1451 | struct ip_tunnel *t, *nt; | ||
1452 | struct net *net = dev_net(dev); | ||
1453 | struct ipgre_net *ign = net_generic(net, ipgre_net_id); | ||
1454 | struct ip_tunnel_parm p; | ||
1455 | int mtu; | ||
1456 | |||
1457 | if (dev == ign->fb_tunnel_dev) | ||
1458 | return -EINVAL; | ||
1459 | |||
1460 | nt = netdev_priv(dev); | ||
1461 | ipgre_netlink_parms(data, &p); | ||
1462 | |||
1463 | t = ipgre_tunnel_locate(net, &p, 0); | ||
1464 | |||
1465 | if (t) { | ||
1466 | if (t->dev != dev) | ||
1467 | return -EEXIST; | ||
1468 | } else { | ||
1469 | unsigned nflags = 0; | ||
1470 | |||
1471 | t = nt; | ||
1472 | |||
1473 | if (ipv4_is_multicast(p.iph.daddr)) | ||
1474 | nflags = IFF_BROADCAST; | ||
1475 | else if (p.iph.daddr) | ||
1476 | nflags = IFF_POINTOPOINT; | ||
1477 | |||
1478 | if ((dev->flags ^ nflags) & | ||
1479 | (IFF_POINTOPOINT | IFF_BROADCAST)) | ||
1480 | return -EINVAL; | ||
1481 | |||
1482 | ipgre_tunnel_unlink(ign, t); | ||
1483 | t->parms.iph.saddr = p.iph.saddr; | ||
1484 | t->parms.iph.daddr = p.iph.daddr; | ||
1485 | t->parms.i_key = p.i_key; | ||
1486 | memcpy(dev->dev_addr, &p.iph.saddr, 4); | ||
1487 | memcpy(dev->broadcast, &p.iph.daddr, 4); | ||
1488 | ipgre_tunnel_link(ign, t); | ||
1489 | netdev_state_change(dev); | ||
1490 | } | ||
1491 | |||
1492 | t->parms.o_key = p.o_key; | ||
1493 | t->parms.iph.ttl = p.iph.ttl; | ||
1494 | t->parms.iph.tos = p.iph.tos; | ||
1495 | t->parms.iph.frag_off = p.iph.frag_off; | ||
1496 | |||
1497 | if (t->parms.link != p.link) { | ||
1498 | t->parms.link = p.link; | ||
1499 | mtu = ipgre_tunnel_bind_dev(dev); | ||
1500 | if (!tb[IFLA_MTU]) | ||
1501 | dev->mtu = mtu; | ||
1502 | netdev_state_change(dev); | ||
1503 | } | ||
1504 | |||
1505 | return 0; | ||
1506 | } | ||
1507 | |||
1508 | static size_t ipgre_get_size(const struct net_device *dev) | ||
1509 | { | ||
1510 | return | ||
1511 | /* IFLA_GRE_LINK */ | ||
1512 | nla_total_size(4) + | ||
1513 | /* IFLA_GRE_IFLAGS */ | ||
1514 | nla_total_size(2) + | ||
1515 | /* IFLA_GRE_OFLAGS */ | ||
1516 | nla_total_size(2) + | ||
1517 | /* IFLA_GRE_IKEY */ | ||
1518 | nla_total_size(4) + | ||
1519 | /* IFLA_GRE_OKEY */ | ||
1520 | nla_total_size(4) + | ||
1521 | /* IFLA_GRE_LOCAL */ | ||
1522 | nla_total_size(4) + | ||
1523 | /* IFLA_GRE_REMOTE */ | ||
1524 | nla_total_size(4) + | ||
1525 | /* IFLA_GRE_TTL */ | ||
1526 | nla_total_size(1) + | ||
1527 | /* IFLA_GRE_TOS */ | ||
1528 | nla_total_size(1) + | ||
1529 | /* IFLA_GRE_PMTUDISC */ | ||
1530 | nla_total_size(1) + | ||
1531 | 0; | ||
1532 | } | ||
1533 | |||
1534 | static int ipgre_fill_info(struct sk_buff *skb, const struct net_device *dev) | ||
1535 | { | ||
1536 | struct ip_tunnel *t = netdev_priv(dev); | ||
1537 | struct ip_tunnel_parm *p = &t->parms; | ||
1538 | |||
1539 | NLA_PUT_U32(skb, IFLA_GRE_LINK, p->link); | ||
1540 | NLA_PUT_BE16(skb, IFLA_GRE_IFLAGS, p->i_flags); | ||
1541 | NLA_PUT_BE16(skb, IFLA_GRE_OFLAGS, p->o_flags); | ||
1542 | NLA_PUT_BE32(skb, IFLA_GRE_IKEY, p->i_key); | ||
1543 | NLA_PUT_BE32(skb, IFLA_GRE_OKEY, p->o_key); | ||
1544 | NLA_PUT_BE32(skb, IFLA_GRE_LOCAL, p->iph.saddr); | ||
1545 | NLA_PUT_BE32(skb, IFLA_GRE_REMOTE, p->iph.daddr); | ||
1546 | NLA_PUT_U8(skb, IFLA_GRE_TTL, p->iph.ttl); | ||
1547 | NLA_PUT_U8(skb, IFLA_GRE_TOS, p->iph.tos); | ||
1548 | NLA_PUT_U8(skb, IFLA_GRE_PMTUDISC, !!(p->iph.frag_off & htons(IP_DF))); | ||
1549 | |||
1550 | return 0; | ||
1551 | |||
1552 | nla_put_failure: | ||
1553 | return -EMSGSIZE; | ||
1554 | } | ||
1555 | |||
1556 | static const struct nla_policy ipgre_policy[IFLA_GRE_MAX + 1] = { | ||
1557 | [IFLA_GRE_LINK] = { .type = NLA_U32 }, | ||
1558 | [IFLA_GRE_IFLAGS] = { .type = NLA_U16 }, | ||
1559 | [IFLA_GRE_OFLAGS] = { .type = NLA_U16 }, | ||
1560 | [IFLA_GRE_IKEY] = { .type = NLA_U32 }, | ||
1561 | [IFLA_GRE_OKEY] = { .type = NLA_U32 }, | ||
1562 | [IFLA_GRE_LOCAL] = { .len = FIELD_SIZEOF(struct iphdr, saddr) }, | ||
1563 | [IFLA_GRE_REMOTE] = { .len = FIELD_SIZEOF(struct iphdr, daddr) }, | ||
1564 | [IFLA_GRE_TTL] = { .type = NLA_U8 }, | ||
1565 | [IFLA_GRE_TOS] = { .type = NLA_U8 }, | ||
1566 | [IFLA_GRE_PMTUDISC] = { .type = NLA_U8 }, | ||
1567 | }; | ||
1568 | |||
1569 | static struct rtnl_link_ops ipgre_link_ops __read_mostly = { | ||
1570 | .kind = "gre", | ||
1571 | .maxtype = IFLA_GRE_MAX, | ||
1572 | .policy = ipgre_policy, | ||
1573 | .priv_size = sizeof(struct ip_tunnel), | ||
1574 | .setup = ipgre_tunnel_setup, | ||
1575 | .validate = ipgre_tunnel_validate, | ||
1576 | .newlink = ipgre_newlink, | ||
1577 | .changelink = ipgre_changelink, | ||
1578 | .get_size = ipgre_get_size, | ||
1579 | .fill_info = ipgre_fill_info, | ||
1580 | }; | ||
1581 | |||
1582 | static struct rtnl_link_ops ipgre_tap_ops __read_mostly = { | ||
1583 | .kind = "gretap", | ||
1584 | .maxtype = IFLA_GRE_MAX, | ||
1585 | .policy = ipgre_policy, | ||
1586 | .priv_size = sizeof(struct ip_tunnel), | ||
1587 | .setup = ipgre_tap_setup, | ||
1588 | .validate = ipgre_tap_validate, | ||
1589 | .newlink = ipgre_newlink, | ||
1590 | .changelink = ipgre_changelink, | ||
1591 | .get_size = ipgre_get_size, | ||
1592 | .fill_info = ipgre_fill_info, | ||
1593 | }; | ||
1594 | |||
1224 | /* | 1595 | /* |
1225 | * And now the modules code and kernel interface. | 1596 | * And now the modules code and kernel interface. |
1226 | */ | 1597 | */ |
@@ -1238,19 +1609,39 @@ static int __init ipgre_init(void) | |||
1238 | 1609 | ||
1239 | err = register_pernet_gen_device(&ipgre_net_id, &ipgre_net_ops); | 1610 | err = register_pernet_gen_device(&ipgre_net_id, &ipgre_net_ops); |
1240 | if (err < 0) | 1611 | if (err < 0) |
1241 | inet_del_protocol(&ipgre_protocol, IPPROTO_GRE); | 1612 | goto gen_device_failed; |
1242 | 1613 | ||
1614 | err = rtnl_link_register(&ipgre_link_ops); | ||
1615 | if (err < 0) | ||
1616 | goto rtnl_link_failed; | ||
1617 | |||
1618 | err = rtnl_link_register(&ipgre_tap_ops); | ||
1619 | if (err < 0) | ||
1620 | goto tap_ops_failed; | ||
1621 | |||
1622 | out: | ||
1243 | return err; | 1623 | return err; |
1624 | |||
1625 | tap_ops_failed: | ||
1626 | rtnl_link_unregister(&ipgre_link_ops); | ||
1627 | rtnl_link_failed: | ||
1628 | unregister_pernet_gen_device(ipgre_net_id, &ipgre_net_ops); | ||
1629 | gen_device_failed: | ||
1630 | inet_del_protocol(&ipgre_protocol, IPPROTO_GRE); | ||
1631 | goto out; | ||
1244 | } | 1632 | } |
1245 | 1633 | ||
1246 | static void __exit ipgre_fini(void) | 1634 | static void __exit ipgre_fini(void) |
1247 | { | 1635 | { |
1636 | rtnl_link_unregister(&ipgre_tap_ops); | ||
1637 | rtnl_link_unregister(&ipgre_link_ops); | ||
1638 | unregister_pernet_gen_device(ipgre_net_id, &ipgre_net_ops); | ||
1248 | if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0) | 1639 | if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0) |
1249 | printk(KERN_INFO "ipgre close: can't remove protocol\n"); | 1640 | printk(KERN_INFO "ipgre close: can't remove protocol\n"); |
1250 | |||
1251 | unregister_pernet_gen_device(ipgre_net_id, &ipgre_net_ops); | ||
1252 | } | 1641 | } |
1253 | 1642 | ||
1254 | module_init(ipgre_init); | 1643 | module_init(ipgre_init); |
1255 | module_exit(ipgre_fini); | 1644 | module_exit(ipgre_fini); |
1256 | MODULE_LICENSE("GPL"); | 1645 | MODULE_LICENSE("GPL"); |
1646 | MODULE_ALIAS_RTNL_LINK("gre"); | ||
1647 | MODULE_ALIAS_RTNL_LINK("gretap"); | ||