From patchwork Thu Aug 5 14:41:09 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luciano Coelho X-Patchwork-Id: 60978 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 8E29C1007D6 for ; Fri, 6 Aug 2010 00:45:27 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933506Ab0HEOlp (ORCPT ); Thu, 5 Aug 2010 10:41:45 -0400 Received: from smtp.nokia.com ([192.100.122.230]:44555 "EHLO mgw-mx03.nokia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933498Ab0HEOlh (ORCPT ); Thu, 5 Aug 2010 10:41:37 -0400 Received: from esebh105.NOE.Nokia.com (esebh105.ntc.nokia.com [172.21.138.211]) by mgw-mx03.nokia.com (Switch-3.3.3/Switch-3.3.3) with ESMTP id o75Ef587029191; Thu, 5 Aug 2010 17:41:27 +0300 Received: from esebh102.NOE.Nokia.com ([172.21.138.183]) by esebh105.NOE.Nokia.com with Microsoft SMTPSVC(6.0.3790.4675); Thu, 5 Aug 2010 17:41:20 +0300 Received: from mgw-da02.ext.nokia.com ([147.243.128.26]) by esebh102.NOE.Nokia.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Thu, 5 Aug 2010 17:41:19 +0300 Received: from localhost.localdomain (chilepepper.research.nokia.com [172.21.50.167]) by mgw-da02.ext.nokia.com (Switch-3.3.3/Switch-3.3.3) with ESMTP id o75Ef9em016419; Thu, 5 Aug 2010 17:41:16 +0300 From: luciano.coelho@nokia.com To: netfilter-devel@vger.kernel.org Cc: netdev@vger.kernel.org, kaber@trash.net, jengelh@medozas.de, sameo@linux.intel.com Subject: [PATCH 2/2] netfilter: xt_condition: change the value from boolean to u32 Date: Thu, 5 Aug 2010 17:41:09 +0300 Message-Id: <1281019269-30985-3-git-send-email-luciano.coelho@nokia.com> X-Mailer: git-send-email 1.6.3.3 In-Reply-To: <1281019269-30985-1-git-send-email-luciano.coelho@nokia.com> References: <1281019269-30985-1-git-send-email-luciano.coelho@nokia.com> X-OriginalArrivalTime: 05 Aug 2010 14:41:19.0657 (UTC) FILETIME=[44635190:01CB34AC] X-Nokia-AV: Clean Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Luciano Coelho 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 | 51 +++++++++++++++++--------------- 2 files changed, 29 insertions(+), 25 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..08dfb67 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,35 @@ 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; - } - } + char buf[14]; + 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 -EINVAL; + + var->value = value; + return length; } @@ -106,7 +109,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 +159,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;