X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fnetlink%2Faf_netlink.c;h=4aa05030ebae63cd589fc4f8aa98bda8b24c56e7;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=69a81d08dcaf44f9aee572f4da9efd53089c50b0;hpb=a2c21200f1c81b08cb55e417b68150bba439b646;p=linux-2.6.git diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 69a81d08d..4aa05030e 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -44,6 +44,10 @@ #include #include #include +#include +#include +#include +#include #include #include @@ -242,6 +246,12 @@ static int netlink_create(struct socket *sock, int protocol) sk->sk_destruct = netlink_sock_destruct; atomic_inc(&netlink_sock_nr); + set_vx_info(&sk->sk_vx_info, current->vx_info); + sk->sk_xid = vx_current_xid(); + vx_sock_inc(sk); + set_nx_info(&sk->sk_nx_info, current->nx_info); + sk->sk_nid = nx_current_nid(); + sk->sk_protocol = protocol; return 0; } @@ -283,6 +293,12 @@ static int netlink_release(struct socket *sock) notifier_call_chain(&netlink_chain, NETLINK_URELEASE, &n); } + vx_sock_dec(sk); + clr_vx_info(&sk->sk_vx_info); + sk->sk_xid = -1; + clr_nx_info(&sk->sk_nx_info); + sk->sk_nid = -1; + sock_put(sk); return 0; } @@ -536,12 +552,31 @@ 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 the packet is charged to a socket, the modification + * of truesize below is illegal and will corrupt socket + * buffer accounting state. + */ + BUG_ON(skb->list != NULL); + + 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 +623,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(); @@ -1220,7 +1257,6 @@ MODULE_ALIAS_NETPROTO(PF_NETLINK); EXPORT_SYMBOL(netlink_ack); EXPORT_SYMBOL(netlink_broadcast); -EXPORT_SYMBOL(netlink_broadcast_deliver); EXPORT_SYMBOL(netlink_dump_start); EXPORT_SYMBOL(netlink_kernel_create); EXPORT_SYMBOL(netlink_register_notifier);