Esempio n. 1
0
int reply_ca(struct sk_buff *skb_2, struct genl_info *info)
{
        struct sk_buff *skb;
	void *msg_head;
	int ret;
	
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)
	printk("reply_ca %d\n", info->snd_pid);
#else
	printk("reply_ca %d\n", info->snd_portid);
#endif

        if (!info)
                goto out;
  
        skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!skb)
		goto out;

       	msg_head = genlmsg_put(skb, 0, info->snd_seq, &ca_family, 0, CMD_ASK_CA_SIZE);
	if (!msg_head) {
		goto out;
	}

	ret = nla_put_u32(skb, ATTR_CA_SIZE, devices_counter);
	if (ret)
		goto out;
	
	genlmsg_end(skb, msg_head);

#if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)
	ret = genlmsg_unicast(&init_net, skb, info->snd_pid );
#else
	ret = genlmsg_unicast(&init_net, skb, info->snd_portid );
#endif
	if (ret)
		goto out;

#if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)
	processPid = info->snd_pid;
#else
	processPid = info->snd_portid;
#endif
	return 0;

 out:
        printk("dvbsoftwareca: reply_ca error\n");
	return 0;
}
static int l2tp_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info)
{
	struct sk_buff *msg;
	void *hdr;
	int ret = -ENOBUFS;

	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!msg) {
		ret = -ENOMEM;
		goto out;
	}

	hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq,
			  &l2tp_nl_family, 0, L2TP_CMD_NOOP);
	if (IS_ERR(hdr)) {
		ret = PTR_ERR(hdr);
		goto err_out;
	}

	genlmsg_end(msg, hdr);

	return genlmsg_unicast(genl_info_net(info), msg, info->snd_pid);

err_out:
	nlmsg_free(msg);

