chiark / gitweb /
networkd: dhcp add vendor class indentifier option 60
authorSusant Sahani <susant@redhat.com>
Mon, 14 Jul 2014 08:04:18 +0000 (13:34 +0530)
committerTom Gundersen <teg@jklm.no>
Mon, 14 Jul 2014 09:39:20 +0000 (11:39 +0200)
Vendor Class Identifier be used by DHCP clients to identify
their vendor type and configuration. When using this option,
vendors can define their own specific identifier values, such
as to convey a particular hardware or operating system
configuration or other identifying information.

Vendor-specified DHCP options—features that let administrators assign
separate options to clients with similar configuration requirements.
For example, if DHCP-aware clients for example we want to separate
different gateway and option for different set of people
(dev/test/hr/finance) in a org or devices for example web/database
servers or let's say in a embedded device etc and require a different
default gateway or DNS server than the rest of clients.

man/systemd.network.xml
src/libsystemd-network/dhcp-protocol.h
src/libsystemd-network/sd-dhcp-client.c
src/network/networkd-link.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd.h
src/systemd/sd-dhcp-client.h

index 738977ee8dfde98c7d6c6c8f2ac755429a8f0fe7..3c4fdd20c8c890ea683fb87048b3df4cdabf9fdd 100644 (file)
                                                 if, say, the root filesystem relies on this connection. Defaults to false.</para>
                                         </listitem>
                                 </varlistentry>
+                                    <varlistentry>
+                                        <term><varname>VendorClassIdentifier=</varname></term>
+                                        <listitem>
+                                                <para>The vendor class identifier used to identify vendor type and configuration.</para>
+                                        </listitem>
+                                </varlistentry>
                        </variablelist>
 
         </refsect1>
index 8cbd98e4ecef9c2a2f13ef5edc75a6cbf5aec4f8..7c06b5ab682056cfe0424d9ee3c702cea55874e6 100644 (file)
@@ -131,6 +131,7 @@ enum {
         DHCP_OPTION_MAXIMUM_MESSAGE_SIZE        = 57,
         DHCP_OPTION_RENEWAL_T1_TIME             = 58,
         DHCP_OPTION_REBINDING_T2_TIME           = 59,
+        DHCP_OPTION_VENDOR_CLASS_IDENTIFIER     = 60,
         DHCP_OPTION_CLIENT_IDENTIFIER           = 61,
         DHCP_OPTION_CLASSLESS_STATIC_ROUTE      = 121,
         DHCP_OPTION_END                         = 255,
index 6b19666c3bc46707a44ce6aecb105be3d9635ef0..3c389931cd17583a9ce01646dbcdb962f796a56e 100644 (file)
@@ -57,6 +57,7 @@ struct sd_dhcp_client {
                 struct ether_addr mac_addr;
         } _packed_ client_id;
         char *hostname;
+        char *vendor_class_identifier;
         uint32_t xid;
         usec_t start_time;
         uint16_t secs;
@@ -200,6 +201,23 @@ int sd_dhcp_client_set_hostname(sd_dhcp_client *client,
         return 0;
 }
 
+int sd_dhcp_client_set_vendor_class_identifier(sd_dhcp_client *client,
+                                               const char *vci) {
+        char *new_vci = NULL;
+
+        assert_return(client, -EINVAL);
+
+        new_vci = strdup(vci);
+        if (!new_vci)
+                return -ENOMEM;
+
+        free(client->vendor_class_identifier);
+
+        client->vendor_class_identifier = new_vci;
+
+        return 0;
+}
+
 int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) {
         assert_return(client, -EINVAL);
         assert_return(ret, -EINVAL);
@@ -419,6 +437,15 @@ static int client_send_discover(sd_dhcp_client *client) {
                         return r;
         }
 
+        if (client->vendor_class_identifier) {
+                r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
+                                       DHCP_OPTION_VENDOR_CLASS_IDENTIFIER,
+                                       strlen(client->vendor_class_identifier),
+                                       client->vendor_class_identifier);
+                if (r < 0)
+                        return r;
+        }
+
         r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
                                DHCP_OPTION_END, 0, NULL);
         if (r < 0)
@@ -1406,6 +1433,7 @@ sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) {
 
                 free(client->req_opts);
                 free(client->hostname);
+                free(client->vendor_class_identifier);
                 free(client);
         }
 
index 5f6c22a611bf5a2e40c77376a88ed4f37fa7a624..9e057ce0ff8bae0b7f6ea23c7e80dc0fd26af8c5 100644 (file)
@@ -2023,6 +2023,13 @@ static int link_configure(Link *link) {
                                         return r;
                         }
                 }
+
+                if (link->network->dhcp_vendor_class_identifier) {
+                        r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client,
+                                                                       link->network->dhcp_vendor_class_identifier);
+                        if (r < 0)
+                                return r;
+                }
         }
 
         if (link->network->dhcp_server) {
index 50cb0f8be9ec1e37fe32b47ce80c55161aaf8d1a..5c1c013373ce9bcecece7f8f97d58fe5d7447473 100644 (file)
@@ -51,6 +51,7 @@ DHCP.UseDomainName,          config_parse_bool,                  0,
 DHCP.UseRoutes,              config_parse_bool,                  0,                             offsetof(Network, dhcp_routes)
 DHCP.SendHostname,           config_parse_bool,                  0,                             offsetof(Network, dhcp_sendhost)
 DHCP.CriticalConnection,     config_parse_bool,                  0,                             offsetof(Network, dhcp_critical)
+DHCP.VendorClassIdentifier,  config_parse_string,                0,                             offsetof(Network, dhcp_vendor_class_identifier)
 /* backwards compatibility: do not add new entries to this section */
 DHCPv4.UseDNS,               config_parse_bool,                  0,                             offsetof(Network, dhcp_dns)
 DHCPv4.UseMTU,               config_parse_bool,                  0,                             offsetof(Network, dhcp_mtu)
index 9f6de185387fd9e3ae1bcfce67add39df530419e..c108ad235828a389ef33c675190c31765b82766b 100644 (file)
@@ -166,6 +166,7 @@ void network_free(Network *network) {
         free(network->match_name);
 
         free(network->description);
+        free(network->dhcp_vendor_class_identifier);
 
         while ((address = network->ntp)) {
                 LIST_REMOVE(addresses, network->ntp, address);
index aca3b8dd24a7264b50742ed1d41387bea6cf0fb5..0f0ecd5c434c0ba1ab8fd26d4f6a728c01021df5 100644 (file)
@@ -175,6 +175,8 @@ struct Network {
         char *match_driver;
         char *match_type;
         char *match_name;
+        char *dhcp_vendor_class_identifier;
+
         Condition *match_host;
         Condition *match_virt;
         Condition *match_kernel;
index c3ea0592f69844e5668b6a501cbe5815620ea2d0..9ab6105e5b67d9870fb2f583e9e4c26a183f88cc 100644 (file)
@@ -52,6 +52,7 @@ int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index);
 int sd_dhcp_client_set_mac(sd_dhcp_client *client,
                            const struct ether_addr *addr);
 int sd_dhcp_client_set_hostname(sd_dhcp_client *client, const char *hostname);
+int sd_dhcp_client_set_vendor_class_identifier(sd_dhcp_client *client, const char *vci);
 int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret);
 
 int sd_dhcp_client_stop(sd_dhcp_client *client);