summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorMichael Bestas <mkbestas@lineageos.org>2020-08-23 00:31:58 +0300
committerMichael Bestas <mkbestas@lineageos.org>2020-08-23 00:31:58 +0300
commit87d399cdabf1a0090ea16259bd747f162dd194c9 (patch)
tree64444772004879911b5e2893b735b333c8f2ae0c /net
parent3cc2d2aa8574a94aca65ac664c3a0fb23d930700 (diff)
Revert "netfilter: xt_quota2: 3.18 netlink notification fix"
This reverts commit f889e67f3704313e5e5ae636fe9ef9845b73d22d.
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/xt_quota2.c134
1 files changed, 74 insertions, 60 deletions
diff --git a/net/netfilter/xt_quota2.c b/net/netfilter/xt_quota2.c
index 8c481e359d94..15f058061f34 100644
--- a/net/netfilter/xt_quota2.c
+++ b/net/netfilter/xt_quota2.c
@@ -16,15 +16,14 @@
#include <linux/proc_fs.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
-#include <linux/workqueue.h>
#include <asm/atomic.h>
#include <net/netlink.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_quota2.h>
-
-#define QUOTA2_SYSFS_WORK_MAX_SIZE 64
-#define QUOTA2_SYSFS_NUM_ENVP 3
+#ifdef CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG
+#include <linux/netfilter_ipv4/ipt_ULOG.h>
+#endif
#ifdef CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG
/* For compatibility, these definitions are copied from the
@@ -58,16 +57,17 @@ struct xt_quota_counter {
atomic_t ref;
char name[sizeof(((struct xt_quota_mtinfo2 *)NULL)->name)];
struct proc_dir_entry *procfs_entry;
- char last_iface[QUOTA2_SYSFS_WORK_MAX_SIZE];
- char last_prefix[QUOTA2_SYSFS_WORK_MAX_SIZE];
- struct work_struct work;
};
-#define to_quota_counter(x) container_of(x, struct xt_quota_counter, work)
-
-static struct class *quota_class;
-static struct device *quota_device;
-static struct kobject *quota_kobj;
+#ifdef CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG
+/* Harald's favorite number +1 :D From ipt_ULOG.C */
+static int qlog_nl_event = 112;
+module_param_named(event_num, qlog_nl_event, uint, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(event_num,
+ "Event number for NETLINK_NFLOG message. 0 disables log."
+ "111 is what ipt_ULOG uses.");
+static struct sock *nflognl;
+#endif
static LIST_HEAD(counter_list);
static DEFINE_SPINLOCK(counter_list_lock);
@@ -78,39 +78,68 @@ static kuid_t quota_list_uid = KUIDT_INIT(0);
static kgid_t quota_list_gid = KGIDT_INIT(0);
module_param_named(perms, quota_list_perms, uint, S_IRUGO | S_IWUSR);
-static void quota2_work(struct work_struct *work)
-{
- char alert_msg[QUOTA2_SYSFS_WORK_MAX_SIZE];
- char iface_name[QUOTA2_SYSFS_WORK_MAX_SIZE];
- char *envp[QUOTA2_SYSFS_NUM_ENVP] = {alert_msg, iface_name, NULL};
- struct xt_quota_counter *counter = to_quota_counter(work);
-
- snprintf(alert_msg, sizeof(alert_msg), "ALERT_NAME=%s", counter->name);
- snprintf(iface_name, sizeof(iface_name), "INTERFACE=%s",
- counter->last_iface);
-
- kobject_uevent_env(quota_kobj, KOBJ_CHANGE, envp);
-}
-
-static void quota2_log(const struct net_device *in,
+#ifdef CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG
+static void quota2_log(unsigned int hooknum,
+ const struct sk_buff *skb,
+ const struct net_device *in,
const struct net_device *out,
- struct xt_quota_counter *q,
const char *prefix)
{
- if (!prefix)
+ ulog_packet_msg_t *pm;
+ struct sk_buff *log_skb;
+ size_t size;
+ struct nlmsghdr *nlh;
+
+ if (!qlog_nl_event)
return;
- strlcpy(q->last_prefix, prefix, QUOTA2_SYSFS_WORK_MAX_SIZE);
+ size = NLMSG_SPACE(sizeof(*pm));
+ size = max(size, (size_t)NLMSG_GOODSIZE);
+ log_skb = alloc_skb(size, GFP_ATOMIC);
+ if (!log_skb) {
+ pr_err("xt_quota2: cannot alloc skb for logging\n");
+ return;
+ }
+ nlh = nlmsg_put(log_skb, /*pid*/0, /*seq*/0, qlog_nl_event,
+ sizeof(*pm), 0);
+ if (!nlh) {
+ pr_err("xt_quota2: nlmsg_put failed\n");
+ kfree_skb(log_skb);
+ return;
+ }
+ pm = nlmsg_data(nlh);
+ if (skb->tstamp.tv64 == 0)
+ __net_timestamp((struct sk_buff *)skb);
+ pm->data_len = 0;
+ pm->hook = hooknum;
+ if (prefix != NULL)
+ strlcpy(pm->prefix, prefix, sizeof(pm->prefix));
+ else
+ *(pm->prefix) = '\0';
if (in)
- strlcpy(q->last_iface, in->name, QUOTA2_SYSFS_WORK_MAX_SIZE);
- else if (out)
- strlcpy(q->last_iface, out->name, QUOTA2_SYSFS_WORK_MAX_SIZE);
+ strlcpy(pm->indev_name, in->name, sizeof(pm->indev_name));
+ else
+ pm->indev_name[0] = '\0';
+
+ if (out)
+ strlcpy(pm->outdev_name, out->name, sizeof(pm->outdev_name));
else
- strlcpy(q->last_iface, "UNKNOWN", QUOTA2_SYSFS_WORK_MAX_SIZE);
+ pm->outdev_name[0] = '\0';
- schedule_work(&q->work);
+ NETLINK_CB(log_skb).dst_group = 1;
+ pr_debug("throwing 1 packets to netlink group 1\n");
+ netlink_broadcast(nflognl, log_skb, 0, 1, GFP_ATOMIC);
+}
+#else
+static void quota2_log(unsigned int hooknum,
+ const struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ const char *prefix)
+{
}
+#endif /* if+else CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG */
static ssize_t quota_proc_read(struct file *file, char __user *buf,
size_t size, loff_t *ppos)
@@ -167,9 +196,6 @@ q2_new_counter(const struct xt_quota_mtinfo2 *q, bool anon)
INIT_LIST_HEAD(&e->list);
atomic_set(&e->ref, 1);
strlcpy(e->name, q->name, sizeof(e->name));
- strlcpy(e->last_prefix, "UNSET", sizeof(e->last_prefix));
- strlcpy(e->last_iface, "UNSET", sizeof(e->last_iface));
- INIT_WORK(&e->work, quota2_work);
}
return e;
}
@@ -303,7 +329,11 @@ quota_mt2(const struct sk_buff *skb, struct xt_action_param *par)
} else {
/* We are transitioning, log that fact. */
if (e->quota) {
- quota2_log(par->in, par->out, e, q->name);
+ quota2_log(par->hooknum,
+ skb,
+ par->in,
+ par->out,
+ q->name);
}
/* we do not allow even small packets from now on */
e->quota = 0;
@@ -341,25 +371,11 @@ static int __init quota_mt2_init(void)
int ret;
pr_debug("xt_quota2: init()");
- quota_class = class_create(THIS_MODULE, "xt_quota2");
- ret = PTR_ERR(quota_class);
- if (IS_ERR(quota_class)) {
- pr_err("xt_quota2: couldn't create class");
- class_destroy(quota_class);
- return ret;
- }
-
- quota_device = device_create(quota_class, NULL, MKDEV(0, 0), NULL,
- "counters");
- ret = PTR_ERR(quota_device);
- if (IS_ERR(quota_device)) {
- pr_err("xt_quota2: couldn't create device");
- device_destroy(quota_class, MKDEV(0, 0));
- class_destroy(quota_class);
- return ret;
- }
-
- quota_kobj = &quota_device->kobj;
+#ifdef CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG
+ nflognl = netlink_kernel_create(&init_net, NETLINK_NFLOG, NULL);
+ if (!nflognl)
+ return -ENOMEM;
+#endif
proc_xt_quota = proc_mkdir("xt_quota", init_net.proc_net);
if (proc_xt_quota == NULL)
@@ -376,8 +392,6 @@ static void __exit quota_mt2_exit(void)
{
xt_unregister_matches(quota_mt2_reg, ARRAY_SIZE(quota_mt2_reg));
remove_proc_entry("xt_quota", init_net.proc_net);
- device_destroy(quota_class, MKDEV(0, 0));
- class_destroy(quota_class);
}
module_init(quota_mt2_init);