Compare commits

...
Author SHA1 Message Date
Tobias Waldekranz e511076060 confd: ethtool: Condense logic around autoneg configuration
Rely on the interface diff to figure out if any autoneg related config
has changed; if so, generate the resulting configuration based on the
current interface config.

- Remove loopback check, the model only allows ethernet config on
  interfaces of type "ethernet".

- Split up the input validation of speed/duplex to give the user an
  error message with as much specificity as possible.

- Validate that the configured speed/duplex is supported.

- Move the generated script to execute earlier to avoid unnecessary
  link flapping.

- Use negative POSIX error codes, these are (or at least should be)
  mapped to sysrepo errors in netdag_gen_iface.
2024-01-17 09:39:02 +01:00
Richard Alpe b41a1b337a confd: add the ability to set speed, duplex and autoneg
Add the ability to configure interface speed, duplex and autoneg.
Initially this was pared with YANG model deviations that restricted
explicit interface speed and duplex when autoneg was enabled. But due
to conflicting default states in YANG, this code was dropped.

Signed-off-by: Richard Alpe <richard@bit42.se>
2024-01-16 16:10:22 +01:00
+72
View File
@@ -653,6 +653,76 @@ skip_mtu:
return err;
}
static int netdag_gen_ethtool_autoneg(struct dagger *net, struct lyd_node *cif)
{
struct lyd_node *eth = lydx_get_child(cif, "ethernet");
struct lyd_node *aneg = lydx_get_child(eth, "auto-negotiation");
const char *ifname = lydx_get_cattr(cif, "name");
const char *speed, *duplex;
int mbps, err = 0;
FILE *fp;
fp = dagger_fopen_next(net, "init", ifname, 10, "ethtool-aneg.sh");
if (!fp)
return -EIO;
fprintf(fp, "ethtool --change %s autoneg ", ifname);
if (!aneg || lydx_is_enabled(aneg, "enable")) {
fputs("on\n", fp);
} else {
speed = lydx_get_cattr(eth, "speed");
if (!speed) {
sr_session_set_error_message(net->session, "%s: "
"\"speed\" must be specified "
"when auto-negotiation is disabled", ifname);
err = -EINVAL;
goto out;
}
mbps = (int)(atof(speed) * 1000.);
if (!((mbps == 10) || (mbps == 100))) {
sr_session_set_error_message(net->session, "%s: "
"\"speed\" must be either 0.01 or 0.1 "
"when auto-negotiation is disabled", ifname);
err = -EINVAL;
goto out;
}
duplex = lydx_get_cattr(eth, "duplex");
if (!duplex || (strcmp(duplex, "full") && strcmp(duplex, "half"))) {
sr_session_set_error_message(net->session, "%s: "
"\"duplex\" must be either "
"\"full\" or \"half\" "
"when auto-negotiation is disabled", ifname);
err = -EINVAL;
goto out;
}
fprintf(fp,"off speed %d duplex %s\n", mbps, duplex);
}
out:
fclose(fp);
return err;
}
static int netdag_gen_ethtool(struct dagger *net, struct lyd_node *cif, struct lyd_node *dif)
{
struct lyd_node *eth = lydx_get_child(dif, "ethernet");
int err;
if (lydx_get_descendant(lyd_child(eth), "auto-negotiation", "enable", NULL) ||
lydx_get_child(eth, "speed") ||
lydx_get_child(eth, "duplex")) {
err = netdag_gen_ethtool_autoneg(net, cif);
if (err)
return err;
}
return 0;
}
static int bridge_diff_vlan_port(struct dagger *net, FILE *br, const char *brname, int vid,
const char *brport, int tagged, enum lydx_op op)
{
@@ -1140,6 +1210,8 @@ static sr_error_t netdag_gen_iface(struct dagger *net,
err = err ? : netdag_gen_sysctl(net, cif, dif);
err = err ? : netdag_gen_ethtool(net, cif, dif);
err_close_ip:
fclose(ip);
err: