diff options
Diffstat (limited to 'net/ipv6/ipcomp6.c')
| -rw-r--r-- | net/ipv6/ipcomp6.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index 2f2a5ca2c878..85cccd6ed0b7 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c | |||
| @@ -53,6 +53,7 @@ | |||
| 53 | static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | 53 | static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, |
| 54 | u8 type, u8 code, int offset, __be32 info) | 54 | u8 type, u8 code, int offset, __be32 info) |
| 55 | { | 55 | { |
| 56 | struct net *net = dev_net(skb->dev); | ||
| 56 | __be32 spi; | 57 | __be32 spi; |
| 57 | struct ipv6hdr *iph = (struct ipv6hdr*)skb->data; | 58 | struct ipv6hdr *iph = (struct ipv6hdr*)skb->data; |
| 58 | struct ip_comp_hdr *ipcomph = | 59 | struct ip_comp_hdr *ipcomph = |
| @@ -63,7 +64,7 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
| 63 | return; | 64 | return; |
| 64 | 65 | ||
| 65 | spi = htonl(ntohs(ipcomph->cpi)); | 66 | spi = htonl(ntohs(ipcomph->cpi)); |
| 66 | x = xfrm_state_lookup(&init_net, (xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET6); | 67 | x = xfrm_state_lookup(net, skb->mark, (xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET6); |
| 67 | if (!x) | 68 | if (!x) |
| 68 | return; | 69 | return; |
| 69 | 70 | ||
| @@ -74,14 +75,15 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
| 74 | 75 | ||
| 75 | static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x) | 76 | static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x) |
| 76 | { | 77 | { |
| 78 | struct net *net = xs_net(x); | ||
| 77 | struct xfrm_state *t = NULL; | 79 | struct xfrm_state *t = NULL; |
| 78 | 80 | ||
| 79 | t = xfrm_state_alloc(&init_net); | 81 | t = xfrm_state_alloc(net); |
| 80 | if (!t) | 82 | if (!t) |
| 81 | goto out; | 83 | goto out; |
| 82 | 84 | ||
| 83 | t->id.proto = IPPROTO_IPV6; | 85 | t->id.proto = IPPROTO_IPV6; |
| 84 | t->id.spi = xfrm6_tunnel_alloc_spi((xfrm_address_t *)&x->props.saddr); | 86 | t->id.spi = xfrm6_tunnel_alloc_spi(net, (xfrm_address_t *)&x->props.saddr); |
| 85 | if (!t->id.spi) | 87 | if (!t->id.spi) |
| 86 | goto error; | 88 | goto error; |
| 87 | 89 | ||
| @@ -90,6 +92,7 @@ static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x) | |||
| 90 | t->props.family = AF_INET6; | 92 | t->props.family = AF_INET6; |
| 91 | t->props.mode = x->props.mode; | 93 | t->props.mode = x->props.mode; |
| 92 | memcpy(t->props.saddr.a6, x->props.saddr.a6, sizeof(struct in6_addr)); | 94 | memcpy(t->props.saddr.a6, x->props.saddr.a6, sizeof(struct in6_addr)); |
| 95 | memcpy(&t->mark, &x->mark, sizeof(t->mark)); | ||
| 93 | 96 | ||
| 94 | if (xfrm_init_state(t)) | 97 | if (xfrm_init_state(t)) |
| 95 | goto error; | 98 | goto error; |
| @@ -108,13 +111,15 @@ error: | |||
| 108 | 111 | ||
| 109 | static int ipcomp6_tunnel_attach(struct xfrm_state *x) | 112 | static int ipcomp6_tunnel_attach(struct xfrm_state *x) |
| 110 | { | 113 | { |
| 114 | struct net *net = xs_net(x); | ||
| 111 | int err = 0; | 115 | int err = 0; |
| 112 | struct xfrm_state *t = NULL; | 116 | struct xfrm_state *t = NULL; |
| 113 | __be32 spi; | 117 | __be32 spi; |
| 118 | u32 mark = x->mark.m & x->mark.v; | ||
| 114 | 119 | ||
| 115 | spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&x->props.saddr); | 120 | spi = xfrm6_tunnel_spi_lookup(net, (xfrm_address_t *)&x->props.saddr); |
| 116 | if (spi) | 121 | if (spi) |
| 117 | t = xfrm_state_lookup(&init_net, (xfrm_address_t *)&x->id.daddr, | 122 | t = xfrm_state_lookup(net, mark, (xfrm_address_t *)&x->id.daddr, |
| 118 | spi, IPPROTO_IPV6, AF_INET6); | 123 | spi, IPPROTO_IPV6, AF_INET6); |
| 119 | if (!t) { | 124 | if (!t) { |
| 120 | t = ipcomp6_tunnel_create(x); | 125 | t = ipcomp6_tunnel_create(x); |
| @@ -154,16 +159,12 @@ static int ipcomp6_init_state(struct xfrm_state *x) | |||
| 154 | if (x->props.mode == XFRM_MODE_TUNNEL) { | 159 | if (x->props.mode == XFRM_MODE_TUNNEL) { |
| 155 | err = ipcomp6_tunnel_attach(x); | 160 | err = ipcomp6_tunnel_attach(x); |
| 156 | if (err) | 161 | if (err) |
| 157 | goto error_tunnel; | 162 | goto out; |
| 158 | } | 163 | } |
| 159 | 164 | ||
| 160 | err = 0; | 165 | err = 0; |
| 161 | out: | 166 | out: |
| 162 | return err; | 167 | return err; |
| 163 | error_tunnel: | ||
| 164 | ipcomp_destroy(x); | ||
| 165 | |||
| 166 | goto out; | ||
| 167 | } | 168 | } |
| 168 | 169 | ||
| 169 | static const struct xfrm_type ipcomp6_type = | 170 | static const struct xfrm_type ipcomp6_type = |
