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 + * (C) UFO Mechanic + * + * 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 +#include +#include +#include + +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("UFO Mechanic "); +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