提交 f57d96b2 编写于 作者: V Vlad Yasevich 提交者: David S. Miller

[SCTP]: Change use_as_src into a full address state

Signed-off-by: NVlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 a08de64d
...@@ -760,12 +760,18 @@ void sctp_init_addrs(struct sctp_chunk *, union sctp_addr *, ...@@ -760,12 +760,18 @@ void sctp_init_addrs(struct sctp_chunk *, union sctp_addr *,
union sctp_addr *); union sctp_addr *);
const union sctp_addr *sctp_source(const struct sctp_chunk *chunk); 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. */ /* This is a structure for holding either an IPv6 or an IPv4 address. */
struct sctp_sockaddr_entry { struct sctp_sockaddr_entry {
struct list_head list; struct list_head list;
struct rcu_head rcu; struct rcu_head rcu;
union sctp_addr a; union sctp_addr a;
__u8 use_as_src; __u8 state;
__u8 valid; __u8 valid;
}; };
...@@ -1190,7 +1196,7 @@ int sctp_bind_addr_dup(struct sctp_bind_addr *dest, ...@@ -1190,7 +1196,7 @@ int sctp_bind_addr_dup(struct sctp_bind_addr *dest,
const struct sctp_bind_addr *src, const struct sctp_bind_addr *src,
gfp_t gfp); gfp_t gfp);
int sctp_add_bind_addr(struct sctp_bind_addr *, union sctp_addr *, 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_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *);
int sctp_bind_addr_match(struct sctp_bind_addr *, const union sctp_addr *, int sctp_bind_addr_match(struct sctp_bind_addr *, const union sctp_addr *,
struct sctp_sock *); struct sctp_sock *);
......
...@@ -171,7 +171,7 @@ void sctp_bind_addr_free(struct sctp_bind_addr *bp) ...@@ -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. */ /* 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, 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; struct sctp_sockaddr_entry *addr;
...@@ -188,7 +188,7 @@ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new, ...@@ -188,7 +188,7 @@ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new,
if (!addr->a.v4.sin_port) if (!addr->a.v4.sin_port)
addr->a.v4.sin_port = htons(bp->port); addr->a.v4.sin_port = htons(bp->port);
addr->use_as_src = use_as_src; addr->state = addr_state;
addr->valid = 1; addr->valid = 1;
INIT_LIST_HEAD(&addr->list); INIT_LIST_HEAD(&addr->list);
...@@ -312,7 +312,7 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_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); 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) { if (retval) {
/* Can't finish building the list, clean up. */ /* Can't finish building the list, clean up. */
sctp_bind_addr_clean(bp); sctp_bind_addr_clean(bp);
...@@ -411,7 +411,8 @@ static int sctp_copy_one_addr(struct sctp_bind_addr *dest, ...@@ -411,7 +411,8 @@ static int sctp_copy_one_addr(struct sctp_bind_addr *dest,
(((AF_INET6 == addr->sa.sa_family) && (((AF_INET6 == addr->sa.sa_family) &&
(flags & SCTP_ADDR6_ALLOWED) && (flags & SCTP_ADDR6_ALLOWED) &&
(flags & SCTP_ADDR6_PEERSUPP)))) (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; return error;
......
...@@ -330,7 +330,7 @@ static void sctp_v6_get_saddr(struct sctp_association *asoc, ...@@ -330,7 +330,7 @@ static void sctp_v6_get_saddr(struct sctp_association *asoc,
list_for_each_entry_rcu(laddr, &bp->address_list, list) { list_for_each_entry_rcu(laddr, &bp->address_list, list) {
if (!laddr->valid) if (!laddr->valid)
continue; continue;
if ((laddr->use_as_src) && if ((laddr->state == SCTP_ADDR_SRC) &&
(laddr->a.sa.sa_family == AF_INET6) && (laddr->a.sa.sa_family == AF_INET6) &&
(scope <= sctp_scope(&laddr->a))) { (scope <= sctp_scope(&laddr->a))) {
bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a); bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a);
......
...@@ -229,8 +229,8 @@ int sctp_copy_local_addr_list(struct sctp_bind_addr *bp, sctp_scope_t scope, ...@@ -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) && (((AF_INET6 == addr->a.sa.sa_family) &&
(copy_flags & SCTP_ADDR6_ALLOWED) && (copy_flags & SCTP_ADDR6_ALLOWED) &&
(copy_flags & SCTP_ADDR6_PEERSUPP)))) { (copy_flags & SCTP_ADDR6_PEERSUPP)))) {
error = sctp_add_bind_addr(bp, &addr->a, 1, error = sctp_add_bind_addr(bp, &addr->a,
GFP_ATOMIC); SCTP_ADDR_SRC, GFP_ATOMIC);
if (error) if (error)
goto end_copy; goto end_copy;
} }
...@@ -472,7 +472,7 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, ...@@ -472,7 +472,7 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
*/ */
rcu_read_lock(); rcu_read_lock();
list_for_each_entry_rcu(laddr, &bp->address_list, list) { 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; continue;
sctp_v4_dst_saddr(&dst_saddr, dst, htons(bp->port)); sctp_v4_dst_saddr(&dst_saddr, dst, htons(bp->port));
if (sctp_v4_cmp_addr(&dst_saddr, &laddr->a)) 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, ...@@ -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) { list_for_each_entry_rcu(laddr, &bp->address_list, list) {
if (!laddr->valid) if (!laddr->valid)
continue; continue;
if ((laddr->use_as_src) && if ((laddr->state == SCTP_ADDR_SRC) &&
(AF_INET == laddr->a.sa.sa_family)) { (AF_INET == laddr->a.sa.sa_family)) {
fl.fl4_src = laddr->a.v4.sin_addr.s_addr; fl.fl4_src = laddr->a.v4.sin_addr.s_addr;
if (!ip_route_output_key(&rt, &fl)) { if (!ip_route_output_key(&rt, &fl)) {
......
...@@ -1692,8 +1692,8 @@ struct sctp_association *sctp_unpack_cookie( ...@@ -1692,8 +1692,8 @@ struct sctp_association *sctp_unpack_cookie(
/* Also, add the destination address. */ /* Also, add the destination address. */
if (list_empty(&retval->base.bind_addr.address_list)) { if (list_empty(&retval->base.bind_addr.address_list)) {
sctp_add_bind_addr(&retval->base.bind_addr, &chunk->dest, 1, sctp_add_bind_addr(&retval->base.bind_addr, &chunk->dest,
GFP_ATOMIC); SCTP_ADDR_SRC, GFP_ATOMIC);
} }
retval->next_tsn = retval->c.initial_tsn; retval->next_tsn = retval->c.initial_tsn;
...@@ -3016,7 +3016,7 @@ static int sctp_asconf_param_success(struct sctp_association *asoc, ...@@ -3016,7 +3016,7 @@ static int sctp_asconf_param_success(struct sctp_association *asoc,
local_bh_disable(); local_bh_disable();
list_for_each_entry(saddr, &bp->address_list, list) { list_for_each_entry(saddr, &bp->address_list, list) {
if (sctp_cmp_addr_exact(&saddr->a, &addr)) if (sctp_cmp_addr_exact(&saddr->a, &addr))
saddr->use_as_src = 1; saddr->state = SCTP_ADDR_SRC;
} }
local_bh_enable(); local_bh_enable();
break; break;
......
...@@ -390,7 +390,7 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len) ...@@ -390,7 +390,7 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
/* Add the address to the bind address list. /* Add the address to the bind address list.
* Use GFP_ATOMIC since BHs will be disabled. * Use GFP_ATOMIC since BHs will be disabled.
*/ */
ret = sctp_add_bind_addr(bp, addr, 1, GFP_ATOMIC); ret = sctp_add_bind_addr(bp, addr, SCTP_ADDR_SRC, GFP_ATOMIC);
/* Copy back into socket for getsockname() use. */ /* Copy back into socket for getsockname() use. */
if (!ret) { if (!ret) {
...@@ -585,8 +585,8 @@ static int sctp_send_asconf_add_ip(struct sock *sk, ...@@ -585,8 +585,8 @@ static int sctp_send_asconf_add_ip(struct sock *sk,
addr = (union sctp_addr *)addr_buf; addr = (union sctp_addr *)addr_buf;
af = sctp_get_af_specific(addr->v4.sin_family); af = sctp_get_af_specific(addr->v4.sin_family);
memcpy(&saveaddr, addr, af->sockaddr_len); memcpy(&saveaddr, addr, af->sockaddr_len);
retval = sctp_add_bind_addr(bp, &saveaddr, 0, retval = sctp_add_bind_addr(bp, &saveaddr,
GFP_ATOMIC); SCTP_ADDR_NEW, GFP_ATOMIC);
addr_buf += af->sockaddr_len; addr_buf += af->sockaddr_len;
} }
} }
...@@ -777,7 +777,7 @@ static int sctp_send_asconf_del_ip(struct sock *sk, ...@@ -777,7 +777,7 @@ static int sctp_send_asconf_del_ip(struct sock *sk,
af = sctp_get_af_specific(laddr->v4.sin_family); af = sctp_get_af_specific(laddr->v4.sin_family);
list_for_each_entry(saddr, &bp->address_list, list) { list_for_each_entry(saddr, &bp->address_list, list) {
if (sctp_cmp_addr_exact(&saddr->a, laddr)) if (sctp_cmp_addr_exact(&saddr->a, laddr))
saddr->use_as_src = 0; saddr->state = SCTP_ADDR_DEL;
} }
addr_buf += af->sockaddr_len; addr_buf += af->sockaddr_len;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册