Commit 44310455 authored by Jon Grimm's avatar Jon Grimm

[SCTP] Supported address types should be based on pf_family.

PF_INET sockets are advertising v6 address support.  Make this
choice a pf_family function. 
parent 1402a73c
...@@ -323,7 +323,8 @@ static inline int sctp_ipv6_addr_type(const struct in6_addr *addr) ...@@ -323,7 +323,8 @@ static inline int sctp_ipv6_addr_type(const struct in6_addr *addr)
return ipv6_addr_type((struct in6_addr*) addr); return ipv6_addr_type((struct in6_addr*) addr);
} }
#define SCTP_SAT_LEN (sizeof(sctp_paramhdr_t) + 2 * sizeof(__u16)) /* Size of Supported Address Parameter for 'x' address types. */
#define SCTP_SAT_LEN(x) (sizeof(struct sctp_paramhdr) + (x) * sizeof(__u16))
/* Note: These V6 macros are obsolescent. */ /* Note: These V6 macros are obsolescent. */
/* Use this macro to enclose code fragments which are V6-dependent. */ /* Use this macro to enclose code fragments which are V6-dependent. */
......
...@@ -293,6 +293,7 @@ struct sctp_pf { ...@@ -293,6 +293,7 @@ struct sctp_pf {
const union sctp_addr *, const union sctp_addr *,
struct sctp_opt *); struct sctp_opt *);
int (*bind_verify) (struct sctp_opt *, union sctp_addr *); int (*bind_verify) (struct sctp_opt *, union sctp_addr *);
int (*supported_addrs)(const struct sctp_opt *, __u16 *);
struct sctp_af *af; struct sctp_af *af;
}; };
...@@ -397,8 +398,6 @@ typedef struct sctp_signed_cookie { ...@@ -397,8 +398,6 @@ typedef struct sctp_signed_cookie {
sctp_cookie_t c; sctp_cookie_t c;
} sctp_signed_cookie_t; } sctp_signed_cookie_t;
/* This is another convenience type to allocate memory for address /* This is another convenience type to allocate memory for address
* params for the maximum size and pass such structures around * params for the maximum size and pass such structures around
* internally. * internally.
......
...@@ -565,6 +565,20 @@ static int sctp_inet6_bind_verify(struct sctp_opt *opt, union sctp_addr *addr) ...@@ -565,6 +565,20 @@ static int sctp_inet6_bind_verify(struct sctp_opt *opt, union sctp_addr *addr)
return af->available(addr); return af->available(addr);
} }
/* Fill in Supported Address Type information for INIT and INIT-ACK
* chunks. Note: In the future, we may want to look at sock options
* to determine whether a PF_INET6 socket really wants to have IPV4
* addresses.
* Returns number of addresses supported.
*/
static int sctp_inet6_supported_addrs(const struct sctp_opt *opt,
__u16 *types)
{
types[0] = SCTP_PARAM_IPV4_ADDRESS;
types[1] = SCTP_PARAM_IPV6_ADDRESS;
return 2;
}
static struct proto_ops inet6_seqpacket_ops = { static struct proto_ops inet6_seqpacket_ops = {
.family = PF_INET6, .family = PF_INET6,
.release = inet6_release, .release = inet6_release,
...@@ -627,6 +641,7 @@ static struct sctp_pf sctp_pf_inet6_specific = { ...@@ -627,6 +641,7 @@ static struct sctp_pf sctp_pf_inet6_specific = {
.af_supported = sctp_inet6_af_supported, .af_supported = sctp_inet6_af_supported,
.cmp_addr = sctp_inet6_cmp_addr, .cmp_addr = sctp_inet6_cmp_addr,
.bind_verify = sctp_inet6_bind_verify, .bind_verify = sctp_inet6_bind_verify,
.supported_addrs = sctp_inet6_supported_addrs,
.af = &sctp_ipv6_specific, .af = &sctp_ipv6_specific,
}; };
......
...@@ -631,6 +631,16 @@ static int sctp_inet_bind_verify(struct sctp_opt *opt, union sctp_addr *addr) ...@@ -631,6 +631,16 @@ static int sctp_inet_bind_verify(struct sctp_opt *opt, union sctp_addr *addr)
return sctp_v4_available(addr); return sctp_v4_available(addr);
} }
/* Fill in Supported Address Type information for INIT and INIT-ACK
* chunks. Returns number of addresses supported.
*/
static int sctp_inet_supported_addrs(const struct sctp_opt *opt,
__u16 *types)
{
types[0] = SCTP_PARAM_IPV4_ADDRESS;
return 1;
}
/* Wrapper routine that calls the ip transmit routine. */ /* Wrapper routine that calls the ip transmit routine. */
static inline int sctp_v4_xmit(struct sk_buff *skb, static inline int sctp_v4_xmit(struct sk_buff *skb,
struct sctp_transport *transport, int ipfragok) struct sctp_transport *transport, int ipfragok)
...@@ -653,6 +663,7 @@ static struct sctp_pf sctp_pf_inet = { ...@@ -653,6 +663,7 @@ static struct sctp_pf sctp_pf_inet = {
.af_supported = sctp_inet_af_supported, .af_supported = sctp_inet_af_supported,
.cmp_addr = sctp_inet_cmp_addr, .cmp_addr = sctp_inet_cmp_addr,
.bind_verify = sctp_inet_bind_verify, .bind_verify = sctp_inet_bind_verify,
.supported_addrs = sctp_inet_supported_addrs,
.af = &sctp_ipv4_specific, .af = &sctp_ipv4_specific,
}; };
......
...@@ -66,29 +66,6 @@ ...@@ -66,29 +66,6 @@
#include <net/sctp/sctp.h> #include <net/sctp/sctp.h>
#include <net/sctp/sm.h> #include <net/sctp/sm.h>
/* RFC 2960 3.3.2 Initiation (INIT) (1)
*
* Note 4: This parameter, when present, specifies all the
* address types the sending endpoint can support. The absence
* of this parameter indicates that the sending endpoint can
* support any address type.
*/
static const sctp_supported_addrs_param_t sat_param = {
{
SCTP_PARAM_SUPPORTED_ADDRESS_TYPES,
__constant_htons(SCTP_SAT_LEN),
}
};
/* gcc 3.2 doesn't allow initialization of zero-length arrays. So the above
* structure is split and the address types array is initialized using a
* fixed length array.
*/
static const __u16 sat_addr_types[2] = {
SCTP_PARAM_IPV4_ADDRESS,
SCTP_V6(SCTP_PARAM_IPV6_ADDRESS,)
};
/* RFC 2960 3.3.2 Initiation (INIT) (1) /* RFC 2960 3.3.2 Initiation (INIT) (1)
* *
* Note 2: The ECN capable field is reserved for future use of * Note 2: The ECN capable field is reserved for future use of
...@@ -174,7 +151,10 @@ sctp_chunk_t *sctp_make_init(const sctp_association_t *asoc, ...@@ -174,7 +151,10 @@ sctp_chunk_t *sctp_make_init(const sctp_association_t *asoc,
union sctp_params addrs; union sctp_params addrs;
size_t chunksize; size_t chunksize;
sctp_chunk_t *retval = NULL; sctp_chunk_t *retval = NULL;
int addrs_len = 0; int num_types, addrs_len = 0;
struct sctp_opt *sp;
sctp_supported_addrs_param_t sat;
__u16 types[2];
/* RFC 2960 3.3.2 Initiation (INIT) (1) /* RFC 2960 3.3.2 Initiation (INIT) (1)
* *
...@@ -195,7 +175,11 @@ sctp_chunk_t *sctp_make_init(const sctp_association_t *asoc, ...@@ -195,7 +175,11 @@ sctp_chunk_t *sctp_make_init(const sctp_association_t *asoc,
init.num_inbound_streams = htons(asoc->c.sinit_max_instreams); init.num_inbound_streams = htons(asoc->c.sinit_max_instreams);
init.initial_tsn = htonl(asoc->c.initial_tsn); init.initial_tsn = htonl(asoc->c.initial_tsn);
chunksize = sizeof(init) + addrs_len + SCTP_SAT_LEN; /* How many address types are needed? */
sp = sctp_sk(asoc->base.sk);
num_types = sp->pf->supported_addrs(sp, types);
chunksize = sizeof(init) + addrs_len + SCTP_SAT_LEN(num_types);
chunksize += sizeof(ecap_param); chunksize += sizeof(ecap_param);
chunksize += vparam_len; chunksize += vparam_len;
...@@ -220,8 +204,18 @@ sctp_chunk_t *sctp_make_init(const sctp_association_t *asoc, ...@@ -220,8 +204,18 @@ sctp_chunk_t *sctp_make_init(const sctp_association_t *asoc,
retval->param_hdr.v = retval->param_hdr.v =
sctp_addto_chunk(retval, addrs_len, addrs.v); sctp_addto_chunk(retval, addrs_len, addrs.v);
sctp_addto_chunk(retval, sizeof(sctp_paramhdr_t), &sat_param); /* RFC 2960 3.3.2 Initiation (INIT) (1)
sctp_addto_chunk(retval, sizeof(sat_addr_types), sat_addr_types); *
* Note 4: This parameter, when present, specifies all the
* address types the sending endpoint can support. The absence
* of this parameter indicates that the sending endpoint can
* support any address type.
*/
sat.param_hdr.type = SCTP_PARAM_SUPPORTED_ADDRESS_TYPES;
sat.param_hdr.length = htons(SCTP_SAT_LEN(num_types));
sctp_addto_chunk(retval, sizeof(sat), &sat);
sctp_addto_chunk(retval, num_types * sizeof(__u16), &types);
sctp_addto_chunk(retval, sizeof(ecap_param), &ecap_param); sctp_addto_chunk(retval, sizeof(ecap_param), &ecap_param);
nodata: nodata:
if (addrs.v) if (addrs.v)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment