Deleted Added
full compact
1/*-
2 * Copyright (c) 2001-2007, Cisco Systems, Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * a) Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.

--- 17 unchanged lines hidden (view full) ---

26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28 * THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/* $KAME: sctp_pcb.c,v 1.38 2005/03/06 16:04:18 itojun Exp $ */
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 166675 2007-02-12 23:24:31Z rrs $");
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 167598 2007-03-15 11:27:14Z rrs $");
35
36#include <netinet/sctp_os.h>
37#include <sys/proc.h>
38#include <netinet/sctp_var.h>
39#include <netinet/sctp_sysctl.h>
40#include <netinet/sctp_pcb.h>
41#include <netinet/sctputil.h>
42#include <netinet/sctp.h>
43#include <netinet/sctp_header.h>
44#include <netinet/sctp_asconf.h>
45#include <netinet/sctp_output.h>
46#include <netinet/sctp_timer.h>
47#include <netinet/sctp_bsd_addr.h>
48
49
48#ifdef SCTP_DEBUG
49uint32_t sctp_debug_on = 0;
50
51#endif /* SCTP_DEBUG */
52
53
54extern int sctp_pcbtblsize;
55extern int sctp_hashtblsize;
56extern int sctp_chunkscale;
57
50struct sctp_epinfo sctppcbinfo;
51
52/* FIX: we don't handle multiple link local scopes */
53/* "scopeless" replacement IN6_ARE_ADDR_EQUAL */
54int
55SCTP6_ARE_ADDR_EQUAL(struct in6_addr *a, struct in6_addr *b)
56{
57 struct in6_addr tmp_a, tmp_b;
58
59 /* use a copy of a and b */
60 tmp_a = *a;
61 tmp_b = *b;
62 in6_clearscope(&tmp_a);
63 in6_clearscope(&tmp_b);
64 return (IN6_ARE_ADDR_EQUAL(&tmp_a, &tmp_b));
65}
66
75
67void
68sctp_fill_pcbinfo(struct sctp_pcbinfo *spcb)
69{
70 /*
71 * We really don't need to lock this, but I will just because it
72 * does not hurt.
73 */
74 SCTP_INP_INFO_RLOCK();

--- 4 unchanged lines hidden (view full) ---

79 spcb->chk_count = sctppcbinfo.ipi_count_chunk;
80 spcb->readq_count = sctppcbinfo.ipi_count_readq;
81 spcb->stream_oque = sctppcbinfo.ipi_count_strmoq;
82 spcb->free_chunks = sctppcbinfo.ipi_free_chunks;
83
84 SCTP_INP_INFO_RUNLOCK();
85}
86
87/*
88 * Addresses are added to VRF's (Virtual Router's). For BSD we
89 * have only the default VRF 0. We maintain a hash list of
90 * VRF's. Each VRF has its own list of sctp_ifn's. Each of
91 * these has a list of addresses. When we add a new address
92 * to a VRF we lookup the ifn/ifn_index, if the ifn does
93 * not exist we create it and add it to the list of IFN's
94 * within the VRF. Once we have the sctp_ifn, we add the
95 * address to the list. So we look something like:
96 *
97 * hash-vrf-table
98 * vrf-> ifn-> ifn -> ifn
99 * vrf |
100 * ... +--ifa-> ifa -> ifa
101 * vrf
102 *
103 * We keep these seperate lists since the SCTP subsystem will
104 * point to these from its source address selection nets structure.
105 * When an address is deleted it does not happen right away on
106 * the SCTP side, it gets scheduled. What we do when a
107 * delete happens is immediately remove the address from
108 * the master list and decrement the refcount. As our
109 * addip iterator works through and frees the src address
110 * selection pointing to the sctp_ifa, eventually the refcount
111 * will reach 0 and we will delete it. Note that it is assumed
112 * that any locking on system level ifn/ifa is done at the
113 * caller of these functions and these routines will only
114 * lock the SCTP structures as they add or delete things.
115 *
116 * Other notes on VRF concepts.
117 * - An endpoint can be in multiple VRF's
118 * - An association lives within a VRF and only one VRF.
119 * - Any incoming packet we can deduce the VRF for by
120 * looking at the mbuf/pak inbound (for BSD its VRF=0 :D)
121 * - Any downward send call or connect call must supply the
122 * VRF via ancillary data or via some sort of set default
123 * VRF socket option call (again for BSD no brainer since
124 * the VRF is always 0).
125 * - An endpoint may add multiple VRF's to it.
126 * - Listening sockets can accept associations in any
127 * of the VRF's they are in but the assoc will end up
128 * in only one VRF (gotten from the packet or connect/send).
129 *
130 */
131
132struct sctp_vrf *
133sctp_allocate_vrf(int vrfid)
134{
135 struct sctp_vrf *vrf = NULL;
136 struct sctp_vrflist *bucket;
137
138 /* First allocate the VRF structure */
139 vrf = sctp_find_vrf(vrfid);
140 if (vrf) {
141 /* Already allocated */
142 return (vrf);
143 }
144 SCTP_MALLOC(vrf, struct sctp_vrf *, sizeof(struct sctp_vrf),
145 "SCTP_VRF");
146 if (vrf == NULL) {
147 /* No memory */
148#ifdef INVARIANTS
149 panic("No memory for VRF:%d", vrfid);
150#endif
151 return (NULL);
152 }
153 /* setup the VRF */
154 memset(vrf, 0, sizeof(struct sctp_vrf));
155 vrf->vrf_id = vrfid;
156 LIST_INIT(&vrf->ifnlist);
157 vrf->total_ifa_count = 0;
158 /* Add it to the hash table */
159 bucket = &sctppcbinfo.sctp_vrfhash[(vrfid & sctppcbinfo.hashvrfmark)];
160 LIST_INSERT_HEAD(bucket, vrf, next_vrf);
161 return (vrf);
162}
163
164
165struct sctp_ifn *
166sctp_find_ifn(struct sctp_vrf *vrf, void *ifn, uint32_t ifn_index)
167{
168 struct sctp_ifn *sctp_ifnp;
169
170 /*
171 * We assume the lock is held for the addresses if thats wrong
172 * problems could occur :-)
173 */
174 LIST_FOREACH(sctp_ifnp, &vrf->ifnlist, next_ifn) {
175 if (sctp_ifnp->ifn_index == ifn_index) {
176 return (sctp_ifnp);
177 }
178 if (sctp_ifnp->ifn_p && ifn && (sctp_ifnp->ifn_p == ifn)) {
179 return (sctp_ifnp);
180 }
181 }
182 return (NULL);
183}
184
185struct sctp_vrf *
186sctp_find_vrf(uint32_t vrfid)
187{
188 struct sctp_vrflist *bucket;
189 struct sctp_vrf *liste;
190
191 bucket = &sctppcbinfo.sctp_vrfhash[(vrfid & sctppcbinfo.hashvrfmark)];
192 LIST_FOREACH(liste, bucket, next_vrf) {
193 if (vrfid == liste->vrf_id) {
194 return (liste);
195 }
196 }
197 return (NULL);
198}
199
200void
201sctp_free_ifa(struct sctp_ifa *sctp_ifap)
202{
203 int ret;
204
205 ret = atomic_fetchadd_int(&sctp_ifap->refcount, -1);
206 if (ret == 1) {
207 /* We zero'd the count */
208 SCTP_FREE(sctp_ifap);
209 }
210}
211
212struct sctp_ifa *
213sctp_add_addr_to_vrf(uint32_t vrfid, void *ifn, uint32_t ifn_index,
214 uint32_t ifn_type, const char *if_name,
215 void *ifa, struct sockaddr *addr, uint32_t ifa_flags)
216{
217 struct sctp_vrf *vrf;
218 struct sctp_ifn *sctp_ifnp = NULL;
219 struct sctp_ifa *sctp_ifap = NULL;
220
221 /* How granular do we need the locks to be here? */
222 SCTP_IPI_ADDR_LOCK();
223 vrf = sctp_find_vrf(vrfid);
224 if (vrf == NULL) {
225 vrf = sctp_allocate_vrf(vrfid);
226 if (vrf == NULL) {
227 SCTP_IPI_ADDR_UNLOCK();
228 return (NULL);
229 }
230 }
231 sctp_ifnp = sctp_find_ifn(vrf, ifn, ifn_index);
232 if (sctp_ifnp == NULL) {
233 /*
234 * build one and add it, can't hold lock until after malloc
235 * done though.
236 */
237 SCTP_IPI_ADDR_UNLOCK();
238 SCTP_MALLOC(sctp_ifnp, struct sctp_ifn *, sizeof(struct sctp_ifn), "SCTP_IFN");
239 if (sctp_ifnp == NULL) {
240#ifdef INVARIANTS
241 panic("No memory for IFN:%u", sctp_ifnp->ifn_index);
242#endif
243 return (NULL);
244 }
245 sctp_ifnp->ifn_index = ifn_index;
246 sctp_ifnp->ifn_p = ifn;
247 sctp_ifnp->ifn_type = ifn_type;
248 sctp_ifnp->ifa_count = 0;
249 sctp_ifnp->refcount = 0;
250 sctp_ifnp->vrf = vrf;
251 memcpy(sctp_ifnp->ifn_name, if_name, SCTP_IFNAMSIZ);
252 LIST_INIT(&sctp_ifnp->ifalist);
253 SCTP_IPI_ADDR_LOCK();
254 LIST_INSERT_HEAD(&vrf->ifnlist, sctp_ifnp, next_ifn);
255 }
256 sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, 1);
257 if (sctp_ifap) {
258 /* Hmm, it already exists? */
259 if ((sctp_ifap->ifn_p) &&
260 (sctp_ifap->ifn_p->ifn_index == ifn_index)) {
261 if (sctp_ifap->localifa_flags & SCTP_BEING_DELETED) {
262 /* easy to solve, just switch back to active */
263 sctp_ifap->localifa_flags = SCTP_ADDR_VALID;
264 sctp_ifap->ifn_p = sctp_ifnp;
265 exit_stage_left:
266 SCTP_IPI_ADDR_UNLOCK();
267 return (sctp_ifap);
268 } else {
269 goto exit_stage_left;
270 }
271 } else {
272 if (sctp_ifap->ifn_p) {
273 /*
274 * The first IFN gets the address,
275 * duplicates are ignored.
276 */
277 goto exit_stage_left;
278 } else {
279 /* repair ifnp which was NULL ? */
280 sctp_ifap->localifa_flags = SCTP_ADDR_VALID;
281 sctp_ifap->ifn_p = sctp_ifnp;
282 atomic_add_int(&sctp_ifnp->refcount, 1);
283 }
284 goto exit_stage_left;
285 }
286 }
287 SCTP_IPI_ADDR_UNLOCK();
288 SCTP_MALLOC(sctp_ifap, struct sctp_ifa *, sizeof(struct sctp_ifa), "SCTP_IFA");
289 if (sctp_ifap == NULL) {
290#ifdef INVARIANTS
291 panic("No memory for IFA");
292#endif
293 return (NULL);
294 }
295 memset(sctp_ifap, 0, sizeof(sctp_ifap));
296 sctp_ifap->ifn_p = sctp_ifnp;
297 atomic_add_int(&sctp_ifnp->refcount, 1);
298
299 sctp_ifap->ifa = ifa;
300 memcpy(&sctp_ifap->address, addr, addr->sa_len);
301 sctp_ifap->localifa_flags = SCTP_ADDR_VALID | SCTP_ADDR_DEFER_USE;
302 sctp_ifap->flags = ifa_flags;
303 /* Set scope */
304 if (sctp_ifap->address.sa.sa_family == AF_INET) {
305 struct sockaddr_in *sin;
306
307 sin = (struct sockaddr_in *)&sctp_ifap->address.sin;
308 if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) ||
309 (IN4_ISLOOPBACK_ADDRESS(&sin->sin_addr))) {
310 sctp_ifap->src_is_loop = 1;
311 }
312 if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
313 sctp_ifap->src_is_priv = 1;
314 }
315 } else if (sctp_ifap->address.sa.sa_family == AF_INET6) {
316 /* ok to use deprecated addresses? */
317 struct sockaddr_in6 *sin6;
318
319 sin6 = (struct sockaddr_in6 *)&sctp_ifap->address.sin6;
320 if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) ||
321 (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))) {
322 sctp_ifap->src_is_loop = 1;
323 }
324 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
325 sctp_ifap->src_is_priv = 1;
326 }
327 }
328 if ((sctp_ifap->src_is_priv == 0) &&
329 (sctp_ifap->src_is_loop == 0)) {
330 sctp_ifap->src_is_glob = 1;
331 }
332 SCTP_IPI_ADDR_LOCK();
333 sctp_ifap->refcount = 1;
334 LIST_INSERT_HEAD(&sctp_ifnp->ifalist, sctp_ifap, next_ifa);
335 sctp_ifnp->ifa_count++;
336 vrf->total_ifa_count++;
337 SCTP_IPI_ADDR_UNLOCK();
338 return (sctp_ifap);
339}
340
341struct sctp_ifa *
342sctp_del_addr_from_vrf(uint32_t vrfid, struct sockaddr *addr,
343 uint32_t ifn_index)
344{
345 struct sctp_vrf *vrf;
346 struct sctp_ifa *sctp_ifap = NULL;
347 struct sctp_ifn *sctp_ifnp = NULL;
348
349 SCTP_IPI_ADDR_LOCK();
350
351 vrf = sctp_find_vrf(vrfid);
352 if (vrf == NULL) {
353 printf("Can't find vrfid:%d\n", vrfid);
354 goto out_now;
355 }
356 sctp_ifnp = sctp_find_ifn(vrf, (void *)NULL, ifn_index);
357 if (sctp_ifnp == NULL) {
358 sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, 1);
359 } else {
360 sctp_ifap = sctp_find_ifa_in_ifn(sctp_ifnp, addr, 1);
361 }
362
363 if (sctp_ifap) {
364 sctp_ifap->localifa_flags &= SCTP_ADDR_VALID;
365 sctp_ifap->localifa_flags |= SCTP_BEING_DELETED;
366 sctp_ifnp->ifa_count--;
367 vrf->total_ifa_count--;
368 LIST_REMOVE(sctp_ifap, next_ifa);
369 atomic_add_int(&sctp_ifnp->refcount, -1);
370 } else {
371 printf("Del Addr-ifn:%d Could not find address:",
372 ifn_index);
373 sctp_print_address(addr);
374 }
375out_now:
376 SCTP_IPI_ADDR_UNLOCK();
377 return (sctp_ifap);
378}
379
380/*
381 * Notes on locks for FreeBSD 5 and up. All association lookups that have a
382 * definte ep, the INP structure is assumed to be locked for reading. If we
383 * need to go find the INP (ususally when a **inp is passed) then we must
384 * lock the INFO structure first and if needed lock the INP too. Note that if
385 * we lock it we must
386 *
387 */

--- 67 unchanged lines hidden (view full) ---

455 if (laddr->ifa == NULL) {
456#ifdef SCTP_DEBUG
457 if (sctp_debug_on & SCTP_DEBUG_PCB1) {
458 printf("An ounce of prevention is worth a pound of cure\n");
459 }
460#endif
461 continue;
462 }
180 if (laddr->ifa->ifa_addr == NULL) {
463 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) {
464#ifdef SCTP_DEBUG
465 if (sctp_debug_on & SCTP_DEBUG_PCB1) {
183 printf("ifa with a NULL address\n");
466 printf("ifa being deleted\n");
467 }
468#endif
469 continue;
470 }
188 if (laddr->ifa->ifa_addr->sa_family ==
471 if (laddr->ifa->address.sa.sa_family ==
472 to->sa_family) {
473 /* see if it matches */
474 struct sockaddr_in *intf_addr, *sin;
475
193 intf_addr = (struct sockaddr_in *)
194 laddr->ifa->ifa_addr;
476 intf_addr = &laddr->ifa->address.sin;
477 sin = (struct sockaddr_in *)to;
478 if (from->sa_family == AF_INET) {
479 if (sin->sin_addr.s_addr ==
480 intf_addr->sin_addr.s_addr) {
481 match = 1;
482 break;
483 }
484 } else {
485 struct sockaddr_in6 *intf_addr6;
486 struct sockaddr_in6 *sin6;
487
488 sin6 = (struct sockaddr_in6 *)
489 to;
208 intf_addr6 = (struct sockaddr_in6 *)
209 laddr->ifa->ifa_addr;
490 intf_addr6 = &laddr->ifa->address.sin6;
491
492 if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
493 &intf_addr6->sin6_addr)) {
494 match = 1;
495 break;
496 }
497 }
498 }

--- 372 unchanged lines hidden (view full) ---

871 }
872 SCTP_INP_INFO_RUNLOCK();
873 return (NULL);
874}
875
876
877static struct sctp_inpcb *
878sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
598 uint16_t lport)
879 uint16_t lport, uint32_t vrf_id)
880{
881 struct sctp_inpcb *inp;
882 struct sockaddr_in *sin;
883 struct sockaddr_in6 *sin6;
884 struct sctp_laddr *laddr;
885 int fnd;
886
887 /*
888 * Endpoing probe expects that the INP_INFO is locked.
889 */
890 if (nam->sa_family == AF_INET) {
891 sin = (struct sockaddr_in *)nam;
892 sin6 = NULL;
893 } else if (nam->sa_family == AF_INET6) {

--- 22 unchanged lines hidden (view full) ---

916 continue;
917 }
918 /* A V6 address and the endpoint is NOT bound V6 */
919 if (nam->sa_family == AF_INET6 &&
920 (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
921 SCTP_INP_RUNLOCK(inp);
922 continue;
923 }
924 /* does a VRF id match? */
925 fnd = 0;
926 if (inp->def_vrf_id == vrf_id)
927 fnd = 1;
928
929 SCTP_INP_RUNLOCK(inp);
930 if (!fnd)
931 continue;
932 return (inp);
933 }
934 SCTP_INP_RUNLOCK(inp);
935 }
936
937 if ((nam->sa_family == AF_INET) &&
938 (sin->sin_addr.s_addr == INADDR_ANY)) {
939 /* Can't hunt for one that has no address specified */

--- 20 unchanged lines hidden (view full) ---

960 /*
961 * Ok this could be a likely candidate, look at all of its
962 * addresses
963 */
964 if (inp->sctp_lport != lport) {
965 SCTP_INP_RUNLOCK(inp);
966 continue;
967 }
968 /* does a VRF id match? */
969 fnd = 0;
970 if (inp->def_vrf_id == vrf_id)
971 fnd = 1;
972
973 if (!fnd) {
974 SCTP_INP_RUNLOCK(inp);
975 continue;
976 }
977 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
978 if (laddr->ifa == NULL) {
979#ifdef SCTP_DEBUG
980 if (sctp_debug_on & SCTP_DEBUG_PCB1) {
981 printf("An ounce of prevention is worth a pound of cure\n");
982 }
983#endif
984 continue;
985 }
986#ifdef SCTP_DEBUG
987 if (sctp_debug_on & SCTP_DEBUG_PCB1) {
988 printf("Ok laddr->ifa:%p is possible, ",
989 laddr->ifa);
990 }
991#endif
694 if (laddr->ifa->ifa_addr == NULL) {
992 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) {
993#ifdef SCTP_DEBUG
994 if (sctp_debug_on & SCTP_DEBUG_PCB1) {
697 printf("Huh IFA as an ifa_addr=NULL, ");
995 printf("Huh IFA being deleted\n");
996 }
997#endif
998 continue;
999 }
702 if (laddr->ifa->ifa_addr->sa_family == nam->sa_family) {
1000 if (laddr->ifa->address.sa.sa_family == nam->sa_family) {
1001 /* possible, see if it matches */
1002 struct sockaddr_in *intf_addr;
1003
706 intf_addr = (struct sockaddr_in *)
707 laddr->ifa->ifa_addr;
1004 intf_addr = &laddr->ifa->address.sin;
1005 if (nam->sa_family == AF_INET) {
1006 if (sin->sin_addr.s_addr ==
1007 intf_addr->sin_addr.s_addr) {
1008 SCTP_INP_RUNLOCK(inp);
1009 return (inp);
1010 }
1011 } else if (nam->sa_family == AF_INET6) {
1012 struct sockaddr_in6 *intf_addr6;
1013
717 intf_addr6 = (struct sockaddr_in6 *)
718 laddr->ifa->ifa_addr;
1014 intf_addr6 = &laddr->ifa->address.sin6;
1015 if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
1016 &intf_addr6->sin6_addr)) {
1017 SCTP_INP_RUNLOCK(inp);
1018 return (inp);
1019 }
1020 }
1021 }
1022 }
1023 SCTP_INP_RUNLOCK(inp);
1024 }
1025 return (NULL);
1026}
1027
1028
1029struct sctp_inpcb *
734sctp_pcb_findep(struct sockaddr *nam, int find_tcp_pool, int have_lock)
1030sctp_pcb_findep(struct sockaddr *nam, int find_tcp_pool, int have_lock, uint32_t vrf_id)
1031{
1032 /*
1033 * First we check the hash table to see if someone has this port
1034 * bound with just the port.
1035 */
1036 struct sctp_inpcb *inp;
1037 struct sctppcbhead *head;
1038 struct sockaddr_in *sin;

--- 17 unchanged lines hidden (view full) ---

1056 */
1057 /* Find the head of the ALLADDR chain */
1058 if (have_lock == 0) {
1059 SCTP_INP_INFO_RLOCK();
1060
1061 }
1062 head = &sctppcbinfo.sctp_ephash[SCTP_PCBHASH_ALLADDR(lport,
1063 sctppcbinfo.hashmark)];
768 inp = sctp_endpoint_probe(nam, head, lport);
1064 inp = sctp_endpoint_probe(nam, head, lport, vrf_id);
1065
1066 /*
1067 * If the TCP model exists it could be that the main listening
1068 * endpoint is gone but there exists a connected socket for this guy
1069 * yet. If so we can return the first one that we find. This may NOT
1070 * be the correct one but the sctp_findassociation_ep_addr has
1071 * further code to look at all TCP models.
1072 */

--- 4 unchanged lines hidden (view full) ---

1077 /*
1078 * This is real gross, but we do NOT have a remote
1079 * port at this point depending on who is calling.
1080 * We must therefore look for ANY one that matches
1081 * our local port :/
1082 */
1083 head = &sctppcbinfo.sctp_tcpephash[i];
1084 if (LIST_FIRST(head)) {
789 inp = sctp_endpoint_probe(nam, head, lport);
1085 inp = sctp_endpoint_probe(nam, head, lport, vrf_id);
1086 if (inp) {
1087 /* Found one */
1088 break;
1089 }
1090 }
1091 }
1092 }
1093 if (inp) {

--- 7 unchanged lines hidden (view full) ---

1101
1102/*
1103 * Find an association for an endpoint with the pointer to whom you want to
1104 * send to and the endpoint pointer. The address can be IPv4 or IPv6. We may
1105 * need to change the *to to some other struct like a mbuf...
1106 */
1107struct sctp_tcb *
1108sctp_findassociation_addr_sa(struct sockaddr *to, struct sockaddr *from,
813 struct sctp_inpcb **inp_p, struct sctp_nets **netp, int find_tcp_pool)
1109 struct sctp_inpcb **inp_p, struct sctp_nets **netp, int find_tcp_pool, uint32_t vrf_id)
1110{
1111 struct sctp_inpcb *inp;
1112 struct sctp_tcb *retval;
1113
1114 SCTP_INP_INFO_RLOCK();
1115 if (find_tcp_pool) {
1116 if (inp_p != NULL) {
1117 retval = sctp_tcb_special_locate(inp_p, from, to, netp);
1118 } else {
1119 retval = sctp_tcb_special_locate(&inp, from, to, netp);
1120 }
1121 if (retval != NULL) {
1122 SCTP_INP_INFO_RUNLOCK();
1123 return (retval);
1124 }
1125 }
830 inp = sctp_pcb_findep(to, 0, 1);
1126 inp = sctp_pcb_findep(to, 0, 1, vrf_id);
1127 if (inp_p != NULL) {
1128 *inp_p = inp;
1129 }
1130 SCTP_INP_INFO_RUNLOCK();
1131
1132 if (inp == NULL) {
1133 return (NULL);
1134 }

--- 183 unchanged lines hidden (view full) ---

1318{
1319 int find_tcp_pool;
1320 struct ip *iph;
1321 struct sctp_tcb *retval;
1322 struct sockaddr_storage to_store, from_store;
1323 struct sockaddr *to = (struct sockaddr *)&to_store;
1324 struct sockaddr *from = (struct sockaddr *)&from_store;
1325 struct sctp_inpcb *inp;
1326 uint32_t vrf_id;
1327
1031
1328 vrf_id = SCTP_DEFAULT_VRFID;
1329 iph = mtod(m, struct ip *);
1330 if (iph->ip_v == IPVERSION) {
1331 /* its IPv4 */
1332 struct sockaddr_in *from4;
1333
1334 from4 = (struct sockaddr_in *)&from_store;
1335 bzero(from4, sizeof(*from4));
1336 from4->sin_family = AF_INET;

--- 66 unchanged lines hidden (view full) ---

1403 (ch->chunk_type != SCTP_INITIATION_ACK) &&
1404 (ch->chunk_type != SCTP_COOKIE_ACK) &&
1405 (ch->chunk_type != SCTP_COOKIE_ECHO)) {
1406 /* Other chunk types go to the tcp pool. */
1407 find_tcp_pool = 1;
1408 }
1409 if (inp_p) {
1410 retval = sctp_findassociation_addr_sa(to, from, inp_p, netp,
1114 find_tcp_pool);
1411 find_tcp_pool, vrf_id);
1412 inp = *inp_p;
1413 } else {
1414 retval = sctp_findassociation_addr_sa(to, from, &inp, netp,
1118 find_tcp_pool);
1415 find_tcp_pool, vrf_id);
1416 }
1417#ifdef SCTP_DEBUG
1418 if (sctp_debug_on & SCTP_DEBUG_PCB1) {
1419 printf("retval:%p inp:%p\n", retval, inp);
1420 }
1421#endif
1422 if (retval == NULL && inp) {
1423 /* Found a EP but not this address */

--- 150 unchanged lines hidden (view full) ---

1574 stcb = sctp_findassociation_ep_addr(inp_p,
1575 (struct sockaddr *)&remote_store, netp,
1576 (struct sockaddr *)&local_store, NULL);
1577 }
1578 return (stcb);
1579}
1580
1581
1285extern int sctp_max_burst_default;
1286
1287extern unsigned int sctp_delayed_sack_time_default;
1288extern unsigned int sctp_heartbeat_interval_default;
1289extern unsigned int sctp_pmtu_raise_time_default;
1290extern unsigned int sctp_shutdown_guard_time_default;
1291extern unsigned int sctp_secret_lifetime_default;
1292
1293extern unsigned int sctp_rto_max_default;
1294extern unsigned int sctp_rto_min_default;
1295extern unsigned int sctp_rto_initial_default;
1296extern unsigned int sctp_init_rto_max_default;
1297extern unsigned int sctp_valid_cookie_life_default;
1298extern unsigned int sctp_init_rtx_max_default;
1299extern unsigned int sctp_assoc_rtx_max_default;
1300extern unsigned int sctp_path_rtx_max_default;
1301extern unsigned int sctp_nr_outgoing_streams_default;
1302
1582/*
1583 * allocate a sctp_inpcb and setup a temporary binding to a port/all
1584 * addresses. This way if we don't get a bind we by default pick a ephemeral
1585 * port with all addresses bound.
1586 */
1587int
1588sctp_inpcb_alloc(struct socket *so)
1589{

--- 48 unchanged lines hidden (view full) ---

1638 }
1639#endif /* IPSEC */
1640 SCTP_INCR_EP_COUNT();
1641 inp->ip_inp.inp.inp_ip_ttl = ip_defttl;
1642 SCTP_INP_INFO_WUNLOCK();
1643
1644 so->so_pcb = (caddr_t)inp;
1645
1367 if ((so->so_type == SOCK_DGRAM) ||
1368 (so->so_type == SOCK_SEQPACKET)) {
1646 if ((SCTP_SO_TYPE(so) == SOCK_DGRAM) ||
1647 (SCTP_SO_TYPE(so) == SOCK_SEQPACKET)) {
1648 /* UDP style socket */
1649 inp->sctp_flags = (SCTP_PCB_FLAGS_UDPTYPE |
1650 SCTP_PCB_FLAGS_UNBOUND);
1651 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT);
1652 /* Be sure it is NON-BLOCKING IO for UDP */
1374 /* so->so_state |= SS_NBIO; */
1375 } else if (so->so_type == SOCK_STREAM) {
1653 /* SCTP_SET_SO_NBIO(so); */
1654 } else if (SCTP_SO_TYPE(so) == SOCK_STREAM) {
1655 /* TCP style socket */
1656 inp->sctp_flags = (SCTP_PCB_FLAGS_TCPTYPE |
1657 SCTP_PCB_FLAGS_UNBOUND);
1658 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT);
1659 /* Be sure we have blocking IO by default */
1381 so->so_state &= ~SS_NBIO;
1660 SCTP_CLEAR_SO_NBIO(so);
1661 } else {
1662 /*
1663 * unsupported socket type (RAW, etc)- in case we missed it
1664 * in protosw
1665 */
1666 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_ep, inp);
1667 return (EOPNOTSUPP);
1668 }
1669 inp->sctp_tcbhash = SCTP_HASH_INIT(sctp_pcbtblsize,
1670 &inp->sctp_hashmark);
1671 if (inp->sctp_tcbhash == NULL) {
1672 printf("Out of SCTP-INPCB->hashinit - no resources\n");
1673 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_ep, inp);
1674 return (ENOBUFS);
1675 }
1676 inp->def_vrf_id = SCTP_DEFAULT_VRFID;
1677
1678 SCTP_INP_INFO_WLOCK();
1679 SCTP_INP_LOCK_INIT(inp);
1680 SCTP_INP_READ_INIT(inp);
1681 SCTP_ASOC_CREATE_LOCK_INIT(inp);
1682 /* lock the new ep */
1683 SCTP_INP_WLOCK(inp);
1684
1685 /* add it to the info area */
1686 LIST_INSERT_HEAD(&sctppcbinfo.listhead, inp, sctp_list);
1687 SCTP_INP_INFO_WUNLOCK();
1688
1689 TAILQ_INIT(&inp->read_queue);
1690 LIST_INIT(&inp->sctp_addr_list);
1691
1692 LIST_INIT(&inp->sctp_asoc_list);
1693
1694#ifdef SCTP_TRACK_FREED_ASOCS
1695 /* TEMP CODE */
1696 LIST_INIT(&inp->sctp_asoc_free_list);
1697#endif
1698 /* Init the timer structure for signature change */
1699 SCTP_OS_TIMER_INIT(&inp->sctp_ep.signature_change.timer);

--- 10 unchanged lines hidden (view full) ---

1710 m->sctp_timeoutticks[SCTP_TIMER_PMTU] = SEC_TO_TICKS(sctp_pmtu_raise_time_default);
1711 m->sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN] = SEC_TO_TICKS(sctp_shutdown_guard_time_default);
1712 m->sctp_timeoutticks[SCTP_TIMER_SIGNATURE] = SEC_TO_TICKS(sctp_secret_lifetime_default);
1713 /* all max/min max are in ms */
1714 m->sctp_maxrto = sctp_rto_max_default;
1715 m->sctp_minrto = sctp_rto_min_default;
1716 m->initial_rto = sctp_rto_initial_default;
1717 m->initial_init_rto_max = sctp_init_rto_max_default;
1718 m->sctp_sack_freq = sctp_sack_freq_default;
1719
1720 m->max_open_streams_intome = MAX_SCTP_STREAMS;
1721
1722 m->max_init_times = sctp_init_rtx_max_default;
1723 m->max_send_times = sctp_assoc_rtx_max_default;
1724 m->def_net_failure = sctp_path_rtx_max_default;
1725 m->sctp_sws_sender = SCTP_SWS_SENDER_DEF;
1726 m->sctp_sws_receiver = SCTP_SWS_RECEIVER_DEF;

--- 21 unchanged lines hidden (view full) ---

1748
1749 for (i = 0; i < SCTP_NUMBER_OF_SECRETS; i++) {
1750 m->secret_key[0][i] = sctp_select_initial_TSN(m);
1751 }
1752 sctp_timer_start(SCTP_TIMER_TYPE_NEWCOOKIE, inp, NULL, NULL);
1753
1754 /* How long is a cookie good for ? */
1755 m->def_cookie_life = sctp_valid_cookie_life_default;
1473
1756 /*
1757 * Initialize authentication parameters
1758 */
1759 m->local_hmacs = sctp_default_supported_hmaclist();
1760 m->local_auth_chunks = sctp_alloc_chunklist();
1761 sctp_auth_set_default_chunks(m->local_auth_chunks);
1762 LIST_INIT(&m->shared_keys);
1763 /* add default NULL key as key id 0 */

--- 114 unchanged lines hidden (view full) ---

1878 net->rxt_timer.ep = (void *)new_inp;
1879 net->fr_timer.ep = (void *)new_inp;
1880 }
1881 SCTP_INP_WUNLOCK(new_inp);
1882 SCTP_INP_WUNLOCK(old_inp);
1883}
1884
1885static int
1604sctp_isport_inuse(struct sctp_inpcb *inp, uint16_t lport)
1886sctp_isport_inuse(struct sctp_inpcb *inp, uint16_t lport, uint32_t vrf_id)
1887{
1888 struct sctppcbhead *head;
1889 struct sctp_inpcb *t_inp;
1890 int fnd;
1891
1892 head = &sctppcbinfo.sctp_ephash[SCTP_PCBHASH_ALLADDR(lport,
1893 sctppcbinfo.hashmark)];
1894
1895 LIST_FOREACH(t_inp, head, sctp_hash) {
1896 if (t_inp->sctp_lport != lport) {
1897 continue;
1898 }
1899 /* is it in the VRF in question */
1900 fnd = 0;
1901 if (t_inp->def_vrf_id == vrf_id)
1902 fnd = 1;
1903 if (!fnd)
1904 continue;
1905
1906 /* This one is in use. */
1907 /* check the v6/v4 binding issue */
1908 if ((t_inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
1909 SCTP_IPV6_V6ONLY(t_inp)) {
1910 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
1911 /* collision in V6 space */
1912 return (1);
1913 } else {

--- 24 unchanged lines hidden (view full) ---

1938{
1939 /* bind a ep to a socket address */
1940 struct sctppcbhead *head;
1941 struct sctp_inpcb *inp, *inp_tmp;
1942 struct inpcb *ip_inp;
1943 int bindall;
1944 uint16_t lport;
1945 int error;
1946 uint32_t vrf_id;
1947
1948 lport = 0;
1949 error = 0;
1950 bindall = 1;
1951 inp = (struct sctp_inpcb *)so->so_pcb;
1952 ip_inp = (struct inpcb *)so->so_pcb;
1953#ifdef SCTP_DEBUG
1954 if (sctp_debug_on & SCTP_DEBUG_PCB1) {

--- 43 unchanged lines hidden (view full) ---

1998 return (EINVAL);
1999 }
2000 /* this must be cleared for ifa_ifwithaddr() */
2001 sin6->sin6_scope_id = 0;
2002 } else {
2003 return (EAFNOSUPPORT);
2004 }
2005 }
2006 /*
2007 * Setup a vrf_id to be the default for the non-bind-all case.
2008 */
2009 vrf_id = inp->def_vrf_id;
2010
2011 SCTP_INP_INFO_WLOCK();
2012 SCTP_INP_WLOCK(inp);
2013 /* increase our count due to the unlock we do */
2014 SCTP_INP_INCR_REF(inp);
2015 if (lport) {
2016 /*
2017 * Did the caller specify a port? if so we must see if a ep
2018 * already has this one bound.
2019 */
2020 /* got to be root to get at low ports */
2021 if (ntohs(lport) < IPPORT_RESERVED) {
2022 if (p && (error =
1727 priv_check(p,
1728 PRIV_NETINET_RESERVEDPORT)
2023 priv_check_cred(p->td_ucred,
2024 PRIV_NETINET_RESERVEDPORT,
2025 SUSER_ALLOWJAIL
2026 )
2027 )) {
2028 SCTP_INP_DECR_REF(inp);
2029 SCTP_INP_WUNLOCK(inp);
2030 SCTP_INP_INFO_WUNLOCK();
2031 return (error);
2032 }
2033 }
2034 if (p == NULL) {
2035 SCTP_INP_DECR_REF(inp);
2036 SCTP_INP_WUNLOCK(inp);
2037 SCTP_INP_INFO_WUNLOCK();
2038 return (error);
2039 }
2040 SCTP_INP_WUNLOCK(inp);
1743 inp_tmp = sctp_pcb_findep(addr, 0, 1);
1744 if (inp_tmp != NULL) {
1745 /*
1746 * lock guy returned and lower count note that we
1747 * are not bound so inp_tmp should NEVER be inp. And
1748 * it is this inp (inp_tmp) that gets the reference
1749 * bump, so we must lower it.
1750 */
1751 SCTP_INP_DECR_REF(inp_tmp);
1752 SCTP_INP_DECR_REF(inp);
1753 /* unlock info */
1754 SCTP_INP_INFO_WUNLOCK();
1755 return (EADDRNOTAVAIL);
2041 if (bindall) {
2042 vrf_id = inp->def_vrf_id;
2043 inp_tmp = sctp_pcb_findep(addr, 0, 1, vrf_id);
2044 if (inp_tmp != NULL) {
2045 /*
2046 * lock guy returned and lower count note
2047 * that we are not bound so inp_tmp should
2048 * NEVER be inp. And it is this inp
2049 * (inp_tmp) that gets the reference bump,
2050 * so we must lower it.
2051 */
2052 SCTP_INP_DECR_REF(inp_tmp);
2053 SCTP_INP_DECR_REF(inp);
2054 /* unlock info */
2055 SCTP_INP_INFO_WUNLOCK();
2056 return (EADDRNOTAVAIL);
2057 }
2058 } else {
2059 inp_tmp = sctp_pcb_findep(addr, 0, 1, vrf_id);
2060 if (inp_tmp != NULL) {
2061 /*
2062 * lock guy returned and lower count note
2063 * that we are not bound so inp_tmp should
2064 * NEVER be inp. And it is this inp
2065 * (inp_tmp) that gets the reference bump,
2066 * so we must lower it.
2067 */
2068 SCTP_INP_DECR_REF(inp_tmp);
2069 SCTP_INP_DECR_REF(inp);
2070 /* unlock info */
2071 SCTP_INP_INFO_WUNLOCK();
2072 return (EADDRNOTAVAIL);
2073 }
2074 }
2075 SCTP_INP_WLOCK(inp);
2076 if (bindall) {
2077 /* verify that no lport is not used by a singleton */
1760 if (sctp_isport_inuse(inp, lport)) {
2078 if (sctp_isport_inuse(inp, lport, vrf_id)) {
2079 /* Sorry someone already has this one bound */
2080 SCTP_INP_DECR_REF(inp);
2081 SCTP_INP_WUNLOCK(inp);
2082 SCTP_INP_INFO_WUNLOCK();
2083 return (EADDRNOTAVAIL);
2084 }
2085 }
2086 } else {

--- 4 unchanged lines hidden (view full) ---

2091
2092 /*
2093 * setup the inp to the top (I could use the union but this
2094 * is just as easy
2095 */
2096 uint32_t port_guess;
2097 uint16_t port_attempt;
2098 int not_done = 1;
2099 int not_found = 1;
2100
2101 while (not_done) {
2102 port_guess = sctp_select_initial_TSN(&inp->sctp_ep);
2103 port_attempt = (port_guess & 0x0000ffff);
2104 if (port_attempt == 0) {
2105 goto next_half;
2106 }
2107 if (port_attempt < IPPORT_RESERVED) {
2108 port_attempt += IPPORT_RESERVED;
2109 }
1791 if (sctp_isport_inuse(inp, htons(port_attempt)) == 0) {
2110 vrf_id = inp->def_vrf_id;
2111 if (sctp_isport_inuse(inp, htons(port_attempt), vrf_id) == 1) {
2112 /* got a port we can use */
2113 not_found = 0;
2114 break;
2115 }
2116 if (not_found == 1) {
2117 /* We can use this port */
2118 not_done = 0;
2119 continue;
2120 }
2121 /* try upper half */
2122 next_half:
2123 port_attempt = ((port_guess >> 16) & 0x0000ffff);
2124 if (port_attempt == 0) {
2125 goto last_try;
2126 }
2127 if (port_attempt < IPPORT_RESERVED) {
2128 port_attempt += IPPORT_RESERVED;
2129 }
1805 if (sctp_isport_inuse(inp, htons(port_attempt)) == 0) {
2130 vrf_id = inp->def_vrf_id;
2131 if (sctp_isport_inuse(inp, htons(port_attempt), vrf_id) == 1) {
2132 /* got a port we can use */
2133 not_found = 0;
2134 break;
2135 }
2136 if (not_found == 1) {
2137 /* We can use this port */
2138 not_done = 0;
2139 continue;
2140 }
2141 /* try two half's added together */
2142 last_try:
2143 port_attempt = (((port_guess >> 16) & 0x0000ffff) +
2144 (port_guess & 0x0000ffff));
2145 if (port_attempt == 0) {
2146 /* get a new random number */
2147 continue;
2148 }
2149 if (port_attempt < IPPORT_RESERVED) {
2150 port_attempt += IPPORT_RESERVED;
2151 }
1821 if (sctp_isport_inuse(inp, htons(port_attempt)) == 0) {
2152 vrf_id = inp->def_vrf_id;
2153 if (sctp_isport_inuse(inp, htons(port_attempt), vrf_id) == 1) {
2154 /* got a port we can use */
2155 not_found = 0;
2156 break;
2157 }
2158 if (not_found == 1) {
2159 /* We can use this port */
2160 not_done = 0;
2161 continue;
2162 }
2163 }
2164 /* we don't get out of the loop until we have a port */
2165 lport = htons(port_attempt);
2166 }
2167 SCTP_INP_DECR_REF(inp);

--- 24 unchanged lines hidden (view full) ---

2192 * address structure to the sctp_addr_list inside the ep
2193 * structure.
2194 *
2195 * We will need to allocate one and insert it at the head. The
2196 * socketopt call can just insert new addresses in there as
2197 * well. It will also have to do the embed scope kame hack
2198 * too (before adding).
2199 */
1863 struct ifaddr *ifa;
2200 struct sctp_ifa *ifa;
2201 struct sockaddr_storage store_sa;
2202
2203 memset(&store_sa, 0, sizeof(store_sa));
2204 if (addr->sa_family == AF_INET) {
2205 struct sockaddr_in *sin;
2206
2207 sin = (struct sockaddr_in *)&store_sa;
2208 memcpy(sin, addr, sizeof(struct sockaddr_in));

--- 5 unchanged lines hidden (view full) ---

2214 memcpy(sin6, addr, sizeof(struct sockaddr_in6));
2215 sin6->sin6_port = 0;
2216 }
2217 /*
2218 * first find the interface with the bound address need to
2219 * zero out the port to find the address! yuck! can't do
2220 * this earlier since need port for sctp_pcb_findep()
2221 */
1885 ifa = sctp_find_ifa_by_addr((struct sockaddr *)&store_sa);
2222 ifa = sctp_find_ifa_by_addr((struct sockaddr *)&store_sa, vrf_id, 0);
2223 if (ifa == NULL) {
2224 /* Can't find an interface with that address */
2225 SCTP_INP_WUNLOCK(inp);
2226 SCTP_INP_INFO_WUNLOCK();
2227 return (EADDRNOTAVAIL);
2228 }
2229 if (addr->sa_family == AF_INET6) {
1893 struct in6_ifaddr *ifa6;
1894
1895 ifa6 = (struct in6_ifaddr *)ifa;
1896 /*
1897 * allow binding of deprecated addresses as per RFC
1898 * 2462 and ipng discussion
1899 */
1900 if (ifa6->ia6_flags & (IN6_IFF_DETACHED |
1901 IN6_IFF_ANYCAST |
1902 IN6_IFF_NOTREADY)) {
2230 /* GAK, more FIXME IFA lock? */
2231 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
2232 /* Can't bind a non-existent addr. */
2233 SCTP_INP_WUNLOCK(inp);
2234 SCTP_INP_INFO_WUNLOCK();
2235 return (EINVAL);
2236 }
2237 }
2238 /* we're not bound all */
2239 inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUNDALL;
2240 /* set the automatic addr changes from kernel flag */
2241 sctp_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF);
2242 if (sctp_auto_asconf == 0) {
2243 sctp_feature_off(inp, SCTP_PCB_FLAGS_AUTO_ASCONF);
2244 } else {
2245 /*
2246 * allow bindx() to send ASCONF's for binding
2247 * changes
2248 */
2249 sctp_feature_on(inp, SCTP_PCB_FLAGS_AUTO_ASCONF);
2250 }
1917 /* allow bindx() to send ASCONF's for binding changes */
1918 sctp_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF);
2251
2252 /* add this address to the endpoint list */
1920 error = sctp_insert_laddr(&inp->sctp_addr_list, ifa);
2253 error = sctp_insert_laddr(&inp->sctp_addr_list, ifa, 0);
2254 if (error != 0) {
2255 SCTP_INP_WUNLOCK(inp);
2256 SCTP_INP_INFO_WUNLOCK();
2257 return (error);
2258 }
2259 inp->laddr_count++;
2260 }
2261 /* find the bucket */

--- 30 unchanged lines hidden (view full) ---

2292 /*
2293 * Go through all iterators, we must do this since it is possible
2294 * that some iterator does NOT have the lock, but is waiting for it.
2295 * And the one that had the lock has either moved in the last
2296 * iteration or we just cleared it above. We need to find all of
2297 * those guys. The list of iterators should never be very big
2298 * though.
2299 */
1967 LIST_FOREACH(it, &sctppcbinfo.iteratorhead, sctp_nxt_itr) {
2300 TAILQ_FOREACH(it, &sctppcbinfo.iteratorhead, sctp_nxt_itr) {
2301 if (it == inp->inp_starting_point_for_iterator)
2302 /* skip this guy, he's special */
2303 continue;
2304 if (it->inp == inp) {
2305 /*
2306 * This is tricky and we DON'T lock the iterator.
2307 * Reason is he's running but waiting for me since
2308 * inp->inp_starting_point_for_iterator has the lock

--- 412 unchanged lines hidden (view full) ---

2721 /*
2722 * if we have an address list the following will free the list of
2723 * ifaddr's that are set into this ep. Again macro limitations here,
2724 * since the LIST_FOREACH could be a bad idea.
2725 */
2726 for ((laddr = LIST_FIRST(&inp->sctp_addr_list)); laddr != NULL;
2727 laddr = nladdr) {
2728 nladdr = LIST_NEXT(laddr, sctp_nxt_addr);
2396 LIST_REMOVE(laddr, sctp_nxt_addr);
2397 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_laddr, laddr);
2398 SCTP_DECR_LADDR_COUNT();
2729 sctp_remove_laddr(laddr);
2730 }
2731
2732#ifdef SCTP_TRACK_FREED_ASOCS
2733 /* TEMP CODE */
2734 for ((asoc = LIST_FIRST(&inp->sctp_asoc_free_list)); asoc != NULL;
2735 asoc = nasoc) {
2736 nasoc = LIST_NEXT(asoc, sctp_tcblist);
2737 LIST_REMOVE(asoc, sctp_tcblist);

--- 36 unchanged lines hidden (view full) ---

2774
2775
2776/*
2777 * add's a remote endpoint address, done with the INIT/INIT-ACK as well as
2778 * when a ASCONF arrives that adds it. It will also initialize all the cwnd
2779 * stats of stuff.
2780 */
2781int
2451sctp_is_address_on_local_host(struct sockaddr *addr)
2782sctp_is_address_on_local_host(struct sockaddr *addr, uint32_t vrf_id)
2783{
2453 struct ifnet *ifn;
2454 struct ifaddr *ifa;
2784 struct sctp_ifa *sctp_ifa;
2785
2456 TAILQ_FOREACH(ifn, &ifnet, if_list) {
2457 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
2458 if (addr->sa_family == ifa->ifa_addr->sa_family) {
2459 /* same family */
2460 if (addr->sa_family == AF_INET) {
2461 struct sockaddr_in *sin, *sin_c;
2786 sctp_ifa = sctp_find_ifa_by_addr(addr, vrf_id, 0);
2787 if (sctp_ifa) {
2788 return (1);
2789 } else {
2790 return (0);
2791 }
2792}
2793
2463 sin = (struct sockaddr_in *)addr;
2464 sin_c = (struct sockaddr_in *)
2465 ifa->ifa_addr;
2466 if (sin->sin_addr.s_addr ==
2467 sin_c->sin_addr.s_addr) {
2468 /*
2469 * we are on the same
2470 * machine
2471 */
2472 return (1);
2473 }
2474 } else if (addr->sa_family == AF_INET6) {
2475 struct sockaddr_in6 *sin6, *sin_c6;
2476
2477 sin6 = (struct sockaddr_in6 *)addr;
2478 sin_c6 = (struct sockaddr_in6 *)
2479 ifa->ifa_addr;
2480 if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
2481 &sin_c6->sin6_addr)) {
2482 /*
2483 * we are on the same
2484 * machine
2485 */
2486 return (1);
2487 }
2488 }
2489 }
2490 }
2794void
2795sctp_set_initial_cc_param(struct sctp_tcb *stcb, struct sctp_nets *net)
2796{
2797 net->cwnd = min((net->mtu * 4), max((2 * net->mtu), SCTP_INITIAL_CWND));
2798 /* we always get at LEAST 2 MTU's */
2799 if (net->cwnd < (2 * net->mtu)) {
2800 net->cwnd = 2 * net->mtu;
2801 }
2492 return (0);
2802 net->ssthresh = stcb->asoc.peers_rwnd;
2803}
2804
2805int
2806sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
2807 int set_scope, int from)
2808{
2809 /*
2810 * The following is redundant to the same lines in the

--- 48 unchanged lines hidden (view full) ---

2859 if (set_scope) {
2860#ifdef SCTP_DONT_DO_PRIVADDR_SCOPE
2861 stcb->ipv4_local_scope = 1;
2862#else
2863 if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
2864 stcb->asoc.ipv4_local_scope = 1;
2865 }
2866#endif /* SCTP_DONT_DO_PRIVADDR_SCOPE */
2557
2558 if (sctp_is_address_on_local_host(newaddr)) {
2559 stcb->asoc.loopback_scope = 1;
2560 stcb->asoc.ipv4_local_scope = 1;
2561 stcb->asoc.local_scope = 1;
2562 stcb->asoc.site_scope = 1;
2563 }
2867 } else {
2565 if (from == SCTP_ADDR_IS_CONFIRMED) {
2566 /* From connectx */
2567 if (sctp_is_address_on_local_host(newaddr)) {
2568 stcb->asoc.loopback_scope = 1;
2569 stcb->asoc.ipv4_local_scope = 1;
2570 stcb->asoc.local_scope = 1;
2571 stcb->asoc.site_scope = 1;
2572 }
2573 }
2868 /* Validate the address is in scope */
2869 if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) &&
2870 (stcb->asoc.ipv4_local_scope == 0)) {
2871 addr_inscope = 0;
2872 }
2873 }
2874 } else if (newaddr->sa_family == AF_INET6) {
2875 struct sockaddr_in6 *sin6;
2876
2877 sin6 = (struct sockaddr_in6 *)newaddr;
2878 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
2879 /* Invalid address */
2880 return (-1);
2881 }
2882 /* assure len is set */
2883 sin6->sin6_len = sizeof(struct sockaddr_in6);
2884 if (set_scope) {
2591 if (sctp_is_address_on_local_host(newaddr)) {
2885 if (sctp_is_address_on_local_host(newaddr, stcb->asoc.vrf_id)) {
2886 stcb->asoc.loopback_scope = 1;
2593 stcb->asoc.local_scope = 1;
2887 stcb->asoc.local_scope = 0;
2888 stcb->asoc.ipv4_local_scope = 1;
2889 stcb->asoc.site_scope = 1;
2890 } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
2891 /*
2892 * If the new destination is a LINK_LOCAL we
2893 * must have common site scope. Don't set
2894 * the local scope since we may not share
2895 * all links, only loopback can do this.

--- 5 unchanged lines hidden (view full) ---

2901 } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
2902 /*
2903 * If the new destination is SITE_LOCAL then
2904 * we must have site scope in common.
2905 */
2906 stcb->asoc.site_scope = 1;
2907 }
2908 } else {
2615 if (from == SCTP_ADDR_IS_CONFIRMED) {
2616 /* From connectx so we check for localhost. */
2617 if (sctp_is_address_on_local_host(newaddr)) {
2618 stcb->asoc.loopback_scope = 1;
2619 stcb->asoc.ipv4_local_scope = 1;
2620 stcb->asoc.local_scope = 1;
2621 stcb->asoc.site_scope = 1;
2622 }
2623 }
2909 /* Validate the address is in scope */
2910 if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) &&
2911 (stcb->asoc.loopback_scope == 0)) {
2912 addr_inscope = 0;
2913 } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) &&
2914 (stcb->asoc.local_scope == 0)) {
2915 addr_inscope = 0;
2916 } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) &&

--- 13 unchanged lines hidden (view full) ---

2930 bzero(net, sizeof(*net));
2931 SCTP_GETTIME_TIMEVAL(&net->start_time);
2932 memcpy(&net->ro._l_addr, newaddr, newaddr->sa_len);
2933 if (newaddr->sa_family == AF_INET) {
2934 ((struct sockaddr_in *)&net->ro._l_addr)->sin_port = stcb->rport;
2935 } else if (newaddr->sa_family == AF_INET6) {
2936 ((struct sockaddr_in6 *)&net->ro._l_addr)->sin6_port = stcb->rport;
2937 }
2653 net->addr_is_local = sctp_is_address_on_local_host(newaddr);
2938 net->addr_is_local = sctp_is_address_on_local_host(newaddr, stcb->asoc.vrf_id);
2939 if (net->addr_is_local && ((set_scope || (from == SCTP_ADDR_IS_CONFIRMED)))) {
2940 stcb->asoc.loopback_scope = 1;
2941 stcb->asoc.ipv4_local_scope = 1;
2942 stcb->asoc.local_scope = 0;
2943 stcb->asoc.site_scope = 1;
2944 addr_inscope = 1;
2945 }
2946 net->failure_threshold = stcb->asoc.def_net_failure;
2947 if (addr_inscope == 0) {
2948 net->dest_state = (SCTP_ADDR_REACHABLE |
2949 SCTP_ADDR_OUT_OF_SCOPE);
2950 } else {
2951 if (from == SCTP_ADDR_IS_CONFIRMED)
2952 /* SCTP_ADDR_IS_CONFIRMED is passed by connect_x */
2953 net->dest_state = SCTP_ADDR_REACHABLE;
2954 else
2955 net->dest_state = SCTP_ADDR_REACHABLE |
2956 SCTP_ADDR_UNCONFIRMED;
2957 }
2958 net->RTO = stcb->asoc.initial_rto;
2959 stcb->asoc.numnets++;
2960 *(&net->ref_count) = 1;
2961 net->tos_flowlabel = 0;
2670#ifdef AF_INET
2962#ifdef INET
2963 if (newaddr->sa_family == AF_INET)
2964 net->tos_flowlabel = stcb->asoc.default_tos;
2965#endif
2674#ifdef AF_INET6
2966#ifdef INET6
2967 if (newaddr->sa_family == AF_INET6)
2968 net->tos_flowlabel = stcb->asoc.default_flowlabel;
2969#endif
2970 /* Init the timer structure */
2971 SCTP_OS_TIMER_INIT(&net->rxt_timer.timer);
2972 SCTP_OS_TIMER_INIT(&net->fr_timer.timer);
2973 SCTP_OS_TIMER_INIT(&net->pmtu_timer.timer);
2974

--- 27 unchanged lines hidden (view full) ---

3002
3003 if (stcb->asoc.smallest_mtu > net->mtu) {
3004 stcb->asoc.smallest_mtu = net->mtu;
3005 }
3006 /*
3007 * We take the max of the burst limit times a MTU or the
3008 * INITIAL_CWND. We then limit this to 4 MTU's of sending.
3009 */
2718 net->cwnd = min((net->mtu * 4), max((2 * net->mtu), SCTP_INITIAL_CWND));
3010 sctp_set_initial_cc_param(stcb, net);
3011
2720 /* we always get at LEAST 2 MTU's */
2721 if (net->cwnd < (2 * net->mtu)) {
2722 net->cwnd = 2 * net->mtu;
2723 }
2724 net->ssthresh = stcb->asoc.peers_rwnd;
3012
3013#if defined(SCTP_CWND_MONITOR) || defined(SCTP_CWND_LOGGING)
3014 sctp_log_cwnd(stcb, net, 0, SCTP_CWND_INITIALIZATION);
3015#endif
3016
3017 /*
3018 * CMT: CUC algo - set find_pseudo_cumack to TRUE (1) at beginning
3019 * of assoc (2005/06/27, iyengar@cis.udel.edu)

--- 82 unchanged lines hidden (view full) ---

3102
3103/*
3104 * allocate an association and add it to the endpoint. The caller must be
3105 * careful to add all additional addresses once they are know right away or
3106 * else the assoc will be may experience a blackout scenario.
3107 */
3108struct sctp_tcb *
3109sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
2823 int for_a_init, int *error, uint32_t override_tag)
3110 int for_a_init, int *error, uint32_t override_tag, uint32_t vrf)
3111{
3112 struct sctp_tcb *stcb;
3113 struct sctp_association *asoc;
3114 struct sctpasochead *head;
3115 uint16_t rport;
3116 int err;
3117
3118 /*

--- 83 unchanged lines hidden (view full) ---

3202
3203 bzero(stcb, sizeof(*stcb));
3204 asoc = &stcb->asoc;
3205 SCTP_TCB_LOCK_INIT(stcb);
3206 SCTP_TCB_SEND_LOCK_INIT(stcb);
3207 /* setup back pointer's */
3208 stcb->sctp_ep = inp;
3209 stcb->sctp_socket = inp->sctp_socket;
2923 if ((err = sctp_init_asoc(inp, asoc, for_a_init, override_tag))) {
3210 if ((err = sctp_init_asoc(inp, asoc, for_a_init, override_tag, vrf))) {
3211 /* failed */
3212 SCTP_TCB_LOCK_DESTROY(stcb);
3213 SCTP_TCB_SEND_LOCK_DESTROY(stcb);
3214 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_asoc, stcb);
3215 SCTP_DECR_ASOC_COUNT();
3216 *error = err;
3217 return (NULL);
3218 }

--- 64 unchanged lines hidden (view full) ---

3283void
3284sctp_remove_net(struct sctp_tcb *stcb, struct sctp_nets *net)
3285{
3286 struct sctp_association *asoc;
3287
3288 asoc = &stcb->asoc;
3289 asoc->numnets--;
3290 TAILQ_REMOVE(&asoc->nets, net, sctp_next);
3004 sctp_free_remote_addr(net);
3291 if (net == asoc->primary_destination) {
3292 /* Reset primary */
3293 struct sctp_nets *lnet;
3294
3295 lnet = TAILQ_FIRST(&asoc->nets);
3296 /* Try to find a confirmed primary */
3011 asoc->primary_destination = sctp_find_alternate_net(stcb, lnet,
3012 0);
3297 asoc->primary_destination = sctp_find_alternate_net(stcb, lnet, 0);
3298 }
3299 if (net == asoc->last_data_chunk_from) {
3300 /* Reset primary */
3301 asoc->last_data_chunk_from = TAILQ_FIRST(&asoc->nets);
3302 }
3303 if (net == asoc->last_control_chunk_from) {
3304 /* Clear net */
3305 asoc->last_control_chunk_from = NULL;
3306 }
3022/* if (net == asoc->asconf_last_sent_to) {*/
3023 /* Reset primary */
3024/* asoc->asconf_last_sent_to = TAILQ_FIRST(&asoc->nets);*/
3025/* }*/
3307 sctp_free_remote_addr(net);
3308}
3309
3310/*
3311 * remove a remote endpoint address from an association, it will fail if the
3312 * address does not exist.
3313 */
3314int
3315sctp_del_remote_addr(struct sctp_tcb *stcb, struct sockaddr *remaddr)

--- 592 unchanged lines hidden (view full) ---

3908#endif
3909 break;
3910 }
3911 prev = net;
3912 TAILQ_REMOVE(&asoc->nets, net, sctp_next);
3913 sctp_free_remote_addr(net);
3914 }
3915
3634 /* local addresses, if any */
3635 while (!SCTP_LIST_EMPTY(&asoc->sctp_local_addr_list)) {
3636 laddr = LIST_FIRST(&asoc->sctp_local_addr_list);
3637 LIST_REMOVE(laddr, sctp_nxt_addr);
3638 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_laddr, laddr);
3639 SCTP_DECR_LADDR_COUNT();
3916 while (!SCTP_LIST_EMPTY(&asoc->sctp_restricted_addrs)) {
3917 laddr = LIST_FIRST(&asoc->sctp_restricted_addrs);
3918 sctp_remove_laddr(laddr);
3919 }
3920
3921 /* pending asconf (address) parameters */
3922 while (!TAILQ_EMPTY(&asoc->asconf_queue)) {
3923 aparam = TAILQ_FIRST(&asoc->asconf_queue);
3924 TAILQ_REMOVE(&asoc->asconf_queue, aparam, next);
3925 SCTP_FREE(aparam);
3926 }
3927 if (asoc->last_asconf_ack_sent != NULL) {
3928 sctp_m_freem(asoc->last_asconf_ack_sent);

--- 137 unchanged lines hidden (view full) ---

4066 if (laddr->ifa == NULL) {
4067#ifdef SCTP_DEBUG
4068 if (sctp_debug_on & SCTP_DEBUG_PCB1) {
4069 printf("An ounce of prevention is worth a pound of cure\n");
4070 }
4071#endif /* SCTP_DEBUG */
4072 continue;
4073 }
3794 if (laddr->ifa->ifa_addr) {
4074 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) {
4075 continue;
4076 }
3797 if (laddr->ifa->ifa_addr->sa_family == AF_INET6) {
4077 if (laddr->ifa->address.sa.sa_family == AF_INET6) {
4078 inp->ip_inp.inp.inp_vflag |= INP_IPV6;
3799 } else if (laddr->ifa->ifa_addr->sa_family == AF_INET) {
4079 } else if (laddr->ifa->address.sa.sa_family == AF_INET) {
4080 inp->ip_inp.inp.inp_vflag |= INP_IPV4;
4081 }
4082 }
4083}
4084
4085/*
4086 * Add the address to the endpoint local address list There is nothing to be
4087 * done if we are bound to all addresses
4088 */
4089int
3810sctp_add_local_addr_ep(struct sctp_inpcb *inp, struct ifaddr *ifa)
4090sctp_add_local_addr_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa, uint32_t action)
4091{
4092 struct sctp_laddr *laddr;
4093 int fnd, error;
4094
4095 fnd = 0;
4096
4097 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
4098 /* You are already bound to all. You have it already */
4099 return (0);
4100 }
3821 if (ifa->ifa_addr->sa_family == AF_INET6) {
3822 struct in6_ifaddr *ifa6;
3823
3824 ifa6 = (struct in6_ifaddr *)ifa;
3825 if (ifa6->ia6_flags & (IN6_IFF_DETACHED |
3826 IN6_IFF_DEPRECATED | IN6_IFF_ANYCAST | IN6_IFF_NOTREADY))
3827 /* Can't bind a non-existent addr. */
4101 if (ifa->address.sa.sa_family == AF_INET6) {
4102 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
4103 /* Can't bind a non-useable addr. */
4104 return (-1);
4105 }
4106 }
4107 /* first, is it already present? */
4108 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
4109 if (laddr->ifa == ifa) {
4110 fnd = 1;
4111 break;
4112 }
4113 }
4114
3838 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) && (fnd == 0)) {
3839 /* Not bound to all */
3840 error = sctp_insert_laddr(&inp->sctp_addr_list, ifa);
4115 if (fnd == 0) {
4116 /* Not in the ep list */
4117 error = sctp_insert_laddr(&inp->sctp_addr_list, ifa, action);
4118 if (error != 0)
4119 return (error);
4120 inp->laddr_count++;
4121 /* update inp_vflag flags */
3845 if (ifa->ifa_addr->sa_family == AF_INET6) {
4122 if (ifa->address.sa.sa_family == AF_INET6) {
4123 inp->ip_inp.inp.inp_vflag |= INP_IPV6;
3847 } else if (ifa->ifa_addr->sa_family == AF_INET) {
4124 } else if (ifa->address.sa.sa_family == AF_INET) {
4125 inp->ip_inp.inp.inp_vflag |= INP_IPV4;
4126 }
4127 }
4128 return (0);
4129}
4130
4131
4132/*

--- 20 unchanged lines hidden (view full) ---

4153}
4154
4155
4156/*
4157 * Delete the address from the endpoint local address list There is nothing
4158 * to be done if we are bound to all addresses
4159 */
4160int
3884sctp_del_local_addr_ep(struct sctp_inpcb *inp, struct ifaddr *ifa)
4161sctp_del_local_addr_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa)
4162{
4163 struct sctp_laddr *laddr;
4164 int fnd;
4165
4166 fnd = 0;
4167 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
4168 /* You are already bound to all. You have it already */
4169 return (EINVAL);
4170 }
4171 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
4172 if (laddr->ifa == ifa) {
4173 fnd = 1;
4174 break;
4175 }
4176 }
4177 if (fnd && (inp->laddr_count < 2)) {
4178 /* can't delete unless there are at LEAST 2 addresses */
4179 return (-1);
4180 }
3904 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) && (fnd)) {
4181 if (fnd) {
4182 /*
4183 * clean up any use of this address go through our
4184 * associations and clear any last_used_address that match
4185 * this one for each assoc, see if a new primary_destination
4186 * is needed
4187 */
4188 struct sctp_tcb *stcb;
4189
4190 /* clean up "next_addr_touse" */
4191 if (inp->next_addr_touse == laddr)
4192 /* delete this address */
4193 inp->next_addr_touse = NULL;
4194
4195 /* clean up "last_used_address" */
4196 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
4197 struct sctp_nets *net;
4198
4199 SCTP_TCB_LOCK(stcb);
4200 if (stcb->asoc.last_used_address == laddr)
4201 /* delete this address */
4202 stcb->asoc.last_used_address = NULL;
3923 } /* for each tcb */
4203 /*
4204 * Now spin through all the nets and purge any ref
4205 * to laddr
4206 */
4207 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
4208 if (net->ro._s_addr &&
4209 (net->ro._s_addr->ifa == laddr->ifa)) {
4210 /* Yep, purge src address selected */
4211 struct rtentry *rt;
4212
4213 /* delete this address if cached */
4214 rt = net->ro.ro_rt;
4215 if (rt != NULL) {
4216 RTFREE(rt);
4217 net->ro.ro_rt = NULL;
4218 }
4219 sctp_free_ifa(net->ro._s_addr);
4220 net->ro._s_addr = NULL;
4221 net->src_addr_selected = 0;
4222 }
4223 }
4224 SCTP_TCB_UNLOCK(stcb);
4225 } /* for each tcb */
4226 /* remove it from the ep list */
4227 sctp_remove_laddr(laddr);
4228 inp->laddr_count--;
4229 /* update inp_vflag flags */
4230 sctp_update_ep_vflag(inp);
3930 /* select a new primary destination if needed */
3931 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
3932 /*
3933 * presume caller (sctp_asconf.c) already owns INP
3934 * lock
3935 */
3936 SCTP_TCB_LOCK(stcb);
3937 if (sctp_destination_is_reachable(stcb,
3938 (struct sockaddr *)&stcb->asoc.primary_destination->ro._l_addr) == 0) {
3939 sctp_select_primary_destination(stcb);
3940 }
3941 SCTP_TCB_UNLOCK(stcb);
3942 } /* for each tcb */
4231 }
4232 return (0);
4233}
4234
4235/*
4236 * Add the addr to the TCB local address list For the BOUNDALL or dynamic
4237 * case, this is a "pending" address list (eg. addresses waiting for an
4238 * ASCONF-ACK response) For the subset binding, static case, this is a
4239 * "valid" address list
4240 */
4241int
3954sctp_add_local_addr_assoc(struct sctp_tcb *stcb, struct ifaddr *ifa)
4242sctp_add_local_addr_assoc(struct sctp_tcb *stcb, struct sctp_ifa *ifa, int restricted_list)
4243{
4244 struct sctp_inpcb *inp;
4245 struct sctp_laddr *laddr;
4246 struct sctpladdr *list;
4247 int error;
4248
4249 /*
3961 * Assumes TCP is locked.. and possiblye the INP. May need to
4250 * Assumes TCB is locked.. and possibly the INP. May need to
4251 * confirm/fix that if we need it and is not the case.
4252 */
3964 inp = stcb->sctp_ep;
3965 if (ifa->ifa_addr->sa_family == AF_INET6) {
3966 struct in6_ifaddr *ifa6;
4253 list = &stcb->asoc.sctp_restricted_addrs;
4254
3968 ifa6 = (struct in6_ifaddr *)ifa;
3969 if (ifa6->ia6_flags & (IN6_IFF_DETACHED |
3970 /* IN6_IFF_DEPRECATED | */
3971 IN6_IFF_ANYCAST |
3972 IN6_IFF_NOTREADY))
4255 inp = stcb->sctp_ep;
4256 if (ifa->address.sa.sa_family == AF_INET6) {
4257 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
4258 /* Can't bind a non-existent addr. */
4259 return (-1);
4260 }
4261 }
4262 /* does the address already exist? */
3977 LIST_FOREACH(laddr, &stcb->asoc.sctp_local_addr_list, sctp_nxt_addr) {
4263 LIST_FOREACH(laddr, list, sctp_nxt_addr) {
4264 if (laddr->ifa == ifa) {
4265 return (-1);
4266 }
4267 }
4268
4269 /* add to the list */
3984 error = sctp_insert_laddr(&stcb->asoc.sctp_local_addr_list, ifa);
4270 error = sctp_insert_laddr(list, ifa, 0);
4271 if (error != 0)
4272 return (error);
4273 return (0);
4274}
4275
4276/*
4277 * insert an laddr entry with the given ifa for the desired list
4278 */
4279int
3994sctp_insert_laddr(struct sctpladdr *list, struct ifaddr *ifa)
4280sctp_insert_laddr(struct sctpladdr *list, struct sctp_ifa *ifa, uint32_t act)
4281{
4282 struct sctp_laddr *laddr;
4283
4284 laddr = SCTP_ZONE_GET(sctppcbinfo.ipi_zone_laddr, struct sctp_laddr);
4285 if (laddr == NULL) {
4286 /* out of memory? */
4287 return (EINVAL);
4288 }
4289 SCTP_INCR_LADDR_COUNT();
4290 bzero(laddr, sizeof(*laddr));
4291 laddr->ifa = ifa;
4292 laddr->action = act;
4293 atomic_add_int(&ifa->refcount, 1);
4294 /* insert it */
4295 LIST_INSERT_HEAD(list, laddr, sctp_nxt_addr);
4296
4297 return (0);
4298}
4299
4300/*
4301 * Remove an laddr entry from the local address list (on an assoc)
4302 */
4303void
4304sctp_remove_laddr(struct sctp_laddr *laddr)
4305{
4306
4307 /* remove from the list */
4308 LIST_REMOVE(laddr, sctp_nxt_addr);
4309 sctp_free_ifa(laddr->ifa);
4310 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_laddr, laddr);
4311 SCTP_DECR_LADDR_COUNT();
4312}
4313
4314/*
4315 * Remove an address from the TCB local address list
4316 */
4317int
4029sctp_del_local_addr_assoc(struct sctp_tcb *stcb, struct ifaddr *ifa)
4318sctp_del_local_addr_assoc(struct sctp_tcb *stcb, struct sctp_ifa *ifa)
4319{
4320 struct sctp_inpcb *inp;
4321 struct sctp_laddr *laddr;
4322
4323 /*
4324 * This is called by asconf work. It is assumed that a) The TCB is
4325 * locked and b) The INP is locked. This is true in as much as I can
4326 * trace through the entry asconf code where I did these locks.

--- 7 unchanged lines hidden (view full) ---

4334 /* if subset bound and don't allow ASCONF's, can't delete last */
4335 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) &&
4336 (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_ASCONF) == 0)) {
4337 if (stcb->asoc.numnets < 2) {
4338 /* can't delete last address */
4339 return (-1);
4340 }
4341 }
4053 LIST_FOREACH(laddr, &stcb->asoc.sctp_local_addr_list, sctp_nxt_addr) {
4342 LIST_FOREACH(laddr, &stcb->asoc.sctp_restricted_addrs, sctp_nxt_addr) {
4343 /* remove the address if it exists */
4344 if (laddr->ifa == NULL)
4345 continue;
4346 if (laddr->ifa == ifa) {
4347 sctp_remove_laddr(laddr);
4348 return (0);
4349 }
4350 }
4351
4352 /* address not found! */
4353 return (-1);
4354}
4355
4067/*
4068 * Remove an address from the TCB local address list lookup using a sockaddr
4069 * addr
4070 */
4071int
4072sctp_del_local_addr_assoc_sa(struct sctp_tcb *stcb, struct sockaddr *sa)
4073{
4074 struct sctp_inpcb *inp;
4075 struct sctp_laddr *laddr;
4076 struct sockaddr *l_sa;
4077
4078 /*
4079 * This function I find does not seem to have a caller. As such we
4080 * NEED TO DELETE this code. If we do find a caller, the caller MUST
4081 * have locked the TCB at the least and probably the INP as well.
4082 */
4083 inp = stcb->sctp_ep;
4084 /* if subset bound and don't allow ASCONF's, can't delete last */
4085 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) &&
4086 (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_ASCONF) == 0)) {
4087 if (stcb->asoc.numnets < 2) {
4088 /* can't delete last address */
4089 return (-1);
4090 }
4091 }
4092 LIST_FOREACH(laddr, &stcb->asoc.sctp_local_addr_list, sctp_nxt_addr) {
4093 /* make sure the address exists */
4094 if (laddr->ifa == NULL)
4095 continue;
4096 if (laddr->ifa->ifa_addr == NULL)
4097 continue;
4098
4099 l_sa = laddr->ifa->ifa_addr;
4100 if (l_sa->sa_family == AF_INET6) {
4101 /* IPv6 address */
4102 struct sockaddr_in6 *sin1, *sin2;
4103
4104 sin1 = (struct sockaddr_in6 *)l_sa;
4105 sin2 = (struct sockaddr_in6 *)sa;
4106 if (memcmp(&sin1->sin6_addr, &sin2->sin6_addr,
4107 sizeof(struct in6_addr)) == 0) {
4108 /* matched */
4109 sctp_remove_laddr(laddr);
4110 return (0);
4111 }
4112 } else if (l_sa->sa_family == AF_INET) {
4113 /* IPv4 address */
4114 struct sockaddr_in *sin1, *sin2;
4115
4116 sin1 = (struct sockaddr_in *)l_sa;
4117 sin2 = (struct sockaddr_in *)sa;
4118 if (sin1->sin_addr.s_addr == sin2->sin_addr.s_addr) {
4119 /* matched */
4120 sctp_remove_laddr(laddr);
4121 return (0);
4122 }
4123 } else {
4124 /* invalid family */
4125 return (-1);
4126 }
4127 } /* end foreach */
4128 /* address not found! */
4129 return (-1);
4130}
4131
4356static char sctp_pcb_initialized = 0;
4357
4358/*
4359 * Temporarily remove for __APPLE__ until we use the Tiger equivalents
4360 */
4361/* sysctl */
4362static int sctp_max_number_of_assoc = SCTP_MAX_NUM_OF_ASOC;
4363static int sctp_scale_up_for_address = SCTP_SCALE_FOR_ADDR;

--- 14 unchanged lines hidden (view full) ---

4378 sctp_pcb_initialized = 1;
4379
4380 bzero(&sctpstat, sizeof(struct sctpstat));
4381 SCTP_GETTIME_TIMEVAL(&sctpstat.sctps_discontinuitytime);
4382 /* init the empty list of (All) Endpoints */
4383 LIST_INIT(&sctppcbinfo.listhead);
4384
4385 /* init the iterator head */
4162 LIST_INIT(&sctppcbinfo.iteratorhead);
4386 TAILQ_INIT(&sctppcbinfo.iteratorhead);
4387
4388 /* init the hash table of endpoints */
4389 TUNABLE_INT_FETCH("net.inet.sctp.tcbhashsize", &sctp_hashtblsize);
4390 TUNABLE_INT_FETCH("net.inet.sctp.pcbhashsize", &sctp_pcbtblsize);
4391 TUNABLE_INT_FETCH("net.inet.sctp.chunkscale", &sctp_chunkscale);
4392 sctppcbinfo.sctp_asochash = SCTP_HASH_INIT((sctp_hashtblsize * 31),
4393 &sctppcbinfo.hashasocmark);
4394 sctppcbinfo.sctp_ephash = SCTP_HASH_INIT(sctp_hashtblsize,
4395 &sctppcbinfo.hashmark);
4396 sctppcbinfo.sctp_tcpephash = SCTP_HASH_INIT(sctp_hashtblsize,
4397 &sctppcbinfo.hashtcpmark);
4398 sctppcbinfo.hashtblsize = sctp_hashtblsize;
4399
4400 /* init the small hash table we use to track restarted asoc's */
4401 sctppcbinfo.sctp_restarthash = SCTP_HASH_INIT(SCTP_STACK_VTAG_HASH_SIZE,
4402 &sctppcbinfo.hashrestartmark);
4403
4404
4405 sctppcbinfo.sctp_vrfhash = SCTP_HASH_INIT(SCTP_SIZE_OF_VRF_HASH,
4406 &sctppcbinfo.hashvrfmark);
4407
4408 /* init the zones */
4409 /*
4410 * FIX ME: Should check for NULL returns, but if it does fail we are
4411 * doomed to panic anyways... add later maybe.
4412 */
4413 SCTP_ZONE_INIT(sctppcbinfo.ipi_zone_ep, "sctp_ep",
4414 sizeof(struct sctp_inpcb), maxsockets);
4415

