From patchwork Thu May 5 11:09:41 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sven Eckelmann X-Patchwork-Id: 16075 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 85164826D8; Thu, 5 May 2016 13:10:31 +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=YS1Uf6Ds; dkim-adsp=none (unprotected policy); dkim-atps=neutral Received-SPF: Neutral (access neither permitted nor denied) identity=mailfrom; client-ip=2a00:1450:400c:c09::22a; helo=mail-wm0-x22a.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-x22a.google.com (mail-wm0-x22a.google.com [IPv6:2a00:1450:400c:c09::22a]) by open-mesh.org (Postfix) with ESMTPS id 443E9826B8 for ; Thu, 5 May 2016 13:10:02 +0200 (CEST) Received: by mail-wm0-x22a.google.com with SMTP id a17so21810688wme.0 for ; Thu, 05 May 2016 04:10:02 -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=YS1Uf6Dslf9Zc4TfluzLbTbVdaQV5QodVUA7RI9Cix0HwgAV2c/t9+SpYKd2VTRM1J zerf6Efc/DqgJ/G4KO52vrC5albN23Q4jcwO9m/bcOzzPw7B0A88XusDDpTf3wd54dPW zcr2hU15G+3E2jYYs3tesnM2WKZcSIH1yj+kEbvof7AqjVQtsYzPpHO5PW31Gh5qY8lD x1kkWbngW7Ki7EUj4Pf038sNTqmVg+05r67wYMegvPf1tjLLEtx6NGuxz+52zNoTgprN wP97s9tkySIHIvVTjsJ7bAYZFHs5wUpSq41iYuM+hkQIzJN+t7BI9tdZBhxehJeUcaqA QfqA== 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=V5FFsBFgHUhMULH5R/2W2d7CiGv9Ywx4g/dJO2Cav9b/EyWL9Oi8B9Ts+Npx6eObo6 itXx5fn1bOLjWCW3Yb/mxEagydZWYF+VvlejvGfQDjy8zEXZWOeYeZL/0kGmrC4i234D Kx40vLZfbVt+QccAT0mzjPDUz1XVFCqX2jYNvmDym78fSnwanjKLB9E2dSJRQyxS/UEX pZvlMlo77aCa/oJ3YY5UAUfi+74tBJGgZzSAWV+xALflLsxNv8pka05pO86EqmDjZpBX MJCmeEmi4Zb0/Xt/LnxYDl8tIdhOyKxL4sa1hTNpNC114sOIH0uTgDS/9LgBiZajOYBP Sedg== X-Gm-Message-State: AOPr4FUeEu4kHpmsvyod9PDmT/skhj/K3heQVsWksLrLnc7YdNbHqTkLih0fznyG6noLYQv/ X-Received: by 10.28.113.67 with SMTP id m64mr2908521wmc.58.1462446601871; Thu, 05 May 2016 04:10:01 -0700 (PDT) Received: from sven-desktop.home.narfation.org (p200300C593C34EFD0000000000002E16.dip0.t-ipconnect.de. [2003:c5:93c3:4efd::2e16]) by smtp.gmail.com with ESMTPSA id q125sm2645946wmd.19.2016.05.05.04.10.01 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 05 May 2016 04:10:01 -0700 (PDT) From: Sven Eckelmann To: b.a.t.m.a.n@lists.open-mesh.org Date: Thu, 5 May 2016 13:09:41 +0200 Message-Id: <1462446587-5304-4-git-send-email-sven.eckelmann@open-mesh.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1462446587-5304-1-git-send-email-sven.eckelmann@open-mesh.com> References: <1462446587-5304-1-git-send-email-sven.eckelmann@open-mesh.com> Subject: [B.A.T.M.A.N.] [PATCH v5 3/5] 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, + }, }; /**