Skip to content

Commit

Permalink
dhcp6: adopted to use new duid/iaid functions
Browse files Browse the repository at this point in the history
  • Loading branch information
mtomaschewski committed Jun 28, 2017
1 parent 3e6e484 commit 91f50be
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 169 deletions.
169 changes: 48 additions & 121 deletions src/dhcp6/device.c
Expand Up @@ -42,6 +42,7 @@
#include "appconfig.h"
#include "util_priv.h"
#include "netinfo_priv.h"
#include "iaid.h"
#include "duid.h"
#include "dhcp.h"

Expand Down Expand Up @@ -76,7 +77,6 @@
#define NI_DHCP6_VENDOR_VERSION_STRING NI_DHCP6_PACKAGE_NAME"/"NI_DHCP6_PACKAGE_VERSION
#endif

static ni_opaque_t ni_dhcp6_duid;
ni_dhcp6_device_t * ni_dhcp6_active;

static void ni_dhcp6_device_close(ni_dhcp6_device_t *);
Expand Down Expand Up @@ -316,38 +316,32 @@ ni_dhcp6_device_uptime(const ni_dhcp6_device_t *dev, unsigned int clamp)
return (uptime < clamp) ? uptime : clamp;
}

int
ni_dhcp6_device_iaid(const ni_dhcp6_device_t *dev, uint32_t *iaid)
ni_bool_t
ni_dhcp6_device_iaid(const ni_dhcp6_device_t *dev, unsigned int *iaid)
{
unsigned int migrate;
ni_netconfig_t *nc;
ni_netdev_t *ifp;
size_t len, off;
uint32_t tmp;
ni_netdev_t *ndev;

if (!dev || !iaid)
return FALSE;

nc = ni_global_state_handle(0);
if(!nc || !(ifp = ni_netdev_by_index(nc, dev->link.ifindex))) {
if(!nc || !(ndev = ni_netdev_by_index(nc, dev->link.ifindex))) {
ni_error("%s: Unable to find network interface by index %u",
dev->ifname, dev->link.ifindex);
return -1;
return FALSE;
}

/* FIXME: simple iaid with 4 last byte of the mac */

*iaid = 0;
if (ifp->link.hwaddr.len > 4) {
off = ifp->link.hwaddr.len - 4;
memcpy(iaid, ifp->link.hwaddr.data + off, sizeof(*iaid));
return 0;
}
if ((len = ni_string_len(dev->ifname))) {
memcpy(&tmp, dev->ifname, len % sizeof(tmp));
*iaid ^= tmp;
if (ifp->vlan && ifp->vlan->tag > 0)
*iaid ^= ifp->vlan->tag;
*iaid ^= dev->link.ifindex;
return 0;
if (!(migrate = dev->iaid) && dev->lease) {
if (!(migrate = ni_dhcp6_lease_ia_na_iaid(dev->lease)))
migrate = ni_dhcp6_lease_ia_ta_iaid(dev->lease);
}
return -1;

if (!ni_iaid_acquire(iaid, ndev, migrate))
return FALSE;

return TRUE;
}

void
Expand Down Expand Up @@ -800,96 +794,42 @@ ni_dhcp6_device_retransmit(ni_dhcp6_device_t *dev)
return 0;
}

void
ni_dhcp6_generate_duid(ni_dhcp6_device_t *dev, ni_opaque_t *duid)
static ni_bool_t
ni_dhcp6_config_init_duid(ni_dhcp6_device_t *dev, ni_dhcp6_config_t *config, const char *preferred)
{
ni_netconfig_t *nc;
ni_netdev_t *ifp;
ni_uuid_t uuid;
ni_netdev_t *ndev;

nc = ni_global_state_handle(0);
if(!nc || !(ifp = ni_netdev_by_index(nc, dev->link.ifindex))) {
if(!nc || !(ndev = ni_netdev_by_index(nc, dev->link.ifindex))) {
ni_error("%s: Unable to find network interface by index %u",
dev->ifname, dev->link.ifindex);
return;
}

/* try the current interface first */
if (ifp->link.hwaddr.len) {
if(ni_duid_init_llt(duid, ifp->link.hwaddr.type,
ifp->link.hwaddr.data, ifp->link.hwaddr.len))
return;
}

/* then another one */
for (ifp = ni_netconfig_devlist(nc); ifp; ifp = ifp->next) {
if (ifp->link.ifindex == dev->link.ifindex)
continue;

switch(ifp->link.hwaddr.type) {
case ARPHRD_ETHER:
case ARPHRD_IEEE802:
case ARPHRD_INFINIBAND:
if (ifp->link.hwaddr.len) {
if(ni_duid_init_llt(duid, ifp->link.hwaddr.type,
ifp->link.hwaddr.data, ifp->link.hwaddr.len))
return;
}
break;
}
dev->ifname, dev->link.ifindex);
return FALSE;
}

/*
* TODO:
* 1) MAC based uuid duid, see
* http://tools.ietf.org/html/rfc4122#section-4.1.6
* 2) There should be some system unique uuid at least on x86_64
*/
memset(&uuid, 0, sizeof(uuid));
ni_uuid_generate(&uuid);
ni_duid_init_uuid(duid, &uuid);
}
if (!ni_duid_acquire(&config->client_duid, ndev, nc, preferred))
return FALSE;

static inline int
ni_dhcp6_duid_load(ni_opaque_t *duid)
{
return ni_duid_load(duid, NULL, NULL);
return TRUE;
}

static inline int
ni_dhcp6_duid_save(const ni_opaque_t *duid)
static int
ni_dhcp6_recover_lease(ni_dhcp6_device_t *dev)
{
return ni_duid_save(duid, NULL, NULL);
}
ni_addrconf_lease_t *lease;

static ni_bool_t
ni_dhcp6_config_init_duid(ni_dhcp6_device_t *dev, ni_dhcp6_config_t *config, const char *preferred)
{
ni_bool_t save = TRUE;
if (!dev || dev->lease)
return 1;

if (preferred) {
ni_duid_parse_hex(&config->client_duid, preferred);
}
if (config->client_duid.len == 0) {
ni_dhcp6_config_default_duid(&config->client_duid);
}
if (config->client_duid.len == 0 && ni_dhcp6_duid.len > 0) {
ni_duid_copy(&config->client_duid, &ni_dhcp6_duid);
}
if (config->client_duid.len == 0) {
if(ni_dhcp6_duid_load(&config->client_duid) == 0)
save = FALSE;
}
if (config->client_duid.len == 0) {
ni_dhcp6_generate_duid(dev, &config->client_duid);
}
if (config->client_duid.len > 0 && save) {
(void)ni_dhcp6_duid_save(&config->client_duid);
}
if (config->client_duid.len > 0 && !ni_dhcp6_duid.len) {
ni_duid_copy(&ni_dhcp6_duid, &config->client_duid);
lease = ni_addrconf_lease_file_read(dev->ifname, NI_ADDRCONF_DHCP, AF_INET6);
if (!ni_addrconf_lease_is_valid(lease)) {
ni_addrconf_lease_free(lease);
return -1;
}
return (config->client_duid.len > 0);

dev->lease = lease;

return 0;
}

static inline unsigned int
Expand Down Expand Up @@ -978,13 +918,14 @@ ni_dhcp6_acquire(ni_dhcp6_device_t *dev, const ni_dhcp6_request_t *req, char **e
config->recover_lease = req->recover_lease;
config->release_lease = req->release_lease;

/*
* Make sure we have a DUID for client-id
* Hmm... Should we fail back to req->uuid?
*/
if (!dev->iaid)
ni_dhcp6_device_iaid(dev, &dev->iaid);
if(!ni_dhcp6_config_init_duid(dev, config, req->clientid)) {
if (!dev->lease && config->dry_run != NI_DHCP6_RUN_OFFER && config->recover_lease)
ni_dhcp6_recover_lease(dev);

if (!ni_dhcp6_device_iaid(dev, &dev->iaid)) {
ni_string_printf(err, "Unable to generate a device IAID");
return -NI_ERROR_GENERAL_FAILURE;
}
if (!ni_dhcp6_config_init_duid(dev, config, req->clientid)) {
size_t len;

ni_dhcp6_device_config_free(config);
Expand Down Expand Up @@ -1322,20 +1263,6 @@ ni_dhcp6_device_transmit(ni_dhcp6_device_t *dev)
/*
* Functions for accessing various global DHCP configuration options
*/
const char *
ni_dhcp6_config_default_duid(ni_opaque_t *duid)
{
const struct ni_config_dhcp6 *dhconf = &ni_global.config->addrconf.dhcp6;

if (ni_string_empty(dhconf->default_duid))
return NULL;

if (!ni_duid_parse_hex(duid, dhconf->default_duid))
return NULL;

return dhconf->default_duid;
}

int
ni_dhcp6_config_user_class(ni_string_array_t *user_class_data)
{
Expand Down
3 changes: 1 addition & 2 deletions src/dhcp6/device.h
Expand Up @@ -45,10 +45,9 @@ extern void ni_dhcp6_device_set_best_offer(ni_dhcp6_device_t *, ni_addrconf_lea
extern void ni_dhcp6_device_drop_best_offer(ni_dhcp6_device_t *);

extern unsigned int ni_dhcp6_device_uptime(const ni_dhcp6_device_t *, unsigned int);
extern int ni_dhcp6_device_iaid(const ni_dhcp6_device_t *dev, uint32_t *iaid);
extern ni_bool_t ni_dhcp6_device_iaid(const ni_dhcp6_device_t *, unsigned int *);

/* config access [/etc/wicked/config.xml, node /config/addrconf/dhcp6] */
extern const char * ni_dhcp6_config_default_duid(ni_opaque_t *);
extern int ni_dhcp6_config_user_class(ni_string_array_t *);
extern int ni_dhcp6_config_vendor_class(unsigned int *, ni_string_array_t *);
extern int ni_dhcp6_config_vendor_opts(unsigned int *, ni_var_array_t *);
Expand Down
11 changes: 8 additions & 3 deletions src/dhcp6/dhcp6.h
Expand Up @@ -297,10 +297,15 @@ extern ni_dhcp6_ia_t * ni_dhcp6_ia_na_new(unsigned int iaid);
extern ni_dhcp6_ia_t * ni_dhcp6_ia_ta_new(unsigned int iaid);
extern ni_dhcp6_ia_t * ni_dhcp6_ia_pd_new(unsigned int iaid);

extern ni_bool_t ni_dhcp6_ia_type_na(ni_dhcp6_ia_t *);
extern ni_bool_t ni_dhcp6_ia_type_ta(ni_dhcp6_ia_t *);
extern ni_bool_t ni_dhcp6_ia_type_pd(ni_dhcp6_ia_t *);
extern ni_bool_t ni_dhcp6_ia_type_na(const ni_dhcp6_ia_t *);
extern ni_bool_t ni_dhcp6_ia_type_ta(const ni_dhcp6_ia_t *);
extern ni_bool_t ni_dhcp6_ia_type_pd(const ni_dhcp6_ia_t *);

extern ni_string_array_t * ni_dhcp6_get_ia_addrs(struct ni_dhcp6_ia *, ni_var_array_t *, ni_var_array_t *);

extern const ni_opaque_t * ni_dhcp6_lease_duid(const ni_addrconf_lease_t *);
extern unsigned int ni_dhcp6_lease_ia_na_iaid(const ni_addrconf_lease_t *);
extern unsigned int ni_dhcp6_lease_ia_ta_iaid(const ni_addrconf_lease_t *);
extern unsigned int ni_dhcp6_lease_ia_pd_iaid(const ni_addrconf_lease_t *);

#endif /* __WICKED_DHCP6_SUPPLICANT_H__ */
50 changes: 46 additions & 4 deletions src/dhcp6/protocol.c
Expand Up @@ -1422,7 +1422,7 @@ __ni_dhcp6_build_solicit_opts(ni_dhcp6_device_t *dev,

/* Init ia list if empty */
if (dev->config->ia_list == NULL) {
if (dev->iaid == 0 && ni_dhcp6_device_iaid(dev, &dev->iaid) < 0)
if (dev->iaid == 0 && !ni_dhcp6_device_iaid(dev, &dev->iaid))
goto cleanup;

ni_dhcp6_ia_t *ia = ni_dhcp6_ia_na_new(dev->iaid);
Expand Down Expand Up @@ -1936,21 +1936,63 @@ ni_dhcp6_ia_pd_new(unsigned int iaid)
}

ni_bool_t
ni_dhcp6_ia_type_na(ni_dhcp6_ia_t *ia)
ni_dhcp6_ia_type_na(const ni_dhcp6_ia_t *ia)
{
return ia->type == NI_DHCP6_OPTION_IA_NA;
}
ni_bool_t
ni_dhcp6_ia_type_ta(ni_dhcp6_ia_t *ia)
ni_dhcp6_ia_type_ta(const ni_dhcp6_ia_t *ia)
{
return ia->type == NI_DHCP6_OPTION_IA_TA;
}
ni_bool_t
ni_dhcp6_ia_type_pd(ni_dhcp6_ia_t *ia)
ni_dhcp6_ia_type_pd(const ni_dhcp6_ia_t *ia)
{
return ia->type == NI_DHCP6_OPTION_IA_PD;
}

unsigned int
ni_dhcp6_lease_ia_na_iaid(const ni_addrconf_lease_t *lease)
{
const ni_dhcp6_ia_t *ia;

for (ia = lease ? lease->dhcp6.ia_list : NULL; ia; ia = ia->next) {
if (ni_dhcp6_ia_type_na(ia) && ia->iaid)
return ia->iaid;
}
return 0;
}

unsigned int
ni_dhcp6_lease_ia_ta_iaid(const ni_addrconf_lease_t *lease)
{
const ni_dhcp6_ia_t *ia;

for (ia = lease ? lease->dhcp6.ia_list : NULL; ia; ia = ia->next) {
if (ni_dhcp6_ia_type_ta(ia) && ia->iaid)
return ia->iaid;
}
return 0;
}

unsigned int
ni_dhcp6_lease_ia_pd_iaid(const ni_addrconf_lease_t *lease)
{
const ni_dhcp6_ia_t *ia;

for (ia = lease ? lease->dhcp6.ia_list : NULL; ia; ia = ia->next) {
if (ni_dhcp6_ia_type_pd(ia) && ia->iaid)
return ia->iaid;
}
return 0;
}

const ni_opaque_t *
ni_dhcp6_lease_duid(const ni_addrconf_lease_t *lease)
{
return lease ? &lease->dhcp6.client_id : NULL;
}

unsigned int
ni_dhcp6_ia_min_preferred_lft(ni_dhcp6_ia_t *ia)
{
Expand Down
36 changes: 0 additions & 36 deletions src/duid.c
Expand Up @@ -284,42 +284,6 @@ ni_duid_format_hex(char **hex, const ni_opaque_t *duid)
return *hex;
}

int
ni_duid_load(ni_opaque_t *duid, const char *filename, const char *name)
{
ni_duid_map_t *map;
int rv = -1;

if (!duid || !(map = ni_duid_map_load(filename)))
return rv;

if (ni_duid_map_get_duid(map, NULL, &name, duid))
rv = 0;

ni_duid_map_free(map);
return rv;
}

int
ni_duid_save(const ni_opaque_t *duid, const char *filename, const char *name)
{
ni_duid_map_t *map;
int rv = -1;

if (!duid || !duid->len || !(map = ni_duid_map_load(filename)))
return rv;

name = ni_duid_print_hex(duid);
if (ni_string_empty(name) || !ni_duid_map_set(map, NULL, name))
return rv;

if (ni_duid_map_save(map))
rv = 0;

ni_duid_map_free(map);
return rv;
}

static ni_bool_t
ni_duid_create_parse_hwaddr(ni_hwaddr_t *hwa, unsigned short hwtype, const char *hwaddr)
{
Expand Down
3 changes: 0 additions & 3 deletions src/duid.h
Expand Up @@ -134,9 +134,6 @@ static inline const char * ni_duid_print_hex(const ni_opaque_t *duid)
return duid ? ni_print_hex(duid->data, duid->len) : NULL;
}

extern int ni_duid_load(ni_opaque_t *, const char *, const char *);
extern int ni_duid_save(const ni_opaque_t *, const char *, const char *);

extern ni_bool_t ni_duid_create_en (ni_opaque_t *duid, const char *enumber, const char *identifier);
extern ni_bool_t ni_duid_create_ll (ni_opaque_t *duid, const char *hwtype, const char *hwaddr);
extern ni_bool_t ni_duid_create_llt(ni_opaque_t *duid, const char *hwtype, const char *hwaddr);
Expand Down

0 comments on commit 91f50be

Please sign in to comment.