OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [net/] [bonding/] [bond_alb.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
3
 *
4
 * This program is free software; you can redistribute it and/or modify it
5
 * under the terms of the GNU General Public License as published by the
6
 * Free Software Foundation; either version 2 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful, but
10
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
 * for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License along
15
 * with this program; if not, write to the Free Software Foundation, Inc.,
16
 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17
 *
18
 * The full GNU General Public License is included in this distribution in the
19
 * file called LICENSE.
20
 *
21
 *
22
 * Changes:
23
 *
24
 * 2003/06/25 - Shmulik Hen <shmulik.hen at intel dot com>
25
 *      - Fixed signed/unsigned calculation errors that caused load sharing
26
 *        to collapse to one slave under very heavy UDP Tx stress.
27
 *
28
 * 2003/08/06 - Amir Noam <amir.noam at intel dot com>
29
 *      - Add support for setting bond's MAC address with special
30
 *        handling required for ALB/TLB.
31
 *
32
 * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
33
 *      - Code cleanup and style changes
34
 *
35
 * 2003/12/30 - Amir Noam <amir.noam at intel dot com>
36
 *      - Fixed: Cannot remove and re-enslave the original active slave.
37
 *
38
 * 2004/01/14 - Shmulik Hen <shmulik.hen at intel dot com>
39
 *      - Add capability to tag self generated packets in ALB/TLB modes.
40
 */
41
 
42
//#define BONDING_DEBUG 1
43
 
44
#include <linux/skbuff.h>
45
#include <linux/netdevice.h>
46
#include <linux/etherdevice.h>
47
#include <linux/pkt_sched.h>
48
#include <linux/spinlock.h>
49
#include <linux/slab.h>
50
#include <linux/timer.h>
51
#include <linux/ip.h>
52
#include <linux/ipv6.h>
53
#include <linux/if_arp.h>
54
#include <linux/if_ether.h>
55
#include <linux/if_bonding.h>
56
#include <linux/if_vlan.h>
57
#include <net/ipx.h>
58
#include <net/arp.h>
59
#include <asm/byteorder.h>
60
#include "bonding.h"
61
#include "bond_alb.h"
62
 
63
 
64
#define ALB_TIMER_TICKS_PER_SEC     10  /* should be a divisor of HZ */
65
#define BOND_TLB_REBALANCE_INTERVAL 10  /* In seconds, periodic re-balancing.
66
                                         * Used for division - never set
67
                                         * to zero !!!
68
                                         */
69
#define BOND_ALB_LP_INTERVAL        1   /* In seconds, periodic send of
70
                                         * learning packets to the switch
71
                                         */
72
 
73
#define BOND_TLB_REBALANCE_TICKS (BOND_TLB_REBALANCE_INTERVAL \
74
                                  * ALB_TIMER_TICKS_PER_SEC)
75
 
76
#define BOND_ALB_LP_TICKS (BOND_ALB_LP_INTERVAL \
77
                           * ALB_TIMER_TICKS_PER_SEC)
78
 
79
#define TLB_HASH_TABLE_SIZE 256 /* The size of the clients hash table.
80
                                 * Note that this value MUST NOT be smaller
81
                                 * because the key hash table is BYTE wide !
82
                                 */
83
 
84
 
85
#define TLB_NULL_INDEX          0xffffffff
86
#define MAX_LP_BURST            3
87
 
88
/* rlb defs */
89
#define RLB_HASH_TABLE_SIZE     256
90
#define RLB_NULL_INDEX          0xffffffff
91
#define RLB_UPDATE_DELAY        2*ALB_TIMER_TICKS_PER_SEC /* 2 seconds */
92
#define RLB_ARP_BURST_SIZE      2
93
#define RLB_UPDATE_RETRY        3       /* 3-ticks - must be smaller than the rlb
94
                                         * rebalance interval (5 min).
95
                                         */
96
/* RLB_PROMISC_TIMEOUT = 10 sec equals the time that the current slave is
97
 * promiscuous after failover
98
 */
99
#define RLB_PROMISC_TIMEOUT     10*ALB_TIMER_TICKS_PER_SEC
100
 
101
static const u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
102
static const int alb_delta_in_ticks = HZ / ALB_TIMER_TICKS_PER_SEC;
103
 
104
#pragma pack(1)
105
struct learning_pkt {
106
        u8 mac_dst[ETH_ALEN];
107
        u8 mac_src[ETH_ALEN];
108
        u16 type;
109
        u8 padding[ETH_ZLEN - ETH_HLEN];
110
};
111
 
112
struct arp_pkt {
113
        u16     hw_addr_space;
114
        u16     prot_addr_space;
115
        u8      hw_addr_len;
116
        u8      prot_addr_len;
117
        u16     op_code;
118
        u8      mac_src[ETH_ALEN];      /* sender hardware address */
119
        u32     ip_src;                 /* sender IP address */
120
        u8      mac_dst[ETH_ALEN];      /* target hardware address */
121
        u32     ip_dst;                 /* target IP address */
122
};
123
#pragma pack()
124
 
125
/* Forward declaration */
126
static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[]);
127
 
128
static inline u8 _simple_hash(u8 *hash_start, int hash_size)
129
{
130
        int i;
131
        u8 hash = 0;
132
 
133
        for (i = 0; i < hash_size; i++) {
134
                hash ^= hash_start[i];
135
        }
136
 
137
        return hash;
138
}
139
 
140
/*********************** tlb specific functions ***************************/
141
 
142
static inline void _lock_tx_hashtbl(struct bonding *bond)
143
{
144
        spin_lock(&(BOND_ALB_INFO(bond).tx_hashtbl_lock));
145
}
146
 
147
static inline void _unlock_tx_hashtbl(struct bonding *bond)
148
{
149
        spin_unlock(&(BOND_ALB_INFO(bond).tx_hashtbl_lock));
150
}
151
 
152
/* Caller must hold tx_hashtbl lock */
153
static inline void tlb_init_table_entry(struct tlb_client_info *entry, int save_load)
154
{
155
        if (save_load) {
156
                entry->load_history = 1 + entry->tx_bytes /
157
                                      BOND_TLB_REBALANCE_INTERVAL;
158
                entry->tx_bytes = 0;
159
        }
160
 
161
        entry->tx_slave = NULL;
162
        entry->next = TLB_NULL_INDEX;
163
        entry->prev = TLB_NULL_INDEX;
164
}
165
 
166
static inline void tlb_init_slave(struct slave *slave)
167
{
168
        SLAVE_TLB_INFO(slave).load = 0;
169
        SLAVE_TLB_INFO(slave).head = TLB_NULL_INDEX;
170
}
171
 
172
/* Caller must hold bond lock for read */
173
static void tlb_clear_slave(struct bonding *bond, struct slave *slave, int save_load)
174
{
175
        struct tlb_client_info *tx_hash_table;
176
        u32 index;
177
 
178
        _lock_tx_hashtbl(bond);
179
 
180
        /* clear slave from tx_hashtbl */
181
        tx_hash_table = BOND_ALB_INFO(bond).tx_hashtbl;
182
 
183
        index = SLAVE_TLB_INFO(slave).head;
184
        while (index != TLB_NULL_INDEX) {
185
                u32 next_index = tx_hash_table[index].next;
186
                tlb_init_table_entry(&tx_hash_table[index], save_load);
187
                index = next_index;
188
        }
189
 
190
        _unlock_tx_hashtbl(bond);
191
 
192
        tlb_init_slave(slave);
193
}
194
 
195
/* Must be called before starting the monitor timer */
196
static int tlb_initialize(struct bonding *bond)
197
{
198
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
199
        int size = TLB_HASH_TABLE_SIZE * sizeof(struct tlb_client_info);
200
        int i;
201
 
202
        spin_lock_init(&(bond_info->tx_hashtbl_lock));
203
 
204
        _lock_tx_hashtbl(bond);
205
 
206
        bond_info->tx_hashtbl = kmalloc(size, GFP_KERNEL);
207
        if (!bond_info->tx_hashtbl) {
208
                printk(KERN_ERR DRV_NAME
209
                       ": Error: %s: Failed to allocate TLB hash table\n",
210
                       bond->dev->name);
211
                _unlock_tx_hashtbl(bond);
212
                return -1;
213
        }
214
 
215
        memset(bond_info->tx_hashtbl, 0, size);
216
 
217
        for (i = 0; i < TLB_HASH_TABLE_SIZE; i++) {
218
                tlb_init_table_entry(&bond_info->tx_hashtbl[i], 1);
219
        }
220
 
221
        _unlock_tx_hashtbl(bond);
222
 
223
        return 0;
224
}
225
 
226
/* Must be called only after all slaves have been released */
227
static void tlb_deinitialize(struct bonding *bond)
228
{
229
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
230
 
231
        _lock_tx_hashtbl(bond);
232
 
233
        kfree(bond_info->tx_hashtbl);
234
        bond_info->tx_hashtbl = NULL;
235
 
236
        _unlock_tx_hashtbl(bond);
237
}
238
 
239
/* Caller must hold bond lock for read */
240
static struct slave *tlb_get_least_loaded_slave(struct bonding *bond)
241
{
242
        struct slave *slave, *least_loaded;
243
        s64 max_gap;
244
        int i, found = 0;
245
 
246
        /* Find the first enabled slave */
247
        bond_for_each_slave(bond, slave, i) {
248
                if (SLAVE_IS_OK(slave)) {
249
                        found = 1;
250
                        break;
251
                }
252
        }
253
 
254
        if (!found) {
255
                return NULL;
256
        }
257
 
258
        least_loaded = slave;
259
        max_gap = (s64)(slave->speed << 20) - /* Convert to Megabit per sec */
260
                        (s64)(SLAVE_TLB_INFO(slave).load << 3); /* Bytes to bits */
261
 
262
        /* Find the slave with the largest gap */
263
        bond_for_each_slave_from(bond, slave, i, least_loaded) {
264
                if (SLAVE_IS_OK(slave)) {
265
                        s64 gap = (s64)(slave->speed << 20) -
266
                                        (s64)(SLAVE_TLB_INFO(slave).load << 3);
267
                        if (max_gap < gap) {
268
                                least_loaded = slave;
269
                                max_gap = gap;
270
                        }
271
                }
272
        }
273
 
274
        return least_loaded;
275
}
276
 
277
/* Caller must hold bond lock for read */
278
struct slave *tlb_choose_channel(struct bonding *bond, u32 hash_index, u32 skb_len)
279
{
280
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
281
        struct tlb_client_info *hash_table;
282
        struct slave *assigned_slave;
283
 
284
        _lock_tx_hashtbl(bond);
285
 
286
        hash_table = bond_info->tx_hashtbl;
287
        assigned_slave = hash_table[hash_index].tx_slave;
288
        if (!assigned_slave) {
289
                assigned_slave = tlb_get_least_loaded_slave(bond);
290
 
291
                if (assigned_slave) {
292
                        struct tlb_slave_info *slave_info =
293
                                &(SLAVE_TLB_INFO(assigned_slave));
294
                        u32 next_index = slave_info->head;
295
 
296
                        hash_table[hash_index].tx_slave = assigned_slave;
297
                        hash_table[hash_index].next = next_index;
298
                        hash_table[hash_index].prev = TLB_NULL_INDEX;
299
 
300
                        if (next_index != TLB_NULL_INDEX) {
301
                                hash_table[next_index].prev = hash_index;
302
                        }
303
 
304
                        slave_info->head = hash_index;
305
                        slave_info->load +=
306
                                hash_table[hash_index].load_history;
307
                }
308
        }
309
 
310
        if (assigned_slave) {
311
                hash_table[hash_index].tx_bytes += skb_len;
312
        }
313
 
314
        _unlock_tx_hashtbl(bond);
315
 
316
        return assigned_slave;
317
}
318
 
319
/*********************** rlb specific functions ***************************/
320
static inline void _lock_rx_hashtbl(struct bonding *bond)
321
{
322
        spin_lock(&(BOND_ALB_INFO(bond).rx_hashtbl_lock));
323
}
324
 
325
static inline void _unlock_rx_hashtbl(struct bonding *bond)
326
{
327
        spin_unlock(&(BOND_ALB_INFO(bond).rx_hashtbl_lock));
328
}
329
 
330
/* when an ARP REPLY is received from a client update its info
331
 * in the rx_hashtbl
332
 */
333
static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp)
334
{
335
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
336
        struct rlb_client_info *client_info;
337
        u32 hash_index;
338
 
339
        _lock_rx_hashtbl(bond);
340
 
341
        hash_index = _simple_hash((u8*)&(arp->ip_src), sizeof(arp->ip_src));
342
        client_info = &(bond_info->rx_hashtbl[hash_index]);
343
 
344
        if ((client_info->assigned) &&
345
            (client_info->ip_src == arp->ip_dst) &&
346
            (client_info->ip_dst == arp->ip_src)) {
347
                /* update the clients MAC address */
348
                memcpy(client_info->mac_dst, arp->mac_src, ETH_ALEN);
349
                client_info->ntt = 1;
350
                bond_info->rx_ntt = 1;
351
        }
352
 
353
        _unlock_rx_hashtbl(bond);
354
}
355
 
356
static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct packet_type *ptype)
357
{
358
        struct bonding *bond = bond_dev->priv;
359
        struct arp_pkt *arp = (struct arp_pkt *)skb->data;
360
        int res = NET_RX_DROP;
361
 
362
        if (!(bond_dev->flags & IFF_MASTER)) {
363
                goto out;
364
        }
365
 
366
        if (!arp) {
367
                dprintk("Packet has no ARP data\n");
368
                goto out;
369
        }
370
 
371
        if (skb->len < sizeof(struct arp_pkt)) {
372
                dprintk("Packet is too small to be an ARP\n");
373
                goto out;
374
        }
375
 
376
        if (arp->op_code == htons(ARPOP_REPLY)) {
377
                /* update rx hash table for this ARP */
378
                rlb_update_entry_from_arp(bond, arp);
379
                dprintk("Server received an ARP Reply from client\n");
380
        }
381
 
382
        res = NET_RX_SUCCESS;
383
 
384
out:
385
        dev_kfree_skb(skb);
386
 
387
        return res;
388
}
389
 
390
/* Caller must hold bond lock for read */
391
static struct slave *rlb_next_rx_slave(struct bonding *bond)
392
{
393
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
394
        struct slave *rx_slave, *slave, *start_at;
395
        int i = 0;
396
 
397
        if (bond_info->next_rx_slave) {
398
                start_at = bond_info->next_rx_slave;
399
        } else {
400
                start_at = bond->first_slave;
401
        }
402
 
403
        rx_slave = NULL;
404
 
405
        bond_for_each_slave_from(bond, slave, i, start_at) {
406
                if (SLAVE_IS_OK(slave)) {
407
                        if (!rx_slave) {
408
                                rx_slave = slave;
409
                        } else if (slave->speed > rx_slave->speed) {
410
                                rx_slave = slave;
411
                        }
412
                }
413
        }
414
 
415
        if (rx_slave) {
416
                bond_info->next_rx_slave = rx_slave->next;
417
        }
418
 
419
        return rx_slave;
420
}
421
 
422
/* teach the switch the mac of a disabled slave
423
 * on the primary for fault tolerance
424
 *
425
 * Caller must hold bond->curr_slave_lock for write or bond lock for write
426
 */
427
static void rlb_teach_disabled_mac_on_primary(struct bonding *bond, u8 addr[])
428
{
429
        if (!bond->curr_active_slave) {
430
                return;
431
        }
432
 
433
        if (!bond->alb_info.primary_is_promisc) {
434
                bond->alb_info.primary_is_promisc = 1;
435
                dev_set_promiscuity(bond->curr_active_slave->dev, 1);
436
        }
437
 
438
        bond->alb_info.rlb_promisc_timeout_counter = 0;
439
 
440
        alb_send_learning_packets(bond->curr_active_slave, addr);
441
}
442
 
443
/* slave being removed should not be active at this point
444
 *
445
 * Caller must hold bond lock for read
446
 */
447
static void rlb_clear_slave(struct bonding *bond, struct slave *slave)
448
{
449
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
450
        struct rlb_client_info *rx_hash_table;
451
        u32 index, next_index;
452
 
453
        /* clear slave from rx_hashtbl */
454
        _lock_rx_hashtbl(bond);
455
 
456
        rx_hash_table = bond_info->rx_hashtbl;
457
        index = bond_info->rx_hashtbl_head;
458
        for (; index != RLB_NULL_INDEX; index = next_index) {
459
                next_index = rx_hash_table[index].next;
460
                if (rx_hash_table[index].slave == slave) {
461
                        struct slave *assigned_slave = rlb_next_rx_slave(bond);
462
 
463
                        if (assigned_slave) {
464
                                rx_hash_table[index].slave = assigned_slave;
465
                                if (memcmp(rx_hash_table[index].mac_dst,
466
                                           mac_bcast, ETH_ALEN)) {
467
                                        bond_info->rx_hashtbl[index].ntt = 1;
468
                                        bond_info->rx_ntt = 1;
469
                                        /* A slave has been removed from the
470
                                         * table because it is either disabled
471
                                         * or being released. We must retry the
472
                                         * update to avoid clients from not
473
                                         * being updated & disconnecting when
474
                                         * there is stress
475
                                         */
476
                                        bond_info->rlb_update_retry_counter =
477
                                                RLB_UPDATE_RETRY;
478
                                }
479
                        } else {  /* there is no active slave */
480
                                rx_hash_table[index].slave = NULL;
481
                        }
482
                }
483
        }
484
 
485
        _unlock_rx_hashtbl(bond);
486
 
487
        write_lock(&bond->curr_slave_lock);
488
 
489
        if (slave != bond->curr_active_slave) {
490
                rlb_teach_disabled_mac_on_primary(bond, slave->dev->dev_addr);
491
        }
492
 
493
        write_unlock(&bond->curr_slave_lock);
494
}
495
 
496
static void rlb_update_client(struct rlb_client_info *client_info)
497
{
498
        int i;
499
 
500
        if (!client_info->slave) {
501
                return;
502
        }
503
 
504
        for (i = 0; i < RLB_ARP_BURST_SIZE; i++) {
505
                struct sk_buff *skb;
506
 
507
                skb = arp_create(ARPOP_REPLY, ETH_P_ARP,
508
                                 client_info->ip_dst,
509
                                 client_info->slave->dev,
510
                                 client_info->ip_src,
511
                                 client_info->mac_dst,
512
                                 client_info->slave->dev->dev_addr,
513
                                 client_info->mac_dst);
514
                if (!skb) {
515
                        printk(KERN_ERR DRV_NAME
516
                               ": Error: failed to create an ARP packet\n");
517
                        continue;
518
                }
519
 
520
                skb->dev = client_info->slave->dev;
521
 
522
                if (client_info->tag) {
523
                        skb = vlan_put_tag(skb, client_info->vlan_id);
524
                        if (!skb) {
525
                                printk(KERN_ERR DRV_NAME
526
                                       ": Error: failed to insert VLAN tag\n");
527
                                continue;
528
                        }
529
                }
530
 
531
                arp_xmit(skb);
532
        }
533
}
534
 
535
/* sends ARP REPLIES that update the clients that need updating */
536
static void rlb_update_rx_clients(struct bonding *bond)
537
{
538
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
539
        struct rlb_client_info *client_info;
540
        u32 hash_index;
541
 
542
        _lock_rx_hashtbl(bond);
543
 
544
        hash_index = bond_info->rx_hashtbl_head;
545
        for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
546
                client_info = &(bond_info->rx_hashtbl[hash_index]);
547
                if (client_info->ntt) {
548
                        rlb_update_client(client_info);
549
                        if (bond_info->rlb_update_retry_counter == 0) {
550
                                client_info->ntt = 0;
551
                        }
552
                }
553
        }
554
 
555
        /* do not update the entries again untill this counter is zero so that
556
         * not to confuse the clients.
557
         */
558
        bond_info->rlb_update_delay_counter = RLB_UPDATE_DELAY;
559
 
560
        _unlock_rx_hashtbl(bond);
561
}
562
 
563
/* The slave was assigned a new mac address - update the clients */
564
static void rlb_req_update_slave_clients(struct bonding *bond, struct slave *slave)
565
{
566
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
567
        struct rlb_client_info *client_info;
568
        int ntt = 0;
569
        u32 hash_index;
570
 
571
        _lock_rx_hashtbl(bond);
572
 
573
        hash_index = bond_info->rx_hashtbl_head;
574
        for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
575
                client_info = &(bond_info->rx_hashtbl[hash_index]);
576
 
577
                if ((client_info->slave == slave) &&
578
                    memcmp(client_info->mac_dst, mac_bcast, ETH_ALEN)) {
579
                        client_info->ntt = 1;
580
                        ntt = 1;
581
                }
582
        }
583
 
584
        // update the team's flag only after the whole iteration
585
        if (ntt) {
586
                bond_info->rx_ntt = 1;
587
                //fasten the change
588
                bond_info->rlb_update_retry_counter = RLB_UPDATE_RETRY;
589
        }
590
 
591
        _unlock_rx_hashtbl(bond);
592
}
593
 
594
/* mark all clients using src_ip to be updated */
595
static void rlb_req_update_subnet_clients(struct bonding *bond, u32 src_ip)
596
{
597
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
598
        struct rlb_client_info *client_info;
599
        u32 hash_index;
600
 
601
        _lock_rx_hashtbl(bond);
602
 
603
        hash_index = bond_info->rx_hashtbl_head;
604
        for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
605
                client_info = &(bond_info->rx_hashtbl[hash_index]);
606
 
607
                if (!client_info->slave) {
608
                        printk(KERN_ERR DRV_NAME
609
                               ": Error: found a client with no channel in "
610
                               "the client's hash table\n");
611
                        continue;
612
                }
613
                /*update all clients using this src_ip, that are not assigned
614
                 * to the team's address (curr_active_slave) and have a known
615
                 * unicast mac address.
616
                 */
617
                if ((client_info->ip_src == src_ip) &&
618
                    memcmp(client_info->slave->dev->dev_addr,
619
                           bond->dev->dev_addr, ETH_ALEN) &&
620
                    memcmp(client_info->mac_dst, mac_bcast, ETH_ALEN)) {
621
                        client_info->ntt = 1;
622
                        bond_info->rx_ntt = 1;
623
                }
624
        }
625
 
626
        _unlock_rx_hashtbl(bond);
627
}
628
 
629
/* Caller must hold both bond and ptr locks for read */
630
struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bond)
631
{
632
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
633
        struct arp_pkt *arp = (struct arp_pkt *)skb->nh.raw;
634
        struct slave *assigned_slave;
635
        struct rlb_client_info *client_info;
636
        u32 hash_index = 0;
637
 
638
        _lock_rx_hashtbl(bond);
639
 
640
        hash_index = _simple_hash((u8 *)&arp->ip_dst, sizeof(arp->ip_src));
641
        client_info = &(bond_info->rx_hashtbl[hash_index]);
642
 
643
        if (client_info->assigned) {
644
                if ((client_info->ip_src == arp->ip_src) &&
645
                    (client_info->ip_dst == arp->ip_dst)) {
646
                        /* the entry is already assigned to this client */
647
                        if (memcmp(arp->mac_dst, mac_bcast, ETH_ALEN)) {
648
                                /* update mac address from arp */
649
                                memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN);
650
                        }
651
 
652
                        assigned_slave = client_info->slave;
653
                        if (assigned_slave) {
654
                                _unlock_rx_hashtbl(bond);
655
                                return assigned_slave;
656
                        }
657
                } else {
658
                        /* the entry is already assigned to some other client,
659
                         * move the old client to primary (curr_active_slave) so
660
                         * that the new client can be assigned to this entry.
661
                         */
662
                        if (bond->curr_active_slave &&
663
                            client_info->slave != bond->curr_active_slave) {
664
                                client_info->slave = bond->curr_active_slave;
665
                                rlb_update_client(client_info);
666
                        }
667
                }
668
        }
