Beispiel #1
0
static int brc_genl_query(struct sk_buff *skb, struct genl_info *info)
{
	int err = -EINVAL;
	struct sk_buff *ans_skb;
	void *data;

	ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (!ans_skb)
		return -ENOMEM;

	data = genlmsg_put_reply(ans_skb, info, &brc_genl_family,
				 0, BRC_GENL_C_QUERY_MC);
	if (data == NULL) {
		err = -ENOMEM;
		goto err;
	}
	NLA_PUT_U32(ans_skb, BRC_GENL_A_MC_GROUP, brc_mc_group.id);

	genlmsg_end(ans_skb, data);
	return genlmsg_reply(ans_skb, info);

err:
nla_put_failure:
	kfree_skb(ans_skb);
	return err;
}
static int ieee802154_list_iface(struct sk_buff *skb,
	struct genl_info *info)
{
	/*                                                       
                          */
	struct sk_buff *msg;
	struct net_device *dev = NULL;
	int rc = -ENOBUFS;

	pr_debug("%s\n", __func__);

	dev = ieee802154_nl_get_dev(info);
	if (!dev)
		return -ENODEV;

	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!msg)
		goto out_dev;

	rc = ieee802154_nl_fill_iface(msg, info->snd_pid, info->snd_seq,
			0, dev);
	if (rc < 0)
		goto out_free;

	dev_put(dev);

	return genlmsg_reply(msg, info);
out_free:
	nlmsg_free(msg);
out_dev:
	dev_put(dev);
	return rc;

}
Beispiel #3
0
static int ieee802154_list_iface(struct sk_buff *skb,
	struct genl_info *info)
{
	/* Request for interface name, index, type, IEEE address,
	   PAN Id, short address */
	struct sk_buff *msg;
	struct net_device *dev = NULL;
	int rc = -ENOBUFS;

	pr_debug("%s\n", __func__);

	dev = ieee802154_nl_get_dev(info);
	if (!dev)
		return -ENODEV;

	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (!msg)
		goto out_dev;

	rc = ieee802154_nl_fill_iface(msg, genl_info_snd_portid(info), info->snd_seq,
			0, dev);
	if (rc < 0)
		goto out_free;

	dev_put(dev);

	return genlmsg_reply(msg, info);
out_free:
	nlmsg_free(msg);
out_dev:
	dev_put(dev);
	return rc;

}
Beispiel #4
0
static int ixgbe_nl_reply(u8 value, u8 cmd, u8 attr, struct genl_info *info)
{
	struct sk_buff *dcb_skb = NULL;
	void *data;
	int ret;

	dcb_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (!dcb_skb)
		return -EINVAL;

	data =  genlmsg_put_reply(dcb_skb, info, &dcb_family, 0, cmd);
	if (!data)
		goto err;

	ret = nla_put_u8(dcb_skb, attr, value);
	if (ret)
        	goto err;

	/* end the message, assign the nlmsg_len. */
	genlmsg_end(dcb_skb, data);
	ret = genlmsg_reply(dcb_skb, info);
	if (ret)
        	goto err;

	return 0;

err:
	kfree(dcb_skb);
	return -EINVAL;
}
/**
 * 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_DEFAULT_SIZE, GFP_KERNEL);
	if (ans_skb == NULL)
		goto list_failure;
	data = genlmsg_put_reply(ans_skb, info, &netlbl_unlabel_gnl_family,
				 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_reply(ans_skb, info);
	if (ret_val != 0)
		goto list_failure;
	return 0;

list_failure:
	kfree(ans_skb);
	return ret_val;
}
Beispiel #6
0
static int wl1251_nl_reg_read(struct sk_buff *skb, struct genl_info *info)
{
	struct wl1251 *wl;
	u32 addr, val;
	int ret = 0;
	struct sk_buff *msg;
	void *hdr;

	if (!info->attrs[WL1251_NL_ATTR_REG_ADDR])
		return -EINVAL;

	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!msg)
		return -ENOMEM;

	wl = ifname_to_wl1251(&init_net, info);
	if (wl == NULL) {
		wl1251_error("wl1251 not found");
		return -EINVAL;
	}

	addr = nla_get_u32(info->attrs[WL1251_NL_ATTR_REG_ADDR]);

	mutex_lock(&wl->mutex);
	val = wl1251_reg_read32(wl, addr);
	mutex_unlock(&wl->mutex);

	hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq,
			  &wl1251_nl_family, 0, WL1251_NL_CMD_PHY_REG_READ);
	if (IS_ERR(hdr)) {
		ret = PTR_ERR(hdr);
		goto nla_put_failure;
	}

	NLA_PUT_STRING(msg, WL1251_NL_ATTR_IFNAME,
		       nla_data(info->attrs[WL1251_NL_ATTR_IFNAME]));

	NLA_PUT_U32(msg, WL1251_NL_ATTR_REG_VAL, val);

	ret = genlmsg_end(msg, hdr);
	if (ret < 0) {
		wl1251_error("%s() failed", __func__);
		goto nla_put_failure;
	}

	return genlmsg_reply(msg, info);

 nla_put_failure:
	nlmsg_free(msg);

	return ret;
}
int ieee802154_nl_reply(struct sk_buff *msg, struct genl_info *info)
{
	/* XXX: nlh is right at the start of msg */
	void *hdr = genlmsg_data(NLMSG_DATA(msg->data));

	if (genlmsg_end(msg, hdr) < 0)
		goto out;

	return genlmsg_reply(msg, info);
