From patchwork Mon May 9 16:41:09 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sven Eckelmann X-Patchwork-Id: 16115 X-Patchwork-Delegate: mareklindner@neomailbox.ch Return-Path: X-Original-To: patchwork@open-mesh.org Delivered-To: patchwork@open-mesh.org Received: from open-mesh.org (localhost [IPv6:::1]) by open-mesh.org (Postfix) with ESMTP id 93F1B82777; Mon, 9 May 2016 18:41:29 +0200 (CEST) Authentication-Results: open-mesh.org; dmarc=none header.from=open-mesh.com Authentication-Results: open-mesh.org; dkim=fail reason="verification failed; unprotected key" header.d=open-mesh-com.20150623.gappssmtp.com header.i=@open-mesh-com.20150623.gappssmtp.com header.b=iYknM8ml; dkim-adsp=none (unprotected policy); dkim-atps=neutral Received-SPF: Neutral (access neither permitted nor denied) identity=mailfrom; client-ip=2a00:1450:400c:c09::22e; helo=mail-wm0-x22e.google.com; envelope-from=sven.eckelmann@open-mesh.com; receiver=b.a.t.m.a.n@lists.open-mesh.org Authentication-Results: open-mesh.org; dmarc=none header.from=open-mesh.com Received: from mail-wm0-x22e.google.com (mail-wm0-x22e.google.com [IPv6:2a00:1450:400c:c09::22e]) by open-mesh.org (Postfix) with ESMTPS id 72DA782764 for ; Mon, 9 May 2016 18:41:14 +0200 (CEST) Received: by mail-wm0-x22e.google.com with SMTP id g17so22451711wme.0 for ; Mon, 09 May 2016 09:41:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=open-mesh-com.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references; bh=BnsIK2B8nMeJ3totVcU+GHyYyWdhxsm6X2UEbpWY7Hs=; b=iYknM8mlTsoxsHhJGHrN1Wlud4DcsTPA9ClzyX32B/0DjVplHLQyX9lcXBX8gdDBfi T9Zwe88MwVIpmj+asg5LbmGOIRl6BdnvJkwcEXnZ5uZWVPaVALQ7MWfSpl0Pg8zJWSgG BQ/QxPq4Sq0jXKWz8ZQvGZAXtvS1tQOLOf4kwxwxR+04YWOnCOMmD8fUNpQwu2KjPQcc locTkScA41JhlO2eLDZzX9gVQMY3PL0bYiIb8CkC0hao9qCPYgu3FePlg6SMtkgNv8Ee OM15yPmiAhQdVwQlLsZlSgFCAgi0bK6UuH+kH3Mp+e1Z3ufj9kROke0HvaaMdVo3PnRI 2XFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=BnsIK2B8nMeJ3totVcU+GHyYyWdhxsm6X2UEbpWY7Hs=; b=F41LDKw0muBwPVm+CQUSvSsqOFyiOP0Oz+fxP93neOGaPHySaTtXPM1b3PUdFo2ARI 5l5MpZ6+D2I82L25gRUz4JcIhRoj+iehkydFZvs3+EdIWFE0/9pNng52bM0Cvk5dsZps aexjPTstIfQ/72sDOKJsZo/ksPBIHLVuaw7SZFERkPBiL9MzKhmDktS7bn88e+JSjvmI w2v45j7Iou4EEUo3TxDx0vOCEdCmRibpE8+1cnVep5EXCz7JBhx+HLy7x2x1G4eJi6GH KV4EM8NN/mIDHNHaGDEgR8FlbU6eR3rkUhTs1LnKBCpjMSJ64tEaMSey1gExodFtck0o mNkw== X-Gm-Message-State: AOPr4FX0E5VXOGBPkQqjLSnXGWJO0EJFpq9X8DMVpt88v4BtUCFjaa7BymYAL+Jyap+HFFOE X-Received: by 10.28.168.76 with SMTP id r73mr11597943wme.44.1462812074096; Mon, 09 May 2016 09:41:14 -0700 (PDT) Received: from sven-desktop.home.narfation.org (p4FFE56B5.dip0.t-ipconnect.de. [79.254.86.181]) by smtp.gmail.com with ESMTPSA id f11sm25662790wmf.22.2016.05.09.09.41.13 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 09 May 2016 09:41:13 -0700 (PDT) From: Sven Eckelmann X-Google-Original-From: Sven Eckelmann To: b.a.t.m.a.n@lists.open-mesh.org Date: Mon, 9 May 2016 18:41:09 +0200 Message-Id: <1462812071-16467-2-git-send-email-sven@open-mesh.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <6307812.WAqRcEYAvX@bentobox> References: <6307812.WAqRcEYAvX@bentobox> Subject: [B.A.T.M.A.N.] [PATCH v7 2/4] batman-adv: add netlink command to query generic mesh information files X-BeenThere: b.a.t.m.a.n@lists.open-mesh.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: The list for a Better Approach To Mobile Ad-hoc Networking List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: The list for a Better Approach To Mobile Ad-hoc Networking Errors-To: b.a.t.m.a.n-bounces@lists.open-mesh.org Sender: "B.A.T.M.A.N" From: Matthias Schiffer BATADV_CMD_GET_MESH_INFO is used to query basic information about a batman-adv softif (name, index and MAC address for both the softif and the primary hardif; routing algorithm; batman-adv version). Signed-off-by: Matthias Schiffer Signed-off-by: Andrew Lunn [sven.eckelmann@open-mesh.com: Reduce the number of changes to BATADV_CMD_GET_MESH_INFO, add missing kerneldoc, add policy for attributes] Signed-off-by: Sven Eckelmann --- compat.h | 6 ++ include/uapi/linux/batman_adv.h | 18 ++++++ net/batman-adv/netlink.c | 135 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 159 insertions(+) diff --git a/compat.h b/compat.h index 5a5f478..7d5c8b6 100644 --- a/compat.h +++ b/compat.h @@ -62,6 +62,12 @@ static int __batadv_interface_kill_vid(struct net_device *dev, __be16 proto,\ #endif /* < KERNEL_VERSION(3, 3, 0) */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0) + +#define snd_portid snd_pid + +#endif /* < KERNEL_VERSION(3, 7, 0) */ + #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0) #define batadv_interface_set_mac_addr(x, y) \ diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h index ba611a7..a908140 100644 --- a/include/uapi/linux/batman_adv.h +++ b/include/uapi/linux/batman_adv.h @@ -24,12 +24,28 @@ * enum batadv_nl_attrs - batman-adv netlink attributes * * @BATADV_ATTR_UNSPEC: unspecified attribute to catch errors + * @BATADV_ATTR_VERSION: batman-adv version string + * @BATADV_ATTR_ALGO_NAME: name of routing algorithm + * @BATADV_ATTR_MESH_IFINDEX: index of the batman-adv interface + * @BATADV_ATTR_MESH_IFNAME: name of the batman-adv interface + * @BATADV_ATTR_MESH_ADDRESS: mac address of the batman-adv interface + * @BATADV_ATTR_HARD_IFINDEX: index of the non-batman-adv interface + * @BATADV_ATTR_HARD_IFNAME: name of the non-batman-adv interface + * @BATADV_ATTR_HARD_ADDRESS: mac address of the non-batman-adv interface * @__BATADV_ATTR_AFTER_LAST: internal use * @NUM_BATADV_ATTR: total number of batadv_nl_attrs available * @BATADV_ATTR_MAX: highest attribute number currently defined */ enum batadv_nl_attrs { BATADV_ATTR_UNSPEC, + BATADV_ATTR_VERSION, + BATADV_ATTR_ALGO_NAME, + BATADV_ATTR_MESH_IFINDEX, + BATADV_ATTR_MESH_IFNAME, + BATADV_ATTR_MESH_ADDRESS, + BATADV_ATTR_HARD_IFINDEX, + BATADV_ATTR_HARD_IFNAME, + BATADV_ATTR_HARD_ADDRESS, /* add attributes above here, update the policy in netlink.c */ __BATADV_ATTR_AFTER_LAST, NUM_BATADV_ATTR = __BATADV_ATTR_AFTER_LAST, @@ -40,11 +56,13 @@ enum batadv_nl_attrs { * enum batadv_nl_commands - supported batman-adv netlink commands * * @BATADV_CMD_UNSPEC: unspecified command to catch errors + * @BATADV_CMD_GET_MESH_INFO: Query basic information about batman-adv device * @__BATADV_CMD_AFTER_LAST: internal use * @BATADV_CMD_MAX: highest used command number */ enum batadv_nl_commands { BATADV_CMD_UNSPEC, + BATADV_CMD_GET_MESH_INFO, /* add new commands above here */ __BATADV_CMD_AFTER_LAST, BATADV_CMD_MAX = __BATADV_CMD_AFTER_LAST - 1 diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c index af3e87e..568523c 100644 --- a/net/batman-adv/netlink.c +++ b/net/batman-adv/netlink.c @@ -18,12 +18,24 @@ #include "main.h" #include "netlink.h" +#include +#include #include +#include #include +#include +#include +#include #include #include +#include #include +#include "hard-interface.h" +#include "soft-interface.h" + +struct sk_buff; + static struct genl_family batadv_netlink_family = { .id = GENL_ID_GENERATE, .hdrsize = 0, @@ -32,7 +44,130 @@ static struct genl_family batadv_netlink_family = { .maxattr = BATADV_ATTR_MAX, }; +static struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = { + [BATADV_ATTR_VERSION] = { .type = NLA_STRING }, + [BATADV_ATTR_ALGO_NAME] = { .type = NLA_STRING }, + [BATADV_ATTR_MESH_IFINDEX] = { .type = NLA_U32 }, + [BATADV_ATTR_MESH_IFNAME] = { .type = NLA_STRING }, + [BATADV_ATTR_MESH_ADDRESS] = { .len = ETH_ALEN }, + [BATADV_ATTR_HARD_IFINDEX] = { .type = NLA_U32 }, + [BATADV_ATTR_HARD_IFNAME] = { .type = NLA_STRING }, + [BATADV_ATTR_HARD_ADDRESS] = { .len = ETH_ALEN }, +}; + +/** + * batadv_netlink_mesh_info_put - Fill generic information about mesh interface + * @msg: netlink message to be sent back + * @soft_iface: interface for which the data should be taken + * + * Return: 0 on success, < 0 on error + */ +static int +batadv_netlink_mesh_info_put(struct sk_buff *msg, struct net_device *soft_iface) +{ + struct batadv_priv *bat_priv = netdev_priv(soft_iface); + struct batadv_hard_iface *primary_if = NULL; + struct net_device *hard_iface; + int ret = -ENOBUFS; + + if (nla_put_string(msg, BATADV_ATTR_VERSION, BATADV_SOURCE_VERSION) || + nla_put_string(msg, BATADV_ATTR_ALGO_NAME, + bat_priv->bat_algo_ops->name) || + nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, soft_iface->ifindex) || + nla_put_string(msg, BATADV_ATTR_MESH_IFNAME, soft_iface->name) || + nla_put(msg, BATADV_ATTR_MESH_ADDRESS, ETH_ALEN, + soft_iface->dev_addr)) + goto out; + + primary_if = batadv_primary_if_get_selected(bat_priv); + if (primary_if && primary_if->if_status == BATADV_IF_ACTIVE) { + hard_iface = primary_if->net_dev; + + if (nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX, + hard_iface->ifindex) || + nla_put_string(msg, BATADV_ATTR_HARD_IFNAME, + hard_iface->name) || + nla_put(msg, BATADV_ATTR_HARD_ADDRESS, ETH_ALEN, + hard_iface->dev_addr)) + goto out; + } + + ret = 0; + + out: + if (primary_if) + batadv_hardif_put(primary_if); + + return ret; +} + +/** + * batadv_netlink_mesh_info_put - Handle BATADV_CMD_GET_MESH_INFO + * @skb: received netlink message + * @info: receiver information + * + * Return: 0 on success, < 0 on error + */ +static int +batadv_netlink_get_mesh_info(struct sk_buff *skb, struct genl_info *info) +{ + struct net *net = genl_info_net(info); + struct net_device *soft_iface; + struct sk_buff *msg = NULL; + void *msg_head; + int ifindex; + int ret; + + if (!info->attrs[BATADV_ATTR_MESH_IFINDEX]) + return -EINVAL; + + ifindex = nla_get_u32(info->attrs[BATADV_ATTR_MESH_IFINDEX]); + if (!ifindex) + return -EINVAL; + + soft_iface = dev_get_by_index(net, ifindex); + if (!soft_iface || !batadv_softif_is_valid(soft_iface)) { + ret = -ENODEV; + goto out; + } + + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!msg) { + ret = -ENOMEM; + goto out; + } + + msg_head = genlmsg_put(msg, info->snd_portid, info->snd_seq, + &batadv_netlink_family, 0, + BATADV_CMD_GET_MESH_INFO); + if (!msg_head) { + ret = -ENOBUFS; + goto out; + } + + ret = batadv_netlink_mesh_info_put(msg, soft_iface); + + out: + if (soft_iface) + dev_put(soft_iface); + + if (ret) { + if (msg) + nlmsg_free(msg); + return ret; + } + + genlmsg_end(msg, msg_head); + return genlmsg_reply(msg, info); +} + static struct genl_ops batadv_netlink_ops[] = { + { + .cmd = BATADV_CMD_GET_MESH_INFO, + .flags = GENL_ADMIN_PERM, + .policy = batadv_netlink_policy, + .doit = batadv_netlink_get_mesh_info, + }, }; /**