if.c (20407) | if.c (21404) |
---|---|
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 * $Id: if.c,v 1.37 1996/12/11 20:38:14 wollman Exp $ | 34 * $Id: if.c,v 1.38 1996/12/13 21:28:37 wollman Exp $ |
35 */ 36 37#include <sys/param.h> 38#include <sys/queue.h> 39#include <sys/mbuf.h> 40#include <sys/systm.h> 41#include <sys/proc.h> 42#include <sys/socket.h> --- 77 unchanged lines hidden (view full) --- 120 /* 121 * XXX - 122 * The old code would work if the interface passed a pre-existing 123 * chain of ifaddrs to this code. We don't trust our callers to 124 * properly initialize the tailq, however, so we no longer allow 125 * this unlikely case. 126 */ 127 TAILQ_INIT(&ifp->if_addrhead); | 35 */ 36 37#include <sys/param.h> 38#include <sys/queue.h> 39#include <sys/mbuf.h> 40#include <sys/systm.h> 41#include <sys/proc.h> 42#include <sys/socket.h> --- 77 unchanged lines hidden (view full) --- 120 /* 121 * XXX - 122 * The old code would work if the interface passed a pre-existing 123 * chain of ifaddrs to this code. We don't trust our callers to 124 * properly initialize the tailq, however, so we no longer allow 125 * this unlikely case. 126 */ 127 TAILQ_INIT(&ifp->if_addrhead); |
128 LIST_INIT(&ifp->if_multiaddrs); |
|
128 microtime(&ifp->if_lastchange); 129 if (ifnet_addrs == 0 || if_index >= if_indexlim) { 130 unsigned n = (if_indexlim <<= 1) * sizeof(ifa); 131 struct ifaddr **q = (struct ifaddr **) 132 malloc(n, M_IFADDR, M_WAITOK); 133 bzero((caddr_t)q, n); 134 if (ifnet_addrs) { 135 bcopy((caddr_t)ifnet_addrs, (caddr_t)q, n/2); --- 617 unchanged lines hidden (view full) --- 753 break; 754 space -= sizeof (ifr); 755 } 756 } 757 ifc->ifc_len -= space; 758 return (error); 759} 760 | 129 microtime(&ifp->if_lastchange); 130 if (ifnet_addrs == 0 || if_index >= if_indexlim) { 131 unsigned n = (if_indexlim <<= 1) * sizeof(ifa); 132 struct ifaddr **q = (struct ifaddr **) 133 malloc(n, M_IFADDR, M_WAITOK); 134 bzero((caddr_t)q, n); 135 if (ifnet_addrs) { 136 bcopy((caddr_t)ifnet_addrs, (caddr_t)q, n/2); --- 617 unchanged lines hidden (view full) --- 754 break; 755 space -= sizeof (ifr); 756 } 757 } 758 ifc->ifc_len -= space; 759 return (error); 760} 761 |
762/* 763 * Just like if_promisc(), but for all-multicast-reception mode. 764 */ 765int 766if_allmulti(ifp, onswitch) 767 struct ifnet *ifp; 768 int onswitch; 769{ 770 int error = 0; 771 int s = splimp(); 772 773 if (onswitch) { 774 if (ifp->if_amcount++ == 0) { 775 ifp->if_flags |= IFF_ALLMULTI; 776 error = ifp->if_ioctl(ifp, SIOCSIFFLAGS, 0); 777 } 778 } else { 779 if (ifp->if_amcount > 1) { 780 ifp->if_amcount--; 781 } else { 782 ifp->if_amcount = 0; 783 ifp->if_flags &= ~IFF_ALLMULTI; 784 error = ifp->if_ioctl(ifp, SIOCSIFFLAGS, 0); 785 } 786 } 787 splx(s); 788 return error; 789} 790 791/* 792 * Add a multicast listenership to the interface in question. 793 * The link layer provides a routine which converts 794 */ 795int 796if_addmulti(ifp, sa) 797 struct ifnet *ifp; /* interface to manipulate */ 798 struct sockaddr *sa; /* address to add */ 799{ 800 struct sockaddr *llsa, *dupsa; 801 int error, s; 802 struct ifmultiaddr *ifma; 803 804 for (ifma = ifp->if_multiaddrs.lh_first; ifma; 805 ifma = ifma->ifma_link.le_next) { 806 if (equal(sa, ifma->ifma_addr)) 807 break; 808 } 809 810 if (ifma) { 811 ifma->ifma_refcount++; 812 return 0; 813 } 814 815 /* 816 * Give the link layer a chance to accept/reject it, and also 817 * find out which AF_LINK address this maps to, if it isn't one 818 * already. 819 */ 820 if (ifp->if_resolvemulti) { 821 error = ifp->if_resolvemulti(ifp, &llsa, sa); 822 if (error) return error; 823 } else { 824 llsa = 0; 825 } 826 827 MALLOC(ifma, struct ifmultiaddr *, sizeof *ifma, M_IFMADDR, M_WAITOK); 828 MALLOC(dupsa, struct sockaddr *, sa->sa_len, M_IFMADDR, M_WAITOK); 829 bcopy(sa, dupsa, sa->sa_len); 830 831 ifma->ifma_addr = dupsa; 832 ifma->ifma_lladdr = llsa; 833 ifma->ifma_ifp = ifp; 834 ifma->ifma_refcount = 1; 835 /* 836 * Some network interfaces can scan the address list at 837 * interrupt time; lock them out. 838 */ 839 s = splimp(); 840 LIST_INSERT_HEAD(&ifp->if_multiaddrs, ifma, ifma_link); 841 splx(s); 842 843 if (llsa != 0) { 844 for (ifma = ifp->if_multiaddrs.lh_first; ifma; 845 ifma = ifma->ifma_link.le_next) { 846 if (equal(ifma->ifma_addr, llsa)) 847 break; 848 } 849 if (ifma) { 850 ifma->ifma_refcount++; 851 } else { 852 MALLOC(ifma, struct ifmultiaddr *, sizeof *ifma, 853 M_IFMADDR, M_WAITOK); 854 ifma->ifma_addr = llsa; 855 ifma->ifma_ifp = ifp; 856 ifma->ifma_refcount = 1; 857 } 858 s = splimp(); 859 LIST_INSERT_HEAD(&ifp->if_multiaddrs, ifma, ifma_link); 860 splx(s); 861 } 862 /* 863 * We are certain we have added something, so call down to the 864 * interface to let them know about it. 865 */ 866 s = splimp(); 867 ifp->if_ioctl(ifp, SIOCADDMULTI, 0); 868 splx(s); 869 870 return 0; 871} 872 873/* 874 * Remove a reference to a multicast address on this interface. Yell 875 * if the request does not match an existing membership. 876 */ 877int 878if_delmulti(ifp, sa) 879 struct ifnet *ifp; 880 struct sockaddr *sa; 881{ 882 struct ifmultiaddr *ifma; 883 int s; 884 885 for (ifma = ifp->if_multiaddrs.lh_first; ifma; 886 ifma = ifma->ifma_link.le_next) 887 if (equal(sa, ifma->ifma_addr)) 888 break; 889 if (ifma == 0) 890 return ENOENT; 891 892 if (ifma->ifma_refcount > 1) { 893 ifma->ifma_refcount--; 894 return 0; 895 } 896 897 sa = ifma->ifma_lladdr; 898 s = splimp(); 899 LIST_REMOVE(ifma, ifma_link); 900 splx(s); 901 free(ifma->ifma_addr, M_IFMADDR); 902 free(ifma, M_IFMADDR); 903 if (sa == 0) 904 return 0; 905 906 /* 907 * Now look for the link-layer address which corresponds to 908 * this network address. It had been squirreled away in 909 * ifma->ifma_lladdr for this purpose (so we don't have 910 * to call ifp->if_resolvemulti() again), and we saved that 911 * value in sa above. If some nasty deleted the 912 * link-layer address out from underneath us, we can deal because 913 * the address we stored was is not the same as the one which was 914 * in the record for the link-layer address. (So we don't complain 915 * in that case.) 916 */ 917 for (ifma = ifp->if_multiaddrs.lh_first; ifma; 918 ifma = ifma->ifma_link.le_next) 919 if (equal(sa, ifma->ifma_addr)) 920 break; 921 if (ifma == 0) 922 return 0; 923 924 if (ifma->ifma_refcount > 1) { 925 ifma->ifma_refcount--; 926 return 0; 927 } 928 929 s = splimp(); 930 LIST_REMOVE(ifma, ifma_link); 931 splx(s); 932 free(ifma->ifma_addr, M_IFMADDR); 933 free(sa, M_IFMADDR); 934 free(ifma, M_IFMADDR); 935 936 return 0; 937} 938 |
|
761SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW, 0, "Link layers"); 762SYSCTL_NODE(_net_link, 0, generic, CTLFLAG_RW, 0, "Generic link-management"); | 939SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW, 0, "Link layers"); 940SYSCTL_NODE(_net_link, 0, generic, CTLFLAG_RW, 0, "Generic link-management"); |