mirror of
git://git.code.sf.net/p/xtables-addons/xtables-addons
synced 2025-09-07 13:15:12 +02:00
xt_condition: support for Linux 3.10
This commit is contained in:
@@ -52,6 +52,7 @@ struct condition_variable {
|
|||||||
struct proc_dir_entry *status_proc;
|
struct proc_dir_entry *status_proc;
|
||||||
unsigned int refcount;
|
unsigned int refcount;
|
||||||
bool enabled;
|
bool enabled;
|
||||||
|
char name[sizeof(((struct xt_condition_mtinfo *)NULL)->name)];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* proc_lock is a user context only semaphore used for write access */
|
/* proc_lock is a user context only semaphore used for write access */
|
||||||
@@ -61,22 +62,23 @@ static DEFINE_MUTEX(proc_lock);
|
|||||||
static LIST_HEAD(conditions_list);
|
static LIST_HEAD(conditions_list);
|
||||||
static struct proc_dir_entry *proc_net_condition;
|
static struct proc_dir_entry *proc_net_condition;
|
||||||
|
|
||||||
static int condition_proc_read(char __user *buffer, char **start, off_t offset,
|
static int condition_proc_show(struct seq_file *m, void *data)
|
||||||
int length, int *eof, void *data)
|
|
||||||
{
|
{
|
||||||
const struct condition_variable *var = data;
|
const struct condition_variable *var = m->private;
|
||||||
|
|
||||||
buffer[0] = var->enabled ? '1' : '0';
|
return seq_printf(m, var->enabled ? "1\n" : "0\n");
|
||||||
buffer[1] = '\n';
|
|
||||||
if (length >= 2)
|
|
||||||
*eof = true;
|
|
||||||
return 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int condition_proc_write(struct file *file, const char __user *buffer,
|
static int condition_proc_open(struct inode *inode, struct file *file)
|
||||||
unsigned long length, void *data)
|
|
||||||
{
|
{
|
||||||
struct condition_variable *var = data;
|
return single_open(file, condition_proc_show, PDE_DATA(inode));
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
condition_proc_write(struct file *file, const char __user *buffer,
|
||||||
|
size_t length, loff_t *loff)
|
||||||
|
{
|
||||||
|
struct condition_variable *var = PDE_DATA(file_inode(file));
|
||||||
char newval;
|
char newval;
|
||||||
|
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
@@ -95,6 +97,14 @@ static int condition_proc_write(struct file *file, const char __user *buffer,
|
|||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct file_operations condition_proc_fops = {
|
||||||
|
.open = condition_proc_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.write = condition_proc_write,
|
||||||
|
.release = single_release,
|
||||||
|
};
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
condition_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
condition_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
||||||
{
|
{
|
||||||
@@ -124,7 +134,7 @@ static int condition_mt_check(const struct xt_mtchk_param *par)
|
|||||||
*/
|
*/
|
||||||
mutex_lock(&proc_lock);
|
mutex_lock(&proc_lock);
|
||||||
list_for_each_entry(var, &conditions_list, list) {
|
list_for_each_entry(var, &conditions_list, list) {
|
||||||
if (strcmp(info->name, var->status_proc->name) == 0) {
|
if (strcmp(info->name, var->name) == 0) {
|
||||||
var->refcount++;
|
var->refcount++;
|
||||||
mutex_unlock(&proc_lock);
|
mutex_unlock(&proc_lock);
|
||||||
info->condvar = var;
|
info->condvar = var;
|
||||||
@@ -139,24 +149,23 @@ static int condition_mt_check(const struct xt_mtchk_param *par)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memcpy(var->name, info->name, sizeof(info->name));
|
||||||
/* Create the condition variable's proc file entry. */
|
/* Create the condition variable's proc file entry. */
|
||||||
var->status_proc = create_proc_entry(info->name, condition_list_perms,
|
var->status_proc = proc_create_data(info->name, condition_list_perms,
|
||||||
proc_net_condition);
|
proc_net_condition, &condition_proc_fops, var);
|
||||||
if (var->status_proc == NULL) {
|
if (var->status_proc == NULL) {
|
||||||
kfree(var);
|
kfree(var);
|
||||||
mutex_unlock(&proc_lock);
|
mutex_unlock(&proc_lock);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc_set_user(var->status_proc,
|
||||||
|
make_kuid(&init_user_ns, condition_uid_perms),
|
||||||
|
make_kgid(&init_user_ns, condition_gid_perms));
|
||||||
var->refcount = 1;
|
var->refcount = 1;
|
||||||
var->enabled = false;
|
var->enabled = false;
|
||||||
var->status_proc->data = var;
|
|
||||||
wmb();
|
wmb();
|
||||||
var->status_proc->read_proc = condition_proc_read;
|
|
||||||
var->status_proc->write_proc = condition_proc_write;
|
|
||||||
list_add(&var->list, &conditions_list);
|
list_add(&var->list, &conditions_list);
|
||||||
var->status_proc->uid = make_kuid(&init_user_ns, condition_uid_perms);
|
|
||||||
var->status_proc->gid = make_kgid(&init_user_ns, condition_gid_perms);
|
|
||||||
mutex_unlock(&proc_lock);
|
mutex_unlock(&proc_lock);
|
||||||
info->condvar = var;
|
info->condvar = var;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -170,7 +179,7 @@ static void condition_mt_destroy(const struct xt_mtdtor_param *par)
|
|||||||
mutex_lock(&proc_lock);
|
mutex_lock(&proc_lock);
|
||||||
if (--var->refcount == 0) {
|
if (--var->refcount == 0) {
|
||||||
list_del(&var->list);
|
list_del(&var->list);
|
||||||
remove_proc_entry(var->status_proc->name, proc_net_condition);
|
proc_remove(var->status_proc);
|
||||||
mutex_unlock(&proc_lock);
|
mutex_unlock(&proc_lock);
|
||||||
kfree(var);
|
kfree(var);
|
||||||
return;
|
return;
|
||||||
|
Reference in New Issue
Block a user