linux-bk/net/ipv4/devinet.c
<<
>>
Prefs
   1/*
   2 *      NET3    IP device support routines.
   3 *
   4 *      Version: $Id: devinet.c,v 1.44 2001/10/31 21:55:54 davem Exp $
   5 *
   6 *              This program is free software; you can redistribute it and/or
   7 *              modify it under the terms of the GNU General Public License
   8 *              as published by the Free Software Foundation; either version
   9 *              2 of the License, or (at your option) any later version.
  10 *
  11 *      Derived from the IP parts of dev.c 1.0.19
  12 *              Authors:        Ross Biro, <bir7@leland.Stanford.Edu>
  13 *                              Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  14 *                              Mark Evans, <evansmp@uhura.aston.ac.uk>
  15 *
  16 *      Additional Authors:
  17 *              Alan Cox, <gw4pts@gw4pts.ampr.org>
  18 *              Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
  19 *
  20 *      Changes:
  21 *              Alexey Kuznetsov:       pa_* fields are replaced with ifaddr
  22 *                                      lists.
  23 *              Cyrus Durgin:           updated for kmod
  24 *              Matthias Andree:        in devinet_ioctl, compare label and
  25 *                                      address (4.4BSD alias style support),
  26 *                                      fall back to comparing just the label
  27 *                                      if no match found.
  28 */
  29
  30#include <linux/config.h>
  31
  32#include <asm/uaccess.h>
  33#include <asm/system.h>
  34#include <linux/bitops.h>
  35#include <linux/module.h>
  36#include <linux/types.h>
  37#include <linux/kernel.h>
  38#include <linux/sched.h>
  39#include <linux/string.h>
  40#include <linux/mm.h>
  41#include <linux/socket.h>
  42#include <linux/sockios.h>
  43#include <linux/in.h>
  44#include <linux/errno.h>
  45#include <linux/interrupt.h>
  46#include <linux/if_ether.h>
  47#include <linux/inet.h>
  48#include <linux/netdevice.h>
  49#include <linux/etherdevice.h>
  50#include <linux/skbuff.h>
  51#include <linux/rtnetlink.h>
  52#include <linux/init.h>
  53#include <linux/notifier.h>
  54#include <linux/inetdevice.h>
  55#include <linux/igmp.h>
  56#ifdef CONFIG_SYSCTL
  57#include <linux/sysctl.h>
  58#endif
  59#include <linux/kmod.h>
  60
  61#include <net/ip.h>
  62#include <net/route.h>
  63#include <net/ip_fib.h>
  64
  65struct ipv4_devconf ipv4_devconf = {
  66        .accept_redirects = 1,
  67        .send_redirects =  1,
  68        .secure_redirects = 1,
  69        .shared_media =   1,
  70};
  71
  72static struct ipv4_devconf ipv4_devconf_dflt = {
  73        .accept_redirects =  1,
  74        .send_redirects =    1,
  75        .secure_redirects =  1,
  76        .shared_media =      1,
  77        .accept_source_route = 1,
  78};
  79
  80static void rtmsg_ifa(int event, struct in_ifaddr *);
  81
  82static struct notifier_block *inetaddr_chain;
  83static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
  84                         int destroy);
  85#ifdef CONFIG_SYSCTL
  86static void devinet_sysctl_register(struct in_device *in_dev,
  87                                    struct ipv4_devconf *p);
  88static void devinet_sysctl_unregister(struct ipv4_devconf *p);
  89#endif
  90
  91/* Locks all the inet devices. */
  92
  93static struct in_ifaddr *inet_alloc_ifa(void)
  94{
  95        struct in_ifaddr *ifa = kmalloc(sizeof(*ifa), GFP_KERNEL);
  96
  97        if (ifa) {
  98                memset(ifa, 0, sizeof(*ifa));
  99                INIT_RCU_HEAD(&ifa->rcu_head);
 100        }
 101
 102        return ifa;
 103}
 104
 105static void inet_rcu_free_ifa(struct rcu_head *head)
 106{
 107        struct in_ifaddr *ifa = container_of(head, struct in_ifaddr, rcu_head);
 108        if (ifa->ifa_dev)
 109                in_dev_put(ifa->ifa_dev);
 110        kfree(ifa);
 111}
 112
 113static inline void inet_free_ifa(struct in_ifaddr *ifa)
 114{
 115        call_rcu(&ifa->rcu_head, inet_rcu_free_ifa);
 116}
 117
 118void in_dev_finish_destroy(struct in_device *idev)
 119{
 120        struct net_device *dev = idev->dev;
 121
 122        BUG_TRAP(!idev->ifa_list);
 123        BUG_TRAP(!idev->mc_list);
 124#ifdef NET_REFCNT_DEBUG
 125        printk(KERN_DEBUG "in_dev_finish_destroy: %p=%s\n",
 126               idev, dev ? dev->name : "NIL");
 127#endif
 128        dev_put(dev);
 129        if (!idev->dead)
 130                printk("Freeing alive in_device %p\n", idev);
 131        else {
 132                kfree(idev);
 133        }
 134}
 135
 136struct in_device *inetdev_init(struct net_device *dev)
 137{
 138        struct in_device *in_dev;
 139
 140        ASSERT_RTNL();
 141
 142        in_dev = kmalloc(sizeof(*in_dev), GFP_KERNEL);
 143        if (!in_dev)
 144                goto out;
 145        memset(in_dev, 0, sizeof(*in_dev));
 146        INIT_RCU_HEAD(&in_dev->rcu_head);
 147        memcpy(&in_dev->cnf, &ipv4_devconf_dflt, sizeof(in_dev->cnf));
 148        in_dev->cnf.sysctl = NULL;
 149        in_dev->dev = dev;
 150        if ((in_dev->arp_parms = neigh_parms_alloc(dev, &arp_tbl)) == NULL)
 151                goto out_kfree;
 152        /* Reference in_dev->dev */
 153        dev_hold(dev);
 154#ifdef CONFIG_SYSCTL
 155        neigh_sysctl_register(dev, in_dev->arp_parms, NET_IPV4,
 156                              NET_IPV4_NEIGH, "ipv4", NULL);
 157#endif
 158
 159        /* Account for reference dev->ip_ptr */
 160        in_dev_hold(in_dev);
 161        rcu_assign_pointer(dev->ip_ptr, in_dev);
 162
 163#ifdef CONFIG_SYSCTL
 164        devinet_sysctl_register(in_dev, &in_dev->cnf);
 165#endif
 166        ip_mc_init_dev(in_dev);
 167        if (dev->flags & IFF_UP)
 168                ip_mc_up(in_dev);
 169out:
 170        return in_dev;
 171out_kfree:
 172        kfree(in_dev);
 173        in_dev = NULL;
 174        goto out;
 175}
 176
 177static void in_dev_rcu_put(struct rcu_head *head)
 178{
 179        struct in_device *idev = container_of(head, struct in_device, rcu_head);
 180        in_dev_put(idev);
 181}
 182
 183static void inetdev_destroy(struct in_device *in_dev)
 184{
 185        struct in_ifaddr *ifa;
 186        struct net_device *dev;
 187
 188        ASSERT_RTNL();
 189
 190        in_dev->dead = 1;
 191
 192        ip_mc_destroy_dev(in_dev);
 193
 194        while ((ifa = in_dev->ifa_list) != NULL) {
 195                inet_del_ifa(in_dev, &in_dev->ifa_list, 0);
 196                inet_free_ifa(ifa);
 197        }
 198
 199#ifdef CONFIG_SYSCTL
 200        devinet_sysctl_unregister(&in_dev->cnf);
 201#endif
 202
 203        dev = in_dev->dev;
 204        dev->ip_ptr = NULL;
 205
 206#ifdef CONFIG_SYSCTL
 207        neigh_sysctl_unregister(in_dev->arp_parms);
 208#endif
 209        neigh_parms_release(&arp_tbl, in_dev->arp_parms);
 210        arp_ifdown(dev);
 211
 212        call_rcu(&in_dev->rcu_head, in_dev_rcu_put);
 213}
 214
 215int inet_addr_onlink(struct in_device *in_dev, u32 a, u32 b)
 216{
 217        rcu_read_lock();
 218        for_primary_ifa(in_dev) {
 219                if (inet_ifa_match(a, ifa)) {
 220                        if (!b || inet_ifa_match(b, ifa)) {
 221                                rcu_read_unlock();
 222                                return 1;
 223                        }
 224                }
 225        } endfor_ifa(in_dev);
 226        rcu_read_unlock();
 227        return 0;
 228}
 229
 230static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
 231                         int destroy)
 232{
 233        struct in_ifaddr *ifa1 = *ifap;
 234
 235        ASSERT_RTNL();
 236
 237        /* 1. Deleting primary ifaddr forces deletion all secondaries */
 238
 239        if (!(ifa1->ifa_flags & IFA_F_SECONDARY)) {
 240                struct in_ifaddr *ifa;
 241                struct in_ifaddr **ifap1 = &ifa1->ifa_next;
 242
 243                while ((ifa = *ifap1) != NULL) {
 244                        if (!(ifa->ifa_flags & IFA_F_SECONDARY) ||
 245                            ifa1->ifa_mask != ifa->ifa_mask ||
 246                            !inet_ifa_match(ifa1->ifa_address, ifa)) {
 247                                ifap1 = &ifa->ifa_next;
 248                                continue;
 249                        }
 250
 251                        *ifap1 = ifa->ifa_next;
 252
 253                        rtmsg_ifa(RTM_DELADDR, ifa);
 254                        notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa);
 255                        inet_free_ifa(ifa);
 256                }
 257        }
 258
 259        /* 2. Unlink it */
 260
 261        *ifap = ifa1->ifa_next;
 262
 263        /* 3. Announce address deletion */
 264
 265        /* Send message first, then call notifier.
 266           At first sight, FIB update triggered by notifier
 267           will refer to already deleted ifaddr, that could confuse
 268           netlink listeners. It is not true: look, gated sees
 269           that route deleted and if it still thinks that ifaddr
 270           is valid, it will try to restore deleted routes... Grr.
 271           So that, this order is correct.
 272         */
 273        rtmsg_ifa(RTM_DELADDR, ifa1);
 274        notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa1);
 275        if (destroy) {
 276                inet_free_ifa(ifa1);
 277
 278                if (!in_dev->ifa_list)
 279                        inetdev_destroy(in_dev);
 280        }
 281}
 282
 283static int inet_insert_ifa(struct in_ifaddr *ifa)
 284{
 285        struct in_device *in_dev = ifa->ifa_dev;
 286        struct in_ifaddr *ifa1, **ifap, **last_primary;
 287
 288        ASSERT_RTNL();
 289
 290        if (!ifa->ifa_local) {
 291                inet_free_ifa(ifa);
 292                return 0;
 293        }
 294
 295        ifa->ifa_flags &= ~IFA_F_SECONDARY;
 296        last_primary = &in_dev->ifa_list;
 297
 298        for (ifap = &in_dev->ifa_list; (ifa1 = *ifap) != NULL;
 299             ifap = &ifa1->ifa_next) {
 300                if (!(ifa1->ifa_flags & IFA_F_SECONDARY) &&
 301                    ifa->ifa_scope <= ifa1->ifa_scope)
 302                        last_primary = &ifa1->ifa_next;
 303                if (ifa1->ifa_mask == ifa->ifa_mask &&
 304                    inet_ifa_match(ifa1->ifa_address, ifa)) {
 305                        if (ifa1->ifa_local == ifa->ifa_local) {
 306                                inet_free_ifa(ifa);
 307                                return -EEXIST;
 308                        }
 309                        if (ifa1->ifa_scope != ifa->ifa_scope) {
 310                                inet_free_ifa(ifa);
 311                                return -EINVAL;
 312                        }
 313                        ifa->ifa_flags |= IFA_F_SECONDARY;
 314                }
 315        }
 316
 317        if (!(ifa->ifa_flags & IFA_F_SECONDARY)) {
 318                net_srandom(ifa->ifa_local);
 319                ifap = last_primary;
 320        }
 321
 322        ifa->ifa_next = *ifap;
 323        *ifap = ifa;
 324
 325        /* Send message first, then call notifier.
 326           Notifier will trigger FIB update, so that
 327           listeners of netlink will know about new ifaddr */
 328        rtmsg_ifa(RTM_NEWADDR, ifa);
 329        notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa);
 330
 331        return 0;
 332}
 333
 334static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa)
 335{
 336        struct in_device *in_dev = __in_dev_get(dev);
 337
 338        ASSERT_RTNL();
 339
 340        if (!in_dev) {
 341                in_dev = inetdev_init(dev);
 342                if (!in_dev) {
 343                        inet_free_ifa(ifa);
 344                        return -ENOBUFS;
 345                }
 346        }
 347        if (ifa->ifa_dev != in_dev) {
 348                BUG_TRAP(!ifa->ifa_dev);
 349                in_dev_hold(in_dev);
 350                ifa->ifa_dev = in_dev;
 351        }
 352        if (LOOPBACK(ifa->ifa_local))
 353                ifa->ifa_scope = RT_SCOPE_HOST;
 354        return inet_insert_ifa(ifa);
 355}
 356
 357struct in_device *inetdev_by_index(int ifindex)
 358{
 359        struct net_device *dev;
 360        struct in_device *in_dev = NULL;
 361        read_lock(&dev_base_lock);
 362        dev = __dev_get_by_index(ifindex);
 363        if (dev)
 364                in_dev = in_dev_get(dev);
 365        read_unlock(&dev_base_lock);
 366        return in_dev;
 367}
 368
 369/* Called only from RTNL semaphored context. No locks. */
 370
 371struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, u32 prefix,
 372                                    u32 mask)
 373{
 374        ASSERT_RTNL();
 375
 376        for_primary_ifa(in_dev) {
 377                if (ifa->ifa_mask == mask && inet_ifa_match(prefix, ifa))
 378                        return ifa;
 379        } endfor_ifa(in_dev);
 380        return NULL;
 381}
 382
 383int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 384{
 385        struct rtattr **rta = arg;
 386        struct in_device *in_dev;
 387        struct ifaddrmsg *ifm = NLMSG_DATA(nlh);
 388        struct in_ifaddr *ifa, **ifap;
 389
 390        ASSERT_RTNL();
 391
 392        if ((in_dev = inetdev_by_index(ifm->ifa_index)) == NULL)
 393                goto out;
 394        __in_dev_put(in_dev);
 395
 396        for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
 397             ifap = &ifa->ifa_next) {
 398                if ((rta[IFA_LOCAL - 1] &&
 399                     memcmp(RTA_DATA(rta[IFA_LOCAL - 1]),
 400                            &ifa->ifa_local, 4)) ||
 401                    (rta[IFA_LABEL - 1] &&
 402                     strcmp(RTA_DATA(rta[IFA_LABEL - 1]), ifa->ifa_label)) ||
 403                    (rta[IFA_ADDRESS - 1] &&
 404                     (ifm->ifa_prefixlen != ifa->ifa_prefixlen ||
 405                      !inet_ifa_match(*(u32*)RTA_DATA(rta[IFA_ADDRESS - 1]),
 406                                      ifa))))
 407                        continue;
 408                inet_del_ifa(in_dev, ifap, 1);
 409                return 0;
 410        }
 411out:
 412        return -EADDRNOTAVAIL;
 413}
 414
 415int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 416{
 417        struct rtattr **rta = arg;
 418        struct net_device *dev;
 419        struct in_device *in_dev;
 420        struct ifaddrmsg *ifm = NLMSG_DATA(nlh);
 421        struct in_ifaddr *ifa;
 422        int rc = -EINVAL;
 423
 424        ASSERT_RTNL();
 425
 426        if (ifm->ifa_prefixlen > 32 || !rta[IFA_LOCAL - 1])
 427                goto out;
 428
 429        rc = -ENODEV;
 430        if ((dev = __dev_get_by_index(ifm->ifa_index)) == NULL)
 431                goto out;
 432
 433        rc = -ENOBUFS;
 434        if ((in_dev = __in_dev_get(dev)) == NULL) {
 435                in_dev = inetdev_init(dev);
 436                if (!in_dev)
 437                        goto out;
 438        }
 439
 440        if ((ifa = inet_alloc_ifa()) == NULL)
 441                goto out;
 442
 443        if (!rta[IFA_ADDRESS - 1])
 444                rta[IFA_ADDRESS - 1] = rta[IFA_LOCAL - 1];
 445        memcpy(&ifa->ifa_local, RTA_DATA(rta[IFA_LOCAL - 1]), 4);
 446        memcpy(&ifa->ifa_address, RTA_DATA(rta[IFA_ADDRESS - 1]), 4);
 447        ifa->ifa_prefixlen = ifm->ifa_prefixlen;
 448        ifa->ifa_mask = inet_make_mask(ifm->ifa_prefixlen);
 449        if (rta[IFA_BROADCAST - 1])
 450                memcpy(&ifa->ifa_broadcast,
 451                       RTA_DATA(rta[IFA_BROADCAST - 1]), 4);
 452        if (rta[IFA_ANYCAST - 1])
 453                memcpy(&ifa->ifa_anycast, RTA_DATA(rta[IFA_ANYCAST - 1]), 4);
 454        ifa->ifa_flags = ifm->ifa_flags;
 455        ifa->ifa_scope = ifm->ifa_scope;
 456        in_dev_hold(in_dev);
 457        ifa->ifa_dev   = in_dev;
 458        if (rta[IFA_LABEL - 1])
 459                memcpy(ifa->ifa_label, RTA_DATA(rta[IFA_LABEL - 1]), IFNAMSIZ);
 460        else
 461                memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
 462
 463        rc = inet_insert_ifa(ifa);
 464out:
 465        return rc;
 466}
 467
 468/*
 469 *      Determine a default network mask, based on the IP address.
 470 */
 471
 472static __inline__ int inet_abc_len(u32 addr)
 473{
 474        int rc = -1;    /* Something else, probably a multicast. */
 475
 476        if (ZERONET(addr))
 477                rc = 0;
 478        else {
 479                addr = ntohl(addr);
 480
 481                if (IN_CLASSA(addr))
 482                        rc = 8;
 483                else if (IN_CLASSB(addr))
 484                        rc = 16;
 485                else if (IN_CLASSC(addr))
 486                        rc = 24;
 487        }
 488
 489        return rc;
 490}
 491
 492
 493int devinet_ioctl(unsigned int cmd, void __user *arg)
 494{
 495        struct ifreq ifr;
 496        struct sockaddr_in sin_orig;
 497        struct sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr;
 498        struct in_device *in_dev;
 499        struct in_ifaddr **ifap = NULL;
 500        struct in_ifaddr *ifa = NULL;
 501        struct net_device *dev;
 502        char *colon;
 503        int ret = -EFAULT;
 504        int tryaddrmatch = 0;
 505
 506        /*
 507         *      Fetch the caller's info block into kernel space
 508         */
 509
 510        if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
 511                goto out;
 512        ifr.ifr_name[IFNAMSIZ - 1] = 0;
 513
 514        /* save original address for comparison */
 515        memcpy(&sin_orig, sin, sizeof(*sin));
 516
 517        colon = strchr(ifr.ifr_name, ':');
 518        if (colon)
 519                *colon = 0;
 520
 521#ifdef CONFIG_KMOD
 522        dev_load(ifr.ifr_name);
 523#endif
 524
 525        switch(cmd) {
 526        case SIOCGIFADDR:       /* Get interface address */
 527        case SIOCGIFBRDADDR:    /* Get the broadcast address */
 528        case SIOCGIFDSTADDR:    /* Get the destination address */
 529        case SIOCGIFNETMASK:    /* Get the netmask for the interface */
 530                /* Note that these ioctls will not sleep,
 531                   so that we do not impose a lock.
 532                   One day we will be forced to put shlock here (I mean SMP)
 533                 */
 534                tryaddrmatch = (sin_orig.sin_family == AF_INET);
 535                memset(sin, 0, sizeof(*sin));
 536                sin->sin_family = AF_INET;
 537                break;
 538
 539        case SIOCSIFFLAGS:
 540                ret = -EACCES;
 541                if (!capable(CAP_NET_ADMIN))
 542                        goto out;
 543                break;
 544        case SIOCSIFADDR:       /* Set interface address (and family) */
 545        case SIOCSIFBRDADDR:    /* Set the broadcast address */
 546        case SIOCSIFDSTADDR:    /* Set the destination address */
 547        case SIOCSIFNETMASK:    /* Set the netmask for the interface */
 548                ret = -EACCES;
 549                if (!capable(CAP_NET_ADMIN))
 550                        goto out;
 551                ret = -EINVAL;
 552                if (sin->sin_family != AF_INET)
 553                        goto out;
 554                break;
 555        default:
 556                ret = -EINVAL;
 557                goto out;
 558        }
 559
 560        rtnl_lock();
 561
 562        ret = -ENODEV;
 563        if ((dev = __dev_get_by_name(ifr.ifr_name)) == NULL)
 564                goto done;
 565
 566        if (colon)
 567                *colon = ':';
 568
 569        if ((in_dev = __in_dev_get(dev)) != NULL) {
 570                if (tryaddrmatch) {
 571                        /* Matthias Andree */
 572                        /* compare label and address (4.4BSD style) */
 573                        /* note: we only do this for a limited set of ioctls
 574                           and only if the original address family was AF_INET.
 575                           This is checked above. */
 576                        for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
 577                             ifap = &ifa->ifa_next) {
 578                                if (!strcmp(ifr.ifr_name, ifa->ifa_label) &&
 579                                    sin_orig.sin_addr.s_addr ==
 580                                                        ifa->ifa_address) {
 581                                        break; /* found */
 582                                }
 583                        }
 584                }
 585                /* we didn't get a match, maybe the application is
 586                   4.3BSD-style and passed in junk so we fall back to
 587                   comparing just the label */
 588                if (!ifa) {
 589                        for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
 590                             ifap = &ifa->ifa_next)
 591                                if (!strcmp(ifr.ifr_name, ifa->ifa_label))
 592                                        break;
 593                }
 594        }
 595
 596        ret = -EADDRNOTAVAIL;
 597        if (!ifa && cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS)
 598                goto done;
 599
 600        switch(cmd) {
 601        case SIOCGIFADDR:       /* Get interface address */
 602                sin->sin_addr.s_addr = ifa->ifa_local;
 603                goto rarok;
 604
 605        case SIOCGIFBRDADDR:    /* Get the broadcast address */
 606                sin->sin_addr.s_addr = ifa->ifa_broadcast;
 607                goto rarok;
 608
 609        case SIOCGIFDSTADDR:    /* Get the destination address */
 610                sin->sin_addr.s_addr = ifa->ifa_address;
 611                goto rarok;
 612
 613        case SIOCGIFNETMASK:    /* Get the netmask for the interface */
 614                sin->sin_addr.s_addr = ifa->ifa_mask;
 615                goto rarok;
 616
 617        case SIOCSIFFLAGS:
 618                if (colon) {
 619                        ret = -EADDRNOTAVAIL;
 620                        if (!ifa)
 621                                break;
 622                        ret = 0;
 623                        if (!(ifr.ifr_flags & IFF_UP))
 624                                inet_del_ifa(in_dev, ifap, 1);
 625                        break;
 626                }
 627                ret = dev_change_flags(dev, ifr.ifr_flags);
 628                break;
 629
 630        case SIOCSIFADDR:       /* Set interface address (and family) */
 631                ret = -EINVAL;
 632                if (inet_abc_len(sin->sin_addr.s_addr) < 0)
 633                        break;
 634
 635                if (!ifa) {
 636                        ret = -ENOBUFS;
 637                        if ((ifa = inet_alloc_ifa()) == NULL)
 638                                break;
 639                        if (colon)
 640                                memcpy(ifa->ifa_label, ifr.ifr_name, IFNAMSIZ);
 641                        else
 642                                memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
 643                } else {
 644                        ret = 0;
 645                        if (ifa->ifa_local == sin->sin_addr.s_addr)
 646                                break;
 647                        inet_del_ifa(in_dev, ifap, 0);
 648                        ifa->ifa_broadcast = 0;
 649                        ifa->ifa_anycast = 0;
 650                }
 651
 652                ifa->ifa_address = ifa->ifa_local = sin->sin_addr.s_addr;
 653
 654                if (!(dev->flags & IFF_POINTOPOINT)) {
 655                        ifa->ifa_prefixlen = inet_abc_len(ifa->ifa_address);
 656                        ifa->ifa_mask = inet_make_mask(ifa->ifa_prefixlen);
 657                        if ((dev->flags & IFF_BROADCAST) &&
 658                            ifa->ifa_prefixlen < 31)
 659                                ifa->ifa_broadcast = ifa->ifa_address |
 660                                                     ~ifa->ifa_mask;
 661                } else {
 662                        ifa->ifa_prefixlen = 32;
 663                        ifa->ifa_mask = inet_make_mask(32);
 664                }
 665                ret = inet_set_ifa(dev, ifa);
 666                break;
 667
 668        case SIOCSIFBRDADDR:    /* Set the broadcast address */
 669                ret = 0;
 670                if (ifa->ifa_broadcast != sin->sin_addr.s_addr) {
 671                        inet_del_ifa(in_dev, ifap, 0);
 672                        ifa->ifa_broadcast = sin->sin_addr.s_addr;
 673                        inet_insert_ifa(ifa);
 674                }
 675                break;
 676
 677        case SIOCSIFDSTADDR:    /* Set the destination address */
 678                ret = 0;
 679                if (ifa->ifa_address == sin->sin_addr.s_addr)
 680                        break;
 681                ret = -EINVAL;
 682                if (inet_abc_len(sin->sin_addr.s_addr) < 0)
 683                        break;
 684                ret = 0;
 685                inet_del_ifa(in_dev, ifap, 0);
 686                ifa->ifa_address = sin->sin_addr.s_addr;
 687                inet_insert_ifa(ifa);
 688                break;
 689
 690        case SIOCSIFNETMASK:    /* Set the netmask for the interface */
 691
 692                /*
 693                 *      The mask we set must be legal.
 694                 */
 695                ret = -EINVAL;
 696                if (bad_mask(sin->sin_addr.s_addr, 0))
 697                        break;
 698                ret = 0;
 699                if (ifa->ifa_mask != sin->sin_addr.s_addr) {
 700                        inet_del_ifa(in_dev, ifap, 0);
 701                        ifa->ifa_mask = sin->sin_addr.s_addr;
 702                        ifa->ifa_prefixlen = inet_mask_len(ifa->ifa_mask);
 703
 704                        /* See if current broadcast address matches
 705                         * with current netmask, then recalculate
 706                         * the broadcast address. Otherwise it's a
 707                         * funny address, so don't touch it since
 708                         * the user seems to know what (s)he's doing...
 709                         */
 710                        if ((dev->flags & IFF_BROADCAST) &&
 711                            (ifa->ifa_prefixlen < 31) &&
 712                            (ifa->ifa_broadcast ==
 713                             (ifa->ifa_local|~ifa->ifa_mask))) {
 714                                ifa->ifa_broadcast = (ifa->ifa_local |
 715                                                      ~sin->sin_addr.s_addr);
 716                        }
 717                        inet_insert_ifa(ifa);
 718                }
 719                break;
 720        }
 721done:
 722        rtnl_unlock();
 723out:
 724        return ret;
 725rarok:
 726        rtnl_unlock();
 727        ret = copy_to_user(arg, &ifr, sizeof(struct ifreq)) ? -EFAULT : 0;
 728        goto out;
 729}
 730
 731static int inet_gifconf(struct net_device *dev, char __user *buf, int len)
 732{
 733        struct in_device *in_dev = __in_dev_get(dev);
 734        struct in_ifaddr *ifa;
 735        struct ifreq ifr;
 736        int done = 0;
 737
 738        if (!in_dev || (ifa = in_dev->ifa_list) == NULL)
 739                goto out;
 740
 741        for (; ifa; ifa = ifa->ifa_next) {
 742                if (!buf) {
 743                        done += sizeof(ifr);
 744                        continue;
 745                }
 746                if (len < (int) sizeof(ifr))
 747                        break;
 748                memset(&ifr, 0, sizeof(struct ifreq));
 749                if (ifa->ifa_label)
 750                        strcpy(ifr.ifr_name, ifa->ifa_label);
 751                else
 752                        strcpy(ifr.ifr_name, dev->name);
 753
 754                (*(struct sockaddr_in *)&ifr.ifr_addr).sin_family = AF_INET;
 755                (*(struct sockaddr_in *)&ifr.ifr_addr).sin_addr.s_addr =
 756                                                                ifa->ifa_local;
 757
 758                if (copy_to_user(buf, &ifr, sizeof(struct ifreq))) {
 759                        done = -EFAULT;
 760                        break;
 761                }
 762                buf  += sizeof(struct ifreq);
 763                len  -= sizeof(struct ifreq);
 764                done += sizeof(struct ifreq);
 765        }
 766out:
 767        return done;
 768}
 769
 770u32 inet_select_addr(const struct net_device *dev, u32 dst, int scope)
 771{
 772        u32 addr = 0;
 773        struct in_device *in_dev;
 774
 775        rcu_read_lock();
 776        in_dev = __in_dev_get(dev);
 777        if (!in_dev)
 778                goto no_in_dev;
 779
 780        for_primary_ifa(in_dev) {
 781                if (ifa->ifa_scope > scope)
 782                        continue;
 783                if (!dst || inet_ifa_match(dst, ifa)) {
 784                        addr = ifa->ifa_local;
 785                        break;
 786                }
 787                if (!addr)
 788                        addr = ifa->ifa_local;
 789        } endfor_ifa(in_dev);
 790no_in_dev:
 791        rcu_read_unlock();
 792
 793        if (addr)
 794                goto out;
 795
 796        /* Not loopback addresses on loopback should be preferred
 797           in this case. It is importnat that lo is the first interface
 798           in dev_base list.
 799         */
 800        read_lock(&dev_base_lock);
 801        rcu_read_lock();
 802        for (dev = dev_base; dev; dev = dev->next) {
 803                if ((in_dev = __in_dev_get(dev)) == NULL)
 804                        continue;
 805
 806                for_primary_ifa(in_dev) {
 807                        if (ifa->ifa_scope != RT_SCOPE_LINK &&
 808                            ifa->ifa_scope <= scope) {
 809                                addr = ifa->ifa_local;
 810                                goto out_unlock_both;
 811                        }
 812                } endfor_ifa(in_dev);
 813        }
 814out_unlock_both:
 815        read_unlock(&dev_base_lock);
 816        rcu_read_unlock();
 817out:
 818        return addr;
 819}
 820
 821static u32 confirm_addr_indev(struct in_device *in_dev, u32 dst,
 822                              u32 local, int scope)
 823{
 824        int same = 0;
 825        u32 addr = 0;
 826
 827        for_ifa(in_dev) {
 828                if (!addr &&
 829                    (local == ifa->ifa_local || !local) &&
 830                    ifa->ifa_scope <= scope) {
 831                        addr = ifa->ifa_local;
 832                        if (same)
 833                                break;
 834                }
 835                if (!same) {
 836                        same = (!local || inet_ifa_match(local, ifa)) &&
 837                                (!dst || inet_ifa_match(dst, ifa));
 838                        if (same && addr) {
 839                                if (local || !dst)
 840                                        break;
 841                                /* Is the selected addr into dst subnet? */
 842                                if (inet_ifa_match(addr, ifa))
 843                                        break;
 844                                /* No, then can we use new local src? */
 845                                if (ifa->ifa_scope <= scope) {
 846                                        addr = ifa->ifa_local;
 847                                        break;
 848                                }
 849                                /* search for large dst subnet for addr */
 850                                same = 0;
 851                        }
 852                }
 853        } endfor_ifa(in_dev);
 854
 855        return same? addr : 0;
 856}
 857
 858/*
 859 * Confirm that local IP address exists using wildcards:
 860 * - dev: only on this interface, 0=any interface
 861 * - dst: only in the same subnet as dst, 0=any dst
 862 * - local: address, 0=autoselect the local address
 863 * - scope: maximum allowed scope value for the local address
 864 */
 865u32 inet_confirm_addr(const struct net_device *dev, u32 dst, u32 local, int scope)
 866{
 867        u32 addr = 0;
 868        struct in_device *in_dev;
 869
 870        if (dev) {
 871                rcu_read_lock();
 872                if ((in_dev = __in_dev_get(dev)))
 873                        addr = confirm_addr_indev(in_dev, dst, local, scope);
 874                rcu_read_unlock();
 875
 876                return addr;
 877        }
 878
 879        read_lock(&dev_base_lock);
 880        rcu_read_lock();
 881        for (dev = dev_base; dev; dev = dev->next) {
 882                if ((in_dev = __in_dev_get(dev))) {
 883                        addr = confirm_addr_indev(in_dev, dst, local, scope);
 884                        if (addr)
 885                                break;
 886                }
 887        }
 888        rcu_read_unlock();
 889        read_unlock(&dev_base_lock);
 890
 891        return addr;
 892}
 893
 894/*
 895 *      Device notifier
 896 */
 897
 898int register_inetaddr_notifier(struct notifier_block *nb)
 899{
 900        return notifier_chain_register(&inetaddr_chain, nb);
 901}
 902
 903int unregister_inetaddr_notifier(struct notifier_block *nb)
 904{
 905        return notifier_chain_unregister(&inetaddr_chain, nb);
 906}
 907
 908/* Rename ifa_labels for a device name change. Make some effort to preserve existing
 909 * alias numbering and to create unique labels if possible.
 910*/
 911static void inetdev_changename(struct net_device *dev, struct in_device *in_dev)
 912{ 
 913        struct in_ifaddr *ifa;
 914        int named = 0;
 915
 916        for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) { 
 917                char old[IFNAMSIZ], *dot; 
 918
 919                memcpy(old, ifa->ifa_label, IFNAMSIZ);
 920                memcpy(ifa->ifa_label, dev->name, IFNAMSIZ); 
 921                if (named++ == 0)
 922                        continue;
 923                dot = strchr(ifa->ifa_label, ':');
 924                if (dot == NULL) { 
 925                        sprintf(old, ":%d", named); 
 926                        dot = old;
 927                }
 928                if (strlen(dot) + strlen(dev->name) < IFNAMSIZ) { 
 929                        strcat(ifa->ifa_label, dot); 
 930                } else { 
 931                        strcpy(ifa->ifa_label + (IFNAMSIZ - strlen(dot) - 1), dot); 
 932                } 
 933        }       
 934} 
 935
 936/* Called only under RTNL semaphore */
 937
 938static int inetdev_event(struct notifier_block *this, unsigned long event,
 939                         void *ptr)
 940{
 941        struct net_device *dev = ptr;
 942        struct in_device *in_dev = __in_dev_get(dev);
 943
 944        ASSERT_RTNL();
 945
 946        if (!in_dev)
 947                goto out;
 948
 949        switch (event) {
 950        case NETDEV_REGISTER:
 951                printk(KERN_DEBUG "inetdev_event: bug\n");
 952                dev->ip_ptr = NULL;
 953                break;
 954        case NETDEV_UP:
 955                if (dev->mtu < 68)
 956                        break;
 957                if (dev == &loopback_dev) {
 958                        struct in_ifaddr *ifa;
 959                        if ((ifa = inet_alloc_ifa()) != NULL) {
 960                                ifa->ifa_local =
 961                                  ifa->ifa_address = htonl(INADDR_LOOPBACK);
 962                                ifa->ifa_prefixlen = 8;
 963                                ifa->ifa_mask = inet_make_mask(8);
 964                                in_dev_hold(in_dev);
 965                                ifa->ifa_dev = in_dev;
 966                                ifa->ifa_scope = RT_SCOPE_HOST;
 967                                memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
 968                                inet_insert_ifa(ifa);
 969                        }
 970                        in_dev->cnf.no_xfrm = 1;
 971                        in_dev->cnf.no_policy = 1;
 972                }
 973                ip_mc_up(in_dev);
 974                break;
 975        case NETDEV_DOWN:
 976                ip_mc_down(in_dev);
 977                break;
 978        case NETDEV_CHANGEMTU:
 979                if (dev->mtu >= 68)
 980                        break;
 981                /* MTU falled under 68, disable IP */
 982        case NETDEV_UNREGISTER:
 983                inetdev_destroy(in_dev);
 984                break;
 985        case NETDEV_CHANGENAME:
 986                /* Do not notify about label change, this event is
 987                 * not interesting to applications using netlink.
 988                 */
 989                inetdev_changename(dev, in_dev);
 990
 991#ifdef CONFIG_SYSCTL
 992                devinet_sysctl_unregister(&in_dev->cnf);
 993                neigh_sysctl_unregister(in_dev->arp_parms);
 994                neigh_sysctl_register(dev, in_dev->arp_parms, NET_IPV4,
 995                                      NET_IPV4_NEIGH, "ipv4", NULL);
 996                devinet_sysctl_register(in_dev, &in_dev->cnf);
 997#endif
 998                break;
 999        }
1000out:
1001        return NOTIFY_DONE;
1002}
1003
1004static struct notifier_block ip_netdev_notifier = {
1005        .notifier_call =inetdev_event,
1006};
1007
1008static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
1009                            u32 pid, u32 seq, int event)
1010{
1011        struct ifaddrmsg *ifm;
1012        struct nlmsghdr  *nlh;
1013        unsigned char    *b = skb->tail;
1014
1015        nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm));
1016        if (pid) nlh->nlmsg_flags |= NLM_F_MULTI;
1017        ifm = NLMSG_DATA(nlh);
1018        ifm->ifa_family = AF_INET;
1019        ifm->ifa_prefixlen = ifa->ifa_prefixlen;
1020        ifm->ifa_flags = ifa->ifa_flags|IFA_F_PERMANENT;
1021        ifm->ifa_scope = ifa->ifa_scope;
1022        ifm->ifa_index = ifa->ifa_dev->dev->ifindex;
1023        if (ifa->ifa_address)
1024                RTA_PUT(skb, IFA_ADDRESS, 4, &ifa->ifa_address);
1025        if (ifa->ifa_local)
1026                RTA_PUT(skb, IFA_LOCAL, 4, &ifa->ifa_local);
1027        if (ifa->ifa_broadcast)
1028                RTA_PUT(skb, IFA_BROADCAST, 4, &ifa->ifa_broadcast);
1029        if (ifa->ifa_anycast)
1030                RTA_PUT(skb, IFA_ANYCAST, 4, &ifa->ifa_anycast);
1031        if (ifa->ifa_label[0])
1032                RTA_PUT(skb, IFA_LABEL, IFNAMSIZ, &ifa->ifa_label);
1033        nlh->nlmsg_len = skb->tail - b;
1034        return skb->len;
1035
1036nlmsg_failure:
1037rtattr_failure:
1038        skb_trim(skb, b - skb->data);
1039        return -1;
1040}
1041
1042static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
1043{
1044        int idx, ip_idx;
1045        struct net_device *dev;
1046        struct in_device *in_dev;
1047        struct in_ifaddr *ifa;
1048        int s_ip_idx, s_idx = cb->args[0];
1049
1050        s_ip_idx = ip_idx = cb->args[1];
1051        read_lock(&dev_base_lock);
1052        for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) {
1053                if (idx < s_idx)
1054                        continue;
1055                if (idx > s_idx)
1056                        s_ip_idx = 0;
1057                rcu_read_lock();
1058                if ((in_dev = __in_dev_get(dev)) == NULL) {
1059                        rcu_read_unlock();
1060                        continue;
1061                }
1062
1063                for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
1064                     ifa = ifa->ifa_next, ip_idx++) {
1065                        if (ip_idx < s_ip_idx)
1066                                continue;
1067                        if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
1068                                             cb->nlh->nlmsg_seq,
1069                                             RTM_NEWADDR) <= 0) {
1070                                rcu_read_unlock();
1071                                goto done;
1072                        }
1073                }
1074                rcu_read_unlock();
1075        }
1076
1077done:
1078        read_unlock(&dev_base_lock);
1079        cb->args[0] = idx;
1080        cb->args[1] = ip_idx;
1081
1082        return skb->len;
1083}
1084
1085static void rtmsg_ifa(int event, struct in_ifaddr* ifa)
1086{
1087        int size = NLMSG_SPACE(sizeof(struct ifaddrmsg) + 128);
1088        struct sk_buff *skb = alloc_skb(size, GFP_KERNEL);
1089
1090        if (!skb)
1091                netlink_set_err(rtnl, 0, RTMGRP_IPV4_IFADDR, ENOBUFS);
1092        else if (inet_fill_ifaddr(skb, ifa, 0, 0, event) < 0) {
1093                kfree_skb(skb);
1094                netlink_set_err(rtnl, 0, RTMGRP_IPV4_IFADDR, EINVAL);
1095        } else {
1096                NETLINK_CB(skb).dst_groups = RTMGRP_IPV4_IFADDR;
1097                netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV4_IFADDR, GFP_KERNEL);
1098        }
1099}
1100
1101static struct rtnetlink_link inet_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = {
1102         [4] = { .doit   = inet_rtm_newaddr,  },
1103         [5] = { .doit   = inet_rtm_deladdr,  },
1104         [6] = { .dumpit = inet_dump_ifaddr,  },
1105         [8] = { .doit   = inet_rtm_newroute, },
1106         [9] = { .doit   = inet_rtm_delroute, },
1107        [10] = { .doit   = inet_rtm_getroute, .dumpit = inet_dump_fib, },
1108#ifdef CONFIG_IP_MULTIPLE_TABLES
1109        [16] = { .doit   = inet_rtm_newrule, },
1110        [17] = { .doit   = inet_rtm_delrule, },
1111        [18] = { .dumpit = inet_dump_rules,  },
1112#endif
1113};
1114
1115#ifdef CONFIG_SYSCTL
1116
1117void inet_forward_change(void)
1118{
1119        struct net_device *dev;
1120        int on = ipv4_devconf.forwarding;
1121
1122        ipv4_devconf.accept_redirects = !on;
1123        ipv4_devconf_dflt.forwarding = on;
1124
1125        read_lock(&dev_base_lock);
1126        for (dev = dev_base; dev; dev = dev->next) {
1127                struct in_device *in_dev;
1128                rcu_read_lock();
1129                in_dev = __in_dev_get(dev);
1130                if (in_dev)
1131                        in_dev->cnf.forwarding = on;
1132                rcu_read_unlock();
1133        }
1134        read_unlock(&dev_base_lock);
1135
1136        rt_cache_flush(0);
1137}
1138
1139static int devinet_sysctl_forward(ctl_table *ctl, int write,
1140                                  struct file* filp, void __user *buffer,
1141                                  size_t *lenp, loff_t *ppos)
1142{
1143        int *valp = ctl->data;
1144        int val = *valp;
1145        int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
1146
1147        if (write && *valp != val) {
1148                if (valp == &ipv4_devconf.forwarding)
1149                        inet_forward_change();
1150                else if (valp != &ipv4_devconf_dflt.forwarding)
1151                        rt_cache_flush(0);
1152        }
1153
1154        return ret;
1155}
1156
1157int ipv4_doint_and_flush(ctl_table *ctl, int write,
1158                         struct file* filp, void __user *buffer,
1159                         size_t *lenp, loff_t *ppos)
1160{
1161        int *valp = ctl->data;
1162        int val = *valp;
1163        int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
1164
1165        if (write && *valp != val)
1166                rt_cache_flush(0);
1167
1168        return ret;
1169}
1170
1171int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen,
1172                                  void __user *oldval, size_t __user *oldlenp,
1173                                  void __user *newval, size_t newlen, 
1174                                  void **context)
1175{
1176        int *valp = table->data;
1177        int new;
1178
1179        if (!newval || !newlen)
1180                return 0;
1181
1182        if (newlen != sizeof(int))
1183                return -EINVAL;
1184
1185        if (get_user(new, (int __user *)newval))
1186                return -EFAULT;
1187
1188        if (new == *valp)
1189                return 0;
1190
1191        if (oldval && oldlenp) {
1192                size_t len;
1193
1194                if (get_user(len, oldlenp))
1195                        return -EFAULT;
1196
1197                if (len) {
1198                        if (len > table->maxlen)
1199                                len = table->maxlen;
1200                        if (copy_to_user(oldval, valp, len))
1201                                return -EFAULT;
1202                        if (put_user(len, oldlenp))
1203                                return -EFAULT;
1204                }
1205        }
1206
1207        *valp = new;
1208        rt_cache_flush(0);
1209        return 1;
1210}
1211
1212
1213static struct devinet_sysctl_table {
1214        struct ctl_table_header *sysctl_header;
1215        ctl_table               devinet_vars[20];
1216        ctl_table               devinet_dev[2];
1217        ctl_table               devinet_conf_dir[2];
1218        ctl_table               devinet_proto_dir[2];
1219        ctl_table               devinet_root_dir[2];
1220} devinet_sysctl = {
1221        .devinet_vars = {
1222                {
1223                        .ctl_name       = NET_IPV4_CONF_FORWARDING,
1224                        .procname       = "forwarding",
1225                        .data           = &ipv4_devconf.forwarding,
1226                        .maxlen         = sizeof(int),
1227                        .mode           = 0644,
1228                        .proc_handler   = &devinet_sysctl_forward,
1229                },
1230                {
1231                        .ctl_name       = NET_IPV4_CONF_MC_FORWARDING,
1232                        .procname       = "mc_forwarding",
1233                        .data           = &ipv4_devconf.mc_forwarding,
1234                        .maxlen         = sizeof(int),
1235                        .mode           = 0444,
1236                        .proc_handler   = &proc_dointvec,
1237                },
1238                {
1239                        .ctl_name       = NET_IPV4_CONF_ACCEPT_REDIRECTS,
1240                        .procname       = "accept_redirects",
1241                        .data           = &ipv4_devconf.accept_redirects,
1242                        .maxlen         = sizeof(int),
1243                        .mode           = 0644,
1244                        .proc_handler   = &proc_dointvec,
1245                },
1246                {
1247                        .ctl_name       = NET_IPV4_CONF_SECURE_REDIRECTS,
1248                        .procname       = "secure_redirects",
1249                        .data           = &ipv4_devconf.secure_redirects,
1250                        .maxlen         = sizeof(int),
1251                        .mode           = 0644,
1252                        .proc_handler   = &proc_dointvec,
1253                },
1254                {
1255                        .ctl_name       = NET_IPV4_CONF_SHARED_MEDIA,
1256                        .procname       = "shared_media",
1257                        .data           = &ipv4_devconf.shared_media,
1258                        .maxlen         = sizeof(int),
1259                        .mode           = 0644,
1260                        .proc_handler   = &proc_dointvec,
1261                },
1262                {
1263                        .ctl_name       = NET_IPV4_CONF_RP_FILTER,
1264                        .procname       = "rp_filter",
1265                        .data           = &ipv4_devconf.rp_filter,
1266                        .maxlen         = sizeof(int),
1267                        .mode           = 0644,
1268                        .proc_handler   = &proc_dointvec,
1269                },
1270                {
1271                        .ctl_name       = NET_IPV4_CONF_SEND_REDIRECTS,
1272                        .procname       = "send_redirects",
1273                        .data           = &ipv4_devconf.send_redirects,
1274                        .maxlen         = sizeof(int),
1275                        .mode           = 0644,
1276                        .proc_handler   = &proc_dointvec,
1277                },
1278                {
1279                        .ctl_name       = NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE,
1280                        .procname       = "accept_source_route",
1281                        .data           = &ipv4_devconf.accept_source_route,
1282                        .maxlen         = sizeof(int),
1283                        .mode           = 0644,
1284                        .proc_handler   = &proc_dointvec,
1285                },
1286                {
1287                        .ctl_name       = NET_IPV4_CONF_PROXY_ARP,
1288                        .procname       = "proxy_arp",
1289                        .data           = &ipv4_devconf.proxy_arp,
1290                        .maxlen         = sizeof(int),
1291                        .mode           = 0644,
1292                        .proc_handler   = &proc_dointvec,
1293                },
1294                {
1295                        .ctl_name       = NET_IPV4_CONF_MEDIUM_ID,
1296                        .procname       = "medium_id",
1297                        .data           = &ipv4_devconf.medium_id,
1298                        .maxlen         = sizeof(int),
1299                        .mode           = 0644,
1300                        .proc_handler   = &proc_dointvec,
1301                },
1302                {
1303                        .ctl_name       = NET_IPV4_CONF_BOOTP_RELAY,
1304                        .procname       = "bootp_relay",
1305                        .data           = &ipv4_devconf.bootp_relay,
1306                        .maxlen         = sizeof(int),
1307                        .mode           = 0644,
1308                        .proc_handler   = &proc_dointvec,
1309                },
1310                {
1311                        .ctl_name       = NET_IPV4_CONF_LOG_MARTIANS,
1312                        .procname       = "log_martians",
1313                        .data           = &ipv4_devconf.log_martians,
1314                        .maxlen         = sizeof(int),
1315                        .mode           = 0644,
1316                        .proc_handler   = &proc_dointvec,
1317                },
1318                {
1319                        .ctl_name       = NET_IPV4_CONF_TAG,
1320                        .procname       = "tag",
1321                        .data           = &ipv4_devconf.tag,
1322                        .maxlen         = sizeof(int),
1323                        .mode           = 0644,
1324                        .proc_handler   = &proc_dointvec,
1325                },
1326                {
1327                        .ctl_name       = NET_IPV4_CONF_ARPFILTER,
1328                        .procname       = "arp_filter",
1329                        .data           = &ipv4_devconf.arp_filter,
1330                        .maxlen         = sizeof(int),
1331                        .mode           = 0644,
1332                        .proc_handler   = &proc_dointvec,
1333                },
1334                {
1335                        .ctl_name       = NET_IPV4_CONF_ARP_ANNOUNCE,
1336                        .procname       = "arp_announce",
1337                        .data           = &ipv4_devconf.arp_announce,
1338                        .maxlen         = sizeof(int),
1339                        .mode           = 0644,
1340                        .proc_handler   = &proc_dointvec,
1341                },
1342                {
1343                        .ctl_name       = NET_IPV4_CONF_ARP_IGNORE,
1344                        .procname       = "arp_ignore",
1345                        .data           = &ipv4_devconf.arp_ignore,
1346                        .maxlen         = sizeof(int),
1347                        .mode           = 0644,
1348                        .proc_handler   = &proc_dointvec,
1349                },
1350                {
1351                        .ctl_name       = NET_IPV4_CONF_NOXFRM,
1352                        .procname       = "disable_xfrm",
1353                        .data           = &ipv4_devconf.no_xfrm,
1354                        .maxlen         = sizeof(int),
1355                        .mode           = 0644,
1356                        .proc_handler   = &ipv4_doint_and_flush,
1357                        .strategy       = &ipv4_doint_and_flush_strategy,
1358                },
1359                {
1360                        .ctl_name       = NET_IPV4_CONF_NOPOLICY,
1361                        .procname       = "disable_policy",
1362                        .data           = &ipv4_devconf.no_policy,
1363                        .maxlen         = sizeof(int),
1364                        .mode           = 0644,
1365                        .proc_handler   = &ipv4_doint_and_flush,
1366                        .strategy       = &ipv4_doint_and_flush_strategy,
1367                },
1368                {
1369                        .ctl_name       = NET_IPV4_CONF_FORCE_IGMP_VERSION,
1370                        .procname       = "force_igmp_version",
1371                        .data           = &ipv4_devconf.force_igmp_version,
1372                        .maxlen         = sizeof(int),
1373                        .mode           = 0644,
1374                        .proc_handler   = &ipv4_doint_and_flush,
1375                        .strategy       = &ipv4_doint_and_flush_strategy,
1376                },
1377        },
1378        .devinet_dev = {
1379                {
1380                        .ctl_name       = NET_PROTO_CONF_ALL,
1381                        .procname       = "all",
1382                        .mode           = 0555,
1383                        .child          = devinet_sysctl.devinet_vars,
1384                },
1385        },
1386        .devinet_conf_dir = {
1387                {
1388                        .ctl_name       = NET_IPV4_CONF,
1389                        .procname       = "conf",
1390                        .mode           = 0555,
1391                        .child          = devinet_sysctl.devinet_dev,
1392                },
1393        },
1394        .devinet_proto_dir = {
1395                {
1396                        .ctl_name       = NET_IPV4,
1397                        .procname       = "ipv4",
1398                        .mode           = 0555,
1399                        .child          = devinet_sysctl.devinet_conf_dir,
1400                },
1401        },
1402        .devinet_root_dir = {
1403                {
1404                        .ctl_name       = CTL_NET,
1405                        .procname       = "net",
1406                        .mode           = 0555,
1407                        .child          = devinet_sysctl.devinet_proto_dir,
1408                },
1409        },
1410};
1411
1412static void devinet_sysctl_register(struct in_device *in_dev,
1413                                    struct ipv4_devconf *p)
1414{
1415        int i;
1416        struct net_device *dev = in_dev ? in_dev->dev : NULL;
1417        struct devinet_sysctl_table *t = kmalloc(sizeof(*t), GFP_KERNEL);
1418        char *dev_name = NULL;
1419
1420        if (!t)
1421                return;
1422        memcpy(t, &devinet_sysctl, sizeof(*t));
1423        for (i = 0; i < ARRAY_SIZE(t->devinet_vars) - 1; i++) {
1424                t->devinet_vars[i].data += (char *)p - (char *)&ipv4_devconf;
1425                t->devinet_vars[i].de = NULL;
1426        }
1427
1428        if (dev) {
1429                dev_name = dev->name; 
1430                t->devinet_dev[0].ctl_name = dev->ifindex;
1431        } else {
1432                dev_name = "default";
1433                t->devinet_dev[0].ctl_name = NET_PROTO_CONF_DEFAULT;
1434        }
1435
1436        /* 
1437         * Make a copy of dev_name, because '.procname' is regarded as const 
1438         * by sysctl and we wouldn't want anyone to change it under our feet
1439         * (see SIOCSIFNAME).
1440         */     
1441        dev_name = net_sysctl_strdup(dev_name);
1442        if (!dev_name)
1443            goto free;
1444
1445        t->devinet_dev[0].procname    = dev_name;
1446        t->devinet_dev[0].child       = t->devinet_vars;
1447        t->devinet_dev[0].de          = NULL;
1448        t->devinet_conf_dir[0].child  = t->devinet_dev;
1449        t->devinet_conf_dir[0].de     = NULL;
1450        t->devinet_proto_dir[0].child = t->devinet_conf_dir;
1451        t->devinet_proto_dir[0].de    = NULL;
1452        t->devinet_root_dir[0].child  = t->devinet_proto_dir;
1453        t->devinet_root_dir[0].de     = NULL;
1454
1455        t->sysctl_header = register_sysctl_table(t->devinet_root_dir, 0);
1456        if (!t->sysctl_header)
1457            goto free_procname;
1458
1459        p->sysctl = t;
1460        return;
1461
1462        /* error path */
1463 free_procname:
1464        kfree(dev_name);
1465 free:
1466        kfree(t);
1467        return;
1468}
1469
1470static void devinet_sysctl_unregister(struct ipv4_devconf *p)
1471{
1472        if (p->sysctl) {
1473                struct devinet_sysctl_table *t = p->sysctl;
1474                p->sysctl = NULL;
1475                unregister_sysctl_table(t->sysctl_header);
1476                kfree(t->devinet_dev[0].procname);
1477                kfree(t);
1478        }
1479}
1480#endif
1481
1482void __init devinet_init(void)
1483{
1484        register_gifconf(PF_INET, inet_gifconf);
1485        register_netdevice_notifier(&ip_netdev_notifier);
1486        rtnetlink_links[PF_INET] = inet_rtnetlink_table;
1487#ifdef CONFIG_SYSCTL
1488        devinet_sysctl.sysctl_header =
1489                register_sysctl_table(devinet_sysctl.devinet_root_dir, 0);
1490        devinet_sysctl_register(NULL, &ipv4_devconf_dflt);
1491#endif
1492}
1493
1494EXPORT_SYMBOL(devinet_ioctl);
1495EXPORT_SYMBOL(in_dev_finish_destroy);
1496EXPORT_SYMBOL(inet_select_addr);
1497EXPORT_SYMBOL(inetdev_by_index);
1498EXPORT_SYMBOL(register_inetaddr_notifier);
1499EXPORT_SYMBOL(unregister_inetaddr_notifier);
1500
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.