libnl: /data/src/libnl3/lib/route/link/ipvlan.c Source File

libnl 3.7.0

ipvlan.c
1 /* SPDX-License-Identifier: LGPL-2.1-only */
2 /*
3 * Copyright (c) 2015 Cong Wang <cwang@twopensource.com>
4 */
5
6 /**
7 * @ingroup link
8 * @defgroup ipvlan IPVLAN
9 * IP-based Virtual LAN link module
10 *
11 * @details
12 * \b Link Type Name: "ipvlan"
13 *
14 * @route_doc{link_ipvlan, IPVLAN Documentation}
15 *
16 * @{
17 */
18
19 #include <netlink-private/netlink.h>
20 #include <netlink/netlink.h>
21 #include <netlink/attr.h>
22 #include <netlink/utils.h>
23 #include <netlink/object.h>
24 #include <netlink/route/rtnl.h>
25 #include <netlink-private/route/link/api.h>
26 #include <netlink/route/link/ipvlan.h>
27
28 #include <linux/if_link.h>
29
30 /** @cond SKIP */
31 #define IPVLAN_HAS_MODE (1<<0)
32
33 struct ipvlan_info
34 {
35 uint16_t ipi_mode;
36 uint32_t ipi_mask;
37 };
38
39 /** @endcond */
40
41 static struct nla_policy ipvlan_policy[IFLA_IPVLAN_MAX+1] = {
42 [IFLA_IPVLAN_MODE] = { .type = NLA_U16 },
43 };
44
45 static int ipvlan_alloc(struct rtnl_link *link)
46 {
47 struct ipvlan_info *ipi;
48
49 if (link->l_info)
50 memset(link->l_info, 0, sizeof(*ipi));
51 else {
52 if ((ipi = calloc(1, sizeof(*ipi))) == NULL)
53 return -NLE_NOMEM;
54
55 link->l_info = ipi;
56 }
57
58 return 0;
59 }
60
61 static int ipvlan_parse(struct rtnl_link *link, struct nlattr *data,
62 struct nlattr *xstats)
63 {
64 struct nlattr *tb[IFLA_IPVLAN_MAX+1];
65 struct ipvlan_info *ipi;
66 int err;
67
68 NL_DBG(3, "Parsing IPVLAN link info\n");
69
70 if ((err = nla_parse_nested(tb, IFLA_IPVLAN_MAX, data, ipvlan_policy)) < 0)
71 goto errout;
72
73 if ((err = ipvlan_alloc(link)) < 0)
74 goto errout;
75
76 ipi = link->l_info;
77
78 if (tb[IFLA_IPVLAN_MODE]) {
79 ipi->ipi_mode = nla_get_u16(tb[IFLA_IPVLAN_MODE]);
80 ipi->ipi_mask |= IPVLAN_HAS_MODE;
81 }
82
83 err = 0;
84 errout:
85 return err;
86 }
87
88 static void ipvlan_free(struct rtnl_link *link)
89 {
90 free(link->l_info);
91 link->l_info = NULL;
92 }
93
94 static void ipvlan_dump(struct rtnl_link *link, struct nl_dump_params *p)
95 {
96 char buf[64];
97 struct ipvlan_info *ipi = link->l_info;
98
99 if (ipi->ipi_mask & IPVLAN_HAS_MODE) {
100 rtnl_link_ipvlan_mode2str(ipi->ipi_mode, buf, sizeof(buf));
101 nl_dump(p, "ipvlan-mode %s", buf);
102 }
103 }
104
105 static int ipvlan_clone(struct rtnl_link *dst, struct rtnl_link *src)
106 {
107 struct ipvlan_info *vdst, *vsrc = src->l_info;
108 int err;
109
110 dst->l_info = NULL;
111 if ((err = rtnl_link_set_type(dst, "ipvlan")) < 0)
112 return err;
113 vdst = dst->l_info;
114
115 if (!vdst || !vsrc)
116 return -NLE_NOMEM;
117
118 memcpy(vdst, vsrc, sizeof(struct ipvlan_info));
119
120 return 0;
121 }
122
123 static int ipvlan_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
124 {
125 struct ipvlan_info *ipi = link->l_info;
126 struct nlattr *data;
127
128 if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
129 return -NLE_MSGSIZE;
130
131 if (ipi->ipi_mask & IPVLAN_HAS_MODE)
132 NLA_PUT_U16(msg, IFLA_IPVLAN_MODE, ipi->ipi_mode);
133
134 nla_nest_end(msg, data);
135
136 nla_put_failure:
137
138 return 0;
139 }
140
141 static struct rtnl_link_info_ops ipvlan_info_ops = {
142 .io_name = "ipvlan",
143 .io_alloc = ipvlan_alloc,
144 .io_parse = ipvlan_parse,
145 .io_dump = {
146 [NL_DUMP_LINE] = ipvlan_dump,
147 [NL_DUMP_DETAILS] = ipvlan_dump,
148 },
149 .io_clone = ipvlan_clone,
150 .io_put_attrs = ipvlan_put_attrs,
151 .io_free = ipvlan_free,
152 };
153
154 /** @cond SKIP */
155 #define IS_IPVLAN_LINK_ASSERT(link) \
156 if ((link)->l_info_ops != &ipvlan_info_ops) { \
157 APPBUG("Link is not a ipvlan link. set type \"ipvlan\" first."); \
158 return -NLE_OPNOTSUPP; \
159 }
160 /** @endcond */
161
162 /**
163 * @name IPVLAN Object
164 * @{
165 */
166
167 /**
168 * Allocate link object of type IPVLAN
169 *
170 * @return Allocated link object or NULL.
171 */
172 struct rtnl_link *rtnl_link_ipvlan_alloc(void)
173 {
174 struct rtnl_link *link;
175
176 if (!(link = rtnl_link_alloc()))
177 return NULL;
178
179 if (rtnl_link_set_type(link, "ipvlan") < 0) {
180 rtnl_link_put(link);
181 return NULL;
182 }
183
184 return link;
185 }
186
187 /**
188 * Check if link is a IPVLAN link
189 * @arg link Link object
190 *
191 * @return True if link is a IPVLAN link, otherwise false is returned.
192 */
193 int rtnl_link_is_ipvlan(struct rtnl_link *link)
194 {
195 return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "ipvlan");
196 }
197
198 /**
199 * Set IPVLAN MODE
200 * @arg link Link object
201 * @arg mode IPVLAN mode
202 *
203 * @return 0 on success or a negative error code
204 */
205 int rtnl_link_ipvlan_set_mode(struct rtnl_link *link, uint16_t mode)
206 {
207 struct ipvlan_info *ipi = link->l_info;
208
209 IS_IPVLAN_LINK_ASSERT(link);
210
211 ipi->ipi_mode = mode;
212 ipi->ipi_mask |= IPVLAN_HAS_MODE;
213
214 return 0;
215 }
216
217 /**
218 * Get IPVLAN Mode
219 * @arg link Link object
220 * @arg out_mode on success, return the mode
221 *
222 * @return 0 on success or a negative error code.
223 */
224 int rtnl_link_ipvlan_get_mode(struct rtnl_link *link, uint16_t *out_mode)
225 {
226 struct ipvlan_info *ipi = link->l_info;
227
228 IS_IPVLAN_LINK_ASSERT(link);
229
230 if (!(ipi->ipi_mask & IPVLAN_HAS_MODE))
231 return -NLE_INVAL;
232 *out_mode = ipi->ipi_mode;
233 return 0;
234 }
235
236 /** @} */
237
238 static const struct trans_tbl ipvlan_modes[] = {
239 __ADD(IPVLAN_MODE_L2, l2),
240 __ADD(IPVLAN_MODE_L3, l3),
241 };
242
243 /**
244 * @name Mode Translation
245 * @{
246 */
247
248 char *rtnl_link_ipvlan_mode2str(int mode, char *buf, size_t len)
249 {
250 return __type2str(mode, buf, len, ipvlan_modes, ARRAY_SIZE(ipvlan_modes));
251 }
252
253 int rtnl_link_ipvlan_str2mode(const char *name)
254 {
255 return __str2type(name, ipvlan_modes, ARRAY_SIZE(ipvlan_modes));
256 }
257
258 /** @} */
259
260 static void __init ipvlan_init(void)
261 {
262 rtnl_link_register_info(&ipvlan_info_ops);
263 }
264
265 static void __exit ipvlan_exit(void)
266 {
267 rtnl_link_unregister_info(&ipvlan_info_ops);
268 }
269
270 /** @} */
nla_get_u16
uint16_t nla_get_u16(const struct nlattr *nla)
Return payload of 16 bit integer attribute.
Definition: attr.c:649
NLA_PUT_U16
#define NLA_PUT_U16(msg, attrtype, value)
Add 16 bit integer attribute to netlink message.
Definition: attr.h:212
nla_nest_start
struct nlattr * nla_nest_start(struct nl_msg *msg, int attrtype)
Start a new level of nested attributes.
Definition: attr.c:895
nla_parse_nested
int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, const struct nla_policy *policy)
Create attribute index based on nested attribute.
Definition: attr.c:1013
nla_nest_end
int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
Finalize nesting of attributes.
Definition: attr.c:958
NLA_U16
@ NLA_U16
16 bit integer
Definition: attr.h:36
rtnl_link_ipvlan_set_mode
int rtnl_link_ipvlan_set_mode(struct rtnl_link *link, uint16_t mode)
Set IPVLAN MODE.
Definition: ipvlan.c:205
rtnl_link_ipvlan_get_mode
int rtnl_link_ipvlan_get_mode(struct rtnl_link *link, uint16_t *out_mode)
Get IPVLAN Mode.
Definition: ipvlan.c:224
rtnl_link_ipvlan_alloc
struct rtnl_link * rtnl_link_ipvlan_alloc(void)
Allocate link object of type IPVLAN.
Definition: ipvlan.c:172
rtnl_link_is_ipvlan
int rtnl_link_is_ipvlan(struct rtnl_link *link)
Check if link is a IPVLAN link.
Definition: ipvlan.c:193
rtnl_link_register_info
int rtnl_link_register_info(struct rtnl_link_info_ops *ops)
Register operations for a link info type.
Definition: api.c:124
rtnl_link_unregister_info
int rtnl_link_unregister_info(struct rtnl_link_info_ops *ops)
Unregister operations for a link info type.
Definition: api.c:159
rtnl_link_put
void rtnl_link_put(struct rtnl_link *link)
Return a link object reference.
Definition: link.c:1919
rtnl_link_set_type
int rtnl_link_set_type(struct rtnl_link *link, const char *type)
Set type of link object.
Definition: link.c:2548
rtnl_link_alloc
struct rtnl_link * rtnl_link_alloc(void)
Allocate link object.
Definition: link.c:1910
nl_dump
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition: utils.c:955
NL_DUMP_LINE
@ NL_DUMP_LINE
Dump object briefly on one line.
Definition: types.h:16
NL_DUMP_DETAILS
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.
Definition: types.h:17
nl_dump_params
Dumping parameters.
Definition: types.h:28
nla_policy
Attribute validation policy.
Definition: attr.h:63
nla_policy::type
uint16_t type
Type of attribute or NLA_UNSPEC.
Definition: attr.h:65
rtnl_link
Link object.