Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 78569
b: refs/heads/master
c: 42e30bf
h: refs/heads/master
i:
  78567: 31513a3
v: v3
  • Loading branch information
Vlad Yasevich authored and David S. Miller committed Jan 28, 2008
1 parent 060888f commit a9c233a
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6afd2e83cd86b17b074e1854d063b8ec590d7f5b
refs/heads/master: 42e30bf3463cd37d73839376662cb79b4d5c416c
2 changes: 2 additions & 0 deletions trunk/include/net/sctp/structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1938,6 +1938,8 @@ void sctp_assoc_rwnd_increase(struct sctp_association *, unsigned);
void sctp_assoc_rwnd_decrease(struct sctp_association *, unsigned);
void sctp_assoc_set_primary(struct sctp_association *,
struct sctp_transport *);
void sctp_assoc_del_nonprimary_peers(struct sctp_association *,
struct sctp_transport *);
int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *,
gfp_t);
int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *,
Expand Down
17 changes: 17 additions & 0 deletions trunk/net/sctp/associola.c
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,23 @@ struct sctp_transport *sctp_assoc_lookup_paddr(
return NULL;
}

/* Remove all transports except a give one */
void sctp_assoc_del_nonprimary_peers(struct sctp_association *asoc,
struct sctp_transport *primary)
{
struct sctp_transport *temp;
struct sctp_transport *t;

list_for_each_entry_safe(t, temp, &asoc->peer.transport_addr_list,
transports) {
/* if the current transport is not the primary one, delete it */
if (t != primary)
sctp_assoc_rm_peer(asoc, t);
}

return;
}

/* Engage in transport control operations.
* Mark the transport up or down and send a notification to the user.
* Select and update the new active and retran paths.
Expand Down
40 changes: 36 additions & 4 deletions trunk/net/sctp/sm_make_chunk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 *)
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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;
Expand Down

0 comments on commit a9c233a

Please sign in to comment.