Commit 54fd494a authored by Jakub Kicinski's avatar Jakub Kicinski

Merge tag 'nf-next-2023-03-30' of https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next

Florian Westphal says:

====================
netfilter updates for net-next

1. No need to disable BH in nfnetlink proc handler, freeing happens
   via call_rcu.
2. Expose classid in nfetlink_queue, from Eric Sage.
3. Fix nfnetlink message description comments, from Matthieu De Beule.
4. Allow removal of offloaded connections via ctnetlink, from Paul Blakey.

* tag 'nf-next-2023-03-30' of https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next:
  netfilter: ctnetlink: Support offloaded conntrack entry deletion
  netfilter: Correct documentation errors in nf_tables.h
  netfilter: nfnetlink_queue: enable classid socket info retrieval
  netfilter: nfnetlink_log: remove rcu_bh usage
====================

Link: https://lore.kernel.org/r/20230331104809.2959-1-fw@strlen.deSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 99b3a769 9b7c68b3
...@@ -685,7 +685,7 @@ enum nft_range_ops { ...@@ -685,7 +685,7 @@ enum nft_range_ops {
* enum nft_range_attributes - nf_tables range expression netlink attributes * enum nft_range_attributes - nf_tables range expression netlink attributes
* *
* @NFTA_RANGE_SREG: source register of data to compare (NLA_U32: nft_registers) * @NFTA_RANGE_SREG: source register of data to compare (NLA_U32: nft_registers)
* @NFTA_RANGE_OP: cmp operation (NLA_U32: nft_cmp_ops) * @NFTA_RANGE_OP: cmp operation (NLA_U32: nft_range_ops)
* @NFTA_RANGE_FROM_DATA: data range from (NLA_NESTED: nft_data_attributes) * @NFTA_RANGE_FROM_DATA: data range from (NLA_NESTED: nft_data_attributes)
* @NFTA_RANGE_TO_DATA: data range to (NLA_NESTED: nft_data_attributes) * @NFTA_RANGE_TO_DATA: data range to (NLA_NESTED: nft_data_attributes)
*/ */
...@@ -878,7 +878,7 @@ enum nft_exthdr_op { ...@@ -878,7 +878,7 @@ enum nft_exthdr_op {
* @NFTA_EXTHDR_LEN: extension header length (NLA_U32) * @NFTA_EXTHDR_LEN: extension header length (NLA_U32)
* @NFTA_EXTHDR_FLAGS: extension header flags (NLA_U32) * @NFTA_EXTHDR_FLAGS: extension header flags (NLA_U32)
* @NFTA_EXTHDR_OP: option match type (NLA_U32) * @NFTA_EXTHDR_OP: option match type (NLA_U32)
* @NFTA_EXTHDR_SREG: option match type (NLA_U32) * @NFTA_EXTHDR_SREG: source register (NLA_U32: nft_registers)
*/ */
enum nft_exthdr_attributes { enum nft_exthdr_attributes {
NFTA_EXTHDR_UNSPEC, NFTA_EXTHDR_UNSPEC,
...@@ -1262,10 +1262,10 @@ enum nft_last_attributes { ...@@ -1262,10 +1262,10 @@ enum nft_last_attributes {
/** /**
* enum nft_log_attributes - nf_tables log expression netlink attributes * enum nft_log_attributes - nf_tables log expression netlink attributes
* *
* @NFTA_LOG_GROUP: netlink group to send messages to (NLA_U32) * @NFTA_LOG_GROUP: netlink group to send messages to (NLA_U16)
* @NFTA_LOG_PREFIX: prefix to prepend to log messages (NLA_STRING) * @NFTA_LOG_PREFIX: prefix to prepend to log messages (NLA_STRING)
* @NFTA_LOG_SNAPLEN: length of payload to include in netlink message (NLA_U32) * @NFTA_LOG_SNAPLEN: length of payload to include in netlink message (NLA_U32)
* @NFTA_LOG_QTHRESHOLD: queue threshold (NLA_U32) * @NFTA_LOG_QTHRESHOLD: queue threshold (NLA_U16)
* @NFTA_LOG_LEVEL: log level (NLA_U32) * @NFTA_LOG_LEVEL: log level (NLA_U32)
* @NFTA_LOG_FLAGS: logging flags (NLA_U32) * @NFTA_LOG_FLAGS: logging flags (NLA_U32)
*/ */
......
...@@ -62,6 +62,7 @@ enum nfqnl_attr_type { ...@@ -62,6 +62,7 @@ enum nfqnl_attr_type {
NFQA_VLAN, /* nested attribute: packet vlan info */ NFQA_VLAN, /* nested attribute: packet vlan info */
NFQA_L2HDR, /* full L2 header */ NFQA_L2HDR, /* full L2 header */
NFQA_PRIORITY, /* skb->priority */ NFQA_PRIORITY, /* skb->priority */
NFQA_CGROUP_CLASSID, /* __u32 cgroup classid */
__NFQA_MAX __NFQA_MAX
}; };
......
...@@ -1554,9 +1554,6 @@ static const struct nla_policy ct_nla_policy[CTA_MAX+1] = { ...@@ -1554,9 +1554,6 @@ static const struct nla_policy ct_nla_policy[CTA_MAX+1] = {
static int ctnetlink_flush_iterate(struct nf_conn *ct, void *data) static int ctnetlink_flush_iterate(struct nf_conn *ct, void *data)
{ {
if (test_bit(IPS_OFFLOAD_BIT, &ct->status))
return 0;
return ctnetlink_filter_match(ct, data); return ctnetlink_filter_match(ct, data);
} }
...@@ -1626,11 +1623,6 @@ static int ctnetlink_del_conntrack(struct sk_buff *skb, ...@@ -1626,11 +1623,6 @@ static int ctnetlink_del_conntrack(struct sk_buff *skb,
ct = nf_ct_tuplehash_to_ctrack(h); ct = nf_ct_tuplehash_to_ctrack(h);
if (test_bit(IPS_OFFLOAD_BIT, &ct->status)) {
nf_ct_put(ct);
return -EBUSY;
}
if (cda[CTA_ID]) { if (cda[CTA_ID]) {
__be32 id = nla_get_be32(cda[CTA_ID]); __be32 id = nla_get_be32(cda[CTA_ID]);
......
...@@ -103,9 +103,9 @@ static inline u_int8_t instance_hashfn(u_int16_t group_num) ...@@ -103,9 +103,9 @@ static inline u_int8_t instance_hashfn(u_int16_t group_num)
} }
static struct nfulnl_instance * static struct nfulnl_instance *
__instance_lookup(struct nfnl_log_net *log, u_int16_t group_num) __instance_lookup(const struct nfnl_log_net *log, u16 group_num)
{ {
struct hlist_head *head; const struct hlist_head *head;
struct nfulnl_instance *inst; struct nfulnl_instance *inst;
head = &log->instance_table[instance_hashfn(group_num)]; head = &log->instance_table[instance_hashfn(group_num)];
...@@ -123,15 +123,25 @@ instance_get(struct nfulnl_instance *inst) ...@@ -123,15 +123,25 @@ instance_get(struct nfulnl_instance *inst)
} }
static struct nfulnl_instance * static struct nfulnl_instance *
instance_lookup_get(struct nfnl_log_net *log, u_int16_t group_num) instance_lookup_get_rcu(const struct nfnl_log_net *log, u16 group_num)
{ {
struct nfulnl_instance *inst; struct nfulnl_instance *inst;
rcu_read_lock_bh();
inst = __instance_lookup(log, group_num); inst = __instance_lookup(log, group_num);
if (inst && !refcount_inc_not_zero(&inst->use)) if (inst && !refcount_inc_not_zero(&inst->use))
inst = NULL; inst = NULL;
rcu_read_unlock_bh();
return inst;
}
static struct nfulnl_instance *
instance_lookup_get(const struct nfnl_log_net *log, u16 group_num)
{
struct nfulnl_instance *inst;
rcu_read_lock();
inst = instance_lookup_get_rcu(log, group_num);
rcu_read_unlock();
return inst; return inst;
} }
...@@ -698,7 +708,7 @@ nfulnl_log_packet(struct net *net, ...@@ -698,7 +708,7 @@ nfulnl_log_packet(struct net *net,
else else
li = &default_loginfo; li = &default_loginfo;
inst = instance_lookup_get(log, li->u.ulog.group); inst = instance_lookup_get_rcu(log, li->u.ulog.group);
if (!inst) if (!inst)
return; return;
...@@ -1030,7 +1040,7 @@ static struct hlist_node *get_first(struct net *net, struct iter_state *st) ...@@ -1030,7 +1040,7 @@ static struct hlist_node *get_first(struct net *net, struct iter_state *st)
struct hlist_head *head = &log->instance_table[st->bucket]; struct hlist_head *head = &log->instance_table[st->bucket];
if (!hlist_empty(head)) if (!hlist_empty(head))
return rcu_dereference_bh(hlist_first_rcu(head)); return rcu_dereference(hlist_first_rcu(head));
} }
return NULL; return NULL;
} }
...@@ -1038,7 +1048,7 @@ static struct hlist_node *get_first(struct net *net, struct iter_state *st) ...@@ -1038,7 +1048,7 @@ static struct hlist_node *get_first(struct net *net, struct iter_state *st)
static struct hlist_node *get_next(struct net *net, struct iter_state *st, static struct hlist_node *get_next(struct net *net, struct iter_state *st,
struct hlist_node *h) struct hlist_node *h)
{ {
h = rcu_dereference_bh(hlist_next_rcu(h)); h = rcu_dereference(hlist_next_rcu(h));
while (!h) { while (!h) {
struct nfnl_log_net *log; struct nfnl_log_net *log;
struct hlist_head *head; struct hlist_head *head;
...@@ -1048,7 +1058,7 @@ static struct hlist_node *get_next(struct net *net, struct iter_state *st, ...@@ -1048,7 +1058,7 @@ static struct hlist_node *get_next(struct net *net, struct iter_state *st,
log = nfnl_log_pernet(net); log = nfnl_log_pernet(net);
head = &log->instance_table[st->bucket]; head = &log->instance_table[st->bucket];
h = rcu_dereference_bh(hlist_first_rcu(head)); h = rcu_dereference(hlist_first_rcu(head));
} }
return h; return h;
} }
...@@ -1066,9 +1076,9 @@ static struct hlist_node *get_idx(struct net *net, struct iter_state *st, ...@@ -1066,9 +1076,9 @@ static struct hlist_node *get_idx(struct net *net, struct iter_state *st,
} }
static void *seq_start(struct seq_file *s, loff_t *pos) static void *seq_start(struct seq_file *s, loff_t *pos)
__acquires(rcu_bh) __acquires(rcu)
{ {
rcu_read_lock_bh(); rcu_read_lock();
return get_idx(seq_file_net(s), s->private, *pos); return get_idx(seq_file_net(s), s->private, *pos);
} }
...@@ -1079,9 +1089,9 @@ static void *seq_next(struct seq_file *s, void *v, loff_t *pos) ...@@ -1079,9 +1089,9 @@ static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
} }
static void seq_stop(struct seq_file *s, void *v) static void seq_stop(struct seq_file *s, void *v)
__releases(rcu_bh) __releases(rcu)
{ {
rcu_read_unlock_bh(); rcu_read_unlock();
} }
static int seq_show(struct seq_file *s, void *v) static int seq_show(struct seq_file *s, void *v)
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <linux/netfilter/nfnetlink_queue.h> #include <linux/netfilter/nfnetlink_queue.h>
#include <linux/netfilter/nf_conntrack_common.h> #include <linux/netfilter/nf_conntrack_common.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/cgroup-defs.h>
#include <net/sock.h> #include <net/sock.h>
#include <net/tcp_states.h> #include <net/tcp_states.h>
#include <net/netfilter/nf_queue.h> #include <net/netfilter/nf_queue.h>
...@@ -301,6 +302,19 @@ static int nfqnl_put_sk_uidgid(struct sk_buff *skb, struct sock *sk) ...@@ -301,6 +302,19 @@ static int nfqnl_put_sk_uidgid(struct sk_buff *skb, struct sock *sk)
return -1; return -1;
} }
static int nfqnl_put_sk_classid(struct sk_buff *skb, struct sock *sk)
{
#if IS_ENABLED(CONFIG_CGROUP_NET_CLASSID)
if (sk && sk_fullsock(sk)) {
u32 classid = sock_cgroup_classid(&sk->sk_cgrp_data);
if (classid && nla_put_be32(skb, NFQA_CGROUP_CLASSID, htonl(classid)))
return -1;
}
#endif
return 0;
}
static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata)
{ {
u32 seclen = 0; u32 seclen = 0;
...@@ -406,6 +420,9 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, ...@@ -406,6 +420,9 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
+ nla_total_size(sizeof(u_int32_t)) /* priority */ + nla_total_size(sizeof(u_int32_t)) /* priority */
+ nla_total_size(sizeof(struct nfqnl_msg_packet_hw)) + nla_total_size(sizeof(struct nfqnl_msg_packet_hw))
+ nla_total_size(sizeof(u_int32_t)) /* skbinfo */ + nla_total_size(sizeof(u_int32_t)) /* skbinfo */
#if IS_ENABLED(CONFIG_CGROUP_NET_CLASSID)
+ nla_total_size(sizeof(u_int32_t)) /* classid */
#endif
+ nla_total_size(sizeof(u_int32_t)); /* cap_len */ + nla_total_size(sizeof(u_int32_t)); /* cap_len */
tstamp = skb_tstamp_cond(entskb, false); tstamp = skb_tstamp_cond(entskb, false);
...@@ -599,6 +616,9 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, ...@@ -599,6 +616,9 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
nfqnl_put_sk_uidgid(skb, entskb->sk) < 0) nfqnl_put_sk_uidgid(skb, entskb->sk) < 0)
goto nla_put_failure; goto nla_put_failure;
if (nfqnl_put_sk_classid(skb, entskb->sk) < 0)
goto nla_put_failure;
if (seclen && nla_put(skb, NFQA_SECCTX, seclen, secdata)) if (seclen && nla_put(skb, NFQA_SECCTX, seclen, secdata))
goto nla_put_failure; goto nla_put_failure;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment