--- linux-2.6.20.21/include/linux/netfilter_ipv4/ip_conntrack_core.h 2007-10-17 15:31:14.000000000 -0400 +++ linux-2.6.20.21.mod/include/linux/netfilter_ipv4/ip_conntrack_core.h 2009-11-02 09:53:44.000000000 -0500 @@ -24,7 +24,12 @@ const struct sk_buff *skb, unsigned int dataoff, struct ip_conntrack_tuple *tuple, +#ifdef CONFIG_IP_NF_CONNTRACK_VLAN + const struct ip_conntrack_protocol *protocol, + unsigned short vid); +#else const struct ip_conntrack_protocol *protocol); +#endif extern int ip_ct_invert_tuple(struct ip_conntrack_tuple *inverse, --- linux-2.6.20.21/include/linux/netfilter_ipv4/ip_conntrack_tuple.h 2007-10-17 15:31:14.000000000 -0400 +++ linux-2.6.20.21.mod/include/linux/netfilter_ipv4/ip_conntrack_tuple.h 2009-11-02 09:56:09.000000000 -0500 @@ -79,6 +79,10 @@ /* The direction (for tuplehash) */ u_int8_t dir; } dst; +#ifdef CONFIG_IP_NF_CONNTRACK_VLAN + __be16 vid; +#endif + }; /* This is optimized opposed to a memset of the whole structure. Everything we @@ -87,6 +91,9 @@ do { \ (tuple)->src.u.all = 0; \ (tuple)->dst.u.all = 0; \ +#ifdef CONFIG_IP_NF_CONNTRACK_VLAN + (tuple)->vid = 0; \ +#endif } while (0) #ifdef __KERNEL__ @@ -125,10 +132,22 @@ && t1->dst.protonum == t2->dst.protonum; } +#ifdef CONFIG_IP_NF_CONNTRACK_VLAN +static inline int ip_ct_tuple_vlan_equal(const struct ip_conntrack_tuple *t1, + const struct ip_conntrack_tuple *t2) +{ + return t1->vid == t2->vid; +} +#endif + static inline int ip_ct_tuple_equal(const struct ip_conntrack_tuple *t1, const struct ip_conntrack_tuple *t2) { +#ifdef CONFIG_IP_NF_CONNTRACK_VLAN + return ip_ct_tuple_src_equal(t1, t2) && ip_ct_tuple_dst_equal(t1, t2) && ip_ct_tuple_vlan_equal(t1, t2); +#else return ip_ct_tuple_src_equal(t1, t2) && ip_ct_tuple_dst_equal(t1, t2); +#endif } static inline int ip_ct_tuple_mask_cmp(const struct ip_conntrack_tuple *t, --- linux-2.6.20.21/net/ipv4/netfilter/ip_conntrack_core.c 2009-11-02 10:57:49.000000000 -0500 +++ linux-2.6.20.21.mod/net/ipv4/netfilter/ip_conntrack_core.c 2009-11-02 09:57:57.000000000 -0500 @@ -45,6 +45,7 @@ #include #include #include +#include /* ip_conntrack_lock protects the main hash table, protocol/helper/expected registrations, conntrack timers*/ @@ -181,7 +182,8 @@ const struct sk_buff *skb, unsigned int dataoff, struct ip_conntrack_tuple *tuple, - const struct ip_conntrack_protocol *protocol) + const struct ip_conntrack_protocol *protocol, + unsigned short vid) { /* Never happen */ if (iph->frag_off & htons(IP_OFFSET)) { @@ -194,6 +196,7 @@ tuple->dst.ip = iph->daddr; tuple->dst.protonum = iph->protocol; tuple->dst.dir = IP_CT_DIR_ORIGINAL; + tuple->vid = vid; return protocol->pkt_to_tuple(skb, dataoff, tuple); } @@ -206,6 +209,7 @@ inverse->src.ip = orig->dst.ip; inverse->dst.ip = orig->src.ip; inverse->dst.protonum = orig->dst.protonum; + inverse->vid = orig->vid; inverse->dst.dir = !orig->dst.dir; return protocol->invert_tuple(inverse, orig); @@ -779,11 +783,26 @@ struct ip_conntrack_tuple tuple; struct ip_conntrack_tuple_hash *h; struct ip_conntrack *ct; +#ifdef CONFIG_IP_NF_CONNTRACK_VLAN + struct vlan_ethhdr *vhdr; + unsigned short vlan_TCI, vid = 8192; + + vhdr = vlan_eth_hdr(skb); + if (vhdr && vhdr->h_vlan_proto == __constant_htons(ETH_P_8021Q)){ + vlan_TCI = ntohs(vhdr->h_vlan_TCI); + vid = (vlan_TCI & VLAN_VID_MASK); + } +#endif IP_NF_ASSERT((skb->nh.iph->frag_off & htons(IP_OFFSET)) == 0); +#ifdef CONFIG_IP_NF_CONNTRACK_VLAN if (!ip_ct_get_tuple(skb->nh.iph, skb, skb->nh.iph->ihl*4, + &tuple,proto,vid)) +#else + if (!ip_ct_get_tuple(skb->nh.iph, skb, skb->nh.iph->ihl*4, &tuple,proto)) +#endif return NULL; /* look for tuple match */ --- linux-2.6.20.21/net/ipv4/netfilter/ip_conntrack_proto_icmp.c 2007-10-17 15:31:14.000000000 -0400 +++ linux-2.6.20.21.mod/net/ipv4/netfilter/ip_conntrack_proto_icmp.c 2009-11-02 09:58:52.000000000 -0500 @@ -20,6 +20,7 @@ #include #include #include +#include unsigned int ip_ct_icmp_timeout __read_mostly = 30*HZ; @@ -146,6 +147,16 @@ struct ip_conntrack_protocol *innerproto; struct ip_conntrack_tuple_hash *h; int dataoff; +#ifdef CONFIG_IP_NF_CONNTRACK_VLAN + struct vlan_ethhdr *vhdr; + unsigned short vlan_TCI, vid = 8192; + + vhdr = vlan_eth_hdr(skb); + if (vhdr && vhdr->h_vlan_proto == __constant_htons(ETH_P_8021Q)){ + vlan_TCI = ntohs(vhdr->h_vlan_TCI); + vid = (vlan_TCI & VLAN_VID_MASK); + } +#endif IP_NF_ASSERT(skb->nfct == NULL); @@ -164,7 +175,11 @@ innerproto = ip_conntrack_proto_find_get(inside->ip.protocol); dataoff = skb->nh.iph->ihl*4 + sizeof(inside->icmp) + inside->ip.ihl*4; /* Are they talking about one of our connections? */ +#ifdef CONFIG_IP_NF_CONNTRACK_VLAN + if (!ip_ct_get_tuple(&inside->ip, skb, dataoff, &origtuple, innerproto, vid)) { +#else if (!ip_ct_get_tuple(&inside->ip, skb, dataoff, &origtuple, innerproto)) { +#endif DEBUGP("icmp_error: ! get_tuple p=%u", inside->ip.protocol); ip_conntrack_proto_put(innerproto); return -NF_ACCEPT; --- linux-2.6.20.21/net/ipv4/netfilter/ip_nat_core.c 2009-11-02 10:57:49.000000000 -0500 +++ linux-2.6.20.21.mod/net/ipv4/netfilter/ip_nat_core.c 2009-11-02 10:01:08.000000000 -0500 @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -821,6 +822,17 @@ unsigned long statusbit; enum ip_nat_manip_type manip = HOOK2MANIP(hooknum); +#ifdef CONFIG_IP_NF_CONNTRACK_VLAN + struct vlan_ethhdr *vhdr; + unsigned short vlan_TCI, vid = 8192; + + vhdr = vlan_eth_hdr(*pskb); + if (vhdr && vhdr->h_vlan_proto == __constant_htons(ETH_P_8021Q)){ + vlan_TCI = ntohs(vhdr->h_vlan_TCI); + vid = (vlan_TCI & VLAN_VID_MASK); + } +#endif + if (!skb_make_writable(pskb, hdrlen + sizeof(*inside))) return 0; @@ -850,10 +862,14 @@ DEBUGP("icmp_reply_translation: translating error %p manp %u dir %s\n", *pskb, manip, dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY"); +#ifdef CONFIG_IP_NF_CONNTRACK_VLAN if (!ip_ct_get_tuple(&inside->ip, *pskb, (*pskb)->nh.iph->ihl*4 + sizeof(struct icmphdr) + inside->ip.ihl*4, &inner, + __ip_conntrack_proto_find(inside->ip.protocol), vid)) +#else __ip_conntrack_proto_find(inside->ip.protocol))) +#endif return 0; /* Change inner back to look like incoming packet. We do the