1054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/* 2054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * lib/route/link/macvlan.c MACVLAN Link Info 3054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 4054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * This library is free software; you can redistribute it and/or 5054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * modify it under the terms of the GNU Lesser General Public 6054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * License as published by the Free Software Foundation version 2.1 7054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * of the License. 8054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 9054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * Copyright (c) 2013 Michael Braun <michael-dev@fami-braun.de> 10054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart */ 11054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 12054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** 13054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @ingroup link 14054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @defgroup macvlan MACVLAN 15054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * MAC-based Virtual LAN link module 16054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 17054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @details 18054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * \b Link Type Name: "macvlan" 19054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 20054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @route_doc{link_macvlan, MACVLAN Documentation} 21054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 22054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @{ 23054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart */ 24054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 25054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart#include <netlink-private/netlink.h> 26054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart#include <netlink/netlink.h> 27054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart#include <netlink/attr.h> 28054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart#include <netlink/utils.h> 29054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart#include <netlink/object.h> 30054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart#include <netlink/route/rtnl.h> 31054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart#include <netlink-private/route/link/api.h> 32054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart#include <netlink/route/link/macvlan.h> 33054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 34054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart#include <linux/if_link.h> 35054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 36054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** @cond SKIP */ 37054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart#define MACVLAN_HAS_MODE (1<<0) 38054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart#define MACVLAN_HAS_FLAGS (1<<1) 39054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 40054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartstruct macvlan_info 41054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 42054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart uint32_t mvi_mode; 43054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart uint16_t mvi_flags; // there currently is only one flag and kernel has no flags_mask yet 44054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart uint32_t mvi_mask; 45054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart}; 46054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 47054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** @endcond */ 48054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 49054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartstatic struct nla_policy macvlan_policy[IFLA_MACVLAN_MAX+1] = { 50054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart [IFLA_MACVLAN_MODE] = { .type = NLA_U32 }, 51054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart [IFLA_MACVLAN_FLAGS] = { .type = NLA_U16 }, 52054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart}; 53054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 54054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartstatic int macvlan_alloc(struct rtnl_link *link) 55054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 56054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart struct macvlan_info *mvi; 57054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 58054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart if ((mvi = calloc(1, sizeof(*mvi))) == NULL) 59054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return -NLE_NOMEM; 60054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 61054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart link->l_info = mvi; 62054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 63054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return 0; 64054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 65054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 66054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartstatic int macvlan_parse(struct rtnl_link *link, struct nlattr *data, 67054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart struct nlattr *xstats) 68054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 69054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart struct nlattr *tb[IFLA_MACVLAN_MAX+1]; 70054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart struct macvlan_info *mvi; 71054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart int err; 72054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 73054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart NL_DBG(3, "Parsing MACVLAN link info"); 74054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 75054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart if ((err = nla_parse_nested(tb, IFLA_MACVLAN_MAX, data, macvlan_policy)) < 0) 76054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart goto errout; 77054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 78054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart if ((err = macvlan_alloc(link)) < 0) 79054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart goto errout; 80054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 81054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart mvi = link->l_info; 82054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 83054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart if (tb[IFLA_MACVLAN_MODE]) { 84054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart mvi->mvi_mode = nla_get_u32(tb[IFLA_MACVLAN_MODE]); 85054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart mvi->mvi_mask |= MACVLAN_HAS_MODE; 86054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart } 87054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 88054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart if (tb[IFLA_MACVLAN_FLAGS]) { 89054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart mvi->mvi_mode = nla_get_u16(tb[IFLA_MACVLAN_FLAGS]); 90054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart mvi->mvi_mask |= MACVLAN_HAS_FLAGS; 91054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart } 92054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 93054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart err = 0; 94054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewarterrout: 95054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return err; 96054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 97054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 98054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartstatic void macvlan_free(struct rtnl_link *link) 99054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 100054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart free(link->l_info); 101054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart link->l_info = NULL; 102054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 103054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 104054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartstatic void macvlan_dump(struct rtnl_link *link, struct nl_dump_params *p) 105054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 106054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart char buf[64]; 107054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart struct macvlan_info *mvi = link->l_info; 108054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 109054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart if (mvi->mvi_mask & MACVLAN_HAS_MODE) { 110054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart rtnl_link_macvlan_mode2str(mvi->mvi_mode, buf, sizeof(buf)); 111054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart nl_dump(p, "macvlan-mode %s", buf); 112054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart } 113054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 114054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart if (mvi->mvi_mask & MACVLAN_HAS_FLAGS) { 115054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart rtnl_link_macvlan_flags2str(mvi->mvi_flags, buf, sizeof(buf)); 116054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart nl_dump(p, "macvlan-flags %s", buf); 117054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart } 118054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 119054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 120054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartstatic int macvlan_clone(struct rtnl_link *dst, struct rtnl_link *src) 121054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 122054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart struct macvlan_info *vdst, *vsrc = src->l_info; 123054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart int err; 124054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 125054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart dst->l_info = NULL; 126054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart if ((err = rtnl_link_set_type(dst, "macvlan")) < 0) 127054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return err; 128054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart vdst = dst->l_info; 129054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 130054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart if (!vdst || !vsrc) 131054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return -NLE_NOMEM; 132054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 133054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart memcpy(vdst, vsrc, sizeof(struct macvlan_info)); 134054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 135054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return 0; 136054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 137054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 138054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartstatic int macvlan_put_attrs(struct nl_msg *msg, struct rtnl_link *link) 139054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 140054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart struct macvlan_info *mvi = link->l_info; 141054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart struct nlattr *data; 142054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 143054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) 144054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return -NLE_MSGSIZE; 145054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 146054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart if (mvi->mvi_mask & MACVLAN_HAS_MODE) 147054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart NLA_PUT_U32(msg, IFLA_MACVLAN_MODE, mvi->mvi_mode); 148054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 149054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart if (mvi->mvi_mask & MACVLAN_HAS_FLAGS) 150054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart NLA_PUT_U16(msg, IFLA_MACVLAN_FLAGS, mvi->mvi_flags); 151054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 152054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart nla_nest_end(msg, data); 153054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 154054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartnla_put_failure: 155054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 156054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return 0; 157054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 158054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 159054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartstatic struct rtnl_link_info_ops macvlan_info_ops = { 160054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart .io_name = "macvlan", 161054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart .io_alloc = macvlan_alloc, 162054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart .io_parse = macvlan_parse, 163054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart .io_dump = { 164054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart [NL_DUMP_LINE] = macvlan_dump, 165054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart [NL_DUMP_DETAILS] = macvlan_dump, 166054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart }, 167054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart .io_clone = macvlan_clone, 168054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart .io_put_attrs = macvlan_put_attrs, 169054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart .io_free = macvlan_free, 170054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart}; 171054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 172054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** @cond SKIP */ 173054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart#define IS_MACVLAN_LINK_ASSERT(link) \ 174054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart if ((link)->l_info_ops != &macvlan_info_ops) { \ 175054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart APPBUG("Link is not a macvlan link. set type \"macvlan\" first."); \ 176054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return -NLE_OPNOTSUPP; \ 177054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart } 178054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** @endcond */ 179054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 180054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** 181054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @name MACVLAN Object 182054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @{ 183054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart */ 184054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 185054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** 186054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * Allocate link object of type MACVLAN 187054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 188054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @return Allocated link object or NULL. 189054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart */ 190054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartstruct rtnl_link *rtnl_link_macvlan_alloc(void) 191054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 192054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart struct rtnl_link *link; 193054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart int err; 194054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 195054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart if (!(link = rtnl_link_alloc())) 196054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return NULL; 197054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 198054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart if ((err = rtnl_link_set_type(link, "macvlan")) < 0) { 199054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart rtnl_link_put(link); 200054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return NULL; 201054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart } 202054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 203054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return link; 204054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 205054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 206054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** 207054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * Check if link is a MACVLAN link 208054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @arg link Link object 209054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 210054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @return True if link is a MACVLAN link, otherwise false is returned. 211054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart */ 212054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartint rtnl_link_is_macvlan(struct rtnl_link *link) 213054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 214054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "macvlan"); 215054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 216054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 217054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** 218054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * Set MACVLAN MODE 219054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @arg link Link object 220054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @arg mode MACVLAN mode 221054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 222054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @return 0 on success or a negative error code 223054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart */ 224054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartint rtnl_link_macvlan_set_mode(struct rtnl_link *link, uint32_t mode) 225054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 226054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart struct macvlan_info *mvi = link->l_info; 227054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 228054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart IS_MACVLAN_LINK_ASSERT(link); 229054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 230054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart mvi->mvi_mode = mode; 231054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart mvi->mvi_mask |= MACVLAN_HAS_MODE; 232054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 233054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return 0; 234054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 235054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 236054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** 237054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * Get MACVLAN Mode 238054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @arg link Link object 239054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 240054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @return MACVLAN mode, 0 if not set or a negative error code. 241054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart */ 242054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartuint32_t rtnl_link_macvlan_get_mode(struct rtnl_link *link) 243054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 244054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart struct macvlan_info *mvi = link->l_info; 245054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 246054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart IS_MACVLAN_LINK_ASSERT(link); 247054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 248054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart if (mvi->mvi_mask & MACVLAN_HAS_MODE) 249054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return mvi->mvi_mode; 250054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart else 251054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return 0; 252054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 253054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 254054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** 255054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * Set MACVLAN flags 256054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @arg link Link object 257054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @arg flags MACVLAN flags 258054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 259054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @return 0 on success or a negative error code. 260054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart */ 261054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartint rtnl_link_macvlan_set_flags(struct rtnl_link *link, uint16_t flags) 262054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 263054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart struct macvlan_info *mvi = link->l_info; 264054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 265054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart IS_MACVLAN_LINK_ASSERT(link); 266054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 267054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart mvi->mvi_flags |= flags; 268054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart mvi->mvi_mask |= MACVLAN_HAS_FLAGS; 269054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 270054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return 0; 271054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 272054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 273054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** 274054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * Unset MACVLAN flags 275054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @arg link Link object 276054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @arg flags MACVLAN flags 277054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 278054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * Note: kernel currently only has a single flag and lacks flags_mask to 279054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * indicate which flags shall be changed (it always all). 280054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 281054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @return 0 on success or a negative error code. 282054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart */ 283054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartint rtnl_link_macvlan_unset_flags(struct rtnl_link *link, uint16_t flags) 284054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 285054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart struct macvlan_info *mvi = link->l_info; 286054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 287054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart IS_MACVLAN_LINK_ASSERT(link); 288054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 289054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart mvi->mvi_flags &= ~flags; 290054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart mvi->mvi_mask |= MACVLAN_HAS_FLAGS; 291054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 292054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return 0; 293054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 294054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 295054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** 296054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * Get MACVLAN flags 297054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @arg link Link object 298054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 299054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @return MACVLAN flags, 0 if none set, or a negative error code. 300054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart */ 301054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartuint16_t rtnl_link_macvlan_get_flags(struct rtnl_link *link) 302054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 303054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart struct macvlan_info *mvi = link->l_info; 304054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 305054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart IS_MACVLAN_LINK_ASSERT(link); 306054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 307054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return mvi->mvi_flags; 308054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 309054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 310054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** @} */ 311054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 312054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartstatic const struct trans_tbl macvlan_flags[] = { 313054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart __ADD(MACVLAN_FLAG_NOPROMISC, nopromisc) 314054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart}; 315054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 316054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartstatic const struct trans_tbl macvlan_modes[] = { 317054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart __ADD(MACVLAN_MODE_PRIVATE, private) 318054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart __ADD(MACVLAN_MODE_VEPA, vepa) 319054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart __ADD(MACVLAN_MODE_BRIDGE, bridge) 320054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart __ADD(MACVLAN_MODE_PASSTHRU, passthru) 321054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart}; 322054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 323054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** 324054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @name Flag Translation 325054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @{ 326054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart */ 327054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 328054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartchar *rtnl_link_macvlan_flags2str(int flags, char *buf, size_t len) 329054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 330054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return __flags2str(flags, buf, len, macvlan_flags, ARRAY_SIZE(macvlan_flags)); 331054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 332054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 333054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartint rtnl_link_macvlan_str2flags(const char *name) 334054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 335054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return __str2flags(name, macvlan_flags, ARRAY_SIZE(macvlan_flags)); 336054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 337054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 338054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** @} */ 339054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 340054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** 341054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @name Mode Translation 342054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @{ 343054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart */ 344054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 345054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartchar *rtnl_link_macvlan_mode2str(int mode, char *buf, size_t len) 346054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 347054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return __type2str(mode, buf, len, macvlan_modes, ARRAY_SIZE(macvlan_modes)); 348054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 349054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 350054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartint rtnl_link_macvlan_str2mode(const char *name) 351054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 352054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return __str2type(name, macvlan_modes, ARRAY_SIZE(macvlan_modes)); 353054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 354054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 355054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** @} */ 356054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 357054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartstatic void __init macvlan_init(void) 358054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 359054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart rtnl_link_register_info(&macvlan_info_ops); 360054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 361054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 362054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartstatic void __exit macvlan_exit(void) 363054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 364054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart rtnl_link_unregister_info(&macvlan_info_ops); 365054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 366054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 367054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** @} */ 368