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; }
/** * 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; }
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; }
struct sk_buff *ieee802154_nl_new_reply(struct genl_info *info, int flags, u8 req) { void *hdr; struct sk_buff *msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); if (!msg) return NULL; hdr = genlmsg_put_reply(msg, info, &nl802154_family, flags, req); if (!hdr) { nlmsg_free(msg); return NULL; } return msg; }
/* 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; }
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; }
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; }
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; }
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; }