669
        /* assign a new slave */
670
        assigned_slave = rlb_next_rx_slave(bond);
671
 
672
        if (assigned_slave) {
673
                client_info->ip_src = arp->ip_src;
674
                client_info->ip_dst = arp->ip_dst;
675
                /* arp->mac_dst is broadcast for arp reqeusts.
676
                 * will be updated with clients actual unicast mac address
677
                 * upon receiving an arp reply.
678
                 */
679
                memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN);
680
                client_info->slave = assigned_slave;
681
 
682
                if (memcmp(client_info->mac_dst, mac_bcast, ETH_ALEN)) {
683
                        client_info->ntt = 1;
684
                        bond->alb_info.rx_ntt = 1;
685
                } else {
686
                        client_info->ntt = 0;
687
                }
688
 
689
                if (!list_empty(&bond->vlan_list)) {
690
                        unsigned short vlan_id;
691
                        int res = vlan_get_tag(skb, &vlan_id);
692
                        if (!res) {
693
                                client_info->tag = 1;
694
                                client_info->vlan_id = vlan_id;
695
                        }
696
                }
697
 
698
                if (!client_info->assigned) {
699
                        u32 prev_tbl_head = bond_info->rx_hashtbl_head;
700
                        bond_info->rx_hashtbl_head = hash_index;
701
                        client_info->next = prev_tbl_head;
702
                        if (prev_tbl_head != RLB_NULL_INDEX) {
703
                                bond_info->rx_hashtbl[prev_tbl_head].prev =
704
                                        hash_index;
705
                        }
706
                        client_info->assigned = 1;
707
                }
708
        }
709
 
710
        _unlock_rx_hashtbl(bond);
711
 
712
        return assigned_slave;
713
}
714
 
715
/* chooses (and returns) transmit channel for arp reply
716
 * does not choose channel for other arp types since they are
717
 * sent on the curr_active_slave
718
 */
719
static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
720
{
721
        struct arp_pkt *arp = (struct arp_pkt *)skb->nh.raw;
722
        struct slave *tx_slave = NULL;
723
 
724
        if (arp->op_code == __constant_htons(ARPOP_REPLY)) {
725
                /* the arp must be sent on the selected
726
                * rx channel
727
                */
728
                tx_slave = rlb_choose_channel(skb, bond);
729
                if (tx_slave) {
730
                        memcpy(arp->mac_src,tx_slave->dev->dev_addr, ETH_ALEN);
731
                }
732
                dprintk("Server sent ARP Reply packet\n");
733
        } else if (arp->op_code == __constant_htons(ARPOP_REQUEST)) {
734
                /* Create an entry in the rx_hashtbl for this client as a
735
                 * place holder.
736
                 * When the arp reply is received the entry will be updated
737
                 * with the correct unicast address of the client.
738
                 */
739
                rlb_choose_channel(skb, bond);
740
 
741
                /* The ARP relpy packets must be delayed so that
742
                 * they can cancel out the influence of the ARP request.
743
                 */
744
                bond->alb_info.rlb_update_delay_counter = RLB_UPDATE_DELAY;
745
 
746
                /* arp requests are broadcast and are sent on the primary
747
                 * the arp request will collapse all clients on the subnet to
748
                 * the primary slave. We must register these clients to be
749
                 * updated with their assigned mac.
750
                 */
751
                rlb_req_update_subnet_clients(bond, arp->ip_src);
752
                dprintk("Server sent ARP Request packet\n");
753
        }
754
 
755
        return tx_slave;
756
}
757
 
758
/* Caller must hold bond lock for read */
759
static void rlb_rebalance(struct bonding *bond)
760
{
761
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
762
        struct slave *assigned_slave;
763
        struct rlb_client_info *client_info;
764
        int ntt;
765
        u32 hash_index;
766
 
767
        _lock_rx_hashtbl(bond);
768
 
769
        ntt = 0;
770
        hash_index = bond_info->rx_hashtbl_head;
771
        for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
772
                client_info = &(bond_info->rx_hashtbl[hash_index]);
773
                assigned_slave = rlb_next_rx_slave(bond);
774
                if (assigned_slave && (client_info->slave != assigned_slave)) {
775
                        client_info->slave = assigned_slave;
776
                        client_info->ntt = 1;
777
                        ntt = 1;
778
                }
779
        }
780
 
781
        /* update the team's flag only after the whole iteration */
782
        if (ntt) {
783
                bond_info->rx_ntt = 1;
784
        }
785
        _unlock_rx_hashtbl(bond);
786
}
787
 
788
/* Caller must hold rx_hashtbl lock */
789
static void rlb_init_table_entry(struct rlb_client_info *entry)
790
{
791
        memset(entry, 0, sizeof(struct rlb_client_info));
792
        entry->next = RLB_NULL_INDEX;
793
        entry->prev = RLB_NULL_INDEX;
794
}
795
 
796
static int rlb_initialize(struct bonding *bond)
797
{
798
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
799
        struct packet_type *pk_type = &(BOND_ALB_INFO(bond).rlb_pkt_type);
800
        int size = RLB_HASH_TABLE_SIZE * sizeof(struct rlb_client_info);
801
        int i;
802
 
803
        spin_lock_init(&(bond_info->rx_hashtbl_lock));
804
 
805
        _lock_rx_hashtbl(bond);
806
 
807
        bond_info->rx_hashtbl = kmalloc(size, GFP_KERNEL);
808
        if (!bond_info->rx_hashtbl) {
809
                printk(KERN_ERR DRV_NAME
810
                       ": Error: %s: Failed to allocate RLB hash table\n",
811
                       bond->dev->name);
812
                _unlock_rx_hashtbl(bond);
813
                return -1;
814
        }
815
 
816
        bond_info->rx_hashtbl_head = RLB_NULL_INDEX;
817
 
818
        for (i = 0; i < RLB_HASH_TABLE_SIZE; i++) {
819
                rlb_init_table_entry(bond_info->rx_hashtbl + i);
820
        }
821
 
822
        _unlock_rx_hashtbl(bond);
823
 
824
        /*initialize packet type*/
825
        pk_type->type = __constant_htons(ETH_P_ARP);
826
        pk_type->dev = bond->dev;
827
        pk_type->func = rlb_arp_recv;
828
        pk_type->data = (void*)1;  /* understand shared skbs */
829
 
830
        /* register to receive ARPs */
831
        dev_add_pack(pk_type);
832
 
833
        return 0;
834
}
835
 
836
static void rlb_deinitialize(struct bonding *bond)
837
{
838
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
839
 
840
        dev_remove_pack(&(bond_info->rlb_pkt_type));
841
 
842
        _lock_rx_hashtbl(bond);
843
 
844
        kfree(bond_info->rx_hashtbl);
845
        bond_info->rx_hashtbl = NULL;
846
        bond_info->rx_hashtbl_head = RLB_NULL_INDEX;
847
 
848
        _unlock_rx_hashtbl(bond);
849
}
850
 
