at v2.6.21 35 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/neighbour.h> 46#include <net/dst.h> 47#include <net/flow.h> 48#include <net/fib_rules.h> 49#include <net/netlink.h> 50#include <net/dn.h> 51#include <net/dn_dev.h> 52#include <net/dn_route.h> 53#include <net/dn_neigh.h> 54#include <net/dn_fib.h> 55 56#define DN_IFREQ_SIZE (sizeof(struct ifreq) - sizeof(struct sockaddr) + sizeof(struct sockaddr_dn)) 57 58static char dn_rt_all_end_mcast[ETH_ALEN] = {0xAB,0x00,0x00,0x04,0x00,0x00}; 59static char dn_rt_all_rt_mcast[ETH_ALEN] = {0xAB,0x00,0x00,0x03,0x00,0x00}; 60static char dn_hiord[ETH_ALEN] = {0xAA,0x00,0x04,0x00,0x00,0x00}; 61static unsigned char dn_eco_version[3] = {0x02,0x00,0x00}; 62 63extern struct neigh_table dn_neigh_table; 64 65/* 66 * decnet_address is kept in network order. 67 */ 68__le16 decnet_address = 0; 69 70static DEFINE_RWLOCK(dndev_lock); 71static struct net_device *decnet_default_device; 72static BLOCKING_NOTIFIER_HEAD(dnaddr_chain); 73 74static struct dn_dev *dn_dev_create(struct net_device *dev, int *err); 75static void dn_dev_delete(struct net_device *dev); 76static void dn_ifaddr_notify(int event, struct dn_ifaddr *ifa); 77 78static int dn_eth_up(struct net_device *); 79static void dn_eth_down(struct net_device *); 80static void dn_send_brd_hello(struct net_device *dev, struct dn_ifaddr *ifa); 81static void dn_send_ptp_hello(struct net_device *dev, struct dn_ifaddr *ifa); 82 83static struct dn_dev_parms dn_dev_list[] = { 84{ 85 .type = ARPHRD_ETHER, /* Ethernet */ 86 .mode = DN_DEV_BCAST, 87 .state = DN_DEV_S_RU, 88 .t2 = 1, 89 .t3 = 10, 90 .name = "ethernet", 91 .ctl_name = NET_DECNET_CONF_ETHER, 92 .up = dn_eth_up, 93 .down = dn_eth_down, 94 .timer3 = dn_send_brd_hello, 95}, 96{ 97 .type = ARPHRD_IPGRE, /* DECnet tunneled over GRE in IP */ 98 .mode = DN_DEV_BCAST, 99 .state = DN_DEV_S_RU, 100 .t2 = 1, 101 .t3 = 10, 102 .name = "ipgre", 103 .ctl_name = NET_DECNET_CONF_GRE, 104 .timer3 = dn_send_brd_hello, 105}, 106#if 0 107{ 108 .type = ARPHRD_X25, /* Bog standard X.25 */ 109 .mode = DN_DEV_UCAST, 110 .state = DN_DEV_S_DS, 111 .t2 = 1, 112 .t3 = 120, 113 .name = "x25", 114 .ctl_name = NET_DECNET_CONF_X25, 115 .timer3 = dn_send_ptp_hello, 116}, 117#endif 118#if 0 119{ 120 .type = ARPHRD_PPP, /* DECnet over PPP */ 121 .mode = DN_DEV_BCAST, 122 .state = DN_DEV_S_RU, 123 .t2 = 1, 124 .t3 = 10, 125 .name = "ppp", 126 .ctl_name = NET_DECNET_CONF_PPP, 127 .timer3 = dn_send_brd_hello, 128}, 129#endif 130{ 131 .type = ARPHRD_DDCMP, /* DECnet over DDCMP */ 132 .mode = DN_DEV_UCAST, 133 .state = DN_DEV_S_DS, 134 .t2 = 1, 135 .t3 = 120, 136 .name = "ddcmp", 137 .ctl_name = NET_DECNET_CONF_DDCMP, 138 .timer3 = dn_send_ptp_hello, 139}, 140{ 141 .type = ARPHRD_LOOPBACK, /* Loopback interface - always last */ 142 .mode = DN_DEV_BCAST, 143 .state = DN_DEV_S_RU, 144 .t2 = 1, 145 .t3 = 10, 146 .name = "loopback", 147 .ctl_name = NET_DECNET_CONF_LOOPBACK, 148 .timer3 = dn_send_brd_hello, 149} 150}; 151 152#define DN_DEV_LIST_SIZE (sizeof(dn_dev_list)/sizeof(struct dn_dev_parms)) 153 154#define DN_DEV_PARMS_OFFSET(x) ((int) ((char *) &((struct dn_dev_parms *)0)->x)) 155 156#ifdef CONFIG_SYSCTL 157 158static int min_t2[] = { 1 }; 159static int max_t2[] = { 60 }; /* No max specified, but this seems sensible */ 160static int min_t3[] = { 1 }; 161static int max_t3[] = { 8191 }; /* Must fit in 16 bits when multiplied by BCT3MULT or T3MULT */ 162 163static int min_priority[1]; 164static int max_priority[] = { 127 }; /* From DECnet spec */ 165 166static int dn_forwarding_proc(ctl_table *, int, struct file *, 167 void __user *, size_t *, loff_t *); 168static int dn_forwarding_sysctl(ctl_table *table, int __user *name, int nlen, 169 void __user *oldval, size_t __user *oldlenp, 170 void __user *newval, size_t newlen); 171 172static struct dn_dev_sysctl_table { 173 struct ctl_table_header *sysctl_header; 174 ctl_table dn_dev_vars[5]; 175 ctl_table dn_dev_dev[2]; 176 ctl_table dn_dev_conf_dir[2]; 177 ctl_table dn_dev_proto_dir[2]; 178 ctl_table dn_dev_root_dir[2]; 179} dn_dev_sysctl = { 180 NULL, 181 { 182 { 183 .ctl_name = NET_DECNET_CONF_DEV_FORWARDING, 184 .procname = "forwarding", 185 .data = (void *)DN_DEV_PARMS_OFFSET(forwarding), 186 .maxlen = sizeof(int), 187 .mode = 0644, 188 .proc_handler = dn_forwarding_proc, 189 .strategy = dn_forwarding_sysctl, 190 }, 191 { 192 .ctl_name = NET_DECNET_CONF_DEV_PRIORITY, 193 .procname = "priority", 194 .data = (void *)DN_DEV_PARMS_OFFSET(priority), 195 .maxlen = sizeof(int), 196 .mode = 0644, 197 .proc_handler = proc_dointvec_minmax, 198 .strategy = sysctl_intvec, 199 .extra1 = &min_priority, 200 .extra2 = &max_priority 201 }, 202 { 203 .ctl_name = NET_DECNET_CONF_DEV_T2, 204 .procname = "t2", 205 .data = (void *)DN_DEV_PARMS_OFFSET(t2), 206 .maxlen = sizeof(int), 207 .mode = 0644, 208 .proc_handler = proc_dointvec_minmax, 209 .strategy = sysctl_intvec, 210 .extra1 = &min_t2, 211 .extra2 = &max_t2 212 }, 213 { 214 .ctl_name = NET_DECNET_CONF_DEV_T3, 215 .procname = "t3", 216 .data = (void *)DN_DEV_PARMS_OFFSET(t3), 217 .maxlen = sizeof(int), 218 .mode = 0644, 219 .proc_handler = proc_dointvec_minmax, 220 .strategy = sysctl_intvec, 221 .extra1 = &min_t3, 222 .extra2 = &max_t3 223 }, 224 {0} 225 }, 226 {{ 227 .ctl_name = 0, 228 .procname = "", 229 .mode = 0555, 230 .child = dn_dev_sysctl.dn_dev_vars 231 }, {0}}, 232 {{ 233 .ctl_name = NET_DECNET_CONF, 234 .procname = "conf", 235 .mode = 0555, 236 .child = dn_dev_sysctl.dn_dev_dev 237 }, {0}}, 238 {{ 239 .ctl_name = NET_DECNET, 240 .procname = "decnet", 241 .mode = 0555, 242 .child = dn_dev_sysctl.dn_dev_conf_dir 243 }, {0}}, 244 {{ 245 .ctl_name = CTL_NET, 246 .procname = "net", 247 .mode = 0555, 248 .child = dn_dev_sysctl.dn_dev_proto_dir 249 }, {0}} 250}; 251 252static void dn_dev_sysctl_register(struct net_device *dev, struct dn_dev_parms *parms) 253{ 254 struct dn_dev_sysctl_table *t; 255 int i; 256 257 t = kmemdup(&dn_dev_sysctl, sizeof(*t), GFP_KERNEL); 258 if (t == NULL) 259 return; 260 261 for(i = 0; i < ARRAY_SIZE(t->dn_dev_vars) - 1; i++) { 262 long offset = (long)t->dn_dev_vars[i].data; 263 t->dn_dev_vars[i].data = ((char *)parms) + offset; 264 } 265 266 if (dev) { 267 t->dn_dev_dev[0].procname = dev->name; 268 t->dn_dev_dev[0].ctl_name = dev->ifindex; 269 } else { 270 t->dn_dev_dev[0].procname = parms->name; 271 t->dn_dev_dev[0].ctl_name = parms->ctl_name; 272 } 273 274 t->dn_dev_dev[0].child = t->dn_dev_vars; 275 t->dn_dev_conf_dir[0].child = t->dn_dev_dev; 276 t->dn_dev_proto_dir[0].child = t->dn_dev_conf_dir; 277 t->dn_dev_root_dir[0].child = t->dn_dev_proto_dir; 278 t->dn_dev_vars[0].extra1 = (void *)dev; 279 280 t->sysctl_header = register_sysctl_table(t->dn_dev_root_dir); 281 if (t->sysctl_header == NULL) 282 kfree(t); 283 else 284 parms->sysctl = t; 285} 286 287static void dn_dev_sysctl_unregister(struct dn_dev_parms *parms) 288{ 289 if (parms->sysctl) { 290 struct dn_dev_sysctl_table *t = parms->sysctl; 291 parms->sysctl = NULL; 292 unregister_sysctl_table(t->sysctl_header); 293 kfree(t); 294 } 295} 296 297static int dn_forwarding_proc(ctl_table *table, int write, 298 struct file *filep, 299 void __user *buffer, 300 size_t *lenp, loff_t *ppos) 301{ 302#ifdef CONFIG_DECNET_ROUTER 303 struct net_device *dev = table->extra1; 304 struct dn_dev *dn_db; 305 int err; 306 int tmp, old; 307 308 if (table->extra1 == NULL) 309 return -EINVAL; 310 311 dn_db = dev->dn_ptr; 312 old = dn_db->parms.forwarding; 313 314 err = proc_dointvec(table, write, filep, buffer, lenp, ppos); 315 316 if ((err >= 0) && write) { 317 if (dn_db->parms.forwarding < 0) 318 dn_db->parms.forwarding = 0; 319 if (dn_db->parms.forwarding > 2) 320 dn_db->parms.forwarding = 2; 321 /* 322 * What an ugly hack this is... its works, just. It 323 * would be nice if sysctl/proc were just that little 324 * bit more flexible so I don't have to write a special 325 * routine, or suffer hacks like this - SJW 326 */ 327 tmp = dn_db->parms.forwarding; 328 dn_db->parms.forwarding = old; 329 if (dn_db->parms.down) 330 dn_db->parms.down(dev); 331 dn_db->parms.forwarding = tmp; 332 if (dn_db->parms.up) 333 dn_db->parms.up(dev); 334 } 335 336 return err; 337#else 338 return -EINVAL; 339#endif 340} 341 342static int dn_forwarding_sysctl(ctl_table *table, int __user *name, int nlen, 343 void __user *oldval, size_t __user *oldlenp, 344 void __user *newval, size_t newlen) 345{ 346#ifdef CONFIG_DECNET_ROUTER 347 struct net_device *dev = table->extra1; 348 struct dn_dev *dn_db; 349 int value; 350 351 if (table->extra1 == NULL) 352 return -EINVAL; 353 354 dn_db = dev->dn_ptr; 355 356 if (newval && newlen) { 357 if (newlen != sizeof(int)) 358 return -EINVAL; 359 360 if (get_user(value, (int __user *)newval)) 361 return -EFAULT; 362 if (value < 0) 363 return -EINVAL; 364 if (value > 2) 365 return -EINVAL; 366 367 if (dn_db->parms.down) 368 dn_db->parms.down(dev); 369 dn_db->parms.forwarding = value; 370 if (dn_db->parms.up) 371 dn_db->parms.up(dev); 372 } 373 374 return 0; 375#else 376 return -EINVAL; 377#endif 378} 379 380#else /* CONFIG_SYSCTL */ 381static void dn_dev_sysctl_unregister(struct dn_dev_parms *parms) 382{ 383} 384static void dn_dev_sysctl_register(struct net_device *dev, struct dn_dev_parms *parms) 385{ 386} 387 388#endif /* CONFIG_SYSCTL */ 389 390static inline __u16 mtu2blksize(struct net_device *dev) 391{ 392 u32 blksize = dev->mtu; 393 if (blksize > 0xffff) 394 blksize = 0xffff; 395 396 if (dev->type == ARPHRD_ETHER || 397 dev->type == ARPHRD_PPP || 398 dev->type == ARPHRD_IPGRE || 399 dev->type == ARPHRD_LOOPBACK) 400 blksize -= 2; 401 402 return (__u16)blksize; 403} 404 405static struct dn_ifaddr *dn_dev_alloc_ifa(void) 406{ 407 struct dn_ifaddr *ifa; 408 409 ifa = kzalloc(sizeof(*ifa), GFP_KERNEL); 410 411 return ifa; 412} 413 414static __inline__ void dn_dev_free_ifa(struct dn_ifaddr *ifa) 415{ 416 kfree(ifa); 417} 418 419static void dn_dev_del_ifa(struct dn_dev *dn_db, struct dn_ifaddr **ifap, int destroy) 420{ 421 struct dn_ifaddr *ifa1 = *ifap; 422 unsigned char mac_addr[6]; 423 struct net_device *dev = dn_db->dev; 424 425 ASSERT_RTNL(); 426 427 *ifap = ifa1->ifa_next; 428 429 if (dn_db->dev->type == ARPHRD_ETHER) { 430 if (ifa1->ifa_local != dn_eth2dn(dev->dev_addr)) { 431 dn_dn2eth(mac_addr, ifa1->ifa_local); 432 dev_mc_delete(dev, mac_addr, ETH_ALEN, 0); 433 } 434 } 435 436 dn_ifaddr_notify(RTM_DELADDR, ifa1); 437 blocking_notifier_call_chain(&dnaddr_chain, NETDEV_DOWN, ifa1); 438 if (destroy) { 439 dn_dev_free_ifa(ifa1); 440 441 if (dn_db->ifa_list == NULL) 442 dn_dev_delete(dn_db->dev); 443 } 444} 445 446static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa) 447{ 448 struct net_device *dev = dn_db->dev; 449 struct dn_ifaddr *ifa1; 450 unsigned char mac_addr[6]; 451 452 ASSERT_RTNL(); 453 454 /* Check for duplicates */ 455 for(ifa1 = dn_db->ifa_list; ifa1; ifa1 = ifa1->ifa_next) { 456 if (ifa1->ifa_local == ifa->ifa_local) 457 return -EEXIST; 458 } 459 460 if (dev->type == ARPHRD_ETHER) { 461 if (ifa->ifa_local != dn_eth2dn(dev->dev_addr)) { 462 dn_dn2eth(mac_addr, ifa->ifa_local); 463 dev_mc_add(dev, mac_addr, ETH_ALEN, 0); 464 dev_mc_upload(dev); 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(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(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(ifindex); 633 if (dev) { 634 dn_dev = dev->dn_ptr; 635 dev_put(dev); 636 } 637 638 return dn_dev; 639} 640 641static struct nla_policy dn_ifa_policy[IFA_MAX+1] __read_mostly = { 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(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 read_lock(&dev_base_lock); 803 for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) { 804 if (idx < skip_ndevs) 805 continue; 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 continue; 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 } 825 } 826done: 827 read_unlock(&dev_base_lock); 828 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 == &loopback_dev) 873 return rv; 874 } 875 dev = &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->nh.raw = skb->data; 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->nh.raw = skb->data; 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 dev_mc_upload(dev); 1068 1069 dn_db->use_long = 1; 1070 1071 return 0; 1072} 1073 1074static void dn_eth_down(struct net_device *dev) 1075{ 1076 struct dn_dev *dn_db = dev->dn_ptr; 1077 1078 if (dn_db->parms.forwarding == 0) 1079 dev_mc_delete(dev, dn_rt_all_end_mcast, ETH_ALEN, 0); 1080 else 1081 dev_mc_delete(dev, dn_rt_all_rt_mcast, ETH_ALEN, 0); 1082} 1083 1084static void dn_dev_set_timer(struct net_device *dev); 1085 1086static void dn_dev_timer_func(unsigned long arg) 1087{ 1088 struct net_device *dev = (struct net_device *)arg; 1089 struct dn_dev *dn_db = dev->dn_ptr; 1090 struct dn_ifaddr *ifa; 1091 1092 if (dn_db->t3 <= dn_db->parms.t2) { 1093 if (dn_db->parms.timer3) { 1094 for(ifa = dn_db->ifa_list; ifa; ifa = ifa->ifa_next) { 1095 if (!(ifa->ifa_flags & IFA_F_SECONDARY)) 1096 dn_db->parms.timer3(dev, ifa); 1097 } 1098 } 1099 dn_db->t3 = dn_db->parms.t3; 1100 } else { 1101 dn_db->t3 -= dn_db->parms.t2; 1102 } 1103 1104 dn_dev_set_timer(dev); 1105} 1106 1107static void dn_dev_set_timer(struct net_device *dev) 1108{ 1109 struct dn_dev *dn_db = dev->dn_ptr; 1110 1111 if (dn_db->parms.t2 > dn_db->parms.t3) 1112 dn_db->parms.t2 = dn_db->parms.t3; 1113 1114 dn_db->timer.data = (unsigned long)dev; 1115 dn_db->timer.function = dn_dev_timer_func; 1116 dn_db->timer.expires = jiffies + (dn_db->parms.t2 * HZ); 1117 1118 add_timer(&dn_db->timer); 1119} 1120 1121struct dn_dev *dn_dev_create(struct net_device *dev, int *err) 1122{ 1123 int i; 1124 struct dn_dev_parms *p = dn_dev_list; 1125 struct dn_dev *dn_db; 1126 1127 for(i = 0; i < DN_DEV_LIST_SIZE; i++, p++) { 1128 if (p->type == dev->type) 1129 break; 1130 } 1131 1132 *err = -ENODEV; 1133 if (i == DN_DEV_LIST_SIZE) 1134 return NULL; 1135 1136 *err = -ENOBUFS; 1137 if ((dn_db = kzalloc(sizeof(struct dn_dev), GFP_ATOMIC)) == NULL) 1138 return NULL; 1139 1140 memcpy(&dn_db->parms, p, sizeof(struct dn_dev_parms)); 1141 smp_wmb(); 1142 dev->dn_ptr = dn_db; 1143 dn_db->dev = dev; 1144 init_timer(&dn_db->timer); 1145 1146 dn_db->uptime = jiffies; 1147 1148 dn_db->neigh_parms = neigh_parms_alloc(dev, &dn_neigh_table); 1149 if (!dn_db->neigh_parms) { 1150 dev->dn_ptr = NULL; 1151 kfree(dn_db); 1152 return NULL; 1153 } 1154 1155 if (dn_db->parms.up) { 1156 if (dn_db->parms.up(dev) < 0) { 1157 neigh_parms_release(&dn_neigh_table, dn_db->neigh_parms); 1158 dev->dn_ptr = NULL; 1159 kfree(dn_db); 1160 return NULL; 1161 } 1162 } 1163 1164 dn_dev_sysctl_register(dev, &dn_db->parms); 1165 1166 dn_dev_set_timer(dev); 1167 1168 *err = 0; 1169 return dn_db; 1170} 1171 1172 1173/* 1174 * This processes a device up event. We only start up 1175 * the loopback device & ethernet devices with correct 1176 * MAC addreses automatically. Others must be started 1177 * specifically. 1178 * 1179 * FIXME: How should we configure the loopback address ? If we could dispense 1180 * with using decnet_address here and for autobind, it will be one less thing 1181 * for users to worry about setting up. 1182 */ 1183 1184void dn_dev_up(struct net_device *dev) 1185{ 1186 struct dn_ifaddr *ifa; 1187 __le16 addr = decnet_address; 1188 int maybe_default = 0; 1189 struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; 1190 1191 if ((dev->type != ARPHRD_ETHER) && (dev->type != ARPHRD_LOOPBACK)) 1192 return; 1193 1194 /* 1195 * Need to ensure that loopback device has a dn_db attached to it 1196 * to allow creation of neighbours against it, even though it might 1197 * not have a local address of its own. Might as well do the same for 1198 * all autoconfigured interfaces. 1199 */ 1200 if (dn_db == NULL) { 1201 int err; 1202 dn_db = dn_dev_create(dev, &err); 1203 if (dn_db == NULL) 1204 return; 1205 } 1206 1207 if (dev->type == ARPHRD_ETHER) { 1208 if (memcmp(dev->dev_addr, dn_hiord, 4) != 0) 1209 return; 1210 addr = dn_eth2dn(dev->dev_addr); 1211 maybe_default = 1; 1212 } 1213 1214 if (addr == 0) 1215 return; 1216 1217 if ((ifa = dn_dev_alloc_ifa()) == NULL) 1218 return; 1219 1220 ifa->ifa_local = ifa->ifa_address = addr; 1221 ifa->ifa_flags = 0; 1222 ifa->ifa_scope = RT_SCOPE_UNIVERSE; 1223 strcpy(ifa->ifa_label, dev->name); 1224 1225 dn_dev_set_ifa(dev, ifa); 1226 1227 /* 1228 * Automagically set the default device to the first automatically 1229 * configured ethernet card in the system. 1230 */ 1231 if (maybe_default) { 1232 dev_hold(dev); 1233 if (dn_dev_set_default(dev, 0)) 1234 dev_put(dev); 1235 } 1236} 1237 1238static void dn_dev_delete(struct net_device *dev) 1239{ 1240 struct dn_dev *dn_db = dev->dn_ptr; 1241 1242 if (dn_db == NULL) 1243 return; 1244 1245 del_timer_sync(&dn_db->timer); 1246 dn_dev_sysctl_unregister(&dn_db->parms); 1247 dn_dev_check_default(dev); 1248 neigh_ifdown(&dn_neigh_table, dev); 1249 1250 if (dn_db->parms.down) 1251 dn_db->parms.down(dev); 1252 1253 dev->dn_ptr = NULL; 1254 1255 neigh_parms_release(&dn_neigh_table, dn_db->neigh_parms); 1256 neigh_ifdown(&dn_neigh_table, dev); 1257 1258 if (dn_db->router) 1259 neigh_release(dn_db->router); 1260 if (dn_db->peer) 1261 neigh_release(dn_db->peer); 1262 1263 kfree(dn_db); 1264} 1265 1266void dn_dev_down(struct net_device *dev) 1267{ 1268 struct dn_dev *dn_db = dev->dn_ptr; 1269 struct dn_ifaddr *ifa; 1270 1271 if (dn_db == NULL) 1272 return; 1273 1274 while((ifa = dn_db->ifa_list) != NULL) { 1275 dn_dev_del_ifa(dn_db, &dn_db->ifa_list, 0); 1276 dn_dev_free_ifa(ifa); 1277 } 1278 1279 dn_dev_delete(dev); 1280} 1281 1282void dn_dev_init_pkt(struct sk_buff *skb) 1283{ 1284 return; 1285} 1286 1287void dn_dev_veri_pkt(struct sk_buff *skb) 1288{ 1289 return; 1290} 1291 1292void dn_dev_hello(struct sk_buff *skb) 1293{ 1294 return; 1295} 1296 1297void dn_dev_devices_off(void) 1298{ 1299 struct net_device *dev; 1300 1301 rtnl_lock(); 1302 for(dev = dev_base; dev; dev = dev->next) 1303 dn_dev_down(dev); 1304 rtnl_unlock(); 1305 1306} 1307 1308void dn_dev_devices_on(void) 1309{ 1310 struct net_device *dev; 1311 1312 rtnl_lock(); 1313 for(dev = dev_base; dev; dev = dev->next) { 1314 if (dev->flags & IFF_UP) 1315 dn_dev_up(dev); 1316 } 1317 rtnl_unlock(); 1318} 1319 1320int register_dnaddr_notifier(struct notifier_block *nb) 1321{ 1322 return blocking_notifier_chain_register(&dnaddr_chain, nb); 1323} 1324 1325int unregister_dnaddr_notifier(struct notifier_block *nb) 1326{ 1327 return blocking_notifier_chain_unregister(&dnaddr_chain, nb); 1328} 1329 1330#ifdef CONFIG_PROC_FS 1331static inline struct net_device *dn_dev_get_next(struct seq_file *seq, struct net_device *dev) 1332{ 1333 do { 1334 dev = dev->next; 1335 } while(dev && !dev->dn_ptr); 1336 1337 return dev; 1338} 1339 1340static struct net_device *dn_dev_get_idx(struct seq_file *seq, loff_t pos) 1341{ 1342 struct net_device *dev; 1343 1344 dev = dev_base; 1345 if (dev && !dev->dn_ptr) 1346 dev = dn_dev_get_next(seq, dev); 1347 if (pos) { 1348 while(dev && (dev = dn_dev_get_next(seq, dev))) 1349 --pos; 1350 } 1351 return dev; 1352} 1353 1354static void *dn_dev_seq_start(struct seq_file *seq, loff_t *pos) 1355{ 1356 if (*pos) { 1357 struct net_device *dev; 1358 read_lock(&dev_base_lock); 1359 dev = dn_dev_get_idx(seq, *pos - 1); 1360 if (dev == NULL) 1361 read_unlock(&dev_base_lock); 1362 return dev; 1363 } 1364 return SEQ_START_TOKEN; 1365} 1366 1367static void *dn_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) 1368{ 1369 struct net_device *dev = v; 1370 loff_t one = 1; 1371 1372 if (v == SEQ_START_TOKEN) { 1373 dev = dn_dev_seq_start(seq, &one); 1374 } else { 1375 dev = dn_dev_get_next(seq, dev); 1376 if (dev == NULL) 1377 read_unlock(&dev_base_lock); 1378 } 1379 ++*pos; 1380 return dev; 1381} 1382 1383static void dn_dev_seq_stop(struct seq_file *seq, void *v) 1384{ 1385 if (v && v != SEQ_START_TOKEN) 1386 read_unlock(&dev_base_lock); 1387} 1388 1389static char *dn_type2asc(char type) 1390{ 1391 switch(type) { 1392 case DN_DEV_BCAST: 1393 return "B"; 1394 case DN_DEV_UCAST: 1395 return "U"; 1396 case DN_DEV_MPOINT: 1397 return "M"; 1398 } 1399 1400 return "?"; 1401} 1402 1403static int dn_dev_seq_show(struct seq_file *seq, void *v) 1404{ 1405 if (v == SEQ_START_TOKEN) 1406 seq_puts(seq, "Name Flags T1 Timer1 T3 Timer3 BlkSize Pri State DevType Router Peer\n"); 1407 else { 1408 struct net_device *dev = v; 1409 char peer_buf[DN_ASCBUF_LEN]; 1410 char router_buf[DN_ASCBUF_LEN]; 1411 struct dn_dev *dn_db = dev->dn_ptr; 1412 1413 seq_printf(seq, "%-8s %1s %04u %04u %04lu %04lu" 1414 " %04hu %03d %02x %-10s %-7s %-7s\n", 1415 dev->name ? dev->name : "???", 1416 dn_type2asc(dn_db->parms.mode), 1417 0, 0, 1418 dn_db->t3, dn_db->parms.t3, 1419 mtu2blksize(dev), 1420 dn_db->parms.priority, 1421 dn_db->parms.state, dn_db->parms.name, 1422 dn_db->router ? dn_addr2asc(dn_ntohs(*(__le16 *)dn_db->router->primary_key), router_buf) : "", 1423 dn_db->peer ? dn_addr2asc(dn_ntohs(*(__le16 *)dn_db->peer->primary_key), peer_buf) : ""); 1424 } 1425 return 0; 1426} 1427 1428static struct seq_operations dn_dev_seq_ops = { 1429 .start = dn_dev_seq_start, 1430 .next = dn_dev_seq_next, 1431 .stop = dn_dev_seq_stop, 1432 .show = dn_dev_seq_show, 1433}; 1434 1435static int dn_dev_seq_open(struct inode *inode, struct file *file) 1436{ 1437 return seq_open(file, &dn_dev_seq_ops); 1438} 1439 1440static const struct file_operations dn_dev_seq_fops = { 1441 .owner = THIS_MODULE, 1442 .open = dn_dev_seq_open, 1443 .read = seq_read, 1444 .llseek = seq_lseek, 1445 .release = seq_release, 1446}; 1447 1448#endif /* CONFIG_PROC_FS */ 1449 1450static struct rtnetlink_link dnet_rtnetlink_table[RTM_NR_MSGTYPES] = 1451{ 1452 [RTM_NEWADDR - RTM_BASE] = { .doit = dn_nl_newaddr, }, 1453 [RTM_DELADDR - RTM_BASE] = { .doit = dn_nl_deladdr, }, 1454 [RTM_GETADDR - RTM_BASE] = { .dumpit = dn_nl_dump_ifaddr, }, 1455#ifdef CONFIG_DECNET_ROUTER 1456 [RTM_NEWROUTE - RTM_BASE] = { .doit = dn_fib_rtm_newroute, }, 1457 [RTM_DELROUTE - RTM_BASE] = { .doit = dn_fib_rtm_delroute, }, 1458 [RTM_GETROUTE - RTM_BASE] = { .doit = dn_cache_getroute, 1459 .dumpit = dn_fib_dump, }, 1460 [RTM_GETRULE - RTM_BASE] = { .dumpit = dn_fib_dump_rules, }, 1461#else 1462 [RTM_GETROUTE - RTM_BASE] = { .doit = dn_cache_getroute, 1463 .dumpit = dn_cache_dump, }, 1464#endif 1465 1466}; 1467 1468static int __initdata addr[2]; 1469module_param_array(addr, int, NULL, 0444); 1470MODULE_PARM_DESC(addr, "The DECnet address of this machine: area,node"); 1471 1472void __init dn_dev_init(void) 1473{ 1474 if (addr[0] > 63 || addr[0] < 0) { 1475 printk(KERN_ERR "DECnet: Area must be between 0 and 63"); 1476 return; 1477 } 1478 1479 if (addr[1] > 1023 || addr[1] < 0) { 1480 printk(KERN_ERR "DECnet: Node must be between 0 and 1023"); 1481 return; 1482 } 1483 1484 decnet_address = dn_htons((addr[0] << 10) | addr[1]); 1485 1486 dn_dev_devices_on(); 1487 1488 rtnetlink_links[PF_DECnet] = dnet_rtnetlink_table; 1489 1490 proc_net_fops_create("decnet_dev", S_IRUGO, &dn_dev_seq_fops); 1491 1492#ifdef CONFIG_SYSCTL 1493 { 1494 int i; 1495 for(i = 0; i < DN_DEV_LIST_SIZE; i++) 1496 dn_dev_sysctl_register(NULL, &dn_dev_list[i]); 1497 } 1498#endif /* CONFIG_SYSCTL */ 1499} 1500 1501void __exit dn_dev_cleanup(void) 1502{ 1503 rtnetlink_links[PF_DECnet] = NULL; 1504 1505#ifdef CONFIG_SYSCTL 1506 { 1507 int i; 1508 for(i = 0; i < DN_DEV_LIST_SIZE; i++) 1509 dn_dev_sysctl_unregister(&dn_dev_list[i]); 1510 } 1511#endif /* CONFIG_SYSCTL */ 1512 1513 proc_net_remove("decnet_dev"); 1514 1515 dn_dev_devices_off(); 1516}