in.c (169454) | in.c (170613) |
---|---|
1/*- 2 * Copyright (c) 1982, 1986, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * Copyright (C) 2001 WIDE Project. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 14 unchanged lines hidden (view full) --- 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 * @(#)in.c 8.4 (Berkeley) 1/9/95 | 1/*- 2 * Copyright (c) 1982, 1986, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * Copyright (C) 2001 WIDE Project. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 14 unchanged lines hidden (view full) --- 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 * @(#)in.c 8.4 (Berkeley) 1/9/95 |
31 * $FreeBSD: head/sys/netinet/in.c 169454 2007-05-10 15:58:48Z rwatson $ | 31 * $FreeBSD: head/sys/netinet/in.c 170613 2007-06-12 16:24:56Z bms $ |
32 */ 33 34#include "opt_carp.h" 35 36#include <sys/param.h> 37#include <sys/systm.h> 38#include <sys/sockio.h> 39#include <sys/malloc.h> --- 4 unchanged lines hidden (view full) --- 44 45#include <net/if.h> 46#include <net/if_types.h> 47#include <net/route.h> 48 49#include <netinet/in.h> 50#include <netinet/in_var.h> 51#include <netinet/in_pcb.h> | 32 */ 33 34#include "opt_carp.h" 35 36#include <sys/param.h> 37#include <sys/systm.h> 38#include <sys/sockio.h> 39#include <sys/malloc.h> --- 4 unchanged lines hidden (view full) --- 44 45#include <net/if.h> 46#include <net/if_types.h> 47#include <net/route.h> 48 49#include <netinet/in.h> 50#include <netinet/in_var.h> 51#include <netinet/in_pcb.h> |
52#include <netinet/ip_var.h> |
|
52 | 53 |
53#include <netinet/igmp_var.h> 54 55static MALLOC_DEFINE(M_IPMADDR, "in_multi", "internet multicast address"); 56 | |
57static int in_mask2len(struct in_addr *); 58static void in_len2mask(struct in_addr *, int); 59static int in_lifaddr_ioctl(struct socket *, u_long, caddr_t, 60 struct ifnet *, struct thread *); 61 62static int in_addprefix(struct in_ifaddr *, int); 63static int in_scrubprefix(struct in_ifaddr *); 64static void in_socktrim(struct sockaddr_in *); --- 4 unchanged lines hidden (view full) --- 69static int subnetsarelocal = 0; 70SYSCTL_INT(_net_inet_ip, OID_AUTO, subnets_are_local, CTLFLAG_RW, 71 &subnetsarelocal, 0, "Treat all subnets as directly connected"); 72static int sameprefixcarponly = 0; 73SYSCTL_INT(_net_inet_ip, OID_AUTO, same_prefix_carp_only, CTLFLAG_RW, 74 &sameprefixcarponly, 0, 75 "Refuse to create same prefixes on different interfaces"); 76 | 54static int in_mask2len(struct in_addr *); 55static void in_len2mask(struct in_addr *, int); 56static int in_lifaddr_ioctl(struct socket *, u_long, caddr_t, 57 struct ifnet *, struct thread *); 58 59static int in_addprefix(struct in_ifaddr *, int); 60static int in_scrubprefix(struct in_ifaddr *); 61static void in_socktrim(struct sockaddr_in *); --- 4 unchanged lines hidden (view full) --- 66static int subnetsarelocal = 0; 67SYSCTL_INT(_net_inet_ip, OID_AUTO, subnets_are_local, CTLFLAG_RW, 68 &subnetsarelocal, 0, "Treat all subnets as directly connected"); 69static int sameprefixcarponly = 0; 70SYSCTL_INT(_net_inet_ip, OID_AUTO, same_prefix_carp_only, CTLFLAG_RW, 71 &sameprefixcarponly, 0, 72 "Refuse to create same prefixes on different interfaces"); 73 |
77/* 78 * The IPv4 multicast list (in_multihead and associated structures) are 79 * protected by the global in_multi_mtx. See in_var.h for more details. For 80 * now, in_multi_mtx is marked as recursible due to IGMP's calling back into 81 * ip_output() to send IGMP packets while holding the lock; this probably is 82 * not quite desirable. 83 */ 84struct in_multihead in_multihead; /* XXX BSS initialization */ 85struct mtx in_multi_mtx; 86MTX_SYSINIT(in_multi_mtx, &in_multi_mtx, "in_multi_mtx", MTX_DEF | MTX_RECURSE); 87 | |
88extern struct inpcbinfo ripcbinfo; 89extern struct inpcbinfo udbinfo; 90 91/* 92 * Return 1 if an internet address is for a ``local'' host 93 * (one to which we have a connection). If subnetsarelocal 94 * is true, this includes other subnets of the local net. 95 * Otherwise, it includes only the directly-connected (sub)nets. --- 876 unchanged lines hidden (view full) --- 972 */ 973 ia->ia_subnetmask != (u_long)0xffffffff) 974 return 1; 975 return (0); 976#undef ia 977} 978 979/* | 74extern struct inpcbinfo ripcbinfo; 75extern struct inpcbinfo udbinfo; 76 77/* 78 * Return 1 if an internet address is for a ``local'' host 79 * (one to which we have a connection). If subnetsarelocal 80 * is true, this includes other subnets of the local net. 81 * Otherwise, it includes only the directly-connected (sub)nets. --- 876 unchanged lines hidden (view full) --- 958 */ 959 ia->ia_subnetmask != (u_long)0xffffffff) 960 return 1; 961 return (0); 962#undef ia 963} 964 965/* |
980 * Add an address to the list of IP multicast addresses for a given interface. 981 */ 982struct in_multi * 983in_addmulti(struct in_addr *ap, struct ifnet *ifp) 984{ 985 struct in_multi *inm; 986 987 inm = NULL; 988 989 IFF_LOCKGIANT(ifp); 990 IN_MULTI_LOCK(); 991 992 IN_LOOKUP_MULTI(*ap, ifp, inm); 993 if (inm != NULL) { 994 /* 995 * If we already joined this group, just bump the 996 * refcount and return it. 997 */ 998 KASSERT(inm->inm_refcount >= 1, 999 ("%s: bad refcount %d", __func__, inm->inm_refcount)); 1000 ++inm->inm_refcount; 1001 } else do { 1002 struct sockaddr_in sin; 1003 struct ifmultiaddr *ifma; 1004 struct in_multi *ninm; 1005 int error; 1006 1007 bzero(&sin, sizeof sin); 1008 sin.sin_family = AF_INET; 1009 sin.sin_len = sizeof(struct sockaddr_in); 1010 sin.sin_addr = *ap; 1011 1012 /* 1013 * Check if a link-layer group is already associated 1014 * with this network-layer group on the given ifnet. 1015 * If so, bump the refcount on the existing network-layer 1016 * group association and return it. 1017 */ 1018 error = if_addmulti(ifp, (struct sockaddr *)&sin, &ifma); 1019 if (error) 1020 break; 1021 if (ifma->ifma_protospec != NULL) { 1022 inm = (struct in_multi *)ifma->ifma_protospec; 1023#ifdef INVARIANTS 1024 if (inm->inm_ifma != ifma || inm->inm_ifp != ifp || 1025 inm->inm_addr.s_addr != ap->s_addr) 1026 panic("%s: ifma is inconsistent", __func__); 1027#endif 1028 ++inm->inm_refcount; 1029 break; 1030 } 1031 1032 /* 1033 * A new membership is needed; construct it and 1034 * perform the IGMP join. 1035 */ 1036 ninm = malloc(sizeof(*ninm), M_IPMADDR, M_NOWAIT | M_ZERO); 1037 if (ninm == NULL) { 1038 if_delmulti_ifma(ifma); 1039 break; 1040 } 1041 ninm->inm_addr = *ap; 1042 ninm->inm_ifp = ifp; 1043 ninm->inm_ifma = ifma; 1044 ninm->inm_refcount = 1; 1045 ifma->ifma_protospec = ninm; 1046 LIST_INSERT_HEAD(&in_multihead, ninm, inm_link); 1047 1048 igmp_joingroup(ninm); 1049 1050 inm = ninm; 1051 } while (0); 1052 1053 IN_MULTI_UNLOCK(); 1054 IFF_UNLOCKGIANT(ifp); 1055 1056 return (inm); 1057} 1058 1059/* 1060 * Delete a multicast address record. 1061 * It is OK to call this routine if the underlying ifnet went away. 1062 * 1063 * XXX: To deal with the ifp going away, we cheat; the link-layer code in net 1064 * will set ifma_ifp to NULL when the associated ifnet instance is detached 1065 * from the system. 1066 * The only reason we need to violate layers and check ifma_ifp here at all 1067 * is because certain hardware drivers still require Giant to be held, 1068 * and it must always be taken before other locks. 1069 */ 1070void 1071in_delmulti(struct in_multi *inm) 1072{ 1073 struct ifnet *ifp; 1074 1075 KASSERT(inm->inm_ifma != NULL, ("%s: no ifma", __func__)); 1076 ifp = inm->inm_ifma->ifma_ifp; 1077 1078 if (ifp != NULL) { 1079 /* 1080 * Sanity check that netinet's notion of ifp is the 1081 * same as net's. 1082 */ 1083 KASSERT(inm->inm_ifp == ifp, ("%s: bad ifp", __func__)); 1084 IFF_LOCKGIANT(ifp); 1085 } 1086 1087 IN_MULTI_LOCK(); 1088 in_delmulti_locked(inm); 1089 IN_MULTI_UNLOCK(); 1090 1091 if (ifp != NULL) 1092 IFF_UNLOCKGIANT(ifp); 1093} 1094 1095/* 1096 * Delete a multicast address record, with locks held. 1097 * 1098 * It is OK to call this routine if the ifp went away. 1099 * Assumes that caller holds the IN_MULTI lock, and that 1100 * Giant was taken before other locks if required by the hardware. 1101 */ 1102void 1103in_delmulti_locked(struct in_multi *inm) 1104{ 1105 struct ifmultiaddr *ifma; 1106 1107 IN_MULTI_LOCK_ASSERT(); 1108 KASSERT(inm->inm_refcount >= 1, ("%s: freeing freed inm", __func__)); 1109 1110 if (--inm->inm_refcount == 0) { 1111 igmp_leavegroup(inm); 1112 1113 ifma = inm->inm_ifma; 1114#ifdef DIAGNOSTIC 1115 printf("%s: purging ifma %p\n", __func__, ifma); 1116#endif 1117 KASSERT(ifma->ifma_protospec == inm, 1118 ("%s: ifma_protospec != inm", __func__)); 1119 ifma->ifma_protospec = NULL; 1120 1121 LIST_REMOVE(inm, inm_link); 1122 free(inm, M_IPMADDR); 1123 1124 if_delmulti_ifma(ifma); 1125 } 1126} 1127 1128/* | |
1129 * Delete all IPv4 multicast address records, and associated link-layer 1130 * multicast address records, associated with ifp. 1131 */ 1132static void 1133in_purgemaddrs(struct ifnet *ifp) 1134{ 1135 struct in_multi *inm; 1136 struct in_multi *oinm; --- 25 unchanged lines hidden --- | 966 * Delete all IPv4 multicast address records, and associated link-layer 967 * multicast address records, associated with ifp. 968 */ 969static void 970in_purgemaddrs(struct ifnet *ifp) 971{ 972 struct in_multi *inm; 973 struct in_multi *oinm; --- 25 unchanged lines hidden --- |