851
static void rlb_clear_vlan(struct bonding *bond, unsigned short vlan_id)
852
{
853
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
854
        u32 curr_index;
855
 
856
        _lock_rx_hashtbl(bond);
857
 
858
        curr_index = bond_info->rx_hashtbl_head;
859
        while (curr_index != RLB_NULL_INDEX) {
860
                struct rlb_client_info *curr = &(bond_info->rx_hashtbl[curr_index]);
861
                u32 next_index = bond_info->rx_hashtbl[curr_index].next;
862
                u32 prev_index = bond_info->rx_hashtbl[curr_index].prev;
863
 
864
                if (curr->tag && (curr->vlan_id == vlan_id)) {
865
                        if (curr_index == bond_info->rx_hashtbl_head) {
866
                                bond_info->rx_hashtbl_head = next_index;
867
                        }
868
                        if (prev_index != RLB_NULL_INDEX) {
869
                                bond_info->rx_hashtbl[prev_index].next = next_index;
870
                        }
871
                        if (next_index != RLB_NULL_INDEX) {
872
                                bond_info->rx_hashtbl[next_index].prev = prev_index;
873
                        }
874
 
875
                        rlb_init_table_entry(curr);
876
                }
877
 
878
                curr_index = next_index;
879
        }
880
 
881
        _unlock_rx_hashtbl(bond);
882
}
883
 
884
/*********************** tlb/rlb shared functions *********************/
885
 
886
static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
887
{
888
        struct bonding *bond = bond_get_bond_by_slave(slave);
889
        struct learning_pkt pkt;
890
        int size = sizeof(struct learning_pkt);
891
        int i;
892
 
893
        memset(&pkt, 0, size);
894
        memcpy(pkt.mac_dst, mac_addr, ETH_ALEN);
895
        memcpy(pkt.mac_src, mac_addr, ETH_ALEN);
896
        pkt.type = __constant_htons(ETH_P_LOOP);
897
 
898
        for (i = 0; i < MAX_LP_BURST; i++) {
899
                struct sk_buff *skb;
900
                char *data;
901
 
902
                skb = dev_alloc_skb(size);
903
                if (!skb) {
904
                        return;
905
                }
906
 
907
                data = skb_put(skb, size);
908
                memcpy(data, &pkt, size);
909
 
910
                skb->mac.raw = data;
911
                skb->nh.raw = data + ETH_HLEN;
912
                skb->protocol = pkt.type;
913
                skb->priority = TC_PRIO_CONTROL;
914
                skb->dev = slave->dev;
915
 
916
                if (!list_empty(&bond->vlan_list)) {
917
                        struct vlan_entry *vlan;
918
 
919
                        vlan = bond_next_vlan(bond,
920
                                              bond->alb_info.current_alb_vlan);
921
 
922
                        bond->alb_info.current_alb_vlan = vlan;
923
                        if (!vlan) {
924
                                kfree_skb(skb);
925
                                continue;
926
                        }
927
 
928
                        skb = vlan_put_tag(skb, vlan->vlan_id);
929
                        if (!skb) {
930
                                printk(KERN_ERR DRV_NAME
931
                                       ": Error: failed to insert VLAN tag\n");
932
                                continue;
933
                        }
934
                }
935
 
936
                dev_queue_xmit(skb);
937
        }
938
}
939
 
940
/* hw is a boolean parameter that determines whether we should try and
941
 * set the hw address of the device as well as the hw address of the
942
 * net_device
943
 */
944
static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[], int hw)
945
{
946
        struct net_device *dev = slave->dev;
947
        struct sockaddr s_addr;
948
 
949
        if (!hw) {
950
                memcpy(dev->dev_addr, addr, dev->addr_len);
951
                return 0;
952
        }
953
 
954
        /* for rlb each slave must have a unique hw mac addresses so that */
955
        /* each slave will receive packets destined to a different mac */
956
        memcpy(s_addr.sa_data, addr, dev->addr_len);
957
        s_addr.sa_family = dev->type;
958
        if (dev->set_mac_address(dev, &s_addr)) {
959
                printk(KERN_ERR DRV_NAME
960
                       ": Error: dev->set_mac_address of dev %s failed! ALB "
961
                       "mode requires that the base driver support setting "
962
                       "the hw address also when the network device's "
963
                       "interface is open\n",
964
                       dev->name);
965
                return -EOPNOTSUPP;
966
        }
967
        return 0;
968
}
969
 
970
/* Caller must hold bond lock for write or curr_slave_lock for write*/
971
static void alb_swap_mac_addr(struct bonding *bond, struct slave *slave1, struct slave *slave2)
972
{
973
        struct slave *disabled_slave = NULL;
974
        u8 tmp_mac_addr[ETH_ALEN];
975
        int slaves_state_differ;
976
 
977
        slaves_state_differ = (SLAVE_IS_OK(slave1) != SLAVE_IS_OK(slave2));
978
 
979
        memcpy(tmp_mac_addr, slave1->dev->dev_addr, ETH_ALEN);
980
        alb_set_slave_mac_addr(slave1, slave2->dev->dev_addr, bond->alb_info.rlb_enabled);
981
        alb_set_slave_mac_addr(slave2, tmp_mac_addr, bond->alb_info.rlb_enabled);
982
 
983
        /* fasten the change in the switch */
984
        if (SLAVE_IS_OK(slave1)) {
985
                alb_send_learning_packets(slave1, slave1->dev->dev_addr);
986
                if (bond->alb_info.rlb_enabled) {
987
                        /* inform the clients that the mac address
988
                         * has changed
989
                         */
990
                        rlb_req_update_slave_clients(bond, slave1);
991
                }
992
        } else {
993
                disabled_slave = slave1;
994
        }
995
 
996
        if (SLAVE_IS_OK(slave2)) {
997
                alb_send_learning_packets(slave2, slave2->dev->dev_addr);
998
                if (bond->alb_info.rlb_enabled) {
999
                        /* inform the clients that the mac address
1000
                         * has changed
1001
                         */
1002
                        rlb_req_update_slave_clients(bond, slave2);
1003
                }
1004
        } else {
1005
                disabled_slave = slave2;
1006
        }
1007
 
1008
        if (bond->alb_info.rlb_enabled && slaves_state_differ) {
1009
                /* A disabled slave was assigned an active mac addr */
1010
                rlb_teach_disabled_mac_on_primary(bond,
1011
                                                  disabled_slave->dev->dev_addr);
1012
        }
1013
}
1014
 
1015
/**
1016
 * alb_change_hw_addr_on_detach
1017
 * @bond: bonding we're working on
1018
 * @slave: the slave that was just detached
1019
 *
1020
 * We assume that @slave was already detached from the slave list.
1021
 *
1022
 * If @slave's permanent hw address is different both from its current
1023
 * address and from @bond's address, then somewhere in the bond there's
1024
 * a slave that has @slave's permanet address as its current address.
1025
 * We'll make sure that that slave no longer uses @slave's permanent address.
1026
 *
1027
 * Caller must hold bond lock
1028
 */
1029
static void alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *slave)
1030
{
1031
        int perm_curr_diff;
1032
        int perm_bond_diff;
1033
 
1034
        perm_curr_diff = memcmp(slave->perm_hwaddr,
1035
                                slave->dev->dev_addr,
1036
                                ETH_ALEN);
1037
        perm_bond_diff = memcmp(slave->perm_hwaddr,
1038
                                bond->dev->dev_addr,
1039
                                ETH_ALEN);
1040
 
1041
        if (perm_curr_diff && perm_bond_diff) {
1042
                struct slave *tmp_slave;
1043
                int i, found = 0;
1044
 
1045
                bond_for_each_slave(bond, tmp_slave, i) {
1046
                        if (!memcmp(slave->perm_hwaddr,
1047
                                    tmp_slave->dev->dev_addr,
1048
                                    ETH_ALEN)) {
1049
                                found = 1;
1050
                                break;
1051
                        }
1052
                }
1053
 
1054
                if (found) {
1055
                        alb_swap_mac_addr(bond, slave, tmp_slave);
1056
                }
1057
        }
1058
}
1059
 
