diff options
Diffstat (limited to 'net/ipv6')
| -rw-r--r-- | net/ipv6/netfilter/ip6t_NPT.c | 33 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6t_REJECT.c | 1 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6table_nat.c | 15 | ||||
| -rw-r--r-- | net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 4 | ||||
| -rw-r--r-- | net/ipv6/netfilter/nf_conntrack_reasm.c | 5 |
5 files changed, 24 insertions, 34 deletions
diff --git a/net/ipv6/netfilter/ip6t_NPT.c b/net/ipv6/netfilter/ip6t_NPT.c index e9486915eff6..7302b0b7b642 100644 --- a/net/ipv6/netfilter/ip6t_NPT.c +++ b/net/ipv6/netfilter/ip6t_NPT.c | |||
| @@ -14,42 +14,23 @@ | |||
| 14 | #include <linux/netfilter_ipv6/ip6t_NPT.h> | 14 | #include <linux/netfilter_ipv6/ip6t_NPT.h> |
| 15 | #include <linux/netfilter/x_tables.h> | 15 | #include <linux/netfilter/x_tables.h> |
| 16 | 16 | ||
| 17 | static __sum16 csum16_complement(__sum16 a) | ||
| 18 | { | ||
| 19 | return (__force __sum16)(0xffff - (__force u16)a); | ||
| 20 | } | ||
| 21 | |||
| 22 | static __sum16 csum16_add(__sum16 a, __sum16 b) | ||
| 23 | { | ||
| 24 | u16 sum; | ||
| 25 | |||
| 26 | sum = (__force u16)a + (__force u16)b; | ||
| 27 | sum += (__force u16)a < (__force u16)b; | ||
| 28 | return (__force __sum16)sum; | ||
| 29 | } | ||
| 30 | |||
| 31 | static __sum16 csum16_sub(__sum16 a, __sum16 b) | ||
| 32 | { | ||
| 33 | return csum16_add(a, csum16_complement(b)); | ||
| 34 | } | ||
| 35 | |||
| 36 | static int ip6t_npt_checkentry(const struct xt_tgchk_param *par) | 17 | static int ip6t_npt_checkentry(const struct xt_tgchk_param *par) |
| 37 | { | 18 | { |
| 38 | struct ip6t_npt_tginfo *npt = par->targinfo; | 19 | struct ip6t_npt_tginfo *npt = par->targinfo; |
| 39 | __sum16 src_sum = 0, dst_sum = 0; | 20 | __wsum src_sum = 0, dst_sum = 0; |
| 40 | unsigned int i; | 21 | unsigned int i; |
| 41 | 22 | ||
| 42 | if (npt->src_pfx_len > 64 || npt->dst_pfx_len > 64) | 23 | if (npt->src_pfx_len > 64 || npt->dst_pfx_len > 64) |
| 43 | return -EINVAL; | 24 | return -EINVAL; |
| 44 | 25 | ||
| 45 | for (i = 0; i < ARRAY_SIZE(npt->src_pfx.in6.s6_addr16); i++) { | 26 | for (i = 0; i < ARRAY_SIZE(npt->src_pfx.in6.s6_addr16); i++) { |
| 46 | src_sum = csum16_add(src_sum, | 27 | src_sum = csum_add(src_sum, |
| 47 | (__force __sum16)npt->src_pfx.in6.s6_addr16[i]); | 28 | (__force __wsum)npt->src_pfx.in6.s6_addr16[i]); |
| 48 | dst_sum = csum16_add(dst_sum, | 29 | dst_sum = csum_add(dst_sum, |
| 49 | (__force __sum16)npt->dst_pfx.in6.s6_addr16[i]); | 30 | (__force __wsum)npt->dst_pfx.in6.s6_addr16[i]); |
| 50 | } | 31 | } |
| 51 | 32 | ||
| 52 | npt->adjustment = csum16_sub(src_sum, dst_sum); | 33 | npt->adjustment = (__force __sum16) csum_sub(src_sum, dst_sum); |
| 53 | return 0; | 34 | return 0; |
| 54 | } | 35 | } |
| 55 | 36 | ||
| @@ -85,7 +66,7 @@ static bool ip6t_npt_map_pfx(const struct ip6t_npt_tginfo *npt, | |||
| 85 | return false; | 66 | return false; |
| 86 | } | 67 | } |
| 87 | 68 | ||
| 88 | sum = csum16_add((__force __sum16)addr->s6_addr16[idx], | 69 | sum = (__force __sum16) csum_add((__force __wsum)addr->s6_addr16[idx], |
| 89 | npt->adjustment); | 70 | npt->adjustment); |
| 90 | if (sum == CSUM_MANGLED_0) | 71 | if (sum == CSUM_MANGLED_0) |
| 91 | sum = 0; | 72 | sum = 0; |
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index fd4fb34c51c7..029623dbd411 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c | |||
| @@ -132,6 +132,7 @@ static void send_reset(struct net *net, struct sk_buff *oldskb) | |||
| 132 | ip6h->saddr = oip6h->daddr; | 132 | ip6h->saddr = oip6h->daddr; |
| 133 | ip6h->daddr = oip6h->saddr; | 133 | ip6h->daddr = oip6h->saddr; |
| 134 | 134 | ||
| 135 | skb_reset_transport_header(nskb); | ||
| 135 | tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr)); | 136 | tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr)); |
| 136 | /* Truncate to length (no data) */ | 137 | /* Truncate to length (no data) */ |
| 137 | tcph->doff = sizeof(struct tcphdr)/4; | 138 | tcph->doff = sizeof(struct tcphdr)/4; |
diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c index 6c8ae24b85eb..e0e788d25b14 100644 --- a/net/ipv6/netfilter/ip6table_nat.c +++ b/net/ipv6/netfilter/ip6table_nat.c | |||
| @@ -127,23 +127,28 @@ nf_nat_ipv6_fn(unsigned int hooknum, | |||
| 127 | ret = nf_nat_rule_find(skb, hooknum, in, out, ct); | 127 | ret = nf_nat_rule_find(skb, hooknum, in, out, ct); |
| 128 | if (ret != NF_ACCEPT) | 128 | if (ret != NF_ACCEPT) |
| 129 | return ret; | 129 | return ret; |
| 130 | } else | 130 | } else { |
| 131 | pr_debug("Already setup manip %s for ct %p\n", | 131 | pr_debug("Already setup manip %s for ct %p\n", |
| 132 | maniptype == NF_NAT_MANIP_SRC ? "SRC" : "DST", | 132 | maniptype == NF_NAT_MANIP_SRC ? "SRC" : "DST", |
| 133 | ct); | 133 | ct); |
| 134 | if (nf_nat_oif_changed(hooknum, ctinfo, nat, out)) | ||
| 135 | goto oif_changed; | ||
| 136 | } | ||
| 134 | break; | 137 | break; |
| 135 | 138 | ||
| 136 | default: | 139 | default: |
| 137 | /* ESTABLISHED */ | 140 | /* ESTABLISHED */ |
| 138 | NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED || | 141 | NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED || |
| 139 | ctinfo == IP_CT_ESTABLISHED_REPLY); | 142 | ctinfo == IP_CT_ESTABLISHED_REPLY); |
| 140 | if (nf_nat_oif_changed(hooknum, ctinfo, nat, out)) { | 143 | if (nf_nat_oif_changed(hooknum, ctinfo, nat, out)) |
| 141 | nf_ct_kill_acct(ct, ctinfo, skb); | 144 | goto oif_changed; |
| 142 | return NF_DROP; | ||
| 143 | } | ||
| 144 | } | 145 | } |
| 145 | 146 | ||
| 146 | return nf_nat_packet(ct, ctinfo, hooknum, skb); | 147 | return nf_nat_packet(ct, ctinfo, hooknum, skb); |
| 148 | |||
| 149 | oif_changed: | ||
| 150 | nf_ct_kill_acct(ct, ctinfo, skb); | ||
| 151 | return NF_DROP; | ||
| 147 | } | 152 | } |
| 148 | 153 | ||
| 149 | static unsigned int | 154 | static unsigned int |
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index 00ee17c3e893..137e245860ab 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | |||
| @@ -81,8 +81,8 @@ static int ipv6_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, | |||
| 81 | } | 81 | } |
| 82 | protoff = ipv6_skip_exthdr(skb, extoff, &nexthdr, &frag_off); | 82 | protoff = ipv6_skip_exthdr(skb, extoff, &nexthdr, &frag_off); |
| 83 | /* | 83 | /* |
| 84 | * (protoff == skb->len) mean that the packet doesn't have no data | 84 | * (protoff == skb->len) means the packet has not data, just |
| 85 | * except of IPv6 & ext headers. but it's tracked anyway. - YK | 85 | * IPv6 and possibly extensions headers, but it is tracked anyway |
| 86 | */ | 86 | */ |
| 87 | if (protoff < 0 || (frag_off & htons(~0x7)) != 0) { | 87 | if (protoff < 0 || (frag_off & htons(~0x7)) != 0) { |
| 88 | pr_debug("ip6_conntrack_core: can't find proto in pkt\n"); | 88 | pr_debug("ip6_conntrack_core: can't find proto in pkt\n"); |
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 22c8ea951185..3dacecc99065 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c | |||
| @@ -311,7 +311,10 @@ found: | |||
| 311 | else | 311 | else |
| 312 | fq->q.fragments = skb; | 312 | fq->q.fragments = skb; |
| 313 | 313 | ||
| 314 | skb->dev = NULL; | 314 | if (skb->dev) { |
| 315 | fq->iif = skb->dev->ifindex; | ||
| 316 | skb->dev = NULL; | ||
| 317 | } | ||
| 315 | fq->q.stamp = skb->tstamp; | 318 | fq->q.stamp = skb->tstamp; |
| 316 | fq->q.meat += skb->len; | 319 | fq->q.meat += skb->len; |
| 317 | if (payload_len > fq->q.max_size) | 320 | if (payload_len > fq->q.max_size) |
