1 /*
2 * Bond several ethernet interfaces into a Cisco, running 'Etherchannel'.
3 *
4 * Portions are (c) Copyright 1995 Simon "Guru Aleph-Null" Janes
5 * NCM: Network and Communications Management, Inc.
6 *
7 * BUT, I'm the one who modified it for ethernet, so:
8 * (c) Copyright 1999, Thomas Davis, tadavis@lbl.gov
9 *
10 * This software may be used and distributed according to the terms
11 * of the GNU Public License, incorporated herein by reference.
12 *
13 *
14 * 2003/03/18 - Amir Noam <amir.noam at intel dot com>,
15 * Tsippy Mendelson <tsippy.mendelson at intel dot com> and
16 * Shmulik Hen <shmulik.hen at intel dot com>
17 * - Added support for IEEE 802.3ad Dynamic link aggregation mode.
18 *
19 * 2003/05/01 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
20 * Amir Noam <amir.noam at intel dot com>
21 * - Code beautification and style changes (mainly in comments).
22 *
23 * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
24 * - Added support for Transmit load balancing mode.
25 */
26
27 #ifndef _LINUX_BONDING_H
28 #define _LINUX_BONDING_H
29
30 #include <linux/timer.h>
31 #include <linux/proc_fs.h>
32 #include "bond_3ad.h"
33 #include "bond_alb.h"
34
35 #ifdef BONDING_DEBUG
36
37 // use this like so: BOND_PRINT_DBG(("foo = %d, bar = %d", foo, bar));
38 #define BOND_PRINT_DBG(X) \
39 do { \
40 printk(KERN_DEBUG "%s (%d)", __FUNCTION__, __LINE__); \
41 printk X; \
42 printk("\n"); \
43 } while(0)
44
45 #else
46 #define BOND_PRINT_DBG(X)
47 #endif /* BONDING_DEBUG */
48
49 #define IS_UP(dev) ((((dev)->flags & (IFF_UP)) == (IFF_UP)) && \
50 (netif_running(dev) && netif_carrier_ok(dev)))
51
52 /* Checks whether the dev is ready for transmit. We do not check netif_running
53 * since a device can be stopped by the driver for short periods of time for
54 * maintainance. dev_queue_xmit() handles this by queing the packet until the
55 * the dev is running again. Keeping packets ordering requires sticking the
56 * same dev as much as possible
57 */
58 #define SLAVE_IS_OK(slave) \
59 ((((slave)->dev->flags & (IFF_UP)) == (IFF_UP)) && \
60 netif_carrier_ok((slave)->dev) && \
61 ((slave)->link == BOND_LINK_UP) && \
62 ((slave)->state == BOND_STATE_ACTIVE))
63
64
65 typedef struct slave {
66 struct slave *next;
67 struct slave *prev;
68 struct net_device *dev;
69 short delay;
70 unsigned long jiffies;
71 char link; /* one of BOND_LINK_XXXX */
72 char state; /* one of BOND_STATE_XXXX */
73 unsigned short original_flags;
74 u32 link_failure_count;
75 u16 speed;
76 u8 duplex;
77 u8 perm_hwaddr[ETH_ALEN];
78 struct ad_slave_info ad_info; /* HUGE - better to dynamically alloc */
79 struct tlb_slave_info tlb_info;
80 } slave_t;
81
82 /*
83 * Here are the locking policies for the two bonding locks:
84 *
85 * 1) Get bond->lock when reading/writing slave list.
86 * 2) Get bond->ptrlock when reading/writing bond->current_slave.
87 * (It is unnecessary when the write-lock is put with bond->lock.)
88 * 3) When we lock with bond->ptrlock, we must lock with bond->lock
89 * beforehand.
90 */
91 typedef struct bonding {
92 slave_t *next;
93 slave_t *prev;
94 slave_t *current_slave;
95 slave_t *primary_slave;
96 slave_t *current_arp_slave;
97 __s32 slave_cnt;
98 rwlock_t lock;
99 rwlock_t ptrlock;
100 struct timer_list mii_timer;
101 struct timer_list arp_timer;
102 struct net_device_stats *stats;
103 #ifdef CONFIG_PROC_FS
104 struct proc_dir_entry *bond_proc_dir;
105 struct proc_dir_entry *bond_proc_info_file;
106 #endif /* CONFIG_PROC_FS */
107 struct bonding *next_bond;
108 struct net_device *device;
109 struct dev_mc_list *mc_list;
110 unsigned short flags;
111 struct ad_bond_info ad_info;
112 struct alb_bond_info alb_info;
113 } bonding_t;
114
115 /* Forward declarations */
116 void bond_set_slave_active_flags(slave_t *slave);
117 void bond_set_slave_inactive_flags(slave_t *slave);
118
119 /**
120 * These functions can be used for iterating the slave list
121 * (which is circular)
122 * Caller must hold bond lock for read
123 */
124 extern inline struct slave*
125 bond_get_first_slave(struct bonding *bond)
126 {
127 /* if there are no slaves return NULL */
128 if (bond->next == (slave_t *)bond) {
129 return NULL;
130 }
131 return bond->next;
132 }
133
134 /**
135 * Caller must hold bond lock for read
136 */
137 extern inline struct slave*
138 bond_get_next_slave(struct bonding *bond, struct slave *slave)
139 {
140 /* If we have reached the last slave return NULL */
141 if (slave->next == bond->next) {
142 return NULL;
143 }
144 return slave->next;
145 }
146
147 /**
148 * Returns NULL if the net_device does not belong to any of the bond's slaves
149 *
150 * Caller must hold bond lock for read
151 */
152 extern inline struct slave*
153 bond_get_slave_by_dev(struct bonding *bond, struct net_device *slave_dev)
154 {
155 struct slave *our_slave = bond->next;
156
157 /* check if the list of slaves is empty */
158 if (our_slave == (slave_t *)bond) {
159 return NULL;
160 }
161
162 for (; our_slave; our_slave = bond_get_next_slave(bond, our_slave)) {
163 if (our_slave->dev == slave_dev) {
164 break;
165 }
166 }
167 return our_slave;
168 }
169
170 extern inline struct bonding*
171 bond_get_bond_by_slave(struct slave *slave)
172 {
173 if (!slave || !slave->dev->master) {
174 return NULL;
175 }
176
177 return (struct bonding *)(slave->dev->master->priv);
178 }
179
180 #endif /* _LINUX_BONDING_H */
181
Cache object: 9245570fa2dece02bff3d90d22c0fb02
|