Skip to content

Commit

Permalink
Merge pull request #660 from mtomaschewski/dhcp-other-opts
Browse files Browse the repository at this point in the history
dhcp4: initial support to request custom options (bsc#916948,bsc#988954)
  • Loading branch information
Nirmoy Das committed Jul 26, 2016
2 parents 1b0c976 + 080acda commit 9af7e22
Show file tree
Hide file tree
Showing 29 changed files with 643 additions and 98 deletions.
17 changes: 17 additions & 0 deletions client/compat.c
Expand Up @@ -180,6 +180,7 @@ ni_compat_netdev_free(ni_compat_netdev_t *compat)
ni_string_free(&compat->dhcp4.client_id);
ni_string_free(&compat->dhcp4.vendor_class);
ni_string_array_destroy(&compat->dhcp4.user_class.class_id);
ni_string_array_destroy(&compat->dhcp4.request_options);

ni_string_free(&compat->dhcp6.hostname);
ni_string_free(&compat->dhcp6.client_id);
Expand Down Expand Up @@ -1981,6 +1982,22 @@ __ni_compat_generate_dhcp4_addrconf(xml_node_t *ifnode, const ni_compat_netdev_t
__ni_compat_generate_dhcp4_user_class(dhcp, &compat->dhcp4.user_class);
}

if (compat->dhcp4.request_options.count) {
xml_node_t *req;
unsigned int i;

req = xml_node_new("request-options", NULL);
for (i = 0; req && i < compat->dhcp4.request_options.count; ++i) {
const char *opt = compat->dhcp4.request_options.data[i];
xml_node_new_element("option", req, opt);
}
if (req->children) {
xml_node_add_child(dhcp, req);
} else {
xml_node_free(req);
}
}

return dhcp;
}

Expand Down
28 changes: 28 additions & 0 deletions client/suse/compat-suse.c
Expand Up @@ -4628,6 +4628,32 @@ __ni_suse_parse_dhcp4_user_class(const ni_sysconfig_t *sc, ni_compat_netdev_t *c
return TRUE;
}

static void
__ni_suse_parse_dhcp4_req_options(const ni_sysconfig_t *sc, ni_compat_netdev_t *compat, const char *prefix)
{
ni_string_array_t vars = NI_STRING_ARRAY_INIT;
ni_string_array_t opts = NI_STRING_ARRAY_INIT;
const char *value;
unsigned int i, j;
unsigned int code;

ni_sysconfig_find_matching(sc, prefix, &vars);
for (i = 0; i < vars.count; ++i) {
value = ni_sysconfig_get_value(sc, vars.data[i]);
ni_string_split(&opts, value, " ", 0);
for (j = 0; j < opts.count; ++j) {
const char *opt = opts.data[j];

/* numeric option codes only for now */
if (ni_parse_uint(opt, &code, 10) || !code || code >= 255)
continue;
ni_string_array_append(&compat->dhcp4.request_options, opt);
}
ni_string_array_destroy(&opts);
}
ni_string_array_destroy(&vars);
}

/*
* Process DHCPv4 addrconf
*/
Expand Down Expand Up @@ -4714,6 +4740,8 @@ __ni_suse_addrconf_dhcp4_options(const ni_sysconfig_t *sc, ni_compat_netdev_t *c
}
}

__ni_suse_parse_dhcp4_req_options(sc, compat, "DHCLIENT_REQUEST_OPTION");

return ret;
}

