Skip to content

Commit 1155a22

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next
Pablo Neira Ayuso says: ==================== Netfilter/IPVS updates for net-next The following patchset contains Netfilter updates for net-next: 1) Add safeguard to check for NULL tupe in objects updates via NFT_MSG_NEWOBJ, this should not ever happen. From Alok Tiwari. 2) Incorrect pointer check in the new destroy rule command, from Yang Yingliang. 3) Incorrect status bitcheck in nf_conntrack_udp_packet(), from Florian Westphal. 4) Simplify seq_print_acct(), from Ilia Gavrilov. 5) Use 2-arg optimal variant of kfree_rcu() in IPVS, from Julian Anastasov. 6) TCP connection enters CLOSE state in conntrack for locally originated TCP reset packet from the reject target, from Florian Westphal. The fixes #2 and #3 in this series address issues from the previous pull nf-next request in this net-next cycle. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 129ff4d + 2954fe6 commit 1155a22

File tree

12 files changed

+87
-11
lines changed

12 files changed

+87
-11
lines changed

include/linux/netfilter.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,11 +437,13 @@ nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)
437437
#include <linux/netfilter/nf_conntrack_zones_common.h>
438438

439439
void nf_ct_attach(struct sk_buff *, const struct sk_buff *);
440+
void nf_ct_set_closing(struct nf_conntrack *nfct);
440441
struct nf_conntrack_tuple;
441442
bool nf_ct_get_tuple_skb(struct nf_conntrack_tuple *dst_tuple,
442443
const struct sk_buff *skb);
443444
#else
444445
static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
446+
static inline void nf_ct_set_closing(struct nf_conntrack *nfct) {}
445447
struct nf_conntrack_tuple;
446448
static inline bool nf_ct_get_tuple_skb(struct nf_conntrack_tuple *dst_tuple,
447449
const struct sk_buff *skb)
@@ -459,6 +461,7 @@ struct nf_ct_hook {
459461
bool (*get_tuple_skb)(struct nf_conntrack_tuple *,
460462
const struct sk_buff *);
461463
void (*attach)(struct sk_buff *nskb, const struct sk_buff *skb);
464+
void (*set_closing)(struct nf_conntrack *nfct);
462465
};
463466
extern const struct nf_ct_hook __rcu *nf_ct_hook;
464467

include/net/ip_vs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ void ip_vs_stats_free(struct ip_vs_stats *stats);
461461

