mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-31 13:03:02 +02:00
Add support for setting and fetching IPv4/IPv6 interface MTU
Setting the link MTU in Linux changes the sysctl IPV6 MTU, so we have to set the IPv6 MTU on each run in case the IPv4 MTU changes. Hence, this also means the IPv6 MTU must be set *after* the IPv4 (link) MTU. statd has been updated to read the sysctl setting for IPv6 MTU. Notice how the loopback interface is unsupported for config + status. Fixes issue #151 Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
@@ -416,6 +416,22 @@ static int netdag_set_conf_addrs(FILE *ip, const char *ifname,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int netdag_gen_link_mtu(FILE *ip, struct lyd_node *dif)
|
||||
{
|
||||
const char *ifname = lydx_get_cattr(dif, "name");
|
||||
struct lyd_node *node;
|
||||
struct lydx_diff nd;
|
||||
|
||||
if (!strcmp(ifname, "lo")) /* skip for now */
|
||||
return 0;
|
||||
|
||||
node = lydx_get_descendant(lyd_child(dif), "ipv4", "mtu", NULL);
|
||||
if (node && lydx_get_diff(node, &nd))
|
||||
fprintf(ip, "link set %s mtu %s\n", ifname, nd.new ? nd.val : "1500");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int netdag_gen_link_addr(FILE *ip, struct lyd_node *cif, struct lyd_node *dif)
|
||||
{
|
||||
const char *ifname = lydx_get_cattr(dif, "name");
|
||||
@@ -570,12 +586,12 @@ static int netdag_gen_ipv4_autoconf(struct dagger *net, struct lyd_node *cif,
|
||||
return err;
|
||||
}
|
||||
|
||||
static int netdag_gen_sysctl_bool(struct dagger *net,
|
||||
const char *ifname, FILE **fpp,
|
||||
struct lyd_node *node,
|
||||
const char *fmt, ...)
|
||||
static int netdag_gen_sysctl_setting(struct dagger *net, const char *ifname, FILE **fpp,
|
||||
int isboolean, const char *fallback,
|
||||
struct lyd_node *node, const char *fmt, ...)
|
||||
{
|
||||
struct lydx_diff nd;
|
||||
const char *value;
|
||||
va_list ap;
|
||||
|
||||
if (!node)
|
||||
@@ -584,18 +600,32 @@ static int netdag_gen_sysctl_bool(struct dagger *net,
|
||||
if (!lydx_get_diff(node, &nd))
|
||||
return 0;
|
||||
|
||||
*fpp = *fpp ? : dagger_fopen_next(net, "init", ifname,
|
||||
60, "init.sysctl");
|
||||
*fpp = *fpp ? : dagger_fopen_next(net, "init", ifname, 60, "init.sysctl");
|
||||
if (!*fpp)
|
||||
return -EIO;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vfprintf(*fpp, fmt, ap);
|
||||
va_end(ap);
|
||||
fprintf(*fpp, " = %u\n", (nd.new && !strcmp(nd.val, "true")) ? 1 : 0);
|
||||
|
||||
if (isboolean) {
|
||||
if (nd.new && !strcmp(nd.val, "true"))
|
||||
value = "1";
|
||||
else
|
||||
value = "0";
|
||||
} else {
|
||||
if (nd.new)
|
||||
value = nd.val;
|
||||
else
|
||||
value = fallback;
|
||||
}
|
||||
|
||||
fprintf(*fpp, " = %s\n", value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int netdag_gen_sysctl(struct dagger *net,
|
||||
struct lyd_node *cif,
|
||||
struct lyd_node *dif)
|
||||
{
|
||||
const char *ifname = lydx_get_cattr(dif, "name");
|
||||
@@ -604,15 +634,21 @@ static int netdag_gen_sysctl(struct dagger *net,
|
||||
int err = 0;
|
||||
|
||||
node = lydx_get_descendant(lyd_child(dif), "ipv4", "forwarding", NULL);
|
||||
err = err ? : netdag_gen_sysctl_bool(net, ifname, &sysctl, node,
|
||||
"net.ipv4.conf.%s.forwarding",
|
||||
ifname);
|
||||
err = err ? : netdag_gen_sysctl_setting(net, ifname, &sysctl, 1, "0", node,
|
||||
"net.ipv4.conf.%s.forwarding", ifname);
|
||||
|
||||
node = lydx_get_descendant(lyd_child(dif), "ipv6", "forwarding", NULL);
|
||||
err = err ? : netdag_gen_sysctl_bool(net, ifname, &sysctl, node,
|
||||
"net.ipv6.conf.%s.forwarding",
|
||||
ifname);
|
||||
err = err ? : netdag_gen_sysctl_setting(net, ifname, &sysctl, 1, "0", node,
|
||||
"net.ipv6.conf.%s.forwarding", ifname);
|
||||
|
||||
if (!strcmp(ifname, "lo")) /* skip for now */
|
||||
goto skip_mtu;
|
||||
|
||||
node = lydx_get_descendant(lyd_child(cif), "ipv6", "mtu", NULL);
|
||||
err = err ? : netdag_gen_sysctl_setting(net, ifname, &sysctl, 0, "1280", node,
|
||||
"net.ipv6.conf.%s.mtu", ifname);
|
||||
|
||||
skip_mtu:
|
||||
if (sysctl)
|
||||
fclose(sysctl);
|
||||
|
||||
@@ -1093,6 +1129,7 @@ static sr_error_t netdag_gen_iface(struct dagger *net,
|
||||
}
|
||||
|
||||
/* Set Addresses */
|
||||
err = err ? : netdag_gen_link_mtu(ip, dif);
|
||||
err = err ? : netdag_gen_link_addr(ip, cif, dif);
|
||||
err = err ? : netdag_gen_ip_addrs(ip, "ipv4", cif, dif);
|
||||
err = err ? : netdag_gen_ip_addrs(ip, "ipv6", cif, dif);
|
||||
@@ -1104,7 +1141,7 @@ static sr_error_t netdag_gen_iface(struct dagger *net,
|
||||
if (!attr || !strcmp(attr, "true"))
|
||||
fprintf(ip, "link set dev %s up state up\n", ifname);
|
||||
|
||||
err = err ? : netdag_gen_sysctl(net, dif);
|
||||
err = err ? : netdag_gen_sysctl(net, cif, dif);
|
||||
|
||||
err_close_ip:
|
||||
fclose(ip);
|
||||
|
||||
@@ -50,10 +50,6 @@ module infix-ip {
|
||||
}
|
||||
}
|
||||
|
||||
deviation "/if:interfaces/if:interface/ip:ipv4/ip:mtu" {
|
||||
deviate not-supported;
|
||||
}
|
||||
|
||||
deviation "/if:interfaces/if:interface/ip:ipv4/ip:address/ip:subnet/ip:netmask" {
|
||||
deviate not-supported;
|
||||
}
|
||||
@@ -62,10 +58,6 @@ module infix-ip {
|
||||
deviate not-supported;
|
||||
}
|
||||
|
||||
deviation "/if:interfaces/if:interface/ip:ipv6/ip:mtu" {
|
||||
deviate not-supported;
|
||||
}
|
||||
|
||||
deviation "/if:interfaces/if:interface/ip:ipv6/ip:address/ip:status" {
|
||||
deviate not-supported;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <jansson.h>
|
||||
@@ -47,6 +48,7 @@ static const char *get_yang_origin(const char *protocol)
|
||||
static int ly_add_ip_mtu(const struct ly_ctx *ctx, struct lyd_node *node,
|
||||
char *xpath, json_t *j_iface, char *ifname)
|
||||
{
|
||||
json_int_t j_mtu;
|
||||
json_t *j_val;
|
||||
int err;
|
||||
|
||||
@@ -57,14 +59,21 @@ static int ly_add_ip_mtu(const struct ly_ctx *ctx, struct lyd_node *node,
|
||||
if (strcmp(ifname, "lo") == 0)
|
||||
return SR_ERR_OK;
|
||||
|
||||
j_val = json_object_get(j_iface, "mtu");
|
||||
if (!json_is_integer(j_val)) {
|
||||
ERROR("Expected a JSON integer for 'mtu'");
|
||||
return SR_ERR_SYS;
|
||||
if (strstr(xpath, "ipv4")) {
|
||||
j_val = json_object_get(j_iface, "mtu");
|
||||
if (!json_is_integer(j_val)) {
|
||||
ERROR("Expected a JSON integer for 'mtu'");
|
||||
return SR_ERR_SYS;
|
||||
}
|
||||
j_mtu = json_integer_value(j_val);
|
||||
} else {
|
||||
if (readllf(&j_mtu, "/proc/sys/net/ipv6/conf/%s/mtu", ifname)) {
|
||||
ERROR("Failed reading sysctl value of %s IPv6 MTU: %s", ifname, strerror(errno));
|
||||
return SR_ERR_SYS;
|
||||
}
|
||||
}
|
||||
|
||||
err = lydx_new_path(ctx, &node, xpath, "mtu", "%lld",
|
||||
json_integer_value(j_val));
|
||||
err = lydx_new_path(ctx, &node, xpath, "mtu", "%lld", j_mtu);
|
||||
if (err) {
|
||||
ERROR("Error, adding 'mtu' to data tree, libyang error %d", err);
|
||||
return SR_ERR_LY;
|
||||
|
||||
Reference in New Issue
Block a user