diff options
| author | Herbert Xu <herbert@gondor.apana.org.au> | 2004-09-28 00:44:58 -0700 |
|---|---|---|
| committer | David S. Miller <davem@nuts.davemloft.net> | 2004-09-28 00:44:58 -0700 |
| commit | 2eff7ad471c23d0aa074fc738c41658269abce30 (patch) | |
| tree | dc3df3d21923c716d6440553203f36d2242abeca | |
| parent | 6ad5331ee3c59d40eb8a52078823a0921c83dfa8 (diff) | |
[NETLINK]: Trim SKBs at netlink_{unicast,broadcast}() time.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | net/netlink/af_netlink.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 671071666d09..8bcf3f30f306 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -536,12 +536,25 @@ void netlink_detachskb(struct sock *sk, struct sk_buff *skb) sock_put(sk); } +static inline void netlink_trim(struct sk_buff *skb, int allocation) +{ + int delta = skb->end - skb->tail; + + if (delta * 2 < skb->truesize) + return; + if (pskb_expand_head(skb, 0, -delta, allocation)) + return; + skb->truesize -= delta; +} + int netlink_unicast(struct sock *ssk, struct sk_buff *skb, u32 pid, int nonblock) { struct sock *sk; int err; long timeo; + netlink_trim(skb, gfp_any()); + timeo = sock_sndtimeo(ssk, nonblock); retry: sk = netlink_getsockbypid(ssk, pid); @@ -588,6 +601,8 @@ int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid, int protocol = ssk->sk_protocol; int failure = 0, delivered = 0; + netlink_trim(skb, allocation); + /* While we sleep in clone, do not allow to change socket list */ netlink_lock_table(); |
