Skip to contentSkip to conversation

Should VLANs be devices or something else?

DISCUSSION Andi Kleen 2 participants 2 messages Jun 20, 2001 1 message not in the archive

Subsystems (2)
lore
Share & tools
lore

Andi Kleen

author
#1 lore raw
In reply to a message not in the archive
Quoted 3 lines · Ben Greear

Adding the hashed lookup for devices took the exponential curve out of ip and ifconfig's performance, btw.

And fixing the ifconfig user data structures took it also. Probably just ip needs similar tuning.
No need to add the name lookup hash table to the kernel.

Perhaps it would be best if you could post your current patch without these hash tables, so that it can be properly reviewed and hopefully merged then.

-Andi

#2 lore raw
In reply to a message not in the archive
Quoted 9 lines · Andi Kleen
Quoted 3 lines · Ben Greear

Adding the hashed lookup for devices took the exponential curve out of ip and ifconfig's performance, btw.

And fixing the ifconfig user data structures took it also. Probably just ip needs similar tuning.
No need to add the name lookup hash table to the kernel.

ip is still much faster than ifconfig for large numbers of devices (say, 1000+).

If I remember correctly, it takes about 20 seconds to do an 'ip addr show' for 4000 interfaces. Most of that time is in the kernel. This may be acceptable, but I know it can be made faster with hashing and/or some other clever way...

If you are interested in exact numbers, I (or you) can run the vlan_test.pl script in my vlan distribution (also attached). It currently has the ifconfig -a part commented out because it makes the test script take too long. The script can also generate output ready to be fed into gnuplot.

Quoted 4 lines

Perhaps it would be best if you could post your current patch without these hash tables, so that it can be properly reviewed and hopefully merged then.

Agreed. It is attached. I have placed 'TODO' comments in the patch where I had questions, I would especially like feedback on these areas of the code...

Quoted 2 lines

-Andi

Signature · 3 lines
Ben Greear <[email protected]>          <[email protected]>
President of Candela Technologies Inc      http://www.candelatech.com
ScryMUD:  http://scry.wanfear.com     http://scry.wanfear.com/~greear
include/linux/if_ether.h +1 -0
diff -u -r -N -X /home/greear/exclude.list linux/include/linux/if_ether.h linux.dev/include/linux/if_ether.h
@@ -56,6 +56,7 @@
 #define ETH_P_RARP      0x8035		/* Reverse Addr Res packet	*/
 #define ETH_P_ATALK	0x809B		/* Appletalk DDP		*/
 #define ETH_P_AARP	0x80F3		/* Appletalk AARP		*/
+#define ETH_P_8021Q	0x8100          /* 802.1Q VLAN Extended Header  */
 #define ETH_P_IPX	0x8137		/* IPX over DIX			*/
 #define ETH_P_IPV6	0x86DD		/* IPv6 over bluebook		*/
 #define ETH_P_PPP_DISC	0x8863		/* PPPoE discovery messages     */
include/linux/if_vlan.h +271 -0

271 lines not on this page · raw message

include/linux/netdevice.h +30 -2
diff -u -r -N -X /home/greear/exclude.list linux/include/linux/netdevice.h linux.dev/include/linux/netdevice.h
@@ -37,8 +37,14 @@
 #include <linux/config.h>
 #ifdef CONFIG_NET_PROFILE
 #include <net/profile.h>
+
+#endif
+
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+struct vlan_dev_info;
 #endif
 
+
 struct divert_blk;
 
 #define HAVE_ALLOC_NETDEV		/* feature macro: alloc_xxxdev
@@ -72,7 +78,11 @@
  */
  
 #if !defined(CONFIG_AX25) && !defined(CONFIG_AX25_MODULE) && !defined(CONFIG_TR)
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+#define LL_MAX_HEADER	36
+#else
 #define LL_MAX_HEADER	32
+#endif
 #else
 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
 #define LL_MAX_HEADER	96
