aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/ulpevent.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/ulpevent.c')
-rw-r--r--net/sctp/ulpevent.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
index ee236784a6bb..a015283a9087 100644
--- a/net/sctp/ulpevent.c
+++ b/net/sctp/ulpevent.c
@@ -55,10 +55,13 @@ static void sctp_ulpevent_release_frag_data(struct sctp_ulpevent *event);
55 55
56 56
57/* Initialize an ULP event from an given skb. */ 57/* Initialize an ULP event from an given skb. */
58SCTP_STATIC void sctp_ulpevent_init(struct sctp_ulpevent *event, int msg_flags) 58SCTP_STATIC void sctp_ulpevent_init(struct sctp_ulpevent *event,
59 int msg_flags,
60 unsigned int len)
59{ 61{
60 memset(event, 0, sizeof(struct sctp_ulpevent)); 62 memset(event, 0, sizeof(struct sctp_ulpevent));
61 event->msg_flags = msg_flags; 63 event->msg_flags = msg_flags;
64 event->rmem_len = len;
62} 65}
63 66
64/* Create a new sctp_ulpevent. */ 67/* Create a new sctp_ulpevent. */
@@ -73,7 +76,7 @@ SCTP_STATIC struct sctp_ulpevent *sctp_ulpevent_new(int size, int msg_flags,
73 goto fail; 76 goto fail;
74 77
75 event = sctp_skb2event(skb); 78 event = sctp_skb2event(skb);
76 sctp_ulpevent_init(event, msg_flags); 79 sctp_ulpevent_init(event, msg_flags, skb->truesize);
77 80
78 return event; 81 return event;
79 82
@@ -101,17 +104,16 @@ static inline void sctp_ulpevent_set_owner(struct sctp_ulpevent *event,
101 sctp_association_hold((struct sctp_association *)asoc); 104 sctp_association_hold((struct sctp_association *)asoc);
102 skb = sctp_event2skb(event); 105 skb = sctp_event2skb(event);
103 event->asoc = (struct sctp_association *)asoc; 106 event->asoc = (struct sctp_association *)asoc;
104 atomic_add(skb->truesize, &event->asoc->rmem_alloc); 107 atomic_add(event->rmem_len, &event->asoc->rmem_alloc);
105 skb_set_owner_r(skb, asoc->base.sk); 108 sctp_skb_set_owner_r(skb, asoc->base.sk);
106} 109}
107 110
108/* A simple destructor to give up the reference to the association. */ 111/* A simple destructor to give up the reference to the association. */
109static inline void sctp_ulpevent_release_owner(struct sctp_ulpevent *event) 112static inline void sctp_ulpevent_release_owner(struct sctp_ulpevent *event)
110{ 113{
111 struct sctp_association *asoc = event->asoc; 114 struct sctp_association *asoc = event->asoc;
112 struct sk_buff *skb = sctp_event2skb(event);
113 115
114 atomic_sub(skb->truesize, &asoc->rmem_alloc); 116 atomic_sub(event->rmem_len, &asoc->rmem_alloc);
115 sctp_association_put(asoc); 117 sctp_association_put(asoc);
116} 118}
117 119
@@ -372,7 +374,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_remote_error(
372 374
373 /* Embed the event fields inside the cloned skb. */ 375 /* Embed the event fields inside the cloned skb. */
374 event = sctp_skb2event(skb); 376 event = sctp_skb2event(skb);
375 sctp_ulpevent_init(event, MSG_NOTIFICATION); 377 sctp_ulpevent_init(event, MSG_NOTIFICATION, skb->truesize);
376 378
377 sre = (struct sctp_remote_error *) 379 sre = (struct sctp_remote_error *)
378 skb_push(skb, sizeof(struct sctp_remote_error)); 380 skb_push(skb, sizeof(struct sctp_remote_error));
@@ -464,7 +466,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_send_failed(
464 466
465 /* Embed the event fields inside the cloned skb. */ 467 /* Embed the event fields inside the cloned skb. */
466 event = sctp_skb2event(skb); 468 event = sctp_skb2event(skb);
467 sctp_ulpevent_init(event, MSG_NOTIFICATION); 469 sctp_ulpevent_init(event, MSG_NOTIFICATION, skb->truesize);
468 470
469 ssf = (struct sctp_send_failed *) 471 ssf = (struct sctp_send_failed *)
470 skb_push(skb, sizeof(struct sctp_send_failed)); 472 skb_push(skb, sizeof(struct sctp_send_failed));
@@ -682,8 +684,11 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc,
682 /* Embed the event fields inside the cloned skb. */ 684 /* Embed the event fields inside the cloned skb. */
683 event = sctp_skb2event(skb); 685 event = sctp_skb2event(skb);
684 686
685 /* Initialize event with flags 0. */ 687 /* Initialize event with flags 0 and correct length
686 sctp_ulpevent_init(event, 0); 688 * Since this is a clone of the original skb, only account for
689 * the data of this chunk as other chunks will be accounted separately.
690 */
691 sctp_ulpevent_init(event, 0, skb->len + sizeof(struct sk_buff));
687 692
688 sctp_ulpevent_receive_data(event, asoc); 693 sctp_ulpevent_receive_data(event, asoc);
689 694