]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/netdev/bareudp.c
license: LGPL-2.1+ -> LGPL-2.1-or-later
[thirdparty/systemd.git] / src / network / netdev / bareudp.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later
2 * Copyright © 2020 VMware, Inc. */
3
4 #include "bareudp.h"
5 #include "netlink-util.h"
6 #include "networkd-manager.h"
7 #include "string-table.h"
8
9 static const char* const bare_udp_protocol_table[_BARE_UDP_PROTOCOL_MAX] = {
10 [BARE_UDP_PROTOCOL_IPV4] = "ipv4",
11 [BARE_UDP_PROTOCOL_IPV6] = "ipv6",
12 [BARE_UDP_PROTOCOL_MPLS_UC] = "mpls-uc",
13 [BARE_UDP_PROTOCOL_MPLS_MC] = "mpls-mc",
14 };
15
16 DEFINE_STRING_TABLE_LOOKUP(bare_udp_protocol, BareUDPProtocol);
17 DEFINE_CONFIG_PARSE_ENUM(config_parse_bare_udp_iftype, bare_udp_protocol, BareUDPProtocol,
18 "Failed to parse EtherType=");
19
20 /* callback for bareudp netdev's created without a backing Link */
21 static int bare_udp_netdev_create_handler(sd_netlink *rtnl, sd_netlink_message *m, NetDev *netdev) {
22 int r;
23
24 assert(netdev);
25 assert(netdev->state != _NETDEV_STATE_INVALID);
26
27 r = sd_netlink_message_get_errno(m);
28 if (r == -EEXIST)
29 log_netdev_info(netdev, "BareUDP netdev exists, using existing without changing its parameters.");
30 else if (r < 0) {
31 log_netdev_warning_errno(netdev, r, "BareUDP netdev could not be created: %m");
32 netdev_drop(netdev);
33
34 return 1;
35 }
36
37 log_netdev_debug(netdev, "BareUDP created.");
38
39 return 1;
40 }
41
42 static int netdev_bare_udp_create(NetDev *netdev) {
43 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
44 BareUDP *u;
45 int r;
46
47 assert(netdev);
48
49 u = BAREUDP(netdev);
50
51 assert(u);
52
53 r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
54 if (r < 0)
55 return log_netdev_error_errno(netdev, r, "Could not allocate RTM_NEWLINK message: %m");
56
57 r = sd_netlink_message_append_string(m, IFLA_IFNAME, netdev->ifname);
58 if (r < 0)
59 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IFNAME, attribute: %m");
60
61 r = sd_netlink_message_open_container(m, IFLA_LINKINFO);
62 if (r < 0)
63 return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m");
64
65 r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, netdev_kind_to_string(netdev->kind));
66 if (r < 0)
67 return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m");
68
69 r = sd_netlink_message_append_u16(m, IFLA_BAREUDP_ETHERTYPE, htobe16(u->iftype));
70 if (r < 0)
71 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BAREUDP_ETHERTYPE attribute: %m");
72
73 r = sd_netlink_message_append_u16(m, IFLA_BAREUDP_PORT, htobe16(u->dest_port));
74 if (r < 0)
75 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BAREUDP_PORT attribute: %m");
76
77 r = sd_netlink_message_close_container(m);
78 if (r < 0)
79 return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m");
80
81 r = sd_netlink_message_close_container(m);
82 if (r < 0)
83 return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m");
84
85 r = netlink_call_async(netdev->manager->rtnl, NULL, m, bare_udp_netdev_create_handler,
86 netdev_destroy_callback, netdev);
87 if (r < 0)
88 return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m");
89
90 netdev_ref(netdev);
91 netdev->state = NETDEV_STATE_CREATING;
92
93 log_netdev_debug(netdev, "Creating");
94
95 return r;
96 }
97
98 static int netdev_bare_udp_verify(NetDev *netdev, const char *filename) {
99 BareUDP *u;
100
101 assert(netdev);
102 assert(filename);
103
104 u = BAREUDP(netdev);
105
106 assert(u);
107
108 if (u->dest_port == 0)
109 return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
110 "%s: BareUDP DesinationPort= is not set. Ignoring.", filename);
111
112 if (u->iftype == _BARE_UDP_PROTOCOL_INVALID)
113 return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
114 "%s: BareUDP EtherType= is not set. Ignoring.", filename);
115
116 return 0;
117 }
118
119 static void bare_udp_init(NetDev *netdev) {
120 BareUDP *u;
121
122 assert(netdev);
123
124 u = BAREUDP(netdev);
125
126 assert(u);
127
128 u->iftype = _BARE_UDP_PROTOCOL_INVALID;
129 }
130
131 const NetDevVTable bare_udp_vtable = {
132 .object_size = sizeof(BareUDP),
133 .sections = NETDEV_COMMON_SECTIONS "BareUDP\0",
134 .init = bare_udp_init,
135 .config_verify = netdev_bare_udp_verify,
136 .create = netdev_bare_udp_create,
137 .create_type = NETDEV_CREATE_INDEPENDENT,
138 };