aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/xfrm.h8
-rw-r--r--net/ipv4/xfrm4_input.c36
-rw-r--r--net/ipv4/xfrm4_tunnel.c9
3 files changed, 26 insertions, 27 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 0e844845f3f4..680739f69003 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1046,7 +1046,15 @@ extern void xfrm_replay_notify(struct xfrm_state *x, int event);
1046extern int xfrm_state_mtu(struct xfrm_state *x, int mtu); 1046extern int xfrm_state_mtu(struct xfrm_state *x, int mtu);
1047extern int xfrm_init_state(struct xfrm_state *x); 1047extern int xfrm_init_state(struct xfrm_state *x);
1048extern int xfrm_output(struct sk_buff *skb); 1048extern int xfrm_output(struct sk_buff *skb);
1049extern int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
1050 int encap_type);
1049extern int xfrm4_rcv(struct sk_buff *skb); 1051extern int xfrm4_rcv(struct sk_buff *skb);
1052
1053static inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
1054{
1055 return xfrm4_rcv_encap(skb, nexthdr, spi, 0);
1056}
1057
1050extern int xfrm4_output(struct sk_buff *skb); 1058extern int xfrm4_output(struct sk_buff *skb);
1051extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family); 1059extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family);
1052extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family); 1060extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family);
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index e9bbfde19ac3..5cb0b5995bc8 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -16,19 +16,6 @@
16#include <net/ip.h> 16#include <net/ip.h>
17#include <net/xfrm.h> 17#include <net/xfrm.h>
18 18
19static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
20{
21 switch (nexthdr) {
22 case IPPROTO_IPIP:
23 case IPPROTO_IPV6:
24 *spi = ip_hdr(skb)->saddr;
25 *seq = 0;
26 return 0;
27 }
28
29 return xfrm_parse_spi(skb, nexthdr, spi, seq);
30}
31
32#ifdef CONFIG_NETFILTER 19#ifdef CONFIG_NETFILTER
33static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb) 20static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb)
34{ 21{
@@ -46,28 +33,29 @@ drop:
46} 33}
47#endif 34#endif
48 35
49static int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) 36int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
37 int encap_type)
50{ 38{
51 __be32 spi, seq; 39 int err;
40 __be32 seq;
52 struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH]; 41 struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
53 struct xfrm_state *x; 42 struct xfrm_state *x;
54 int xfrm_nr = 0; 43 int xfrm_nr = 0;
55 int decaps = 0; 44 int decaps = 0;
56 int err = xfrm4_parse_spi(skb, ip_hdr(skb)->protocol, &spi, &seq);
57 unsigned int nhoff = offsetof(struct iphdr, protocol); 45 unsigned int nhoff = offsetof(struct iphdr, protocol);
58 46
59 if (err != 0) 47 seq = 0;
48 if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
60 goto drop; 49 goto drop;
61 50
62 do { 51 do {
63 const struct iphdr *iph = ip_hdr(skb); 52 const struct iphdr *iph = ip_hdr(skb);
64 int nexthdr;
65 53
66 if (xfrm_nr == XFRM_MAX_DEPTH) 54 if (xfrm_nr == XFRM_MAX_DEPTH)
67 goto drop; 55 goto drop;
68 56
69 x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi, 57 x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi,
70 iph->protocol != IPPROTO_IPV6 ? iph->protocol : IPPROTO_IPIP, AF_INET); 58 nexthdr, AF_INET);
71 if (x == NULL) 59 if (x == NULL)
72 goto drop; 60 goto drop;
73 61
@@ -111,7 +99,7 @@ static int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
111 break; 99 break;
112 } 100 }
113 101
114 err = xfrm_parse_spi(skb, ip_hdr(skb)->protocol, &spi, &seq); 102 err = xfrm_parse_spi(skb, nexthdr, &spi, &seq);
115 if (err < 0) 103 if (err < 0)
116 goto drop; 104 goto drop;
117 } while (!err); 105 } while (!err);
@@ -165,6 +153,7 @@ drop:
165 kfree_skb(skb); 153 kfree_skb(skb);
166 return 0; 154 return 0;
167} 155}
156EXPORT_SYMBOL(xfrm4_rcv_encap);
168 157
169/* If it's a keepalive packet, then just eat it. 158/* If it's a keepalive packet, then just eat it.
170 * If it's an encapsulated packet, then pass it to the 159 * If it's an encapsulated packet, then pass it to the
@@ -252,11 +241,8 @@ int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
252 __skb_pull(skb, len); 241 __skb_pull(skb, len);
253 skb_reset_transport_header(skb); 242 skb_reset_transport_header(skb);
254 243
255 /* modify the protocol (it's ESP!) */
256 iph->protocol = IPPROTO_ESP;
257
258 /* process ESP */ 244 /* process ESP */
259 ret = xfrm4_rcv_encap(skb, encap_type); 245 ret = xfrm4_rcv_encap(skb, IPPROTO_ESP, 0, encap_type);
260 return ret; 246 return ret;
261 247
262drop: 248drop:
@@ -266,7 +252,7 @@ drop:
266 252
267int xfrm4_rcv(struct sk_buff *skb) 253int xfrm4_rcv(struct sk_buff *skb)
268{ 254{
269 return xfrm4_rcv_encap(skb, 0); 255 return xfrm4_rcv_spi(skb, ip_hdr(skb)->protocol, 0);
270} 256}
271 257
272EXPORT_SYMBOL(xfrm4_rcv); 258EXPORT_SYMBOL(xfrm4_rcv);
diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c
index 83e9580feac4..326845195620 100644
--- a/net/ipv4/xfrm4_tunnel.c
+++ b/net/ipv4/xfrm4_tunnel.c
@@ -48,20 +48,25 @@ static struct xfrm_type ipip_type = {
48 .output = ipip_output 48 .output = ipip_output
49}; 49};
50 50
51static int xfrm_tunnel_rcv(struct sk_buff *skb)
52{
53 return xfrm4_rcv_spi(skb, IPPROTO_IP, ip_hdr(skb)->saddr);
54}
55
51static int xfrm_tunnel_err(struct sk_buff *skb, u32 info) 56static int xfrm_tunnel_err(struct sk_buff *skb, u32 info)
52{ 57{
53 return -ENOENT; 58 return -ENOENT;
54} 59}
55 60
56static struct xfrm_tunnel xfrm_tunnel_handler = { 61static struct xfrm_tunnel xfrm_tunnel_handler = {
57 .handler = xfrm4_rcv, 62 .handler = xfrm_tunnel_rcv,
58 .err_handler = xfrm_tunnel_err, 63 .err_handler = xfrm_tunnel_err,
59 .priority = 2, 64 .priority = 2,
60}; 65};
61 66
62#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 67#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
63static struct xfrm_tunnel xfrm64_tunnel_handler = { 68static struct xfrm_tunnel xfrm64_tunnel_handler = {
64 .handler = xfrm4_rcv, 69 .handler = xfrm_tunnel_rcv,
65 .err_handler = xfrm_tunnel_err, 70 .err_handler = xfrm_tunnel_err,
66 .priority = 2, 71 .priority = 2,
67}; 72};