Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 66be7d2b authored by Henning Rogge's avatar Henning Rogge Committed by Johannes Berg
Browse files

cfg80211: add ops to query mesh proxy path table



Add two new cfg80211 operations for querying a table with proxied mesh
paths.

Signed-off-by: default avatarHenning Rogge <henning.rogge@fkie.fraunhofer.de>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent cc61d8df
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -2146,6 +2146,8 @@ struct cfg80211_qos_map {
 * @change_mpath: change a given mesh path
 * @get_mpath: get a mesh path for the given parameters
 * @dump_mpath: dump mesh path callback -- resume dump at index @idx
 * @get_mpp: get a mesh proxy path for the given parameters
 * @dump_mpp: dump mesh proxy path callback -- resume dump at index @idx
 * @join_mesh: join the mesh network with the specified parameters
 *	(invoked with the wireless_dev mutex held)
 * @leave_mesh: leave the current mesh network
@@ -2396,6 +2398,11 @@ struct cfg80211_ops {
	int	(*dump_mpath)(struct wiphy *wiphy, struct net_device *dev,
			      int idx, u8 *dst, u8 *next_hop,
			      struct mpath_info *pinfo);
	int	(*get_mpp)(struct wiphy *wiphy, struct net_device *dev,
			   u8 *dst, u8 *mpp, struct mpath_info *pinfo);
	int	(*dump_mpp)(struct wiphy *wiphy, struct net_device *dev,
			    int idx, u8 *dst, u8 *mpp,
			    struct mpath_info *pinfo);
	int	(*get_mesh_config)(struct wiphy *wiphy,
				struct net_device *dev,
				struct mesh_config *conf);
+6 −0
Original line number Diff line number Diff line
@@ -738,6 +738,10 @@
 *	before removing a station entry entirely, or before disassociating
 *	or similar, cleanup will happen in the driver/device in this case.
 *
 * @NL80211_CMD_GET_MPP: Get mesh path attributes for mesh proxy path to
 *	destination %NL80211_ATTR_MAC on the interface identified by
 *	%NL80211_ATTR_IFINDEX.
 *
 * @NL80211_CMD_MAX: highest used command number
 * @__NL80211_CMD_AFTER_LAST: internal use
 */
@@ -912,6 +916,8 @@ enum nl80211_commands {
	NL80211_CMD_ADD_TX_TS,
	NL80211_CMD_DEL_TX_TS,

	NL80211_CMD_GET_MPP,

	/* add new commands above here */

	/* used to define NL80211_CMD_MAX below */
+99 −0
Original line number Diff line number Diff line
@@ -4624,6 +4624,96 @@ static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
	return rdev_del_mpath(rdev, dev, dst);
}

static int nl80211_get_mpp(struct sk_buff *skb, struct genl_info *info)
{
	struct cfg80211_registered_device *rdev = info->user_ptr[0];
	int err;
	struct net_device *dev = info->user_ptr[1];
	struct mpath_info pinfo;
	struct sk_buff *msg;
	u8 *dst = NULL;
	u8 mpp[ETH_ALEN];

	memset(&pinfo, 0, sizeof(pinfo));

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

	dst = nla_data(info->attrs[NL80211_ATTR_MAC]);

	if (!rdev->ops->get_mpp)
		return -EOPNOTSUPP;

	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
		return -EOPNOTSUPP;

	err = rdev_get_mpp(rdev, dev, dst, mpp, &pinfo);
	if (err)
		return err;

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

	if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
			       dev, dst, mpp, &pinfo) < 0) {
		nlmsg_free(msg);
		return -ENOBUFS;
	}

	return genlmsg_reply(msg, info);
}

static int nl80211_dump_mpp(struct sk_buff *skb,
			    struct netlink_callback *cb)
{
	struct mpath_info pinfo;
	struct cfg80211_registered_device *rdev;
	struct wireless_dev *wdev;
	u8 dst[ETH_ALEN];
	u8 mpp[ETH_ALEN];
	int path_idx = cb->args[2];
	int err;

	err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
	if (err)
		return err;

	if (!rdev->ops->dump_mpp) {
		err = -EOPNOTSUPP;
		goto out_err;
	}

	if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
		err = -EOPNOTSUPP;
		goto out_err;
	}

	while (1) {
		err = rdev_dump_mpp(rdev, wdev->netdev, path_idx, dst,
				    mpp, &pinfo);
		if (err == -ENOENT)
			break;
		if (err)
			goto out_err;

		if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
				       cb->nlh->nlmsg_seq, NLM_F_MULTI,
				       wdev->netdev, dst, mpp,
				       &pinfo) < 0)
			goto out;

		path_idx++;
	}

 out:
	cb->args[2] = path_idx;
	err = skb->len;
 out_err:
	nl80211_finish_wdev_dump(rdev);
	return err;
}

