Deleted Added
full compact
if.c (83129) if.c (83130)
1/*
2 * Copyright (c) 1980, 1986, 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

--- 17 unchanged lines hidden (view full) ---

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 * @(#)if.c 8.3 (Berkeley) 1/4/94
1/*
2 * Copyright (c) 1980, 1986, 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

--- 17 unchanged lines hidden (view full) ---

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 * @(#)if.c 8.3 (Berkeley) 1/4/94
34 * $FreeBSD: head/sys/net/if.c 83129 2001-09-06 00:44:45Z jlemon $
34 * $FreeBSD: head/sys/net/if.c 83130 2001-09-06 02:40:43Z jlemon $
35 */
36
37#include "opt_compat.h"
38#include "opt_inet6.h"
39#include "opt_inet.h"
40
41#include <sys/param.h>
42#include <sys/malloc.h>

--- 23 unchanged lines hidden (view full) ---

66#include <netinet/in_var.h>
67#ifdef INET6
68#include <netinet6/in6_var.h>
69#include <netinet6/in6_ifattach.h>
70#endif
71#endif
72
73static int ifconf(u_long, caddr_t);
35 */
36
37#include "opt_compat.h"
38#include "opt_inet6.h"
39#include "opt_inet.h"
40
41#include <sys/param.h>
42#include <sys/malloc.h>

--- 23 unchanged lines hidden (view full) ---

