diff options
Diffstat (limited to 'net/ipv6/netfilter')
-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 e948691..7302b0b 100644 --- a/net/ipv6/netfilter/ip6t_NPT.c +++ b/net/ipv6/netfilter/ip6t_NPT.c @@ -14,42 +14,23 @@ #include <linux/netfilter_ipv6/ip6t_NPT.h> #include <linux/netfilter/x_tables.h> -static __sum16 csum16_complement(__sum16 a) -{ - return (__force __sum16)(0xffff - (__force u16)a); -} - -static __sum16 csum16_add(__sum16 a, __sum16 b) -{ - u16 sum; - - sum = (__force u16)a + (__force u16)b; - sum += (__force u16)a < (__force u16)b; - return (__force __sum16)sum; -} - -static __sum16 csum16_sub(__sum16 a, __sum16 b) -{ - return csum16_add(a, csum16_complement(b)); -} - static int ip6t_npt_checkentry(const struct xt_tgchk_param *par) { struct ip6t_npt_tginfo *npt = par->targinfo; - __sum16 src_sum = 0, dst_sum = 0; + __wsum src_sum = 0, dst_sum = 0; unsigned int i; if (npt->src_pfx_len > 64 || npt->dst_pfx_len > 64) return -EINVAL; for (i = 0; i < ARRAY_SIZE(npt->src_pfx.in6.s6_addr16); i++) { - src_sum = csum16_add(src_sum, - (__force __sum16)npt->src_pfx.in6.s6_addr16[i]); - dst_sum = csum16_add(dst_sum, - (__force __sum16)npt->dst_pfx.in6.s6_addr16[i]); + src_sum = csum_add(src_sum, + (__force __wsum)npt->src_pfx.in6.s6_addr16[i]); + dst_sum = csum_add(dst_sum, + (__force __wsum)npt->dst_pfx.in6.s6_addr16[i]); } - npt->adjustment = csum16_sub(src_sum, dst_sum); + npt->adjustment = (__force __sum16) csum_sub(src_sum, dst_sum); return 0; } @@ -85,7 +66,7 @@ static bool ip6t_npt_map_pfx(const struct ip6t_npt_tginfo *npt, return false; } - sum = csum16_add((__force __sum16)addr->s6_addr16[idx], + sum = (__force __sum16) csum_add((__force __wsum)addr->s6_addr16[idx], npt->adjustment); if (sum == CSUM_MANGLED_0) sum = 0; diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index fd4fb34..029623d 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) ip6h->saddr = oip6h->daddr; ip6h->daddr = oip6h->saddr; + skb_reset_transport_header(nskb); tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr)); /* Truncate to length (no data) */ tcph->doff = sizeof(struct tcphdr)/4; diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c index 6c8ae24..e0e788d 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, ret = nf_nat_rule_find(skb, hooknum, in, out, ct); if (ret != NF_ACCEPT) return ret; - } else + } else { pr_debug("Already setup manip %s for ct %p\n", maniptype == NF_NAT_MANIP_SRC ? "SRC" : "DST", ct); + if (nf_nat_oif_changed(hooknum, ctinfo, nat, out)) + goto oif_changed; + } break; default: /* ESTABLISHED */ NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED || ctinfo == IP_CT_ESTABLISHED_REPLY); - if (nf_nat_oif_changed(hooknum, ctinfo, nat, out)) { - nf_ct_kill_acct(ct, ctinfo, skb); - return NF_DROP; - } + if (nf_nat_oif_changed(hooknum, ctinfo, nat, out)) + goto oif_changed; } return nf_nat_packet(ct, ctinfo, hooknum, skb); + +oif_changed: + nf_ct_kill_acct(ct, ctinfo, skb); + return NF_DROP; } static unsigned int diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index 00ee17c..137e245 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, } protoff = ipv6_skip_exthdr(skb, extoff, &nexthdr, &frag_off); /* - * (protoff == skb->len) mean that the packet doesn't have no data - * except of IPv6 & ext headers. but it's tracked anyway. - YK + * (protoff == skb->len) means the packet has not data, just + * IPv6 and possibly extensions headers, but it is tracked anyway */ if (protoff < 0 || (frag_off & htons(~0x7)) != 0) { 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 22c8ea9..3dacecc 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -311,7 +311,10 @@ found: else fq->q.fragments = skb; - skb->dev = NULL; + if (skb->dev) { + fq->iif = skb->dev->ifindex; + skb->dev = NULL; + } fq->q.stamp = skb->tstamp; fq->q.meat += skb->len; if (payload_len > fq->q.max_size) |