xref: /aosp_15_r20/external/libnl/lib/route/link/veth.c (revision 4dc78e53d49367fa8e61b07018507c90983a077d)
1*4dc78e53SAndroid Build Coastguard Worker /* SPDX-License-Identifier: LGPL-2.1-only */
2*4dc78e53SAndroid Build Coastguard Worker /*
3*4dc78e53SAndroid Build Coastguard Worker  * Copyright (c) 2013 Cong Wang <[email protected]>
4*4dc78e53SAndroid Build Coastguard Worker  */
5*4dc78e53SAndroid Build Coastguard Worker 
6*4dc78e53SAndroid Build Coastguard Worker /**
7*4dc78e53SAndroid Build Coastguard Worker  * @ingroup link
8*4dc78e53SAndroid Build Coastguard Worker  * @defgroup veth VETH
9*4dc78e53SAndroid Build Coastguard Worker  * Virtual Ethernet
10*4dc78e53SAndroid Build Coastguard Worker  *
11*4dc78e53SAndroid Build Coastguard Worker  * @details
12*4dc78e53SAndroid Build Coastguard Worker  * \b Link Type Name: "veth"
13*4dc78e53SAndroid Build Coastguard Worker  *
14*4dc78e53SAndroid Build Coastguard Worker  * @route_doc{link_veth, VETH Documentation}
15*4dc78e53SAndroid Build Coastguard Worker  *
16*4dc78e53SAndroid Build Coastguard Worker  * @{
17*4dc78e53SAndroid Build Coastguard Worker  */
18*4dc78e53SAndroid Build Coastguard Worker 
19*4dc78e53SAndroid Build Coastguard Worker #include "nl-default.h"
20*4dc78e53SAndroid Build Coastguard Worker 
21*4dc78e53SAndroid Build Coastguard Worker #include <linux/if_link.h>
22*4dc78e53SAndroid Build Coastguard Worker #include <linux/veth.h>
23*4dc78e53SAndroid Build Coastguard Worker 
24*4dc78e53SAndroid Build Coastguard Worker #include <netlink/netlink.h>
25*4dc78e53SAndroid Build Coastguard Worker #include <netlink/attr.h>
26*4dc78e53SAndroid Build Coastguard Worker #include <netlink/utils.h>
27*4dc78e53SAndroid Build Coastguard Worker #include <netlink/object.h>
28*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/rtnl.h>
29*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/link/veth.h>
30*4dc78e53SAndroid Build Coastguard Worker 
31*4dc78e53SAndroid Build Coastguard Worker #include "nl-route.h"
32*4dc78e53SAndroid Build Coastguard Worker #include "link-api.h"
33*4dc78e53SAndroid Build Coastguard Worker 
34*4dc78e53SAndroid Build Coastguard Worker static struct nla_policy veth_policy[VETH_INFO_MAX+1] = {
35*4dc78e53SAndroid Build Coastguard Worker 	[VETH_INFO_PEER]	= { .minlen = sizeof(struct ifinfomsg) },
36*4dc78e53SAndroid Build Coastguard Worker };
37*4dc78e53SAndroid Build Coastguard Worker 
veth_parse(struct rtnl_link * link,struct nlattr * data,struct nlattr * xstats)38*4dc78e53SAndroid Build Coastguard Worker static int veth_parse(struct rtnl_link *link, struct nlattr *data,
39*4dc78e53SAndroid Build Coastguard Worker 		      struct nlattr *xstats)
40*4dc78e53SAndroid Build Coastguard Worker {
41*4dc78e53SAndroid Build Coastguard Worker 	struct nlattr *tb[VETH_INFO_MAX+1];
42*4dc78e53SAndroid Build Coastguard Worker 	struct nlattr *peer_tb[IFLA_MAX + 1];
43*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_link *peer = link->l_info;
44*4dc78e53SAndroid Build Coastguard Worker 	int err;
45*4dc78e53SAndroid Build Coastguard Worker 
46*4dc78e53SAndroid Build Coastguard Worker 	NL_DBG(3, "Parsing veth link info\n");
47*4dc78e53SAndroid Build Coastguard Worker 
48*4dc78e53SAndroid Build Coastguard Worker 	if ((err = nla_parse_nested(tb, VETH_INFO_MAX, data, veth_policy)) < 0)
49*4dc78e53SAndroid Build Coastguard Worker 		goto errout;
50*4dc78e53SAndroid Build Coastguard Worker 
51*4dc78e53SAndroid Build Coastguard Worker 	if (tb[VETH_INFO_PEER]) {
52*4dc78e53SAndroid Build Coastguard Worker 		struct nlattr *nla_peer;
53*4dc78e53SAndroid Build Coastguard Worker 		struct ifinfomsg *ifi;
54*4dc78e53SAndroid Build Coastguard Worker 
55*4dc78e53SAndroid Build Coastguard Worker 		nla_peer = tb[VETH_INFO_PEER];
56*4dc78e53SAndroid Build Coastguard Worker 		ifi = nla_data(nla_peer);
57*4dc78e53SAndroid Build Coastguard Worker 
58*4dc78e53SAndroid Build Coastguard Worker 		peer->l_family = ifi->ifi_family;
59*4dc78e53SAndroid Build Coastguard Worker 		peer->l_arptype = ifi->ifi_type;
60*4dc78e53SAndroid Build Coastguard Worker 		peer->l_index = ifi->ifi_index;
61*4dc78e53SAndroid Build Coastguard Worker 		peer->l_flags = ifi->ifi_flags;
62*4dc78e53SAndroid Build Coastguard Worker 		peer->l_change = ifi->ifi_change;
63*4dc78e53SAndroid Build Coastguard Worker 		err = nla_parse(peer_tb, IFLA_MAX, (struct nlattr *)
64*4dc78e53SAndroid Build Coastguard Worker 		                ((char *) nla_data(nla_peer) + sizeof(struct ifinfomsg)),
65*4dc78e53SAndroid Build Coastguard Worker 				nla_len(nla_peer) - sizeof(struct ifinfomsg),
66*4dc78e53SAndroid Build Coastguard Worker 				rtln_link_policy);
67*4dc78e53SAndroid Build Coastguard Worker 		if (err < 0)
68*4dc78e53SAndroid Build Coastguard Worker 			goto errout;
69*4dc78e53SAndroid Build Coastguard Worker 
70*4dc78e53SAndroid Build Coastguard Worker 		err = rtnl_link_info_parse(peer, peer_tb);
71*4dc78e53SAndroid Build Coastguard Worker 		if (err < 0)
72*4dc78e53SAndroid Build Coastguard Worker 			goto errout;
73*4dc78e53SAndroid Build Coastguard Worker 	}
74*4dc78e53SAndroid Build Coastguard Worker 
75*4dc78e53SAndroid Build Coastguard Worker 	err = 0;
76*4dc78e53SAndroid Build Coastguard Worker 
77*4dc78e53SAndroid Build Coastguard Worker errout:
78*4dc78e53SAndroid Build Coastguard Worker 	return err;
79*4dc78e53SAndroid Build Coastguard Worker }
80*4dc78e53SAndroid Build Coastguard Worker 
veth_dump_line(struct rtnl_link * link,struct nl_dump_params * p)81*4dc78e53SAndroid Build Coastguard Worker static void veth_dump_line(struct rtnl_link *link, struct nl_dump_params *p)
82*4dc78e53SAndroid Build Coastguard Worker {
83*4dc78e53SAndroid Build Coastguard Worker }
84*4dc78e53SAndroid Build Coastguard Worker 
veth_dump_details(struct rtnl_link * link,struct nl_dump_params * p)85*4dc78e53SAndroid Build Coastguard Worker static void veth_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
86*4dc78e53SAndroid Build Coastguard Worker {
87*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_link *peer = link->l_info;
88*4dc78e53SAndroid Build Coastguard Worker 	char *name;
89*4dc78e53SAndroid Build Coastguard Worker 	name = rtnl_link_get_name(peer);
90*4dc78e53SAndroid Build Coastguard Worker 	nl_dump(p, "      peer ");
91*4dc78e53SAndroid Build Coastguard Worker 	if (name)
92*4dc78e53SAndroid Build Coastguard Worker 		nl_dump_line(p, "%s\n", name);
93*4dc78e53SAndroid Build Coastguard Worker 	else
94*4dc78e53SAndroid Build Coastguard Worker 		nl_dump_line(p, "%u\n", peer->l_index);
95*4dc78e53SAndroid Build Coastguard Worker }
96*4dc78e53SAndroid Build Coastguard Worker 
veth_clone(struct rtnl_link * dst,struct rtnl_link * src)97*4dc78e53SAndroid Build Coastguard Worker static int veth_clone(struct rtnl_link *dst, struct rtnl_link *src)
98*4dc78e53SAndroid Build Coastguard Worker {
99*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_link *dst_peer = NULL, *src_peer = src->l_info;
100*4dc78e53SAndroid Build Coastguard Worker 
101*4dc78e53SAndroid Build Coastguard Worker 	/* we are calling nl_object_clone() recursively, this should
102*4dc78e53SAndroid Build Coastguard Worker 	 * happen only once */
103*4dc78e53SAndroid Build Coastguard Worker 	if (src_peer) {
104*4dc78e53SAndroid Build Coastguard Worker 		src_peer->l_info = NULL;
105*4dc78e53SAndroid Build Coastguard Worker 		dst_peer = (struct rtnl_link *)nl_object_clone(OBJ_CAST(src_peer));
106*4dc78e53SAndroid Build Coastguard Worker 		if (!dst_peer)
107*4dc78e53SAndroid Build Coastguard Worker 			return -NLE_NOMEM;
108*4dc78e53SAndroid Build Coastguard Worker 		src_peer->l_info = src;
109*4dc78e53SAndroid Build Coastguard Worker 		dst_peer->l_info = dst;
110*4dc78e53SAndroid Build Coastguard Worker 	}
111*4dc78e53SAndroid Build Coastguard Worker 	dst->l_info = dst_peer;
112*4dc78e53SAndroid Build Coastguard Worker 	return 0;
113*4dc78e53SAndroid Build Coastguard Worker }
114*4dc78e53SAndroid Build Coastguard Worker 
veth_put_attrs(struct nl_msg * msg,struct rtnl_link * link)115*4dc78e53SAndroid Build Coastguard Worker static int veth_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
116*4dc78e53SAndroid Build Coastguard Worker {
117*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_link *peer = link->l_info;
118*4dc78e53SAndroid Build Coastguard Worker 	struct ifinfomsg ifi;
119*4dc78e53SAndroid Build Coastguard Worker 	struct nlattr *data, *info_peer;
120*4dc78e53SAndroid Build Coastguard Worker 
121*4dc78e53SAndroid Build Coastguard Worker 	memset(&ifi, 0, sizeof ifi);
122*4dc78e53SAndroid Build Coastguard Worker 	ifi.ifi_family = peer->l_family;
123*4dc78e53SAndroid Build Coastguard Worker 	ifi.ifi_type = peer->l_arptype;
124*4dc78e53SAndroid Build Coastguard Worker 	ifi.ifi_index = peer->l_index;
125*4dc78e53SAndroid Build Coastguard Worker 	ifi.ifi_flags = peer->l_flags;
126*4dc78e53SAndroid Build Coastguard Worker 	ifi.ifi_change = peer->l_change;
127*4dc78e53SAndroid Build Coastguard Worker 
128*4dc78e53SAndroid Build Coastguard Worker 	if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
129*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_MSGSIZE;
130*4dc78e53SAndroid Build Coastguard Worker 	if (!(info_peer = nla_nest_start(msg, VETH_INFO_PEER)))
131*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_MSGSIZE;
132*4dc78e53SAndroid Build Coastguard Worker 	if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0)
133*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_MSGSIZE;
134*4dc78e53SAndroid Build Coastguard Worker 	rtnl_link_fill_info(msg, peer);
135*4dc78e53SAndroid Build Coastguard Worker 	nla_nest_end(msg, info_peer);
136*4dc78e53SAndroid Build Coastguard Worker 	nla_nest_end(msg, data);
137*4dc78e53SAndroid Build Coastguard Worker 
138*4dc78e53SAndroid Build Coastguard Worker 	return 0;
139*4dc78e53SAndroid Build Coastguard Worker }
140*4dc78e53SAndroid Build Coastguard Worker 
veth_alloc(struct rtnl_link * link)141*4dc78e53SAndroid Build Coastguard Worker static int veth_alloc(struct rtnl_link *link)
142*4dc78e53SAndroid Build Coastguard Worker {
143*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_link *peer;
144*4dc78e53SAndroid Build Coastguard Worker 	int err;
145*4dc78e53SAndroid Build Coastguard Worker 
146*4dc78e53SAndroid Build Coastguard Worker 	/* return early if we are in recursion */
147*4dc78e53SAndroid Build Coastguard Worker 	if (link->l_info)
148*4dc78e53SAndroid Build Coastguard Worker 		return 0;
149*4dc78e53SAndroid Build Coastguard Worker 
150*4dc78e53SAndroid Build Coastguard Worker 	if (!(peer = rtnl_link_alloc()))
151*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
152*4dc78e53SAndroid Build Coastguard Worker 
153*4dc78e53SAndroid Build Coastguard Worker 	/* We don't need to hold a reference here, as link and
154*4dc78e53SAndroid Build Coastguard Worker 	 * its peer should always be freed together.
155*4dc78e53SAndroid Build Coastguard Worker 	 */
156*4dc78e53SAndroid Build Coastguard Worker 	peer->l_info = link;
157*4dc78e53SAndroid Build Coastguard Worker 	if ((err = rtnl_link_set_type(peer, "veth")) < 0) {
158*4dc78e53SAndroid Build Coastguard Worker 		rtnl_link_put(peer);
159*4dc78e53SAndroid Build Coastguard Worker 		return err;
160*4dc78e53SAndroid Build Coastguard Worker 	}
161*4dc78e53SAndroid Build Coastguard Worker 
162*4dc78e53SAndroid Build Coastguard Worker 	link->l_info = peer;
163*4dc78e53SAndroid Build Coastguard Worker 	return 0;
164*4dc78e53SAndroid Build Coastguard Worker }
165*4dc78e53SAndroid Build Coastguard Worker 
veth_free(struct rtnl_link * link)166*4dc78e53SAndroid Build Coastguard Worker static void veth_free(struct rtnl_link *link)
167*4dc78e53SAndroid Build Coastguard Worker {
168*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_link *peer = link->l_info;
169*4dc78e53SAndroid Build Coastguard Worker 	if (peer) {
170*4dc78e53SAndroid Build Coastguard Worker 		link->l_info = NULL;
171*4dc78e53SAndroid Build Coastguard Worker 		/* avoid calling this recursively */
172*4dc78e53SAndroid Build Coastguard Worker 		peer->l_info = NULL;
173*4dc78e53SAndroid Build Coastguard Worker 		rtnl_link_put(peer);
174*4dc78e53SAndroid Build Coastguard Worker 	}
175*4dc78e53SAndroid Build Coastguard Worker 	/* the caller should finally free link */
176*4dc78e53SAndroid Build Coastguard Worker }
177*4dc78e53SAndroid Build Coastguard Worker 
178*4dc78e53SAndroid Build Coastguard Worker static struct rtnl_link_info_ops veth_info_ops = {
179*4dc78e53SAndroid Build Coastguard Worker 	.io_name		= "veth",
180*4dc78e53SAndroid Build Coastguard Worker 	.io_parse		= veth_parse,
181*4dc78e53SAndroid Build Coastguard Worker 	.io_dump = {
182*4dc78e53SAndroid Build Coastguard Worker 	    [NL_DUMP_LINE]	= veth_dump_line,
183*4dc78e53SAndroid Build Coastguard Worker 	    [NL_DUMP_DETAILS]	= veth_dump_details,
184*4dc78e53SAndroid Build Coastguard Worker 	},
185*4dc78e53SAndroid Build Coastguard Worker 	.io_alloc		= veth_alloc,
186*4dc78e53SAndroid Build Coastguard Worker 	.io_clone		= veth_clone,
187*4dc78e53SAndroid Build Coastguard Worker 	.io_put_attrs		= veth_put_attrs,
188*4dc78e53SAndroid Build Coastguard Worker 	.io_free		= veth_free,
189*4dc78e53SAndroid Build Coastguard Worker };
190*4dc78e53SAndroid Build Coastguard Worker 
191*4dc78e53SAndroid Build Coastguard Worker /** @cond SKIP */
192*4dc78e53SAndroid Build Coastguard Worker 
193*4dc78e53SAndroid Build Coastguard Worker #define IS_VETH_LINK_ASSERT(link) \
194*4dc78e53SAndroid Build Coastguard Worker 	if ((link)->l_info_ops != &veth_info_ops) { \
195*4dc78e53SAndroid Build Coastguard Worker 		APPBUG("Link is not a veth link. set type \"veth\" first."); \
196*4dc78e53SAndroid Build Coastguard Worker 		return NULL; \
197*4dc78e53SAndroid Build Coastguard Worker 	}
198*4dc78e53SAndroid Build Coastguard Worker /** @endcond */
199*4dc78e53SAndroid Build Coastguard Worker 
200*4dc78e53SAndroid Build Coastguard Worker /**
201*4dc78e53SAndroid Build Coastguard Worker  * @name VETH Object
202*4dc78e53SAndroid Build Coastguard Worker  * @{
203*4dc78e53SAndroid Build Coastguard Worker  */
204*4dc78e53SAndroid Build Coastguard Worker 
205*4dc78e53SAndroid Build Coastguard Worker /**
206*4dc78e53SAndroid Build Coastguard Worker  * Allocate link object of type veth
207*4dc78e53SAndroid Build Coastguard Worker  *
208*4dc78e53SAndroid Build Coastguard Worker  * @return Allocated link object or NULL.
209*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_veth_alloc(void)210*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *rtnl_link_veth_alloc(void)
211*4dc78e53SAndroid Build Coastguard Worker {
212*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_link *link;
213*4dc78e53SAndroid Build Coastguard Worker 
214*4dc78e53SAndroid Build Coastguard Worker 	if (!(link = rtnl_link_alloc()))
215*4dc78e53SAndroid Build Coastguard Worker 		return NULL;
216*4dc78e53SAndroid Build Coastguard Worker 	if (rtnl_link_set_type(link, "veth") < 0) {
217*4dc78e53SAndroid Build Coastguard Worker 		rtnl_link_put(link);
218*4dc78e53SAndroid Build Coastguard Worker 		return NULL;
219*4dc78e53SAndroid Build Coastguard Worker 	}
220*4dc78e53SAndroid Build Coastguard Worker 
221*4dc78e53SAndroid Build Coastguard Worker 	return link;
222*4dc78e53SAndroid Build Coastguard Worker }
223*4dc78e53SAndroid Build Coastguard Worker 
224*4dc78e53SAndroid Build Coastguard Worker /**
225*4dc78e53SAndroid Build Coastguard Worker  * Get the peer link of a veth link
226*4dc78e53SAndroid Build Coastguard Worker  *
227*4dc78e53SAndroid Build Coastguard Worker  * @return the peer link object.
228*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_veth_get_peer(struct rtnl_link * link)229*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *rtnl_link_veth_get_peer(struct rtnl_link *link)
230*4dc78e53SAndroid Build Coastguard Worker {
231*4dc78e53SAndroid Build Coastguard Worker 	IS_VETH_LINK_ASSERT(link);
232*4dc78e53SAndroid Build Coastguard Worker 	nl_object_get(OBJ_CAST(link->l_info));
233*4dc78e53SAndroid Build Coastguard Worker 	return link->l_info;
234*4dc78e53SAndroid Build Coastguard Worker }
235*4dc78e53SAndroid Build Coastguard Worker 
236*4dc78e53SAndroid Build Coastguard Worker /**
237*4dc78e53SAndroid Build Coastguard Worker  * Release a veth link and its peer
238*4dc78e53SAndroid Build Coastguard Worker  *
239*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_veth_release(struct rtnl_link * link)240*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_veth_release(struct rtnl_link *link)
241*4dc78e53SAndroid Build Coastguard Worker {
242*4dc78e53SAndroid Build Coastguard Worker 	veth_free(link);
243*4dc78e53SAndroid Build Coastguard Worker 	rtnl_link_put(link);
244*4dc78e53SAndroid Build Coastguard Worker }
245*4dc78e53SAndroid Build Coastguard Worker 
246*4dc78e53SAndroid Build Coastguard Worker /**
247*4dc78e53SAndroid Build Coastguard Worker  * Check if link is a veth link
248*4dc78e53SAndroid Build Coastguard Worker  * @arg link		Link object
249*4dc78e53SAndroid Build Coastguard Worker  *
250*4dc78e53SAndroid Build Coastguard Worker  * @return True if link is a veth link, otherwise false is returned.
251*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_is_veth(struct rtnl_link * link)252*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_is_veth(struct rtnl_link *link)
253*4dc78e53SAndroid Build Coastguard Worker {
254*4dc78e53SAndroid Build Coastguard Worker 	return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "veth");
255*4dc78e53SAndroid Build Coastguard Worker }
256*4dc78e53SAndroid Build Coastguard Worker 
257*4dc78e53SAndroid Build Coastguard Worker /**
258*4dc78e53SAndroid Build Coastguard Worker  * Create a new kernel veth device
259*4dc78e53SAndroid Build Coastguard Worker  * @arg sock		netlink socket
260*4dc78e53SAndroid Build Coastguard Worker  * @arg name		name of the veth device or NULL
261*4dc78e53SAndroid Build Coastguard Worker  * @arg peer_name	name of its peer or NULL
262*4dc78e53SAndroid Build Coastguard Worker  * @arg pid		pid of the process in the new netns
263*4dc78e53SAndroid Build Coastguard Worker  *
264*4dc78e53SAndroid Build Coastguard Worker  * Creates a new veth device pair in the kernel and move the peer
265*4dc78e53SAndroid Build Coastguard Worker  * to the network namespace where the process is. If no name is
266*4dc78e53SAndroid Build Coastguard Worker  * provided, the kernel will automatically pick a name of the
267*4dc78e53SAndroid Build Coastguard Worker  * form "veth%d" (e.g. veth0, veth1, etc.)
268*4dc78e53SAndroid Build Coastguard Worker  *
269*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code
270*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_link_veth_add(struct nl_sock * sock,const char * name,const char * peer_name,pid_t pid)271*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_veth_add(struct nl_sock *sock, const char *name,
272*4dc78e53SAndroid Build Coastguard Worker                        const char *peer_name, pid_t pid)
273*4dc78e53SAndroid Build Coastguard Worker {
274*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_link *link, *peer;
275*4dc78e53SAndroid Build Coastguard Worker 	int err = -NLE_NOMEM;
276*4dc78e53SAndroid Build Coastguard Worker 
277*4dc78e53SAndroid Build Coastguard Worker 	if (!(link = rtnl_link_veth_alloc()))
278*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
279*4dc78e53SAndroid Build Coastguard Worker 	peer = link->l_info;
280*4dc78e53SAndroid Build Coastguard Worker 
281*4dc78e53SAndroid Build Coastguard Worker 	if (name)
282*4dc78e53SAndroid Build Coastguard Worker 		rtnl_link_set_name(link, name);
283*4dc78e53SAndroid Build Coastguard Worker 	if (peer_name)
284*4dc78e53SAndroid Build Coastguard Worker 		rtnl_link_set_name(peer, peer_name);
285*4dc78e53SAndroid Build Coastguard Worker 
286*4dc78e53SAndroid Build Coastguard Worker 	rtnl_link_set_ns_pid(peer, pid);
287*4dc78e53SAndroid Build Coastguard Worker 	err = rtnl_link_add(sock, link, NLM_F_CREATE | NLM_F_EXCL);
288*4dc78e53SAndroid Build Coastguard Worker 
289*4dc78e53SAndroid Build Coastguard Worker 	rtnl_link_put(link);
290*4dc78e53SAndroid Build Coastguard Worker 	return err;
291*4dc78e53SAndroid Build Coastguard Worker }
292*4dc78e53SAndroid Build Coastguard Worker 
293*4dc78e53SAndroid Build Coastguard Worker /** @} */
294*4dc78e53SAndroid Build Coastguard Worker 
veth_init(void)295*4dc78e53SAndroid Build Coastguard Worker static void _nl_init veth_init(void)
296*4dc78e53SAndroid Build Coastguard Worker {
297*4dc78e53SAndroid Build Coastguard Worker 	rtnl_link_register_info(&veth_info_ops);
298*4dc78e53SAndroid Build Coastguard Worker }
299*4dc78e53SAndroid Build Coastguard Worker 
veth_exit(void)300*4dc78e53SAndroid Build Coastguard Worker static void _nl_exit veth_exit(void)
301*4dc78e53SAndroid Build Coastguard Worker {
302*4dc78e53SAndroid Build Coastguard Worker 	rtnl_link_unregister_info(&veth_info_ops);
303*4dc78e53SAndroid Build Coastguard Worker }
304*4dc78e53SAndroid Build Coastguard Worker 
305*4dc78e53SAndroid Build Coastguard Worker /** @} */
306