1054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/* 2054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * lib/route/link/bonding.c Bonding Link Module 3054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 4054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * This library is free software; you can redistribute it and/or 5054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * modify it under the terms of the GNU Lesser General Public 6054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * License as published by the Free Software Foundation version 2.1 7054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * of the License. 8054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 9054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * Copyright (c) 2011-2013 Thomas Graf <tgraf@suug.ch> 10054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart */ 11054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 12054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** 13054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @ingroup link 14054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @defgroup bonding Bonding 15054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 16054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @details 17054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * \b Link Type Name: "bond" 18054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 19054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @route_doc{link_bonding, Bonding Documentation} 20054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @{ 21054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart */ 22054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 23054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart#include <netlink-private/netlink.h> 24054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart#include <netlink/netlink.h> 25054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart#include <netlink-private/route/link/api.h> 26054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 27054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** 28054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * Allocate link object of type bond 29054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 30054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @return Allocated link object or NULL. 31054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart */ 32054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartstruct rtnl_link *rtnl_link_bond_alloc(void) 33054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 34054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart struct rtnl_link *link; 35054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart int err; 36054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 37054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart if (!(link = rtnl_link_alloc())) 38054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return NULL; 39054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 40054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart if ((err = rtnl_link_set_type(link, "bond")) < 0) { 41054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart rtnl_link_put(link); 42054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return NULL; 43054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart } 44054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 45054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return link; 46054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 47054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 48054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** 49054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * Create a new kernel bonding device 50054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @arg sock netlink socket 51054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @arg name name of bonding device or NULL 52054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @arg opts bonding options (currently unused) 53054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 54054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * Creates a new bonding device in the kernel. If no name is 55054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * provided, the kernel will automatically pick a name of the 56054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * form "type%d" (e.g. bond0, vlan1, etc.) 57054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 58054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * The \a opts argument is currently unused. In the future, it 59054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * may be used to carry additional bonding options to be set 60054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * when creating the bonding device. 61054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 62054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @note When letting the kernel assign a name, it will become 63054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * difficult to retrieve the interface afterwards because 64054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * you have to guess the name the kernel has chosen. It is 65054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * therefore not recommended to not provide a device name. 66054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 67054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @see rtnl_link_bond_enslave() 68054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @see rtnl_link_bond_release() 69054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 70054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @return 0 on success or a negative error code 71054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart */ 72054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartint rtnl_link_bond_add(struct nl_sock *sock, const char *name, 73054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart struct rtnl_link *opts) 74054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 75054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart struct rtnl_link *link; 76054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart int err; 77054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 78054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart if (!(link = rtnl_link_bond_alloc())) 79054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return -NLE_NOMEM; 80054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 81054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart if (!name && opts) 82054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart name = rtnl_link_get_name(opts); 83054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 84054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart if (name) 85054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart rtnl_link_set_name(link, name); 86054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 87054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart err = rtnl_link_add(sock, link, NLM_F_CREATE); 88054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 89054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart rtnl_link_put(link); 90054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 91054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return err; 92054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 93054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 94054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** 95054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * Add a link to a bond (enslave) 96054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @arg sock netlink socket 97054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @arg master ifindex of bonding master 98054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @arg slave ifindex of slave link to add to bond 99054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 100054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * This function is identical to rtnl_link_bond_enslave() except that 101054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * it takes interface indices instead of rtnl_link objcets. 102054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 103054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @see rtnl_link_bond_enslave() 104054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 105054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @return 0 on success or a negative error code. 106054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart */ 107054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartint rtnl_link_bond_enslave_ifindex(struct nl_sock *sock, int master, 108054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart int slave) 109054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 110054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart struct rtnl_link *link; 111054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart int err; 112054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 113054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart if (!(link = rtnl_link_bond_alloc())) 114054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return -NLE_NOMEM; 115054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 116054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart rtnl_link_set_ifindex(link, slave); 117054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart rtnl_link_set_master(link, master); 118054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 119054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart if ((err = rtnl_link_change(sock, link, link, 0)) < 0) 120054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart goto errout; 121054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 122054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart rtnl_link_put(link); 123054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 124054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart /* 125054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * Due to the kernel not signaling whether this opertion is 126054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * supported or not, we will retrieve the attribute to see if the 127054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * request was successful. If the master assigned remains unchanged 128054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * we will return NLE_OPNOTSUPP to allow performing backwards 129054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * compatibility of some sort. 130054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart */ 131054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart if ((err = rtnl_link_get_kernel(sock, slave, NULL, &link)) < 0) 132054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return err; 133054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 134054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart if (rtnl_link_get_master(link) != master) 135054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart err = -NLE_OPNOTSUPP; 136054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 137054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewarterrout: 138054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart rtnl_link_put(link); 139054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 140054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return err; 141054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 142054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 143054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** 144054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * Add a link to a bond (enslave) 145054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @arg sock netlink socket 146054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @arg master bonding master 147054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @arg slave slave link to add to bond 148054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 149054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * Constructs a RTM_NEWLINK or RTM_SETLINK message adding the slave to 150054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * the master and sends the request via the specified netlink socket. 151054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 152054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @note The feature of enslaving/releasing via netlink has only been added 153054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * recently to the kernel (Feb 2011). Also, the kernel does not signal 154054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * if the operation is not supported. Therefore this function will 155054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * verify if the master assignment has changed and will return 156054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * -NLE_OPNOTSUPP if it did not. 157054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 158054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @see rtnl_link_bond_enslave_ifindex() 159054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @see rtnl_link_bond_release() 160054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 161054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @return 0 on success or a negative error code. 162054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart */ 163054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartint rtnl_link_bond_enslave(struct nl_sock *sock, struct rtnl_link *master, 164054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart struct rtnl_link *slave) 165054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 166054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return rtnl_link_bond_enslave_ifindex(sock, 167054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart rtnl_link_get_ifindex(master), 168054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart rtnl_link_get_ifindex(slave)); 169054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 170054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 171054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** 172054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * Release a link from a bond 173054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @arg sock netlink socket 174054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @arg slave slave link to be released 175054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 176054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * This function is identical to rtnl_link_bond_release() except that 177054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * it takes an interface index instead of a rtnl_link object. 178054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 179054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @see rtnl_link_bond_release() 180054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 181054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @return 0 on success or a negative error code. 182054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart */ 183054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartint rtnl_link_bond_release_ifindex(struct nl_sock *sock, int slave) 184054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 185054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return rtnl_link_bond_enslave_ifindex(sock, 0, slave); 186054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 187054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 188054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** 189054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * Release a link from a bond 190054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @arg sock netlink socket 191054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @arg slave slave link to be released 192054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 193054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * Constructs a RTM_NEWLINK or RTM_SETLINK message releasing the slave from 194054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * its master and sends the request via the specified netlink socket. 195054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 196054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @note The feature of enslaving/releasing via netlink has only been added 197054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * recently to the kernel (Feb 2011). Also, the kernel does not signal 198054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * if the operation is not supported. Therefore this function will 199054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * verify if the master assignment has changed and will return 200054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * -NLE_OPNOTSUPP if it did not. 201054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 202054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @see rtnl_link_bond_release_ifindex() 203054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @see rtnl_link_bond_enslave() 204054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * 205054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @return 0 on success or a negative error code. 206054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart */ 207054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartint rtnl_link_bond_release(struct nl_sock *sock, struct rtnl_link *slave) 208054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 209054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart return rtnl_link_bond_release_ifindex(sock, 210054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart rtnl_link_get_ifindex(slave)); 211054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 212054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 213054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartstatic struct rtnl_link_info_ops bonding_info_ops = { 214054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart .io_name = "bond", 215054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart}; 216054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 217054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartstatic void __init bonding_init(void) 218054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 219054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart rtnl_link_register_info(&bonding_info_ops); 220054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 221054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 222054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewartstatic void __exit bonding_exit(void) 223054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart{ 224054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart rtnl_link_unregister_info(&bonding_info_ops); 225054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart} 226054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart 227054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart/** @} */ 228