diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-02-15 02:15:32 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-02-15 02:15:32 +0000 |
commit | 86464aed71025541805e7b1515541aee89879e33 (patch) | |
tree | e01a457a4912a8553bc65524aa3125d51f29f810 /net/bridge | |
parent | 88f99939ecc6a95a79614574cb7d95ffccfc3466 (diff) |
Merge with Linux 2.2.1.
Diffstat (limited to 'net/bridge')
-rw-r--r-- | net/bridge/br.c | 76 | ||||
-rw-r--r-- | net/bridge/br_tree.c | 50 |
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; +} |