Skip to content

Commit ccefd04

Browse files
authored
Merge pull request systemd#5529 from ssahani/label
networkd / sd-netlink: add support for address label
2 parents fe685ff + c23ae61 commit ccefd04

File tree

13 files changed

+481
-15
lines changed

13 files changed

+481
-15
lines changed

Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5812,6 +5812,8 @@ libnetworkd_core_la_SOURCES = \
58125812
src/network/networkd-network-bus.c \
58135813
src/network/networkd-address.h \
58145814
src/network/networkd-address.c \
5815+
src/network/networkd-address-label.h \
5816+
src/network/networkd-address-label.c \
58155817
src/network/networkd-route.h \
58165818
src/network/networkd-route.c \
58175819
src/network/networkd-fdb.h \

man/systemd.network.xml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,33 @@
796796
</variablelist>
797797
</refsect1>
798798

799+
<refsect1>
800+
<title>[IPv6AddressLabel] Section Options</title>
801+
802+
<para>An <literal>[IPv6AddressLabel]</literal> section accepts the
803+
following keys. Specify several <literal>[IPv6AddressLabel]</literal>
804+
sections to configure several addresse labels. IPv6 address labels are
805+
used for address selection. See <ulink url="https://tools.ietf.org/html/rfc3484">RFC 3484</ulink>.
806+
Precedence is managed by userspace, and only the label itself is stored in the kernel</para>
807+
808+
<variablelist class='network-directives'>
809+
<varlistentry>
810+
<term><varname>Label=</varname></term>
811+
<listitem>
812+
<para> The label for the prefix (an unsigned integer) ranges 0 to 4294967294.
813+
0xffffffff is reserved. This key is mandatory.</para>
814+
</listitem>
815+
</varlistentry>
816+
<varlistentry>
817+
<term><varname>Prefix=</varname></term>
818+
<listitem>
819+
<para>IPv6 prefix is an address with a prefix length, separated by a slash <literal>/</literal> character.
820+
This key is mandatory. </para>
821+
</listitem>
822+
</varlistentry>
823+
</variablelist>
824+
</refsect1>
825+
799826
<refsect1>
800827
<title>[Route] Section Options</title>
801828
<para>The <literal>[Route]</literal> section accepts the

src/libsystemd/sd-netlink/netlink-types.c

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <linux/veth.h>
2727
#include <linux/if_bridge.h>
2828
#include <linux/if_addr.h>
29+
#include <linux/if_addrlabel.h>
2930
#include <linux/if.h>
3031
#include <linux/ip.h>
3132
#include <linux/if_link.h>
@@ -586,22 +587,35 @@ static const NLTypeSystem rtnl_neigh_type_system = {
586587
.types = rtnl_neigh_types,
587588
};
588589

590+
static const NLType rtnl_addrlabel_types[] = {
591+
[IFAL_ADDRESS] = { .type = NETLINK_TYPE_IN_ADDR, .size = sizeof(struct in6_addr) },
592+
[IFAL_LABEL] = { .type = NETLINK_TYPE_U32 },
593+
};
594+
595+
static const NLTypeSystem rtnl_addrlabel_type_system = {
596+
.count = ELEMENTSOF(rtnl_addrlabel_types),
597+
.types = rtnl_addrlabel_types,
598+
};
599+
589600
static const NLType rtnl_types[] = {
590-
[NLMSG_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = 0 },
591-
[NLMSG_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = sizeof(struct nlmsgerr) },
592-
[RTM_NEWLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
593-
[RTM_DELLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
594-
[RTM_GETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
595-
[RTM_SETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
596-
[RTM_NEWADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
597-
[RTM_DELADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
598-
[RTM_GETADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
599-
[RTM_NEWROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
600-
[RTM_DELROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
601-
[RTM_GETROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
602-
[RTM_NEWNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
603-
[RTM_DELNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
604-
[RTM_GETNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
601+
[NLMSG_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = 0 },
602+
[NLMSG_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = sizeof(struct nlmsgerr) },
603+
[RTM_NEWLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
604+
[RTM_DELLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
605+
[RTM_GETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
606+
[RTM_SETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
607+
[RTM_NEWADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
608+
[RTM_DELADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
609+
[RTM_GETADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
610+
[RTM_NEWROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
611+
[RTM_DELROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
612+
[RTM_GETROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
613+
[RTM_NEWNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
614+
[RTM_DELNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
615+
[RTM_GETNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
616+
[RTM_NEWADDRLABEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_addrlabel_type_system, .size = sizeof(struct ifaddrlblmsg) },
617+
[RTM_DELADDRLABEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_addrlabel_type_system, .size = sizeof(struct ifaddrlblmsg) },
618+
[RTM_GETADDRLABEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_addrlabel_type_system, .size = sizeof(struct ifaddrlblmsg) },
605619
};
606620

607621
const NLTypeSystem type_system_root = {

src/libsystemd/sd-netlink/netlink-util.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ bool rtnl_message_type_is_addr(uint16_t type);
3232
bool rtnl_message_type_is_route(uint16_t type);
3333
bool rtnl_message_type_is_neigh(uint16_t type);
3434

35+
static inline bool rtnl_message_type_is_addrlabel(uint16_t type) {
36+
return IN_SET(type, RTM_NEWADDRLABEL, RTM_DELADDRLABEL, RTM_GETADDRLABEL);
37+
}
38+
3539
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name);
3640
int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, const struct ether_addr *mac, unsigned mtu);
3741

src/libsystemd/sd-netlink/rtnl-message.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
***/
1919

2020
#include <netinet/in.h>
21+
#include <linux/if_addrlabel.h>
2122
#include <stdbool.h>
2223
#include <unistd.h>
2324

@@ -700,3 +701,42 @@ int sd_rtnl_message_get_family(sd_netlink_message *m, int *family) {
700701

701702
return -EOPNOTSUPP;
702703
}
704+
705+
int sd_rtnl_message_new_addrlabel(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int ifindex, int ifal_family) {
706+
struct ifaddrlblmsg *addrlabel;
707+
int r;
708+
709+
assert_return(rtnl_message_type_is_addrlabel(nlmsg_type), -EINVAL);
710+
assert_return(ret, -EINVAL);
711+
712+
r = message_new(rtnl, ret, nlmsg_type);
713+
if (r < 0)
714+
return r;
715+
716+
if (nlmsg_type == RTM_NEWADDRLABEL)
717+
(*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
718+
719+
addrlabel = NLMSG_DATA((*ret)->hdr);
720+
721+
addrlabel->ifal_family = ifal_family;
722+
addrlabel->ifal_index = ifindex;
723+
724+
return 0;
725+
}
726+
727+
int sd_rtnl_message_addrlabel_set_prefixlen(sd_netlink_message *m, unsigned char prefixlen) {
728+
struct ifaddrlblmsg *addrlabel;
729+
730+
assert_return(m, -EINVAL);
731+
assert_return(m->hdr, -EINVAL);
732+
assert_return(rtnl_message_type_is_addrlabel(m->hdr->nlmsg_type), -EINVAL);
733+
734+
addrlabel = NLMSG_DATA(m->hdr);
735+
736+
if (prefixlen > 128)
737+
return -ERANGE;
738+
739+
addrlabel->ifal_prefixlen = prefixlen;
740+
741+
return 0;
742+
}

src/network/meson.build

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ sources = files('''
2727
netdev/vxlan.h
2828
netdev/geneve.c
2929
netdev/geneve.h
30+
networkd-address-label.c
31+
networkd-address-label.h
3032
networkd-address-pool.c
3133
networkd-address-pool.h
3234
networkd-address.c

0 commit comments

Comments
 (0)