Commit f57d96b2 authored by Vlad Yasevich's avatar Vlad Yasevich Committed by David S. Miller
Browse files

[SCTP]: Change use_as_src into a full address state

parent a08de64d
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -760,12 +760,18 @@ void sctp_init_addrs(struct sctp_chunk *, union sctp_addr *,
		     union sctp_addr *);
const union sctp_addr *sctp_source(const struct sctp_chunk *chunk);

enum {
	SCTP_ADDR_NEW,		/* new address added to assoc/ep */
	SCTP_ADDR_SRC,		/* address can be used as source */
	SCTP_ADDR_DEL,		/* address about to be deleted */
};

/* This is a structure for holding either an IPv6 or an IPv4 address.  */
struct sctp_sockaddr_entry {
	struct list_head list;
	struct rcu_head	rcu;
	union sctp_addr a;
	__u8 use_as_src;
	__u8 state;
	__u8 valid;
};

@@ -1190,7 +1196,7 @@ int sctp_bind_addr_dup(struct sctp_bind_addr *dest,
			const struct sctp_bind_addr *src,
			gfp_t gfp);
int sctp_add_bind_addr(struct sctp_bind_addr *, union sctp_addr *,
		       __u8 use_as_src, gfp_t gfp);
		       __u8 addr_state, gfp_t gfp);
int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *);
int sctp_bind_addr_match(struct sctp_bind_addr *, const union sctp_addr *,
			 struct sctp_sock *);
+5 −4
Original line number Diff line number Diff line
@@ -171,7 +171,7 @@ void sctp_bind_addr_free(struct sctp_bind_addr *bp)

/* Add an address to the bind address list in the SCTP_bind_addr structure. */
int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new,
		       __u8 use_as_src, gfp_t gfp)
		       __u8 addr_state, gfp_t gfp)
{
	struct sctp_sockaddr_entry *addr;

@@ -188,7 +188,7 @@ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new,
	if (!addr->a.v4.sin_port)
		addr->a.v4.sin_port = htons(bp->port);

	addr->use_as_src = use_as_src;
	addr->state = addr_state;
	addr->valid = 1;

	INIT_LIST_HEAD(&addr->list);
@@ -312,7 +312,7 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_addr_list,
		}

		af->from_addr_param(&addr, rawaddr, htons(port), 0);
		retval = sctp_add_bind_addr(bp, &addr, 1, gfp);
		retval = sctp_add_bind_addr(bp, &addr, SCTP_ADDR_SRC, gfp);
		if (retval) {
			/* Can't finish building the list, clean up. */
			sctp_bind_addr_clean(bp);
@@ -411,7 +411,8 @@ static int sctp_copy_one_addr(struct sctp_bind_addr *dest,
		    (((AF_INET6 == addr->sa.sa_family) &&
		      (flags & SCTP_ADDR6_ALLOWED) &&
		      (flags & SCTP_ADDR6_PEERSUPP))))
			error = sctp_add_bind_addr(dest, addr, 1, gfp);
			error = sctp_add_bind_addr(dest, addr, SCTP_ADDR_SRC,
						    gfp);
	}

	return error;
+1 −1
Original line number Diff line number Diff line
@@ -330,7 +330,7 @@ static void sctp_v6_get_saddr(struct sctp_association *asoc,
	list_for_each_entry_rcu(laddr, &bp->address_list, list) {
		if (!laddr->valid)
			continue;
		if ((laddr->use_as_src) &&
		if ((laddr->state == SCTP_ADDR_SRC) &&
		    (laddr->a.sa.sa_family == AF_INET6) &&
		    (scope <= sctp_scope(&laddr->a))) {
			bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a);
+4 −4
Original line number Diff line number Diff line
@@ -229,8 +229,8 @@ int sctp_copy_local_addr_list(struct sctp_bind_addr *bp, sctp_scope_t scope,
			    (((AF_INET6 == addr->a.sa.sa_family) &&
			      (copy_flags & SCTP_ADDR6_ALLOWED) &&
			      (copy_flags & SCTP_ADDR6_PEERSUPP)))) {
				error = sctp_add_bind_addr(bp, &addr->a, 1,
						    GFP_ATOMIC);
				error = sctp_add_bind_addr(bp, &addr->a,
						    SCTP_ADDR_SRC, GFP_ATOMIC);
				if (error)
					goto end_copy;
			}
@@ -472,7 +472,7 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
		 */
		rcu_read_lock();
		list_for_each_entry_rcu(laddr, &bp->address_list, list) {
			if (!laddr->valid || !laddr->use_as_src)
			if (!laddr->valid || (laddr->state != SCTP_ADDR_SRC))
				continue;
			sctp_v4_dst_saddr(&dst_saddr, dst, htons(bp->port));
			if (sctp_v4_cmp_addr(&dst_saddr, &laddr->a))
@@ -494,7 +494,7 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
	list_for_each_entry_rcu(laddr, &bp->address_list, list) {
		if (!laddr->valid)
			continue;
		if ((laddr->use_as_src) &&
		if ((laddr->state == SCTP_ADDR_SRC) &&
		    (AF_INET == laddr->a.sa.sa_family)) {
			fl.fl4_src = laddr->a.v4.sin_addr.s_addr;
			if (!ip_route_output_key(&rt, &fl)) {
+3 −3
Original line number Diff line number Diff line
@@ -1692,8 +1692,8 @@ no_hmac:

	/* Also, add the destination address. */
	if (list_empty(&retval->base.bind_addr.address_list)) {
		sctp_add_bind_addr(&retval->base.bind_addr, &chunk->dest, 1,
				GFP_ATOMIC);
		sctp_add_bind_addr(&retval->base.bind_addr, &chunk->dest,
				SCTP_ADDR_SRC, GFP_ATOMIC);
	}

	retval->next_tsn = retval->c.initial_tsn;
@@ -3016,7 +3016,7 @@ static int sctp_asconf_param_success(struct sctp_association *asoc,
		local_bh_disable();
		list_for_each_entry(saddr, &bp->address_list, list) {
			if (sctp_cmp_addr_exact(&saddr->a, &addr))
				saddr->use_as_src = 1;
				saddr->state = SCTP_ADDR_SRC;
		}
		local_bh_enable();
		break;
Loading