2 * NET3: Token ring device handling subroutines
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
9 * Fixes: 3 Feb 97 Paul Norton <pnorton@cts.com> Minor routing fixes.
10 * Added rif table to /proc/net/tr_rif and rif timeout to
11 * /proc/sys/net/token-ring/rif_timeout.
12 * 22 Jun 98 Paul Norton <p.norton@computer.org> Rearranged
13 * tr_header and tr_type_trans to handle passing IPX SNAP and
14 * 802.2 through the correct layers. Eliminated tr_reformat.
18 #include <asm/uaccess.h>
19 #include <asm/system.h>
20 #include <linux/config.h>
21 #include <linux/types.h>
22 #include <linux/kernel.h>
23 #include <linux/sched.h>
24 #include <linux/string.h>
26 #include <linux/socket.h>
28 #include <linux/inet.h>
29 #include <linux/netdevice.h>
30 #include <linux/trdevice.h>
31 #include <linux/skbuff.h>
32 #include <linux/errno.h>
33 #include <linux/timer.h>
34 #include <linux/net.h>
35 #include <linux/proc_fs.h>
36 #include <linux/init.h>
39 static void tr_source_route(struct sk_buff
*skb
, struct trh_hdr
*trh
, struct device
*dev
);
40 static void tr_add_rif_info(struct trh_hdr
*trh
, struct device
*dev
);
41 static void rif_check_expire(unsigned long dummy
);
45 typedef struct rif_cache_s
*rif_cache
;
48 * Each RIF entry we learn is kept this way
52 unsigned char addr
[TR_ALEN
];
53 unsigned char iface
[5];
57 unsigned long last_used
;
58 unsigned char local_ring
;
61 #define RIF_TABLE_SIZE 32
64 * We hash the RIF cache 32 ways. We do after all have to look it
68 rif_cache rif_table
[RIF_TABLE_SIZE
]={ NULL
, };
70 static spinlock_t rif_lock
= SPIN_LOCK_UNLOCKED
;
72 #define RIF_TIMEOUT 60*10*HZ
73 #define RIF_CHECK_INTERVAL 60*HZ
76 * Garbage disposal timer.
79 static struct timer_list rif_timer
;
81 int sysctl_tr_rif_timeout
= RIF_TIMEOUT
;
84 * Put the headers on a token ring packet. Token ring source routing
85 * makes this a little more exciting than on ethernet.
88 int tr_header(struct sk_buff
*skb
, struct device
*dev
, unsigned short type
,
89 void *daddr
, void *saddr
, unsigned len
)
95 * Add the 802.2 SNAP header if IP as the IPv4 code calls
96 * dev->hard_header directly.
98 if (type
== ETH_P_IP
|| type
== ETH_P_ARP
)
100 struct trllc
*trllc
=(struct trllc
*)(trh
+1);
102 hdr_len
= sizeof(struct trh_hdr
) + sizeof(struct trllc
);
103 trh
= (struct trh_hdr
*)skb_push(skb
, hdr_len
);
104 trllc
= (struct trllc
*)(trh
+1);
105 trllc
->dsap
= trllc
->ssap
= EXTENDED_SAP
;
107 trllc
->protid
[0] = trllc
->protid
[1] = trllc
->protid
[2] = 0x00;
108 trllc
->ethertype
= htons(type
);
112 hdr_len
= sizeof(struct trh_hdr
);
113 trh
= (struct trh_hdr
*)skb_push(skb
, hdr_len
);
120 memcpy(trh
->saddr
,saddr
,dev
->addr_len
);
122 memcpy(trh
->saddr
,dev
->dev_addr
,dev
->addr_len
);
125 * Build the destination and then source route the frame
130 memcpy(trh
->daddr
,daddr
,dev
->addr_len
);
131 tr_source_route(skb
,trh
,dev
);
139 * A neighbour discovery of some species (eg arp) has completed. We
140 * can now send the packet.
143 int tr_rebuild_header(struct sk_buff
*skb
)
145 struct trh_hdr
*trh
=(struct trh_hdr
*)skb
->data
;
146 struct trllc
*trllc
=(struct trllc
*)(skb
->data
+sizeof(struct trh_hdr
));
147 struct device
*dev
= skb
->dev
;
150 * FIXME: We don't yet support IPv6 over token rings
153 if(trllc
->ethertype
!= htons(ETH_P_IP
)) {
154 printk("tr_rebuild_header: Don't know how to resolve type %04X addresses ?\n",(unsigned int)htons(trllc
->ethertype
));
159 if(arp_find(trh
->daddr
, skb
)) {
165 tr_source_route(skb
,trh
,dev
);
171 * Some of this is a bit hackish. We intercept RIF information
172 * used for source routing. We also grab IP directly and don't feed
176 unsigned short tr_type_trans(struct sk_buff
*skb
, struct device
*dev
)
179 struct trh_hdr
*trh
=(struct trh_hdr
*)skb
->data
;
183 skb
->mac
.raw
= skb
->data
;
185 if(trh
->saddr
[0] & TR_RII
)
186 riflen
= (ntohs(trh
->rcf
) & TR_RCF_LEN_MASK
) >> 8;
188 trllc
= (struct trllc
*)(skb
->data
+sizeof(struct trh_hdr
)-TR_MAXRIFLEN
+riflen
);
190 skb_pull(skb
,sizeof(struct trh_hdr
)-TR_MAXRIFLEN
+riflen
);
192 tr_add_rif_info(trh
, dev
);
196 if(!memcmp(trh
->daddr
,dev
->broadcast
,TR_ALEN
))
197 skb
->pkt_type
=PACKET_BROADCAST
;
199 skb
->pkt_type
=PACKET_MULTICAST
;
202 else if(dev
->flags
& IFF_PROMISC
)
204 if(memcmp(trh
->daddr
, dev
->dev_addr
, TR_ALEN
))
205 skb
->pkt_type
=PACKET_OTHERHOST
;
209 * Strip the SNAP header from ARP packets since we don't
210 * pass them through to the 802.2/SNAP layers.
213 if (trllc
->dsap
== EXTENDED_SAP
&&
214 (trllc
->ethertype
== ntohs(ETH_P_IP
) ||
215 trllc
->ethertype
== ntohs(ETH_P_ARP
)))
217 skb_pull(skb
, sizeof(struct trllc
));
218 return trllc
->ethertype
;
221 return ntohs(ETH_P_802_2
);
225 * We try to do source routing...
228 static void tr_source_route(struct sk_buff
*skb
,struct trh_hdr
*trh
,struct device
*dev
)
233 unsigned char *olddata
;
236 spin_lock_irqsave(&rif_lock
, flags
);
239 * Broadcasts are single route as stated in RFC 1042
241 if(!memcmp(&(trh
->daddr
[0]),&(dev
->broadcast
[0]),TR_ALEN
))
243 trh
->rcf
=htons((((sizeof(trh
->rcf
)) << 8) & TR_RCF_LEN_MASK
)
244 | TR_RCF_FRAME2K
| TR_RCF_LIMITED_BROADCAST
);
245 trh
->saddr
[0]|=TR_RII
;
249 for(i
=0,hash
=0;i
<TR_ALEN
;hash
+=trh
->daddr
[i
++]);
250 hash
&=RIF_TABLE_SIZE
-1;
252 * Walk the hash table and look for an entry
254 for(entry
=rif_table
[hash
];entry
&& memcmp(&(entry
->addr
[0]),&(trh
->daddr
[0]),TR_ALEN
);entry
=entry
->next
);
257 * If we found an entry we can route the frame.
262 printk("source routing for %02X %02X %02X %02X %02X %02X\n",trh
->daddr
[0],
263 trh
->daddr
[1],trh
->daddr
[2],trh
->daddr
[3],trh
->daddr
[4],trh
->daddr
[5]);
265 if(!entry
->local_ring
&& (ntohs(entry
->rcf
) & TR_RCF_LEN_MASK
) >> 8)
268 memcpy(&trh
->rseg
[0],&entry
->rseg
[0],8*sizeof(unsigned short));
269 trh
->rcf
^=htons(TR_RCF_DIR_BIT
);
270 trh
->rcf
&=htons(0x1fff); /* Issam Chehab <ichehab@madge1.demon.co.uk> */
272 trh
->saddr
[0]|=TR_RII
;
274 printk("entry found with rcf %04x\n", entry
->rcf
);
278 printk("entry found but without rcf length, local=%02x\n", entry
->local_ring
);
281 entry
->last_used
=jiffies
;
286 * Without the information we simply have to shout
287 * on the wire. The replies should rapidly clean this
290 trh
->rcf
=htons((((sizeof(trh
->rcf
)) << 8) & TR_RCF_LEN_MASK
)
291 | TR_RCF_FRAME2K
| TR_RCF_LIMITED_BROADCAST
);
292 trh
->saddr
[0]|=TR_RII
;
294 printk("no entry in rif table found - broadcasting frame\n");
299 /* Compress the RIF here so we don't have to do it in the driver(s) */
300 if (!(trh
->saddr
[0] & 0x80))
303 slack
= 18 - ((ntohs(trh
->rcf
) & TR_RCF_LEN_MASK
)>>8);
305 spin_unlock_irqrestore(&rif_lock
, flags
);
307 skb_pull(skb
, slack
);
308 memmove(skb
->data
, olddata
, sizeof(struct trh_hdr
) - slack
);
312 * We have learned some new RIF information for our source
316 static void tr_add_rif_info(struct trh_hdr
*trh
, struct device
*dev
)
319 unsigned int hash
, rii_p
= 0;
324 spin_lock_irqsave(&rif_lock
, flags
);
327 * Firstly see if the entry exists
330 if(trh
->saddr
[0] & TR_RII
)
333 if (((ntohs(trh
->rcf
) & TR_RCF_LEN_MASK
) >> 8) > 2)
339 for(i
=0,hash
=0;i
<TR_ALEN
;hash
+=trh
->saddr
[i
++]);
340 hash
&=RIF_TABLE_SIZE
-1;
341 for(entry
=rif_table
[hash
];entry
&& memcmp(&(entry
->addr
[0]),&(trh
->saddr
[0]),TR_ALEN
);entry
=entry
->next
);
346 printk("adding rif_entry: addr:%02X:%02X:%02X:%02X:%02X:%02X rcf:%04X\n",
347 trh
->saddr
[0],trh
->saddr
[1],trh
->saddr
[2],
348 trh
->saddr
[3],trh
->saddr
[4],trh
->saddr
[5],
352 * Allocate our new entry. A failure to allocate loses
353 * use the information. This is harmless.
355 * FIXME: We ought to keep some kind of cache size
356 * limiting and adjust the timers to suit.
358 entry
=kmalloc(sizeof(struct rif_cache_s
),GFP_ATOMIC
);
362 printk(KERN_DEBUG
"tr.c: Couldn't malloc rif cache entry !\n");
363 spin_unlock_irqrestore(&rif_lock
, flags
);
367 memcpy(&(entry
->addr
[0]),&(trh
->saddr
[0]),TR_ALEN
);
368 memcpy(&(entry
->iface
[0]),dev
->name
,5);
369 entry
->next
=rif_table
[hash
];
370 entry
->last_used
=jiffies
;
371 rif_table
[hash
]=entry
;
375 entry
->rcf
= trh
->rcf
& htons((unsigned short)~TR_RCF_BROADCAST_MASK
);
376 memcpy(&(entry
->rseg
[0]),&(trh
->rseg
[0]),8*sizeof(unsigned short));
377 entry
->local_ring
= 0;
378 trh
->saddr
[0]|=TR_RII
; /* put the routing indicator back for tcpdump */
382 entry
->local_ring
= 1;
385 else /* Y. Tahara added */
388 * Update existing entries
390 if (!entry
->local_ring
)
391 if (entry
->rcf
!= (trh
->rcf
& htons((unsigned short)~TR_RCF_BROADCAST_MASK
)) &&
392 !(trh
->rcf
& htons(TR_RCF_BROADCAST_MASK
)))
395 printk("updating rif_entry: addr:%02X:%02X:%02X:%02X:%02X:%02X rcf:%04X\n",
396 trh
->saddr
[0],trh
->saddr
[1],trh
->saddr
[2],
397 trh
->saddr
[3],trh
->saddr
[4],trh
->saddr
[5],
400 entry
->rcf
= trh
->rcf
& htons((unsigned short)~TR_RCF_BROADCAST_MASK
);
401 memcpy(&(entry
->rseg
[0]),&(trh
->rseg
[0]),8*sizeof(unsigned short));
403 entry
->last_used
=jiffies
;
405 spin_unlock_irqrestore(&rif_lock
, flags
);
409 * Scan the cache with a timer and see what we need to throw out.
412 static void rif_check_expire(unsigned long dummy
)
415 unsigned long now
=jiffies
,flags
;
417 spin_lock_irqsave(&rif_lock
, flags
);
419 for(i
=0; i
< RIF_TABLE_SIZE
;i
++)
421 rif_cache entry
, *pentry
=rif_table
+i
;
422 while((entry
=*pentry
))
427 if((now
-entry
->last_used
) > sysctl_tr_rif_timeout
)
430 kfree_s(entry
,sizeof(struct rif_cache_s
));
437 spin_unlock_irqrestore(&rif_lock
, flags
);
443 del_timer(&rif_timer
);
444 rif_timer
.expires
= jiffies
+ sysctl_tr_rif_timeout
;
445 add_timer(&rif_timer
);
450 * Generate the /proc/net information for the token ring RIF
454 #ifdef CONFIG_PROC_FS
455 int rif_get_info(char *buffer
,char **start
, off_t offset
, int length
, int dummy
)
460 int size
,i
,j
,rcf_len
,segment
,brdgnmb
;
461 unsigned long now
=jiffies
;
466 "if TR address TTL rcf routing segments\n");
470 for(i
=0;i
< RIF_TABLE_SIZE
;i
++)
472 for(entry
=rif_table
[i
];entry
;entry
=entry
->next
) {
473 size
=sprintf(buffer
+len
,"%s %02X:%02X:%02X:%02X:%02X:%02X %7li ",
474 entry
->iface
,entry
->addr
[0],entry
->addr
[1],entry
->addr
[2],entry
->addr
[3],entry
->addr
[4],entry
->addr
[5],
475 sysctl_tr_rif_timeout
-(now
-entry
->last_used
));
478 if (entry
->local_ring
)
479 size
=sprintf(buffer
+len
,"local\n");
481 size
=sprintf(buffer
+len
,"%04X", ntohs(entry
->rcf
));
482 rcf_len
= ((ntohs(entry
->rcf
) & TR_RCF_LEN_MASK
)>>8)-2;
485 for(j
= 1; j
< rcf_len
; j
++) {
487 segment
=ntohs(entry
->rseg
[j
-1])>>4;
490 size
=sprintf(buffer
+len
," %03X",segment
);
492 segment
=ntohs(entry
->rseg
[j
])>>4;
493 brdgnmb
=ntohs(entry
->rseg
[j
-1])&0x00f;
496 size
=sprintf(buffer
+len
,"-%01X-%03X",brdgnmb
,segment
);
500 size
=sprintf(buffer
+len
,"\n");
510 if(pos
>offset
+length
)
513 if(pos
>offset
+length
)
517 *start
=buffer
+(offset
-begin
); /* Start of wanted data */
518 len
-=(offset
-begin
); /* Start slop */
520 len
=length
; /* Ending slop */
526 * Called during bootup. We don't actually have to initialise
530 #ifdef CONFIG_PROC_FS
531 static struct proc_dir_entry tr_rif_proc
= {
532 PROC_NET_TR_RIF
, 6, "tr_rif",
533 S_IFREG
| S_IRUGO
, 1, 0, 0,
534 0, &proc_net_inode_operations
,
539 __initfunc(void rif_init(struct net_proto
*unused
))
541 rif_timer
.expires
= RIF_TIMEOUT
;
543 rif_timer
.function
= rif_check_expire
;
544 init_timer(&rif_timer
);
545 add_timer(&rif_timer
);
547 #ifdef CONFIG_PROC_FS
548 proc_net_register(&tr_rif_proc
);