Commit 268cb38e1802db560c73167e643f14a3dcb4b07c

Authored by Adam Nielsen
Committed by Patrick McHardy
1 parent af07d241dc

netfilter: x_tables: add LED trigger target

Kernel module providing implementation of LED netfilter target.  Each
instance of the target appears as a led-trigger device, which can be
associated with one or more LEDs in /sys/class/leds/

Signed-off-by: Adam Nielsen <a.nielsen@shikadi.net>
Acked-by: Richard Purdie <rpurdie@linux.intel.com>
Signed-off-by: Patrick McHardy <kaber@trash.net>

Showing 6 changed files with 203 additions and 0 deletions Side-by-side Diff

drivers/leds/Kconfig
... ... @@ -223,5 +223,8 @@
223 223 This allows LEDs to be initialised in the ON state.
224 224 If unsure, say Y.
225 225  
  226 +comment "iptables trigger is under Netfilter config (LED target)"
  227 + depends on LEDS_TRIGGERS
  228 +
226 229 endif # NEW_LEDS
include/linux/netfilter/Kbuild
... ... @@ -7,6 +7,7 @@
7 7 header-y += xt_CONNMARK.h
8 8 header-y += xt_CONNSECMARK.h
9 9 header-y += xt_DSCP.h
  10 +header-y += xt_LED.h
10 11 header-y += xt_MARK.h
11 12 header-y += xt_NFLOG.h
12 13 header-y += xt_NFQUEUE.h
include/linux/netfilter/xt_LED.h
  1 +#ifndef _XT_LED_H
  2 +#define _XT_LED_H
  3 +
  4 +struct xt_led_info {
  5 + char id[27]; /* Unique ID for this trigger in the LED class */
  6 + __u8 always_blink; /* Blink even if the LED is already on */
  7 + __u32 delay; /* Delay until LED is switched off after trigger */
  8 +
  9 + /* Kernel data used in the module */
  10 + void *internal_data __attribute__((aligned(8)));
  11 +};
  12 +
  13 +#endif /* _XT_LED_H */
net/netfilter/Kconfig
... ... @@ -372,6 +372,30 @@
372 372 since you can easily create immortal packets that loop
373 373 forever on the network.
374 374  
  375 +config NETFILTER_XT_TARGET_LED
  376 + tristate '"LED" target support'
  377 + depends on LEDS_CLASS
  378 + depends on NETFILTER_ADVANCED
  379 + help
  380 + This option adds a `LED' target, which allows you to blink LEDs in
  381 + response to particular packets passing through your machine.
  382 +
  383 + This can be used to turn a spare LED into a network activity LED,
  384 + which only flashes in response to FTP transfers, for example. Or
  385 + you could have an LED which lights up for a minute or two every time
  386 + somebody connects to your machine via SSH.
  387 +
  388 + You will need support for the "led" class to make this work.
  389 +
  390 + To create an LED trigger for incoming SSH traffic:
  391 + iptables -A INPUT -p tcp --dport 22 -j LED --led-trigger-id ssh --led-delay 1000
  392 +
  393 + Then attach the new trigger to an LED on your system:
  394 + echo netfilter-ssh > /sys/class/leds/<ledname>/trigger
  395 +
  396 + For more information on the LEDs available on your system, see
  397 + Documentation/leds-class.txt
  398 +
375 399 config NETFILTER_XT_TARGET_MARK
376 400 tristate '"MARK" target support'
377 401 default m if NETFILTER_ADVANCED=n
net/netfilter/Makefile
... ... @@ -46,6 +46,7 @@
46 46 obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
47 47 obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
48 48 obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o
  49 +obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
49 50 obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o
50 51 obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o
51 52 obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
net/netfilter/xt_LED.c
  1 +/*
  2 + * xt_LED.c - netfilter target to make LEDs blink upon packet matches
  3 + *
  4 + * Copyright (C) 2008 Adam Nielsen <a.nielsen@shikadi.net>
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify
  7 + * it under the terms of the GNU General Public License as published by
  8 + * the Free Software Foundation; version 2 of the License.
  9 + *
  10 + * This program is distributed in the hope that it will be useful,
  11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13 + * GNU General Public License for more details.
  14 + *
  15 + * You should have received a copy of the GNU General Public License
  16 + * along with this program; if not, write to the Free Software
  17 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  18 + * 02110-1301 USA.
  19 + *
  20 + */
  21 +
  22 +#include <linux/module.h>
  23 +#include <linux/skbuff.h>
  24 +#include <linux/netfilter/x_tables.h>
  25 +#include <linux/leds.h>
  26 +#include <linux/mutex.h>
  27 +
  28 +#include <linux/netfilter/xt_LED.h>
  29 +
  30 +MODULE_LICENSE("GPL");
  31 +MODULE_AUTHOR("Adam Nielsen <a.nielsen@shikadi.net>");
  32 +MODULE_DESCRIPTION("Xtables: trigger LED devices on packet match");
  33 +
  34 +/*
  35 + * This is declared in here (the kernel module) only, to avoid having these
  36 + * dependencies in userspace code. This is what xt_led_info.internal_data
  37 + * points to.
  38 + */
  39 +struct xt_led_info_internal {
  40 + struct led_trigger netfilter_led_trigger;
  41 + struct timer_list timer;
  42 +};
  43 +
  44 +static unsigned int
  45 +led_tg(struct sk_buff *skb, const struct xt_target_param *par)
  46 +{
  47 + const struct xt_led_info *ledinfo = par->targinfo;
  48 + struct xt_led_info_internal *ledinternal = ledinfo->internal_data;
  49 +
  50 + /*
  51 + * If "always blink" is enabled, and there's still some time until the
  52 + * LED will switch off, briefly switch it off now.
  53 + */
  54 + if ((ledinfo->delay > 0) && ledinfo->always_blink &&
  55 + timer_pending(&ledinternal->timer))
  56 + led_trigger_event(&ledinternal->netfilter_led_trigger,LED_OFF);
  57 +
  58 + led_trigger_event(&ledinternal->netfilter_led_trigger, LED_FULL);
  59 +
  60 + /* If there's a positive delay, start/update the timer */
  61 + if (ledinfo->delay > 0) {
  62 + mod_timer(&ledinternal->timer,
  63 + jiffies + msecs_to_jiffies(ledinfo->delay));
  64 +
  65 + /* Otherwise if there was no delay given, blink as fast as possible */
  66 + } else if (ledinfo->delay == 0) {
  67 + led_trigger_event(&ledinternal->netfilter_led_trigger, LED_OFF);
  68 + }
  69 +
  70 + /* else the delay is negative, which means switch on and stay on */
  71 +
  72 + return XT_CONTINUE;
  73 +}
  74 +
  75 +static void led_timeout_callback(unsigned long data)
  76 +{
  77 + struct xt_led_info *ledinfo = (struct xt_led_info *)data;
  78 + struct xt_led_info_internal *ledinternal = ledinfo->internal_data;
  79 +
  80 + led_trigger_event(&ledinternal->netfilter_led_trigger, LED_OFF);
  81 +}
  82 +
  83 +static bool led_tg_check(const struct xt_tgchk_param *par)
  84 +{
  85 + struct xt_led_info *ledinfo = par->targinfo;
  86 + struct xt_led_info_internal *ledinternal;
  87 + int err;
  88 +
  89 + if (ledinfo->id[0] == '\0') {
  90 + printk(KERN_ERR KBUILD_MODNAME ": No 'id' parameter given.\n");
  91 + return false;
  92 + }
  93 +
  94 + ledinternal = kzalloc(sizeof(struct xt_led_info_internal), GFP_KERNEL);
  95 + if (!ledinternal) {
  96 + printk(KERN_CRIT KBUILD_MODNAME ": out of memory\n");
  97 + return false;
  98 + }
  99 +
  100 + ledinternal->netfilter_led_trigger.name = ledinfo->id;
  101 +
  102 + err = led_trigger_register(&ledinternal->netfilter_led_trigger);
  103 + if (err) {
  104 + printk(KERN_CRIT KBUILD_MODNAME
  105 + ": led_trigger_register() failed\n");
  106 + if (err == -EEXIST)
  107 + printk(KERN_ERR KBUILD_MODNAME
  108 + ": Trigger name is already in use.\n");
  109 + goto exit_alloc;
  110 + }
  111 +
  112 + /* See if we need to set up a timer */
  113 + if (ledinfo->delay > 0)
  114 + setup_timer(&ledinternal->timer, led_timeout_callback,
  115 + (unsigned long)ledinfo);
  116 +
  117 + ledinfo->internal_data = ledinternal;
  118 +
  119 + return true;
  120 +
  121 +exit_alloc:
  122 + kfree(ledinternal);
  123 +
  124 + return false;
  125 +}
  126 +
  127 +static void led_tg_destroy(const struct xt_tgdtor_param *par)
  128 +{
  129 + const struct xt_led_info *ledinfo = par->targinfo;
  130 + struct xt_led_info_internal *ledinternal = ledinfo->internal_data;
  131 +
  132 + if (ledinfo->delay > 0)
  133 + del_timer_sync(&ledinternal->timer);
  134 +
  135 + led_trigger_unregister(&ledinternal->netfilter_led_trigger);
  136 + kfree(ledinternal);
  137 +}
  138 +
  139 +static struct xt_target led_tg_reg __read_mostly = {
  140 + .name = "LED",
  141 + .revision = 0,
  142 + .family = NFPROTO_UNSPEC,
  143 + .target = led_tg,
  144 + .targetsize = XT_ALIGN(sizeof(struct xt_led_info)),
  145 + .checkentry = led_tg_check,
  146 + .destroy = led_tg_destroy,
  147 + .me = THIS_MODULE,
  148 +};
  149 +
  150 +static int __init led_tg_init(void)
  151 +{
  152 + return xt_register_target(&led_tg_reg);
  153 +}
  154 +
  155 +static void __exit led_tg_exit(void)
  156 +{
  157 + xt_unregister_target(&led_tg_reg);
  158 +}
  159 +
  160 +module_init(led_tg_init);
  161 +module_exit(led_tg_exit);