aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/flow.h2
-rw-r--r--include/net/xfrm.h6
-rw-r--r--net/ipv4/ip_gre.c12
-rw-r--r--net/ipv4/xfrm4_policy.c15
4 files changed, 30 insertions, 5 deletions
diff --git a/include/net/flow.h b/include/net/flow.h
index 0ac3fb5e0973..7196e6864b8d 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -67,6 +67,7 @@ struct flowi {
67 } dnports; 67 } dnports;
68 68
69 __be32 spi; 69 __be32 spi;
70 __be32 gre_key;
70 71
71 struct { 72 struct {
72 __u8 type; 73 __u8 type;
@@ -78,6 +79,7 @@ struct flowi {
78#define fl_icmp_code uli_u.icmpt.code 79#define fl_icmp_code uli_u.icmpt.code
79#define fl_ipsec_spi uli_u.spi 80#define fl_ipsec_spi uli_u.spi
80#define fl_mh_type uli_u.mht.type 81#define fl_mh_type uli_u.mht.type
82#define fl_gre_key uli_u.gre_key
81 __u32 secid; /* used by xfrm; see secid.txt */ 83 __u32 secid; /* used by xfrm; see secid.txt */
82} __attribute__((__aligned__(BITS_PER_LONG/8))); 84} __attribute__((__aligned__(BITS_PER_LONG/8)));
83 85
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index bcfb6b24b019..54b283229488 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -805,6 +805,9 @@ __be16 xfrm_flowi_sport(struct flowi *fl)
805 case IPPROTO_MH: 805 case IPPROTO_MH:
806 port = htons(fl->fl_mh_type); 806 port = htons(fl->fl_mh_type);
807 break; 807 break;
808 case IPPROTO_GRE:
809 port = htonl(fl->fl_gre_key) >> 16;
810 break;
808 default: 811 default:
809 port = 0; /*XXX*/ 812 port = 0; /*XXX*/
810 } 813 }
@@ -826,6 +829,9 @@ __be16 xfrm_flowi_dport(struct flowi *fl)
826 case IPPROTO_ICMPV6: 829 case IPPROTO_ICMPV6:
827 port = htons(fl->fl_icmp_code); 830 port = htons(fl->fl_icmp_code);
828 break; 831 break;
832 case IPPROTO_GRE:
833 port = htonl(fl->fl_gre_key) & 0xffff;
834 break;
829 default: 835 default:
830 port = 0; /*XXX*/ 836 port = 0; /*XXX*/
831 } 837 }
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index cab2057d5430..aace653710f6 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -779,9 +779,9 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
779 .tos = RT_TOS(tos) 779 .tos = RT_TOS(tos)
780 } 780 }
781 }, 781 },
782 .proto = IPPROTO_GRE 782 .proto = IPPROTO_GRE,
783 } 783 .fl_gre_key = tunnel->parms.o_key
784; 784 };
785 if (ip_route_output_key(dev_net(dev), &rt, &fl)) { 785 if (ip_route_output_key(dev_net(dev), &rt, &fl)) {
786 dev->stats.tx_carrier_errors++; 786 dev->stats.tx_carrier_errors++;
787 goto tx_error; 787 goto tx_error;
@@ -958,7 +958,8 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev)
958 .tos = RT_TOS(iph->tos) 958 .tos = RT_TOS(iph->tos)
959 } 959 }
960 }, 960 },
961 .proto = IPPROTO_GRE 961 .proto = IPPROTO_GRE,
962 .fl_gre_key = tunnel->parms.o_key
962 }; 963 };
963 struct rtable *rt; 964 struct rtable *rt;
964 965
@@ -1223,7 +1224,8 @@ static int ipgre_open(struct net_device *dev)
1223 .tos = RT_TOS(t->parms.iph.tos) 1224 .tos = RT_TOS(t->parms.iph.tos)
1224 } 1225 }
1225 }, 1226 },
1226 .proto = IPPROTO_GRE 1227 .proto = IPPROTO_GRE,
1228 .fl_gre_key = t->parms.o_key
1227 }; 1229 };
1228 struct rtable *rt; 1230 struct rtable *rt;
1229 1231
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index dd1fd8c473fc..4a8c5335770c 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -11,6 +11,7 @@
11#include <linux/err.h> 11#include <linux/err.h>
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/inetdevice.h> 13#include <linux/inetdevice.h>
14#include <linux/if_tunnel.h>
14#include <net/dst.h> 15#include <net/dst.h>
15#include <net/xfrm.h> 16#include <net/xfrm.h>
16#include <net/ip.h> 17#include <net/ip.h>
@@ -154,6 +155,20 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
154 fl->fl_ipsec_spi = htonl(ntohs(ipcomp_hdr[1])); 155 fl->fl_ipsec_spi = htonl(ntohs(ipcomp_hdr[1]));
155 } 156 }
156 break; 157 break;
158
159 case IPPROTO_GRE:
160 if (pskb_may_pull(skb, xprth + 12 - skb->data)) {
161 __be16 *greflags = (__be16 *)xprth;
162 __be32 *gre_hdr = (__be32 *)xprth;
163
164 if (greflags[0] & GRE_KEY) {
165 if (greflags[0] & GRE_CSUM)
166 gre_hdr++;
167 fl->fl_gre_key = gre_hdr[1];
168 }
169 }
170 break;
171
157 default: 172 default:
158 fl->fl_ipsec_spi = 0; 173 fl->fl_ipsec_spi = 0;
159 break; 174 break;