Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a8c617ea authored by David S. Miller's avatar David S. Miller
Browse files
parents 2307f866 c6ba68a2
Loading
Loading
Loading
Loading
+10 −10
Original line number Diff line number Diff line
@@ -487,17 +487,17 @@ typedef enum {
	 *
	 * Value          Cause Code
	 * ---------      ----------------
	 * 0x0100          Request to Delete Last Remaining IP Address.
	 * 0x0101          Operation Refused Due to Resource Shortage.
	 * 0x0102          Request to Delete Source IP Address.
	 * 0x0103          Association Aborted due to illegal ASCONF-ACK
	 * 0x0104          Request refused - no authorization.
	 * 0x00A0          Request to Delete Last Remaining IP Address.
	 * 0x00A1          Operation Refused Due to Resource Shortage.
	 * 0x00A2          Request to Delete Source IP Address.
	 * 0x00A3          Association Aborted due to illegal ASCONF-ACK
	 * 0x00A4          Request refused - no authorization.
	 */
	SCTP_ERROR_DEL_LAST_IP	= cpu_to_be16(0x0100),
	SCTP_ERROR_RSRC_LOW	= cpu_to_be16(0x0101),
	SCTP_ERROR_DEL_SRC_IP	= cpu_to_be16(0x0102),
	SCTP_ERROR_ASCONF_ACK   = cpu_to_be16(0x0103),
	SCTP_ERROR_REQ_REFUSED	= cpu_to_be16(0x0104),
	SCTP_ERROR_DEL_LAST_IP	= cpu_to_be16(0x00A0),
	SCTP_ERROR_RSRC_LOW	= cpu_to_be16(0x00A1),
	SCTP_ERROR_DEL_SRC_IP	= cpu_to_be16(0x00A2),
	SCTP_ERROR_ASCONF_ACK   = cpu_to_be16(0x00A3),
	SCTP_ERROR_REQ_REFUSED	= cpu_to_be16(0x00A4),

	/* AUTH Section 4.  New Error Cause
	 *
+2 −4
Original line number Diff line number Diff line
@@ -1939,10 +1939,8 @@ void sctp_association_free(struct sctp_association *);
void sctp_association_put(struct sctp_association *);
void sctp_association_hold(struct sctp_association *);

struct sctp_transport *sctp_assoc_choose_init_transport(
	struct sctp_association *);
struct sctp_transport *sctp_assoc_choose_shutdown_transport(
	struct sctp_association *);
struct sctp_transport *sctp_assoc_choose_alter_transport(
	struct sctp_association *, struct sctp_transport *);
void sctp_assoc_update_retran_path(struct sctp_association *);
struct sctp_transport *sctp_assoc_lookup_paddr(const struct sctp_association *,
					  const union sctp_addr *);
+2 −0
Original line number Diff line number Diff line
@@ -147,6 +147,8 @@ enum sctp_optname {
#define SCTP_GET_LOCAL_ADDRS	SCTP_GET_LOCAL_ADDRS
	SCTP_SOCKOPT_CONNECTX, /* CONNECTX requests. */
#define SCTP_SOCKOPT_CONNECTX	SCTP_SOCKOPT_CONNECTX
	SCTP_SOCKOPT_CONNECTX3, /* CONNECTX requests. (new implementation) */
#define SCTP_SOCKOPT_CONNECTX3	SCTP_SOCKOPT_CONNECTX3
};

/*
+28 −36
Original line number Diff line number Diff line
@@ -293,6 +293,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
	 * told otherwise.
	 */
	asoc->peer.ipv4_address = 1;
	if (asoc->base.sk->sk_family == PF_INET6)
		asoc->peer.ipv6_address = 1;
	INIT_LIST_HEAD(&asoc->asocs);

@@ -566,6 +567,21 @@ void sctp_assoc_rm_peer(struct sctp_association *asoc,
	if (asoc->init_last_sent_to == peer)
		asoc->init_last_sent_to = NULL;

	/* If we remove the transport an SHUTDOWN was last sent to, set it
	 * to NULL. Combined with the update of the retran path above, this
	 * will cause the next SHUTDOWN to be sent to the next available
	 * transport, maintaining the cycle.
	 */
	if (asoc->shutdown_last_sent_to == peer)
		asoc->shutdown_last_sent_to = NULL;

	/* If we remove the transport an ASCONF was last sent to, set it to
	 * NULL.
	 */
	if (asoc->addip_last_asconf &&
	    asoc->addip_last_asconf->transport == peer)
		asoc->addip_last_asconf->transport = NULL;

	asoc->peer.transport_count--;

	sctp_transport_free(peer);
@@ -1268,49 +1284,21 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc)
				 ntohs(t->ipaddr.v4.sin_port));
}