out:
	return ret;
}
static int handle_cmd(struct sk_buff *skb, struct genl_info *info)
{
	struct sk_buff *rep_buf;
	struct nlmsghdr *rep_nlh;
	struct nlmsghdr *req_nlh = info->nlhdr;
	struct tipc_genlmsghdr *req_userhdr = info->userhdr;
	int hdr_space = nlmsg_total_size(GENL_HDRLEN + TIPC_GENL_HDRLEN);
	u16 cmd;

	if ((req_userhdr->cmd & 0xC000) && (!capable(CAP_NET_ADMIN)))
		cmd = TIPC_CMD_NOT_NET_ADMIN;
	else
		cmd = req_userhdr->cmd;

	rep_buf = tipc_cfg_do_cmd(req_userhdr->dest, cmd,
			nlmsg_data(req_nlh) + GENL_HDRLEN + TIPC_GENL_HDRLEN,
			nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN),
			hdr_space);

	if (rep_buf) {
		skb_push(rep_buf, hdr_space);
		rep_nlh = nlmsg_hdr(rep_buf);
		memcpy(rep_nlh, req_nlh, hdr_space);
		rep_nlh->nlmsg_len = rep_buf->len;
		genlmsg_unicast(&init_net, rep_buf, NETLINK_CB(skb).portid);
	}

	return 0;
}
Esempio n. 4
0
int netlink_send_cw(unsigned char ca_num, ca_descr_t *ca_descr) {
        struct sk_buff *skb;
	void *msg_head;
	int ret;

        skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!skb)
		goto out;

       	msg_head = genlmsg_put(skb, 0, 0, &ca_family, 0, CMD_SET_CW);
	if (!msg_head) {
		goto out;
	}

	ret = nla_put_u16(skb, ATTR_CA_NUM, ca_num);
	if (ret)
		goto out;
	ret = nla_put(skb, ATTR_CA_DESCR, sizeof(ca_descr_t), ca_descr);
	if (ret)
		goto out;

	genlmsg_end(skb, msg_head);

	ret = genlmsg_unicast(&init_net, skb, processPid );
	if (ret)
		goto out;

	return 0;

 out:
        printk("dvbsoftwareca: send_cw error\n");
	return 0;
}
Esempio n. 5
0
int genl_exec(genl_exec_func_t func, void *data)
{
	int ret;

	mutex_lock(&genl_exec_lock);

	init_completion(&done);
	skb_get(genlmsg_skb);
	genlmsg_put(genlmsg_skb, 0, 0, &genl_exec_family,
		    NLM_F_REQUEST, GENL_EXEC_RUN);

	genl_exec_function = func;
	genl_exec_data = data;

	/* There is no need to send msg to current namespace. */
	ret = genlmsg_unicast(&init_net, genlmsg_skb, 0);

	if (!ret) {
		wait_for_completion(&done);
		ret = genl_exec_function_ret;
	} else {
		pr_err("genl_exec send error %d\n", ret);
	}

	/* Wait for genetlink to kfree skb. */
	while (skb_shared(genlmsg_skb))
		cpu_relax();

	genlmsg_skb->data = genlmsg_skb->head;
	skb_reset_tail_pointer(genlmsg_skb);

	mutex_unlock(&genl_exec_lock);

	return ret;
}
char
stp_dbg_nl_send(
    char *  aucMsg,
    unsigned char      cmd
)
{
    struct sk_buff *skb = NULL;
    void *msg_head = NULL;
    int rc = -1;
    int i;

    if(num_bind_process == 0)
    {
        /* no listening process */
        STP_DBG_ERR_FUNC("%s(): the process is not invoked\n", __func__);
        return 0;
    }

    for(i = 0 ; i < num_bind_process ; i++)
    {
        skb = genlmsg_new(2048, GFP_KERNEL);

        if(skb)
        {
            msg_head = genlmsg_put(skb, 0, stp_dbg_seqnum++, &stp_dbg_gnl_family, 0, cmd);
            if(msg_head == NULL)
            {
                nlmsg_free(skb);
                STP_DBG_ERR_FUNC("%s(): genlmsg_put fail...\n", __func__);
                return -1;
            }

            rc = nla_put_string(skb, STP_DBG_ATTR_MSG, aucMsg);
            if(rc != 0)
            {
                nlmsg_free(skb);
                STP_DBG_ERR_FUNC("%s(): nla_put_string fail...\n", __func__);
                return -1;
            }

            /* finalize the message */
            genlmsg_end(skb, msg_head);

            /* sending message */
            rc = genlmsg_unicast(&init_net, skb, bind_pid[i]);
            if(rc != 0)
            {
                STP_DBG_ERR_FUNC("%s(): genlmsg_unicast fail...\n", __func__);
                return -1;
            }
        }
        else
        {
            STP_DBG_ERR_FUNC("%s(): genlmsg_new fail...\n", __func__);
            return -1;
        }
    }

    return 0;
}
Esempio n. 7
0
int kg2_genl_system_is_resumed(void)
{
	int ret = 0;
	void * hdr;
	struct sk_buff * msg;

	msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);

	if (msg == NULL)
	{
		return -ENOMEM;
	}

	// Create Generic Netlink message header
	hdr = genlmsg_put(msg, g_daemon_pid, 0, &kg2_genl_family, NLM_F_REQUEST, KG2_GENL_EVT_SYSTEM_IS_RESUMED);

	if (hdr == NULL)
	{
		ret = -EMSGSIZE;
		goto err;
	}

	// Finalize the message
	genlmsg_end(msg, hdr);

	// Send the message
	ret = genlmsg_unicast(&init_net, msg, g_daemon_pid);

	return ret;
 err:
	nlmsg_free(msg);

	return ret;
}
static int l2tp_nl_cmd_session_get(struct sk_buff *skb, struct genl_info *info)
{
	struct l2tp_session *session;
	struct sk_buff *msg;
	int ret;

	session = l2tp_nl_session_find(info);
	if (session == NULL) {
		ret = -ENODEV;
		goto out;
	}

	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!msg) {
		ret = -ENOMEM;
		goto out;
	}

	ret = l2tp_nl_session_send(msg, info->snd_pid, info->snd_seq,
				   0, session);
	if (ret < 0)
		goto err_out;

	return genlmsg_unicast(genl_info_net(info), msg, info->snd_pid);

err_out:
	nlmsg_free(msg);

out:
	return ret;
}
Esempio n. 9
0
static int send_data(struct sk_buff *skb)
{
	struct genlmsghdr *genlhdr = nlmsg_data((struct nlmsghdr *)skb->data);
	void *data = genlmsg_data(genlhdr);

	genlmsg_end(skb, data);

	return genlmsg_unicast(&init_net, skb, listener_nlportid);
}
/*
 * @pid:用户进行id
   @data:发送数据缓冲区
   @data_len:缓冲区长度
  */
static int genlnet_msg_send(int pid, char *data, uint32_t data_len)
{
    char buf[MAX_STR_LEN];
    void            *msg;
    int             ret;
    size_t          size;
    struct sk_buff  *skb;
    struct genlmsghdr   *genlhdr;
    void                *reply;

    memcpy(buf, data, data_len);
    size = nla_total_size(data_len) + nla_total_size(0);
    skb = genlmsg_new(size, GFP_KERNEL);
    if (skb == NULL) {
        printk("%s %d\n", __func__, __LINE__);
        return -1;
    }

    msg = genlmsg_put(skb, 0, 0, &genlnet_family, 0, MSG_CMD_NOTIFY);
    if (msg == NULL) {
        printk("%s %d\n", __func__, __LINE__);
        goto err;
    }

    ret = nla_put(skb, MSG_CMD, data_len, data);
    if (ret < 0) {
        printk("%s %d, ret = %d\n", __func__, __LINE__, ret);
        goto err;
    }

    genlhdr = nlmsg_data(nlmsg_hdr(skb));
    reply = genlmsg_data(genlhdr);

    ret = genlmsg_end(skb, reply);
    if (ret < 0) {
        printk("%s %d, ret = %d\n", __func__, __LINE__, ret);
        goto err;
    }

    ret = genlmsg_unicast(&init_net, skb, pid);
    if (ret < 0) {
        printk("%s %d, ret = %d\n", __func__, __LINE__, ret);
        goto err;
    }

    return 0;

err:
    //nlmsg_free(skb);
    return -1;
}
Esempio n. 11
0
static int send_data(struct sk_buff *skb)
{
	struct genlmsghdr *genlhdr = nlmsg_data((struct nlmsghdr *)skb->data);
	void *data = genlmsg_data(genlhdr);
	int rv;

	rv = genlmsg_end(skb, data);
	if (rv < 0) {
		nlmsg_free(skb);
		return rv;
	}

	return genlmsg_unicast(&init_net, skb, listener_nlpid);
}
Esempio n. 12
0
/*----------------------------------------------------------------------------*/
static BOOLEAN
glResetSendMessage(
    char *  aucMsg,
    u8      cmd
    )
{
    struct sk_buff *skb = NULL;
    void *msg_head = NULL;
    int rc = -1;
    int i;

    if(num_bind_process == 0) {
        /* no listening process */
        return FALSE;
    }

    for(i = 0 ; i < num_bind_process ; i++) {
        skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);

        if(skb) {
            msg_head = genlmsg_put(skb, 0, mtk_wifi_seqnum++, &mtk_wifi_gnl_family, 0, cmd);

            if(msg_head == NULL) {
                nlmsg_free(skb);
                return FALSE;
            }

            rc = nla_put_string(skb, MTK_WIFI_ATTR_MSG, aucMsg);
            if(rc != 0) {
                nlmsg_free(skb);
                return FALSE;
            }
        
            /* finalize the message */
            genlmsg_end(skb, msg_head);
        
            /* sending message */
            rc = genlmsg_unicast(&init_net, skb, bind_pid[i]);
            if(rc != 0) {
                return FALSE;
            }
        }
        else {
            return FALSE;
        }
    }

    return TRUE;
}
Esempio n. 13
0
static int tipc_nl_compat_recv(struct sk_buff *skb, struct genl_info *info)
{
	int err;
	int len;
	struct tipc_nl_compat_msg msg;
	struct nlmsghdr *req_nlh;
	struct nlmsghdr *rep_nlh;
	struct tipc_genlmsghdr *req_userhdr = info->userhdr;
	struct net *net = genl_info_net(info);

	memset(&msg, 0, sizeof(msg));

	req_nlh = (struct nlmsghdr *)skb->data;
	msg.req = nlmsg_data(req_nlh) + GENL_HDRLEN + TIPC_GENL_HDRLEN;
	msg.cmd = req_userhdr->cmd;
	msg.dst_sk = info->dst_sk;

	if ((msg.cmd & 0xC000) && (!netlink_net_capable(skb, CAP_NET_ADMIN))) {
		msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_NET_ADMIN);
		err = -EACCES;
		goto send;
	}

	len = nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN);
	if (TLV_GET_LEN(msg.req) && !TLV_OK(msg.req, len)) {
		msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_SUPPORTED);
		err = -EOPNOTSUPP;
		goto send;
	}

	err = tipc_nl_compat_handle(&msg);
	if (err == -EOPNOTSUPP)
		msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_SUPPORTED);
	else if (err == -EINVAL)
		msg.rep = tipc_get_err_tlv(TIPC_CFG_TLV_ERROR);
send:
	if (!msg.rep)
		return err;

	len = nlmsg_total_size(GENL_HDRLEN + TIPC_GENL_HDRLEN);
	skb_push(msg.rep, len);
	rep_nlh = nlmsg_hdr(msg.rep);
	memcpy(rep_nlh, info->nlhdr, len);
	rep_nlh->nlmsg_len = msg.rep->len;
	genlmsg_unicast(net, msg.rep, NETLINK_CB(skb).portid);

	return err;
}
Esempio n. 14
0
static int l2tp_nl_cmd_tunnel_get(struct sk_buff *skb, struct genl_info *info)
{
	struct l2tp_tunnel *tunnel;
	struct sk_buff *msg;
	u32 tunnel_id;
	int ret = -ENOBUFS;
	struct net *net = genl_info_net(info);

	if (!info->attrs[L2TP_ATTR_CONN_ID]) {
		ret = -EINVAL;
		goto err;
	}

	tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);

	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (!msg) {
		ret = -ENOMEM;
		goto err;
	}

	tunnel = l2tp_tunnel_get(net, tunnel_id);
	if (!tunnel) {
		ret = -ENODEV;
		goto err_nlmsg;
	}

	ret = l2tp_nl_tunnel_send(msg, info->snd_portid, info->snd_seq,
				  NLM_F_ACK, tunnel, L2TP_CMD_TUNNEL_GET);
	if (ret < 0)
		goto err_nlmsg_tunnel;

	l2tp_tunnel_dec_refcount(tunnel);

	return genlmsg_unicast(net, msg, info->snd_portid);

