systemd-link: add support to configure the device port (#6153)
authorSusant Sahani <ssahani@users.noreply.github.com>
Sun, 25 Jun 2017 22:42:57 +0000 (22:42 +0000)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sun, 25 Jun 2017 22:42:57 +0000 (18:42 -0400)
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.

man/systemd.link.xml
src/udev/net/ethtool-util.c
src/udev/net/ethtool-util.h
src/udev/net/link-config-gperf.gperf
src/udev/net/link-config.c
src/udev/net/link-config.h

index 023e24e..1e4a152 100644 (file)
         </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
index d7edbb3..19f5f04 100644 (file)
@@ -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);
index 75d6af3..a4beedf 100644 (file)
@@ -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);
index 78e551d..5488867 100644 (file)
@@ -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])
index 3af87f1..e65a879 100644 (file)
@@ -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);
index 5a25cec..ff91a65 100644 (file)
@@ -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);