Message ID | 1354642293-4114-7-git-send-email-pablo@netfilter.org |
---|---|
State | Accepted |
Headers | show |
On Tue, Dec 4, 2012 at 10:31 AM, <pablo@netfilter.org> wrote: > > From: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> > > When the route changes (backup default route, VPNs) which affect a > masqueraded target, the packets were sent out with the outdated source > address. The patch addresses the issue by comparing the outgoing interface > directly with the masqueraded interface in the nat table. > > Events are inefficient in this case, because it'd require adding route > events to the network core and then scanning the whole conntrack table > and re-checking the route for all entry. > > Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> > Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Jozsef, a small question about this change. Should this same check not exist here: case IP_CT_NEW: /* Seen it before? This can happen for loopback, retrans, * or local packets. */ if (!nf_nat_initialized(ct, maniptype)) { unsigned int ret; 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)) { + nf_ct_kill_acct(ct, ctinfo, skb); + return NF_DROP; + } + } break; as well? It's *significantly* less common than the case you fixed, and perhaps just letting the state time out is acceptable, but I've seen TCP connections get stuck with the wrong source address if we haven't hit ESTABLISHED at the point when the routing change occurs (most reproducible on high latency links). -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Tue, 11 Dec 2012, Andrew Collins wrote: > On Tue, Dec 4, 2012 at 10:31 AM, <pablo@netfilter.org> wrote: > > > > From: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> > > > > When the route changes (backup default route, VPNs) which affect a > > masqueraded target, the packets were sent out with the outdated source > > address. The patch addresses the issue by comparing the outgoing interface > > directly with the masqueraded interface in the nat table. > > > > Events are inefficient in this case, because it'd require adding route > > events to the network core and then scanning the whole conntrack table > > and re-checking the route for all entry. > > > > Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> > > Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> > > Jozsef, a small question about this change. Should this same check > not exist here: > > case IP_CT_NEW: > /* Seen it before? This can happen for loopback, retrans, > * or local packets. > */ > if (!nf_nat_initialized(ct, maniptype)) { > unsigned int ret; > > 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)) { > + nf_ct_kill_acct(ct, ctinfo, skb); > + return NF_DROP; > + } > + } > break; > > as well? It's *significantly* less common than the case you fixed, > and perhaps just letting the state time out is acceptable, but I've > seen TCP connections get stuck with the wrong source address if we > haven't hit ESTABLISHED at the point when the routing change occurs > (most reproducible on high latency links). It is a less common case, but I think you are right: the timeout can take several minutes. But instead of repeating the code segment, a "goto" case handling were better. Are you going to submit a patch? Best regards, Jozsef - E-mail : kadlec@blackhole.kfki.hu, kadlecsik.jozsef@wigner.mta.hu PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt Address : Wigner Research Centre for Physics, Hungarian Academy of Sciences H-1525 Budapest 114, POB. 49, Hungary -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/include/net/netfilter/nf_nat.h b/include/net/netfilter/nf_nat.h index bd8eea7..ad14a79 100644 --- a/include/net/netfilter/nf_nat.h +++ b/include/net/netfilter/nf_nat.h @@ -68,4 +68,19 @@ static inline struct nf_conn_nat *nfct_nat(const struct nf_conn *ct) #endif } +static inline bool nf_nat_oif_changed(unsigned int hooknum, + enum ip_conntrack_info ctinfo, + struct nf_conn_nat *nat, + const struct net_device *out) +{ +#if IS_ENABLED(CONFIG_IP_NF_TARGET_MASQUERADE) || \ + IS_ENABLED(CONFIG_IP6_NF_TARGET_MASQUERADE) + return nat->masq_index && hooknum == NF_INET_POST_ROUTING && + CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL && + nat->masq_index != out->ifindex; +#else + return false; +#endif +} + #endif diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c index ac635a7..da2c8a3 100644 --- a/net/ipv4/netfilter/iptable_nat.c +++ b/net/ipv4/netfilter/iptable_nat.c @@ -134,6 +134,10 @@ nf_nat_ipv4_fn(unsigned int hooknum, /* 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; + } } return nf_nat_packet(ct, ctinfo, hooknum, skb); diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c index fa84cf8..6c8ae24 100644 --- a/net/ipv6/netfilter/ip6table_nat.c +++ b/net/ipv6/netfilter/ip6table_nat.c @@ -137,6 +137,10 @@ nf_nat_ipv6_fn(unsigned int hooknum, /* 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; + } } return nf_nat_packet(ct, ctinfo, hooknum, skb);