if.c (159528) | if.c (159781) |
---|---|
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 --- 13 unchanged lines hidden (view full) --- 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * @(#)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 --- 13 unchanged lines hidden (view full) --- 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * @(#)if.c 8.5 (Berkeley) 1/9/95 |
30 * $FreeBSD: head/sys/net/if.c 159528 2006-06-11 22:09:28Z fjoe $ | 30 * $FreeBSD: head/sys/net/if.c 159781 2006-06-19 22:20:45Z mlaier $ |
31 */ 32 33#include "opt_compat.h" 34#include "opt_inet6.h" 35#include "opt_inet.h" 36#include "opt_mac.h" 37#include "opt_carp.h" 38 --- 69 unchanged lines hidden (view full) --- 108static int if_setflag(struct ifnet *, int, int, int *, int); 109static void if_slowtimo(void *); 110static void if_unroute(struct ifnet *, int flag, int fam); 111static void link_rtrequest(int, struct rtentry *, struct rt_addrinfo *); 112static int if_rtdel(struct radix_node *, void *); 113static int ifhwioctl(u_long, struct ifnet *, caddr_t, struct thread *); 114static void if_start_deferred(void *context, int pending); 115static void do_link_state_change(void *, int); | 31 */ 32 33#include "opt_compat.h" 34#include "opt_inet6.h" 35#include "opt_inet.h" 36#include "opt_mac.h" 37#include "opt_carp.h" 38 --- 69 unchanged lines hidden (view full) --- 108static int if_setflag(struct ifnet *, int, int, int *, int); 109static void if_slowtimo(void *); 110static void if_unroute(struct ifnet *, int flag, int fam); 111static void link_rtrequest(int, struct rtentry *, struct rt_addrinfo *); 112static int if_rtdel(struct radix_node *, void *); 113static int ifhwioctl(u_long, struct ifnet *, caddr_t, struct thread *); 114static void if_start_deferred(void *context, int pending); 115static void do_link_state_change(void *, int); |
116static int if_getgroup(struct ifgroupreq *, struct ifnet *); 117static int if_getgroupmembers(struct ifgroupreq *); |
|
116#ifdef INET6 117/* 118 * XXX: declare here to avoid to include many inet6 related files.. 119 * should be more generalized? 120 */ 121extern void nd6_setmtu(struct ifnet *); 122#endif 123 124int if_index = 0; 125struct ifindex_entry *ifindex_table = NULL; 126int ifqmaxlen = IFQ_MAXLEN; 127struct ifnethead ifnet; /* depend on static init XXX */ | 118#ifdef INET6 119/* 120 * XXX: declare here to avoid to include many inet6 related files.. 121 * should be more generalized? 122 */ 123extern void nd6_setmtu(struct ifnet *); 124#endif 125 126int if_index = 0; 127struct ifindex_entry *ifindex_table = NULL; 128int ifqmaxlen = IFQ_MAXLEN; 129struct ifnethead ifnet; /* depend on static init XXX */ |
130struct ifgrouphead ifg_head; |
|
128struct mtx ifnet_lock; 129static if_com_alloc_t *if_com_alloc[256]; 130static if_com_free_t *if_com_free[256]; 131 132static int if_indexlim = 8; 133static struct knlist ifklist; 134 135static void filt_netdetach(struct knote *kn); --- 141 unchanged lines hidden (view full) --- 277 */ 278/* ARGSUSED*/ 279static void 280if_init(void *dummy __unused) 281{ 282 283 IFNET_LOCK_INIT(); 284 TAILQ_INIT(&ifnet); | 131struct mtx ifnet_lock; 132static if_com_alloc_t *if_com_alloc[256]; 133static if_com_free_t *if_com_free[256]; 134 135static int if_indexlim = 8; 136static struct knlist ifklist; 137 138static void filt_netdetach(struct knote *kn); --- 141 unchanged lines hidden (view full) --- 280 */ 281/* ARGSUSED*/ 282static void 283if_init(void *dummy __unused) 284{ 285 286 IFNET_LOCK_INIT(); 287 TAILQ_INIT(&ifnet); |
288 TAILQ_INIT(&ifg_head); |
|
285 knlist_init(&ifklist, NULL, NULL, NULL, NULL); 286 if_grow(); /* create initial table */ 287 ifdev_byindex(0) = make_dev(&net_cdevsw, 0, 288 UID_ROOT, GID_WHEEL, 0600, "network"); 289 if_clone_init(); 290} 291 292static void --- 143 unchanged lines hidden (view full) --- 436 * The old code would work if the interface passed a pre-existing 437 * chain of ifaddrs to this code. We don't trust our callers to 438 * properly initialize the tailq, however, so we no longer allow 439 * this unlikely case. 440 */ 441 TAILQ_INIT(&ifp->if_addrhead); 442 TAILQ_INIT(&ifp->if_prefixhead); 443 TAILQ_INIT(&ifp->if_multiaddrs); | 289 knlist_init(&ifklist, NULL, NULL, NULL, NULL); 290 if_grow(); /* create initial table */ 291 ifdev_byindex(0) = make_dev(&net_cdevsw, 0, 292 UID_ROOT, GID_WHEEL, 0600, "network"); 293 if_clone_init(); 294} 295 296static void --- 143 unchanged lines hidden (view full) --- 440 * The old code would work if the interface passed a pre-existing 441 * chain of ifaddrs to this code. We don't trust our callers to 442 * properly initialize the tailq, however, so we no longer allow 443 * this unlikely case. 444 */ 445 TAILQ_INIT(&ifp->if_addrhead); 446 TAILQ_INIT(&ifp->if_prefixhead); 447 TAILQ_INIT(&ifp->if_multiaddrs); |
448 TAILQ_INIT(&ifp->if_groups); 449 450 if_addgroup(ifp, IFG_ALL); 451 |
|
444 knlist_init(&ifp->if_klist, NULL, NULL, NULL, NULL); 445 getmicrotime(&ifp->if_lastchange); 446 ifp->if_data.ifi_epoch = time_uptime; 447 ifp->if_data.ifi_datalen = sizeof(struct if_data); 448 449#ifdef MAC 450 mac_init_ifnet(ifp); 451 mac_create_ifnet(ifp); --- 258 unchanged lines hidden (view full) --- 710 TAILQ_REMOVE(&ifnet, ifp, if_link); 711 IFNET_WUNLOCK(); 712 mtx_destroy(&ifp->if_snd.ifq_mtx); 713 IF_AFDATA_DESTROY(ifp); 714 splx(s); 715} 716 717/* | 452 knlist_init(&ifp->if_klist, NULL, NULL, NULL, NULL); 453 getmicrotime(&ifp->if_lastchange); 454 ifp->if_data.ifi_epoch = time_uptime; 455 ifp->if_data.ifi_datalen = sizeof(struct if_data); 456 457#ifdef MAC 458 mac_init_ifnet(ifp); 459 mac_create_ifnet(ifp); --- 258 unchanged lines hidden (view full) --- 718 TAILQ_REMOVE(&ifnet, ifp, if_link); 719 IFNET_WUNLOCK(); 720 mtx_destroy(&ifp->if_snd.ifq_mtx); 721 IF_AFDATA_DESTROY(ifp); 722 splx(s); 723} 724 725/* |
726 * Add a group to an interface 727 */ 728int 729if_addgroup(struct ifnet *ifp, const char *groupname) 730{ 731 struct ifg_list *ifgl; 732 struct ifg_group *ifg = NULL; 733 struct ifg_member *ifgm; 734 735 if (groupname[0] && groupname[strlen(groupname) - 1] >= '0' && 736 groupname[strlen(groupname) - 1] <= '9') 737 return (EINVAL); 738 739 IFNET_WLOCK(); 740 TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) 741 if (!strcmp(ifgl->ifgl_group->ifg_group, groupname)) { 742 IFNET_WUNLOCK(); 743 return (EEXIST); 744 } 745 746 if ((ifgl = (struct ifg_list *)malloc(sizeof(struct ifg_list), M_TEMP, 747 M_NOWAIT)) == NULL) { 748 IFNET_WUNLOCK(); 749 return (ENOMEM); 750 } 751 752 if ((ifgm = (struct ifg_member *)malloc(sizeof(struct ifg_member), 753 M_TEMP, M_NOWAIT)) == NULL) { 754 free(ifgl, M_TEMP); 755 IFNET_WUNLOCK(); 756 return (ENOMEM); 757 } 758 759 TAILQ_FOREACH(ifg, &ifg_head, ifg_next) 760 if (!strcmp(ifg->ifg_group, groupname)) 761 break; 762 763 if (ifg == NULL) { 764 if ((ifg = (struct ifg_group *)malloc(sizeof(struct ifg_group), 765 M_TEMP, M_NOWAIT)) == NULL) { 766 free(ifgl, M_TEMP); 767 free(ifgm, M_TEMP); 768 IFNET_WUNLOCK(); 769 return (ENOMEM); 770 } 771 strlcpy(ifg->ifg_group, groupname, sizeof(ifg->ifg_group)); 772 ifg->ifg_refcnt = 0; 773 TAILQ_INIT(&ifg->ifg_members); 774 EVENTHANDLER_INVOKE(group_attach_event, ifg); 775 TAILQ_INSERT_TAIL(&ifg_head, ifg, ifg_next); 776 } 777 778 ifg->ifg_refcnt++; 779 ifgl->ifgl_group = ifg; 780 ifgm->ifgm_ifp = ifp; 781 782 IF_ADDR_LOCK(ifp); 783 TAILQ_INSERT_TAIL(&ifg->ifg_members, ifgm, ifgm_next); 784 TAILQ_INSERT_TAIL(&ifp->if_groups, ifgl, ifgl_next); 785 IF_ADDR_UNLOCK(ifp); 786 787 IFNET_WUNLOCK(); 788 789 EVENTHANDLER_INVOKE(group_change_event, groupname); 790 791 return (0); 792} 793 794/* 795 * Remove a group from an interface 796 */ 797int 798if_delgroup(struct ifnet *ifp, const char *groupname) 799{ 800 struct ifg_list *ifgl; 801 struct ifg_member *ifgm; 802 803 IFNET_WLOCK(); 804 TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) 805 if (!strcmp(ifgl->ifgl_group->ifg_group, groupname)) 806 break; 807 if (ifgl == NULL) { 808 IFNET_WUNLOCK(); 809 return (ENOENT); 810 } 811 812 IF_ADDR_LOCK(ifp); 813 TAILQ_REMOVE(&ifp->if_groups, ifgl, ifgl_next); 814 IF_ADDR_UNLOCK(ifp); 815 816 TAILQ_FOREACH(ifgm, &ifgl->ifgl_group->ifg_members, ifgm_next) 817 if (ifgm->ifgm_ifp == ifp) 818 break; 819 820 if (ifgm != NULL) { 821 TAILQ_REMOVE(&ifgl->ifgl_group->ifg_members, ifgm, ifgm_next); 822 free(ifgm, M_TEMP); 823 } 824 825 if (--ifgl->ifgl_group->ifg_refcnt == 0) { 826 TAILQ_REMOVE(&ifg_head, ifgl->ifgl_group, ifg_next); 827 EVENTHANDLER_INVOKE(group_detach_event, ifgl->ifgl_group); 828 free(ifgl->ifgl_group, M_TEMP); 829 } 830 IFNET_WUNLOCK(); 831 832 free(ifgl, M_TEMP); 833 834 EVENTHANDLER_INVOKE(group_change_event, groupname); 835 836 return (0); 837} 838 839/* 840 * Stores all groups from an interface in memory pointed 841 * to by data 842 */ 843static int 844if_getgroup(struct ifgroupreq *data, struct ifnet *ifp) 845{ 846 int len, error; 847 struct ifg_list *ifgl; 848 struct ifg_req ifgrq, *ifgp; 849 struct ifgroupreq *ifgr = data; 850 851 if (ifgr->ifgr_len == 0) { 852 IF_ADDR_LOCK(ifp); 853 TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) 854 ifgr->ifgr_len += sizeof(struct ifg_req); 855 IF_ADDR_UNLOCK(ifp); 856 return (0); 857 } 858 859 len = ifgr->ifgr_len; 860 ifgp = ifgr->ifgr_groups; 861 /* XXX: wire */ 862 IF_ADDR_LOCK(ifp); 863 TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) { 864 if (len < sizeof(ifgrq)) { 865 IF_ADDR_UNLOCK(ifp); 866 return (EINVAL); 867 } 868 bzero(&ifgrq, sizeof ifgrq); 869 strlcpy(ifgrq.ifgrq_group, ifgl->ifgl_group->ifg_group, 870 sizeof(ifgrq.ifgrq_group)); 871 if ((error = copyout(&ifgrq, ifgp, sizeof(struct ifg_req)))) { 872 IF_ADDR_UNLOCK(ifp); 873 return (error); 874 } 875 len -= sizeof(ifgrq); 876 ifgp++; 877 } 878 IF_ADDR_UNLOCK(ifp); 879 880 return (0); 881} 882 883/* 884 * Stores all members of a group in memory pointed to by data 885 */ 886static int 887if_getgroupmembers(struct ifgroupreq *data) 888{ 889 struct ifgroupreq *ifgr = data; 890 struct ifg_group *ifg; 891 struct ifg_member *ifgm; 892 struct ifg_req ifgrq, *ifgp; 893 int len, error; 894 895 IFNET_RLOCK(); 896 TAILQ_FOREACH(ifg, &ifg_head, ifg_next) 897 if (!strcmp(ifg->ifg_group, ifgr->ifgr_name)) 898 break; 899 if (ifg == NULL) { 900 IFNET_RUNLOCK(); 901 return (ENOENT); 902 } 903 904 if (ifgr->ifgr_len == 0) { 905 TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next) 906 ifgr->ifgr_len += sizeof(ifgrq); 907 IFNET_RUNLOCK(); 908 return (0); 909 } 910 911 len = ifgr->ifgr_len; 912 ifgp = ifgr->ifgr_groups; 913 TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next) { 914 if (len < sizeof(ifgrq)) { 915 IFNET_RUNLOCK(); 916 return (EINVAL); 917 } 918 bzero(&ifgrq, sizeof ifgrq); 919 strlcpy(ifgrq.ifgrq_member, ifgm->ifgm_ifp->if_xname, 920 sizeof(ifgrq.ifgrq_member)); 921 if ((error = copyout(&ifgrq, ifgp, sizeof(struct ifg_req)))) { 922 IFNET_RUNLOCK(); 923 return (error); 924 } 925 len -= sizeof(ifgrq); 926 ifgp++; 927 } 928 IFNET_RUNLOCK(); 929 930 return (0); 931} 932 933/* |
|
718 * Delete Routes for a Network Interface 719 * 720 * Called for each routing entry via the rnh->rnh_walktree() call above 721 * to delete all route entries referencing a detaching network interface. 722 * 723 * Arguments: 724 * rn pointer to node in the routing table 725 * arg argument passed to rnh->rnh_walktree() - detaching interface --- 741 unchanged lines hidden (view full) --- 1467 case SIOCSIFLLADDR: 1468 error = suser(td); 1469 if (error) 1470 return (error); 1471 error = if_setlladdr(ifp, 1472 ifr->ifr_addr.sa_data, ifr->ifr_addr.sa_len); 1473 break; 1474 | 934 * Delete Routes for a Network Interface 935 * 936 * Called for each routing entry via the rnh->rnh_walktree() call above 937 * to delete all route entries referencing a detaching network interface. 938 * 939 * Arguments: 940 * rn pointer to node in the routing table 941 * arg argument passed to rnh->rnh_walktree() - detaching interface --- 741 unchanged lines hidden (view full) --- 1683 case SIOCSIFLLADDR: 1684 error = suser(td); 1685 if (error) 1686 return (error); 1687 error = if_setlladdr(ifp, 1688 ifr->ifr_addr.sa_data, ifr->ifr_addr.sa_len); 1689 break; 1690 |
1691 case SIOCAIFGROUP: 1692 { 1693 struct ifgroupreq *ifgr = (struct ifgroupreq *)ifr; 1694 1695 error = suser(td); 1696 if (error) 1697 return (error); 1698 if ((error = if_addgroup(ifp, ifgr->ifgr_group))) 1699 return (error); 1700 break; 1701 } 1702 1703 case SIOCGIFGROUP: 1704 if ((error = if_getgroup((struct ifgroupreq *)ifr, ifp))) 1705 return (error); 1706 break; 1707 1708 case SIOCDIFGROUP: 1709 { 1710 struct ifgroupreq *ifgr = (struct ifgroupreq *)ifr; 1711 1712 error = suser(td); 1713 if (error) 1714 return (error); 1715 if ((error = if_delgroup(ifp, ifgr->ifgr_group))) 1716 return (error); 1717 break; 1718 } 1719 |
|
1475 default: 1476 error = ENOIOCTL; 1477 break; 1478 } 1479 return (error); 1480} 1481 1482/* --- 23 unchanged lines hidden (view full) --- 1506 if ((error = suser(td)) != 0) 1507 return (error); 1508 return ((cmd == SIOCIFCREATE) ? 1509 if_clone_create(ifr->ifr_name, sizeof(ifr->ifr_name)) : 1510 if_clone_destroy(ifr->ifr_name)); 1511 1512 case SIOCIFGCLONERS: 1513 return (if_clone_list((struct if_clonereq *)data)); | 1720 default: 1721 error = ENOIOCTL; 1722 break; 1723 } 1724 return (error); 1725} 1726 1727/* --- 23 unchanged lines hidden (view full) --- 1751 if ((error = suser(td)) != 0) 1752 return (error); 1753 return ((cmd == SIOCIFCREATE) ? 1754 if_clone_create(ifr->ifr_name, sizeof(ifr->ifr_name)) : 1755 if_clone_destroy(ifr->ifr_name)); 1756 1757 case SIOCIFGCLONERS: 1758 return (if_clone_list((struct if_clonereq *)data)); |
1759 case SIOCGIFGMEMB: 1760 return (if_getgroupmembers((struct ifgroupreq *)data)); |
|
1514 } 1515 1516 ifp = ifunit(ifr->ifr_name); 1517 if (ifp == 0) 1518 return (ENXIO); 1519 1520 error = ifhwioctl(cmd, ifp, data, td); 1521 if (error != ENOIOCTL) --- 767 unchanged lines hidden --- | 1761 } 1762 1763 ifp = ifunit(ifr->ifr_name); 1764 if (ifp == 0) 1765 return (ENXIO); 1766 1767 error = ifhwioctl(cmd, ifp, data, td); 1768 if (error != ENOIOCTL) --- 767 unchanged lines hidden --- |