1060
/**
1061
 * alb_handle_addr_collision_on_attach
1062
 * @bond: bonding we're working on
1063
 * @slave: the slave that was just attached
1064
 *
1065
 * checks uniqueness of slave's mac address and handles the case the
1066
 * new slave uses the bonds mac address.
1067
 *
1068
 * If the permanent hw address of @slave is @bond's hw address, we need to
1069
 * find a different hw address to give @slave, that isn't in use by any other
1070
 * slave in the bond. This address must be, of course, one of the premanent
1071
 * addresses of the other slaves.
1072
 *
1073
 * We go over the slave list, and for each slave there we compare its
1074
 * permanent hw address with the current address of all the other slaves.
1075
 * If no match was found, then we've found a slave with a permanent address
1076
 * that isn't used by any other slave in the bond, so we can assign it to
1077
 * @slave.
1078
 *
1079
 * assumption: this function is called before @slave is attached to the
1080
 *             bond slave list.
1081
 *
1082
 * caller must hold the bond lock for write since the mac addresses are compared
1083
 * and may be swapped.
1084
 */
1085
static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slave *slave)
1086
{
1087
        struct slave *tmp_slave1, *tmp_slave2, *free_mac_slave;
1088
        struct slave *has_bond_addr = bond->curr_active_slave;
1089
        int i, j, found = 0;
1090
 
1091
        if (bond->slave_cnt == 0) {
1092
                /* this is the first slave */
1093
                return 0;
1094
        }
1095
 
1096
        /* if slave's mac address differs from bond's mac address
1097
         * check uniqueness of slave's mac address against the other
1098
         * slaves in the bond.
1099
         */
1100
        if (memcmp(slave->perm_hwaddr, bond->dev->dev_addr, ETH_ALEN)) {
1101
                bond_for_each_slave(bond, tmp_slave1, i) {
1102
                        if (!memcmp(tmp_slave1->dev->dev_addr, slave->dev->dev_addr,
1103
                                    ETH_ALEN)) {
1104
                                found = 1;
1105
                                break;
1106
                        }
1107
                }
1108
 
1109
                if (found) {
1110
                        /* a slave was found that is using the mac address
1111
                         * of the new slave
1112
                         */
1113
                        printk(KERN_ERR DRV_NAME
1114
                               ": Error: the hw address of slave %s is not "
1115
                               "unique - cannot enslave it!",
1116
                               slave->dev->name);
1117
                        return -EINVAL;
1118
                }
1119
 
1120
                return 0;
1121
        }
1122
 
1123
        /* The slave's address is equal to the address of the bond.
1124
         * Search for a spare address in the bond for this slave.
1125
         */
1126
        free_mac_slave = NULL;
1127
 
1128
        bond_for_each_slave(bond, tmp_slave1, i) {
1129
                found = 0;
1130
                bond_for_each_slave(bond, tmp_slave2, j) {
1131
                        if (!memcmp(tmp_slave1->perm_hwaddr,
1132
                                    tmp_slave2->dev->dev_addr,
1133
                                    ETH_ALEN)) {
1134
                                found = 1;
1135
                                break;
1136
                        }
1137
                }
1138
 
1139
                if (!found) {
1140
                        /* no slave has tmp_slave1's perm addr
1141
                         * as its curr addr
1142
                         */
1143
                        free_mac_slave = tmp_slave1;
1144
                        break;
1145
                }
1146
 
1147
                if (!has_bond_addr) {
1148
                        if (!memcmp(tmp_slave1->dev->dev_addr,
1149
                                    bond->dev->dev_addr,
1150
                                    ETH_ALEN)) {
1151
 
1152
                                has_bond_addr = tmp_slave1;
1153
                        }
1154
                }
1155
        }
1156
 
1157
        if (free_mac_slave) {
1158
                alb_set_slave_mac_addr(slave, free_mac_slave->perm_hwaddr,
1159
                                       bond->alb_info.rlb_enabled);
1160
 
1161
                printk(KERN_WARNING DRV_NAME
1162
                       ": Warning: the hw address of slave %s is in use by "
1163
                       "the bond; giving it the hw address of %s\n",
1164
                       slave->dev->name, free_mac_slave->dev->name);
1165
 
1166
        } else if (has_bond_addr) {
1167
                printk(KERN_ERR DRV_NAME
1168
                       ": Error: the hw address of slave %s is in use by the "
1169
                       "bond; couldn't find a slave with a free hw address to "
1170
                       "give it (this should not have happened)\n",
1171
                       slave->dev->name);
1172
                return -EFAULT;
1173
        }
1174
 
1175
        return 0;
1176
}
1177
 
1178
/**
1179
 * alb_set_mac_address
1180
 * @bond:
1181
 * @addr:
1182
 *
1183
 * In TLB mode all slaves are configured to the bond's hw address, but set
1184
 * their dev_addr field to different addresses (based on their permanent hw
1185
 * addresses).
1186
 *
1187
 * For each slave, this function sets the interface to the new address and then
1188
 * changes its dev_addr field to its previous value.
1189
 *
1190
 * Unwinding assumes bond's mac address has not yet changed.
1191
 */
1192
static int alb_set_mac_address(struct bonding *bond, void *addr)
1193
{
1194
        struct sockaddr sa;
1195
        struct slave *slave, *stop_at;
1196
        char tmp_addr[ETH_ALEN];
1197
        int res;
1198
        int i;
1199
 
1200
        if (bond->alb_info.rlb_enabled) {
1201
                return 0;
1202
        }
1203
 
1204
        bond_for_each_slave(bond, slave, i) {
1205
                if (slave->dev->set_mac_address == NULL) {
1206
                        res = -EOPNOTSUPP;
1207
                        goto unwind;
1208
                }
1209
 
1210
                /* save net_device's current hw address */
1211
                memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN);
1212
 
1213
                res = slave->dev->set_mac_address(slave->dev, addr);
1214
 
1215
                /* restore net_device's hw address */
1216
                memcpy(slave->dev->dev_addr, tmp_addr, ETH_ALEN);
1217
 
1218
                if (res) {
1219
                        goto unwind;
1220
                }
1221
        }
1222
 
1223
        return 0;
1224
 
1225
unwind:
1226
        memcpy(sa.sa_data, bond->dev->dev_addr, bond->dev->addr_len);
1227
        sa.sa_family = bond->dev->type;
1228
 
1229
        /* unwind from head to the slave that failed */
1230
        stop_at = slave;
1231
        bond_for_each_slave_from_to(bond, slave, i, bond->first_slave, stop_at) {
1232
                memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN);
1233
                slave->dev->set_mac_address(slave->dev, &sa);
1234
                memcpy(slave->dev->dev_addr, tmp_addr, ETH_ALEN);
1235
        }
1236
 
1237
        return res;
1238
}
1239
 
1240
/************************ exported alb funcions ************************/
1241
 
1242
int bond_alb_initialize(struct bonding *bond, int rlb_enabled)
1243
{
1244
        int res;
1245
 
1246
        res = tlb_initialize(bond);
1247
        if (res) {
1248
                return res;
1249
        }
1250
 
1251
        if (rlb_enabled) {
1252
                bond->alb_info.rlb_enabled = 1;
1253
                /* initialize rlb */
1254
                res = rlb_initialize(bond);
1255
                if (res) {
1256
                        tlb_deinitialize(bond);
1257
                        return res;
1258
                }
1259
        }
1260
 
1261
        return 0;
1262
}
1263
 
1264
void bond_alb_deinitialize(struct bonding *bond)
1265
{
1266
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
1267
 
1268
        tlb_deinitialize(bond);
1269
 
1270
        if (bond_info->rlb_enabled) {
1271
                rlb_deinitialize(bond);
1272
        }
1273
}
1274
 
