at v2.6.24-rc2 1490 lines 34 kB view raw
1/* 2 * DECnet An implementation of the DECnet protocol suite for the LINUX 3 * operating system. DECnet is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * DECnet Device Layer 7 * 8 * Authors: Steve Whitehouse <SteveW@ACM.org> 9 * Eduardo Marcelo Serrat <emserrat@geocities.com> 10 * 11 * Changes: 12 * Steve Whitehouse : Devices now see incoming frames so they 13 * can mark on who it came from. 14 * Steve Whitehouse : Fixed bug in creating neighbours. Each neighbour 15 * can now have a device specific setup func. 16 * Steve Whitehouse : Added /proc/sys/net/decnet/conf/<dev>/ 17 * Steve Whitehouse : Fixed bug which sometimes killed timer 18 * Steve Whitehouse : Multiple ifaddr support 19 * Steve Whitehouse : SIOCGIFCONF is now a compile time option 20 * Steve Whitehouse : /proc/sys/net/decnet/conf/<sys>/forwarding 21 * Steve Whitehouse : Removed timer1 - it's a user space issue now 22 * Patrick Caulfield : Fixed router hello message format 23 * Steve Whitehouse : Got rid of constant sizes for blksize for 24 * devices. All mtu based now. 25 */ 26 27#include <linux/capability.h> 28#include <linux/module.h> 29#include <linux/moduleparam.h> 30#include <linux/init.h> 31#include <linux/net.h> 32#include <linux/netdevice.h> 33#include <linux/proc_fs.h> 34#include <linux/seq_file.h> 35#include <linux/timer.h> 36#include <linux/string.h> 37#include <linux/if_addr.h> 38#include <linux/if_arp.h> 39#include <linux/if_ether.h> 40#include <linux/skbuff.h> 41#include <linux/sysctl.h> 42#include <linux/notifier.h> 43#include <asm/uaccess.h> 44#include <asm/system.h> 45#include <net/net_namespace.h> 46#include <net/neighbour.h> 47#include <net/dst.h> 48#include <net/flow.h> 49#include <net/fib_rules.h> 50#include <net/netlink.h> 51#include <net/dn.h> 52#include <net/dn_dev.h> 53#include <net/dn_route.h> 54#include <net/dn_neigh.h> 55#include <net/dn_fib.h> 56 57#define DN_IFREQ_SIZE (sizeof(struct ifreq) - sizeof(struct sockaddr) + sizeof(struct sockaddr_dn)) 58 59static char dn_rt_all_end_mcast[ETH_ALEN] = {0xAB,0x00,0x00,0x04,0x00,0x00}; 60static char dn_rt_all_rt_mcast[ETH_ALEN] = {0xAB,0x00,0x00,0x03,0x00,0x00}; 61static char dn_hiord[ETH_ALEN] = {0xAA,0x00,0x04,0x00,0x00,0x00}; 62static unsigned char dn_eco_version[3] = {0x02,0x00,0x00}; 63 64extern struct neigh_table dn_neigh_table; 65 66/* 67 * decnet_address is kept in network order. 68 */ 69__le16 decnet_address = 0; 70 71static DEFINE_RWLOCK(dndev_lock); 72static struct net_device *decnet_default_device; 73static BLOCKING_NOTIFIER_HEAD(dnaddr_chain); 74 75static struct dn_dev *dn_dev_create(struct net_device *dev, int *err); 76static void dn_dev_delete(struct net_device *dev); 77static void dn_ifaddr_notify(int event, struct dn_ifaddr *ifa); 78 79static int dn_eth_up(struct net_device *); 80static void dn_eth_down(struct net_device *); 81static void dn_send_brd_hello(struct net_device *dev, struct dn_ifaddr *ifa); 82static void dn_send_ptp_hello(struct net_device *dev, struct dn_ifaddr *ifa); 83 84static struct dn_dev_parms dn_dev_list[] = { 85{ 86 .type = ARPHRD_ETHER, /* Ethernet */ 87 .mode = DN_DEV_BCAST, 88 .state = DN_DEV_S_RU, 89 .t2 = 1, 90 .t3 = 10, 91 .name = "ethernet", 92 .ctl_name = NET_DECNET_CONF_ETHER, 93 .up = dn_eth_up, 94 .down = dn_eth_down, 95 .timer3 = dn_send_brd_hello, 96}, 97{ 98 .type = ARPHRD_IPGRE, /* DECnet tunneled over GRE in IP */ 99 .mode = DN_DEV_BCAST, 100 .state = DN_DEV_S_RU, 101 .t2 = 1, 102 .t3 = 10, 103 .name = "ipgre", 104 .ctl_name = NET_DECNET_CONF_GRE, 105 .timer3 = dn_send_brd_hello, 106}, 107#if 0 108{ 109 .type = ARPHRD_X25, /* Bog standard X.25 */ 110 .mode = DN_DEV_UCAST, 111 .state = DN_DEV_S_DS, 112 .t2 = 1, 113 .t3 = 120, 114 .name = "x25", 115 .ctl_name = NET_DECNET_CONF_X25, 116 .timer3 = dn_send_ptp_hello, 117}, 118#endif 119#if 0 120{ 121 .type = ARPHRD_PPP, /* DECnet over PPP */ 122 .mode = DN_DEV_BCAST, 123 .state = DN_DEV_S_RU, 124 .t2 = 1, 125 .t3 = 10, 126 .name = "ppp", 127 .ctl_name = NET_DECNET_CONF_PPP, 128 .timer3 = dn_send_brd_hello, 129}, 130#endif 131{ 132 .type = ARPHRD_DDCMP, /* DECnet over DDCMP */ 133 .mode = DN_DEV_UCAST, 134 .state = DN_DEV_S_DS, 135 .t2 = 1, 136 .t3 = 120, 137 .name = "ddcmp", 138 .ctl_name = NET_DECNET_CONF_DDCMP, 139 .timer3 = dn_send_ptp_hello, 140}, 141{ 142 .type = ARPHRD_LOOPBACK, /* Loopback interface - always last */ 143 .mode = DN_DEV_BCAST, 144 .state = DN_DEV_S_RU, 145 .t2 = 1, 146 .t3 = 10, 147 .name = "loopback", 148 .ctl_name = NET_DECNET_CONF_LOOPBACK, 149 .timer3 = dn_send_brd_hello, 150} 151}; 152 153#define DN_DEV_LIST_SIZE ARRAY_SIZE(dn_dev_list) 154 155#define DN_DEV_PARMS_OFFSET(x) ((int) ((char *) &((struct dn_dev_parms *)0)->x)) 156 157#ifdef CONFIG_SYSCTL 158 159static int min_t2[] = { 1 }; 160static int max_t2[] = { 60 }; /* No max specified, but this seems sensible */ 161static int min_t3[] = { 1 }; 162static int max_t3[] = { 8191 }; /* Must fit in 16 bits when multiplied by BCT3MULT or T3MULT */ 163 164static int min_priority[1]; 165static int max_priority[] = { 127 }; /* From DECnet spec */ 166 167static int dn_forwarding_proc(ctl_table *, int, struct file *, 168 void __user *, size_t *, loff_t *); 169static int dn_forwarding_sysctl(ctl_table *table, int __user *name, int nlen, 170 void __user *oldval, size_t __user *oldlenp, 171 void __user *newval, size_t newlen); 172 173static struct dn_dev_sysctl_table { 174 struct ctl_table_header *sysctl_header; 175 ctl_table dn_dev_vars[5]; 176 ctl_table dn_dev_dev[2]; 177 ctl_table dn_dev_conf_dir[2]; 178 ctl_table dn_dev_proto_dir[2]; 179 ctl_table dn_dev_root_dir[2]; 180} dn_dev_sysctl = { 181 NULL, 182 { 183 { 184 .ctl_name = NET_DECNET_CONF_DEV_FORWARDING, 185 .procname = "forwarding", 186 .data = (void *)DN_DEV_PARMS_OFFSET(forwarding), 187 .maxlen = sizeof(int), 188 .mode = 0644, 189 .proc_handler = dn_forwarding_proc, 190 .strategy = dn_forwarding_sysctl, 191 }, 192 { 193 .ctl_name = NET_DECNET_CONF_DEV_PRIORITY, 194 .procname = "priority", 195 .data = (void *)DN_DEV_PARMS_OFFSET(priority), 196 .maxlen = sizeof(int), 197 .mode = 0644, 198 .proc_handler = proc_dointvec_minmax, 199 .strategy = sysctl_intvec, 200 .extra1 = &min_priority, 201 .extra2 = &max_priority 202 }, 203 { 204 .ctl_name = NET_DECNET_CONF_DEV_T2, 205 .procname = "t2", 206 .data = (void *)DN_DEV_PARMS_OFFSET(t2), 207 .maxlen = sizeof(int), 208 .mode = 0644, 209 .proc_handler = proc_dointvec_minmax, 210 .strategy = sysctl_intvec, 211 .extra1 = &min_t2, 212 .extra2 = &max_t2 213 }, 214 { 215 .ctl_name = NET_DECNET_CONF_DEV_T3, 216 .procname = "t3", 217 .data = (void *)DN_DEV_PARMS_OFFSET(t3), 218 .maxlen = sizeof(int), 219 .mode = 0644, 220 .proc_handler = proc_dointvec_minmax, 221 .strategy = sysctl_intvec, 222 .extra1 = &min_t3, 223 .extra2 = &max_t3 224 }, 225 {0} 226 }, 227 {{ 228 .ctl_name = 0, 229 .procname = "", 230 .mode = 0555, 231 .child = dn_dev_sysctl.dn_dev_vars 232 }, {0}}, 233 {{ 234 .ctl_name = NET_DECNET_CONF, 235 .procname = "conf", 236 .mode = 0555, 237 .child = dn_dev_sysctl.dn_dev_dev 238 }, {0}}, 239 {{ 240 .ctl_name = NET_DECNET, 241 .procname = "decnet", 242 .mode = 0555, 243 .child = dn_dev_sysctl.dn_dev_conf_dir 244 }, {0}}, 245 {{ 246 .ctl_name = CTL_NET, 247 .procname = "net", 248 .mode = 0555, 249 .child = dn_dev_sysctl.dn_dev_proto_dir 250 }, {0}} 251}; 252 253static void dn_dev_sysctl_register(struct net_device *dev, struct dn_dev_parms *parms) 254{ 255 struct dn_dev_sysctl_table *t; 256 int i; 257 258 t = kmemdup(&dn_dev_sysctl, sizeof(*t), GFP_KERNEL); 259 if (t == NULL) 260 return; 261 262 for(i = 0; i < ARRAY_SIZE(t->dn_dev_vars) - 1; i++) { 263 long offset = (long)t->dn_dev_vars[i].data; 264 t->dn_dev_vars[i].data = ((char *)parms) + offset; 265 } 266 267 if (dev) { 268 t->dn_dev_dev[0].procname = dev->name; 269 t->dn_dev_dev[0].ctl_name = dev->ifindex; 270 } else { 271 t->dn_dev_dev[0].procname = parms->name; 272 t->dn_dev_dev[0].ctl_name = parms->ctl_name; 273 } 274 275 t->dn_dev_dev[0].child = t->dn_dev_vars; 276 t->dn_dev_conf_dir[0].child = t->dn_dev_dev; 277 t->dn_dev_proto_dir[0].child = t->dn_dev_conf_dir; 278 t->dn_dev_root_dir[0].child = t->dn_dev_proto_dir; 279 t->dn_dev_vars[0].extra1 = (void *)dev; 280 281 t->sysctl_header = register_sysctl_table(t->dn_dev_root_dir); 282 if (t->sysctl_header == NULL) 283 kfree(t); 284 else 285 parms->sysctl = t; 286} 287 288static void dn_dev_sysctl_unregister(struct dn_dev_parms *parms) 289{ 290 if (parms->sysctl) { 291 struct dn_dev_sysctl_table *t = parms->sysctl; 292 parms->sysctl = NULL; 293 unregister_sysctl_table(t->sysctl_header); 294 kfree(t); 295 } 296} 297 298static int dn_forwarding_proc(ctl_table *table, int write, 299 struct file *filep, 300 void __user *buffer, 301 size_t *lenp, loff_t *ppos) 302{ 303#ifdef CONFIG_DECNET_ROUTER 304 struct net_device *dev = table->extra1; 305 struct dn_dev *dn_db; 306 int err; 307 int tmp, old; 308 309 if (table->extra1 == NULL) 310 return -EINVAL; 311 312 dn_db = dev->dn_ptr; 313 old = dn_db->parms.forwarding; 314 315 err = proc_dointvec(table, write, filep, buffer, lenp, ppos); 316 317 if ((err >= 0) && write) { 318 if (dn_db->parms.forwarding < 0) 319 dn_db->parms.forwarding = 0; 320 if (dn_db->parms.forwarding > 2) 321 dn_db->parms.forwarding = 2; 322 /* 323 * What an ugly hack this is... its works, just. It 324 * would be nice if sysctl/proc were just that little 325 * bit more flexible so I don't have to write a special 326 * routine, or suffer hacks like this - SJW 327 */ 328 tmp = dn_db->parms.forwarding; 329 dn_db->parms.forwarding = old; 330 if (dn_db->parms.down) 331 dn_db->parms.down(dev); 332 dn_db->parms.forwarding = tmp; 333 if (dn_db->parms.up) 334 dn_db->parms.up(dev); 335 } 336 337 return err; 338#else 339 return -EINVAL; 340#endif 341} 342 343static int dn_forwarding_sysctl(ctl_table *table, int __user *name, int nlen, 344 void __user *oldval, size_t __user *oldlenp, 345 void __user *newval, size_t newlen) 346{ 347#ifdef CONFIG_DECNET_ROUTER 348 struct net_device *dev = table->extra1; 349 struct dn_dev *dn_db; 350 int value; 351 352 if (table->extra1 == NULL) 353 return -EINVAL; 354 355 dn_db = dev->dn_ptr; 356 357 if (newval && newlen) { 358 if (newlen != sizeof(int)) 359 return -EINVAL; 360 361 if (get_user(value, (int __user *)newval)) 362 return -EFAULT; 363 if (value < 0) 364 return -EINVAL; 365 if (value > 2) 366 return -EINVAL; 367 368 if (dn_db->parms.down) 369 dn_db->parms.down(dev); 370 dn_db->parms.forwarding = value; 371 if (dn_db->parms.up) 372 dn_db->parms.up(dev); 373 } 374 375 return 0; 376#else 377 return -EINVAL; 378#endif 379} 380 381#else /* CONFIG_SYSCTL */ 382static void dn_dev_sysctl_unregister(struct dn_dev_parms *parms) 383{ 384} 385static void dn_dev_sysctl_register(struct net_device *dev, struct dn_dev_parms *parms) 386{ 387} 388 389#endif /* CONFIG_SYSCTL */ 390 391static inline __u16 mtu2blksize(struct net_device *dev) 392{ 393 u32 blksize = dev->mtu; 394 if (blksize > 0xffff) 395 blksize = 0xffff; 396 397 if (dev->type == ARPHRD_ETHER || 398 dev->type == ARPHRD_PPP || 399 dev->type == ARPHRD_IPGRE || 400 dev->type == ARPHRD_LOOPBACK) 401 blksize -= 2; 402 403 return (__u16)blksize; 404} 405 406static struct dn_ifaddr *dn_dev_alloc_ifa(void) 407{ 408 struct dn_ifaddr *ifa; 409 410 ifa = kzalloc(sizeof(*ifa), GFP_KERNEL); 411 412 return ifa; 413} 414 415static __inline__ void dn_dev_free_ifa(struct dn_ifaddr *ifa) 416{ 417 kfree(ifa); 418} 419 420static void dn_dev_del_ifa(struct dn_dev *dn_db, struct dn_ifaddr **ifap, int destroy) 421{ 422 struct dn_ifaddr *ifa1 = *ifap; 423 unsigned char mac_addr[6]; 424 struct net_device *dev = dn_db->dev; 425 426 ASSERT_RTNL(); 427 428 *ifap = ifa1->ifa_next; 429 430 if (dn_db->dev->type == ARPHRD_ETHER) { 431 if (ifa1->ifa_local != dn_eth2dn(dev->dev_addr)) { 432 dn_dn2eth(mac_addr, ifa1->ifa_local); 433 dev_mc_delete(dev, mac_addr, ETH_ALEN, 0); 434 } 435 } 436 437 dn_ifaddr_notify(RTM_DELADDR, ifa1); 438 blocking_notifier_call_chain(&dnaddr_chain, NETDEV_DOWN, ifa1); 439 if (destroy) { 440 dn_dev_free_ifa(ifa1); 441 442 if (dn_db->ifa_list == NULL) 443 dn_dev_delete(dn_db->dev); 444 } 445} 446 447static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa) 448{ 449 struct net_device *dev = dn_db->dev; 450 struct dn_ifaddr *ifa1; 451 unsigned char mac_addr[6]; 452 453 ASSERT_RTNL(); 454 455 /* Check for duplicates */ 456 for(ifa1 = dn_db->ifa_list; ifa1; ifa1 = ifa1->ifa_next) { 457 if (ifa1->ifa_local == ifa->ifa_local) 458 return -EEXIST; 459 } 460 461 if (dev->type == ARPHRD_ETHER) { 462 if (ifa->ifa_local != dn_eth2dn(dev->dev_addr)) { 463 dn_dn2eth(mac_addr, ifa->ifa_local); 464 dev_mc_add(dev, mac_addr, ETH_ALEN, 0); 465 } 466 } 467 468 ifa->ifa_next = dn_db->ifa_list; 469 dn_db->ifa_list = ifa; 470 471 dn_ifaddr_notify(RTM_NEWADDR, ifa); 472 blocking_notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa); 473 474 return 0; 475} 476 477static int dn_dev_set_ifa(struct net_device *dev, struct dn_ifaddr *ifa) 478{ 479 struct dn_dev *dn_db = dev->dn_ptr; 480 int rv; 481 482 if (dn_db == NULL) { 483 int err; 484 dn_db = dn_dev_create(dev, &err); 485 if (dn_db == NULL) 486 return err; 487 } 488 489 ifa->ifa_dev = dn_db; 490 491 if (dev->flags & IFF_LOOPBACK) 492 ifa->ifa_scope = RT_SCOPE_HOST; 493 494 rv = dn_dev_insert_ifa(dn_db, ifa); 495 if (rv) 496 dn_dev_free_ifa(ifa); 497 return rv; 498} 499 500 501int dn_dev_ioctl(unsigned int cmd, void __user *arg) 502{ 503 char buffer[DN_IFREQ_SIZE]; 504 struct ifreq *ifr = (struct ifreq *)buffer; 505 struct sockaddr_dn *sdn = (struct sockaddr_dn *)&ifr->ifr_addr; 506 struct dn_dev *dn_db; 507 struct net_device *dev; 508 struct dn_ifaddr *ifa = NULL, **ifap = NULL; 509 int ret = 0; 510 511 if (copy_from_user(ifr, arg, DN_IFREQ_SIZE)) 512 return -EFAULT; 513 ifr->ifr_name[IFNAMSIZ-1] = 0; 514 515#ifdef CONFIG_KMOD 516 dev_load(&init_net, ifr->ifr_name); 517#endif 518 519 switch(cmd) { 520 case SIOCGIFADDR: 521 break; 522 case SIOCSIFADDR: 523 if (!capable(CAP_NET_ADMIN)) 524 return -EACCES; 525 if (sdn->sdn_family != AF_DECnet) 526 return -EINVAL; 527 break; 528 default: 529 return -EINVAL; 530 } 531 532 rtnl_lock(); 533 534 if ((dev = __dev_get_by_name(&init_net, ifr->ifr_name)) == NULL) { 535 ret = -ENODEV; 536 goto done; 537 } 538 539 if ((dn_db = dev->dn_ptr) != NULL) { 540 for (ifap = &dn_db->ifa_list; (ifa=*ifap) != NULL; ifap = &ifa->ifa_next) 541 if (strcmp(ifr->ifr_name, ifa->ifa_label) == 0) 542 break; 543 } 544 545 if (ifa == NULL && cmd != SIOCSIFADDR) { 546 ret = -EADDRNOTAVAIL; 547 goto done; 548 } 549 550 switch(cmd) { 551 case SIOCGIFADDR: 552 *((__le16 *)sdn->sdn_nodeaddr) = ifa->ifa_local; 553 goto rarok; 554 555 case SIOCSIFADDR: 556 if (!ifa) { 557 if ((ifa = dn_dev_alloc_ifa()) == NULL) { 558 ret = -ENOBUFS; 559 break; 560 } 561 memcpy(ifa->ifa_label, dev->name, IFNAMSIZ); 562 } else { 563 if (ifa->ifa_local == dn_saddr2dn(sdn)) 564 break; 565 dn_dev_del_ifa(dn_db, ifap, 0); 566 } 567 568 ifa->ifa_local = ifa->ifa_address = dn_saddr2dn(sdn); 569 570 ret = dn_dev_set_ifa(dev, ifa); 571 } 572done: 573 rtnl_unlock(); 574 575 return ret; 576rarok: 577 if (copy_to_user(arg, ifr, DN_IFREQ_SIZE)) 578 ret = -EFAULT; 579 goto done; 580} 581 582struct net_device *dn_dev_get_default(void) 583{ 584 struct net_device *dev; 585 read_lock(&dndev_lock); 586 dev = decnet_default_device; 587 if (dev) { 588 if (dev->dn_ptr) 589 dev_hold(dev); 590 else 591 dev = NULL; 592 } 593 read_unlock(&dndev_lock); 594 return dev; 595} 596 597int dn_dev_set_default(struct net_device *dev, int force) 598{ 599 struct net_device *old = NULL; 600 int rv = -EBUSY; 601 if (!dev->dn_ptr) 602 return -ENODEV; 603 write_lock(&dndev_lock); 604 if (force || decnet_default_device == NULL) { 605 old = decnet_default_device; 606 decnet_default_device = dev; 607 rv = 0; 608 } 609 write_unlock(&dndev_lock); 610 if (old) 611 dev_put(old); 612 return rv; 613} 614 615static void dn_dev_check_default(struct net_device *dev) 616{ 617 write_lock(&dndev_lock); 618 if (dev == decnet_default_device) { 619 decnet_default_device = NULL; 620 } else { 621 dev = NULL; 622 } 623 write_unlock(&dndev_lock); 624 if (dev) 625 dev_put(dev); 626} 627 628static struct dn_dev *dn_dev_by_index(int ifindex) 629{ 630 struct net_device *dev; 631 struct dn_dev *dn_dev = NULL; 632 dev = dev_get_by_index(&init_net, ifindex); 633 if (dev) { 634 dn_dev = dev->dn_ptr; 635 dev_put(dev); 636 } 637 638 return dn_dev; 639} 640 641static const struct nla_policy dn_ifa_policy[IFA_MAX+1] = { 642 [IFA_ADDRESS] = { .type = NLA_U16 }, 643 [IFA_LOCAL] = { .type = NLA_U16 }, 644 [IFA_LABEL] = { .type = NLA_STRING, 645 .len = IFNAMSIZ - 1 }, 646}; 647 648static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 649{ 650 struct nlattr *tb[IFA_MAX+1]; 651 struct dn_dev *dn_db; 652 struct ifaddrmsg *ifm; 653 struct dn_ifaddr *ifa, **ifap; 654 int err = -EADDRNOTAVAIL; 655 656 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy); 657 if (err < 0) 658 goto errout; 659 660 ifm = nlmsg_data(nlh); 661 if ((dn_db = dn_dev_by_index(ifm->ifa_index)) == NULL) 662 goto errout; 663 664 for (ifap = &dn_db->ifa_list; (ifa = *ifap); ifap = &ifa->ifa_next) { 665 if (tb[IFA_LOCAL] && 666 nla_memcmp(tb[IFA_LOCAL], &ifa->ifa_local, 2)) 667 continue; 668 669 if (tb[IFA_LABEL] && nla_strcmp(tb[IFA_LABEL], ifa->ifa_label)) 670 continue; 671 672 dn_dev_del_ifa(dn_db, ifap, 1); 673 return 0; 674 } 675 676errout: 677 return err; 678} 679 680static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 681{ 682 struct nlattr *tb[IFA_MAX+1]; 683 struct net_device *dev; 684 struct dn_dev *dn_db; 685 struct ifaddrmsg *ifm; 686 struct dn_ifaddr *ifa; 687 int err; 688 689 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy); 690 if (err < 0) 691 return err; 692 693 if (tb[IFA_LOCAL] == NULL) 694 return -EINVAL; 695 696 ifm = nlmsg_data(nlh); 697 if ((dev = __dev_get_by_index(&init_net, ifm->ifa_index)) == NULL) 698 return -ENODEV; 699 700 if ((dn_db = dev->dn_ptr) == NULL) { 701 int err; 702 dn_db = dn_dev_create(dev, &err); 703 if (!dn_db) 704 return err; 705 } 706 707 if ((ifa = dn_dev_alloc_ifa()) == NULL) 708 return -ENOBUFS; 709 710 if (tb[IFA_ADDRESS] == NULL) 711 tb[IFA_ADDRESS] = tb[IFA_LOCAL]; 712 713 ifa->ifa_local = nla_get_le16(tb[IFA_LOCAL]); 714 ifa->ifa_address = nla_get_le16(tb[IFA_ADDRESS]); 715 ifa->ifa_flags = ifm->ifa_flags; 716 ifa->ifa_scope = ifm->ifa_scope; 717 ifa->ifa_dev = dn_db; 718 719 if (tb[IFA_LABEL]) 720 nla_strlcpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ); 721 else 722 memcpy(ifa->ifa_label, dev->name, IFNAMSIZ); 723 724 err = dn_dev_insert_ifa(dn_db, ifa); 725 if (err) 726 dn_dev_free_ifa(ifa); 727 728 return err; 729} 730 731static inline size_t dn_ifaddr_nlmsg_size(void) 732{ 733 return NLMSG_ALIGN(sizeof(struct ifaddrmsg)) 734 + nla_total_size(IFNAMSIZ) /* IFA_LABEL */ 735 + nla_total_size(2) /* IFA_ADDRESS */ 736 + nla_total_size(2); /* IFA_LOCAL */ 737} 738 739static int dn_nl_fill_ifaddr(struct sk_buff *skb, struct dn_ifaddr *ifa, 740 u32 pid, u32 seq, int event, unsigned int flags) 741{ 742 struct ifaddrmsg *ifm; 743 struct nlmsghdr *nlh; 744 745 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*ifm), flags); 746 if (nlh == NULL) 747 return -EMSGSIZE; 748 749 ifm = nlmsg_data(nlh); 750 ifm->ifa_family = AF_DECnet; 751 ifm->ifa_prefixlen = 16; 752 ifm->ifa_flags = ifa->ifa_flags | IFA_F_PERMANENT; 753 ifm->ifa_scope = ifa->ifa_scope; 754 ifm->ifa_index = ifa->ifa_dev->dev->ifindex; 755 756 if (ifa->ifa_address) 757 NLA_PUT_LE16(skb, IFA_ADDRESS, ifa->ifa_address); 758 if (ifa->ifa_local) 759 NLA_PUT_LE16(skb, IFA_LOCAL, ifa->ifa_local); 760 if (ifa->ifa_label[0]) 761 NLA_PUT_STRING(skb, IFA_LABEL, ifa->ifa_label); 762 763 return nlmsg_end(skb, nlh); 764 765nla_put_failure: 766 nlmsg_cancel(skb, nlh); 767 return -EMSGSIZE; 768} 769 770static void dn_ifaddr_notify(int event, struct dn_ifaddr *ifa) 771{ 772 struct sk_buff *skb; 773 int err = -ENOBUFS; 774 775 skb = alloc_skb(dn_ifaddr_nlmsg_size(), GFP_KERNEL); 776 if (skb == NULL) 777 goto errout; 778 779 err = dn_nl_fill_ifaddr(skb, ifa, 0, 0, event, 0); 780 if (err < 0) { 781 /* -EMSGSIZE implies BUG in dn_ifaddr_nlmsg_size() */ 782 WARN_ON(err == -EMSGSIZE); 783 kfree_skb(skb); 784 goto errout; 785 } 786 err = rtnl_notify(skb, 0, RTNLGRP_DECnet_IFADDR, NULL, GFP_KERNEL); 787errout: 788 if (err < 0) 789 rtnl_set_sk_err(RTNLGRP_DECnet_IFADDR, err); 790} 791 792static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) 793{ 794 int idx, dn_idx = 0, skip_ndevs, skip_naddr; 795 struct net_device *dev; 796 struct dn_dev *dn_db; 797 struct dn_ifaddr *ifa; 798 799 skip_ndevs = cb->args[0]; 800 skip_naddr = cb->args[1]; 801 802 idx = 0; 803 for_each_netdev(&init_net, dev) { 804 if (idx < skip_ndevs) 805 goto cont; 806 else if (idx > skip_ndevs) { 807 /* Only skip over addresses for first dev dumped 808 * in this iteration (idx == skip_ndevs) */ 809 skip_naddr = 0; 810 } 811 812 if ((dn_db = dev->dn_ptr) == NULL) 813 goto cont; 814 815 for (ifa = dn_db->ifa_list, dn_idx = 0; ifa; 816 ifa = ifa->ifa_next, dn_idx++) { 817 if (dn_idx < skip_naddr) 818 continue; 819 820 if (dn_nl_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid, 821 cb->nlh->nlmsg_seq, RTM_NEWADDR, 822 NLM_F_MULTI) < 0) 823 goto done; 824 } 825cont: 826 idx++; 827 } 828done: 829 cb->args[0] = idx; 830 cb->args[1] = dn_idx; 831 832 return skb->len; 833} 834 835static int dn_dev_get_first(struct net_device *dev, __le16 *addr) 836{ 837 struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; 838 struct dn_ifaddr *ifa; 839 int rv = -ENODEV; 840 if (dn_db == NULL) 841 goto out; 842 ifa = dn_db->ifa_list; 843 if (ifa != NULL) { 844 *addr = ifa->ifa_local; 845 rv = 0; 846 } 847out: 848 return rv; 849} 850 851/* 852 * Find a default address to bind to. 853 * 854 * This is one of those areas where the initial VMS concepts don't really 855 * map onto the Linux concepts, and since we introduced multiple addresses 856 * per interface we have to cope with slightly odd ways of finding out what 857 * "our address" really is. Mostly it's not a problem; for this we just guess 858 * a sensible default. Eventually the routing code will take care of all the 859 * nasties for us I hope. 860 */ 861int dn_dev_bind_default(__le16 *addr) 862{ 863 struct net_device *dev; 864 int rv; 865 dev = dn_dev_get_default(); 866last_chance: 867 if (dev) { 868 read_lock(&dev_base_lock); 869 rv = dn_dev_get_first(dev, addr); 870 read_unlock(&dev_base_lock); 871 dev_put(dev); 872 if (rv == 0 || dev == init_net.loopback_dev) 873 return rv; 874 } 875 dev = init_net.loopback_dev; 876 dev_hold(dev); 877 goto last_chance; 878} 879 880static void dn_send_endnode_hello(struct net_device *dev, struct dn_ifaddr *ifa) 881{ 882 struct endnode_hello_message *msg; 883 struct sk_buff *skb = NULL; 884 __le16 *pktlen; 885 struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; 886 887 if ((skb = dn_alloc_skb(NULL, sizeof(*msg), GFP_ATOMIC)) == NULL) 888 return; 889 890 skb->dev = dev; 891 892 msg = (struct endnode_hello_message *)skb_put(skb,sizeof(*msg)); 893 894 msg->msgflg = 0x0D; 895 memcpy(msg->tiver, dn_eco_version, 3); 896 dn_dn2eth(msg->id, ifa->ifa_local); 897 msg->iinfo = DN_RT_INFO_ENDN; 898 msg->blksize = dn_htons(mtu2blksize(dev)); 899 msg->area = 0x00; 900 memset(msg->seed, 0, 8); 901 memcpy(msg->neighbor, dn_hiord, ETH_ALEN); 902 903 if (dn_db->router) { 904 struct dn_neigh *dn = (struct dn_neigh *)dn_db->router; 905 dn_dn2eth(msg->neighbor, dn->addr); 906 } 907 908 msg->timer = dn_htons((unsigned short)dn_db->parms.t3); 909 msg->mpd = 0x00; 910 msg->datalen = 0x02; 911 memset(msg->data, 0xAA, 2); 912 913 pktlen = (__le16 *)skb_push(skb,2); 914 *pktlen = dn_htons(skb->len - 2); 915 916 skb_reset_network_header(skb); 917 918 dn_rt_finish_output(skb, dn_rt_all_rt_mcast, msg->id); 919} 920 921 922#define DRDELAY (5 * HZ) 923 924static int dn_am_i_a_router(struct dn_neigh *dn, struct dn_dev *dn_db, struct dn_ifaddr *ifa) 925{ 926 /* First check time since device went up */ 927 if ((jiffies - dn_db->uptime) < DRDELAY) 928 return 0; 929 930 /* If there is no router, then yes... */ 931 if (!dn_db->router) 932 return 1; 933 934 /* otherwise only if we have a higher priority or.. */ 935 if (dn->priority < dn_db->parms.priority) 936 return 1; 937 938 /* if we have equal priority and a higher node number */ 939 if (dn->priority != dn_db->parms.priority) 940 return 0; 941 942 if (dn_ntohs(dn->addr) < dn_ntohs(ifa->ifa_local)) 943 return 1; 944 945 return 0; 946} 947 948static void dn_send_router_hello(struct net_device *dev, struct dn_ifaddr *ifa) 949{ 950 int n; 951 struct dn_dev *dn_db = dev->dn_ptr; 952 struct dn_neigh *dn = (struct dn_neigh *)dn_db->router; 953 struct sk_buff *skb; 954 size_t size; 955 unsigned char *ptr; 956 unsigned char *i1, *i2; 957 __le16 *pktlen; 958 char *src; 959 960 if (mtu2blksize(dev) < (26 + 7)) 961 return; 962 963 n = mtu2blksize(dev) - 26; 964 n /= 7; 965 966 if (n > 32) 967 n = 32; 968 969 size = 2 + 26 + 7 * n; 970 971 if ((skb = dn_alloc_skb(NULL, size, GFP_ATOMIC)) == NULL) 972 return; 973 974 skb->dev = dev; 975 ptr = skb_put(skb, size); 976 977 *ptr++ = DN_RT_PKT_CNTL | DN_RT_PKT_ERTH; 978 *ptr++ = 2; /* ECO */ 979 *ptr++ = 0; 980 *ptr++ = 0; 981 dn_dn2eth(ptr, ifa->ifa_local); 982 src = ptr; 983 ptr += ETH_ALEN; 984 *ptr++ = dn_db->parms.forwarding == 1 ? 985 DN_RT_INFO_L1RT : DN_RT_INFO_L2RT; 986 *((__le16 *)ptr) = dn_htons(mtu2blksize(dev)); 987 ptr += 2; 988 *ptr++ = dn_db->parms.priority; /* Priority */ 989 *ptr++ = 0; /* Area: Reserved */ 990 *((__le16 *)ptr) = dn_htons((unsigned short)dn_db->parms.t3); 991 ptr += 2; 992 *ptr++ = 0; /* MPD: Reserved */ 993 i1 = ptr++; 994 memset(ptr, 0, 7); /* Name: Reserved */ 995 ptr += 7; 996 i2 = ptr++; 997 998 n = dn_neigh_elist(dev, ptr, n); 999 1000 *i2 = 7 * n; 1001 *i1 = 8 + *i2; 1002 1003 skb_trim(skb, (27 + *i2)); 1004 1005 pktlen = (__le16 *)skb_push(skb, 2); 1006 *pktlen = dn_htons(skb->len - 2); 1007 1008 skb_reset_network_header(skb); 1009 1010 if (dn_am_i_a_router(dn, dn_db, ifa)) { 1011 struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC); 1012 if (skb2) { 1013 dn_rt_finish_output(skb2, dn_rt_all_end_mcast, src); 1014 } 1015 } 1016 1017 dn_rt_finish_output(skb, dn_rt_all_rt_mcast, src); 1018} 1019 1020static void dn_send_brd_hello(struct net_device *dev, struct dn_ifaddr *ifa) 1021{ 1022 struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; 1023 1024 if (dn_db->parms.forwarding == 0) 1025 dn_send_endnode_hello(dev, ifa); 1026 else 1027 dn_send_router_hello(dev, ifa); 1028} 1029 1030static void dn_send_ptp_hello(struct net_device *dev, struct dn_ifaddr *ifa) 1031{ 1032 int tdlen = 16; 1033 int size = dev->hard_header_len + 2 + 4 + tdlen; 1034 struct sk_buff *skb = dn_alloc_skb(NULL, size, GFP_ATOMIC); 1035 int i; 1036 unsigned char *ptr; 1037 char src[ETH_ALEN]; 1038 1039 if (skb == NULL) 1040 return ; 1041 1042 skb->dev = dev; 1043 skb_push(skb, dev->hard_header_len); 1044 ptr = skb_put(skb, 2 + 4 + tdlen); 1045 1046 *ptr++ = DN_RT_PKT_HELO; 1047 *((__le16 *)ptr) = ifa->ifa_local; 1048 ptr += 2; 1049 *ptr++ = tdlen; 1050 1051 for(i = 0; i < tdlen; i++) 1052 *ptr++ = 0252; 1053 1054 dn_dn2eth(src, ifa->ifa_local); 1055 dn_rt_finish_output(skb, dn_rt_all_rt_mcast, src); 1056} 1057 1058static int dn_eth_up(struct net_device *dev) 1059{ 1060 struct dn_dev *dn_db = dev->dn_ptr; 1061 1062 if (dn_db->parms.forwarding == 0) 1063 dev_mc_add(dev, dn_rt_all_end_mcast, ETH_ALEN, 0); 1064 else 1065 dev_mc_add(dev, dn_rt_all_rt_mcast, ETH_ALEN, 0); 1066 1067 dn_db->use_long = 1; 1068 1069 return 0; 1070} 1071 1072static void dn_eth_down(struct net_device *dev) 1073{ 1074 struct dn_dev *dn_db = dev->dn_ptr; 1075 1076 if (dn_db->parms.forwarding == 0) 1077 dev_mc_delete(dev, dn_rt_all_end_mcast, ETH_ALEN, 0); 1078 else 1079 dev_mc_delete(dev, dn_rt_all_rt_mcast, ETH_ALEN, 0); 1080} 1081 1082static void dn_dev_set_timer(struct net_device *dev); 1083 1084static void dn_dev_timer_func(unsigned long arg) 1085{ 1086 struct net_device *dev = (struct net_device *)arg; 1087 struct dn_dev *dn_db = dev->dn_ptr; 1088 struct dn_ifaddr *ifa; 1089 1090 if (dn_db->t3 <= dn_db->parms.t2) { 1091 if (dn_db->parms.timer3) { 1092 for(ifa = dn_db->ifa_list; ifa; ifa = ifa->ifa_next) { 1093 if (!(ifa->ifa_flags & IFA_F_SECONDARY)) 1094 dn_db->parms.timer3(dev, ifa); 1095 } 1096 } 1097 dn_db->t3 = dn_db->parms.t3; 1098 } else { 1099 dn_db->t3 -= dn_db->parms.t2; 1100 } 1101 1102 dn_dev_set_timer(dev); 1103} 1104 1105static void dn_dev_set_timer(struct net_device *dev) 1106{ 1107 struct dn_dev *dn_db = dev->dn_ptr; 1108 1109 if (dn_db->parms.t2 > dn_db->parms.t3) 1110 dn_db->parms.t2 = dn_db->parms.t3; 1111 1112 dn_db->timer.data = (unsigned long)dev; 1113 dn_db->timer.function = dn_dev_timer_func; 1114 dn_db->timer.expires = jiffies + (dn_db->parms.t2 * HZ); 1115 1116 add_timer(&dn_db->timer); 1117} 1118 1119struct dn_dev *dn_dev_create(struct net_device *dev, int *err) 1120{ 1121 int i; 1122 struct dn_dev_parms *p = dn_dev_list; 1123 struct dn_dev *dn_db; 1124 1125 for(i = 0; i < DN_DEV_LIST_SIZE; i++, p++) { 1126 if (p->type == dev->type) 1127 break; 1128 } 1129 1130 *err = -ENODEV; 1131 if (i == DN_DEV_LIST_SIZE) 1132 return NULL; 1133 1134 *err = -ENOBUFS; 1135 if ((dn_db = kzalloc(sizeof(struct dn_dev), GFP_ATOMIC)) == NULL) 1136 return NULL; 1137 1138 memcpy(&dn_db->parms, p, sizeof(struct dn_dev_parms)); 1139 smp_wmb(); 1140 dev->dn_ptr = dn_db; 1141 dn_db->dev = dev; 1142 init_timer(&dn_db->timer); 1143 1144 dn_db->uptime = jiffies; 1145 1146 dn_db->neigh_parms = neigh_parms_alloc(dev, &dn_neigh_table); 1147 if (!dn_db->neigh_parms) { 1148 dev->dn_ptr = NULL; 1149 kfree(dn_db); 1150 return NULL; 1151 } 1152 1153 if (dn_db->parms.up) { 1154 if (dn_db->parms.up(dev) < 0) { 1155 neigh_parms_release(&dn_neigh_table, dn_db->neigh_parms); 1156 dev->dn_ptr = NULL; 1157 kfree(dn_db); 1158 return NULL; 1159 } 1160 } 1161 1162 dn_dev_sysctl_register(dev, &dn_db->parms); 1163 1164 dn_dev_set_timer(dev); 1165 1166 *err = 0; 1167 return dn_db; 1168} 1169 1170 1171/* 1172 * This processes a device up event. We only start up 1173 * the loopback device & ethernet devices with correct 1174 * MAC addreses automatically. Others must be started 1175 * specifically. 1176 * 1177 * FIXME: How should we configure the loopback address ? If we could dispense 1178 * with using decnet_address here and for autobind, it will be one less thing 1179 * for users to worry about setting up. 1180 */ 1181 1182void dn_dev_up(struct net_device *dev) 1183{ 1184 struct dn_ifaddr *ifa; 1185 __le16 addr = decnet_address; 1186 int maybe_default = 0; 1187 struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; 1188 1189 if ((dev->type != ARPHRD_ETHER) && (dev->type != ARPHRD_LOOPBACK)) 1190 return; 1191 1192 /* 1193 * Need to ensure that loopback device has a dn_db attached to it 1194 * to allow creation of neighbours against it, even though it might 1195 * not have a local address of its own. Might as well do the same for 1196 * all autoconfigured interfaces. 1197 */ 1198 if (dn_db == NULL) { 1199 int err; 1200 dn_db = dn_dev_create(dev, &err); 1201 if (dn_db == NULL) 1202 return; 1203 } 1204 1205 if (dev->type == ARPHRD_ETHER) { 1206 if (memcmp(dev->dev_addr, dn_hiord, 4) != 0) 1207 return; 1208 addr = dn_eth2dn(dev->dev_addr); 1209 maybe_default = 1; 1210 } 1211 1212 if (addr == 0) 1213 return; 1214 1215 if ((ifa = dn_dev_alloc_ifa()) == NULL) 1216 return; 1217 1218 ifa->ifa_local = ifa->ifa_address = addr; 1219 ifa->ifa_flags = 0; 1220 ifa->ifa_scope = RT_SCOPE_UNIVERSE; 1221 strcpy(ifa->ifa_label, dev->name); 1222 1223 dn_dev_set_ifa(dev, ifa); 1224 1225 /* 1226 * Automagically set the default device to the first automatically 1227 * configured ethernet card in the system. 1228 */ 1229 if (maybe_default) { 1230 dev_hold(dev); 1231 if (dn_dev_set_default(dev, 0)) 1232 dev_put(dev); 1233 } 1234} 1235 1236static void dn_dev_delete(struct net_device *dev) 1237{ 1238 struct dn_dev *dn_db = dev->dn_ptr; 1239 1240 if (dn_db == NULL) 1241 return; 1242 1243 del_timer_sync(&dn_db->timer); 1244 dn_dev_sysctl_unregister(&dn_db->parms); 1245 dn_dev_check_default(dev); 1246 neigh_ifdown(&dn_neigh_table, dev); 1247 1248 if (dn_db->parms.down) 1249 dn_db->parms.down(dev); 1250 1251 dev->dn_ptr = NULL; 1252 1253 neigh_parms_release(&dn_neigh_table, dn_db->neigh_parms); 1254 neigh_ifdown(&dn_neigh_table, dev); 1255 1256 if (dn_db->router) 1257 neigh_release(dn_db->router); 1258 if (dn_db->peer) 1259 neigh_release(dn_db->peer); 1260 1261 kfree(dn_db); 1262} 1263 1264void dn_dev_down(struct net_device *dev) 1265{ 1266 struct dn_dev *dn_db = dev->dn_ptr; 1267 struct dn_ifaddr *ifa; 1268 1269 if (dn_db == NULL) 1270 return; 1271 1272 while((ifa = dn_db->ifa_list) != NULL) { 1273 dn_dev_del_ifa(dn_db, &dn_db->ifa_list, 0); 1274 dn_dev_free_ifa(ifa); 1275 } 1276 1277 dn_dev_delete(dev); 1278} 1279 1280void dn_dev_init_pkt(struct sk_buff *skb) 1281{ 1282 return; 1283} 1284 1285void dn_dev_veri_pkt(struct sk_buff *skb) 1286{ 1287 return; 1288} 1289 1290void dn_dev_hello(struct sk_buff *skb) 1291{ 1292 return; 1293} 1294 1295void dn_dev_devices_off(void) 1296{ 1297 struct net_device *dev; 1298 1299 rtnl_lock(); 1300 for_each_netdev(&init_net, dev) 1301 dn_dev_down(dev); 1302 rtnl_unlock(); 1303 1304} 1305 1306void dn_dev_devices_on(void) 1307{ 1308 struct net_device *dev; 1309 1310 rtnl_lock(); 1311 for_each_netdev(&init_net, dev) { 1312 if (dev->flags & IFF_UP) 1313 dn_dev_up(dev); 1314 } 1315 rtnl_unlock(); 1316} 1317 1318int register_dnaddr_notifier(struct notifier_block *nb) 1319{ 1320 return blocking_notifier_chain_register(&dnaddr_chain, nb); 1321} 1322 1323int unregister_dnaddr_notifier(struct notifier_block *nb) 1324{ 1325 return blocking_notifier_chain_unregister(&dnaddr_chain, nb); 1326} 1327 1328#ifdef CONFIG_PROC_FS 1329static inline int is_dn_dev(struct net_device *dev) 1330{ 1331 return dev->dn_ptr != NULL; 1332} 1333 1334static void *dn_dev_seq_start(struct seq_file *seq, loff_t *pos) 1335{ 1336 int i; 1337 struct net_device *dev; 1338 1339 read_lock(&dev_base_lock); 1340 1341 if (*pos == 0) 1342 return SEQ_START_TOKEN; 1343 1344 i = 1; 1345 for_each_netdev(&init_net, dev) { 1346 if (!is_dn_dev(dev)) 1347 continue; 1348 1349 if (i++ == *pos) 1350 return dev; 1351 } 1352 1353 return NULL; 1354} 1355 1356static void *dn_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) 1357{ 1358 struct net_device *dev; 1359 1360 ++*pos; 1361 1362 dev = (struct net_device *)v; 1363 if (v == SEQ_START_TOKEN) 1364 dev = net_device_entry(&init_net.dev_base_head); 1365 1366 for_each_netdev_continue(&init_net, dev) { 1367 if (!is_dn_dev(dev)) 1368 continue; 1369 1370 return dev; 1371 } 1372 1373 return NULL; 1374} 1375 1376static void dn_dev_seq_stop(struct seq_file *seq, void *v) 1377{ 1378 read_unlock(&dev_base_lock); 1379} 1380 1381static char *dn_type2asc(char type) 1382{ 1383 switch(type) { 1384 case DN_DEV_BCAST: 1385 return "B"; 1386 case DN_DEV_UCAST: 1387 return "U"; 1388 case DN_DEV_MPOINT: 1389 return "M"; 1390 } 1391 1392 return "?"; 1393} 1394 1395static int dn_dev_seq_show(struct seq_file *seq, void *v) 1396{ 1397 if (v == SEQ_START_TOKEN) 1398 seq_puts(seq, "Name Flags T1 Timer1 T3 Timer3 BlkSize Pri State DevType Router Peer\n"); 1399 else { 1400 struct net_device *dev = v; 1401 char peer_buf[DN_ASCBUF_LEN]; 1402 char router_buf[DN_ASCBUF_LEN]; 1403 struct dn_dev *dn_db = dev->dn_ptr; 1404 1405 seq_printf(seq, "%-8s %1s %04u %04u %04lu %04lu" 1406 " %04hu %03d %02x %-10s %-7s %-7s\n", 1407 dev->name ? dev->name : "???", 1408 dn_type2asc(dn_db->parms.mode), 1409 0, 0, 1410 dn_db->t3, dn_db->parms.t3, 1411 mtu2blksize(dev), 1412 dn_db->parms.priority, 1413 dn_db->parms.state, dn_db->parms.name, 1414 dn_db->router ? dn_addr2asc(dn_ntohs(*(__le16 *)dn_db->router->primary_key), router_buf) : "", 1415 dn_db->peer ? dn_addr2asc(dn_ntohs(*(__le16 *)dn_db->peer->primary_key), peer_buf) : ""); 1416 } 1417 return 0; 1418} 1419 1420static const struct seq_operations dn_dev_seq_ops = { 1421 .start = dn_dev_seq_start, 1422 .next = dn_dev_seq_next, 1423 .stop = dn_dev_seq_stop, 1424 .show = dn_dev_seq_show, 1425}; 1426 1427static int dn_dev_seq_open(struct inode *inode, struct file *file) 1428{ 1429 return seq_open(file, &dn_dev_seq_ops); 1430} 1431 1432static const struct file_operations dn_dev_seq_fops = { 1433 .owner = THIS_MODULE, 1434 .open = dn_dev_seq_open, 1435 .read = seq_read, 1436 .llseek = seq_lseek, 1437 .release = seq_release, 1438}; 1439 1440#endif /* CONFIG_PROC_FS */ 1441 1442static int __initdata addr[2]; 1443module_param_array(addr, int, NULL, 0444); 1444MODULE_PARM_DESC(addr, "The DECnet address of this machine: area,node"); 1445 1446void __init dn_dev_init(void) 1447{ 1448 if (addr[0] > 63 || addr[0] < 0) { 1449 printk(KERN_ERR "DECnet: Area must be between 0 and 63"); 1450 return; 1451 } 1452 1453 if (addr[1] > 1023 || addr[1] < 0) { 1454 printk(KERN_ERR "DECnet: Node must be between 0 and 1023"); 1455 return; 1456 } 1457 1458 decnet_address = dn_htons((addr[0] << 10) | addr[1]); 1459 1460 dn_dev_devices_on(); 1461 1462 rtnl_register(PF_DECnet, RTM_NEWADDR, dn_nl_newaddr, NULL); 1463 rtnl_register(PF_DECnet, RTM_DELADDR, dn_nl_deladdr, NULL); 1464 rtnl_register(PF_DECnet, RTM_GETADDR, NULL, dn_nl_dump_ifaddr); 1465 1466 proc_net_fops_create(&init_net, "decnet_dev", S_IRUGO, &dn_dev_seq_fops); 1467 1468#ifdef CONFIG_SYSCTL 1469 { 1470 int i; 1471 for(i = 0; i < DN_DEV_LIST_SIZE; i++) 1472 dn_dev_sysctl_register(NULL, &dn_dev_list[i]); 1473 } 1474#endif /* CONFIG_SYSCTL */ 1475} 1476 1477void __exit dn_dev_cleanup(void) 1478{ 1479#ifdef CONFIG_SYSCTL 1480 { 1481 int i; 1482 for(i = 0; i < DN_DEV_LIST_SIZE; i++) 1483 dn_dev_sysctl_unregister(&dn_dev_list[i]); 1484 } 1485#endif /* CONFIG_SYSCTL */ 1486 1487 proc_net_remove(&init_net, "decnet_dev"); 1488 1489 dn_dev_devices_off(); 1490}