Skip to content

Commit 5ab92e7

Browse files
Rajkumar Manoharanjmberg-intel
authored andcommitted
cfg80211: add support to probe unexercised mesh link
Adding support to allow mesh HWMP to measure link metrics on unexercised direct mesh path by sending some data frames to other mesh points which are not currently selected as a primary traffic path but only 1 hop away. The absence of the primary path to the chosen node makes it necessary to apply some form of marking on a chosen packet stream so that the packets can be properly steered to the selected node for testing, and not by the regular mesh path lookup. Tested-by: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org> Signed-off-by: Rajkumar Manoharan <rmanohar@codeaurora.org> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
1 parent 387bc00 commit 5ab92e7

File tree

5 files changed

+101
-0
lines changed

5 files changed

+101
-0
lines changed

include/net/cfg80211.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3501,6 +3501,9 @@ struct cfg80211_update_owe_info {
35013501
* @update_owe_info: Provide updated OWE info to driver. Driver implementing SME
35023502
* but offloading OWE processing to the user space will get the updated
35033503
* DH IE through this interface.
3504+
*
3505+
* @probe_mesh_link: Probe direct Mesh peer's link quality by sending data frame
3506+
* and overrule HWMP path selection algorithm.
35043507
*/
35053508
struct cfg80211_ops {
35063509
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -3817,6 +3820,8 @@ struct cfg80211_ops {
38173820
struct cfg80211_pmsr_request *request);
38183821
int (*update_owe_info)(struct wiphy *wiphy, struct net_device *dev,
38193822
struct cfg80211_update_owe_info *owe_info);
3823+
int (*probe_mesh_link)(struct wiphy *wiphy, struct net_device *dev,
3824+
const u8 *buf, size_t len);
38203825
};
38213826

38223827
/*

include/uapi/linux/nl80211.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,6 +1070,21 @@
10701070
* OWE AKM by the host drivers that implement SME but rely
10711071
* on the user space for the cryptographic/DH IE processing in AP mode.
10721072
*
1073+
* @NL80211_CMD_PROBE_MESH_LINK: The requirement for mesh link metric
1074+
* refreshing, is that from one mesh point we be able to send some data
1075+
* frames to other mesh points which are not currently selected as a
1076+
* primary traffic path, but which are only 1 hop away. The absence of
1077+
* the primary path to the chosen node makes it necessary to apply some
1078+
* form of marking on a chosen packet stream so that the packets can be
1079+
* properly steered to the selected node for testing, and not by the
1080+
* regular mesh path lookup. Further, the packets must be of type data
1081+
* so that the rate control (often embedded in firmware) is used for
1082+
* rate selection.
1083+
*
1084+
* Here attribute %NL80211_ATTR_MAC is used to specify connected mesh
1085+
* peer MAC address and %NL80211_ATTR_FRAME is used to specify the frame
1086+
* content. The frame is ethernet data.
1087+
*
10731088
* @NL80211_CMD_MAX: highest used command number
10741089
* @__NL80211_CMD_AFTER_LAST: internal use
10751090
*/
@@ -1292,6 +1307,8 @@ enum nl80211_commands {
12921307

12931308
NL80211_CMD_UPDATE_OWE_INFO,
12941309

1310+
NL80211_CMD_PROBE_MESH_LINK,
1311+
12951312
/* add new commands above here */
12961313

12971314
/* used to define NL80211_CMD_MAX below */

net/wireless/nl80211.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13404,6 +13404,47 @@ static int nl80211_update_owe_info(struct sk_buff *skb, struct genl_info *info)
1340413404
return rdev_update_owe_info(rdev, dev, &owe_info);
1340513405
}
1340613406

13407+
static int nl80211_probe_mesh_link(struct sk_buff *skb, struct genl_info *info)
13408+
{
13409+
struct cfg80211_registered_device *rdev = info->user_ptr[0];
13410+
struct net_device *dev = info->user_ptr[1];
13411+
struct wireless_dev *wdev = dev->ieee80211_ptr;
13412+
struct station_info sinfo = {};
13413+
const u8 *buf;
13414+
size_t len;
13415+
u8 *dest;
13416+
int err;
13417+
13418+
if (!rdev->ops->probe_mesh_link || !rdev->ops->get_station)
13419+
return -EOPNOTSUPP;
13420+
13421+
if (!info->attrs[NL80211_ATTR_MAC] ||
13422+
!info->attrs[NL80211_ATTR_FRAME]) {
13423+
GENL_SET_ERR_MSG(info, "Frame or MAC missing");
13424+
return -EINVAL;
13425+
}
13426+
13427+
if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
13428+
return -EOPNOTSUPP;
13429+
13430+
dest = nla_data(info->attrs[NL80211_ATTR_MAC]);
13431+
buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
13432+
len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
13433+
13434+
if (len < sizeof(struct ethhdr))
13435+
return -EINVAL;
13436+
13437+
if (!ether_addr_equal(buf, dest) || is_multicast_ether_addr(buf) ||
13438+
!ether_addr_equal(buf + ETH_ALEN, dev->dev_addr))
13439+
return -EINVAL;
13440+
13441+
err = rdev_get_station(rdev, dev, dest, &sinfo);
13442+
if (err)
13443+
return err;
13444+
13445+
return rdev_probe_mesh_link(rdev, dev, dest, buf, len);
13446+
}
13447+
1340713448
#define NL80211_FLAG_NEED_WIPHY 0x01
1340813449
#define NL80211_FLAG_NEED_NETDEV 0x02
1340913450
#define NL80211_FLAG_NEED_RTNL 0x04
@@ -14241,6 +14282,13 @@ static const struct genl_ops nl80211_ops[] = {
1424114282
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
1424214283
NL80211_FLAG_NEED_RTNL,
1424314284
},
14285+
{
14286+
.cmd = NL80211_CMD_PROBE_MESH_LINK,
14287+
.doit = nl80211_probe_mesh_link,
14288+
.flags = GENL_UNS_ADMIN_PERM,
14289+
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14290+
NL80211_FLAG_NEED_RTNL,
14291+
},
1424414292
};
1424514293

