diff options
| -rw-r--r-- | net/ipv4/xfrm4_policy.c | 8 | ||||
| -rw-r--r-- | net/ipv6/xfrm6_policy.c | 8 | ||||
| -rw-r--r-- | net/xfrm/xfrm_ipcomp.c | 12 |
3 files changed, 18 insertions, 10 deletions
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index ccde54248c8c..e1a63930a967 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
| @@ -104,10 +104,14 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
| 104 | const struct iphdr *iph = ip_hdr(skb); | 104 | const struct iphdr *iph = ip_hdr(skb); |
| 105 | u8 *xprth = skb_network_header(skb) + iph->ihl * 4; | 105 | u8 *xprth = skb_network_header(skb) + iph->ihl * 4; |
| 106 | struct flowi4 *fl4 = &fl->u.ip4; | 106 | struct flowi4 *fl4 = &fl->u.ip4; |
| 107 | int oif = 0; | ||
| 108 | |||
| 109 | if (skb_dst(skb)) | ||
| 110 | oif = skb_dst(skb)->dev->ifindex; | ||
| 107 | 111 | ||
| 108 | memset(fl4, 0, sizeof(struct flowi4)); | 112 | memset(fl4, 0, sizeof(struct flowi4)); |
| 109 | fl4->flowi4_mark = skb->mark; | 113 | fl4->flowi4_mark = skb->mark; |
| 110 | fl4->flowi4_oif = skb_dst(skb)->dev->ifindex; | 114 | fl4->flowi4_oif = reverse ? skb->skb_iif : oif; |
| 111 | 115 | ||
| 112 | if (!ip_is_fragment(iph)) { | 116 | if (!ip_is_fragment(iph)) { |
| 113 | switch (iph->protocol) { | 117 | switch (iph->protocol) { |
| @@ -236,7 +240,7 @@ static struct dst_ops xfrm4_dst_ops = { | |||
| 236 | .destroy = xfrm4_dst_destroy, | 240 | .destroy = xfrm4_dst_destroy, |
| 237 | .ifdown = xfrm4_dst_ifdown, | 241 | .ifdown = xfrm4_dst_ifdown, |
| 238 | .local_out = __ip_local_out, | 242 | .local_out = __ip_local_out, |
| 239 | .gc_thresh = 1024, | 243 | .gc_thresh = 32768, |
| 240 | }; | 244 | }; |
| 241 | 245 | ||
| 242 | static struct xfrm_policy_afinfo xfrm4_policy_afinfo = { | 246 | static struct xfrm_policy_afinfo xfrm4_policy_afinfo = { |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 08ed2772b7aa..5f8e128c512d 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
| @@ -135,10 +135,14 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
| 135 | struct ipv6_opt_hdr *exthdr; | 135 | struct ipv6_opt_hdr *exthdr; |
| 136 | const unsigned char *nh = skb_network_header(skb); | 136 | const unsigned char *nh = skb_network_header(skb); |
| 137 | u8 nexthdr = nh[IP6CB(skb)->nhoff]; | 137 | u8 nexthdr = nh[IP6CB(skb)->nhoff]; |
| 138 | int oif = 0; | ||
| 139 | |||
| 140 | if (skb_dst(skb)) | ||
| 141 | oif = skb_dst(skb)->dev->ifindex; | ||
| 138 | 142 | ||
| 139 | memset(fl6, 0, sizeof(struct flowi6)); | 143 | memset(fl6, 0, sizeof(struct flowi6)); |
| 140 | fl6->flowi6_mark = skb->mark; | 144 | fl6->flowi6_mark = skb->mark; |
| 141 | fl6->flowi6_oif = skb_dst(skb)->dev->ifindex; | 145 | fl6->flowi6_oif = reverse ? skb->skb_iif : oif; |
| 142 | 146 | ||
| 143 | fl6->daddr = reverse ? hdr->saddr : hdr->daddr; | 147 | fl6->daddr = reverse ? hdr->saddr : hdr->daddr; |
| 144 | fl6->saddr = reverse ? hdr->daddr : hdr->saddr; | 148 | fl6->saddr = reverse ? hdr->daddr : hdr->saddr; |
| @@ -285,7 +289,7 @@ static struct dst_ops xfrm6_dst_ops = { | |||
| 285 | .destroy = xfrm6_dst_destroy, | 289 | .destroy = xfrm6_dst_destroy, |
| 286 | .ifdown = xfrm6_dst_ifdown, | 290 | .ifdown = xfrm6_dst_ifdown, |
| 287 | .local_out = __ip6_local_out, | 291 | .local_out = __ip6_local_out, |
| 288 | .gc_thresh = 1024, | 292 | .gc_thresh = 32768, |
| 289 | }; | 293 | }; |
| 290 | 294 | ||
| 291 | static struct xfrm_policy_afinfo xfrm6_policy_afinfo = { | 295 | static struct xfrm_policy_afinfo xfrm6_policy_afinfo = { |
diff --git a/net/xfrm/xfrm_ipcomp.c b/net/xfrm/xfrm_ipcomp.c index 2906d520eea7..3be02b680268 100644 --- a/net/xfrm/xfrm_ipcomp.c +++ b/net/xfrm/xfrm_ipcomp.c | |||
| @@ -141,14 +141,14 @@ static int ipcomp_compress(struct xfrm_state *x, struct sk_buff *skb) | |||
| 141 | const int plen = skb->len; | 141 | const int plen = skb->len; |
| 142 | int dlen = IPCOMP_SCRATCH_SIZE; | 142 | int dlen = IPCOMP_SCRATCH_SIZE; |
| 143 | u8 *start = skb->data; | 143 | u8 *start = skb->data; |
| 144 | const int cpu = get_cpu(); | 144 | struct crypto_comp *tfm; |
| 145 | u8 *scratch = *per_cpu_ptr(ipcomp_scratches, cpu); | 145 | u8 *scratch; |
| 146 | struct crypto_comp *tfm = *per_cpu_ptr(ipcd->tfms, cpu); | ||
| 147 | int err; | 146 | int err; |
| 148 | 147 | ||
| 149 | local_bh_disable(); | 148 | local_bh_disable(); |
| 149 | scratch = *this_cpu_ptr(ipcomp_scratches); | ||
| 150 | tfm = *this_cpu_ptr(ipcd->tfms); | ||
| 150 | err = crypto_comp_compress(tfm, start, plen, scratch, &dlen); | 151 | err = crypto_comp_compress(tfm, start, plen, scratch, &dlen); |
| 151 | local_bh_enable(); | ||
| 152 | if (err) | 152 | if (err) |
| 153 | goto out; | 153 | goto out; |
| 154 | 154 | ||
| @@ -158,13 +158,13 @@ static int ipcomp_compress(struct xfrm_state *x, struct sk_buff *skb) | |||
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | memcpy(start + sizeof(struct ip_comp_hdr), scratch, dlen); | 160 | memcpy(start + sizeof(struct ip_comp_hdr), scratch, dlen); |
| 161 | put_cpu(); | 161 | local_bh_enable(); |
| 162 | 162 | ||
| 163 | pskb_trim(skb, dlen + sizeof(struct ip_comp_hdr)); | 163 | pskb_trim(skb, dlen + sizeof(struct ip_comp_hdr)); |
| 164 | return 0; | 164 | return 0; |
| 165 | 165 | ||
| 166 | out: | 166 | out: |
| 167 | put_cpu(); | 167 | local_bh_enable(); |
| 168 | return err; | 168 | return err; |
| 169 | } | 169 | } |
| 170 | 170 | ||
