From c6aeedd0f7d3edbae598aa4ae2a943de13465b68 Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni <47657796+AkhileshSamineni@users.noreply.github.com> Date: Thu, 25 Jun 2020 03:06:45 +0530 Subject: [PATCH] Updated NAT kernel patch for 4.19 buster (#147) Updated NAT kernel patch for 4.19 buster and enabled the "Support-for-fullcone-nat.patch" in series. Depends on : Azure/sonic-buildimage#4843 Signed-off-by: Akhilesh Samineni --- patch/Support-for-fullcone-nat.patch | 253 ++++++++++++--------------- patch/series | 2 +- 2 files changed, 110 insertions(+), 145 deletions(-) diff --git a/patch/Support-for-fullcone-nat.patch b/patch/Support-for-fullcone-nat.patch index 4c4d46c3a..6c6777479 100644 --- a/patch/Support-for-fullcone-nat.patch +++ b/patch/Support-for-fullcone-nat.patch @@ -1,35 +1,11 @@ -From 67cc2bd46c7ad1431ddd1819cdfad6ecc08a7593 Mon Sep 17 00:00:00 2001 -From: Kiran Kella -Date: Fri, 6 Sep 2019 20:54:19 -0700 -Subject: [PATCH] Support for fullcone nat - ---- - include/net/netfilter/nf_conntrack.h | 4 + - include/net/netfilter/nf_nat.h | 6 + - include/net/netfilter/nf_nat_l4proto.h | 12 +- - include/uapi/linux/netfilter/nf_nat.h | 1 + - net/ipv4/netfilter/nf_nat_proto_gre.c | 8 +- - net/ipv4/netfilter/nf_nat_proto_icmp.c | 6 +- - net/ipv6/netfilter/nf_nat_proto_icmpv6.c | 5 +- - net/netfilter/nf_nat_core.c | 175 ++++++++++++++++++++--- - net/netfilter/nf_nat_proto_common.c | 23 ++- - net/netfilter/nf_nat_proto_dccp.c | 6 +- - net/netfilter/nf_nat_proto_sctp.c | 6 +- - net/netfilter/nf_nat_proto_tcp.c | 6 +- - net/netfilter/nf_nat_proto_udp.c | 6 +- - net/netfilter/nf_nat_proto_udplite.c | 6 +- - net/netfilter/nf_nat_proto_unknown.c | 4 +- - 15 files changed, 220 insertions(+), 54 deletions(-) - diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h -index 9ae819e..91796e9 100644 +index f45141bdbb83..64b9293a31f6 100644 --- a/include/net/netfilter/nf_conntrack.h +++ b/include/net/netfilter/nf_conntrack.h -@@ -102,6 +102,10 @@ struct nf_conn { +@@ -84,6 +84,9 @@ struct nf_conn { #if IS_ENABLED(CONFIG_NF_NAT) struct hlist_node nat_bysource; #endif -+ + /* To optionally ensure 3-tuple uniqueness on the translated source */ + struct hlist_node nat_by_manip_src; + @@ -37,10 +13,10 @@ index 9ae819e..91796e9 100644 u8 __nfct_init_offset[0]; diff --git a/include/net/netfilter/nf_nat.h b/include/net/netfilter/nf_nat.h -index 02515f7..8d4d180 100644 +index a17eb2f8d40e..7c3cc3c7b35f 100644 --- a/include/net/netfilter/nf_nat.h +++ b/include/net/netfilter/nf_nat.h -@@ -50,6 +50,12 @@ struct nf_conn_nat *nf_ct_nat_ext_add(struct nf_conn *ct); +@@ -51,6 +51,12 @@ struct nf_conn_nat *nf_ct_nat_ext_add(struct nf_conn *ct); int nf_nat_used_tuple(const struct nf_conntrack_tuple *tuple, const struct nf_conn *ignored_conntrack); @@ -54,49 +30,49 @@ index 02515f7..8d4d180 100644 { #if defined(CONFIG_NF_NAT) || defined(CONFIG_NF_NAT_MODULE) diff --git a/include/net/netfilter/nf_nat_l4proto.h b/include/net/netfilter/nf_nat_l4proto.h -index 12f4cc8..cfcd10c 100644 +index b4d6b29bca62..fbcbb9ad9e4b 100644 --- a/include/net/netfilter/nf_nat_l4proto.h +++ b/include/net/netfilter/nf_nat_l4proto.h -@@ -31,7 +31,7 @@ struct nf_nat_l4proto { +@@ -32,7 +32,7 @@ struct nf_nat_l4proto { * possible. Per-protocol part of tuple is initialized to the * incoming packet. */ - void (*unique_tuple)(const struct nf_nat_l3proto *l3proto, -+ int (*unique_tuple)(const struct nf_nat_l3proto *l3proto, ++ int (*unique_tuple)(const struct nf_nat_l3proto *l3proto, struct nf_conntrack_tuple *tuple, - const struct nf_nat_range *range, + const struct nf_nat_range2 *range, enum nf_nat_manip_type maniptype, -@@ -60,11 +60,11 @@ bool nf_nat_l4proto_in_range(const struct nf_conntrack_tuple *tuple, +@@ -70,11 +70,11 @@ bool nf_nat_l4proto_in_range(const struct nf_conntrack_tuple *tuple, const union nf_conntrack_man_proto *min, const union nf_conntrack_man_proto *max); -void nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto, - struct nf_conntrack_tuple *tuple, -- const struct nf_nat_range *range, +- const struct nf_nat_range2 *range, - enum nf_nat_manip_type maniptype, - const struct nf_conn *ct, u16 *rover); +int nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto, + struct nf_conntrack_tuple *tuple, -+ const struct nf_nat_range *range, ++ const struct nf_nat_range2 *range, + enum nf_nat_manip_type maniptype, + const struct nf_conn *ct, u16 *rover); int nf_nat_l4proto_nlattr_to_range(struct nlattr *tb[], - struct nf_nat_range *range); + struct nf_nat_range2 *range); diff --git a/include/uapi/linux/netfilter/nf_nat.h b/include/uapi/linux/netfilter/nf_nat.h -index 0880781..5e43ce8 100644 +index 4a95c0db14d4..1cda390e17c6 100644 --- a/include/uapi/linux/netfilter/nf_nat.h +++ b/include/uapi/linux/netfilter/nf_nat.h -@@ -9,6 +9,7 @@ - #define NF_NAT_RANGE_PROTO_RANDOM (1 << 2) +@@ -11,6 +11,7 @@ #define NF_NAT_RANGE_PERSISTENT (1 << 3) #define NF_NAT_RANGE_PROTO_RANDOM_FULLY (1 << 4) -+#define NF_NAT_RANGE_FULLCONE (1 << 5) + #define NF_NAT_RANGE_PROTO_OFFSET (1 << 5) ++#define NF_NAT_RANGE_FULLCONE (1 << 6) #define NF_NAT_RANGE_PROTO_RANDOM_ALL \ (NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PROTO_RANDOM_FULLY) diff --git a/net/ipv4/netfilter/nf_nat_proto_gre.c b/net/ipv4/netfilter/nf_nat_proto_gre.c -index edf0500..8518466 100644 +index 00fda6331ce5..d2ca4f6003ba 100644 --- a/net/ipv4/netfilter/nf_nat_proto_gre.c +++ b/net/ipv4/netfilter/nf_nat_proto_gre.c @@ -38,7 +38,7 @@ MODULE_AUTHOR("Harald Welte "); @@ -107,7 +83,7 @@ index edf0500..8518466 100644 +static int gre_unique_tuple(const struct nf_nat_l3proto *l3proto, struct nf_conntrack_tuple *tuple, - const struct nf_nat_range *range, + const struct nf_nat_range2 *range, @@ -52,7 +52,7 @@ gre_unique_tuple(const struct nf_nat_l3proto *l3proto, /* If there is no master conntrack we are not PPTP, do not change tuples */ @@ -132,7 +108,7 @@ index edf0500..8518466 100644 /* manipulate a GRE packet according to maniptype */ diff --git a/net/ipv4/netfilter/nf_nat_proto_icmp.c b/net/ipv4/netfilter/nf_nat_proto_icmp.c -index 7b98baa..d45face 100644 +index 6d7cf1d79baf..403783cda503 100644 --- a/net/ipv4/netfilter/nf_nat_proto_icmp.c +++ b/net/ipv4/netfilter/nf_nat_proto_icmp.c @@ -27,7 +27,7 @@ icmp_in_range(const struct nf_conntrack_tuple *tuple, @@ -143,7 +119,7 @@ index 7b98baa..d45face 100644 +static int icmp_unique_tuple(const struct nf_nat_l3proto *l3proto, struct nf_conntrack_tuple *tuple, - const struct nf_nat_range *range, + const struct nf_nat_range2 *range, @@ -48,9 +48,9 @@ icmp_unique_tuple(const struct nf_nat_l3proto *l3proto, tuple->src.u.icmp.id = htons(ntohs(range->min_proto.icmp.id) + (id % range_size)); @@ -157,7 +133,7 @@ index 7b98baa..d45face 100644 static bool diff --git a/net/ipv6/netfilter/nf_nat_proto_icmpv6.c b/net/ipv6/netfilter/nf_nat_proto_icmpv6.c -index 57593b0..271674a 100644 +index d9bf42ba44fa..7ff30a023f04 100644 --- a/net/ipv6/netfilter/nf_nat_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_nat_proto_icmpv6.c @@ -29,7 +29,7 @@ icmpv6_in_range(const struct nf_conntrack_tuple *tuple, @@ -168,7 +144,7 @@ index 57593b0..271674a 100644 +static int icmpv6_unique_tuple(const struct nf_nat_l3proto *l3proto, struct nf_conntrack_tuple *tuple, - const struct nf_nat_range *range, + const struct nf_nat_range2 *range, @@ -50,8 +50,9 @@ icmpv6_unique_tuple(const struct nf_nat_l3proto *l3proto, tuple->src.u.icmp.id = htons(ntohs(range->min_proto.icmp.id) + (id % range_size)); @@ -181,18 +157,18 @@ index 57593b0..271674a 100644 static bool diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c -index 51b0d83..d6efc9b 100644 +index 2268b10a9dcf..1b83427a7a68 100644 --- a/net/netfilter/nf_nat_core.c +++ b/net/netfilter/nf_nat_core.c -@@ -39,6 +39,7 @@ static const struct nf_nat_l4proto __rcu **nf_nat_l4protos[NFPROTO_NUMPROTO] - __read_mostly; +@@ -43,6 +43,7 @@ static const struct nf_nat_l4proto __rcu **nf_nat_l4protos[NFPROTO_NUMPROTO] + static unsigned int nat_net_id __read_mostly; static struct hlist_head *nf_nat_bysource __read_mostly; +static struct hlist_head *nf_nat_by_manip_src __read_mostly; static unsigned int nf_nat_htable_size __read_mostly; static unsigned int nf_nat_hash_rnd __read_mostly; -@@ -134,6 +135,31 @@ hash_by_src(const struct net *n, const struct nf_conntrack_tuple *tuple) +@@ -155,6 +156,31 @@ hash_by_src(const struct net *n, const struct nf_conntrack_tuple *tuple) return reciprocal_scale(hash, nf_nat_htable_size); } @@ -204,7 +180,7 @@ index 51b0d83..d6efc9b 100644 + get_random_once(&nf_nat_hash_rnd, sizeof(nf_nat_hash_rnd)); + + hash = jhash2((u32 *)&tuple->dst, sizeof(tuple->dst) / sizeof(u32), -+ tuple->dst.protonum ^ nf_nat_hash_rnd ^ net_hash_mix(n)); ++ tuple->dst.protonum ^ nf_nat_hash_rnd ^ net_hash_mix(n)); + + return reciprocal_scale(hash, nf_nat_htable_size); +} @@ -224,7 +200,7 @@ index 51b0d83..d6efc9b 100644 /* Is this tuple already taken? (not by us) */ int nf_nat_used_tuple(const struct nf_conntrack_tuple *tuple, -@@ -150,7 +176,41 @@ nf_nat_used_tuple(const struct nf_conntrack_tuple *tuple, +@@ -171,7 +197,40 @@ nf_nat_used_tuple(const struct nf_conntrack_tuple *tuple, nf_ct_invert_tuplepr(&reply, tuple); return nf_conntrack_tuple_taken(&reply, ignored_conntrack); } @@ -260,13 +236,12 @@ index 51b0d83..d6efc9b 100644 + } + return 0; +} -+ EXPORT_SYMBOL(nf_nat_used_tuple); +EXPORT_SYMBOL(nf_nat_used_3_tuple); /* If we source map this tuple so reply looks like reply_tuple, will * that meet the constraints of range. -@@ -216,6 +276,36 @@ find_appropriate_src(struct net *net, +@@ -237,6 +296,36 @@ find_appropriate_src(struct net *net, return 0; } @@ -303,7 +278,7 @@ index 51b0d83..d6efc9b 100644 /* For [FUTURE] fragmentation handling, we want the least-used * src-ip/dst-ip/proto triple. Fairness doesn't come into it. Thus * if the range specifies 1.2.3.4 ports 10000-10005 and 1.2.3.5 ports -@@ -293,10 +383,15 @@ find_best_ips_proto(const struct nf_conntrack_zone *zone, +@@ -314,10 +403,15 @@ find_best_ips_proto(const struct nf_conntrack_zone *zone, /* Manipulate the tuple into the range given. For NF_INET_POST_ROUTING, * we change the source to map into the range. For NF_INET_PRE_ROUTING * and NF_INET_LOCAL_OUT, we change the destination to map into the @@ -312,29 +287,29 @@ index 51b0d83..d6efc9b 100644 * At worst (or if we race), we will end up with a final duplicate in - * __ip_conntrack_confirm and drop the packet. */ -static void -+ * __nf_conntrack_confirm and drop the packet. ++ * __ip_conntrack_confirm and drop the packet. + * If the range is of type fullcone, if we end up with a 3-tuple + * duplicate, we do not wait till the packet reaches the + * nf_conntrack_confirm to drop the packet. Instead return the packet + * to be dropped at this stage. -+ * */ ++ */ +static int get_unique_tuple(struct nf_conntrack_tuple *tuple, const struct nf_conntrack_tuple *orig_tuple, - const struct nf_nat_range *range, -@@ -306,8 +401,11 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple, + const struct nf_nat_range2 *range, +@@ -327,8 +421,11 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple, const struct nf_conntrack_zone *zone; const struct nf_nat_l3proto *l3proto; const struct nf_nat_l4proto *l4proto; -+ struct nf_nat_range nat_range; ++ struct nf_nat_range2 nat_range; struct net *net = nf_ct_net(ct); -+ memcpy(&nat_range, range, sizeof(struct nf_nat_range)); ++ memcpy(&nat_range, range, sizeof(struct nf_nat_range2)); + zone = nf_ct_zone(ct); rcu_read_lock(); -@@ -324,47 +422,75 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple, +@@ -345,48 +442,77 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple, * manips not an issue. */ if (maniptype == NF_NAT_MANIP_SRC && @@ -355,6 +330,7 @@ index 51b0d83..d6efc9b 100644 goto out; } } + + if (maniptype == NF_NAT_MANIP_DST) { + if (nat_range.flags & NF_NAT_RANGE_FULLCONE) { + /* Destination IP range does not apply when fullcone flag is set. */ @@ -373,10 +349,10 @@ index 51b0d83..d6efc9b 100644 + /* If not mapped, proceed with the original tuple */ + *tuple = *orig_tuple; + goto out; -+ } ++ } + } + } - ++ /* 2) Select the least-used IP/proto combination in the given range */ *tuple = *orig_tuple; - find_best_ips_proto(zone, tuple, range, ct, maniptype); @@ -389,22 +365,24 @@ index 51b0d83..d6efc9b 100644 /* Only bother mapping if it's not already in range and unique */ - if (!(range->flags & NF_NAT_RANGE_PROTO_RANDOM_ALL)) { - if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED) { +- if (!(range->flags & NF_NAT_RANGE_PROTO_OFFSET) && + if (!(nat_range.flags & NF_NAT_RANGE_PROTO_RANDOM_ALL)) { + if (nat_range.flags & NF_NAT_RANGE_PROTO_SPECIFIED) { - if (l4proto->in_range(tuple, maniptype, -- &range->min_proto, -- &range->max_proto) && ++ if (!(nat_range.flags & NF_NAT_RANGE_PROTO_OFFSET) && + l4proto->in_range(tuple, maniptype, +- &range->min_proto, +- &range->max_proto) && - (range->min_proto.all == range->max_proto.all || - !nf_nat_used_tuple(tuple, ct))) - goto out; -+ &(nat_range.min_proto), -+ &(nat_range.max_proto))) { ++ &(nat_range.min_proto), ++ &(nat_range.max_proto))) { + if (nat_range.flags & NF_NAT_RANGE_FULLCONE) { + if (!nf_nat_used_3_tuple(tuple, ct, maniptype)) + goto out; + } else { + if ((nat_range.min_proto.all == nat_range.max_proto.all) || -+ !nf_nat_used_tuple(tuple, ct)) ++ !nf_nat_used_tuple(tuple, ct)) + goto out; + } + } @@ -413,7 +391,7 @@ index 51b0d83..d6efc9b 100644 } } - /* Last change: get protocol to try to obtain unique tuple. */ + /* Last chance: get protocol to try to obtain unique tuple. */ - l4proto->unique_tuple(l3proto, tuple, range, maniptype, ct); + return l4proto->unique_tuple(l3proto, tuple, &nat_range, maniptype, ct); out: @@ -422,7 +400,7 @@ index 51b0d83..d6efc9b 100644 } struct nf_conn_nat *nf_ct_nat_ext_add(struct nf_conn *ct) -@@ -406,7 +532,9 @@ nf_nat_setup_info(struct nf_conn *ct, +@@ -428,7 +554,9 @@ nf_nat_setup_info(struct nf_conn *ct, nf_ct_invert_tuplepr(&curr_tuple, &ct->tuplehash[IP_CT_DIR_REPLY].tuple); @@ -433,40 +411,32 @@ index 51b0d83..d6efc9b 100644 if (!nf_ct_tuple_equal(&new_tuple, &curr_tuple)) { struct nf_conntrack_tuple reply; -@@ -428,10 +556,16 @@ nf_nat_setup_info(struct nf_conn *ct, +@@ -450,12 +578,16 @@ nf_nat_setup_info(struct nf_conn *ct, if (maniptype == NF_NAT_MANIP_SRC) { unsigned int srchash; + unsigned int manip_src_hash; + spinlock_t *lock; + manip_src_hash = hash_by_src(net, &new_tuple); srchash = hash_by_src(net, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); -+ - spin_lock_bh(&nf_nat_lock); + lock = &nf_nat_locks[srchash % CONNTRACK_LOCKS]; + spin_lock_bh(lock); + hlist_add_head_rcu(&ct->nat_by_manip_src, + &nf_nat_by_manip_src[manip_src_hash]); -+ - /* nf_conntrack_alter_reply might re-allocate extension aera */ - nat = nfct_nat(ct); hlist_add_head_rcu(&ct->nat_bysource, -@@ -546,6 +680,7 @@ static int nf_nat_proto_clean(struct nf_conn *ct, void *data) - */ - spin_lock_bh(&nf_nat_lock); + &nf_nat_bysource[srchash]); + spin_unlock_bh(lock); +@@ -644,6 +776,7 @@ static void __nf_nat_cleanup_conntrack(struct nf_conn *ct) + h = hash_by_src(nf_ct_net(ct), &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); + spin_lock_bh(&nf_nat_locks[h % CONNTRACK_LOCKS]); hlist_del_rcu(&ct->nat_bysource); + hlist_del_rcu(&ct->nat_by_manip_src); - ct->status &= ~IPS_NAT_DONE_MASK; - spin_unlock_bh(&nf_nat_lock); - -@@ -675,6 +810,7 @@ static void nf_nat_cleanup_conntrack(struct nf_conn *ct) - if (ct->status & IPS_SRC_NAT_DONE) { - spin_lock_bh(&nf_nat_lock); - hlist_del_rcu(&ct->nat_bysource); -+ hlist_del_rcu(&ct->nat_by_manip_src); - spin_unlock_bh(&nf_nat_lock); - } + spin_unlock_bh(&nf_nat_locks[h % CONNTRACK_LOCKS]); } -@@ -818,9 +954,14 @@ static int __init nf_nat_init(void) + +@@ -1055,9 +1188,14 @@ static int __init nf_nat_init(void) if (!nf_nat_bysource) return -ENOMEM; @@ -476,40 +446,42 @@ index 51b0d83..d6efc9b 100644 + ret = nf_ct_extend_register(&nat_extend); if (ret < 0) { - nf_ct_free_hashtable(nf_nat_bysource, nf_nat_htable_size); -+ nf_ct_free_hashtable(nf_nat_by_manip_src, nf_nat_htable_size); - printk(KERN_ERR "nf_nat_core: Unable to register extension\n"); + kvfree(nf_nat_bysource); ++ kvfree(nf_nat_by_manip_src); + pr_err("Unable to register extension\n"); return ret; } -@@ -845,6 +986,7 @@ static int __init nf_nat_init(void) - - cleanup_extend: - nf_ct_free_hashtable(nf_nat_bysource, nf_nat_htable_size); -+ nf_ct_free_hashtable(nf_nat_by_manip_src, nf_nat_htable_size); - nf_ct_extend_unregister(&nat_extend); - return ret; - } -@@ -866,6 +1008,7 @@ static void __exit nf_nat_cleanup(void) +@@ -1096,6 +1234,7 @@ static void __exit nf_nat_cleanup(void) kfree(nf_nat_l4protos[i]); synchronize_net(); - nf_ct_free_hashtable(nf_nat_bysource, nf_nat_htable_size); -+ nf_ct_free_hashtable(nf_nat_by_manip_src, nf_nat_htable_size); + kvfree(nf_nat_bysource); ++ kvfree(nf_nat_by_manip_src); + unregister_pernet_subsys(&nat_net_ops); } - MODULE_LICENSE("GPL"); diff --git a/net/netfilter/nf_nat_proto_common.c b/net/netfilter/nf_nat_proto_common.c -index 7d7466d..fe13b74 100644 +index 5d849d835561..6ee918302a02 100644 --- a/net/netfilter/nf_nat_proto_common.c +++ b/net/netfilter/nf_nat_proto_common.c -@@ -34,7 +34,7 @@ bool nf_nat_l4proto_in_range(const struct nf_conntrack_tuple *tuple, +@@ -34,12 +34,12 @@ bool nf_nat_l4proto_in_range(const struct nf_conntrack_tuple *tuple, } EXPORT_SYMBOL_GPL(nf_nat_l4proto_in_range); -void nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto, +- struct nf_conntrack_tuple *tuple, +- const struct nf_nat_range2 *range, +- enum nf_nat_manip_type maniptype, +- const struct nf_conn *ct, +- u16 *rover) +int nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto, - struct nf_conntrack_tuple *tuple, - const struct nf_nat_range *range, - enum nf_nat_manip_type maniptype, ++ struct nf_conntrack_tuple *tuple, ++ const struct nf_nat_range2 *range, ++ enum nf_nat_manip_type maniptype, ++ const struct nf_conn *ct, ++ u16 *rover) + { + unsigned int range_size, min, max, i; + __be16 *portptr; @@ -54,7 +54,7 @@ void nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto, if (!(range->flags & NF_NAT_RANGE_PROTO_SPECIFIED)) { /* If it's dst rewrite, can't change port */ @@ -519,8 +491,8 @@ index 7d7466d..fe13b74 100644 if (ntohs(*portptr) < 1024) { /* Loose convention: >> 512 is credential passing */ -@@ -85,16 +85,27 @@ void nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto, - off = prandom_u32(); +@@ -87,17 +87,27 @@ void nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto, + off = (ntohs(*portptr) - ntohs(range->base_proto.all)); } else { off = *rover; + if ((range->flags & NF_NAT_RANGE_FULLCONE) && (maniptype == NF_NAT_MANIP_SRC)) { @@ -534,7 +506,6 @@ index 7d7466d..fe13b74 100644 *portptr = htons(min + off % range_size); - if (++i != range_size && nf_nat_used_tuple(tuple, ct)) - continue; -+ + if ((range->flags & NF_NAT_RANGE_FULLCONE) && (maniptype == NF_NAT_MANIP_SRC)) { + if (nf_nat_used_3_tuple(tuple, ct, maniptype)) + continue; @@ -542,7 +513,8 @@ index 7d7466d..fe13b74 100644 + if (nf_nat_used_tuple(tuple, ct)) + continue; + } - if (!(range->flags & NF_NAT_RANGE_PROTO_RANDOM_ALL)) + if (!(range->flags & (NF_NAT_RANGE_PROTO_RANDOM_ALL| + NF_NAT_RANGE_PROTO_OFFSET))) *rover = off; - return; + return 1; @@ -552,10 +524,10 @@ index 7d7466d..fe13b74 100644 EXPORT_SYMBOL_GPL(nf_nat_l4proto_unique_tuple); diff --git a/net/netfilter/nf_nat_proto_dccp.c b/net/netfilter/nf_nat_proto_dccp.c -index 15c47b2..48d22d4 100644 +index 67ea0d83aa5a..68ef70bb55df 100644 --- a/net/netfilter/nf_nat_proto_dccp.c +++ b/net/netfilter/nf_nat_proto_dccp.c -@@ -22,15 +22,15 @@ +@@ -20,15 +20,15 @@ static u_int16_t dccp_port_rover; @@ -563,22 +535,22 @@ index 15c47b2..48d22d4 100644 +static int dccp_unique_tuple(const struct nf_nat_l3proto *l3proto, struct nf_conntrack_tuple *tuple, - const struct nf_nat_range *range, + const struct nf_nat_range2 *range, enum nf_nat_manip_type maniptype, const struct nf_conn *ct) { - nf_nat_l4proto_unique_tuple(l3proto, tuple, range, maniptype, ct, - &dccp_port_rover); -+ return nf_nat_l4proto_unique_tuple(l3proto, tuple, range, maniptype, ct, -+ &dccp_port_rover); ++ return nf_nat_l4proto_unique_tuple(l3proto, tuple, range, maniptype, ct, ++ &dccp_port_rover); } static bool diff --git a/net/netfilter/nf_nat_proto_sctp.c b/net/netfilter/nf_nat_proto_sctp.c -index cbc7ade..c765cbc 100644 +index 1c5d9b65fbba..a9d9070c36c8 100644 --- a/net/netfilter/nf_nat_proto_sctp.c +++ b/net/netfilter/nf_nat_proto_sctp.c -@@ -16,15 +16,15 @@ +@@ -14,15 +14,15 @@ static u_int16_t nf_sctp_port_rover; @@ -586,19 +558,19 @@ index cbc7ade..c765cbc 100644 +static int sctp_unique_tuple(const struct nf_nat_l3proto *l3proto, struct nf_conntrack_tuple *tuple, - const struct nf_nat_range *range, + const struct nf_nat_range2 *range, enum nf_nat_manip_type maniptype, const struct nf_conn *ct) { - nf_nat_l4proto_unique_tuple(l3proto, tuple, range, maniptype, ct, - &nf_sctp_port_rover); + return nf_nat_l4proto_unique_tuple(l3proto, tuple, range, maniptype, ct, -+ &nf_sctp_port_rover); ++ &nf_sctp_port_rover); } static bool diff --git a/net/netfilter/nf_nat_proto_tcp.c b/net/netfilter/nf_nat_proto_tcp.c -index 4f8820f..1cb5e69 100644 +index f15fcd475f98..1b039055421f 100644 --- a/net/netfilter/nf_nat_proto_tcp.c +++ b/net/netfilter/nf_nat_proto_tcp.c @@ -20,15 +20,15 @@ @@ -609,7 +581,7 @@ index 4f8820f..1cb5e69 100644 +static int tcp_unique_tuple(const struct nf_nat_l3proto *l3proto, struct nf_conntrack_tuple *tuple, - const struct nf_nat_range *range, + const struct nf_nat_range2 *range, enum nf_nat_manip_type maniptype, const struct nf_conn *ct) { @@ -621,7 +593,7 @@ index 4f8820f..1cb5e69 100644 static bool diff --git a/net/netfilter/nf_nat_proto_udp.c b/net/netfilter/nf_nat_proto_udp.c -index b1e6272..f7e8b04 100644 +index 5790f70a83b2..0b26bb52aef6 100644 --- a/net/netfilter/nf_nat_proto_udp.c +++ b/net/netfilter/nf_nat_proto_udp.c @@ -19,15 +19,15 @@ @@ -632,7 +604,7 @@ index b1e6272..f7e8b04 100644 +static int udp_unique_tuple(const struct nf_nat_l3proto *l3proto, struct nf_conntrack_tuple *tuple, - const struct nf_nat_range *range, + const struct nf_nat_range2 *range, enum nf_nat_manip_type maniptype, const struct nf_conn *ct) { @@ -642,20 +614,16 @@ index b1e6272..f7e8b04 100644 + &udp_port_rover); } - static bool -diff --git a/net/netfilter/nf_nat_proto_udplite.c b/net/netfilter/nf_nat_proto_udplite.c -index 58340c9..56b06fe 100644 ---- a/net/netfilter/nf_nat_proto_udplite.c -+++ b/net/netfilter/nf_nat_proto_udplite.c -@@ -19,15 +19,15 @@ - - static u16 udplite_port_rover; + static void +@@ -97,15 +97,15 @@ static bool udplite_manip_pkt(struct sk_buff *skb, + return true; + } -static void +static int udplite_unique_tuple(const struct nf_nat_l3proto *l3proto, struct nf_conntrack_tuple *tuple, - const struct nf_nat_range *range, + const struct nf_nat_range2 *range, enum nf_nat_manip_type maniptype, const struct nf_conn *ct) { @@ -665,9 +633,9 @@ index 58340c9..56b06fe 100644 + &udplite_port_rover); } - static bool + const struct nf_nat_l4proto nf_nat_l4proto_udplite = { diff --git a/net/netfilter/nf_nat_proto_unknown.c b/net/netfilter/nf_nat_proto_unknown.c -index 6e494d5..4ad71c8 100644 +index c5db3e251232..377a2938cd79 100644 --- a/net/netfilter/nf_nat_proto_unknown.c +++ b/net/netfilter/nf_nat_proto_unknown.c @@ -25,7 +25,7 @@ static bool unknown_in_range(const struct nf_conntrack_tuple *tuple, @@ -677,7 +645,7 @@ index 6e494d5..4ad71c8 100644 -static void unknown_unique_tuple(const struct nf_nat_l3proto *l3proto, +static int unknown_unique_tuple(const struct nf_nat_l3proto *l3proto, struct nf_conntrack_tuple *tuple, - const struct nf_nat_range *range, + const struct nf_nat_range2 *range, enum nf_nat_manip_type maniptype, @@ -34,7 +34,7 @@ static void unknown_unique_tuple(const struct nf_nat_l3proto *l3proto, /* Sorry: we can't help you; if it's not unique, we can't frob @@ -688,6 +656,3 @@ index 6e494d5..4ad71c8 100644 } static bool --- -2.18.0 - diff --git a/patch/series b/patch/series index 7ad66f8b6..187055c91 100755 --- a/patch/series +++ b/patch/series @@ -36,7 +36,7 @@ driver-net-tg3-add-param-short-preamble-and-reset.patch # 0042-armhf-proc-dma-kconfig.patch net-psample-fix-skb-over-panic.patch net-backport-ipv6-missing-route.patch -# Support-for-fullcone-nat.patch +Support-for-fullcone-nat.patch driver-ixgbe-external-phy.patch net-fix-skb-csum-update-in-inet_proto_csum_replace16.patch #