/* Choose the transport for sending a INIT packet.  */
struct sctp_transport *sctp_assoc_choose_init_transport(
	struct sctp_association *asoc)
{
	struct sctp_transport *t;

	/* Use the retran path. If the last INIT was sent over the
	 * retran path, update the retran path and use it.
	 */
	if (!asoc->init_last_sent_to) {
		t = asoc->peer.active_path;
	} else {
		if (asoc->init_last_sent_to == asoc->peer.retran_path)
			sctp_assoc_update_retran_path(asoc);
		t = asoc->peer.retran_path;
	}

	SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_update_retran_path:association"
				 " %p addr: ",
				 " port: %d\n",
				 asoc,
				 (&t->ipaddr),
				 ntohs(t->ipaddr.v4.sin_port));

	return t;
}

/* Choose the transport for sending a SHUTDOWN packet.  */
struct sctp_transport *sctp_assoc_choose_shutdown_transport(
	struct sctp_association *asoc)
/* Choose the transport for sending retransmit packet.  */
struct sctp_transport *sctp_assoc_choose_alter_transport(
	struct sctp_association *asoc, struct sctp_transport *last_sent_to)
{
	/* If this is the first time SHUTDOWN is sent, use the active path,
	 * else use the retran path. If the last SHUTDOWN was sent over the
	/* If this is the first time packet is sent, use the active path,
	 * else use the retran path. If the last packet was sent over the
	 * retran path, update the retran path and use it.
	 */
	if (!asoc->shutdown_last_sent_to)
	if (!last_sent_to)
		return asoc->peer.active_path;
	else {
		if (asoc->shutdown_last_sent_to == asoc->peer.retran_path)
		if (last_sent_to == asoc->peer.retran_path)
			sctp_assoc_update_retran_path(asoc);
		return asoc->peer.retran_path;
	}

}

/* Update the association's pmtu and frag_point by going through all the
@@ -1482,6 +1470,10 @@ int sctp_assoc_set_id(struct sctp_association *asoc, gfp_t gfp)
{
	int assoc_id;
	int error = 0;

	/* If the id is already assigned, keep it. */
	if (asoc->assoc_id)
		return error;
retry:
	if (unlikely(!idr_pre_get(&sctp_assocs_id, gfp)))
		return -ENOMEM;
+8 −8
Original line number Diff line number Diff line
@@ -2864,19 +2864,19 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
	switch (addr_param->v4.param_hdr.type) {
	case SCTP_PARAM_IPV6_ADDRESS:
		if (!asoc->peer.ipv6_address)
			return SCTP_ERROR_INV_PARAM;
			return SCTP_ERROR_DNS_FAILED;
		break;
	case SCTP_PARAM_IPV4_ADDRESS:
		if (!asoc->peer.ipv4_address)
			return SCTP_ERROR_INV_PARAM;
			return SCTP_ERROR_DNS_FAILED;
		break;
	default:
		return SCTP_ERROR_INV_PARAM;
		return SCTP_ERROR_DNS_FAILED;
	}

	af = sctp_get_af_specific(param_type2af(addr_param->v4.param_hdr.type));
	if (unlikely(!af))
		return SCTP_ERROR_INV_PARAM;
		return SCTP_ERROR_DNS_FAILED;

	af->from_addr_param(&addr, addr_param, htons(asoc->peer.port), 0);

@@ -2886,7 +2886,7 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
	 *  make sure we check for that)
	 */
	if (!af->is_any(&addr) && !af->addr_valid(&addr, NULL, asconf->skb))
		return SCTP_ERROR_INV_PARAM;
		return SCTP_ERROR_DNS_FAILED;

	switch (asconf_param->param_hdr.type) {
	case SCTP_PARAM_ADD_IP:
@@ -2954,12 +2954,12 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,

		peer = sctp_assoc_lookup_paddr(asoc, &addr);
		if (!peer)
			return SCTP_ERROR_INV_PARAM;
			return SCTP_ERROR_DNS_FAILED;

		sctp_assoc_set_primary(asoc, peer);
		break;
	default:
		return SCTP_ERROR_INV_PARAM;
		return SCTP_ERROR_UNKNOWN_PARAM;
		break;
	}

@@ -3273,7 +3273,7 @@ int sctp_process_asconf_ack(struct sctp_association *asoc,
			retval = 1;
			break;

		case SCTP_ERROR_INV_PARAM:
		case SCTP_ERROR_UNKNOWN_PARAM:
			/* Disable sending this type of asconf parameter in
			 * future.
			 */
Loading