diff options
author | Jay Vosburgh <fubar@us.ibm.com> | 2005-09-26 19:11:50 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-10-03 22:15:00 -0400 |
commit | 217df670d9a4da036d68b22500ac06128811d5c8 (patch) | |
tree | b944f0379c1e513ca2d663f6dc0b5d226e9bdd73 | |
parent | 9123e0d78990246304fe681167b8d8097f1e02d7 (diff) |
[PATCH] fix bonding crash, remove old ABI support
David S. Miller <davem@davemloft.net> wrote:
>I think removing support for older ifenslave binaries is
>the least painful solution to this problem.
This patch removes backwards compatibility for old ifenslave
binaries (ifenslave prior to verison 1.0.0).
I did not similarly modify ifenslave itself; with sysfs on the
horizon, I don't see that as being worthwhile.
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
-rw-r--r-- | drivers/net/bonding/bond_main.c | 280 | ||||
-rw-r--r-- | drivers/net/bonding/bonding.h | 4 |
2 files changed, 71 insertions, 213 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index bf81cd45e4d4..fd62e43a3510 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -487,6 +487,8 @@ | |||
487 | * * Added xmit_hash_policy_layer34() | 487 | * * Added xmit_hash_policy_layer34() |
488 | * - Modified by Jay Vosburgh <fubar@us.ibm.com> to also support mode 4. | 488 | * - Modified by Jay Vosburgh <fubar@us.ibm.com> to also support mode 4. |
489 | * Set version to 2.6.3. | 489 | * Set version to 2.6.3. |
490 | * 2005/09/26 - Jay Vosburgh <fubar@us.ibm.com> | ||
491 | * - Removed backwards compatibility for old ifenslaves. Version 2.6.4. | ||
490 | */ | 492 | */ |
491 | 493 | ||
492 | //#define BONDING_DEBUG 1 | 494 | //#define BONDING_DEBUG 1 |
@@ -595,14 +597,7 @@ static int arp_ip_count = 0; | |||
595 | static int bond_mode = BOND_MODE_ROUNDROBIN; | 597 | static int bond_mode = BOND_MODE_ROUNDROBIN; |
596 | static int xmit_hashtype= BOND_XMIT_POLICY_LAYER2; | 598 | static int xmit_hashtype= BOND_XMIT_POLICY_LAYER2; |
597 | static int lacp_fast = 0; | 599 | static int lacp_fast = 0; |
598 | static int app_abi_ver = 0; | 600 | |
599 | static int orig_app_abi_ver = -1; /* This is used to save the first ABI version | ||
600 | * we receive from the application. Once set, | ||
601 | * it won't be changed, and the module will | ||
602 | * refuse to enslave/release interfaces if the | ||
603 | * command comes from an application using | ||
604 | * another ABI version. | ||
605 | */ | ||
606 | struct bond_parm_tbl { | 601 | struct bond_parm_tbl { |
607 | char *modename; | 602 | char *modename; |
608 | int mode; | 603 | int mode; |
@@ -1702,51 +1697,29 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de | |||
1702 | } | 1697 | } |
1703 | } | 1698 | } |
1704 | 1699 | ||
1705 | if (app_abi_ver >= 1) { | 1700 | /* |
1706 | /* The application is using an ABI, which requires the | 1701 | * Old ifenslave binaries are no longer supported. These can |
1707 | * slave interface to be closed. | 1702 | * be identified with moderate accurary by the state of the slave: |
1708 | */ | 1703 | * the current ifenslave will set the interface down prior to |
1709 | if ((slave_dev->flags & IFF_UP)) { | 1704 | * enslaving it; the old ifenslave will not. |
1710 | printk(KERN_ERR DRV_NAME | 1705 | */ |
1711 | ": Error: %s is up\n", | 1706 | if ((slave_dev->flags & IFF_UP)) { |
1712 | slave_dev->name); | 1707 | printk(KERN_ERR DRV_NAME ": %s is up. " |
1713 | res = -EPERM; | 1708 | "This may be due to an out of date ifenslave.\n", |
1714 | goto err_undo_flags; | 1709 | slave_dev->name); |
1715 | } | 1710 | res = -EPERM; |
1716 | 1711 | goto err_undo_flags; | |
1717 | if (slave_dev->set_mac_address == NULL) { | 1712 | } |
1718 | printk(KERN_ERR DRV_NAME | ||
1719 | ": Error: The slave device you specified does " | ||
1720 | "not support setting the MAC address.\n"); | ||
1721 | printk(KERN_ERR | ||
1722 | "Your kernel likely does not support slave " | ||
1723 | "devices.\n"); | ||
1724 | 1713 | ||
1725 | res = -EOPNOTSUPP; | 1714 | if (slave_dev->set_mac_address == NULL) { |
1726 | goto err_undo_flags; | 1715 | printk(KERN_ERR DRV_NAME |
1727 | } | 1716 | ": Error: The slave device you specified does " |
1728 | } else { | 1717 | "not support setting the MAC address.\n"); |
1729 | /* The application is not using an ABI, which requires the | 1718 | printk(KERN_ERR |
1730 | * slave interface to be open. | 1719 | "Your kernel likely does not support slave devices.\n"); |
1731 | */ | ||
1732 | if (!(slave_dev->flags & IFF_UP)) { | ||
1733 | printk(KERN_ERR DRV_NAME | ||
1734 | ": Error: %s is not running\n", | ||
1735 | slave_dev->name); | ||
1736 | res = -EINVAL; | ||
1737 | goto err_undo_flags; | ||
1738 | } | ||
1739 | 1720 | ||
1740 | if ((bond->params.mode == BOND_MODE_8023AD) || | 1721 | res = -EOPNOTSUPP; |
1741 | (bond->params.mode == BOND_MODE_TLB) || | 1722 | goto err_undo_flags; |
1742 | (bond->params.mode == BOND_MODE_ALB)) { | ||
1743 | printk(KERN_ERR DRV_NAME | ||
1744 | ": Error: to use %s mode, you must upgrade " | ||
1745 | "ifenslave.\n", | ||
1746 | bond_mode_name(bond->params.mode)); | ||
1747 | res = -EOPNOTSUPP; | ||
1748 | goto err_undo_flags; | ||
1749 | } | ||
1750 | } | 1723 | } |
1751 | 1724 | ||
1752 | new_slave = kmalloc(sizeof(struct slave), GFP_KERNEL); | 1725 | new_slave = kmalloc(sizeof(struct slave), GFP_KERNEL); |
@@ -1762,41 +1735,36 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de | |||
1762 | */ | 1735 | */ |
1763 | new_slave->original_flags = slave_dev->flags; | 1736 | new_slave->original_flags = slave_dev->flags; |
1764 | 1737 | ||
1765 | if (app_abi_ver >= 1) { | 1738 | /* |
1766 | /* save slave's original ("permanent") mac address for | 1739 | * Save slave's original ("permanent") mac address for modes |
1767 | * modes that needs it, and for restoring it upon release, | 1740 | * that need it, and for restoring it upon release, and then |
1768 | * and then set it to the master's address | 1741 | * set it to the master's address |
1769 | */ | 1742 | */ |
1770 | memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN); | 1743 | memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN); |
1771 | 1744 | ||
1772 | /* set slave to master's mac address | 1745 | /* |
1773 | * The application already set the master's | 1746 | * Set slave to master's mac address. The application already |
1774 | * mac address to that of the first slave | 1747 | * set the master's mac address to that of the first slave |
1775 | */ | 1748 | */ |
1776 | memcpy(addr.sa_data, bond_dev->dev_addr, bond_dev->addr_len); | 1749 | memcpy(addr.sa_data, bond_dev->dev_addr, bond_dev->addr_len); |
1777 | addr.sa_family = slave_dev->type; | 1750 | addr.sa_family = slave_dev->type; |
1778 | res = dev_set_mac_address(slave_dev, &addr); | 1751 | res = dev_set_mac_address(slave_dev, &addr); |
1779 | if (res) { | 1752 | if (res) { |
1780 | dprintk("Error %d calling set_mac_address\n", res); | 1753 | dprintk("Error %d calling set_mac_address\n", res); |
1781 | goto err_free; | 1754 | goto err_free; |
1782 | } | 1755 | } |
1783 | 1756 | ||
1784 | /* open the slave since the application closed it */ | 1757 | /* open the slave since the application closed it */ |
1785 | res = dev_open(slave_dev); | 1758 | res = dev_open(slave_dev); |
1786 | if (res) { | 1759 | if (res) { |
1787 | dprintk("Openning slave %s failed\n", slave_dev->name); | 1760 | dprintk("Openning slave %s failed\n", slave_dev->name); |
1788 | goto err_restore_mac; | 1761 | goto err_restore_mac; |
1789 | } | ||
1790 | } | 1762 | } |
1791 | 1763 | ||
1792 | res = netdev_set_master(slave_dev, bond_dev); | 1764 | res = netdev_set_master(slave_dev, bond_dev); |
1793 | if (res) { | 1765 | if (res) { |
1794 | dprintk("Error %d calling netdev_set_master\n", res); | 1766 | dprintk("Error %d calling netdev_set_master\n", res); |
1795 | if (app_abi_ver < 1) { | 1767 | goto err_close; |
1796 | goto err_free; | ||
1797 | } else { | ||
1798 | goto err_close; | ||
1799 | } | ||
1800 | } | 1768 | } |
1801 | 1769 | ||
1802 | new_slave->dev = slave_dev; | 1770 | new_slave->dev = slave_dev; |
@@ -1997,39 +1965,6 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de | |||
1997 | 1965 | ||
1998 | write_unlock_bh(&bond->lock); | 1966 | write_unlock_bh(&bond->lock); |
1999 | 1967 | ||
2000 | if (app_abi_ver < 1) { | ||
2001 | /* | ||
2002 | * !!! This is to support old versions of ifenslave. | ||
2003 | * We can remove this in 2.5 because our ifenslave takes | ||
2004 | * care of this for us. | ||
2005 | * We check to see if the master has a mac address yet. | ||
2006 | * If not, we'll give it the mac address of our slave device. | ||
2007 | */ | ||
2008 | int ndx = 0; | ||
2009 | |||
2010 | for (ndx = 0; ndx < bond_dev->addr_len; ndx++) { | ||
2011 | dprintk("Checking ndx=%d of bond_dev->dev_addr\n", | ||
2012 | ndx); | ||
2013 | if (bond_dev->dev_addr[ndx] != 0) { | ||
2014 | dprintk("Found non-zero byte at ndx=%d\n", | ||
2015 | ndx); | ||
2016 | break; | ||
2017 | } | ||
2018 | } | ||
2019 | |||
2020 | if (ndx == bond_dev->addr_len) { | ||
2021 | /* | ||
2022 | * We got all the way through the address and it was | ||
2023 | * all 0's. | ||
2024 | */ | ||
2025 | dprintk("%s doesn't have a MAC address yet. \n", | ||
2026 | bond_dev->name); | ||
2027 | dprintk("Going to give assign it from %s.\n", | ||
2028 | slave_dev->name); | ||
2029 | bond_sethwaddr(bond_dev, slave_dev); | ||
2030 | } | ||
2031 | } | ||
2032 | |||
2033 | printk(KERN_INFO DRV_NAME | 1968 | printk(KERN_INFO DRV_NAME |
2034 | ": %s: enslaving %s as a%s interface with a%s link.\n", | 1969 | ": %s: enslaving %s as a%s interface with a%s link.\n", |
2035 | bond_dev->name, slave_dev->name, | 1970 | bond_dev->name, slave_dev->name, |
@@ -2227,12 +2162,10 @@ static int bond_release(struct net_device *bond_dev, struct net_device *slave_de | |||
2227 | /* close slave before restoring its mac address */ | 2162 | /* close slave before restoring its mac address */ |
2228 | dev_close(slave_dev); | 2163 | dev_close(slave_dev); |
2229 | 2164 | ||
2230 | if (app_abi_ver >= 1) { | 2165 | /* restore original ("permanent") mac address */ |
2231 | /* restore original ("permanent") mac address */ | 2166 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); |
2232 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); | 2167 | addr.sa_family = slave_dev->type; |
2233 | addr.sa_family = slave_dev->type; | 2168 | dev_set_mac_address(slave_dev, &addr); |
2234 | dev_set_mac_address(slave_dev, &addr); | ||
2235 | } | ||
2236 | 2169 | ||
2237 | /* restore the original state of the | 2170 | /* restore the original state of the |
2238 | * IFF_NOARP flag that might have been | 2171 | * IFF_NOARP flag that might have been |
@@ -2320,12 +2253,10 @@ static int bond_release_all(struct net_device *bond_dev) | |||
2320 | /* close slave before restoring its mac address */ | 2253 | /* close slave before restoring its mac address */ |
2321 | dev_close(slave_dev); | 2254 | dev_close(slave_dev); |
2322 | 2255 | ||
2323 | if (app_abi_ver >= 1) { | 2256 | /* restore original ("permanent") mac address*/ |
2324 | /* restore original ("permanent") mac address*/ | 2257 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); |
2325 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); | 2258 | addr.sa_family = slave_dev->type; |
2326 | addr.sa_family = slave_dev->type; | 2259 | dev_set_mac_address(slave_dev, &addr); |
2327 | dev_set_mac_address(slave_dev, &addr); | ||
2328 | } | ||
2329 | 2260 | ||
2330 | /* restore the original state of the IFF_NOARP flag that might have | 2261 | /* restore the original state of the IFF_NOARP flag that might have |
2331 | * been set by bond_set_slave_inactive_flags() | 2262 | * been set by bond_set_slave_inactive_flags() |
@@ -2423,57 +2354,6 @@ static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_devi | |||
2423 | return res; | 2354 | return res; |
2424 | } | 2355 | } |
2425 | 2356 | ||
2426 | static int bond_ethtool_ioctl(struct net_device *bond_dev, struct ifreq *ifr) | ||
2427 | { | ||
2428 | struct ethtool_drvinfo info; | ||
2429 | void __user *addr = ifr->ifr_data; | ||
2430 | uint32_t cmd; | ||
2431 | |||
2432 | if (get_user(cmd, (uint32_t __user *)addr)) { | ||
2433 | return -EFAULT; | ||
2434 | } | ||
2435 | |||
2436 | switch (cmd) { | ||
2437 | case ETHTOOL_GDRVINFO: | ||
2438 | if (copy_from_user(&info, addr, sizeof(info))) { | ||
2439 | return -EFAULT; | ||
2440 | } | ||
2441 | |||
2442 | if (strcmp(info.driver, "ifenslave") == 0) { | ||
2443 | int new_abi_ver; | ||
2444 | char *endptr; | ||
2445 | |||
2446 | new_abi_ver = simple_strtoul(info.fw_version, | ||
2447 | &endptr, 0); | ||
2448 | if (*endptr) { | ||
2449 | printk(KERN_ERR DRV_NAME | ||
2450 | ": Error: got invalid ABI " | ||
2451 | "version from application\n"); | ||
2452 | |||
2453 | return -EINVAL; | ||
2454 | } | ||
2455 | |||
2456 | if (orig_app_abi_ver == -1) { | ||
2457 | orig_app_abi_ver = new_abi_ver; | ||
2458 | } | ||
2459 | |||
2460 | app_abi_ver = new_abi_ver; | ||
2461 | } | ||
2462 | |||
2463 | strncpy(info.driver, DRV_NAME, 32); | ||
2464 | strncpy(info.version, DRV_VERSION, 32); | ||
2465 | snprintf(info.fw_version, 32, "%d", BOND_ABI_VERSION); | ||
2466 | |||
2467 | if (copy_to_user(addr, &info, sizeof(info))) { | ||
2468 | return -EFAULT; | ||
2469 | } | ||
2470 | |||
2471 | return 0; | ||
2472 | default: | ||
2473 | return -EOPNOTSUPP; | ||
2474 | } | ||
2475 | } | ||
2476 | |||
2477 | static int bond_info_query(struct net_device *bond_dev, struct ifbond *info) | 2357 | static int bond_info_query(struct net_device *bond_dev, struct ifbond *info) |
2478 | { | 2358 | { |
2479 | struct bonding *bond = bond_dev->priv; | 2359 | struct bonding *bond = bond_dev->priv; |
@@ -3442,16 +3322,11 @@ static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave | |||
3442 | seq_printf(seq, "Link Failure Count: %d\n", | 3322 | seq_printf(seq, "Link Failure Count: %d\n", |
3443 | slave->link_failure_count); | 3323 | slave->link_failure_count); |
3444 | 3324 | ||
3445 | if (app_abi_ver >= 1) { | 3325 | seq_printf(seq, |
3446 | seq_printf(seq, | 3326 | "Permanent HW addr: %02x:%02x:%02x:%02x:%02x:%02x\n", |
3447 | "Permanent HW addr: %02x:%02x:%02x:%02x:%02x:%02x\n", | 3327 | slave->perm_hwaddr[0], slave->perm_hwaddr[1], |
3448 | slave->perm_hwaddr[0], | 3328 | slave->perm_hwaddr[2], slave->perm_hwaddr[3], |
3449 | slave->perm_hwaddr[1], | 3329 | slave->perm_hwaddr[4], slave->perm_hwaddr[5]); |
3450 | slave->perm_hwaddr[2], | ||
3451 | slave->perm_hwaddr[3], | ||
3452 | slave->perm_hwaddr[4], | ||
3453 | slave->perm_hwaddr[5]); | ||
3454 | } | ||
3455 | 3330 | ||
3456 | if (bond->params.mode == BOND_MODE_8023AD) { | 3331 | if (bond->params.mode == BOND_MODE_8023AD) { |
3457 | const struct aggregator *agg | 3332 | const struct aggregator *agg |
@@ -4010,15 +3885,12 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd | |||
4010 | struct ifslave k_sinfo; | 3885 | struct ifslave k_sinfo; |
4011 | struct ifslave __user *u_sinfo = NULL; | 3886 | struct ifslave __user *u_sinfo = NULL; |
4012 | struct mii_ioctl_data *mii = NULL; | 3887 | struct mii_ioctl_data *mii = NULL; |
4013 | int prev_abi_ver = orig_app_abi_ver; | ||
4014 | int res = 0; | 3888 | int res = 0; |
4015 | 3889 | ||
4016 | dprintk("bond_ioctl: master=%s, cmd=%d\n", | 3890 | dprintk("bond_ioctl: master=%s, cmd=%d\n", |
4017 | bond_dev->name, cmd); | 3891 | bond_dev->name, cmd); |
4018 | 3892 | ||
4019 | switch (cmd) { | 3893 | switch (cmd) { |
4020 | case SIOCETHTOOL: | ||
4021 | return bond_ethtool_ioctl(bond_dev, ifr); | ||
4022 | case SIOCGMIIPHY: | 3894 | case SIOCGMIIPHY: |
4023 | mii = if_mii(ifr); | 3895 | mii = if_mii(ifr); |
4024 | if (!mii) { | 3896 | if (!mii) { |
@@ -4090,21 +3962,6 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd | |||
4090 | return -EPERM; | 3962 | return -EPERM; |
4091 | } | 3963 | } |
4092 | 3964 | ||
4093 | if (orig_app_abi_ver == -1) { | ||
4094 | /* no orig_app_abi_ver was provided yet, so we'll use the | ||
4095 | * current one from now on, even if it's 0 | ||
4096 | */ | ||
4097 | orig_app_abi_ver = app_abi_ver; | ||
4098 | |||
4099 | } else if (orig_app_abi_ver != app_abi_ver) { | ||
4100 | printk(KERN_ERR DRV_NAME | ||
4101 | ": Error: already using ifenslave ABI version %d; to " | ||
4102 | "upgrade ifenslave to version %d, you must first " | ||
4103 | "reload bonding.\n", | ||
4104 | orig_app_abi_ver, app_abi_ver); | ||
4105 | return -EINVAL; | ||
4106 | } | ||
4107 | |||
4108 | slave_dev = dev_get_by_name(ifr->ifr_slave); | 3965 | slave_dev = dev_get_by_name(ifr->ifr_slave); |
4109 | 3966 | ||
4110 | dprintk("slave_dev=%p: \n", slave_dev); | 3967 | dprintk("slave_dev=%p: \n", slave_dev); |
@@ -4137,14 +3994,6 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd | |||
4137 | dev_put(slave_dev); | 3994 | dev_put(slave_dev); |
4138 | } | 3995 | } |
4139 | 3996 | ||
4140 | if (res < 0) { | ||
4141 | /* The ioctl failed, so there's no point in changing the | ||
4142 | * orig_app_abi_ver. We'll restore it's value just in case | ||
4143 | * we've changed it earlier in this function. | ||
4144 | */ | ||
4145 | orig_app_abi_ver = prev_abi_ver; | ||
4146 | } | ||
4147 | |||
4148 | return res; | 3997 | return res; |
4149 | } | 3998 | } |
4150 | 3999 | ||
@@ -4578,9 +4427,18 @@ static inline void bond_set_mode_ops(struct bonding *bond, int mode) | |||
4578 | } | 4427 | } |
4579 | } | 4428 | } |
4580 | 4429 | ||
4430 | static void bond_ethtool_get_drvinfo(struct net_device *bond_dev, | ||
4431 | struct ethtool_drvinfo *drvinfo) | ||
4432 | { | ||
4433 | strncpy(drvinfo->driver, DRV_NAME, 32); | ||
4434 | strncpy(drvinfo->version, DRV_VERSION, 32); | ||
4435 | snprintf(drvinfo->fw_version, 32, "%d", BOND_ABI_VERSION); | ||
4436 | } | ||
4437 | |||
4581 | static struct ethtool_ops bond_ethtool_ops = { | 4438 | static struct ethtool_ops bond_ethtool_ops = { |
4582 | .get_tx_csum = ethtool_op_get_tx_csum, | 4439 | .get_tx_csum = ethtool_op_get_tx_csum, |
4583 | .get_sg = ethtool_op_get_sg, | 4440 | .get_sg = ethtool_op_get_sg, |
4441 | .get_drvinfo = bond_ethtool_get_drvinfo, | ||
4584 | }; | 4442 | }; |
4585 | 4443 | ||
4586 | /* | 4444 | /* |
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 388196980862..bbf9da8af624 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
@@ -40,8 +40,8 @@ | |||
40 | #include "bond_3ad.h" | 40 | #include "bond_3ad.h" |
41 | #include "bond_alb.h" | 41 | #include "bond_alb.h" |
42 | 42 | ||
43 | #define DRV_VERSION "2.6.3" | 43 | #define DRV_VERSION "2.6.4" |
44 | #define DRV_RELDATE "June 8, 2005" | 44 | #define DRV_RELDATE "September 26, 2005" |
45 | #define DRV_NAME "bonding" | 45 | #define DRV_NAME "bonding" |
46 | #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" | 46 | #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" |
47 | 47 | ||