Deleted Added
full compact
sctp_asconf.c (167598) sctp_asconf.c (168299)
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_asconf.c,v 1.24 2005/03/06 16:04:16 itojun Exp $ */
32
33#include <sys/cdefs.h>
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_asconf.c,v 1.24 2005/03/06 16:04:16 itojun Exp $ */
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.c 167598 2007-03-15 11:27:14Z rrs $");
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.c 168299 2007-04-03 11:15:32Z rrs $");
35#include <netinet/sctp_os.h>
36#include <netinet/sctp_var.h>
37#include <netinet/sctp_sysctl.h>
38#include <netinet/sctp_pcb.h>
39#include <netinet/sctp_header.h>
40#include <netinet/sctputil.h>
41#include <netinet/sctp_output.h>
35#include <netinet/sctp_os.h>
36#include <netinet/sctp_var.h>
37#include <netinet/sctp_sysctl.h>
38#include <netinet/sctp_pcb.h>
39#include <netinet/sctp_header.h>
40#include <netinet/sctputil.h>
41#include <netinet/sctp_output.h>
42#include <netinet/sctp_bsd_addr.h>
43#include <netinet/sctp_asconf.h>
44
45/*
46 * debug flags:
47 * SCTP_DEBUG_ASCONF1: protocol info, general info and errors
48 * SCTP_DEBUG_ASCONF2: detailed info
49 */
50#ifdef SCTP_DEBUG

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

1049 /* delete requested, add already queued */
1050 (type == SCTP_DEL_IP_ADDRESS &&
1051 aa->ap.aph.ph.param_type == SCTP_ADD_IP_ADDRESS))) {
1052 /* delete the existing entry in the queue */
1053 TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
1054 /* take the entry off the appropriate list */
1055 sctp_asconf_addr_mgmt_ack(stcb, aa->ifa, type, 1);
1056 /* free the entry */
42#include <netinet/sctp_asconf.h>
43
44/*
45 * debug flags:
46 * SCTP_DEBUG_ASCONF1: protocol info, general info and errors
47 * SCTP_DEBUG_ASCONF2: detailed info
48 */
49#ifdef SCTP_DEBUG

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

1048 /* delete requested, add already queued */
1049 (type == SCTP_DEL_IP_ADDRESS &&
1050 aa->ap.aph.ph.param_type == SCTP_ADD_IP_ADDRESS))) {
1051 /* delete the existing entry in the queue */
1052 TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
1053 /* take the entry off the appropriate list */
1054 sctp_asconf_addr_mgmt_ack(stcb, aa->ifa, type, 1);
1055 /* free the entry */
1056 sctp_free_ifa(aa->ifa);
1057 SCTP_FREE(aa);
1058 return (-1);
1059 }
1060 } /* for each aa */
1061
1062 /* adding new request to the queue */
1063 SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa), "AsconfAddr");
1064 if (aa == NULL) {

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

1069 }
1070#endif /* SCTP_DEBUG */
1071 return (-1);
1072 }
1073 /* fill in asconf address parameter fields */
1074 /* top level elements are "networked" during send */
1075 aa->ap.aph.ph.param_type = type;
1076 aa->ifa = ifa;
1057 SCTP_FREE(aa);
1058 return (-1);
1059 }
1060 } /* for each aa */
1061
1062 /* adding new request to the queue */
1063 SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa), "AsconfAddr");
1064 if (aa == NULL) {

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

1069 }
1070#endif /* SCTP_DEBUG */
1071 return (-1);
1072 }
1073 /* fill in asconf address parameter fields */
1074 /* top level elements are "networked" during send */
1075 aa->ap.aph.ph.param_type = type;
1076 aa->ifa = ifa;
1077 atomic_add_int(&ifa->refcount, 1);
1077 /* correlation_id filled in during send routine later... */
1078 if (ifa->address.sa.sa_family == AF_INET6) {
1079 /* IPv6 address */
1080 struct sockaddr_in6 *sin6;
1081
1082 sin6 = (struct sockaddr_in6 *)&ifa->address.sa;
1083 sa = (struct sockaddr *)sin6;
1084 aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;

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

1145 * NOTE: if adding, but delete already scheduled (and not yet sent out),
1146 * simply remove from queue. Same for deleting an address already scheduled
1147 * for add. If a duplicate operation is found, ignore the new one.
1148 */
1149static uint32_t
1150sctp_asconf_queue_add_sa(struct sctp_tcb *stcb, struct sockaddr *sa,
1151 uint16_t type)
1152{
1078 /* correlation_id filled in during send routine later... */
1079 if (ifa->address.sa.sa_family == AF_INET6) {
1080 /* IPv6 address */
1081 struct sockaddr_in6 *sin6;
1082
1083 sin6 = (struct sockaddr_in6 *)&ifa->address.sa;
1084 sa = (struct sockaddr *)sin6;
1085 aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;

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

1146 * NOTE: if adding, but delete already scheduled (and not yet sent out),
1147 * simply remove from queue. Same for deleting an address already scheduled
1148 * for add. If a duplicate operation is found, ignore the new one.
1149 */
1150static uint32_t
1151sctp_asconf_queue_add_sa(struct sctp_tcb *stcb, struct sockaddr *sa,
1152 uint16_t type)
1153{
1154 struct sctp_ifa *ifa;
1153 struct sctp_asconf_addr *aa, *aa_next;
1154 uint32_t vrf_id;
1155
1156 /* see if peer supports ASCONF */
1157 if (stcb->asoc.peer_supports_asconf == 0) {
1158 return (-1);
1159 }
1160 /* make sure the request isn't already in the queue */

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

1173 continue;
1174 if (type == SCTP_ADD_IP_ADDRESS &&
1175 aa->ap.aph.ph.param_type == SCTP_DEL_IP_ADDRESS) {
1176 /* add requested, delete already queued */
1177
1178 /* delete the existing entry in the queue */
1179 TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
1180 /* free the entry */
1155 struct sctp_asconf_addr *aa, *aa_next;
1156 uint32_t vrf_id;
1157
1158 /* see if peer supports ASCONF */
1159 if (stcb->asoc.peer_supports_asconf == 0) {
1160 return (-1);
1161 }
1162 /* make sure the request isn't already in the queue */

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

1175 continue;
1176 if (type == SCTP_ADD_IP_ADDRESS &&
1177 aa->ap.aph.ph.param_type == SCTP_DEL_IP_ADDRESS) {
1178 /* add requested, delete already queued */
1179
1180 /* delete the existing entry in the queue */
1181 TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
1182 /* free the entry */
1183 sctp_free_ifa(aa->ifa);
1181 SCTP_FREE(aa);
1182 return (-1);
1183 } else if (type == SCTP_DEL_IP_ADDRESS &&
1184 aa->ap.aph.ph.param_type == SCTP_ADD_IP_ADDRESS) {
1185 /* delete requested, add already queued */
1186
1187 /* delete the existing entry in the queue */
1188 TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
1189 /* take the entry off the appropriate list */
1190 sctp_asconf_addr_mgmt_ack(stcb, aa->ifa, type, 1);
1191 /* free the entry */
1184 SCTP_FREE(aa);
1185 return (-1);
1186 } else if (type == SCTP_DEL_IP_ADDRESS &&
1187 aa->ap.aph.ph.param_type == SCTP_ADD_IP_ADDRESS) {
1188 /* delete requested, add already queued */
1189
1190 /* delete the existing entry in the queue */
1191 TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
1192 /* take the entry off the appropriate list */
1193 sctp_asconf_addr_mgmt_ack(stcb, aa->ifa, type, 1);
1194 /* free the entry */
1195 sctp_free_ifa(aa->ifa);
1192 SCTP_FREE(aa);
1193 return (-1);
1194 }
1195 } /* for each aa */
1196 SCTP_FREE(aa);
1197 return (-1);
1198 }
1199 } /* for each aa */
1200 if (stcb) {
1201 vrf_id = stcb->asoc.vrf_id;
1202 } else {
1203 vrf_id = SCTP_DEFAULT_VRFID;
1204 }
1196
1205
1206 ifa = sctp_find_ifa_by_addr(sa, vrf_id, 0);
1207 if (ifa == NULL) {
1208 /* Invalid address */
1209 return (-1);
1210 }
1197 /* adding new request to the queue */
1198 SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa), "AsconfAddr");
1199 if (aa == NULL) {
1200 /* didn't get memory */
1201#ifdef SCTP_DEBUG
1202 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) {
1203 printf("asconf_queue_add_sa: failed to get memory!\n");
1204 }
1205#endif /* SCTP_DEBUG */
1206 return (-1);
1207 }
1208 /* fill in asconf address parameter fields */
1209 /* top level elements are "networked" during send */
1211 /* adding new request to the queue */
1212 SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa), "AsconfAddr");
1213 if (aa == NULL) {
1214 /* didn't get memory */
1215#ifdef SCTP_DEBUG
1216 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) {
1217 printf("asconf_queue_add_sa: failed to get memory!\n");
1218 }
1219#endif /* SCTP_DEBUG */
1220 return (-1);
1221 }
1222 /* fill in asconf address parameter fields */
1223 /* top level elements are "networked" during send */
1210 vrf_id = SCTP_DEFAULT_VRFID;
1211 aa->ap.aph.ph.param_type = type;
1224 aa->ap.aph.ph.param_type = type;
1212 aa->ifa = sctp_find_ifa_by_addr(sa, vrf_id, 0);
1225 aa->ifa = ifa;
1226 atomic_add_int(&ifa->refcount, 1);
1213 /* correlation_id filled in during send routine later... */
1214 if (sa->sa_family == AF_INET6) {
1215 /* IPv6 address */
1216 struct sockaddr_in6 *sin6;
1217
1218 sin6 = (struct sockaddr_in6 *)sa;
1219 aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
1220 aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param));

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

1367 break;
1368 default:
1369 /* should NEVER happen */
1370 break;
1371 }
1372
1373 /* remove the param and free it */
1374 TAILQ_REMOVE(&stcb->asoc.asconf_queue, aparam, next);
1227 /* correlation_id filled in during send routine later... */
1228 if (sa->sa_family == AF_INET6) {
1229 /* IPv6 address */
1230 struct sockaddr_in6 *sin6;
1231
1232 sin6 = (struct sockaddr_in6 *)sa;
1233 aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
1234 aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param));

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

1381 break;
1382 default:
1383 /* should NEVER happen */
1384 break;
1385 }
1386
1387 /* remove the param and free it */
1388 TAILQ_REMOVE(&stcb->asoc.asconf_queue, aparam, next);
1389 sctp_free_ifa(aparam->ifa);
1375 SCTP_FREE(aparam);
1376}
1377
1378/*
1379 * cleanup from a bad asconf ack parameter
1380 */
1381static void
1382sctp_asconf_ack_clear(struct sctp_tcb *stcb)

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

2408 }
2409 sin.sin_addr.s_addr = a4p->addr;
2410 sa = (struct sockaddr *)&sin;
2411 } else {
2412 goto next_addr;
2413 }
2414
2415 /* see if this address really (still) exists */
1390 SCTP_FREE(aparam);
1391}
1392
1393/*
1394 * cleanup from a bad asconf ack parameter
1395 */
1396static void
1397sctp_asconf_ack_clear(struct sctp_tcb *stcb)

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

2423 }
2424 sin.sin_addr.s_addr = a4p->addr;
2425 sa = (struct sockaddr *)&sin;
2426 } else {
2427 goto next_addr;
2428 }
2429
2430 /* see if this address really (still) exists */
2416 vrf_id = SCTP_DEFAULT_VRFID;
2431 if (stcb) {
2432 vrf_id = stcb->asoc.vrf_id;
2433 } else {
2434 vrf_id = SCTP_DEFAULT_VRFID;
2435 }
2436
2417 sctp_ifa = sctp_find_ifa_by_addr(sa, vrf_id, 0);
2418 if (sctp_ifa == NULL) {
2419 /* address doesn't exist anymore */
2420 int status;
2421
2422 /* are ASCONFs allowed ? */
2423 if ((sctp_is_feature_on(stcb->sctp_ep,
2424 SCTP_PCB_FLAGS_DO_ASCONF)) &&

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

2621 uint16_t local_scope, uint16_t site_scope,
2622 uint16_t ipv4_scope, uint16_t loopback_scope)
2623{
2624 struct sctp_vrf *vrf = NULL;
2625 struct sctp_ifn *sctp_ifn;
2626 struct sctp_ifa *sctp_ifa;
2627 uint32_t vrf_id;
2628
2437 sctp_ifa = sctp_find_ifa_by_addr(sa, vrf_id, 0);
2438 if (sctp_ifa == NULL) {
2439 /* address doesn't exist anymore */
2440 int status;
2441
2442 /* are ASCONFs allowed ? */
2443 if ((sctp_is_feature_on(stcb->sctp_ep,
2444 SCTP_PCB_FLAGS_DO_ASCONF)) &&

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

2641 uint16_t local_scope, uint16_t site_scope,
2642 uint16_t ipv4_scope, uint16_t loopback_scope)
2643{
2644 struct sctp_vrf *vrf = NULL;
2645 struct sctp_ifn *sctp_ifn;
2646 struct sctp_ifa *sctp_ifa;
2647 uint32_t vrf_id;
2648
2629 vrf_id = SCTP_DEFAULT_VRFID;
2649 if (stcb) {
2650 vrf_id = stcb->asoc.vrf_id;
2651 } else {
2652 vrf_id = SCTP_DEFAULT_VRFID;
2653 }
2630 vrf = sctp_find_vrf(vrf_id);
2631 if (vrf == NULL) {
2632 return;
2633 }
2634 /* go through all our known interfaces */
2635 LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
2636 if (loopback_scope == 0 && SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
2637 /* skip loopback interface */

--- 118 unchanged lines hidden ---
2654 vrf = sctp_find_vrf(vrf_id);
2655 if (vrf == NULL) {
2656 return;
2657 }
2658 /* go through all our known interfaces */
2659 LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
2660 if (loopback_scope == 0 && SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
2661 /* skip loopback interface */

--- 118 unchanged lines hidden ---