Re: [RFC] netfilter: WIP: Xtables idletimer target implementation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thursday 2010-05-27 22:54, Luciano Coelho wrote:

>This patch implements an idletimer Xtables target that can be used to
>identify when interfaces have been idle for a certain period of time.
>
>It adds a file to the sysfs for each interface that is brought up.  The file
>contains the time remaining before the event is triggered.
>
>The timeout should be set when the Xtable rule is defined with the --timeout
>parameter set.
>
>There are still some issues to be resolved:
>
>How to treat several rules for the same interface?
>
>We need a key for the timer list.  I'm using the targinfo pointer for that,
>but this looks shaky, because there is no assurance that this pointer will
>live for the entire lifetime of the rule.

Well xt_quota for example has its targinfo around at all times,
as have other modules.

>This is now an x_tables target, so other protocols need to be implemented.

Huh? You're not looking at packets, so why does it need proto-specific
stuff?

>+static
>+struct utimer_t *__utimer_find_by_name(const char *name, const struct net *net)
>+{
>+	struct utimer_t *entry;
>+
>+	list_for_each_entry(entry, &active_utimer_head, entry) {
>+		if (!strcmp(name, entry->name) &&
>+		    (net == entry->net)) {
>+			return entry;
>+		}
>+	}
>+
>+	return NULL;
>+}
>+
>+static
>+struct utimer_t *__utimer_find_by_info(const struct xt_idletimer_info *info)
>+{
>+	struct utimer_t *entry;
>+
>+	list_for_each_entry(entry, &active_utimer_head, entry) {
>+		if (info == entry->info) {
>+			return entry;
>+		}
>+	}
>+
>+	return NULL;
>+}

Can do with less braces.

>+static void utimer_expired(unsigned long data)
>+{
>+	struct utimer_t *timer = (struct utimer_t *) data;
>+
>+	pr_debug("xt_idletimer: timer '%s' ns %p expired\n",
>+		 timer->name, timer->net);
>+
>+	schedule_work(&timer->work);
>+}

You don't need xt_idletimer, because pr_debug already prints
that (with #define pr_fmt(fmt) KBUILD_MODNAME ": " as many
other modules do)

>+
>+static struct utimer_t *utimer_create(const char *name,
>+				      struct net *net,
>+				      const struct xt_idletimer_info *info)
>+{
>+	struct utimer_t *timer;
>+
>+	timer = kmalloc(sizeof(struct utimer_t), GFP_ATOMIC);
>+	if (timer == NULL)
>+		return NULL;

This is called from user context, so GFP_KERNEL will perfectly suffice.

>+static int xt_idletimer_checkentry(const struct xt_tgchk_param *par)
>+{
>+	const struct xt_idletimer_info *info = par->targinfo;
>+	const struct ipt_entry *entryinfo = par->entryinfo;
>+	const struct ipt_ip *ip = &entryinfo->ip;

I'm not sure spying on ipt_ip is a long-term viable solution.

>+	pr_debug("xt_idletimer: checkentry targinfo %p\n", par->targinfo);
>+
>+	if (info->timeout == 0) {
>+		pr_debug("xt_idletimer: timeout value is zero\n");
>+		return -EINVAL;
>+	}
>+
>+	/* FIXME: implement support for other protocol families */
>+	switch (par->family) {
>+	case NFPROTO_IPV4   :
>+		pr_debug("xt_idletimer: NFPROTO_IPV4\n");
>+		break;
>+
>+	default:
>+		pr_debug("xt_idletimer: Unsupported protocol family family!\n");
>+		return -EINVAL;
>+	}
>+
>+	if (strlen(ip->iniface) == 0 && strlen(ip->outiface) == 0) {
>+		pr_debug("xt_idletimer: in or out interface must "
>+			 "be specified\n");
>+		return -EINVAL;
>+	}
>+
>+	if (utimer_create(ip->iniface, par->net, info) == NULL) {
>+		pr_debug("xt_idletimer: failed to create timer\n");
>+		return -ENOMEM;
>+	}

What about outiface?
What blows up when iniface is empty?

>+	return 0;
>+}
>+
>+static void xt_idletimer_destroy(const struct xt_tgdtor_param *par)
>+{
>+	const struct xt_idletimer_info *info = par->targinfo;
>+
>+	pr_debug("xt_idletimer: destroy targinfo %p\n", par->targinfo);
>+
>+	utimer_delete(info);
>+}
>+
>+static int __init init(void)
>+{
>+	int ret;
>+
>+	ret = utimer_init();
>+	if (ret)
>+		return ret;
>+
>+	ret =  xt_register_target(&xt_idletimer);
>+	if (ret < 0) {
>+		utimer_fini();
>+		return ret;
>+	}
>+
>+	return 0;
>+}
>+
>+static void __exit fini(void)
>+{
>+	xt_unregister_target(&xt_idletimer);
>+	utimer_fini();
>+}
>+
>+module_init(init);
>+module_exit(fini);

Call it just exit?
Also give the functions better names (see other modules), that is going
to be unrecognizable in stacktraces otherwise.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux