Commit c4907c6e authored by David S. Miller's avatar David S. Miller

Merge branch 'sctp-cleanups'

Marcelo Ricardo Leitner says:

====================
SCTP cleanups

Some cleanups/simplifications I've been collecting.
Resending now with net-next open.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 8f18e4d0 509e7a31
...@@ -722,10 +722,9 @@ struct sctp_packet { ...@@ -722,10 +722,9 @@ struct sctp_packet {
ipfragok:1; /* So let ip fragment this packet */ ipfragok:1; /* So let ip fragment this packet */
}; };
struct sctp_packet *sctp_packet_init(struct sctp_packet *, void sctp_packet_init(struct sctp_packet *, struct sctp_transport *,
struct sctp_transport *, __u16 sport, __u16 dport);
__u16 sport, __u16 dport); void sctp_packet_config(struct sctp_packet *, __u32 vtag, int);
struct sctp_packet *sctp_packet_config(struct sctp_packet *, __u32 vtag, int);
sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *, sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *,
struct sctp_chunk *, int, gfp_t); struct sctp_chunk *, int, gfp_t);
sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *, sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *,
......
...@@ -412,22 +412,20 @@ static void sctp_v6_copy_addrlist(struct list_head *addrlist, ...@@ -412,22 +412,20 @@ static void sctp_v6_copy_addrlist(struct list_head *addrlist,
static void sctp_v6_from_skb(union sctp_addr *addr, struct sk_buff *skb, static void sctp_v6_from_skb(union sctp_addr *addr, struct sk_buff *skb,
int is_saddr) int is_saddr)
{ {
__be16 *port; /* Always called on head skb, so this is safe */
struct sctphdr *sh; struct sctphdr *sh = sctp_hdr(skb);
struct sockaddr_in6 *sa = &addr->v6;
port = &addr->v6.sin6_port;
addr->v6.sin6_family = AF_INET6; addr->v6.sin6_family = AF_INET6;
addr->v6.sin6_flowinfo = 0; /* FIXME */ addr->v6.sin6_flowinfo = 0; /* FIXME */
addr->v6.sin6_scope_id = ((struct inet6_skb_parm *)skb->cb)->iif; addr->v6.sin6_scope_id = ((struct inet6_skb_parm *)skb->cb)->iif;
/* Always called on head skb, so this is safe */
sh = sctp_hdr(skb);
if (is_saddr) { if (is_saddr) {
*port = sh->source; sa->sin6_port = sh->source;
addr->v6.sin6_addr = ipv6_hdr(skb)->saddr; sa->sin6_addr = ipv6_hdr(skb)->saddr;
} else { } else {
*port = sh->dest; sa->sin6_port = sh->dest;
addr->v6.sin6_addr = ipv6_hdr(skb)->daddr; sa->sin6_addr = ipv6_hdr(skb)->daddr;
} }
} }
......
...@@ -81,8 +81,8 @@ static void sctp_packet_reset(struct sctp_packet *packet) ...@@ -81,8 +81,8 @@ static void sctp_packet_reset(struct sctp_packet *packet)
/* Config a packet. /* Config a packet.
* This appears to be a followup set of initializations. * This appears to be a followup set of initializations.
*/ */
struct sctp_packet *sctp_packet_config(struct sctp_packet *packet, void sctp_packet_config(struct sctp_packet *packet, __u32 vtag,
__u32 vtag, int ecn_capable) int ecn_capable)
{ {
struct sctp_transport *tp = packet->transport; struct sctp_transport *tp = packet->transport;
struct sctp_association *asoc = tp->asoc; struct sctp_association *asoc = tp->asoc;
...@@ -123,14 +123,12 @@ struct sctp_packet *sctp_packet_config(struct sctp_packet *packet, ...@@ -123,14 +123,12 @@ struct sctp_packet *sctp_packet_config(struct sctp_packet *packet,
if (chunk) if (chunk)
sctp_packet_append_chunk(packet, chunk); sctp_packet_append_chunk(packet, chunk);
} }
return packet;
} }
/* Initialize the packet structure. */ /* Initialize the packet structure. */
struct sctp_packet *sctp_packet_init(struct sctp_packet *packet, void sctp_packet_init(struct sctp_packet *packet,
struct sctp_transport *transport, struct sctp_transport *transport,
__u16 sport, __u16 dport) __u16 sport, __u16 dport)
{ {
struct sctp_association *asoc = transport->asoc; struct sctp_association *asoc = transport->asoc;
size_t overhead; size_t overhead;
...@@ -151,8 +149,6 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet *packet, ...@@ -151,8 +149,6 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet *packet,
packet->overhead = overhead; packet->overhead = overhead;
sctp_packet_reset(packet); sctp_packet_reset(packet);
packet->vtag = 0; packet->vtag = 0;
return packet;
} }
/* Free a packet. */ /* Free a packet. */
......
...@@ -237,23 +237,19 @@ int sctp_copy_local_addr_list(struct net *net, struct sctp_bind_addr *bp, ...@@ -237,23 +237,19 @@ int sctp_copy_local_addr_list(struct net *net, struct sctp_bind_addr *bp,
static void sctp_v4_from_skb(union sctp_addr *addr, struct sk_buff *skb, static void sctp_v4_from_skb(union sctp_addr *addr, struct sk_buff *skb,
int is_saddr) int is_saddr)
{ {
void *from; /* Always called on head skb, so this is safe */
__be16 *port; struct sctphdr *sh = sctp_hdr(skb);
struct sctphdr *sh; struct sockaddr_in *sa = &addr->v4;
port = &addr->v4.sin_port;
addr->v4.sin_family = AF_INET; addr->v4.sin_family = AF_INET;
/* Always called on head skb, so this is safe */
sh = sctp_hdr(skb);
if (is_saddr) { if (is_saddr) {
*port = sh->source; sa->sin_port = sh->source;
from = &ip_hdr(skb)->saddr; sa->sin_addr.s_addr = ip_hdr(skb)->saddr;
} else { } else {
*port = sh->dest; sa->sin_port = sh->dest;
from = &ip_hdr(skb)->daddr; sa->sin_addr.s_addr = ip_hdr(skb)->daddr;
} }
memcpy(&addr->v4.sin_addr.s_addr, from, sizeof(struct in_addr));
} }
/* Initialize an sctp_addr from a socket. */ /* Initialize an sctp_addr from a socket. */
......
...@@ -160,23 +160,22 @@ static sctp_disposition_t __sctp_sf_do_9_1_abort(struct net *net, ...@@ -160,23 +160,22 @@ static sctp_disposition_t __sctp_sf_do_9_1_abort(struct net *net,
/* Small helper function that checks if the chunk length /* Small helper function that checks if the chunk length
* is of the appropriate length. The 'required_length' argument * is of the appropriate length. The 'required_length' argument
* is set to be the size of a specific chunk we are testing. * is set to be the size of a specific chunk we are testing.
* Return Values: 1 = Valid length * Return Values: true = Valid length
* 0 = Invalid length * false = Invalid length
* *
*/ */
static inline int static inline bool
sctp_chunk_length_valid(struct sctp_chunk *chunk, sctp_chunk_length_valid(struct sctp_chunk *chunk, __u16 required_length)
__u16 required_length)
{ {
__u16 chunk_length = ntohs(chunk->chunk_hdr->length); __u16 chunk_length = ntohs(chunk->chunk_hdr->length);
/* Previously already marked? */ /* Previously already marked? */
if (unlikely(chunk->pdiscard)) if (unlikely(chunk->pdiscard))
return 0; return false;
if (unlikely(chunk_length < required_length)) if (unlikely(chunk_length < required_length))
return 0; return false;
return 1; return true;
} }
/********************************************************** /**********************************************************
...@@ -3237,36 +3236,34 @@ static sctp_disposition_t sctp_sf_tabort_8_4_8(struct net *net, ...@@ -3237,36 +3236,34 @@ static sctp_disposition_t sctp_sf_tabort_8_4_8(struct net *net,
struct sctp_chunk *abort; struct sctp_chunk *abort;
packet = sctp_ootb_pkt_new(net, asoc, chunk); packet = sctp_ootb_pkt_new(net, asoc, chunk);
if (!packet)
return SCTP_DISPOSITION_NOMEM;
if (packet) { /* Make an ABORT. The T bit will be set if the asoc
/* Make an ABORT. The T bit will be set if the asoc * is NULL.
* is NULL. */
*/ abort = sctp_make_abort(asoc, chunk, 0);
abort = sctp_make_abort(asoc, chunk, 0); if (!abort) {
if (!abort) { sctp_ootb_pkt_free(packet);
sctp_ootb_pkt_free(packet); return SCTP_DISPOSITION_NOMEM;
return SCTP_DISPOSITION_NOMEM; }
}
/* Reflect vtag if T-Bit is set */ /* Reflect vtag if T-Bit is set */
if (sctp_test_T_bit(abort)) if (sctp_test_T_bit(abort))
packet->vtag = ntohl(chunk->sctp_hdr->vtag); packet->vtag = ntohl(chunk->sctp_hdr->vtag);
/* Set the skb to the belonging sock for accounting. */ /* Set the skb to the belonging sock for accounting. */
abort->skb->sk = ep->base.sk; abort->skb->sk = ep->base.sk;
sctp_packet_append_chunk(packet, abort);
sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT, sctp_packet_append_chunk(packet, abort);
SCTP_PACKET(packet));
SCTP_INC_STATS(net, SCTP_MIB_OUTCTRLCHUNKS); sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
SCTP_PACKET(packet));
sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); SCTP_INC_STATS(net, SCTP_MIB_OUTCTRLCHUNKS);
return SCTP_DISPOSITION_CONSUME;
}
return SCTP_DISPOSITION_NOMEM; sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
return SCTP_DISPOSITION_CONSUME;
} }
/* /*
...@@ -3503,45 +3500,43 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(struct net *net, ...@@ -3503,45 +3500,43 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(struct net *net,
struct sctp_chunk *shut; struct sctp_chunk *shut;
packet = sctp_ootb_pkt_new(net, asoc, chunk); packet = sctp_ootb_pkt_new(net, asoc, chunk);
if (!packet)
return SCTP_DISPOSITION_NOMEM;
if (packet) { /* Make an SHUTDOWN_COMPLETE.
/* Make an SHUTDOWN_COMPLETE. * The T bit will be set if the asoc is NULL.
* The T bit will be set if the asoc is NULL. */
*/ shut = sctp_make_shutdown_complete(asoc, chunk);
shut = sctp_make_shutdown_complete(asoc, chunk); if (!shut) {
if (!shut) { sctp_ootb_pkt_free(packet);
sctp_ootb_pkt_free(packet); return SCTP_DISPOSITION_NOMEM;
return SCTP_DISPOSITION_NOMEM; }
}
/* Reflect vtag if T-Bit is set */
if (sctp_test_T_bit(shut))
packet->vtag = ntohl(chunk->sctp_hdr->vtag);
/* Set the skb to the belonging sock for accounting. */ /* Reflect vtag if T-Bit is set */
shut->skb->sk = ep->base.sk; if (sctp_test_T_bit(shut))
packet->vtag = ntohl(chunk->sctp_hdr->vtag);
sctp_packet_append_chunk(packet, shut); /* Set the skb to the belonging sock for accounting. */
shut->skb->sk = ep->base.sk;
sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT, sctp_packet_append_chunk(packet, shut);
SCTP_PACKET(packet));
SCTP_INC_STATS(net, SCTP_MIB_OUTCTRLCHUNKS); sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
SCTP_PACKET(packet));
/* If the chunk length is invalid, we don't want to process SCTP_INC_STATS(net, SCTP_MIB_OUTCTRLCHUNKS);
* the reset of the packet.
*/
if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* We need to discard the rest of the packet to prevent /* If the chunk length is invalid, we don't want to process
* potential bomming attacks from additional bundled chunks. * the reset of the packet.
* This is documented in SCTP Threats ID. */
*/ if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
}
return SCTP_DISPOSITION_NOMEM; /* We need to discard the rest of the packet to prevent
* potential bomming attacks from additional bundled chunks.
* This is documented in SCTP Threats ID.
*/
return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
} }
/* /*
...@@ -6036,8 +6031,9 @@ static struct sctp_packet *sctp_ootb_pkt_new(struct net *net, ...@@ -6036,8 +6031,9 @@ static struct sctp_packet *sctp_ootb_pkt_new(struct net *net,
sctp_transport_route(transport, (union sctp_addr *)&chunk->dest, sctp_transport_route(transport, (union sctp_addr *)&chunk->dest,
sctp_sk(net->sctp.ctl_sock)); sctp_sk(net->sctp.ctl_sock));
packet = sctp_packet_init(&transport->packet, transport, sport, dport); packet = &transport->packet;
packet = sctp_packet_config(packet, vtag, 0); sctp_packet_init(packet, transport, sport, dport);
sctp_packet_config(packet, vtag, 0);
return packet; return packet;
......
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