All of lore.kernel.org
 help / color / mirror / Atom feed
From: Amin Azez <azez@ufomechanic.net>
To: netfilter-devel@lists.netfilter.org
Subject: Re: vlan target for iptables
Date: Mon, 26 Sep 2005 14:50:14 +0100	[thread overview]
Message-ID: <4337FC96.4080207@ufomechanic.net> (raw)
In-Reply-To: <dd80kc$n5o$1@sea.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 1299 bytes --]

Am I supposed to do anything particular to get this included with iptables?

I know pom is going out of the window.

Azez

Amin Azez wrote:
> Please consider this for inclusion in iptables. Should this go in pom?
> 
> This adds --vlan target matching for iptables.
> Useful when running as a bridge and perhaps in other cases.
> 
> I've tested it while bridging packets with vlan headers set.
> Anyone trying to use this, realise that in most configurations your
> switch does not transmit the vlan headers, and if it does, then realise
> that your networked PC's will not generally accept the packets.
> The test rig involved a few PC's and some segmented switches.
> 
> I'm afraid I had to steal the vlan packet matching code IS_VLAN_* from
> one of the  vlan modules as it was private to that module.  I hate
> having to do that.
> 
> For user-space:
> 
> Just add dump libipt_vlan.c extensions and add vlan to PF_EXT_SLIB
> definition in extensions/Makefile
> 
> I'm not sending a patch for extensions/Makefile that because it's bound
> to fail applying with all the PF_EXT_SLIB stuff all on one line.
> 
> 
> For kernel-space, apply vlan.patch
> 
> Comments? This code is based on the MAC target with minimal changes (and
> careful "grep -i mac *" and is naturally GPL licensed too),
> 
> Azez

[-- Attachment #2: libipt_vlan.c --]
[-- Type: text/x-csrc, Size: 2273 bytes --]

/* Shared library add-on to iptables to add VLAN address support. */
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#if defined(__GLIBC__) && __GLIBC__ == 2
#include <net/ethernet.h>
#else
#include <linux/if_ether.h>
#endif
#include <iptables.h>
#include <linux/netfilter_ipv4/ipt_vlan.h>

/* Function which prints out usage message. */
static void
help(void)
{
	printf(
"VLAN v%s options:\n"
" --vlan [!] <vlan_id>\n"
"				Match source VLAN id\n"
"\n", IPTABLES_VERSION);
}

static struct option opts[] = {
	{ "vlan", 1, 0, '1' },
	{0}
};

/* Function which parses command options; returns true if it
   ate an option */
static int
parse(int c, char **argv, int invert, unsigned int *flags,
      const struct ipt_entry *entry,
      unsigned int *nfcache,
      struct ipt_entry_match **match)
{
	struct ipt_vlan_info *vlaninfo = (struct ipt_vlan_info *)(*match)->data;

	switch (c) {
	case '1':
		check_inverse(optarg, &invert, &optind, 0);
		vlaninfo->vlan=atoi(argv[optind-1]);
		if (invert)
			vlaninfo->invert = 1;
		*flags = 1;
		break;

	default:
		return 0;
	}

	return 1;
}

/* Final check; must have specified --vlan. */
static void final_check(unsigned int flags)
{
	if (!flags)
		exit_error(PARAMETER_PROBLEM,
			   "You must specify `--vlan'");
}

/* Prints out the matchinfo. */
static void
print(const struct ipt_ip *ip,
      const struct ipt_entry_match *match,
      int numeric)
{
	printf("vlan ");

	if (((struct ipt_vlan_info *)match->data)->invert)
		printf("! ");

	printf("%d ",((struct ipt_vlan_info *)match->data)->vlan);
}

/* Saves the union ipt_matchinfo in parsable form to stdout. */
static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
{
	if (((struct ipt_vlan_info *)match->data)->invert)
		printf("! ");

	printf("--vlan %d ",((struct ipt_vlan_info *)match->data)->vlan);
}

static struct iptables_match vlan = { 
	.next		= NULL,
 	.name		= "vlan",
	.version	= IPTABLES_VERSION,
	.size		= IPT_ALIGN(sizeof(struct ipt_vlan_info)),
	.userspacesize	= IPT_ALIGN(sizeof(struct ipt_vlan_info)),
	.help		= &help,
	.parse		= &parse,
	.final_check	= &final_check,
	.print		= &print,
	.save		= &save,
	.extra_opts	= opts
};

void _init(void)
{
	register_match(&vlan);
}

[-- Attachment #3: vlan.patch --]
[-- Type: text/x-patch, Size: 4417 bytes --]

diff -Nru ../linux-2.6.11.7-reference/include/linux/netfilter_ipv4/ipt_vlan.h ./include/linux/netfilter_ipv4/ipt_vlan.h
--- ../linux-2.6.11.7-reference/include/linux/netfilter_ipv4/ipt_vlan.h	1970-01-01 01:00:00.000000000 +0100
+++ ./include/linux/netfilter_ipv4/ipt_vlan.h	2005-07-13 14:59:24.000000000 +0100
@@ -0,0 +1,8 @@
+#ifndef _IPT_VLAN_H
+#define _IPT_VLAN_H
+
+struct ipt_vlan_info {
+    unsigned short vlan;
+    int invert;
+};
+#endif /*_IPT_VLAN_H*/
diff -Nru ../linux-2.6.11.7-reference/net/ipv4/netfilter/ipt_vlan.c ./net/ipv4/netfilter/ipt_vlan.c
--- ../linux-2.6.11.7-reference/net/ipv4/netfilter/ipt_vlan.c	1970-01-01 01:00:00.000000000 +0100
+++ ./net/ipv4/netfilter/ipt_vlan.c	2005-07-22 09:49:01.000000000 +0100
@@ -0,0 +1,82 @@
+/* Kernel module to match VLAN parameters based on ipt_mac */
+
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ * (C) UFO Mechanic <azez@ufomechanic.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/if_ether.h>
+#include <linux/if_vlan.h>
+
+#include <linux/netfilter_ipv4/ipt_vlan.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("UFO Mechanic <azez@ufomechanic.net>");
+MODULE_DESCRIPTION("iptables vlan matching module");
+
+#define IS_VLAN_IP (skb->protocol == __constant_htons(ETH_P_8021Q) &&    \
+	hdr->h_vlan_encapsulated_proto == __constant_htons(ETH_P_IP)) /* &&  \ brnf_filter_vlan_tagged) */
+#define IS_VLAN_IPV6 (skb->protocol == __constant_htons(ETH_P_8021Q) &&    \
+	hdr->h_vlan_encapsulated_proto == __constant_htons(ETH_P_IPV6)) /* &&  \ brnf_filter_vlan_tagged) */
+#define IS_VLAN_ARP (skb->protocol == __constant_htons(ETH_P_8021Q) &&   \
+	hdr->h_vlan_encapsulated_proto == __constant_htons(ETH_P_ARP)) /* && \ brnf_filter_vlan_tagged) */
+
+static int
+match(const struct sk_buff *skb,
+      const struct net_device *in,
+      const struct net_device *out,
+      const void *matchinfo,
+      int offset,
+      int *hotdrop)
+{
+    const struct ipt_vlan_info *info = matchinfo;
+    struct vlan_ethhdr *hdr = vlan_eth_hdr(skb);
+
+/* should we use: static inline int __vlan_get_tag(struct sk_buff *skb, unsigned short *tag) */
+    /* Is it even a VLAN packet? */
+    if ((IS_VLAN_IP || IS_VLAN_IPV6 || IS_VLAN_ARP)) {
+	    /* If so, compare... */
+	    return (( (ntohs(hdr->h_vlan_TCI)==info->vlan) ^ info->invert));
+    }
+    return 0 ^ info->invert;
+}
+
+static int
+ipt_vlan_checkentry(const char *tablename,
+		   const struct ipt_ip *ip,
+		   void *matchinfo,
+		   unsigned int matchsize,
+		   unsigned int hook_mask)
+{
+	if (matchsize != IPT_ALIGN(sizeof(struct ipt_vlan_info)))
+		return 0;
+
+	return 1;
+}
+
+static struct ipt_match vlan_match = {
+	.name		= "vlan",
+	.match		= &match,
+	.checkentry	= &ipt_vlan_checkentry,
+	.me		= THIS_MODULE,
+};
+
+static int __init init(void)
+{
+	return ipt_register_match(&vlan_match);
+}
+
+static void __exit fini(void)
+{
+	ipt_unregister_match(&vlan_match);
+}
+
+module_init(init);
+module_exit(fini);
--- kernel/net/ipv4/netfilter/Makefile.orig	2005-07-22 12:12:46.000000000 +0100
+++ kernel/net/ipv4/netfilter/Makefile	2005-07-22 12:13:08.000000000 +0100
@@ -45,6 +45,7 @@
 obj-$(CONFIG_IP_NF_MATCH_SCTP) += ipt_sctp.o
 obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o
 obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o
+obj-$(CONFIG_IP_NF_MATCH_VLAN) += ipt_vlan.o
 obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
 obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o
 obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o
--- kernel/net/ipv4/netfilter/Kconfig.orig	2005-07-22 12:13:18.000000000 +0100
+++ kernel/net/ipv4/netfilter/Kconfig	2005-07-22 12:14:37.000000000 +0100
@@ -183,6 +183,15 @@
 	  Unless you know what you're doing, leave it at the default of 2kB.
 
 
+config IP_NF_MATCH_VLAN
+	tristate "VLAN address match support"
+	depends on IP_NF_IPTABLES
+	help
+	  VLAN matching allows you to match packets based on the vlan
+	  tag of the packet, if your switch fowards them
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
 config IP_NF_MATCH_PKTTYPE
 	tristate "Packet type match support"
 	depends on IP_NF_IPTABLES

  reply	other threads:[~2005-09-26 13:50 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-08-08 16:18 vlan target for iptables Amin Azez
2005-09-26 13:50 ` Amin Azez [this message]
2005-09-26 14:20   ` Cedric Blancher
2005-10-21 12:17 ` Harald Welte

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4337FC96.4080207@ufomechanic.net \
    --to=azez@ufomechanic.net \
    --cc=netfilter-devel@lists.netfilter.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.