Skip to content

Commit 42e30bf

Browse files
Vlad Yasevichdavem330
authored andcommitted
[SCTP]: Handle the wildcard ADD-IP Address parameter
The Address Parameter in the parameter list of the ASCONF chunk may be a wildcard address. In this case special processing is required. For the 'add' case, the source IP of the packet is added. In the 'del' case, all addresses except the source IP of packet are removed. In the "mark primary" case, the source address is marked as primary. Signed-off-by: Vlad Yasevich <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 6afd2e8 commit 42e30bf

File tree

3 files changed

+55
-4
lines changed

3 files changed

+55
-4
lines changed

include/net/sctp/structs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1938,6 +1938,8 @@ void sctp_assoc_rwnd_increase(struct sctp_association *, unsigned);
19381938
void sctp_assoc_rwnd_decrease(struct sctp_association *, unsigned);
19391939
void sctp_assoc_set_primary(struct sctp_association *,
19401940
struct sctp_transport *);
1941+
void sctp_assoc_del_nonprimary_peers(struct sctp_association *,
1942+
struct sctp_transport *);
19411943
int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *,
19421944
gfp_t);
19431945
int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *,

net/sctp/associola.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,23 @@ struct sctp_transport *sctp_assoc_lookup_paddr(
730730
return NULL;
731731
}
732732

733+
/* Remove all transports except a give one */
734+
void sctp_assoc_del_nonprimary_peers(struct sctp_association *asoc,
735+
struct sctp_transport *primary)
736+
{
737+
struct sctp_transport *temp;
738+
struct sctp_transport *t;
739+
740+
list_for_each_entry_safe(t, temp, &asoc->peer.transport_addr_list,
741+
transports) {
742+
/* if the current transport is not the primary one, delete it */
743+
if (t != primary)
744+
sctp_assoc_rm_peer(asoc, t);
745+
}
746+
747+
return;
748+
}
749+
733750
/* Engage in transport control operations.
734751
* Mark the transport up or down and send a notification to the user.
735752
* Select and update the new active and retran paths.

net/sctp/sm_make_chunk.c

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2727,7 +2727,6 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
27272727
struct sctp_transport *peer;
27282728
struct sctp_af *af;
27292729
union sctp_addr addr;
2730-
struct list_head *pos;
27312730
union sctp_addr_param *addr_param;
27322731

27332732
addr_param = (union sctp_addr_param *)
@@ -2738,8 +2737,24 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
27382737
return SCTP_ERROR_INV_PARAM;
27392738

27402739
af->from_addr_param(&addr, addr_param, htons(asoc->peer.port), 0);
2740+
2741+
/* ADDIP 4.2.1 This parameter MUST NOT contain a broadcast
2742+
* or multicast address.
2743+
* (note: wildcard is permitted and requires special handling so
2744+
* make sure we check for that)
2745+
*/
2746+
if (!af->is_any(&addr) && !af->addr_valid(&addr, NULL, asconf->skb))
2747+
return SCTP_ERROR_INV_PARAM;
2748+
27412749
switch (asconf_param->param_hdr.type) {
27422750
case SCTP_PARAM_ADD_IP:
2751+
/* Section 4.2.1:
2752+
* If the address 0.0.0.0 or ::0 is provided, the source
2753+
* address of the packet MUST be added.
2754+
*/
2755+
if (af->is_any(&addr))
2756+
memcpy(&addr, &asconf->source, sizeof(addr));
2757+
27432758
/* ADDIP 4.3 D9) If an endpoint receives an ADD IP address
27442759
* request and does not have the local resources to add this
27452760
* new address to the association, it MUST return an Error
@@ -2761,8 +2776,7 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
27612776
* MUST send an Error Cause TLV with the error cause set to the
27622777
* new error code 'Request to Delete Last Remaining IP Address'.
27632778
*/
2764-
pos = asoc->peer.transport_addr_list.next;
2765-
if (pos->next == &asoc->peer.transport_addr_list)
2779+
if (asoc->peer.transport_count == 1)
27662780
return SCTP_ERROR_DEL_LAST_IP;
27672781

27682782
/* 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,
27752789
if (sctp_cmp_addr_exact(sctp_source(asconf), &addr))
27762790
return SCTP_ERROR_DEL_SRC_IP;
27772791

2778-
sctp_assoc_del_peer(asoc, &addr);
2792+
/* Section 4.2.2
2793+
* If the address 0.0.0.0 or ::0 is provided, all
2794+
* addresses of the peer except the source address of the
2795+
* packet MUST be deleted.
2796+
*/
2797+
if (af->is_any(&addr)) {
2798+
sctp_assoc_set_primary(asoc, asconf->transport);
2799+
sctp_assoc_del_nonprimary_peers(asoc,
2800+
asconf->transport);
2801+
} else
2802+
sctp_assoc_del_peer(asoc, &addr);
27792803
break;
27802804
case SCTP_PARAM_SET_PRIMARY:
2805+
/* ADDIP Section 4.2.4
2806+
* If the address 0.0.0.0 or ::0 is provided, the receiver
2807+
* MAY mark the source address of the packet as its
2808+
* primary.
2809+
*/
2810+
if (af->is_any(&addr))
2811+
memcpy(&addr.v4, sctp_source(asconf), sizeof(addr));
2812+
27812813
peer = sctp_assoc_lookup_paddr(asoc, &addr);
27822814
if (!peer)
27832815
return SCTP_ERROR_INV_PARAM;

0 commit comments

Comments
 (0)