462462
/* Multiple chains processed in same tick */
463463
struct ip_vs_est_tick_data {
464+
struct rcu_head rcu_head;
464465
struct hlist_head chains[IPVS_EST_TICK_CHAINS];
465466
DECLARE_BITMAP(present, IPVS_EST_TICK_CHAINS);
466467
DECLARE_BITMAP(full, IPVS_EST_TICK_CHAINS);

include/net/netfilter/nf_conntrack.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,12 @@ struct nf_conn {
125125
union nf_conntrack_proto proto;
126126
};
127127

128+
static inline struct nf_conn *
129+
nf_ct_to_nf_conn(const struct nf_conntrack *nfct)
130+
{
131+
return container_of(nfct, struct nf_conn, ct_general);
132+
}
133+
128134
static inline struct nf_conn *
129135
nf_ct_tuplehash_to_ctrack(const struct nf_conntrack_tuple_hash *hash)
130136
{
@@ -175,6 +181,8 @@ nf_ct_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo)
175181

176182
void nf_ct_destroy(struct nf_conntrack *nfct);
177183

184+
void nf_conntrack_tcp_set_closing(struct nf_conn *ct);
185+
178186
/* decrement reference count on a conntrack */
179187
static inline void nf_ct_put(struct nf_conn *ct)
180188
{

net/ipv4/netfilter/nf_reject_ipv4.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ void nf_send_reset(struct net *net, struct sock *sk, struct sk_buff *oldskb,
280280
goto free_nskb;
281281

282282
nf_ct_attach(nskb, oldskb);
283+
nf_ct_set_closing(skb_nfct(oldskb));
283284

284285
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
285286
/* If we use ip_local_out for bridged traffic, the MAC source on

net/ipv6/netfilter/nf_reject_ipv6.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ void nf_send_reset6(struct net *net, struct sock *sk, struct sk_buff *oldskb,
345345
nf_reject_ip6_tcphdr_put(nskb, oldskb, otcph, otcplen);
346346

347347
nf_ct_attach(nskb, oldskb);
348+
nf_ct_set_closing(skb_nfct(oldskb));
348349

349350
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
350351
/* If we use ip6_local_out for bridged traffic, the MAC source on

net/netfilter/core.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,22 @@ void nf_conntrack_destroy(struct nf_conntrack *nfct)
702702
}
703703
EXPORT_SYMBOL(nf_conntrack_destroy);
704704

705+
void nf_ct_set_closing(struct nf_conntrack *nfct)
706+
{
707+
const struct nf_ct_hook *ct_hook;
708+
709+
if (!nfct)
710+
return;
711+
712+
rcu_read_lock();
713+
ct_hook = rcu_dereference(nf_ct_hook);
714+
if (ct_hook)
715+
ct_hook->set_closing(nfct);
716+
717+
rcu_read_unlock();
718+
}
719+
EXPORT_SYMBOL_GPL(nf_ct_set_closing);
720+
705721
bool nf_ct_get_tuple_skb(struct nf_conntrack_tuple *dst_tuple,
706722
const struct sk_buff *skb)
707723
{

net/netfilter/ipvs/ip_vs_est.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ void ip_vs_stop_estimator(struct netns_ipvs *ipvs, struct ip_vs_stats *stats)
549549
__set_bit(row, kd->avail);
550550
if (!kd->tick_len[row]) {
551551
RCU_INIT_POINTER(kd->ticks[row], NULL);
552-
kfree_rcu(td);
552+
kfree_rcu(td, rcu_head);
553553
}
554554
kd->est_count--;
555555
if (kd->est_count) {

net/netfilter/nf_conntrack_core.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2748,11 +2748,23 @@ int nf_conntrack_init_start(void)
27482748
return ret;
27492749
}
27502750

2751+
static void nf_conntrack_set_closing(struct nf_conntrack *nfct)
2752+
{
2753+
struct nf_conn *ct = nf_ct_to_nf_conn(nfct);
2754+
2755+
switch (nf_ct_protonum(ct)) {
2756+
case IPPROTO_TCP:
2757+
nf_conntrack_tcp_set_closing(ct);
2758+
break;
2759+
}
2760+
}
2761+
27512762
static const struct nf_ct_hook nf_conntrack_hook = {
27522763
.update = nf_conntrack_update,
27532764
.destroy = nf_ct_destroy,
27542765
.get_tuple_skb = nf_conntrack_get_tuple_skb,
27552766
.attach = nf_conntrack_attach,
2767+
.set_closing = nf_conntrack_set_closing,
27562768
};
27572769

27582770
void nf_conntrack_init_end(void)

net/netfilter/nf_conntrack_proto_tcp.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,41 @@ static bool tcp_can_early_drop(const struct nf_conn *ct)
911911
return false;
912912
}
913913

914+
void nf_conntrack_tcp_set_closing(struct nf_conn *ct)
915+
{
916+
enum tcp_conntrack old_state;
917+
const unsigned int *timeouts;
918+
u32 timeout;
919+
920+
if (!nf_ct_is_confirmed(ct))
921+
return;
922+
923+
spin_lock_bh(&ct->lock);
924+
old_state = ct->proto.tcp.state;
925+
ct->proto.tcp.state = TCP_CONNTRACK_CLOSE;
926+
927+
if (old_state == TCP_CONNTRACK_CLOSE ||
928+
test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status)) {
929+
spin_unlock_bh(&ct->lock);
930+
return;
931+
}
932+
933+
timeouts = nf_ct_timeout_lookup(ct);
934+
if (!timeouts) {
935+
const struct nf_tcp_net *tn;
936+
937+
tn = nf_tcp_pernet(nf_ct_net(ct));
938+
timeouts = tn->timeouts;
939+
}
940+
941+
timeout = timeouts[TCP_CONNTRACK_CLOSE];
942+
WRITE_ONCE(ct->timeout, timeout + nfct_time_stamp);
943+
944+
spin_unlock_bh(&ct->lock);
945+
946+
nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
947+
}
948+
914949
static void nf_ct_tcp_state_reset(struct ip_ct_tcp_state *state)
915950
{
916951
state->td_end = 0;

net/netfilter/nf_conntrack_proto_udp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ int nf_conntrack_udp_packet(struct nf_conn *ct,
104104
/* If we've seen traffic both ways, this is some kind of UDP
105105
* stream. Set Assured.
106106
*/
107-
if (status & IPS_SEEN_REPLY_BIT) {
107+
if (status & IPS_SEEN_REPLY) {
108108
unsigned long extra = timeouts[UDP_CT_UNREPLIED];
109109
bool stream = false;
110110

0 commit comments

Comments
 (0)