summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSusant Sahani <ssahani@users.noreply.github.com>2017-06-25 22:42:57 +0000
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2017-06-25 18:42:57 -0400
commit593022fa377d40d9a645919759b04c53cf4eace8 (patch)
treee7f3fbd15dd1c0848e4be49df5ddc020f93c9e0f
parent66c36247e95e598d5cf6d78a627946d10f8c576f (diff)
downloadsystemd-593022fa377d40d9a645919759b04c53cf4eace8.tar.gz
systemd-link: add support to configure the device port (#6153)
This work allows to configure device port: tp — An Ethernet interface using Twisted-Pair cable as the medium. aui — Attachment Unit Interface (AUI). Normally used with hubs. bnc — An Ethernet interface using BNC connectors and co-axial cable. mii — An Ethernet interface using a Media Independent Interface (MII). fibre — An Ethernet interface using Optical Fibre as the medium.
-rw-r--r--man/systemd.link.xml41
-rw-r--r--src/udev/net/ethtool-util.c29
-rw-r--r--src/udev/net/ethtool-util.h20
-rw-r--r--src/udev/net/link-config-gperf.gperf1
-rw-r--r--src/udev/net/link-config.c7
-rw-r--r--src/udev/net/link-config.h1
6 files changed, 88 insertions, 11 deletions
diff --git a/man/systemd.link.xml b/man/systemd.link.xml
index 023e24eeb3..1e4a1528db 100644
--- a/man/systemd.link.xml
+++ b/man/systemd.link.xml
@@ -402,6 +402,47 @@
</listitem>
</varlistentry>
<varlistentry>
+ <term><varname>Port=</varname></term>
+ <listitem>
+ <para>The port option is used to select the device port. The
+ supported values are:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>tp</literal></term>
+ <listitem>
+ <para>An Ethernet interface using Twisted-Pair cable as the medium.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>aui</literal></term>
+ <listitem>
+ <para>Attachment Unit Interface (AUI). Normally used with hubs.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>bnc</literal></term>
+ <listitem>
+ <para>An Ethernet interface using BNC connectors and co-axial cable.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>mii</literal></term>
+ <listitem>
+ <para>An Ethernet interface using a Media Independent Interface (MII).</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>fibre</literal></term>
+ <listitem>
+ <para>An Ethernet interface using Optical Fibre as the medium.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><varname>TCPSegmentationOffload=</varname></term>
<listitem>
<para>The TCP Segmentation Offload (TSO) when true enables
diff --git a/src/udev/net/ethtool-util.c b/src/udev/net/ethtool-util.c
index d7edbb396b..19f5f049e4 100644
--- a/src/udev/net/ethtool-util.c
+++ b/src/udev/net/ethtool-util.c
@@ -25,6 +25,7 @@
#include "conf-parser.h"
#include "ethtool-util.h"
#include "log.h"
+#include "link-config.h"
#include "socket-util.h"
#include "string-table.h"
#include "strxcpyx.h"
@@ -48,6 +49,17 @@ static const char* const wol_table[_WOL_MAX] = {
DEFINE_STRING_TABLE_LOOKUP(wol, WakeOnLan);
DEFINE_CONFIG_PARSE_ENUM(config_parse_wol, wol, WakeOnLan, "Failed to parse WakeOnLan setting");
+static const char* const port_table[_NET_DEV_PORT_MAX] = {
+ [NET_DEV_PORT_TP] = "tp",
+ [NET_DEV_PORT_AUI] = "aui",
+ [NET_DEV_PORT_MII] = "mii",
+ [NET_DEV_PORT_FIBRE] = "fibre",
+ [NET_DEV_PORT_BNC] = "bnc"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(port, NetDevPort);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_port, port, NetDevPort, "Failed to parse Port setting");
+
static const char* const netdev_feature_table[_NET_DEV_FEAT_MAX] = {
[NET_DEV_FEAT_GSO] = "tx-generic-segmentation",
[NET_DEV_FEAT_GRO] = "rx-gro",
@@ -488,12 +500,12 @@ static int set_sset(int *fd, struct ifreq *ifr, const struct ethtool_link_usetti
* enabled speed and @duplex is %DUPLEX_UNKNOWN or the best enabled duplex mode.
*/
-int ethtool_set_glinksettings(int *fd, const char *ifname, unsigned int speed, Duplex duplex, int autonegotiation) {
+int ethtool_set_glinksettings(int *fd, const char *ifname, struct link_config *link) {
_cleanup_free_ struct ethtool_link_usettings *u = NULL;
struct ifreq ifr = {};
int r;
- if (autonegotiation != 0) {
+ if (link->autonegotiation != 0) {
log_info("link_config: autonegotiation is unset or enabled, the speed and duplex are not writable.");
return 0;
}
@@ -514,13 +526,16 @@ int ethtool_set_glinksettings(int *fd, const char *ifname, unsigned int speed, D
return log_warning_errno(r, "link_config: Cannot get device settings for %s : %m", ifname);
}
- if (speed)
- u->base.speed = speed;
+ if (link->speed)
+ u->base.speed = link->speed;
+
+ if (link->duplex != _DUP_INVALID)
+ u->base.duplex = link->duplex;
- if (duplex != _DUP_INVALID)
- u->base.duplex = duplex;
+ if (link->port != _NET_DEV_PORT_INVALID)
+ u->base.port = link->port;
- u->base.autoneg = autonegotiation;
+ u->base.autoneg = link->autonegotiation;
if (u->base.cmd == ETHTOOL_GLINKSETTINGS)
r = set_slinksettings(fd, &ifr, u);
diff --git a/src/udev/net/ethtool-util.h b/src/udev/net/ethtool-util.h
index 75d6af396b..a4beedf00f 100644
--- a/src/udev/net/ethtool-util.h
+++ b/src/udev/net/ethtool-util.h
@@ -24,6 +24,8 @@
#include "missing.h"
+struct link_config;
+
/* we can't use DUPLEX_ prefix, as it
* clashes with <linux/ethtool.h> */
typedef enum Duplex {
@@ -51,6 +53,18 @@ typedef enum NetDevFeature {
_NET_DEV_FEAT_INVALID = -1
} NetDevFeature;
+typedef enum NetDevPort {
+ NET_DEV_PORT_TP = 0x00,
+ NET_DEV_PORT_AUI = 0x01,
+ NET_DEV_PORT_MII = 0x02,
+ NET_DEV_PORT_FIBRE = 0x03,
+ NET_DEV_PORT_BNC = 0x04,
+ NET_DEV_PORT_DA = 0x05,
+ NET_DEV_PORT_NONE = 0xef,
+ NET_DEV_PORT_OTHER = 0xff,
+ _NET_DEV_PORT_MAX,
+ _NET_DEV_PORT_INVALID = -1
+} NetDevPort;
#define ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32 (SCHAR_MAX)
@@ -71,7 +85,7 @@ int ethtool_get_driver(int *fd, const char *ifname, char **ret);
int ethtool_set_speed(int *fd, const char *ifname, unsigned int speed, Duplex duplex);
int ethtool_set_wol(int *fd, const char *ifname, WakeOnLan wol);
int ethtool_set_features(int *fd, const char *ifname, NetDevFeature *features);
-int ethtool_set_glinksettings(int *fd, const char *ifname, unsigned int speed, Duplex duplex, int autoneg);
+int ethtool_set_glinksettings(int *fd, const char *ifname, struct link_config *link);
const char *duplex_to_string(Duplex d) _const_;
Duplex duplex_from_string(const char *d) _pure_;
@@ -79,5 +93,9 @@ Duplex duplex_from_string(const char *d) _pure_;
const char *wol_to_string(WakeOnLan wol) _const_;
WakeOnLan wol_from_string(const char *wol) _pure_;
+const char *port_to_string(NetDevPort port) _const_;
+NetDevPort port_from_string(const char *port) _pure_;
+
int config_parse_duplex(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_wol(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_port(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);
diff --git a/src/udev/net/link-config-gperf.gperf b/src/udev/net/link-config-gperf.gperf
index 78e551df22..5488867ba7 100644
--- a/src/udev/net/link-config-gperf.gperf
+++ b/src/udev/net/link-config-gperf.gperf
@@ -36,6 +36,7 @@ Link.BitsPerSecond, config_parse_si_size, 0,
Link.Duplex, config_parse_duplex, 0, offsetof(link_config, duplex)
Link.AutoNegotiation, config_parse_tristate, 0, offsetof(link_config, autonegotiation)
Link.WakeOnLan, config_parse_wol, 0, offsetof(link_config, wol)
+Link.Port, config_parse_port, 0, offsetof(link_config, port)
Link.GenericSegmentationOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_GSO])
Link.TCPSegmentationOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_TSO])
Link.UDPSegmentationOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_UFO])
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index 3af87f1388..e65a8794dc 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -167,6 +167,7 @@ static int load_link(link_config_ctx *ctx, const char *filename) {
link->mac_policy = _MACPOLICY_INVALID;
link->wol = _WOL_INVALID;
link->duplex = _DUP_INVALID;
+ link->port = _NET_DEV_PORT_INVALID;
link->autonegotiation = -1;
memset(&link->features, -1, sizeof(link->features));
@@ -380,15 +381,15 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
speed = DIV_ROUND_UP(config->speed, 1000000);
- r = ethtool_set_glinksettings(&ctx->ethtool_fd, old_name, speed, config->duplex, config->autonegotiation);
+ r = ethtool_set_glinksettings(&ctx->ethtool_fd, old_name, config);
if (r < 0) {
if (r == -EOPNOTSUPP)
r = ethtool_set_speed(&ctx->ethtool_fd, old_name, speed, config->duplex);
if (r < 0)
- log_warning_errno(r, "Could not set speed or duplex of %s to %u Mbps (%s): %m",
- old_name, speed, duplex_to_string(config->duplex));
+ log_warning_errno(r, "Could not set speed, duplex or port (%s) of %s to %u Mbps (%s): %m",
+ port_to_string(config->port), old_name, speed, duplex_to_string(config->duplex));
}
r = ethtool_set_wol(&ctx->ethtool_fd, old_name, config->wol);
diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h
index 5a25cec6fd..ff91a65135 100644
--- a/src/udev/net/link-config.h
+++ b/src/udev/net/link-config.h
@@ -71,6 +71,7 @@ struct link_config {
Duplex duplex;
int autonegotiation;
WakeOnLan wol;
+ NetDevPort port;
NetDevFeature features[_NET_DEV_FEAT_MAX];
LIST_FIELDS(link_config, links);