err_nlmsg_tunnel:
	l2tp_tunnel_dec_refcount(tunnel);
err_nlmsg:
	nlmsg_free(msg);
err:
	return ret;
}
Esempio n. 15
0
static int l2tp_nl_cmd_tunnel_get(struct sk_buff *skb, struct genl_info *info)
{
	struct l2tp_tunnel *tunnel;
	struct sk_buff *msg;
	u32 tunnel_id;
	int ret = -ENOBUFS;
	struct net *net = genl_info_net(info);

	if (!info->attrs[L2TP_ATTR_CONN_ID]) {
		ret = -EINVAL;
		goto out;
	}

	tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);

	tunnel = l2tp_tunnel_find(net, tunnel_id);
	if (tunnel == NULL) {
		ret = -ENODEV;
		goto out;
	}

	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!msg) {
		ret = -ENOMEM;
		goto out;
	}

	ret = l2tp_nl_tunnel_send(msg, info->snd_pid, info->snd_seq,
				  NLM_F_ACK, tunnel);
	if (ret < 0)
		goto err_out;

	return genlmsg_unicast(net, msg, info->snd_pid);

err_out:
	nlmsg_free(msg);

out:
	return ret;
}
Esempio n. 16
0
/**
 * netlbl_unlabel_list - Handle a LIST message
 * @skb: the NETLINK buffer
 * @info: the Generic NETLINK info block
 *
 * Description:
 * Process a user generated LIST message and respond with the current status.
 * Returns zero on success, negative values on failure.
 *
 */
static int netlbl_unlabel_list(struct sk_buff *skb, struct genl_info *info)
{
	int ret_val = -EINVAL;
	struct sk_buff *ans_skb;
	void *data;

	ans_skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (ans_skb == NULL)
		goto list_failure;
	data = netlbl_netlink_hdr_put(ans_skb,
				      info->snd_pid,
				      info->snd_seq,
				      netlbl_unlabel_gnl_family.id,
				      0,
				      NLBL_UNLABEL_C_LIST);
	if (data == NULL) {
		ret_val = -ENOMEM;
		goto list_failure;
	}

	rcu_read_lock();
	ret_val = nla_put_u8(ans_skb,
			     NLBL_UNLABEL_A_ACPTFLG,
			     netlabel_unlabel_acceptflg);
	rcu_read_unlock();
	if (ret_val != 0)
		goto list_failure;

	genlmsg_end(ans_skb, data);

	ret_val = genlmsg_unicast(ans_skb, info->snd_pid);
	if (ret_val != 0)
		goto list_failure;
	return 0;

list_failure:
	kfree(ans_skb);
	return ret_val;
}
Esempio n. 17
0
static int l2tp_nl_cmd_session_get(struct sk_buff *skb, struct genl_info *info)
{
	struct l2tp_session *session;
	struct sk_buff *msg;
	int ret;

	session = l2tp_nl_session_get(info);
	if (session == NULL) {
		ret = -ENODEV;
		goto err;
	}

	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (!msg) {
		ret = -ENOMEM;
		goto err_ref;
	}

	ret = l2tp_nl_session_send(msg, info->snd_portid, info->snd_seq,
				   0, session, L2TP_CMD_SESSION_GET);
	if (ret < 0)
		goto err_ref_msg;

	ret = genlmsg_unicast(genl_info_net(info), msg, info->snd_portid);

	l2tp_session_dec_refcount(session);

	return ret;

err_ref_msg:
	nlmsg_free(msg);
err_ref:
	l2tp_session_dec_refcount(session);
err:
	return ret;
}
Esempio n. 18
0
/* HSR_C_GET_NODE_STATUS lets userspace query the internal HSR node table
 * about the status of a specific node in the network, defined by its MAC
 * address.
 *
 * Input: hsr ifindex, node mac address
 * Output: hsr ifindex, node mac address (copied from request),
 *	   age of latest frame from node over slave 1, slave 2 [ms]
 */
