Commit 2766297c authored by Sridhar Samudrala's avatar Sridhar Samudrala

[SCTP] Reduce the size of struct sctp_ulpevent so that it fits in

       skb->cb even on 64-bit systems. 

Removed the redundant 'asoc' field in struct sctp_ulpevent and
instead use sinfo_assoc_id which is present within the other field
'sndrcvinfo'. This makes the size of struct sctp_ulpevent to be less
than the size of skb->cb[](48 bytes) even on 64-bit systems.
parent 845ddb44
......@@ -54,7 +54,6 @@
* growing this structure as it is at the maximum limit now.
*/
struct sctp_ulpevent {
struct sctp_association *asoc;
struct sctp_sndrcvinfo sndrcvinfo;
int msg_flags;
int iif;
......
......@@ -662,18 +662,20 @@ static void sctp_inet6_event_msgname(struct sctp_ulpevent *event,
if (msgname) {
union sctp_addr *addr;
struct sctp_association *asoc;
asoc = event->sndrcvinfo.sinfo_assoc_id;
sctp_inet6_msgname(msgname, addrlen);
sin6 = (struct sockaddr_in6 *)msgname;
sin6->sin6_port = htons(event->asoc->peer.port);
addr = &event->asoc->peer.primary_addr;
sin6->sin6_port = htons(asoc->peer.port);
addr = &asoc->peer.primary_addr;
/* Note: If we go to a common v6 format, this code
* will change.
*/
/* Map ipv4 address into v4-mapped-on-v6 address. */
if (sctp_sk(event->asoc->base.sk)->v4mapped &&
if (sctp_sk(asoc->base.sk)->v4mapped &&
AF_INET == addr->sa.sa_family) {
sctp_v4_map_v6((union sctp_addr *)sin6);
sin6->sin6_addr.s6_addr32[3] =
......@@ -681,7 +683,7 @@ static void sctp_inet6_event_msgname(struct sctp_ulpevent *event,
return;
}
sin6from = &event->asoc->peer.primary_addr.v6;
sin6from = &asoc->peer.primary_addr.v6;
ipv6_addr_copy(&sin6->sin6_addr, &sin6from->sin6_addr);
if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
sin6->sin6_scope_id = sin6from->sin6_scope_id;
......
......@@ -691,10 +691,13 @@ static void sctp_inet_event_msgname(struct sctp_ulpevent *event, char *msgname,
struct sockaddr_in *sin, *sinfrom;
if (msgname) {
struct sctp_association *asoc;
asoc = event->sndrcvinfo.sinfo_assoc_id;
sctp_inet_msgname(msgname, addr_len);
sin = (struct sockaddr_in *)msgname;
sinfrom = &event->asoc->peer.primary_addr.v4;
sin->sin_port = htons(event->asoc->peer.port);
sinfrom = &asoc->peer.primary_addr.v4;
sin->sin_port = htons(asoc->peer.port);
sin->sin_addr.s_addr = sinfrom->sin_addr.s_addr;
}
}
......
......@@ -1347,7 +1347,8 @@ SCTP_STATIC int sctp_recvmsg(struct kiocb *iocb, struct sock *sk,
* rwnd by that amount. If all the data in the skb is read,
* rwnd is updated when the event is freed.
*/
sctp_assoc_rwnd_increase(event->asoc, copied);
sctp_assoc_rwnd_increase(event->sndrcvinfo.sinfo_assoc_id,
copied);
goto out;
} else if ((event->msg_flags & MSG_NOTIFICATION) ||
(event->msg_flags & MSG_EOR))
......@@ -4233,7 +4234,7 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
*/
sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) {
event = sctp_skb2event(skb);
if (event->asoc == assoc) {
if (event->sndrcvinfo.sinfo_assoc_id == assoc) {
__skb_unlink(skb, skb->list);
__skb_queue_tail(&newsk->sk_receive_queue, skb);
}
......@@ -4262,7 +4263,7 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
*/
sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) {
event = sctp_skb2event(skb);
if (event->asoc == assoc) {
if (event->sndrcvinfo.sinfo_assoc_id == assoc) {
__skb_unlink(skb, skb->list);
__skb_queue_tail(queue, skb);
}
......
......@@ -831,14 +831,14 @@ static inline void sctp_ulpevent_set_owner(struct sctp_ulpevent *event,
sctp_association_hold((struct sctp_association *)asoc);
skb = sctp_event2skb(event);
skb->sk = asoc->base.sk;
event->asoc = (struct sctp_association *)asoc;
event->sndrcvinfo.sinfo_assoc_id = sctp_assoc2id(asoc);
skb->destructor = sctp_stub_rfree;
}
/* A simple destructor to give up the reference to the association. */
static inline void sctp_ulpevent_release_owner(struct sctp_ulpevent *event)
{
sctp_association_put(event->asoc);
sctp_association_put(event->sndrcvinfo.sinfo_assoc_id);
}
/* Do accounting for bytes received and hold a reference to the association
......@@ -880,7 +880,8 @@ static void sctp_ulpevent_release_data(struct sctp_ulpevent *event)
*/
skb = sctp_event2skb(event);
sctp_assoc_rwnd_increase(event->asoc, skb_headlen(skb));
sctp_assoc_rwnd_increase(event->sndrcvinfo.sinfo_assoc_id,
skb_headlen(skb));
/* Don't forget the fragments. */
for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) {
......
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