]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/netdev/macvlan.c
Merge pull request #33352 from YHNdnzj/freeconp-void
[thirdparty/systemd.git] / src / network / netdev / macvlan.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
0372cb2b 2
edda10f2 3/* Make sure the net/if.h header is included before any linux/ one */
0372cb2b 4#include <net/if.h>
9f0cf80d
YW
5#include <netinet/in.h>
6#include <linux/if_arp.h>
0372cb2b 7
0372cb2b 8#include "conf-parser.h"
737f1405 9#include "macvlan.h"
d5167480 10#include "macvlan-util.h"
17a6a4ae 11#include "networkd-network.h"
dca0a4e1 12#include "parse-util.h"
0372cb2b 13
9adafedd
SS
14typedef enum BCQueueThreshold {
15 BC_QUEUE_THRESHOLD_UNDEF = INT32_MIN,
16 BC_QUEUE_THRESHOLD_DISABLE = -1,
17} BCQueueThreshold;
18
0372cb2b
TG
19DEFINE_CONFIG_PARSE_ENUM(config_parse_macvlan_mode, macvlan_mode, MacVlanMode, "Failed to parse macvlan mode");
20
1c4baffc 21static int netdev_macvlan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *req) {
0372cb2b 22 assert(netdev);
0372cb2b 23 assert(netdev->ifname);
117843fe 24 assert(link);
17a6a4ae 25 assert(link->network);
0372cb2b 26
117843fe
ZJS
27 MacVlan *m = netdev->kind == NETDEV_KIND_MACVLAN ? MACVLAN(netdev) : MACVTAP(netdev);
28 int r;
f33ff02b 29
0d0de133 30 if (m->mode == NETDEV_MACVLAN_MODE_SOURCE && !set_isempty(m->match_source_mac)) {
0d0de133
31 const struct ether_addr *mac_addr;
32
33 r = sd_netlink_message_append_u32(req, IFLA_MACVLAN_MACADDR_MODE, MACVLAN_MACADDR_SET);
34 if (r < 0)
5b80ecea 35 return r;
0d0de133
36
37 r = sd_netlink_message_open_container(req, IFLA_MACVLAN_MACADDR_DATA);
38 if (r < 0)
5b80ecea 39 return r;
0d0de133 40
90e74a66 41 SET_FOREACH(mac_addr, m->match_source_mac) {
0d0de133
42 r = sd_netlink_message_append_ether_addr(req, IFLA_MACVLAN_MACADDR, mac_addr);
43 if (r < 0)
5b80ecea 44 return r;
0d0de133
45 }
46
47 r = sd_netlink_message_close_container(req);
48 if (r < 0)
5b80ecea 49 return r;
0d0de133
50 }
51
aa9f1140 52 if (m->mode != _NETDEV_MACVLAN_MODE_INVALID) {
1c4baffc 53 r = sd_netlink_message_append_u32(req, IFLA_MACVLAN_MODE, m->mode);
c8a09ef4 54 if (r < 0)
5b80ecea 55 return r;
0372cb2b
TG
56 }
57
17a6a4ae
TY
58 /* set the nopromisc flag if Promiscuous= of the link is explicitly set to false */
59 if (m->mode == NETDEV_MACVLAN_MODE_PASSTHRU && link->network->promiscuous == 0) {
60 r = sd_netlink_message_append_u16(req, IFLA_MACVLAN_FLAGS, MACVLAN_FLAG_NOPROMISC);
61 if (r < 0)
5b80ecea 62 return r;
17a6a4ae
TY
63 }
64
dca0a4e1
SS
65 if (m->bc_queue_length != UINT32_MAX) {
66 r = sd_netlink_message_append_u32(req, IFLA_MACVLAN_BC_QUEUE_LEN, m->bc_queue_length);
67 if (r < 0)
5b80ecea 68 return r;
dca0a4e1
SS
69 }
70
9adafedd
SS
71 if (m->bc_queue_threshold != BC_QUEUE_THRESHOLD_UNDEF) {
72 r = sd_netlink_message_append_s32(req, IFLA_MACVLAN_BC_CUTOFF, m->bc_queue_threshold);
73 if (r < 0)
74 return r;
75 }
76
dca0a4e1
SS
77 return 0;
78}
79
80int config_parse_macvlan_broadcast_queue_size(
81 const char *unit,
82 const char *filename,
83 unsigned line,
84 const char *section,
85 unsigned section_line,
86 const char *lvalue,
87 int ltype,
88 const char *rvalue,
89 void *data,
90 void *userdata) {
91
dca0a4e1
SS
92 assert(filename);
93 assert(section);
94 assert(lvalue);
95 assert(rvalue);
96 assert(data);
dca0a4e1 97
851cdffd
ZJS
98 MacVlan *m = ASSERT_PTR(userdata);
99
dca0a4e1
SS
100 if (isempty(rvalue)) {
101 m->bc_queue_length = UINT32_MAX;
102 return 0;
103 }
104
851cdffd
ZJS
105 return config_parse_uint32_bounded(
106 unit, filename, line, section, section_line, lvalue, rvalue,
107 0, UINT32_MAX - 1, true,
108 &m->bc_queue_length);
aa9f1140 109}
0372cb2b 110
9adafedd
SS
111int config_parse_macvlan_broadcast_queue_threshold(
112 const char *unit,
113 const char *filename,
114 unsigned line,
115 const char *section,
116 unsigned section_line,
117 const char *lvalue,
118 int ltype,
119 const char *rvalue,
120 void *data,
121 void *userdata) {
122
123 assert(filename);
124 assert(lvalue);
125 assert(rvalue);
126
127 int32_t v, *threshold = ASSERT_PTR(data);
128 int r;
129
130 if (isempty(rvalue)) {
131 *threshold = BC_QUEUE_THRESHOLD_UNDEF;
132 return 0;
133 }
134
135 if (streq(rvalue, "no")) {
136 *threshold = BC_QUEUE_THRESHOLD_DISABLE;
137 return 0;
138 }
139
140 r = safe_atoi32(rvalue, &v);
141 if (r < 0) {
142 log_syntax(unit, LOG_WARNING, filename, line, r,
143 "Failed to parse %s=, ignoring assignment: %s",
144 lvalue, rvalue);
145 return 0;
146 }
147 if (v < 0) {
148 log_syntax(unit, LOG_WARNING, filename, line, 0,
149 "Invalid %s= value specified, ignoring assignment: %s",
150 lvalue, rvalue);
151 return 0;
152 }
153
154 *threshold = v;
155 return 0;
156}
157
117843fe
ZJS
158static void macvlan_done(NetDev *netdev) {
159 MacVlan *m = ASSERT_PTR(netdev)->kind == NETDEV_KIND_MACVLAN ? MACVLAN(netdev) : MACVTAP(netdev);
0d0de133 160
c6df73ca 161 set_free(m->match_source_mac);
0d0de133
162}
163
117843fe
ZJS
164static void macvlan_init(NetDev *netdev) {
165 MacVlan *m = ASSERT_PTR(netdev)->kind == NETDEV_KIND_MACVLAN ? MACVLAN(netdev) : MACVTAP(netdev);
aa9f1140
TG
166
167 m->mode = _NETDEV_MACVLAN_MODE_INVALID;
dca0a4e1 168 m->bc_queue_length = UINT32_MAX;
9adafedd 169 m->bc_queue_threshold = BC_QUEUE_THRESHOLD_UNDEF;
0372cb2b 170}
3be1d7e0 171
f33ff02b
SS
172const NetDevVTable macvtap_vtable = {
173 .object_size = sizeof(MacVlan),
174 .init = macvlan_init,
0d0de133 175 .done = macvlan_done,
130b812f 176 .sections = NETDEV_COMMON_SECTIONS "MACVTAP\0",
f33ff02b
SS
177 .fill_message_create = netdev_macvlan_fill_message_create,
178 .create_type = NETDEV_CREATE_STACKED,
9f0cf80d 179 .iftype = ARPHRD_ETHER,
daf0f8ca 180 .generate_mac = true,
f33ff02b
SS
181};
182
3be1d7e0 183const NetDevVTable macvlan_vtable = {
aa9f1140
TG
184 .object_size = sizeof(MacVlan),
185 .init = macvlan_init,
0d0de133 186 .done = macvlan_done,
130b812f 187 .sections = NETDEV_COMMON_SECTIONS "MACVLAN\0",
aa9f1140
TG
188 .fill_message_create = netdev_macvlan_fill_message_create,
189 .create_type = NETDEV_CREATE_STACKED,
9f0cf80d 190 .iftype = ARPHRD_ETHER,
daf0f8ca 191 .generate_mac = true,
3be1d7e0 192};