summaryrefslogtreecommitdiffstats
path: root/net/bridge
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-02-15 02:15:32 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-02-15 02:15:32 +0000
commit86464aed71025541805e7b1515541aee89879e33 (patch)
treee01a457a4912a8553bc65524aa3125d51f29f810 /net/bridge
parent88f99939ecc6a95a79614574cb7d95ffccfc3466 (diff)
Merge with Linux 2.2.1.
Diffstat (limited to 'net/bridge')
-rw-r--r--net/bridge/br.c76
-rw-r--r--net/bridge/br_tree.c50
2 files changed, 107 insertions, 19 deletions
diff --git a/net/bridge/br.c b/net/bridge/br.c
index 014453f8c..204b00ca0 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -50,6 +50,7 @@
*
*/
+#include <linux/config.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
@@ -71,6 +72,7 @@
#include <asm/uaccess.h>
#include <asm/system.h>
#include <net/br.h>
+#include <linux/proc_fs.h>
#ifndef min
#define min(a, b) (((a) <= (b)) ? (a) : (b))
@@ -802,11 +804,45 @@ static void hold_timer_expiry(int port_no) /* (4.7.8) */
} /* (4.6.1.2.3) */
}
+/* Vova Oksman: Write the buffer (contents of the Bridge table) */
+/* to a PROCfs file */
+int br_tree_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
+{
+ int size;
+ int len=0;
+ off_t pos=0;
+ char* pbuffer;
+
+ if(0==offset)
+ {
+ /* first time write the header */
+ size = sprintf(buffer,"%s","MAC address Device Flags Age (sec.)\n");
+ len=size;
+ }
+
+ pbuffer=&buffer[len];
+ sprintf_avl(&pbuffer,NULL,&pos,&len,offset,length);
+
+ *start = buffer+len-(pos-offset); /* Start of wanted data */
+ len = pos-offset; /* Start slop */
+ if (len>length)
+ len = length; /* Ending slop */
+
+ return len;
+}
+#ifdef CONFIG_PROC_FS
+struct proc_dir_entry proc_net_bridge= {
+ PROC_NET_BRIDGE, 6, "bridge",
+ S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, &proc_net_inode_operations,
+ br_tree_get_info
+};
+#endif
__initfunc(void br_init(void))
{ /* (4.8.1) */
int port_no;
- printk(KERN_INFO "Ethernet Bridge 005 for NET3.037 (Linux 2.1)\n");
+ printk(KERN_INFO "NET4: Ethernet Bridge 005 for NET4.0\n");
/*
* Form initial topology change time.
@@ -857,6 +893,10 @@ __initfunc(void br_init(void))
br_stats.policy = BR_ACCEPT; /* Enable bridge to accpet all protocols */
br_stats.exempt_protocols = 0;
/*start_hello_timer();*/
+ /* Vova Oksman: register the function for the PROCfs "bridge" file */
+#ifdef CONFIG_PROC_FS
+ proc_net_register(&proc_net_bridge);
+#endif
}
static inline unsigned short make_port_id(int port_no)
@@ -1157,8 +1197,8 @@ static struct sk_buff *alloc_bridge_skb(int port_no, int pdu_size, char *pdu_nam
return NULL;
}
skb->dev = dev;
- skb->mac.raw = skb->h.raw = skb_put(skb,size);
- memset(skb->h.raw + 60 - pad_size, 0xa5, pad_size);
+ skb->mac.raw = skb->nh.raw = skb_put(skb,size);
+ memset(skb->nh.raw + 60 - pad_size, 0xa5, pad_size);
eth = skb->mac.ethernet;
memcpy(eth->h_dest, bridge_ula, ETH_ALEN);
memcpy(eth->h_source, dev->dev_addr, ETH_ALEN);
@@ -1181,13 +1221,13 @@ static struct sk_buff *alloc_bridge_skb(int port_no, int pdu_size, char *pdu_nam
#endif
eth->h_proto = htons(pdu_size + BRIDGE_LLC1_HS);
- skb->h.raw += skb->dev->hard_header_len;
- llc_buffer = skb->h.raw;
+ skb->nh.raw += skb->dev->hard_header_len;
+ llc_buffer = skb->nh.raw;
*llc_buffer++ = BRIDGE_LLC1_DSAP;
*llc_buffer++ = BRIDGE_LLC1_SSAP;
*llc_buffer++ = BRIDGE_LLC1_CTRL;
- /* set h.raw to where the bpdu starts */
- skb->h.raw += BRIDGE_LLC1_HS;
+ /* set nh.raw to where the bpdu starts */
+ skb->nh.raw += BRIDGE_LLC1_HS;
/* mark that we've been here... */
skb->pkt_bridged = IS_BRIDGED;
@@ -1208,18 +1248,18 @@ static int send_config_bpdu(int port_no, Config_bpdu *config_bpdu)
return(-1);
/* copy fields before "flags" */
- memcpy(skb->h.raw, config_bpdu, BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET);
+ memcpy(skb->nh.raw, config_bpdu, BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET);
/* build the "flags" field */
- *(skb->h.raw+BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET) = 0;
+ *(skb->nh.raw+BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET) = 0;
if (config_bpdu->top_change_ack)
- *(skb->h.raw+BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET) |= 0x80;
+ *(skb->nh.raw+BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET) |= 0x80;
if (config_bpdu->top_change)
- *(skb->h.raw+BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET) |= 0x01;
+ *(skb->nh.raw+BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET) |= 0x01;
config_bpdu_hton(config_bpdu);
/* copy the rest */
- memcpy(skb->h.raw+BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET+1,
+ memcpy(skb->nh.raw+BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET+1,
(char*)&(config_bpdu->root_id),
BRIDGE_BPDU_8021_CONFIG_SIZE-1-BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET);
@@ -1235,7 +1275,7 @@ static int send_tcn_bpdu(int port_no, Tcn_bpdu *bpdu)
if (skb == NULL)
return(-1);
- memcpy(skb->h.raw, bpdu, sizeof(Tcn_bpdu));
+ memcpy(skb->nh.raw, bpdu, sizeof(Tcn_bpdu));
dev_queue_xmit(skb);
return(0);
@@ -1336,7 +1376,7 @@ int br_receive_frame(struct sk_buff *skb) /* 3.5 */
if(!port)
return 0;
- skb->h.raw = skb->mac.raw;
+ skb->nh.raw = skb->mac.raw;
eth = skb->mac.ethernet;
p = &port_info[port];
@@ -1440,7 +1480,7 @@ int br_tx_frame(struct sk_buff *skb) /* 3.5 */
return(0);
}
++br_stats_cnt.port_not_disable;
- skb->mac.raw = skb->h.raw = skb->data;
+ skb->mac.raw = skb->nh.raw = skb->data;
eth = skb->mac.ethernet;
port = 0; /* an impossible port (locally generated) */
if (br_stats.flags & BR_DEBUG)
@@ -1499,7 +1539,7 @@ static inline int mcast_quench(struct fdb *f)
f->mcast_timer = jiffies;
else {
if(f->mcast_count > max_mcast_per_period) {
- if(jiffies > (f->mcast_timer + mcast_hold_time))
+ if(time_after(jiffies, f->mcast_timer + mcast_hold_time))
f->mcast_count = 0;
else return 1;
}
@@ -1695,7 +1735,7 @@ static int br_forward(struct sk_buff *skb, int port) /* 3.7 */
skb->pkt_bridged = IS_BRIDGED;
/* reset the skb->ip pointer */
- skb->h.raw = skb->data + ETH_HLEN;
+ skb->nh.raw = skb->data + ETH_HLEN;
/*
* Send the buffer out.
@@ -1764,7 +1804,7 @@ static int br_flood(struct sk_buff *skb, int port)
or have a received valid MAC header */
/* printk("Flood to port %d\n",i);*/
- nskb->h.raw = nskb->data + ETH_HLEN;
+ nskb->nh.raw = nskb->data + ETH_HLEN;
#if LINUX_VERSION_CODE >= 0x20100
nskb->priority = 1;
dev_queue_xmit(nskb);
diff --git a/net/bridge/br_tree.c b/net/bridge/br_tree.c
index 709bafb2b..0936a0f8b 100644
--- a/net/bridge/br_tree.c
+++ b/net/bridge/br_tree.c
@@ -7,6 +7,7 @@
#include <linux/string.h>
#include <linux/malloc.h>
#include <linux/skbuff.h>
+#include <linux/netdevice.h>
#include <net/br.h>
#define _DEBUG_AVL
@@ -28,6 +29,10 @@ static struct fdb *fhp = &fdb_head;
static struct fdb **fhpp = &fhp;
static int fdb_inited = 0;
+#ifdef DEBUG_AVL
+static void printk_avl (struct fdb * tree);
+#endif
+
static int addr_cmp(unsigned char *a1, unsigned char *a2);
/*
@@ -80,7 +85,7 @@ struct fdb *br_avl_find_addr(unsigned char addr[6])
addr[4],
addr[5]);
#endif /* DEBUG_AVL */
- for (tree = &fdb_head ; ; ) {
+ for (tree = fhp ; ; ) {
if (tree == avl_br_empty) {
#if (DEBUG_AVL)
printk("search failed, returning node 0x%x\n", (unsigned int)result);
@@ -426,3 +431,46 @@ static int addr_cmp(unsigned char a1[], unsigned char a2[])
return(0);
}
+/* Vova Oksman: function for copy tree to the buffer */
+void sprintf_avl (char **pbuffer, struct fdb * tree, off_t *pos,
+ int* len, off_t offset, int length)
+{
+ int size;
+
+ if( 0 == *pos){
+ if(avl_br_empty == tree)
+ /* begin from the root */
+ tree = fhp;
+ *pos = *len;
+ }
+
+ if (*pos >= offset+length)
+ return;
+
+ if (tree != avl_br_empty) {
+ /* don't write the local device */
+ if(tree->port != 0){
+ size = sprintf(*pbuffer,
+ "%02x:%02x:%02x:%02x:%02x:%02x %s %d %ld\n",
+ tree->ula[0],tree->ula[1],tree->ula[2],
+ tree->ula[3],tree->ula[4],tree->ula[5],
+ port_info[tree->port].dev->name, tree->flags,CURRENT_TIME-tree->timer);
+
+ (*pos)+=size;
+ (*len)+=size;
+ (*pbuffer)+=size;
+ }
+ if (*pos <= offset)
+ *len=0;
+
+ if (tree->fdb_avl_left != avl_br_empty) {
+ sprintf_avl (pbuffer,tree->fdb_avl_left,pos,len,offset,length);
+ }
+ if (tree->fdb_avl_right != avl_br_empty) {
+ sprintf_avl (pbuffer,tree->fdb_avl_right,pos,len,offset,length);
+ }
+
+ }
+
+ return;
+}