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 --- |