static int hsr_get_node_status(struct sk_buff *skb_in, struct genl_info *info)
{
    /* For receiving */
    struct nlattr *na;
    struct net_device *hsr_dev;

    /* For sending */
    struct sk_buff *skb_out;
    void *msg_head;
    struct hsr_priv *hsr;
    struct hsr_port *port;
    unsigned char hsr_node_addr_b[ETH_ALEN];
    int hsr_node_if1_age;
    u16 hsr_node_if1_seq;
    int hsr_node_if2_age;
    u16 hsr_node_if2_seq;
    int addr_b_ifindex;
    int res;

    if (!info)
        goto invalid;

    na = info->attrs[HSR_A_IFINDEX];
    if (!na)
        goto invalid;
    na = info->attrs[HSR_A_NODE_ADDR];
    if (!na)
        goto invalid;

    hsr_dev = __dev_get_by_index(genl_info_net(info),
                                 nla_get_u32(info->attrs[HSR_A_IFINDEX]));
    if (!hsr_dev)
        goto invalid;
    if (!is_hsr_master(hsr_dev))
        goto invalid;


    /* Send reply */

    skb_out = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
    if (!skb_out) {
        res = -ENOMEM;
        goto fail;
    }

    msg_head = genlmsg_put(skb_out, NETLINK_CB(skb_in).portid,
                           info->snd_seq, &hsr_genl_family, 0,
                           HSR_C_SET_NODE_STATUS);
    if (!msg_head) {
        res = -ENOMEM;
        goto nla_put_failure;
    }

    res = nla_put_u32(skb_out, HSR_A_IFINDEX, hsr_dev->ifindex);
    if (res < 0)
        goto nla_put_failure;

    hsr = netdev_priv(hsr_dev);
    res = hsr_get_node_data(hsr,
                            (unsigned char *) nla_data(info->attrs[HSR_A_NODE_ADDR]),
                            hsr_node_addr_b,
                            &addr_b_ifindex,
                            &hsr_node_if1_age,
                            &hsr_node_if1_seq,
                            &hsr_node_if2_age,
                            &hsr_node_if2_seq);
    if (res < 0)
        goto nla_put_failure;

    res = nla_put(skb_out, HSR_A_NODE_ADDR, ETH_ALEN,
                  nla_data(info->attrs[HSR_A_NODE_ADDR]));
    if (res < 0)
        goto nla_put_failure;

    if (addr_b_ifindex > -1) {
        res = nla_put(skb_out, HSR_A_NODE_ADDR_B, ETH_ALEN,
                      hsr_node_addr_b);
        if (res < 0)
            goto nla_put_failure;

        res = nla_put_u32(skb_out, HSR_A_ADDR_B_IFINDEX, addr_b_ifindex);
        if (res < 0)
            goto nla_put_failure;
    }

    res = nla_put_u32(skb_out, HSR_A_IF1_AGE, hsr_node_if1_age);
    if (res < 0)
        goto nla_put_failure;
    res = nla_put_u16(skb_out, HSR_A_IF1_SEQ, hsr_node_if1_seq);
    if (res < 0)
        goto nla_put_failure;
    rcu_read_lock();
    port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_A);
    if (port)
        res = nla_put_u32(skb_out, HSR_A_IF1_IFINDEX,
                          port->dev->ifindex);
    rcu_read_unlock();
    if (res < 0)
        goto nla_put_failure;

    res = nla_put_u32(skb_out, HSR_A_IF2_AGE, hsr_node_if2_age);
    if (res < 0)
        goto nla_put_failure;
    res = nla_put_u16(skb_out, HSR_A_IF2_SEQ, hsr_node_if2_seq);
    if (res < 0)
        goto nla_put_failure;
    rcu_read_lock();
    port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B);
    if (port)
        res = nla_put_u32(skb_out, HSR_A_IF2_IFINDEX,
                          port->dev->ifindex);
    rcu_read_unlock();
    if (res < 0)
        goto nla_put_failure;

    genlmsg_end(skb_out, msg_head);
    genlmsg_unicast(genl_info_net(info), skb_out, info->snd_portid);

    return 0;

invalid:
    netlink_ack(skb_in, nlmsg_hdr(skb_in), -EINVAL);
    return 0;

nla_put_failure:
    kfree_skb(skb_out);
    /* Fall through */