@@ -183,12 +193,24 @@
 {
 	struct hh_cache *hh_next;	/* Next entry			     */
 	atomic_t	hh_refcnt;	/* number of users                   */
-	unsigned short  hh_type;	/* protocol identifier, f.e ETH_P_IP */
+	unsigned short  hh_type;	/* protocol identifier, f.e ETH_P_IP
+                                         *  NOTE:  For VLANs, this will be the
+                                         *  encapuslated type. --BLG
+                                         */
 	int		hh_len;		/* length of header */
 	int		(*hh_output)(struct sk_buff *skb);
 	rwlock_t	hh_lock;
 	/* cached hardware header; allow for machine alignment needs.        */
-	unsigned long	hh_data[16/sizeof(unsigned long)];
+
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+        /* we need 4 extra bytes for VLAN headers
+         * FIXME: DO THIS ONLY IF WE REALLY START TO DO VLAN HEADER
+         * CACHE THING! MAKE SURE THIS WORKS WHEN sizeof(long) > 4 ! */
+  	unsigned long	hh_data[20/sizeof(__u32)];
+#else
+  	unsigned long	hh_data[16/sizeof(unsigned long)];
+#endif
+
 };
 
 /* These flag bits are private to the generic network queueing
@@ -394,6 +416,12 @@
 
 	/* open/release and usage marking */
 	struct module *owner;
+
+
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+        /*  Holds information that makes sense if this device is a VLAN device. */
+        struct vlan_dev_info* vlan_dev;
+#endif
 
 	/* bridge stuff */
 	struct net_bridge_port	*br_port;
net/8021q/Makefile +19 -0
diff -u -r -N -X /home/greear/exclude.list linux/net/8021q/Makefile linux.dev/net/8021q/Makefile
@@ -0,0 +1,19 @@
+#
+# Makefile for the Linux VLAN layer.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+
+O_TARGET := 8021q.o
+
+obj-y := vlan.o vlanproc.o vlan_dev.o
+obj-m := $(O_TARGET)
+obj-$(CONFIG_SYSCTL) += sysctl_net_vlan.o
+
+include $(TOPDIR)/Rules.make
+
+tar:
+	tar -cvf /dev/f1 .
net/8021q/sysctl_net_vlan.c +20 -0
diff -u -r -N -X /home/greear/exclude.list linux/net/8021q/sysctl_net_vlan.c linux.dev/net/8021q/sysctl_net_vlan.c
@@ -0,0 +1,20 @@
+/* 
+ * sysctl_net_vlan.c: sysctl interface to net Ethernet VLAN subsystem.
+ *
+ * Begun Dec 20, 1998, Ben Greear
+ *
+ * TODO:  What, if anything, should this do??
+ */
+
+#include <linux/module.h>
+
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+   
+#include <linux/mm.h>
+#include <linux/sysctl.h>
+
+ctl_table ether_vlan_table[] = {
+	{0}
+};
+
+#endif
net/8021q/vlan.c +438 -0

438 lines not on this page · raw message

net/8021q/vlan.h +41 -0

41 lines not on this page · raw message

net/8021q/vlan_dev.c +760 -0

760 lines not on this page · raw message

net/8021q/vlanproc.c +604 -0

604 lines not on this page · raw message

net/8021q/vlanproc.h +27 -0
diff -u -r -N -X /home/greear/exclude.list linux/net/8021q/vlanproc.h linux.dev/net/8021q/vlanproc.h
@@ -0,0 +1,27 @@
+
+#ifndef __BEN_VLAN_PROC_INC__
+#define __BEN_VLAN_PROC_INC__
+
+
+int vlan_proc_init(void);
+
+int vlan_proc_rem_dev(struct net_device* vlandev);
+int vlan_proc_add_dev (struct net_device* vlandev);
+void vlan_proc_cleanup (void);
+
+
+#define	VLAN_PROC_BUFSZ	(4096)	/* buffer size for printing proc info */
+
+/****** Data Types **********************************************************/
+
+/*
+typedef struct vlan_stat_entry {
+   struct vlan_stat_entry *	next;
+   char *description;		* description string *
+   void *data;			* -> data *
+   unsigned data_type;		* data type *
+} vlan_stat_entry_t;
+*/
+
+
+#endif
net/Config.in +3 -0
diff -u -r -N -X /home/greear/exclude.list linux/net/Config.in linux.dev/net/Config.in
@@ -46,6 +46,9 @@
 	 tristate '    Multi-Protocol Over ATM (MPOA) support' CONFIG_ATM_MPOA
       fi
    fi
+
+   tristate '802.1Q VLAN Support (EXPERIMENTAL)' CONFIG_VLAN_8021Q
+
 fi
 
 comment ' '
net/Makefile +1 -0
diff -u -r -N -X /home/greear/exclude.list linux/net/Makefile linux.dev/net/Makefile
@@ -45,6 +45,7 @@
 subdir-$(CONFIG_ATM)		+= atm
 subdir-$(CONFIG_DECNET)		+= decnet
 subdir-$(CONFIG_ECONET)		+= econet
+subdir-$(CONFIG_VLAN_8021Q)           += 8021q
 
 
 obj-y	:= socket.o $(join $(subdir-y), $(patsubst %,/%.o,$(notdir $(subdir-y))))
