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