fail:
    return res;
}
Esempio n. 19
0
int kg2_genl_set_output_timing(AVC_CMD_TIMING_PARAM * timing)
{
	int ret = 0;
	void * hdr;
	struct sk_buff * msg;

	msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);

	if (msg == NULL)
	{
		return -ENOMEM;
	}

	// Create Generic Netlink message header
	hdr = genlmsg_put(msg, g_daemon_pid, 0, &kg2_genl_family, NLM_F_REQUEST, KG2_GENL_CMD_SET_OUTPUT_TIMING);

	if (hdr == NULL)
	{
		ret = -EMSGSIZE;
		goto err;
	}

	// Add a KG2_GENL_ATTR_MSG attribute
	ret = nla_put_u16(msg, KG2_GENL_ATTR_HTOTAL, timing->HTotal);

	if (ret)
	{
		ret = -ENOBUFS;
		goto err;
	}

	ret = nla_put_u16(msg, KG2_GENL_ATTR_HACTIVE, timing->HActive);

	if (ret)
	{
		ret = -ENOBUFS;
		goto err;
	}

	ret = nla_put_u16(msg, KG2_GENL_ATTR_HFRONTPORCH, timing->HFrontPorch);

	if (ret)
	{
		ret = -ENOBUFS;
		goto err;
	}

	ret = nla_put_u8(msg, KG2_GENL_ATTR_HSYNCWIDTH, timing->HSyncWidth);

	if (ret)
	{
		ret = -ENOBUFS;
		goto err;
	}

	ret = nla_put_u32(msg, KG2_GENL_ATTR_HPOLARITY, timing->HPolarity);

	if (ret)
	{
		ret = -ENOBUFS;
		goto err;
	}

	ret = nla_put_u16(msg, KG2_GENL_ATTR_VTOTAL, timing->VTotal);

	if (ret)
	{
		ret = -ENOBUFS;
		goto err;
	}

	ret = nla_put_u16(msg, KG2_GENL_ATTR_VACTIVE, timing->VActive);

	if (ret)
	{
		ret = -ENOBUFS;
		goto err;
	}

	ret = nla_put_u16(msg, KG2_GENL_ATTR_VFRONTPORCH, timing->VFrontPorch);

	if (ret)
	{
		ret = -ENOBUFS;
		goto err;
	}

	ret = nla_put_u8(msg, KG2_GENL_ATTR_VSYNCWIDTH, timing->VSyncWidth);

	if (ret)
	{
		ret = -ENOBUFS;
		goto err;
	}

	ret = nla_put_u32(msg, KG2_GENL_ATTR_VPOLARITY, timing->VPolarity);

	if (ret)
	{
		ret = -ENOBUFS;
		goto err;
	}

	ret = nla_put_u32(msg, KG2_GENL_ATTR_ASPRATIO, timing->AspRatio);

	if (ret)
	{
		ret = -ENOBUFS;
		goto err;
	}

	ret = nla_put_u8(msg, KG2_GENL_ATTR_ISPROGRESSIVE, timing->IsProgressive);

	if (ret)
	{
		ret = -ENOBUFS;
		goto err;
	}

	ret = nla_put_u16(msg, KG2_GENL_ATTR_REFRATE, timing->RefRate);

	if (ret)
	{
		ret = -ENOBUFS;
		goto err;
	}

	// Finalize the message
	genlmsg_end(msg, hdr);

	// Send the message
	ret = genlmsg_unicast(&init_net, msg, g_daemon_pid);

	return ret;
 err:
	nlmsg_free(msg);

	return ret;
}
Esempio n. 20
0
int demo_cmd(struct sk_buff *skb_2, struct genl_info *info)
{
	struct nlattr *na;
	struct sk_buff *skb;
	int rc = 0;
	void *msg_head;
	char *attr_str;
    u16 attr_u16;
	struct attr_custom cp;

	printk("got demo_cmd\n");

	if (info == NULL) {
		goto out;
	}

	na = info->attrs[DEMO_ATTR1_STRING];
	if (na) {
		attr_str = (char *)nla_data(na);
		if (attr_str == NULL) {
			printk("error while receiving data\n");
		}
		else {
			printk("attr1: %s\n", attr_str);
		}
	}
	else {
		printk("no attr1\n");
	}

	na = info->attrs[DEMO_ATTR2_UINT16];
	if (na) {
		attr_u16 = nla_get_u16(na);
		printk("attr2: %x\n", attr_u16);
	}
	else {
		printk("no attr2\n");
	}

	/* send message back */
	/* allocate some memory, since the size is not yet known use NLMSG_GOODSIZE */
	skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (skb == NULL) {
		goto out;
	}

	/* create the message */
	msg_head =
	    genlmsg_put(skb, 0, info->snd_seq + 1, &demo_gnl_family, 0,
			DEMO_CMD);

	if (msg_head == NULL) {
		rc = -ENOMEM;
		goto out;
	}

	rc |= nla_put_string(skb, DEMO_ATTR1_STRING,"world");
	rc |= nla_put_u16(skb, DEMO_ATTR2_UINT16, 0x1f);
	cp.a = 1;
	cp.b = 2;
	cp.c = 3.0;
	cp.d = 4.0;
	rc |= nla_put(skb, DEMO_ATTR3_CUSTOM, sizeof(struct attr_custom), &cp);

	if (rc != 0) {
		goto out;
	}

	/* finalize the message */
	genlmsg_end(skb, msg_head);

	/* send the message back */
	rc = genlmsg_unicast(&init_net, skb, info->snd_portid);

	if (rc != 0) {
		goto out;
	}

	return 0;

 out:
	printk("an error occured\n");

	return -1;
}
Esempio n. 21
0
static int queue_userspace_packet(int dp_ifindex, struct sk_buff *skb,
				  const struct dp_upcall_info *upcall_info)
{
	struct ovs_header *upcall;
	struct sk_buff *nskb = NULL;
	struct sk_buff *user_skb; /* to be queued to userspace */
	struct nlattr *nla;
	unsigned int len;
	int err;

	if (vlan_tx_tag_present(skb)) {
		nskb = skb_clone(skb, GFP_ATOMIC);
		if (!nskb)
			return -ENOMEM;

		nskb = __vlan_put_tag(nskb, vlan_tx_tag_get(nskb));
		if (!nskb)
			return -ENOMEM;

		nskb->vlan_tci = 0;
		skb = nskb;
	}

	if (nla_attr_size(skb->len) > USHRT_MAX) {
		err = -EFBIG;
		goto out;
	}

	len = sizeof(struct ovs_header);
	len += nla_total_size(skb->len);
	len += nla_total_size(FLOW_BUFSIZE);
	if (upcall_info->cmd == OVS_PACKET_CMD_ACTION)
		len += nla_total_size(8);

	user_skb = genlmsg_new(len, GFP_ATOMIC);
	if (!user_skb) {
		err = -ENOMEM;
		goto out;
	}

	upcall = genlmsg_put(user_skb, 0, 0, &dp_packet_genl_family,
			     0, upcall_info->cmd);
	upcall->dp_ifindex = dp_ifindex;

	nla = nla_nest_start(user_skb, OVS_PACKET_ATTR_KEY);
	ovs_flow_to_nlattrs(upcall_info->key, user_skb);
	nla_nest_end(user_skb, nla);

	if (upcall_info->userdata)
		nla_put_u64(user_skb, OVS_PACKET_ATTR_USERDATA,
			    nla_get_u64(upcall_info->userdata));

	nla = __nla_reserve(user_skb, OVS_PACKET_ATTR_PACKET, skb->len);

	skb_copy_and_csum_dev(skb, nla_data(nla));

	err = genlmsg_unicast(&init_net, user_skb, upcall_info->pid);

out:
	kfree_skb(nskb);
	return err;
}
Esempio n. 22
0
s32
wl_genl_send_msg(
	struct net_device *ndev,
	u32 event_type,
	u8 *buf,
	u16 len,
	u8 *subhdr,
	u16 subhdr_len)
{
	int ret = 0;
	struct sk_buff *skb;
	void *msg;
	u32 attr_type = 0;
	bcm_event_hdr_t *hdr = NULL;
	int mcast = 1; /* By default sent as mutlicast type */
	int pid = 0;
	u8 *ptr = NULL, *p = NULL;
	u32 tot_len = sizeof(bcm_event_hdr_t) + subhdr_len + len;
	u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;


	WL_DBG(("Enter \n"));

	/* Decide between STRING event and Data event */
	if (event_type == 0)
		attr_type = BCM_GENL_ATTR_STRING;
	else
		attr_type = BCM_GENL_ATTR_MSG;

	skb = genlmsg_new(NLMSG_GOODSIZE, kflags);
	if (skb == NULL) {
		ret = -ENOMEM;
		goto out;
	}

	msg = genlmsg_put(skb, 0, 0, &wl_genl_family, 0, BCM_GENL_CMD_MSG);
	if (msg == NULL) {
		ret = -ENOMEM;
		goto out;
	}


	if (attr_type == BCM_GENL_ATTR_STRING) {
		/* Add a BCM_GENL_MSG attribute. Since it is specified as a string.
		 * make sure it is null terminated
		 */
		if (subhdr || subhdr_len) {
			WL_ERR(("No sub hdr support for the ATTR STRING type \n"));
			ret =  -EINVAL;
			goto out;
		}

		ret = nla_put_string(skb, BCM_GENL_ATTR_STRING, buf);
		if (ret != 0) {
			WL_ERR(("nla_put_string failed\n"));
			goto out;
		}
	} else {
		/* ATTR_MSG */

		/* Create a single buffer for all */
		p = ptr = kzalloc(tot_len, kflags);
		if (!ptr) {
			ret = -ENOMEM;
			WL_ERR(("ENOMEM!!\n"));
			goto out;
		}

		/* Include the bcm event header */
		hdr = (bcm_event_hdr_t *)ptr;
		hdr->event_type = wl_event_to_bcm_event(event_type);
		hdr->len = len + subhdr_len;
		ptr += sizeof(bcm_event_hdr_t);

		/* Copy subhdr (if any) */
		if (subhdr && subhdr_len) {
			memcpy(ptr, subhdr, subhdr_len);
			ptr += subhdr_len;
		}

		/* Copy the data */
		if (buf && len) {
			memcpy(ptr, buf, len);
		}

		ret = nla_put(skb, BCM_GENL_ATTR_MSG, tot_len, p);
		if (ret != 0) {
			WL_ERR(("nla_put_string failed\n"));
			goto out;
		}
	}

	if (mcast) {
		int err = 0;
		/* finalize the message */
		genlmsg_end(skb, msg);
		/* NETLINK_CB(skb).dst_group = 1; */
		if ((err = genlmsg_multicast(skb, 0, wl_genl_mcast.id, GFP_ATOMIC)) < 0)
			WL_ERR(("genlmsg_multicast for attr(%d) failed. Error:%d \n",
				attr_type, err));
		else
			WL_DBG(("Multicast msg sent successfully. attr_type:%d len:%d \n",
				attr_type, tot_len));
	} else {
		NETLINK_CB(skb).dst_group = 0; /* Not in multicast group */

		/* finalize the message */
		genlmsg_end(skb, msg);

		/* send the message back */
		if (genlmsg_unicast(&init_net, skb, pid) < 0)
			WL_ERR(("genlmsg_unicast failed\n"));
	}

out:
	if (p)
		kfree(p);
	if (ret)
		nlmsg_free(skb);

	return ret;
}
Esempio n. 23
0
/* Get a list of MacAddressA of all nodes known to this node (including self).
 */
static int hsr_get_node_list(struct sk_buff *skb_in, struct genl_info *info)
{
    /* For receiving */
    struct nlattr *na;
    struct net_device *hsr_dev;

    /* For sending */
    struct sk_buff *skb_out;
    void *msg_head;
    struct hsr_priv *hsr;
    void *pos;
    unsigned char addr[ETH_ALEN];
    int res;

    if (!info)
        goto invalid;

    na = info->attrs[HSR_A_IFINDEX];
    if (!na)
        goto invalid;

    hsr_dev = __dev_get_by_index(genl_info_net(info),
                                 nla_get_u32(info->attrs[HSR_A_IFINDEX]));
    if (!hsr_dev)
        goto invalid;
    if (!is_hsr_master(hsr_dev))
        goto invalid;


    /* Send reply */

    skb_out = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
    if (!skb_out) {
        res = -ENOMEM;
        goto fail;
    }

    msg_head = genlmsg_put(skb_out, NETLINK_CB(skb_in).portid,
                           info->snd_seq, &hsr_genl_family, 0,
                           HSR_C_SET_NODE_LIST);
    if (!msg_head) {
        res = -ENOMEM;
        goto nla_put_failure;
    }

    res = nla_put_u32(skb_out, HSR_A_IFINDEX, hsr_dev->ifindex);
    if (res < 0)
        goto nla_put_failure;

    hsr = netdev_priv(hsr_dev);

    rcu_read_lock();
    pos = hsr_get_next_node(hsr, NULL, addr);
    while (pos) {
        res = nla_put(skb_out, HSR_A_NODE_ADDR, ETH_ALEN, addr);
        if (res < 0) {
            rcu_read_unlock();
            goto nla_put_failure;
        }
        pos = hsr_get_next_node(hsr, pos, addr);
    }
    rcu_read_unlock();

    genlmsg_end(skb_out, msg_head);
    genlmsg_unicast(genl_info_net(info), skb_out, info->snd_portid);

    return 0;

invalid:
    netlink_ack(skb_in, nlmsg_hdr(skb_in), -EINVAL);
    return 0;

nla_put_failure:
    kfree_skb(skb_out);
    /* Fall through */

fail:
    return res;
}
Esempio n. 24
0
/* an echo command, receives a message, prints it and sends another message back */
int doc_exmpl_echo(struct sk_buff *skb_2, struct genl_info *info)
{
        struct nlattr *na;
        struct sk_buff *skb;
        int rc;
	void *msg_head;
	char * mydata;
	
        if (info == NULL)
                goto out;
  
        /*for each attribute there is an index in info->attrs which points to a nlattr structure
         *in this structure the data is given
         */
        na = info->attrs[DOC_EXMPL_A_MSG];
       	if (na) {
		mydata = (char *)nla_data(na);
		if (mydata == NULL)
			printk("error while receiving data\n");
		else
			printk("received: %s\n", mydata);
		}
	else
		printk("no info->attrs %i\n", DOC_EXMPL_A_MSG);

        /* send a message back*/
        /* allocate some memory, since the size is not yet known use NLMSG_GOODSIZE*/	
        skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (skb == NULL)
		goto out;

	/* create the message headers */
        /* arguments of genlmsg_put: 
           struct sk_buff *, 
           int (sending) pid, 
           int sequence number, 
           struct genl_family *, 
           int flags, 
           u8 command index (why do we need this?)
        */
       	msg_head = genlmsg_put(skb, 0, info->snd_seq+1, &doc_exmpl_gnl_family, 0, DOC_EXMPL_C_ECHO);
	if (msg_head == NULL) {
		rc = -ENOMEM;
		goto out;
	}
	/* add a DOC_EXMPL_A_MSG attribute (actual value to be sent) */
	rc = nla_put_string(skb, DOC_EXMPL_A_MSG, "hello world from kernel space");
	if (rc != 0)
		goto out;
	
        /* finalize the message */
	genlmsg_end(skb, msg_head);

        /* send the message back */
	rc = genlmsg_unicast(&init_net, skb,info->snd_pid );
	if (rc != 0)
		goto out;
	return 0;

 out:
        printk("an error occured in doc_exmpl_echo:\n");
  
      return 0;
}