00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
#include <linux/config.h>
00030
00031
#include <asm/uaccess.h>
00032
#include <asm/system.h>
00033
#include <asm/bitops.h>
00034
#include <linux/types.h>
00035
#include <linux/kernel.h>
00036
#include <linux/sched.h>
00037
#include <linux/string.h>
00038
#include <linux/mm.h>
00039
#include <linux/socket.h>
00040
#include <linux/sockios.h>
00041
#include <linux/in.h>
00042
#include <linux/errno.h>
00043
#include <linux/interrupt.h>
00044
#include <linux/if_ether.h>
00045
#include <linux/inet.h>
00046
#include <linux/netdevice.h>
00047
#include <linux/etherdevice.h>
00048
#include <linux/skbuff.h>
00049
#include <linux/rtnetlink.h>
00050
#include <linux/init.h>
00051
#include <linux/notifier.h>
00052
#include <linux/inetdevice.h>
00053
#include <linux/igmp.h>
00054
#ifdef CONFIG_SYSCTL
00055
#include <linux/sysctl.h>
00056
#endif
00057
#include <linux/kmod.h>
00058
00059
#include <net/ip.h>
00060
#include <net/route.h>
00061
#include <net/ip_fib.h>
00062
00063 struct ipv4_devconf ipv4_devconf = { 1, 1, 1, 1, 0, };
00064 static struct ipv4_devconf ipv4_devconf_dflt = { 1, 1, 1, 1, 1, };
00065
00066
static void rtmsg_ifa(
int event,
struct in_ifaddr *);
00067
00068 static struct notifier_block *
inetaddr_chain;
00069
static void inet_del_ifa(
struct in_device *in_dev,
struct in_ifaddr **ifap,
int destroy);
00070
#ifdef CONFIG_SYSCTL
00071
static void devinet_sysctl_register(
struct in_device *in_dev,
struct ipv4_devconf *p);
00072
static void devinet_sysctl_unregister(
struct ipv4_devconf *p);
00073
#endif
00074
00075 int inet_ifa_count;
00076 int inet_dev_count;
00077
00078
00079
00080 rwlock_t
inetdev_lock = RW_LOCK_UNLOCKED;
00081
00082
00083 static struct in_ifaddr *
inet_alloc_ifa(
void)
00084 {
00085
struct in_ifaddr *ifa;
00086
00087 ifa = kmalloc(
sizeof(*ifa), GFP_KERNEL);
00088
if (ifa) {
00089 memset(ifa, 0,
sizeof(*ifa));
00090
inet_ifa_count++;
00091 }
00092
00093
return ifa;
00094 }
00095
00096 static __inline__
void inet_free_ifa(
struct in_ifaddr *ifa)
00097 {
00098
if (ifa->
ifa_dev)
00099
__in_dev_put(ifa->
ifa_dev);
00100 kfree(ifa);
00101
inet_ifa_count--;
00102 }
00103
00104 void in_dev_finish_destroy(
struct in_device *idev)
00105 {
00106
struct net_device *dev = idev->
dev;
00107
00108 BUG_TRAP(idev->
ifa_list==NULL);
00109 BUG_TRAP(idev->
mc_list==NULL);
00110
#ifdef NET_REFCNT_DEBUG
00111
printk(KERN_DEBUG
"in_dev_finish_destroy: %p=%s\n", idev, dev ? dev->name :
"NIL");
00112
#endif
00113
dev_put(dev);
00114
if (!idev->
dead) {
00115 printk(
"Freeing alive in_device %p\n", idev);
00116
return;
00117 }
00118
inet_dev_count--;
00119 kfree(idev);
00120 }
00121
00122 struct in_device *
inetdev_init(
struct net_device *dev)
00123 {
00124
struct in_device *in_dev;
00125
00126 ASSERT_RTNL();
00127
00128 in_dev = kmalloc(
sizeof(*in_dev), GFP_KERNEL);
00129
if (!in_dev)
00130
return NULL;
00131 memset(in_dev, 0,
sizeof(*in_dev));
00132 in_dev->lock = RW_LOCK_UNLOCKED;
00133 memcpy(&in_dev->cnf, &
ipv4_devconf_dflt,
sizeof(in_dev->cnf));
00134 in_dev->cnf.sysctl = NULL;
00135 in_dev->dev = dev;
00136
if ((in_dev->arp_parms =
neigh_parms_alloc(dev, &
arp_tbl)) == NULL) {
00137 kfree(in_dev);
00138
return NULL;
00139 }
00140
inet_dev_count++;
00141
00142
dev_hold(dev);
00143
#ifdef CONFIG_SYSCTL
00144
neigh_sysctl_register(dev, in_dev->arp_parms, NET_IPV4, NET_IPV4_NEIGH,
"ipv4");
00145
#endif
00146
write_lock_bh(&
inetdev_lock);
00147 dev->
ip_ptr = in_dev;
00148
00149
in_dev_hold(in_dev);
00150 write_unlock_bh(&
inetdev_lock);
00151
#ifdef CONFIG_SYSCTL
00152
devinet_sysctl_register(in_dev, &in_dev->cnf);
00153
#endif
00154
if (dev->
flags&IFF_UP)
00155
ip_mc_up(in_dev);
00156
return in_dev;
00157 }
00158
00159 static void inetdev_destroy(
struct in_device *in_dev)
00160 {
00161
struct in_ifaddr *ifa;
00162
00163 ASSERT_RTNL();
00164
00165 in_dev->
dead = 1;
00166
00167
ip_mc_destroy_dev(in_dev);
00168
00169
while ((ifa = in_dev->
ifa_list) != NULL) {
00170
inet_del_ifa(in_dev, &in_dev->
ifa_list, 0);
00171
inet_free_ifa(ifa);
00172 }
00173
00174
#ifdef CONFIG_SYSCTL
00175
devinet_sysctl_unregister(&in_dev->
cnf);
00176
#endif
00177
write_lock_bh(&
inetdev_lock);
00178 in_dev->
dev->
ip_ptr = NULL;
00179
00180 write_unlock_bh(&
inetdev_lock);
00181
00182
00183
neigh_parms_release(&
arp_tbl, in_dev->
arp_parms);
00184
in_dev_put(in_dev);
00185 }
00186
00187 int inet_addr_onlink(
struct in_device *in_dev, u32 a, u32 b)
00188 {
00189 read_lock(&in_dev->
lock);
00190
for_primary_ifa(in_dev) {
00191
if (
inet_ifa_match(a, ifa)) {
00192
if (!b ||
inet_ifa_match(b, ifa)) {
00193 read_unlock(&in_dev->
lock);
00194
return 1;
00195 }
00196 }
00197 }
endfor_ifa(in_dev);
00198 read_unlock(&in_dev->
lock);
00199
return 0;
00200 }
00201
00202
static void
00203 inet_del_ifa(
struct in_device *in_dev,
struct in_ifaddr **ifap,
int destroy)
00204 {
00205
struct in_ifaddr *ifa1 = *ifap;
00206
00207 ASSERT_RTNL();
00208
00209
00210
00211
if (!(ifa1->ifa_flags&IFA_F_SECONDARY)) {
00212
struct in_ifaddr *ifa;
00213
struct in_ifaddr **ifap1 = &ifa1->ifa_next;
00214
00215
while ((ifa=*ifap1) != NULL) {
00216
if (!(ifa->ifa_flags&IFA_F_SECONDARY) ||
00217 ifa1->ifa_mask != ifa->ifa_mask ||
00218 !
inet_ifa_match(ifa1->ifa_address, ifa)) {
00219 ifap1 = &ifa->ifa_next;
00220
continue;
00221 }
00222 write_lock_bh(&in_dev->
lock);
00223 *ifap1 = ifa->ifa_next;
00224 write_unlock_bh(&in_dev->
lock);
00225
00226
rtmsg_ifa(RTM_DELADDR, ifa);
00227 notifier_call_chain(&
inetaddr_chain, NETDEV_DOWN, ifa);
00228
inet_free_ifa(ifa);
00229 }
00230 }
00231
00232
00233
00234 write_lock_bh(&in_dev->
lock);
00235 *ifap = ifa1->ifa_next;
00236 write_unlock_bh(&in_dev->
lock);
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
rtmsg_ifa(RTM_DELADDR, ifa1);
00249 notifier_call_chain(&
inetaddr_chain, NETDEV_DOWN, ifa1);
00250
if (destroy) {
00251
inet_free_ifa(ifa1);
00252
00253
if (in_dev->
ifa_list == NULL)
00254
inetdev_destroy(in_dev);
00255 }
00256 }
00257
00258
static int
00259 inet_insert_ifa(
struct in_ifaddr *ifa)
00260 {
00261
struct in_device *in_dev = ifa->
ifa_dev;
00262
struct in_ifaddr *ifa1, **ifap, **last_primary;
00263
00264 ASSERT_RTNL();
00265
00266
if (ifa->
ifa_local == 0) {
00267
inet_free_ifa(ifa);
00268
return 0;
00269 }
00270
00271 ifa->
ifa_flags &= ~IFA_F_SECONDARY;
00272 last_primary = &in_dev->ifa_list;
00273
00274
for (ifap=&in_dev->ifa_list; (ifa1=*ifap)!=NULL; ifap=&ifa1->ifa_next) {
00275
if (!(ifa1->ifa_flags&IFA_F_SECONDARY) && ifa->
ifa_scope <= ifa1->ifa_scope)
00276 last_primary = &ifa1->ifa_next;
00277
if (ifa1->ifa_mask == ifa->
ifa_mask &&
inet_ifa_match(ifa1->ifa_address, ifa)) {
00278
if (ifa1->ifa_local == ifa->
ifa_local) {
00279
inet_free_ifa(ifa);
00280
return -EEXIST;
00281 }
00282
if (ifa1->ifa_scope != ifa->
ifa_scope) {
00283
inet_free_ifa(ifa);
00284
return -EINVAL;
00285 }
00286 ifa->
ifa_flags |= IFA_F_SECONDARY;
00287 }
00288 }
00289
00290
if (!(ifa->
ifa_flags&IFA_F_SECONDARY)) {
00291
net_srandom(ifa->
ifa_local);
00292 ifap = last_primary;
00293 }
00294
00295 ifa->
ifa_next = *ifap;
00296 write_lock_bh(&in_dev->lock);
00297 *ifap = ifa;
00298 write_unlock_bh(&in_dev->lock);
00299
00300
00301
00302
00303
rtmsg_ifa(RTM_NEWADDR, ifa);
00304 notifier_call_chain(&
inetaddr_chain, NETDEV_UP, ifa);
00305
00306
return 0;
00307 }
00308
00309
static int
00310 inet_set_ifa(
struct net_device *dev,
struct in_ifaddr *ifa)
00311 {
00312
struct in_device *in_dev =
__in_dev_get(dev);
00313
00314 ASSERT_RTNL();
00315
00316
if (in_dev == NULL) {
00317 in_dev =
inetdev_init(dev);
00318
if (in_dev == NULL) {
00319
inet_free_ifa(ifa);
00320
return -ENOBUFS;
00321 }
00322 }
00323
if (ifa->
ifa_dev != in_dev) {
00324 BUG_TRAP(ifa->
ifa_dev==NULL);
00325
in_dev_hold(in_dev);
00326 ifa->
ifa_dev=in_dev;
00327 }
00328
if (
LOOPBACK(ifa->
ifa_local))
00329 ifa->
ifa_scope = RT_SCOPE_HOST;
00330
return inet_insert_ifa(ifa);
00331 }
00332
00333 struct in_device *
inetdev_by_index(
int ifindex)
00334 {
00335
struct net_device *dev;
00336
struct in_device *in_dev = NULL;
00337 read_lock(&
dev_base_lock);
00338 dev =
__dev_get_by_index(ifindex);
00339
if (dev)
00340 in_dev =
in_dev_get(dev);
00341 read_unlock(&
dev_base_lock);
00342
return in_dev;
00343 }
00344
00345
00346
00347 struct in_ifaddr *
inet_ifa_byprefix(
struct in_device *in_dev, u32 prefix, u32 mask)
00348 {
00349 ASSERT_RTNL();
00350
00351
for_primary_ifa(in_dev) {
00352
if (ifa->ifa_mask == mask &&
inet_ifa_match(prefix, ifa))
00353
return ifa;
00354 }
endfor_ifa(in_dev);
00355
return NULL;
00356 }
00357
00358
int
00359 inet_rtm_deladdr(
struct sk_buff *skb,
struct nlmsghdr *nlh,
void *arg)
00360 {
00361
struct rtattr **rta = arg;
00362
struct in_device *in_dev;
00363
struct ifaddrmsg *ifm =
NLMSG_DATA(nlh);
00364
struct in_ifaddr *ifa, **ifap;
00365
00366 ASSERT_RTNL();
00367
00368
if ((in_dev =
inetdev_by_index(ifm->ifa_index)) == NULL)
00369
return -EADDRNOTAVAIL;
00370
__in_dev_put(in_dev);
00371
00372
for (ifap=&in_dev->ifa_list; (ifa=*ifap)!=NULL; ifap=&ifa->ifa_next) {
00373
if ((rta[IFA_LOCAL-1] && memcmp(RTA_DATA(rta[IFA_LOCAL-1]), &ifa->ifa_local, 4)) ||
00374 (rta[IFA_LABEL-1] && strcmp(RTA_DATA(rta[IFA_LABEL-1]), ifa->ifa_label)) ||
00375 (rta[IFA_ADDRESS-1] &&
00376 (ifm->ifa_prefixlen != ifa->ifa_prefixlen ||
00377 !
inet_ifa_match(*(u32*)RTA_DATA(rta[IFA_ADDRESS-1]), ifa))))
00378
continue;
00379
inet_del_ifa(in_dev, ifap, 1);
00380
return 0;
00381 }
00382
00383
return -EADDRNOTAVAIL;
00384 }
00385
00386
int
00387 inet_rtm_newaddr(
struct sk_buff *skb,
struct nlmsghdr *nlh,
void *arg)
00388 {
00389
struct rtattr **rta = arg;
00390
struct net_device *dev;
00391
struct in_device *in_dev;
00392
struct ifaddrmsg *ifm =
NLMSG_DATA(nlh);
00393
struct in_ifaddr *ifa;
00394
00395 ASSERT_RTNL();
00396
00397
if (ifm->ifa_prefixlen > 32 || rta[IFA_LOCAL-1] == NULL)
00398
return -EINVAL;
00399
00400
if ((dev =
__dev_get_by_index(ifm->ifa_index)) == NULL)
00401
return -ENODEV;
00402
00403
if ((in_dev =
__in_dev_get(dev)) == NULL) {
00404 in_dev =
inetdev_init(dev);
00405
if (!in_dev)
00406
return -ENOBUFS;
00407 }
00408
00409
if ((ifa =
inet_alloc_ifa()) == NULL)
00410
return -ENOBUFS;
00411
00412
if (rta[IFA_ADDRESS-1] == NULL)
00413 rta[IFA_ADDRESS-1] = rta[IFA_LOCAL-1];
00414 memcpy(&ifa->ifa_local, RTA_DATA(rta[IFA_LOCAL-1]), 4);
00415 memcpy(&ifa->ifa_address, RTA_DATA(rta[IFA_ADDRESS-1]), 4);
00416 ifa->ifa_prefixlen = ifm->ifa_prefixlen;
00417 ifa->ifa_mask =
inet_make_mask(ifm->ifa_prefixlen);
00418
if (rta[IFA_BROADCAST-1])
00419 memcpy(&ifa->ifa_broadcast, RTA_DATA(rta[IFA_BROADCAST-1]), 4);
00420
if (rta[IFA_ANYCAST-1])
00421 memcpy(&ifa->ifa_anycast, RTA_DATA(rta[IFA_ANYCAST-1]), 4);
00422 ifa->ifa_flags = ifm->ifa_flags;
00423 ifa->ifa_scope = ifm->ifa_scope;
00424
in_dev_hold(in_dev);
00425 ifa->ifa_dev = in_dev;
00426
if (rta[IFA_LABEL-1])
00427 memcpy(ifa->ifa_label, RTA_DATA(rta[IFA_LABEL-1]), IFNAMSIZ);
00428
else
00429 memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
00430
00431
return inet_insert_ifa(ifa);
00432 }
00433
00434
00435
00436
00437
00438 static __inline__
int inet_abc_len(u32 addr)
00439 {
00440
if (
ZERONET(addr))
00441
return 0;
00442
00443 addr = ntohl(addr);
00444
if (
IN_CLASSA(addr))
00445
return 8;
00446
if (
IN_CLASSB(addr))
00447
return 16;
00448
if (
IN_CLASSC(addr))
00449
return 24;
00450
00451
00452
00453
00454
00455
return -1;
00456 }
00457
00458
00459 int devinet_ioctl(
unsigned int cmd,
void *arg)
00460 {
00461
struct ifreq ifr;
00462
struct sockaddr_in sin_orig;
00463
struct sockaddr_in *sin = (
struct sockaddr_in *)&ifr.ifr_addr;
00464
struct in_device *in_dev;
00465
struct in_ifaddr **ifap = NULL;
00466
struct in_ifaddr *ifa = NULL;
00467
struct net_device *dev;
00468
char *colon;
00469
int ret = 0;
00470
int tryaddrmatch = 0;
00471
00472
00473
00474
00475
00476
if (copy_from_user(&ifr, arg,
sizeof(
struct ifreq)))
00477
return -EFAULT;
00478 ifr.ifr_name[IFNAMSIZ-1] = 0;
00479
00480
00481 memcpy(&sin_orig, sin,
sizeof(*sin));
00482
00483 colon = strchr(ifr.ifr_name,
':');
00484
if (colon)
00485 *colon = 0;
00486
00487
#ifdef CONFIG_KMOD
00488
dev_load(ifr.ifr_name);
00489
#endif
00490
00491
switch(cmd) {
00492
case SIOCGIFADDR:
00493
case SIOCGIFBRDADDR:
00494
case SIOCGIFDSTADDR:
00495
case SIOCGIFNETMASK:
00496
00497
00498
00499
00500 tryaddrmatch = (sin_orig.
sin_family == AF_INET);
00501 memset(sin, 0,
sizeof(*sin));
00502 sin->sin_family = AF_INET;
00503
break;
00504
00505
case SIOCSIFFLAGS:
00506
if (!capable(CAP_NET_ADMIN))
00507
return -EACCES;
00508
break;
00509
case SIOCSIFADDR:
00510
case SIOCSIFBRDADDR:
00511
case SIOCSIFDSTADDR:
00512
case SIOCSIFNETMASK:
00513
if (!capable(CAP_NET_ADMIN))
00514
return -EACCES;
00515
if (sin->sin_family != AF_INET)
00516
return -EINVAL;
00517
break;
00518
default:
00519
return -EINVAL;
00520 }
00521
00522 dev_probe_lock();
00523
rtnl_lock();
00524
00525
if ((dev =
__dev_get_by_name(ifr.ifr_name)) == NULL) {
00526 ret = -ENODEV;
00527
goto done;
00528 }
00529
00530
if (colon)
00531 *colon =
':';
00532
00533
if ((in_dev=
__in_dev_get(dev)) != NULL) {
00534
if (tryaddrmatch) {
00535
00536
00537
00538
00539
00540
for (ifap=&in_dev->ifa_list; (ifa=*ifap) != NULL; ifap=&ifa->ifa_next) {
00541
if ((strcmp(ifr.ifr_name, ifa->ifa_label) == 0)
00542 && (sin_orig.
sin_addr.
s_addr == ifa->ifa_address)) {
00543
break;
00544 }
00545 }
00546 }
00547
00548
00549
00550
if (ifa == NULL) {
00551
for (ifap=&in_dev->ifa_list; (ifa=*ifap) != NULL; ifap=&ifa->ifa_next)
00552
if (strcmp(ifr.ifr_name, ifa->ifa_label) == 0)
00553
break;
00554 }
00555 }
00556
00557
if (ifa == NULL && cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS) {
00558 ret = -EADDRNOTAVAIL;
00559
goto done;
00560 }
00561
00562
switch(cmd) {
00563
case SIOCGIFADDR:
00564 sin->sin_addr.s_addr = ifa->ifa_local;
00565
goto rarok;
00566
00567
case SIOCGIFBRDADDR:
00568 sin->sin_addr.s_addr = ifa->ifa_broadcast;
00569
goto rarok;
00570
00571
case SIOCGIFDSTADDR:
00572 sin->sin_addr.s_addr = ifa->ifa_address;
00573
goto rarok;
00574
00575
case SIOCGIFNETMASK:
00576 sin->sin_addr.s_addr = ifa->ifa_mask;
00577
goto rarok;
00578
00579
case SIOCSIFFLAGS:
00580
if (colon) {
00581
if (ifa == NULL) {
00582 ret = -EADDRNOTAVAIL;
00583
break;
00584 }
00585
if (!(ifr.ifr_flags&IFF_UP))
00586
inet_del_ifa(in_dev, ifap, 1);
00587
break;
00588 }
00589 ret =
dev_change_flags(dev, ifr.ifr_flags);
00590
break;
00591
00592
case SIOCSIFADDR:
00593
if (
inet_abc_len(sin->sin_addr.s_addr) < 0) {
00594 ret = -EINVAL;
00595
break;
00596 }
00597
00598
if (!ifa) {
00599
if ((ifa =
inet_alloc_ifa()) == NULL) {
00600 ret = -ENOBUFS;
00601
break;
00602 }
00603
if (colon)
00604 memcpy(ifa->ifa_label, ifr.ifr_name, IFNAMSIZ);
00605
else
00606 memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
00607 }
else {
00608 ret = 0;
00609
if (ifa->ifa_local == sin->sin_addr.s_addr)
00610
break;
00611
inet_del_ifa(in_dev, ifap, 0);
00612 ifa->ifa_broadcast = 0;
00613 ifa->ifa_anycast = 0;
00614 }
00615
00616 ifa->ifa_address =
00617 ifa->ifa_local = sin->sin_addr.s_addr;
00618
00619
if (!(dev->flags&IFF_POINTOPOINT)) {
00620 ifa->ifa_prefixlen =
inet_abc_len(ifa->ifa_address);
00621 ifa->ifa_mask =
inet_make_mask(ifa->ifa_prefixlen);
00622
if ((dev->flags&IFF_BROADCAST) && ifa->ifa_prefixlen < 31)
00623 ifa->ifa_broadcast = ifa->ifa_address|~ifa->ifa_mask;
00624 }
else {
00625 ifa->ifa_prefixlen = 32;
00626 ifa->ifa_mask =
inet_make_mask(32);
00627 }
00628 ret =
inet_set_ifa(dev, ifa);
00629
break;
00630
00631
case SIOCSIFBRDADDR:
00632
if (ifa->ifa_broadcast != sin->sin_addr.s_addr) {
00633
inet_del_ifa(in_dev, ifap, 0);
00634 ifa->ifa_broadcast = sin->sin_addr.s_addr;
00635
inet_insert_ifa(ifa);
00636 }
00637
break;
00638
00639
case SIOCSIFDSTADDR:
00640
if (ifa->ifa_address != sin->sin_addr.s_addr) {
00641
if (
inet_abc_len(sin->sin_addr.s_addr) < 0) {
00642 ret = -EINVAL;
00643
break;
00644 }
00645
inet_del_ifa(in_dev, ifap, 0);
00646 ifa->ifa_address = sin->sin_addr.s_addr;
00647
inet_insert_ifa(ifa);
00648 }
00649
break;
00650
00651
case SIOCSIFNETMASK:
00652
00653
00654
00655
00656
if (
bad_mask(sin->sin_addr.s_addr, 0)) {
00657 ret = -EINVAL;
00658
break;
00659 }
00660
00661
if (ifa->ifa_mask != sin->sin_addr.s_addr) {
00662
inet_del_ifa(in_dev, ifap, 0);
00663 ifa->ifa_mask = sin->sin_addr.s_addr;
00664 ifa->ifa_prefixlen =
inet_mask_len(ifa->ifa_mask);
00665
inet_insert_ifa(ifa);
00666 }
00667
break;
00668 }
00669 done:
00670
rtnl_unlock();
00671 dev_probe_unlock();
00672
return ret;
00673
00674 rarok:
00675
rtnl_unlock();
00676 dev_probe_unlock();
00677
if (copy_to_user(arg, &ifr,
sizeof(
struct ifreq)))
00678
return -EFAULT;
00679
return 0;
00680 }
00681
00682
static int
00683 inet_gifconf(
struct net_device *dev,
char *buf,
int len)
00684 {
00685
struct in_device *in_dev =
__in_dev_get(dev);
00686
struct in_ifaddr *ifa;
00687
struct ifreq ifr;
00688
int done=0;
00689
00690
if (in_dev==NULL || (ifa=in_dev->ifa_list)==NULL)
00691
return 0;
00692
00693
for ( ; ifa; ifa = ifa->ifa_next) {
00694
if (!buf) {
00695 done +=
sizeof(ifr);
00696
continue;
00697 }
00698
if (len < (
int)
sizeof(ifr))
00699
return done;
00700 memset(&ifr, 0,
sizeof(
struct ifreq));
00701
if (ifa->ifa_label)
00702 strcpy(ifr.ifr_name, ifa->ifa_label);
00703
else
00704 strcpy(ifr.ifr_name, dev->
name);
00705
00706 (*(
struct sockaddr_in *) &ifr.ifr_addr).sin_family = AF_INET;
00707 (*(
struct sockaddr_in *) &ifr.ifr_addr).sin_addr.s_addr = ifa->ifa_local;
00708
00709
if (copy_to_user(buf, &ifr,
sizeof(
struct ifreq)))
00710
return -EFAULT;
00711 buf +=
sizeof(
struct ifreq);
00712 len -=
sizeof(
struct ifreq);
00713 done +=
sizeof(
struct ifreq);
00714 }
00715
return done;
00716 }
00717
00718 u32
inet_select_addr(
const struct net_device *dev, u32 dst,
int scope)
00719 {
00720 u32 addr = 0;
00721
struct in_device *in_dev;
00722
00723 read_lock(&
inetdev_lock);
00724 in_dev =
__in_dev_get(dev);
00725
if (in_dev == NULL) {
00726 read_unlock(&
inetdev_lock);
00727
return 0;
00728 }
00729
00730 read_lock(&in_dev->lock);
00731
for_primary_ifa(in_dev) {
00732
if (ifa->ifa_scope >
scope)
00733
continue;
00734
if (!dst ||
inet_ifa_match(dst, ifa)) {
00735 addr = ifa->ifa_local;
00736
break;
00737 }
00738
if (!addr)
00739 addr = ifa->ifa_local;
00740 }
endfor_ifa(in_dev);
00741 read_unlock(&in_dev->lock);
00742 read_unlock(&
inetdev_lock);
00743
00744
if (addr)
00745
return addr;
00746
00747
00748
00749
00750
00751 read_lock(&
dev_base_lock);
00752 read_lock(&
inetdev_lock);
00753
for (dev=
dev_base; dev; dev=dev->
next) {
00754
if ((in_dev=
__in_dev_get(dev)) == NULL)
00755
continue;
00756
00757 read_lock(&in_dev->lock);
00758
for_primary_ifa(in_dev) {
00759
if (ifa->ifa_scope != RT_SCOPE_LINK &&
00760 ifa->ifa_scope <=
scope) {
00761 read_unlock(&in_dev->lock);
00762 read_unlock(&
inetdev_lock);
00763 read_unlock(&
dev_base_lock);
00764
return ifa->ifa_local;
00765 }
00766 }
endfor_ifa(in_dev);
00767 read_unlock(&in_dev->lock);
00768 }
00769 read_unlock(&
inetdev_lock);
00770 read_unlock(&
dev_base_lock);
00771
00772
return 0;
00773 }
00774
00775
00776
00777
00778
00779 int register_inetaddr_notifier(
struct notifier_block *nb)
00780 {
00781
return notifier_chain_register(&
inetaddr_chain, nb);
00782 }
00783
00784 int unregister_inetaddr_notifier(
struct notifier_block *nb)
00785 {
00786
return notifier_chain_unregister(&
inetaddr_chain,nb);
00787 }
00788
00789
00790
00791
00792 static void inetdev_changename(
struct net_device *dev,
struct in_device *in_dev)
00793 {
00794
struct in_ifaddr *ifa;
00795
int named = 0;
00796
00797
for (ifa = in_dev->
ifa_list; ifa; ifa = ifa->
ifa_next) {
00798
char old[IFNAMSIZ], *dot;
00799
00800 memcpy(old, ifa->ifa_label, IFNAMSIZ);
00801 memcpy(ifa->ifa_label, dev->
name, IFNAMSIZ);
00802
if (named++ == 0)
00803
continue;
00804 dot = strchr(ifa->ifa_label,
':');
00805
if (dot == NULL) {
00806 sprintf(old,
":%d", named);
00807 dot = old;
00808 }
00809
if (strlen(dot) + strlen(dev->
name) < IFNAMSIZ) {
00810 strcat(ifa->ifa_label, dot);
00811 }
else {
00812 strcpy(ifa->ifa_label + (IFNAMSIZ - strlen(dot) - 1), dot);
00813 }
00814 }
00815 }
00816
00817
00818
00819 static int inetdev_event(
struct notifier_block *
this,
unsigned long event,
void *ptr)
00820 {
00821
struct net_device *dev = ptr;
00822
struct in_device *in_dev =
__in_dev_get(dev);
00823
00824 ASSERT_RTNL();
00825
00826
if (in_dev == NULL)
00827
return NOTIFY_DONE;
00828
00829
switch (event) {
00830
case NETDEV_REGISTER:
00831 printk(KERN_DEBUG
"inetdev_event: bug\n");
00832 dev->ip_ptr = NULL;
00833
break;
00834
case NETDEV_UP:
00835
if (dev->mtu < 68)
00836
break;
00837
if (dev == &
loopback_dev) {
00838
struct in_ifaddr *ifa;
00839
if ((ifa =
inet_alloc_ifa()) != NULL) {
00840 ifa->ifa_local =
00841 ifa->ifa_address = htonl(
INADDR_LOOPBACK);
00842 ifa->ifa_prefixlen = 8;
00843 ifa->ifa_mask =
inet_make_mask(8);
00844
in_dev_hold(in_dev);
00845 ifa->ifa_dev = in_dev;
00846 ifa->ifa_scope = RT_SCOPE_HOST;
00847 memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
00848
inet_insert_ifa(ifa);
00849 }
00850 }
00851
ip_mc_up(in_dev);
00852
break;
00853
case NETDEV_DOWN:
00854
ip_mc_down(in_dev);
00855
break;
00856
case NETDEV_CHANGEMTU:
00857
if (dev->mtu >= 68)
00858
break;
00859
00860
case NETDEV_UNREGISTER:
00861
inetdev_destroy(in_dev);
00862
break;
00863
case NETDEV_CHANGENAME:
00864
00865
00866
00867
inetdev_changename(dev, in_dev);
00868
break;
00869 }
00870
00871
return NOTIFY_DONE;
00872 }
00873
00874 struct notifier_block
ip_netdev_notifier = {
00875 notifier_call:
inetdev_event,
00876 };
00877
00878 static int inet_fill_ifaddr(
struct sk_buff *skb,
struct in_ifaddr *ifa,
00879 u32 pid, u32 seq,
int event)
00880 {
00881
struct ifaddrmsg *ifm;
00882
struct nlmsghdr *nlh;
00883
unsigned char *b = skb->
tail;
00884
00885 nlh =
NLMSG_PUT(skb, pid, seq, event,
sizeof(*ifm));
00886
if (pid) nlh->nlmsg_flags |=
NLM_F_MULTI;
00887 ifm =
NLMSG_DATA(nlh);
00888 ifm->ifa_family = AF_INET;
00889 ifm->ifa_prefixlen = ifa->
ifa_prefixlen;
00890 ifm->ifa_flags = ifa->
ifa_flags|IFA_F_PERMANENT;
00891 ifm->ifa_scope = ifa->
ifa_scope;
00892 ifm->ifa_index = ifa->
ifa_dev->
dev->
ifindex;
00893
if (ifa->
ifa_address)
00894 RTA_PUT(skb, IFA_ADDRESS, 4, &ifa->
ifa_address);
00895
if (ifa->
ifa_local)
00896 RTA_PUT(skb, IFA_LOCAL, 4, &ifa->
ifa_local);
00897
if (ifa->
ifa_broadcast)
00898 RTA_PUT(skb, IFA_BROADCAST, 4, &ifa->
ifa_broadcast);
00899
if (ifa->
ifa_anycast)
00900 RTA_PUT(skb, IFA_ANYCAST, 4, &ifa->
ifa_anycast);
00901
if (ifa->
ifa_label[0])
00902 RTA_PUT(skb, IFA_LABEL, IFNAMSIZ, &ifa->
ifa_label);
00903 nlh->nlmsg_len = skb->
tail - b;
00904
return skb->
len;
00905
00906 nlmsg_failure:
00907 rtattr_failure:
00908
skb_trim(skb, b - skb->
data);
00909
return -1;
00910 }
00911
00912 static int inet_dump_ifaddr(
struct sk_buff *skb,
struct netlink_callback *cb)
00913 {
00914
int idx, ip_idx;
00915
int s_idx, s_ip_idx;
00916
struct net_device *dev;
00917
struct in_device *in_dev;
00918
struct in_ifaddr *ifa;
00919
00920 s_idx = cb->
args[0];
00921 s_ip_idx = ip_idx = cb->
args[1];
00922 read_lock(&
dev_base_lock);
00923
for (dev=
dev_base, idx=0; dev; dev = dev->
next, idx++) {
00924
if (idx < s_idx)
00925
continue;
00926
if (idx > s_idx)
00927 s_ip_idx = 0;
00928 read_lock(&
inetdev_lock);
00929
if ((in_dev =
__in_dev_get(dev)) == NULL) {
00930 read_unlock(&
inetdev_lock);
00931
continue;
00932 }
00933 read_lock(&in_dev->lock);
00934
for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
00935 ifa = ifa->ifa_next, ip_idx++) {
00936
if (ip_idx < s_ip_idx)
00937
continue;
00938
if (
inet_fill_ifaddr(skb, ifa,
NETLINK_CB(cb->
skb).pid,
00939 cb->
nlh->
nlmsg_seq, RTM_NEWADDR) <= 0) {
00940 read_unlock(&in_dev->lock);
00941 read_unlock(&
inetdev_lock);
00942
goto done;
00943 }
00944 }
00945 read_unlock(&in_dev->lock);
00946 read_unlock(&
inetdev_lock);
00947 }
00948
00949 done:
00950 read_unlock(&
dev_base_lock);
00951 cb->
args[0] = idx;
00952 cb->
args[1] = ip_idx;
00953
00954
return skb->
len;
00955 }
00956
00957 static void rtmsg_ifa(
int event,
struct in_ifaddr * ifa)
00958 {
00959
struct sk_buff *skb;
00960
int size =
NLMSG_SPACE(
sizeof(
struct ifaddrmsg)+128);
00961
00962 skb =
alloc_skb(size, GFP_KERNEL);
00963
if (!skb) {
00964
netlink_set_err(
rtnl, 0, RTMGRP_IPV4_IFADDR, ENOBUFS);
00965
return;
00966 }
00967
if (
inet_fill_ifaddr(skb, ifa, 0, 0, event) < 0) {
00968
kfree_skb(skb);
00969
netlink_set_err(
rtnl, 0, RTMGRP_IPV4_IFADDR, EINVAL);
00970
return;
00971 }
00972
NETLINK_CB(skb).dst_groups = RTMGRP_IPV4_IFADDR;
00973
netlink_broadcast(
rtnl, skb, 0, RTMGRP_IPV4_IFADDR, GFP_KERNEL);
00974 }
00975
00976
00977 static struct rtnetlink_link
inet_rtnetlink_table[RTM_MAX-RTM_BASE+1] =
00978 {
00979 { NULL, NULL, },
00980 { NULL, NULL, },
00981 { NULL, NULL, },
00982 { NULL, NULL, },
00983
00984 {
inet_rtm_newaddr, NULL, },
00985 {
inet_rtm_deladdr, NULL, },
00986 { NULL,
inet_dump_ifaddr, },
00987 { NULL, NULL, },
00988
00989 {
inet_rtm_newroute, NULL, },
00990 {
inet_rtm_delroute, NULL, },
00991 {
inet_rtm_getroute,
inet_dump_fib, },
00992 { NULL, NULL, },
00993
00994 { NULL, NULL, },
00995 { NULL, NULL, },
00996 { NULL, NULL, },
00997 { NULL, NULL, },
00998
00999
#ifdef CONFIG_IP_MULTIPLE_TABLES
01000
{
inet_rtm_newrule, NULL, },
01001 {
inet_rtm_delrule, NULL, },
01002 { NULL,
inet_dump_rules, },
01003 { NULL, NULL, },
01004
#else
01005
{ NULL, NULL, },
01006 { NULL, NULL, },
01007 { NULL, NULL, },
01008 { NULL, NULL, },
01009
#endif
01010
};
01011
01012
01013
#ifdef CONFIG_SYSCTL
01014
01015
void inet_forward_change()
01016 {
01017
struct net_device *dev;
01018
int on =
ipv4_devconf.
forwarding;
01019
01020
ipv4_devconf.
accept_redirects = !on;
01021
ipv4_devconf_dflt.
forwarding = on;
01022
01023 read_lock(&dev_base_lock);
01024
for (dev =
dev_base; dev; dev = dev->
next) {
01025
struct in_device *in_dev;
01026 read_lock(&inetdev_lock);
01027 in_dev =
__in_dev_get(dev);
01028
if (in_dev)
01029 in_dev->cnf.forwarding = on;
01030 read_unlock(&inetdev_lock);
01031 }
01032 read_unlock(&dev_base_lock);
01033
01034
rt_cache_flush(0);
01035 }
01036
01037
static
01038
int devinet_sysctl_forward(ctl_table *ctl,
int write,
struct file * filp,
01039
void *buffer, size_t *lenp)
01040 {
01041
int *valp = ctl->data;
01042
int val = *valp;
01043
int ret;
01044
01045 ret = proc_dointvec(ctl, write, filp, buffer, lenp);
01046
01047
if (write && *valp != val) {
01048
if (valp == &
ipv4_devconf.
forwarding)
01049
inet_forward_change();
01050
else if (valp != &
ipv4_devconf_dflt.
forwarding)
01051
rt_cache_flush(0);
01052 }
01053
01054
return ret;
01055 }
01056
01057
static struct devinet_sysctl_table
01058 {
01059
struct ctl_table_header *sysctl_header;
01060 ctl_table devinet_vars[16];
01061 ctl_table devinet_dev[2];
01062 ctl_table devinet_conf_dir[2];
01063 ctl_table devinet_proto_dir[2];
01064 ctl_table devinet_root_dir[2];
01065 } devinet_sysctl = {
01066 NULL,
01067 {{NET_IPV4_CONF_FORWARDING,
"forwarding",
01068 &
ipv4_devconf.
forwarding,
sizeof(
int), 0644, NULL,
01069 &devinet_sysctl_forward},
01070 {NET_IPV4_CONF_MC_FORWARDING,
"mc_forwarding",
01071 &
ipv4_devconf.
mc_forwarding,
sizeof(
int), 0444, NULL,
01072 &proc_dointvec},
01073 {NET_IPV4_CONF_ACCEPT_REDIRECTS,
"accept_redirects",
01074 &
ipv4_devconf.
accept_redirects,
sizeof(
int), 0644, NULL,
01075 &proc_dointvec},
01076 {NET_IPV4_CONF_SECURE_REDIRECTS,
"secure_redirects",
01077 &
ipv4_devconf.
secure_redirects,
sizeof(
int), 0644, NULL,
01078 &proc_dointvec},
01079 {NET_IPV4_CONF_SHARED_MEDIA,
"shared_media",
01080 &
ipv4_devconf.
shared_media,
sizeof(
int), 0644, NULL,
01081 &proc_dointvec},
01082 {NET_IPV4_CONF_RP_FILTER,
"rp_filter",
01083 &
ipv4_devconf.
rp_filter,
sizeof(
int), 0644, NULL,
01084 &proc_dointvec},
01085 {NET_IPV4_CONF_SEND_REDIRECTS,
"send_redirects",
01086 &
ipv4_devconf.
send_redirects,
sizeof(
int), 0644, NULL,
01087 &proc_dointvec},
01088 {NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE,
"accept_source_route",
01089 &
ipv4_devconf.
accept_source_route,
sizeof(
int), 0644, NULL,
01090 &proc_dointvec},
01091 {NET_IPV4_CONF_PROXY_ARP,
"proxy_arp",
01092 &
ipv4_devconf.
proxy_arp,
sizeof(
int), 0644, NULL,
01093 &proc_dointvec},
01094 {NET_IPV4_CONF_MEDIUM_ID,
"medium_id",
01095 &
ipv4_devconf.
medium_id,
sizeof(
int), 0644, NULL,
01096 &proc_dointvec},
01097 {NET_IPV4_CONF_BOOTP_RELAY,
"bootp_relay",
01098 &
ipv4_devconf.
bootp_relay,
sizeof(
int), 0644, NULL,
01099 &proc_dointvec},
01100 {NET_IPV4_CONF_LOG_MARTIANS,
"log_martians",
01101 &
ipv4_devconf.
log_martians,
sizeof(
int), 0644, NULL,
01102 &proc_dointvec},
01103 {NET_IPV4_CONF_TAG,
"tag",
01104 &
ipv4_devconf.
tag,
sizeof(
int), 0644, NULL,
01105 &proc_dointvec},
01106 {NET_IPV4_CONF_ARPFILTER,
"arp_filter",
01107 &
ipv4_devconf.
arp_filter,
sizeof(
int), 0644, NULL,
01108 &proc_dointvec},
01109 {NET_IPV4_CONF_LOOP,
"loop",
01110 &
ipv4_devconf.
loop,
sizeof(
int), 0644, NULL,
01111 &proc_dointvec},
01112 {0}},
01113
01114 {{NET_PROTO_CONF_ALL,
"all", NULL, 0, 0555, devinet_sysctl.devinet_vars},{0}},
01115 {{NET_IPV4_CONF,
"conf", NULL, 0, 0555, devinet_sysctl.devinet_dev},{0}},
01116 {{NET_IPV4,
"ipv4", NULL, 0, 0555, devinet_sysctl.devinet_conf_dir},{0}},
01117 {{CTL_NET,
"net", NULL, 0, 0555, devinet_sysctl.devinet_proto_dir},{0}}
01118 };
01119
01120
static void devinet_sysctl_register(
struct in_device *in_dev,
struct ipv4_devconf *p)
01121 {
01122
int i;
01123
struct net_device *dev = in_dev ? in_dev->
dev : NULL;
01124
struct devinet_sysctl_table *t;
01125
01126 t = kmalloc(
sizeof(*t), GFP_KERNEL);
01127
if (t == NULL)
01128
return;
01129 memcpy(t, &devinet_sysctl,
sizeof(*t));
01130
for (i=0; i<
sizeof(t->devinet_vars)/
sizeof(t->devinet_vars[0])-1; i++) {
01131 t->devinet_vars[i].data += (
char*)p - (
char*)&
ipv4_devconf;
01132 t->devinet_vars[i].de = NULL;
01133 }
01134
if (dev) {
01135 t->devinet_dev[0].procname = dev->name;
01136 t->devinet_dev[0].ctl_name = dev->ifindex;
01137 }
else {
01138 t->devinet_dev[0].procname =
"default";
01139 t->devinet_dev[0].ctl_name = NET_PROTO_CONF_DEFAULT;
01140 }
01141 t->devinet_dev[0].child = t->devinet_vars;
01142 t->devinet_dev[0].de = NULL;
01143 t->devinet_conf_dir[0].child = t->devinet_dev;
01144 t->devinet_conf_dir[0].de = NULL;
01145 t->devinet_proto_dir[0].child = t->devinet_conf_dir;
01146 t->devinet_proto_dir[0].de = NULL;
01147 t->devinet_root_dir[0].child = t->devinet_proto_dir;
01148 t->devinet_root_dir[0].de = NULL;
01149
01150 t->sysctl_header = register_sysctl_table(t->devinet_root_dir, 0);
01151
if (t->sysctl_header == NULL)
01152 kfree(t);
01153
else
01154 p->
sysctl = t;
01155 }
01156
01157
static void devinet_sysctl_unregister(
struct ipv4_devconf *p)
01158 {
01159
if (p->
sysctl) {
01160
struct devinet_sysctl_table *t = p->
sysctl;
01161 p->
sysctl = NULL;
01162 unregister_sysctl_table(t->sysctl_header);
01163 kfree(t);
01164 }
01165 }
01166
#endif
01167
01168 void __init
devinet_init(
void)
01169 {
01170
register_gifconf(PF_INET,
inet_gifconf);
01171
register_netdevice_notifier(&
ip_netdev_notifier);
01172
rtnetlink_links[PF_INET] =
inet_rtnetlink_table;
01173
#ifdef CONFIG_SYSCTL
01174
devinet_sysctl.sysctl_header =
01175 register_sysctl_table(devinet_sysctl.devinet_root_dir, 0);
01176 devinet_sysctl_register(NULL, &
ipv4_devconf_dflt);
01177
#endif
01178
}