diff options
-rw-r--r-- | include/net/sctp/structs.h | 10 | ||||
-rw-r--r-- | net/sctp/bind_addr.c | 9 | ||||
-rw-r--r-- | net/sctp/ipv6.c | 2 | ||||
-rw-r--r-- | net/sctp/protocol.c | 8 | ||||
-rw-r--r-- | net/sctp/sm_make_chunk.c | 6 | ||||
-rw-r--r-- | net/sctp/socket.c | 8 |
6 files changed, 25 insertions, 18 deletions
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index fa87873fee76..2528f8a837d9 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
@@ -760,12 +760,18 @@ void sctp_init_addrs(struct sctp_chunk *, union sctp_addr *, | |||
760 | union sctp_addr *); | 760 | union sctp_addr *); |
761 | const union sctp_addr *sctp_source(const struct sctp_chunk *chunk); | 761 | const union sctp_addr *sctp_source(const struct sctp_chunk *chunk); |
762 | 762 | ||
763 | enum { | ||
764 | SCTP_ADDR_NEW, /* new address added to assoc/ep */ | ||
765 | SCTP_ADDR_SRC, /* address can be used as source */ | ||
766 | SCTP_ADDR_DEL, /* address about to be deleted */ | ||
767 | }; | ||
768 | |||
763 | /* This is a structure for holding either an IPv6 or an IPv4 address. */ | 769 | /* This is a structure for holding either an IPv6 or an IPv4 address. */ |
764 | struct sctp_sockaddr_entry { | 770 | struct sctp_sockaddr_entry { |
765 | struct list_head list; | 771 | struct list_head list; |
766 | struct rcu_head rcu; | 772 | struct rcu_head rcu; |
767 | union sctp_addr a; | 773 | union sctp_addr a; |
768 | __u8 use_as_src; | 774 | __u8 state; |
769 | __u8 valid; | 775 | __u8 valid; |
770 | }; | 776 | }; |
771 | 777 | ||
@@ -1190,7 +1196,7 @@ int sctp_bind_addr_dup(struct sctp_bind_addr *dest, | |||
1190 | const struct sctp_bind_addr *src, | 1196 | const struct sctp_bind_addr *src, |
1191 | gfp_t gfp); | 1197 | gfp_t gfp); |
1192 | int sctp_add_bind_addr(struct sctp_bind_addr *, union sctp_addr *, | 1198 | int sctp_add_bind_addr(struct sctp_bind_addr *, union sctp_addr *, |
1193 | __u8 use_as_src, gfp_t gfp); | 1199 | __u8 addr_state, gfp_t gfp); |
1194 | int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *); | 1200 | int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *); |
1195 | int sctp_bind_addr_match(struct sctp_bind_addr *, const union sctp_addr *, | 1201 | int sctp_bind_addr_match(struct sctp_bind_addr *, const union sctp_addr *, |
1196 | struct sctp_sock *); | 1202 | struct sctp_sock *); |
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c index 6a7d01091f0c..432661174789 100644 --- a/net/sctp/bind_addr.c +++ b/net/sctp/bind_addr.c | |||
@@ -171,7 +171,7 @@ void sctp_bind_addr_free(struct sctp_bind_addr *bp) | |||
171 | 171 | ||
172 | /* Add an address to the bind address list in the SCTP_bind_addr structure. */ | 172 | /* Add an address to the bind address list in the SCTP_bind_addr structure. */ |
173 | int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new, | 173 | int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new, |
174 | __u8 use_as_src, gfp_t gfp) | 174 | __u8 addr_state, gfp_t gfp) |
175 | { | 175 | { |
176 | struct sctp_sockaddr_entry *addr; | 176 | struct sctp_sockaddr_entry *addr; |
177 | 177 | ||
@@ -188,7 +188,7 @@ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new, | |||
188 | if (!addr->a.v4.sin_port) | 188 | if (!addr->a.v4.sin_port) |
189 | addr->a.v4.sin_port = htons(bp->port); | 189 | addr->a.v4.sin_port = htons(bp->port); |
190 | 190 | ||
191 | addr->use_as_src = use_as_src; | 191 | addr->state = addr_state; |
192 | addr->valid = 1; | 192 | addr->valid = 1; |
193 | 193 | ||
194 | INIT_LIST_HEAD(&addr->list); | 194 | 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 | } | 312 | } |
313 | 313 | ||
314 | af->from_addr_param(&addr, rawaddr, htons(port), 0); | 314 | af->from_addr_param(&addr, rawaddr, htons(port), 0); |
315 | retval = sctp_add_bind_addr(bp, &addr, 1, gfp); | 315 | retval = sctp_add_bind_addr(bp, &addr, SCTP_ADDR_SRC, gfp); |
316 | if (retval) { | 316 | if (retval) { |
317 | /* Can't finish building the list, clean up. */ | 317 | /* Can't finish building the list, clean up. */ |
318 | sctp_bind_addr_clean(bp); | 318 | sctp_bind_addr_clean(bp); |
@@ -411,7 +411,8 @@ static int sctp_copy_one_addr(struct sctp_bind_addr *dest, | |||
411 | (((AF_INET6 == addr->sa.sa_family) && | 411 | (((AF_INET6 == addr->sa.sa_family) && |
412 | (flags & SCTP_ADDR6_ALLOWED) && | 412 | (flags & SCTP_ADDR6_ALLOWED) && |
413 | (flags & SCTP_ADDR6_PEERSUPP)))) | 413 | (flags & SCTP_ADDR6_PEERSUPP)))) |
414 | error = sctp_add_bind_addr(dest, addr, 1, gfp); | 414 | error = sctp_add_bind_addr(dest, addr, SCTP_ADDR_SRC, |
415 | gfp); | ||
415 | } | 416 | } |
416 | 417 | ||
417 | return error; | 418 | return error; |
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 7f31ff638bc6..bd04aed673cb 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
@@ -330,7 +330,7 @@ static void sctp_v6_get_saddr(struct sctp_association *asoc, | |||
330 | list_for_each_entry_rcu(laddr, &bp->address_list, list) { | 330 | list_for_each_entry_rcu(laddr, &bp->address_list, list) { |
331 | if (!laddr->valid) | 331 | if (!laddr->valid) |
332 | continue; | 332 | continue; |
333 | if ((laddr->use_as_src) && | 333 | if ((laddr->state == SCTP_ADDR_SRC) && |
334 | (laddr->a.sa.sa_family == AF_INET6) && | 334 | (laddr->a.sa.sa_family == AF_INET6) && |
335 | (scope <= sctp_scope(&laddr->a))) { | 335 | (scope <= sctp_scope(&laddr->a))) { |
336 | bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a); | 336 | bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a); |
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index dc22d7108494..e466e00b9a9f 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
@@ -229,8 +229,8 @@ int sctp_copy_local_addr_list(struct sctp_bind_addr *bp, sctp_scope_t scope, | |||
229 | (((AF_INET6 == addr->a.sa.sa_family) && | 229 | (((AF_INET6 == addr->a.sa.sa_family) && |
230 | (copy_flags & SCTP_ADDR6_ALLOWED) && | 230 | (copy_flags & SCTP_ADDR6_ALLOWED) && |
231 | (copy_flags & SCTP_ADDR6_PEERSUPP)))) { | 231 | (copy_flags & SCTP_ADDR6_PEERSUPP)))) { |
232 | error = sctp_add_bind_addr(bp, &addr->a, 1, | 232 | error = sctp_add_bind_addr(bp, &addr->a, |
233 | GFP_ATOMIC); | 233 | SCTP_ADDR_SRC, GFP_ATOMIC); |
234 | if (error) | 234 | if (error) |
235 | goto end_copy; | 235 | goto end_copy; |
236 | } | 236 | } |
@@ -472,7 +472,7 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, | |||
472 | */ | 472 | */ |
473 | rcu_read_lock(); | 473 | rcu_read_lock(); |
474 | list_for_each_entry_rcu(laddr, &bp->address_list, list) { | 474 | list_for_each_entry_rcu(laddr, &bp->address_list, list) { |
475 | if (!laddr->valid || !laddr->use_as_src) | 475 | if (!laddr->valid || (laddr->state != SCTP_ADDR_SRC)) |
476 | continue; | 476 | continue; |
477 | sctp_v4_dst_saddr(&dst_saddr, dst, htons(bp->port)); | 477 | sctp_v4_dst_saddr(&dst_saddr, dst, htons(bp->port)); |
478 | if (sctp_v4_cmp_addr(&dst_saddr, &laddr->a)) | 478 | 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 | list_for_each_entry_rcu(laddr, &bp->address_list, list) { | 494 | list_for_each_entry_rcu(laddr, &bp->address_list, list) { |
495 | if (!laddr->valid) | 495 | if (!laddr->valid) |
496 | continue; | 496 | continue; |
497 | if ((laddr->use_as_src) && | 497 | if ((laddr->state == SCTP_ADDR_SRC) && |
498 | (AF_INET == laddr->a.sa.sa_family)) { | 498 | (AF_INET == laddr->a.sa.sa_family)) { |
499 | fl.fl4_src = laddr->a.v4.sin_addr.s_addr; | 499 | fl.fl4_src = laddr->a.v4.sin_addr.s_addr; |
500 | if (!ip_route_output_key(&rt, &fl)) { | 500 | if (!ip_route_output_key(&rt, &fl)) { |
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 7fd6a6b68614..46f54188f00a 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
@@ -1692,8 +1692,8 @@ no_hmac: | |||
1692 | 1692 | ||
1693 | /* Also, add the destination address. */ | 1693 | /* Also, add the destination address. */ |
1694 | if (list_empty(&retval->base.bind_addr.address_list)) { | 1694 | if (list_empty(&retval->base.bind_addr.address_list)) { |
1695 | sctp_add_bind_addr(&retval->base.bind_addr, &chunk->dest, 1, | 1695 | sctp_add_bind_addr(&retval->base.bind_addr, &chunk->dest, |
1696 | GFP_ATOMIC); | 1696 | SCTP_ADDR_SRC, GFP_ATOMIC); |
1697 | } | 1697 | } |
1698 | 1698 | ||
1699 | retval->next_tsn = retval->c.initial_tsn; | 1699 | retval->next_tsn = retval->c.initial_tsn; |
@@ -3016,7 +3016,7 @@ static int sctp_asconf_param_success(struct sctp_association *asoc, | |||
3016 | local_bh_disable(); | 3016 | local_bh_disable(); |
3017 | list_for_each_entry(saddr, &bp->address_list, list) { | 3017 | list_for_each_entry(saddr, &bp->address_list, list) { |
3018 | if (sctp_cmp_addr_exact(&saddr->a, &addr)) | 3018 | if (sctp_cmp_addr_exact(&saddr->a, &addr)) |
3019 | saddr->use_as_src = 1; | 3019 | saddr->state = SCTP_ADDR_SRC; |
3020 | } | 3020 | } |
3021 | local_bh_enable(); | 3021 | local_bh_enable(); |
3022 | break; | 3022 | break; |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index dc2f9221f092..7a8650f01d08 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -390,7 +390,7 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len) | |||
390 | /* Add the address to the bind address list. | 390 | /* Add the address to the bind address list. |
391 | * Use GFP_ATOMIC since BHs will be disabled. | 391 | * Use GFP_ATOMIC since BHs will be disabled. |
392 | */ | 392 | */ |
393 | ret = sctp_add_bind_addr(bp, addr, 1, GFP_ATOMIC); | 393 | ret = sctp_add_bind_addr(bp, addr, SCTP_ADDR_SRC, GFP_ATOMIC); |
394 | 394 | ||
395 | /* Copy back into socket for getsockname() use. */ | 395 | /* Copy back into socket for getsockname() use. */ |
396 | if (!ret) { | 396 | if (!ret) { |
@@ -585,8 +585,8 @@ static int sctp_send_asconf_add_ip(struct sock *sk, | |||
585 | addr = (union sctp_addr *)addr_buf; | 585 | addr = (union sctp_addr *)addr_buf; |
586 | af = sctp_get_af_specific(addr->v4.sin_family); | 586 | af = sctp_get_af_specific(addr->v4.sin_family); |
587 | memcpy(&saveaddr, addr, af->sockaddr_len); | 587 | memcpy(&saveaddr, addr, af->sockaddr_len); |
588 | retval = sctp_add_bind_addr(bp, &saveaddr, 0, | 588 | retval = sctp_add_bind_addr(bp, &saveaddr, |
589 | GFP_ATOMIC); | 589 | SCTP_ADDR_NEW, GFP_ATOMIC); |
590 | addr_buf += af->sockaddr_len; | 590 | addr_buf += af->sockaddr_len; |
591 | } | 591 | } |
592 | } | 592 | } |
@@ -777,7 +777,7 @@ static int sctp_send_asconf_del_ip(struct sock *sk, | |||
777 | af = sctp_get_af_specific(laddr->v4.sin_family); | 777 | af = sctp_get_af_specific(laddr->v4.sin_family); |
778 | list_for_each_entry(saddr, &bp->address_list, list) { | 778 | list_for_each_entry(saddr, &bp->address_list, list) { |
779 | if (sctp_cmp_addr_exact(&saddr->a, laddr)) | 779 | if (sctp_cmp_addr_exact(&saddr->a, laddr)) |
780 | saddr->use_as_src = 0; | 780 | saddr->state = SCTP_ADDR_DEL; |
781 | } | 781 | } |
782 | addr_buf += af->sockaddr_len; | 782 | addr_buf += af->sockaddr_len; |
783 | } | 783 | } |