X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2F802%2Ftr.c;h=e9dc803f2fe0a67de78c4219227f4876352cd89a;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=bd22ae2aabffebfc5fcd104860e65f86e35183d1;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/net/802/tr.c b/net/802/tr.c index bd22ae2aa..e9dc803f2 100644 --- a/net/802/tr.c +++ b/net/802/tr.c @@ -47,12 +47,12 @@ static void rif_check_expire(unsigned long dummy); * Each RIF entry we learn is kept this way */ -struct rif_cache_s { +struct rif_cache { unsigned char addr[TR_ALEN]; int iface; - __u16 rcf; - __u16 rseg[8]; - struct rif_cache_s *next; + __be16 rcf; + __be16 rseg[8]; + struct rif_cache *next; unsigned long last_used; unsigned char local_ring; }; @@ -64,9 +64,9 @@ struct rif_cache_s { * up a lot. */ -static struct rif_cache_s *rif_table[RIF_TABLE_SIZE]; +static struct rif_cache *rif_table[RIF_TABLE_SIZE]; -static spinlock_t rif_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(rif_lock); /* @@ -98,8 +98,9 @@ static inline unsigned long rif_hash(const unsigned char *addr) * makes this a little more exciting than on ethernet. */ -int tr_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, - void *daddr, void *saddr, unsigned len) +static int tr_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, + void *daddr, void *saddr, unsigned len) { struct trh_hdr *trh; int hdr_len; @@ -153,7 +154,7 @@ int tr_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, * can now send the packet. */ -int tr_rebuild_header(struct sk_buff *skb) +static int tr_rebuild_header(struct sk_buff *skb) { struct trh_hdr *trh=(struct trh_hdr *)skb->data; struct trllc *trllc=(struct trllc *)(skb->data+sizeof(struct trh_hdr)); @@ -237,7 +238,7 @@ unsigned short tr_type_trans(struct sk_buff *skb, struct net_device *dev) return trllc->ethertype; } - return ntohs(ETH_P_802_2); + return ntohs(ETH_P_TR_802_2); } /* @@ -248,12 +249,13 @@ void tr_source_route(struct sk_buff *skb,struct trh_hdr *trh,struct net_device * { int slack; unsigned int hash; - struct rif_cache_s *entry; + struct rif_cache *entry; unsigned char *olddata; + unsigned long flags; static const unsigned char mcast_func_addr[] = {0xC0,0x00,0x00,0x04,0x00,0x00}; - spin_lock_bh(&rif_lock); + spin_lock_irqsave(&rif_lock, flags); /* * Broadcasts are single route as stated in RFC 1042 @@ -322,7 +324,7 @@ printk("source routing for %02X:%02X:%02X:%02X:%02X:%02X\n",trh->daddr[0], else slack = 18 - ((ntohs(trh->rcf) & TR_RCF_LEN_MASK)>>8); olddata = skb->data; - spin_unlock_bh(&rif_lock); + spin_unlock_irqrestore(&rif_lock, flags); skb_pull(skb, slack); memmove(skb->data, olddata, sizeof(struct trh_hdr) - slack); @@ -336,10 +338,12 @@ printk("source routing for %02X:%02X:%02X:%02X:%02X:%02X\n",trh->daddr[0], static void tr_add_rif_info(struct trh_hdr *trh, struct net_device *dev) { unsigned int hash, rii_p = 0; - struct rif_cache_s *entry; + unsigned long flags; + struct rif_cache *entry; + unsigned char saddr0; - - spin_lock_bh(&rif_lock); + spin_lock_irqsave(&rif_lock, flags); + saddr0 = trh->saddr[0]; /* * Firstly see if the entry exists @@ -372,12 +376,12 @@ printk("adding rif_entry: addr:%02X:%02X:%02X:%02X:%02X:%02X rcf:%04X\n", * FIXME: We ought to keep some kind of cache size * limiting and adjust the timers to suit. */ - entry=kmalloc(sizeof(struct rif_cache_s),GFP_ATOMIC); + entry=kmalloc(sizeof(struct rif_cache),GFP_ATOMIC); if(!entry) { printk(KERN_DEBUG "tr.c: Couldn't malloc rif cache entry !\n"); - spin_unlock_bh(&rif_lock); + spin_unlock_irqrestore(&rif_lock, flags); return; } @@ -392,7 +396,6 @@ printk("adding rif_entry: addr:%02X:%02X:%02X:%02X:%02X:%02X rcf:%04X\n", entry->rcf = trh->rcf & htons((unsigned short)~TR_RCF_BROADCAST_MASK); memcpy(&(entry->rseg[0]),&(trh->rseg[0]),8*sizeof(unsigned short)); entry->local_ring = 0; - trh->saddr[0]|=TR_RII; /* put the routing indicator back for tcpdump */ } else { @@ -419,7 +422,8 @@ printk("updating rif_entry: addr:%02X:%02X:%02X:%02X:%02X:%02X rcf:%04X\n", } entry->last_used=jiffies; } - spin_unlock_bh(&rif_lock); + trh->saddr[0]=saddr0; /* put the routing indicator back for tcpdump */ + spin_unlock_irqrestore(&rif_lock, flags); } /* @@ -429,12 +433,12 @@ printk("updating rif_entry: addr:%02X:%02X:%02X:%02X:%02X:%02X rcf:%04X\n", static void rif_check_expire(unsigned long dummy) { int i; - unsigned long next_interval = jiffies + sysctl_tr_rif_timeout/2; + unsigned long flags, next_interval = jiffies + sysctl_tr_rif_timeout/2; - spin_lock_bh(&rif_lock); + spin_lock_irqsave(&rif_lock, flags); for(i =0; i < RIF_TABLE_SIZE; i++) { - struct rif_cache_s *entry, **pentry; + struct rif_cache *entry, **pentry; pentry = rif_table+i; while((entry=*pentry) != NULL) { @@ -453,7 +457,7 @@ static void rif_check_expire(unsigned long dummy) } } - spin_unlock_bh(&rif_lock); + spin_unlock_irqrestore(&rif_lock, flags); mod_timer(&rif_timer, next_interval); @@ -466,10 +470,10 @@ static void rif_check_expire(unsigned long dummy) #ifdef CONFIG_PROC_FS -static struct rif_cache_s *rif_get_idx(loff_t pos) +static struct rif_cache *rif_get_idx(loff_t pos) { int i; - struct rif_cache_s *entry; + struct rif_cache *entry; loff_t off = 0; for(i = 0; i < RIF_TABLE_SIZE; i++) @@ -484,7 +488,7 @@ static struct rif_cache_s *rif_get_idx(loff_t pos) static void *rif_seq_start(struct seq_file *seq, loff_t *pos) { - spin_lock_bh(&rif_lock); + spin_lock_irq(&rif_lock); return *pos ? rif_get_idx(*pos - 1) : SEQ_START_TOKEN; } @@ -492,7 +496,7 @@ static void *rif_seq_start(struct seq_file *seq, loff_t *pos) static void *rif_seq_next(struct seq_file *seq, void *v, loff_t *pos) { int i; - struct rif_cache_s *ent = v; + struct rif_cache *ent = v; ++*pos; @@ -515,13 +519,13 @@ static void *rif_seq_next(struct seq_file *seq, void *v, loff_t *pos) static void rif_seq_stop(struct seq_file *seq, void *v) { - spin_unlock_bh(&rif_lock); + spin_unlock_irq(&rif_lock); } static int rif_seq_show(struct seq_file *seq, void *v) { int j, rcf_len, segment, brdgnmb; - struct rif_cache_s *entry = v; + struct rif_cache *entry = v; if (v == SEQ_START_TOKEN) seq_puts(seq, @@ -583,6 +587,43 @@ static struct file_operations rif_seq_fops = { #endif +static void tr_setup(struct net_device *dev) +{ + /* + * Configure and register + */ + + dev->hard_header = tr_header; + dev->rebuild_header = tr_rebuild_header; + + dev->type = ARPHRD_IEEE802_TR; + dev->hard_header_len = TR_HLEN; + dev->mtu = 2000; + dev->addr_len = TR_ALEN; + dev->tx_queue_len = 100; /* Long queues on tr */ + + memset(dev->broadcast,0xFF, TR_ALEN); + + /* New-style flags. */ + dev->flags = IFF_BROADCAST | IFF_MULTICAST ; +} + +/** + * alloc_trdev - Register token ring device + * @sizeof_priv: Size of additional driver-private structure to be allocated + * for this token ring device + * + * Fill in the fields of the device structure with token ring-generic values. + * + * Constructs a new net device, complete with a private data area of + * size @sizeof_priv. A 32-byte (not bit) alignment is enforced for + * this private data area. + */ +struct net_device *alloc_trdev(int sizeof_priv) +{ + return alloc_netdev(sizeof_priv, "tr%d", tr_setup); +} + /* * Called during bootup. We don't actually have to initialise * too much for this. @@ -602,5 +643,5 @@ static int __init rif_init(void) module_init(rif_init); -EXPORT_SYMBOL(tr_source_route); EXPORT_SYMBOL(tr_type_trans); +EXPORT_SYMBOL(alloc_trdev);