Merge git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next
Pablo Neira Ayuso says: ==================== Netfilter updates for net-next The following patchset contains Netfilter updates for net-next, misc updates and fallout fixes from recent Florian's code rewritting (from last pull request): 1) Use new flowi4_l3mdev field in ip_route_me_harder(), from Martin Willi. 2) Avoid unnecessary GC with a timestamp in conncount, from William Tu and Yifeng Sun. 3) Remove TCP conntrack debugging, from Florian Westphal. 4) Fix compilation warning in ctnetlink, from Florian. * git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next: netfilter: ctnetlink: fix up for "netfilter: conntrack: remove unconfirmed list" netfilter: conntrack: remove pr_debug callsites from tcp tracker netfilter: nf_conncount: reduce unnecessary GC netfilter: Use l3mdev flow key when re-routing mangled packets ==================== Link: https://lore.kernel.org/r/20220519220206.722153-1-pablo@netfilter.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
805cb5aadc
|
@ -10,6 +10,7 @@ struct nf_conncount_data;
|
||||||
|
|
||||||
struct nf_conncount_list {
|
struct nf_conncount_list {
|
||||||
spinlock_t list_lock;
|
spinlock_t list_lock;
|
||||||
|
u32 last_gc; /* jiffies at most recent gc */
|
||||||
struct list_head head; /* connections with the same filtering key */
|
struct list_head head; /* connections with the same filtering key */
|
||||||
unsigned int count; /* length of list */
|
unsigned int count; /* length of list */
|
||||||
};
|
};
|
||||||
|
|
|
@ -45,8 +45,7 @@ int ip_route_me_harder(struct net *net, struct sock *sk, struct sk_buff *skb, un
|
||||||
fl4.saddr = saddr;
|
fl4.saddr = saddr;
|
||||||
fl4.flowi4_tos = RT_TOS(iph->tos);
|
fl4.flowi4_tos = RT_TOS(iph->tos);
|
||||||
fl4.flowi4_oif = sk ? sk->sk_bound_dev_if : 0;
|
fl4.flowi4_oif = sk ? sk->sk_bound_dev_if : 0;
|
||||||
if (!fl4.flowi4_oif)
|
fl4.flowi4_l3mdev = l3mdev_master_ifindex(dev);
|
||||||
fl4.flowi4_oif = l3mdev_master_ifindex(dev);
|
|
||||||
fl4.flowi4_mark = skb->mark;
|
fl4.flowi4_mark = skb->mark;
|
||||||
fl4.flowi4_flags = flags;
|
fl4.flowi4_flags = flags;
|
||||||
fib4_rules_early_flow_dissect(net, skb, &fl4, &flkeys);
|
fib4_rules_early_flow_dissect(net, skb, &fl4, &flkeys);
|
||||||
|
|
|
@ -31,6 +31,7 @@ int ip6_route_me_harder(struct net *net, struct sock *sk_partial, struct sk_buff
|
||||||
int strict = (ipv6_addr_type(&iph->daddr) &
|
int strict = (ipv6_addr_type(&iph->daddr) &
|
||||||
(IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL));
|
(IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL));
|
||||||
struct flowi6 fl6 = {
|
struct flowi6 fl6 = {
|
||||||
|
.flowi6_l3mdev = l3mdev_master_ifindex(dev),
|
||||||
.flowi6_mark = skb->mark,
|
.flowi6_mark = skb->mark,
|
||||||
.flowi6_uid = sock_net_uid(net, sk),
|
.flowi6_uid = sock_net_uid(net, sk),
|
||||||
.daddr = iph->daddr,
|
.daddr = iph->daddr,
|
||||||
|
@ -42,8 +43,6 @@ int ip6_route_me_harder(struct net *net, struct sock *sk_partial, struct sk_buff
|
||||||
fl6.flowi6_oif = sk->sk_bound_dev_if;
|
fl6.flowi6_oif = sk->sk_bound_dev_if;
|
||||||
else if (strict)
|
else if (strict)
|
||||||
fl6.flowi6_oif = dev->ifindex;
|
fl6.flowi6_oif = dev->ifindex;
|
||||||
else
|
|
||||||
fl6.flowi6_oif = l3mdev_master_ifindex(dev);
|
|
||||||
|
|
||||||
fib6_rules_early_flow_dissect(net, skb, &fl6, &flkeys);
|
fib6_rules_early_flow_dissect(net, skb, &fl6, &flkeys);
|
||||||
dst = ip6_route_output(net, sk, &fl6);
|
dst = ip6_route_output(net, sk, &fl6);
|
||||||
|
|
|
@ -132,6 +132,9 @@ static int __nf_conncount_add(struct net *net,
|
||||||
struct nf_conn *found_ct;
|
struct nf_conn *found_ct;
|
||||||
unsigned int collect = 0;
|
unsigned int collect = 0;
|
||||||
|
|
||||||
|
if (time_is_after_eq_jiffies((unsigned long)list->last_gc))
|
||||||
|
goto add_new_node;
|
||||||
|
|
||||||
/* check the saved connections */
|
/* check the saved connections */
|
||||||
list_for_each_entry_safe(conn, conn_n, &list->head, node) {
|
list_for_each_entry_safe(conn, conn_n, &list->head, node) {
|
||||||
if (collect > CONNCOUNT_GC_MAX_NODES)
|
if (collect > CONNCOUNT_GC_MAX_NODES)
|
||||||
|
@ -177,6 +180,7 @@ static int __nf_conncount_add(struct net *net,
|
||||||
nf_ct_put(found_ct);
|
nf_ct_put(found_ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
add_new_node:
|
||||||
if (WARN_ON_ONCE(list->count > INT_MAX))
|
if (WARN_ON_ONCE(list->count > INT_MAX))
|
||||||
return -EOVERFLOW;
|
return -EOVERFLOW;
|
||||||
|
|
||||||
|
@ -190,6 +194,7 @@ static int __nf_conncount_add(struct net *net,
|
||||||
conn->jiffies32 = (u32)jiffies;
|
conn->jiffies32 = (u32)jiffies;
|
||||||
list_add_tail(&conn->node, &list->head);
|
list_add_tail(&conn->node, &list->head);
|
||||||
list->count++;
|
list->count++;
|
||||||
|
list->last_gc = (u32)jiffies;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,6 +219,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
|
||||||
spin_lock_init(&list->list_lock);
|
spin_lock_init(&list->list_lock);
|
||||||
INIT_LIST_HEAD(&list->head);
|
INIT_LIST_HEAD(&list->head);
|
||||||
list->count = 0;
|
list->count = 0;
|
||||||
|
list->last_gc = (u32)jiffies;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(nf_conncount_list_init);
|
EXPORT_SYMBOL_GPL(nf_conncount_list_init);
|
||||||
|
|
||||||
|
@ -227,6 +233,10 @@ bool nf_conncount_gc_list(struct net *net,
|
||||||
unsigned int collected = 0;
|
unsigned int collected = 0;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
|
/* don't bother if we just did GC */
|
||||||
|
if (time_is_after_eq_jiffies((unsigned long)READ_ONCE(list->last_gc)))
|
||||||
|
return false;
|
||||||
|
|
||||||
/* don't bother if other cpu is already doing GC */
|
/* don't bother if other cpu is already doing GC */
|
||||||
if (!spin_trylock(&list->list_lock))
|
if (!spin_trylock(&list->list_lock))
|
||||||
return false;
|
return false;
|
||||||
|
@ -258,6 +268,7 @@ bool nf_conncount_gc_list(struct net *net,
|
||||||
|
|
||||||
if (!list->count)
|
if (!list->count)
|
||||||
ret = true;
|
ret = true;
|
||||||
|
list->last_gc = (u32)jiffies;
|
||||||
spin_unlock(&list->list_lock);
|
spin_unlock(&list->list_lock);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -1714,6 +1714,7 @@ static int ctnetlink_done_list(struct netlink_callback *cb)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_NF_CONNTRACK_EVENTS
|
||||||
static int ctnetlink_dump_one_entry(struct sk_buff *skb,
|
static int ctnetlink_dump_one_entry(struct sk_buff *skb,
|
||||||
struct netlink_callback *cb,
|
struct netlink_callback *cb,
|
||||||
struct nf_conn *ct,
|
struct nf_conn *ct,
|
||||||
|
@ -1754,6 +1755,7 @@ static int ctnetlink_dump_one_entry(struct sk_buff *skb,
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ctnetlink_dump_unconfirmed(struct sk_buff *skb, struct netlink_callback *cb)
|
ctnetlink_dump_unconfirmed(struct sk_buff *skb, struct netlink_callback *cb)
|
||||||
|
|
|
@ -485,7 +485,6 @@ static bool tcp_in_window(struct nf_conn *ct,
|
||||||
struct nf_tcp_net *tn = nf_tcp_pernet(net);
|
struct nf_tcp_net *tn = nf_tcp_pernet(net);
|
||||||
struct ip_ct_tcp_state *sender = &state->seen[dir];
|
struct ip_ct_tcp_state *sender = &state->seen[dir];
|
||||||
struct ip_ct_tcp_state *receiver = &state->seen[!dir];
|
struct ip_ct_tcp_state *receiver = &state->seen[!dir];
|
||||||
const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
|
|
||||||
__u32 seq, ack, sack, end, win, swin;
|
__u32 seq, ack, sack, end, win, swin;
|
||||||
u16 win_raw;
|
u16 win_raw;
|
||||||
s32 receiver_offset;
|
s32 receiver_offset;
|
||||||
|
@ -508,18 +507,6 @@ static bool tcp_in_window(struct nf_conn *ct,
|
||||||
ack -= receiver_offset;
|
ack -= receiver_offset;
|
||||||
sack -= receiver_offset;
|
sack -= receiver_offset;
|
||||||
|
|
||||||
pr_debug("tcp_in_window: START\n");
|
|
||||||
pr_debug("tcp_in_window: ");
|
|
||||||
nf_ct_dump_tuple(tuple);
|
|
||||||
pr_debug("seq=%u ack=%u+(%d) sack=%u+(%d) win=%u end=%u\n",
|
|
||||||
seq, ack, receiver_offset, sack, receiver_offset, win, end);
|
|
||||||
pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
|
|
||||||
"receiver end=%u maxend=%u maxwin=%u scale=%i\n",
|
|
||||||
sender->td_end, sender->td_maxend, sender->td_maxwin,
|
|
||||||
sender->td_scale,
|
|
||||||
receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
|
|
||||||
receiver->td_scale);
|
|
||||||
|
|
||||||
if (sender->td_maxwin == 0) {
|
if (sender->td_maxwin == 0) {
|
||||||
/*
|
/*
|
||||||
* Initialize sender data.
|
* Initialize sender data.
|
||||||
|
@ -597,27 +584,10 @@ static bool tcp_in_window(struct nf_conn *ct,
|
||||||
*/
|
*/
|
||||||
seq = end = sender->td_end;
|
seq = end = sender->td_end;
|
||||||
|
|
||||||
pr_debug("tcp_in_window: ");
|
|
||||||
nf_ct_dump_tuple(tuple);
|
|
||||||
pr_debug("seq=%u ack=%u+(%d) sack=%u+(%d) win=%u end=%u\n",
|
|
||||||
seq, ack, receiver_offset, sack, receiver_offset, win, end);
|
|
||||||
pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
|
|
||||||
"receiver end=%u maxend=%u maxwin=%u scale=%i\n",
|
|
||||||
sender->td_end, sender->td_maxend, sender->td_maxwin,
|
|
||||||
sender->td_scale,
|
|
||||||
receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
|
|
||||||
receiver->td_scale);
|
|
||||||
|
|
||||||
/* Is the ending sequence in the receive window (if available)? */
|
/* Is the ending sequence in the receive window (if available)? */
|
||||||
in_recv_win = !receiver->td_maxwin ||
|
in_recv_win = !receiver->td_maxwin ||
|
||||||
after(end, sender->td_end - receiver->td_maxwin - 1);
|
after(end, sender->td_end - receiver->td_maxwin - 1);
|
||||||
|
|
||||||
pr_debug("tcp_in_window: I=%i II=%i III=%i IV=%i\n",
|
|
||||||
before(seq, sender->td_maxend + 1),
|
|
||||||
(in_recv_win ? 1 : 0),
|
|
||||||
before(sack, receiver->td_end + 1),
|
|
||||||
after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1));
|
|
||||||
|
|
||||||
if (before(seq, sender->td_maxend + 1) &&
|
if (before(seq, sender->td_maxend + 1) &&
|
||||||
in_recv_win &&
|
in_recv_win &&
|
||||||
before(sack, receiver->td_end + 1) &&
|
before(sack, receiver->td_end + 1) &&
|
||||||
|
@ -698,11 +668,6 @@ static bool tcp_in_window(struct nf_conn *ct,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_debug("tcp_in_window: res=%u sender end=%u maxend=%u maxwin=%u "
|
|
||||||
"receiver end=%u maxend=%u maxwin=%u\n",
|
|
||||||
res, sender->td_end, sender->td_maxend, sender->td_maxwin,
|
|
||||||
receiver->td_end, receiver->td_maxend, receiver->td_maxwin);
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -772,8 +737,6 @@ static noinline bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb,
|
||||||
enum tcp_conntrack new_state;
|
enum tcp_conntrack new_state;
|
||||||
struct net *net = nf_ct_net(ct);
|
struct net *net = nf_ct_net(ct);
|
||||||
const struct nf_tcp_net *tn = nf_tcp_pernet(net);
|
const struct nf_tcp_net *tn = nf_tcp_pernet(net);
|
||||||
const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[0];
|
|
||||||
const struct ip_ct_tcp_state *receiver = &ct->proto.tcp.seen[1];
|
|
||||||
|
|
||||||
/* Don't need lock here: this conntrack not in circulation yet */
|
/* Don't need lock here: this conntrack not in circulation yet */
|
||||||
new_state = tcp_conntracks[0][get_conntrack_index(th)][TCP_CONNTRACK_NONE];
|
new_state = tcp_conntracks[0][get_conntrack_index(th)][TCP_CONNTRACK_NONE];
|
||||||
|
@ -826,14 +789,6 @@ static noinline bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb,
|
||||||
|
|
||||||
/* tcp_packet will set them */
|
/* tcp_packet will set them */
|
||||||
ct->proto.tcp.last_index = TCP_NONE_SET;
|
ct->proto.tcp.last_index = TCP_NONE_SET;
|
||||||
|
|
||||||
pr_debug("%s: sender end=%u maxend=%u maxwin=%u scale=%i "
|
|
||||||
"receiver end=%u maxend=%u maxwin=%u scale=%i\n",
|
|
||||||
__func__,
|
|
||||||
sender->td_end, sender->td_maxend, sender->td_maxwin,
|
|
||||||
sender->td_scale,
|
|
||||||
receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
|
|
||||||
receiver->td_scale);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1032,10 +987,11 @@ int nf_conntrack_tcp_packet(struct nf_conn *ct,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Invalid packet */
|
/* Invalid packet */
|
||||||
pr_debug("nf_ct_tcp: Invalid dir=%i index=%u ostate=%u\n",
|
|
||||||
dir, get_conntrack_index(th), old_state);
|
|
||||||
spin_unlock_bh(&ct->lock);
|
spin_unlock_bh(&ct->lock);
|
||||||
nf_ct_l4proto_log_invalid(skb, ct, state, "invalid state");
|
nf_ct_l4proto_log_invalid(skb, ct, state,
|
||||||
|
"packet (index %d) in dir %d invalid, state %s",
|
||||||
|
index, dir,
|
||||||
|
tcp_conntrack_names[old_state]);
|
||||||
return -NF_ACCEPT;
|
return -NF_ACCEPT;
|
||||||
case TCP_CONNTRACK_TIME_WAIT:
|
case TCP_CONNTRACK_TIME_WAIT:
|
||||||
/* RFC5961 compliance cause stack to send "challenge-ACK"
|
/* RFC5961 compliance cause stack to send "challenge-ACK"
|
||||||
|
|
Loading…
Reference in New Issue