#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/init.h>
+#include <linux/sysctl.h>
#include <net/arp.h>
+#include <net/net_namespace.h>
static void tr_add_rif_info(struct trh_hdr *trh, struct net_device *dev);
static void rif_check_expire(unsigned long dummy);
static struct timer_list rif_timer;
-int sysctl_tr_rif_timeout = 60*10*HZ;
+static int sysctl_tr_rif_timeout = 60*10*HZ;
static inline unsigned long rif_hash(const unsigned char *addr)
{
static int tr_header(struct sk_buff *skb, struct net_device *dev,
unsigned short type,
- void *daddr, void *saddr, unsigned len)
+ const void *daddr, const void *saddr, unsigned len)
{
struct trh_hdr *trh;
int hdr_len;
if(daddr)
{
memcpy(trh->daddr,daddr,dev->addr_len);
- tr_source_route(skb,trh,dev);
+ tr_source_route(skb, trh, dev);
return(hdr_len);
}
struct trllc *trllc;
unsigned riflen=0;
- skb->mac.raw = skb->data;
+ skb->dev = dev;
+ skb_reset_mac_header(skb);
trh = tr_hdr(skb);
if(trh->saddr[0] & TR_RII)
* We try to do source routing...
*/
-void tr_source_route(struct sk_buff *skb,struct trh_hdr *trh,struct net_device *dev)
+void tr_source_route(struct sk_buff *skb,struct trh_hdr *trh,
+ struct net_device *dev)
{
int slack;
unsigned int hash;
if(entry)
{
#if TR_SR_DEBUG
-printk("source routing for %02X:%02X:%02X:%02X:%02X:%02X\n",trh->daddr[0],
- trh->daddr[1],trh->daddr[2],trh->daddr[3],trh->daddr[4],trh->daddr[5]);
+printk("source routing for %pM\n", trh->daddr);
#endif
if(!entry->local_ring && (ntohs(entry->rcf) & TR_RCF_LEN_MASK) >> 8)
{
if(entry==NULL)
{
#if TR_SR_DEBUG
-printk("adding rif_entry: addr:%02X:%02X:%02X:%02X:%02X:%02X rcf:%04X\n",
- trh->saddr[0],trh->saddr[1],trh->saddr[2],
- trh->saddr[3],trh->saddr[4],trh->saddr[5],
- ntohs(trh->rcf));
+ printk("adding rif_entry: addr:%pM rcf:%04X\n",
+ trh->saddr, ntohs(trh->rcf));
#endif
/*
* Allocate our new entry. A failure to allocate loses
!(trh->rcf & htons(TR_RCF_BROADCAST_MASK)))
{
#if TR_SR_DEBUG
-printk("updating rif_entry: addr:%02X:%02X:%02X:%02X:%02X:%02X rcf:%04X\n",
- trh->saddr[0],trh->saddr[1],trh->saddr[2],
- trh->saddr[3],trh->saddr[4],trh->saddr[5],
- ntohs(trh->rcf));
+printk("updating rif_entry: addr:%pM rcf:%04X\n",
+ trh->saddr, ntohs(trh->rcf));
#endif
entry->rcf = trh->rcf & htons((unsigned short)~TR_RCF_BROADCAST_MASK);
memcpy(&(entry->rseg[0]),&(trh->rseg[0]),8*sizeof(unsigned short));
}
static void *rif_seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(&rif_lock)
{
spin_lock_irq(&rif_lock);
}
static void rif_seq_stop(struct seq_file *seq, void *v)
+ __releases(&rif_lock)
{
spin_unlock_irq(&rif_lock);
}
seq_puts(seq,
"if TR address TTL rcf routing segments\n");
else {
- struct net_device *dev = dev_get_by_index(entry->iface);
+ struct net_device *dev = dev_get_by_index(&init_net, entry->iface);
long ttl = (long) (entry->last_used + sysctl_tr_rif_timeout)
- (long) jiffies;
- seq_printf(seq, "%s %02X:%02X:%02X:%02X:%02X:%02X %7li ",
+ seq_printf(seq, "%s %pM %7li ",
dev?dev->name:"?",
- entry->addr[0],entry->addr[1],entry->addr[2],
- entry->addr[3],entry->addr[4],entry->addr[5],
+ entry->addr,
ttl/HZ);
if (entry->local_ring)
if(j==1) {
segment=ntohs(entry->rseg[j-1])>>4;
seq_printf(seq," %03X",segment);
- };
+ }
+
segment=ntohs(entry->rseg[j])>>4;
brdgnmb=ntohs(entry->rseg[j-1])&0x00f;
seq_printf(seq,"-%01X-%03X",brdgnmb,segment);
}
seq_putc(seq, '\n');
}
+
+ if (dev)
+ dev_put(dev);
}
return 0;
}
-static struct seq_operations rif_seq_ops = {
+static const struct seq_operations rif_seq_ops = {
.start = rif_seq_start,
.next = rif_seq_next,
.stop = rif_seq_stop,
#endif
+static const struct header_ops tr_header_ops = {
+ .create = tr_header,
+ .rebuild= tr_rebuild_header,
+};
+
static void tr_setup(struct net_device *dev)
{
/*
* Configure and register
*/
- dev->hard_header = tr_header;
- dev->rebuild_header = tr_rebuild_header;
+ dev->header_ops = &tr_header_ops;
dev->type = ARPHRD_IEEE802_TR;
dev->hard_header_len = TR_HLEN;
return alloc_netdev(sizeof_priv, "tr%d", tr_setup);
}
+#ifdef CONFIG_SYSCTL
+static struct ctl_table tr_table[] = {
+ {
+ .procname = "rif_timeout",
+ .data = &sysctl_tr_rif_timeout,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec
+ },
+ { },
+};
+
+static __initdata struct ctl_path tr_path[] = {
+ { .procname = "net", },
+ { .procname = "token-ring", },
+ { }
+};
+#endif
+
/*
* Called during bootup. We don't actually have to initialise
* too much for this.
static int __init rif_init(void)
{
- init_timer(&rif_timer);
- rif_timer.expires = sysctl_tr_rif_timeout;
- rif_timer.data = 0L;
- rif_timer.function = rif_check_expire;
+ rif_timer.expires = jiffies + sysctl_tr_rif_timeout;
+ setup_timer(&rif_timer, rif_check_expire, 0);
add_timer(&rif_timer);
-
- proc_net_fops_create("tr_rif", S_IRUGO, &rif_seq_fops);
+#ifdef CONFIG_SYSCTL
+ register_sysctl_paths(tr_path, tr_table);
+#endif
+ proc_net_fops_create(&init_net, "tr_rif", S_IRUGO, &rif_seq_fops);
return 0;
}
EXPORT_SYMBOL(tr_type_trans);
EXPORT_SYMBOL(alloc_trdev);
+
+MODULE_LICENSE("GPL");