mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-30 13:46:47 +07:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
Pablo Neira Ayuso says: ==================== Netfilter fixes for net The following patchset contains Netfilter fixes for your net tree, they are: 1) Fix incorrect timestamp in nfnetlink_queue introduced when addressing y2038 safe timestamp, from Florian Westphal. 2) Get rid of leftover conntrack definition from the previous merge window, oneliner from Florian. 3) Make nf_queue handler pernet to resolve race on dereferencing the hook state structure with netns removal, from Eric Biederman. 4) Ensure clean exit on unregistered helper ports, from Taehee Yoo. 5) Restore FLOWI_FLAG_KNOWN_NH in nf_dup_ipv6. This got lost while generalizing xt_TEE to add packet duplication support in nf_tables, from Paolo Abeni. 6) Insufficient netlink NFTA_SET_TABLE attribute check in nf_tables_getset(), from Phil Turnbull. 7) Reject helper registration on duplicated ports via modparams. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
fc14963f24
@ -28,8 +28,8 @@ struct nf_queue_handler {
|
||||
struct nf_hook_ops *ops);
|
||||
};
|
||||
|
||||
void nf_register_queue_handler(const struct nf_queue_handler *qh);
|
||||
void nf_unregister_queue_handler(void);
|
||||
void nf_register_queue_handler(struct net *net, const struct nf_queue_handler *qh);
|
||||
void nf_unregister_queue_handler(struct net *net);
|
||||
void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);
|
||||
|
||||
void nf_queue_entry_get_refs(struct nf_queue_entry *entry);
|
||||
|
@ -5,11 +5,13 @@
|
||||
|
||||
struct proc_dir_entry;
|
||||
struct nf_logger;
|
||||
struct nf_queue_handler;
|
||||
|
||||
struct netns_nf {
|
||||
#if defined CONFIG_PROC_FS
|
||||
struct proc_dir_entry *proc_netfilter;
|
||||
#endif
|
||||
const struct nf_queue_handler __rcu *queue_handler;
|
||||
const struct nf_logger __rcu *nf_loggers[NFPROTO_NUMPROTO];
|
||||
#ifdef CONFIG_SYSCTL
|
||||
struct ctl_table_header *nf_log_dir_header;
|
||||
|
@ -33,6 +33,7 @@ static bool nf_dup_ipv6_route(struct net *net, struct sk_buff *skb,
|
||||
fl6.daddr = *gw;
|
||||
fl6.flowlabel = (__force __be32)(((iph->flow_lbl[0] & 0xF) << 16) |
|
||||
(iph->flow_lbl[1] << 8) | iph->flow_lbl[2]);
|
||||
fl6.flowi6_flags = FLOWI_FLAG_KNOWN_NH;
|
||||
dst = ip6_route_output(net, NULL, &fl6);
|
||||
if (dst->error) {
|
||||
dst_release(dst);
|
||||
|
@ -632,6 +632,7 @@ static int __init nf_conntrack_ftp_init(void)
|
||||
if (ret) {
|
||||
pr_err("failed to register helper for pf: %d port: %d\n",
|
||||
ftp[i][j].tuple.src.l3num, ports[i]);
|
||||
ports_c = i;
|
||||
nf_conntrack_ftp_fini();
|
||||
return ret;
|
||||
}
|
||||
|
@ -361,9 +361,10 @@ EXPORT_SYMBOL_GPL(nf_ct_helper_log);
|
||||
|
||||
int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
|
||||
{
|
||||
int ret = 0;
|
||||
struct nf_conntrack_helper *cur;
|
||||
struct nf_conntrack_tuple_mask mask = { .src.u.all = htons(0xFFFF) };
|
||||
unsigned int h = helper_hash(&me->tuple);
|
||||
struct nf_conntrack_helper *cur;
|
||||
int ret = 0;
|
||||
|
||||
BUG_ON(me->expect_policy == NULL);
|
||||
BUG_ON(me->expect_class_max >= NF_CT_MAX_EXPECT_CLASSES);
|
||||
@ -371,9 +372,7 @@ int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
|
||||
|
||||
mutex_lock(&nf_ct_helper_mutex);
|
||||
hlist_for_each_entry(cur, &nf_ct_helper_hash[h], hnode) {
|
||||
if (strncmp(cur->name, me->name, NF_CT_HELPER_NAME_LEN) == 0 &&
|
||||
cur->tuple.src.l3num == me->tuple.src.l3num &&
|
||||
cur->tuple.dst.protonum == me->tuple.dst.protonum) {
|
||||
if (nf_ct_tuple_src_mask_cmp(&cur->tuple, &me->tuple, &mask)) {
|
||||
ret = -EEXIST;
|
||||
goto out;
|
||||
}
|
||||
|
@ -271,6 +271,7 @@ static int __init nf_conntrack_irc_init(void)
|
||||
if (ret) {
|
||||
pr_err("failed to register helper for pf: %u port: %u\n",
|
||||
irc[i].tuple.src.l3num, ports[i]);
|
||||
ports_c = i;
|
||||
nf_conntrack_irc_fini();
|
||||
return ret;
|
||||
}
|
||||
|
@ -223,6 +223,7 @@ static int __init nf_conntrack_sane_init(void)
|
||||
if (ret) {
|
||||
pr_err("failed to register helper for pf: %d port: %d\n",
|
||||
sane[i][j].tuple.src.l3num, ports[i]);
|
||||
ports_c = i;
|
||||
nf_conntrack_sane_fini();
|
||||
return ret;
|
||||
}
|
||||
|
@ -1669,6 +1669,7 @@ static int __init nf_conntrack_sip_init(void)
|
||||
if (ret) {
|
||||
pr_err("failed to register helper for pf: %u port: %u\n",
|
||||
sip[i][j].tuple.src.l3num, ports[i]);
|
||||
ports_c = i;
|
||||
nf_conntrack_sip_fini();
|
||||
return ret;
|
||||
}
|
||||
|
@ -487,8 +487,6 @@ static struct ctl_table nf_ct_sysctl_table[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
#define NET_NF_CONNTRACK_MAX 2089
|
||||
|
||||
static struct ctl_table nf_ct_netfilter_table[] = {
|
||||
{
|
||||
.procname = "nf_conntrack_max",
|
||||
|
@ -142,6 +142,7 @@ static int __init nf_conntrack_tftp_init(void)
|
||||
if (ret) {
|
||||
pr_err("failed to register helper for pf: %u port: %u\n",
|
||||
tftp[i][j].tuple.src.l3num, ports[i]);
|
||||
ports_c = i;
|
||||
nf_conntrack_tftp_fini();
|
||||
return ret;
|
||||
}
|
||||
|
@ -26,23 +26,21 @@
|
||||
* Once the queue is registered it must reinject all packets it
|
||||
* receives, no matter what.
|
||||
*/
|
||||
static const struct nf_queue_handler __rcu *queue_handler __read_mostly;
|
||||
|
||||
/* return EBUSY when somebody else is registered, return EEXIST if the
|
||||
* same handler is registered, return 0 in case of success. */
|
||||
void nf_register_queue_handler(const struct nf_queue_handler *qh)
|
||||
void nf_register_queue_handler(struct net *net, const struct nf_queue_handler *qh)
|
||||
{
|
||||
/* should never happen, we only have one queueing backend in kernel */
|
||||
WARN_ON(rcu_access_pointer(queue_handler));
|
||||
rcu_assign_pointer(queue_handler, qh);
|
||||
WARN_ON(rcu_access_pointer(net->nf.queue_handler));
|
||||
rcu_assign_pointer(net->nf.queue_handler, qh);
|
||||
}
|
||||
EXPORT_SYMBOL(nf_register_queue_handler);
|
||||
|
||||
/* The caller must flush their queue before this */
|
||||
void nf_unregister_queue_handler(void)
|
||||
void nf_unregister_queue_handler(struct net *net)
|
||||
{
|
||||
RCU_INIT_POINTER(queue_handler, NULL);
|
||||
synchronize_rcu();
|
||||
RCU_INIT_POINTER(net->nf.queue_handler, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL(nf_unregister_queue_handler);
|
||||
|
||||
@ -103,7 +101,7 @@ void nf_queue_nf_hook_drop(struct net *net, struct nf_hook_ops *ops)
|
||||
const struct nf_queue_handler *qh;
|
||||
|
||||
rcu_read_lock();
|
||||
qh = rcu_dereference(queue_handler);
|
||||
qh = rcu_dereference(net->nf.queue_handler);
|
||||
if (qh)
|
||||
qh->nf_hook_drop(net, ops);
|
||||
rcu_read_unlock();
|
||||
@ -122,9 +120,10 @@ int nf_queue(struct sk_buff *skb,
|
||||
struct nf_queue_entry *entry = NULL;
|
||||
const struct nf_afinfo *afinfo;
|
||||
const struct nf_queue_handler *qh;
|
||||
struct net *net = state->net;
|
||||
|
||||
/* QUEUE == DROP if no one is waiting, to be safe. */
|
||||
qh = rcu_dereference(queue_handler);
|
||||
qh = rcu_dereference(net->nf.queue_handler);
|
||||
if (!qh) {
|
||||
status = -ESRCH;
|
||||
goto err;
|
||||
|
@ -2647,6 +2647,8 @@ static int nf_tables_getset(struct net *net, struct sock *nlsk,
|
||||
/* Only accept unspec with dump */
|
||||
if (nfmsg->nfgen_family == NFPROTO_UNSPEC)
|
||||
return -EAFNOSUPPORT;
|
||||
if (!nla[NFTA_SET_TABLE])
|
||||
return -EINVAL;
|
||||
|
||||
set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME]);
|
||||
if (IS_ERR(set))
|
||||
|
@ -557,7 +557,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
|
||||
|
||||
if (entskb->tstamp.tv64) {
|
||||
struct nfqnl_msg_packet_timestamp ts;
|
||||
struct timespec64 kts = ktime_to_timespec64(skb->tstamp);
|
||||
struct timespec64 kts = ktime_to_timespec64(entskb->tstamp);
|
||||
|
||||
ts.sec = cpu_to_be64(kts.tv_sec);
|
||||
ts.usec = cpu_to_be64(kts.tv_nsec / NSEC_PER_USEC);
|
||||
@ -1482,19 +1482,27 @@ static int __net_init nfnl_queue_net_init(struct net *net)
|
||||
net->nf.proc_netfilter, &nfqnl_file_ops))
|
||||
return -ENOMEM;
|
||||
#endif
|
||||
nf_register_queue_handler(net, &nfqh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __net_exit nfnl_queue_net_exit(struct net *net)
|
||||
{
|
||||
nf_unregister_queue_handler(net);
|
||||
#ifdef CONFIG_PROC_FS
|
||||
remove_proc_entry("nfnetlink_queue", net->nf.proc_netfilter);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void nfnl_queue_net_exit_batch(struct list_head *net_exit_list)
|
||||
{
|
||||
synchronize_rcu();
|
||||
}
|
||||
|
||||
static struct pernet_operations nfnl_queue_net_ops = {
|
||||
.init = nfnl_queue_net_init,
|
||||
.exit = nfnl_queue_net_exit,
|
||||
.exit_batch = nfnl_queue_net_exit_batch,
|
||||
.id = &nfnl_queue_net_id,
|
||||
.size = sizeof(struct nfnl_queue_net),
|
||||
};
|
||||
@ -1517,7 +1525,6 @@ static int __init nfnetlink_queue_init(void)
|
||||
}
|
||||
|
||||
register_netdevice_notifier(&nfqnl_dev_notifier);
|
||||
nf_register_queue_handler(&nfqh);
|
||||
return status;
|
||||
|
||||
cleanup_netlink_notifier:
|
||||
@ -1529,7 +1536,6 @@ static int __init nfnetlink_queue_init(void)
|
||||
|
||||
static void __exit nfnetlink_queue_fini(void)
|
||||
{
|
||||
nf_unregister_queue_handler();
|
||||
unregister_netdevice_notifier(&nfqnl_dev_notifier);
|
||||
nfnetlink_subsys_unregister(&nfqnl_subsys);
|
||||
netlink_unregister_notifier(&nfqnl_rtnl_notifier);
|
||||
|
Loading…
Reference in New Issue
Block a user