Deleted Added
full compact
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");