net/core/dev.c +11 -2
diff -u -r -N -X /home/greear/exclude.list linux/net/core/dev.c linux.dev/net/core/dev.c
@@ -1,4 +1,4 @@
-/*
+/* -*- linux-c -*-
  * 	NET3	Protocol independent device support routines.
  *
  *		This program is free software; you can redistribute it and/or
@@ -103,6 +103,7 @@
 extern int plip_init(void);
 #endif
 
+
 /* This define, if set, will randomly drop a packet when congestion
  * is more than moderate.  It helps fairness in the multi-interface
  * case when one of them is a hog, but it kills performance for the
@@ -133,9 +134,17 @@
  *	and the routines to invoke.
  *
  *	Why 16. Because with 16 the only overlap we get on a hash of the
- *	low nibble of the protocol value is RARP/SNAP/X.25. 
+ *	low nibble of the protocol value is RARP/SNAP/X.25.
+ *
+ *      NOTE:  That is no longer true with the addition of VLAN tags.  Not
+ *             sure which should go first, but I bet it won't make much
+ *             difference if we are running VLANs.  The good news is that
+ *             this protocol won't be in the list unless compiled in, so
+ *             the average user (w/out VLANs) will not be adversly affected.
+ *             --BLG
  *
  *		0800	IP
+ *		8100    802.1Q VLAN
  *		0001	802.3
  *		0002	AX.25
  *		0004	802.2
net/ethernet/eth.c +11 -10
diff -u -r -N -X /home/greear/exclude.list linux/net/ethernet/eth.c linux.dev/net/ethernet/eth.c
@@ -82,7 +82,7 @@
 	 *	in here instead. It is up to the 802.2 layer to carry protocol information.
 	 */
 	
-	if(type!=ETH_P_802_3) 
+	if (type != ETH_P_802_3) 
 		eth->h_proto = htons(type);
 	else
 		eth->h_proto = htons(len);
@@ -92,9 +92,9 @@
 	 */
 	 
 	if(saddr)
-		memcpy(eth->h_source,saddr,dev->addr_len);
+		memcpy(eth->h_source, saddr, dev->addr_len);
 	else
-		memcpy(eth->h_source,dev->dev_addr,dev->addr_len);
+		memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
 
 	/*
 	 *	Anyway, the loopback-device should never use this function... 
@@ -159,11 +159,12 @@
 {
 	struct ethhdr *eth;
 	unsigned char *rawp;
-	
-	skb->mac.raw=skb->data;
-	skb_pull(skb,dev->hard_header_len);
-	eth= skb->mac.ethernet;
-	
+
+      skb->mac.raw = skb->data;
+      skb_pull(skb, dev->hard_header_len);
+      eth = skb->mac.ethernet;
+        
+
 	if(*eth->h_dest&1)
 	{
 		if(memcmp(eth->h_dest,dev->broadcast, ETH_ALEN)==0)
@@ -198,12 +199,12 @@
 	 *	won't work for fault tolerant netware but does for the rest.
 	 */
 	if (*(unsigned short *)rawp == 0xFFFF)
-		return htons(ETH_P_802_3);
+		return __constant_htons(ETH_P_802_3);
 		
 	/*
 	 *	Real 802.2 LLC
 	 */
-	return htons(ETH_P_802_2);
+	return __constant_htons(ETH_P_802_2);
 }
 
 int eth_header_parse(struct sk_buff *skb, unsigned char *haddr)
net/netsyms.c +11 -0
diff -u -r -N -X /home/greear/exclude.list linux/net/netsyms.c linux.dev/net/netsyms.c
@@ -211,6 +211,15 @@
 EXPORT_SYMBOL(destroy_EII_client);
 #endif
 
+
+/* for 801q VLAN support */
+#ifdef CONFIG_VLAN_8021Q_MODULE
+EXPORT_SYMBOL(dev_change_flags);
+#endif
+
+
+
+
 EXPORT_SYMBOL(sklist_destroy_socket);
 EXPORT_SYMBOL(sklist_insert_socket);
 
@@ -521,6 +530,8 @@
 EXPORT_SYMBOL(qdisc_restart);
 EXPORT_SYMBOL(qdisc_create_dflt);
 EXPORT_SYMBOL(noop_qdisc);
+extern struct Qdisc noqueue_qdisc;
+EXPORT_SYMBOL(noqueue_qdisc);
 EXPORT_SYMBOL(qdisc_tree_lock);
 #ifdef CONFIG_NET_SCHED
 PSCHED_EXPORTLIST;