66#include <netinet/in_var.h>
67#ifdef INET6
68#include <netinet6/in6_var.h>
69#include <netinet6/in6_ifattach.h>
70#endif
71#endif
72
73static int ifconf(u_long, caddr_t);
74static void ifinit(void *);
74static void if_grow(void);
75static void if_init(void *);
76static void if_check(void *);
75static void if_qflush(struct ifqueue *);
76static void if_slowtimo(void *);
77static void link_rtrequest(int, struct rtentry *, struct sockaddr *);
78static int if_rtdel(struct radix_node *, void *);
79static struct if_clone *if_clone_lookup(const char *, int *);
80static int if_clone_list(struct if_clonereq *);
81#ifdef INET6
82/*
83 * XXX: declare here to avoid to include many inet6 related files..
84 * should be more generalized?
85 */
86extern void nd6_setmtu __P((struct ifnet *));
87#endif
88
89int if_index = 0;
77static void if_qflush(struct ifqueue *);
78static void if_slowtimo(void *);
79static void link_rtrequest(int, struct rtentry *, struct sockaddr *);
80static int if_rtdel(struct radix_node *, void *);
81static struct if_clone *if_clone_lookup(const char *, int *);
82static int if_clone_list(struct if_clonereq *);
83#ifdef INET6
84/*
85 * XXX: declare here to avoid to include many inet6 related files..
86 * should be more generalized?
87 */
88extern void nd6_setmtu __P((struct ifnet *));
89#endif
90
91int if_index = 0;
90struct ifaddr **ifnet_addrs;
91struct ifnet **ifindex2ifnet = NULL;
92struct ifindex_entry *ifindex_table = NULL;
92int ifqmaxlen = IFQ_MAXLEN;
93struct ifnethead ifnet; /* depend on static init XXX */
94int if_cloners_count;
95LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners);
96
93int ifqmaxlen = IFQ_MAXLEN;
94struct ifnethead ifnet; /* depend on static init XXX */
95int if_cloners_count;
96LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners);
97
98static int if_indexlim = 8;
99
97/*
98 * System initialization
99 */
100/*
101 * System initialization
102 */
100SYSINIT(interfaces, SI_SUB_PROTO_IF, SI_ORDER_FIRST, ifinit, NULL)
103SYSINIT(interfaces, SI_SUB_INIT_IF, SI_ORDER_FIRST, if_init, NULL)
104SYSINIT(interface_check, SI_SUB_PROTO_IF, SI_ORDER_FIRST, if_check, NULL)
101
102MALLOC_DEFINE(M_IFADDR, "ifaddr", "interface address");
103MALLOC_DEFINE(M_IFMADDR, "ether_multi", "link-level multicast address");
104
105/*
106 * Network interface utility routines.
107 *
108 * Routines with ifa_ifwith* names take sockaddr *'s as
109 * parameters.
110 */
111/* ARGSUSED*/
105
106MALLOC_DEFINE(M_IFADDR, "ifaddr", "interface address");
107MALLOC_DEFINE(M_IFMADDR, "ether_multi", "link-level multicast address");
108
109/*
110 * Network interface utility routines.
111 *
112 * Routines with ifa_ifwith* names take sockaddr *'s as
113 * parameters.
114 */
115/* ARGSUSED*/
112void
113ifinit(dummy)
116static void
117if_init(dummy)
114 void *dummy;
115{
118 void *dummy;
119{
120
121 TAILQ_INIT(&ifnet);
122 if_grow(); /* create initial table */
123}
124
125static void
126if_grow(void)
127{
128 u_int n;
129 struct ifindex_entry *e;
130
131 if_indexlim <<= 1;
132 n = if_indexlim * sizeof(*e);
133 e = malloc(n, M_IFADDR, M_WAITOK | M_ZERO);
134 if (ifindex_table != NULL) {
135 memcpy((caddr_t)e, (caddr_t)ifindex_table, n/2);
136 free((caddr_t)ifindex_table, M_IFADDR);
137 }
138 ifindex_table = e;
139}
140
141/* ARGSUSED*/
142static void
143if_check(dummy)
144 void *dummy;
145{
116 struct ifnet *ifp;
117 int s;
118
119 s = splimp();
120 TAILQ_FOREACH(ifp, &ifnet, if_link) {
121 if (ifp->if_snd.ifq_maxlen == 0) {
122 printf("%s%d XXX: driver didn't set ifq_maxlen\n",
123 ifp->if_name, ifp->if_unit);

--- 17 unchanged lines hidden (view full) ---

141if_attach(ifp)
142 struct ifnet *ifp;
143{
144 unsigned socksize, ifasize;
145 int namelen, masklen;
146 char workbuf[64];
147 register struct sockaddr_dl *sdl;
148 register struct ifaddr *ifa;
146 struct ifnet *ifp;
147 int s;
148
149 s = splimp();
150 TAILQ_FOREACH(ifp, &ifnet, if_link) {
151 if (ifp->if_snd.ifq_maxlen == 0) {
152 printf("%s%d XXX: driver didn't set ifq_maxlen\n",
153 ifp->if_name, ifp->if_unit);

--- 17 unchanged lines hidden (view full) ---

171if_attach(ifp)
172 struct ifnet *ifp;
173{
174 unsigned socksize, ifasize;
175 int namelen, masklen;
176 char workbuf[64];
177 register struct sockaddr_dl *sdl;
178 register struct ifaddr *ifa;
149 static int if_indexlim = 8;
150 static int inited;
151
179
152 if (!inited) {
153 TAILQ_INIT(&ifnet);
154 inited = 1;
155 }
156
157 TAILQ_INSERT_TAIL(&ifnet, ifp, if_link);
158 ifp->if_index = ++if_index;
159 /*
160 * XXX -
161 * The old code would work if the interface passed a pre-existing
162 * chain of ifaddrs to this code. We don't trust our callers to
163 * properly initialize the tailq, however, so we no longer allow
164 * this unlikely case.
165 */
166 TAILQ_INIT(&ifp->if_addrhead);
167 TAILQ_INIT(&ifp->if_prefixhead);
168 TAILQ_INIT(&ifp->if_multiaddrs);
169 getmicrotime(&ifp->if_lastchange);
180 TAILQ_INSERT_TAIL(&ifnet, ifp, if_link);
181 ifp->if_index = ++if_index;
182 /*
183 * XXX -
184 * The old code would work if the interface passed a pre-existing
185 * chain of ifaddrs to this code. We don't trust our callers to
186 * properly initialize the tailq, however, so we no longer allow
187 * this unlikely case.
188 */
189 TAILQ_INIT(&ifp->if_addrhead);
190 TAILQ_INIT(&ifp->if_prefixhead);
191 TAILQ_INIT(&ifp->if_multiaddrs);
192 getmicrotime(&ifp->if_lastchange);
170 if (ifnet_addrs == 0 || if_index >= if_indexlim) {
171 unsigned n = (if_indexlim <<= 1) * sizeof(ifa);
172 caddr_t q = malloc(n, M_IFADDR, M_WAITOK | M_ZERO);
173 if (ifnet_addrs) {
174 bcopy((caddr_t)ifnet_addrs, (caddr_t)q, n/2);
175 free((caddr_t)ifnet_addrs, M_IFADDR);
176 }
177 ifnet_addrs = (struct ifaddr **)q;
193 if (if_index >= if_indexlim)
194 if_grow();
178
195
179 /* grow ifindex2ifnet */
180 n = if_indexlim * sizeof(struct ifnet *);
181 q = malloc(n, M_IFADDR, M_WAITOK | M_ZERO);
182 if (ifindex2ifnet) {
183 bcopy((caddr_t)ifindex2ifnet, q, n/2);
184 free((caddr_t)ifindex2ifnet, M_IFADDR);
185 }
186 ifindex2ifnet = (struct ifnet **)q;
187 }
188
189 ifindex2ifnet[if_index] = ifp;
190
196 ifnet_byindex(if_index) = ifp;
191 mtx_init(&ifp->if_snd.ifq_mtx, ifp->if_name, MTX_DEF);
192
193 /*
194 * create a Link Level name for this device
195 */
196 namelen = snprintf(workbuf, sizeof(workbuf),
197 "%s%d", ifp->if_name, ifp->if_unit);
198#define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))

--- 8 unchanged lines hidden (view full) ---

207 if (ifa) {
208 sdl = (struct sockaddr_dl *)(ifa + 1);
209 sdl->sdl_len = socksize;
210 sdl->sdl_family = AF_LINK;
211 bcopy(workbuf, sdl->sdl_data, namelen);
212 sdl->sdl_nlen = namelen;
213 sdl->sdl_index = ifp->if_index;
214 sdl->sdl_type = ifp->if_type;
197 mtx_init(&ifp->if_snd.ifq_mtx, ifp->if_name, MTX_DEF);
198
199 /*
200 * create a Link Level name for this device
201 */
202 namelen = snprintf(workbuf, sizeof(workbuf),
203 "%s%d", ifp->if_name, ifp->if_unit);
204#define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))

--- 8 unchanged lines hidden (view full) ---

213 if (ifa) {
214 sdl = (struct sockaddr_dl *)(ifa + 1);
215 sdl->sdl_len = socksize;
216 sdl->sdl_family = AF_LINK;
217 bcopy(workbuf, sdl->sdl_data, namelen);
218 sdl->sdl_nlen = namelen;
219 sdl->sdl_index = ifp->if_index;
220 sdl->sdl_type = ifp->if_type;
215 ifnet_addrs[if_index - 1] = ifa;
221 ifaddr_byindex(if_index) = ifa;
216 ifa->ifa_ifp = ifp;
217 ifa->ifa_rtrequest = link_rtrequest;
218 ifa->ifa_addr = (struct sockaddr *)sdl;
219 sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl);
220 ifa->ifa_netmask = (struct sockaddr *)sdl;
221 sdl->sdl_len = masklen;
222 while (namelen != 0)
223 sdl->sdl_data[--namelen] = 0xff;

--- 16 unchanged lines hidden (view full) ---

240
241 /*
242 * Remove routes and flush queues.
243 */
244 s = splnet();
245 if_down(ifp);
246
247 /*
222 ifa->ifa_ifp = ifp;
223 ifa->ifa_rtrequest = link_rtrequest;
224 ifa->ifa_addr = (struct sockaddr *)sdl;
225 sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl);
226 ifa->ifa_netmask = (struct sockaddr *)sdl;
227 sdl->sdl_len = masklen;
228 while (namelen != 0)
229 sdl->sdl_data[--namelen] = 0xff;

--- 16 unchanged lines hidden (view full) ---

246
247 /*
248 * Remove routes and flush queues.
249 */
250 s = splnet();
251 if_down(ifp);
252
253 /*
248 * Remove address from ifnet_addrs[] and maybe decrement if_index.
254 * Remove address from ifindex_table[] and maybe decrement if_index.
249 * Clean up all addresses.
250 */
255 * Clean up all addresses.
256 */
251 ifnet_addrs[ifp->if_index - 1] = 0;
252 while (if_index > 0 && ifnet_addrs[if_index - 1] == 0)
257 ifaddr_byindex(ifp->if_index) = NULL;
258
259 while (if_index > 0 && ifaddr_byindex(if_index) == NULL)
253 if_index--;
254
255 for (ifa = TAILQ_FIRST(&ifp->if_addrhead); ifa;
256 ifa = TAILQ_FIRST(&ifp->if_addrhead)) {
257#ifdef INET
258 /* XXX: Ugly!! ad hoc just for INET */
259 if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) {
260 struct ifaliasreq ifr;

--- 334 unchanged lines hidden (view full) ---

595
596 /*
597 * AF_LINK addresses can be looked up directly by their index number,
598 * so do that if we can.
599 */
600 if (af == AF_LINK) {
601 register struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr;
602 if (sdl->sdl_index && sdl->sdl_index <= if_index)
260 if_index--;
261
262 for (ifa = TAILQ_FIRST(&ifp->if_addrhead); ifa;
263 ifa = TAILQ_FIRST(&ifp->if_addrhead)) {
264#ifdef INET
265 /* XXX: Ugly!! ad hoc just for INET */
266 if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) {
267 struct ifaliasreq ifr;

--- 334 unchanged lines hidden (view full) ---

602
603 /*
604 * AF_LINK addresses can be looked up directly by their index number,
605 * so do that if we can.
606 */
607 if (af == AF_LINK) {
608 register struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr;
609 if (sdl->sdl_index && sdl->sdl_index <= if_index)
603 return (ifnet_addrs[sdl->sdl_index - 1]);
610 return (ifaddr_byindex(sdl->sdl_index));
604 }
605
606 /*
607 * Scan though each interface, looking for ones that have
608 * addresses in this address family.
609 */
610 TAILQ_FOREACH(ifp, &ifnet, if_link) {
611 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {

--- 102 unchanged lines hidden (view full) ---

714 cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
715 for (; cp3 < cplim; cp3++)
716 if ((*cp++ ^ *cp2++) & *cp3)
717 break;
718 if (cp3 == cplim)
719 return (ifa);
720 }
721 }
611 }
612
613 /*
614 * Scan though each interface, looking for ones that have
615 * addresses in this address family.
616 */
617 TAILQ_FOREACH(ifp, &ifnet, if_link) {
618 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {

--- 102 unchanged lines hidden (view full) ---

721 cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
722 for (; cp3 < cplim; cp3++)
723 if ((*cp++ ^ *cp2++) & *cp3)
724 break;
725 if (cp3 == cplim)
726 return (ifa);
727 }
728 }
722 return (ifa_maybe);
729 ifa = ifa_maybe;
730done:
731 return (ifa);
723}
724
725#include <net/route.h>
726
727/*
728 * Default action when installing a route with a Link Level gateway.
729 * Lookup an appropriate real ifa to point to.
730 * This should be moved to /sys/net/link.c eventually.

--- 817 unchanged lines hidden (view full) ---

1548 * and we don't allow the length of the address to change.
1549 */
1550int
1551if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
1552{
1553 struct sockaddr_dl *sdl;
1554 struct ifaddr *ifa;
1555
732}
733
734#include <net/route.h>
735
736/*
737 * Default action when installing a route with a Link Level gateway.
738 * Lookup an appropriate real ifa to point to.
739 * This should be moved to /sys/net/link.c eventually.

--- 817 unchanged lines hidden (view full) ---

1557 * and we don't allow the length of the address to change.
1558 */
1559int
1560if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
1561{
1562 struct sockaddr_dl *sdl;
1563 struct ifaddr *ifa;
1564
1556 ifa = ifnet_addrs[ifp->if_index - 1];
1565 ifa = ifaddr_byindex(ifp->if_index);
1557 if (ifa == NULL)
1558 return (EINVAL);
1559 sdl = (struct sockaddr_dl *)ifa->ifa_addr;
1560 if (sdl == NULL)
1561 return (EINVAL);
1562 if (len != sdl->sdl_alen) /* don't allow length to change */
1563 return (EINVAL);
1564 switch (ifp->if_type) {

--- 41 unchanged lines hidden ---
1566 if (ifa == NULL)
1567 return (EINVAL);
1568 sdl = (struct sockaddr_dl *)ifa->ifa_addr;
1569 if (sdl == NULL)
1570 return (EINVAL);
1571 if (len != sdl->sdl_alen) /* don't allow length to change */
1572 return (EINVAL);
1573 switch (ifp->if_type) {

--- 41 unchanged lines hidden ---