1275
int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
1276
{
1277
        struct bonding *bond = bond_dev->priv;
1278
        struct ethhdr *eth_data = (struct ethhdr *)skb->mac.raw = skb->data;
1279
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
1280
        struct slave *tx_slave = NULL;
1281
        static u32 ip_bcast = 0xffffffff;
1282
        int hash_size = 0;
1283
        int do_tx_balance = 1;
1284
        u32 hash_index = 0;
1285
        u8 *hash_start = NULL;
1286
        int res = 1;
1287
 
1288
        /* make sure that the curr_active_slave and the slaves list do
1289
         * not change during tx
1290
         */
1291
        read_lock(&bond->lock);
1292
        read_lock(&bond->curr_slave_lock);
1293
 
1294
        if (!BOND_IS_OK(bond)) {
1295
                goto out;
1296
        }
1297
 
1298
        switch (ntohs(skb->protocol)) {
1299
        case ETH_P_IP:
1300
                if ((memcmp(eth_data->h_dest, mac_bcast, ETH_ALEN) == 0) ||
1301
                    (skb->nh.iph->daddr == ip_bcast)) {
1302
                        do_tx_balance = 0;
1303
                        break;
1304
                }
1305
                hash_start = (char*)&(skb->nh.iph->daddr);
1306
                hash_size = sizeof(skb->nh.iph->daddr);
1307
                break;
1308
        case ETH_P_IPV6:
1309
                if (memcmp(eth_data->h_dest, mac_bcast, ETH_ALEN) == 0) {
1310
                        do_tx_balance = 0;
1311
                        break;
1312
                }
1313
 
1314
                hash_start = (char*)&(skb->nh.ipv6h->daddr);
1315
                hash_size = sizeof(skb->nh.ipv6h->daddr);
1316
                break;
1317
        case ETH_P_IPX:
1318
                if (skb->nh.ipxh->ipx_checksum !=
1319
                    __constant_htons(IPX_NO_CHECKSUM)) {
1320
                        /* something is wrong with this packet */
1321
                        do_tx_balance = 0;
1322
                        break;
1323
                }
1324
 
1325
                if (skb->nh.ipxh->ipx_type != IPX_TYPE_NCP) {
1326
                        /* The only protocol worth balancing in
1327
                         * this family since it has an "ARP" like
1328
                         * mechanism
1329
                         */
1330
                        do_tx_balance = 0;
1331
                        break;
1332
                }
1333
 
1334
                hash_start = (char*)eth_data->h_dest;
1335
                hash_size = ETH_ALEN;
1336
                break;
1337
        case ETH_P_ARP:
1338
                do_tx_balance = 0;
1339
                if (bond_info->rlb_enabled) {
1340
                        tx_slave = rlb_arp_xmit(skb, bond);
1341
                }
1342
                break;
1343
        default:
1344
                do_tx_balance = 0;
1345
                break;
1346
        }
1347
 
1348
        if (do_tx_balance) {
1349
                hash_index = _simple_hash(hash_start, hash_size);
1350
                tx_slave = tlb_choose_channel(bond, hash_index, skb->len);
1351
        }
1352
 
1353
        if (!tx_slave) {
1354
                /* unbalanced or unassigned, send through primary */
1355
                tx_slave = bond->curr_active_slave;
1356
                bond_info->unbalanced_load += skb->len;
1357
        }
1358
 
1359
        if (tx_slave && SLAVE_IS_OK(tx_slave)) {
1360
                if (tx_slave != bond->curr_active_slave) {
1361
                        memcpy(eth_data->h_source,
1362
                               tx_slave->dev->dev_addr,
1363
                               ETH_ALEN);
1364
                }
1365
 
1366
                res = bond_dev_queue_xmit(bond, skb, tx_slave->dev);
1367
        } else {
1368
                if (tx_slave) {
1369
                        tlb_clear_slave(bond, tx_slave, 0);
1370
                }
1371
        }
1372
 
1373
out:
1374
        if (res) {
1375
                /* no suitable interface, frame not sent */
1376
                dev_kfree_skb(skb);
1377
        }
1378
        read_unlock(&bond->curr_slave_lock);
1379
        read_unlock(&bond->lock);
1380
        return 0;
1381
}
1382
 
1383
void bond_alb_monitor(struct bonding *bond)
1384
{
1385
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
1386
        struct slave *slave;
1387
        int i;
1388
 
1389
        read_lock(&bond->lock);
1390
 
1391
        if (bond->kill_timers) {
1392
                goto out;
1393
        }
1394
 
1395
        if (bond->slave_cnt == 0) {
1396
                bond_info->tx_rebalance_counter = 0;
1397
                bond_info->lp_counter = 0;
1398
                goto re_arm;
1399
        }
1400
 
1401
        bond_info->tx_rebalance_counter++;
1402
        bond_info->lp_counter++;
1403
 
1404
        /* send learning packets */
1405
        if (bond_info->lp_counter >= BOND_ALB_LP_TICKS) {
1406
                /* change of curr_active_slave involves swapping of mac addresses.
1407
                 * in order to avoid this swapping from happening while
1408
                 * sending the learning packets, the curr_slave_lock must be held for
1409
                 * read.
1410
                 */
1411
                read_lock(&bond->curr_slave_lock);
1412
 
1413
                bond_for_each_slave(bond, slave, i) {
1414
                        alb_send_learning_packets(slave,slave->dev->dev_addr);
1415
                }
1416
 
1417
                read_unlock(&bond->curr_slave_lock);
1418
 
1419
                bond_info->lp_counter = 0;
1420
        }
1421
 
1422
        /* rebalance tx traffic */
1423
        if (bond_info->tx_rebalance_counter >= BOND_TLB_REBALANCE_TICKS) {
1424
 
1425
                read_lock(&bond->curr_slave_lock);
1426
 
1427
                bond_for_each_slave(bond, slave, i) {
1428
                        tlb_clear_slave(bond, slave, 1);
1429
                        if (slave == bond->curr_active_slave) {
1430
                                SLAVE_TLB_INFO(slave).load =
1431
                                        bond_info->unbalanced_load /
1432
                                                BOND_TLB_REBALANCE_INTERVAL;
1433
                                bond_info->unbalanced_load = 0;
1434
                        }
1435
                }
1436
 
1437
                read_unlock(&bond->curr_slave_lock);
1438
 
1439
                bond_info->tx_rebalance_counter = 0;
1440
        }
1441
 
1442
        /* handle rlb stuff */
1443
        if (bond_info->rlb_enabled) {
1444
                /* the following code changes the promiscuity of the
1445
                 * the curr_active_slave. It needs to be locked with a
1446
                 * write lock to protect from other code that also
1447
                 * sets the promiscuity.
1448
                 */
1449
                write_lock(&bond->curr_slave_lock);
1450
 
1451
                if (bond_info->primary_is_promisc &&
1452
                    (++bond_info->rlb_promisc_timeout_counter >= RLB_PROMISC_TIMEOUT)) {
1453
 
1454
                        bond_info->rlb_promisc_timeout_counter = 0;
1455
 
1456
                        /* If the primary was set to promiscuous mode
1457
                         * because a slave was disabled then
1458
                         * it can now leave promiscuous mode.
1459
                         */
1460
                        dev_set_promiscuity(bond->curr_active_slave->dev, -1);
1461
                        bond_info->primary_is_promisc = 0;
1462
                }
1463
 
1464
                write_unlock(&bond->curr_slave_lock);
1465
 
1466
                if (bond_info->rlb_rebalance) {
1467
                        bond_info->rlb_rebalance = 0;
1468
                        rlb_rebalance(bond);
1469
                }
1470
 
1471
                /* check if clients need updating */
1472
                if (bond_info->rx_ntt) {
1473
                        if (bond_info->rlb_update_delay_counter) {
1474
                                --bond_info->rlb_update_delay_counter;
1475
                        } else {
1476
                                rlb_update_rx_clients(bond);
1477
                                if (bond_info->rlb_update_retry_counter) {
1478
                                        --bond_info->rlb_update_retry_counter;
1479
                                } else {
1480
                                        bond_info->rx_ntt = 0;
1481
                                }
1482
                        }
1483
                }
1484
        }
1485
 
1486
re_arm:
1487
        mod_timer(&(bond_info->alb_timer), jiffies + alb_delta_in_ticks);
1488
out:
1489
        read_unlock(&bond->lock);
1490
}
1491
 
