25 #include <netlink-private/netlink.h>
26 #include <netlink/netlink.h>
27 #include <netlink/attr.h>
28 #include <netlink/utils.h>
29 #include <netlink/object.h>
30 #include <netlink/route/rtnl.h>
31 #include <netlink-private/route/link/api.h>
32 #include <netlink/route/link/macvlan.h>
34 #include <linux/if_link.h>
37 #define MACVLAN_HAS_MODE (1<<0)
38 #define MACVLAN_HAS_FLAGS (1<<1)
49 static struct nla_policy macvlan_policy[IFLA_MACVLAN_MAX+1] = {
51 [IFLA_MACVLAN_FLAGS] = { .type =
NLA_U16 },
54 static int macvlan_alloc(
struct rtnl_link *link)
56 struct macvlan_info *mvi;
58 if ((mvi = calloc(1,
sizeof(*mvi))) == NULL)
66 static int macvlan_parse(
struct rtnl_link *link,
struct nlattr *data,
67 struct nlattr *xstats)
69 struct nlattr *tb[IFLA_MACVLAN_MAX+1];
70 struct macvlan_info *mvi;
73 NL_DBG(3,
"Parsing MACVLAN link info");
75 if ((err =
nla_parse_nested(tb, IFLA_MACVLAN_MAX, data, macvlan_policy)) < 0)
78 if ((err = macvlan_alloc(link)) < 0)
83 if (tb[IFLA_MACVLAN_MODE]) {
85 mvi->mvi_mask |= MACVLAN_HAS_MODE;
88 if (tb[IFLA_MACVLAN_FLAGS]) {
89 mvi->mvi_mode =
nla_get_u16(tb[IFLA_MACVLAN_FLAGS]);
90 mvi->mvi_mask |= MACVLAN_HAS_FLAGS;
98 static void macvlan_free(
struct rtnl_link *link)
107 struct macvlan_info *mvi = link->l_info;
109 if (mvi->mvi_mask & MACVLAN_HAS_MODE) {
110 rtnl_link_macvlan_mode2str(mvi->mvi_mode, buf,
sizeof(buf));
111 nl_dump(p,
"macvlan-mode %s", buf);
114 if (mvi->mvi_mask & MACVLAN_HAS_FLAGS) {
115 rtnl_link_macvlan_flags2str(mvi->mvi_flags, buf,
sizeof(buf));
116 nl_dump(p,
"macvlan-flags %s", buf);
122 struct macvlan_info *vdst, *vsrc = src->l_info;
133 memcpy(vdst, vsrc,
sizeof(
struct macvlan_info));
138 static int macvlan_put_attrs(
struct nl_msg *msg,
struct rtnl_link *link)
140 struct macvlan_info *mvi = link->l_info;
146 if (mvi->mvi_mask & MACVLAN_HAS_MODE)
147 NLA_PUT_U32(msg, IFLA_MACVLAN_MODE, mvi->mvi_mode);
149 if (mvi->mvi_mask & MACVLAN_HAS_FLAGS)
150 NLA_PUT_U16(msg, IFLA_MACVLAN_FLAGS, mvi->mvi_flags);
159 static struct rtnl_link_info_ops macvlan_info_ops = {
160 .io_name =
"macvlan",
161 .io_alloc = macvlan_alloc,
162 .io_parse = macvlan_parse,
167 .io_clone = macvlan_clone,
168 .io_put_attrs = macvlan_put_attrs,
169 .io_free = macvlan_free,
173 #define IS_MACVLAN_LINK_ASSERT(link) \
174 if ((link)->l_info_ops != &macvlan_info_ops) { \
175 APPBUG("Link is not a macvlan link. set type \"macvlan\" first."); \
176 return -NLE_OPNOTSUPP; \
214 return link->l_info_ops && !strcmp(link->l_info_ops->io_name,
"macvlan");
226 struct macvlan_info *mvi = link->l_info;
228 IS_MACVLAN_LINK_ASSERT(link);
230 mvi->mvi_mode = mode;
231 mvi->mvi_mask |= MACVLAN_HAS_MODE;
244 struct macvlan_info *mvi = link->l_info;
246 IS_MACVLAN_LINK_ASSERT(link);
248 if (mvi->mvi_mask & MACVLAN_HAS_MODE)
249 return mvi->mvi_mode;
263 struct macvlan_info *mvi = link->l_info;
265 IS_MACVLAN_LINK_ASSERT(link);
267 mvi->mvi_flags |= flags;
268 mvi->mvi_mask |= MACVLAN_HAS_FLAGS;
285 struct macvlan_info *mvi = link->l_info;
287 IS_MACVLAN_LINK_ASSERT(link);
289 mvi->mvi_flags &= ~flags;
290 mvi->mvi_mask |= MACVLAN_HAS_FLAGS;
303 struct macvlan_info *mvi = link->l_info;
305 IS_MACVLAN_LINK_ASSERT(link);
307 return mvi->mvi_flags;
312 static const struct trans_tbl macvlan_flags[] = {
313 __ADD(MACVLAN_FLAG_NOPROMISC, nopromisc)
316 static const struct trans_tbl macvlan_modes[] = {
317 __ADD(MACVLAN_MODE_PRIVATE,
private)
318 __ADD(MACVLAN_MODE_VEPA, vepa)
319 __ADD(MACVLAN_MODE_BRIDGE, bridge)
320 __ADD(MACVLAN_MODE_PASSTHRU, passthru)
328 char *rtnl_link_macvlan_flags2str(
int flags,
char *buf,
size_t len)
330 return __flags2str(flags, buf, len, macvlan_flags, ARRAY_SIZE(macvlan_flags));
333 int rtnl_link_macvlan_str2flags(
const char *name)
335 return __str2flags(name, macvlan_flags, ARRAY_SIZE(macvlan_flags));
345 char *rtnl_link_macvlan_mode2str(
int mode,
char *buf,
size_t len)
347 return __type2str(mode, buf, len, macvlan_modes, ARRAY_SIZE(macvlan_modes));
350 int rtnl_link_macvlan_str2mode(
const char *name)
352 return __str2type(name, macvlan_modes, ARRAY_SIZE(macvlan_modes));
357 static void __init macvlan_init(
void)
362 static void __exit macvlan_exit(
void)