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

libnl 3.7.0

bonding.c
1 /* SPDX-License-Identifier: LGPL-2.1-only */
2 /*
3 * Copyright (c) 2011-2013 Thomas Graf <tgraf@suug.ch>
4 */
5
6 /**
7 * @ingroup link
8 * @defgroup bonding Bonding
9 *
10 * @details
11 * \b Link Type Name: "bond"
12 *
13 * @route_doc{link_bonding, Bonding Documentation}
14 * @{
15 */
16
17 #include <netlink-private/netlink.h>
18 #include <netlink/netlink.h>
19 #include <netlink/route/link/bonding.h>
20 #include <netlink-private/route/link/api.h>
21
22 /**
23 * Allocate link object of type bond
24 *
25 * @return Allocated link object or NULL.
26 */
27 struct rtnl_link *rtnl_link_bond_alloc(void)
28 {
29 struct rtnl_link *link;
30
31 if (!(link = rtnl_link_alloc()))
32 return NULL;
33
34 if (rtnl_link_set_type(link, "bond") < 0) {
35 rtnl_link_put(link);
36 return NULL;
37 }
38
39 return link;
40 }
41
42 /**
43 * Create a new kernel bonding device
44 * @arg sock netlink socket
45 * @arg name name of bonding device or NULL
46 * @arg opts bonding options (currently unused)
47 *
48 * Creates a new bonding device in the kernel. If no name is
49 * provided, the kernel will automatically pick a name of the
50 * form "type%d" (e.g. bond0, vlan1, etc.)
51 *
52 * The \a opts argument is currently unused. In the future, it
53 * may be used to carry additional bonding options to be set
54 * when creating the bonding device.
55 *
56 * @note When letting the kernel assign a name, it will become
57 * difficult to retrieve the interface afterwards because
58 * you have to guess the name the kernel has chosen. It is
59 * therefore not recommended to not provide a device name.
60 *
61 * @see rtnl_link_bond_enslave()
62 * @see rtnl_link_bond_release()
63 *
64 * @return 0 on success or a negative error code
65 */
66 int rtnl_link_bond_add(struct nl_sock *sock, const char *name,
67 struct rtnl_link *opts)
68 {
69 struct rtnl_link *link;
70 int err;
71
72 if (!(link = rtnl_link_bond_alloc()))
73 return -NLE_NOMEM;
74
75 if (!name && opts)
76 name = rtnl_link_get_name(opts);
77
78 if (name)
79 rtnl_link_set_name(link, name);
80
81 err = rtnl_link_add(sock, link, NLM_F_CREATE);
82
83 rtnl_link_put(link);
84
85 return err;
86 }
87
88 /**
89 * Add a link to a bond (enslave)
90 * @arg sock netlink socket
91 * @arg master ifindex of bonding master
92 * @arg slave ifindex of slave link to add to bond
93 *
94 * This function is identical to rtnl_link_bond_enslave() except that
95 * it takes interface indices instead of rtnl_link objcets.
96 *
97 * @see rtnl_link_bond_enslave()
98 *
99 * @return 0 on success or a negative error code.
100 */
101 int rtnl_link_bond_enslave_ifindex(struct nl_sock *sock, int master,
102 int slave)
103 {
104 struct rtnl_link *link;
105 int err;
106
107 if (!(link = rtnl_link_bond_alloc()))
108 return -NLE_NOMEM;
109
110 rtnl_link_set_ifindex(link, slave);
111 rtnl_link_set_master(link, master);
112
113 if ((err = rtnl_link_change(sock, link, link, 0)) < 0)
114 goto errout;
115
116 rtnl_link_put(link);
117
118 /*
119 * Due to the kernel not signaling whether this opertion is
120 * supported or not, we will retrieve the attribute to see if the
121 * request was successful. If the master assigned remains unchanged
122 * we will return NLE_OPNOTSUPP to allow performing backwards
123 * compatibility of some sort.
124 */
125 if ((err = rtnl_link_get_kernel(sock, slave, NULL, &link)) < 0)
126 return err;
127
128 if (rtnl_link_get_master(link) != master)
129 err = -NLE_OPNOTSUPP;
130
131 errout:
132 rtnl_link_put(link);
133
134 return err;
135 }
136
137 /**
138 * Add a link to a bond (enslave)
139 * @arg sock netlink socket
140 * @arg master bonding master
141 * @arg slave slave link to add to bond
142 *
143 * Constructs a RTM_NEWLINK or RTM_SETLINK message adding the slave to
144 * the master and sends the request via the specified netlink socket.
145 *
146 * @note The feature of enslaving/releasing via netlink has only been added
147 * recently to the kernel (Feb 2011). Also, the kernel does not signal
148 * if the operation is not supported. Therefore this function will
149 * verify if the master assignment has changed and will return
150 * -NLE_OPNOTSUPP if it did not.
151 *
152 * @see rtnl_link_bond_enslave_ifindex()
153 * @see rtnl_link_bond_release()
154 *
155 * @return 0 on success or a negative error code.
156 */
157 int rtnl_link_bond_enslave(struct nl_sock *sock, struct rtnl_link *master,
158 struct rtnl_link *slave)
159 {
160 return rtnl_link_bond_enslave_ifindex(sock,
161 rtnl_link_get_ifindex(master),
162 rtnl_link_get_ifindex(slave));
163 }
164
165 /**
166 * Release a link from a bond
167 * @arg sock netlink socket
168 * @arg slave slave link to be released
169 *
170 * This function is identical to rtnl_link_bond_release() except that
171 * it takes an interface index instead of a rtnl_link object.
172 *
173 * @see rtnl_link_bond_release()
174 *
175 * @return 0 on success or a negative error code.
176 */
177 int rtnl_link_bond_release_ifindex(struct nl_sock *sock, int slave)
178 {
179 return rtnl_link_bond_enslave_ifindex(sock, 0, slave);
180 }
181
182 /**
183 * Release a link from a bond
184 * @arg sock netlink socket
185 * @arg slave slave link to be released
186 *
187 * Constructs a RTM_NEWLINK or RTM_SETLINK message releasing the slave from
188 * its master and sends the request via the specified netlink socket.
189 *
190 * @note The feature of enslaving/releasing via netlink has only been added
191 * recently to the kernel (Feb 2011). Also, the kernel does not signal
192 * if the operation is not supported. Therefore this function will
193 * verify if the master assignment has changed and will return
194 * -NLE_OPNOTSUPP if it did not.
195 *
196 * @see rtnl_link_bond_release_ifindex()
197 * @see rtnl_link_bond_enslave()
198 *
199 * @return 0 on success or a negative error code.
200 */
201 int rtnl_link_bond_release(struct nl_sock *sock, struct rtnl_link *slave)
202 {
203 return rtnl_link_bond_release_ifindex(sock,
204 rtnl_link_get_ifindex(slave));
205 }
206
207 static struct rtnl_link_info_ops bonding_info_ops = {
208 .io_name = "bond",
209 };
210
211 static void __init bonding_init(void)
212 {
213 rtnl_link_register_info(&bonding_info_ops);
214 }
215
216 static void __exit bonding_exit(void)
217 {
218 rtnl_link_unregister_info(&bonding_info_ops);
219 }
220
221 /** @} */
rtnl_link_bond_alloc
struct rtnl_link * rtnl_link_bond_alloc(void)
Allocate link object of type bond.
Definition: bonding.c:27
rtnl_link_bond_enslave_ifindex
int rtnl_link_bond_enslave_ifindex(struct nl_sock *sock, int master, int slave)
Add a link to a bond (enslave)
Definition: bonding.c:101
rtnl_link_bond_add
int rtnl_link_bond_add(struct nl_sock *sock, const char *name, struct rtnl_link *opts)
Create a new kernel bonding device.
Definition: bonding.c:66
rtnl_link_bond_enslave
int rtnl_link_bond_enslave(struct nl_sock *sock, struct rtnl_link *master, struct rtnl_link *slave)
Add a link to a bond (enslave)
Definition: bonding.c:157
rtnl_link_bond_release
int rtnl_link_bond_release(struct nl_sock *sock, struct rtnl_link *slave)
Release a link from a bond.
Definition: bonding.c:201
rtnl_link_bond_release_ifindex
int rtnl_link_bond_release_ifindex(struct nl_sock *sock, int slave)
Release a link from a bond.
Definition: bonding.c:177
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_add
int rtnl_link_add(struct nl_sock *sk, struct rtnl_link *link, int flags)
Add virtual link.
Definition: link.c:1684
rtnl_link_get_master
int rtnl_link_get_master(struct rtnl_link *link)
Return master link of link object.
Definition: link.c:2310
rtnl_link_get_name
char * rtnl_link_get_name(struct rtnl_link *link)
Return name of link object.
Definition: link.c:1952
rtnl_link_set_name
void rtnl_link_set_name(struct rtnl_link *link, const char *name)
Set name of link object.
Definition: link.c:1938
rtnl_link_get_kernel
int rtnl_link_get_kernel(struct nl_sock *sk, int ifindex, const char *name, struct rtnl_link **result)
Get a link object directly from kernel.
Definition: link.c:1421
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_set_master
void rtnl_link_set_master(struct rtnl_link *link, int ifindex)
Set master link of link object.
Definition: link.c:2297
rtnl_link_alloc
struct rtnl_link * rtnl_link_alloc(void)
Allocate link object.
Definition: link.c:1910
rtnl_link_set_ifindex
void rtnl_link_set_ifindex(struct rtnl_link *link, int ifindex)
Set interface index of link object.
Definition: link.c:2167
rtnl_link_get_ifindex
int rtnl_link_get_ifindex(struct rtnl_link *link)
Return interface index of link object.
Definition: link.c:2182
rtnl_link_change
int rtnl_link_change(struct nl_sock *sk, struct rtnl_link *orig, struct rtnl_link *changes, int flags)
Change link.
Definition: link.c:1787
rtnl_link
Link object.