1424614294
static struct genl_family nl80211_fam __ro_after_init = {

net/wireless/rdev-ops.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,4 +1286,17 @@ static inline int rdev_update_owe_info(struct cfg80211_registered_device *rdev,
12861286
return ret;
12871287
}
12881288

1289+
static inline int
1290+
rdev_probe_mesh_link(struct cfg80211_registered_device *rdev,
1291+
struct net_device *dev, const u8 *dest,
1292+
const void *buf, size_t len)
1293+
{
1294+
int ret;
1295+
1296+
trace_rdev_probe_mesh_link(&rdev->wiphy, dev, dest, buf, len);
1297+
ret = rdev->ops->probe_mesh_link(&rdev->wiphy, dev, buf, len);
1298+
trace_rdev_return_int(&rdev->wiphy, ret);
1299+
return ret;
1300+
}
1301+
12891302
#endif /* __CFG80211_RDEV_OPS */

net/wireless/trace.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3421,6 +3421,24 @@ TRACE_EVENT(cfg80211_update_owe_info_event,
34213421
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer))
34223422
);
34233423

3424+
TRACE_EVENT(rdev_probe_mesh_link,
3425+
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
3426+
const u8 *dest, const u8 *buf, size_t len),
3427+
TP_ARGS(wiphy, netdev, dest, buf, len),
3428+
TP_STRUCT__entry(
3429+
WIPHY_ENTRY
3430+
NETDEV_ENTRY
3431+
MAC_ENTRY(dest)
3432+
),
3433+
TP_fast_assign(
3434+
WIPHY_ASSIGN;
3435+
NETDEV_ASSIGN;
3436+
MAC_ASSIGN(dest, dest);
3437+
),
3438+
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT,
3439+
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(dest))
3440+
);
3441+
34243442
#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
34253443

34263444
#undef TRACE_INCLUDE_PATH

0 commit comments

Comments
 (0)