diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h index 72945cf623704f1dda6f721a29894ff249ff9164..b88b52c33db7402476269a90714459b9c1397e61 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack.h +++ b/include/linux/netfilter_ipv4/ip_conntrack.h @@ -224,9 +224,8 @@ struct ip_conntrack /* get master conntrack via master expectation */ #define master_ct(conntr) (conntr->master ? conntr->master->expectant : NULL) -/* Alter reply tuple (maybe alter helper). If it's already taken, - return 0 and don't do alteration. */ -extern int +/* Alter reply tuple (maybe alter helper). */ +extern void ip_conntrack_alter_reply(struct ip_conntrack *conntrack, const struct ip_conntrack_tuple *newreply); diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index 2e5e4a936b6e4264ecb63bf748218047ee029fc4..0fc1a677a2b297001cd0452521c375ae8d767f42 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c @@ -1035,16 +1035,12 @@ int ip_conntrack_change_expect(struct ip_conntrack_expect *expect, return ret; } -/* Alter reply tuple (maybe alter helper). If it's already taken, - return 0 and don't do alteration. */ -int ip_conntrack_alter_reply(struct ip_conntrack *conntrack, - const struct ip_conntrack_tuple *newreply) +/* Alter reply tuple (maybe alter helper). This is for NAT, and is + implicitly racy: see __ip_conntrack_confirm */ +void ip_conntrack_alter_reply(struct ip_conntrack *conntrack, + const struct ip_conntrack_tuple *newreply) { WRITE_LOCK(&ip_conntrack_lock); - if (__ip_conntrack_find(newreply, conntrack)) { - WRITE_UNLOCK(&ip_conntrack_lock); - return 0; - } /* Should be unconfirmed, so not in hash table yet */ IP_NF_ASSERT(!is_confirmed(conntrack)); @@ -1055,8 +1051,6 @@ int ip_conntrack_alter_reply(struct ip_conntrack *conntrack, if (!conntrack->master && list_empty(&conntrack->sibling_list)) conntrack->helper = ip_ct_find_helper(newreply); WRITE_UNLOCK(&ip_conntrack_lock); - - return 1; } int ip_conntrack_helper_register(struct ip_conntrack_helper *me) diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c index 213bb07a24d952bface8f5151ee372a625a07970..278b959015f81d30887fd16d3115daacc53e0b66 100644 --- a/net/ipv4/netfilter/ip_nat_core.c +++ b/net/ipv4/netfilter/ip_nat_core.c @@ -467,38 +467,25 @@ ip_nat_setup_info(struct ip_conntrack *conntrack, } #endif - do { - if (!get_unique_tuple(&new_tuple, &orig_tp, range, conntrack, - hooknum)) { - DEBUGP("ip_nat_setup_info: Can't get unique for %p.\n", - conntrack); - return NF_DROP; - } - -#if 0 - DEBUGP("Hook %u (%s) %p\n", hooknum, - HOOK2MANIP(hooknum)==IP_NAT_MANIP_SRC ? "SRC" : "DST", + if (!get_unique_tuple(&new_tuple, &orig_tp, range,conntrack,hooknum)) { + DEBUGP("ip_nat_setup_info: Can't get unique for %p.\n", conntrack); - DEBUGP("Original: "); - DUMP_TUPLE(&orig_tp); - DEBUGP("New: "); - DUMP_TUPLE(&new_tuple); -#endif + return NF_DROP; + } - /* We now have two tuples (SRCIP/SRCPT/DSTIP/DSTPT): - the original (A/B/C/D') and the mangled one (E/F/G/H'). + /* We now have two tuples (SRCIP/SRCPT/DSTIP/DSTPT): + the original (A/B/C/D') and the mangled one (E/F/G/H'). - We're only allowed to work with the SRC per-proto - part, so we create inverses of both to start, then - derive the other fields we need. */ + We're only allowed to work with the SRC per-proto + part, so we create inverses of both to start, then + derive the other fields we need. */ - /* Reply connection: simply invert the new tuple - (G/H/E/F') */ - invert_tuplepr(&reply, &new_tuple); + /* Reply connection: simply invert the new tuple + (G/H/E/F') */ + invert_tuplepr(&reply, &new_tuple); - /* Alter conntrack table so it recognizes replies. - If fail this race (reply tuple now used), repeat. */ - } while (!ip_conntrack_alter_reply(conntrack, &reply)); + /* Alter conntrack table so will recognize replies. */ + ip_conntrack_alter_reply(conntrack, &reply); /* FIXME: We can simply used existing conntrack reply tuple here --RR */