static int enslave(char *master_ifname, char *slave_ifname) { struct ifreq ifr; int res = 0; if (slave_flags.ifr_flags & IFF_SLAVE) { fprintf(stderr, "Illegal operation: The specified slave interface " "'%s' is already a slave\n", slave_ifname); return 1; } res = set_if_down(slave_ifname, slave_flags.ifr_flags); if (res) { fprintf(stderr, "Slave '%s': Error: bring interface down failed\n", slave_ifname); return res; } if (abi_ver < 2) { /* Older bonding versions would panic if the slave has no IP * address, so get the IP setting from the master. */ set_if_addr(master_ifname, slave_ifname); } else { res = clear_if_addr(slave_ifname); if (res) { fprintf(stderr, "Slave '%s': Error: clear address failed\n", slave_ifname); return res; } } if (master_mtu.ifr_mtu != slave_mtu.ifr_mtu) { res = set_slave_mtu(slave_ifname, master_mtu.ifr_mtu); if (res) { fprintf(stderr, "Slave '%s': Error: set MTU failed\n", slave_ifname); return res; } } if (hwaddr_set) { /* Master already has an hwaddr * so set it's hwaddr to the slave */ if (abi_ver < 1) { /* The driver is using an old ABI, so * the application sets the slave's * hwaddr */ res = set_slave_hwaddr(slave_ifname, &(master_hwaddr.ifr_hwaddr)); if (res) { fprintf(stderr, "Slave '%s': Error: set hw address " "failed\n", slave_ifname); goto undo_mtu; } /* For old ABI the application needs to bring the * slave back up */ res = set_if_up(slave_ifname, slave_flags.ifr_flags); if (res) { fprintf(stderr, "Slave '%s': Error: bring interface " "down failed\n", slave_ifname); goto undo_slave_mac; } } /* The driver is using a new ABI, * so the driver takes care of setting * the slave's hwaddr and bringing * it up again */ } else { /* No hwaddr for master yet, so * set the slave's hwaddr to it */ if (abi_ver < 1) { /* For old ABI, the master needs to be * down before setting its hwaddr */ res = set_if_down(master_ifname, master_flags.ifr_flags); if (res) { fprintf(stderr, "Master '%s': Error: bring interface " "down failed\n", master_ifname); goto undo_mtu; } } res = set_master_hwaddr(master_ifname, &(slave_hwaddr.ifr_hwaddr)); if (res) { fprintf(stderr, "Master '%s': Error: set hw address " "failed\n", master_ifname); goto undo_mtu; } if (abi_ver < 1) { /* For old ABI, bring the master * back up */ res = set_if_up(master_ifname, master_flags.ifr_flags); if (res) { fprintf(stderr, "Master '%s': Error: bring interface " "up failed\n", master_ifname); goto undo_master_mac; } } hwaddr_set = 1; } /* Do the real thing */ strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ); strncpy(ifr.ifr_slave, slave_ifname, IFNAMSIZ); if ((ioctl(skfd, SIOCBONDENSLAVE, &ifr) < 0) && (ioctl(skfd, BOND_ENSLAVE_OLD, &ifr) < 0)) { saved_errno = errno; v_print("Master '%s': Error: SIOCBONDENSLAVE failed: %s\n", master_ifname, strerror(saved_errno)); res = 1; } if (res) { goto undo_master_mac; } return 0; /* rollback (best effort) */ undo_master_mac: set_master_hwaddr(master_ifname, &(master_hwaddr.ifr_hwaddr)); hwaddr_set = 0; goto undo_mtu; undo_slave_mac: set_slave_hwaddr(slave_ifname, &(slave_hwaddr.ifr_hwaddr)); undo_mtu: set_slave_mtu(slave_ifname, slave_mtu.ifr_mtu); return res; }
static int enslave(char *master_ifname, char *slave_ifname) { struct ifreq ifr; int res = 0; if (slave_flags.ifr_flags & IFF_SLAVE) { fprintf(stderr, "Illegal operation: The specified slave interface " "'%s' is already a slave\n", slave_ifname); return 1; } res = set_if_down(slave_ifname, slave_flags.ifr_flags); if (res) { fprintf(stderr, "Slave '%s': Error: bring interface down failed\n", slave_ifname); return res; } if (abi_ver < 2) { /* */ set_if_addr(master_ifname, slave_ifname); } else { res = clear_if_addr(slave_ifname); if (res) { fprintf(stderr, "Slave '%s': Error: clear address failed\n", slave_ifname); return res; } } if (master_mtu.ifr_mtu != slave_mtu.ifr_mtu) { res = set_slave_mtu(slave_ifname, master_mtu.ifr_mtu); if (res) { fprintf(stderr, "Slave '%s': Error: set MTU failed\n", slave_ifname); return res; } } if (hwaddr_set) { /* */ if (abi_ver < 1) { /* */ res = set_slave_hwaddr(slave_ifname, &(master_hwaddr.ifr_hwaddr)); if (res) { fprintf(stderr, "Slave '%s': Error: set hw address " "failed\n", slave_ifname); goto undo_mtu; } /* */ res = set_if_up(slave_ifname, slave_flags.ifr_flags); if (res) { fprintf(stderr, "Slave '%s': Error: bring interface " "down failed\n", slave_ifname); goto undo_slave_mac; } } /* */ } else { /* */ if (abi_ver < 1) { /* */ res = set_if_down(master_ifname, master_flags.ifr_flags); if (res) { fprintf(stderr, "Master '%s': Error: bring interface " "down failed\n", master_ifname); goto undo_mtu; } } res = set_master_hwaddr(master_ifname, &(slave_hwaddr.ifr_hwaddr)); if (res) { fprintf(stderr, "Master '%s': Error: set hw address " "failed\n", master_ifname); goto undo_mtu; } if (abi_ver < 1) { /* */ res = set_if_up(master_ifname, master_flags.ifr_flags); if (res) { fprintf(stderr, "Master '%s': Error: bring interface " "up failed\n", master_ifname); goto undo_master_mac; } } hwaddr_set = 1; } /* */ strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ); strncpy(ifr.ifr_slave, slave_ifname, IFNAMSIZ); if ((ioctl(skfd, SIOCBONDENSLAVE, &ifr) < 0) && (ioctl(skfd, BOND_ENSLAVE_OLD, &ifr) < 0)) { saved_errno = errno; v_print("Master '%s': Error: SIOCBONDENSLAVE failed: %s\n", master_ifname, strerror(saved_errno)); res = 1; } if (res) { goto undo_master_mac; } return 0; /* */ undo_master_mac: set_master_hwaddr(master_ifname, &(master_hwaddr.ifr_hwaddr)); hwaddr_set = 0; goto undo_mtu; undo_slave_mac: set_slave_hwaddr(slave_ifname, &(slave_hwaddr.ifr_hwaddr)); undo_mtu: set_slave_mtu(slave_ifname, slave_mtu.ifr_mtu); return res; }