1492
/* assumption: called before the slave is attached to the bond
1493
 * and not locked by the bond lock
1494
 */
1495
int bond_alb_init_slave(struct bonding *bond, struct slave *slave)
1496
{
1497
        int res;
1498
 
1499
        res = alb_set_slave_mac_addr(slave, slave->perm_hwaddr,
1500
                                     bond->alb_info.rlb_enabled);
1501
        if (res) {
1502
                return res;
1503
        }
1504
 
1505
        /* caller must hold the bond lock for write since the mac addresses
1506
         * are compared and may be swapped.
1507
         */
1508
        write_lock_bh(&bond->lock);
1509
 
1510
        res = alb_handle_addr_collision_on_attach(bond, slave);
1511
 
1512
        write_unlock_bh(&bond->lock);
1513
 
1514
        if (res) {
1515
                return res;
1516
        }
1517
 
1518
        tlb_init_slave(slave);
1519
 
1520
        /* order a rebalance ASAP */
1521
        bond->alb_info.tx_rebalance_counter = BOND_TLB_REBALANCE_TICKS;
1522
 
1523
        if (bond->alb_info.rlb_enabled) {
1524
                bond->alb_info.rlb_rebalance = 1;
1525
        }
1526
 
1527
        return 0;
1528
}
1529
 
1530
/* Caller must hold bond lock for write */
1531
void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave)
1532
{
1533
        if (bond->slave_cnt > 1) {
1534
                alb_change_hw_addr_on_detach(bond, slave);
1535
        }
1536
 
1537
        tlb_clear_slave(bond, slave, 0);
1538
 
1539
        if (bond->alb_info.rlb_enabled) {
1540
                bond->alb_info.next_rx_slave = NULL;
1541
                rlb_clear_slave(bond, slave);
1542
        }
1543
}
1544
 
1545
/* Caller must hold bond lock for read */
1546
void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char link)
1547
{
1548
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
1549
 
1550
        if (link == BOND_LINK_DOWN) {
1551
                tlb_clear_slave(bond, slave, 0);
1552
                if (bond->alb_info.rlb_enabled) {
1553
                        rlb_clear_slave(bond, slave);
1554
                }
1555
        } else if (link == BOND_LINK_UP) {
1556
                /* order a rebalance ASAP */
1557
                bond_info->tx_rebalance_counter = BOND_TLB_REBALANCE_TICKS;
1558
                if (bond->alb_info.rlb_enabled) {
1559
                        bond->alb_info.rlb_rebalance = 1;
1560
                        /* If the updelay module parameter is smaller than the
1561
                         * forwarding delay of the switch the rebalance will
1562
                         * not work because the rebalance arp replies will
1563
                         * not be forwarded to the clients..
1564
                         */
1565
                }
1566
        }
1567
}
1568
 
1569
/**
1570
 * bond_alb_handle_active_change - assign new curr_active_slave
1571
 * @bond: our bonding struct
1572
 * @new_slave: new slave to assign
1573
 *
1574
 * Set the bond->curr_active_slave to @new_slave and handle
1575
 * mac address swapping and promiscuity changes as needed.
1576
 *
1577
 * Caller must hold bond curr_slave_lock for write (or bond lock for write)
1578
 */
1579
void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave)
1580
{
1581
        struct slave *swap_slave;
1582
        int i;
1583
 
1584
        if (bond->curr_active_slave == new_slave) {
1585
                return;
1586
        }
1587
 
1588
        if (bond->curr_active_slave && bond->alb_info.primary_is_promisc) {
1589
                dev_set_promiscuity(bond->curr_active_slave->dev, -1);
1590
                bond->alb_info.primary_is_promisc = 0;
1591
                bond->alb_info.rlb_promisc_timeout_counter = 0;
1592
        }
1593
 
1594
        swap_slave = bond->curr_active_slave;
1595
        bond->curr_active_slave = new_slave;
1596
 
1597
        if (!new_slave || (bond->slave_cnt == 0)) {
1598
                return;
1599
        }
1600
 
1601
        /* set the new curr_active_slave to the bonds mac address
1602
         * i.e. swap mac addresses of old curr_active_slave and new curr_active_slave
1603
         */
1604
        if (!swap_slave) {
1605
                struct slave *tmp_slave;
1606
                /* find slave that is holding the bond's mac address */
1607
                bond_for_each_slave(bond, tmp_slave, i) {
1608
                        if (!memcmp(tmp_slave->dev->dev_addr,
1609
                                    bond->dev->dev_addr, ETH_ALEN)) {
1610
                                swap_slave = tmp_slave;
1611
                                break;
1612
                        }
1613
                }
1614
        }
1615
 
1616
        /* curr_active_slave must be set before calling alb_swap_mac_addr */
1617
        if (swap_slave) {
1618
                /* swap mac address */
1619
                alb_swap_mac_addr(bond, swap_slave, new_slave);
1620
        } else {
1621
                /* set the new_slave to the bond mac address */
1622
                alb_set_slave_mac_addr(new_slave, bond->dev->dev_addr,
1623
                                       bond->alb_info.rlb_enabled);
1624
                /* fasten bond mac on new current slave */
1625
                alb_send_learning_packets(new_slave, bond->dev->dev_addr);
1626
        }
1627
}
1628
 
1629
int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr)
1630
{
1631
        struct bonding *bond = bond_dev->priv;
1632
        struct sockaddr *sa = addr;
1633
        struct slave *slave, *swap_slave;
1634
        int res;
1635
        int i;
1636
 
1637
        if (!is_valid_ether_addr(sa->sa_data)) {
1638
                return -EADDRNOTAVAIL;
1639
        }
1640
 
1641
        res = alb_set_mac_address(bond, addr);
1642
        if (res) {
1643
                return res;
1644
        }
1645
 
1646
        memcpy(bond_dev->dev_addr, sa->sa_data, bond_dev->addr_len);
1647
 
1648
        /* If there is no curr_active_slave there is nothing else to do.
1649
         * Otherwise we'll need to pass the new address to it and handle
1650
         * duplications.
1651
         */
1652
        if (!bond->curr_active_slave) {
1653
                return 0;
1654
        }
1655
 
1656
        swap_slave = NULL;
1657
 
1658
        bond_for_each_slave(bond, slave, i) {
1659
                if (!memcmp(slave->dev->dev_addr, bond_dev->dev_addr, ETH_ALEN)) {
1660
                        swap_slave = slave;
1661
                        break;
1662
                }
1663
        }
1664
 
1665
        if (swap_slave) {
1666
                alb_swap_mac_addr(bond, swap_slave, bond->curr_active_slave);
1667
        } else {
1668
                alb_set_slave_mac_addr(bond->curr_active_slave, bond_dev->dev_addr,
1669
                                       bond->alb_info.rlb_enabled);
1670
 
1671
                alb_send_learning_packets(bond->curr_active_slave, bond_dev->dev_addr);
1672
                if (bond->alb_info.rlb_enabled) {
1673
                        /* inform clients mac address has changed */
1674
                        rlb_req_update_slave_clients(bond, bond->curr_active_slave);
1675
                }
1676
        }
1677
 
1678
        return 0;
1679
}
1680
 
1681
void bond_alb_clear_vlan(struct bonding *bond, unsigned short vlan_id)
1682
{
1683
        if (bond->alb_info.current_alb_vlan &&
1684
            (bond->alb_info.current_alb_vlan->vlan_id == vlan_id)) {
1685
                bond->alb_info.current_alb_vlan = NULL;
1686
        }
1687
 
1688
        if (bond->alb_info.rlb_enabled) {
1689
                rlb_clear_vlan(bond, vlan_id);
1690
        }
1691
}
1692
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.