aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPravin B Shelar <pshelar@nicira.com>2013-06-17 20:50:02 -0400
committerDavid S. Miller <davem@davemloft.net>2013-06-19 21:07:41 -0400
commit3d7b46cd20e300bd6989fb1f43d46f1b9645816e (patch)
treeb8a063f8ecb7e380f0e1672a60815ff48c3f9b56 /net
parent0e6fbc5b6c6218987c93b8c7ca60cf786062899d (diff)
ip_tunnel: push generic protocol handling to ip_tunnel module.
Process skb tunnel header before sending packet to protocol handler. this allows code sharing between gre and ovs gre modules. Signed-off-by: Pravin B Shelar <pshelar@nicira.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/gre.c3
-rw-r--r--net/ipv4/ip_tunnel.c30
-rw-r--r--net/ipv4/ip_tunnel_core.c34
-rw-r--r--net/ipv4/ipip.c6
-rw-r--r--net/ipv6/sit.c7
5 files changed, 53 insertions, 27 deletions
diff --git a/net/ipv4/gre.c b/net/ipv4/gre.c
index 5ecc9c49b4dc..ba4803e609b5 100644
--- a/net/ipv4/gre.c
+++ b/net/ipv4/gre.c
@@ -201,7 +201,8 @@ static int parse_gre_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
201 return -EINVAL; 201 return -EINVAL;
202 } 202 }
203 } 203 }
204 return 0; 204
205 return iptunnel_pull_header(skb, hdr_len, tpi->proto);
205} 206}
206 207
207static int gre_cisco_rcv(struct sk_buff *skb) 208static int gre_cisco_rcv(struct sk_buff *skb)
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index a06a2ed49597..bd227e5ea9da 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -408,13 +408,6 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
408 const struct iphdr *iph = ip_hdr(skb); 408 const struct iphdr *iph = ip_hdr(skb);
409 int err; 409 int err;
410 410
411 secpath_reset(skb);
412
413 skb->protocol = tpi->proto;
414
415 skb->mac_header = skb->network_header;
416 __pskb_pull(skb, tunnel->hlen);
417 skb_postpull_rcsum(skb, skb_transport_header(skb), tunnel->hlen);
418#ifdef CONFIG_NET_IPGRE_BROADCAST 411#ifdef CONFIG_NET_IPGRE_BROADCAST
419 if (ipv4_is_multicast(iph->daddr)) { 412 if (ipv4_is_multicast(iph->daddr)) {
420 /* Looped back packet, drop it! */ 413 /* Looped back packet, drop it! */
@@ -442,23 +435,6 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
442 tunnel->i_seqno = ntohl(tpi->seq) + 1; 435 tunnel->i_seqno = ntohl(tpi->seq) + 1;
443 } 436 }
444 437
445 /* Warning: All skb pointers will be invalidated! */
446 if (tunnel->dev->type == ARPHRD_ETHER) {
447 if (!pskb_may_pull(skb, ETH_HLEN)) {
448 tunnel->dev->stats.rx_length_errors++;
449 tunnel->dev->stats.rx_errors++;
450 goto drop;
451 }
452
453 iph = ip_hdr(skb);
454 skb->protocol = eth_type_trans(skb, tunnel->dev);
455 skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
456 }
457
458 skb->pkt_type = PACKET_HOST;
459 __skb_tunnel_rx(skb, tunnel->dev);
460
461 skb_reset_network_header(skb);
462 err = IP_ECN_decapsulate(iph, skb); 438 err = IP_ECN_decapsulate(iph, skb);
463 if (unlikely(err)) { 439 if (unlikely(err)) {
464 if (log_ecn_error) 440 if (log_ecn_error)
@@ -477,6 +453,12 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
477 tstats->rx_bytes += skb->len; 453 tstats->rx_bytes += skb->len;
478 u64_stats_update_end(&tstats->syncp); 454 u64_stats_update_end(&tstats->syncp);
479 455
456 if (tunnel->dev->type == ARPHRD_ETHER) {
457 skb->protocol = eth_type_trans(skb, tunnel->dev);
458 skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
459 } else {
460 skb->dev = tunnel->dev;
461 }
480 gro_cells_receive(&tunnel->gro_cells, skb); 462 gro_cells_receive(&tunnel->gro_cells, skb);
481 return 0; 463 return 0;
482 464
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
index 927687e83f18..7167b08977df 100644
--- a/net/ipv4/ip_tunnel_core.c
+++ b/net/ipv4/ip_tunnel_core.c
@@ -86,3 +86,37 @@ int iptunnel_xmit(struct net *net, struct rtable *rt,
86 return pkt_len; 86 return pkt_len;
87} 87}
88EXPORT_SYMBOL_GPL(iptunnel_xmit); 88EXPORT_SYMBOL_GPL(iptunnel_xmit);
89
90int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto)
91{
92 if (unlikely(!pskb_may_pull(skb, hdr_len)))
93 return -ENOMEM;
94
95 skb_pull_rcsum(skb, hdr_len);
96
97 if (inner_proto == htons(ETH_P_TEB)) {
98 struct ethhdr *eh = (struct ethhdr *)skb->data;
99
100 if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
101 return -ENOMEM;
102
103 if (likely(ntohs(eh->h_proto) >= ETH_P_802_3_MIN))
104 skb->protocol = eh->h_proto;
105 else
106 skb->protocol = htons(ETH_P_802_2);
107
108 } else {
109 skb->protocol = inner_proto;
110 }
111
112 nf_reset(skb);
113 secpath_reset(skb);
114 if (!skb->l4_rxhash)
115 skb->rxhash = 0;
116 skb_dst_drop(skb);
117 skb->vlan_tci = 0;
118 skb_set_queue_mapping(skb, 0);
119 skb->pkt_type = PACKET_HOST;
120 return 0;
121}
122EXPORT_SYMBOL_GPL(iptunnel_pull_header);
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 9df7ecd393f2..e6905fbda2a2 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -188,8 +188,12 @@ static int ipip_rcv(struct sk_buff *skb)
188 struct net *net = dev_net(skb->dev); 188 struct net *net = dev_net(skb->dev);
189 struct ip_tunnel_net *itn = net_generic(net, ipip_net_id); 189 struct ip_tunnel_net *itn = net_generic(net, ipip_net_id);
190 struct ip_tunnel *tunnel; 190 struct ip_tunnel *tunnel;
191 const struct iphdr *iph = ip_hdr(skb); 191 const struct iphdr *iph;
192 192
193 if (iptunnel_pull_header(skb, 0, tpi.proto))
194 goto drop;
195
196 iph = ip_hdr(skb);
193 tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY, 197 tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY,
194 iph->saddr, iph->daddr, 0); 198 iph->saddr, iph->daddr, 0);
195 if (tunnel) { 199 if (tunnel) {
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 76bb8de435b2..6cee844678e2 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -640,9 +640,14 @@ static const struct tnl_ptk_info tpi = {
640 640
641static int ipip_rcv(struct sk_buff *skb) 641static int ipip_rcv(struct sk_buff *skb)
642{ 642{
643 const struct iphdr *iph = ip_hdr(skb); 643 const struct iphdr *iph;
644 struct ip_tunnel *tunnel; 644 struct ip_tunnel *tunnel;
645 645
646 if (iptunnel_pull_header(skb, 0, tpi.proto))
647 goto drop;
648
649 iph = ip_hdr(skb);
650
646 tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev, 651 tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev,
647 iph->saddr, iph->daddr); 652 iph->saddr, iph->daddr);
648 if (tunnel != NULL) { 653 if (tunnel != NULL) {