out:
	nlmsg_free(msg);
	return -ENOBUFS;
}
Beispiel #8
0
int ieee802154_nl_reply(struct sk_buff *msg, struct genl_info *info)
{
	struct nlmsghdr *nlh = nlmsg_hdr(msg);
	void *hdr = genlmsg_data(nlmsg_data(nlh));

	if (genlmsg_end(msg, hdr) < 0)
		goto out;

	return genlmsg_reply(msg, info);
out:
	nlmsg_free(msg);
	return -ENOBUFS;
}
Beispiel #9
0
int tipc_nl_bearer_get(struct sk_buff *skb, struct genl_info *info)
{
	int err;
	char *name;
	struct sk_buff *rep;
	struct tipc_bearer *bearer;
	struct tipc_nl_msg msg;
	struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
	struct net *net = genl_info_net(info);

	if (!info->attrs[TIPC_NLA_BEARER])
		return -EINVAL;

	err = nla_parse_nested(attrs, TIPC_NLA_BEARER_MAX,
			       info->attrs[TIPC_NLA_BEARER],
			       tipc_nl_bearer_policy);
	if (err)
		return err;

	if (!attrs[TIPC_NLA_BEARER_NAME])
		return -EINVAL;
	name = nla_data(attrs[TIPC_NLA_BEARER_NAME]);

	rep = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!rep)
		return -ENOMEM;

	msg.skb = rep;
	msg.portid = info->snd_portid;
	msg.seq = info->snd_seq;

	rtnl_lock();
	bearer = tipc_bearer_find(net, name);
	if (!bearer) {
		err = -EINVAL;
		goto err_out;
	}

	err = __tipc_nl_add_bearer(&msg, bearer);
	if (err)
		goto err_out;
	rtnl_unlock();

	return genlmsg_reply(rep, info);
err_out:
	rtnl_unlock();
	nlmsg_free(rep);

	return err;
}
Beispiel #10
0
int tipc_nl_media_get(struct sk_buff *skb, struct genl_info *info)
{
	int err;
	char *name;
	struct tipc_nl_msg msg;
	struct tipc_media *media;
	struct sk_buff *rep;
	struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];

	if (!info->attrs[TIPC_NLA_MEDIA])
		return -EINVAL;

	err = nla_parse_nested(attrs, TIPC_NLA_MEDIA_MAX,
			       info->attrs[TIPC_NLA_MEDIA],
			       tipc_nl_media_policy);
	if (err)
		return err;

	if (!attrs[TIPC_NLA_MEDIA_NAME])
		return -EINVAL;
	name = nla_data(attrs[TIPC_NLA_MEDIA_NAME]);

	rep = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!rep)
		return -ENOMEM;

	msg.skb = rep;
	msg.portid = info->snd_portid;
	msg.seq = info->snd_seq;

	rtnl_lock();
	media = tipc_media_find(name);
	if (!media) {
		err = -EINVAL;
		goto err_out;
	}

	err = __tipc_nl_add_media(&msg, media);
	if (err)
		goto err_out;
	rtnl_unlock();

	return genlmsg_reply(rep, info);