--- 22 unchanged lines hidden (view full) ---

4438
4439 /* Master Lock INIT for info structure */
4440 SCTP_INP_INFO_LOCK_INIT();
4441 SCTP_STATLOG_INIT_LOCK();
4442 SCTP_ITERATOR_LOCK_INIT();
4443
4444 SCTP_IPI_COUNT_INIT();
4445 SCTP_IPI_ADDR_INIT();
4446 SCTP_IPI_ITERATOR_WQ_INIT();
4447
4448 LIST_INIT(&sctppcbinfo.addr_wq);
4449
4450 /* not sure if we need all the counts */
4451 sctppcbinfo.ipi_count_ep = 0;
4452 /* assoc/tcb zone info */
4453 sctppcbinfo.ipi_count_asoc = 0;
4454 /* local addrlist zone info */
4455 sctppcbinfo.ipi_count_laddr = 0;

--- 13 unchanged lines hidden (view full) ---

4469
4470 SCTP_OS_TIMER_INIT(&sctppcbinfo.addr_wq_timer.timer);
4471
4472 /* Init the TIMEWAIT list */
4473 for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE; i++) {
4474 LIST_INIT(&sctppcbinfo.vtag_timewait[i]);
4475 }
4476
4477#if defined(SCTP_USE_THREAD_BASED_ITERATOR)
4478 sctppcbinfo.iterator_running = 0;
4479 sctp_startup_iterator();
4480#endif
4481
4482 /*
4483 * INIT the default VRF which for BSD is the only one, other O/S's
4484 * may have more. But initially they must start with one and then
4485 * add the VRF's as addresses are added.
4486 */
4487 sctp_init_vrf_list(SCTP_DEFAULT_VRF);
4488
4489}
4490
4491
4492int
4493sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
4494 int iphlen, int offset, int limit, struct sctphdr *sh,
4495 struct sockaddr *altsa)
4496{

--- 554 unchanged lines hidden (view full) ---

5051 net = sctp_findnet(stcb, sa);
5052
5053 if (net == NULL) {
5054 /* didn't find the requested primary address! */
5055 return (-1);
5056 } else {
5057 /* set the primary address */
5058 if (net->dest_state & SCTP_ADDR_UNCONFIRMED) {
4817 /* Must be confirmed */
4818 return (-1);
5059 /* Must be confirmed, so queue to set */
5060 net->dest_state |= SCTP_ADDR_REQ_PRIMARY;
5061 return (0);
5062 }
5063 stcb->asoc.primary_destination = net;
5064 net->dest_state &= ~SCTP_ADDR_WAS_PRIMARY;
5065 net = TAILQ_FIRST(&stcb->asoc.nets);
5066 if (net != stcb->asoc.primary_destination) {
5067 /*
5068 * first one on the list is NOT the primary
5069 * sctp_cmpaddr() is much more efficent if the

--- 90 unchanged lines hidden (view full) ---

5160 }
5161 }
5162 /* Not found, ok to use the tag */
5163 SCTP_INP_INFO_WUNLOCK();
5164 return (1);
5165}
5166
5167
4925/*
4926 * Delete the address from the endpoint local address list Lookup using a
4927 * sockaddr address (ie. not an ifaddr)
4928 */
4929int
4930sctp_del_local_addr_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa)
4931{
4932 struct sctp_laddr *laddr;
4933 struct sockaddr *l_sa;
4934 int found = 0;
4935
4936 /*
4937 * Here is another function I cannot find a caller for. As such we
4938 * SHOULD delete it if we have no users. If we find a user that user
4939 * MUST have the INP locked.
4940 *
4941 */
4942
4943 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
4944 /* You are already bound to all. You have it already */
4945 return (EINVAL);
4946 }
4947 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
4948 /* make sure the address exists */
4949 if (laddr->ifa == NULL)
4950 continue;
4951 if (laddr->ifa->ifa_addr == NULL)
4952 continue;
4953
4954 l_sa = laddr->ifa->ifa_addr;
4955 if (l_sa->sa_family == AF_INET6) {
4956 /* IPv6 address */
4957 struct sockaddr_in6 *sin1, *sin2;
4958
4959 sin1 = (struct sockaddr_in6 *)l_sa;
4960 sin2 = (struct sockaddr_in6 *)sa;
4961 if (memcmp(&sin1->sin6_addr, &sin2->sin6_addr,
4962 sizeof(struct in6_addr)) == 0) {
4963 /* matched */
4964 found = 1;
4965 break;
4966 }
4967 } else if (l_sa->sa_family == AF_INET) {
4968 /* IPv4 address */
4969 struct sockaddr_in *sin1, *sin2;
4970
4971 sin1 = (struct sockaddr_in *)l_sa;
4972 sin2 = (struct sockaddr_in *)sa;
4973 if (sin1->sin_addr.s_addr == sin2->sin_addr.s_addr) {
4974 /* matched */
4975 found = 1;
4976 break;
4977 }
4978 } else {
4979 /* invalid family */
4980 return (-1);
4981 }
4982 }
4983
4984 if (found && inp->laddr_count < 2) {
4985 /* can't delete unless there are at LEAST 2 addresses */
4986 return (-1);
4987 }
4988 if (found && (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
4989 /*
4990 * remove it from the ep list, this should NOT be done until
4991 * its really gone from the interface list and we won't be
4992 * receiving more of these. Probably right away. If we do
4993 * allow a removal of an address from an association
4994 * (sub-set bind) than this should NOT be called until the
4995 * all ASCONF come back from this association.
4996 */
4997 sctp_remove_laddr(laddr);
4998 return (0);
4999 } else {
5000 return (-1);
5001 }
5002}
5003
5168static sctp_assoc_t reneged_asoc_ids[256];
5169static uint8_t reneged_at = 0;
5170
5007extern int sctp_do_drain;
5171
5172static void
5173sctp_drain_mbufs(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
5174{
5175 /*
5176 * We must hunt this association for MBUF's past the cumack (i.e.
5177 * out of order data that we can renege on).
5178 */

--- 139 unchanged lines hidden (view full) ---

5318 /* Nothing left in map */
5319 memset(asoc->mapping_array, 0, asoc->mapping_array_size);
5320 asoc->mapping_array_base_tsn = asoc->cumulative_tsn + 1;
5321 asoc->highest_tsn_inside_map = asoc->cumulative_tsn;
5322 }
5323 asoc->last_revoke_count = cnt;
5324 SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
5325 sctp_send_sack(stcb);
5326 sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_DRAIN);
5327 reneged_asoc_ids[reneged_at] = sctp_get_associd(stcb);
5328 reneged_at++;
5329 }
5330 /*
5331 * Another issue, in un-setting the TSN's in the mapping array we
5332 * DID NOT adjust the higest_tsn marker. This will cause one of two
5333 * things to occur. It may cause us to do extra work in checking for
5334 * our mapping array movement. More importantly it may cause us to

--- 33 unchanged lines hidden (view full) ---

5368 * start a new iterator
5369 * iterates through all endpoints and associations based on the pcb_state
5370 * flags and asoc_state. "af" (mandatory) is executed for all matching
5371 * assocs and "ef" (optional) is executed when the iterator completes.
5372 * "inpf" (optional) is executed for each new endpoint as it is being
5373 * iterated through.
5374 */
5375int
5212sctp_initiate_iterator(inp_func inpf, asoc_func af, uint32_t pcb_state,
5213 uint32_t pcb_features, uint32_t asoc_state, void *argp, uint32_t argi,
5214 end_func ef, struct sctp_inpcb *s_inp, uint8_t chunk_output_off)
5376sctp_initiate_iterator(inp_func inpf,
5377 asoc_func af,
5378 inp_func inpe,
5379 uint32_t pcb_state,
5380 uint32_t pcb_features,
5381 uint32_t asoc_state,
5382 void *argp,
5383 uint32_t argi,
5384 end_func ef,
5385 struct sctp_inpcb *s_inp,
5386 uint8_t chunk_output_off)
5387{
5388 struct sctp_iterator *it = NULL;
5389
5390 if (af == NULL) {
5391 return (-1);
5392 }
5393 SCTP_MALLOC(it, struct sctp_iterator *, sizeof(struct sctp_iterator),
5394 "Iterator");
5395 if (it == NULL) {
5396 return (ENOMEM);
5397 }
5398 memset(it, 0, sizeof(*it));
5399 it->function_assoc = af;
5400 it->function_inp = inpf;
5401 if (inpf)
5402 it->done_current_ep = 0;
5403 else
5404 it->done_current_ep = 1;
5405 it->function_atend = ef;
5406 it->pointer = argp;
5407 it->val = argi;
5408 it->pcb_flags = pcb_state;
5409 it->pcb_features = pcb_features;
5410 it->asoc_state = asoc_state;
5411 it->function_inp_end = inpe;
5412 it->no_chunk_output = chunk_output_off;
5413 if (s_inp) {
5414 it->inp = s_inp;
5415 it->iterator_flags = SCTP_ITERATOR_DO_SINGLE_INP;
5416 } else {
5417 SCTP_INP_INFO_RLOCK();
5418 it->inp = LIST_FIRST(&sctppcbinfo.listhead);
5419
5420 SCTP_INP_INFO_RUNLOCK();
5421 it->iterator_flags = SCTP_ITERATOR_DO_ALL_INP;
5422
5423 }
5424 SCTP_IPI_ITERATOR_WQ_LOCK();
5425 if (it->inp)
5426 SCTP_INP_INCR_REF(it->inp);
5427 TAILQ_INSERT_TAIL(&sctppcbinfo.iteratorhead, it, sctp_nxt_itr);
5428#if defined(SCTP_USE_THREAD_BASED_ITERATOR)
5429 if (sctppcbinfo.iterator_running == 0) {
5430 sctp_wakeup_iterator();
5431 }
5432 SCTP_IPI_ITERATOR_WQ_UNLOCK();
5433#else
5434 if (it->inp)
5435 SCTP_INP_DECR_REF(it->inp);
5436 SCTP_IPI_ITERATOR_WQ_UNLOCK();
5437 /* Init the timer */
5438 SCTP_OS_TIMER_INIT(&it->tmr.timer);
5439 /* add to the list of all iterators */
5249 SCTP_INP_INFO_WLOCK();
5250 LIST_INSERT_HEAD(&sctppcbinfo.iteratorhead, it, sctp_nxt_itr);
5251 SCTP_INP_INFO_WUNLOCK();
5440 sctp_timer_start(SCTP_TIMER_TYPE_ITERATOR, (struct sctp_inpcb *)it,
5441 NULL, NULL);
5442#endif
5443 return (0);
5444}