struct sock *netlink_getsockbyfilp(struct file *filp)
{
- struct inode *inode = filp->f_dentry->d_inode;
+ struct inode *inode = filp->f_path.dentry->d_inode;
struct sock *sock;
if (!S_ISSOCK(inode->i_mode))
return -EINVAL;
len = sizeof(int);
val = nlk->flags & NETLINK_RECV_PKTINFO ? 1 : 0;
- put_user(len, optlen);
- put_user(val, optval);
+ if (put_user(len, optlen) ||
+ put_user(val, optval))
+ return -EFAULT;
err = 0;
break;
default:
if (len > sk->sk_sndbuf - 32)
goto out;
err = -ENOBUFS;
- skb = nlmsg_new(len, GFP_KERNEL);
+ skb = alloc_skb(len, GFP_KERNEL);
if (skb==NULL)
goto out;
NETLINK_CB(skb).pid = nlk->pid;
- NETLINK_CB(skb).dst_pid = dst_pid;
NETLINK_CB(skb).dst_group = dst_group;
NETLINK_CB(skb).loginuid = audit_get_loginuid(current->audit_context);
selinux_get_task_sid(current, &(NETLINK_CB(skb).sid));
struct sk_buff *skb;
struct nlmsghdr *rep;
struct nlmsgerr *errmsg;
- int size;
+ size_t payload = sizeof(*errmsg);
- if (err == 0)
- size = nlmsg_total_size(sizeof(*errmsg));
- else
- size = nlmsg_total_size(sizeof(*errmsg) + nlmsg_len(nlh));
+ /* error messages get the original request appened */
+ if (err)
+ payload += nlmsg_len(nlh);
- skb = nlmsg_new(size, GFP_KERNEL);
+ skb = nlmsg_new(payload, GFP_KERNEL);
if (!skb) {
struct sock *sk;
skb_pull(skb, msglen);
}
+/**
+ * nlmsg_notify - send a notification netlink message
+ * @sk: netlink socket to use
+ * @skb: notification message
+ * @pid: destination netlink pid for reports or 0
+ * @group: destination multicast group or 0
+ * @report: 1 to report back, 0 to disable
+ * @flags: allocation flags
+ */
+int nlmsg_notify(struct sock *sk, struct sk_buff *skb, u32 pid,
+ unsigned int group, int report, gfp_t flags)
+{
+ int err = 0;
+
+ if (group) {
+ int exclude_pid = 0;
+
+ if (report) {
+ atomic_inc(&skb->users);
+ exclude_pid = pid;
+ }
+
+ /* errors reported via destination sk->sk_err */
+ nlmsg_multicast(sk, skb, exclude_pid, group, flags);
+ }
+
+ if (report)
+ err = nlmsg_unicast(sk, skb, pid);
+
+ return err;
+}
+
#ifdef CONFIG_PROC_FS
struct nl_seq_iter {
int link;
.owner = THIS_MODULE, /* for consistency 8) */
};
-extern void netlink_skb_parms_too_large(void);
-
static int __init netlink_proto_init(void)
{
struct sk_buff *dummy_skb;
if (err != 0)
goto out;
- if (sizeof(struct netlink_skb_parms) > sizeof(dummy_skb->cb))
- netlink_skb_parms_too_large();
+ BUILD_BUG_ON(sizeof(struct netlink_skb_parms) > sizeof(dummy_skb->cb));
nl_table = kcalloc(MAX_LINKS, sizeof(*nl_table), GFP_KERNEL);
if (!nl_table)
EXPORT_SYMBOL(netlink_set_nonroot);
EXPORT_SYMBOL(netlink_unicast);
EXPORT_SYMBOL(netlink_unregister_notifier);
-
+EXPORT_SYMBOL(nlmsg_notify);