err_out:
	rtnl_unlock();
	nlmsg_free(rep);

	return err;
}
static int irda_nl_get_mode(struct sk_buff *skb, struct genl_info *info)
{
	struct net_device * dev;
	struct irlap_cb * irlap;
	struct sk_buff *msg;
	void *hdr;
	int ret = -ENOBUFS;

	dev = ifname_to_netdev(&init_net, info);
	if (!dev)
		return -ENODEV;

	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (!msg) {
		dev_put(dev);
		return -ENOMEM;
	}

	irlap = (struct irlap_cb *)dev->atalk_ptr;
	if (!irlap) {
		ret = -ENODEV;
		goto err_out;
	}

	hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq,
			  &irda_nl_family, 0,  IRDA_NL_CMD_GET_MODE);
	if (hdr == NULL) {
		ret = -EMSGSIZE;
		goto err_out;
	}

	if(nla_put_string(msg, IRDA_NL_ATTR_IFNAME,
			  dev->name))
		goto err_out;

	if(nla_put_u32(msg, IRDA_NL_ATTR_MODE, irlap->mode))
		goto err_out;

	genlmsg_end(msg, hdr);

	return genlmsg_reply(msg, info);

 err_out:
	nlmsg_free(msg);
	dev_put(dev);

	return ret;
}
Beispiel #12
0
static int kg2_genl_get_daemon_pid(struct sk_buff * skb, struct genl_info * info)
{
	int ret = 0;
	void * hdr;
	struct sk_buff * msg;

	printk(KERN_INFO "kg2: Send daemon PID to user: %u\n", info->snd_pid);

	if (g_daemon_pid == 0)
		return -EINVAL;

	// Allocate message
	msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);

	if (msg == NULL)
		return -ENOMEM;

	// Set message header
	hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq, &kg2_genl_family,
	                  0, KG2_GENL_CMD_SET_DAEMON_PID);

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

	// Set message payload
	ret = nla_put_u32(msg, KG2_GENL_ATTR_PID, g_daemon_pid);

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

	// Finalize message
	genlmsg_end(msg, hdr);

	// Reply message
	return genlmsg_reply(msg, info);
 err:
	nlmsg_free(msg);

	return ret;
}
Beispiel #13
0
static int ipctl_reply(struct sk_buff *skb, struct genl_info *info,
		       int property, int ifIndex, int value)
{
	struct sk_buff *skb_reply;
	void *msg_head;
	int rc = 0;

	pr_debug("ipctl: reply start\n");

	skb_reply = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (skb_reply == NULL)
		goto out;

	msg_head = genlmsg_put(skb_reply, 0, info->snd_seq, &ipctl_gnl_family, 0, IPCTL_CMD_GET);
	if (msg_head == NULL) {
		rc = -ENOMEM;
		goto out;
	}

	rc = nla_put_u32(skb_reply, IPCTL_ATTR_PROPERTY, property);
	if (rc != 0)
		goto out;

	rc = nla_put_u32(skb_reply, IPCTL_ATTR_IFINDEX, ifIndex);
	if (rc != 0)
		goto out;

	rc = nla_put_u8(skb_reply, IPCTL_ATTR_VALUE, value);
	if (rc != 0)
		goto out;
	
	/* finalize the message */
	genlmsg_end(skb_reply, msg_head);

	rc = genlmsg_reply(skb_reply , info);
	if (rc != 0)
		goto out;

	return 0;
out:
	pr_warning("ipctl: Error occured in reply: %d\n", rc);

	return rc;
}
Beispiel #14
0
static int ieee802154_list_phy(struct sk_buff *skb,
	struct genl_info *info)
{
	/* Request for interface name, index, type, IEEE address,
	   PAN Id, short address */
	struct sk_buff *msg;
	struct wpan_phy *phy;
	const char *name;
	int rc = -ENOBUFS;

	pr_debug("%s\n", __func__);

	if (!info->attrs[IEEE802154_ATTR_PHY_NAME])
		return -EINVAL;

	name = nla_data(info->attrs[IEEE802154_ATTR_PHY_NAME]);
	if (name[nla_len(info->attrs[IEEE802154_ATTR_PHY_NAME]) - 1] != '\0')
		return -EINVAL; /* phy name should be null-terminated */


	phy = wpan_phy_find(name);
	if (!phy)
		return -ENODEV;

	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!msg)
		goto out_dev;

	rc = ieee802154_nl_fill_phy(msg, info->snd_pid, info->snd_seq,
			0, phy);
	if (rc < 0)
		goto out_free;

	wpan_phy_put(phy);

	return genlmsg_reply(msg, info);
out_free:
	nlmsg_free(msg);
