libnl 3.5.0

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