Merge pull request #14350 from yuwata/network-udev-altnames-support

network, udev: add altname support
This commit is contained in:
Lennart Poettering 2019-12-16 09:15:23 +01:00 committed by GitHub
commit 32b7cdc14c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 1245 additions and 793 deletions

View File

@ -356,6 +356,14 @@
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>AlternativeName=</varname></term>
<listitem>
<para>The alternative interface name to use. This option can be specified multiple times.
If the empty string is assigned to this option, the list is reset, and all prior assignments
have no effect.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>MTUBytes=</varname></term>
<listitem>

View File

@ -132,10 +132,9 @@
<varlistentry>
<term><varname>Name=</varname></term>
<listitem>
<para>A whitespace-separated list of shell-style globs
matching the device name, as exposed by the udev property
<literal>INTERFACE</literal>. If the list is prefixed
with a "!", the test is inverted.</para>
<para>A whitespace-separated list of shell-style globs matching the device name, as exposed
by the udev property <literal>INTERFACE</literal>, or device's alternative names. If the
list is prefixed with a "!", the test is inverted.</para>
</listitem>
</varlistentry>
<varlistentry>

View File

@ -270,6 +270,7 @@ struct btrfs_ioctl_fs_info_args {
#define BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA (1ULL << 8)
#define BTRFS_FEATURE_INCOMPAT_NO_HOLES (1ULL << 9)
#define BTRFS_FEATURE_INCOMPAT_METADATA_UUID (1ULL << 10)
#define BTRFS_FEATURE_INCOMPAT_RAID1C34 (1ULL << 11)
struct btrfs_ioctl_feature_flags {
__u64 compat_flags;
@ -665,7 +666,12 @@ struct btrfs_ioctl_get_dev_stats {
/* out values: */
__u64 values[BTRFS_DEV_STAT_VALUES_MAX];
__u64 unused[128 - 2 - BTRFS_DEV_STAT_VALUES_MAX]; /* pad to 1k */
/*
* This pads the struct to 1032 bytes. It was originally meant to pad to
* 1024 bytes, but when adding the flags field, the padding calculation
* was not adjusted.
*/
__u64 unused[128 - 2 - BTRFS_DEV_STAT_VALUES_MAX];
};
#define BTRFS_QUOTA_CTL_ENABLE 1
@ -826,7 +832,9 @@ enum btrfs_err_code {
BTRFS_ERROR_DEV_TGT_REPLACE,
BTRFS_ERROR_DEV_MISSING_NOT_FOUND,
BTRFS_ERROR_DEV_ONLY_WRITABLE,
BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS
BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS,
BTRFS_ERROR_DEV_RAID1C3_MIN_NOT_MET,
BTRFS_ERROR_DEV_RAID1C4_MIN_NOT_MET,
};
#define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
@ -917,10 +925,8 @@ enum btrfs_err_code {
#define BTRFS_IOC_QUOTA_RESCAN_STATUS _IOR(BTRFS_IOCTL_MAGIC, 45, \
struct btrfs_ioctl_quota_rescan_args)
#define BTRFS_IOC_QUOTA_RESCAN_WAIT _IO(BTRFS_IOCTL_MAGIC, 46)
#define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 49, \
char[BTRFS_LABEL_SIZE])
#define BTRFS_IOC_SET_FSLABEL _IOW(BTRFS_IOCTL_MAGIC, 50, \
char[BTRFS_LABEL_SIZE])
#define BTRFS_IOC_GET_FSLABEL FS_IOC_GETFSLABEL
#define BTRFS_IOC_SET_FSLABEL FS_IOC_SETFSLABEL
#define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \
struct btrfs_ioctl_get_dev_stats)
#define BTRFS_IOC_DEV_REPLACE _IOWR(BTRFS_IOCTL_MAGIC, 53, \

View File

@ -300,7 +300,12 @@
#define BTRFS_CSUM_SIZE 32
/* csum types */
#define BTRFS_CSUM_TYPE_CRC32 0
enum btrfs_csum_type {
BTRFS_CSUM_TYPE_CRC32 = 0,
BTRFS_CSUM_TYPE_XXHASH = 1,
BTRFS_CSUM_TYPE_SHA256 = 2,
BTRFS_CSUM_TYPE_BLAKE2 = 3,
};
/*
* flags definitions for directory entry item type
@ -735,10 +740,12 @@ struct btrfs_balance_item {
__le64 unused[4];
} __attribute__ ((__packed__));
#define BTRFS_FILE_EXTENT_INLINE 0
#define BTRFS_FILE_EXTENT_REG 1
#define BTRFS_FILE_EXTENT_PREALLOC 2
#define BTRFS_FILE_EXTENT_TYPES 2
enum {
BTRFS_FILE_EXTENT_INLINE = 0,
BTRFS_FILE_EXTENT_REG = 1,
BTRFS_FILE_EXTENT_PREALLOC = 2,
BTRFS_NR_FILE_EXTENT_TYPES = 3,
};
struct btrfs_file_extent_item {
/*
@ -806,11 +813,6 @@ struct btrfs_dev_stats_item {
#define BTRFS_DEV_REPLACE_ITEM_CONT_READING_FROM_SRCDEV_MODE_ALWAYS 0
#define BTRFS_DEV_REPLACE_ITEM_CONT_READING_FROM_SRCDEV_MODE_AVOID 1
#define BTRFS_DEV_REPLACE_ITEM_STATE_NEVER_STARTED 0
#define BTRFS_DEV_REPLACE_ITEM_STATE_STARTED 1
#define BTRFS_DEV_REPLACE_ITEM_STATE_SUSPENDED 2
#define BTRFS_DEV_REPLACE_ITEM_STATE_FINISHED 3
#define BTRFS_DEV_REPLACE_ITEM_STATE_CANCELED 4
struct btrfs_dev_replace_item {
/*
@ -839,6 +841,8 @@ struct btrfs_dev_replace_item {
#define BTRFS_BLOCK_GROUP_RAID10 (1ULL << 6)
#define BTRFS_BLOCK_GROUP_RAID5 (1ULL << 7)
#define BTRFS_BLOCK_GROUP_RAID6 (1ULL << 8)
#define BTRFS_BLOCK_GROUP_RAID1C3 (1ULL << 9)
#define BTRFS_BLOCK_GROUP_RAID1C4 (1ULL << 10)
#define BTRFS_BLOCK_GROUP_RESERVED (BTRFS_AVAIL_ALLOC_BIT_SINGLE | \
BTRFS_SPACE_INFO_GLOBAL_RSV)
@ -850,6 +854,8 @@ enum btrfs_raid_types {
BTRFS_RAID_SINGLE,
BTRFS_RAID_RAID5,
BTRFS_RAID_RAID6,
BTRFS_RAID_RAID1C3,
BTRFS_RAID_RAID1C4,
BTRFS_NR_RAID_TYPES
};
@ -859,6 +865,8 @@ enum btrfs_raid_types {
#define BTRFS_BLOCK_GROUP_PROFILE_MASK (BTRFS_BLOCK_GROUP_RAID0 | \
BTRFS_BLOCK_GROUP_RAID1 | \
BTRFS_BLOCK_GROUP_RAID1C3 | \
BTRFS_BLOCK_GROUP_RAID1C4 | \
BTRFS_BLOCK_GROUP_RAID5 | \
BTRFS_BLOCK_GROUP_RAID6 | \
BTRFS_BLOCK_GROUP_DUP | \
@ -866,6 +874,10 @@ enum btrfs_raid_types {
#define BTRFS_BLOCK_GROUP_RAID56_MASK (BTRFS_BLOCK_GROUP_RAID5 | \
BTRFS_BLOCK_GROUP_RAID6)
#define BTRFS_BLOCK_GROUP_RAID1_MASK (BTRFS_BLOCK_GROUP_RAID1 | \
BTRFS_BLOCK_GROUP_RAID1C3 | \
BTRFS_BLOCK_GROUP_RAID1C4)
/*
* We need a bit for restriper to be able to tell when chunks of type
* SINGLE are available. This "extended" profile format is used in

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
#ifndef _UAPI_CAN_VXCAN_H
#define _UAPI_CAN_VXCAN_H

View File

@ -32,6 +32,7 @@
#define IFNAMSIZ 16
#endif /* __UAPI_DEF_IF_IFNAMSIZ */
#define IFALIASZ 256
#define ALTIFNAMSIZ 128
#include <linux/hdlc/ioctl.h>
/* For glibc compatibility. An empty enum does not compile. */

View File

@ -237,6 +237,7 @@ struct br_mdb_entry {
#define MDB_PERMANENT 1
__u8 state;
#define MDB_FLAGS_OFFLOAD (1 << 0)
#define MDB_FLAGS_FAST_LEAVE (1 << 1)
__u8 flags;
__u16 vid;
struct {

View File

@ -91,6 +91,7 @@
#define ETH_P_802_EX1 0x88B5 /* 802.1 Local Experimental 1. */
#define ETH_P_PREAUTH 0x88C7 /* 802.11 Preauthentication */
#define ETH_P_TIPC 0x88CA /* TIPC */
#define ETH_P_LLDP 0x88CC /* Link Layer Discovery Protocol */
#define ETH_P_MACSEC 0x88E5 /* 802.1ae MACsec */
#define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */
#define ETH_P_MVRP 0x88F5 /* 802.1Q MVRP */

View File

@ -167,6 +167,8 @@ enum {
IFLA_NEW_IFINDEX,
IFLA_MIN_MTU,
IFLA_MAX_MTU,
IFLA_PROP_LIST,
IFLA_ALT_IFNAME, /* Alternative ifname */
__IFLA_MAX
};
@ -636,6 +638,7 @@ enum {
IFLA_BOND_AD_USER_PORT_KEY,
IFLA_BOND_AD_ACTOR_SYSTEM,
IFLA_BOND_TLB_DYNAMIC_LB,
IFLA_BOND_PEER_NOTIF_DELAY,
__IFLA_BOND_MAX,
};
@ -694,6 +697,7 @@ enum {
IFLA_VF_IB_NODE_GUID, /* VF Infiniband node GUID */
IFLA_VF_IB_PORT_GUID, /* VF Infiniband port GUID */
IFLA_VF_VLAN_LIST, /* nested list of vlans, option for QinQ */
IFLA_VF_BROADCAST, /* VF broadcast */
__IFLA_VF_MAX,
};
@ -704,6 +708,10 @@ struct ifla_vf_mac {
__u8 mac[32]; /* MAX_ADDR_LEN */
};
struct ifla_vf_broadcast {
__u8 broadcast[32];
};
struct ifla_vf_vlan {
__u32 vf;
__u32 vlan; /* 0 - 4095, 0 disables VLAN filter */

View File

@ -1,56 +1,56 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _LINUX_NEXTHOP_H
#define _LINUX_NEXTHOP_H
#ifndef _UAPI_LINUX_NEXTHOP_H
#define _UAPI_LINUX_NEXTHOP_H
#include <linux/types.h>
struct nhmsg {
unsigned char nh_family;
unsigned char nh_scope; /* return only */
unsigned char nh_protocol; /* Routing protocol that installed nh */
unsigned char resvd;
unsigned int nh_flags; /* RTNH_F flags */
unsigned char nh_family;
unsigned char nh_scope; /* return only */
unsigned char nh_protocol; /* Routing protocol that installed nh */
unsigned char resvd;
unsigned int nh_flags; /* RTNH_F flags */
};
/* entry in a nexthop group */
struct nexthop_grp {
__u32 id; /* nexthop id - must exist */
__u8 weight; /* weight of this nexthop */
__u8 resvd1;
__u16 resvd2;
__u32 id; /* nexthop id - must exist */
__u8 weight; /* weight of this nexthop */
__u8 resvd1;
__u16 resvd2;
};
enum {
NEXTHOP_GRP_TYPE_MPATH, /* default type if not specified */
__NEXTHOP_GRP_TYPE_MAX,
NEXTHOP_GRP_TYPE_MPATH, /* default type if not specified */
__NEXTHOP_GRP_TYPE_MAX,
};
#define NEXTHOP_GRP_TYPE_MAX (__NEXTHOP_GRP_TYPE_MAX - 1)
enum {
NHA_UNSPEC,
NHA_ID, /* u32; id for nexthop. id == 0 means auto-assign */
NHA_UNSPEC,
NHA_ID, /* u32; id for nexthop. id == 0 means auto-assign */
NHA_GROUP, /* array of nexthop_grp */
NHA_GROUP_TYPE, /* u16 one of NEXTHOP_GRP_TYPE */
/* if NHA_GROUP attribute is added, no other attributes can be set */
NHA_GROUP, /* array of nexthop_grp */
NHA_GROUP_TYPE, /* u16 one of NEXTHOP_GRP_TYPE */
/* if NHA_GROUP attribute is added, no other attributes can be set */
NHA_BLACKHOLE, /* flag; nexthop used to blackhole packets */
/* if NHA_BLACKHOLE is added, OIF, GATEWAY, ENCAP can not be set */
NHA_BLACKHOLE, /* flag; nexthop used to blackhole packets */
/* if NHA_BLACKHOLE is added, OIF, GATEWAY, ENCAP can not be set */
NHA_OIF, /* u32; nexthop device */
NHA_GATEWAY, /* be32 (IPv4) or in6_addr (IPv6) gw address */
NHA_ENCAP_TYPE, /* u16; lwt encap type */
NHA_ENCAP, /* lwt encap data */
NHA_OIF, /* u32; nexthop device */
NHA_GATEWAY, /* be32 (IPv4) or in6_addr (IPv6) gw address */
NHA_ENCAP_TYPE, /* u16; lwt encap type */
NHA_ENCAP, /* lwt encap data */
/* NHA_OIF can be appended to dump request to return only
* nexthops using given device
*/
NHA_GROUPS, /* flag; only return nexthop groups in dump */
NHA_MASTER, /* u32; only return nexthops with given master dev */
/* NHA_OIF can be appended to dump request to return only
* nexthops using given device
*/
NHA_GROUPS, /* flag; only return nexthop groups in dump */
NHA_MASTER, /* u32; only return nexthops with given master dev */
__NHA_MAX,
__NHA_MAX,
};
#define NHA_MAX (__NHA_MAX - 1)
#define NHA_MAX (__NHA_MAX - 1)
#endif

File diff suppressed because it is too large Load Diff

View File

@ -157,13 +157,20 @@ enum {
RTM_GETCHAIN,
#define RTM_GETCHAIN RTM_GETCHAIN
RTM_NEWNEXTHOP = 104,
RTM_NEWNEXTHOP = 104,
#define RTM_NEWNEXTHOP RTM_NEWNEXTHOP
RTM_DELNEXTHOP,
RTM_DELNEXTHOP,
#define RTM_DELNEXTHOP RTM_DELNEXTHOP
RTM_GETNEXTHOP,
RTM_GETNEXTHOP,
#define RTM_GETNEXTHOP RTM_GETNEXTHOP
RTM_NEWLINKPROP = 108,
#define RTM_NEWLINKPROP RTM_NEWLINKPROP
RTM_DELLINKPROP,
#define RTM_DELLINKPROP RTM_DELLINKPROP
RTM_GETLINKPROP,
#define RTM_GETLINKPROP RTM_GETLINKPROP
__RTM_MAX,
#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
};
@ -172,7 +179,7 @@ enum {
#define RTM_NR_FAMILIES (RTM_NR_MSGTYPES >> 2)
#define RTM_FAM(cmd) (((cmd) - RTM_BASE) >> 2)
/*
/*
Generic structure for encapsulation of optional route information.
It is reminiscent of sockaddr, but with sa_family replaced
with attribute type.
@ -212,7 +219,7 @@ struct rtmsg {
unsigned char rtm_table; /* Routing table id */
unsigned char rtm_protocol; /* Routing protocol; see below */
unsigned char rtm_scope; /* See below */
unsigned char rtm_scope; /* See below */
unsigned char rtm_type; /* See below */
unsigned rtm_flags;
@ -349,7 +356,7 @@ enum rtattr_type_t {
RTA_IP_PROTO,
RTA_SPORT,
RTA_DPORT,
RTA_NH_ID,
RTA_NH_ID,
__RTA_MAX
};
@ -523,7 +530,7 @@ struct ifinfomsg {
};
/********************************************************************
* prefix information
* prefix information
****/
struct prefixmsg {
@ -537,7 +544,7 @@ struct prefixmsg {
unsigned char prefix_pad3;
};
enum
enum
{
PREFIX_UNSPEC,
PREFIX_ADDRESS,
@ -712,7 +719,7 @@ enum rtnetlink_groups {
#define RTNLGRP_IPV4_MROUTE_R RTNLGRP_IPV4_MROUTE_R
RTNLGRP_IPV6_MROUTE_R,
#define RTNLGRP_IPV6_MROUTE_R RTNLGRP_IPV6_MROUTE_R
RTNLGRP_NEXTHOP,
RTNLGRP_NEXTHOP,
#define RTNLGRP_NEXTHOP RTNLGRP_NEXTHOP
__RTNLGRP_MAX
};

View File

@ -18,30 +18,30 @@
* one but not both of:
*
* WGDEVICE_A_IFINDEX: NLA_U32
* WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMESIZ - 1
* WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMSIZ - 1
*
* The kernel will then return several messages (NLM_F_MULTI) containing the
* following tree of nested items:
*
* WGDEVICE_A_IFINDEX: NLA_U32
* WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMESIZ - 1
* WGDEVICE_A_PRIVATE_KEY: len WG_KEY_LEN
* WGDEVICE_A_PUBLIC_KEY: len WG_KEY_LEN
* WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMSIZ - 1
* WGDEVICE_A_PRIVATE_KEY: NLA_EXACT_LEN, len WG_KEY_LEN
* WGDEVICE_A_PUBLIC_KEY: NLA_EXACT_LEN, len WG_KEY_LEN
* WGDEVICE_A_LISTEN_PORT: NLA_U16
* WGDEVICE_A_FWMARK: NLA_U32
* WGDEVICE_A_PEERS: NLA_NESTED
* 0: NLA_NESTED
* WGPEER_A_PUBLIC_KEY: len WG_KEY_LEN
* WGPEER_A_PRESHARED_KEY: len WG_KEY_LEN
* WGPEER_A_ENDPOINT: struct sockaddr_in or struct sockaddr_in6
* WGPEER_A_PUBLIC_KEY: NLA_EXACT_LEN, len WG_KEY_LEN
* WGPEER_A_PRESHARED_KEY: NLA_EXACT_LEN, len WG_KEY_LEN
* WGPEER_A_ENDPOINT: NLA_MIN_LEN(struct sockaddr), struct sockaddr_in or struct sockaddr_in6
* WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL: NLA_U16
* WGPEER_A_LAST_HANDSHAKE_TIME: struct __kernel_timespec
* WGPEER_A_LAST_HANDSHAKE_TIME: NLA_EXACT_LEN, struct __kernel_timespec
* WGPEER_A_RX_BYTES: NLA_U64
* WGPEER_A_TX_BYTES: NLA_U64
* WGPEER_A_ALLOWEDIPS: NLA_NESTED
* 0: NLA_NESTED
* WGALLOWEDIP_A_FAMILY: NLA_U16
* WGALLOWEDIP_A_IPADDR: struct in_addr or struct in6_addr
* WGALLOWEDIP_A_IPADDR: NLA_MIN_LEN(struct in_addr), struct in_addr or struct in6_addr
* WGALLOWEDIP_A_CIDR_MASK: NLA_U8
* 0: NLA_NESTED
* ...
@ -77,7 +77,7 @@
* WGDEVICE_A_IFINDEX and WGDEVICE_A_IFNAME:
*
* WGDEVICE_A_IFINDEX: NLA_U32
* WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMESIZ - 1
* WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMSIZ - 1
* WGDEVICE_A_FLAGS: NLA_U32, 0 or WGDEVICE_F_REPLACE_PEERS if all current
* peers should be removed prior to adding the list below.
* WGDEVICE_A_PRIVATE_KEY: len WG_KEY_LEN, all zeros to remove
@ -87,10 +87,12 @@
* 0: NLA_NESTED
* WGPEER_A_PUBLIC_KEY: len WG_KEY_LEN
* WGPEER_A_FLAGS: NLA_U32, 0 and/or WGPEER_F_REMOVE_ME if the
* specified peer should be removed rather than
* added/updated and/or WGPEER_F_REPLACE_ALLOWEDIPS
* if all current allowed IPs of this peer should be
* removed prior to adding the list below.
* specified peer should not exist at the end of the
* operation, rather than added/updated and/or
* WGPEER_F_REPLACE_ALLOWEDIPS if all current allowed
* IPs of this peer should be removed prior to adding
* the list below and/or WGPEER_F_UPDATE_ONLY if the
* peer should only be set if it already exists.
* WGPEER_A_PRESHARED_KEY: len WG_KEY_LEN, all zeros to remove
* WGPEER_A_ENDPOINT: struct sockaddr_in or struct sockaddr_in6
* WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL: NLA_U16, 0 to disable
@ -119,7 +121,7 @@
* filling in information not contained in the prior. Note that if
* WGDEVICE_F_REPLACE_PEERS is specified in the first message, it probably
* should not be specified in fragments that come after, so that the list
* of peers is only cleared the first time but appened after. Likewise for
* of peers is only cleared the first time but appended after. Likewise for
* peers, if WGPEER_F_REPLACE_ALLOWEDIPS is specified in the first message
* of a peer, it likely should not be specified in subsequent fragments.
*
@ -142,7 +144,8 @@ enum wg_cmd {
#define WG_CMD_MAX (__WG_CMD_MAX - 1)
enum wgdevice_flag {
WGDEVICE_F_REPLACE_PEERS = 1U << 0
WGDEVICE_F_REPLACE_PEERS = 1U << 0,
__WGDEVICE_F_ALL = WGDEVICE_F_REPLACE_PEERS
};
enum wgdevice_attribute {
WGDEVICE_A_UNSPEC,
@ -160,7 +163,10 @@ enum wgdevice_attribute {
enum wgpeer_flag {
WGPEER_F_REMOVE_ME = 1U << 0,
WGPEER_F_REPLACE_ALLOWEDIPS = 1U << 1
WGPEER_F_REPLACE_ALLOWEDIPS = 1U << 1,
WGPEER_F_UPDATE_ONLY = 1U << 2,
__WGPEER_F_ALL = WGPEER_F_REMOVE_ME | WGPEER_F_REPLACE_ALLOWEDIPS |
WGPEER_F_UPDATE_ONLY
};
enum wgpeer_attribute {
WGPEER_A_UNSPEC,

View File

@ -13,6 +13,7 @@
#include <stdlib.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <linux/if.h>
#include "alloc-util.h"
#include "errno-util.h"
@ -909,7 +910,7 @@ static const char* const ip_tos_table[] = {
DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
bool ifname_valid(const char *p) {
bool ifname_valid_full(const char *p, bool alternative) {
bool numeric = true;
/* Checks whether a network interface name is valid. This is inspired by dev_valid_name() in the kernel sources
@ -919,8 +920,13 @@ bool ifname_valid(const char *p) {
if (isempty(p))
return false;
if (strlen(p) >= IFNAMSIZ)
return false;
if (alternative) {
if (strlen(p) >= ALTIFNAMSIZ)
return false;
} else {
if (strlen(p) >= IFNAMSIZ)
return false;
}
if (dot_or_dot_dot(p))
return false;

View File

@ -130,7 +130,10 @@ int fd_inc_rcvbuf(int fd, size_t n);
int ip_tos_to_string_alloc(int i, char **s);
int ip_tos_from_string(const char *s);
bool ifname_valid(const char *p);
bool ifname_valid_full(const char *p, bool alternative);
static inline bool ifname_valid(const char *p) {
return ifname_valid_full(p, false);
}
bool address_label_valid(const char *p);
int getpeercred(int fd, struct ucred *ucred);

View File

@ -103,6 +103,18 @@ static bool net_condition_test_strv(char * const *patterns, const char *string)
return has_positive_rule ? match : true;
}
static bool net_condition_test_ifname(char * const *patterns, const char *ifname, char * const *alternative_names) {
if (net_condition_test_strv(patterns, ifname))
return true;
char * const *p;
STRV_FOREACH(p, alternative_names)
if (net_condition_test_strv(patterns, *p))
return true;
return false;
}
static int net_condition_test_property(char * const *match_property, sd_device *device) {
char * const *p;
@ -166,6 +178,7 @@ bool net_match_config(Set *match_mac,
sd_device *device,
const struct ether_addr *dev_mac,
const char *dev_name,
char * const *alternative_names,
enum nl80211_iftype wifi_iftype,
const char *ssid,
const struct ether_addr *bssid) {
@ -196,7 +209,7 @@ bool net_match_config(Set *match_mac,
if (!net_condition_test_strv(match_types, dev_type))
return false;
if (!net_condition_test_strv(match_names, dev_name))
if (!net_condition_test_ifname(match_names, dev_name, alternative_names))
return false;
if (!net_condition_test_property(match_property, device))
@ -349,7 +362,7 @@ int config_parse_match_ifnames(
return 0;
}
if (!ifname_valid(word)) {
if (!ifname_valid_full(word, ltype)) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"Interface name is not valid or too long, ignoring assignment: %s", word);
continue;

View File

@ -27,6 +27,7 @@ bool net_match_config(Set *match_mac,
sd_device *device,
const struct ether_addr *dev_mac,
const char *dev_name,
char * const *alternative_names,
enum nl80211_iftype wifi_iftype,
const char *ssid,
const struct ether_addr *bssid);

View File

@ -8,11 +8,12 @@
#include "alloc-util.h"
#include "format-util.h"
#include "memory-util.h"
#include "netlink-internal.h"
#include "netlink-types.h"
#include "netlink-util.h"
#include "socket-util.h"
#include "memory-util.h"
#include "strv.h"
#define GET_CONTAINER(m, i) ((i) < (m)->n_containers ? (struct rtattr*)((uint8_t*)(m)->hdr + (m)->containers[i].offset) : NULL)
#define PUSH_CONTAINER(m, new) (m)->container_offsets[(m)->n_containers++] = (uint8_t*)(new) - (uint8_t*)(m)->hdr;
@ -86,7 +87,8 @@ int sd_netlink_message_request_dump(sd_netlink_message *m, int dump) {
assert_return(m, -EINVAL);
assert_return(m->hdr, -EINVAL);
assert_return(IN_SET(m->hdr->nlmsg_type, RTM_GETLINK, RTM_GETADDR, RTM_GETROUTE, RTM_GETNEIGH,
assert_return(IN_SET(m->hdr->nlmsg_type,
RTM_GETLINK, RTM_GETLINKPROP, RTM_GETADDR, RTM_GETROUTE, RTM_GETNEIGH,
RTM_GETRULE, RTM_GETADDRLABEL, RTM_GETNEXTHOP), -EINVAL);
SET_FLAG(m->hdr->nlmsg_flags, NLM_F_DUMP, dump);
@ -248,6 +250,35 @@ int sd_netlink_message_append_string(sd_netlink_message *m, unsigned short type,
return 0;
}
int sd_netlink_message_append_strv(sd_netlink_message *m, unsigned short type, char * const *data) {
size_t length, size;
char * const *p;
int r;
assert_return(m, -EINVAL);
assert_return(!m->sealed, -EPERM);
assert_return(data, -EINVAL);
r = message_attribute_has_type(m, &size, type, NETLINK_TYPE_STRING);
if (r < 0)
return r;
STRV_FOREACH(p, data) {
if (size) {
length = strnlen(*p, size+1);
if (length > size)
return -EINVAL;
} else
length = strlen(*p);
r = add_rtattr(m, type, *p, length + 1);
if (r < 0)
return r;
}
return 0;
}
int sd_netlink_message_append_flag(sd_netlink_message *m, unsigned short type) {
size_t size;
int r;
@ -827,6 +858,63 @@ int sd_netlink_message_read_in6_addr(sd_netlink_message *m, unsigned short type,
return 0;
}
int sd_netlink_message_read_strv(sd_netlink_message *m, unsigned short container_type, unsigned short type_id, char ***ret) {
_cleanup_strv_free_ char **s = NULL;
const NLTypeSystem *type_system;
const NLType *nl_type;
struct rtattr *rta;
void *container;
unsigned short rt_len;
int r;
assert_return(m, -EINVAL);
assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -EINVAL);
r = type_system_get_type(m->containers[m->n_containers].type_system,
&nl_type,
container_type);
if (r < 0)
return r;
if (type_get_type(nl_type) != NETLINK_TYPE_NESTED)
return -EINVAL;
r = type_system_get_type_system(m->containers[m->n_containers].type_system,
&type_system,
container_type);
if (r < 0)
return r;
r = type_system_get_type(type_system, &nl_type, type_id);
if (r < 0)
return r;
if (type_get_type(nl_type) != NETLINK_TYPE_STRING)
return -EINVAL;
r = netlink_message_read_internal(m, container_type, &container, NULL);
if (r < 0)
return r;
rt_len = (unsigned short) r;
rta = container;
for (; RTA_OK(rta, rt_len); rta = RTA_NEXT(rta, rt_len)) {
unsigned short type;
type = RTA_TYPE(rta);
if (type != type_id)
continue;
r = strv_extend(&s, RTA_DATA(rta));
if (r < 0)
return r;
}
*ret = TAKE_PTR(s);
return 0;
}
static int netlink_container_parse(sd_netlink_message *m,
struct netlink_container *container,
struct rtattr *rta,

View File

@ -527,6 +527,15 @@ static const NLTypeSystem rtnl_af_spec_type_system = {
.types = rtnl_af_spec_types,
};
static const NLType rtnl_prop_list_types[] = {
[IFLA_ALT_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = ALTIFNAMSIZ - 1 },
};
static const NLTypeSystem rtnl_prop_list_type_system = {
.count = ELEMENTSOF(rtnl_prop_list_types),
.types = rtnl_prop_list_types,
};
static const NLType rtnl_link_types[] = {
[IFLA_ADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR },
[IFLA_BROADCAST] = { .type = NETLINK_TYPE_ETHER_ADDR },
@ -581,8 +590,9 @@ static const NLType rtnl_link_types[] = {
/*
[IFLA_PHYS_PORT_ID] = { .type = NETLINK_TYPE_BINARY, .len = MAX_PHYS_PORT_ID_LEN },
*/
[IFLA_MIN_MTU] = { .type = NETLINK_TYPE_U32 },
[IFLA_MAX_MTU] = { .type = NETLINK_TYPE_U32 },
[IFLA_MIN_MTU] = { .type = NETLINK_TYPE_U32 },
[IFLA_MAX_MTU] = { .type = NETLINK_TYPE_U32 },
[IFLA_PROP_LIST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_prop_list_type_system },
};
static const NLTypeSystem rtnl_link_type_system = {
@ -824,6 +834,9 @@ static const NLType rtnl_types[] = {
[RTM_DELLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
[RTM_GETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
[RTM_SETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
[RTM_NEWLINKPROP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
[RTM_DELLINKPROP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
[RTM_GETLINKPROP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
[RTM_NEWADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
[RTM_DELADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
[RTM_GETADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },

View File

@ -4,6 +4,7 @@
#include "netlink-internal.h"
#include "netlink-util.h"
#include "strv.h"
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
@ -83,6 +84,45 @@ int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias,
return 0;
}
int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
int r;
assert(rtnl);
assert(ifindex > 0);
if (strv_isempty(alternative_names))
return 0;
if (!*rtnl) {
r = sd_netlink_open(rtnl);
if (r < 0)
return r;
}
r = sd_rtnl_message_new_link(*rtnl, &message, RTM_NEWLINKPROP, ifindex);
if (r < 0)
return r;
r = sd_netlink_message_open_container(message, IFLA_PROP_LIST);
if (r < 0)
return r;
r = sd_netlink_message_append_strv(message, IFLA_ALT_IFNAME, alternative_names);
if (r < 0)
return r;
r = sd_netlink_message_close_container(message);
if (r < 0)
return r;
r = sd_netlink_call(*rtnl, message, 0, NULL);
if (r < 0)
return r;
return 0;
}
int rtnl_message_new_synthetic_error(sd_netlink *rtnl, int error, uint32_t serial, sd_netlink_message **ret) {
struct nlmsgerr *err;
int r;

View File

@ -26,7 +26,9 @@ static inline bool rtnl_message_type_is_nexthop(uint16_t type) {
}
static inline bool rtnl_message_type_is_link(uint16_t type) {
return IN_SET(type, RTM_NEWLINK, RTM_SETLINK, RTM_GETLINK, RTM_DELLINK);
return IN_SET(type,
RTM_NEWLINK, RTM_SETLINK, RTM_GETLINK, RTM_DELLINK,
RTM_NEWLINKPROP, RTM_DELLINKPROP, RTM_GETLINKPROP);
}
static inline bool rtnl_message_type_is_addr(uint16_t type) {
@ -47,6 +49,7 @@ static inline bool rtnl_message_type_is_qdisc(uint16_t type) {
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name);
int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, const struct ether_addr *mac, uint32_t mtu);
int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names);
int rtnl_log_parse_error(int r);
int rtnl_log_create_error(int r);

View File

@ -512,6 +512,8 @@ int sd_rtnl_message_new_link(sd_netlink *rtnl, sd_netlink_message **ret,
if (nlmsg_type == RTM_NEWLINK)
(*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
else if (nlmsg_type == RTM_NEWLINK)
(*ret)->hdr->nlmsg_flags |= NLM_F_EXCL | NLM_F_CREATE | NLM_F_APPEND;
ifi = NLMSG_DATA((*ret)->hdr);

View File

@ -13,6 +13,7 @@
#include "socket-util.h"
#include "stdio-util.h"
#include "string-util.h"
#include "strv.h"
#include "util.h"
static void test_message_link_bridge(sd_netlink *rtnl) {
@ -547,7 +548,36 @@ static void test_array(void) {
assert_se(streq(name, expected));
}
assert_se(sd_netlink_message_exit_container(m) >= 0);
}
static void test_strv(sd_netlink *rtnl) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
_cleanup_strv_free_ char **names_in = NULL, **names_out;
const char *p;
assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINKPROP, 1) >= 0);
for (unsigned i = 0; i < 10; i++) {
char name[STRLEN("hoge") + DECIMAL_STR_MAX(uint32_t)];
xsprintf(name, "hoge%" PRIu32, i + 1000);
assert_se(strv_extend(&names_in, name) >= 0);
}
assert_se(sd_netlink_message_open_container(m, IFLA_PROP_LIST) >= 0);
assert_se(sd_netlink_message_append_strv(m, IFLA_ALT_IFNAME, names_in) >= 0);
assert_se(sd_netlink_message_close_container(m) >= 0);
rtnl_message_seal(m);
assert_se(sd_netlink_message_rewind(m, NULL) >= 0);
assert_se(sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &names_out) >= 0);
assert_se(strv_equal(names_in, names_out));
assert_se(sd_netlink_message_enter_container(m, IFLA_PROP_LIST) >= 0);
assert_se(sd_netlink_message_read_string(m, IFLA_ALT_IFNAME, &p) >= 0);
assert_se(streq(p, "hoge1009"));
assert_se(sd_netlink_message_exit_container(m) >= 0);
}
int main(void) {
@ -568,6 +598,7 @@ int main(void) {
test_message(rtnl);
test_container(rtnl);
test_array();
test_strv(rtnl);
if_loopback = (int) if_nametoindex("lo");
assert_se(if_loopback > 0);

View File

@ -139,6 +139,7 @@ typedef struct LinkInfo {
uint32_t max_mtu;
uint32_t tx_queues;
uint32_t rx_queues;
char **alternative_names;
union {
struct rtnl_link_stats64 stats64;
@ -191,6 +192,7 @@ static const LinkInfo* link_info_array_free(LinkInfo *array) {
for (unsigned i = 0; array && array[i].needs_freeing; i++) {
sd_device_unref(array[i].sd_device);
free(array[i].ssid);
strv_free(array[i].alternative_names);
}
return mfree(array);
@ -304,6 +306,7 @@ static int decode_link(sd_netlink_message *m, LinkInfo *info, char **patterns) {
(void) sd_netlink_message_read_u32(m, IFLA_MTU, &info->mtu);
(void) sd_netlink_message_read_u32(m, IFLA_MIN_MTU, &info->min_mtu);
(void) sd_netlink_message_read_u32(m, IFLA_MAX_MTU, &info->max_mtu);
(void) sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &info->alternative_names);
info->has_rx_queues =
sd_netlink_message_read_u32(m, IFLA_NUM_RX_QUEUES, &info->rx_queues) >= 0 &&
@ -1063,6 +1066,7 @@ static int link_status_one(
_cleanup_free_ int *carrier_bound_to = NULL, *carrier_bound_by = NULL;
_cleanup_(table_unrefp) Table *table = NULL;
TableCell *cell;
char **p;
int r;
assert(rtnl);
@ -1144,6 +1148,18 @@ static int link_status_one(
if (r < 0)
return r;
STRV_FOREACH(p, info->alternative_names)
if (p == info->alternative_names)
r = table_add_many(table,
TABLE_EMPTY,
TABLE_STRING, "Alternative Names:",
TABLE_STRING, *p);
else
r = table_add_many(table,
TABLE_EMPTY,
TABLE_EMPTY,
TABLE_STRING, *p);
if (path) {
r = table_add_many(table,
TABLE_EMPTY,

View File

@ -542,10 +542,10 @@ static int link_update_flags(Link *link, sd_netlink_message *m, bool force_updat
static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
_cleanup_(link_unrefp) Link *link = NULL;
uint16_t type;
const char *ifname, *kind = NULL;
int r, ifindex;
unsigned short iftype;
int r, ifindex;
uint16_t type;
assert(manager);
assert(message);
@ -617,6 +617,10 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
if (r < 0)
log_link_debug_errno(link, r, "MAC address not found for new device, continuing without");
r = sd_netlink_message_read_strv(message, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &link->alternative_names);
if (r < 0 && r != -ENODATA)
return r;
if (asprintf(&link->state_file, "/run/systemd/netif/links/%d", link->ifindex) < 0)
return -ENOMEM;
@ -713,6 +717,7 @@ static Link *link_free(Link *link) {
free(link->lldp_file);
free(link->ifname);
strv_free(link->alternative_names);
free(link->kind);
free(link->ssid);
@ -2934,14 +2939,28 @@ static int link_configure_duid(Link *link) {
return 0;
}
int link_reconfigure(Link *link, bool force) {
static int link_reconfigure_internal(Link *link, sd_netlink_message *m, bool force) {
Network *network;
int r;
if (IN_SET(link->state, LINK_STATE_PENDING, LINK_STATE_LINGER))
return 0;
r = network_get(link->manager, link->sd_device, link->ifname,
if (m) {
_cleanup_strv_free_ char **s = NULL;
r = sd_netlink_message_get_errno(m);
if (r < 0)
return r;
r = sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &s);
if (r < 0 && r != -ENODATA)
return r;
strv_free_and_replace(link->alternative_names, s);
}
r = network_get(link->manager, link->sd_device, link->ifname, link->alternative_names,
&link->mac, link->wlan_iftype, link->ssid, &link->bssid, &network);
if (r == -ENOENT) {
link_enter_unmanaged(link);
@ -2959,10 +2978,8 @@ int link_reconfigure(Link *link, bool force) {
/* Dropping old .network file */
r = link_stop_clients(link, false);
if (r < 0) {
link_enter_failed(link);
if (r < 0)
return r;
}
if (link_dhcp4_server_enabled(link))
(void) sd_dhcp_server_stop(link->dhcp_server);
@ -3006,6 +3023,46 @@ int link_reconfigure(Link *link, bool force) {
return 0;
}
static int link_reconfigure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
r = link_reconfigure_internal(link, m, false);
if (r < 0)
link_enter_failed(link);
return 1;
}
static int link_force_reconfigure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
r = link_reconfigure_internal(link, m, true);
if (r < 0)
link_enter_failed(link);
return 1;
}
int link_reconfigure(Link *link, bool force) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
int r;
r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK,
link->ifindex);
if (r < 0)
return r;
r = netlink_call_async(link->manager->rtnl, NULL, req,
force ? link_force_reconfigure_handler : link_reconfigure_handler,
link_netlink_destroy_callback, link);
if (r < 0)
return r;
link_ref(link);
return 0;
}
static int link_initialized_and_synced(Link *link) {
Network *network;
int r;
@ -3035,7 +3092,7 @@ static int link_initialized_and_synced(Link *link) {
if (r < 0)
return r;
r = network_get(link->manager, link->sd_device, link->ifname,
r = network_get(link->manager, link->sd_device, link->ifname, link->alternative_names,
&link->mac, link->wlan_iftype, link->ssid, &link->bssid, &network);
if (r == -ENOENT) {
link_enter_unmanaged(link);
@ -3080,8 +3137,23 @@ static int link_initialized_and_synced(Link *link) {
}
static int link_initialized_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
_cleanup_strv_free_ char **s = NULL;
int r;
r = sd_netlink_message_get_errno(m);
if (r < 0) {
link_enter_failed(link);
return 0;
}
r = sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &s);
if (r < 0 && r != -ENODATA) {
link_enter_failed(link);
return 0;
}
strv_free_and_replace(link->alternative_names, s);
r = link_initialized_and_synced(link);
if (r < 0)
link_enter_failed(link);
@ -3414,9 +3486,11 @@ static int link_carrier_gained(Link *link) {
if (r < 0)
return r;
if (r > 0) {
r = link_reconfigure(link, false);
if (r < 0)
r = link_reconfigure_internal(link, NULL, false);
if (r < 0) {
link_enter_failed(link);
return r;
}
}
if (IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED)) {
@ -3520,6 +3594,7 @@ static int link_admin_state_up(Link *link) {
}
int link_update(Link *link, sd_netlink_message *m) {
_cleanup_strv_free_ char **s = NULL;
struct ether_addr mac;
const char *ifname;
uint32_t mtu;
@ -3551,6 +3626,10 @@ int link_update(Link *link, sd_netlink_message *m) {
return r;
}
r = sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &s);
if (r >= 0)
strv_free_and_replace(link->alternative_names, s);
r = sd_netlink_message_read_u32(m, IFLA_MTU, &mtu);
if (r >= 0 && mtu > 0) {
link->mtu = mtu;

View File

@ -48,6 +48,7 @@ typedef struct Link {
int ifindex;
int master_ifindex;
char *ifname;
char **alternative_names;
char *kind;
unsigned short iftype;
char *state_file;

View File

@ -34,7 +34,7 @@ Match.Type, config_parse_match_strv,
Match.WLANInterfaceType, config_parse_match_strv, 0, offsetof(Network, match_wlan_iftype)
Match.SSID, config_parse_match_strv, 0, offsetof(Network, match_ssid)
Match.BSSID, config_parse_hwaddrs, 0, offsetof(Network, match_bssid)
Match.Name, config_parse_match_ifnames, 0, offsetof(Network, match_name)
Match.Name, config_parse_match_ifnames, 1, offsetof(Network, match_name)
Match.Property, config_parse_match_property, 0, offsetof(Network, match_property)
Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(Network, conditions)
Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(Network, conditions)

View File

@ -718,7 +718,7 @@ int network_get_by_name(Manager *manager, const char *name, Network **ret) {
}
int network_get(Manager *manager, sd_device *device,
const char *ifname, const struct ether_addr *address,
const char *ifname, char * const *alternative_names, const struct ether_addr *address,
enum nl80211_iftype wlan_iftype, const char *ssid, const struct ether_addr *bssid,
Network **ret) {
Network *network;
@ -731,7 +731,7 @@ int network_get(Manager *manager, sd_device *device,
if (net_match_config(network->match_mac, network->match_path, network->match_driver,
network->match_type, network->match_name, network->match_property,
network->match_wlan_iftype, network->match_ssid, network->match_bssid,
device, address, ifname, wlan_iftype, ssid, bssid)) {
device, address, ifname, alternative_names, wlan_iftype, ssid, bssid)) {
if (network->match_name && device) {
const char *attr;
uint8_t name_assign_type = NET_NAME_UNKNOWN;

View File

@ -297,8 +297,9 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
int network_verify(Network *network);
int network_get_by_name(Manager *manager, const char *name, Network **ret);
int network_get(Manager *manager, sd_device *device, const char *ifname, const struct ether_addr *mac,
enum nl80211_iftype wlan_iftype, const char *ssid, const struct ether_addr *bssid, Network **ret);
int network_get(Manager *manager, sd_device *device, const char *ifname, char * const *alternative_names,
const struct ether_addr *mac, enum nl80211_iftype wlan_iftype, const char *ssid,
const struct ether_addr *bssid, Network **ret);
int network_apply(Network *network, Link *link);
void network_apply_anonymize_if_set(Network *network);

View File

@ -125,7 +125,7 @@ static void test_network_get(Manager *manager, sd_device *loopback) {
/* let's assume that the test machine does not have a .network file
that applies to the loopback device... */
assert_se(network_get(manager, loopback, "lo", &mac, 0, NULL, NULL, &network) == -ENOENT);
assert_se(network_get(manager, loopback, "lo", NULL, &mac, 0, NULL, NULL, &network) == -ENOENT);
assert_se(!network);
}

View File

@ -985,6 +985,66 @@ int config_parse_ifname(
return 0;
}
int config_parse_ifnames(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
_cleanup_strv_free_ char **names = NULL;
char ***s = data;
const char *p;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
if (isempty(rvalue)) {
*s = strv_free(*s);
return 0;
}
p = rvalue;
for (;;) {
_cleanup_free_ char *word = NULL;
r = extract_first_word(&p, &word, NULL, 0);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to extract interface name, ignoring assignment: %s",
rvalue);
return 0;
}
if (r == 0)
break;
if (!ifname_valid_full(word, ltype)) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"Interface name is not valid or too long, ignoring assignment: %s",
word);
continue;
}
r = strv_consume(&names, TAKE_PTR(word));
if (r < 0)
return log_oom();
}
r = strv_extend_strv(s, names, true);
if (r < 0)
return log_oom();
return 0;
}
int config_parse_ip_port(
const char *unit,
const char *filename,

View File

@ -137,6 +137,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_signal);
CONFIG_PARSER_PROTOTYPE(config_parse_personality);
CONFIG_PARSER_PROTOTYPE(config_parse_permille);
CONFIG_PARSER_PROTOTYPE(config_parse_ifname);
CONFIG_PARSER_PROTOTYPE(config_parse_ifnames);
CONFIG_PARSER_PROTOTYPE(config_parse_ip_port);
CONFIG_PARSER_PROTOTYPE(config_parse_mtu);
CONFIG_PARSER_PROTOTYPE(config_parse_rlimit);

View File

@ -80,6 +80,7 @@ int sd_netlink_attach_event(sd_netlink *nl, sd_event *e, int64_t priority);
int sd_netlink_detach_event(sd_netlink *nl);
int sd_netlink_message_append_string(sd_netlink_message *m, unsigned short type, const char *data);
int sd_netlink_message_append_strv(sd_netlink_message *m, unsigned short type, char * const *data);
int sd_netlink_message_append_flag(sd_netlink_message *m, unsigned short type);
int sd_netlink_message_append_u8(sd_netlink_message *m, unsigned short type, uint8_t data);
int sd_netlink_message_append_u16(sd_netlink_message *m, unsigned short type, uint16_t data);
@ -100,6 +101,7 @@ int sd_netlink_message_close_container(sd_netlink_message *m);
int sd_netlink_message_read(sd_netlink_message *m, unsigned short type, size_t size, void *data);
int sd_netlink_message_read_string_strdup(sd_netlink_message *m, unsigned short type, char **data);
int sd_netlink_message_read_string(sd_netlink_message *m, unsigned short type, const char **data);
int sd_netlink_message_read_strv(sd_netlink_message *m, unsigned short container_type, unsigned short type_id, char ***ret);
int sd_netlink_message_read_u8(sd_netlink_message *m, unsigned short type, uint8_t *data);
int sd_netlink_message_read_u16(sd_netlink_message *m, unsigned short type, uint16_t *data);
int sd_netlink_message_read_u32(sd_netlink_message *m, unsigned short type, uint32_t *data);

View File

@ -45,6 +45,7 @@ static void test_ifname_valid(void) {
assert(ifname_valid("xxxxxxxxxxxxxxx"));
assert(!ifname_valid("xxxxxxxxxxxxxxxx"));
assert(ifname_valid_full("xxxxxxxxxxxxxxxx", true));
}
static void test_socket_address_parse_one(const char *in, int ret, int family, const char *expected) {

View File

@ -35,6 +35,7 @@ Link.MACAddressPolicy, config_parse_mac_address_policy, 0,
Link.MACAddress, config_parse_hwaddr, 0, offsetof(link_config, mac)
Link.NamePolicy, config_parse_name_policy, 0, offsetof(link_config, name_policy)
Link.Name, config_parse_ifname, 0, offsetof(link_config, name)
Link.AlternativeName, config_parse_ifnames, 1, offsetof(link_config, alternative_names)
Link.Alias, config_parse_ifalias, 0, offsetof(link_config, alias)
Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(link_config, mtu)
Link.BitsPerSecond, config_parse_si_size, 0, offsetof(link_config, speed)

View File

@ -58,6 +58,7 @@ static void link_config_free(link_config *link) {
free(link->mac);
free(link->name_policy);
free(link->name);
strv_free(link->alternative_names);
free(link->alias);
free(link);
@ -243,7 +244,7 @@ int link_config_get(link_config_ctx *ctx, sd_device *device, link_config **ret)
LIST_FOREACH(links, link, ctx->links) {
if (net_match_config(link->match_mac, link->match_path, link->match_driver,
link->match_type, link->match_name, link->match_property, NULL, NULL, NULL,
device, NULL, NULL, 0, NULL, NULL)) {
device, NULL, NULL, NULL, 0, NULL, NULL)) {
if (link->match_name && !strv_contains(link->match_name, "*")) {
unsigned name_assign_type = NET_NAME_UNKNOWN;
@ -458,6 +459,10 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
if (r < 0)
return log_warning_errno(r, "Could not set Alias=, MACAddress= or MTU= on %s: %m", old_name);
r = rtnl_set_link_alternative_names(&ctx->rtnl, ifindex, config->alternative_names);
if (r < 0)
return log_warning_errno(r, "Could not set AlternativeName= on %s: %m", old_name);
*name = new_name;
return 0;

View File

@ -48,6 +48,7 @@ struct link_config {
MACAddressPolicy mac_address_policy;
NamePolicy *name_policy;
char *name;
char **alternative_names;
char *alias;
uint32_t mtu;
size_t speed;

View File

@ -16,6 +16,7 @@ MACAddressPolicy=
MACAddress=
NamePolicy=
Name=
AlternativeName=
Alias=
MTUBytes=
BitsPerSecond=

View File

@ -0,0 +1,5 @@
[Match]
OriginalName=dummy98
[Link]
AlternativeName=hogehogehogehogehogehoge

View File

@ -14,6 +14,7 @@ Name=ifb99
Name=ipiptun99
Name=nlmon99
Name=xfrm99
Name=hogehogehogehogehogehoge
[Network]
LinkLocalAddressing=yes

View File

@ -127,6 +127,17 @@ def expectedFailureIfNexthopIsNotAvailable():
return f
def expectedFailureIfAlternativeNameIsNotAvailable():
def f(func):
call('ip link add dummy98 type dummy', stderr=subprocess.DEVNULL)
rc = call('ip link prop add dev dummy98 altname hogehogehogehogehoge', stderr=subprocess.DEVNULL)
if rc == 0:
return func
else:
return unittest.expectedFailure(func)
return f
def setUpModule():
global running_units
@ -425,6 +436,7 @@ class NetworkctlTests(unittest.TestCase, Utilities):
'11-dummy-mtu.netdev',
'11-dummy.network',
'12-dummy.netdev',
'12-dummy.link',
'25-address-static.network',
'25-veth.netdev',
'netdev-link-local-addressing-yes.network',
@ -439,6 +451,16 @@ class NetworkctlTests(unittest.TestCase, Utilities):
remove_unit_from_networkd_path(self.units)
stop_networkd(show_logs=True)
@expectedFailureIfAlternativeNameIsNotAvailable()
def test_altname(self):
copy_unit_to_networkd_unit_path('netdev-link-local-addressing-yes.network', '12-dummy.netdev', '12-dummy.link')
check_output('udevadm control --reload')
start_networkd()
self.wait_online(['dummy98:degraded'])
output = check_output(*networkctl_cmd, 'status', 'dummy98', env=env)
self.assertRegex(output, 'hogehogehogehogehogehoge')
def test_reconfigure(self):
copy_unit_to_networkd_unit_path('25-address-static.network', '12-dummy.netdev')
start_networkd()
@ -529,11 +551,11 @@ class NetworkctlTests(unittest.TestCase, Utilities):
start_networkd()
self.wait_online(['test1:degraded'])
output = check_output(*networkctl_cmd, 'status', 'test1')
output = check_output(*networkctl_cmd, 'status', 'test1', env=env)
print(output)
self.assertRegex(output, 'Type: ether')
output = check_output(*networkctl_cmd, 'status', 'lo')
output = check_output(*networkctl_cmd, 'status', 'lo', env=env)
print(output)
self.assertRegex(output, 'Type: loopback')
@ -543,12 +565,12 @@ class NetworkctlTests(unittest.TestCase, Utilities):
start_networkd()
self.wait_online(['test1:degraded'])
output = check_output(*networkctl_cmd, 'status', 'test1')
output = check_output(*networkctl_cmd, 'status', 'test1', env=env)
print(output)
self.assertRegex(output, r'Link File: (/usr)?/lib/systemd/network/99-default.link')
self.assertRegex(output, r'Network File: /run/systemd/network/11-dummy.network')
output = check_output(*networkctl_cmd, 'status', 'lo')
output = check_output(*networkctl_cmd, 'status', 'lo', env=env)
print(output)
self.assertRegex(output, r'Link File: (/usr)?/lib/systemd/network/99-default.link')
self.assertRegex(output, r'Network File: n/a')
@ -560,7 +582,7 @@ class NetworkctlTests(unittest.TestCase, Utilities):
self.wait_online(['test1:degraded', 'veth99:degraded', 'veth-peer:degraded'])
check_output(*networkctl_cmd, 'delete', 'test1', 'veth99')
check_output(*networkctl_cmd, 'delete', 'test1', 'veth99', env=env)
self.assertFalse(link_exists('test1'))
self.assertFalse(link_exists('veth99'))
self.assertFalse(link_exists('veth-peer'))
@ -805,7 +827,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
self.assertEqual(1, int(read_link_attr('bridge99', 'bridge', 'stp_state')))
self.assertEqual(3, int(read_link_attr('bridge99', 'bridge', 'multicast_igmp_version')))
output = check_output(*networkctl_cmd, 'status', 'bridge99')
output = check_output(*networkctl_cmd, 'status', 'bridge99', env=env)
print(output)
self.assertRegex(output, 'Priority: 9')
self.assertRegex(output, 'STP: yes')
@ -1372,7 +1394,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
self.assertRegex(output, '00:11:22:33:44:66 dst 10.0.0.6 self permanent')
self.assertRegex(output, '00:11:22:33:44:77 dst 10.0.0.7 self permanent')
output = check_output(*networkctl_cmd, 'status', 'vxlan99')
output = check_output(*networkctl_cmd, 'status', 'vxlan99', env=env)
print(output)
self.assertRegex(output, 'VNI: 999')
self.assertRegex(output, 'Destination Port: 5555')
@ -1643,7 +1665,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
start_networkd()
self.wait_online(['test1:routable'])
output = check_output(*networkctl_cmd, 'status', 'test1')
output = check_output(*networkctl_cmd, 'status', 'test1', env=env)
print(output)
self.assertRegex(output, '192.168.0.15')
self.assertRegex(output, '192.168.0.1')