diff options
author | Michael Bestas <mkbestas@lineageos.org> | 2020-08-23 00:31:58 +0300 |
---|---|---|
committer | Michael Bestas <mkbestas@lineageos.org> | 2020-08-23 00:31:58 +0300 |
commit | 87d399cdabf1a0090ea16259bd747f162dd194c9 (patch) | |
tree | 64444772004879911b5e2893b735b333c8f2ae0c /net | |
parent | 3cc2d2aa8574a94aca65ac664c3a0fb23d930700 (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.c | 134 |
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 = "a_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); |