[prev in list] [next in list] [prev in thread] [next in thread]
List: linux-vlan
Subject: Re: [VLAN] Proposal: temporarily adopt NICE
From: Ard van Breemen <ard () telegraafnet ! nl>
Date: 2001-10-22 9:50:27
[Download RAW message or body]
On Sat, Oct 20, 2001 at 04:03:37PM -0700, Ben Greear wrote:
> Is the NICE patch still considered stable? Any changes since you
> sent me the 'diffie' patch?
Hi,
Sorry for the late reply... Had social things todo this weekend :(
I've attached the latest patch, that has that thing fixed of put_dev.
Annyway, this is straight from the package that I intend to upload for
debian users.
(The debian patch exist of the original patch, with seperate fixes, and
nice patch, so users have a choice, and you don't get bothered by my
bugs ;) ).
--
<ard@telegraafnet.nl> Telegraaf Elektronische Media http://wwwijzer.nl
http://leerquoten.monster.org/ http://www.faqs.org/rfcs/rfc1855.html
Let your government know you value your freedom. Sign the petition:
http://petition.eurolinux.org/
["vlan-nice.patch" (text/plain)]
diff -ruN -X exclude kernel-source-2.4.12-vanilla/net/8021q/Makefile \
kernel-source-2.4.12/net/8021q/Makefile
--- kernel-source-2.4.12-vanilla/net/8021q/Makefile Wed Oct 17 11:11:15 2001
+++ kernel-source-2.4.12/net/8021q/Makefile Wed Oct 17 16:34:11 2001
@@ -9,7 +9,7 @@
O_TARGET := 8021q.o
-obj-y := vlan.o vlanproc.o vlan_dev.o
+obj-y := vlan.o vlanproc.o vlan_dev.o vlan_nice.o
obj-m := $(O_TARGET)
obj-$(CONFIG_SYSCTL) += sysctl_net_vlan.o
diff -ruN -X exclude kernel-source-2.4.12-vanilla/net/8021q/nicext.h \
kernel-source-2.4.12/net/8021q/nicext.h
--- kernel-source-2.4.12-vanilla/net/8021q/nicext.h Thu Jan 1 01:00:00 1970
+++ kernel-source-2.4.12/net/8021q/nicext.h Wed Oct 17 16:34:11 2001
@@ -0,0 +1,88 @@
+/****************************************************************************
+ * Copyright(c) 2000-2001 Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ *
+ * Name: nicext.h
+ *
+ * Description: Broadcom Network Interface Card Extension (NICE) is an
+ * extension to Linux NET device kernel mode drivers.
+ * NICE is designed to provide additional functionalities,
+ * such as receive packet intercept. To support Broadcom NICE,
+ * the network device driver can be modified by adding an
+ * device ioctl handler and by indicating receiving packets
+ * to the NICE receive handler. Broadcom NICE will only be
+ * enabled by a NICE-aware intermediate driver, such as
+ * Broadcom Advanced Server Program Driver (BASP). When NICE
+ * is not enabled, the modified network device drivers
+ * functions exactly as other non-NICE aware drivers.
+ *
+ * Author: Frankie Fan
+ *
+ * Created: September 17, 2000
+ *
+ ****************************************************************************/
+#ifndef _nicext_h_
+#define _nicext_h_
+
+/*
+ * ioctl for NICE
+ */
+#define SIOCNICE SIOCDEVPRIVATE+7
+
+/*
+ * SIOCNICE:
+ *
+ * The following structure needs to be less than IFNAMSIZ (16 bytes) because
+ * we're overloading ifreq.ifr_ifru.
+ *
+ * If 16 bytes is not enough, we should consider relaxing this because
+ * this is no field after ifr_ifru in the ifreq structure. But we may
+ * run into future compatiability problem in case of changing struct ifreq.
+ */
+struct nice_req
+{
+ __u32 cmd;
+
+ union
+ {
+ /* cmd = NICE_CMD_SET_RX or NICE_CMD_GET_RX */
+ struct
+ {
+ void (*nrqus1_rx)( struct sk_buff*, void* );
+ void* nrqus1_ctx;
+ } nrqu_nrqus1;
+
+ /* cmd = NICE_CMD_QUERY_SUPPORT */
+ struct
+ {
+ __u32 nrqus2_magic;
+ __u32 nrqus2_support_rx:1;
+ __u32 nrqus2_support_vlan:1;
+ } nrqu_nrqus2;
+ } nrq_nrqu;
+};
+
+#define nrq_rx nrq_nrqu.nrqu_nrqus1.nrqus1_rx
+#define nrq_ctx nrq_nrqu.nrqu_nrqus1.nrqus1_ctx
+#define nrq_support_rx nrq_nrqu.nrqu_nrqus2.nrqus2_support_rx
+#define nrq_magic nrq_nrqu.nrqu_nrqus2.nrqus2_magic
+#define nrq_support_vlan nrq_nrqu.nrqu_nrqus2.nrqus2_support_vlan
+
+/*
+ * magic constants
+ */
+#define NICE_REQUESTOR_MAGIC 0x4543494E // NICE in ascii
+#define NICE_DEVICE_MAGIC 0x4E494345 // ECIN in ascii
+
+/*
+ * command field
+ */
+#define NICE_CMD_QUERY_SUPPORT 0x00000001
+#define NICE_CMD_SET_RX 0x00000002
+#define NICE_CMD_GET_RX 0x00000003
+
+#endif // _nicext_h_
+
diff -ruN -X exclude kernel-source-2.4.12-vanilla/net/8021q/vlan.c \
kernel-source-2.4.12/net/8021q/vlan.c
--- kernel-source-2.4.12-vanilla/net/8021q/vlan.c Wed Oct 17 11:11:15 2001
+++ kernel-source-2.4.12/net/8021q/vlan.c Thu Oct 18 13:41:24 2001
@@ -34,6 +34,7 @@
#include <linux/if_vlan.h>
#include "vlan.h"
#include "vlanproc.h"
+#include "vlan_nice.h"
/* Global VLAN variables */
@@ -106,6 +107,20 @@
}
/*
+ * Cleanup of groups before exit
+ */
+
+static void vlan_group_cleanup(void) {
+ struct vlan_group* grp = NULL;
+ for (grp = p802_1Q_vlan_list; (grp != NULL);) {
+ struct vlan_group *nextgroup=grp->next;
+ nextgroup=grp->next;
+ kfree(grp);
+ grp = nextgroup;
+ }
+}
+
+/*
* Module 'remove' entry point.
* o delete /proc/net/router directory and static entries.
*/
@@ -115,6 +130,7 @@
dev_remove_pack(&vlan_packet_type);
vlan_proc_cleanup();
+ vlan_group_cleanup();
vlan_ioctl_hook = NULL;
}
@@ -159,6 +175,17 @@
}/* find_802_1Q_vlan_client */
+/** Will search the vlan group table to see if there is a vlan defined
+ */
+
+int vlan_group_empty(struct vlan_group* grp) {
+ int i;
+ for(i=0;i<VLAN_GROUP_ARRAY_LEN;i++) {
+ if(grp->vlan_devices[i]) return 0;
+ }
+ return 1;
+}
+
/** This method will explicitly do a dev_put on the device if do_dev_put
* is TRUE. This gets around a difficulty with reference counting, and
* the unregister-by-name (below). If do_locks is true, it will grab
@@ -209,7 +236,14 @@
else {
unregister_netdevice(dev);
}
-
+ if(vlan_group_empty(grp)) {
+ struct net_device *real_dev;
+ real_dev=dev_get_by_index(real_dev_ifindex);
+ if(real_dev) {
+ vlan_nice_disable_rx(real_dev);
+ dev_put(real_dev);
+ }
+ }
MOD_DEC_USE_COUNT;
}/* if */
@@ -262,6 +296,7 @@
struct net_device *new_dev;
struct net_device *real_dev; /* the ethernet device */
int malloc_size = 0;
+ int nice_supported =0; /* Is the device nice capable */
#ifdef VLAN_DEBUG
printk(VLAN_DBG __FUNCTION__ ": if_name -:%s:- vid: %i\n",
@@ -297,6 +332,7 @@
if (new_dev != NULL) {
/* printk(KERN_ALERT "Got a new device.."); */
+ nice_supported=vlan_nice_supported(real_dev);
memset(new_dev, 0, malloc_size); /* zero everything \
out */
/* set us up to not use a Qdisc, as the underlying \
Hardware device @@ -361,8 +397,13 @@
new_dev->type = real_dev->type; /* TODO: maybe just \
assign it to be ETHERNET? */
- /* Regular ethernet + 4 bytes (18 total). */
- new_dev->hard_header_len = VLAN_HLEN + \
real_dev->hard_header_len; + if(nice_supported) {
+ /* Regular ethernet, tag is done seperately */
+ new_dev->hard_header_len=real_dev->hard_header_len;
+ } else {
+ /* Regular ethernet + 4 bytes tag (18 total). */
+ new_dev->hard_header_len = VLAN_HLEN + real_dev->hard_header_len;
+ }
new_dev->priv = kmalloc(sizeof(struct \
vlan_dev_info), GFP_KERNEL);
@@ -379,9 +420,19 @@
new_dev->open = vlan_dev_open;
new_dev->stop = vlan_dev_stop;
- new_dev->hard_header = vlan_dev_hard_header;
- new_dev->hard_start_xmit = vlan_dev_hard_start_xmit;
+ if(nice_supported) {
+ /* We do not have to insert tags */
+ new_dev->hard_header=real_dev->hard_header;
+ /* We must send extra info in the skb */
+ new_dev->hard_start_xmit = vlan_nice_dev_hard_start_xmit;
+ } else {
+ /* We must insert tags */
+ new_dev->hard_header = vlan_dev_hard_header;
+ /* We must make sure it is tagged */
+ new_dev->hard_start_xmit = vlan_dev_hard_start_xmit;
+ }
+
new_dev->rebuild_header = vlan_dev_rebuild_header;
new_dev->hard_header_parse = \
real_dev->hard_header_parse;
new_dev->set_mac_address = vlan_dev_set_mac_address;
@@ -447,6 +498,11 @@
* so hold on to the reference.
*/
MOD_INC_USE_COUNT; /* Add was a success!! */
+ /** It is not a problem to re-enable again and again.
+ * We must do it after MOD_INC_USE_COUNT, since only
+ * then we are sure that our noce functions will not be removed
+ */
+ vlan_nice_enable_rx(real_dev,grp);
#ifdef VLAN_DEBUG
printk(VLAN_DBG "Allocated new device successfully, \
returning.\n");
diff -ruN -X exclude kernel-source-2.4.12-vanilla/net/8021q/vlan_nice.c \
kernel-source-2.4.12/net/8021q/vlan_nice.c
--- kernel-source-2.4.12-vanilla/net/8021q/vlan_nice.c Thu Jan 1 01:00:00 1970
+++ kernel-source-2.4.12/net/8021q/vlan_nice.c Wed Oct 17 16:34:11 2001
@@ -0,0 +1,143 @@
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/in.h>
+#include <linux/init.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <net/datalink.h>
+#include <net/p8022.h>
+#include <net/arp.h>
+#include <linux/brlock.h>
+
+
+#include "vlan.h"
+#include "vlanproc.h"
+#include <linux/if_vlan.h>
+#include <net/ip.h>
+#include "nicext.h"
+#include "vlan_nice.h"
+
+int vlan_nice_netif_rx(struct sk_buff *skb, struct vlan_group *grp) {
+ unsigned short vid;
+ struct net_device_stats* stats;
+ vlan_tag_t *nice_vlan;
+ struct net_device *dev;
+
+ unsigned short vlan_TCI;
+
+ /* vlan_TCI = ntohs(get_unaligned(&vhdr->h_vlan_TCI)); */
+ nice_vlan=(vlan_tag_t *)&skb->cb[0];
+ if(NICE_VLAN_RXTAG!=nice_vlan->signature) {
+ /* Nope, do a plain netif_rx */
+ return netif_rx(skb);
+ }
+ /* Clear signature just in case */
+ nice_vlan->signature=0;
+ dev=skb->dev;
+ /* Yep, we got vlan */
+ vlan_TCI=nice_vlan->tag;
+ /*vlan_TCI = ntohs(vhdr->h_vlan_TCI);*/
+ vid = (vlan_TCI & 0xFFF);
+
+ /* At this moment we have to:
+ * check if the vid is valid for this device
+ * If it is, we do a netif_rx with the right skb->dev
+ */
+
+#ifdef VLAN_DEBUG
+ printk(VLAN_DBG __FUNCTION__ ": skb: %p vlan_id: %hx\n",
+ skb, vid);
+#endif
+
+ /* we have 12 bits of vlan ID. */
+ skb->dev = grp->vlan_devices[vid];
+
+ if (!skb->dev) {
+ #ifdef VLAN_DEBUG
+ printk(VLAN_DBG __FUNCTION__ ": ERROR: No net_device for VID: %i on dev: %s \
[%i]\n", (unsigned int)(vid), dev->name, dev->ifindex); + #endif
+ kfree_skb(skb);
+ return -1;
+ }
+
+ /* Bump the rx counters for the VLAN device. */
+ stats = vlan_dev_get_stats(skb->dev);
+ stats->rx_packets++;
+ stats->rx_bytes += skb->len;
+ return netif_rx(skb);
+}
+
+int vlan_nice_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) {
+ struct net_device_stats* stats = vlan_dev_get_stats(dev);
+ vlan_tag_t *nice_vlan;
+
+ /* Prepare vlan tag insertion by nice driver.
+ */
+
+ nice_vlan=(vlan_tag_t *)&skb->cb[0];
+ nice_vlan->tag = VLAN_DEV_INFO(dev)->vlan_id;
+ nice_vlan->tag |= vlan_dev_get_egress_qos_mask(dev, skb);
+ nice_vlan->signature=NICE_VLAN_TXTAG;
+
+ skb->dev = VLAN_DEV_INFO(dev)->real_dev;
+
+ dev_queue_xmit(skb);
+ stats->tx_packets++; /* for statics only */
+ stats->tx_bytes += skb->len;
+ return 0;
+}/* vlan_nice_dev_hard_start_xmit */
+
+int vlan_nice_supported(struct net_device *dev) {
+ static struct ifreq ifr;
+ static struct nice_req *nrq;
+ static int (* ioctl)(struct net_device *, struct ifreq *, int);
+ memset(&ifr,0,sizeof(ifr));
+ nrq=&ifr.ifr_ifru;
+ nrq->cmd=NICE_CMD_QUERY_SUPPORT;
+ if (((ioctl = dev->do_ioctl) != NULL) && (ioctl(dev, &ifr, SIOCNICE) == 0)) {
+ /* Now we have something nice? */
+ if(NICE_DEVICE_MAGIC==nrq->nrq_magic && nrq->nrq_support_rx) {
+ /* Yes. It supports _rx and vlan */
+ /* Actually the test is not complete, but the bcm5700 driver is also not complete \
*/ + return 1;
+ }
+ }
+ printk(KERN_INFO "VLAN NICE: device %s is not NICE capable.\n",dev->name);
+ return 0;
+}
+
+int vlan_nice_enable_rx(struct net_device *dev, void *data) {
+ static struct ifreq ifr;
+ static struct nice_req *nrq;
+ static int (* ioctl)(struct net_device *, struct ifreq *, int);
+ memset(&ifr,0,sizeof(ifr));
+ nrq=&ifr.ifr_ifru;
+ if(!vlan_nice_supported(dev)) return 0;
+ nrq->cmd=NICE_CMD_SET_RX;
+ nrq->nrq_rx=vlan_nice_netif_rx;
+ nrq->nrq_ctx=data;
+ printk(KERN_INFO "VLAN NICE: enabling NICE on %s.\n",dev->name);
+ if (((ioctl = dev->do_ioctl) != NULL) && (ioctl(dev, &ifr, SIOCNICE) == 0)) {
+ /* Hmmm, ok.... */
+ }
+ return 0;
+}
+
+int vlan_nice_disable_rx(struct net_device *dev) {
+ static struct ifreq ifr;
+ static struct nice_req *nrq;
+ static int (* ioctl)(struct net_device *, struct ifreq *, int);
+ memset(&ifr,0,sizeof(ifr));
+ nrq=&ifr.ifr_ifru;
+ if(!vlan_nice_supported(dev)) return 0;
+ nrq->cmd=NICE_CMD_SET_RX;
+ nrq->nrq_rx=NULL;
+ nrq->nrq_ctx=NULL;
+ printk(KERN_INFO "VLAN NICE: disabling NICE on %s.\n",dev->name);
+ if (((ioctl = dev->do_ioctl) != NULL) && (ioctl(dev, &ifr, SIOCNICE) == 0)) {
+ /* Hmmm, ok.... */
+ }
+ return 0;
+}
+
diff -ruN -X exclude kernel-source-2.4.12-vanilla/net/8021q/vlan_nice.h \
kernel-source-2.4.12/net/8021q/vlan_nice.h
--- kernel-source-2.4.12-vanilla/net/8021q/vlan_nice.h Thu Jan 1 01:00:00 1970
+++ kernel-source-2.4.12/net/8021q/vlan_nice.h Wed Oct 17 16:34:11 2001
@@ -0,0 +1,23 @@
+/******************************************************************************/
+/* */
+/* This file is based on bcm5700.c written by Broadcom */
+/* */
+/******************************************************************************/
+#include "nicext.h"
+
+#ifndef NICE_VLAN
+#define NICE_VLAN
+typedef struct {
+ unsigned short tag;
+ unsigned short signature;
+} vlan_tag_t;
+
+#define NICE_VLAN_TXTAG 0x5555
+#define NICE_VLAN_RXTAG 0x7777
+#define NICE_VLAN_EMPTY 0
+
+extern int vlan_nice_enable_rx(struct net_device *dev, void *data);
+extern int vlan_nice_disable_rx(struct net_device *dev);
+extern int vlan_nice_dev_hard_start_xmit(struct sk_buff *skb, struct net_device \
*dev); +
+#endif
_______________________________________________
VLAN mailing list - VLAN@Scry.WANfear.com
http://www.WANfear.com/mailman/listinfo/vlan
VLAN Page: http://scry.wanfear.com/~greear/vlan.html
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic