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