From patchwork Tue Aug 17 08:36:52 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luciano Coelho X-Patchwork-Id: 61871 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id DF12EB70CE for ; Tue, 17 Aug 2010 18:37:46 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755979Ab0HQIh3 (ORCPT ); Tue, 17 Aug 2010 04:37:29 -0400 Received: from mgw-sa02.nokia.com ([147.243.1.48]:52564 "EHLO mgw-sa02.nokia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754009Ab0HQIhY (ORCPT ); Tue, 17 Aug 2010 04:37:24 -0400 Received: from nokia.com (localhost [127.0.0.1]) by mgw-sa02.nokia.com (Switch-3.4.3/Switch-3.4.3) with ESMTP id o7H8XaTT017515; Tue, 17 Aug 2010 11:33:36 +0300 Received: from localhost.localdomain ([chilepepper.research.nokia.com [172.21.50.167]]) by mgw-sa02.nokia.com with RELAY id o7H8XEef017230 ; Tue, 17 Aug 2010 11:33:17 +0300 From: Luciano Coelho To: kaber@trash.net Cc: netfilter-devel@vger.kernel.org, netdev@vger.kernel.org, jengelh@medozas.de, sameo@linux.intel.com, janne.ylalehto@nokia.com Subject: [PATCH RESEND 2/3] netfilter: xt_condition: change the value from boolean to u32 Date: Tue, 17 Aug 2010 11:36:52 +0300 Message-Id: <1282034213-1829-3-git-send-email-luciano.coelho@nokia.com> X-Mailer: git-send-email 1.6.3.3 In-Reply-To: <1282034213-1829-1-git-send-email-luciano.coelho@nokia.com> References: <1282034213-1829-1-git-send-email-luciano.coelho@nokia.com> X-Nokia-AV: Clean Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Previously the condition match was using boolean values for the condition, which is a bit limited, so this patch changes the value to a u32. This is not a problem at the moment, since only userspace can set the condition and it can do more advanced checks before setting the value. But when the condition target gets implemented, having a u32 value will make it much more flexible. Signed-off-by: Luciano Coelho --- include/linux/netfilter/xt_condition.h | 3 +- net/netfilter/xt_condition.c | 54 +++++++++++++++++--------------- 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/include/linux/netfilter/xt_condition.h b/include/linux/netfilter/xt_condition.h index 4faf3ca..c4fe899 100644 --- a/include/linux/netfilter/xt_condition.h +++ b/include/linux/netfilter/xt_condition.h @@ -4,8 +4,9 @@ #include struct xt_condition_mtinfo { - char name[31]; + char name[27]; __u8 invert; + __u32 value; /* Used internally by the kernel */ void *condvar __attribute__((aligned(8))); diff --git a/net/netfilter/xt_condition.c b/net/netfilter/xt_condition.c index a78d832..cc9ada9 100644 --- a/net/netfilter/xt_condition.c +++ b/net/netfilter/xt_condition.c @@ -48,7 +48,7 @@ struct condition_variable { struct list_head list; struct proc_dir_entry *status_proc; unsigned int refcount; - bool enabled; + u32 value; }; struct condition_net { @@ -71,32 +71,36 @@ static int condition_proc_read(char __user *buffer, char **start, off_t offset, { const struct condition_variable *var = data; - buffer[0] = var->enabled ? '1' : '0'; - buffer[1] = '\n'; - if (length >= 2) - *eof = true; - return 2; + return snprintf(buffer, length, "%u\n", var->value); } -static int condition_proc_write(struct file *file, const char __user *buffer, +static int condition_proc_write(struct file *file, const char __user *input, unsigned long length, void *data) { struct condition_variable *var = data; - char newval; - - if (length > 0) { - if (get_user(newval, buffer) != 0) - return -EFAULT; - /* Match only on the first character */ - switch (newval) { - case '0': - var->enabled = false; - break; - case '1': - var->enabled = true; - break; - } - } + /* the longest possible string is MAX_UINT in octal */ + char buf[sizeof("+037777777777")]; + unsigned long long value; + + if (length == 0) + return 0; + + if (length > sizeof(buf)) + return -EINVAL; + + if (copy_from_user(buf, input, length) != 0) + return -EFAULT; + + buf[length - 1] = '\0'; + + if (strict_strtoull(buf, 0, &value) != 0) + return -EINVAL; + + if (value > (u32) value) + return -ERANGE; + + var->value = value; + return length; } @@ -106,7 +110,7 @@ condition_mt(const struct sk_buff *skb, struct xt_action_param *par) const struct xt_condition_mtinfo *info = par->matchinfo; const struct condition_variable *var = info->condvar; - return var->enabled ^ info->invert; + return (var->value == info->value) ^ info->invert; } static int condition_mt_check(const struct xt_mtchk_param *par) @@ -156,7 +160,7 @@ static int condition_mt_check(const struct xt_mtchk_param *par) } var->refcount = 1; - var->enabled = false; + var->value = 0; var->status_proc->data = var; var->status_proc->read_proc = condition_proc_read; var->status_proc->write_proc = condition_proc_write; @@ -190,7 +194,7 @@ static void condition_mt_destroy(const struct xt_mtdtor_param *par) static struct xt_match condition_mt_reg __read_mostly = { .name = "condition", - .revision = 1, + .revision = 2, .family = NFPROTO_UNSPEC, .matchsize = sizeof(struct xt_condition_mtinfo), .match = condition_mt,