Skip to content

Commit 04d6472

Browse files
authored
enable mld_ap configuration (#352)
* enable mld_ap configuration * don't break old linux for backward compitibility
1 parent 8ef42a6 commit 04d6472

11 files changed

Lines changed: 178 additions & 1 deletion

File tree

api/protos/WifiCore.proto

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,11 +208,12 @@ message Dot11AccessPointConfiguration
208208
Dot11MacAddress Bssid = 2;
209209
Dot11PhyType PhyType = 3;
210210
Dot11AuthenticationData AuthenticationData = 4;
211-
Dot11AuthenticationDot1x AuthenticationDot1x = 9;
212211
repeated Dot11AuthenticationAlgorithm AuthenticationAlgorithms = 5;
213212
repeated Dot11CipherSuiteConfiguration PairwiseCipherSuites = 6;
214213
repeated Dot11AkmSuite AkmSuites = 7;
215214
repeated Dot11FrequencyBand FrequencyBands = 8;
215+
Dot11AuthenticationDot1x AuthenticationDot1x = 9;
216+
bool mldAp = 10;
216217
}
217218

218219
message Dot11AccessPointCapabilities

src/common/net/wifi/core/include/microsoft/net/wifi/IAccessPointController.hxx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,15 @@ struct IAccessPointController
157157
*/
158158
virtual AccessPointOperationStatus
159159
SetRadiusConfiguration(Ieee8021xRadiusConfiguration radiusConfiguration) noexcept = 0;
160+
161+
/**
162+
* @brief Set whether the access point is a Multi-Link Device (MLD) AP.
163+
*
164+
* @param mldAp True if the access point is an MLD AP, false otherwise.
165+
* @return AccessPointOperationStatus
166+
*/
167+
virtual AccessPointOperationStatus
168+
SetMldAp(bool mldAp) noexcept = 0;
160169
};
161170

162171
/**

src/common/service/NetRemoteService.cxx

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <ranges>
1111
#include <string>
1212
#include <string_view>
13+
#include <sys/utsname.h>
1314
#include <thread>
1415
#include <utility>
1516
#include <vector>
@@ -613,6 +614,32 @@ NetRemoteService::WifiAccessPointEnableImpl(std::string_view accessPointId, cons
613614
return wifiOperationStatus;
614615
}
615616
}
617+
618+
// Check Linux kernel version before setting MLD AP
619+
bool shouldSetMldAp = false;
620+
struct utsname buffer;
621+
if (uname(&buffer) == 0) {
622+
std::string release(buffer.release);
623+
std::smatch match;
624+
std::regex versionRegex(R"((\d+)\.(\d+))");
625+
if (std::regex_search(release, match, versionRegex) && match.size() >= 3) {
626+
int major = std::stoi(match[1]);
627+
int minor = std::stoi(match[2]);
628+
if (major > 6 || (major == 6 && minor >= 11)) {
629+
shouldSetMldAp = true;
630+
}
631+
}
632+
}
633+
634+
if (shouldSetMldAp) {
635+
bool mldAp = dot11AccessPointConfiguration->mldap();
636+
wifiOperationStatus = WifiAccessPointSetMldApImpl(accessPointId, mldAp, accessPointController);
637+
if (wifiOperationStatus.code() != WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeSucceeded) {
638+
return wifiOperationStatus;
639+
}
640+
} else {
641+
LOGW << "Skipping setting MLD AP configuration due to unsupported kernel version";
642+
}
616643
}
617644

618645
// Obtain current operational state.
@@ -1467,6 +1494,36 @@ NetRemoteService::WifiAccessPointSetAuthenticationDot1xImpl(std::string_view acc
14671494
return wifiOperationStatus;
14681495
}
14691496

1497+
WifiAccessPointOperationStatus
1498+
NetRemoteService::WifiAccessPointSetMldApImpl(std::string_view accessPointId, bool mldAp, std::shared_ptr<IAccessPointController> accessPointController)
1499+
{
1500+
WifiAccessPointOperationStatus wifiOperationStatus{};
1501+
1502+
AccessPointOperationStatus operationStatus{ accessPointId };
1503+
1504+
// Create an AP controller for the requested AP if one wasn't specified.
1505+
if (accessPointController == nullptr) {
1506+
operationStatus = TryGetAccessPointController(accessPointId, accessPointController);
1507+
if (!operationStatus.Succeeded() || accessPointController == nullptr) {
1508+
wifiOperationStatus.set_code(ToDot11AccessPointOperationStatusCode(operationStatus.Code));
1509+
wifiOperationStatus.set_message(std::format("Failed to create access point controller for access point {} - {}", accessPointId, operationStatus.ToString()));
1510+
return wifiOperationStatus;
1511+
}
1512+
}
1513+
1514+
// Attempt to set the MLD AP setting.
1515+
operationStatus = accessPointController->SetMldAp(mldAp);
1516+
if (!operationStatus.Succeeded()) {
1517+
wifiOperationStatus.set_code(ToDot11AccessPointOperationStatusCode(operationStatus.Code));
1518+
wifiOperationStatus.set_message(std::format("Failed to set MLD AP setting for access point {} - {}", accessPointId, operationStatus.ToString()));
1519+
return wifiOperationStatus;
1520+
}
1521+
1522+
wifiOperationStatus.set_code(WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeSucceeded);
1523+
1524+
return wifiOperationStatus;
1525+
}
1526+
14701527
using google::protobuf::Map;
14711528

14721529
WifiAccessPointOperationStatus

src/common/service/include/microsoft/net/remote/service/NetRemoteService.hxx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,17 @@ protected:
370370
Microsoft::Net::Remote::Wifi::WifiAccessPointOperationStatus
371371
WifiAccessPointSetAuthenticationDot1xImpl(std::string_view accessPointId, const Microsoft::Net::Wifi::Dot11AuthenticationDot1x& dot11AuthenticationDot1x, std::shared_ptr<Microsoft::Net::Wifi::IAccessPointController> accessPointController = nullptr);
372372

373+
/**
374+
* @brief Set whether the access point is a Multi-Link Device Access Point (MLD AP).
375+
*
376+
* @param accessPointId The access point identifier.
377+
* @param mldAp True to configure the access point as an MLD AP, false otherwise.
378+
* @param accessPointController The access point controller for the specified access point (optional).
379+
* @return Microsoft::Net::Remote::Wifi::WifiAccessPointOperationStatus
380+
*/
381+
Microsoft::Net::Remote::Wifi::WifiAccessPointOperationStatus
382+
WifiAccessPointSetMldApImpl(std::string_view accessPointId, bool mldAp, std::shared_ptr<Microsoft::Net::Wifi::IAccessPointController> accessPointController = nullptr);
383+
373384
/**
374385
* @brief Get the sttaic attributes of the specified access point.
375386
*

src/linux/net/wifi/core/AccessPointControllerLinux.cxx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,29 @@ AccessPointControllerLinux::SetRadiusConfiguration(Ieee8021xRadiusConfiguration
664664
return status;
665665
}
666666

667+
AccessPointOperationStatus
668+
AccessPointControllerLinux::SetMldAp(bool mldAp) noexcept
669+
{
670+
AccessPointOperationStatus status{ GetInterfaceName() };
671+
const AccessPointOperationStatusLogOnExit logStatusOnExit(&status);
672+
673+
AUDITD << std::format("Attempting to set MLD AP for AP {} to {}", status.AccessPointId, mldAp ? "enabled" : "disabled");
674+
675+
std::string_view propertyValueToSet = mldAp ? Wpa::ProtocolHostapd::PropertyEnabled : Wpa::ProtocolHostapd::PropertyDisabled;
676+
677+
// Set the hostapd "mld_ap" property.
678+
try {
679+
m_hostapd.SetProperty(Wpa::ProtocolHostapd::PropertyNameMldAp, propertyValueToSet, EnforceConfigurationChange::Now);
680+
} catch (const Wpa::HostapdException& ex) {
681+
status.Code = AccessPointOperationStatusCode::InternalError;
682+
status.Details = std::format("failed to set hostapd property '{}' to '{}' - {}", Wpa::ProtocolHostapd::PropertyNameMldAp, propertyValueToSet, ex.what());
683+
return status;
684+
}
685+
686+
status.Code = AccessPointOperationStatusCode::Succeeded;
687+
return status;
688+
}
689+
667690
std::unique_ptr<IAccessPointController>
668691
AccessPointControllerLinuxFactory::Create(std::string_view interfaceName)
669692
{

src/linux/net/wifi/core/include/microsoft/net/wifi/AccessPointControllerLinux.hxx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,15 @@ struct AccessPointControllerLinux :
156156
AccessPointOperationStatus
157157
SetRadiusConfiguration(Microsoft::Net::Ieee8021xRadiusConfiguration radiusConfiguration) noexcept override;
158158

159+
/**
160+
* @brief Set whether the access point is a Multi-Link Device (MLD) AP.
161+
*
162+
* @param mldAp True if the access point is an MLD AP, false otherwise.
163+
* @return AccessPointOperationStatus
164+
*/
165+
AccessPointOperationStatus
166+
SetMldAp(bool mldAp) noexcept override;
167+
159168
private:
160169
Wpa::Hostapd m_hostapd;
161170
};

src/linux/net/wifi/wpa-controller/include/Wpa/ProtocolHostapd.hxx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,9 @@ struct ProtocolHostapd :
684684
static constexpr auto PropertyValueSaePasswordClearAll = "";
685685
static constexpr auto PropertyValueSaeKeyValueSeparator = "|";
686686

687+
// Wi-Fi 7 (IEEE 802.11be) properties.
688+
static constexpr auto PropertyNameMldAp = "mld_ap";
689+
687690
// Property names for "GET_CONFIG" command.
688691
static constexpr auto PropertyNameKeyManagement = "key_mgmt";
689692
static constexpr auto PropertyNameGroupCipher = "group_cipher";

tests/unit/TestNetRemoteServiceClient.cxx

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,48 @@ TEST_CASE("WifiAccessPointEnable API", "[basic][rpc][client][remote]")
314314
REQUIRE(result.has_status());
315315
REQUIRE(result.status().code() == WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeSucceeded);
316316
}
317+
318+
SECTION("Enable MLD AP")
319+
{
320+
// Enable the MLD AP flag via the configuration and verify it sticks.
321+
Dot11AccessPointConfiguration apConfiguration{};
322+
apConfiguration.set_mldap(true);
323+
324+
WifiAccessPointEnableRequest request{};
325+
request.set_accesspointid(InterfaceName1);
326+
*request.mutable_configuration() = std::move(apConfiguration);
327+
328+
WifiAccessPointEnableResult result{};
329+
grpc::ClientContext clientContext{};
330+
331+
auto status = client->WifiAccessPointEnable(&clientContext, request, &result);
332+
REQUIRE(status.ok());
333+
REQUIRE(result.accesspointid() == request.accesspointid());
334+
REQUIRE(result.has_status());
335+
REQUIRE(result.status().code() == WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeSucceeded);
336+
REQUIRE(apTest1->MldAp == true);
337+
}
338+
339+
SECTION("Disable MLD AP")
340+
{
341+
// Disable the MLD AP flag via the configuration and verify it sticks.
342+
Dot11AccessPointConfiguration apConfiguration{};
343+
apConfiguration.set_mldap(false);
344+
345+
WifiAccessPointEnableRequest request{};
346+
request.set_accesspointid(InterfaceName2);
347+
*request.mutable_configuration() = std::move(apConfiguration);
348+
349+
WifiAccessPointEnableResult result{};
350+
grpc::ClientContext clientContext{};
351+
352+
auto status = client->WifiAccessPointEnable(&clientContext, request, &result);
353+
REQUIRE(status.ok());
354+
REQUIRE(result.accesspointid() == request.accesspointid());
355+
REQUIRE(result.has_status());
356+
REQUIRE(result.status().code() == WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeSucceeded);
357+
REQUIRE(apTest2->MldAp == false);
358+
}
317359
}
318360

319361
TEST_CASE("WifiAccessPointDisable API", "[basic][rpc][client][remote]")

tests/unit/net/wifi/helpers/AccessPointControllerTest.cxx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,18 @@ AccessPointControllerTest::SetRadiusConfiguration(Ieee8021xRadiusConfiguration r
203203
return AccessPointOperationStatus::MakeSucceeded(AccessPoint->InterfaceName);
204204
}
205205

206+
AccessPointOperationStatus
207+
AccessPointControllerTest::SetMldAp(bool mldAp) noexcept
208+
{
209+
assert(AccessPoint != nullptr);
210+
if (AccessPoint == nullptr) {
211+
return AccessPointOperationStatus::InvalidAccessPoint("null AccessPoint");
212+
}
213+
214+
AccessPoint->MldAp = mldAp;
215+
return AccessPointOperationStatus::MakeSucceeded(AccessPoint->InterfaceName);
216+
}
217+
206218
AccessPointControllerFactoryTest::AccessPointControllerFactoryTest(AccessPointTest *accessPoint) :
207219
AccessPoint(accessPoint)
208220
{}

tests/unit/net/wifi/helpers/include/microsoft/net/wifi/test/AccessPointControllerTest.hxx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,15 @@ struct AccessPointControllerTest final :
166166
*/
167167
AccessPointOperationStatus
168168
SetRadiusConfiguration(Ieee8021xRadiusConfiguration radiusConfiguration) noexcept override;
169+
170+
/**
171+
* @brief Set whether the access point is a Multi-Link Device (MLD) AP.
172+
*
173+
* @param mldAp True if the access point is an MLD AP, false otherwise.
174+
* @return AccessPointOperationStatus
175+
*/
176+
AccessPointOperationStatus
177+
SetMldAp(bool mldAp) noexcept override;
169178
};
170179

171180
/**

0 commit comments

Comments
 (0)