-static int dp_genl_show(struct sk_buff *skb, struct genl_info *info)
-{
- struct datapath *dp;
- int err = -ENOMEM;
- struct sk_buff *ans_skb = NULL;
- void *data;
- struct nlattr *attr;
- struct ofp_data_hello *odh;
- size_t odh_max_len, odh_len, port_max_len, len;
- int port_count;
-
- if (!info->attrs[DP_GENL_A_DP_IDX])
- return -EINVAL;
-
- mutex_lock(&dp_mutex);
- dp = dp_get(nla_get_u32((info->attrs[DP_GENL_A_DP_IDX])));
- if (!dp)
- goto error;
-
- /* Overallocate, since we can't reliably determine the number of
- * ports a priori. */
- port_max_len = sizeof(struct ofp_phy_port) * OFPP_MAX;
-
- len = nla_total_size(sizeof(*odh) + port_max_len)
- + nla_total_size(sizeof(uint32_t));
-
- ans_skb = nlmsg_new(MAX(len, NLMSG_GOODSIZE), GFP_KERNEL);
- if (!ans_skb)
- goto error;
-
- data = genlmsg_put_reply(ans_skb, info, &dp_genl_family,
- 0, DP_GENL_C_SHOW_DP);
- if (data == NULL)
- goto error;
-
- NLA_PUT_U32(ans_skb, DP_GENL_A_DP_IDX, dp->dp_idx);
-
- odh_max_len = sizeof(*odh) + port_max_len;
- attr = nla_reserve(ans_skb, DP_GENL_A_DP_INFO, odh_max_len);
- if (!attr)
- goto error;
- odh = nla_data(attr);
- port_count = fill_data_hello(dp, odh);
-
- /* Only now that we know how many ports we've added can we say
- * say something about the length. */
- odh_len = sizeof(*odh) + (sizeof(struct ofp_phy_port) * port_count);
- odh->header.length = htons(odh_len);
-
- /* Take back the unused part that was reserved */
- nla_unreserve(ans_skb, attr, (odh_max_len - odh_len));
-
- genlmsg_end(ans_skb, data);
- err = genlmsg_reply(ans_skb, info);
- if (!err)
- ans_skb = NULL;
-
-error:
-nla_put_failure:
- if (ans_skb)
- kfree_skb(ans_skb);
- mutex_unlock(&dp_mutex);
- return err;
-}
-
-static struct genl_ops dp_genl_ops_show_dp = {
- .cmd = DP_GENL_C_SHOW_DP,
- .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
- .policy = dp_genl_policy,
- .doit = dp_genl_show,
- .dumpit = NULL,
-};
-