Loading drivers/net/bonding/bond_main.c +251 −32 Original line number Diff line number Diff line Loading @@ -475,7 +475,10 @@ * Solution is to move call to dev_remove_pack outside of the * spinlock. * Set version to 2.6.1. * * 2005/06/05 - Jay Vosburgh <fubar@us.ibm.com> * - Support for generating gratuitous ARPs in active-backup mode. * Includes support for VLAN tagging all bonding-generated ARPs * as needed. Set version to 2.6.2. */ //#define BONDING_DEBUG 1 Loading Loading @@ -519,6 +522,7 @@ #include <linux/ethtool.h> #include <linux/if_vlan.h> #include <linux/if_bonding.h> #include <net/route.h> #include "bonding.h" #include "bond_3ad.h" #include "bond_alb.h" Loading Loading @@ -574,7 +578,6 @@ static struct proc_dir_entry *bond_proc_dir = NULL; static u32 arp_target[BOND_MAX_ARP_TARGETS] = { 0, } ; static int arp_ip_count = 0; static u32 my_ip = 0; static int bond_mode = BOND_MODE_ROUNDROBIN; static int lacp_fast = 0; static int app_abi_ver = 0; Loading Loading @@ -611,6 +614,7 @@ static struct bond_parm_tbl bond_mode_tbl[] = { /*-------------------------- Forward declarations ---------------------------*/ static inline void bond_set_mode_ops(struct net_device *bond_dev, int mode); static void bond_send_gratuitous_arp(struct bonding *bond); /*---------------------------- General routines -----------------------------*/ Loading Loading @@ -659,6 +663,7 @@ static int bond_add_vlan(struct bonding *bond, unsigned short vlan_id) INIT_LIST_HEAD(&vlan->vlan_list); vlan->vlan_id = vlan_id; vlan->vlan_ip = 0; write_lock_bh(&bond->lock); Loading Loading @@ -1468,16 +1473,6 @@ static void bond_change_active_slave(struct bonding *bond, struct slave *new_act } } if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) { if (old_active) { bond_set_slave_inactive_flags(old_active); } if (new_active) { bond_set_slave_active_flags(new_active); } } if (USES_PRIMARY(bond->params.mode)) { bond_mc_swap(bond, new_active, old_active); } Loading @@ -1488,6 +1483,17 @@ static void bond_change_active_slave(struct bonding *bond, struct slave *new_act } else { bond->curr_active_slave = new_active; } if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) { if (old_active) { bond_set_slave_inactive_flags(old_active); } if (new_active) { bond_set_slave_active_flags(new_active); } bond_send_gratuitous_arp(bond); } } /** Loading Loading @@ -2694,15 +2700,180 @@ static void bond_mii_monitor(struct net_device *bond_dev) read_unlock(&bond->lock); } static u32 bond_glean_dev_ip(struct net_device *dev) { struct in_device *idev; struct in_ifaddr *ifa; u32 addr = 0; if (!dev) return 0; rcu_read_lock(); idev = __in_dev_get(dev); if (!idev) goto out; ifa = idev->ifa_list; if (!ifa) goto out; addr = ifa->ifa_local; out: rcu_read_unlock(); return addr; } static int bond_has_ip(struct bonding *bond) { struct vlan_entry *vlan, *vlan_next; if (bond->master_ip) return 1; if (list_empty(&bond->vlan_list)) return 0; list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list, vlan_list) { if (vlan->vlan_ip) return 1; } return 0; } /* * We go to the (large) trouble of VLAN tagging ARP frames because * switches in VLAN mode (especially if ports are configured as * "native" to a VLAN) might not pass non-tagged frames. */ static void bond_arp_send(struct net_device *slave_dev, int arp_op, u32 dest_ip, u32 src_ip, unsigned short vlan_id) { struct sk_buff *skb; dprintk("arp %d on slave %s: dst %x src %x vid %d\n", arp_op, slave_dev->name, dest_ip, src_ip, vlan_id); skb = arp_create(arp_op, ETH_P_ARP, dest_ip, slave_dev, src_ip, NULL, slave_dev->dev_addr, NULL); if (!skb) { printk(KERN_ERR DRV_NAME ": ARP packet allocation failed\n"); return; } if (vlan_id) { skb = vlan_put_tag(skb, vlan_id); if (!skb) { printk(KERN_ERR DRV_NAME ": failed to insert VLAN tag\n"); return; } } arp_xmit(skb); } static void bond_arp_send_all(struct bonding *bond, struct slave *slave) { int i; int i, vlan_id, rv; u32 *targets = bond->params.arp_targets; struct vlan_entry *vlan, *vlan_next; struct net_device *vlan_dev; struct flowi fl; struct rtable *rt; for (i = 0; (i < BOND_MAX_ARP_TARGETS) && targets[i]; i++) { arp_send(ARPOP_REQUEST, ETH_P_ARP, targets[i], slave->dev, my_ip, NULL, slave->dev->dev_addr, NULL); dprintk("basa: target %x\n", targets[i]); if (list_empty(&bond->vlan_list)) { dprintk("basa: empty vlan: arp_send\n"); bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], bond->master_ip, 0); continue; } /* * If VLANs are configured, we do a route lookup to * determine which VLAN interface would be used, so we * can tag the ARP with the proper VLAN tag. */ memset(&fl, 0, sizeof(fl)); fl.fl4_dst = targets[i]; fl.fl4_tos = RTO_ONLINK; rv = ip_route_output_key(&rt, &fl); if (rv) { if (net_ratelimit()) { printk(KERN_WARNING DRV_NAME ": %s: no route to arp_ip_target %u.%u.%u.%u\n", bond->dev->name, NIPQUAD(fl.fl4_dst)); } continue; } /* * This target is not on a VLAN */ if (rt->u.dst.dev == bond->dev) { dprintk("basa: rtdev == bond->dev: arp_send\n"); bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], bond->master_ip, 0); continue; } vlan_id = 0; list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list, vlan_list) { vlan_dev = bond->vlgrp->vlan_devices[vlan->vlan_id]; if (vlan_dev == rt->u.dst.dev) { vlan_id = vlan->vlan_id; dprintk("basa: vlan match on %s %d\n", vlan_dev->name, vlan_id); break; } } if (vlan_id) { bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], vlan->vlan_ip, vlan_id); continue; } if (net_ratelimit()) { printk(KERN_WARNING DRV_NAME ": %s: no path to arp_ip_target %u.%u.%u.%u via rt.dev %s\n", bond->dev->name, NIPQUAD(fl.fl4_dst), rt->u.dst.dev ? rt->u.dst.dev->name : "NULL"); } } } /* * Kick out a gratuitous ARP for an IP on the bonding master plus one * for each VLAN above us. */ static void bond_send_gratuitous_arp(struct bonding *bond) { struct slave *slave = bond->curr_active_slave; struct vlan_entry *vlan; struct net_device *vlan_dev; dprintk("bond_send_grat_arp: bond %s slave %s\n", bond->dev->name, slave ? slave->dev->name : "NULL"); if (!slave) return; if (bond->master_ip) { bond_arp_send(slave->dev, ARPOP_REPLY, bond->master_ip, bond->master_ip, 0); } list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { vlan_dev = bond->vlgrp->vlan_devices[vlan->vlan_id]; if (vlan->vlan_ip) { bond_arp_send(slave->dev, ARPOP_REPLY, vlan->vlan_ip, vlan->vlan_ip, vlan->vlan_id); } } } Loading Loading @@ -2781,7 +2952,7 @@ static void bond_loadbalance_arp_mon(struct net_device *bond_dev) */ if (((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) || (((jiffies - slave->dev->last_rx) >= (2*delta_in_ticks)) && my_ip)) { bond_has_ip(bond))) { slave->link = BOND_LINK_DOWN; slave->state = BOND_STATE_BACKUP; Loading Loading @@ -2920,7 +3091,7 @@ static void bond_activebackup_arp_mon(struct net_device *bond_dev) if ((slave != bond->curr_active_slave) && (!bond->current_arp_slave) && (((jiffies - slave->dev->last_rx) >= 3*delta_in_ticks) && my_ip)) { bond_has_ip(bond))) { /* a backup slave has gone down; three times * the delta allows the current slave to be * taken out before the backup slave. Loading Loading @@ -2967,7 +3138,7 @@ static void bond_activebackup_arp_mon(struct net_device *bond_dev) */ if ((((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) || (((jiffies - slave->dev->last_rx) >= (2*delta_in_ticks)) && my_ip)) && bond_has_ip(bond))) && ((jiffies - slave->jiffies) >= 2*delta_in_ticks)) { slave->link = BOND_LINK_DOWN; Loading Loading @@ -3019,7 +3190,7 @@ static void bond_activebackup_arp_mon(struct net_device *bond_dev) /* the current slave must tx an arp to ensure backup slaves * rx traffic */ if (slave && my_ip) { if (slave && bond_has_ip(bond)) { bond_arp_send_all(bond, slave); } } Loading Loading @@ -3471,10 +3642,67 @@ static int bond_netdev_event(struct notifier_block *this, unsigned long event, v return NOTIFY_DONE; } /* * bond_inetaddr_event: handle inetaddr notifier chain events. * * We keep track of device IPs primarily to use as source addresses in * ARP monitor probes (rather than spewing out broadcasts all the time). * * We track one IP for the main device (if it has one), plus one per VLAN. */ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event, void *ptr) { struct in_ifaddr *ifa = ptr; struct net_device *vlan_dev, *event_dev = ifa->ifa_dev->dev; struct bonding *bond, *bond_next; struct vlan_entry *vlan, *vlan_next; list_for_each_entry_safe(bond, bond_next, &bond_dev_list, bond_list) { if (bond->dev == event_dev) { switch (event) { case NETDEV_UP: bond->master_ip = ifa->ifa_local; return NOTIFY_OK; case NETDEV_DOWN: bond->master_ip = bond_glean_dev_ip(bond->dev); return NOTIFY_OK; default: return NOTIFY_DONE; } } if (list_empty(&bond->vlan_list)) continue; list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list, vlan_list) { vlan_dev = bond->vlgrp->vlan_devices[vlan->vlan_id]; if (vlan_dev == event_dev) { switch (event) { case NETDEV_UP: vlan->vlan_ip = ifa->ifa_local; return NOTIFY_OK; case NETDEV_DOWN: vlan->vlan_ip = bond_glean_dev_ip(vlan_dev); return NOTIFY_OK; default: return NOTIFY_DONE; } } } } return NOTIFY_DONE; } static struct notifier_block bond_netdev_notifier = { .notifier_call = bond_netdev_event, }; static struct notifier_block bond_inetaddr_notifier = { .notifier_call = bond_inetaddr_event, }; /*-------------------------- Packet type handling ---------------------------*/ /* register to receive lacpdus on a bond */ Loading Loading @@ -4060,17 +4288,6 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d struct bonding *bond = bond_dev->priv; int res = 1; /* if we are sending arp packets, try to at least identify our own ip address */ if (bond->params.arp_interval && !my_ip && (skb->protocol == __constant_htons(ETH_P_ARP))) { char *the_ip = (char *)skb->data + sizeof(struct ethhdr) + sizeof(struct arphdr) + ETH_ALEN; memcpy(&my_ip, the_ip, 4); } read_lock(&bond->lock); read_lock(&bond->curr_slave_lock); Loading Loading @@ -4669,6 +4886,7 @@ static int __init bonding_init(void) rtnl_unlock(); register_netdevice_notifier(&bond_netdev_notifier); register_inetaddr_notifier(&bond_inetaddr_notifier); return 0; Loading @@ -4684,6 +4902,7 @@ static int __init bonding_init(void) static void __exit bonding_exit(void) { unregister_netdevice_notifier(&bond_netdev_notifier); unregister_inetaddr_notifier(&bond_inetaddr_notifier); rtnl_lock(); bond_free_all(); Loading drivers/net/bonding/bonding.h +4 −2 Original line number Diff line number Diff line Loading @@ -36,8 +36,8 @@ #include "bond_3ad.h" #include "bond_alb.h" #define DRV_VERSION "2.6.1" #define DRV_RELDATE "October 29, 2004" #define DRV_VERSION "2.6.2" #define DRV_RELDATE "June 5, 2005" #define DRV_NAME "bonding" #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" Loading Loading @@ -149,6 +149,7 @@ struct bond_params { struct vlan_entry { struct list_head vlan_list; u32 vlan_ip; unsigned short vlan_id; }; Loading Loading @@ -197,6 +198,7 @@ struct bonding { #endif /* CONFIG_PROC_FS */ struct list_head bond_list; struct dev_mc_list *mc_list; u32 master_ip; u16 flags; struct ad_bond_info ad_info; struct alb_bond_info alb_info; Loading Loading
drivers/net/bonding/bond_main.c +251 −32 Original line number Diff line number Diff line Loading @@ -475,7 +475,10 @@ * Solution is to move call to dev_remove_pack outside of the * spinlock. * Set version to 2.6.1. * * 2005/06/05 - Jay Vosburgh <fubar@us.ibm.com> * - Support for generating gratuitous ARPs in active-backup mode. * Includes support for VLAN tagging all bonding-generated ARPs * as needed. Set version to 2.6.2. */ //#define BONDING_DEBUG 1 Loading Loading @@ -519,6 +522,7 @@ #include <linux/ethtool.h> #include <linux/if_vlan.h> #include <linux/if_bonding.h> #include <net/route.h> #include "bonding.h" #include "bond_3ad.h" #include "bond_alb.h" Loading Loading @@ -574,7 +578,6 @@ static struct proc_dir_entry *bond_proc_dir = NULL; static u32 arp_target[BOND_MAX_ARP_TARGETS] = { 0, } ; static int arp_ip_count = 0; static u32 my_ip = 0; static int bond_mode = BOND_MODE_ROUNDROBIN; static int lacp_fast = 0; static int app_abi_ver = 0; Loading Loading @@ -611,6 +614,7 @@ static struct bond_parm_tbl bond_mode_tbl[] = { /*-------------------------- Forward declarations ---------------------------*/ static inline void bond_set_mode_ops(struct net_device *bond_dev, int mode); static void bond_send_gratuitous_arp(struct bonding *bond); /*---------------------------- General routines -----------------------------*/ Loading Loading @@ -659,6 +663,7 @@ static int bond_add_vlan(struct bonding *bond, unsigned short vlan_id) INIT_LIST_HEAD(&vlan->vlan_list); vlan->vlan_id = vlan_id; vlan->vlan_ip = 0; write_lock_bh(&bond->lock); Loading Loading @@ -1468,16 +1473,6 @@ static void bond_change_active_slave(struct bonding *bond, struct slave *new_act } } if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) { if (old_active) { bond_set_slave_inactive_flags(old_active); } if (new_active) { bond_set_slave_active_flags(new_active); } } if (USES_PRIMARY(bond->params.mode)) { bond_mc_swap(bond, new_active, old_active); } Loading @@ -1488,6 +1483,17 @@ static void bond_change_active_slave(struct bonding *bond, struct slave *new_act } else { bond->curr_active_slave = new_active; } if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) { if (old_active) { bond_set_slave_inactive_flags(old_active); } if (new_active) { bond_set_slave_active_flags(new_active); } bond_send_gratuitous_arp(bond); } } /** Loading Loading @@ -2694,15 +2700,180 @@ static void bond_mii_monitor(struct net_device *bond_dev) read_unlock(&bond->lock); } static u32 bond_glean_dev_ip(struct net_device *dev) { struct in_device *idev; struct in_ifaddr *ifa; u32 addr = 0; if (!dev) return 0; rcu_read_lock(); idev = __in_dev_get(dev); if (!idev) goto out; ifa = idev->ifa_list; if (!ifa) goto out; addr = ifa->ifa_local; out: rcu_read_unlock(); return addr; } static int bond_has_ip(struct bonding *bond) { struct vlan_entry *vlan, *vlan_next; if (bond->master_ip) return 1; if (list_empty(&bond->vlan_list)) return 0; list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list, vlan_list) { if (vlan->vlan_ip) return 1; } return 0; } /* * We go to the (large) trouble of VLAN tagging ARP frames because * switches in VLAN mode (especially if ports are configured as * "native" to a VLAN) might not pass non-tagged frames. */ static void bond_arp_send(struct net_device *slave_dev, int arp_op, u32 dest_ip, u32 src_ip, unsigned short vlan_id) { struct sk_buff *skb; dprintk("arp %d on slave %s: dst %x src %x vid %d\n", arp_op, slave_dev->name, dest_ip, src_ip, vlan_id); skb = arp_create(arp_op, ETH_P_ARP, dest_ip, slave_dev, src_ip, NULL, slave_dev->dev_addr, NULL); if (!skb) { printk(KERN_ERR DRV_NAME ": ARP packet allocation failed\n"); return; } if (vlan_id) { skb = vlan_put_tag(skb, vlan_id); if (!skb) { printk(KERN_ERR DRV_NAME ": failed to insert VLAN tag\n"); return; } } arp_xmit(skb); } static void bond_arp_send_all(struct bonding *bond, struct slave *slave) { int i; int i, vlan_id, rv; u32 *targets = bond->params.arp_targets; struct vlan_entry *vlan, *vlan_next; struct net_device *vlan_dev; struct flowi fl; struct rtable *rt; for (i = 0; (i < BOND_MAX_ARP_TARGETS) && targets[i]; i++) { arp_send(ARPOP_REQUEST, ETH_P_ARP, targets[i], slave->dev, my_ip, NULL, slave->dev->dev_addr, NULL); dprintk("basa: target %x\n", targets[i]); if (list_empty(&bond->vlan_list)) { dprintk("basa: empty vlan: arp_send\n"); bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], bond->master_ip, 0); continue; } /* * If VLANs are configured, we do a route lookup to * determine which VLAN interface would be used, so we * can tag the ARP with the proper VLAN tag. */ memset(&fl, 0, sizeof(fl)); fl.fl4_dst = targets[i]; fl.fl4_tos = RTO_ONLINK; rv = ip_route_output_key(&rt, &fl); if (rv) { if (net_ratelimit()) { printk(KERN_WARNING DRV_NAME ": %s: no route to arp_ip_target %u.%u.%u.%u\n", bond->dev->name, NIPQUAD(fl.fl4_dst)); } continue; } /* * This target is not on a VLAN */ if (rt->u.dst.dev == bond->dev) { dprintk("basa: rtdev == bond->dev: arp_send\n"); bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], bond->master_ip, 0); continue; } vlan_id = 0; list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list, vlan_list) { vlan_dev = bond->vlgrp->vlan_devices[vlan->vlan_id]; if (vlan_dev == rt->u.dst.dev) { vlan_id = vlan->vlan_id; dprintk("basa: vlan match on %s %d\n", vlan_dev->name, vlan_id); break; } } if (vlan_id) { bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], vlan->vlan_ip, vlan_id); continue; } if (net_ratelimit()) { printk(KERN_WARNING DRV_NAME ": %s: no path to arp_ip_target %u.%u.%u.%u via rt.dev %s\n", bond->dev->name, NIPQUAD(fl.fl4_dst), rt->u.dst.dev ? rt->u.dst.dev->name : "NULL"); } } } /* * Kick out a gratuitous ARP for an IP on the bonding master plus one * for each VLAN above us. */ static void bond_send_gratuitous_arp(struct bonding *bond) { struct slave *slave = bond->curr_active_slave; struct vlan_entry *vlan; struct net_device *vlan_dev; dprintk("bond_send_grat_arp: bond %s slave %s\n", bond->dev->name, slave ? slave->dev->name : "NULL"); if (!slave) return; if (bond->master_ip) { bond_arp_send(slave->dev, ARPOP_REPLY, bond->master_ip, bond->master_ip, 0); } list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { vlan_dev = bond->vlgrp->vlan_devices[vlan->vlan_id]; if (vlan->vlan_ip) { bond_arp_send(slave->dev, ARPOP_REPLY, vlan->vlan_ip, vlan->vlan_ip, vlan->vlan_id); } } } Loading Loading @@ -2781,7 +2952,7 @@ static void bond_loadbalance_arp_mon(struct net_device *bond_dev) */ if (((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) || (((jiffies - slave->dev->last_rx) >= (2*delta_in_ticks)) && my_ip)) { bond_has_ip(bond))) { slave->link = BOND_LINK_DOWN; slave->state = BOND_STATE_BACKUP; Loading Loading @@ -2920,7 +3091,7 @@ static void bond_activebackup_arp_mon(struct net_device *bond_dev) if ((slave != bond->curr_active_slave) && (!bond->current_arp_slave) && (((jiffies - slave->dev->last_rx) >= 3*delta_in_ticks) && my_ip)) { bond_has_ip(bond))) { /* a backup slave has gone down; three times * the delta allows the current slave to be * taken out before the backup slave. Loading Loading @@ -2967,7 +3138,7 @@ static void bond_activebackup_arp_mon(struct net_device *bond_dev) */ if ((((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) || (((jiffies - slave->dev->last_rx) >= (2*delta_in_ticks)) && my_ip)) && bond_has_ip(bond))) && ((jiffies - slave->jiffies) >= 2*delta_in_ticks)) { slave->link = BOND_LINK_DOWN; Loading Loading @@ -3019,7 +3190,7 @@ static void bond_activebackup_arp_mon(struct net_device *bond_dev) /* the current slave must tx an arp to ensure backup slaves * rx traffic */ if (slave && my_ip) { if (slave && bond_has_ip(bond)) { bond_arp_send_all(bond, slave); } } Loading Loading @@ -3471,10 +3642,67 @@ static int bond_netdev_event(struct notifier_block *this, unsigned long event, v return NOTIFY_DONE; } /* * bond_inetaddr_event: handle inetaddr notifier chain events. * * We keep track of device IPs primarily to use as source addresses in * ARP monitor probes (rather than spewing out broadcasts all the time). * * We track one IP for the main device (if it has one), plus one per VLAN. */ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event, void *ptr) { struct in_ifaddr *ifa = ptr; struct net_device *vlan_dev, *event_dev = ifa->ifa_dev->dev; struct bonding *bond, *bond_next; struct vlan_entry *vlan, *vlan_next; list_for_each_entry_safe(bond, bond_next, &bond_dev_list, bond_list) { if (bond->dev == event_dev) { switch (event) { case NETDEV_UP: bond->master_ip = ifa->ifa_local; return NOTIFY_OK; case NETDEV_DOWN: bond->master_ip = bond_glean_dev_ip(bond->dev); return NOTIFY_OK; default: return NOTIFY_DONE; } } if (list_empty(&bond->vlan_list)) continue; list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list, vlan_list) { vlan_dev = bond->vlgrp->vlan_devices[vlan->vlan_id]; if (vlan_dev == event_dev) { switch (event) { case NETDEV_UP: vlan->vlan_ip = ifa->ifa_local; return NOTIFY_OK; case NETDEV_DOWN: vlan->vlan_ip = bond_glean_dev_ip(vlan_dev); return NOTIFY_OK; default: return NOTIFY_DONE; } } } } return NOTIFY_DONE; } static struct notifier_block bond_netdev_notifier = { .notifier_call = bond_netdev_event, }; static struct notifier_block bond_inetaddr_notifier = { .notifier_call = bond_inetaddr_event, }; /*-------------------------- Packet type handling ---------------------------*/ /* register to receive lacpdus on a bond */ Loading Loading @@ -4060,17 +4288,6 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d struct bonding *bond = bond_dev->priv; int res = 1; /* if we are sending arp packets, try to at least identify our own ip address */ if (bond->params.arp_interval && !my_ip && (skb->protocol == __constant_htons(ETH_P_ARP))) { char *the_ip = (char *)skb->data + sizeof(struct ethhdr) + sizeof(struct arphdr) + ETH_ALEN; memcpy(&my_ip, the_ip, 4); } read_lock(&bond->lock); read_lock(&bond->curr_slave_lock); Loading Loading @@ -4669,6 +4886,7 @@ static int __init bonding_init(void) rtnl_unlock(); register_netdevice_notifier(&bond_netdev_notifier); register_inetaddr_notifier(&bond_inetaddr_notifier); return 0; Loading @@ -4684,6 +4902,7 @@ static int __init bonding_init(void) static void __exit bonding_exit(void) { unregister_netdevice_notifier(&bond_netdev_notifier); unregister_inetaddr_notifier(&bond_inetaddr_notifier); rtnl_lock(); bond_free_all(); Loading
drivers/net/bonding/bonding.h +4 −2 Original line number Diff line number Diff line Loading @@ -36,8 +36,8 @@ #include "bond_3ad.h" #include "bond_alb.h" #define DRV_VERSION "2.6.1" #define DRV_RELDATE "October 29, 2004" #define DRV_VERSION "2.6.2" #define DRV_RELDATE "June 5, 2005" #define DRV_NAME "bonding" #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" Loading Loading @@ -149,6 +149,7 @@ struct bond_params { struct vlan_entry { struct list_head vlan_list; u32 vlan_ip; unsigned short vlan_id; }; Loading Loading @@ -197,6 +198,7 @@ struct bonding { #endif /* CONFIG_PROC_FS */ struct list_head bond_list; struct dev_mc_list *mc_list; u32 master_ip; u16 flags; struct ad_bond_info ad_info; struct alb_bond_info alb_info; Loading