libnl
3.2.7
|
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 00065 if ((err = rtnl_link_set_type(link, "bond")) < 0) 00066 goto errout; 00067 00068 if (name) 00069 rtnl_link_set_name(link, name); 00070 00071 err = rtnl_link_add(sock, link, NLM_F_CREATE); 00072 errout: 00073 rtnl_link_put(link); 00074 00075 return err; 00076 } 00077 00078 /** 00079 * Add a link to a bond (enslave) 00080 * @arg sock netlink socket 00081 * @arg master ifindex of bonding master 00082 * @arg slave ifindex of slave link to add to bond 00083 * 00084 * This function is identical to rtnl_link_bond_enslave() except that 00085 * it takes interface indices instead of rtnl_link objcets. 00086 * 00087 * @see rtnl_link_bond_enslave() 00088 * 00089 * @return 0 on success or a negative error code. 00090 */ 00091 int rtnl_link_bond_enslave_ifindex(struct nl_sock *sock, int master, 00092 int slave) 00093 { 00094 struct rtnl_link *link; 00095 int err; 00096 00097 if (!(link = rtnl_link_alloc())) 00098 return -NLE_NOMEM; 00099 00100 if ((err = rtnl_link_set_type(link, "bond")) < 0) 00101 goto errout; 00102 00103 rtnl_link_set_ifindex(link, slave); 00104 rtnl_link_set_master(link, master); 00105 00106 if ((err = rtnl_link_change(sock, link, link, 0)) < 0) 00107 goto errout; 00108 00109 rtnl_link_put(link); 00110 00111 /* 00112 * Due to the kernel not signaling whether this opertion is 00113 * supported or not, we will retrieve the attribute to see if the 00114 * request was successful. If the master assigned remains unchanged 00115 * we will return NLE_OPNOTSUPP to allow performing backwards 00116 * compatibility of some sort. 00117 */ 00118 if ((err = rtnl_link_get_kernel(sock, slave, NULL, &link)) < 0) 00119 return err; 00120 00121 if (rtnl_link_get_master(link) != master) 00122 err = -NLE_OPNOTSUPP; 00123 00124 errout: 00125 rtnl_link_put(link); 00126 00127 return err; 00128 } 00129 00130 /** 00131 * Add a link to a bond (enslave) 00132 * @arg sock netlink socket 00133 * @arg master bonding master 00134 * @arg slave slave link to add to bond 00135 * 00136 * Constructs a RTM_NEWLINK or RTM_SETLINK message adding the slave to 00137 * the master and sends the request via the specified netlink socket. 00138 * 00139 * @note The feature of enslaving/releasing via netlink has only been added 00140 * recently to the kernel (Feb 2011). Also, the kernel does not signal 00141 * if the operation is not supported. Therefore this function will 00142 * verify if the master assignment has changed and will return 00143 * -NLE_OPNOTSUPP if it did not. 00144 * 00145 * @see rtnl_link_bond_enslave_ifindex() 00146 * @see rtnl_link_bond_release() 00147 * 00148 * @return 0 on success or a negative error code. 00149 */ 00150 int rtnl_link_bond_enslave(struct nl_sock *sock, struct rtnl_link *master, 00151 struct rtnl_link *slave) 00152 { 00153 return rtnl_link_bond_enslave_ifindex(sock, 00154 rtnl_link_get_ifindex(master), 00155 rtnl_link_get_ifindex(slave)); 00156 } 00157 00158 /** 00159 * Release a link from a bond 00160 * @arg sock netlink socket 00161 * @arg slave slave link to be released 00162 * 00163 * This function is identical to rtnl_link_bond_release() except that 00164 * it takes an interface index instead of a rtnl_link object. 00165 * 00166 * @see rtnl_link_bond_release() 00167 * 00168 * @return 0 on success or a negative error code. 00169 */ 00170 int rtnl_link_bond_release_ifindex(struct nl_sock *sock, int slave) 00171 { 00172 return rtnl_link_bond_enslave_ifindex(sock, 0, slave); 00173 } 00174 00175 /** 00176 * Release a link from a bond 00177 * @arg sock netlink socket 00178 * @arg slave slave link to be released 00179 * 00180 * Constructs a RTM_NEWLINK or RTM_SETLINK message releasing the slave from 00181 * its master and sends the request via the specified netlink socket. 00182 * 00183 * @note The feature of enslaving/releasing via netlink has only been added 00184 * recently to the kernel (Feb 2011). Also, the kernel does not signal 00185 * if the operation is not supported. Therefore this function will 00186 * verify if the master assignment has changed and will return 00187 * -NLE_OPNOTSUPP if it did not. 00188 * 00189 * @see rtnl_link_bond_release_ifindex() 00190 * @see rtnl_link_bond_enslave() 00191 * 00192 * @return 0 on success or a negative error code. 00193 */ 00194 int rtnl_link_bond_release(struct nl_sock *sock, struct rtnl_link *slave) 00195 { 00196 return rtnl_link_bond_release_ifindex(sock, 00197 rtnl_link_get_ifindex(slave)); 00198 } 00199 00200 static struct rtnl_link_info_ops bonding_info_ops = { 00201 .io_name = "bond", 00202 }; 00203 00204 static void __init bonding_init(void) 00205 { 00206 rtnl_link_register_info(&bonding_info_ops); 00207 } 00208 00209 static void __exit bonding_exit(void) 00210 { 00211 rtnl_link_unregister_info(&bonding_info_ops); 00212 } 00213 00214 /** @} */