|
@@ -2727,7 +2727,6 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
|
|
|
struct sctp_transport *peer;
|
|
|
struct sctp_af *af;
|
|
|
union sctp_addr addr;
|
|
|
- struct list_head *pos;
|
|
|
union sctp_addr_param *addr_param;
|
|
|
|
|
|
addr_param = (union sctp_addr_param *)
|
|
@@ -2738,8 +2737,24 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
|
|
|
return SCTP_ERROR_INV_PARAM;
|
|
|
|
|
|
af->from_addr_param(&addr, addr_param, htons(asoc->peer.port), 0);
|
|
|
+
|
|
|
+ /* ADDIP 4.2.1 This parameter MUST NOT contain a broadcast
|
|
|
+ * or multicast address.
|
|
|
+ * (note: wildcard is permitted and requires special handling so
|
|
|
+ * make sure we check for that)
|
|
|
+ */
|
|
|
+ if (!af->is_any(&addr) && !af->addr_valid(&addr, NULL, asconf->skb))
|
|
|
+ return SCTP_ERROR_INV_PARAM;
|
|
|
+
|
|
|
switch (asconf_param->param_hdr.type) {
|
|
|
case SCTP_PARAM_ADD_IP:
|
|
|
+ /* Section 4.2.1:
|
|
|
+ * If the address 0.0.0.0 or ::0 is provided, the source
|
|
|
+ * address of the packet MUST be added.
|
|
|
+ */
|
|
|
+ if (af->is_any(&addr))
|
|
|
+ memcpy(&addr, &asconf->source, sizeof(addr));
|
|
|
+
|
|
|
/* ADDIP 4.3 D9) If an endpoint receives an ADD IP address
|
|
|
* request and does not have the local resources to add this
|
|
|
* new address to the association, it MUST return an Error
|
|
@@ -2761,8 +2776,7 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
|
|
|
* MUST send an Error Cause TLV with the error cause set to the
|
|
|
* new error code 'Request to Delete Last Remaining IP Address'.
|
|
|
*/
|
|
|
- pos = asoc->peer.transport_addr_list.next;
|
|
|
- if (pos->next == &asoc->peer.transport_addr_list)
|
|
|
+ if (asoc->peer.transport_count == 1)
|
|
|
return SCTP_ERROR_DEL_LAST_IP;
|
|
|
|
|
|
/* ADDIP 4.3 D8) If a request is received to delete an IP
|
|
@@ -2775,9 +2789,27 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
|
|
|
if (sctp_cmp_addr_exact(sctp_source(asconf), &addr))
|
|
|
return SCTP_ERROR_DEL_SRC_IP;
|
|
|
|
|
|
- sctp_assoc_del_peer(asoc, &addr);
|
|
|
+ /* Section 4.2.2
|
|
|
+ * If the address 0.0.0.0 or ::0 is provided, all
|
|
|
+ * addresses of the peer except the source address of the
|
|
|
+ * packet MUST be deleted.
|
|
|
+ */
|
|
|
+ if (af->is_any(&addr)) {
|
|
|
+ sctp_assoc_set_primary(asoc, asconf->transport);
|
|
|
+ sctp_assoc_del_nonprimary_peers(asoc,
|
|
|
+ asconf->transport);
|
|
|
+ } else
|
|
|
+ sctp_assoc_del_peer(asoc, &addr);
|
|
|
break;
|
|
|
case SCTP_PARAM_SET_PRIMARY:
|
|
|
+ /* ADDIP Section 4.2.4
|
|
|
+ * If the address 0.0.0.0 or ::0 is provided, the receiver
|
|
|
+ * MAY mark the source address of the packet as its
|
|
|
+ * primary.
|
|
|
+ */
|
|
|
+ if (af->is_any(&addr))
|
|
|
+ memcpy(&addr.v4, sctp_source(asconf), sizeof(addr));
|
|
|
+
|
|
|
peer = sctp_assoc_lookup_paddr(asoc, &addr);
|
|
|
if (!peer)
|
|
|
return SCTP_ERROR_INV_PARAM;
|