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 --- |