From 17c5337f7b2993619d84acc2088b2ba1789e6477 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 30 Oct 2024 02:01:59 +0900 Subject: [PATCH 1/4] network/netdev: introduce netdev_can_set_mac/mtu() helper functions Several netdevs cannot set IFLA_ADDRESS or IFLA_MTU attribute on update. Currently, the vtable field is unused, as we do not support updating existing netdevs. Preparation for later commits. --- src/network/netdev/netdev.c | 29 +++++++++++++++++++++++++++-- src/network/netdev/netdev.h | 6 ++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c index f7598dc7ea..4d55250569 100644 --- a/src/network/netdev/netdev.c +++ b/src/network/netdev/netdev.c @@ -611,6 +611,31 @@ finalize: return 0; } +static bool netdev_can_set_mac(NetDev *netdev, const struct hw_addr_data *hw_addr) { + assert(netdev); + assert(hw_addr); + + if (hw_addr->length <= 0) + return false; + + if (!NETDEV_VTABLE(netdev)->can_set_mac) + return true; + + return NETDEV_VTABLE(netdev)->can_set_mac(netdev, hw_addr); +} + +static bool netdev_can_set_mtu(NetDev *netdev, uint32_t mtu) { + assert(netdev); + + if (mtu <= 0) + return false; + + if (!NETDEV_VTABLE(netdev)->can_set_mtu) + return true; + + return NETDEV_VTABLE(netdev)->can_set_mtu(netdev, mtu); +} + static int netdev_create_message(NetDev *netdev, Link *link, sd_netlink_message *m) { int r; @@ -623,14 +648,14 @@ static int netdev_create_message(NetDev *netdev, Link *link, sd_netlink_message if (r < 0) return r; - if (hw_addr.length > 0) { + if (netdev_can_set_mac(netdev, &hw_addr)) { log_netdev_debug(netdev, "Using MAC address: %s", HW_ADDR_TO_STR(&hw_addr)); r = netlink_message_append_hw_addr(m, IFLA_ADDRESS, &hw_addr); if (r < 0) return r; } - if (netdev->mtu != 0) { + if (netdev_can_set_mtu(netdev, netdev->mtu)) { r = sd_netlink_message_append_u32(m, IFLA_MTU, netdev->mtu); if (r < 0) return r; diff --git a/src/network/netdev/netdev.h b/src/network/netdev/netdev.h index 10b9d0dd77..9d8c4c7afd 100644 --- a/src/network/netdev/netdev.h +++ b/src/network/netdev/netdev.h @@ -179,6 +179,12 @@ typedef struct NetDevVTable { /* get ifindex of the netdev. */ int (*get_ifindex)(NetDev *netdev, const char *name); + /* provides if MAC address can be set. If this is not set, assumed to be yes. */ + bool (*can_set_mac)(NetDev *netdev, const struct hw_addr_data *hw_addr); + + /* provides if MTU can be set. If this is not set, assumed to be yes. */ + bool (*can_set_mtu)(NetDev *netdev, uint32_t mtu); + /* expected iftype, e.g. ARPHRD_ETHER. */ uint16_t iftype; From 49639363ab189c7bf0dc57ed108717f8ddf054cb Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 29 Oct 2024 05:30:39 +0900 Subject: [PATCH 2/4] network/vxlan: do not try to update several parameters Currently, netdev->ifindex is always zero when this function is called. So, this does not change any behavior. Preparation for later commits. --- src/network/netdev/vxlan.c | 70 +++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/src/network/netdev/vxlan.c b/src/network/netdev/vxlan.c index e928b20d83..2c4aaecbf0 100644 --- a/src/network/netdev/vxlan.c +++ b/src/network/netdev/vxlan.c @@ -44,12 +44,6 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netli int local_family, r; VxLan *v = VXLAN(netdev); - if (v->vni <= VXLAN_VID_MAX) { - r = sd_netlink_message_append_u32(m, IFLA_VXLAN_ID, v->vni); - if (r < 0) - return r; - } - if (in_addr_is_set(v->group_family, &v->group)) { if (v->group_family == AF_INET) r = sd_netlink_message_append_in_addr(m, IFLA_VXLAN_GROUP, &v->group.in); @@ -83,12 +77,12 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netli if (r < 0) return r; - if (v->inherit) { - r = sd_netlink_message_append_flag(m, IFLA_VXLAN_TTL_INHERIT); - if (r < 0) - return r; - } else { - r = sd_netlink_message_append_u8(m, IFLA_VXLAN_TTL, v->ttl); + r = sd_netlink_message_append_u8(m, IFLA_VXLAN_TTL, v->ttl); + if (r < 0) + return r; + + if (v->fdb_ageing != 0) { + r = sd_netlink_message_append_u32(m, IFLA_VXLAN_AGEING, v->fdb_ageing / USEC_PER_SEC); if (r < 0) return r; } @@ -99,6 +93,34 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netli return r; } + r = sd_netlink_message_append_u32(m, IFLA_VXLAN_LABEL, htobe32(v->flow_label)); + if (r < 0) + return r; + + if (v->df != _NETDEV_VXLAN_DF_INVALID) { + r = sd_netlink_message_append_u8(m, IFLA_VXLAN_DF, v->df); + if (r < 0) + return r; + } + + if (netdev->ifindex > 0) + return 0; + + /* The properties below cannot be updated, and the kernel refuses the whole request if one of the + * following attributes is set for an existing interface. */ + + if (v->vni <= VXLAN_VID_MAX) { + r = sd_netlink_message_append_u32(m, IFLA_VXLAN_ID, v->vni); + if (r < 0) + return r; + } + + if (v->inherit) { + r = sd_netlink_message_append_flag(m, IFLA_VXLAN_TTL_INHERIT); + if (r < 0) + return r; + } + r = sd_netlink_message_append_u8(m, IFLA_VXLAN_LEARNING, v->learning); if (r < 0) return r; @@ -119,12 +141,6 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netli if (r < 0) return r; - if (v->fdb_ageing != 0) { - r = sd_netlink_message_append_u32(m, IFLA_VXLAN_AGEING, v->fdb_ageing / USEC_PER_SEC); - if (r < 0) - return r; - } - if (v->max_fdb != 0) { r = sd_netlink_message_append_u32(m, IFLA_VXLAN_LIMIT, v->max_fdb); if (r < 0) @@ -166,10 +182,6 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netli return r; } - r = sd_netlink_message_append_u32(m, IFLA_VXLAN_LABEL, htobe32(v->flow_label)); - if (r < 0) - return r; - if (v->group_policy) { r = sd_netlink_message_append_flag(m, IFLA_VXLAN_GBP); if (r < 0) @@ -182,15 +194,16 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netli return r; } - if (v->df != _NETDEV_VXLAN_DF_INVALID) { - r = sd_netlink_message_append_u8(m, IFLA_VXLAN_DF, v->df); - if (r < 0) - return r; - } - return 0; } +static bool vxlan_can_set_mtu(NetDev *netdev, uint32_t mtu) { + assert(netdev); + + /* MTU cannot be updated. Even unchanged, IFLA_MTU attribute cannot be set in the message. */ + return netdev->ifindex <= 0; +} + int config_parse_vxlan_address( const char *unit, const char *filename, @@ -431,6 +444,7 @@ const NetDevVTable vxlan_vtable = { .create_type = NETDEV_CREATE_STACKED, .is_ready_to_create = netdev_vxlan_is_ready_to_create, .config_verify = netdev_vxlan_verify, + .can_set_mtu = vxlan_can_set_mtu, .iftype = ARPHRD_ETHER, .generate_mac = true, }; From 6804bbdaf153f533ac874ed2c937d9cce230f035 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 30 Oct 2024 00:22:17 +0900 Subject: [PATCH 3/4] network/macsec: IFLA_MACSEC_PORT attribute cannot be changed Also, though currently not supported by networkd, IFLA_MACSEC_CIPHER_SUITE, IFLA_MACSEC_ICV_LEN, IFLA_MACSEC_SCI cannot be updated. --- src/network/netdev/macsec.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/network/netdev/macsec.c b/src/network/netdev/macsec.c index 15d79906f7..6dd434f803 100644 --- a/src/network/netdev/macsec.c +++ b/src/network/netdev/macsec.c @@ -509,12 +509,6 @@ static int netdev_macsec_fill_message_create(NetDev *netdev, Link *link, sd_netl MACsec *v = MACSEC(netdev); int r; - if (v->port > 0) { - r = sd_netlink_message_append_u16(m, IFLA_MACSEC_PORT, v->port); - if (r < 0) - return r; - } - if (v->encrypt >= 0) { r = sd_netlink_message_append_u8(m, IFLA_MACSEC_ENCRYPT, v->encrypt); if (r < 0) @@ -525,6 +519,20 @@ static int netdev_macsec_fill_message_create(NetDev *netdev, Link *link, sd_netl if (r < 0) return r; + /* The properties below cannot be updated, and the kernel refuses the whole request if one of the + * following attributes is set for an existing interface. */ + if (netdev->ifindex > 0) + return 0; + + if (v->port > 0) { + r = sd_netlink_message_append_u16(m, IFLA_MACSEC_PORT, v->port); + if (r < 0) + return r; + } + + /* Currently not supported by networkd, but IFLA_MACSEC_CIPHER_SUITE, IFLA_MACSEC_ICV_LEN, and + * IFLA_MACSEC_SCI can neither set for an existing interface. */ + return 0; } From ceae9f9a384b1485449a151503e9aa4f1c2ec33d Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 30 Oct 2024 01:36:10 +0900 Subject: [PATCH 4/4] network/ipvlan: do not try to update MAC address --- src/network/netdev/ipvlan.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/network/netdev/ipvlan.c b/src/network/netdev/ipvlan.c index 892678b4ad..5cfae1eb64 100644 --- a/src/network/netdev/ipvlan.c +++ b/src/network/netdev/ipvlan.c @@ -37,6 +37,13 @@ static int netdev_ipvlan_fill_message_create(NetDev *netdev, Link *link, sd_netl return 0; } +static bool ipvlan_can_set_mac(NetDev *netdev, const struct hw_addr_data *hw_addr) { + assert(netdev); + + /* MAC address cannot be updated. Even unchanged, IFLA_ADDRESS attribute cannot be set in the message. */ + return netdev->ifindex <= 0; +} + static void ipvlan_init(NetDev *netdev) { IPVlan *m = ASSERT_PTR(netdev)->kind == NETDEV_KIND_IPVLAN ? IPVLAN(netdev) : IPVTAP(netdev); @@ -50,6 +57,7 @@ const NetDevVTable ipvlan_vtable = { .sections = NETDEV_COMMON_SECTIONS "IPVLAN\0", .fill_message_create = netdev_ipvlan_fill_message_create, .create_type = NETDEV_CREATE_STACKED, + .can_set_mac = ipvlan_can_set_mac, .iftype = ARPHRD_ETHER, .generate_mac = true, }; @@ -60,6 +68,7 @@ const NetDevVTable ipvtap_vtable = { .sections = NETDEV_COMMON_SECTIONS "IPVTAP\0", .fill_message_create = netdev_ipvlan_fill_message_create, .create_type = NETDEV_CREATE_STACKED, + .can_set_mac = ipvlan_can_set_mac, .iftype = ARPHRD_ETHER, .generate_mac = true, };