out_dev:
	wpan_phy_put(phy);
	return rc;

}
Beispiel #15
0
/* hello world from the inner space */
int hello_world(struct sk_buff *request, struct genl_info *info)
{
        struct sk_buff *reply;
        int rc;
        void *msg_head;
        
        if (info == NULL)
                goto out;
  
        /* send a message back*/
        /* allocate some memory, since the size is not yet known use NLMSG_GOODSIZE*/   
        reply = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
        if (reply == NULL)
                goto out;

        msg_head = genlmsg_put_reply(reply, info, &exmpl_gnl_family, 0, info->genlhdr->cmd);
        if (msg_head == NULL) {
                rc = -ENOMEM;
                goto out;
        }
        /* add a EXMPL_MSG attribute (actual value to be sent) */
        rc = nla_put_string(reply, EXMPL_MSG, "hello world from kernel space");
        if (rc != 0)
                goto out;
        
        /* finalize the message */
        genlmsg_end(reply, msg_head);

        /* send the message back */
        rc = genlmsg_reply(reply, info);
        if (rc != 0)
                goto out;
        return 0;

 out:
        printk("an error occured in hello_world:\n");
  
      return 0;
}
Beispiel #16
0
static int nfc_genl_get_device(struct sk_buff *skb, struct genl_info *info)
{
	struct sk_buff *msg;
	struct nfc_dev *dev;
	u32 idx;
	int rc = -ENOBUFS;

	if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
		return -EINVAL;

	idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);

	dev = nfc_get_device(idx);
	if (!dev)
		return -ENODEV;

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

	rc = nfc_genl_send_device(msg, dev, info->snd_pid, info->snd_seq,
				  NULL, 0);
	if (rc < 0)
		goto out_free;

	nfc_put_device(dev);

	return genlmsg_reply(msg, info);

out_free:
	nlmsg_free(msg);
out_putdev:
	nfc_put_device(dev);
	return rc;
}
Beispiel #17
0
static int seg6_genl_get_tunsrc(struct sk_buff *skb, struct genl_info *info)
{
	struct net *net = genl_info_net(info);
	struct in6_addr *tun_src;
	struct sk_buff *msg;
	void *hdr;

	msg = genlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (!msg)
		return -ENOMEM;

	hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq,
			  &seg6_genl_family, 0, SEG6_CMD_GET_TUNSRC);
	if (!hdr)
		goto free_msg;

	rcu_read_lock();
	tun_src = rcu_dereference(seg6_pernet(net)->tun_src);

	if (nla_put(msg, SEG6_ATTR_DST, sizeof(struct in6_addr), tun_src))
		goto nla_put_failure;

	rcu_read_unlock();

	genlmsg_end(msg, hdr);
	genlmsg_reply(msg, info);

	return 0;

nla_put_failure:
	rcu_read_unlock();
	genlmsg_cancel(msg, hdr);
