]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/netdev/vxcan.c
NEWS: fix typos and remove backticks
[thirdparty/systemd.git] / src / network / netdev / vxcan.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
d6df583c 2
9714c020 3#include <linux/can/vxcan.h>
9f0cf80d 4#include <linux/if_arp.h>
9714c020 5
737f1405 6#include "vxcan.h"
d6df583c
SS
7
8static int netdev_vxcan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
d6df583c
SS
9 assert(!link);
10 assert(m);
11
117843fe
ZJS
12 VxCan *v = VXCAN(netdev);
13 int r;
d6df583c
SS
14
15 r = sd_netlink_message_open_container(m, VXCAN_INFO_PEER);
16 if (r < 0)
5b80ecea 17 return r;
d6df583c
SS
18
19 if (v->ifname_peer) {
20 r = sd_netlink_message_append_string(m, IFLA_IFNAME, v->ifname_peer);
21 if (r < 0)
5b80ecea 22 return r;
d6df583c
SS
23 }
24
25 r = sd_netlink_message_close_container(m);
26 if (r < 0)
5b80ecea 27 return r;
d6df583c 28
5b80ecea 29 return 0;
d6df583c
SS
30}
31
32static int netdev_vxcan_verify(NetDev *netdev, const char *filename) {
d6df583c
SS
33 assert(filename);
34
117843fe 35 VxCan *v = VXCAN(netdev);
d6df583c 36
d15cba96
ZJS
37 if (!v->ifname_peer)
38 return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
39 "VxCan NetDev without peer name configured in %s. Ignoring", filename);
d6df583c 40
971c0ce8
YW
41 if (streq(v->ifname_peer, netdev->ifname))
42 return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
43 "VxCan peer name cannot be the same as the main interface name.");
44
d6df583c
SS
45 return 0;
46}
47
d0899c6a
YW
48static int netdev_vxcan_attach(NetDev *netdev) {
49 VxCan *v = VXCAN(netdev);
50 assert(v->ifname_peer);
51
52 return netdev_attach_name(netdev, v->ifname_peer);
53}
54
55static void netdev_vxcan_detach(NetDev *netdev) {
56 VxCan *v = VXCAN(netdev);
57
58 netdev_detach_name(netdev, v->ifname_peer);
59}
60
61static int netdev_vxcan_set_ifindex(NetDev *netdev, const char *name, int ifindex) {
62 VxCan *v = VXCAN(netdev);
63 int r;
64
65 assert(name);
66 assert(ifindex > 0);
67
68 if (streq(netdev->ifname, name)) {
69 r = netdev_set_ifindex_internal(netdev, ifindex);
70 if (r <= 0)
71 return r;
72
73 } else if (streq(v->ifname_peer, name)) {
74 if (v->ifindex_peer == ifindex)
75 return 0; /* already set */
76 if (v->ifindex_peer > 0 && v->ifindex_peer != ifindex)
77 return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EEXIST),
78 "Could not set ifindex %i for peer %s, already set to %i.",
79 ifindex, v->ifname_peer, v->ifindex_peer);
80
81 v->ifindex_peer = ifindex;
82 log_netdev_debug(netdev, "Peer interface %s gained index %i.", v->ifname_peer, ifindex);
83
84 } else
85 return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
86 "Received netlink message with unexpected interface name %s (ifindex=%i).",
87 name, ifindex);
88
89 if (netdev->ifindex > 0 && v->ifindex_peer > 0)
90 return netdev_enter_ready(netdev);
91
92 return 0;
93}
94
95static int netdev_vxcan_get_ifindex(NetDev *netdev, const char *name) {
96 VxCan *v = VXCAN(netdev);
97
98 assert(name);
99
100 if (streq(netdev->ifname, name))
101 return netdev->ifindex;
102
103 if (streq(v->ifname_peer, name))
104 return v->ifindex_peer;
105
106 return -ENODEV;
107}
108
117843fe
ZJS
109static void vxcan_done(NetDev *netdev) {
110 VxCan *v = VXCAN(netdev);
d6df583c
SS
111
112 free(v->ifname_peer);
113}
114
115const NetDevVTable vxcan_vtable = {
116 .object_size = sizeof(VxCan),
130b812f 117 .sections = NETDEV_COMMON_SECTIONS "VXCAN\0",
d6df583c
SS
118 .done = vxcan_done,
119 .fill_message_create = netdev_vxcan_fill_message_create,
120 .create_type = NETDEV_CREATE_INDEPENDENT,
121 .config_verify = netdev_vxcan_verify,
d0899c6a
YW
122 .attach = netdev_vxcan_attach,
123 .detach = netdev_vxcan_detach,
124 .set_ifindex = netdev_vxcan_set_ifindex,
125 .get_ifindex = netdev_vxcan_get_ifindex,
9f0cf80d 126 .iftype = ARPHRD_CAN,
d6df583c 127};