Expand Down
2 changes: 2 additions & 0 deletions client/wicked-client.h
Expand Up @@ -76,6 +76,8 @@ typedef struct ni_compat_netdev {

unsigned int route_priority;
unsigned int update;

ni_string_array_t request_options;
} dhcp4;
struct {
ni_bool_t enabled;
Expand Down
7 changes: 6 additions & 1 deletion dhcp4/dbus-api.c
Expand Up @@ -24,7 +24,7 @@
#include <wicked/dbus-errors.h>
#include <wicked/objectmodel.h>
#include "appconfig.h"
#include "dhcp4/dhcp.h"
#include "dhcp4/dhcp4.h"

static ni_dhcp4_request_t * ni_objectmodel_dhcp4_request_from_dict(const ni_dbus_variant_t *);
static void __ni_objectmodel_dhcp4_device_release(ni_dbus_object_t *);
Expand Down Expand Up @@ -265,6 +265,8 @@ static ni_dbus_class_t ni_objectmodel_dhcp4req_class = {
NI_DBUS_GENERIC_BOOL_PROPERTY(dhcp4_request, dbus_name, member_name, rw)
#define DHCP4REQ_PROPERTY_SIGNATURE(signature, __name, rw) \
__NI_DBUS_PROPERTY(signature, __name, __dhcp4_request, rw)
#define DHCP4REQ_STRING_ARRAY_PROPERTY(dbus_name, member_name, rw) \
NI_DBUS_GENERIC_STRING_ARRAY_PROPERTY(dhcp4_request, dbus_name, member_name, rw)

static ni_dhcp4_request_t *
__ni_objectmodel_get_dhcp4_request(const ni_dbus_object_t *object, DBusError *error)
Expand Down Expand Up @@ -403,6 +405,9 @@ static ni_dbus_property_t dhcp4_request_properties[] = {
DHCP4REQ_UINT_PROPERTY(update, update, RO),
DHCP4REQ_STRING_PROPERTY(hostname, hostname, RO),
DHCP4REQ_UINT_PROPERTY(route-priority, route_priority, RO),

DHCP4REQ_STRING_ARRAY_PROPERTY(request-options, request_options, RO),

{ NULL },
};

Expand Down
2 changes: 1 addition & 1 deletion dhcp4/main.c
Expand Up @@ -21,7 +21,7 @@
#include <wicked/logging.h>
#include <wicked/objectmodel.h>

#include "dhcp4/dhcp.h"
#include "dhcp4/dhcp4.h"
#include "dhcp4/tester.h"

enum {
Expand Down
2 changes: 1 addition & 1 deletion dhcp6/dbus-api.h
Expand Up @@ -23,7 +23,7 @@
#define __WICKED_DHCP6_DBUS_API_H__

#include <wicked/dbus.h>
#include "dhcp6/dhcp.h"
#include "dhcp6/dhcp6.h"

extern void ni_objectmodel_dhcp6_init(void);
extern ni_dbus_object_t * ni_objectmodel_register_dhcp6_device(ni_dbus_server_t *, ni_dhcp6_device_t *);
Expand Down
6 changes: 6 additions & 0 deletions include/wicked/addrconf.h
Expand Up @@ -97,6 +97,8 @@ typedef struct ni_dhcp4_user_class {
ni_string_array_t class_id;
} ni_dhcp4_user_class_t;

typedef struct ni_dhcp_option ni_dhcp_option_t;

typedef struct ni_addrconf_updater ni_addrconf_updater_t;

struct ni_addrconf_lease {
Expand Down Expand Up @@ -164,6 +166,8 @@ struct ni_addrconf_lease {
char * boot_file;
char * root_path;
char * message;

ni_dhcp_option_t * options;
} dhcp4;
struct ni_addrconf_lease_dhcp6 {
ni_opaque_t client_id;
Expand All @@ -175,6 +179,8 @@ struct ni_addrconf_lease {
struct ni_dhcp6_ia * ia_list;
char * boot_url;
ni_string_array_t boot_params;

ni_dhcp_option_t * options;
} dhcp6;
};
};
Expand Down
4 changes: 4 additions & 0 deletions man/ifcfg-dhcp.5.in
Expand Up @@ -67,6 +67,10 @@ compliant array, otherwise DHCLIENT_USER_CLASS_ID is used as string.
Specifies the user class identifier [array] to send in dhcp requests.
The DHCLIENT_USER_CLASS_FORMAT variable specified how to interpret it.
.TP
.BR DHCLIENT_REQUEST_OPTION[SUFFIX]
Specifies a space separate list of additional DHCPv4 options to request.
Currently limited to numeric option codes only.
.TP
.BR DHCLIENT_LEASE_TIME
Specifies the lease time (in seconds), that is suggested to the server. Default
is unset which means to use the lease time offered by the server.
Expand Down
2 changes: 2 additions & 0 deletions schema/addrconf.xml
Expand Up @@ -198,6 +198,8 @@
<update type="builtin-addrconf-update-mask" />
<hostname type="string" />
<route-priority type="uint32" />

<request-options class="array" element-type="string" element-name="option" />
</define>
<define name="properties" type="interface:addrconf-lease"/>

Expand Down
6 changes: 4 additions & 2 deletions src/Makefile.am
Expand Up @@ -56,6 +56,7 @@ libwicked_la_SOURCES = \
dbus-object.c \
dbus-server.c \
dbus-xml.c \
dhcp.c \
duid.c \
errors.c \
ethernet.c \
Expand Down Expand Up @@ -194,17 +195,18 @@ wicked_headers = \
dbus-objects/model.h \
dbus-server.h \
debug.h \
dhcp4/dhcp.h \
dhcp4/dhcp4.h \
dhcp4/lease.h \
dhcp4/protocol.h \
dhcp4/tester.h \
dhcp6/device.h \
dhcp6/dhcp.h \
dhcp6/dhcp6.h \
dhcp6/lease.h \
dhcp6/fsm.h \
dhcp6/options.h \
dhcp6/protocol.h \
dhcp6/tester.h \
dhcp.h \
duid.h \
ibft.h \
ipv6_priv.h \
Expand Down
76 changes: 76 additions & 0 deletions src/dbus-objects/misc.c
Expand Up @@ -31,6 +31,7 @@
#include "misc.h"
#include "model.h"
#include "debug.h"
#include "dhcp.h"

static dbus_bool_t __ni_objectmodel_callback_info_to_dict(const ni_objectmodel_callback_info_t *, ni_dbus_variant_t *);
static dbus_bool_t __ni_objectmodel_address_to_dict(const ni_address_t *, ni_dbus_variant_t *);
Expand Down Expand Up @@ -1524,6 +1525,73 @@ ni_objectmodel_rule_from_dict(ni_rule_t *rule, const ni_dbus_variant_t *dict)
/*
* Build a DBus dict from an addrconf lease
*/
static void
__ni_objectmodel_get_addrconf_dhcp_opts_dict(const ni_dhcp_option_t *options,
ni_dbus_variant_t *dict,
unsigned int minlen, unsigned int maxlen)
{
ni_dbus_variant_t *array;
const ni_dhcp_option_t *opt;

if (!options || !dict || !(array = ni_dbus_dict_add(dict, "options")))
return;

ni_dbus_dict_array_init(array);
for (opt = options; opt; opt = opt->next) {
if (!opt->code || opt->len < minlen || maxlen < opt->len)
continue;

if (!(dict = ni_dbus_dict_array_add(array)))
continue;

ni_dbus_variant_init_dict(dict);
ni_dbus_dict_add_uint16(dict, "code", opt->code);
if (!opt->len)
continue;
ni_dbus_dict_add_byte_array(dict, "data", opt->data, opt->len);
}
}

static void
__ni_objectmodel_set_addrconf_dhcp_opts_dict(ni_dhcp_option_t **options,
const ni_dbus_variant_t *dict,
unsigned int minlen, unsigned int maxlen)
{
const ni_dbus_variant_t *array, *var;
ni_dhcp_option_t *opt;
unsigned int i;

ni_dhcp_option_list_destroy(options);
if (!dict || !(array = ni_dbus_dict_get(dict, "options")))
return;

if (!ni_dbus_variant_is_dict_array(array))
return;

for (i = 0; i < array->array.len; ++i) {
uint16_t code;

dict = &array->variant_array_value[i];
if (!ni_dbus_variant_is_dict(dict))
continue;

if (!ni_dbus_dict_get_uint16(dict, "code", &code) || !code)
continue;

if (!(var = ni_dbus_dict_get(dict, "data")))
continue;
if (!ni_dbus_variant_is_byte_array(var))
continue;

if (var->array.len < minlen || maxlen < var->array.len)
continue;

opt = ni_dhcp_option_new(code, var->array.len, var->byte_array_value);
if (!ni_dhcp_option_list_append(options, opt))
ni_dhcp_option_free(opt);
}
}

static void
__ni_objectmodel_get_addrconf_dhcp4_dict(const struct ni_addrconf_lease_dhcp4 *dhcp4,
ni_dbus_variant_t *dict)
Expand Down Expand Up @@ -1572,6 +1640,8 @@ __ni_objectmodel_get_addrconf_dhcp4_dict(const struct ni_addrconf_lease_dhcp4 *d
ni_dbus_dict_add_string(dict, "message",
dhcp4->message);
}

__ni_objectmodel_get_addrconf_dhcp_opts_dict(dhcp4->options, dict, 1, 65535);
}

static void
Expand Down Expand Up @@ -1609,6 +1679,8 @@ __ni_objectmodel_get_addrconf_dhcp6_dict(const struct ni_addrconf_lease_dhcp6 *d
__ni_objectmodel_set_string_array(dict, "bootfile-params",
&dhcp6->boot_params);
}

__ni_objectmodel_get_addrconf_dhcp_opts_dict(dhcp6->options, dict, 0, 65535);
}

dbus_bool_t
Expand Down Expand Up @@ -1778,6 +1850,8 @@ __ni_objectmodel_set_addrconf_dhcp4_data(struct ni_addrconf_lease_dhcp4 *dhcp4,
if (__ni_objectmodel_get_printable_string(dict, "message", &string_value))
ni_string_dup(&dhcp4->message, string_value);

__ni_objectmodel_set_addrconf_dhcp_opts_dict(&dhcp4->options, dict, 1, 65536);

return TRUE;
}

Expand Down Expand Up @@ -1827,6 +1901,8 @@ __ni_objectmodel_set_addrconf_dhcp6_data(struct ni_addrconf_lease_dhcp6 *dhcp6,
error, "bootfile-params"))
return FALSE;

__ni_objectmodel_set_addrconf_dhcp_opts_dict(&dhcp6->options, dict, 0, 65535);

return TRUE;
}

Expand Down

0 comments on commit 9af7e22

Please sign in to comment.