mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-10 01:17:44 +03:00
LLDP: Add support to transmit MUD URL
This commit is contained in:
parent
f69b4ae885
commit
e9a8c550c1
@ -459,6 +459,7 @@
|
||||
reception.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>BindCarrier=</varname></term>
|
||||
<listitem>
|
||||
@ -2351,6 +2352,28 @@
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>[LLDP] Section Options</title>
|
||||
<para>The <literal>[LLDP]</literal> section manages the Link Layer Discovery Protocol (LLDP) and accepts the
|
||||
following keys.</para>
|
||||
<variablelist class='network-directives'>
|
||||
<varlistentry>
|
||||
<term><varname>MUDURL=</varname></term>
|
||||
<listitem>
|
||||
<para>Controls support for Ethernet LLDP packet's Manufacturer Usage Description (MUD). MUD is an embedded software
|
||||
standard defined by the IETF that allows IoT Device makers to advertise device specifications, including the intended
|
||||
communication patterns for their device when it connects to the network. The network can then use this intent to author
|
||||
a context-specific access policy, so the device functions only within those parameters. Takes an URL of length up to 255
|
||||
characters. A superficial verification that the string is a valid URL
|
||||
will be performed. See
|
||||
<ulink url="https://tools.ietf.org/html/rfc8520">RFC 8520</ulink> for details. The MUD URL received
|
||||
from the LLDP packets will be saved at the state files and can be read via
|
||||
<function>sd_lldp_neighbor_get_mud_url()</function> function.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>[CAN] Section Options</title>
|
||||
<para>The <literal>[CAN]</literal> section manages the Controller Area Network (CAN bus) and accepts the
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <net/if_arp.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "escape.h"
|
||||
#include "env-file.h"
|
||||
#include "fd-util.h"
|
||||
#include "hostname-util.h"
|
||||
@ -18,6 +19,7 @@
|
||||
#include "socket-util.h"
|
||||
#include "string-util.h"
|
||||
#include "unaligned.h"
|
||||
#include "web-util.h"
|
||||
|
||||
/* The LLDP spec calls this "txFastInit", see 9.2.5.19 */
|
||||
#define LLDP_TX_FAST_INIT 4U
|
||||
@ -81,9 +83,11 @@ static int lldp_make_packet(
|
||||
const char *pretty_hostname,
|
||||
uint16_t system_capabilities,
|
||||
uint16_t enabled_capabilities,
|
||||
char *mud,
|
||||
void **ret, size_t *sz) {
|
||||
|
||||
size_t machine_id_length, ifname_length, port_description_length = 0, hostname_length = 0, pretty_hostname_length = 0;
|
||||
size_t machine_id_length, ifname_length, port_description_length = 0, hostname_length = 0,
|
||||
pretty_hostname_length = 0, mud_length = 0;
|
||||
_cleanup_free_ void *packet = NULL;
|
||||
struct ether_header *h;
|
||||
uint8_t *p;
|
||||
@ -110,6 +114,9 @@ static int lldp_make_packet(
|
||||
if (pretty_hostname)
|
||||
pretty_hostname_length = strlen(pretty_hostname);
|
||||
|
||||
if (mud)
|
||||
mud_length = strlen(mud);
|
||||
|
||||
l = sizeof(struct ether_header) +
|
||||
/* Chassis ID */
|
||||
2 + 1 + machine_id_length +
|
||||
@ -134,6 +141,10 @@ static int lldp_make_packet(
|
||||
if (pretty_hostname)
|
||||
l += 2 + pretty_hostname_length;
|
||||
|
||||
/* MUD URL */
|
||||
if (mud)
|
||||
l += 2 + sizeof(SD_LLDP_OUI_MUD) + 1 + mud_length;
|
||||
|
||||
packet = malloc(l);
|
||||
if (!packet)
|
||||
return -ENOMEM;
|
||||
@ -184,6 +195,32 @@ static int lldp_make_packet(
|
||||
p = mempcpy(p, pretty_hostname, pretty_hostname_length);
|
||||
}
|
||||
|
||||
if (mud) {
|
||||
uint8_t oui_mud[sizeof(SD_LLDP_OUI_MUD)] = {0x00, 0x00, 0x5E};
|
||||
/*
|
||||
* +--------+--------+----------+---------+--------------
|
||||
* |TLV Type| len | OUI |subtype | MUDString
|
||||
* | =127 | |= 00 00 5E| = 1 |
|
||||
* |(7 bits)|(9 bits)|(3 octets)|(1 octet)|(1-255 octets)
|
||||
* +--------+--------+----------+---------+--------------
|
||||
* where:
|
||||
|
||||
* o TLV Type = 127 indicates a vendor-specific TLV
|
||||
* o len = indicates the TLV string length
|
||||
* o OUI = 00 00 5E is the organizationally unique identifier of IANA
|
||||
* o subtype = 1 (as assigned by IANA for the MUDstring)
|
||||
* o MUDstring = the length MUST NOT exceed 255 octets
|
||||
*/
|
||||
|
||||
r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_PRIVATE, sizeof(SD_LLDP_OUI_MUD) + 1 + mud_length);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
p = mempcpy(p, &oui_mud, sizeof(SD_LLDP_OUI_MUD));
|
||||
*(p++) = SD_LLDP_OUI_SUBTYPE_MUD_USAGE_DESCRIPTION;
|
||||
p = mempcpy(p, mud, mud_length);
|
||||
}
|
||||
|
||||
r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_SYSTEM_CAPABILITIES, 4);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -281,6 +318,7 @@ static int link_send_lldp(Link *link) {
|
||||
pretty_hostname,
|
||||
SD_LLDP_SYSTEM_CAPABILITIES_STATION|SD_LLDP_SYSTEM_CAPABILITIES_BRIDGE|SD_LLDP_SYSTEM_CAPABILITIES_ROUTER,
|
||||
caps,
|
||||
link->network ? link->network->lldp_mud : NULL,
|
||||
&packet, &packet_size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -414,3 +452,40 @@ int config_parse_lldp_emit(
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_lldp_mud(
|
||||
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) {
|
||||
|
||||
_cleanup_free_ char *unescaped = NULL;
|
||||
Network *n = data;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
|
||||
r = cunescape(rvalue, 0, &unescaped);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to Failed to unescape LLDP MUD URL, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!http_url_is_valid(unescaped) || strlen(unescaped) > 255) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||
"Failed to parse LLDP MUD URL '%s', ignoring: %m", rvalue);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return free_and_replace(n->lldp_mud, unescaped);
|
||||
}
|
||||
|
@ -20,3 +20,4 @@ int link_lldp_emit_start(Link *link);
|
||||
void link_lldp_emit_stop(Link *link);
|
||||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_lldp_emit);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_lldp_mud);
|
||||
|
@ -259,6 +259,7 @@ IPv6Prefix.PreferredLifetimeSec, config_parse_prefix_lifetime,
|
||||
IPv6Prefix.Assign, config_parse_prefix_assign, 0, 0
|
||||
IPv6RoutePrefix.Route, config_parse_route_prefix, 0, 0
|
||||
IPv6RoutePrefix.LifetimeSec, config_parse_route_prefix_lifetime, 0, 0
|
||||
LLDP.MUDURL, config_parse_lldp_mud, 0, 0
|
||||
CAN.BitRate, config_parse_can_bitrate, 0, offsetof(Network, can_bitrate)
|
||||
CAN.SamplePoint, config_parse_permille, 0, offsetof(Network, can_sample_point)
|
||||
CAN.DataBitRate, config_parse_can_bitrate, 0, offsetof(Network, can_data_bitrate)
|
||||
|
@ -485,6 +485,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
|
||||
"IPv6PrefixDelegation\0"
|
||||
"IPv6Prefix\0"
|
||||
"IPv6RoutePrefix\0"
|
||||
"LLDP\0"
|
||||
"TrafficControlQueueingDiscipline\0"
|
||||
"CAN\0"
|
||||
"QDisc\0"
|
||||
@ -726,6 +727,8 @@ static Network *network_free(Network *network) {
|
||||
|
||||
set_free_free(network->dnssec_negative_trust_anchors);
|
||||
|
||||
free(network->lldp_mud);
|
||||
|
||||
ordered_hashmap_free(network->dhcp_client_send_options);
|
||||
ordered_hashmap_free(network->dhcp_client_send_vendor_options);
|
||||
ordered_hashmap_free(network->dhcp_server_send_options);
|
||||
|
@ -258,8 +258,10 @@ struct Network {
|
||||
bool required_for_online; /* Is this network required to be considered online? */
|
||||
LinkOperationalStateRange required_operstate_for_online;
|
||||
|
||||
/* LLDP support */
|
||||
LLDPMode lldp_mode; /* LLDP reception */
|
||||
LLDPEmit lldp_emit; /* LLDP transmission */
|
||||
char *lldp_mud; /* LLDP MUD URL */
|
||||
|
||||
LIST_HEAD(Address, static_addresses);
|
||||
LIST_HEAD(Route, static_routes);
|
||||
|
@ -199,6 +199,8 @@ LifetimeSec=
|
||||
EgressUntagged=
|
||||
VLAN=
|
||||
PVID=
|
||||
[LLDP]
|
||||
MUDURL=
|
||||
[CAN]
|
||||
SamplePoint=
|
||||
BitRate=
|
||||
|
Loading…
Reference in New Issue
Block a user