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