]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: add support matching based on BSSID= 13142/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 24 Jul 2019 06:32:24 +0000 (15:32 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 14 Oct 2019 16:59:56 +0000 (01:59 +0900)
man/systemd.network.xml
src/libsystemd-network/network-internal.c
src/libsystemd-network/network-internal.h
src/network/networkd-link.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h
src/network/test-network.c
src/udev/net/link-config.c
test/fuzz/fuzz-network-parser/directives.network

index 03c488d7dcc386f26a04c1eb2dc0e97a4c0b66f9..3863f3d0047c63640321e74feb9d469743b0fe86 100644 (file)
             </para>
           </listitem>
         </varlistentry>
+        <varlistentry>
+          <term><varname>BSSID=</varname></term>
+          <listitem>
+            <para>A whitespace-separated list of hardware address of the currently connected wireless
+            LAN. Use full colon-, hyphen- or dot-delimited hexadecimal. See the example in
+            <varname>MACAddress=</varname>. This option may appear more than one, in which case the
+            lists are merged. If the empty string is assigned to this option, the list of BSSID defined
+            prior to this is reset.</para>
+          </listitem>
+        </varlistentry>
         <varlistentry>
           <term><varname>Host=</varname></term>
           <listitem>
index 08c756788e1992aab629e9f6f04f8aa66d890dc6..a8cb4ea28697959ef97a1c90be3cec259cca6ee0 100644 (file)
@@ -143,10 +143,12 @@ bool net_match_config(Set *match_mac,
                       char * const *match_names,
                       char * const *match_property,
                       char * const *match_ssid,
+                      Set *match_bssid,
                       sd_device *device,
                       const struct ether_addr *dev_mac,
                       const char *dev_name,
-                      const char *ssid) {
+                      const char *ssid,
+                      const struct ether_addr *bssid) {
 
         const char *dev_path = NULL, *dev_driver = NULL, *dev_type = NULL, *mac_str;
 
@@ -183,6 +185,9 @@ bool net_match_config(Set *match_mac,
         if (!net_condition_test_strv(match_ssid, ssid))
                 return false;
 
+        if (match_bssid && (!bssid || !set_contains(match_bssid, bssid)))
+                return false;
+
         return true;
 }
 
index 71aec1a99bb2aae4f2333ae46983a1ed897ad168..f40ad6b1dd3237ed9ded74eb6ec996602b530168 100644 (file)
@@ -21,10 +21,12 @@ bool net_match_config(Set *match_mac,
                       char * const *match_name,
                       char * const *match_property,
                       char * const *match_ssid,
+                      Set *match_bssid,
                       sd_device *device,
                       const struct ether_addr *dev_mac,
                       const char *dev_name,
-                      const char *ssid);
+                      const char *ssid,
+                      const struct ether_addr *bssid);
 
 CONFIG_PARSER_PROTOTYPE(config_parse_net_condition);
 CONFIG_PARSER_PROTOTYPE(config_parse_hwaddr);
index 1c0ae0184c257930cd26fb2605123b22e1aa2566..5fedd3765c50c96a01384adb8744e1ba3bd08ef1 100644 (file)
@@ -2865,7 +2865,7 @@ int link_reconfigure(Link *link) {
                 return 0;
 
         r = network_get(link->manager, link->sd_device, link->ifname,
-                        &link->mac, link->ssid, &network);
+                        &link->mac, link->ssid, &link->bssid, &network);
         if (r == -ENOENT) {
                 link_enter_unmanaged(link);
                 return 0;
@@ -2959,7 +2959,7 @@ static int link_initialized_and_synced(Link *link) {
                         return r;
 
                 r = network_get(link->manager, link->sd_device, link->ifname,
-                                &link->mac, link->ssid, &network);
+                                &link->mac, link->ssid, &link->bssid, &network);
                 if (r == -ENOENT) {
                         link_enter_unmanaged(link);
                         return 0;
index 95d3331222385bc4ba530d58e979de5699707261..832303aaa72239bdd602337a5b1dfa511285c5bc 100644 (file)
@@ -30,6 +30,7 @@ Match.Path,                             config_parse_match_strv,
 Match.Driver,                           config_parse_match_strv,                         0,                             offsetof(Network, match_driver)
 Match.Type,                             config_parse_match_strv,                         0,                             offsetof(Network, match_type)
 Match.SSID,                             config_parse_match_strv,                         0,                             offsetof(Network, match_ssid)
+Match.BSSID,                            config_parse_hwaddrs,                            0,                             offsetof(Network, match_bssid)
 Match.Name,                             config_parse_match_ifnames,                      0,                             offsetof(Network, match_name)
 Match.Property,                         config_parse_match_property,                     0,                             offsetof(Network, match_property)
 Match.Host,                             config_parse_net_condition,                      CONDITION_HOST,                offsetof(Network, conditions)
index b3bc598c4428d575a9cb8fe36beb173591b5e777..7a2ee5ff85b22b3162adb16e4bfe030542ecf192 100644 (file)
@@ -548,6 +548,7 @@ static Network *network_free(Network *network) {
         strv_free(network->match_name);
         strv_free(network->match_property);
         strv_free(network->match_ssid);
+        set_free_free(network->match_bssid);
         condition_free_list(network->conditions);
 
         free(network->description);
@@ -654,7 +655,7 @@ int network_get_by_name(Manager *manager, const char *name, Network **ret) {
 
 int network_get(Manager *manager, sd_device *device,
                 const char *ifname, const struct ether_addr *address,
-                const char *ssid, Network **ret) {
+                const char *ssid, const struct ether_addr *bssid, Network **ret) {
         Network *network;
         Iterator i;
 
@@ -664,8 +665,8 @@ int network_get(Manager *manager, sd_device *device,
         ORDERED_HASHMAP_FOREACH(network, manager->networks, i)
                 if (net_match_config(network->match_mac, network->match_path, network->match_driver,
                                      network->match_type, network->match_name, network->match_property,
-                                     network->match_ssid,
-                                     device, address, ifname, ssid)) {
+                                     network->match_ssid, network->match_bssid,
+                                     device, address, ifname, ssid, bssid)) {
                         if (network->match_name && device) {
                                 const char *attr;
                                 uint8_t name_assign_type = NET_NAME_UNKNOWN;
index 883f0fab6ef2d513f94a2ce663d4f934b2dd2871..fd98d88d6a0af04ae71093e98649153a1da2c402 100644 (file)
@@ -64,6 +64,7 @@ struct Network {
         char **match_name;
         char **match_property;
         char **match_ssid;
+        Set *match_bssid;
         LIST_HEAD(Condition, conditions);
 
         char *description;
@@ -286,7 +287,8 @@ int network_load_one(Manager *manager, const char *filename);
 int network_verify(Network *network);
 
 int network_get_by_name(Manager *manager, const char *name, Network **ret);
-int network_get(Manager *manager, sd_device *device, const char *ifname, const struct ether_addr *mac, const char *ssid, Network **ret);
+int network_get(Manager *manager, sd_device *device, const char *ifname, const struct ether_addr *mac,
+                const char *ssid, const struct ether_addr *bssid, Network **ret);
 int network_apply(Network *network, Link *link);
 void network_apply_anonymize_if_set(Network *network);
 
index 50b5cc047c8a6747ba2714cb540c14365e0b6d0d..130adcbca841acb35559341108019a5166d114c7 100644 (file)
@@ -125,7 +125,7 @@ static void test_network_get(Manager *manager, sd_device *loopback) {
 
         /* let's assume that the test machine does not have a .network file
            that applies to the loopback device... */
-        assert_se(network_get(manager, loopback, "lo", &mac, NULL, &network) == -ENOENT);
+        assert_se(network_get(manager, loopback, "lo", &mac, NULL, NULL, &network) == -ENOENT);
         assert_se(!network);
 }
 
index 62974b7c9588939f95822b3f42207af336a8b0de..b84caaf45961dbb16c84025dc9ae0116519206f0 100644 (file)
@@ -242,8 +242,8 @@ int link_config_get(link_config_ctx *ctx, sd_device *device, link_config **ret)
 
         LIST_FOREACH(links, link, ctx->links) {
                 if (net_match_config(link->match_mac, link->match_path, link->match_driver,
-                                     link->match_type, link->match_name, link->match_property, NULL,
-                                     device, NULL, NULL, NULL)) {
+                                     link->match_type, link->match_name, link->match_property, NULL, NULL,
+                                     device, NULL, NULL, NULL, NULL)) {
                         if (link->match_name && !strv_contains(link->match_name, "*")) {
                                 unsigned name_assign_type = NET_NAME_UNKNOWN;
 
index 8f3153079baff2e295e7041a2d2b2820ece09aca..22fe2b4e3372c1faf26a4908f924634aba179142 100644 (file)
@@ -20,6 +20,7 @@ Driver=
 Architecture=
 Path=
 SSID=
+BSSID=
 Name=
 Property=
 Virtualization=