libnl
3.2.3
|
00001 /* 00002 * lib/route/link/bonding.c Bonding Link Module 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation version 2.1 00007 * of the License. 00008 * 00009 * Copyright (c) 2011 Thomas Graf <tgraf@suug.ch> 00010 */ 00011 00012 /** 00013 * @ingroup link 00014 * @defgroup bonding Bonding 00015 * 00016 * @details 00017 * \b Link Type Name: "bond" 00018 * 00019 * @route_doc{link_bonding, Bonding Documentation} 00020 * @{ 00021 */ 00022 00023 #include <netlink-local.h> 00024 #include <netlink/netlink.h> 00025 #include <netlink/route/link/api.h> 00026 00027 /** 00028 * Create a new kernel bonding device 00029 * @arg sock netlink socket 00030 * @arg name name of bonding device or NULL 00031 * @arg opts bonding options (currently unused) 00032 * 00033 * Creates a new bonding device in the kernel. If no name is 00034 * provided, the kernel will automatically pick a name of the 00035 * form "type%d" (e.g. bond0, vlan1, etc.) 00036 * 00037 * The \a opts argument is currently unused. In the future, it 00038 * may be used to carry additional bonding options to be set 00039 * when creating the bonding device. 00040 * 00041 * @note When letting the kernel assign a name, it will become 00042 * difficult to retrieve the interface afterwards because 00043 * you have to guess the name the kernel has chosen. It is 00044 * therefore not recommended to not provide a device name. 00045 * 00046 * @see rtnl_link_bond_enslave() 00047 * @see rtnl_link_bond_release() 00048 * 00049 * @return 0 on success or a negative error code 00050 */ 00051 int rtnl_link_bond_add(struct nl_sock *sock, const char *name, 00052 struct rtnl_link *opts) 00053 { 00054 struct rtnl_link *link; 00055 int err; 00056 00057 if (!(link = rtnl_link_alloc())) 00058 return -NLE_NOMEM; 00059 00060 if (!name) { 00061 if (opts) 00062 name = rtnl_link_get_name(opts); 00063 00064 if (!name) 00065 return -NLE_MISSING_ATTR; 00066 } 00067 00068 if ((err = rtnl_link_set_type(link, "bond")) < 0) 00069 goto errout; 00070 00071 00072 rtnl_link_set_name(link, name); 00073 00074 err = rtnl_link_add(sock, link, NLM_F_CREATE); 00075 errout: 00076 rtnl_link_put(link); 00077 00078 return err; 00079 } 00080 00081 /** 00082 * Add a link to a bond (enslave) 00083 * @arg sock netlink socket 00084 * @arg master ifindex of bonding master 00085 * @arg slave ifindex of slave link to add to bond 00086 * 00087 * This function is identical to rtnl_link_bond_enslave() except that 00088 * it takes interface indices instead of rtnl_link objcets. 00089 * 00090 * @see rtnl_link_bond_enslave() 00091 * 00092 * @return 0 on success or a negative error code. 00093 */ 00094 int rtnl_link_bond_enslave_ifindex(struct nl_sock *sock, int master, 00095 int slave) 00096 { 00097 struct rtnl_link *link; 00098 int err; 00099 00100 if (!(link = rtnl_link_alloc())) 00101 return -NLE_NOMEM; 00102 00103 if ((err = rtnl_link_set_type(link, "bond")) < 0) 00104 goto errout; 00105 00106 rtnl_link_set_ifindex(link, slave); 00107 rtnl_link_set_master(link, master); 00108 00109 if ((err = rtnl_link_change(sock, link, link, 0)) < 0) 00110 goto errout; 00111 00112 rtnl_link_put(link); 00113 00114 /* 00115 * Due to the kernel not signaling whether this opertion is 00116 * supported or not, we will retrieve the attribute to see if the 00117 * request was successful. If the master assigned remains unchanged 00118 * we will return NLE_OPNOTSUPP to allow performing backwards 00119 * compatibility of some sort. 00120 */ 00121 if ((err = rtnl_link_get_kernel(sock, slave, NULL, &link)) < 0) 00122 return err; 00123 00124 if (rtnl_link_get_master(link) != master) 00125 err = -NLE_OPNOTSUPP; 00126 00127 errout: 00128 rtnl_link_put(link); 00129 00130 return err; 00131 } 00132 00133 /** 00134 * Add a link to a bond (enslave) 00135 * @arg sock netlink socket 00136 * @arg master bonding master 00137 * @arg slave slave link to add to bond 00138 * 00139 * Constructs a RTM_NEWLINK or RTM_SETLINK message adding the slave to 00140 * the master and sends the request via the specified netlink socket. 00141 * 00142 * @note The feature of enslaving/releasing via netlink has only been added 00143 * recently to the kernel (Feb 2011). Also, the kernel does not signal 00144 * if the operation is not supported. Therefore this function will 00145 * verify if the master assignment has changed and will return 00146 * -NLE_OPNOTSUPP if it did not. 00147 * 00148 * @see rtnl_link_bond_enslave_ifindex() 00149 * @see rtnl_link_bond_release() 00150 * 00151 * @return 0 on success or a negative error code. 00152 */ 00153 int rtnl_link_bond_enslave(struct nl_sock *sock, struct rtnl_link *master, 00154 struct rtnl_link *slave) 00155 { 00156 return rtnl_link_bond_enslave_ifindex(sock, 00157 rtnl_link_get_ifindex(master), 00158 rtnl_link_get_ifindex(slave)); 00159 } 00160 00161 /** 00162 * Release a link from a bond 00163 * @arg sock netlink socket 00164 * @arg slave slave link to be released 00165 * 00166 * This function is identical to rtnl_link_bond_release() except that 00167 * it takes an interface index instead of a rtnl_link object. 00168 * 00169 * @see rtnl_link_bond_release() 00170 * 00171 * @return 0 on success or a negative error code. 00172 */ 00173 int rtnl_link_bond_release_ifindex(struct nl_sock *sock, int slave) 00174 { 00175 return rtnl_link_bond_enslave_ifindex(sock, 0, slave); 00176 } 00177 00178 /** 00179 * Release a link from a bond 00180 * @arg sock netlink socket 00181 * @arg slave slave link to be released 00182 * 00183 * Constructs a RTM_NEWLINK or RTM_SETLINK message releasing the slave from 00184 * its master and sends the request via the specified netlink socket. 00185 * 00186 * @note The feature of enslaving/releasing via netlink has only been added 00187 * recently to the kernel (Feb 2011). Also, the kernel does not signal 00188 * if the operation is not supported. Therefore this function will 00189 * verify if the master assignment has changed and will return 00190 * -NLE_OPNOTSUPP if it did not. 00191 * 00192 * @see rtnl_link_bond_release_ifindex() 00193 * @see rtnl_link_bond_enslave() 00194 * 00195 * @return 0 on success or a negative error code. 00196 */ 00197 int rtnl_link_bond_release(struct nl_sock *sock, struct rtnl_link *slave) 00198 { 00199 return rtnl_link_bond_release_ifindex(sock, 00200 rtnl_link_get_ifindex(slave)); 00201 } 00202 00203 static struct rtnl_link_info_ops bonding_info_ops = { 00204 .io_name = "bond", 00205 }; 00206 00207 static void __init bonding_init(void) 00208 { 00209 rtnl_link_register_info(&bonding_info_ops); 00210 } 00211 00212 static void __exit bonding_exit(void) 00213 { 00214 rtnl_link_unregister_info(&bonding_info_ops); 00215 } 00216 00217 /** @} */