mirror of
https://github.com/systemd/systemd.git
synced 2024-12-23 21:35:11 +03:00
Merge pull request #20537 from yuwata/sd-netlink-more-attributes
udev: use link info obtained through netlink
This commit is contained in:
commit
42ffc40ce3
64
src/basic/linux/cfm_bridge.h
Normal file
64
src/basic/linux/cfm_bridge.h
Normal file
@ -0,0 +1,64 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
|
||||
|
||||
#ifndef _UAPI_LINUX_CFM_BRIDGE_H_
|
||||
#define _UAPI_LINUX_CFM_BRIDGE_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/if_ether.h>
|
||||
|
||||
#define ETHER_HEADER_LENGTH (6+6+4+2)
|
||||
#define CFM_MAID_LENGTH 48
|
||||
#define CFM_CCM_PDU_LENGTH 75
|
||||
#define CFM_PORT_STATUS_TLV_LENGTH 4
|
||||
#define CFM_IF_STATUS_TLV_LENGTH 4
|
||||
#define CFM_IF_STATUS_TLV_TYPE 4
|
||||
#define CFM_PORT_STATUS_TLV_TYPE 2
|
||||
#define CFM_ENDE_TLV_TYPE 0
|
||||
#define CFM_CCM_MAX_FRAME_LENGTH (ETHER_HEADER_LENGTH+\
|
||||
CFM_CCM_PDU_LENGTH+\
|
||||
CFM_PORT_STATUS_TLV_LENGTH+\
|
||||
CFM_IF_STATUS_TLV_LENGTH)
|
||||
#define CFM_FRAME_PRIO 7
|
||||
#define CFM_CCM_TLV_OFFSET 70
|
||||
#define CFM_CCM_PDU_MAID_OFFSET 10
|
||||
#define CFM_CCM_PDU_MEPID_OFFSET 8
|
||||
#define CFM_CCM_PDU_SEQNR_OFFSET 4
|
||||
#define CFM_CCM_PDU_TLV_OFFSET 74
|
||||
#define CFM_CCM_ITU_RESERVED_SIZE 16
|
||||
|
||||
struct br_cfm_common_hdr {
|
||||
__u8 mdlevel_version;
|
||||
__u8 opcode;
|
||||
__u8 flags;
|
||||
__u8 tlv_offset;
|
||||
};
|
||||
|
||||
enum br_cfm_opcodes {
|
||||
BR_CFM_OPCODE_CCM = 0x1,
|
||||
};
|
||||
|
||||
/* MEP domain */
|
||||
enum br_cfm_domain {
|
||||
BR_CFM_PORT,
|
||||
BR_CFM_VLAN,
|
||||
};
|
||||
|
||||
/* MEP direction */
|
||||
enum br_cfm_mep_direction {
|
||||
BR_CFM_MEP_DIRECTION_DOWN,
|
||||
BR_CFM_MEP_DIRECTION_UP,
|
||||
};
|
||||
|
||||
/* CCM interval supported. */
|
||||
enum br_cfm_ccm_interval {
|
||||
BR_CFM_CCM_INTERVAL_NONE,
|
||||
BR_CFM_CCM_INTERVAL_3_3_MS,
|
||||
BR_CFM_CCM_INTERVAL_10_MS,
|
||||
BR_CFM_CCM_INTERVAL_100_MS,
|
||||
BR_CFM_CCM_INTERVAL_1_SEC,
|
||||
BR_CFM_CCM_INTERVAL_10_SEC,
|
||||
BR_CFM_CCM_INTERVAL_1_MIN,
|
||||
BR_CFM_CCM_INTERVAL_10_MIN,
|
||||
};
|
||||
|
||||
#endif
|
74
src/basic/linux/mrp_bridge.h
Normal file
74
src/basic/linux/mrp_bridge.h
Normal file
@ -0,0 +1,74 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
|
||||
|
||||
#ifndef _UAPI_LINUX_MRP_BRIDGE_H_
|
||||
#define _UAPI_LINUX_MRP_BRIDGE_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/if_ether.h>
|
||||
|
||||
#define MRP_MAX_FRAME_LENGTH 200
|
||||
#define MRP_DEFAULT_PRIO 0x8000
|
||||
#define MRP_DOMAIN_UUID_LENGTH 16
|
||||
#define MRP_VERSION 1
|
||||
#define MRP_FRAME_PRIO 7
|
||||
#define MRP_OUI_LENGTH 3
|
||||
#define MRP_MANUFACTURE_DATA_LENGTH 2
|
||||
|
||||
enum br_mrp_ring_role_type {
|
||||
BR_MRP_RING_ROLE_DISABLED,
|
||||
BR_MRP_RING_ROLE_MRC,
|
||||
BR_MRP_RING_ROLE_MRM,
|
||||
BR_MRP_RING_ROLE_MRA,
|
||||
};
|
||||
|
||||
enum br_mrp_in_role_type {
|
||||
BR_MRP_IN_ROLE_DISABLED,
|
||||
BR_MRP_IN_ROLE_MIC,
|
||||
BR_MRP_IN_ROLE_MIM,
|
||||
};
|
||||
|
||||
enum br_mrp_ring_state_type {
|
||||
BR_MRP_RING_STATE_OPEN,
|
||||
BR_MRP_RING_STATE_CLOSED,
|
||||
};
|
||||
|
||||
enum br_mrp_in_state_type {
|
||||
BR_MRP_IN_STATE_OPEN,
|
||||
BR_MRP_IN_STATE_CLOSED,
|
||||
};
|
||||
|
||||
enum br_mrp_port_state_type {
|
||||
BR_MRP_PORT_STATE_DISABLED,
|
||||
BR_MRP_PORT_STATE_BLOCKED,
|
||||
BR_MRP_PORT_STATE_FORWARDING,
|
||||
BR_MRP_PORT_STATE_NOT_CONNECTED,
|
||||
};
|
||||
|
||||
enum br_mrp_port_role_type {
|
||||
BR_MRP_PORT_ROLE_PRIMARY,
|
||||
BR_MRP_PORT_ROLE_SECONDARY,
|
||||
BR_MRP_PORT_ROLE_INTER,
|
||||
};
|
||||
|
||||
enum br_mrp_tlv_header_type {
|
||||
BR_MRP_TLV_HEADER_END = 0x0,
|
||||
BR_MRP_TLV_HEADER_COMMON = 0x1,
|
||||
BR_MRP_TLV_HEADER_RING_TEST = 0x2,
|
||||
BR_MRP_TLV_HEADER_RING_TOPO = 0x3,
|
||||
BR_MRP_TLV_HEADER_RING_LINK_DOWN = 0x4,
|
||||
BR_MRP_TLV_HEADER_RING_LINK_UP = 0x5,
|
||||
BR_MRP_TLV_HEADER_IN_TEST = 0x6,
|
||||
BR_MRP_TLV_HEADER_IN_TOPO = 0x7,
|
||||
BR_MRP_TLV_HEADER_IN_LINK_DOWN = 0x8,
|
||||
BR_MRP_TLV_HEADER_IN_LINK_UP = 0x9,
|
||||
BR_MRP_TLV_HEADER_IN_LINK_STATUS = 0xa,
|
||||
BR_MRP_TLV_HEADER_OPTION = 0x7f,
|
||||
};
|
||||
|
||||
enum br_mrp_sub_tlv_header_type {
|
||||
BR_MRP_SUB_TLV_HEADER_TEST_MGR_NACK = 0x1,
|
||||
BR_MRP_SUB_TLV_HEADER_TEST_PROPAGATE = 0x2,
|
||||
BR_MRP_SUB_TLV_HEADER_TEST_AUTO_MGR = 0x3,
|
||||
};
|
||||
|
||||
#endif
|
@ -81,6 +81,7 @@ basic_sources = files('''
|
||||
linux/btrfs_tree.h
|
||||
linux/can/netlink.h
|
||||
linux/can/vxcan.h
|
||||
linux/cfm_bridge.h
|
||||
linux/fib_rules.h
|
||||
linux/fou.h
|
||||
linux/genetlink.h
|
||||
@ -101,6 +102,7 @@ basic_sources = files('''
|
||||
linux/l2tp.h
|
||||
linux/libc-compat.h
|
||||
linux/loadavg.h
|
||||
linux/mrp_bridge.h
|
||||
linux/netdevice.h
|
||||
linux/netfilter/nf_tables.h
|
||||
linux/netfilter/nfnetlink.h
|
||||
|
@ -34,3 +34,13 @@
|
||||
#ifndef ETHERTYPE_LLDP
|
||||
#define ETHERTYPE_LLDP 0x88cc
|
||||
#endif
|
||||
|
||||
/* Not exposed but defined in linux/netdevice.h */
|
||||
#ifndef MAX_PHYS_ITEM_ID_LEN
|
||||
#define MAX_PHYS_ITEM_ID_LEN 32
|
||||
#endif
|
||||
|
||||
/* Not exposed but defined in include/net/bonding.h */
|
||||
#ifndef BOND_MAX_ARP_TARGETS
|
||||
#define BOND_MAX_ARP_TARGETS 16
|
||||
#endif
|
||||
|
@ -112,7 +112,7 @@ struct netlink_container {
|
||||
const struct NLTypeSystem *type_system; /* the type system of the container */
|
||||
size_t offset; /* offset from hdr to the start of the container */
|
||||
struct netlink_attribute *attributes;
|
||||
unsigned short n_attributes; /* number of attributes in container */
|
||||
uint16_t max_attribute; /* the maximum attribute in container */
|
||||
};
|
||||
|
||||
struct sd_netlink_message {
|
||||
|
@ -712,7 +712,7 @@ static int netlink_message_read_internal(
|
||||
if (!m->containers[m->n_containers].attributes)
|
||||
return -ENODATA;
|
||||
|
||||
if (type >= m->containers[m->n_containers].n_attributes)
|
||||
if (type > m->containers[m->n_containers].max_attribute)
|
||||
return -ENODATA;
|
||||
|
||||
attribute = &m->containers[m->n_containers].attributes[type];
|
||||
@ -1093,38 +1093,38 @@ int sd_netlink_message_read_strv(sd_netlink_message *m, unsigned short container
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int netlink_container_parse(sd_netlink_message *m,
|
||||
struct netlink_container *container,
|
||||
struct rtattr *rta,
|
||||
size_t rt_len) {
|
||||
static int netlink_container_parse(
|
||||
sd_netlink_message *m,
|
||||
struct netlink_container *container,
|
||||
struct rtattr *rta,
|
||||
size_t rt_len) {
|
||||
|
||||
_cleanup_free_ struct netlink_attribute *attributes = NULL;
|
||||
size_t n = 0;
|
||||
uint16_t max_attr = 0;
|
||||
|
||||
/* RTA_OK() macro compares with rta->rt_len, which is unsigned short, and
|
||||
* LGTM.com analysis does not like the type difference. Hence, here we
|
||||
* introduce an unsigned short variable as a workaround. */
|
||||
unsigned short len = rt_len;
|
||||
for (; RTA_OK(rta, len); rta = RTA_NEXT(rta, len)) {
|
||||
unsigned short type;
|
||||
uint16_t attr;
|
||||
|
||||
type = RTA_TYPE(rta);
|
||||
attr = RTA_TYPE(rta);
|
||||
max_attr = MAX(max_attr, attr);
|
||||
|
||||
if (!GREEDY_REALLOC0(attributes, type + 1))
|
||||
if (!GREEDY_REALLOC0(attributes, (size_t) max_attr + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
if (attributes[type].offset != 0)
|
||||
if (attributes[attr].offset != 0)
|
||||
log_debug("sd-netlink: message parse - overwriting repeated attribute");
|
||||
|
||||
attributes[type].offset = (uint8_t *) rta - (uint8_t *) m->hdr;
|
||||
attributes[type].nested = RTA_FLAGS(rta) & NLA_F_NESTED;
|
||||
attributes[type].net_byteorder = RTA_FLAGS(rta) & NLA_F_NET_BYTEORDER;
|
||||
|
||||
if (type + 1U > n)
|
||||
n = type + 1U;
|
||||
attributes[attr].offset = (uint8_t *) rta - (uint8_t *) m->hdr;
|
||||
attributes[attr].nested = RTA_FLAGS(rta) & NLA_F_NESTED;
|
||||
attributes[attr].net_byteorder = RTA_FLAGS(rta) & NLA_F_NET_BYTEORDER;
|
||||
}
|
||||
|
||||
container->attributes = TAKE_PTR(attributes);
|
||||
container->n_attributes = n;
|
||||
container->max_attribute = max_attr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1259,6 +1259,7 @@ int sd_netlink_message_exit_container(sd_netlink_message *m) {
|
||||
assert_return(m->n_containers > 0, -EINVAL);
|
||||
|
||||
m->containers[m->n_containers].attributes = mfree(m->containers[m->n_containers].attributes);
|
||||
m->containers[m->n_containers].max_attribute = 0;
|
||||
m->containers[m->n_containers].type_system = NULL;
|
||||
|
||||
m->n_containers--;
|
||||
@ -1266,6 +1267,15 @@ int sd_netlink_message_exit_container(sd_netlink_message *m) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_netlink_message_get_max_attribute(sd_netlink_message *m, uint16_t *ret) {
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(m->sealed, -EINVAL);
|
||||
assert_return(ret, -EINVAL);
|
||||
|
||||
*ret = m->containers[m->n_containers].max_attribute;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t message_get_serial(sd_netlink_message *m) {
|
||||
assert(m);
|
||||
assert(m->hdr);
|
||||
|
@ -50,18 +50,18 @@ static const NLType genl_batadv_types[] = {
|
||||
[BATADV_ATTR_ALGO_NAME] = { .type = NETLINK_TYPE_STRING },
|
||||
[BATADV_ATTR_MESH_IFINDEX] = { .type = NETLINK_TYPE_U32 },
|
||||
[BATADV_ATTR_MESH_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ },
|
||||
[BATADV_ATTR_MESH_ADDRESS] = { .size = ETH_ALEN },
|
||||
[BATADV_ATTR_MESH_ADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR, .size = ETH_ALEN },
|
||||
[BATADV_ATTR_HARD_IFINDEX] = { .type = NETLINK_TYPE_U32 },
|
||||
[BATADV_ATTR_HARD_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ },
|
||||
[BATADV_ATTR_HARD_ADDRESS] = { .size = ETH_ALEN },
|
||||
[BATADV_ATTR_ORIG_ADDRESS] = { .size = ETH_ALEN },
|
||||
[BATADV_ATTR_HARD_ADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR, .size = ETH_ALEN },
|
||||
[BATADV_ATTR_ORIG_ADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR, .size = ETH_ALEN },
|
||||
[BATADV_ATTR_TPMETER_RESULT] = { .type = NETLINK_TYPE_U8 },
|
||||
[BATADV_ATTR_TPMETER_TEST_TIME] = { .type = NETLINK_TYPE_U32 },
|
||||
[BATADV_ATTR_TPMETER_BYTES] = { .type = NETLINK_TYPE_U64 },
|
||||
[BATADV_ATTR_TPMETER_COOKIE] = { .type = NETLINK_TYPE_U32 },
|
||||
[BATADV_ATTR_PAD] = { .type = NETLINK_TYPE_UNSPEC },
|
||||
[BATADV_ATTR_ACTIVE] = { .type = NETLINK_TYPE_FLAG },
|
||||
[BATADV_ATTR_TT_ADDRESS] = { .size = ETH_ALEN },
|
||||
[BATADV_ATTR_TT_ADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR, .size = ETH_ALEN },
|
||||
[BATADV_ATTR_TT_TTVN] = { .type = NETLINK_TYPE_U8 },
|
||||
[BATADV_ATTR_TT_LAST_TTVN] = { .type = NETLINK_TYPE_U8 },
|
||||
[BATADV_ATTR_TT_CRC32] = { .type = NETLINK_TYPE_U32 },
|
||||
@ -69,19 +69,19 @@ static const NLType genl_batadv_types[] = {
|
||||
[BATADV_ATTR_TT_FLAGS] = { .type = NETLINK_TYPE_U32 },
|
||||
[BATADV_ATTR_FLAG_BEST] = { .type = NETLINK_TYPE_FLAG },
|
||||
[BATADV_ATTR_LAST_SEEN_MSECS] = { .type = NETLINK_TYPE_U32 },
|
||||
[BATADV_ATTR_NEIGH_ADDRESS] = { .size = ETH_ALEN },
|
||||
[BATADV_ATTR_NEIGH_ADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR, .size = ETH_ALEN },
|
||||
[BATADV_ATTR_TQ] = { .type = NETLINK_TYPE_U8 },
|
||||
[BATADV_ATTR_THROUGHPUT] = { .type = NETLINK_TYPE_U32 },
|
||||
[BATADV_ATTR_BANDWIDTH_UP] = { .type = NETLINK_TYPE_U32 },
|
||||
[BATADV_ATTR_BANDWIDTH_DOWN] = { .type = NETLINK_TYPE_U32 },
|
||||
[BATADV_ATTR_ROUTER] = { .size = ETH_ALEN },
|
||||
[BATADV_ATTR_ROUTER] = { .type = NETLINK_TYPE_ETHER_ADDR, .size = ETH_ALEN },
|
||||
[BATADV_ATTR_BLA_OWN] = { .type = NETLINK_TYPE_FLAG },
|
||||
[BATADV_ATTR_BLA_ADDRESS] = { .size = ETH_ALEN },
|
||||
[BATADV_ATTR_BLA_ADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR, .size = ETH_ALEN },
|
||||
[BATADV_ATTR_BLA_VID] = { .type = NETLINK_TYPE_U16 },
|
||||
[BATADV_ATTR_BLA_BACKBONE] = { .size = ETH_ALEN },
|
||||
[BATADV_ATTR_BLA_BACKBONE] = { .type = NETLINK_TYPE_ETHER_ADDR, .size = ETH_ALEN },
|
||||
[BATADV_ATTR_BLA_CRC] = { .type = NETLINK_TYPE_U16 },
|
||||
[BATADV_ATTR_DAT_CACHE_IP4ADDRESS] = { .type = NETLINK_TYPE_U32 },
|
||||
[BATADV_ATTR_DAT_CACHE_HWADDRESS] = { .size = ETH_ALEN },
|
||||
[BATADV_ATTR_DAT_CACHE_HWADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR, .size = ETH_ALEN },
|
||||
[BATADV_ATTR_DAT_CACHE_VID] = { .type = NETLINK_TYPE_U16 },
|
||||
[BATADV_ATTR_MCAST_FLAGS] = { .type = NETLINK_TYPE_U32 },
|
||||
[BATADV_ATTR_MCAST_FLAGS_PRIV] = { .type = NETLINK_TYPE_U32 },
|
||||
@ -118,9 +118,9 @@ static const NLType genl_fou_types[] = {
|
||||
[FOU_ATTR_LOCAL_V4] = { .type = NETLINK_TYPE_IN_ADDR },
|
||||
[FOU_ATTR_PEER_V4] = { .type = NETLINK_TYPE_IN_ADDR },
|
||||
[FOU_ATTR_LOCAL_V6] = { .type = NETLINK_TYPE_IN_ADDR },
|
||||
[FOU_ATTR_PEER_V6] = { .type = NETLINK_TYPE_IN_ADDR},
|
||||
[FOU_ATTR_PEER_PORT] = { .type = NETLINK_TYPE_U16},
|
||||
[FOU_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32},
|
||||
[FOU_ATTR_PEER_V6] = { .type = NETLINK_TYPE_IN_ADDR },
|
||||
[FOU_ATTR_PEER_PORT] = { .type = NETLINK_TYPE_U16 },
|
||||
[FOU_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 },
|
||||
};
|
||||
|
||||
/***************** genl l2tp type systems *****************/
|
||||
@ -165,8 +165,8 @@ static const NLType genl_macsec_sa_types[] = {
|
||||
[MACSEC_SA_ATTR_AN] = { .type = NETLINK_TYPE_U8 },
|
||||
[MACSEC_SA_ATTR_ACTIVE] = { .type = NETLINK_TYPE_U8 },
|
||||
[MACSEC_SA_ATTR_PN] = { .type = NETLINK_TYPE_U32 },
|
||||
[MACSEC_SA_ATTR_KEYID] = { .size = MACSEC_KEYID_LEN },
|
||||
[MACSEC_SA_ATTR_KEY] = { .size = MACSEC_MAX_KEY_LEN },
|
||||
[MACSEC_SA_ATTR_KEYID] = { .type = NETLINK_TYPE_BINARY, .size = MACSEC_KEYID_LEN },
|
||||
[MACSEC_SA_ATTR_KEY] = { .type = NETLINK_TYPE_BINARY, .size = MACSEC_MAX_KEY_LEN },
|
||||
};
|
||||
|
||||
DEFINE_TYPE_SYSTEM(genl_macsec_sa);
|
||||
@ -195,9 +195,9 @@ static const NLType genl_wireguard_allowedip_types[] = {
|
||||
DEFINE_TYPE_SYSTEM(genl_wireguard_allowedip);
|
||||
|
||||
static const NLType genl_wireguard_peer_types[] = {
|
||||
[WGPEER_A_PUBLIC_KEY] = { .size = WG_KEY_LEN },
|
||||
[WGPEER_A_PUBLIC_KEY] = { .type = NETLINK_TYPE_BINARY, .size = WG_KEY_LEN },
|
||||
[WGPEER_A_FLAGS] = { .type = NETLINK_TYPE_U32 },
|
||||
[WGPEER_A_PRESHARED_KEY] = { .size = WG_KEY_LEN },
|
||||
[WGPEER_A_PRESHARED_KEY] = { .type = NETLINK_TYPE_BINARY, .size = WG_KEY_LEN },
|
||||
[WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL] = { .type = NETLINK_TYPE_U16 },
|
||||
[WGPEER_A_ENDPOINT] = { .type = NETLINK_TYPE_SOCKADDR },
|
||||
[WGPEER_A_ALLOWEDIPS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_allowedip_type_system },
|
||||
@ -209,7 +209,7 @@ static const NLType genl_wireguard_types[] = {
|
||||
[WGDEVICE_A_IFINDEX] = { .type = NETLINK_TYPE_U32 },
|
||||
[WGDEVICE_A_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ-1 },
|
||||
[WGDEVICE_A_FLAGS] = { .type = NETLINK_TYPE_U32 },
|
||||
[WGDEVICE_A_PRIVATE_KEY] = { .size = WG_KEY_LEN },
|
||||
[WGDEVICE_A_PRIVATE_KEY] = { .type = NETLINK_TYPE_BINARY, .size = WG_KEY_LEN },
|
||||
[WGDEVICE_A_LISTEN_PORT] = { .type = NETLINK_TYPE_U16 },
|
||||
[WGDEVICE_A_FWMARK] = { .type = NETLINK_TYPE_U32 },
|
||||
[WGDEVICE_A_PEERS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_peer_type_system },
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -515,19 +515,23 @@ static int netdev_create(NetDev *netdev, Link *link, link_netlink_message_handle
|
||||
if (r < 0)
|
||||
return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m");
|
||||
|
||||
r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, netdev_kind_to_string(netdev->kind));
|
||||
if (r < 0)
|
||||
return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m");
|
||||
|
||||
if (NETDEV_VTABLE(netdev)->fill_message_create) {
|
||||
r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, netdev_kind_to_string(netdev->kind));
|
||||
if (r < 0)
|
||||
return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m");
|
||||
|
||||
r = NETDEV_VTABLE(netdev)->fill_message_create(netdev, link, m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = sd_netlink_message_close_container(m);
|
||||
if (r < 0)
|
||||
return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m");
|
||||
r = sd_netlink_message_close_container(m);
|
||||
if (r < 0)
|
||||
return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m");
|
||||
} else {
|
||||
r = sd_netlink_message_append_string(m, IFLA_INFO_KIND, netdev_kind_to_string(netdev->kind));
|
||||
if (r < 0)
|
||||
return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_KIND attribute: %m");
|
||||
}
|
||||
|
||||
r = sd_netlink_message_close_container(m);
|
||||
if (r < 0)
|
||||
|
@ -126,6 +126,7 @@ int sd_netlink_message_get_errno(sd_netlink_message *m);
|
||||
int sd_netlink_message_get_type(sd_netlink_message *m, uint16_t *type);
|
||||
int sd_netlink_message_set_flags(sd_netlink_message *m, uint16_t flags);
|
||||
int sd_netlink_message_is_broadcast(sd_netlink_message *m);
|
||||
int sd_netlink_message_get_max_attribute(sd_netlink_message *m, uint16_t *ret);
|
||||
|
||||
/* rtnl */
|
||||
int sd_rtnl_message_get_family(sd_netlink_message *m, int *family);
|
||||
|
@ -33,6 +33,8 @@ libudevd_core_sources = '''
|
||||
udev-builtin-hwdb.c
|
||||
udev-builtin-input_id.c
|
||||
udev-builtin-keyboard.c
|
||||
udev-builtin-net_id-netlink.c
|
||||
udev-builtin-net_id-netlink.h
|
||||
udev-builtin-net_id.c
|
||||
udev-builtin-net_setup_link.c
|
||||
udev-builtin-path_id.c
|
||||
@ -210,6 +212,10 @@ tests += [
|
||||
[threads,
|
||||
libacl]],
|
||||
|
||||
[['src/udev/test-udev-builtin-net_id-netlink.c',
|
||||
'src/udev/udev-builtin-net_id-netlink.c',
|
||||
'src/udev/udev-builtin-net_id-netlink.h']],
|
||||
|
||||
[['src/udev/fido_id/test-fido-id-desc.c',
|
||||
'src/udev/fido_id/fido_id_desc.c']],
|
||||
]
|
||||
|
@ -37,7 +37,6 @@ struct LinkConfigContext {
|
||||
LIST_HEAD(LinkConfig, links);
|
||||
int ethtool_fd;
|
||||
bool enable_name_policy;
|
||||
sd_netlink *rtnl;
|
||||
usec_t network_dirs_ts_usec;
|
||||
};
|
||||
|
||||
@ -78,7 +77,6 @@ LinkConfigContext *link_config_ctx_free(LinkConfigContext *ctx) {
|
||||
return NULL;
|
||||
|
||||
safe_close(ctx->ethtool_fd);
|
||||
sd_netlink_unref(ctx->rtnl);
|
||||
link_configs_free(ctx);
|
||||
return mfree(ctx);
|
||||
}
|
||||
@ -239,7 +237,7 @@ bool link_config_should_reload(LinkConfigContext *ctx) {
|
||||
return paths_check_timestamp(NETWORK_DIRS, &ctx->network_dirs_ts_usec, false);
|
||||
}
|
||||
|
||||
int link_config_get(LinkConfigContext *ctx, sd_device *device, LinkConfig **ret) {
|
||||
int link_config_get(LinkConfigContext *ctx, sd_netlink **rtnl, sd_device *device, LinkConfig **ret) {
|
||||
unsigned name_assign_type = NET_NAME_UNKNOWN;
|
||||
struct ether_addr permanent_mac = {};
|
||||
unsigned short iftype;
|
||||
@ -249,6 +247,7 @@ int link_config_get(LinkConfigContext *ctx, sd_device *device, LinkConfig **ret)
|
||||
int ifindex, r;
|
||||
|
||||
assert(ctx);
|
||||
assert(rtnl);
|
||||
assert(device);
|
||||
assert(ret);
|
||||
|
||||
@ -260,7 +259,7 @@ int link_config_get(LinkConfigContext *ctx, sd_device *device, LinkConfig **ret)
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = rtnl_get_link_info(&ctx->rtnl, ifindex, &iftype, &flags);
|
||||
r = rtnl_get_link_info(rtnl, ifindex, &iftype, &flags);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -606,13 +605,14 @@ static int link_config_apply_alternative_names(sd_netlink **rtnl, const LinkConf
|
||||
return 0;
|
||||
}
|
||||
|
||||
int link_config_apply(LinkConfigContext *ctx, const LinkConfig *config, sd_device *device, const char **ret_name) {
|
||||
int link_config_apply(LinkConfigContext *ctx, const LinkConfig *config, sd_netlink **rtnl, sd_device *device, const char **ret_name) {
|
||||
const char *new_name;
|
||||
sd_device_action_t a;
|
||||
int r;
|
||||
|
||||
assert(ctx);
|
||||
assert(config);
|
||||
assert(rtnl);
|
||||
assert(device);
|
||||
assert(ret_name);
|
||||
|
||||
@ -634,7 +634,7 @@ int link_config_apply(LinkConfigContext *ctx, const LinkConfig *config, sd_devic
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = link_config_apply_rtnl_settings(&ctx->rtnl, config, device);
|
||||
r = link_config_apply_rtnl_settings(rtnl, config, device);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -650,7 +650,7 @@ int link_config_apply(LinkConfigContext *ctx, const LinkConfig *config, sd_devic
|
||||
return r;
|
||||
}
|
||||
|
||||
r = link_config_apply_alternative_names(&ctx->rtnl, config, device, new_name);
|
||||
r = link_config_apply_alternative_names(rtnl, config, device, new_name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "sd-device.h"
|
||||
#include "sd-netlink.h"
|
||||
|
||||
#include "condition.h"
|
||||
#include "conf-parser.h"
|
||||
@ -77,8 +78,8 @@ int link_load_one(LinkConfigContext *ctx, const char *filename);
|
||||
int link_config_load(LinkConfigContext *ctx);
|
||||
bool link_config_should_reload(LinkConfigContext *ctx);
|
||||
|
||||
int link_config_get(LinkConfigContext *ctx, sd_device *device, LinkConfig **ret);
|
||||
int link_config_apply(LinkConfigContext *ctx, const LinkConfig *config, sd_device *device, const char **ret_name);
|
||||
int link_config_get(LinkConfigContext *ctx, sd_netlink **rtnl, sd_device *device, LinkConfig **ret);
|
||||
int link_config_apply(LinkConfigContext *ctx, const LinkConfig *config, sd_netlink **rtnl, sd_device *device, const char **ret_name);
|
||||
int link_get_driver(LinkConfigContext *ctx, sd_device *device, char **ret);
|
||||
|
||||
const char *name_policy_to_string(NamePolicy p) _const_;
|
||||
|
85
src/udev/test-udev-builtin-net_id-netlink.c
Normal file
85
src/udev/test-udev-builtin-net_id-netlink.c
Normal file
@ -0,0 +1,85 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "sd-device.h"
|
||||
|
||||
#include "arphrd-list.h"
|
||||
#include "ether-addr-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "tests.h"
|
||||
#include "udev-builtin-net_id-netlink.h"
|
||||
|
||||
static void test_link_info_one(sd_netlink *rtnl, int ifindex) {
|
||||
_cleanup_(link_info_clear) LinkInfo info = LINK_INFO_NULL;
|
||||
_cleanup_(sd_device_unrefp) sd_device *dev = NULL;
|
||||
unsigned iftype, iflink;
|
||||
const char *s;
|
||||
|
||||
log_debug("/* %s(ifindex=%i) */", __func__, ifindex);
|
||||
|
||||
assert_se(link_info_get(&rtnl, ifindex, &info) >= 0);
|
||||
assert_se(sd_device_new_from_ifindex(&dev, ifindex) >= 0);
|
||||
|
||||
/* check iftype */
|
||||
log_debug("iftype: %"PRIu16" (%s)", info.iftype, strna(arphrd_to_name(info.iftype)));
|
||||
assert_se(sd_device_get_sysattr_value(dev, "type", &s) >= 0);
|
||||
assert_se(safe_atou(s, &iftype) >= 0);
|
||||
assert_se(iftype == info.iftype);
|
||||
|
||||
/* check hardware address */
|
||||
log_debug("hardware address: %s", HW_ADDR_TO_STR(&info.hw_addr));
|
||||
assert_se(sd_device_get_sysattr_value(dev, "address", &s) >= 0);
|
||||
assert_se(streq(s, HW_ADDR_TO_STR(&info.hw_addr)));
|
||||
|
||||
/* check ifname */
|
||||
log_debug("ifname: %s", info.ifname);
|
||||
assert_se(sd_device_get_sysname(dev, &s) >= 0);
|
||||
assert_se(streq(s, info.ifname));
|
||||
|
||||
/* check iflink */
|
||||
log_debug("iflink: %"PRIu32, info.iflink);
|
||||
assert_se(sd_device_get_sysattr_value(dev, "iflink", &s) >= 0);
|
||||
assert_se(safe_atou(s, &iflink) >= 0);
|
||||
assert_se(iflink == info.iflink);
|
||||
|
||||
/* check phys_port_name */
|
||||
log_debug("phys_port_name: %s (%s)",
|
||||
strna(info.phys_port_name),
|
||||
info.support_phys_port_name ? "supported" : "unsupported");
|
||||
if (info.support_phys_port_name) {
|
||||
s = NULL;
|
||||
(void) sd_device_get_sysattr_value(dev, "phys_port_name", &s);
|
||||
assert_se(streq_ptr(s, info.phys_port_name));
|
||||
}
|
||||
}
|
||||
|
||||
static void test_link_info_get(void) {
|
||||
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
|
||||
|
||||
log_debug("/* %s */", __func__);
|
||||
|
||||
assert_se(sd_netlink_open(&rtnl) >= 0);
|
||||
|
||||
assert_se(sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0) >= 0);
|
||||
assert_se(sd_netlink_message_request_dump(req, true) >= 0);
|
||||
assert_se(sd_netlink_call(rtnl, req, 0, &reply) >= 0);
|
||||
|
||||
for (sd_netlink_message *reply_one = reply; reply_one; reply_one = sd_netlink_message_next(reply_one)) {
|
||||
uint16_t nlmsg_type;
|
||||
int ifindex;
|
||||
|
||||
assert_se(sd_netlink_message_get_type(reply_one, &nlmsg_type) >= 0);
|
||||
assert_se(nlmsg_type == RTM_NEWLINK);
|
||||
assert_se(sd_rtnl_message_link_get_ifindex(reply_one, &ifindex) >= 0);
|
||||
|
||||
test_link_info_one(rtnl, ifindex);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
test_setup_logging(LOG_DEBUG);
|
||||
|
||||
test_link_info_get();
|
||||
|
||||
return 0;
|
||||
}
|
@ -233,7 +233,7 @@ static int probe_superblocks(blkid_probe pr) {
|
||||
return blkid_do_safeprobe(pr);
|
||||
}
|
||||
|
||||
static int builtin_blkid(sd_device *dev, int argc, char *argv[], bool test) {
|
||||
static int builtin_blkid(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) {
|
||||
const char *devnode, *root_partition = NULL, *data, *name;
|
||||
_cleanup_(blkid_free_probep) blkid_probe pr = NULL;
|
||||
bool noraid = false, is_gpt = false;
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include "udev-builtin.h"
|
||||
#include "util.h"
|
||||
|
||||
static int builtin_btrfs(sd_device *dev, int argc, char *argv[], bool test) {
|
||||
static int builtin_btrfs(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) {
|
||||
struct btrfs_ioctl_vol_args args = {};
|
||||
_cleanup_close_ int fd = -1;
|
||||
int r;
|
||||
|
@ -118,7 +118,7 @@ next:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int builtin_hwdb(sd_device *dev, int argc, char *argv[], bool test) {
|
||||
static int builtin_hwdb(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) {
|
||||
static const struct option options[] = {
|
||||
{ "filter", required_argument, NULL, 'f' },
|
||||
{ "device", required_argument, NULL, 'd' },
|
||||
|
@ -322,7 +322,7 @@ static bool test_key(sd_device *dev,
|
||||
return found;
|
||||
}
|
||||
|
||||
static int builtin_input_id(sd_device *dev, int argc, char *argv[], bool test) {
|
||||
static int builtin_input_id(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) {
|
||||
sd_device *pdev;
|
||||
unsigned long bitmask_ev[NBITS(EV_MAX)];
|
||||
unsigned long bitmask_abs[NBITS(ABS_MAX)];
|
||||
|
@ -159,7 +159,7 @@ static int set_trackpoint_sensitivity(sd_device *dev, const char *value) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int builtin_keyboard(sd_device *dev, int argc, char *argv[], bool test) {
|
||||
static int builtin_keyboard(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) {
|
||||
unsigned release[1024];
|
||||
unsigned release_count = 0;
|
||||
_cleanup_close_ int fd = -1;
|
||||
|
@ -20,7 +20,7 @@ _printf_(6,0) static void udev_kmod_log(void *data, int priority, const char *fi
|
||||
log_internalv(priority, 0, file, line, fn, format, args);
|
||||
}
|
||||
|
||||
static int builtin_kmod(sd_device *dev, int argc, char *argv[], bool test) {
|
||||
static int builtin_kmod(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) {
|
||||
if (!ctx)
|
||||
return 0;
|
||||
|
||||
|
87
src/udev/udev-builtin-net_id-netlink.c
Normal file
87
src/udev/udev-builtin-net_id-netlink.c
Normal file
@ -0,0 +1,87 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "netlink-util.h"
|
||||
#include "udev-builtin-net_id-netlink.h"
|
||||
|
||||
void link_info_clear(LinkInfo *info) {
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
info->ifname = mfree(info->ifname);
|
||||
info->phys_port_name = mfree(info->phys_port_name);
|
||||
}
|
||||
|
||||
int link_info_get(sd_netlink **rtnl, int ifindex, LinkInfo *ret) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL, *reply = NULL;
|
||||
_cleanup_(link_info_clear) LinkInfo info = LINK_INFO_NULL;
|
||||
uint16_t nlmsg_type;
|
||||
int r;
|
||||
|
||||
assert(rtnl);
|
||||
assert(ifindex > 0);
|
||||
assert(ret);
|
||||
|
||||
if (!*rtnl) {
|
||||
r = sd_netlink_open(rtnl);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = sd_rtnl_message_new_link(*rtnl, &message, RTM_GETLINK, ifindex);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_netlink_call(*rtnl, message, 0, &reply);
|
||||
if (r == -EINVAL)
|
||||
return -ENODEV; /* The device does not exist */
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_netlink_message_get_type(reply, &nlmsg_type);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (nlmsg_type != RTM_NEWLINK)
|
||||
return -ENXIO;
|
||||
|
||||
r = sd_rtnl_message_link_get_ifindex(reply, &info.ifindex);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (info.ifindex != ifindex)
|
||||
return -ENXIO;
|
||||
|
||||
r = sd_rtnl_message_link_get_type(reply, &info.iftype);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = netlink_message_read_hw_addr(reply, IFLA_ADDRESS, &info.hw_addr);
|
||||
if (r < 0 && r != -ENODATA)
|
||||
return r;
|
||||
|
||||
r = sd_netlink_message_read_string_strdup(reply, IFLA_IFNAME, &info.ifname);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_netlink_message_read_u32(reply, IFLA_LINK, &info.iflink);
|
||||
if (r == -ENODATA)
|
||||
info.iflink = info.ifindex;
|
||||
else if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_netlink_message_read_string_strdup(reply, IFLA_PHYS_PORT_NAME, &info.phys_port_name);
|
||||
if (r == -ENODATA) {
|
||||
uint16_t max_attr;
|
||||
|
||||
r = sd_netlink_message_get_max_attribute(reply, &max_attr);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
info.support_phys_port_name = max_attr >= IFLA_PHYS_PORT_NAME;
|
||||
} else if (r >= 0)
|
||||
info.support_phys_port_name = true;
|
||||
else
|
||||
return r;
|
||||
|
||||
*ret = info;
|
||||
info = LINK_INFO_NULL;
|
||||
return 0;
|
||||
}
|
23
src/udev/udev-builtin-net_id-netlink.h
Normal file
23
src/udev/udev-builtin-net_id-netlink.h
Normal file
@ -0,0 +1,23 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "sd-netlink.h"
|
||||
|
||||
#include "ether-addr-util.h"
|
||||
|
||||
typedef struct LinkInfo {
|
||||
int ifindex;
|
||||
uint16_t iftype; /* ARPHRD_* */
|
||||
|
||||
struct hw_addr_data hw_addr; /* IFLA_ADDRESS */
|
||||
char *ifname; /* IFLA_IFNAME */
|
||||
uint32_t iflink; /* IFLA_LINK */
|
||||
char *phys_port_name; /* IFLA_PHYS_PORT_NAME */
|
||||
|
||||
bool support_phys_port_name;
|
||||
} LinkInfo;
|
||||
|
||||
#define LINK_INFO_NULL ((LinkInfo) {})
|
||||
|
||||
void link_info_clear(LinkInfo *info);
|
||||
int link_info_get(sd_netlink **rtnl, int ifindex, LinkInfo *ret);
|
@ -15,10 +15,11 @@
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/pci_regs.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
@ -34,12 +35,13 @@
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "strxcpyx.h"
|
||||
#include "udev-builtin-net_id-netlink.h"
|
||||
#include "udev-builtin.h"
|
||||
|
||||
#define ONBOARD_14BIT_INDEX_MAX ((1U << 14) - 1)
|
||||
#define ONBOARD_16BIT_INDEX_MAX ((1U << 16) - 1)
|
||||
|
||||
enum netname_type{
|
||||
typedef enum NetNameType {
|
||||
NET_UNDEF,
|
||||
NET_PCI,
|
||||
NET_USB,
|
||||
@ -49,13 +51,10 @@ enum netname_type{
|
||||
NET_VIO,
|
||||
NET_PLATFORM,
|
||||
NET_NETDEVSIM,
|
||||
};
|
||||
} NetNameType;
|
||||
|
||||
struct netnames {
|
||||
enum netname_type type;
|
||||
|
||||
uint8_t mac[6];
|
||||
bool mac_valid;
|
||||
typedef struct NetNames {
|
||||
NetNameType type;
|
||||
|
||||
sd_device *pcidev;
|
||||
char pci_slot[ALTIFNAMSIZ];
|
||||
@ -69,12 +68,7 @@ struct netnames {
|
||||
char vio_slot[ALTIFNAMSIZ];
|
||||
char platform_path[ALTIFNAMSIZ];
|
||||
char netdevsim_path[ALTIFNAMSIZ];
|
||||
};
|
||||
|
||||
struct virtfn_info {
|
||||
sd_device *physfn_pcidev;
|
||||
char suffix[ALTIFNAMSIZ];
|
||||
};
|
||||
} NetNames;
|
||||
|
||||
/* skip intermediate virtio devices */
|
||||
static sd_device *skip_virtio(sd_device *dev) {
|
||||
@ -97,47 +91,45 @@ static sd_device *skip_virtio(sd_device *dev) {
|
||||
return dev;
|
||||
}
|
||||
|
||||
static int get_virtfn_info(sd_device *dev, struct netnames *names, struct virtfn_info *ret) {
|
||||
static int get_virtfn_info(sd_device *pcidev, sd_device **ret_physfn_pcidev, char **ret_suffix) {
|
||||
_cleanup_(sd_device_unrefp) sd_device *physfn_pcidev = NULL;
|
||||
const char *physfn_link_file, *syspath;
|
||||
_cleanup_free_ char *physfn_pci_syspath = NULL;
|
||||
_cleanup_free_ char *virtfn_pci_syspath = NULL;
|
||||
struct dirent *dent;
|
||||
const char *physfn_syspath, *syspath;
|
||||
_cleanup_closedir_ DIR *dir = NULL;
|
||||
char suffix[ALTIFNAMSIZ];
|
||||
struct dirent *dent;
|
||||
int r;
|
||||
|
||||
assert(dev);
|
||||
assert(names);
|
||||
assert(ret);
|
||||
assert(pcidev);
|
||||
assert(ret_physfn_pcidev);
|
||||
assert(ret_suffix);
|
||||
|
||||
r = sd_device_get_syspath(names->pcidev, &syspath);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Check if this is a virtual function. */
|
||||
physfn_link_file = strjoina(syspath, "/physfn");
|
||||
r = chase_symlinks(physfn_link_file, NULL, 0, &physfn_pci_syspath, NULL);
|
||||
r = sd_device_get_syspath(pcidev, &syspath);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Get physical function's pci device. */
|
||||
r = sd_device_new_from_syspath(&physfn_pcidev, physfn_pci_syspath);
|
||||
physfn_syspath = strjoina(syspath, "/physfn");
|
||||
r = sd_device_new_from_syspath(&physfn_pcidev, physfn_syspath);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_device_get_syspath(physfn_pcidev, &physfn_syspath);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Find the virtual function number by finding the right virtfn link. */
|
||||
dir = opendir(physfn_pci_syspath);
|
||||
dir = opendir(physfn_syspath);
|
||||
if (!dir)
|
||||
return -errno;
|
||||
|
||||
FOREACH_DIRENT_ALL(dent, dir, break) {
|
||||
_cleanup_free_ char *virtfn_link_file = NULL;
|
||||
_cleanup_free_ char *virtfn_link_file = NULL, *virtfn_pci_syspath = NULL;
|
||||
const char *n;
|
||||
|
||||
if (!startswith(dent->d_name, "virtfn"))
|
||||
n = startswith(dent->d_name, "virtfn");
|
||||
if (!n)
|
||||
continue;
|
||||
|
||||
virtfn_link_file = path_join(physfn_pci_syspath, dent->d_name);
|
||||
virtfn_link_file = path_join(physfn_syspath, dent->d_name);
|
||||
if (!virtfn_link_file)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -145,19 +137,19 @@ static int get_virtfn_info(sd_device *dev, struct netnames *names, struct virtfn
|
||||
continue;
|
||||
|
||||
if (streq(syspath, virtfn_pci_syspath)) {
|
||||
if (!snprintf_ok(suffix, sizeof(suffix), "v%s", &dent->d_name[6]))
|
||||
return -ENOENT;
|
||||
char *suffix;
|
||||
|
||||
break;
|
||||
suffix = strjoin("v", n);
|
||||
if (!suffix)
|
||||
return -ENOMEM;
|
||||
|
||||
*ret_physfn_pcidev = TAKE_PTR(physfn_pcidev);
|
||||
*ret_suffix = suffix;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (isempty(suffix))
|
||||
return -ENOENT;
|
||||
|
||||
ret->physfn_pcidev = TAKE_PTR(physfn_pcidev);
|
||||
strncpy(ret->suffix, suffix, sizeof(ret->suffix));
|
||||
|
||||
return 0;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static bool is_valid_onboard_index(unsigned long idx) {
|
||||
@ -171,13 +163,17 @@ static bool is_valid_onboard_index(unsigned long idx) {
|
||||
}
|
||||
|
||||
/* retrieve on-board index number and label from firmware */
|
||||
static int dev_pci_onboard(sd_device *dev, struct netnames *names) {
|
||||
static int dev_pci_onboard(sd_device *dev, const LinkInfo *info, NetNames *names) {
|
||||
unsigned long idx, dev_port = 0;
|
||||
const char *attr, *port_name = NULL;
|
||||
const char *attr;
|
||||
size_t l;
|
||||
char *s;
|
||||
int r;
|
||||
|
||||
assert(dev);
|
||||
assert(info);
|
||||
assert(names);
|
||||
|
||||
/* ACPI _DSM — device specific method for naming a PCI or PCI Express device */
|
||||
if (sd_device_get_sysattr_value(names->pcidev, "acpi_index", &attr) < 0) {
|
||||
/* SMBIOS type 41 — Onboard Devices Extended Information */
|
||||
@ -202,14 +198,12 @@ static int dev_pci_onboard(sd_device *dev, struct netnames *names) {
|
||||
log_device_debug_errno(dev, r, "Failed to parse dev_port, ignoring: %m");
|
||||
}
|
||||
|
||||
/* kernel provided front panel port name for multiple port PCI device */
|
||||
(void) sd_device_get_sysattr_value(dev, "phys_port_name", &port_name);
|
||||
|
||||
s = names->pci_onboard;
|
||||
l = sizeof(names->pci_onboard);
|
||||
l = strpcpyf(&s, l, "o%lu", idx);
|
||||
if (port_name)
|
||||
l = strpcpyf(&s, l, "n%s", port_name);
|
||||
if (!isempty(info->phys_port_name))
|
||||
/* kernel provided front panel port name for multiple port PCI device */
|
||||
l = strpcpyf(&s, l, "n%s", info->phys_port_name);
|
||||
else if (dev_port > 0)
|
||||
l = strpcpyf(&s, l, "d%lu", dev_port);
|
||||
if (l == 0)
|
||||
@ -313,8 +307,8 @@ static int parse_hotplug_slot_from_function_id(sd_device *dev, const char *slots
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dev_pci_slot(sd_device *dev, struct netnames *names) {
|
||||
const char *sysname, *attr, *port_name = NULL, *syspath;
|
||||
static int dev_pci_slot(sd_device *dev, const LinkInfo *info, NetNames *names) {
|
||||
const char *sysname, *attr, *syspath;
|
||||
_cleanup_(sd_device_unrefp) sd_device *pci = NULL;
|
||||
_cleanup_closedir_ DIR *dir = NULL;
|
||||
unsigned domain, bus, slot, func;
|
||||
@ -325,6 +319,10 @@ static int dev_pci_slot(sd_device *dev, struct netnames *names) {
|
||||
size_t l;
|
||||
int r;
|
||||
|
||||
assert(dev);
|
||||
assert(info);
|
||||
assert(names);
|
||||
|
||||
r = sd_device_get_sysname(names->pcidev, &sysname);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -363,9 +361,6 @@ static int dev_pci_slot(sd_device *dev, struct netnames *names) {
|
||||
}
|
||||
}
|
||||
|
||||
/* kernel provided front panel port name for multi-port PCI device */
|
||||
(void) sd_device_get_sysattr_value(dev, "phys_port_name", &port_name);
|
||||
|
||||
/* compose a name based on the raw kernel's PCI bus, slot numbers */
|
||||
s = names->pci_path;
|
||||
l = sizeof(names->pci_path);
|
||||
@ -374,8 +369,9 @@ static int dev_pci_slot(sd_device *dev, struct netnames *names) {
|
||||
l = strpcpyf(&s, l, "p%us%u", bus, slot);
|
||||
if (func > 0 || is_pci_multifunction(names->pcidev))
|
||||
l = strpcpyf(&s, l, "f%u", func);
|
||||
if (port_name)
|
||||
l = strpcpyf(&s, l, "n%s", port_name);
|
||||
if (!isempty(info->phys_port_name))
|
||||
/* kernel provided front panel port name for multi-port PCI device */
|
||||
l = strpcpyf(&s, l, "n%s", info->phys_port_name);
|
||||
else if (dev_port > 0)
|
||||
l = strpcpyf(&s, l, "d%lu", dev_port);
|
||||
if (l == 0)
|
||||
@ -455,8 +451,8 @@ static int dev_pci_slot(sd_device *dev, struct netnames *names) {
|
||||
l = strpcpyf(&s, l, "s%"PRIu32, hotplug_slot);
|
||||
if (func > 0 || is_pci_multifunction(names->pcidev))
|
||||
l = strpcpyf(&s, l, "f%d", func);
|
||||
if (port_name)
|
||||
l = strpcpyf(&s, l, "n%s", port_name);
|
||||
if (!isempty(info->phys_port_name))
|
||||
l = strpcpyf(&s, l, "n%s", info->phys_port_name);
|
||||
else if (dev_port > 0)
|
||||
l = strpcpyf(&s, l, "d%lu", dev_port);
|
||||
if (l == 0)
|
||||
@ -466,7 +462,7 @@ static int dev_pci_slot(sd_device *dev, struct netnames *names) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int names_vio(sd_device *dev, struct netnames *names) {
|
||||
static int names_vio(sd_device *dev, NetNames *names) {
|
||||
sd_device *parent;
|
||||
unsigned busid, slotid, ethid;
|
||||
const char *syspath, *subsystem;
|
||||
@ -503,7 +499,7 @@ static int names_vio(sd_device *dev, struct netnames *names) {
|
||||
#define _PLATFORM_PATTERN4 "/sys/devices/platform/%4s%4x:%2x/net/eth%u"
|
||||
#define _PLATFORM_PATTERN3 "/sys/devices/platform/%3s%4x:%2x/net/eth%u"
|
||||
|
||||
static int names_platform(sd_device *dev, struct netnames *names, bool test) {
|
||||
static int names_platform(sd_device *dev, NetNames *names, bool test) {
|
||||
sd_device *parent;
|
||||
char vendor[5];
|
||||
unsigned model, instance, ethid;
|
||||
@ -558,14 +554,15 @@ static int names_platform(sd_device *dev, struct netnames *names, bool test) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int names_pci(sd_device *dev, struct netnames *names) {
|
||||
static int names_pci(sd_device *dev, const LinkInfo *info, NetNames *names) {
|
||||
_cleanup_(sd_device_unrefp) sd_device *physfn_pcidev = NULL;
|
||||
_cleanup_free_ char *virtfn_suffix = NULL;
|
||||
sd_device *parent;
|
||||
struct netnames vf_names = {};
|
||||
struct virtfn_info vf_info = {};
|
||||
const char *subsystem;
|
||||
int r;
|
||||
|
||||
assert(dev);
|
||||
assert(info);
|
||||
assert(names);
|
||||
|
||||
r = sd_device_get_parent(dev, &parent);
|
||||
@ -589,33 +586,35 @@ static int names_pci(sd_device *dev, struct netnames *names) {
|
||||
}
|
||||
|
||||
if (naming_scheme_has(NAMING_SR_IOV_V) &&
|
||||
get_virtfn_info(dev, names, &vf_info) >= 0) {
|
||||
get_virtfn_info(names->pcidev, &physfn_pcidev, &virtfn_suffix) >= 0) {
|
||||
NetNames vf_names = {};
|
||||
|
||||
/* If this is an SR-IOV virtual device, get base name using physical device and add virtfn suffix. */
|
||||
vf_names.pcidev = vf_info.physfn_pcidev;
|
||||
dev_pci_onboard(dev, &vf_names);
|
||||
dev_pci_slot(dev, &vf_names);
|
||||
vf_names.pcidev = physfn_pcidev;
|
||||
dev_pci_onboard(dev, info, &vf_names);
|
||||
dev_pci_slot(dev, info, &vf_names);
|
||||
|
||||
if (vf_names.pci_onboard[0])
|
||||
if (strlen(vf_names.pci_onboard) + strlen(vf_info.suffix) < sizeof(names->pci_onboard))
|
||||
if (strlen(vf_names.pci_onboard) + strlen(virtfn_suffix) < sizeof(names->pci_onboard))
|
||||
strscpyl(names->pci_onboard, sizeof(names->pci_onboard),
|
||||
vf_names.pci_onboard, vf_info.suffix, NULL);
|
||||
vf_names.pci_onboard, virtfn_suffix, NULL);
|
||||
if (vf_names.pci_slot[0])
|
||||
if (strlen(vf_names.pci_slot) + strlen(vf_info.suffix) < sizeof(names->pci_slot))
|
||||
if (strlen(vf_names.pci_slot) + strlen(virtfn_suffix) < sizeof(names->pci_slot))
|
||||
strscpyl(names->pci_slot, sizeof(names->pci_slot),
|
||||
vf_names.pci_slot, vf_info.suffix, NULL);
|
||||
vf_names.pci_slot, virtfn_suffix, NULL);
|
||||
if (vf_names.pci_path[0])
|
||||
if (strlen(vf_names.pci_path) + strlen(vf_info.suffix) < sizeof(names->pci_path))
|
||||
if (strlen(vf_names.pci_path) + strlen(virtfn_suffix) < sizeof(names->pci_path))
|
||||
strscpyl(names->pci_path, sizeof(names->pci_path),
|
||||
vf_names.pci_path, vf_info.suffix, NULL);
|
||||
sd_device_unref(vf_info.physfn_pcidev);
|
||||
vf_names.pci_path, virtfn_suffix, NULL);
|
||||
} else {
|
||||
dev_pci_onboard(dev, names);
|
||||
dev_pci_slot(dev, names);
|
||||
dev_pci_onboard(dev, info, names);
|
||||
dev_pci_slot(dev, info, names);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int names_usb(sd_device *dev, struct netnames *names) {
|
||||
static int names_usb(sd_device *dev, NetNames *names) {
|
||||
sd_device *usbdev;
|
||||
char name[256], *ports, *config, *interf, *s;
|
||||
const char *sysname;
|
||||
@ -673,7 +672,7 @@ static int names_usb(sd_device *dev, struct netnames *names) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int names_bcma(sd_device *dev, struct netnames *names) {
|
||||
static int names_bcma(sd_device *dev, NetNames *names) {
|
||||
sd_device *bcmadev;
|
||||
unsigned core;
|
||||
const char *sysname;
|
||||
@ -701,7 +700,7 @@ static int names_bcma(sd_device *dev, struct netnames *names) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int names_ccw(sd_device *dev, struct netnames *names) {
|
||||
static int names_ccw(sd_device *dev, NetNames *names) {
|
||||
sd_device *cdev;
|
||||
const char *bus_id, *subsys;
|
||||
size_t bus_id_len;
|
||||
@ -759,76 +758,49 @@ static int names_ccw(sd_device *dev, struct netnames *names) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int names_mac(sd_device *dev, struct netnames *names) {
|
||||
static int names_mac(sd_device *dev, const LinkInfo *info) {
|
||||
const char *s;
|
||||
unsigned long i;
|
||||
unsigned a1, a2, a3, a4, a5, a6;
|
||||
unsigned i;
|
||||
int r;
|
||||
|
||||
/* Some kinds of devices tend to have hardware addresses
|
||||
* that are impossible to use in an iface name.
|
||||
*/
|
||||
r = sd_device_get_sysattr_value(dev, "type", &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
assert(dev);
|
||||
assert(info);
|
||||
|
||||
r = safe_atolu_full(s, 10, &i);
|
||||
if (r < 0)
|
||||
return r;
|
||||
switch (i) {
|
||||
/* The persistent part of a hardware address of an InfiniBand NIC
|
||||
* is 8 bytes long. We cannot fit this much in an iface name.
|
||||
*/
|
||||
case ARPHRD_INFINIBAND:
|
||||
return -EINVAL;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* The persistent part of a hardware address of an InfiniBand NIC is 8 bytes long. We cannot
|
||||
* fit this much in an iface name.
|
||||
* TODO: but it can be used as alternative names?? */
|
||||
if (info->iftype == ARPHRD_INFINIBAND || info->hw_addr.length != 6)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* check for NET_ADDR_PERM, skip random MAC addresses */
|
||||
r = sd_device_get_sysattr_value(dev, "addr_assign_type", &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = safe_atolu(s, &i);
|
||||
r = safe_atou(s, &i);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (i != 0)
|
||||
return 0;
|
||||
|
||||
r = sd_device_get_sysattr_value(dev, "address", &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (sscanf(s, "%x:%x:%x:%x:%x:%x", &a1, &a2, &a3, &a4, &a5, &a6) != 6)
|
||||
if (i != NET_ADDR_PERM)
|
||||
return -EINVAL;
|
||||
|
||||
/* skip empty MAC addresses */
|
||||
if (a1 + a2 + a3 + a4 + a5 + a6 == 0)
|
||||
return -EINVAL;
|
||||
|
||||
names->mac[0] = a1;
|
||||
names->mac[1] = a2;
|
||||
names->mac[2] = a3;
|
||||
names->mac[3] = a4;
|
||||
names->mac[4] = a5;
|
||||
names->mac[5] = a6;
|
||||
names->mac_valid = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int names_netdevsim(sd_device *dev, struct netnames *names) {
|
||||
static int names_netdevsim(sd_device *dev, const LinkInfo *info, NetNames *names) {
|
||||
sd_device *netdevsimdev;
|
||||
const char *sysname;
|
||||
unsigned addr;
|
||||
const char *port_name = NULL;
|
||||
int r;
|
||||
bool ok;
|
||||
|
||||
if (!naming_scheme_has(NAMING_NETDEVSIM))
|
||||
return 0;
|
||||
|
||||
assert(dev);
|
||||
assert(info);
|
||||
assert(names);
|
||||
|
||||
if (isempty(info->phys_port_name))
|
||||
return -EINVAL;
|
||||
|
||||
r = sd_device_get_parent_with_subsystem_devtype(dev, "netdevsim", NULL, &netdevsimdev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -839,12 +811,7 @@ static int names_netdevsim(sd_device *dev, struct netnames *names) {
|
||||
if (sscanf(sysname, "netdevsim%u", &addr) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
r = sd_device_get_sysattr_value(dev, "phys_port_name", &port_name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
ok = snprintf_ok(names->netdevsim_path, sizeof(names->netdevsim_path), "i%un%s", addr, port_name);
|
||||
if (!ok)
|
||||
if (!snprintf_ok(names->netdevsim_path, sizeof(names->netdevsim_path), "i%un%s", addr, info->phys_port_name))
|
||||
return -ENOBUFS;
|
||||
|
||||
names->type = NET_NETDEVSIM;
|
||||
@ -853,36 +820,62 @@ static int names_netdevsim(sd_device *dev, struct netnames *names) {
|
||||
}
|
||||
|
||||
/* IEEE Organizationally Unique Identifier vendor string */
|
||||
static int ieee_oui(sd_device *dev, struct netnames *names, bool test) {
|
||||
static int ieee_oui(sd_device *dev, const LinkInfo *info, bool test) {
|
||||
char str[32];
|
||||
|
||||
if (!names->mac_valid)
|
||||
return -ENOENT;
|
||||
assert(dev);
|
||||
assert(info);
|
||||
|
||||
if (info->hw_addr.length != 6)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* skip commonly misused 00:00:00 (Xerox) prefix */
|
||||
if (memcmp(names->mac, "\0\0\0", 3) == 0)
|
||||
if (info->hw_addr.bytes[0] == 0 &&
|
||||
info->hw_addr.bytes[1] == 0 &&
|
||||
info->hw_addr.bytes[2] == 0)
|
||||
return -EINVAL;
|
||||
xsprintf(str, "OUI:%02X%02X%02X%02X%02X%02X", names->mac[0],
|
||||
names->mac[1], names->mac[2], names->mac[3], names->mac[4],
|
||||
names->mac[5]);
|
||||
udev_builtin_hwdb_lookup(dev, NULL, str, NULL, test);
|
||||
return 0;
|
||||
|
||||
xsprintf(str, "OUI:%02X%02X%02X%02X%02X%02X",
|
||||
info->hw_addr.bytes[0],
|
||||
info->hw_addr.bytes[1],
|
||||
info->hw_addr.bytes[2],
|
||||
info->hw_addr.bytes[3],
|
||||
info->hw_addr.bytes[4],
|
||||
info->hw_addr.bytes[5]);
|
||||
return udev_builtin_hwdb_lookup(dev, NULL, str, NULL, test);
|
||||
}
|
||||
|
||||
static int builtin_net_id(sd_device *dev, int argc, char *argv[], bool test) {
|
||||
const char *s, *p, *devtype, *prefix = "en";
|
||||
struct netnames names = {};
|
||||
unsigned long i;
|
||||
int r;
|
||||
static int builtin_net_id(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) {
|
||||
_cleanup_(link_info_clear) LinkInfo info = LINK_INFO_NULL;
|
||||
const char *devtype, *prefix = "en";
|
||||
NetNames names = {};
|
||||
int ifindex, r;
|
||||
|
||||
r = sd_device_get_ifindex(dev, &ifindex);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = link_info_get(rtnl, ifindex, &info);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!info.support_phys_port_name) {
|
||||
const char *s;
|
||||
|
||||
r = sd_device_get_sysattr_value(dev, "phys_port_name", &s);
|
||||
if (r >= 0) {
|
||||
info.phys_port_name = strdup(s);
|
||||
if (!info.phys_port_name)
|
||||
return log_oom();
|
||||
}
|
||||
}
|
||||
|
||||
/* skip stacked devices, like VLANs, ... */
|
||||
if (info.ifindex != (int) info.iflink)
|
||||
return 0;
|
||||
|
||||
/* handle only ARPHRD_ETHER, ARPHRD_SLIP and ARPHRD_INFINIBAND devices */
|
||||
r = sd_device_get_sysattr_value(dev, "type", &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = safe_atolu_full(s, 10, &i);
|
||||
if (r < 0)
|
||||
return r;
|
||||
switch (i) {
|
||||
switch (info.iftype) {
|
||||
case ARPHRD_ETHER:
|
||||
prefix = "en";
|
||||
break;
|
||||
@ -899,16 +892,6 @@ static int builtin_net_id(sd_device *dev, int argc, char *argv[], bool test) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* skip stacked devices, like VLANs, ... */
|
||||
r = sd_device_get_sysattr_value(dev, "ifindex", &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = sd_device_get_sysattr_value(dev, "iflink", &p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (!streq(s, p))
|
||||
return 0;
|
||||
|
||||
if (sd_device_get_devtype(dev, &devtype) >= 0) {
|
||||
if (streq("wlan", devtype))
|
||||
prefix = "wl";
|
||||
@ -918,16 +901,13 @@ static int builtin_net_id(sd_device *dev, int argc, char *argv[], bool test) {
|
||||
|
||||
udev_builtin_add_property(dev, test, "ID_NET_NAMING_SCHEME", naming_scheme()->name);
|
||||
|
||||
r = names_mac(dev, &names);
|
||||
if (r >= 0 && names.mac_valid) {
|
||||
if (names_mac(dev, &info) >= 0) {
|
||||
char str[ALTIFNAMSIZ];
|
||||
|
||||
xsprintf(str, "%sx%02x%02x%02x%02x%02x%02x", prefix,
|
||||
names.mac[0], names.mac[1], names.mac[2],
|
||||
names.mac[3], names.mac[4], names.mac[5]);
|
||||
xsprintf(str, "%s%s", prefix, HW_ADDR_TO_STR(&info.hw_addr));
|
||||
udev_builtin_add_property(dev, test, "ID_NET_NAME_MAC", str);
|
||||
|
||||
ieee_oui(dev, &names, test);
|
||||
ieee_oui(dev, &info, test);
|
||||
}
|
||||
|
||||
/* get path names for Linux on System z network devices */
|
||||
@ -958,7 +938,7 @@ static int builtin_net_id(sd_device *dev, int argc, char *argv[], bool test) {
|
||||
}
|
||||
|
||||
/* get netdevsim path names */
|
||||
if (names_netdevsim(dev, &names) >= 0 && names.type == NET_NETDEVSIM) {
|
||||
if (names_netdevsim(dev, &info, &names) >= 0 && names.type == NET_NETDEVSIM) {
|
||||
char str[ALTIFNAMSIZ];
|
||||
|
||||
if (snprintf_ok(str, sizeof str, "%s%s", prefix, names.netdevsim_path))
|
||||
@ -968,7 +948,7 @@ static int builtin_net_id(sd_device *dev, int argc, char *argv[], bool test) {
|
||||
}
|
||||
|
||||
/* get PCI based path names, we compose only PCI based paths */
|
||||
if (names_pci(dev, &names) < 0)
|
||||
if (names_pci(dev, &info, &names) < 0)
|
||||
return 0;
|
||||
|
||||
/* plain PCI device */
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
static LinkConfigContext *ctx = NULL;
|
||||
|
||||
static int builtin_net_setup_link(sd_device *dev, int argc, char **argv, bool test) {
|
||||
static int builtin_net_setup_link(sd_device *dev, sd_netlink **rtnl, int argc, char **argv, bool test) {
|
||||
_cleanup_free_ char *driver = NULL;
|
||||
const char *name = NULL;
|
||||
LinkConfig *link;
|
||||
@ -26,7 +26,7 @@ static int builtin_net_setup_link(sd_device *dev, int argc, char **argv, bool te
|
||||
else
|
||||
udev_builtin_add_property(dev, test, "ID_NET_DRIVER", driver);
|
||||
|
||||
r = link_config_get(ctx, dev, &link);
|
||||
r = link_config_get(ctx, rtnl, dev, &link);
|
||||
if (r < 0) {
|
||||
if (r == -ENODEV)
|
||||
return log_device_debug_errno(dev, r, "Link vanished while searching for configuration for it.");
|
||||
@ -38,7 +38,7 @@ static int builtin_net_setup_link(sd_device *dev, int argc, char **argv, bool te
|
||||
return log_device_error_errno(dev, r, "Failed to get link config: %m");
|
||||
}
|
||||
|
||||
r = link_config_apply(ctx, link, dev, &name);
|
||||
r = link_config_apply(ctx, link, rtnl, dev, &name);
|
||||
if (r == -ENODEV)
|
||||
log_device_debug_errno(dev, r, "Link vanished while applying configuration, ignoring.");
|
||||
else if (r < 0)
|
||||
|
@ -530,7 +530,7 @@ static sd_device *handle_ap(sd_device *parent, char **path) {
|
||||
return skip_subsystem(parent, "ap");
|
||||
}
|
||||
|
||||
static int builtin_path_id(sd_device *dev, int argc, char *argv[], bool test) {
|
||||
static int builtin_path_id(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) {
|
||||
sd_device *parent;
|
||||
_cleanup_free_ char *path = NULL;
|
||||
_cleanup_free_ char *compat_path = NULL;
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "log.h"
|
||||
#include "udev-builtin.h"
|
||||
|
||||
static int builtin_uaccess(sd_device *dev, int argc, char *argv[], bool test) {
|
||||
static int builtin_uaccess(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) {
|
||||
const char *path = NULL, *seat;
|
||||
bool changed_acl = false;
|
||||
uid_t uid;
|
||||
|
@ -224,7 +224,7 @@ static int dev_if_packed_info(sd_device *dev, char *ifs_str, size_t len) {
|
||||
* 6.) If the device supplies a serial number, this number
|
||||
* is concatenated with the identification with an underscore '_'.
|
||||
*/
|
||||
static int builtin_usb_id(sd_device *dev, int argc, char *argv[], bool test) {
|
||||
static int builtin_usb_id(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) {
|
||||
char vendor_str[64] = "";
|
||||
char vendor_str_enc[256];
|
||||
const char *vendor_id;
|
||||
|
@ -107,7 +107,7 @@ UdevBuiltinCommand udev_builtin_lookup(const char *command) {
|
||||
return _UDEV_BUILTIN_INVALID;
|
||||
}
|
||||
|
||||
int udev_builtin_run(sd_device *dev, UdevBuiltinCommand cmd, const char *command, bool test) {
|
||||
int udev_builtin_run(sd_device *dev, sd_netlink **rtnl, UdevBuiltinCommand cmd, const char *command, bool test) {
|
||||
_cleanup_strv_free_ char **argv = NULL;
|
||||
int r;
|
||||
|
||||
@ -124,7 +124,7 @@ int udev_builtin_run(sd_device *dev, UdevBuiltinCommand cmd, const char *command
|
||||
|
||||
/* we need '0' here to reset the internal state */
|
||||
optind = 0;
|
||||
return builtins[cmd]->cmd(dev, strv_length(argv), argv, test);
|
||||
return builtins[cmd]->cmd(dev, rtnl, strv_length(argv), argv, test);
|
||||
}
|
||||
|
||||
int udev_builtin_add_property(sd_device *dev, bool test, const char *key, const char *val) {
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "sd-device.h"
|
||||
#include "sd-netlink.h"
|
||||
|
||||
typedef enum {
|
||||
#if HAVE_BLKID
|
||||
@ -29,7 +30,7 @@ typedef enum {
|
||||
|
||||
typedef struct UdevBuiltin {
|
||||
const char *name;
|
||||
int (*cmd)(sd_device *dev, int argc, char *argv[], bool test);
|
||||
int (*cmd)(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test);
|
||||
const char *help;
|
||||
int (*init)(void);
|
||||
void (*exit)(void);
|
||||
@ -73,7 +74,7 @@ void udev_builtin_exit(void);
|
||||
UdevBuiltinCommand udev_builtin_lookup(const char *command);
|
||||
const char *udev_builtin_name(UdevBuiltinCommand cmd);
|
||||
bool udev_builtin_run_once(UdevBuiltinCommand cmd);
|
||||
int udev_builtin_run(sd_device *dev, UdevBuiltinCommand cmd, const char *command, bool test);
|
||||
int udev_builtin_run(sd_device *dev, sd_netlink **rtnl, UdevBuiltinCommand cmd, const char *command, bool test);
|
||||
void udev_builtin_list(void);
|
||||
bool udev_builtin_validate(void);
|
||||
int udev_builtin_add_property(sd_device *dev, bool test, const char *key, const char *val);
|
||||
|
@ -1073,7 +1073,7 @@ void udev_event_execute_run(UdevEvent *event, usec_t timeout_usec, int timeout_s
|
||||
|
||||
if (builtin_cmd != _UDEV_BUILTIN_INVALID) {
|
||||
log_device_debug(event->dev, "Running built-in command \"%s\"", command);
|
||||
r = udev_builtin_run(event->dev, builtin_cmd, command, false);
|
||||
r = udev_builtin_run(event->dev, &event->rtnl, builtin_cmd, command, false);
|
||||
if (r < 0)
|
||||
log_device_debug_errno(event->dev, r, "Failed to run built-in command \"%s\", ignoring: %m", command);
|
||||
} else {
|
||||
|
@ -1829,7 +1829,7 @@ static int udev_rule_apply_token_to_event(
|
||||
(void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false);
|
||||
log_rule_debug(dev, rules, "Importing properties from results of builtin command '%s'", buf);
|
||||
|
||||
r = udev_builtin_run(dev, cmd, buf, false);
|
||||
r = udev_builtin_run(dev, &event->rtnl, cmd, buf, false);
|
||||
if (r < 0) {
|
||||
/* remember failure */
|
||||
log_rule_debug_errno(dev, rules, r, "Failed to run builtin '%s': %m", buf);
|
||||
|
@ -72,6 +72,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
int builtin_main(int argc, char *argv[], void *userdata) {
|
||||
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||
_cleanup_(sd_device_unrefp) sd_device *dev = NULL;
|
||||
UdevBuiltinCommand cmd;
|
||||
int r;
|
||||
@ -97,7 +98,7 @@ int builtin_main(int argc, char *argv[], void *userdata) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
r = udev_builtin_run(dev, cmd, arg_command, true);
|
||||
r = udev_builtin_run(dev, &rtnl, cmd, arg_command, true);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Builtin command '%s' fails: %m", arg_command);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user