diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2006-11-20 20:02:01 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-12-03 00:26:24 -0500 |
commit | 04afd8b282d702bc122051751466000e9513ef96 (patch) | |
tree | 1a5bc840fbc322daaf71b1e9fdd83b27274f9cc9 | |
parent | dbc16db1e58da6c346ca3e63870c17b93fbed0f0 (diff) |
[SCTP]: Beginning of sin_port fixes.
That's going to be a long series. Introduced temporary helpers
doing copy-and-convert for sctp_addr; they are used to kill
flip-in-place in global data structures and will be used
to gradually push host-endian uses of sctp_addr out of existence.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/sctp/structs.h | 22 | ||||
-rw-r--r-- | net/sctp/socket.c | 29 |
2 files changed, 34 insertions, 17 deletions
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index ca77bc5b7ff5..2aa61ac9a9f3 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
@@ -74,6 +74,28 @@ union sctp_addr { | |||
74 | struct sockaddr sa; | 74 | struct sockaddr sa; |
75 | }; | 75 | }; |
76 | 76 | ||
77 | static inline void flip_to_n(union sctp_addr *to, const union sctp_addr *from) | ||
78 | { | ||
79 | size_t len; | ||
80 | if (from->sa.sa_family == AF_INET6) | ||
81 | len = sizeof(struct sockaddr_in6); | ||
82 | else | ||
83 | len = sizeof(struct sockaddr); | ||
84 | memcpy(to, from, len); | ||
85 | to->v4.sin_port = htons(from->v4.sin_port); | ||
86 | } | ||
87 | |||
88 | static inline void flip_to_h(union sctp_addr *to, const union sctp_addr *from) | ||
89 | { | ||
90 | size_t len; | ||
91 | if (from->sa.sa_family == AF_INET6) | ||
92 | len = sizeof(struct sockaddr_in6); | ||
93 | else | ||
94 | len = sizeof(struct sockaddr); | ||
95 | memcpy(to, from, len); | ||
96 | to->v4.sin_port = ntohs(from->v4.sin_port); | ||
97 | } | ||
98 | |||
77 | /* Forward declarations for data structures. */ | 99 | /* Forward declarations for data structures. */ |
78 | struct sctp_globals; | 100 | struct sctp_globals; |
79 | struct sctp_endpoint; | 101 | struct sctp_endpoint; |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 935bc9187fd8..f4d13ab79f49 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -228,12 +228,12 @@ static struct sctp_transport *sctp_addr_id2transport(struct sock *sk, | |||
228 | struct sctp_association *addr_asoc = NULL, *id_asoc = NULL; | 228 | struct sctp_association *addr_asoc = NULL, *id_asoc = NULL; |
229 | struct sctp_transport *transport; | 229 | struct sctp_transport *transport; |
230 | union sctp_addr *laddr = (union sctp_addr *)addr; | 230 | union sctp_addr *laddr = (union sctp_addr *)addr; |
231 | union sctp_addr tmp; | ||
231 | 232 | ||
232 | laddr->v4.sin_port = ntohs(laddr->v4.sin_port); | 233 | flip_to_h(&tmp, laddr); |
233 | addr_asoc = sctp_endpoint_lookup_assoc(sctp_sk(sk)->ep, | 234 | addr_asoc = sctp_endpoint_lookup_assoc(sctp_sk(sk)->ep, |
234 | (union sctp_addr *)addr, | 235 | &tmp, |
235 | &transport); | 236 | &transport); |
236 | laddr->v4.sin_port = htons(laddr->v4.sin_port); | ||
237 | 237 | ||
238 | if (!addr_asoc) | 238 | if (!addr_asoc) |
239 | return NULL; | 239 | return NULL; |
@@ -313,6 +313,7 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len) | |||
313 | struct sctp_af *af; | 313 | struct sctp_af *af; |
314 | unsigned short snum; | 314 | unsigned short snum; |
315 | int ret = 0; | 315 | int ret = 0; |
316 | union sctp_addr tmp; | ||
316 | 317 | ||
317 | /* Common sockaddr verification. */ | 318 | /* Common sockaddr verification. */ |
318 | af = sctp_sockaddr_af(sp, addr, len); | 319 | af = sctp_sockaddr_af(sp, addr, len); |
@@ -368,9 +369,8 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len) | |||
368 | sctp_write_lock(&ep->base.addr_lock); | 369 | sctp_write_lock(&ep->base.addr_lock); |
369 | 370 | ||
370 | /* Use GFP_ATOMIC since BHs are disabled. */ | 371 | /* Use GFP_ATOMIC since BHs are disabled. */ |
371 | addr->v4.sin_port = ntohs(addr->v4.sin_port); | 372 | flip_to_h(&tmp, addr); |
372 | ret = sctp_add_bind_addr(bp, addr, 1, GFP_ATOMIC); | 373 | ret = sctp_add_bind_addr(bp, &tmp, 1, GFP_ATOMIC); |
373 | addr->v4.sin_port = htons(addr->v4.sin_port); | ||
374 | sctp_write_unlock(&ep->base.addr_lock); | 374 | sctp_write_unlock(&ep->base.addr_lock); |
375 | sctp_local_bh_enable(); | 375 | sctp_local_bh_enable(); |
376 | 376 | ||
@@ -4194,12 +4194,8 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len, | |||
4194 | if (!asoc->peer.primary_path) | 4194 | if (!asoc->peer.primary_path) |
4195 | return -ENOTCONN; | 4195 | return -ENOTCONN; |
4196 | 4196 | ||
4197 | asoc->peer.primary_path->ipaddr.v4.sin_port = | 4197 | flip_to_n((union sctp_addr *)&prim.ssp_addr, |
4198 | htons(asoc->peer.primary_path->ipaddr.v4.sin_port); | 4198 | &asoc->peer.primary_path->ipaddr); |
4199 | memcpy(&prim.ssp_addr, &asoc->peer.primary_path->ipaddr, | ||
4200 | sizeof(union sctp_addr)); | ||
4201 | asoc->peer.primary_path->ipaddr.v4.sin_port = | ||
4202 | ntohs(asoc->peer.primary_path->ipaddr.v4.sin_port); | ||
4203 | 4199 | ||
4204 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, | 4200 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, |
4205 | (union sctp_addr *)&prim.ssp_addr); | 4201 | (union sctp_addr *)&prim.ssp_addr); |
@@ -4642,12 +4638,12 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr) | |||
4642 | { | 4638 | { |
4643 | struct sctp_bind_hashbucket *head; /* hash list */ | 4639 | struct sctp_bind_hashbucket *head; /* hash list */ |
4644 | struct sctp_bind_bucket *pp; /* hash list port iterator */ | 4640 | struct sctp_bind_bucket *pp; /* hash list port iterator */ |
4641 | union sctp_addr tmp; | ||
4645 | unsigned short snum; | 4642 | unsigned short snum; |
4646 | int ret; | 4643 | int ret; |
4647 | 4644 | ||
4648 | /* NOTE: Remember to put this back to net order. */ | 4645 | flip_to_h(&tmp, addr); |
4649 | addr->v4.sin_port = ntohs(addr->v4.sin_port); | 4646 | snum = ntohs(addr->v4.sin_port); |
4650 | snum = addr->v4.sin_port; | ||
4651 | 4647 | ||
4652 | SCTP_DEBUG_PRINTK("sctp_get_port() begins, snum=%d\n", snum); | 4648 | SCTP_DEBUG_PRINTK("sctp_get_port() begins, snum=%d\n", snum); |
4653 | sctp_local_bh_disable(); | 4649 | sctp_local_bh_disable(); |
@@ -4744,7 +4740,7 @@ pp_found: | |||
4744 | if (reuse && sk2->sk_reuse) | 4740 | if (reuse && sk2->sk_reuse) |
4745 | continue; | 4741 | continue; |
4746 | 4742 | ||
4747 | if (sctp_bind_addr_match(&ep2->base.bind_addr, addr, | 4743 | if (sctp_bind_addr_match(&ep2->base.bind_addr, &tmp, |
4748 | sctp_sk(sk))) { | 4744 | sctp_sk(sk))) { |
4749 | ret = (long)sk2; | 4745 | ret = (long)sk2; |
4750 | goto fail_unlock; | 4746 | goto fail_unlock; |
@@ -4784,7 +4780,6 @@ fail_unlock: | |||
4784 | 4780 | ||
4785 | fail: | 4781 | fail: |
4786 | sctp_local_bh_enable(); | 4782 | sctp_local_bh_enable(); |
4787 | addr->v4.sin_port = htons(addr->v4.sin_port); | ||
4788 | return ret; | 4783 | return ret; |
4789 | } | 4784 | } |
4790 | 4785 | ||