When svlan(4) was introduced, it got its own taghash in if_vlan.c.
This wasn't necessary as "etype" was already checked in the old hash
lookup.

So simplify the code again, and use the savings for some extra hash 
buckets.  :-)

Survives this stacked test between i386 and sparc64 (use .1 on one system, 
and .2 on the other and ping all ip's):

#!/bin/sh
VLANDEV="fxp0"
IP4="1"

ifconfig svlan100 vlan 100 vlanprio 1 vlandev $VLANDEV \
    10.10.101.$IP4 netmask 255.255.255.0
ifconfig svlan200 vlan 200 vlanprio 2 vlandev svlan100 \
    10.10.102.$IP4 netmask 255.255.255.0
ifconfig vlan300  vlan 300 vlanprio 3 vlandev svlan200 \
    10.10.103.$IP4 netmask 255.255.255.0
ifconfig svlan300 vlan 300 vlanprio 4 vlandev vlan300 \
    10.10.104.$IP4 netmask 255.255.255.0
ifconfig vlan200  vlan 200 vlanprio 5 vlandev svlan300 \
    10.10.105.$IP4 netmask 255.255.255.0
ifconfig vlan100  vlan 100 vlanprio 6 vlandev vlan200 \
    10.10.106.$IP4 netmask 255.255.255.0

tcpdump:

19:53:17.566551 QinQ svid 100 pri 1 QinQ svid 200 pri 2 802.1Q vid 300 pri 
3 QinQ svid 300 pri 4 802.1Q vid 200 pri 5 802.1Q vid 100 pri 6 
10.10.106.1 > 10.10.106.2: icmp: echo request

19:53:17.566636 QinQ svid 100 pri 1 QinQ svid 200 pri 2 802.1Q vid 300 pri 
3 QinQ svid 300 pri 4 802.1Q vid 200 pri 5 802.1Q vid 100 pri 6 
10.10.106.2 > 10.10.106.1: icmp: echo reply


--
Cam


Index: if_vlan.c
===================================================================
RCS file: /cvs/src/sys/net/if_vlan.c,v
retrieving revision 1.87
diff -u -r1.87 if_vlan.c
--- if_vlan.c   18 Feb 2011 17:06:45 -0000      1.87
+++ if_vlan.c   4 Jul 2011 18:33:47 -0000
@@ -77,11 +77,11 @@
 #include <net/if_vlan_var.h>
 
 extern struct  ifaddr  **ifnet_addrs;
-u_long vlan_tagmask, svlan_tagmask;
+u_long vlan_tagmask;
 
-#define TAG_HASH_SIZE          32
+#define TAG_HASH_SIZE          64      
 #define TAG_HASH(tag)          (tag & vlan_tagmask)
-LIST_HEAD(vlan_taghash, ifvlan)        *vlan_tagh, *svlan_tagh;
+LIST_HEAD(vlan_taghash, ifvlan)        *vlan_tagh;
 
 void   vlan_start(struct ifnet *ifp);
 int    vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr);
@@ -107,18 +107,12 @@
 void
 vlanattach(int count)
 {
-       /* Normal VLAN */
        vlan_tagh = hashinit(TAG_HASH_SIZE, M_DEVBUF, M_NOWAIT,
            &vlan_tagmask);
        if (vlan_tagh == NULL)
                panic("vlanattach: hashinit");
-       if_clone_attach(&vlan_cloner);
 
-       /* Service-VLAN for QinQ/802.1ad provider bridges */
-       svlan_tagh = hashinit(TAG_HASH_SIZE, M_DEVBUF, M_NOWAIT,
-           &svlan_tagmask);
-       if (svlan_tagh == NULL)
-               panic("vlanattach: hashinit");
+       if_clone_attach(&vlan_cloner);
        if_clone_attach(&svlan_cloner);
 }
 
@@ -277,13 +271,11 @@
 {
        struct ifvlan *ifv;
        struct ifnet *ifp = m->m_pkthdr.rcvif;
-       struct vlan_taghash *tagh;
        u_int tag;
        u_int16_t etype;
 
        if (m->m_flags & M_VLANTAG) {
                etype = ETHERTYPE_VLAN;
-               tagh = vlan_tagh;
                tag = EVL_VLANOFTAG(m->m_pkthdr.ether_vtag);
        } else {
                if (m->m_len < EVL_ENCAPLEN &&
@@ -293,11 +285,10 @@
                }
 
                etype = ntohs(eh->ether_type);
-               tagh = etype == ETHERTYPE_QINQ ? svlan_tagh : vlan_tagh;
                tag = EVL_VLANOFTAG(ntohs(*mtod(m, u_int16_t *)));
        }
 
-       LIST_FOREACH(ifv, &tagh[TAG_HASH(tag)], ifv_list) {
+       LIST_FOREACH(ifv, &vlan_tagh[TAG_HASH(tag)], ifv_list) {
                if (m->m_pkthdr.rcvif == ifv->ifv_p && tag == ifv->ifv_tag &&
                    etype == ifv->ifv_type)
                        break;
@@ -359,7 +350,6 @@
 {
        struct ifaddr *ifa1, *ifa2;
        struct sockaddr_dl *sdl1, *sdl2;
-       struct vlan_taghash *tagh;
        u_int flags;
        int s;
 
@@ -449,8 +439,7 @@
 
        ifv->ifv_tag = tag;
        s = splnet();
-       tagh = ifv->ifv_type == ETHERTYPE_QINQ ? svlan_tagh : vlan_tagh;
-       LIST_INSERT_HEAD(&tagh[TAG_HASH(tag)], ifv, ifv_list);
+       LIST_INSERT_HEAD(&vlan_tagh[TAG_HASH(tag)], ifv, ifv_list);
 
        /* Register callback for physical link state changes */
        ifv->lh_cookie = hook_establish(p->if_linkstatehooks, 1,

Reply via email to