diff options
Diffstat (limited to 'net/ipv4/ip_gre.c')
-rw-r--r-- | net/ipv4/ip_gre.c | 63 |
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 | ||
194 | static struct ip_tunnel **ipgre_bucket(struct ip_tunnel *t) | 194 | static 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 | ||
212 | static inline struct ip_tunnel **ipgre_bucket(struct ip_tunnel *t) | ||
213 | { | ||
214 | return __ipgre_bucket(&t->parms); | ||
215 | } | ||
216 | |||
212 | static void ipgre_tunnel_link(struct ip_tunnel *t) | 217 | static 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; |