free_msg:
	nlmsg_free(msg);
	return -ENOMEM;
}
Beispiel #18
0
static int ixgbe_dcb_pg_gcfg(struct sk_buff *skb, struct genl_info *info,
				int dir)
{
	void *data;
	struct sk_buff *dcb_skb = NULL;
	struct nlattr *pg_nest, *param_nest, *tb;
	struct nlattr *pg_tb[IXGBE_DCB_PG_A_MAX + 1];
	struct nlattr *param_tb[IXGBE_DCB_TC_A_PARAM_MAX + 1];
	struct net_device *netdev = NULL;
	struct ixgbe_adapter *adapter = NULL;
	struct tc_configuration *tc_config = NULL;
	struct tc_bw_alloc *tc = NULL;
	int ret  = -ENOMEM;
	int i, tc_max;

	if (!info->attrs[DCB_A_IFNAME] || !info->attrs[DCB_A_PG_CFG])
		return -EINVAL;

	netdev = dev_get_by_name(&init_net,
				 nla_data(info->attrs[DCB_A_IFNAME]));
	if (!netdev)
		return -EINVAL;

	ret = ixgbe_dcb_check_adapter(netdev);
	if (ret)
		goto err_out;
	else
		adapter = netdev_priv(netdev);

	ret = nla_parse_nested(pg_tb, IXGBE_DCB_PG_A_MAX,
			       info->attrs[DCB_A_PG_CFG], dcb_pg_nest);
	if (ret)
		goto err;

	dcb_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (!dcb_skb)
		goto err;

	data =  genlmsg_put_reply(dcb_skb, info, &dcb_family, 0,
				 (dir) ? DCB_C_PGRX_GCFG : DCB_C_PGTX_GCFG);

	if (!data)
		goto err;

	pg_nest = nla_nest_start(dcb_skb, DCB_A_PG_CFG);
	if (!pg_nest)
		goto err;

	tc_max = adapter->ring_feature[RING_F_DCB].indices;
	for (i = PG_A_TC_0; i < tc_max + PG_A_TC_0; i++) {
		if (!pg_tb[i] && !pg_tb[PG_A_TC_ALL])
			continue;

		if (pg_tb[PG_A_TC_ALL])
			tb = pg_tb[PG_A_TC_ALL];
		else
			tb = pg_tb[i];
		ret = nla_parse_nested(param_tb, IXGBE_DCB_TC_A_PARAM_MAX,
				       tb, dcb_tc_param_nest);
		if (ret)
			goto err_pg;

		param_nest = nla_nest_start(dcb_skb, i);
		if (!param_nest)
			goto err_pg;

		tc_config = &adapter->dcb_cfg.tc_config[i - PG_A_TC_0];
		tc = &adapter->dcb_cfg.tc_config[i - PG_A_TC_0].path[dir];

		if (param_tb[TC_A_PARAM_STRICT_PRIO] ||
		    param_tb[TC_A_PARAM_ALL]) {
			ret = nla_put_u8(dcb_skb, TC_A_PARAM_STRICT_PRIO,
					 tc->prio_type);
			if (ret)
				goto err_param;
		}
		if (param_tb[TC_A_PARAM_BW_GROUP_ID] ||
		    param_tb[TC_A_PARAM_ALL]) {
			ret = nla_put_u8(dcb_skb, TC_A_PARAM_BW_GROUP_ID,
					 tc->bwg_id);
			if (ret)
				goto err_param;
		}
		if (param_tb[TC_A_PARAM_BW_PCT_IN_GROUP] ||
		    param_tb[TC_A_PARAM_ALL]) {
			ret = nla_put_u8(dcb_skb, TC_A_PARAM_BW_PCT_IN_GROUP,
					 tc->bwg_percent);
			if (ret)
				goto err_param;
		}
		if (param_tb[TC_A_PARAM_UP_MAPPING] ||
		    param_tb[TC_A_PARAM_ALL]) {
			ret = nla_put_u8(dcb_skb, TC_A_PARAM_UP_MAPPING,
					 tc->up_to_tc_bitmap);
			if (ret)
				goto err_param;
		}
		nla_nest_end(dcb_skb, param_nest);
	}

	for (i = PG_A_BWG_0; i < PG_A_BWG_MAX; i++) {
		if (!pg_tb[i] && !pg_tb[PG_A_BWG_ALL])
			continue;

		ret = nla_put_u8(dcb_skb, i,
		            adapter->dcb_cfg.bw_percentage[dir][i-PG_A_BWG_0]);

		if (ret)
			goto err_pg;
	}

	nla_nest_end(dcb_skb, pg_nest);

	genlmsg_end(dcb_skb, data);
	ret = genlmsg_reply(dcb_skb, info);
	if (ret)
		goto err;

	dev_put(netdev);
	return 0;

err_param:
	DPRINTK(DRV, ERR, "Error in get pg %s.\n", dir?"rx":"tx");
	nla_nest_cancel(dcb_skb, param_nest);
err_pg:
	nla_nest_cancel(dcb_skb, pg_nest);
err:
	kfree(dcb_skb);
err_out:
	dev_put(netdev);
	return ret;
}
Beispiel #19
0
static int ixgbe_dcb_gperm_hwaddr(struct sk_buff *skb, struct genl_info *info)
{
	void *data;
	struct sk_buff *dcb_skb = NULL;
	struct nlattr *tb[IXGBE_DCB_PERM_HW_A_MAX + 1], *nest;
	struct net_device *netdev = NULL;
	struct ixgbe_adapter *adapter = NULL;
	struct ixgbe_hw *hw = NULL;
	int ret = -ENOMEM;
	int i;

	if (!info->attrs[DCB_A_IFNAME] || !info->attrs[DCB_A_PERM_HWADDR])
		return -EINVAL;

	netdev = dev_get_by_name(&init_net,
				 nla_data(info->attrs[DCB_A_IFNAME]));
	if (!netdev)
		return -EINVAL;

	ret = ixgbe_dcb_check_adapter(netdev);
	if (ret)
		goto err_out;
	else
		adapter = netdev_priv(netdev);

	hw = &adapter->hw;

	ret = nla_parse_nested(tb, IXGBE_DCB_PERM_HW_A_MAX,
				info->attrs[DCB_A_PERM_HWADDR],
				dcb_perm_hwaddr_nest);
	if (ret)
		goto err;

	dcb_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (!dcb_skb)
		goto err;

	data =  genlmsg_put_reply(dcb_skb, info, &dcb_family, 0,
				  DCB_C_GPERM_HWADDR);
	if (!data)
		goto err;

	nest = nla_nest_start(dcb_skb, DCB_A_PERM_HWADDR);
	if (!nest)
		goto err;

	for (i = 0; i < netdev->addr_len; i++) {
		if (!tb[i+PERM_HW_A_0] && !tb[PERM_HW_A_ALL])
			goto err;

		ret = nla_put_u8(dcb_skb, DCB_A_PERM_HWADDR,
				 hw->mac.perm_addr[i]);

		if (ret) {
			nla_nest_cancel(dcb_skb, nest);
			goto err;
		}
	}

	nla_nest_end(dcb_skb, nest);

	genlmsg_end(dcb_skb, data);

	ret = genlmsg_reply(dcb_skb, info);
	if (ret)
		goto err;

	dev_put(netdev);
	return 0;

err:
	DPRINTK(DRV, ERR, "Error in get permanent hwaddr.\n");
	kfree(dcb_skb);
err_out:
	dev_put(netdev);
	return ret;
}
Beispiel #20
0
static int 
kfm_genl_get_cmd(struct sk_buff *skb, struct genl_info *info)
{
	struct sk_buff *msg;
	void *reply;
	int ret, cmd, reply_cmd;
	
	cmd = info->genlhdr->cmd;

	switch (cmd) {
	case KFM_CMD_GET_INFO:
		reply_cmd = KFM_CMD_GET_INFO_REPLY;
		break;
	case KFM_CMD_GET_CACHE_INFO:
		reply_cmd = KFM_CMD_GET_CACHE_INFO_REPLY;
		break;
	case KFM_CMD_GET_MEMPAGE_INFO:
		reply_cmd = KFM_CMD_GET_MEMPAGE_INFO_REPLY;
		break;
	default:
		KFM_ERR("unknown Generic Netlink command\n");
		return -EINVAL;
	}
	
	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (!msg)
		return -ENOMEM;

	mutex_lock(&__kfm_mutex);  // need lock??

	reply = genlmsg_put_reply(msg, info, &kfm_genl_family, 0, reply_cmd);
	if (reply == NULL)
		goto nla_put_failure;

	switch (cmd) {
	case KFM_CMD_GET_INFO:
		if (nla_put_u32(msg, KFM_INFO_ATTR_VERSION, KFM_VERSION_CODE))
			goto nla_put_failure;
		break;
	
	case KFM_CMD_GET_CACHE_INFO:
	{
		struct kfm_cache_u ucache;
		
		ret = kfm_genl_parse_cache(&ucache, info->attrs);
		if (ret)
			goto out_err;

		if((ret = kfm_cache_status_on_cpu(ucache.cpu)) < 0)
			goto out_err;
		ucache.status = ret;

		ret = kfm_genl_fill_cache(msg, &ucache);
		if (ret)
				goto nla_put_failure;

		break;
	}

	case KFM_CMD_GET_MEMPAGE_INFO:
	{
		struct kfm_mempage_u umempage;

		ret = kfm_genl_parse_mempage(&umempage, info->attrs);
		if (ret)
			goto out_err;

		if(kfm_get_mempage_info(umempage.addr, &umempage))
			goto out_err;

		ret = kfm_genl_fill_mempage(msg, &umempage);
		if (ret)
				goto nla_put_failure;
		
		break;
	}
	
	/* for other get cmd */
	}

	genlmsg_end(msg, reply);
	ret = genlmsg_reply(msg, info);
	goto out;

nla_put_failure:
	pr_err("not enough space in Netlink message\n");
	ret = -EMSGSIZE;

out_err:
	nlmsg_free(msg);
out:
	mutex_unlock(&__kfm_mutex);

	return ret;
}
Beispiel #21
0
static int wl1251_nl_test_cmd(struct sk_buff *skb, struct genl_info *info)
{
	struct wl1251 *wl;
	struct wl1251_command *cmd;
	char *buf;
	int buf_len, ret, cmd_len;
	u8 answer;

	if (!info->attrs[WL1251_NL_ATTR_CMD_TEST_PARAM])
		return -EINVAL;

	wl = ifname_to_wl1251(&init_net, info);
	if (wl == NULL) {
		wl1251_error("wl1251 not found");
		return -EINVAL;
	}

	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
	if (!cmd)
		return -ENOMEM;

	buf = nla_data(info->attrs[WL1251_NL_ATTR_CMD_TEST_PARAM]);
	buf_len = nla_len(info->attrs[WL1251_NL_ATTR_CMD_TEST_PARAM]);
	answer = nla_get_u8(info->attrs[WL1251_NL_ATTR_CMD_TEST_ANSWER]);

	cmd->header.id = CMD_TEST;
	memcpy(cmd->parameters, buf, buf_len);
	cmd_len = sizeof(struct wl1251_cmd_header) + buf_len;

	mutex_lock(&wl->mutex);
	ret = wl1251_cmd_test(wl, cmd, cmd_len, answer);
	mutex_unlock(&wl->mutex);

	if (ret < 0) {
		wl1251_error("%s() failed", __func__);
		goto out;
	}

	if (answer) {
		struct sk_buff *msg;
		void *hdr;

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

		hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq,
				  &wl1251_nl_family, 0, WL1251_NL_CMD_TEST);
		if (IS_ERR(hdr)) {
			ret = PTR_ERR(hdr);
			goto nla_put_failure;
		}

		NLA_PUT_STRING(msg, WL1251_NL_ATTR_IFNAME,
			       nla_data(info->attrs[WL1251_NL_ATTR_IFNAME]));
		NLA_PUT(msg, WL1251_NL_ATTR_CMD_TEST_ANSWER,
			sizeof(*cmd), cmd);

		ret = genlmsg_end(msg, hdr);
		if (ret < 0) {
			wl1251_error("%s() failed", __func__);
			goto nla_put_failure;
		}

		wl1251_debug(DEBUG_NETLINK, "TEST cmd sent, answer");
		ret = genlmsg_reply(msg, info);
		goto out;

 nla_put_failure:
		nlmsg_free(msg);
	} else
		wl1251_debug(DEBUG_NETLINK, "TEST cmd sent");

out:
	kfree(cmd);
	return ret;
}
Beispiel #22
0
static int wl1251_nl_interrogate(struct sk_buff *skb, struct genl_info *info)
{
	struct wl1251 *wl;
	struct sk_buff *msg;
	int ret = -ENOBUFS, cmd_ie, cmd_ie_len;
	struct wl1251_command *cmd;
	void *hdr;

	if (!info->attrs[WL1251_NL_ATTR_CMD_IE])
		return -EINVAL;

	if (!info->attrs[WL1251_NL_ATTR_CMD_IE_LEN])
		return -EINVAL;

	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
	if (!cmd)
		return -ENOMEM;

	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!msg)
		return -ENOMEM;

	wl = ifname_to_wl1251(&init_net, info);
	if (wl == NULL) {
		wl1251_error("wl1251 not found");
		ret = -EINVAL;
		goto nla_put_failure;
	}

	/* acx id */
	cmd_ie = nla_get_u32(info->attrs[WL1251_NL_ATTR_CMD_IE]);

	/* maximum length of acx, including all headers */
	cmd_ie_len = nla_get_u32(info->attrs[WL1251_NL_ATTR_CMD_IE_LEN]);

	wl1251_debug(DEBUG_NETLINK, "Getting IE 0x%x (len %d)",
		     cmd_ie, cmd_ie_len);

	mutex_lock(&wl->mutex);
	ret = wl1251_cmd_interrogate(wl, cmd_ie, cmd, cmd_ie_len);
	mutex_unlock(&wl->mutex);

	if (ret < 0) {
		wl1251_error("%s() failed", __func__);
		goto nla_put_failure;
	}

	hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq,
			  &wl1251_nl_family, 0, WL1251_NL_CMD_INTERROGATE);
	if (IS_ERR(hdr)) {
		ret = PTR_ERR(hdr);
		goto nla_put_failure;
	}

	NLA_PUT_STRING(msg, WL1251_NL_ATTR_IFNAME,
		       nla_data(info->attrs[WL1251_NL_ATTR_IFNAME]));
	NLA_PUT(msg, WL1251_NL_ATTR_CMD_IE_ANSWER, cmd_ie_len, cmd);

	ret = genlmsg_end(msg, hdr);
	if (ret < 0) {
		wl1251_error("%s() failed", __func__);
		goto nla_put_failure;
	}

	kfree(cmd);
	return genlmsg_reply(msg, info);

 nla_put_failure:
	kfree(cmd);
	nlmsg_free(msg);

	return ret;
}
Beispiel #23
0
static int wl1251_nl_phy_reg_read(struct sk_buff *skb, struct genl_info *info)
{
	struct wl1251 *wl;
	struct sk_buff *msg;
	u32 reg_addr, *reg_value = NULL;
	int ret = 0;
	void *hdr;

	if (!info->attrs[WL1251_NL_ATTR_REG_ADDR])
		return -EINVAL;

	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!msg)
		return -ENOMEM;

	wl = ifname_to_wl1251(&init_net, info);
	if (wl == NULL) {
		wl1251_error("wl1251 not found");
		ret = -EINVAL;
		goto nla_put_failure;
	}

	reg_value = kmalloc(sizeof(*reg_value), GFP_KERNEL);
	if (!reg_value) {
		ret = -ENOMEM;
		goto nla_put_failure;
	}

	reg_addr = nla_get_u32(info->attrs[WL1251_NL_ATTR_REG_ADDR]);

	wl1251_debug(DEBUG_NETLINK, "Reading PHY reg 0x%x", reg_addr);

	mutex_lock(&wl->mutex);
	ret = wl1251_cmd_read_memory(wl, reg_addr, reg_value,
				     sizeof(*reg_value));
	mutex_unlock(&wl->mutex);

	if (ret < 0) {
		wl1251_error("%s() failed", __func__);
		goto nla_put_failure;
	}


	hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq,
			  &wl1251_nl_family, 0, WL1251_NL_CMD_PHY_REG_READ);
	if (IS_ERR(hdr)) {
		ret = PTR_ERR(hdr);
		goto nla_put_failure;
	}

	NLA_PUT_STRING(msg, WL1251_NL_ATTR_IFNAME,
		       nla_data(info->attrs[WL1251_NL_ATTR_IFNAME]));

	NLA_PUT_U32(msg, WL1251_NL_ATTR_REG_VAL, *reg_value);

	ret = genlmsg_end(msg, hdr);
	if (ret < 0) {
		wl1251_error("%s() failed", __func__);
		goto nla_put_failure;
	}

	kfree(reg_value);

	return genlmsg_reply(msg, info);

 nla_put_failure:
	nlmsg_free(msg);
	kfree(reg_value);

	return ret;
}
Beispiel #24
0
static int ixgbe_dcb_gpfccfg(struct sk_buff *skb, struct genl_info *info)
{
	void *data;
	struct sk_buff *dcb_skb = NULL;
	struct nlattr *tb[IXGBE_DCB_PFC_A_UP_MAX + 1], *nest;
	struct net_device *netdev = NULL;
	struct ixgbe_adapter *adapter = NULL;
	int ret = -ENOMEM;
	int i;

	if (!info->attrs[DCB_A_IFNAME] || !info->attrs[DCB_A_PFC_CFG])
		return -EINVAL;

	netdev = dev_get_by_name(&init_net,
				 nla_data(info->attrs[DCB_A_IFNAME]));
	if (!netdev)
		return -EINVAL;

	ret = ixgbe_dcb_check_adapter(netdev);
	if (ret)
		goto err_out;
	else
		adapter = netdev_priv(netdev);

	ret = nla_parse_nested(tb, IXGBE_DCB_PFC_A_UP_MAX,
			       info->attrs[DCB_A_PFC_CFG], dcb_pfc_up_nest);
	if (ret)
		goto err;

	dcb_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (!dcb_skb)
		goto err;

	data =  genlmsg_put_reply(dcb_skb, info, &dcb_family, 0,
				  DCB_C_PFC_GCFG);
	if (!data)
		goto err;

	nest = nla_nest_start(dcb_skb, DCB_A_PFC_CFG);
	if (!nest)
		goto err;

	for (i = PFC_A_UP_0; i < PFC_A_UP_MAX; i++) {
		if (!tb[i] && !tb[PFC_A_UP_ALL])
			continue;

		ret = nla_put_u8(dcb_skb, i,
			      adapter->dcb_cfg.tc_config[i-PFC_A_UP_0].dcb_pfc);
		if (ret) {
			nla_nest_cancel(dcb_skb, nest);
			goto err;
		}
	}

	nla_nest_end(dcb_skb, nest);

	genlmsg_end(dcb_skb, data);

	ret = genlmsg_reply(dcb_skb, info);
	if (ret)
		goto err;

	dev_put(netdev);
	return 0;

err:
	DPRINTK(DRV, ERR, "Error in get pfc stats.\n");
	kfree(dcb_skb);
err_out:
	dev_put(netdev);
	return ret;
}