~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/net/ipv4/devinet.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *      NET3    IP device support routines.
  3  *
  4  *      Version: $Id: devinet.c,v 1.39 2000/12/10 22:24:11 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 lists.
 22  *              Cyrus Durgin:           updated for kmod
 23  */
 24 
 25 #include <linux/config.h>
 26  
 27 #include <asm/uaccess.h>
 28 #include <asm/system.h>
 29 #include <asm/bitops.h>
 30 #include <linux/types.h>
 31 #include <linux/kernel.h>
 32 #include <linux/sched.h>
 33 #include <linux/string.h>
 34 #include <linux/mm.h>
 35 #include <linux/socket.h>
 36 #include <linux/sockios.h>
 37 #include <linux/in.h>
 38 #include <linux/errno.h>
 39 #include <linux/interrupt.h>
 40 #include <linux/if_ether.h>
 41 #include <linux/inet.h>
 42 #include <linux/netdevice.h>
 43 #include <linux/etherdevice.h>
 44 #include <linux/skbuff.h>
 45 #include <linux/rtnetlink.h>
 46 #include <linux/init.h>
 47 #include <linux/notifier.h>
 48 #include <linux/inetdevice.h>
 49 #include <linux/igmp.h>
 50 #ifdef CONFIG_SYSCTL
 51 #include <linux/sysctl.h>
 52 #endif
 53 #ifdef CONFIG_KMOD
 54 #include <linux/kmod.h>
 55 #endif
 56 
 57 #include <net/ip.h>
 58 #include <net/route.h>
 59 #include <net/ip_fib.h>
 60 
 61 struct ipv4_devconf ipv4_devconf = { 1, 1, 1, 1, 0, };
 62 static struct ipv4_devconf ipv4_devconf_dflt = { 1, 1, 1, 1, 1, };
 63 
 64 #ifdef CONFIG_RTNETLINK
 65 static void rtmsg_ifa(int event, struct in_ifaddr *);
 66 #else
 67 #define rtmsg_ifa(a,b)  do { } while(0)
 68 #endif
 69 
 70 static struct notifier_block *inetaddr_chain;
 71 static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, int destroy);
 72 #ifdef CONFIG_SYSCTL
 73 static void devinet_sysctl_register(struct in_device *in_dev, struct ipv4_devconf *p);
 74 static void devinet_sysctl_unregister(struct ipv4_devconf *p);
 75 #endif
 76 
 77 int inet_ifa_count;
 78 int inet_dev_count;
 79 
 80 /* Locks all the inet devices. */
 81 
 82 rwlock_t inetdev_lock = RW_LOCK_UNLOCKED;
 83 
 84 
 85 static struct in_ifaddr * inet_alloc_ifa(void)
 86 {
 87         struct in_ifaddr *ifa;
 88 
 89         ifa = kmalloc(sizeof(*ifa), GFP_KERNEL);
 90         if (ifa) {
 91                 memset(ifa, 0, sizeof(*ifa));
 92                 inet_ifa_count++;
 93         }
 94 
 95         return ifa;
 96 }
 97 
 98 static __inline__ void inet_free_ifa(struct in_ifaddr *ifa)
 99 {
100         if (ifa->ifa_dev)
101                 __in_dev_put(ifa->ifa_dev);
102         kfree(ifa);
103         inet_ifa_count--;
104 }
105 
106 void in_dev_finish_destroy(struct in_device *idev)
107 {
108         struct net_device *dev = idev->dev;
109 
110         BUG_TRAP(idev->ifa_list==NULL);
111         BUG_TRAP(idev->mc_list==NULL);
112 #ifdef NET_REFCNT_DEBUG
113         printk(KERN_DEBUG "in_dev_finish_destroy: %p=%s\n", idev, dev ? dev->name : "NIL");
114 #endif
115         dev_put(dev);
116         if (!idev->dead) {
117                 printk("Freeing alive in_device %p\n", idev);
118                 return;
119         }
120         inet_dev_count--;
121         kfree(idev);
122 }
123 
124 struct in_device *inetdev_init(struct net_device *dev)
125 {
126         struct in_device *in_dev;
127 
128         ASSERT_RTNL();
129 
130         in_dev = kmalloc(sizeof(*in_dev), GFP_KERNEL);
131         if (!in_dev)
132                 return NULL;
133         memset(in_dev, 0, sizeof(*in_dev));
134         in_dev->lock = RW_LOCK_UNLOCKED;
135         memcpy(&in_dev->cnf, &ipv4_devconf_dflt, sizeof(in_dev->cnf));
136         in_dev->cnf.sysctl = NULL;
137         in_dev->dev = dev;
138         if ((in_dev->arp_parms = neigh_parms_alloc(dev, &arp_tbl)) == NULL) {
139                 kfree(in_dev);
140                 return NULL;
141         }
142         inet_dev_count++;
143         /* Reference in_dev->dev */
144         dev_hold(dev);
145 #ifdef CONFIG_SYSCTL
146         neigh_sysctl_register(dev, in_dev->arp_parms, NET_IPV4, NET_IPV4_NEIGH, "ipv4");
147 #endif
148         write_lock_bh(&inetdev_lock);
149         dev->ip_ptr = in_dev;
150         /* Account for reference dev->ip_ptr */
151         in_dev_hold(in_dev);
152         write_unlock_bh(&inetdev_lock);
153 #ifdef CONFIG_SYSCTL
154         devinet_sysctl_register(in_dev, &in_dev->cnf);
155 #endif
156         if (dev->flags&IFF_UP)
157                 ip_mc_up(in_dev);
158         return in_dev;
159 }
160 
161 static void inetdev_destroy(struct in_device *in_dev)
162 {
163         struct in_ifaddr *ifa;
164 
165         ASSERT_RTNL();
166 
167         in_dev->dead = 1;
168 
169         ip_mc_destroy_dev(in_dev);
170 
171         while ((ifa = in_dev->ifa_list) != NULL) {
172                 inet_del_ifa(in_dev, &in_dev->ifa_list, 0);
173                 inet_free_ifa(ifa);
174         }
175 
176 #ifdef CONFIG_SYSCTL
177         devinet_sysctl_unregister(&in_dev->cnf);
178 #endif
179         write_lock_bh(&inetdev_lock);
180         in_dev->dev->ip_ptr = NULL;
181         /* in_dev_put following below will kill the in_device */
182         write_unlock_bh(&inetdev_lock);
183 
184 
185         neigh_parms_release(&arp_tbl, in_dev->arp_parms);
186         in_dev_put(in_dev);
187 }
188 
189 int inet_addr_onlink(struct in_device *in_dev, u32 a, u32 b)
190 {
191         read_lock(&in_dev->lock);
192         for_primary_ifa(in_dev) {
193                 if (inet_ifa_match(a, ifa)) {
194                         if (!b || inet_ifa_match(b, ifa)) {
195                                 read_unlock(&in_dev->lock);
196                                 return 1;
197                         }
198                 }
199         } endfor_ifa(in_dev);
200         read_unlock(&in_dev->lock);
201         return 0;
202 } 
203 
204 static void
205 inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, int destroy)
206 {
207         struct in_ifaddr *ifa1 = *ifap;
208 
209         ASSERT_RTNL();
210 
211         /* 1. Deleting primary ifaddr forces deletion all secondaries */
212 
213         if (!(ifa1->ifa_flags&IFA_F_SECONDARY)) {
214                 struct in_ifaddr *ifa;
215                 struct in_ifaddr **ifap1 = &ifa1->ifa_next;
216 
217                 while ((ifa=*ifap1) != NULL) {
218                         if (!(ifa->ifa_flags&IFA_F_SECONDARY) ||
219                             ifa1->ifa_mask != ifa->ifa_mask ||
220                             !inet_ifa_match(ifa1->ifa_address, ifa)) {
221                                 ifap1 = &ifa->ifa_next;
222                                 continue;
223                         }
224                         write_lock_bh(&in_dev->lock);
225                         *ifap1 = ifa->ifa_next;
226                         write_unlock_bh(&in_dev->lock);
227 
228                         rtmsg_ifa(RTM_DELADDR, ifa);
229                         notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa);
230                         inet_free_ifa(ifa);
231                 }
232         }
233 
234         /* 2. Unlink it */
235 
236         write_lock_bh(&in_dev->lock);
237         *ifap = ifa1->ifa_next;
238         write_unlock_bh(&in_dev->lock);
239 
240         /* 3. Announce address deletion */
241 
242         /* Send message first, then call notifier.
243            At first sight, FIB update triggered by notifier
244            will refer to already deleted ifaddr, that could confuse
245            netlink listeners. It is not true: look, gated sees
246            that route deleted and if it still thinks that ifaddr
247            is valid, it will try to restore deleted routes... Grr.
248            So that, this order is correct.
249          */
250         rtmsg_ifa(RTM_DELADDR, ifa1);
251         notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa1);
252         if (destroy) {
253                 inet_free_ifa(ifa1);
254 
255                 if (in_dev->ifa_list == NULL)
256                         inetdev_destroy(in_dev);
257         }
258 }
259 
260 static int
261 inet_insert_ifa(struct in_ifaddr *ifa)
262 {
263         struct in_device *in_dev = ifa->ifa_dev;
264         struct in_ifaddr *ifa1, **ifap, **last_primary;
265 
266         ASSERT_RTNL();
267 
268         if (ifa->ifa_local == 0) {
269                 inet_free_ifa(ifa);
270                 return 0;
271         }
272 
273         ifa->ifa_flags &= ~IFA_F_SECONDARY;
274         last_primary = &in_dev->ifa_list;
275 
276         for (ifap=&in_dev->ifa_list; (ifa1=*ifap)!=NULL; ifap=&ifa1->ifa_next) {
277                 if (!(ifa1->ifa_flags&IFA_F_SECONDARY) && ifa->ifa_scope <= ifa1->ifa_scope)
278                         last_primary = &ifa1->ifa_next;
279                 if (ifa1->ifa_mask == ifa->ifa_mask && inet_ifa_match(ifa1->ifa_address, ifa)) {
280                         if (ifa1->ifa_local == ifa->ifa_local) {
281                                 inet_free_ifa(ifa);
282                                 return -EEXIST;
283                         }
284                         if (ifa1->ifa_scope != ifa->ifa_scope) {
285                                 inet_free_ifa(ifa);
286                                 return -EINVAL;
287                         }
288                         ifa->ifa_flags |= IFA_F_SECONDARY;
289                 }
290         }
291 
292         if (!(ifa->ifa_flags&IFA_F_SECONDARY)) {
293                 net_srandom(ifa->ifa_local);
294                 ifap = last_primary;
295         }
296 
297         ifa->ifa_next = *ifap;
298         write_lock_bh(&in_dev->lock);
299         *ifap = ifa;
300         write_unlock_bh(&in_dev->lock);
301 
302         /* Send message first, then call notifier.
303            Notifier will trigger FIB update, so that
304            listeners of netlink will know about new ifaddr */
305         rtmsg_ifa(RTM_NEWADDR, ifa);
306         notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa);
307 
308         return 0;
309 }
310 
311 static int
312 inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa)
313 {
314         struct in_device *in_dev = __in_dev_get(dev);
315 
316         ASSERT_RTNL();
317 
318         if (in_dev == NULL) {
319                 in_dev = inetdev_init(dev);
320                 if (in_dev == NULL) {
321                         inet_free_ifa(ifa);
322                         return -ENOBUFS;
323                 }
324         }
325         if (ifa->ifa_dev != in_dev) {
326                 BUG_TRAP(ifa->ifa_dev==NULL);
327                 in_dev_hold(in_dev);
328                 ifa->ifa_dev=in_dev;
329         }
330         if (LOOPBACK(ifa->ifa_local))
331                 ifa->ifa_scope = RT_SCOPE_HOST;
332         return inet_insert_ifa(ifa);
333 }
334 
335 struct in_device *inetdev_by_index(int ifindex)
336 {
337         struct net_device *dev;
338         struct in_device *in_dev = NULL;
339         read_lock(&dev_base_lock);
340         dev = __dev_get_by_index(ifindex);
341         if (dev)
342                 in_dev = in_dev_get(dev);
343         read_unlock(&dev_base_lock);
344         return in_dev;
345 }
346 
347 /* Called only from RTNL semaphored context. No locks. */
348 
349 struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, u32 prefix, u32 mask)
350 {
351         ASSERT_RTNL();
352 
353         for_primary_ifa(in_dev) {
354                 if (ifa->ifa_mask == mask && inet_ifa_match(prefix, ifa))
355                         return ifa;
356         } endfor_ifa(in_dev);
357         return NULL;
358 }
359 
360 #ifdef CONFIG_RTNETLINK
361 
362 int
363 inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
364 {
365         struct rtattr  **rta = arg;
366         struct in_device *in_dev;
367         struct ifaddrmsg *ifm = NLMSG_DATA(nlh);
368         struct in_ifaddr *ifa, **ifap;
369 
370         ASSERT_RTNL();
371 
372         if ((in_dev = inetdev_by_index(ifm->ifa_index)) == NULL)
373                 return -EADDRNOTAVAIL;
374         __in_dev_put(in_dev);
375 
376         for (ifap=&in_dev->ifa_list; (ifa=*ifap)!=NULL; ifap=&ifa->ifa_next) {
377                 if ((rta[IFA_LOCAL-1] && memcmp(RTA_DATA(rta[IFA_LOCAL-1]), &ifa->ifa_local, 4)) ||
378                     (rta[IFA_LABEL-1] && strcmp(RTA_DATA(rta[IFA_LABEL-1]), ifa->ifa_label)) ||
379                     (rta[IFA_ADDRESS-1] &&
380                      (ifm->ifa_prefixlen != ifa->ifa_prefixlen ||
381                       !inet_ifa_match(*(u32*)RTA_DATA(rta[IFA_ADDRESS-1]), ifa))))
382                         continue;
383                 inet_del_ifa(in_dev, ifap, 1);
384                 return 0;
385         }
386 
387         return -EADDRNOTAVAIL;
388 }
389 
390 int
391 inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
392 {
393         struct rtattr **rta = arg;
394         struct net_device *dev;
395         struct in_device *in_dev;
396         struct ifaddrmsg *ifm = NLMSG_DATA(nlh);
397         struct in_ifaddr *ifa;
398 
399         ASSERT_RTNL();
400 
401         if (ifm->ifa_prefixlen > 32 || rta[IFA_LOCAL-1] == NULL)
402                 return -EINVAL;
403 
404         if ((dev = __dev_get_by_index(ifm->ifa_index)) == NULL)
405                 return -ENODEV;
406 
407         if ((in_dev = __in_dev_get(dev)) == NULL) {
408                 in_dev = inetdev_init(dev);
409                 if (!in_dev)
410                         return -ENOBUFS;
411         }
412 
413         if ((ifa = inet_alloc_ifa()) == NULL)
414                 return -ENOBUFS;
415 
416         if (rta[IFA_ADDRESS-1] == NULL)
417                 rta[IFA_ADDRESS-1] = rta[IFA_LOCAL-1];
418         memcpy(&ifa->ifa_local, RTA_DATA(rta[IFA_LOCAL-1]), 4);
419         memcpy(&ifa->ifa_address, RTA_DATA(rta[IFA_ADDRESS-1]), 4);
420         ifa->ifa_prefixlen = ifm->ifa_prefixlen;
421         ifa->ifa_mask = inet_make_mask(ifm->ifa_prefixlen);
422         if (rta[IFA_BROADCAST-1])
423                 memcpy(&ifa->ifa_broadcast, RTA_DATA(rta[IFA_BROADCAST-1]), 4);
424         if (rta[IFA_ANYCAST-1])
425                 memcpy(&ifa->ifa_anycast, RTA_DATA(rta[IFA_ANYCAST-1]), 4);
426         ifa->ifa_flags = ifm->ifa_flags;
427         ifa->ifa_scope = ifm->ifa_scope;
428         in_dev_hold(in_dev);
429         ifa->ifa_dev = in_dev;
430         if (rta[IFA_LABEL-1])
431                 memcpy(ifa->ifa_label, RTA_DATA(rta[IFA_LABEL-1]), IFNAMSIZ);
432         else
433                 memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
434 
435         return inet_insert_ifa(ifa);
436 }
437 
438 #endif
439 
440 /* 
441  *      Determine a default network mask, based on the IP address. 
442  */
443 
444 static __inline__ int inet_abc_len(u32 addr)
445 {
446         if (ZERONET(addr))
447                 return 0;
448 
449         addr = ntohl(addr);
450         if (IN_CLASSA(addr)) 
451                 return 8;
452         if (IN_CLASSB(addr)) 
453                 return 16;
454         if (IN_CLASSC(addr)) 
455                 return 24;
456 
457         /*
458          *      Something else, probably a multicast. 
459          */
460          
461         return -1;
462 }
463 
464 
465 int devinet_ioctl(unsigned int cmd, void *arg)
466 {
467         struct ifreq ifr;
468         struct sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr;
469         struct in_device *in_dev;
470         struct in_ifaddr **ifap = NULL;
471         struct in_ifaddr *ifa = NULL;
472         struct net_device *dev;
473         char *colon;
474         int ret = 0;
475 
476         /*
477          *      Fetch the caller's info block into kernel space
478          */
479 
480         if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
481                 return -EFAULT;
482         ifr.ifr_name[IFNAMSIZ-1] = 0;
483 
484         colon = strchr(ifr.ifr_name, ':');
485         if (colon)
486                 *colon = 0;
487 
488 #ifdef CONFIG_KMOD
489         dev_load(ifr.ifr_name);
490 #endif
491 
492         switch(cmd) {
493         case SIOCGIFADDR:       /* Get interface address */
494         case SIOCGIFBRDADDR:    /* Get the broadcast address */
495         case SIOCGIFDSTADDR:    /* Get the destination address */
496         case SIOCGIFNETMASK:    /* Get the netmask for the interface */
497                 /* Note that this ioctls will not sleep,
498                    so that we do not impose a lock.
499                    One day we will be forced to put shlock here (I mean SMP)
500                  */
501                 memset(sin, 0, sizeof(*sin));
502                 sin->sin_family = AF_INET;
503                 break;
504 
505         case SIOCSIFFLAGS:
506                 if (!capable(CAP_NET_ADMIN))
507                         return -EACCES;
508                 break;
509         case SIOCSIFADDR:       /* Set interface address (and family) */
510         case SIOCSIFBRDADDR:    /* Set the broadcast address */
511         case SIOCSIFDSTADDR:    /* Set the destination address */
512         case SIOCSIFNETMASK:    /* Set the netmask for the interface */
513                 if (!capable(CAP_NET_ADMIN))
514                         return -EACCES;
515                 if (sin->sin_family != AF_INET)
516                         return -EINVAL;
517                 break;
518         default:
519                 return -EINVAL;
520         }
521 
522         dev_probe_lock();
523         rtnl_lock();
524 
525         if ((dev = __dev_get_by_name(ifr.ifr_name)) == NULL) {
526                 ret = -ENODEV;
527                 goto done;
528         }
529 
530         if (colon)
531                 *colon = ':';
532 
533         if ((in_dev=__in_dev_get(dev)) != NULL) {
534                 for (ifap=&in_dev->ifa_list; (ifa=*ifap) != NULL; ifap=&ifa->ifa_next)
535                         if (strcmp(ifr.ifr_name, ifa->ifa_label) == 0)
536                                 break;
537         }
538 
539         if (ifa == NULL && cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS) {
540                 ret = -EADDRNOTAVAIL;
541                 goto done;
542         }
543 
544         switch(cmd) {
545                 case SIOCGIFADDR:       /* Get interface address */
546                         sin->sin_addr.s_addr = ifa->ifa_local;
547                         goto rarok;
548 
549                 case SIOCGIFBRDADDR:    /* Get the broadcast address */
550                         sin->sin_addr.s_addr = ifa->ifa_broadcast;
551                         goto rarok;
552 
553                 case SIOCGIFDSTADDR:    /* Get the destination address */
554                         sin->sin_addr.s_addr = ifa->ifa_address;
555                         goto rarok;
556 
557                 case SIOCGIFNETMASK:    /* Get the netmask for the interface */
558                         sin->sin_addr.s_addr = ifa->ifa_mask;
559                         goto rarok;
560 
561                 case SIOCSIFFLAGS:
562                         if (colon) {
563                                 if (ifa == NULL) {
564                                         ret = -EADDRNOTAVAIL;
565                                         break;
566                                 }
567                                 if (!(ifr.ifr_flags&IFF_UP))
568                                         inet_del_ifa(in_dev, ifap, 1);
569                                 break;
570                         }
571                         ret = dev_change_flags(dev, ifr.ifr_flags);
572                         break;
573         
574                 case SIOCSIFADDR:       /* Set interface address (and family) */
575                         if (inet_abc_len(sin->sin_addr.s_addr) < 0) {
576                                 ret = -EINVAL;
577                                 break;
578                         }
579 
580                         if (!ifa) {
581                                 if ((ifa = inet_alloc_ifa()) == NULL) {
582                                         ret = -ENOBUFS;
583                                         break;
584                                 }
585                                 if (colon)
586                                         memcpy(ifa->ifa_label, ifr.ifr_name, IFNAMSIZ);
587                                 else
588                                         memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
589                         } else {
590                                 ret = 0;
591                                 if (ifa->ifa_local == sin->sin_addr.s_addr)
592                                         break;
593                                 inet_del_ifa(in_dev, ifap, 0);
594                                 ifa->ifa_broadcast = 0;
595                                 ifa->ifa_anycast = 0;
596                         }
597 
598                         ifa->ifa_address =
599                         ifa->ifa_local = sin->sin_addr.s_addr;
600 
601                         if (!(dev->flags&IFF_POINTOPOINT)) {
602                                 ifa->ifa_prefixlen = inet_abc_len(ifa->ifa_address);
603                                 ifa->ifa_mask = inet_make_mask(ifa->ifa_prefixlen);
604                                 if ((dev->flags&IFF_BROADCAST) && ifa->ifa_prefixlen < 31)
605                                         ifa->ifa_broadcast = ifa->ifa_address|~ifa->ifa_mask;
606                         } else {
607                                 ifa->ifa_prefixlen = 32;
608                                 ifa->ifa_mask = inet_make_mask(32);
609                         }
610                         ret = inet_set_ifa(dev, ifa);
611                         break;
612 
613                 case SIOCSIFBRDADDR:    /* Set the broadcast address */
614                         if (ifa->ifa_broadcast != sin->sin_addr.s_addr) {
615                                 inet_del_ifa(in_dev, ifap, 0);
616                                 ifa->ifa_broadcast = sin->sin_addr.s_addr;
617                                 inet_insert_ifa(ifa);
618                         }
619                         break;
620         
621                 case SIOCSIFDSTADDR:    /* Set the destination address */
622                         if (ifa->ifa_address != sin->sin_addr.s_addr) {
623                                 if (inet_abc_len(sin->sin_addr.s_addr) < 0) {
624                                         ret = -EINVAL;
625                                         break;
626                                 }
627                                 inet_del_ifa(in_dev, ifap, 0);
628                                 ifa->ifa_address = sin->sin_addr.s_addr;
629                                 inet_insert_ifa(ifa);
630                         }
631                         break;
632 
633                 case SIOCSIFNETMASK:    /* Set the netmask for the interface */
634 
635                         /*
636                          *      The mask we set must be legal.
637                          */
638                         if (bad_mask(sin->sin_addr.s_addr, 0)) {
639                                 ret = -EINVAL;
640                                 break;
641                         }
642 
643                         if (ifa->ifa_mask != sin->sin_addr.s_addr) {
644                                 inet_del_ifa(in_dev, ifap, 0);
645                                 ifa->ifa_mask = sin->sin_addr.s_addr;
646                                 ifa->ifa_prefixlen = inet_mask_len(ifa->ifa_mask);
647                                 inet_insert_ifa(ifa);
648                         }
649                         break;
650         }
651 done:
652         rtnl_unlock();
653         dev_probe_unlock();
654         return ret;
655 
656 rarok:
657         rtnl_unlock();
658         dev_probe_unlock();
659         if (copy_to_user(arg, &ifr, sizeof(struct ifreq)))
660                 return -EFAULT;
661         return 0;
662 }
663 
664 static int
665 inet_gifconf(struct net_device *dev, char *buf, int len)
666 {
667         struct in_device *in_dev = __in_dev_get(dev);
668         struct in_ifaddr *ifa;
669         struct ifreq ifr;
670         int done=0;
671 
672         if (in_dev==NULL || (ifa=in_dev->ifa_list)==NULL)
673                 return 0;
674 
675         for ( ; ifa; ifa = ifa->ifa_next) {
676                 if (!buf) {
677                         done += sizeof(ifr);
678                         continue;
679                 }
680                 if (len < (int) sizeof(ifr))
681                         return done;
682                 memset(&ifr, 0, sizeof(struct ifreq));
683                 if (ifa->ifa_label)
684                         strcpy(ifr.ifr_name, ifa->ifa_label);
685                 else
686                         strcpy(ifr.ifr_name, dev->name);
687 
688                 (*(struct sockaddr_in *) &ifr.ifr_addr).sin_family = AF_INET;
689                 (*(struct sockaddr_in *) &ifr.ifr_addr).sin_addr.s_addr = ifa->ifa_local;
690 
691                 if (copy_to_user(buf, &ifr, sizeof(struct ifreq)))
692                         return -EFAULT;
693                 buf += sizeof(struct ifreq);
694                 len -= sizeof(struct ifreq);
695                 done += sizeof(struct ifreq);
696         }
697         return done;
698 }
699 
700 u32 inet_select_addr(const struct net_device *dev, u32 dst, int scope)
701 {
702         u32 addr = 0;
703         struct in_device *in_dev;
704 
705         read_lock(&inetdev_lock);
706         in_dev = __in_dev_get(dev);
707         if (in_dev == NULL) {
708                 read_unlock(&inetdev_lock);
709                 return 0;
710         }
711 
712         read_lock(&in_dev->lock);
713         for_primary_ifa(in_dev) {
714                 if (ifa->ifa_scope > scope)
715                         continue;
716                 if (!dst || inet_ifa_match(dst, ifa)) {
717                         addr = ifa->ifa_local;
718                         break;
719                 }
720                 if (!addr)
721                         addr = ifa->ifa_local;
722         } endfor_ifa(in_dev);
723         read_unlock(&in_dev->lock);
724         read_unlock(&inetdev_lock);
725 
726         if (addr)
727                 return addr;
728 
729         /* Not loopback addresses on loopback should be preferred
730            in this case. It is importnat that lo is the first interface
731            in dev_base list.
732          */
733         read_lock(&dev_base_lock);
734         read_lock(&inetdev_lock);
735         for (dev=dev_base; dev; dev=dev->next) {
736                 if ((in_dev=__in_dev_get(dev)) == NULL)
737                         continue;
738 
739                 read_lock(&in_dev->lock);
740                 for_primary_ifa(in_dev) {
741                         if (ifa->ifa_scope != RT_SCOPE_LINK &&
742                             ifa->ifa_scope <= scope) {
743                                 read_unlock(&in_dev->lock);
744                                 read_unlock(&inetdev_lock);
745                                 read_unlock(&dev_base_lock);
746                                 return ifa->ifa_local;
747                         }
748                 } endfor_ifa(in_dev);
749                 read_unlock(&in_dev->lock);
750         }
751         read_unlock(&inetdev_lock);
752         read_unlock(&dev_base_lock);
753 
754         return 0;
755 }
756 
757 /*
758  *      Device notifier
759  */
760 
761 int register_inetaddr_notifier(struct notifier_block *nb)
762 {
763         return notifier_chain_register(&inetaddr_chain, nb);
764 }
765 
766 int unregister_inetaddr_notifier(struct notifier_block *nb)
767 {
768         return notifier_chain_unregister(&inetaddr_chain,nb);
769 }
770 
771 /* Called only under RTNL semaphore */
772 
773 static int inetdev_event(struct notifier_block *this, unsigned long event, void *ptr)
774 {
775         struct net_device *dev = ptr;
776         struct in_device *in_dev = __in_dev_get(dev);
777 
778         ASSERT_RTNL();
779 
780         if (in_dev == NULL)
781                 return NOTIFY_DONE;
782 
783         switch (event) {
784         case NETDEV_REGISTER:
785                 printk(KERN_DEBUG "inetdev_event: bug\n");
786                 dev->ip_ptr = NULL;
787                 break;
788         case NETDEV_UP:
789                 if (dev->mtu < 68)
790                         break;
791                 if (dev == &loopback_dev) {
792                         struct in_ifaddr *ifa;
793                         if ((ifa = inet_alloc_ifa()) != NULL) {
794                                 ifa->ifa_local =
795                                 ifa->ifa_address = htonl(INADDR_LOOPBACK);
796                                 ifa->ifa_prefixlen = 8;
797                                 ifa->ifa_mask = inet_make_mask(8);
798                                 in_dev_hold(in_dev);
799                                 ifa->ifa_dev = in_dev;
800                                 ifa->ifa_scope = RT_SCOPE_HOST;
801                                 memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
802                                 inet_insert_ifa(ifa);
803                         }
804                 }
805                 ip_mc_up(in_dev);
806                 break;
807         case NETDEV_DOWN:
808                 ip_mc_down(in_dev);
809                 break;
810         case NETDEV_CHANGEMTU:
811                 if (dev->mtu >= 68)
812                         break;
813                 /* MTU falled under 68, disable IP */
814         case NETDEV_UNREGISTER:
815                 inetdev_destroy(in_dev);
816                 break;
817         case NETDEV_CHANGENAME:
818                 if (in_dev->ifa_list) {
819                         struct in_ifaddr *ifa;
820                         for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next)
821                                 memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
822                         /* Do not notify about label change, this event is
823                            not interesting to applications using netlink.
824                          */
825                 }
826                 break;
827         }
828 
829         return NOTIFY_DONE;
830 }
831 
832 struct notifier_block ip_netdev_notifier={
833         inetdev_event,
834         NULL,
835         0
836 };
837 
838 #ifdef CONFIG_RTNETLINK
839 
840 static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
841                             u32 pid, u32 seq, int event)
842 {
843         struct ifaddrmsg *ifm;
844         struct nlmsghdr  *nlh;
845         unsigned char    *b = skb->tail;
846 
847         nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm));
848         ifm = NLMSG_DATA(nlh);
849         ifm->ifa_family = AF_INET;
850         ifm->ifa_prefixlen = ifa->ifa_prefixlen;
851         ifm->ifa_flags = ifa->ifa_flags|IFA_F_PERMANENT;
852         ifm->ifa_scope = ifa->ifa_scope;
853         ifm->ifa_index = ifa->ifa_dev->dev->ifindex;
854         if (ifa->ifa_address)
855                 RTA_PUT(skb, IFA_ADDRESS, 4, &ifa->ifa_address);
856         if (ifa->ifa_local)
857                 RTA_PUT(skb, IFA_LOCAL, 4, &ifa->ifa_local);
858         if (ifa->ifa_broadcast)
859                 RTA_PUT(skb, IFA_BROADCAST, 4, &ifa->ifa_broadcast);
860         if (ifa->ifa_anycast)
861                 RTA_PUT(skb, IFA_ANYCAST, 4, &ifa->ifa_anycast);
862         if (ifa->ifa_label[0])
863                 RTA_PUT(skb, IFA_LABEL, IFNAMSIZ, &ifa->ifa_label);
864         nlh->nlmsg_len = skb->tail - b;
865         return skb->len;
866 
867 nlmsg_failure:
868 rtattr_failure:
869         skb_trim(skb, b - skb->data);
870         return -1;
871 }
872 
873 static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
874 {
875         int idx, ip_idx;
876         int s_idx, s_ip_idx;
877         struct net_device *dev;
878         struct in_device *in_dev;
879         struct in_ifaddr *ifa;
880 
881         s_idx = cb->args[0];
882         s_ip_idx = ip_idx = cb->args[1];
883         read_lock(&dev_base_lock);
884         for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) {
885                 if (idx < s_idx)
886                         continue;
887                 if (idx > s_idx)
888                         s_ip_idx = 0;
889                 read_lock(&inetdev_lock);
890                 if ((in_dev = __in_dev_get(dev)) == NULL) {
891                         read_unlock(&inetdev_lock);
892                         continue;
893                 }
894                 read_lock(&in_dev->lock);
895                 for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
896                      ifa = ifa->ifa_next, ip_idx++) {
897                         if (ip_idx < s_ip_idx)
898                                 continue;
899                         if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
900                                              cb->nlh->nlmsg_seq, RTM_NEWADDR) <= 0) {
901                                 read_unlock(&in_dev->lock);
902                                 read_unlock(&inetdev_lock);
903                                 goto done;
904                         }
905                 }
906                 read_unlock(&in_dev->lock);
907                 read_unlock(&inetdev_lock);
908         }
909 
910 done:
911         read_unlock(&dev_base_lock);
912         cb->args[0] = idx;
913         cb->args[1] = ip_idx;
914 
915         return skb->len;
916 }
917 
918 static void rtmsg_ifa(int event, struct in_ifaddr * ifa)
919 {
920         struct sk_buff *skb;
921         int size = NLMSG_SPACE(sizeof(struct ifaddrmsg)+128);
922 
923         skb = alloc_skb(size, GFP_KERNEL);
924         if (!skb) {
925                 netlink_set_err(rtnl, 0, RTMGRP_IPV4_IFADDR, ENOBUFS);
926                 return;
927         }
928         if (inet_fill_ifaddr(skb, ifa, 0, 0, event) < 0) {
929                 kfree_skb(skb);
930                 netlink_set_err(rtnl, 0, RTMGRP_IPV4_IFADDR, EINVAL);
931                 return;
932         }
933         NETLINK_CB(skb).dst_groups = RTMGRP_IPV4_IFADDR;
934         netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV4_IFADDR, GFP_KERNEL);
935 }
936 
937 
938 static struct rtnetlink_link inet_rtnetlink_table[RTM_MAX-RTM_BASE+1] =
939 {
940         { NULL,                 NULL,                   },
941         { NULL,                 NULL,                   },
942         { NULL,                 NULL,                   },
943         { NULL,                 NULL,                   },
944 
945         { inet_rtm_newaddr,     NULL,                   },
946         { inet_rtm_deladdr,     NULL,                   },
947         { NULL,                 inet_dump_ifaddr,       },
948         { NULL,                 NULL,                   },
949 
950         { inet_rtm_newroute,    NULL,                   },
951         { inet_rtm_delroute,    NULL,                   },
952         { inet_rtm_getroute,    inet_dump_fib,          },
953         { NULL,                 NULL,                   },
954 
955         { NULL,                 NULL,                   },
956         { NULL,                 NULL,                   },
957         { NULL,                 NULL,                   },
958         { NULL,                 NULL,                   },
959 
960 #ifdef CONFIG_IP_MULTIPLE_TABLES
961         { inet_rtm_newrule,     NULL,                   },
962         { inet_rtm_delrule,     NULL,                   },
963         { NULL,                 inet_dump_rules,        },
964         { NULL,                 NULL,                   },
965 #else
966         { NULL,                 NULL,                   },
967         { NULL,                 NULL,                   },
968         { NULL,                 NULL,                   },
969         { NULL,                 NULL,                   },
970 #endif
971 };
972 
973 #endif /* CONFIG_RTNETLINK */
974 
975 
976 #ifdef CONFIG_SYSCTL
977 
978 void inet_forward_change()
979 {
980         struct net_device *dev;
981         int on = ipv4_devconf.forwarding;
982 
983         ipv4_devconf.accept_redirects = !on;
984         ipv4_devconf_dflt.forwarding = on;
985 
986         read_lock(&dev_base_lock);
987         for (dev = dev_base; dev; dev = dev->next) {
988                 struct in_device *in_dev;
989                 read_lock(&inetdev_lock);
990                 in_dev = __in_dev_get(dev);
991                 if (in_dev)
992                         in_dev->cnf.forwarding = on;
993                 read_unlock(&inetdev_lock);
994         }
995         read_unlock(&dev_base_lock);
996 
997         rt_cache_flush(0);
998 }
999 
1000 static
1001 int devinet_sysctl_forward(ctl_table *ctl, int write, struct file * filp,
1002                            void *buffer, size_t *lenp)
1003 {
1004         int *valp = ctl->data;
1005         int val = *valp;
1006         int ret;
1007 
1008         ret = proc_dointvec(ctl, write, filp, buffer, lenp);
1009 
1010         if (write && *valp != val) {
1011                 if (valp == &ipv4_devconf.forwarding)
1012                         inet_forward_change();
1013                 else if (valp != &ipv4_devconf_dflt.forwarding)
1014                         rt_cache_flush(0);
1015         }
1016 
1017         return ret;
1018 }
1019 
1020 static struct devinet_sysctl_table
1021 {
1022         struct ctl_table_header *sysctl_header;
1023         ctl_table devinet_vars[13];
1024         ctl_table devinet_dev[2];
1025         ctl_table devinet_conf_dir[2];
1026         ctl_table devinet_proto_dir[2];
1027         ctl_table devinet_root_dir[2];
1028 } devinet_sysctl = {
1029         NULL,
1030         {{NET_IPV4_CONF_FORWARDING, "forwarding",
1031          &ipv4_devconf.forwarding, sizeof(int), 0644, NULL,
1032          &devinet_sysctl_forward},
1033         {NET_IPV4_CONF_MC_FORWARDING, "mc_forwarding",
1034          &ipv4_devconf.mc_forwarding, sizeof(int), 0444, NULL,
1035          &proc_dointvec},
1036         {NET_IPV4_CONF_ACCEPT_REDIRECTS, "accept_redirects",
1037          &ipv4_devconf.accept_redirects, sizeof(int), 0644, NULL,
1038          &proc_dointvec},
1039         {NET_IPV4_CONF_SECURE_REDIRECTS, "secure_redirects",
1040          &ipv4_devconf.secure_redirects, sizeof(int), 0644, NULL,
1041          &proc_dointvec},
1042         {NET_IPV4_CONF_SHARED_MEDIA, "shared_media",
1043          &ipv4_devconf.shared_media, sizeof(int), 0644, NULL,
1044          &proc_dointvec},
1045         {NET_IPV4_CONF_RP_FILTER, "rp_filter",
1046          &ipv4_devconf.rp_filter, sizeof(int), 0644, NULL,
1047          &proc_dointvec},
1048         {NET_IPV4_CONF_SEND_REDIRECTS, "send_redirects",
1049          &ipv4_devconf.send_redirects, sizeof(int), 0644, NULL,
1050          &proc_dointvec},
1051         {NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE, "accept_source_route",
1052          &ipv4_devconf.accept_source_route, sizeof(int), 0644, NULL,
1053          &proc_dointvec},
1054         {NET_IPV4_CONF_PROXY_ARP, "proxy_arp",
1055          &ipv4_devconf.proxy_arp, sizeof(int), 0644, NULL,
1056          &proc_dointvec},
1057         {NET_IPV4_CONF_BOOTP_RELAY, "bootp_relay",
1058          &ipv4_devconf.bootp_relay, sizeof(int), 0644, NULL,
1059          &proc_dointvec},
1060         {NET_IPV4_CONF_LOG_MARTIANS, "log_martians",
1061          &ipv4_devconf.log_martians, sizeof(int), 0644, NULL,
1062          &proc_dointvec},
1063         {NET_IPV4_CONF_TAG, "tag",
1064          &ipv4_devconf.tag, sizeof(int), 0644, NULL,
1065          &proc_dointvec},
1066          {0}},
1067 
1068         {{NET_PROTO_CONF_ALL, "all", NULL, 0, 0555, devinet_sysctl.devinet_vars},{0}},
1069         {{NET_IPV4_CONF, "conf", NULL, 0, 0555, devinet_sysctl.devinet_dev},{0}},
1070         {{NET_IPV4, "ipv4", NULL, 0, 0555, devinet_sysctl.devinet_conf_dir},{0}},
1071         {{CTL_NET, "net", NULL, 0, 0555, devinet_sysctl.devinet_proto_dir},{0}}
1072 };
1073 
1074 static void devinet_sysctl_register(struct in_device *in_dev, struct ipv4_devconf *p)
1075 {
1076         int i;
1077         struct net_device *dev = in_dev ? in_dev->dev : NULL;
1078         struct devinet_sysctl_table *t;
1079 
1080         t = kmalloc(sizeof(*t), GFP_KERNEL);
1081         if (t == NULL)
1082                 return;
1083         memcpy(t, &devinet_sysctl, sizeof(*t));
1084         for (i=0; i<sizeof(t->devinet_vars)/sizeof(t->devinet_vars[0])-1; i++) {
1085                 t->devinet_vars[i].data += (char*)p - (char*)&ipv4_devconf;
1086                 t->devinet_vars[i].de = NULL;
1087         }
1088         if (dev) {
1089                 t->devinet_dev[0].procname = dev->name;
1090                 t->devinet_dev[0].ctl_name = dev->ifindex;
1091         } else {
1092                 t->devinet_dev[0].procname = "default";
1093                 t->devinet_dev[0].ctl_name = NET_PROTO_CONF_DEFAULT;
1094         }
1095         t->devinet_dev[0].child = t->devinet_vars;
1096         t->devinet_dev[0].de = NULL;
1097         t->devinet_conf_dir[0].child = t->devinet_dev;
1098         t->devinet_conf_dir[0].de = NULL;
1099         t->devinet_proto_dir[0].child = t->devinet_conf_dir;
1100         t->devinet_proto_dir[0].de = NULL;
1101         t->devinet_root_dir[0].child = t->devinet_proto_dir;
1102         t->devinet_root_dir[0].de = NULL;
1103 
1104         t->sysctl_header = register_sysctl_table(t->devinet_root_dir, 0);
1105         if (t->sysctl_header == NULL)
1106                 kfree(t);
1107         else
1108                 p->sysctl = t;
1109 }
1110 
1111 static void devinet_sysctl_unregister(struct ipv4_devconf *p)
1112 {
1113         if (p->sysctl) {
1114                 struct devinet_sysctl_table *t = p->sysctl;
1115                 p->sysctl = NULL;
1116                 unregister_sysctl_table(t->sysctl_header);
1117                 kfree(t);
1118         }
1119 }
1120 #endif
1121 
1122 void __init devinet_init(void)
1123 {
1124         register_gifconf(PF_INET, inet_gifconf);
1125         register_netdevice_notifier(&ip_netdev_notifier);
1126 #ifdef CONFIG_RTNETLINK
1127         rtnetlink_links[PF_INET] = inet_rtnetlink_table;
1128 #endif
1129 #ifdef CONFIG_SYSCTL
1130         devinet_sysctl.sysctl_header =
1131                 register_sysctl_table(devinet_sysctl.devinet_root_dir, 0);
1132         devinet_sysctl_register(NULL, &ipv4_devconf_dflt);
1133 #endif
1134 }
1135 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.