]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
10142d75 | 2 | |
dccca82b | 3 | #include <errno.h> |
dccca82b | 4 | #include <net/if.h> |
9aa5d8ba | 5 | #include <linux/veth.h> |
10142d75 | 6 | |
737f1405 | 7 | #include "veth.h" |
10142d75 | 8 | |
1c4baffc | 9 | static int netdev_veth_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) { |
cd946b9c | 10 | Veth *v; |
10142d75 SS |
11 | int r; |
12 | ||
13 | assert(netdev); | |
aa9f1140 | 14 | assert(!link); |
10142d75 SS |
15 | assert(m); |
16 | ||
cd946b9c SS |
17 | v = VETH(netdev); |
18 | ||
19 | assert(v); | |
20 | ||
1c4baffc | 21 | r = sd_netlink_message_open_container(m, VETH_INFO_PEER); |
7676666c SS |
22 | if (r < 0) |
23 | return log_netdev_error_errno(netdev, r, "Could not append VETH_INFO_PEER attribute: %m"); | |
10142d75 | 24 | |
aa9f1140 | 25 | if (v->ifname_peer) { |
1c4baffc | 26 | r = sd_netlink_message_append_string(m, IFLA_IFNAME, v->ifname_peer); |
f647962d | 27 | if (r < 0) |
98b02994 | 28 | return log_netdev_error_errno(netdev, r, "Failed to add netlink interface name: %m"); |
10142d75 SS |
29 | } |
30 | ||
aa9f1140 | 31 | if (v->mac_peer) { |
1c4baffc | 32 | r = sd_netlink_message_append_ether_addr(m, IFLA_ADDRESS, v->mac_peer); |
7676666c SS |
33 | if (r < 0) |
34 | return log_netdev_error_errno(netdev, r, "Could not append IFLA_ADDRESS attribute: %m"); | |
96c90742 TG |
35 | } |
36 | ||
1c4baffc | 37 | r = sd_netlink_message_close_container(m); |
7676666c SS |
38 | if (r < 0) |
39 | return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m"); | |
10142d75 | 40 | |
10142d75 SS |
41 | return r; |
42 | } | |
43 | ||
3be1d7e0 | 44 | static int netdev_veth_verify(NetDev *netdev, const char *filename) { |
cd946b9c | 45 | Veth *v; |
10142d75 SS |
46 | int r; |
47 | ||
48 | assert(netdev); | |
3be1d7e0 | 49 | assert(filename); |
10142d75 | 50 | |
cd946b9c SS |
51 | v = VETH(netdev); |
52 | ||
53 | assert(v); | |
54 | ||
aa9f1140 | 55 | if (!v->ifname_peer) { |
98b02994 YW |
56 | log_netdev_warning(netdev, "Veth NetDev without peer name configured in %s. Ignoring", |
57 | filename); | |
3be1d7e0 | 58 | return -EINVAL; |
10142d75 SS |
59 | } |
60 | ||
aa9f1140 TG |
61 | if (!v->mac_peer) { |
62 | r = netdev_get_mac(v->ifname_peer, &v->mac_peer); | |
3be1d7e0 | 63 | if (r < 0) { |
98b02994 YW |
64 | log_netdev_warning(netdev, |
65 | "Failed to generate predictable MAC address for %s. Ignoring", | |
66 | v->ifname_peer); | |
3be1d7e0 TG |
67 | return -EINVAL; |
68 | } | |
10142d75 SS |
69 | } |
70 | ||
10142d75 SS |
71 | return 0; |
72 | } | |
3be1d7e0 | 73 | |
aa9f1140 | 74 | static void veth_done(NetDev *n) { |
cd946b9c | 75 | Veth *v; |
aa9f1140 TG |
76 | |
77 | assert(n); | |
cd946b9c SS |
78 | |
79 | v = VETH(n); | |
80 | ||
aa9f1140 TG |
81 | assert(v); |
82 | ||
83 | free(v->ifname_peer); | |
84 | free(v->mac_peer); | |
85 | } | |
86 | ||
3be1d7e0 | 87 | const NetDevVTable veth_vtable = { |
aa9f1140 | 88 | .object_size = sizeof(Veth), |
130b812f | 89 | .sections = NETDEV_COMMON_SECTIONS "Peer\0", |
aa9f1140 | 90 | .done = veth_done, |
3be1d7e0 | 91 | .fill_message_create = netdev_veth_fill_message_create, |
aa9f1140 | 92 | .create_type = NETDEV_CREATE_INDEPENDENT, |
3be1d7e0 | 93 | .config_verify = netdev_veth_verify, |
daf0f8ca | 94 | .generate_mac = true, |
3be1d7e0 | 95 | }; |