diff --git a/src/confd/src/ietf-interfaces.c b/src/confd/src/ietf-interfaces.c index 4cd6c1d78..d4727ae55 100644 --- a/src/confd/src/ietf-interfaces.c +++ b/src/confd/src/ietf-interfaces.c @@ -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); diff --git a/src/confd/yang/infix-ip@2023-09-14.yang b/src/confd/yang/infix-ip@2023-09-14.yang index c92e15b54..2cbd816b6 100644 --- a/src/confd/yang/infix-ip@2023-09-14.yang +++ b/src/confd/yang/infix-ip@2023-09-14.yang @@ -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; } diff --git a/src/statd/iface-ip-addr.c b/src/statd/iface-ip-addr.c index 5362f1c49..b47c54eb0 100644 --- a/src/statd/iface-ip-addr.c +++ b/src/statd/iface-ip-addr.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -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;