if.c (108033) | if.c (108172) |
---|---|
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.5 (Berkeley) 1/9/95 | 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.5 (Berkeley) 1/9/95 |
34 * $FreeBSD: head/sys/net/if.c 108033 2002-12-18 11:46:59Z hsu $ | 34 * $FreeBSD: head/sys/net/if.c 108172 2002-12-22 05:35:03Z hsu $ |
35 */ 36 37#include "opt_compat.h" 38#include "opt_inet6.h" 39#include "opt_inet.h" 40#include "opt_mac.h" 41 42#include <sys/param.h> --- 54 unchanged lines hidden (view full) --- 97 */ 98extern void nd6_setmtu(struct ifnet *); 99#endif 100 101int if_index = 0; 102struct ifindex_entry *ifindex_table = NULL; 103int ifqmaxlen = IFQ_MAXLEN; 104struct ifnethead ifnet; /* depend on static init XXX */ | 35 */ 36 37#include "opt_compat.h" 38#include "opt_inet6.h" 39#include "opt_inet.h" 40#include "opt_mac.h" 41 42#include <sys/param.h> --- 54 unchanged lines hidden (view full) --- 97 */ 98extern void nd6_setmtu(struct ifnet *); 99#endif 100 101int if_index = 0; 102struct ifindex_entry *ifindex_table = NULL; 103int ifqmaxlen = IFQ_MAXLEN; 104struct ifnethead ifnet; /* depend on static init XXX */ |
105struct mtx ifnet_lock; |
|
105int if_cloners_count; 106LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners); 107 108static int if_indexlim = 8; 109static struct klist ifklist; 110 111static void filt_netdetach(struct knote *kn); 112static int filt_netdev(struct knote *kn, long hint); --- 145 unchanged lines hidden (view full) --- 258 * parameters. 259 */ 260/* ARGSUSED*/ 261static void 262if_init(dummy) 263 void *dummy; 264{ 265 | 106int if_cloners_count; 107LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners); 108 109static int if_indexlim = 8; 110static struct klist ifklist; 111 112static void filt_netdetach(struct knote *kn); 113static int filt_netdev(struct knote *kn, long hint); --- 145 unchanged lines hidden (view full) --- 259 * parameters. 260 */ 261/* ARGSUSED*/ 262static void 263if_init(dummy) 264 void *dummy; 265{ 266 |
267 IFNET_LOCK_INIT(); |
|
266 TAILQ_INIT(&ifnet); 267 SLIST_INIT(&ifklist); 268 if_grow(); /* create initial table */ 269 ifdev_byindex(0) = make_dev(&net_cdevsw, 0, 270 UID_ROOT, GID_WHEEL, 0600, "network"); 271} 272 273static void --- 16 unchanged lines hidden (view full) --- 290static void 291if_check(dummy) 292 void *dummy; 293{ 294 struct ifnet *ifp; 295 int s; 296 297 s = splimp(); | 268 TAILQ_INIT(&ifnet); 269 SLIST_INIT(&ifklist); 270 if_grow(); /* create initial table */ 271 ifdev_byindex(0) = make_dev(&net_cdevsw, 0, 272 UID_ROOT, GID_WHEEL, 0600, "network"); 273} 274 275static void --- 16 unchanged lines hidden (view full) --- 292static void 293if_check(dummy) 294 void *dummy; 295{ 296 struct ifnet *ifp; 297 int s; 298 299 s = splimp(); |
300 IFNET_RLOCK(); /* could sleep on rare error; mostly okay XXX */ |
|
298 TAILQ_FOREACH(ifp, &ifnet, if_link) { 299 if (ifp->if_snd.ifq_maxlen == 0) { 300 printf("%s%d XXX: driver didn't set ifq_maxlen\n", 301 ifp->if_name, ifp->if_unit); 302 ifp->if_snd.ifq_maxlen = ifqmaxlen; 303 } 304 if (!mtx_initialized(&ifp->if_snd.ifq_mtx)) { 305 printf("%s%d XXX: driver didn't initialize queue mtx\n", 306 ifp->if_name, ifp->if_unit); 307 mtx_init(&ifp->if_snd.ifq_mtx, "unknown", 308 MTX_NETWORK_LOCK, MTX_DEF); 309 } 310 } | 301 TAILQ_FOREACH(ifp, &ifnet, if_link) { 302 if (ifp->if_snd.ifq_maxlen == 0) { 303 printf("%s%d XXX: driver didn't set ifq_maxlen\n", 304 ifp->if_name, ifp->if_unit); 305 ifp->if_snd.ifq_maxlen = ifqmaxlen; 306 } 307 if (!mtx_initialized(&ifp->if_snd.ifq_mtx)) { 308 printf("%s%d XXX: driver didn't initialize queue mtx\n", 309 ifp->if_name, ifp->if_unit); 310 mtx_init(&ifp->if_snd.ifq_mtx, "unknown", 311 MTX_NETWORK_LOCK, MTX_DEF); 312 } 313 } |
314 IFNET_RUNLOCK(); |
|
311 splx(s); 312 if_slowtimo(0); 313} 314 315static int 316if_findindex(struct ifnet *ifp) 317{ 318 int i, unit; --- 52 unchanged lines hidden (view full) --- 371 struct ifnet *ifp; 372{ 373 unsigned socksize, ifasize; 374 int namelen, masklen; 375 char workbuf[64]; 376 register struct sockaddr_dl *sdl; 377 register struct ifaddr *ifa; 378 | 315 splx(s); 316 if_slowtimo(0); 317} 318 319static int 320if_findindex(struct ifnet *ifp) 321{ 322 int i, unit; --- 52 unchanged lines hidden (view full) --- 375 struct ifnet *ifp; 376{ 377 unsigned socksize, ifasize; 378 int namelen, masklen; 379 char workbuf[64]; 380 register struct sockaddr_dl *sdl; 381 register struct ifaddr *ifa; 382 |
383 IFNET_WLOCK(); |
|
379 TAILQ_INSERT_TAIL(&ifnet, ifp, if_link); | 384 TAILQ_INSERT_TAIL(&ifnet, ifp, if_link); |
385 IFNET_WUNLOCK(); |
|
380 /* 381 * XXX - 382 * The old code would work if the interface passed a pre-existing 383 * chain of ifaddrs to this code. We don't trust our callers to 384 * properly initialize the tailq, however, so we no longer allow 385 * this unlikely case. 386 */ 387 TAILQ_INIT(&ifp->if_addrhead); --- 144 unchanged lines hidden (view full) --- 532 533 /* Announce that the interface is gone. */ 534 rt_ifannouncemsg(ifp, IFAN_DEPARTURE); 535 536#ifdef MAC 537 mac_destroy_ifnet(ifp); 538#endif /* MAC */ 539 KNOTE(&ifp->if_klist, NOTE_EXIT); | 386 /* 387 * XXX - 388 * The old code would work if the interface passed a pre-existing 389 * chain of ifaddrs to this code. We don't trust our callers to 390 * properly initialize the tailq, however, so we no longer allow 391 * this unlikely case. 392 */ 393 TAILQ_INIT(&ifp->if_addrhead); --- 144 unchanged lines hidden (view full) --- 538 539 /* Announce that the interface is gone. */ 540 rt_ifannouncemsg(ifp, IFAN_DEPARTURE); 541 542#ifdef MAC 543 mac_destroy_ifnet(ifp); 544#endif /* MAC */ 545 KNOTE(&ifp->if_klist, NOTE_EXIT); |
546 IFNET_WLOCK(); |
|
540 TAILQ_REMOVE(&ifnet, ifp, if_link); | 547 TAILQ_REMOVE(&ifnet, ifp, if_link); |
548 IFNET_WUNLOCK(); |
|
541 mtx_destroy(&ifp->if_snd.ifq_mtx); 542 splx(s); 543} 544 545/* 546 * Delete Routes for a Network Interface 547 * 548 * Called for each routing entry via the rnh->rnh_walktree() call above --- 292 unchanged lines hidden (view full) --- 841/*ARGSUSED*/ 842struct ifaddr * 843ifa_ifwithaddr(addr) 844 struct sockaddr *addr; 845{ 846 struct ifnet *ifp; 847 struct ifaddr *ifa; 848 | 549 mtx_destroy(&ifp->if_snd.ifq_mtx); 550 splx(s); 551} 552 553/* 554 * Delete Routes for a Network Interface 555 * 556 * Called for each routing entry via the rnh->rnh_walktree() call above --- 292 unchanged lines hidden (view full) --- 849/*ARGSUSED*/ 850struct ifaddr * 851ifa_ifwithaddr(addr) 852 struct sockaddr *addr; 853{ 854 struct ifnet *ifp; 855 struct ifaddr *ifa; 856 |
857 IFNET_RLOCK(); |
|
849 TAILQ_FOREACH(ifp, &ifnet, if_link) 850 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 851 if (ifa->ifa_addr->sa_family != addr->sa_family) 852 continue; 853 if (equal(addr, ifa->ifa_addr)) 854 goto done; 855 /* IP6 doesn't have broadcast */ 856 if ((ifp->if_flags & IFF_BROADCAST) && 857 ifa->ifa_broadaddr && 858 ifa->ifa_broadaddr->sa_len != 0 && 859 equal(ifa->ifa_broadaddr, addr)) 860 goto done; 861 } 862 ifa = NULL; 863done: | 858 TAILQ_FOREACH(ifp, &ifnet, if_link) 859 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 860 if (ifa->ifa_addr->sa_family != addr->sa_family) 861 continue; 862 if (equal(addr, ifa->ifa_addr)) 863 goto done; 864 /* IP6 doesn't have broadcast */ 865 if ((ifp->if_flags & IFF_BROADCAST) && 866 ifa->ifa_broadaddr && 867 ifa->ifa_broadaddr->sa_len != 0 && 868 equal(ifa->ifa_broadaddr, addr)) 869 goto done; 870 } 871 ifa = NULL; 872done: |
873 IFNET_RUNLOCK(); |
|
864 return (ifa); 865} 866 867/* 868 * Locate the point to point interface with a given destination address. 869 */ 870/*ARGSUSED*/ 871struct ifaddr * 872ifa_ifwithdstaddr(addr) 873 struct sockaddr *addr; 874{ 875 struct ifnet *ifp; 876 struct ifaddr *ifa; 877 | 874 return (ifa); 875} 876 877/* 878 * Locate the point to point interface with a given destination address. 879 */ 880/*ARGSUSED*/ 881struct ifaddr * 882ifa_ifwithdstaddr(addr) 883 struct sockaddr *addr; 884{ 885 struct ifnet *ifp; 886 struct ifaddr *ifa; 887 |
888 IFNET_RLOCK(); |
|
878 TAILQ_FOREACH(ifp, &ifnet, if_link) { 879 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) 880 continue; 881 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 882 if (ifa->ifa_addr->sa_family != addr->sa_family) 883 continue; 884 if (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr)) 885 goto done; 886 } 887 } 888 ifa = NULL; 889done: | 889 TAILQ_FOREACH(ifp, &ifnet, if_link) { 890 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) 891 continue; 892 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 893 if (ifa->ifa_addr->sa_family != addr->sa_family) 894 continue; 895 if (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr)) 896 goto done; 897 } 898 } 899 ifa = NULL; 900done: |
901 IFNET_RUNLOCK(); |
|
890 return (ifa); 891} 892 893/* 894 * Find an interface on a specific network. If many, choice 895 * is most specific found. 896 */ 897struct ifaddr * --- 15 unchanged lines hidden (view full) --- 913 if (sdl->sdl_index && sdl->sdl_index <= if_index) 914 return (ifaddr_byindex(sdl->sdl_index)); 915 } 916 917 /* 918 * Scan though each interface, looking for ones that have 919 * addresses in this address family. 920 */ | 902 return (ifa); 903} 904 905/* 906 * Find an interface on a specific network. If many, choice 907 * is most specific found. 908 */ 909struct ifaddr * --- 15 unchanged lines hidden (view full) --- 925 if (sdl->sdl_index && sdl->sdl_index <= if_index) 926 return (ifaddr_byindex(sdl->sdl_index)); 927 } 928 929 /* 930 * Scan though each interface, looking for ones that have 931 * addresses in this address family. 932 */ |
933 IFNET_RLOCK(); |
|
921 TAILQ_FOREACH(ifp, &ifnet, if_link) { 922 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 923 register char *cp, *cp2, *cp3; 924 925 if (ifa->ifa_addr->sa_family != af) 926next: continue; 927 if (af == AF_INET && ifp->if_flags & IFF_POINTOPOINT) { 928 /* --- 46 unchanged lines hidden (view full) --- 975 rn_refines((caddr_t)ifa->ifa_netmask, 976 (caddr_t)ifa_maybe->ifa_netmask)) 977 ifa_maybe = ifa; 978 } 979 } 980 } 981 ifa = ifa_maybe; 982done: | 934 TAILQ_FOREACH(ifp, &ifnet, if_link) { 935 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 936 register char *cp, *cp2, *cp3; 937 938 if (ifa->ifa_addr->sa_family != af) 939next: continue; 940 if (af == AF_INET && ifp->if_flags & IFF_POINTOPOINT) { 941 /* --- 46 unchanged lines hidden (view full) --- 988 rn_refines((caddr_t)ifa->ifa_netmask, 989 (caddr_t)ifa_maybe->ifa_netmask)) 990 ifa_maybe = ifa; 991 } 992 } 993 } 994 ifa = ifa_maybe; 995done: |
996 IFNET_RUNLOCK(); |
|
983 return (ifa); 984} 985 986/* 987 * Find an interface address specific to an interface best matching 988 * a given address. 989 */ 990struct ifaddr * --- 166 unchanged lines hidden (view full) --- 1157 */ 1158static void 1159if_slowtimo(arg) 1160 void *arg; 1161{ 1162 register struct ifnet *ifp; 1163 int s = splimp(); 1164 | 997 return (ifa); 998} 999 1000/* 1001 * Find an interface address specific to an interface best matching 1002 * a given address. 1003 */ 1004struct ifaddr * --- 166 unchanged lines hidden (view full) --- 1171 */ 1172static void 1173if_slowtimo(arg) 1174 void *arg; 1175{ 1176 register struct ifnet *ifp; 1177 int s = splimp(); 1178 |
1179 IFNET_RLOCK(); |
|
1165 TAILQ_FOREACH(ifp, &ifnet, if_link) { 1166 if (ifp->if_timer == 0 || --ifp->if_timer) 1167 continue; 1168 if (ifp->if_watchdog) 1169 (*ifp->if_watchdog)(ifp); 1170 } | 1180 TAILQ_FOREACH(ifp, &ifnet, if_link) { 1181 if (ifp->if_timer == 0 || --ifp->if_timer) 1182 continue; 1183 if (ifp->if_watchdog) 1184 (*ifp->if_watchdog)(ifp); 1185 } |
1186 IFNET_RUNLOCK(); |
|
1171 splx(s); 1172 timeout(if_slowtimo, (void *)0, hz / IFNET_SLOWHZ); 1173} 1174 1175/* 1176 * Map interface name to 1177 * interface structure pointer. 1178 */ --- 8 unchanged lines hidden (view full) --- 1187 * Now search all the interfaces for this name/number 1188 */ 1189 1190 /* 1191 * XXX 1192 * Devices should really be known as /dev/fooN, not /dev/net/fooN. 1193 */ 1194 snprintf(namebuf, IFNAMSIZ, "%s/%s", net_cdevsw.d_name, name); | 1187 splx(s); 1188 timeout(if_slowtimo, (void *)0, hz / IFNET_SLOWHZ); 1189} 1190 1191/* 1192 * Map interface name to 1193 * interface structure pointer. 1194 */ --- 8 unchanged lines hidden (view full) --- 1203 * Now search all the interfaces for this name/number 1204 */ 1205 1206 /* 1207 * XXX 1208 * Devices should really be known as /dev/fooN, not /dev/net/fooN. 1209 */ 1210 snprintf(namebuf, IFNAMSIZ, "%s/%s", net_cdevsw.d_name, name); |
1211 IFNET_RLOCK(); |
|
1195 TAILQ_FOREACH(ifp, &ifnet, if_link) { 1196 dev = ifdev_byindex(ifp->if_index); 1197 if (strcmp(devtoname(dev), namebuf) == 0) 1198 break; 1199 if (dev_named(dev, name)) 1200 break; 1201 } | 1212 TAILQ_FOREACH(ifp, &ifnet, if_link) { 1213 dev = ifdev_byindex(ifp->if_index); 1214 if (strcmp(devtoname(dev), namebuf) == 0) 1215 break; 1216 if (dev_named(dev, name)) 1217 break; 1218 } |
1219 IFNET_RUNLOCK(); |
|
1202 return (ifp); 1203} 1204 1205/* 1206 * Map interface name in a sockaddr_dl to 1207 * interface structure pointer. 1208 */ 1209struct ifnet * --- 410 unchanged lines hidden (view full) --- 1620{ 1621 struct ifconf *ifc = (struct ifconf *)data; 1622 struct ifnet *ifp; 1623 struct ifaddr *ifa; 1624 struct ifreq ifr, *ifrp; 1625 int space = ifc->ifc_len, error = 0; 1626 1627 ifrp = ifc->ifc_req; | 1220 return (ifp); 1221} 1222 1223/* 1224 * Map interface name in a sockaddr_dl to 1225 * interface structure pointer. 1226 */ 1227struct ifnet * --- 410 unchanged lines hidden (view full) --- 1638{ 1639 struct ifconf *ifc = (struct ifconf *)data; 1640 struct ifnet *ifp; 1641 struct ifaddr *ifa; 1642 struct ifreq ifr, *ifrp; 1643 int space = ifc->ifc_len, error = 0; 1644 1645 ifrp = ifc->ifc_req; |
1646 IFNET_RLOCK(); /* could sleep XXX */ |
|
1628 TAILQ_FOREACH(ifp, &ifnet, if_link) { 1629 char workbuf[64]; 1630 int ifnlen, addrs; 1631 1632 if (space < sizeof(ifr)) 1633 break; 1634 ifnlen = snprintf(workbuf, sizeof(workbuf), 1635 "%s%d", ifp->if_name, ifp->if_unit); --- 54 unchanged lines hidden (view full) --- 1690 error = copyout((caddr_t)&ifr, (caddr_t)ifrp, 1691 sizeof (ifr)); 1692 if (error) 1693 break; 1694 space -= sizeof (ifr); 1695 ifrp++; 1696 } 1697 } | 1647 TAILQ_FOREACH(ifp, &ifnet, if_link) { 1648 char workbuf[64]; 1649 int ifnlen, addrs; 1650 1651 if (space < sizeof(ifr)) 1652 break; 1653 ifnlen = snprintf(workbuf, sizeof(workbuf), 1654 "%s%d", ifp->if_name, ifp->if_unit); --- 54 unchanged lines hidden (view full) --- 1709 error = copyout((caddr_t)&ifr, (caddr_t)ifrp, 1710 sizeof (ifr)); 1711 if (error) 1712 break; 1713 space -= sizeof (ifr); 1714 ifrp++; 1715 } 1716 } |
1717 IFNET_RUNLOCK(); |
|
1698 ifc->ifc_len -= space; 1699 return (error); 1700} 1701 1702/* 1703 * Just like if_promisc(), but for all-multicast-reception mode. 1704 */ 1705int --- 288 unchanged lines hidden --- | 1718 ifc->ifc_len -= space; 1719 return (error); 1720} 1721 1722/* 1723 * Just like if_promisc(), but for all-multicast-reception mode. 1724 */ 1725int --- 288 unchanged lines hidden --- |