Parallelize ifnet.if_addrhead accessing by duplicating the list itself
[dragonfly.git] / sys / netinet / in.c
1 /*
2  * Copyright (c) 1982, 1986, 1991, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by the University of
16  *      California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  *      @(#)in.c        8.4 (Berkeley) 1/9/95
34  * $FreeBSD: src/sys/netinet/in.c,v 1.44.2.14 2002/11/08 00:45:50 suz Exp $
35  * $DragonFly: src/sys/netinet/in.c,v 1.26 2008/03/07 11:34:20 sephe Exp $
36  */
37
38 #include "opt_bootp.h"
39
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/sockio.h>
43 #include <sys/malloc.h>
44 #include <sys/proc.h>
45 #include <sys/msgport.h>
46 #include <sys/socket.h>
47
48 #include <sys/kernel.h>
49 #include <sys/sysctl.h>
50 #include <sys/thread2.h>
51
52 #include <net/if.h>
53 #include <net/if_types.h>
54 #include <net/route.h>
55 #include <net/netmsg2.h>
56
57 #include <netinet/in.h>
58 #include <netinet/in_var.h>
59 #include <netinet/in_pcb.h>
60
61 #include <netinet/igmp_var.h>
62
63 MALLOC_DEFINE(M_IPMADDR, "in_multi", "internet multicast address");
64
65 static int in_mask2len (struct in_addr *);
66 static void in_len2mask (struct in_addr *, int);
67 static int in_lifaddr_ioctl (struct socket *, u_long, caddr_t,
68         struct ifnet *, struct thread *);
69
70 static void     in_socktrim (struct sockaddr_in *);
71 static int      in_ifinit (struct ifnet *,
72             struct in_ifaddr *, struct sockaddr_in *, int);
73
74 static void     in_control_dispatch(struct netmsg *);
75 static int      in_control_internal(u_long, caddr_t, struct ifnet *,
76                     struct thread *);
77
78 static int subnetsarelocal = 0;
79 SYSCTL_INT(_net_inet_ip, OID_AUTO, subnets_are_local, CTLFLAG_RW,
80         &subnetsarelocal, 0, "");
81
82 struct in_multihead in_multihead; /* XXX BSS initialization */
83
84 extern struct inpcbinfo ripcbinfo;
85 extern struct inpcbinfo udbinfo;
86
87 /*
88  * Return 1 if an internet address is for a ``local'' host
89  * (one to which we have a connection).  If subnetsarelocal
90  * is true, this includes other subnets of the local net.
91  * Otherwise, it includes only the directly-connected (sub)nets.
92  */
93 int
94 in_localaddr(struct in_addr in)
95 {
96         u_long i = ntohl(in.s_addr);
97         struct in_ifaddr *ia;
98
99         if (subnetsarelocal) {
100                 TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link)
101                         if ((i & ia->ia_netmask) == ia->ia_net)
102                                 return (1);
103         } else {
104                 TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link)
105                         if ((i & ia->ia_subnetmask) == ia->ia_subnet)
106                                 return (1);
107         }
108         return (0);
109 }
110
111 /*
112  * Determine whether an IP address is in a reserved set of addresses
113  * that may not be forwarded, or whether datagrams to that destination
114  * may be forwarded.
115  */
116 int
117 in_canforward(struct in_addr in)
118 {
119         u_long i = ntohl(in.s_addr);
120         u_long net;
121
122         if (IN_EXPERIMENTAL(i) || IN_MULTICAST(i))
123                 return (0);
124         if (IN_CLASSA(i)) {
125                 net = i & IN_CLASSA_NET;
126                 if (net == 0 || net == (IN_LOOPBACKNET << IN_CLASSA_NSHIFT))
127                         return (0);
128         }
129         return (1);
130 }
131
132 /*
133  * Trim a mask in a sockaddr
134  */
135 static void
136 in_socktrim(struct sockaddr_in *ap)
137 {
138     char *cplim = (char *) &ap->sin_addr;
139     char *cp = (char *) (&ap->sin_addr + 1);
140
141     ap->sin_len = 0;
142     while (--cp >= cplim)
143         if (*cp) {
144             (ap)->sin_len = cp - (char *) (ap) + 1;
145             break;
146         }
147 }
148
149 static int
150 in_mask2len(struct in_addr *mask)
151 {
152         int x, y;
153         u_char *p;
154
155         p = (u_char *)mask;
156         for (x = 0; x < sizeof *mask; x++) {
157                 if (p[x] != 0xff)
158                         break;
159         }
160         y = 0;
161         if (x < sizeof *mask) {
162                 for (y = 0; y < 8; y++) {
163                         if ((p[x] & (0x80 >> y)) == 0)
164                                 break;
165                 }
166         }
167         return x * 8 + y;
168 }
169
170 static void
171 in_len2mask(struct in_addr *mask, int len)
172 {
173         int i;
174         u_char *p;
175
176         p = (u_char *)mask;
177         bzero(mask, sizeof *mask);
178         for (i = 0; i < len / 8; i++)
179                 p[i] = 0xff;
180         if (len % 8)
181                 p[i] = (0xff00 >> (len % 8)) & 0xff;
182 }
183
184 static int in_interfaces;       /* number of external internet interfaces */
185
186 struct in_control_arg {
187         u_long          cmd;
188         caddr_t         data;
189         struct ifnet    *ifp;
190         struct thread   *td;
191 };
192
193 static void
194 in_control_dispatch(struct netmsg *nmsg)
195 {
196         struct lwkt_msg *msg = &nmsg->nm_lmsg;
197         const struct in_control_arg *arg = msg->u.ms_resultp;
198         int error;
199
200         error = in_control_internal(arg->cmd, arg->data, arg->ifp, arg->td);
201         lwkt_replymsg(msg, error);
202 }
203
204 /*
205  * Generic internet control operations (ioctl's).
206  * Ifp is 0 if not an interface-specific ioctl.
207  *
208  * NOTE! td might be NULL.
209  */
210 /* ARGSUSED */
211 int
212 in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
213            struct thread *td)
214 {
215         struct netmsg nmsg;
216         struct in_control_arg arg;
217         struct lwkt_msg *msg;
218         int error;
219
220         switch (cmd) {
221         case SIOCALIFADDR:
222         case SIOCDLIFADDR:
223                 if (td && (error = suser(td)) != 0)
224                         return error;
225                 /*fall through*/
226         case SIOCGLIFADDR:
227                 if (!ifp)
228                         return EINVAL;
229                 return in_lifaddr_ioctl(so, cmd, data, ifp, td);
230         }
231
232         KASSERT(cmd != SIOCALIFADDR && cmd != SIOCDLIFADDR,
233                 ("recursive SIOC%cLIFADDR!\n",
234                  cmd == SIOCDLIFADDR ? 'D' : 'A'));
235
236         switch (cmd) {
237         case SIOCSIFDSTADDR:
238         case SIOCSIFBRDADDR:
239         case SIOCSIFADDR:
240         case SIOCSIFNETMASK:
241         case SIOCAIFADDR:
242         case SIOCDIFADDR:
243                 bzero(&arg, sizeof(arg));
244                 arg.cmd = cmd;
245                 arg.data = data;
246                 arg.ifp = ifp;
247                 arg.td = td;
248
249                 netmsg_init(&nmsg, &curthread->td_msgport, 0,
250                             in_control_dispatch);
251                 msg = &nmsg.nm_lmsg;
252                 msg->u.ms_resultp = &arg;
253
254                 lwkt_domsg(cpu_portfn(0), msg, 0);
255                 return msg->ms_error;
256         default:
257                 return in_control_internal(cmd, data, ifp, td);
258         }
259 }
260
261 static int
262 in_control_internal(u_long cmd, caddr_t data, struct ifnet *ifp,
263                     struct thread *td)
264 {
265         struct ifreq *ifr = (struct ifreq *)data;
266         struct in_ifaddr *ia = 0, *iap;
267         struct in_addr dst;
268         struct in_ifaddr *oia;
269         struct in_aliasreq *ifra = (struct in_aliasreq *)data;
270         struct sockaddr_in oldaddr;
271         int hostIsNew, iaIsNew, maskIsNew;
272         int error = 0;
273
274         iaIsNew = 0;
275
276         /*
277          * Find address for this interface, if it exists.
278          *
279          * If an alias address was specified, find that one instead of
280          * the first one on the interface, if possible
281          */
282         if (ifp) {
283                 dst = ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr;
284                 LIST_FOREACH(iap, INADDR_HASH(dst.s_addr), ia_hash)
285                         if (iap->ia_ifp == ifp &&
286                             iap->ia_addr.sin_addr.s_addr == dst.s_addr) {
287                                 ia = iap;
288                                 break;
289                         }
290                 if (ia == NULL) {
291                         struct ifaddr_container *ifac;
292
293                         TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid],
294                                       ifa_link) {
295                                 iap = ifatoia(ifac->ifa);
296                                 if (iap->ia_addr.sin_family == AF_INET) {
297                                         ia = iap;
298                                         break;
299                                 }
300                         }
301                 }
302         }
303
304         switch (cmd) {
305
306         case SIOCAIFADDR:
307         case SIOCDIFADDR:
308                 if (ifp == NULL)
309                         return (EADDRNOTAVAIL);
310                 if (ifra->ifra_addr.sin_family == AF_INET) {
311                         for (oia = ia; ia; ia = TAILQ_NEXT(ia, ia_link)) {
312                                 if (ia->ia_ifp == ifp  &&
313                                     ia->ia_addr.sin_addr.s_addr ==
314                                     ifra->ifra_addr.sin_addr.s_addr)
315                                         break;
316                         }
317                         if ((ifp->if_flags & IFF_POINTOPOINT)
318                             && (cmd == SIOCAIFADDR)
319                             && (ifra->ifra_dstaddr.sin_addr.s_addr
320                                 == INADDR_ANY)) {
321                                 return EDESTADDRREQ;
322                         }
323                 }
324                 if (cmd == SIOCDIFADDR && ia == NULL)
325                         return (EADDRNOTAVAIL);
326                 /* FALLTHROUGH */
327         case SIOCSIFADDR:
328         case SIOCSIFNETMASK:
329         case SIOCSIFDSTADDR:
330                 if (td && (error = suser(td)) != 0)
331                         return error;
332
333                 if (ifp == NULL)
334                         return (EADDRNOTAVAIL);
335                 if (ia == NULL) {
336                         struct ifaddr *ifa;
337
338                         ia = ifa_create(sizeof(*ia), M_WAITOK);
339
340                         /*
341                          * Protect from NETISR_IP traversing address list
342                          * while we're modifying it.
343                          */
344                         crit_enter();
345                         
346                         TAILQ_INSERT_TAIL(&in_ifaddrhead, ia, ia_link);
347                         ifa = &ia->ia_ifa;
348                         ifa_iflink(ifa, ifp, 1);
349
350                         ifa->ifa_addr = (struct sockaddr *)&ia->ia_addr;
351                         ifa->ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr;
352                         ifa->ifa_netmask = (struct sockaddr *)&ia->ia_sockmask;
353                         ia->ia_sockmask.sin_len = 8;
354                         ia->ia_sockmask.sin_family = AF_INET;
355                         if (ifp->if_flags & IFF_BROADCAST) {
356                                 ia->ia_broadaddr.sin_len = sizeof ia->ia_addr;
357                                 ia->ia_broadaddr.sin_family = AF_INET;
358                         }
359                         ia->ia_ifp = ifp;
360                         if (!(ifp->if_flags & IFF_LOOPBACK))
361                                 in_interfaces++;
362                         iaIsNew = 1;
363                         crit_exit();
364                 }
365                 break;
366
367         case SIOCSIFBRDADDR:
368                 if (td && (error = suser(td)) != 0)
369                         return error;
370                 /* FALLTHROUGH */
371
372         case SIOCGIFADDR:
373         case SIOCGIFNETMASK:
374         case SIOCGIFDSTADDR:
375         case SIOCGIFBRDADDR:
376                 if (ia == NULL)
377                         return (EADDRNOTAVAIL);
378                 break;
379         }
380         switch (cmd) {
381
382         case SIOCGIFADDR:
383                 *((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_addr;
384                 return (0);
385
386         case SIOCGIFBRDADDR:
387                 if ((ifp->if_flags & IFF_BROADCAST) == 0)
388                         return (EINVAL);
389                 *((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_broadaddr;
390                 return (0);
391
392         case SIOCGIFDSTADDR:
393                 if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
394                         return (EINVAL);
395                 *((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_dstaddr;
396                 return (0);
397
398         case SIOCGIFNETMASK:
399                 *((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_sockmask;
400                 return (0);
401
402         case SIOCSIFDSTADDR:
403                 if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
404                         return (EINVAL);
405                 oldaddr = ia->ia_dstaddr;
406                 ia->ia_dstaddr = *(struct sockaddr_in *)&ifr->ifr_dstaddr;
407                 lwkt_serialize_enter(ifp->if_serializer);
408                 if (ifp->if_ioctl &&
409                     (error = ifp->if_ioctl(ifp, SIOCSIFDSTADDR, (caddr_t)ia,
410                                               td->td_proc->p_ucred))) {
411                         ia->ia_dstaddr = oldaddr;
412                         lwkt_serialize_exit(ifp->if_serializer);
413                         return (error);
414                 }
415                 if (ia->ia_flags & IFA_ROUTE) {
416                         ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&oldaddr;
417                         rtinit(&ia->ia_ifa, RTM_DELETE, RTF_HOST);
418                         ia->ia_ifa.ifa_dstaddr =
419                                         (struct sockaddr *)&ia->ia_dstaddr;
420                         rtinit(&ia->ia_ifa, RTM_ADD, RTF_HOST | RTF_UP);
421                 }
422                 lwkt_serialize_exit(ifp->if_serializer);
423                 return (0);
424
425         case SIOCSIFBRDADDR:
426                 if ((ifp->if_flags & IFF_BROADCAST) == 0)
427                         return (EINVAL);
428                 ia->ia_broadaddr = *(struct sockaddr_in *)&ifr->ifr_broadaddr;
429                 return (0);
430
431         case SIOCSIFADDR:
432                 error = in_ifinit(ifp, ia,
433                     (struct sockaddr_in *) &ifr->ifr_addr, 1);
434                 if (error != 0 && iaIsNew)
435                         break;
436                 if (error == 0)
437                         EVENTHANDLER_INVOKE(ifaddr_event, ifp);
438                 return (0);
439
440         case SIOCSIFNETMASK:
441                 ia->ia_sockmask.sin_addr = ifra->ifra_addr.sin_addr;
442                 ia->ia_subnetmask = ntohl(ia->ia_sockmask.sin_addr.s_addr);
443                 return (0);
444
445         case SIOCAIFADDR:
446                 maskIsNew = 0;
447                 hostIsNew = 1;
448                 error = 0;
449                 if (ia->ia_addr.sin_family == AF_INET) {
450                         if (ifra->ifra_addr.sin_len == 0) {
451                                 ifra->ifra_addr = ia->ia_addr;
452                                 hostIsNew = 0;
453                         } else if (ifra->ifra_addr.sin_addr.s_addr ==
454                                                ia->ia_addr.sin_addr.s_addr)
455                                 hostIsNew = 0;
456                 }
457                 if (ifra->ifra_mask.sin_len) {
458                         in_ifscrub(ifp, ia);
459                         ia->ia_sockmask = ifra->ifra_mask;
460                         ia->ia_sockmask.sin_family = AF_INET;
461                         ia->ia_subnetmask =
462                              ntohl(ia->ia_sockmask.sin_addr.s_addr);
463                         maskIsNew = 1;
464                 }
465                 if ((ifp->if_flags & IFF_POINTOPOINT) &&
466                     (ifra->ifra_dstaddr.sin_family == AF_INET)) {
467                         in_ifscrub(ifp, ia);
468                         ia->ia_dstaddr = ifra->ifra_dstaddr;
469                         maskIsNew  = 1; /* We lie; but the effect's the same */
470                 }
471                 if (ifra->ifra_addr.sin_family == AF_INET &&
472                     (hostIsNew || maskIsNew))
473                         error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0);
474
475                 if (error != 0 && iaIsNew)
476                         break;
477
478                 if ((ifp->if_flags & IFF_BROADCAST) &&
479                     (ifra->ifra_broadaddr.sin_family == AF_INET))
480                         ia->ia_broadaddr = ifra->ifra_broadaddr;
481                 if (error == 0)
482                         EVENTHANDLER_INVOKE(ifaddr_event, ifp);
483                 return (error);
484
485         case SIOCDIFADDR:
486                 /*
487                  * in_ifscrub kills the interface route.
488                  */
489                 in_ifscrub(ifp, ia);
490                 /*
491                  * in_ifadown gets rid of all the rest of
492                  * the routes.  This is not quite the right
493                  * thing to do, but at least if we are running
494                  * a routing process they will come back.
495                  */
496                 in_ifadown(&ia->ia_ifa, 1);
497                 EVENTHANDLER_INVOKE(ifaddr_event, ifp);
498                 error = 0;
499                 break;
500
501         default:
502                 if (ifp == NULL || ifp->if_ioctl == NULL)
503                         return (EOPNOTSUPP);
504                 lwkt_serialize_enter(ifp->if_serializer);
505                 error = ifp->if_ioctl(ifp, cmd, data, td->td_proc->p_ucred);
506                 lwkt_serialize_exit(ifp->if_serializer);
507                 return (error);
508         }
509
510         ifa_ifunlink(&ia->ia_ifa, ifp);
511
512         /*
513          * Protect from NETISR_IP traversing address list while we're modifying
514          * it.
515          */
516         crit_enter();   /* XXX MP */
517         TAILQ_REMOVE(&in_ifaddrhead, ia, ia_link);
518         LIST_REMOVE(ia, ia_hash);
519         crit_exit();    /* XXX MP */
520
521         ifa_destroy(&ia->ia_ifa);
522
523         return (error);
524 }
525
526 /*
527  * SIOC[GAD]LIFADDR.
528  *      SIOCGLIFADDR: get first address. (?!?)
529  *      SIOCGLIFADDR with IFLR_PREFIX:
530  *              get first address that matches the specified prefix.
531  *      SIOCALIFADDR: add the specified address.
532  *      SIOCALIFADDR with IFLR_PREFIX:
533  *              EINVAL since we can't deduce hostid part of the address.
534  *      SIOCDLIFADDR: delete the specified address.
535  *      SIOCDLIFADDR with IFLR_PREFIX:
536  *              delete the first address that matches the specified prefix.
537  * return values:
538  *      EINVAL on invalid parameters
539  *      EADDRNOTAVAIL on prefix match failed/specified address not found
540  *      other values may be returned from in_ioctl()
541  *
542  * NOTE! td might be NULL.
543  */
544 static int
545 in_lifaddr_ioctl(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
546                  struct thread *td)
547 {
548         struct if_laddrreq *iflr = (struct if_laddrreq *)data;
549
550         /* sanity checks */
551         if (!data || !ifp) {
552                 panic("invalid argument to in_lifaddr_ioctl");
553                 /*NOTRECHED*/
554         }
555
556         switch (cmd) {
557         case SIOCGLIFADDR:
558                 /* address must be specified on GET with IFLR_PREFIX */
559                 if ((iflr->flags & IFLR_PREFIX) == 0)
560                         break;
561                 /*FALLTHROUGH*/
562         case SIOCALIFADDR:
563         case SIOCDLIFADDR:
564                 /* address must be specified on ADD and DELETE */
565                 if (iflr->addr.ss_family != AF_INET)
566                         return EINVAL;
567                 if (iflr->addr.ss_len != sizeof(struct sockaddr_in))
568                         return EINVAL;
569                 /* XXX need improvement */
570                 if (iflr->dstaddr.ss_family
571                  && iflr->dstaddr.ss_family != AF_INET)
572                         return EINVAL;
573                 if (iflr->dstaddr.ss_family
574                  && iflr->dstaddr.ss_len != sizeof(struct sockaddr_in))
575                         return EINVAL;
576                 break;
577         default: /*shouldn't happen*/
578                 return EOPNOTSUPP;
579         }
580         if (sizeof(struct in_addr) * 8 < iflr->prefixlen)
581                 return EINVAL;
582
583         switch (cmd) {
584         case SIOCALIFADDR:
585             {
586                 struct in_aliasreq ifra;
587
588                 if (iflr->flags & IFLR_PREFIX)
589                         return EINVAL;
590
591                 /* copy args to in_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */
592                 bzero(&ifra, sizeof ifra);
593                 bcopy(iflr->iflr_name, ifra.ifra_name, sizeof ifra.ifra_name);
594
595                 bcopy(&iflr->addr, &ifra.ifra_addr, iflr->addr.ss_len);
596
597                 if (iflr->dstaddr.ss_family) {  /*XXX*/
598                         bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr,
599                                 iflr->dstaddr.ss_len);
600                 }
601
602                 ifra.ifra_mask.sin_family = AF_INET;
603                 ifra.ifra_mask.sin_len = sizeof(struct sockaddr_in);
604                 in_len2mask(&ifra.ifra_mask.sin_addr, iflr->prefixlen);
605
606                 return in_control(so, SIOCAIFADDR, (caddr_t)&ifra, ifp, td);
607             }
608         case SIOCGLIFADDR:
609         case SIOCDLIFADDR:
610             {
611                 struct ifaddr_container *ifac;
612                 struct in_ifaddr *ia;
613                 struct in_addr mask, candidate, match;
614                 struct sockaddr_in *sin;
615                 int cmp;
616
617                 bzero(&mask, sizeof mask);
618                 if (iflr->flags & IFLR_PREFIX) {
619                         /* lookup a prefix rather than address. */
620                         in_len2mask(&mask, iflr->prefixlen);
621
622                         sin = (struct sockaddr_in *)&iflr->addr;
623                         match.s_addr = sin->sin_addr.s_addr;
624                         match.s_addr &= mask.s_addr;
625
626                         /* if you set extra bits, that's wrong */
627                         if (match.s_addr != sin->sin_addr.s_addr)
628                                 return EINVAL;
629
630                         cmp = 1;
631                 } else {
632                         if (cmd == SIOCGLIFADDR) {
633                                 /* on getting an address, take the 1st match */
634                                 match.s_addr = 0; /* gcc4 warning */
635                                 cmp = 0;        /*XXX*/
636                         } else {
637                                 /* on deleting an address, do exact match */
638                                 in_len2mask(&mask, 32);
639                                 sin = (struct sockaddr_in *)&iflr->addr;
640                                 match.s_addr = sin->sin_addr.s_addr;
641
642                                 cmp = 1;
643                         }
644                 }
645
646                 TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
647                         struct ifaddr *ifa = ifac->ifa;
648
649                         if (ifa->ifa_addr->sa_family != AF_INET6)
650                                 continue;
651                         if (!cmp)
652                                 break;
653                         candidate.s_addr =
654                         ((struct sockaddr_in *)&ifa->ifa_addr)->sin_addr.s_addr;
655                         candidate.s_addr &= mask.s_addr;
656                         if (candidate.s_addr == match.s_addr)
657                                 break;
658                 }
659                 if (ifac == NULL)
660                         return EADDRNOTAVAIL;
661                 ia = (struct in_ifaddr *)(ifac->ifa);
662
663                 if (cmd == SIOCGLIFADDR) {
664                         /* fill in the if_laddrreq structure */
665                         bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin_len);
666
667                         if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
668                                 bcopy(&ia->ia_dstaddr, &iflr->dstaddr,
669                                         ia->ia_dstaddr.sin_len);
670                         } else
671                                 bzero(&iflr->dstaddr, sizeof iflr->dstaddr);
672
673                         iflr->prefixlen =
674                                 in_mask2len(&ia->ia_sockmask.sin_addr);
675
676                         iflr->flags = 0;        /*XXX*/
677
678                         return 0;
679                 } else {
680                         struct in_aliasreq ifra;
681
682                         /* fill in_aliasreq and do ioctl(SIOCDIFADDR_IN6) */
683                         bzero(&ifra, sizeof ifra);
684                         bcopy(iflr->iflr_name, ifra.ifra_name,
685                                 sizeof ifra.ifra_name);
686
687                         bcopy(&ia->ia_addr, &ifra.ifra_addr,
688                                 ia->ia_addr.sin_len);
689                         if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
690                                 bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr,
691                                         ia->ia_dstaddr.sin_len);
692                         }
693                         bcopy(&ia->ia_sockmask, &ifra.ifra_dstaddr,
694                                 ia->ia_sockmask.sin_len);
695
696                         return in_control(so, SIOCDIFADDR, (caddr_t)&ifra,
697                                           ifp, td);
698                 }
699             }
700         }
701
702         return EOPNOTSUPP;      /*just for safety*/
703 }
704
705 /*
706  * Delete any existing route for an interface.
707  */
708 void
709 in_ifscrub(struct ifnet *ifp, struct in_ifaddr *ia)
710 {
711
712         if ((ia->ia_flags & IFA_ROUTE) == 0)
713                 return;
714         if (ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT))
715                 rtinit(&ia->ia_ifa, RTM_DELETE, RTF_HOST);
716         else
717                 rtinit(&ia->ia_ifa, RTM_DELETE, 0);
718         ia->ia_flags &= ~IFA_ROUTE;
719 }
720
721 /*
722  * Initialize an interface's internet address
723  * and routing table entry.
724  */
725 static int
726 in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin, int scrub)
727 {
728         u_long i = ntohl(sin->sin_addr.s_addr);
729         struct sockaddr_in oldaddr;
730         int flags = RTF_UP, error = 0;
731
732         lwkt_serialize_enter(ifp->if_serializer);
733
734         oldaddr = ia->ia_addr;
735         if (oldaddr.sin_family == AF_INET)
736                 LIST_REMOVE(ia, ia_hash);
737         ia->ia_addr = *sin;
738         if (ia->ia_addr.sin_family == AF_INET)
739                 LIST_INSERT_HEAD(INADDR_HASH(ia->ia_addr.sin_addr.s_addr),
740                     ia, ia_hash);
741         /*
742          * Give the interface a chance to initialize
743          * if this is its first address,
744          * and to validate the address if necessary.
745          */
746         if (ifp->if_ioctl &&
747             (error = ifp->if_ioctl(ifp, SIOCSIFADDR, (caddr_t)ia, NULL))) {
748                 lwkt_serialize_exit(ifp->if_serializer);
749                 /* LIST_REMOVE(ia, ia_hash) is done in in_control */
750                 ia->ia_addr = oldaddr;
751                 if (ia->ia_addr.sin_family == AF_INET)
752                         LIST_INSERT_HEAD(INADDR_HASH(ia->ia_addr.sin_addr.s_addr),
753                             ia, ia_hash);
754                 return (error);
755         }
756         lwkt_serialize_exit(ifp->if_serializer);
757         if (scrub) {
758                 ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
759                 in_ifscrub(ifp, ia);
760                 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
761         }
762         if (IN_CLASSA(i))
763                 ia->ia_netmask = IN_CLASSA_NET;
764         else if (IN_CLASSB(i))
765                 ia->ia_netmask = IN_CLASSB_NET;
766         else
767                 ia->ia_netmask = IN_CLASSC_NET;
768         /*
769          * The subnet mask usually includes at least the standard network part,
770          * but may may be smaller in the case of supernetting.
771          * If it is set, we believe it.
772          */
773         if (ia->ia_subnetmask == 0) {
774                 ia->ia_subnetmask = ia->ia_netmask;
775                 ia->ia_sockmask.sin_addr.s_addr = htonl(ia->ia_subnetmask);
776         } else
777                 ia->ia_netmask &= ia->ia_subnetmask;
778         ia->ia_net = i & ia->ia_netmask;
779         ia->ia_subnet = i & ia->ia_subnetmask;
780         in_socktrim(&ia->ia_sockmask);
781         /*
782          * Add route for the network.
783          */
784         ia->ia_ifa.ifa_metric = ifp->if_metric;
785         if (ifp->if_flags & IFF_BROADCAST) {
786                 ia->ia_broadaddr.sin_addr.s_addr =
787                         htonl(ia->ia_subnet | ~ia->ia_subnetmask);
788                 ia->ia_netbroadcast.s_addr =
789                         htonl(ia->ia_net | ~ ia->ia_netmask);
790         } else if (ifp->if_flags & IFF_LOOPBACK) {
791                 ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
792                 flags |= RTF_HOST;
793         } else if (ifp->if_flags & IFF_POINTOPOINT) {
794                 if (ia->ia_dstaddr.sin_family != AF_INET)
795                         return (0);
796                 flags |= RTF_HOST;
797         }
798
799         /*-
800          * Don't add host routes for interface addresses of
801          * 0.0.0.0 --> 0.255.255.255 netmask 255.0.0.0.  This makes it
802          * possible to assign several such address pairs with consistent
803          * results (no host route) and is required by BOOTP.
804          *
805          * XXX: This is ugly !  There should be a way for the caller to
806          *      say that they don't want a host route.
807          */
808         if (ia->ia_addr.sin_addr.s_addr != INADDR_ANY ||
809             ia->ia_netmask != IN_CLASSA_NET ||
810             ia->ia_dstaddr.sin_addr.s_addr != htonl(IN_CLASSA_HOST)) {
811                 if ((error = rtinit(&ia->ia_ifa, (int)RTM_ADD, flags)) != 0) {
812                         ia->ia_addr = oldaddr;
813                         return (error);
814                 }
815                 ia->ia_flags |= IFA_ROUTE;
816         }
817
818         /*
819          * If the interface supports multicast, join the "all hosts"
820          * multicast group on that interface.
821          */
822         if (ifp->if_flags & IFF_MULTICAST) {
823                 struct in_addr addr;
824
825                 addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP);
826                 in_addmulti(&addr, ifp);
827         }
828         return (error);
829 }
830
831
832 /*
833  * Return 1 if the address might be a local broadcast address.
834  */
835 int
836 in_broadcast(struct in_addr in, struct ifnet *ifp)
837 {
838         struct ifaddr_container *ifac;
839         u_long t;
840
841         if (in.s_addr == INADDR_BROADCAST ||
842             in.s_addr == INADDR_ANY)
843                 return 1;
844         if ((ifp->if_flags & IFF_BROADCAST) == 0)
845                 return 0;
846         t = ntohl(in.s_addr);
847         /*
848          * Look through the list of addresses for a match
849          * with a broadcast address.
850          */
851 #define ia ((struct in_ifaddr *)ifa)
852         TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
853                 struct ifaddr *ifa = ifac->ifa;
854
855                 if (ifa->ifa_addr->sa_family == AF_INET &&
856                     (in.s_addr == ia->ia_broadaddr.sin_addr.s_addr ||
857                      in.s_addr == ia->ia_netbroadcast.s_addr ||
858                      /*
859                       * Check for old-style (host 0) broadcast.
860                       */
861                      t == ia->ia_subnet || t == ia->ia_net) &&
862                      /*
863                       * Check for an all one subnetmask. These
864                       * only exist when an interface gets a secondary
865                       * address.
866                       */
867                      ia->ia_subnetmask != (u_long)0xffffffff)
868                             return 1;
869         }
870         return (0);
871 #undef ia
872 }
873 /*
874  * Add an address to the list of IP multicast addresses for a given interface.
875  */
876 struct in_multi *
877 in_addmulti(struct in_addr *ap, struct ifnet *ifp)
878 {
879         struct in_multi *inm;
880         int error;
881         struct sockaddr_in sin;
882         struct ifmultiaddr *ifma;
883
884         /*
885          * Call generic routine to add membership or increment
886          * refcount.  It wants addresses in the form of a sockaddr,
887          * so we build one here (being careful to zero the unused bytes).
888          */
889         bzero(&sin, sizeof sin);
890         sin.sin_family = AF_INET;
891         sin.sin_len = sizeof sin;
892         sin.sin_addr = *ap;
893         crit_enter();
894         error = if_addmulti(ifp, (struct sockaddr *)&sin, &ifma);
895         if (error) {
896                 crit_exit();
897                 return 0;
898         }
899
900         /*
901          * If ifma->ifma_protospec is null, then if_addmulti() created
902          * a new record.  Otherwise, we are done.
903          */
904         if (ifma->ifma_protospec != 0) {
905                 crit_exit();
906                 return ifma->ifma_protospec;
907         }
908
909         /* XXX - if_addmulti uses M_WAITOK.  Can this really be called
910            at interrupt time?  If so, need to fix if_addmulti. XXX */
911         inm = kmalloc(sizeof *inm, M_IPMADDR, M_WAITOK | M_ZERO);
912         inm->inm_addr = *ap;
913         inm->inm_ifp = ifp;
914         inm->inm_ifma = ifma;
915         ifma->ifma_protospec = inm;
916         LIST_INSERT_HEAD(&in_multihead, inm, inm_link);
917
918         /*
919          * Let IGMP know that we have joined a new IP multicast group.
920          */
921         igmp_joingroup(inm);
922         crit_exit();
923         return (inm);
924 }
925
926 /*
927  * Delete a multicast address record.
928  */
929 void
930 in_delmulti(struct in_multi *inm)
931 {
932         struct ifmultiaddr *ifma;
933         struct in_multi my_inm;
934
935         crit_enter();
936         ifma = inm->inm_ifma;
937         my_inm.inm_ifp = NULL ; /* don't send the leave msg */
938         if (ifma->ifma_refcount == 1) {
939                 /*
940                  * No remaining claims to this record; let IGMP know that
941                  * we are leaving the multicast group.
942                  * But do it after the if_delmulti() which might reset
943                  * the interface and nuke the packet.
944                  */
945                 my_inm = *inm ;
946                 ifma->ifma_protospec = 0;
947                 LIST_REMOVE(inm, inm_link);
948                 kfree(inm, M_IPMADDR);
949         }
950         /* XXX - should be separate API for when we have an ifma? */
951         if_delmulti(ifma->ifma_ifp, ifma->ifma_addr);
952         if (my_inm.inm_ifp != NULL)
953                 igmp_leavegroup(&my_inm);
954         crit_exit();
955 }
956
957 void
958 in_ifdetach(struct ifnet *ifp)
959 {
960         in_pcbpurgeif0(LIST_FIRST(&ripcbinfo.pcblisthead), ifp);
961         in_pcbpurgeif0(LIST_FIRST(&udbinfo.pcblisthead), ifp);
962 }