From edb85f0d8d0a84f27308a3728f3fde3c52b9dce2 Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Mon, 14 Jul 2014 13:34:18 +0530 Subject: [PATCH] networkd: dhcp add vendor class indentifier option 60 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 | 6 ++++++ src/libsystemd-network/dhcp-protocol.h | 1 + src/libsystemd-network/sd-dhcp-client.c | 28 ++++++++++++++++++++++++++++ src/network/networkd-link.c | 7 +++++++ src/network/networkd-network-gperf.gperf | 1 + src/network/networkd-network.c | 1 + src/network/networkd.h | 2 ++ src/systemd/sd-dhcp-client.h | 1 + 8 files changed, 47 insertions(+) diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 738977e..3c4fdd2 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -446,6 +446,12 @@ if, say, the root filesystem relies on this connection. Defaults to false. + + VendorClassIdentifier= + + The vendor class identifier used to identify vendor type and configuration. + + diff --git a/src/libsystemd-network/dhcp-protocol.h b/src/libsystemd-network/dhcp-protocol.h index 8cbd98e..7c06b5a 100644 --- a/src/libsystemd-network/dhcp-protocol.h +++ b/src/libsystemd-network/dhcp-protocol.h @@ -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, diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 6b19666..3c38993 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -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); } diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 5f6c22a..9e057ce 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -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) { diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 50cb0f8..5c1c013 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -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) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 9f6de18..c108ad2 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -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); diff --git a/src/network/networkd.h b/src/network/networkd.h index aca3b8d..0f0ecd5 100644 --- a/src/network/networkd.h +++ b/src/network/networkd.h @@ -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; diff --git a/src/systemd/sd-dhcp-client.h b/src/systemd/sd-dhcp-client.h index c3ea059..9ab6105 100644 --- a/src/systemd/sd-dhcp-client.h +++ b/src/systemd/sd-dhcp-client.h @@ -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); -- 2.7.4