Commit 5617cd4e authored by Thomas Haller's avatar Thomas Haller

merge: merge branch 'systemd' into master

After merging https://github.com/systemd/systemd/pull/2898,
use the LLDP defines now from public systemd API.
parents ec542df4 2fcd9f8b
......@@ -148,7 +148,6 @@ libsystemd_nm_la_SOURCES = \
systemd/src/libsystemd-network/lldp-neighbor.h \
systemd/src/libsystemd-network/lldp-network.c \
systemd/src/libsystemd-network/lldp-network.h \
systemd/src/libsystemd-network/lldp.h \
systemd/src/libsystemd-network/network-internal.c \
systemd/src/libsystemd-network/network-internal.h \
systemd/src/libsystemd-network/sd-dhcp-client.c \
......
......@@ -30,9 +30,6 @@
#include "sd-lldp.h"
#include "nm-sd-adapt.h"
#include "lldp.h"
#define MAX_NEIGHBORS 4096
#define MIN_UPDATE_INTERVAL_NS (2 * NM_UTILS_NS_PER_SECOND)
......@@ -402,13 +399,13 @@ lldp_neighbor_new (sd_lldp_neighbor *neighbor_sd, GError **error)
}
switch (chassis_id_type) {
case LLDP_CHASSIS_SUBTYPE_INTERFACE_ALIAS:
case LLDP_CHASSIS_SUBTYPE_INTERFACE_NAME:
case LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED:
case LLDP_CHASSIS_SUBTYPE_CHASSIS_COMPONENT:
case SD_LLDP_CHASSIS_SUBTYPE_INTERFACE_ALIAS:
case SD_LLDP_CHASSIS_SUBTYPE_INTERFACE_NAME:
case SD_LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED:
case SD_LLDP_CHASSIS_SUBTYPE_CHASSIS_COMPONENT:
neigh->chassis_id = g_strndup ((const char *) chassis_id, chassis_id_len);
break;
case LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS:
case SD_LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS:
neigh->chassis_id = nm_utils_hwaddr_ntoa (chassis_id, chassis_id_len);
break;
default:
......@@ -418,13 +415,13 @@ lldp_neighbor_new (sd_lldp_neighbor *neighbor_sd, GError **error)
}
switch (port_id_type) {
case LLDP_PORT_SUBTYPE_INTERFACE_ALIAS:
case LLDP_PORT_SUBTYPE_INTERFACE_NAME:
case LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED:
case LLDP_PORT_SUBTYPE_PORT_COMPONENT:
case SD_LLDP_PORT_SUBTYPE_INTERFACE_ALIAS:
case SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME:
case SD_LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED:
case SD_LLDP_PORT_SUBTYPE_PORT_COMPONENT:
neigh->port_id = strndup ((char *) port_id, port_id_len);
break;
case LLDP_PORT_SUBTYPE_MAC_ADDRESS:
case SD_LLDP_PORT_SUBTYPE_MAC_ADDRESS:
neigh->port_id = nm_utils_hwaddr_ntoa (port_id, port_id_len);
break;
default:
......@@ -464,11 +461,11 @@ lldp_neighbor_new (sd_lldp_neighbor *neighbor_sd, GError **error)
goto out;
}
if (!( memcmp (oui, LLDP_OUI_802_1, sizeof (oui)) == 0
if (!( memcmp (oui, SD_LLDP_OUI_802_1, sizeof (oui)) == 0
&& NM_IN_SET (subtype,
LLDP_OUI_802_1_SUBTYPE_PORT_PROTOCOL_VLAN_ID,
LLDP_OUI_802_1_SUBTYPE_PORT_VLAN_ID,
LLDP_OUI_802_1_SUBTYPE_VLAN_NAME)))
SD_LLDP_OUI_802_1_SUBTYPE_PORT_PROTOCOL_VLAN_ID,
SD_LLDP_OUI_802_1_SUBTYPE_PORT_VLAN_ID,
SD_LLDP_OUI_802_1_SUBTYPE_VLAN_NAME)))
continue;
if (sd_lldp_neighbor_tlv_get_raw (neighbor_sd, (void *) &data8, &len) < 0)
......@@ -492,16 +489,16 @@ lldp_neighbor_new (sd_lldp_neighbor *neighbor_sd, GError **error)
data8 += 6;
len -= 6;
/*if (memcmp (oui, LLDP_OUI_802_1, sizeof (oui)) == 0)*/
/*if (memcmp (oui, SD_LLDP_OUI_802_1, sizeof (oui)) == 0)*/
{
switch (subtype) {
case LLDP_OUI_802_1_SUBTYPE_PORT_VLAN_ID:
case SD_LLDP_OUI_802_1_SUBTYPE_PORT_VLAN_ID:
if (len != 2)
continue;
_lldp_attr_set_uint32 (neigh->attrs, LLDP_ATTR_ID_IEEE_802_1_PVID,
_access_uint16 (data8));
break;
case LLDP_OUI_802_1_SUBTYPE_PORT_PROTOCOL_VLAN_ID:
case SD_LLDP_OUI_802_1_SUBTYPE_PORT_PROTOCOL_VLAN_ID:
if (len != 3)
continue;
_lldp_attr_set_uint32 (neigh->attrs, LLDP_ATTR_ID_IEEE_802_1_PPVID_FLAGS,
......@@ -509,7 +506,7 @@ lldp_neighbor_new (sd_lldp_neighbor *neighbor_sd, GError **error)
_lldp_attr_set_uint32 (neigh->attrs, LLDP_ATTR_ID_IEEE_802_1_PPVID,
_access_uint16 (&data8[1]));
break;
case LLDP_OUI_802_1_SUBTYPE_VLAN_NAME: {
case SD_LLDP_OUI_802_1_SUBTYPE_VLAN_NAME: {
int l;
if (len <= 3)
......
......@@ -29,8 +29,7 @@
#include "nm-lldp-listener.h"
#include "nm-sd.h"
#include "nm-sd-adapt.h"
#include "lldp.h"
#include "sd-lldp.h"
#include "test-common.h"
......@@ -147,8 +146,8 @@ _test_recv_data0_check (GMainLoop *loop, NMLldpListener *listener)
g_assert_cmpint (g_variant_n_children (neighbors), ==, 1);
neighbor = get_lldp_neighbor (neighbors,
LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS, "00:01:02:03:04:05",
LLDP_PORT_SUBTYPE_INTERFACE_NAME, "1/3");
SD_LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS, "00:01:02:03:04:05",
SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME, "1/3");
g_assert (neighbor);
g_assert_cmpint (g_variant_n_children (neighbor), ==, 4 + 4);
......@@ -244,8 +243,8 @@ _test_recv_data1_check (GMainLoop *loop, NMLldpListener *listener)
g_assert_cmpint (g_variant_n_children (neighbors), ==, 1);
neighbor = get_lldp_neighbor (neighbors,
LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS, "00:01:30:F9:AD:A0",
LLDP_PORT_SUBTYPE_INTERFACE_NAME, "1/1");
SD_LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS, "00:01:30:F9:AD:A0",
SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME, "1/1");
g_assert (neighbor);
g_assert_cmpint (g_variant_n_children (neighbor), ==, 4 + 10);
......
......@@ -762,9 +762,6 @@ manager_device_state_changed (NMDevice *device,
break;
}
if (old_state >= NM_DEVICE_STATE_ACTIVATED)
return;
if ( new_state == NM_DEVICE_STATE_UNAVAILABLE
|| new_state == NM_DEVICE_STATE_DISCONNECTED)
nm_settings_device_added (priv->settings, device);
......
......@@ -32,6 +32,7 @@
#endif /* NM_IGNORED */
#define UTF8_REPLACEMENT_CHARACTER "\xef\xbf\xbd"
#define UTF8_BYTE_ORDER_MARK "\xef\xbb\xbf"
bool unichar_is_valid(char32_t c);
......
......@@ -51,7 +51,7 @@ int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) {
if (r < 0)
return r;
unaligned_write_be16(&duid->type, DHCP6_DUID_EN);
unaligned_write_be16(&duid->type, DUID_TYPE_EN);
unaligned_write_be32(&duid->en.pen, SYSTEMD_PEN);
*len = sizeof(duid->type) + sizeof(duid->en);
......
......@@ -25,13 +25,23 @@
#include "sparse-endian.h"
#include "unaligned.h"
typedef enum DUIDType {
DUID_TYPE_RAW = 0,
DUID_TYPE_LLT = 1,
DUID_TYPE_EN = 2,
DUID_TYPE_LL = 3,
DUID_TYPE_UUID = 4,
_DUID_TYPE_MAX,
_DUID_TYPE_INVALID = -1,
} DUIDType;
/* RFC 3315 section 9.1:
* A DUID can be no more than 128 octets long (not including the type code).
*/
#define MAX_DUID_LEN 128
struct duid {
uint16_t type;
be16_t type;
union {
struct {
/* DHCP6_DUID_LLT */
......@@ -61,3 +71,32 @@ struct duid {
int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len);
int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_id);
static inline int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len) {
struct duid d;
assert_return(duid_len > 0 && duid_len <= MAX_DUID_LEN, -EINVAL);
switch (duid_type) {
case DUID_TYPE_LLT:
if (duid_len <= sizeof(d.llt))
return -EINVAL;
break;
case DUID_TYPE_EN:
if (duid_len != sizeof(d.en))
return -EINVAL;
break;
case DUID_TYPE_LL:
if (duid_len <= sizeof(d.ll))
return -EINVAL;
break;
case DUID_TYPE_UUID:
if (duid_len != sizeof(d.uuid))
return -EINVAL;
break;
default:
/* accept unknown type in order to be forward compatible */
break;
}
return 0;
}
......@@ -62,13 +62,6 @@ enum {
#define DHCP6_REB_TIMEOUT 10 * USEC_PER_SEC
#define DHCP6_REB_MAX_RT 600 * USEC_PER_SEC
enum {
DHCP6_DUID_LLT = 1,
DHCP6_DUID_EN = 2,
DHCP6_DUID_LL = 3,
DHCP6_DUID_UUID = 4,
};
enum DHCP6State {
DHCP6_STATE_STOPPED = 0,
DHCP6_STATE_INFORMATION_REQUEST = 1,
......
......@@ -26,7 +26,6 @@
#include "in-addr-util.h"
#include "lldp-internal.h"
#include "lldp-neighbor.h"
#include "lldp.h"
#include "unaligned.h"
static void lldp_neighbor_id_hash_func(const void *p, struct siphash *state) {
......@@ -247,7 +246,7 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) {
switch (type) {
case LLDP_TYPE_END:
case SD_LLDP_TYPE_END:
if (length != 0) {
log_lldp("End marker TLV not zero-sized, ignoring datagram.");
return -EBADMSG;
......@@ -259,7 +258,7 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) {
goto end_marker;
case LLDP_TYPE_CHASSIS_ID:
case SD_LLDP_TYPE_CHASSIS_ID:
if (length < 2 || length > 256) { /* includes the chassis subtype, hence one extra byte */
log_lldp("Chassis ID field size out of range, ignoring datagram.");
return -EBADMSG;
......@@ -276,7 +275,7 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) {
n->id.chassis_id_size = length;
break;
case LLDP_TYPE_PORT_ID:
case SD_LLDP_TYPE_PORT_ID:
if (length < 2 || length > 256) { /* includes the port subtype, hence one extra byte */
log_lldp("Port ID field size out of range, ignoring datagram.");
return -EBADMSG;
......@@ -293,7 +292,7 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) {
n->id.port_id_size = length;
break;
case LLDP_TYPE_TTL:
case SD_LLDP_TYPE_TTL:
if (length != 2) {
log_lldp("TTL field has wrong size, ignoring datagram.");
return -EBADMSG;
......@@ -308,25 +307,25 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) {
n->has_ttl = true;
break;
case LLDP_TYPE_PORT_DESCRIPTION:
case SD_LLDP_TYPE_PORT_DESCRIPTION:
r = parse_string(&n->port_description, p, length);
if (r < 0)
return r;
break;
case LLDP_TYPE_SYSTEM_NAME:
case SD_LLDP_TYPE_SYSTEM_NAME:
r = parse_string(&n->system_name, p, length);
if (r < 0)
return r;
break;
case LLDP_TYPE_SYSTEM_DESCRIPTION:
case SD_LLDP_TYPE_SYSTEM_DESCRIPTION:
r = parse_string(&n->system_description, p, length);
if (r < 0)
return r;
break;
case LLDP_TYPE_SYSTEM_CAPABILITIES:
case SD_LLDP_TYPE_SYSTEM_CAPABILITIES:
if (length != 4)
log_lldp("System capabilities field has wrong size, ignoring.");
else {
......@@ -337,7 +336,7 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) {
break;
case LLDP_TYPE_PRIVATE:
case SD_LLDP_TYPE_PRIVATE:
if (length < 4)
log_lldp("Found private TLV that is too short, ignoring.");
......@@ -481,18 +480,18 @@ _public_ int sd_lldp_neighbor_get_chassis_id_as_string(sd_lldp_neighbor *n, cons
switch (*(uint8_t*) n->id.chassis_id) {
case LLDP_CHASSIS_SUBTYPE_CHASSIS_COMPONENT:
case LLDP_CHASSIS_SUBTYPE_INTERFACE_ALIAS:
case LLDP_CHASSIS_SUBTYPE_PORT_COMPONENT:
case LLDP_CHASSIS_SUBTYPE_INTERFACE_NAME:
case LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED:
case SD_LLDP_CHASSIS_SUBTYPE_CHASSIS_COMPONENT:
case SD_LLDP_CHASSIS_SUBTYPE_INTERFACE_ALIAS:
case SD_LLDP_CHASSIS_SUBTYPE_PORT_COMPONENT:
case SD_LLDP_CHASSIS_SUBTYPE_INTERFACE_NAME:
case SD_LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED:
k = cescape_length((char*) n->id.chassis_id + 1, n->id.chassis_id_size - 1);
if (!k)
return -ENOMEM;
goto done;
case LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS:
case SD_LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS:
r = format_mac_address(n->id.chassis_id, n->id.chassis_id_size, &k);
if (r < 0)
return r;
......@@ -501,7 +500,7 @@ _public_ int sd_lldp_neighbor_get_chassis_id_as_string(sd_lldp_neighbor *n, cons
break;
case LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS:
case SD_LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS:
r = format_network_address(n->id.chassis_id, n->id.chassis_id_size, &k);
if (r < 0)
return r;
......@@ -552,17 +551,17 @@ _public_ int sd_lldp_neighbor_get_port_id_as_string(sd_lldp_neighbor *n, const c
switch (*(uint8_t*) n->id.port_id) {
case LLDP_PORT_SUBTYPE_INTERFACE_ALIAS:
case LLDP_PORT_SUBTYPE_PORT_COMPONENT:
case LLDP_PORT_SUBTYPE_INTERFACE_NAME:
case LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED:
case SD_LLDP_PORT_SUBTYPE_INTERFACE_ALIAS:
case SD_LLDP_PORT_SUBTYPE_PORT_COMPONENT:
case SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME:
case SD_LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED:
k = cescape_length((char*) n->id.port_id + 1, n->id.port_id_size - 1);
if (!k)
return -ENOMEM;
goto done;
case LLDP_PORT_SUBTYPE_MAC_ADDRESS:
case SD_LLDP_PORT_SUBTYPE_MAC_ADDRESS:
r = format_mac_address(n->id.port_id, n->id.port_id_size, &k);
if (r < 0)
return r;
......@@ -571,7 +570,7 @@ _public_ int sd_lldp_neighbor_get_port_id_as_string(sd_lldp_neighbor *n, const c
break;
case LLDP_PORT_SUBTYPE_NETWORK_ADDRESS:
case SD_LLDP_PORT_SUBTYPE_NETWORK_ADDRESS:
r = format_network_address(n->id.port_id, n->id.port_id_size, &k);
if (r < 0)
return r;
......@@ -740,7 +739,7 @@ _public_ int sd_lldp_neighbor_tlv_get_oui(sd_lldp_neighbor *n, uint8_t oui[3], u
assert_return(oui, -EINVAL);
assert_return(subtype, -EINVAL);
r = sd_lldp_neighbor_tlv_is_type(n, LLDP_TYPE_PRIVATE);
r = sd_lldp_neighbor_tlv_is_type(n, SD_LLDP_TYPE_PRIVATE);
if (r < 0)
return r;
if (r == 0)
......
#pragma once
/***
This file is part of systemd.
Copyright (C) 2014 Tom Gundersen
Copyright (C) 2014 Susant Sahani
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#define LLDP_MULTICAST_ADDR { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e }
/* IEEE 802.3AB Clause 9: TLV Types */
enum {
LLDP_TYPE_END = 0,
LLDP_TYPE_CHASSIS_ID = 1,
LLDP_TYPE_PORT_ID = 2,
LLDP_TYPE_TTL = 3,
LLDP_TYPE_PORT_DESCRIPTION = 4,
LLDP_TYPE_SYSTEM_NAME = 5,
LLDP_TYPE_SYSTEM_DESCRIPTION = 6,
LLDP_TYPE_SYSTEM_CAPABILITIES = 7,
LLDP_TYPE_MGMT_ADDRESS = 8,
LLDP_TYPE_PRIVATE = 127,
};
/* IEEE 802.3AB Clause 9.5.2: Chassis subtypes */
enum {
LLDP_CHASSIS_SUBTYPE_RESERVED = 0,
LLDP_CHASSIS_SUBTYPE_CHASSIS_COMPONENT = 1,
LLDP_CHASSIS_SUBTYPE_INTERFACE_ALIAS = 2,
LLDP_CHASSIS_SUBTYPE_PORT_COMPONENT = 3,
LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS = 4,
LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS = 5,
LLDP_CHASSIS_SUBTYPE_INTERFACE_NAME = 6,
LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED = 7,
};
/* IEEE 802.3AB Clause 9.5.3: Port subtype */
enum {
LLDP_PORT_SUBTYPE_RESERVED = 0,
LLDP_PORT_SUBTYPE_INTERFACE_ALIAS = 1,
LLDP_PORT_SUBTYPE_PORT_COMPONENT = 2,
LLDP_PORT_SUBTYPE_MAC_ADDRESS = 3,
LLDP_PORT_SUBTYPE_NETWORK_ADDRESS = 4,
LLDP_PORT_SUBTYPE_INTERFACE_NAME = 5,
LLDP_PORT_SUBTYPE_AGENT_CIRCUIT_ID = 6,
LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED = 7,
};
enum {
LLDP_SYSTEM_CAPABILITIES_OTHER = 1 << 0,
LLDP_SYSTEM_CAPABILITIES_REPEATER = 1 << 1,
LLDP_SYSTEM_CAPABILITIES_BRIDGE = 1 << 2,
LLDP_SYSTEM_CAPABILITIES_WLAN_AP = 1 << 3,
LLDP_SYSTEM_CAPABILITIES_ROUTER = 1 << 4,
LLDP_SYSTEM_CAPABILITIES_PHONE = 1 << 5,
LLDP_SYSTEM_CAPABILITIES_DOCSIS = 1 << 6,
LLDP_SYSTEM_CAPABILITIES_STATION = 1 << 7,
LLDP_SYSTEM_CAPABILITIES_CVLAN = 1 << 8,
LLDP_SYSTEM_CAPABILITIES_SVLAN = 1 << 9,
LLDP_SYSTEM_CAPABILITIES_TPMR = 1 << 10,
};
#define _LLDP_SYSTEM_CAPABILITIES_ALL ((uint16_t) -1)
#define _LLDP_SYSTEM_CAPABILITIES_ALL_ROUTERS \
((uint16_t) \
(LLDP_SYSTEM_CAPABILITIES_REPEATER| \
LLDP_SYSTEM_CAPABILITIES_BRIDGE| \
LLDP_SYSTEM_CAPABILITIES_WLAN_AP| \
LLDP_SYSTEM_CAPABILITIES_ROUTER| \
LLDP_SYSTEM_CAPABILITIES_DOCSIS| \
LLDP_SYSTEM_CAPABILITIES_CVLAN| \
LLDP_SYSTEM_CAPABILITIES_SVLAN| \
LLDP_SYSTEM_CAPABILITIES_TPMR))
#define LLDP_OUI_802_1 (uint8_t[]) { 0x00, 0x80, 0xc2 }
#define LLDP_OUI_802_3 (uint8_t[]) { 0x00, 0x12, 0x0f }
enum {
LLDP_OUI_802_1_SUBTYPE_PORT_VLAN_ID = 1,
LLDP_OUI_802_1_SUBTYPE_PORT_PROTOCOL_VLAN_ID = 2,
LLDP_OUI_802_1_SUBTYPE_VLAN_NAME = 3,
LLDP_OUI_802_1_SUBTYPE_PROTOCOL_IDENTITY = 4,
LLDP_OUI_802_1_SUBTYPE_VID_USAGE_DIGEST = 5,
LLDP_OUI_802_1_SUBTYPE_MANAGEMENT_VID = 6,
LLDP_OUI_802_1_SUBTYPE_LINK_AGGREGATION = 7,
};
......@@ -339,6 +339,35 @@ int config_parse_hwaddr(const char *unit,
return 0;
}
int config_parse_iaid(const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
uint32_t iaid;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
r = safe_atou32(rvalue, &iaid);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Unable to read IAID: %s", rvalue);
return r;
}
*((uint32_t *)data) = iaid;
return 0;
}
#endif /* NM_IGNORED */
void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size) {
......
......@@ -63,6 +63,10 @@ int config_parse_ifalias(const char *unit, const char *filename, unsigned line,
const char *section, unsigned section_line, const char *lvalue,
int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_iaid(const char *unit, const char *filename, unsigned line,
const char *section, unsigned section_line, const char *lvalue,
int ltype, const char *rvalue, void *data, void *userdata);
int net_get_unique_predictable_data(struct udev_device *device, uint64_t *result);
const char *net_get_name(struct udev_device *device);
#endif /* NM_IGNORED */
......
......@@ -84,7 +84,7 @@ struct sd_dhcp_client {
} _packed_ ll;
struct {
/* 255: Node-specific (RFC 4361) */
uint32_t iaid;
be32_t iaid;
struct duid duid;
} _packed_ ns;
struct {
......@@ -300,6 +300,54 @@ int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type,
return 0;
}
#if 0 /* NM_IGNORED */
int sd_dhcp_client_set_iaid_duid(sd_dhcp_client *client, uint32_t iaid,
uint16_t duid_type, uint8_t *duid, size_t duid_len) {
DHCP_CLIENT_DONT_DESTROY(client);
int r;
assert_return(client, -EINVAL);
zero(client->client_id);
client->client_id.type = 255;
/* If IAID is not configured, generate it. */
if (iaid == 0) {
r = dhcp_identifier_set_iaid(client->index, client->mac_addr,
client->mac_addr_len,
&client->client_id.ns.iaid);
if (r < 0)
return r;
} else
client->client_id.ns.iaid = htobe32(iaid);
/* If DUID is not configured, generate DUID-EN. */
if (duid_len == 0) {
r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid,
&duid_len);
if (r < 0)
return r;
} else {
r = dhcp_validate_duid_len(client->client_id.type, duid_len);
if (r < 0)
return r;
client->client_id.ns.duid.type = htobe16(duid_type);
memcpy(&client->client_id.ns.duid.raw.data, duid, duid_len);
duid_len += sizeof(client->client_id.ns.duid.type);
}
client->client_id_len = sizeof(client->client_id.type) + duid_len +
sizeof(client->client_id.ns.iaid);
if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
log_dhcp_client(client, "Configured IAID+DUID, restarting.");
client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
sd_dhcp_client_start(client);
}
return 0;
}
#endif /* NM_IGNORED */
int sd_dhcp_client_set_hostname(sd_dhcp_client *client,
const char *hostname) {
char *new_hostname = NULL;
......
......@@ -182,44 +182,34 @@ static int client_ensure_duid(sd_dhcp6_client *client) {
return dhcp_identifier_set_duid_en(&client->duid, &client->duid_len);
}
int sd_dhcp6_client_set_duid(
sd_dhcp6_client *client,
uint16_t type,
uint8_t *duid, size_t duid_len) {
int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t duid_type,
uint8_t *duid, size_t duid_len) {
int r;
assert_return(client, -EINVAL);
assert_return(duid, -EINVAL);
assert_return(duid_len > 0 && duid_len <= MAX_DUID_LEN, -EINVAL);
assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
switch (type) {
case DHCP6_DUID_LLT:
if (duid_len <= sizeof(client->duid.llt))
return -EINVAL;
break;
case DHCP6_DUID_EN:
if (duid_len != sizeof(client->duid.en))
return -EINVAL;
break;
case DHCP6_DUID_LL:
if (duid_len <= sizeof(client->duid.ll))
return -EINVAL;
break;
case DHCP6_DUID_UUID:
if (duid_len != sizeof(client->duid.uuid))
return -EINVAL;
break;
default:
/* accept unknown type in order to be forward compatible */
break;
if (duid_len > 0) {
r = dhcp_validate_duid_len(duid_type, duid_len);
if (r < 0)
return r;
client->duid.type = htobe16(duid_type);
memcpy(&client->duid.raw.data, duid, duid_len);
client->duid_len = duid_len + sizeof(client->duid.type);
}
client->duid.type = htobe16(type);
memcpy(&client->duid.raw.data, duid, duid_len);
client->duid_len = duid_len + sizeof(client->duid.type);
return 0;
}
#if 0 /* NM_IGNORED */
int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, uint32_t iaid) {
assert_return(client, -EINVAL);
assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
client->ia_na.id = htobe32(iaid);
return 0;
}
#endif /* NM_IGNORED */
int sd_dhcp6_client_set_information_request(sd_dhcp6_client *client, int enabled) {
assert_return(client, -EINVAL);
......
......@@ -98,6 +98,8 @@ int sd_dhcp_client_set_mac(sd_dhcp_client *client, const uint8_t *addr,
size_t addr_len, uint16_t arp_type);
int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type,
const uint8_t *data, size_t data_len);
int sd_dhcp_client_set_iaid_duid(sd_dhcp_client *client, uint32_t iaid,
uint16_t duid_type, uint8_t *duid, size_t duid_len);
int sd_dhcp_client_get_client_id(sd_dhcp_client *client, uint8_t *type,
const uint8_t **data, size_t *data_len);
int sd_dhcp_client_set_mtu(sd_dhcp_client *client, uint32_t mtu);
......
......@@ -85,8 +85,9 @@ int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index);
int sd_dhcp6_client_set_local_address(sd_dhcp6_client *client, const struct in6_addr *local_address);
int sd_dhcp6_client_set_mac(sd_dhcp6_client *client, const uint8_t *addr,
size_t addr_len, uint16_t arp_type);
int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t type, uint8_t *duid,
size_t duid_len);
int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t duid_type,
uint8_t *duid, size_t duid_len);
int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, uint32_t iaid);
int sd_dhcp6_client_set_information_request(sd_dhcp6_client *client, int enabled);
int sd_dhcp6_client_get_information_request(sd_dhcp6_client *client, int *enabled);
int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client,
......
......@@ -33,6 +33,87 @@ _SD_BEGIN_DECLARATIONS;
typedef struct sd_lldp sd_lldp;
typedef struct sd_lldp_neighbor sd_lldp_neighbor;
#define SD_LLDP_MULTICAST_ADDR { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e }
/* IEEE 802.3AB Clause 9: TLV Types */
enum {
SD_LLDP_TYPE_END = 0,
SD_LLDP_TYPE_CHASSIS_ID = 1,
SD_LLDP_TYPE_PORT_ID = 2,
SD_LLDP_TYPE_TTL = 3,
SD_LLDP_TYPE_PORT_DESCRIPTION = 4,
SD_LLDP_TYPE_SYSTEM_NAME = 5,
SD_LLDP_TYPE_SYSTEM_DESCRIPTION = 6,
SD_LLDP_TYPE_SYSTEM_CAPABILITIES = 7,
SD_LLDP_TYPE_MGMT_ADDRESS = 8,
SD_LLDP_TYPE_PRIVATE = 127,
};
/* IEEE 802.3AB Clause 9.5.2: Chassis subtypes */
enum {
SD_LLDP_CHASSIS_SUBTYPE_RESERVED = 0,
SD_LLDP_CHASSIS_SUBTYPE_CHASSIS_COMPONENT = 1,
SD_LLDP_CHASSIS_SUBTYPE_INTERFACE_ALIAS = 2,
SD_LLDP_CHASSIS_SUBTYPE_PORT_COMPONENT = 3,
SD_LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS = 4,
SD_LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS = 5,
SD_LLDP_CHASSIS_SUBTYPE_INTERFACE_NAME = 6,
SD_LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED = 7,