static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
{
	struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -9773,6 +9863,15 @@ static const struct genl_ops nl80211_ops[] = {
		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
				  NL80211_FLAG_NEED_RTNL,
	},
	{
		.cmd = NL80211_CMD_GET_MPP,
		.doit = nl80211_get_mpp,
		.dumpit = nl80211_dump_mpp,
		.policy = nl80211_policy,
		.flags = GENL_ADMIN_PERM,
		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
				  NL80211_FLAG_NEED_RTNL,
	},
	{
		.cmd = NL80211_CMD_SET_MPATH,
		.doit = nl80211_set_mpath,
+26 −1
Original line number Diff line number Diff line
@@ -263,6 +263,18 @@ static inline int rdev_get_mpath(struct cfg80211_registered_device *rdev,

}

static inline int rdev_get_mpp(struct cfg80211_registered_device *rdev,
			       struct net_device *dev, u8 *dst, u8 *mpp,
			       struct mpath_info *pinfo)
{
	int ret;

	trace_rdev_get_mpp(&rdev->wiphy, dev, dst, mpp);
	ret = rdev->ops->get_mpp(&rdev->wiphy, dev, dst, mpp, pinfo);
	trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo);
	return ret;
}

static inline int rdev_dump_mpath(struct cfg80211_registered_device *rdev,
				  struct net_device *dev, int idx, u8 *dst,
				  u8 *next_hop, struct mpath_info *pinfo)
@@ -276,6 +288,19 @@ static inline int rdev_dump_mpath(struct cfg80211_registered_device *rdev,
	return ret;
}

static inline int rdev_dump_mpp(struct cfg80211_registered_device *rdev,
				struct net_device *dev, int idx, u8 *dst,
				u8 *mpp, struct mpath_info *pinfo)

{
	int ret;

	trace_rdev_dump_mpp(&rdev->wiphy, dev, idx, dst, mpp);
	ret = rdev->ops->dump_mpp(&rdev->wiphy, dev, idx, dst, mpp, pinfo);
	trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo);
	return ret;
}

static inline int
rdev_get_mesh_config(struct cfg80211_registered_device *rdev,
		     struct net_device *dev, struct mesh_config *conf)
+45 −0
Original line number Diff line number Diff line
@@ -801,6 +801,51 @@ TRACE_EVENT(rdev_dump_mpath,
		  MAC_PR_ARG(next_hop))
);

TRACE_EVENT(rdev_get_mpp,
	TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
		 u8 *dst, u8 *mpp),
	TP_ARGS(wiphy, netdev, dst, mpp),
	TP_STRUCT__entry(
		WIPHY_ENTRY
		NETDEV_ENTRY
		MAC_ENTRY(dst)
		MAC_ENTRY(mpp)
	),
	TP_fast_assign(
		WIPHY_ASSIGN;
		NETDEV_ASSIGN;
		MAC_ASSIGN(dst, dst);
		MAC_ASSIGN(mpp, mpp);
	),
	TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", destination: " MAC_PR_FMT
		  ", mpp: " MAC_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG,
		  MAC_PR_ARG(dst), MAC_PR_ARG(mpp))
);

TRACE_EVENT(rdev_dump_mpp,
	TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int idx,
		 u8 *dst, u8 *mpp),
	TP_ARGS(wiphy, netdev, idx, mpp, dst),
	TP_STRUCT__entry(
		WIPHY_ENTRY
		NETDEV_ENTRY
		MAC_ENTRY(dst)
		MAC_ENTRY(mpp)
		__field(int, idx)
	),
	TP_fast_assign(
		WIPHY_ASSIGN;
		NETDEV_ASSIGN;
		MAC_ASSIGN(dst, dst);
		MAC_ASSIGN(mpp, mpp);
		__entry->idx = idx;
	),
	TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", index: %d, destination: "
		  MAC_PR_FMT ", mpp: " MAC_PR_FMT,
		  WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx, MAC_PR_ARG(dst),
		  MAC_PR_ARG(mpp))
);

TRACE_EVENT(rdev_return_int_mpath_info,
	TP_PROTO(struct wiphy *wiphy, int ret, struct mpath_info *pinfo),
	TP_ARGS(wiphy, ret, pinfo),