aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ip_gre.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/ip_gre.c')
-rw-r--r--net/ipv4/ip_gre.c63
1 files changed, 31 insertions, 32 deletions
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 9151da642318..63282934725e 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -191,11 +191,11 @@ static struct ip_tunnel * ipgre_tunnel_lookup(__be32 remote, __be32 local, __be3
191 return NULL; 191 return NULL;
192} 192}
193 193
194static struct ip_tunnel **ipgre_bucket(struct ip_tunnel *t) 194static struct ip_tunnel **__ipgre_bucket(struct ip_tunnel_parm *parms)
195{ 195{
196 __be32 remote = t->parms.iph.daddr; 196 __be32 remote = parms->iph.daddr;
197 __be32 local = t->parms.iph.saddr; 197 __be32 local = parms->iph.saddr;
198 __be32 key = t->parms.i_key; 198 __be32 key = parms->i_key;
199 unsigned h = HASH(key); 199 unsigned h = HASH(key);
200 int prio = 0; 200 int prio = 0;
201 201
@@ -209,6 +209,11 @@ static struct ip_tunnel **ipgre_bucket(struct ip_tunnel *t)
209 return &tunnels[prio][h]; 209 return &tunnels[prio][h];
210} 210}
211 211
212static inline struct ip_tunnel **ipgre_bucket(struct ip_tunnel *t)
213{
214 return __ipgre_bucket(&t->parms);
215}
216
212static void ipgre_tunnel_link(struct ip_tunnel *t) 217static void ipgre_tunnel_link(struct ip_tunnel *t)
213{ 218{
214 struct ip_tunnel **tp = ipgre_bucket(t); 219 struct ip_tunnel **tp = ipgre_bucket(t);
@@ -240,17 +245,9 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int
240 __be32 key = parms->i_key; 245 __be32 key = parms->i_key;
241 struct ip_tunnel *t, **tp, *nt; 246 struct ip_tunnel *t, **tp, *nt;
242 struct net_device *dev; 247 struct net_device *dev;
243 unsigned h = HASH(key);
244 int prio = 0;
245 char name[IFNAMSIZ]; 248 char name[IFNAMSIZ];
246 249
247 if (local) 250 for (tp = __ipgre_bucket(parms); (t = *tp) != NULL; tp = &t->next) {
248 prio |= 1;
249 if (remote && !MULTICAST(remote)) {
250 prio |= 2;
251 h ^= HASH(remote);
252 }
253 for (tp = &tunnels[prio][h]; (t = *tp) != NULL; tp = &t->next) {
254 if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) { 251 if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) {
255 if (key == t->parms.i_key) 252 if (key == t->parms.i_key)
256 return t; 253 return t;
@@ -320,8 +317,8 @@ static void ipgre_err(struct sk_buff *skb, u32 info)
320 struct iphdr *iph = (struct iphdr*)skb->data; 317 struct iphdr *iph = (struct iphdr*)skb->data;
321 __be16 *p = (__be16*)(skb->data+(iph->ihl<<2)); 318 __be16 *p = (__be16*)(skb->data+(iph->ihl<<2));
322 int grehlen = (iph->ihl<<2) + 4; 319 int grehlen = (iph->ihl<<2) + 4;
323 int type = skb->h.icmph->type; 320 const int type = icmp_hdr(skb)->type;
324 int code = skb->h.icmph->code; 321 const int code = icmp_hdr(skb)->code;
325 struct ip_tunnel *t; 322 struct ip_tunnel *t;
326 __be16 flags; 323 __be16 flags;
327 324
@@ -388,8 +385,8 @@ out:
388 struct iphdr *iph = (struct iphdr*)dp; 385 struct iphdr *iph = (struct iphdr*)dp;
389 struct iphdr *eiph; 386 struct iphdr *eiph;
390 __be16 *p = (__be16*)(dp+(iph->ihl<<2)); 387 __be16 *p = (__be16*)(dp+(iph->ihl<<2));
391 int type = skb->h.icmph->type; 388 const int type = icmp_hdr(skb)->type;
392 int code = skb->h.icmph->code; 389 const int code = icmp_hdr(skb)->code;
393 int rel_type = 0; 390 int rel_type = 0;
394 int rel_code = 0; 391 int rel_code = 0;
395 __be32 rel_info = 0; 392 __be32 rel_info = 0;
@@ -422,7 +419,7 @@ out:
422 default: 419 default:
423 return; 420 return;
424 case ICMP_PARAMETERPROB: 421 case ICMP_PARAMETERPROB:
425 n = ntohl(skb->h.icmph->un.gateway) >> 24; 422 n = ntohl(icmp_hdr(skb)->un.gateway) >> 24;
426 if (n < (iph->ihl<<2)) 423 if (n < (iph->ihl<<2))
427 return; 424 return;
428 425
@@ -442,7 +439,7 @@ out:
442 return; 439 return;
443 case ICMP_FRAG_NEEDED: 440 case ICMP_FRAG_NEEDED:
444 /* And it is the only really necessary thing :-) */ 441 /* And it is the only really necessary thing :-) */
445 n = ntohs(skb->h.icmph->un.frag.mtu); 442 n = ntohs(icmp_hdr(skb)->un.frag.mtu);
446 if (n < grehlen+68) 443 if (n < grehlen+68)
447 return; 444 return;
448 n -= grehlen; 445 n -= grehlen;
@@ -474,7 +471,7 @@ out:
474 dst_release(skb2->dst); 471 dst_release(skb2->dst);
475 skb2->dst = NULL; 472 skb2->dst = NULL;
476 skb_pull(skb2, skb->data - (u8*)eiph); 473 skb_pull(skb2, skb->data - (u8*)eiph);
477 skb2->nh.raw = skb2->data; 474 skb_reset_network_header(skb2);
478 475
479 /* Try to guess incoming interface */ 476 /* Try to guess incoming interface */
480 memset(&fl, 0, sizeof(fl)); 477 memset(&fl, 0, sizeof(fl));
@@ -533,9 +530,9 @@ static inline void ipgre_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb)
533{ 530{
534 if (INET_ECN_is_ce(iph->tos)) { 531 if (INET_ECN_is_ce(iph->tos)) {
535 if (skb->protocol == htons(ETH_P_IP)) { 532 if (skb->protocol == htons(ETH_P_IP)) {
536 IP_ECN_set_ce(skb->nh.iph); 533 IP_ECN_set_ce(ip_hdr(skb));
537 } else if (skb->protocol == htons(ETH_P_IPV6)) { 534 } else if (skb->protocol == htons(ETH_P_IPV6)) {
538 IP6_ECN_set_ce(skb->nh.ipv6h); 535 IP6_ECN_set_ce(ipv6_hdr(skb));
539 } 536 }
540 } 537 }
541} 538}
@@ -565,7 +562,7 @@ static int ipgre_rcv(struct sk_buff *skb)
565 if (!pskb_may_pull(skb, 16)) 562 if (!pskb_may_pull(skb, 16))
566 goto drop_nolock; 563 goto drop_nolock;
567 564
568 iph = skb->nh.iph; 565 iph = ip_hdr(skb);
569 h = skb->data; 566 h = skb->data;
570 flags = *(__be16*)h; 567 flags = *(__be16*)h;
571 568
@@ -616,9 +613,10 @@ static int ipgre_rcv(struct sk_buff *skb)
616 offset += 4; 613 offset += 4;
617 } 614 }
618 615
619 skb->mac.raw = skb->nh.raw; 616 skb_reset_mac_header(skb);
620 skb->nh.raw = __pskb_pull(skb, offset); 617 __pskb_pull(skb, offset);
621 skb_postpull_rcsum(skb, skb->h.raw, offset); 618 skb_reset_network_header(skb);
619 skb_postpull_rcsum(skb, skb_transport_header(skb), offset);
622 skb->pkt_type = PACKET_HOST; 620 skb->pkt_type = PACKET_HOST;
623#ifdef CONFIG_NET_IPGRE_BROADCAST 621#ifdef CONFIG_NET_IPGRE_BROADCAST
624 if (MULTICAST(iph->daddr)) { 622 if (MULTICAST(iph->daddr)) {
@@ -669,7 +667,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
669{ 667{
670 struct ip_tunnel *tunnel = netdev_priv(dev); 668 struct ip_tunnel *tunnel = netdev_priv(dev);
671 struct net_device_stats *stats = &tunnel->stat; 669 struct net_device_stats *stats = &tunnel->stat;
672 struct iphdr *old_iph = skb->nh.iph; 670 struct iphdr *old_iph = ip_hdr(skb);
673 struct iphdr *tiph; 671 struct iphdr *tiph;
674 u8 tos; 672 u8 tos;
675 __be16 df; 673 __be16 df;
@@ -720,7 +718,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
720 addr_type = ipv6_addr_type(addr6); 718 addr_type = ipv6_addr_type(addr6);
721 719
722 if (addr_type == IPV6_ADDR_ANY) { 720 if (addr_type == IPV6_ADDR_ANY) {
723 addr6 = &skb->nh.ipv6h->daddr; 721 addr6 = &ipv6_hdr(skb)->daddr;
724 addr_type = ipv6_addr_type(addr6); 722 addr_type = ipv6_addr_type(addr6);
725 } 723 }
726 724
@@ -824,11 +822,12 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
824 skb_set_owner_w(new_skb, skb->sk); 822 skb_set_owner_w(new_skb, skb->sk);
825 dev_kfree_skb(skb); 823 dev_kfree_skb(skb);
826 skb = new_skb; 824 skb = new_skb;
827 old_iph = skb->nh.iph; 825 old_iph = ip_hdr(skb);
828 } 826 }
829 827
830 skb->h.raw = skb->nh.raw; 828 skb->transport_header = skb->network_header;
831 skb->nh.raw = skb_push(skb, gre_hlen); 829 skb_push(skb, gre_hlen);
830 skb_reset_network_header(skb);
832 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); 831 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
833 IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | 832 IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED |
834 IPSKB_REROUTED); 833 IPSKB_REROUTED);
@@ -839,7 +838,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
839 * Push down and install the IPIP header. 838 * Push down and install the IPIP header.
840 */ 839 */
841 840
842 iph = skb->nh.iph; 841 iph = ip_hdr(skb);
843 iph->version = 4; 842 iph->version = 4;
844 iph->ihl = sizeof(struct iphdr) >> 2; 843 iph->ihl = sizeof(struct iphdr) >> 2;
845 iph->frag_off = df; 844 iph->frag_off = df;